关机时 WUBI 如何处理分区?

关机时 WUBI 如何处理分区?

好吧,基本上,我正尝试以类似于 WUBI 的方式启动 Gentoo;我有一个 ext4 格式的环回文件安装,在 Windows Bootloader 下安装了 BURG,并且 kernel/initramfs 可用于启动。启动仍然有一些问题(我认为我可以解决这些问题,它们主要是因为程序本身的小问题),但我有基本的想法:

  1. 设置 busybox 并使用 mdev 获取设备
  2. 解析命令行选项,确定是否要求实数根或循环根
  3. 如果是真正的root,则将其挂载/root并切换为root,然后执行/sbin/init
  4. 如果循环根,则将主机分区挂载上/host
  5. 安装环回 ( /host/${LOOP}) 于/root
  6. 移动主机的挂载点(mount -o move /host /root/host用于 busybox)
  7. 切换root到/root并执行/sbin/init

我在这里有init脚本:

#!/bin/sh

# Rescue shell in case of error.
rescue_shell() {
     echo "Something went wrong. Dropping you to a shell."
     exec /bin/sh
 }

parse_opt() {
        case "$1" in
                *\=*)
                        echo "$1" | cut -d= -f2-
                ;;
        esac
}

# Set up BusyBox...
busybox --install -s

# Mount the /proc and /sys filesystems.
mount -t proc none /proc
mount -t sysfs none /sys

# Populate /dev
echo ":: Populating /dev..."
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

# Get command line options...
for x in ${CMDLINE}
do
        case "${x}" in
                root\=*)
                        ROOT=`parse_opt "${x}"`
                ;;
                # Loadloop
                loop\=*)
                        LOOP=`parse_opt "${x}"`
                ;;
                ntfsroot)
                        NTFSROOT=1
  ;;
 esac
done


if [ "${NTFSROOT}" != 1 ]
then
 # Mount the root filesystem, plain and simple.
 echo ":: Mounting real root..."
 mount -o ro "${ROOT}" /mnt/root || rescue_shell
else
 # Load up an NTFS-based root.
 echo ":: NTFS Root mount requested. Mounting..."
 ntfs-3g "${ROOT}" /host

 if [ -f "/host/${LOOP}" ]
 then
  mount -o loop,ro  "/host/${LOOP}" /root || rescue_shell
  echo ":: Mounted. Moving host..."
  mount -o move /host /root/host || rescue_shell
  echo ":: Mounted."
 else
  "!! ERROR: Invalid/nonexistant loop given!"
  rescue_shell
 fi
fi

# Clean up.
umount /proc
umount /sys

# Boot the real thing.
echo ":: Switching to root and calling init..."
exec switch_root /root /sbin/init

其实没什么复杂的。NTFS-3G 显然不同意 busybox 的实现mount和其他东西(它出于某种原因添加了参数 -i,然后ntfs-3g就崩溃了),所以我正在考虑直接复制coreutils实现或其他东西。此外,我需要检查安装环回分区所需的内容(当我尝试手动安装环回时,它会给我一个错误,如“文件未找到”)。不过,我认为这些很容易自己解决。

但是,我有点疑惑的是关机。一旦switch_root完成,系统将留下一个/回送挂载文件和/dev/sda2(这是 Windows 7 安装)在/host。现在,无法卸载/host,因为它正在使用中。但是,/当根目录的文件系统挂载在子目录中时,无法卸载。基于 WUBI 的 Ubuntu 安装必须面临同样的困境。如何克服这个问题?这是一个先有鸡还是先有蛋的问题,这真的让我很恼火。

我正在考虑编写一个引导脚本,该脚本保存用于基本根目录(类似于 initramfs,但反过来)的临时文件缓存。它会最后运行,将文件复制到 tmpfs,旋转根目录,也许将其恢复为 initramfs 的原始布局。我基本上会这样做:

  1. 安装 atmpfs或者/tmp/shutdown/某物。
  2. 复制关机文件(也许/usr/share/shutdown/或其他)
  3. pivot_root将根目录移至 tmpfs/loop并 chroot 到 tmpfs 中。
  4. mount --move/loop/host/host
  5. 卸载/loop
  6. 卸载/host
  7. 彻底关闭,因为所有分区都已卸载。

但是,我从未对 Gentoo 进行过如此多的修改。使用 initscript 可以实现吗?我不希望它被对 baselayout 或任何 ebuild 的任何更新所覆盖,因为这会导致我的关机功能中断(我真的不想丢失主机分区)。还有一个问题是弄清楚 Gentoo 的 init 系统是否支持这样的功能。它似乎足够干净(如果有点黑客),但我对此不太确定。我想知道 Ubuntu 是否以不同的方式做到这一点,如果是,怎么做的?任何建议都会有所帮助。

编辑

我启动成功了。只需使用 版本即可coreutilsmount就像我所想的那样。但是,我在关机时遇到了我预期的错误;无法卸载文件系统的错误和环回文件系统的日志错误。我仍然不知道如何修复这个问题。

编辑2:

好吧,我做了一些事情……有点奏效。我基本上编辑/etc/init.d/{halt.sh,reboot.sh,shutdown.sh}并做了以下事情:

  • 添加/hostRC_NO_UMOUNTS变量中,可防止 EXT4 模块因日志错误而阻塞
  • 添加-o `pidof ntfs-3g`到 opts 中killall5(以确保它不会杀死 ntfs-3g)
  • 修改了 shutdown.sh 和 restart.sh,以在 /boot/shutdownfs 上挂载 tmpfs,并将一些 initramfs 文件复制到那里,旋转根,然后 chroot 进入其中,调用 /down 或 /restart。
  • 这两个脚本本质上会进行一些快速而粗糙的 /proc 和 /sys 设置,将 /root/host 移动到 /host,然后进行延迟卸载。我无法让常规卸载工作(文件系统仍然很忙),但至少这似乎可以完全阻止文件系统呕吐。

该解决方案仍然不够完善,因此,如果能提供任何帮助,我们将不胜感激。

答案1

我不是这方面的专家,但在阅读umount手册页后,我看到一个特定于循环安装设备的标志:

-d     In case the unmounted device was a loop device, also free this loop device.

另外进一步阅读losetup(仍然在手册页中),我建议您可以使用它来调试,因为它可用于查看循环安装设备的状态。

我指的是手册页的链接在这儿. 此选项:

-a     Show status of all loop devices.

可能会给你一个线索,并且一些其他标志可能会帮助卸载循环设备。

由于我无法复制您的情况,我只能建议您自己寻找答案的方法,很抱歉我无法提供更多帮助。

答案2

man 8 umount

-l

延迟卸载。立即将文件系统从文件系统层次结构中分离出来,并在文件系统不再繁忙时立即清除对文件系统的所有引用。(需要内核 2.4.11 或更高版本。)

相关内容