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?

GuySoft
fonte

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.

bennettp123
fonte
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.

DonGar
fonte
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.

Geremia
fonte
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.)

Piskvor saiu do prédio
fonte
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