Como a WUBI manipula as partições no desligamento?

10

Tudo bem, basicamente, estou tentando inicializar o Gentoo de maneira semelhante à WUBI; Eu tenho uma instalação em um arquivo de loopback formatado para ext4, BURG instalado sob o Windows Bootloader e o kernel / initramfs disponível para inicialização. A inicialização ainda tem alguns problemas (aqueles que eu acho que posso resolver, eles são principalmente por causa de pequenos problemas com os programas em si), mas eu tenho a idéia básica para baixo:

  1. Configure o busybox e obtenha dispositivos com o mdev
  2. Analise as opções da linha de comando, determine se está pedindo raiz real ou raiz de loop
  3. Se raiz real, monte-a em /root e mude a raiz, execute /sbin/init .
  4. Se raiz de loop, monte a partição do host em /host .
  5. Montar loopback ( /host/${LOOP} ) em /root
  6. Mover o ponto de montagem do host ( mount -o move /host /root/host para busybox)
  7. Alterne a raiz para /root e execute /sbin/init

Eu tenho o script init aqui:

#!/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

Nada complicado, na verdade. O NTFS-3G aparentemente não concorda com a implementação do busybox de mount e outras coisas (ele adiciona o parâmetro -i por algum motivo e ntfs-3g craps), então estou pensando em copiar apenas a implementação coreutils ou alguma coisa. Isso, e eu preciso examinar o que é necessário para montar partições de loopback (isso me dá um erro como "Arquivo não encontrado" quando tento montar o loopback manualmente). Ainda assim, acho que são fáceis o suficiente para descobrir por mim mesmo.

No entanto, o que estou me perguntando é sobre o desligamento. Quando o switch_root for concluído, o sistema ficará com um arquivo / montado em loopback e /dev/sda2 (esta é uma instalação do Windows 7) em /host . Agora, não há como desmontar /host , como está em uso. No entanto, não é possível desmontar / enquanto a raiz tiver sistemas de arquivos montados em um subdiretório. As instalações do Ubuntu baseadas em WUBI devem enfrentar o mesmo dilema. Como alguém supera esse problema? É um problema de galinha e ovo, e isso está realmente me irritando.

Eu estava considerando algo nos moldes de um script de inicialização que contém um cache temporário de arquivos para uma raiz básica básica (como um initramfs, mas o contrário). Ele seria executado por último, copiando os arquivos para um tmpfs, girando a raiz, talvez voltando ao layout original do initramfs. Eu essencialmente estaria fazendo isso:

  1. Monte um tmpfs em /tmp/shutdown/ ou algo assim.
  2. Copiar os arquivos de desligamento (talvez /usr/share/shutdown/ ou algo assim)
  3. pivot_root para mover a raiz para /loop e chroot para o tmpfs.
  4. mount --move the /loop/host to /host
  5. Desmontar /loop
  6. Desmontar /host
  7. Desligue-o, pois todas as partições foram desmontadas.

No entanto, nunca modifiquei muito o Gentoo. Isso é possível com um initscript? Eu não quero que isso seja sobrescrito por quaisquer atualizações no baselayout ou no ebuild, já que isso me deixaria com a funcionalidade de desligamento interrompido (e eu realmente não quero perder a partição host). Existe também o problema de descobrir se o sistema init do Gentoo suporta mesmo algo assim. Parece limpo o suficiente (se um pouco hackish), mas não tenho certeza sobre isso. Eu quero saber se o Ubuntu faz diferente, e se sim, como? Qualquer sugestão seria útil.

EDITAR :

Eu tenho a inicialização funcionando. Apenas uma questão de usar a versão coreutils de mount , como eu pensei. Estou tendo os erros que eu esperava no desligamento; erros ao não conseguir desmontar sistemas de arquivos e erros de registro no diário com o FS de loopback. Não tenho ideia de como consertar isso ainda.

EDIT 2:

Tudo bem, bem, eu tenho algo acontecendo assim ... Mais ou menos. Eu basicamente editei /etc/init.d/{halt.sh,reboot.sh,shutdown.sh} e fiz o seguinte:

  • Adicionado /host à variável RC_NO_UMOUNTS , o que impede que o módulo EXT4 fique sufocado com um erro de registro no diário
  • Adicionado -o 'pidof ntfs-3g' às opções de killall5 (para garantir que ele não tenha matado o ntfs-3g)
  • Modificado o shutdown.sh e o restart.sh para montar um tmpfs em / boot / shutdownfs e copiar alguns arquivos initramfs lá, girar a raiz e fazer chroot nela, chamando / down ou / restart.
  • Esses dois scripts basicamente fazem uma configuração rápida e suja / proc e / sys, movem o / root / host para / host e, em seguida, fazem a desmontagem lenta. Não consegui fazer com que as desmontagens regulares funcionassem (o sistema de arquivos ainda estaria ocupado), mas pelo menos isso parece impedir os sistemas de arquivos de vomitar completamente.

Esta solução ainda é inferior, portanto, qualquer ajuda seria apreciada.

    
por Animus 18.11.2010 / 14:43

2 respostas

1

Não é um especialista aqui, mas depois de ler a página umount , vejo um sinalizador específico para dispositivos montados em loop:

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

Além disso, lendo ainda mais em losetup (em manpages ainda), eu sugiro que você o use para depurar, já que pode ser usado para ver o status de dispositivos montados em loop.

O link para a página do manual que estou me referindo a está aqui . Esta opção:

-a     Show status of all loop devices.

pode lhe dar uma pista, e alguns outros sinalizadores podem ajudar a desmontar os dispositivos em loop.

Como não posso replicar sua situação, só posso sugerir formas de encontrar sua resposta por conta própria, lamentando não poder ajudar mais.

    
por 06.03.2012 / 22:19
0

man 8 umount :

-l

Lazy unmount. Detach the filesystem from the filesystem hierarchy now, and cleanup all references to the filesystem as soon as it is not busy anymore. (Requires kernel 2.4.11 or later.)

    
por 31.08.2011 / 18:15