私はDebian Stretchを使用しています。ルートパーティションがread-only
にマウントされています。パッケージをインストールまたはアップグレードした場合のみ、/
がread-write
に再マウントされ(aptフックを使用)、次にro
に再マウントされます。
パッケージのアップグレード後、/
を読み取り専用に再マウントできないことがあります。
mount -o remount,ro /
mount: / is busy
古いDebianバージョン(Wheezy)では、lsof
でリンク解除された開いているファイルを一覧表示できました。
lsof +L1
または、具体的には、/
がroに再マウントされないようにするファイル:
{ lsof +L1 ; lsof|sed -n '/SYSV/d; /DEL|(path /p;' ; } | grep -Ev '/(dev|home|tmp|var)'
ただし、Debian Stretchでは、lsof +L1
はファイルをリストしません。
+|-L
のman lsof
が変更された理由はわかりません。
lsof + L1がリンク解除された開いているファイルを一覧表示しないのはなぜですか?
/が読み取り専用に再マウントされないようにするファイルを一覧表示するにはどうすればよいですか?
[〜#〜]更新[〜#〜]
停止できるすべてのプロセスを停止しましたが、init
とgetty
のみが実行されていますが、/
をro
に再マウントできません。
/が読み取り専用に再マウントされないようにするファイルを一覧表示するにはどうすればよいですか?
A)fuser
はpsmisc
パッケージにあります。これは、fuser
がlsof
より優れており、systemd
よりも有用である場合の使用例です。
_# fuser -v -m / 2>&1 | grep '[Ff]r.e'
_
これにより、読み取り(f)および書き込み(F)のために/でファイルを開いているすべてのプロセスが表示されます。 /が読み取り専用に再マウントされるのを防ぐファイルは、書き込み用に開かれているファイルです(F)。
書き込み可能なルートディレクトリファイルを開いた状態で実行されている実行可能ファイル]であるプロセスを強制終了します 。、つまり
# for fupid in $(fuser -v -m / 2>&1 | grep Fr.e | awk '{print $2}'); do kill $fupid; done
これは、systemd
コメントを上回っていますが、注意が必要です。 init
がfuser
の場合、systemd
はそれを表示し、他の考慮事項があります。 fuser
を実行すると、たとえsystemd
でプロセスが識別されて強制終了された場合でも、背後でプロセスを(再)開始できます。 sysvinit
は、従来のinit
よりもはるかに高度です。
B)説明の[〜#〜] update [〜#〜]には、システムにあるのは...getty
およびsystemd
はまだ実行中です...
システムがinit
を使用しておらず、systemd
を使用しているというコメントが表示されます。ストレッチでは、init
issysvinit
です。コメントにはsystemd
が明示的に示されていなかったため、問題のシステムがinit
にデフォルトのストレッチsystemd
を使用している可能性があると想定しています。または、この投稿につまずいてストレッチのsysvinit
を使用している他の人がこの部分が役立つと感じていること。
Debian Wiki によると、
システム初期化プロセスは、initデーモンによって処理されます。 squeeze以前のリリースでは、そのデーモンはsysvinitパッケージによって提供されており、代替はサポートされていません。Inwheezyでは、デフォルトのinitデーモンは
systemd
のままですが、systemdの「テクノロジープレビュー」を利用できます。Injessieおよびstretch、デフォルトの初期化システムはsystemd
、ただし、sysvinitへの切り替えはサポートされています。Jessie以降、systemdのみが完全にサポートされています。 sysvinitはほとんどサポートされていますが、sysvinit起動スクリプトを提供するためにDebianパッケージは必要ありません。 runitもパッケージ化されていますが、他のものと同じレベルのテストとサポートを受けておらず、現在PID 1としてサポートされていません。
NetworkManager
を実行している場合、問題なく再マウントできるように、解放するために実行する必要がある追加の手順がいくつかあります。
_system.slice
_が_systemd-journald.service
_または_systemd-udevd.service
_(どちらもソケット依存関係がある)のオープンファイルを保持している可能性があります。または、dhclient
が実行されている場合、リースを/ var /...(&/ var /isnに書き込むfuser
を再生成できます。常にそれ自身のデバイスではありません)など。dhclient
は検出する可能性があり、NetworkManager
を強制終了します。
道徳は、自動化された多くのことを「望んでいる」/(さらにはsystemd
を使用して)可能です。
確かに、可能であれば、実行レベル1に相当するsystemd
は_rescue.target
_と一致します(および_runlevel1.target
_は_rescue.target
_へのシンボリックリンクです)。
1)システムを_rescue.target
_に分離することから始めます
_# systemctl isolate rescue.target
_
rootパスワードの入力を求めるプロンプトが表示されます。画面の指示に従ってください。
2)レスキューシェルで、何が必要かを確認します。
_# systemctl show -p Wants /
_
通常、それは_system.slice
_です。 /.を必要とするすべてのものを停止します。
_# systemctl stop system.slice
_
3)この時点で、再マウントは_mount: / is busy
_と_mount -o remount,ro /
_を報告しないはずですはずです。そうでない場合は、fuser
で再度確認してください。
4)FWIW;また、別のマウントのサブディレクトリに別のデバイスがマウントされている場合、つまりネストされたマウントの場合、umount
が失敗することもありました。たとえば、/ var /または/ boot /が別のデバイス上にあり、マウントされている場合、_umount /
_は失敗します。ただし、この場合でも_mount -o remount,ro /
_は機能します。
lsblk
は、ネストされたマウントを視覚化するのに役立ちます。
lsof + L1がリンク解除された開いているファイルを一覧表示しないのはなぜですか?
それらは利用できないため(ソケットまたはほとんどのFIFOおよびパイプ)、ファイルを開いていない(親プロセスがファイル記述子を閉じている)か、リンク数が1を超えています(まだ)。
man lsof(8) 詳細...
+ | -L[l]
このオプションは、ファイルリンクカウントのリストを有効化( '+')または無効化( '-')します。使用可能な場所-たとえば、ソケットやほとんどのFIFOでは使用できません。パイプ
+ Lを次の番号なしで指定すると、すべてのリンク数がリストされます。 -Lが指定されている場合(デフォルト)、リンク数はリストされません。
+ Lの後に数字が続く場合、その数より少ないリンク数を持つファイルのみがリストされます。 (-Lの後に数字を続けることはできません。) '' + L1 ''の形式で指定すると、リンクが解除された開いているファイルが選択されます。 _
+aL1 <file_system>
_形式の指定は、指定されたファイルシステム上のリンクされていない開いているファイルを選択します。
_/proc
_をマウントしていますか?
ほとんどの場合、_/
_が読み取り専用でマウントされるように注意を払っている人であるように思われるので、procfsをマウントしないことを選択した可能性もあります。しかし、procfsはlsof
が開いているファイルを見つけるために必要です。
プロセスによって開かれているファイルは、procfsのシンボリックリンクを介してカーネルによって公開されます。ディレクトリ_/proc/<pid>/fd
_には、開いたままにした各ファイルのシンボリックリンクが含まれています。シンボリックリンクの名前はファイル記述子番号であり、シンボリックリンクによって参照されるパスはファイルパスです。
既に削除されている開いているファイルのぶら下がりシンボリックリンクは_/proc
_に残ります。そして、ファイルの参照パスは「(削除済み)」で終わるように名前が変更されます。
_lsof +L1
_の機能は、基本的に次のような簡単なワンライナーと同じです。
_stat -c%N /proc/[0-9]*/fd/* | grep deleted
_
したがって、同様のワンライナーを使用して、ルートファイルシステムの再マウントを妨げる可能性があるall開いているファイルをリストできます(動作する_/proc
_が提供されている場合)。
ただし、_/proc
_をマウントしたか、またはマウントした場合、私が考えることができる他の唯一の原因はバグです...とにかく、私の現在のDebian Stretchシステムでの参考までに。 _lsof +L1
_は期待どおりに機能します。
_bash# lsb_release -d
Description: Debian GNU/Linux 9.5 (stretch)
bash# uname -a
Linux bwp-249-8 4.9.0-8-AMD64 #1 SMP Debian 4.9.110-3+deb9u4 (2018-08-21) x86_64 GNU/Linux
bash# lsof -v
lsof version information:
revision: 4.89
[...]
_
システムを可視化しないと、問題が何であるかを正確に伝えることは非常に困難です。コメントと以前の回答は良いスタートです。
とは言っても、マウント/読み取り専用の前提条件について説明しているdebian wikiを最後まで遡ります。
ドキュメントへのリンクはここにあります: https://wiki.debian.org/ReadonlyRoot
大きな問題はここで説明します。
1-/の下に読み取りと書き込みが必要な特定の場所があります。ドキュメントに基づくと、次のようになります。
ストレージデバイスの構成(パーティション、パーションレスlvmなど)に応じて、ブロックデバイスはおそらく異なりますが、主要なアイデアは、RWマウントオプションを使用するために、次のマウントされたファイルシステムに4つのマウントポイントが必要であることです。
2-/ etcには、シンボリックリンクを作成したり、その他の変更を実装したりする必要のある特別なファイルがいくつかあります(詳細は、リンク先の記事で詳しく説明されています)。これらは、Linuxサーバーが実行しているアプリケーションに基づいて適用される場合と適用されない場合があります。一部のファイルはあなたのマシンに存在しないかもしれませんが、私はすべてをドキュメントに含めました。プロセスのPIDを強制終了した場合でも、これらの変更を行うことを強くお勧めします。以下は、debian wikiからの直接のパスです。
上記のすべてをチェックし、それらがwikiの仕様に準拠していることを確認したら、次に確認することは/etc/apt/apt.confです。
DPkg {
// Auto re-mounting of a readonly /
Pre-Invoke { "mount -o remount,rw /"; };
Post-Invoke { "test ${NO_APT_REMOUNT:-no} = yes || mount -o remount,ro / || true"; };
};
あなたのエラーに基づいて、ドキュメントに基づいて確認できる最後のものは以下から来ます:
「パッケージのアップグレード後、mountが読み取り専用でファイルシステムを再マウントすることを拒否し、「/がビジーである」という問題に直面する場合があります。これは、プロセスがまだ使用している削除済みファイルが原因です。どのプロセスが削除済みファイルを使用しているかを確認するには、パッケージdebian-goodiesのツールcheckrestart(1)を使用するか、次のコマンドを使用します。多くの場合、これらはアップグレードされたライブラリを使用するデーモンです。ファイルを解放するために再起動する必要があります。」
ドキュメントで提供されるコマンド:
{lsof +L1; lsof|sed -n '/SYSV/d; /DEL\|(path /p;'} |grep -Ev '/(dev|home|tmp|var)'
ファイルシステムの正確な構成、パーティショニング、ストレージデバイスの構成を知らなければ、他に多くのことを実行するのは困難です。私は戻って、ドキュメントで(そして上記で概説した)前提条件を再確認することから始めます。
この問題を再現できるのは1回だけであり、mount
を-nオプションとともに使用するだけで解決できました。
引用man mount:
-n, --no-mtab Mount without writing in /etc/mtab. This is necessary for example when /etc is on a read-only filesystem.
ルートファイルシステムでmount
プログラム自体がwritingのファイルを開くのは、私にはもっともらしい説明のように聞こえました。具体的には、mount
は結局/etc/mtab
を書き込み、/etc
はルートファイルシステムの一部であることがよくあります。しかし、一度行った後、同じマシンで再び再現することはできませんでした...
これで問題を解決できますか?