我有一个包含某些文件的文件夹。有没有办法将其挂载到/
,以便给定目录的内容出现在 中的相应位置/
?
就我而言,目录包含与应用程序相关的文件 - 它没有像/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 。mtab
mount
您基本上需要执行典型 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
应该足够了。