chroot 技术–Linux 系统的瑞士军刀

有没有遇到过即使在确保 BIOS 设置没问题、没有重大硬件错误的情况下,Linux 系统还是无法启动的情况?

那么你就需要了解chroot技术,它可以拯救你的生命。

例如,在通过.iso 文件重新安装的官方方法失败后,我在上周用这种方法成功修复了一台 Nanopore GridION 设备,这提醒我要努力记录这些步骤。

我是在把 Linux 作为日常驱动程序使用了十多年之后才接触到这项技术的(感谢 Matt!),这意味着,鉴于它的实用性,我认为它值得更多关注。因此,我希望通过这篇文章来宣传一下。

简要说明

简而言之,它的原理是,如果你能访问损坏或无法启动的 Linux 机器的硬盘驱动器(例如,可以从 Live USB 盘启动,或将硬盘驱动器作为另一个 Linux 机器的额外驱动器插入),你就可以挂载该硬盘驱动器,从而欺骗当前的 Linux 会话,让它以为这是当前正在运行的系统的硬盘驱动器,而它当然不是。

实现这一功能的诀窍在于根据以下两点创建一个文件树:

已损坏系统的硬盘分区,该分区在主机操作系统上被挂载为 / 文件夹。

一组来自当前正在运行的临时操作系统(live stick 或替换电脑)的特殊系统文件夹,它们不是磁盘上的普通目录,而是包含正在运行的 linux 系统所需的系统信息。这些目录包括 /sys/proc 和其他一些目录,我们将在下文中详细介绍。

然后,在这个新组合的文件夹结构上运行 chroot 命令,这意味着当前运行的 Linux 会话将用这个新组合的文件夹替换当前的文件系统,而这些文件夹大多来自旧的、坏掉的硬盘。

这有点像把一辆出了故障的汽车连接到外部电源上,这样你至少可以访问它的仪表,检查里程数和显示屏上的错误代码等。

总之,这样就可以运行各种命令来修复或诊断你的系统了,如 apt upgradedpkg-reconfigure(用于 Debian 系统上损坏的软件包)或其他命令,具体取决于你系统的具体情况。

流程

最好能将设置组装文件夹结构和进行 chroot 的完整流程放在一处,以便需要时可以轻松找到。最理想的情况是,你甚至可以将这些命令打印出来,或者将它们存储在 “修复工具包 ”U 盘或类似设备的文本文件中。

总之,下面就是整个过程的所有步骤:

    1. 启动你的替代操作系统(Live USB 记忆棒,或其他连接有损坏电脑硬盘的电脑)。
    2. 找出故障系统硬盘上哪个分区存放根文件系统,哪个分区存放 /boot 文件夹。
      • 我通常使用 gparted 来完成这项工作,大多数基于 Ubuntu/Linux Mint 的实时磁盘上都有该工具。
      • 你也可以使用基于命令行的工具,如 sudo fdisk -l
      • 我通常会尝试将每个坏掉的系统分区挂载到文件导航器中(它们在 Thunar i Linux Mint XFCE 中通常显示为可挂载驱动器),以确保我选择了正确的分区。
      • 如果无法做到这一点,就只能根据文件系统的大小和类型、它们是否已在 /etc/fstab 中可用等进行猜测。
      • 在本例中,我们假设根文件夹位于分区中:
        /dev/nvme0n1p5
        

        ……并且 /boot 分区在其中:

        /dev/nvme0n1p3
        

        (我提到过的 Nanopore GridION 设备最近就是这样修理的)。

    3. 在当前运行系统的文件系统中创建一个文件夹,作为新的根文件夹,并在其中创建 /boot 文件夹:
      sudo mkdir /rescue
      sudo mkdir /rescue/boot
      
    4. 将已损坏系统的主分区和启动分区挂载到这些文件夹中,例如
      sudo mount /dev/nvme0n1p5 /rescue
      sudo mount /dev/nvme0n1p3 /rescue/boot
      
    5. 然后,将当前运行系统中需要的特殊文件夹挂载到新文件结构的适当位置(mount 命令的形式为 mount -t <文件系统类型> -o <选项> <设备> <挂载点>)。
      sudo mount -t proc proc /rescue/proc
      sudo mount -t sysfs sys /rescue/sys
      sudo mount -o bind /dev /rescue/dev
      sudo mount -t devpts pts /rescue/dev/pts
      
    6. 现在,我们准备 chroot,或 “更改根文件夹”,进入新创建的文件夹结构:
      chroot /rescue /bin/bash -i
      
    7. 我们就大功告成了!

现在,你可以查看文件系统,找出导致系统无法工作的原因,并使用所需的任何文件命令来修复损坏的系统,

在我们的 GridION 设备损坏案例中,我们在 /boot 中发现了一些损坏的 symlinks 和空 initrd.img-* 文件,这表明 Linux 内核更新可能在软件包更新或类似操作过程中中途中断了。

在这种情况下,运行 sudo apt update && sudo apt upgrade 就能解决这个问题,它抱怨说有一些软件包坏了,并建议我们运行 sudo dpkg-reconfigure,最终解决了问题。

你也许感兴趣的:

共有 117 条讨论

  1. 使用 qemu-user 和 binfmt,你甚至可以 chroot 到国外的 CPU 架构,这在你挂载手机的 eMMC 以修复黑客程序错误时非常方便。

    不过,如今你可能需要考虑使用 systemd-nspawn 来代替普通 chroot。

    1. > 你甚至可以chroot到国外的CPU架构,这在你挂载手机的eMMC时非常方便

      这听起来非常有趣!什么情况下你会这么做?比如,你会在 x86 电脑上用 qemu 模拟 ARM 处理器,然后在 eMMC 上chroot 到 Android 系统吗?

      1. 下面是在 x86 计算机上使用 debootstrap、qemu 和 chroot 准备 debian ARM 映像的示例:

         ~# sudo apt install qemu-user-static debootstrap
         ~# mkdir /tmp/arm
         ~# debootstrap --foreign --arch=armhf buster /tmp/arm http://deb.debian.org/debian
         ~# cp /usr/bin/qemu-arm-static /tmp/arm/usr/bin/
         ~# chroot /tmp/arm # 从这一点来看,你正在运行 ARM!
          ~# /debootstrap/debootstrap --second-stage
        1. 如今(使用最新内核),你甚至不需要将 qemu 二进制文件复制到 rootfs 中,也不需要使用静态二进制文件–这些过去都是内核自行处理的变通办法。

        2. 这很酷!我不知道你还能 chroot 到不同的架构。

          1. 技术上来说是不可以的,因为 chroot 不知道你在这么做… 内核中神奇的 binfmt 支持(我相信是通过 qemu-user-static 的安装后脚本为 qemu 设置的)基本上可以让你运行 qemu-user-* 支持的任何架构的二进制文件,只需尝试原生执行即可,它基本上只是将“./other-arch-cmd ”的执行转换为 “qemu-user-static ./other-arch-cmd”。

            1. 谢谢。这就说得通了。尽管通过 qemu-user-static 有一个翻译层,但拥有透明翻译层的设施仍然非常奇妙。对于像我这样的大胡子老前辈来说,这也是一个非常迷人的启示,因为我以前从未见过它。

      2. 我曾用它来构建定制的 RPi 映像。这比在低功耗 ARM 平台上构建要快得多,也没有交叉编译器那么脆弱。

        1. 我也是这么做的,在 M2 macbook air 上使用 macOS 内置的虚拟化框架运行 arm64 Debian,速度快得惊人。

          也许在 Asahi Linux 上运行速度会更快,但同时拥有 macOS 和快速的 Debian 实在是太爽了:)

          1. 也许是因为 M2 已经是 arm64 的缘故,所以速度很快。

      3. 是的,在闪存之前,我们就是这样定制 NVidia Orin BSP 的。将 rootfs 解压缩到一台快速的 x86-64 机器上,然后 chroot 进入,使用 qemu-user 运行大量 Arm 命令并构建一些东西。这比设置跨编译器工具链要简单得多。

      4. 我曾在工作中使用的一些修补板上这么做过。

        systemd-nspawn 是一个很好的工具。

      5. chroot 可以替代繁琐的交叉编译器设置。虽然速度会慢一些,但只要你花在额外 CPU 周期上的时间比花在交叉编译器上的时间少,速度慢也是值得的。

        它对路由器/物联网固件的逆向工程也很有用。

      6. 我在手机上的 Debian 系统中使用过它,不过是的。

      7. 没错,你的笔记本电脑是 x86,而你的手机、Raspberry Pi 或其他硬件不是。

    2. 的确,使用 systemd-nspawn 可以跳过大部分不必要的附加挂载要求。如果/dev/sde1(你的根分区)被挂载到/tmp/rescue,只需运行:

      systemd-nspawn –directory /tmp/rescue –boot —-unit rescue.target

      它就会自动找到启动分区并将其挂载。

    3. 当然你并不需要它,但如果你喜欢 docker 镜像,也可以配置 docker 或 podman 在运行容器时使用 QEMU。

  2. 这勾起了我的回忆–我拥有一家大型虚拟主机公司,我们有成千上万台机器。当硬件出现问题或机器无法启动时,使用这种方法是我们的第一道防线–我们会从 “Recovery Is Possible ”的刻录副本启动机器,这是一个用于恢复的一体化 Linux 发行版,然后挂载分区并chroot,找出问题所在–或者根据需要使用 rsync 迁移数据。

    刚看了一下,“Recovery Is Possible”(恢复是可能的)好像已经十几年没有更新了,这让我的故事过时了,但我还清楚地记得,新来的系统管理员接到惊慌失措的电话后,我连夜给他们打电话,告诉他们要冷静,“RIP it and get chroot in”(把它复制下来,然后chroot进去),然后醒来帮他们排除故障。

    1. System Rescue 是我现在使用的软件,但说实话,我不记得在过去几年中使用过它。https://www.system-rescue.org/

      1. 遇到这种情况时,我会使用我的 Gentoo 安装 USB

        1. System Rescue 曾经基于 Gentoo,后来改用 Arch。你可以用 SR 安装 Arch 和 Gentoo,显然也可以用 Gentoo 安装光盘安装 Arch,反之亦然。

          SR 还有一些相当方便的 SAM 数据库编辑功能。将 Windows 挂载到 /mnt,然后启用并重置管理员密码。这对于在 Windows 操作系统上获得超级用户访问权限非常方便。

          我已经有一段时间没有安装 Gentoo 了,但你可以很容易地在 Gentoo 安装光盘中添加更多内容。我不知道 Gentoo 是否添加了脚本来完成所有绑定挂载,但 “arch-chroot /bin/bash ”非常方便。我曾经忘记了 /sys.

          1. 是的,他们确实有这样的脚本。

    2. Hetzner 也会将你切入恢复 Linux,并挂载你的驱动器以供访问。同样的事情,不同的规模。

  3. 我真希望我们能有一个更好的 chroot,而不是 docker 等…… 或者只是一个新的内核系统调用,即 chroot()++。

    1. 正常人对沙箱的理解与Linux对命名空间的管理之间似乎存在着根本性的不匹配。

      一个对 Linux 一无所知的开发者会希望从一个什么都不能访问的有效载荷中产生一个新进程。它看不到其他进程,只有一个只读根目录,里面什么都没有,没有网络设备,没有用户,等等。然后,他们会希望通过阅读文档来了解如何在沙盒中添加内容。他们希望添加一个目录、一个网络接口或一些用户。他们要做的是向沙盒添加资源,而不是拿走资源。

      相反,主进程会举行一个复杂的仪式,在这个仪式上,主进程基本上会产生另一个拥有相同权限的自己,然后放弃这些权限,只留下它希望沙盒进程拥有的东西。确保不要忘记撤销任何权限。

      1. > 一个只读的 root,里面什么都没有

        如果没有 /proc/self,很多事情都会出错。如果没有 terminfo 数据库,还会有更多问题。如果没有时区数据库,则会有更多问题。最后,如果根文件系统中没有 libc.so.6,几乎所有事情都会出错。

        在编写 Dockerfile 时,你可以从头开始。然后,你就可以很容易地观察到沙盒中的东西是否真的能运行。

        > 没有用户

        现在,你正在破坏像 getuid 这样最基本的东西。

        1. 现代静态链接语言(我特别想到了 Go 和 Zig)越来越不需要你提到的那些垃圾。希望这种趋势能继续下去。

          > 没有用户

          我指的是以 root 身份运行。我认为 Linux 上的所有进程都必须有一个用户 ID。沙盒中的任何东西都应该以该环境的所有权限启动。如果沙箱进程想在用户/组授权模型上做手脚,那么它可以在沙箱内创建这些资源。

          1. 如果 /proc/self 或 terminfo DB 丢失,在 C 语言中会出现问题的东西在 Go 和 Zig 中也会出现问题。

            我想你可能是想说 “在使用 Go 和 Zig 等语言编写的现代静态链接应用程序中,调用需要此类资源的操作系统服务的可能性要小得多。

      2. 这差不多就是 FreeBSD 中的 jails,尤其是瘦 jails。

        1. 或能力。数十年前,人们就已经知道了附加安全性;Linux 在这一点上确实做得不够好。Linux 的文件描述符(开放文件描述符等)接近于真正的能力模型,只是在不安全的基础上存在大量泄漏。

      3. > 相反,有一个精心设计的仪式,主进程基本上会产生另一个拥有相同权限的自己,然后放弃这些权限

        取消共享的标志是 clone3 args 的副本,所以你实际上可以自由地这么做。不过这其中也有一些曲折,因为实际上不可能执行一个任意二进制文件,让它什么权限都没有。

        但我认为最大的分歧在于,“用一个新的可执行文件生成一个新进程 ”本质上需要两个步骤。不是这样的–你需要克隆 3/fork 到一个新的子进程,根据克隆的 args/flags(可能是所有的,也可能什么都不是)从父进程继承你想要的东西,做一些设置工作,然后执行。

      4. > 正常人对沙箱的理解与 Linux 对命名空间的管理之间似乎存在着根本性的偏差。

        关于 linux 命名空间的沙箱,最让我头疼的是不断出现的边缘情况,这些情况会诱使内核授予比它应该授予的更多权限。

        我想知道,Landlock 能否/是否会带来更多类似 FreeBSD jails 的功能。(我还没来得及详细了解它。)

        1. 这就是为什么我仍然宁愿使用 QEMU、docker 或 Virtually Box 进行隔离,而不愿使用类似 chroot 的环境

          1. Docker 默认使用命名空间。你是否在使用一个插件,让它使用管理程序?

      5. 我认为这是因为在 POSIX 系统上,创建新进程的唯一方法是 fork()。

        1. 还有后来添加的 posix_spawn,它可以用系统调用来实现,即使在 Linux 上它是用 clone + exec 来模拟的。

          posix_spawn 可以做很多用 clone + exec 可以做的事情,但不是全部。可能是标准编辑器害怕为其调用添加过于复杂的函数参数,不过如果所有参数都有合理的默认值,这应该不是问题。

          1. 在 docker 出现之前,Virsh 已经工作了很长时间,但是是的……你基本上必须构建自己的类似于 Docker 的基础架构,只有你自己在使用

    2. 来到 FreeBSD,我们就有监狱。

      1. 是的!FreeBSD jails 本质上就是 OP 想要的 chroot++。

        当 Docker 和 LXC 以 “前无古人 ”的姿态出现时,我感到非常困惑;在 Linux 加入安全组之前,FreeBSD 支持类似概念已有多年。

        在服务器上运行各种服务时,Jails 和 ezjail 是用来制作迷你无开销容器的明星产品。888/3/danieldk

        这整个新事物被认为是 “前无古人”;

        了解沙箱技术的人都不会相信这一点,毕竟 Virtuozzo 和后来的 OpenVZ 在 Linux 上已经存在了很长时间。Virtuozzo 甚至与 FreeBSD jails 的出现时间相近(2000 年左右)。

        Docker 的关键创新在于提供了一种构建、分发和运行容器镜像的标准化方式。

        1. Solaris Zones。绝对神奇,比 Docker 和它的朋友们还要早很多年。

    3. 苹果和橘子。

      在许多其他事情中,Docker(和 Podman 等)有

      1. Images and OverlayFS

      2. Networking

      3. User namespace mapping 4. 用户命名空间映射

      4. 资源管理

      如果你想要的只是文件系统隔离,那么docker(和postman等)就是矫枉过正的chroot,这是正确的。

    4. Plan9对此有一个合适的解决方案。新进程默认情况下无法访问任何文件–你必须为它们明确挂载目录,这就是能力风格。

      可惜 Plan9 浪费了它的怪异预算。

      1. 这与怪异无关;Unix 本身在当时就已经很怪异了。Unix™ 和 Plan9 之间的相关区别在于,Unix 的源代码被赠送(或廉价授权)给了硬件公司,这些公司都在其基础上编写了自己的操作系统(SunOS、Ultrix、HP-UX 等)。这使得 Unix 成为许多商业工作站环境的共同因素。计划 9?它是作为商业产品直接销售的,没有特定的硬件平台。没有人愿意购买它。

        人们喜欢 Unix 是因为它是免费的–通过 BSD 实现真正的免费,或者在人们购买工作站时免费提供 Unix 的衍生产品。一个新的革命性操作系统完全没有理由让人购买: 没有商业开发商愿意开发一个没有用户的平台,也没有用户想要一个没有软件的平台。

        Plan 9 只是在许多年后才修改了许可证,当时已经太晚了,没有人再关心这个问题,Unix 已经成为既定的标准。

    5. Pids and cgroups all the way down(这也是为什么聪明的灰胡子们拒绝了 docker)

    6. 正如许多评论所指出的,chroot 在许多方面都可以做得 “更好”–例如安全性和沙箱。

      前不久,我写了 https://github.com/aidanhs/machroot(最初是从 bubble wrap 分支而来),目的是在 chroot 的纯粹 “假装我看到了另一个文件系统 ”方面提供更多便利(因此不以安全为重点)。例如,它允许设置覆盖文件系统,允许挂载带有覆盖层的 squashfs 文件系统……由于它使用了挂载命名空间,这意味着你不需要拆卸挂载点,只要退出命令就可以了。

      代码库非常小,所以我只是根据当时的需要对其功能进行了调整,而不是试图将其打造成一个完全成熟的工具。

      (老实说,你也许可以用一个调用 unshare 和相应挂载命令的 shell 脚本来复制大部分功能)

    7. systemd-nspawn 也许就是你想要的。

    8. LXC 不就是一个孤立进程中的无监督 chroot 吗?

      1. 是的。如果通过隔离保证安全是首要任务,那么 bubblewrap 也是如此。

    9. 你认为 “更好的 chroot “与 Docker 容器有何不同?在我看来,Docker 正是如此。

    10. 我们应该得到一个更好的chroot,LD_LIBRARY_PATH会根据新的root自动更新。在这里和那里打上几个标记,设置子进程的权限,我们就可以开始比赛了。

      哇哦,哇哦。这一切听起来太复杂、太难以理解了。我们需要做的是建立一个高度正规化的程序来处理所有这些问题。让我们把它正规化,就像税收或 AWS 那样,让人们可以通过了解这头野兽来谋生。它可以是 systemd 和 multics 的结合,也可以是 Java 和 systemd 的结合。它有自己的各种复杂命令、复杂文件格式等等。chroot()在历史上只被大家理解过,所以让我们从 java 的剧本中偷师,用我们自己的术语重新命名一切。这样的产品一定会非常出色,哇哦,我把它叫做 “震撼者”

      1. 我不是 GP,但如果让我大胆猜测,他们想要的不仅仅是挂载空间隔离。类似于 BSD jails,没有 OCI 容器的繁琐功能,如覆盖文件系统、网络虚拟化、资源管理等。

        这种需求是合理的,因为它更简单,也足够适用于我们目前使用 OCI 容器的许多应用。例如,隔离构建、开发环境、沙箱等(我有一个用于 Gentoo 的隔离构建工具)。

        但是,Linux 已经有了多种符合要求的解决方案,如 systemd-nspawn、LXC、bubblewrap 等。可惜的是,它们不像 chroot 那样广为人知。

        1. 这些东西都没有chroot的功能,但其中很多都涉及chroot–所以,除了 “不是chroot,而是完全不同的东西 “之外,我还是不明白什么是 “更好的chroot”。

          听起来人们想要的是 “更好的执行”

          1. 使用 chroot 的一个恼人之处在于拆卸,如果你是临时创建 chroot 的话–你必须手动调用 umount,还要注意正确处理部分创建的 chroots(也许你在挂载 proc 之后,在获取其他文件的过程中发现了错误)。

            这就是我创建 machroot(在本主题其他地方提到过)并让它使用命名空间的最初动机。

    11. 具有讽刺意味的是,Docker 从未给你带来真正的网络隔离,因为没有办法让它对用户友好。此外,这个功能强大的守护进程还存在许多漏洞。

      ,但现在大多数专业领域都使用 systemd 来启动隔离进程,这有点像你所暗示的。Cgroups2 和命名空间才是你想要的。

    12. Docker 并没有以任何方式使用 chroot。逃离 chroot 只需调用 chdir(‘…’),噗,你就离开了 “沙盒”

      1. 我记得第一次安装 Gentoo 的时候…打印了整本手册,然后跟着做。在一次失败的尝试和第二次成功的安装之后,我学到了足够多的知识,知道我可以使用自己选择的 LiveUSB 并 chroot 安装。好时光啊

        1. 在 Gentoo 上,在 chroot 环境中安装一个全新的系统也很简单,即使该系统是为一台具有不同但兼容架构的电脑而设计的。

          如果你想在一台廉价的小型计算机(如配备英特尔 Atom CPU 的计算机)上从源代码编译安装 Gentoo 系统,这通常会非常方便。

          与其在资源有限的电脑上编译,不如在一台快速台式电脑上以 chroot 环境为其安装一个全新的 Gentoo 系统。

          然后将安装结果复制到目标电脑的固态硬盘/移动硬盘上即可。如果你有多台相同的电脑,你可以顺利地将安装好的 Gentoo 复制到所有电脑上,无需多次安装。

          如果需要,您可以保留带有安装结果的 chroot 环境,并在此基础上执行后续更新。然后从 chroot 环境将更新后的 Gentoo 系统同步到一台或多台目标计算机上。

          1. 是的,有一些 Gentoo 开发人员和 Bug 猎人就是这么做的,不过是为了查找 Bug 和测试更新 8D!

      2. Debian 的 debootstrap 也想参与这个讨论

        1. Debootstrap 用于将最小系统从另一个运行中的系统安装到一个目录中(因此只在设置阶段有用),而 arch-chroot 则用于访问已安装的系统(例如从 U 盘启动以修复某些问题)。它们不是一回事。arch中类似debootstrap的工具叫做pacstrap。

    1. Manjaro 也有同样的工具,我想应该是继承自 arch 并进行了修改。

      我只是希望脚本能找出 BTRFS 驱动器,而不需要我手动挂载卷:(

      1. 我很高兴 Arch-chroot + pacstrap 简化了我的 Arch 设置,而无需运行这些挂载(我记得为了不使用 anaconda 和删除臃肿,或者说安装我想要的东西,我为 centos/rhel 的 Arch 做了同样的设置过程)

        ,对于 Btrfs,如果您在系统上使用一致的卷映射,就会非常容易。在 Arch 设置中,我通常会启用 ssh,并为目标设备、压缩和挂载点设置一套相当简单的 bashisms。然后是 copy-pasta,因为当我需要恢复或重新安装时,它是一个锅炉板

        没看过 manjaro,所以不熟悉它的安装方法

    2. 实际上,我以前曾用它来解锁我的笔记本电脑。非常有用

  4. > sudo mkdir /rescue/boot

    > sudo mount /dev/nvme0n1p3 /rescue/boot

    这是一个额外的小功能。一般来说,你可以在 chroot 后立即运行 “mount -a”,从 chroot 的 fstab 中挂载所有内容。空的 `/boot` 可能已经存在。

  5. 我刚从 WSL2 上用这种方法安装了 Gentoo,安装在 Framework 16 上的辅助 NVME 上。除了一些需要注意的小问题外,安装过程非常顺利:

    从 WSL 无法访问 EFI 子系统意味着你需要通过一些额外的标志来帮助 grub/等系统,而且你可能需要在 BIOS 中手动将其设置为启动分区

    -你必须使用 “wsl –mount <DiskPath> –bare ”将硬盘挂载到 WSL、 在使用 `Get-CimInstance -query “SELECT * from Win32_DiskDrive”`找到正确的磁盘路径后,你可能需要先在 Windows 磁盘管理器中将磁盘脱机

    1. 这真是不可思议,在 Windows 中也能运行!

      现在我想知道,在浏览器中运行 Linux 并通过 WebUSB 访问 USB 时,它是否也能工作;D

  6. 目前正在编写脚本,以便使用 chroot 在本机之外配置硬盘。到目前为止,我已经好几次不小心从主机系统卸载了 /dev/pts,而且在 chroot 内运行 docker 会导致硬锁定。真有意思。

  7. 我曾多次使用这种或至少是非常类似的技术来解决启动问题。

    我有一个版本的挂载命令,我认为更容易使用:

     for f in proc sys dev run dev/pts ; do mount --bind /$f /mnt/$f ; done
    

    将”/mnt/$f “改为您正在使用的挂载点,即”/rescue/$f”,以便与 TFA 一致。

    我不知道挂载 /run 有什么不同,但一旦 chroot 到挂载点,就可以挂载启动分区等,并运行任何 grub 或 mkinitramfs 命令来修复问题。

    我会将 /boot 挂载留到稍后进行,即 chroot 之后。这样你就可以很容易地检查 /etc/fstab,查看引导分区的位置(或是否有引导分区),所以你只需要在一开始找到根分区,而根分区一般很容易从磁盘大小中找到。

    不过,如果系统使用 LVM,则需要额外的步骤。

  8. chroot 曾经是(现在是?)安装 gentoo 的推荐方式,这是一种教学方法。

    现在有很多方便的(chroot)技术可能已经被认为是 “老派 ”了。例如,有一个可以远程启动的 “应急分区”,从那里重新安装或修复 “主操作系统”。例如,在远程重新分区时就需要这样做。

    1. 这仍然是大多数 Linux 操作系统安装程序的安装方式。他们只是帮你安装而已。

      它仍然用于恢复,但随着持续启动能力的提高,恢复分区已经有点过时了。此外,优盘和网络启动也让分区变得没那么必要了。

  9. 看到这被称为一种技术有点好笑。我做过很多次这种事,都取得了令人印象深刻的效果。对我来说,只要你对 Linux 有足够的了解,你就能在无数其他事情中做到这一点。

    1. “技术 “是一个术语,指 “只要你对 X 有足够的了解,就能在无数其他事情中做到的事情”。

  10. 这些工具应该不需要使用 chroot。在 Solaris 上,指定一个应被视为工具根目录的路径(通常是 -R)是很常见的。这在使用 nfs 的 netboot 世界和崩溃恢复中非常有用。

    如果系统已经够糟了,那么chroot策略就会失效,因为它依赖于你chroot到的路径通常是有效和实用的。如果缺少库,你可能就完蛋了。

  11. 如果我通过 ssh 进入一个 Linux 操作系统,然后想(比如)格式化它的根磁盘。我能在内存中启动一个新的 Linux 实例,然后访问根磁盘吗?

    1. 绝对可以。nixos-anywhere [0] 在一个专门针对 NixOS 的软件包中实现了这一功能。我比较肯定的是,你可以使用相同的脚本启动到不同的发行版,不过安装部分本身显然需要调整。

      [0] https://github.com/nix-community/nixos-anywhere

    2. 有趣的问题,我不知道该怎么做–也许可以使用一些静态链接的二进制文件来实现 fdisk 和 mkfs。不过,为什么要这么做呢?如果你想删除磁盘上的数据,只需运行一个合适的 “dd ”命令就能擦除磁盘。我想不出还有什么其他使用情况不会随后涉及从 Live iso 启动,而 Live iso 无论如何都会让你格式化磁盘。

      1. 一种使用情况是:如果计算机在远程位置,而你想在主磁盘上放一个新镜像怎么办?如果 Linux 正在使用该磁盘作为根磁盘,那么我想你必须以某种方式卸载它,或者使用完全在内存中运行的另一个 Linux 实例(这样你就可以杀死原来的 Linux 实例并覆盖它)。

        1. 我想你可以启动到实时安装程序 ISO,然后让它安装到根磁盘上,不过我不知道你在试图卸载原始根分区时会遇到什么问题。

          如果你想经常做这样的事情,那么运行虚拟机(如 QEMU/KVM)来做这样的事情会更简单。

  12. 创建挂载命名空间并使用 pivot_root 似乎是更安全的解决方案。

    1. 我不认为 pivot_root 是必要的,但一个新的挂载命名空间肯定有助于避免意外造成混乱

    2. 来这里就是为了提出这个建议。pivot_root 的优势在于它可以重新挂载现有的 root。它主要用于从使用 linuxrc 启动的 initramfs 到另一个根文件系统中的完全启动。如果问题严重,你可以使用 shell 或其他进程作为 init。

  13. 啊–我的尝试几乎成功了,除了因为没有正确挂载proc、dev等挂载点而不断出错的部分:) 可以再试试。当时,我想用一个不需要 docker 的简单工具来存储所有使用不同库的开发相关内容。这就是 debootstrap+chroot 的用武之地–根据 Debian 中不同版本的库进行构建(如果我没记错的话–已经有一段时间了)。

  14. 是否已经有一个封装工具可以自动完成文章中列出的所有过程?

    1. sudo arch-chroot .

      现在这已经成为我设置树莓派电脑的默认工具。

  15. 有一次,我不得不拯救一个 SunOS 系统并编辑 /etc/vfstab,但我只有 ed 可以用。在那之前,我从未接触过 ed,所以这无疑是一次学习机会。

    1. 在大学时,我曾在一个计算机实验室里闲逛…

      我们用 rcp 保持密码同步。在主机上添加账户,然后把密码文件传输到另一台机器上。sudo rcp /etc/password other:/etc/passwd 是我们的记忆。

      有一天,为了能在服务器网络项目中工作,有人被添加到了组文件中。 sudo rcp /etc/group other:/etc/passwd

      Ooops。无法登录修复。

      “有人登录过另一台机器吗?(有人说有)。“输入 1 同步”……(好)…… 然后我们打开电源开关,以单用户模式启动(因为密码文件无效)。接下来,需要建立一个最小/etc/passwd … emacs /etc/passwd(不行) vi /etc/passwd(不行–无效终端 300h 不在 termcap 中)。”嗯……cat > /etc/passwd?(有可能,但转录时出现错别字会很麻烦)

      我是 lpmud 上的向导。“我知道埃德”。

      在读取哈希值的同时,我们恢复了一个最小的密码文件(我们不可能让 root::0:0:……作为文件,哪怕是一秒钟),然后将正确的 /etc/passwd 和 /etc/group 文件 rcp 到另一台机器上。

      https://www.gnu.org/fun/jokes/ed-msg.txt

  16. 这就是 Linux 和 Unix 如此强大的原因。其实都是文件而已。

    1. 并非如此,但确实有很多文件或看似文件的东西。不过可以试试 plan9。

      1. 如果你想了解操作系统隔离的可能性,请阅读 1985 年的 KeyKOS:https://css.csail.mit.edu/6.858/2014/readings/keykos.pdf

        这类系统很少非常实用,但确实展示了一堆奇怪的概念。

        1. 绝对怪异,或许是我想象力不够丰富。我很难弄清 KeyKOS 的一些构造在我们熟悉的术语中是什么意思,尤其是某一特征是本质复杂性还是偶然复杂性的实例。我更熟悉今天的 seL4,它继承了 KeyKOS 的许多原则。学习当今的技术水平是一回事,但学习历史又是另一回事。我依赖内核设计的简洁性,以避免妨碍他人更有创造力的想法。

    2. “文件 “显然用词不当,应该是 “对象”。

  17. 当然,chroot 在紧要关头是有用的,但我不会首先使用它。如果你已经挂载了分区,不需要 chroot 就可以做很多事情了。

    1. 这通常是正确的。在这种特殊情况下,问题实际上出在 /boot,而仅仅挂载主分区可能并不明显。

  18. 这就是 “从零开始的Linux ”的操作方法,我也曾用同样的方法安装过Ubuntu安装时因某种原因没有包含的视频驱动程序。

  19. 哈哈,在安装 Void Linux 时学到了这个技巧

    1. 哈哈,真有趣。Void Linux 迫切需要一个更好的安装程序。(IMHO)

  20. 我们都知道的 Docker 和容器其实就是花哨的 chroot。

    在非 Linux 系统上,它是 Linux 虚拟机中的花式 chroot。

    1. 这就提出了一个问题:既然他们有虚拟机,为什么还需要 chroot?

      另一个半相关但同样奇怪的观点: Docker 是操作系统,而容器是进程。

      顺便说一句,Docker 和 chroot 的区别在于,Docker 会执行更多的系统调用,以获取其他几个非文件系统的根目录。默认情况下,它还会在这些根目录下为你设置一些东西,比如你的容器可以访问互联网。

      1. 我发现这个项目是一个有趣的 POC,让我知道它究竟是如何工作的。

        https://github.com/p8952/bocker

        基本上,它使用 chroot 运行 docker 容器,以证明这是可行的。

        Docker 使用分层文件系统(将多个文件系统挂载在同一个文件夹下,并相互叠加),这在以前主要用于只读文件系统(如 CDROM),然后在同一挂载点挂载可写文件夹,使该文件夹可写。

        Bocker 在运行 docker 容器时,也使用了类似的 chroot 层挂载方法。

  21. Chroot拯救了我的系统很多次,我都不愿意承认。虽然我并不真正了解它是如何工作的,但这很有趣。

  22. 它救了我很多次,让我不用再去找光盘来拯救我的主系统。当你安装 Arch 时,它会使用这种技术,非常轻便。

    1. 使用 “弱智 ”对你的评论有什么实际意义?这完全没有必要。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注