sistema de arquivos raiz btrfs no raspbian


11

Eu pensei que poderia experimentar com o btrfs como partição raiz para ver como ele lida com a corrupção de arquivos durante cortes de energia. Mas não consigo inicializá-lo.

O que eu fiz:

  1. no PI antes de alternar:

    apt-get install btrfs-tools 2. Em um computador linux:

    btrfs-convert / dev / sda2

  2. Em /etc/fstabmudança ext4parabtrfs

  3. Em /cmdline.txtmudança ext4parabtrfs

Eu fico com um pânico no kernel se tentar inicializar. Devo fazer mais alguma coisa?

Respostas:


7

Se o btrfs for compilado como um módulo do kernel, você precisará criar um initramfs para carregar o módulo na inicialização. No Raspian (e em outros derivados do debian), update-initramfsé o método mais fácil de fazer isso.

Se initramfs-toolsestiver instalado, a qualquer momento que apt-getinstalar um novo kernel, ele deve ser acionado update-initramfsautomaticamente.

sudo apt-get update
sudo apt-get install initramfs-tools

No entanto, se você usa rpi-updatepara instalar um novo kernel, precisará executar update-initramfsmanualmente antes de reiniciar no novo kernel:

sudo update-initramfs -u -k <kernel-version>

Isso criará ou atualizará o initramfs no /boot/initrd.img-<kernel-version>.

A etapa final é adicioná-lo à sua configuração de inicialização: adicione a seguinte linha em /boot/config.txt:

initramfs initrd.img-<kernel-version> followkernel

initrd-<kernel-version>deve corresponder exatamente ao nome do arquivo /boot.

Você precisará repetir essas etapas sempre que executar rpi-update.


2

Meu teste rápido mostra que o suporte ao btrfs é construído como um módulo externo no raspbian, não vinculado diretamente ao kernel.

Isso significa que o kernel precisa carregar esse módulo (que é armazenado no sistema de arquivos raiz) antes de saber como montar o sistema de arquivos raiz. Obviamente, isso não funciona.

Abordagem 1:

Construa seu próprio kernel e ajuste sua configuração para pré-linkar btrfs. Ajustar a configuração é fácil se você descobriu como criar e carregar seu próprio kernel.

Abordagem 2:

Reajuste as coisas para que o kernel e os módulos estejam em um sistema de arquivos ext4 e os dados que você mais deseja compactar estejam em uma partição btrfs.

Abordagem 2A:

Deixe a partição raiz como ext4 e crie uma nova partição baseada em btrfs, mas isso não ajuda a diminuir a instalação do sistema operacional (se esse for seu objetivo).

Abordagem 2B:

Crie uma partição de inicialização que seja pequena e mantenha o kernel e os módulos, deixando todo o resto no btrfs. Não tenho idéia de como fazer isso para o carregador de inicialização de um Pi ou quais são as limitações.


Que tal copiar os módulos btrfs para a partição de inicialização e carregá-los a partir daí antes?
— GuySoft

3
Também não é possível começar com um initrd.img?
— Anders

Sim, e o initrd.img parece a maneira mais fácil de resolvê-lo! Eu apenas nunca o usei. Procure documentos no "mkinitrd".
— Dongar

Hmm parece que CONFIG_BLK_DEV_INITRD não está ativado no Raspbian mais recente. Isso significa que você precisa recompilar o kernel para ativar o suporte initd.
— 7269 GuySoft

11
Consulte paxswill.com/blog/2013/11/04/encrypted-raspberry-pi - O initramfs é usado para permitir raiz criptografada. Da mesma forma, o suporte ao cryptsetup (aqui btrfs) é necessário antes que o root esteja disponível.
— Rbjz

1

Para encontrar minha partição raiz BTRFS externa, eu precisava especificar explicitamente o UUID da partição raiz na partição de inicialização cmdline.txt. Por exemplo:

dwc_otg.lpm_enable = 0 console = tty1 root = PARTUUID = 123e4567-e89b-12d3-a456-426655440000 rootfstype = btrfs elevador = prazo final rootwait quiet splash

Você pode determinar o UUID da partição BTRFS usando lsblk -f.


1

O kernel Raspbian não inclui suporte btrfspor padrão; os estágios iniciais de inicialização são executados normalmente, mas quando o kernel carrega, ele não vê nenhum sistema de arquivos que possa montar - e entra em pânico. Existe uma solução: adicione btrfs como um módulo do kernel, no initramfs. Em grande parte graças a três artigos diferentes , eu o configurei assim:

  • Instale os pacotes necessários - o módulo do kernel e as ferramentas para atualizar o initramfs com ele: sudo apt install btrfs-tools initramfs-tools
  • Diga ao initramfs para carregar o módulo btrfs (deve estar acontecendo automaticamente, por algum motivo, não funcionou no meu RPi1) - adicione uma linha com "btrfs" à lista de módulos necessários: echo 'btrfs' | sudo tee -a /etc/initramfs-tools/modules
  • Crie um gancho initramfs (para construir a imagem) e um script (para inicializar) para btrfs - os padrões são fornecidos, mas nos meus testes, eles não foram usados ​​automaticamente, tiveram que copiá-los para / etc. sudo mkdir -p /etc/initramfs-tools/hooks ; sudo mkdir -p /etc/initramfs-tools/scripts/local-premount ; sudo cp /usr/share/initramfs-tools/hooks/btrfs /etc/initramfs-tools/hooks ; sudo cp /usr/share/initramfs-tools/scripts/local-premount/btrfs /etc/initramfs-tools/scripts/local-premount; sudo chmod +x /etc/initramfs-tools/hooks/btrfs /etc/initramfs-tools/scripts/local-premount/btrfs
  • Crie ( -c) o novo initramfs para a versão atual do kernel (uname -r) - se você estiver atualizando uma versão existente, precisará usar update ( -u). Isso criará um arquivo chamado /boot/initrd.img-*, onde * é a versão atual do kernel. Observe o nome gerado (o script o exibirá), nós o usaremos na próxima etapa.update-initramfs -c -k $(uname -r)
  • Edite /boot/config.txtpara usar este initramfs, adicionando initramfs initrd.img-3.11.0+ followkernelO nome do arquivo está sem caminho, é o gerado na etapa anterior; "followkernel" controla a localização na memória ( documentação config.txt ).
  • Isso resolve o kernel atual, mas como o @Ingo apontou, a atualização do kernel quebraria o sistema. Para corrigir isso, usei seus scripts de gancho de instalação do kernel :

    • Edite / etc / default / raspberrypi-kernel e descomente INITRD=Yes
    • excluir /etc/kernel/postinst.d/initramfs-tools
    • adicionar RPI-initramfs-tools para /etc/kernel/postinst.d/ e chmod +xele
    • opcionalmente, faça o download de update-rpi-initramfs para obter atualizações manuais mais simples dos initramfs.
  • Neste ponto, temos um sistema que poderia usar o btrfs como dispositivo raiz. Teste reinicializando: o sistema ainda será inicializado a partir da partição ext4 (ou o que estiver no seu / boot / cmdline.txt ), mas dmesg | grep -i btrfsagora deve mostrar uma linha contendo "Btrfs carregado". Agora precisamos criar e usar uma partição btrfs.

  • Faça um backup da /partição (ext4) - assumindo que seja / dev / mmcblk0p2 - normalmente: desligue o RPi, retire o cartão SD, monte-o em outro lugar (neste exemplo, sudo mount /dev/mmcblk0p2 /mntem um computador Linux) e arquive o conteúdo; observe que você precisa usar uma ferramenta que preserva a propriedade e as permissões, por exemplo, tar: cd /mnt; sudo tar -czvf ~/rpi-rootfs-backup.tgz *(e desmonte o cartão SD novamente)

  • Crie uma partição btrfs em algum lugar - reutilizei o cartão SD, substituindo a partição ext4 (/ dev / mmcblk0p2); se você deseja criar uma matriz btrfs-raid, é hora de fazer isso ( é um dos argumentos para mkfs.btrfs , além do escopo desta resposta):mkfs.btrfs /dev/mmcblk0p2
  • Monte a partição btrfs e restaure o backup nela: sudo partprobe; sudo mount /dev/mmcblk0p2 /mnt; cd /mnt; tar -xzvf ~/rpi-rootfs-backup.tgz
  • Edite o fstab na partição btrfs :sudo nano /mnt/etc/fstab

Deve haver uma linha semelhante a esta:

/dev/mmcblk0p2  / ext4 foo,bar,baz 0 1

Altere para este (o novo tipo FS é btrfs e usa as opções padrão):

/dev/mmcblk0p2  / btrfs defaults 0 1
  • Desmonte a partição, mas não remova o cartão SD ainda! sudo umount /mnt
  • Precisamos dizer ao RPi que ele será inicializado a partir do btrfs
  • Encontre o UUID da sua nova partição btrfs - encontre a linha com / dev / mmcblk0p2 e copie a parte UUID =, com o (não UUID_SUB, não PARTUUID! Isso provocaria um bug no gerenciador de inicialização e o kernel não inicializaria .):sudo blkid

    / dev / mmcblk0p2: UUID = "cafebeef-0000-1234-aaaa-12346589" UUID_SUB = "ababccdd-2345-cafe-beee-587989991110" TYPE = "btrfs" PARTUUID = "beef0bee-02"

  • Monte a partição de inicialização (FAT32): sudo mount /dev/mmcblk0p1 /mnt

  • Edite cmdline.txt: sudo nano /mnt/cmdline.txt

Encontre estes dois parâmetros

 root=PARTUUID=1234-5678 rootfstype=ext4

E substitua por

 root=UUID=cafebeef-0000-1234-aaaa-12346589 rootfstype=btrfs

Observe que o UUID é o que copiamos anteriormente, apenas sem aspas.

  • Desmonte a partição de inicialização do RPi: sudo umount /mnt
  • Substitua o cartão SD em RPi e inicialize.
  • No RPi, veja se você está realmente executando a partir de uma montagem raiz btrfs: mount

    / dev / mmcblk0p2 em / digite btrfs (rw, space_cache, subvol = /)

  • Et voilà! Não é só apontar e clicar, mas ao ficar nos ombros de gigantes, eu poderia fazê-lo funcionar. (Transforme isso em um repositório também.)


11
No primeiro sudo apt upgradecaso, se ele também atualizar o kernel, essa configuração falhará drasticamente na inicialização, porque o novo kernel tenta carregar o initramfs antigo que falhará e o kernel não pode carregar os drivers btrfs. E não é uma maneira fácil de consertá-lo, pelo menos com um chrootsistema armhf.
— Ingo

O update-initramfs não seria chamado na atualização do kernel?
— Piskvor saiu do prédio em 25/02/19

11
Não, o Raspbian padrão falha ao gerar um novo initramfs. Não está configurado para isso. Você sempre precisa monitorar com seus olhos o que apt upgradeestá fazendo e gerar um initramfs manualmente, se necessário - antes de inicializar o novo kernel. Não é uma tarefa factível para um iniciante, porque falhar é dramática. Você pode dar uma olhada em Como posso usar um init ramdisk (initramfs) na inicialização do Raspberry Pi?
— Ingo

11
Ele tem um pequeno bug que acabei de encontrar, mas que não foi corrigido até o momento. O kernel suporta dois modelos, por exemplo, 4.14.98+e 4.14.98-v7+. Se update-initramfs for acionado por uma atualização do kernel, ele gerará dois initrd.img *, um para cada modelo. Isso não cabe na /bootpartição (erro sem espaço) e a geração não termina.
— Ingo

11
Eu considero usar MODULES=list.
— Ingo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.