Linuxには、/dev/root
デバイスノードがあります。これは、などの別のデバイスノードと同じブロックデバイスになります/dev/sdaX
。/dev/root
この状況で「実際の」デバイスノードに解決して、ユーザーに適切なデバイス名を表示するにはどうすればよいですか?
たとえば、解析中にこの状況が発生する場合があります/proc/mounts
。
私はシェル/ Pythonスクリプトで動作するがCでは動作しないソリューションを探しています。
Linuxには、/dev/root
デバイスノードがあります。これは、などの別のデバイスノードと同じブロックデバイスになります/dev/sdaX
。/dev/root
この状況で「実際の」デバイスノードに解決して、ユーザーに適切なデバイス名を表示するにはどうすればよいですか?
たとえば、解析中にこの状況が発生する場合があります/proc/mounts
。
私はシェル/ Pythonスクリプトで動作するがCでは動作しないソリューションを探しています。
回答:
root=
からパラメータを解析します/proc/cmdline
。
私が見たシステムで/dev/root
は、実際のデバイスへのシンボリックリンクであるため、readlink /dev/root
(またはreadlink -f /dev/root
フルパスが必要な場合)、それを行います。
ls -l /dev/root
-入力するのが短い:)
ls
(彼はスクリプトで使用するものを求めました)。
ここで提供される情報の多くは誤解を招くものであり、実際には包括的に正しいものではなかった可能性があるため、これはおそらく更新する必要があります。
https://bootlin.com/blog/find-root-device/
/マウントポイントについては、探している実際のデバイスではない/ dev / rootに対応していることが通知されます。
もちろん、カーネルコマンドラインを見て、Linuxが起動するように指示された初期ルートファイルシステムを確認できます(ルートパラメーター)。
$ cat / proc / cmdline mem = 512M console = ttyS2,115200n8 root = / dev / mmcblk0p2 rw rootwait
ただし、これは、表示されているものが現在のルートデバイスであることを意味するものではありません。多くのLinuxシステムは、中間ルートファイルシステム(initramdisksやinitramfsなど)でブートします。これらは最終システムにアクセスするために使用されます。
これが指摘していることの1つは、/ proc / cmdlineにあるものが、実際に実際に存在する実際の最終的なデバイスルートとは限らないことです。
これはbusyboxの人たちからです。私は彼らがブート状況に関して何について話しているか知っていると思います。
https://www.linuxquestions.org/questions/slackware-14/slackware-current-dev-root-688189/page2.html
私が見つけた2番目の有用なリソースは、/ dev / rootの問題に関する非常に古いSlackwareスレッドです。このスレッドの時代から、すべてのバリアントが常に存在していたことがわかりますが、「ほとんどの」ディストリビューションはシンボリックを使用していたと信じていますリンク方法ですが、それは単純なカーネルコンパイルスイッチでした。ポスターを正しく理解していれば、それを作成することも、作成しないこともできます。つまり、一方向に切り替え、readlink / dev / rootが実際のデバイス名を報告して、それを切り替えます。もう一方、そうではありません。
そのスレッドの主なトピックは/ dev / rootを取り除く方法でしたので、彼らはそれが実際に何であるか、何がそれを作るのかなどを理解しなければなりませんでした。
gnashlyはそれをうまく説明しました:
/ dev / rootは、fstabで使用できる汎用デバイスです。「rootfs」も使用できます。これを行うと、特定性が低くなるという利点があります。つまり、ルートパーティションが外部ドライブ上にある場合、常に同じデバイスとして表示されず、/として正しくマウントされるとは限らないため、正しいデバイスに合わせてfstabを変更する必要があります。/ dev / rootを使用することにより、liloまたはgrubのカーネルブートパラメーターで指定されたデバイスと常に一致します。
/ dev / rootは、見たことがない場合でも常に仮想マウントポイントとして存在します。rootfsも同様です(これを、/ devの前にないprocやtmpfsなどの特別な仮想デバイスと比較してください)
/ dev / rootは、「proc」や/ dev / tcpなどの仮想デバイスです。これらのことのために/ devにデバイスノードはありません-それはすでに仮想デバイスとしてカーネルにあります。
これは、シンボリックリンクが必ずしも存在しない理由を説明しています。この情報を知る必要があるいくつかのプログラムを維持しているのに、今までこの問題に出会ったことがないのに驚いていますが、決して遅くはありません。
ここで提供される解決策のいくつかは「しばしば」機能し、おそらく私がやることだと思いますが、それは問題に対する実際の真の解決策ではありません。busyboxの著者が述べたように、堅牢な方法。
[更新:}ユーザーテストデータを取得した後、少なくとも一部のケースでは問題ないように思えるマウントメソッドを使用します。バリアントが多すぎるため、/ proc / cmdlineは役に立ちませんでした。最初の例では、古いメソッドが表示されます。これらのパスは動的に変更される可能性があるため(ディスクの順序を入れ替える、新しいディスクを挿入するなど)、突然/ dev / sda1は/ dev / sdb1になります。
root=/dev/sda1
root=UUID=5a25cf4a-9772-40cd-b527-62848d4bdfda
root=LABEL=random string
root=PARTUUID=a2079bfb-02
VS非常にクリーンで解析しやすい:
mount
/dev/sda1 on / type ext4 (rw,noatime,data=ordered)
/ dev / sdxyのような移動するターゲットにルートを参照するべきではないため、cmdlineの場合、理論的に正しい「答え」である唯一のバリアントは、非推奨の最初のバリアントです。
次の2つは、/ dev / disk / by-uuidまたは/ dev / disk / by-labelの文字列からシンボリックリンクを取得するという追加のアクションを実行する必要があります
最後の1つは、parted -lを使用して、そのparted IDが指しているものを見つけることを信じる必要があります。
それは私が知っていて見た変種だけです。たとえば、GPTIDのような他のものがあるかもしれません。
だから私が使用しているソリューションはこれです:
まず、/ dev / rootがシンボリックリンクかどうかを確認します。存在する場合は、/ dev / disk / by-uuidまたはby-labelでないことを確認します。存在する場合は、処理の2番目のステップを実行して、最後の実際のパスを取得する必要があります。使用するツールに依存します。
何も得られない場合は、マウントに移動して、それがどのようであるかを確認します。最後のフォールバックケースとして、私が使用していないものは、必ずしも問題の実際のパーティションまたはデバイスであるとは限らないために与えられた引数は、私のプログラムの解決策を拒否するのに十分であるためです。マウントは完全に堅牢なソリューションではなく、十分なサンプルが与えられていると確信しています。まったく正しくないケースを見つけるのは簡単ですが、これらの2つのケースは「ほとんどの」ユーザーをカバーすると信じています。
最も素晴らしく、きれいで、最も信頼性の高いソリューションは、カーネルが常にシンボリックリンクを作成することでした。これにより、何もまたは誰も傷つけず、それを良いと呼ぶことができましたが、それは現実の世界ではうまくいきませんでした。。
これらのいずれも「良いまたは堅牢な」ソリューションとは見なしませんが、マウントオプションは「十分な」を満たしているように見えます。真に堅牢なソリューションが必要な場合は、busyboxが推奨するものを使用してください。