O que você está pedindo para fazer é feito pelo menos uma vez em praticamente todos os sistemas Linux comumente configurados. A maioria usa a ferramenta disponibilizada por busybox
chamado switch_root
:
What switch_root
does is delete all the files out of rootfs (to free up the memory) and then chroot
into a new filesystem and exec a new init process out of the new filesystem.
Isso acontece durante a inicialização do sistema. Quando um sistema linux é inicializado, o kernel traz o sistema em etapas. No início, o kernel é executado na memória por algum outro sistema - como um gerenciador de inicialização ou o firmware - e neste ponto o kernel é apenas deixado por si mesmo - sem nenhum quadro real de referência para o sistema no qual foi apenas executado.
Isto é o que a imagem initramfs
normalmente anexa ao seu espaço de memória (mas possivelmente também compilada diretamente no kernel) é projetada para manipular. O initramfs é uma raiz real do linux (completa com /dev
e /proc
e o que você tem) imagem do sistema de arquivos - é o primeiro sistema de arquivos raiz já montado por um kernel linux. Ele inclui um arquivo do sistema de arquivos raiz contendo qualquer / todos os módulos / arquivos de configuração específicos do sistema que são necessários para colocar o kernel em seus pés - para inicializá-lo.
De qualquer forma, o kernel monta esse arquivo como rootfs (basicamente um tmpfs ) e faz o necessário para encontrar alguns outros /
e montá-lo sobre ele. Ele faz isso toda vez que você inicializa seu sistema. Ele pode fazer isso de novo, e sem recorrer a hacks desnecessários como unionfs ou aufs - os quais provavelmente gerarão todos os tipos de complicações e detalhes de configuração específicos da implementação (o que é para não mencionar a instabilidade) .
Na descrição switch_root
citada acima, você provavelmente notará a frase excluir todos os arquivos de rootfs . Obviamente, isso não seria um comportamento desejável ao sair de um rootfs baseado em disco. Mas isso só acontece dessa maneira com switch_root
para liberar a memória para o sistema de arquivos baseado em RAM de qualquer maneira - e é completamente desnecessário. Aqui está mais um pouco do artigo anterior citado:
The following shell script fragment demonstrates how to use 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
Como você pode ver acima, o tratamento dos problemas relacionados com /dev
, /proc
e /sys
pode ser simplesmente realizado. Se você fosse colocar camadas de mount --move
d, a propósito, você teria que lidar não apenas com mtab
e mount
, mas também quaisquer outras complicações introduzidas pelo seu sistema de camadas. É mais simples fazer exatamente como você descreve na pergunta - mount root de algum outro lugar.
Você precisará fazer basicamente todas as coisas que acontecem em uma configuração típica do initramfs e muito pouco mais - (que não é para incluir Debian ou Redhat < Imagens de initramfs do / strong> - ambas muito projetadas em excesso) . O único problema real que você pode encontrar é como fazer o PID1 seguir o mesmo caminho - se você deixar o init do seu sistema encalhado em alguns rootfs órfãos, coisas muito estranhas podem começar a acontecer em breve no seu sistema. A maneira óbvia de lidar com isso é preparar a partir do initramfs. Apenas certifique-se de que o processo init
do seu disco rígido esteja preparado para exec
outro mais tarde quando quiser mudar de raiz. Se você estiver usando um systemd
init
, essa complicação já foi feita para você:
systemctl --help
...
switch-root ROOT [INIT] Change to a different root file system
...
Se você estiver usando um systemd
-based init
, você deve estudar os arquivos unitários em /usr/lib/systemd/system/initrd*
para ter uma ideia de como é a situação comum do script comutado em systemd
.
Outra maneira de fazer isso é imitar busybox
' switch_root
no initramfs', mas deixar de fora a parte em que você exclui todos os arquivos da raiz inicial. Os sistemas Arch Linux configurados com systemd
no initramfs fazem isso. Nelas, a raiz do initramfs é montada em /newroot
' /run/initramfs
' antes de fazer a comutação de raiz e é o que o sistema usa no desligamento para lidar corretamente com suspensão / suspensão e similares. Esse pode ser o melhor caminho para o seu caso, na verdade - apenas um pequeno sistema de raiz persistente que você executa pingue-pongue para seus vários aplicativos baseados individualmente.