不要尝试挂载/,让自己成为一个“新”(假的,只读)的:

不要尝试挂载/,让自己成为一个“新”(假的,只读)的:

我有一个包含某些文件的文件夹。有没有办法将其挂载到/,以便给定目录的内容出现在 中的相应位置/

就我而言,目录包含与应用程序相关的文件 - 它没有像/dev和 之类的目录/proc

我尝试通过以下方式创建绑定安装:

mount --bind ~/applications/firefox /

然而,这根本没有任何作用。与评论中猜测的不同,它也没有任何不利影响。


这样做的动机是我有许多自定义应用程序,我想将它们干净地安装在任务关键型系统上。可以理解的是,我希望将相关管理保持在最低限度。我使用以下命令获取应用程序安装的文件系统布局unionfs-fuse + chroot 方法,但我仍然需要处理应用程序文件与系统文件混在一起的问题。挂载某些目录/可以帮助我保持文件系统的整洁。

虽然这种安装软件的方法可能看起来很反常,但有一个名为“Porteus”的发行版正是以这种方式安装软件(并且出于相同的原因),但是,众所周知,它们与 aufs 一起使用修补过的内核。但是,我无法在系统上使用自定义内核。

答案1

您要求做的事情在几乎每个常用配置的 Linux 系统上至少完成一次。大多数人使用busybox称为switch_root:

什么switch_root是删除所有文件根文件系统 (释放内存)然后chroot进入一个新的文件系统并在新的文件系统中执行一个新的 init 进程。

这发生在系统初始化期间。当 Linux 系统启动时,内核会分阶段启动系统。起初,内核由其他一些系统(例如引导加载程序或固件)在内存中执行,此时内核就只能自生自灭了——没有真正的系统参考框架它刚刚被执行。

这就是initramfs图像通常附加到其内存空间的内容(但也可能直接编译到内核中)被设计来处理。 initramfs 是真正的 linux root(完整的w//dev/proc以及你有什么)文件系统映像 - 它是 Linux 内核挂载的第一个根文件系统。它包括一个根文件系统存档,其中包含使内核站稳脚跟(引导它)所需的任何/所有系统特定模块/配置文件。

无论如何,内核将该存档安装为根文件系统 (基本上是一个临时文件系统然后做任何必要的事情来找到其他/并将其安装在其上。每次启动系统时它都会执行此操作。它可以再次做到这一点,并且无需诉诸不必要的黑客手段,例如联盟或者奥夫斯- 两者都可能产生各种特定于实现的复杂性和配置细节(更不用说不稳定了)

switch_root上面引用的描述中,您可能会注意到这个短语删除 rootfs 中的所有文件。显然,当切换出基于磁盘的 rootfs 时,这不是一个理想的行为。但无论如何,只有在switch_root释放基于 ram 的文件系统的内存时才会发生这种情况 - 并且完全没有必要。以下是之前引用的文章中的更多内容:

以下 shell 脚本片段演示了如何使用 switch_root:

   # First, find and mount the new filesystem.

   mkdir /newroot
   mount /dev/whatever /newroot

   # Unmount everything else you've attached to rootfs.  (Moving the filesystems
   # into newroot is something useful to do with them.)

   mount --move /sys /newroot/sys
   mount --move /proc /newroot/proc
   mount --move /dev /newroot/dev

   # Now switch to the new filesystem, and run /sbin/init out of it.  Don't
   # forget the "exec" here, because you want the new init program to inherit
   # PID 1.

   exec switch_root /newroot /sbin/init

正如您在上面所看到的,处理/dev/proc、 以及/sys相关问题可以非常简单地完成。顺便说一句,如果您要对任何 d 安装架进行分层,您不仅mount --move要处理分层系统引入的任何其他复杂问题。正如您在问题中所描述的那样,这样做更简单 - 从其他地方挂载 root 。mtabmount

您基本上需要执行典型 initramfs 配置中发生的所有操作,而几乎不需要执行其他操作 -(这并不意味着包括德班或者红帽的 initramfs 映像 - 两者都是方式过度设计)。您可能遇到的唯一真正问题是如何让 PID1 跟进 - 如果您让系统的 init 陷入某些孤立的 rootfs 上,那么非常奇怪的事情很快就会开始在您的系统上发生。处理这个问题的明显方法是从 initramfs 开始准备。只要确保您的硬盘init进程已准备好在exec以后要切换根目录时进行另一个进程即可。如果您使用的是,systemd init那么这个并发症已经为您处理:

systemctl --help
...
switch-root ROOT [INIT]         Change to a different root file system
...

如果您使用的是systemd基于 - 的,init您应该研究其中的单元文件,/usr/lib/systemd/system/initrd*以了解常见的脚本式systemd切换根目录的情况。

另一种方法可能是模仿initramfs 中的busybox's switch_root- 但省略删除所有初始根文件的部分。systemd在 initramfs 中配置的 Arch Linux 系统可以执行此操作。在这些上, initramfs 根目录在执行 switch-root 之前将自身安装到/newroot's中/run/initramfs,并且是系统在关闭时回退到的目录,以干净地处理睡眠/挂起等。实际上,这可能是适合您的情况的最佳方式 - 只是一个微小的、内存持久的根系统,您可以在其中为各种单独的根应用程序进行乒乓操作。

答案2

不要尝试挂载/,让自己成为一个“新”(假的,只读)的:

我也做过类似的事情。当时我使用 AUFS,但这也应该适用于 overlayfs 和/或 unionfs-fuse:

  • 制作一个文件夹(例如)~/apps/_App1_FakeRoot
  • Unionfs在挂载点 ~/apps/_App1_FakeRoot 上以读写方式挂载/(根)只读。~/apps/_App1
  • chroot 到 FakeRoot,运行您的应用程序。

在我的具体情况下,我使用了类似上面的东西来统一多个层,包括用于(临时)写入的(ram)磁盘。

具体语法将取决于您(可以)使用的联合 FS 的任何实现。您可能还需要在 chroot 中安装另一个 /proc /sys /dev/pts,具体取决于您的应用程序的需求。也有可能,某些类型的程序不会在这样的 chroot 中运行,也许如果想要做硬件级的事情

(如果您的特定 unionfs 实现不想使用 / 作为只读基础,您可以通过首先以只读方式将自己绑定安装为“根文件系统”来绕过它,以用作您的应用程序的基础。)

答案3

mount --bind ~/applications/firefox /会隐藏整个目录树,包括/dev/proc等等。这将使所有被遮蔽的东西都无法访问。它不起作用,因为您无法绑定安装它会隐藏自身的目录。

你想要混合您的目录树和另一个目录树中已有的内容。这被称为联合安装。 Linux 有多种可用的联合文件系统;奥夫斯存在于非古老内核中;UnionFS熔断器无论 FUSE 在哪里,都可以使用。 Aufs支持根目录作为挂载点,但是Unionfs-fuse。对于您的用例,联合安装/usr应该足够了。

相关内容