web-dev-qa-db-ja.com

Linuxで/ dev / rootが表すデバイスを見つけますか?

Linuxでは、/dev/rootデバイスノードがあります。これは、/dev/sdaXなどの別のデバイスノードと同じブロックデバイスになります。この状況で/dev/rootを「実際の」デバイスノードに解決して、ユーザーにわかりやすいデバイス名を表示するにはどうすればよいですか?

たとえば、/proc/mountsを解析するときにこの状況が発生する可能性があります。

Shell/pythonスクリプトで機能するがCでは機能しないソリューションを探しています。

17
kdt

root=/proc/cmdlineパラメータを解析します。

私が調べたシステムでは、/dev/rootは実際のデバイスへのシンボリックリンクなので、readlink /dev/root(またはreadlink -f /dev/rootフルパスが必要な場合)、それを行います。

12
cjm

まあ_/dev/root_は実際のデバイスへの単なるシンボリックリンクなので、readlink(2)を使用してプログラムからどこを指しているかを見つけるか、readlink(1)を使用して同じことを行うことができますシェルスクリプトから。

7
TomH

ここに記載されている情報の多くは誤解を招くものであり、実際には完全に正しいものではなかった可能性があるため、これはおそらく更新する必要があります。

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スレッドです。このスレッドの時代から、すべてのバリアントが常に存在していたことがわかりますが、「ほとんどの」ディストリビューションはシンボリックを使用していたと思いますlinkメソッドですが、これは単純なカーネルコンパイルスイッチでした。投稿者を正しく理解していれば、1つにしたり、1つにしたりできません。つまり、一方向に切り替え、readlink/dev/rootが実際のデバイス名を報告し、切り替えます。他の、そしてそれはしません。

そのスレッドの主なトピックは/ dev/rootを取り除く方法でしたので、実際に何であるか、何を作るかなどを理解する必要がありました。つまり、それを理解するには、それを理解する必要がありました。

gnashlyはそれをうまく説明しました:

/ dev/rootは、fstabで使用できる汎用デバイスです。 「rootfs」を使用することもできます。これを行うと、特定性が低くなるという利点があります。つまり、ルートパーティションが外付けドライブにある場合、ルートパーティションが常に同じデバイスとして表示されず、正常にマウントできない場合があります。正しいデバイスに一致するようにfstabを変更する必要があります。/dev/rootを使用することで、liloまたはgrubからのカーネルブートパラメーターで指定されたデバイスと常に一致します。

/ dev/rootは、見たことがない場合でも、常に仮想マウントポイントとして存在します。 rootfsもある(これを、/ devの前に/ devがないprocやtmpfsなどの特別な仮想デバイスと比較してください)

/ dev/rootは、「proc」または/ dev/tcpのような仮想デバイスです。これらのもののための/ devにはデバイスノードがありません-それは仮想デバイスとしてカーネルにすでにあります。

これは、シンボリックリンクが必ずしも存在しない理由を説明しています。この情報を知る必要があるいくつかのプログラムを維持していることを考えると、今までにこの問題に遭遇したことがないことに驚いていますが、遅くなることはありません。

ここで提供されるソリューションのいくつかは「しばしば」機能し、おそらく私がすることになると思いますが、busyboxの作者が指摘したように、これらのソリューションは非常に複雑で非常に複雑です。堅牢な方法。

[更新:}いくつかのユーザーテストデータを取得した後、mountメソッドを使用します。これは、少なくとも一部のケースでは問題ないようです。バリアントが多すぎるため、/ proc/cmdlineは役に立ちませんでした。最初の例では、古いメソッドが表示されています。これらのパスは動的に変化する可能性があるため(ディスクの順序を入れ替えたり、新しいディスクを挿入したり、突然/ dev /)、これを使用することを強くお勧めしません(元の/ dev/sdx [0-9]タイプ構文)。 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)

Cmdlineの場合、理論的に正しい「答え」である唯一のバリアントは最初の非推奨のものです。これは、ルートを/ dev/sdxyのような移動するターゲットに参照するべきではないためです。

次の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が推奨するものを使用してください。

3
Lizardx

多分私は何かが足りないのですが、どうですか:

mount|grep ' / '|cut -d' ' -f 1
3
g33kz0r