私のシステムにrootfsファイルシステムがないのはなぜですか?

私のシステムにrootfsファイルシステムがないのはなぜですか?

これLinuxカーネルドキュメント主張する:

Rootfs は、2.6 システムに常に存在していた ramfs (またはアクティブな場合は tmpfs) の特別なインスタンスです。 rootfsをアンマウントできません...

私がテストしたすべてのLinuxシステム(カーネル> 2.6および私が知っている限り、通常のブートプロセス、例えばubuntu 12.04)ではエントリは表示されませmountん。rootfs

しかしルートディレクトリの構築外部.cpioアーカイブを使用して存在するイメージを起動します。

rootfsどのような状況で入国が行われますかmount

答え1

  1. 以前のシステムでは、mountこれが一致しない可能性があります。/proc/mounts
  2. ほとんどの場合は表示されませんが、rootfsまだ/proc/mountsインストールされています。
  3. rootfsがまだマウントされていることを証明できますか?

1. 以前のシステムではmount同意しないことがあります。/proc/mounts

man mount「プログラムはmount通常、umountファイルに現在マウントされているファイルシステムのリストを維持します/etc/mtab。」

以前の方法は実際にはルートファイルシステムでは機能しません。ルートファイルシステムはmount//etc/mtab

まだ決定していないが、現実的に以前のスキームを使用するシステムmtabrootfsmountrootfsmtab

man mount続行:「実際のmtabファイルは引き続きサポートされていますが、現在のLinuxシステムではこれを/ proc / mountsへのシンボリックリンクにすることをお勧めします。他の高度なLinuxと組み合わせて使用​​してください。

mtabはDebian 7とUbuntu 15.04でシンボリックリンクに変換されます。

1.1 ソース

Debian レポート#494001 - "debian-installer: /etc/mtab は /proc/mounts へのシンボリックリンクでなければなりません。 Linux >= 2.6.26"

#494001 sysvinit-2.88dsf-14で修正されました。より結論、2011年12月14日付。この変更はDebian 7「Wheezy」に含まれています。 2013年5月4日に投稿しました。 (sysvinit-2.88dsf-41を使用してください)。

Ubuntuはこの変更を次に延期しました。sysvinit_2.88dsf-53.2ubuntu1。この変更ログページは、「鮮やかな」変更を示しています。Ubuntu 15.04のコードネームです。

rootfs2.ほとんどの場合は表示されませんが、/proc/mountsまだインストールされています。

Linux v4.17以降、このカーネル文書はまだ最新の状態です。 rootfsは常に存在し、マウント解除できません。ただし、ほとんどの場合、/proc/mountsではこれを見ることはできません。

initramfs シェルから起動すると rootfs を表示できます。dracutFedora Linuxのようにinitramfsがある場合は、カーネル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」をどうやって見つけますか?'。これは、Debian 7のカーネルバージョンと現在のカーネルv4.17の間のある時点で/proc/mountsがどのように表示されるかをカーネルが変更したためだと思います。さらなる検索では、私はrootfsだと思います。はいUbuntu 14.04では表示されますが、いいえUbuntu カーネル 4.4.0-28-generic を使用する Ubuntu 16.04 に表示されます。

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この技術では全体の順序を元に戻すことはできません。完全な順序は

  1. 現在の作業ディレクトリ(参照/proc/self/cwd)を新しいファイルシステムのマウントポイントに変更します。

    cd /newmount
    
  2. 新しいファイルシステムを移動します。つまり、マウントポイントを変更してルートディレクトリのすぐ上に配置します。

    mount --move . /
    
  3. /proc/self/root現在の作業ディレクトリと一致するように、現在のルートディレクトリ(のように)を変更します。

    chroot .
    

上記のchrootエスケープでは、ファイルシステムがにマウントされているため、usingを使用してext4ファイルシステムのルートから戻ることができます。rootfs..ext4rootfsext4rootfs のディレクトリです。

rootfsさまざまな方法で見つけることができました。 (少なくとも1つの重要なカーネル開発者はこれがLinuxのバグであると信じています。)

http://archive.today/2018.07.22-161140/https://lore.kernel.org/lkml/[Eメール保護]/

/* 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

(ファイルシステムが空であることも確認しました)予想通り、書き込み可能)。

関連情報