(O+P)ut

アウトプット



(O+P)ut

エンジニアのアウトプット

【Linux】Device or resource busy で消せないファイル

スポンサーリンク

はじめに

Docker環境で以下の禁断コマンドを打った結果、「Device or resource busy」という理由で消えなかったファイルをピックアップしてみました。

rm -rf / 
環境情報

Ubuntuのコンテナに接続

# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                       PORTS               NAMES
06196a0265ca        ubuntu              "/bin/bash"         3 weeks ago         Up 3 weeks   
# docker attach 06196a0265ca
root@06196a0265ca:/#

Ubuntuのバージョン

root@06196a0265ca:/# cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.2 LTS"

カーネルはRHEL

root@06196a0265ca:/# uname -a
Linux c78225ab5e9e 3.10.0-957.10.1.el7.x86_64 #1 SMP Thu Feb 7 07:12:53 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

ルートディレクトリ直下を全削除

最近のOSはよくできており空で rm -r f / を押下すると以下のように実行されません。

root@06196a0265ca:/# rm -rf /
rm: it is dangerous to operate recursively on '/'
rm: use --no-preserve-root to override this failsafe

ちなみに消す前の情報ですがルート直下には以下ディレクトリが存在します。

root@06196a0265ca:/# ls
bin   dev  home  lib64  mnt  proc  run   srv  tmp  var
boot  etc  lib   media  opt  root  sbin  sys  usr

以下コマンドで削除がスタートです。

root@06196a0265ca:/# rm -rf / --no-preserve-root
rm: cannot remove '/dev/console': Device or resource busy
...
rm: cannot remove '/dev/pts/ptmx': Operation not permitted
...
rm: cannot remove '/proc/fb': Permission denied
...
rm: cannot remove '/proc/fs/xfs/stat': Read-only file system
...

上にもある通り4パターンの理由で消えません

  • Device or resource busy
  • Operation not permitted
  • Permission denied
  • Read-only file system

ちなみにこのパターンの割合は消去できなかった全体12400ファイルに対して

Device or resource busy 7
Operation not permitted 1
Permission denied 542
Read-only file system 11850

でした。

Device or resource busyで消せなかったファイル

rm: cannot remove '/dev/console': Device or resource busy
rm: cannot remove '/dev/shm': Device or resource busy
rm: cannot remove '/dev/mqueue': Device or resource busy
rm: cannot remove '/etc/hostname': Device or resource busy
rm: cannot remove '/etc/hosts': Device or resource busy
rm: cannot remove '/etc/resolv.conf': Device or resource busy
rm: cannot remove '/run/secrets': Device or resource busy

それぞれの役割を解説します。

/dev/console

こちらはシステムメッセージを表示するコンソール用のデバイスファイルです。
カーネルメッセージが/dev/console送信されます。

# file /dev/console
/dev/console: character special (136/2)
/dev/shm

こちらはメモリの一部の領域として利用するRAMディスクです。
実体はディレクトリです。

# file /dev/shm
/dev/shm: sticky, directory
/dev/mqueue

こちらはプロセス間でデータのやり取りを行う際に利用します。
実体はディレクトリです。

# file /dev/mqueue
/dev/mqueue: sticky, directory
/etc/hostname

こちらはホスト名が記載されているテキストファイルです。

# file /etc/hostname
/etc/hostname: ASCII text
/etc/hosts

こちらは所謂hostsファイルです。編集する機会も多いファイルですが、消せないファイルです。

# file /etc/hosts   
/etc/hosts: ASCII text
/etc/resolv.conf

こちらはレゾルバ設定ファイルでネームサーバーのIPアドレスを記載するファイルですが、消せません。

# file /etc/resolv.conf
/etc/resolv.conf: ASCII text
/run/secrets/

こちらはDocker故に存在するディレクトリで、ホスト側には存在しません。
機密データがこちらに格納されます。

# file /run/secrets/
/run/secrets/: directory

ディレクトリ自体の権限はゆるいですが削除はできません

# ls -ld /run/secrets drwxr-xr-x. 2 root root X X X /run/secrets/

おまけ

上記コマンドによって/bin/配下を全て消してしまってもechoやprintfは使えます。こんな状況を想像したくないですが...

root@06196a0265ca:/# ls
bash: /bin/ls: No such file or directory
root@06196a0265ca:/# echo *    
dev etc proc run sys
root@06196a0265ca:/# echo /dev/*
/dev/console /dev/mqueue /dev/pts /dev/shm

終わりに

Docker環境では好き勝手なコマンドをホスト側に影響を与えることなく打つことができます。改めて、開発環境としては便利なことを再確認しました。

それと合わせて、権限上は消すことが可能でも「Device or resource busy」という理由で消すことができないファイル/ディレクトリがあることも頭の片隅に入れておくとどこかで役立つやもしれません。

以上、同様なことに興味がある方の参考になれば幸いです。