はじめに
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」という理由で消すことができないファイル/ディレクトリがあることも頭の片隅に入れておくとどこかで役立つやもしれません。
以上、同様なことに興味がある方の参考になれば幸いです。