내 시스템에 rootfs 파일 시스템이 없는 이유는 무엇입니까?

내 시스템에 rootfs 파일 시스템이 없는 이유는 무엇입니까?

이것리눅스 커널 문서주장하다:

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

아직 결정 하지는 않았지만 현실적으로 이전 구성표를 사용 하는 시스템 mtabrootfs.mountrootfsmtab

man mount계속: "실제 mtab 파일은 계속 지원되지만 현재 Linux 시스템에서는 이를 /proc/mounts에 대한 심볼릭 링크로 만드는 것이 더 좋습니다. 사용자 공간에 유지되는 일반 mtab 파일은 네임스페이스, 컨테이너와 안정적으로 상호 작용할 수 없기 때문입니다. 다른 고급 Linux와 함께 사용하십시오. 특징."

mtab은 Debian 7 및 Ubuntu 15.04에서 심볼릭 링크로 변환됩니다.

1.1 소스

데비안 보고서#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을 사용합니다).

우분투는 이 변경을 다음으로 연기했습니다.sysvinit_2.88dsf-53.2ubuntu1. 이 변경 로그 페이지는 "생생한" 변경 사항을 보여줍니다.우분투 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..ext4rootfsext4뿌리rootfs의 디렉터리입니다.

rootfs다양한 방법으로 찾을 수 있었습니다 . (적어도 한 명의 중요한 커널 개발자는 이것이 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

(파일시스템이 비어있는 것도 확인했어요)예상대로, 쓰기 가능).

관련 정보