Linuxカーネルのドキュメントによると:
Rootfsは、ramfs(または、有効になっている場合はtmpfs)の特別なインスタンスです。
これは、2.6システムに常に存在します。 rootfsをアンマウントすることはできません…
テストしたすべてのLinuxシステム(カーネル> 2.6およびafaikの通常の起動手順(ubuntu 12.04など))、mount
rootfs
は表示されません エントリ。
ただし、外部の.cpio
で起動する場合のbuildrootイメージの場合 アーカイブ、それは存在します。
どのような場合にrootfs
がありますか mount
のエントリ ?
承認された回答:
- 古いシステムでは、
mount
/proc/mounts
と一致しない場合があります - ほとんどの場合、
rootfs
は表示されません/proc/mounts
にあります 、しかしそれはまだマウントされています。 - rootfsがまだマウントされていることを証明できますか?
1。古いシステムでは、mount
/proc/mounts
と一致しない場合があります
man mount
「プログラムはmount
およびumount
従来、ファイル/etc/mtab
に現在マウントされているファイルシステムのリストを保持していました 。」
古いアプローチは、ルートファイルシステムでは実際には機能しません。ルートファイルシステムは、mount
ではなく、カーネルによってマウントされている可能性があります 。したがって、/
のエントリ /etc/mtab
にあります かなり工夫されている可能性があり、必ずしもカーネルの現在のマウントリストと同期しているとは限りません。
確認はしていませんが、実際には、古いスキームを使用するシステムでmtab
が初期化されるとは思いません。 rootfs
の行を表示するには 。 (理論的には、mount
かどうか rootfs
を表示します mtab
を最初にインストールしたソフトウェアによって異なります ファイル)。
man mount
「実際のmtabファイルは引き続きサポートされますが、現在のLinuxシステムでは、代わりに/ proc / mountsへのシンボリックリンクにすることをお勧めします。ユーザースペースに保持されている通常のmtabファイルは、名前空間、コンテナー、その他の高度なLinuxで確実に機能しないためです。機能。」
mtabは、Debian7およびUbuntu15.04でシンボリックリンクに変換されます。
1.1ソース
Debianレポート#494001 –「debian-installer:/ etc / mtabは、Linux>=2.6.26で/proc/mountsへのシンボリックリンクである必要があります」
#494001はsysvinit-2.88dsf-14で解決されています。 2011年12月14日付けのクロージングメッセージを参照してください。この変更は、2013年5月4日にリリースされたDebian 7「Wheezy」に含まれています(sysvinit-2.88dsf-41を使用しています)。
Ubuntuはこの変更をsysvinit_2.88dsf-53.2ubuntu1まで延期しました。その変更ログページには、Ubuntu15.04のコードネームである「vivid」に変更が入力されていることが示されています。
2。ほとんどの場合、rootfs
は表示されません /proc/mounts
にあります 、しかしそれはまだマウントされています
Linux v4.17の時点で、このカーネルのドキュメントはまだ最新です。 rootfsは常に存在し、アンマウントすることはできません。ただし、ほとんどの場合、/ proc/mountsには表示されません。
initramfsシェルを起動すると、rootfsが表示されます。 initramfsがdracut
の場合 、Fedora Linuxの場合と同様に、オプションrd.break
を追加することでこれを行うことができます。 カーネルコマンドラインに。 (例:GRUBブートローダー内)
switch_root:/# grep rootfs /proc/mounts
rootfs / rootfs rw 0 0
dracutがシステムを実際のルートファイルシステムに切り替えると、/ proc/mountsにrootfsが表示されなくなります。 dracutは、switch_root
のいずれかを使用できます またはsystemd
これをする。これらは両方とも同じ一連の操作に従います。これは、リンクされたカーネルドキュメントで推奨されています。
他のいくつかの投稿では、initramfsから切り替えた後、/ proc/mountsでrootfsを見ることができます。たとえば、Debian 7の場合:「「rootfs」について知るにはどうすればよいですか?」これは、Debian7のカーネルバージョンと現在のカーネルv4.17の間のある時点で、カーネルが/ proc/mountsの表示方法を変更したためだと思います。さらに検索すると、rootfsはUbuntu 14.04に表示されていると思いますが、Ubuntuカーネル4.4.0-28-genericを搭載したUbuntu16.04には表示されていません。
関連:Linux – / dev / urandomの文字「u」はどういう意味ですか?initramfsを使用せず、代わりにカーネルにルートファイルシステムをマウントさせても、/ proc/mountsにrootfsが表示されません。カーネルコードも同じ一連の操作に従うように見えるため、これは理にかなっています。
rootfsを非表示にする操作はchroot
です。 。
switch_root:/# cd /sysroot
switch_root:/sysroot# mount --bind /proc proc
switch_root:/sysroot# grep rootfs proc/mounts
rootfs / rootfs rw 0 0
switch_root:/sysroot# chroot .
sh-4.4# cat proc/mounts
/dev/sda3 / ext4 ro,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
3。 rootfsがまだマウントされていることを証明できますか?
有名なことに、単純なchroot
特権ユーザーとして実行しているときにエスケープすることができます。 switch_root
の場合 chroot
以外は何もしませんでした 、それを逆にして、rootfsをもう一度見ることができます。
sh-4.4# python3
...
>>> import os
>>> os.system('mount --bind / /mnt')
>>> os.system('cat proc/mounts')
/dev/sda3 / ext4 ro,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
/dev/sda3 /mnt ext4 ro,relatime 0 0
>>> os.chroot('/mnt')
>>>
>>> # now the root, "/", is the old "/mnt"...
>>> # but the current directory, ".", is outside the root :-)
>>>
>>> os.system('cat proc/mounts')
/dev/sda3 / ext4 ro,relatime 0 0
>>> os.chdir('..')
>>> os.system('bash')
shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
bash-4.4# chroot .
sh-4.4# grep rootfs proc/mounts
rootfs / rootfs rw 0 0
ただし、完全なswitch_root
この手法ではシーケンスを逆にすることはできません。完全なシーケンスは
-
現在の作業ディレクトリを変更します(
/proc/self/cwd
のように) )、新しいファイルシステムのマウントポイントへ:cd /newmount
-
新しいファイルシステムを移動します。つまり、マウントポイントを変更して、ルートディレクトリの一番上に直接配置されるようにします。
mount --move . /
-
現在のルートディレクトリを変更します(
/proc/self/root
のように) )現在の作業ディレクトリと一致させます。chroot .
上記のchrootエスケープでは、ext4
のルートディレクトリからトラバースできました。 ファイルシステムをrootfs
に戻す ..
を使用する 、ext4
ファイルシステムはrootfs
のサブディレクトリにマウントされました 。 ext4
の場合、escapeメソッドは機能しません ファイルシステムはルートにマウントされています rootfsのディレクトリ。
rootfs
を見つけることができました 別の方法を使用します。 (少なくとも1人の重要なカーネル開発者はこれをLinuxのバグと考えています。)
http://archive.today/2018.07.22-161140/https://lore.kernel.org/lkml/[メール保護]/
/* CURSED.c - DO NOT RUN THIS PROGRAM INSIDE YOUR MAIN MOUNT NAMESPACE */
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> /* open() */
#include <sys/mount.h>
#include <sched.h> /* setns() */
#include <sys/statfs.h>
int main() {
int fd = open("/proc/self/ns/mnt", O_RDONLY);
/* "umount -l /" - lazy unmount everything we can see */
umount2("/", MNT_DETACH);
/* reset root, by re-entering our mount namespace */
setns(fd, CLONE_NEWNS);
/* "stat -f /" - inspect the root */
struct statfs fs;
statfs("/", &fs);
}
Linux 4.17.3-200.fc28.x86_64でテスト済み:
$ make CURSED
cc CURSED.c -o CURSED
$ sudo unshare -m strace ./CURSED
...
openat(AT_FDCWD, "/proc/self/ns/mnt", O_RDONLY) = 3
umount2("/", MNT_DETACH) = 0
setns(3, CLONE_NEWNS) = 0
statfs("/", {f_type=RAMFS_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID}) = 0
^
^ result: rootfs uses ramfs code on this system
(また、このファイルシステムは期待どおりに空であり、書き込み可能であることを確認しました。)