Gerando um .img a partir do tarball: Os dispositivos / dev / loop

3

Estou tentando fazer um .img a partir de um tarball usando o seguinte script que encontrei:

#!/bin/bash

# Packages required
# dosfstools parted 
# Can be run on any Linux system
# loop.max_part=15 must be in kernel cmdline (cmdline.txt for rpi)
# then reboot

echo "creating image to fit on 2Gb card"
dd if=/dev/zero of=arch-rpi.img bs=1M count=1850

echo "Partitioning"
fdisk arch-rpi.img <<EOF
o
n
p
1

+100M

t
c
n
p
2


w
EOF

sleep 5

losetup -f arch-rpi.img
sleep 5

echo "Formatting vfat"
mkfs.vfat /dev/loop0p1
sleep 5
mkdir boot
echo "Mounting boot"
mount /dev/loop0p1 boot
echo "Installing"

echo "Formatting ext4"
mkfs.ext4 /dev/loop0p2
sleep 5
mkdir root
echo "Mounting root"
mount /dev/loop0p2 root

wget http://archlinuxarm.org/os/ArchLinuxARM-rpi-latest.tar.gz
echo "Installing"
bsdtar -xpf ArchLinuxARM-rpi-latest.tar.gz -C root
sync
mv root/boot/* boot
sync
umount boot root
losetup -d /dev/loop0p1
losetup -d /dev/loop0p1
losetup -d /dev/loop0
echo "All complete, image arch-rpi.img created, compressing...."
zip -9 arch-rpi.img.zip arch-rpi.img

Estou fazendo isso no meu Raspberry Pi - Raspbian Wheezy. E quando chegar na linha mkfs.vfat /dev/loop0p1 , diz que não existe tal arquivo / diretório. Eu li o suficiente no Linux para saber que estou tentando montar o .img como um dispositivo de loop e, em seguida, usar o mkfs para preparar a imagem para o tarball, mas eu não sei bem por que os arquivos loop0p # não estão lá, eles estão listados por fdisk -l . O que eu preciso para obter este script que encontrei trabalhando?

    
por Ward9250 28.02.2015 / 04:30

2 respostas

2

No driver loop , o suporte para partições é opcional, determinado pelo argumento max_part quando o driver é carregado. O valor padrão é 0, então o driver de loop não irá procurar por partições; com um valor diferente de zero, o driver suporta muitas partições. Dependendo das opções de compilação do kernel, o driver pode ser incluído no kernel, caso em que você precisa passar loop.max_part=… na linha de comando do kernel no momento da inicialização, ou ser carregado como um módulo, caso em que você precisa passar max_part=… quando o módulo é carregado.

No Debian wheezy, loop é um módulo e o argumento max_part não é passado. Para obter suporte à partição, descarregue o módulo e carregue-o de volta com um argumento max_part (primeiro será necessário desativar qualquer dispositivo de loop existente com losetup -d ):

if lsmod | grep -wq loop; then rmmod loop; fi
modprobe loop max_part=31

Você pode tornar isso padrão adicionando options loop max_part=31 a /etc/modprobe.conf .

Se você não puder descarregar o módulo (ou reinicializar, em uma distribuição onde loop está embutido no kernel), você pode calcular o deslocamento da partição manualmente e usar a opção -o para losetup . Vejo Lendo um sistema de arquivos a partir de uma imagem de disco inteira

Com novas distribuições, você pode usar losetup -P ao configurar o dispositivo de loop :

…
losetup -P -f arch-rpi.img
…

mas o pacote util-linux no Debian wheezy é muito antigo para ter essa opção.

    
por 01.03.2015 / 00:41
1

Você precisa usar losetup -P para criar um dispositivo de loop -P artitioned, ou então você precisa particionar o dispositivo de loop original e então partx -u pdate a tabela de partições do kernel depois. Os dispositivos /dev/loop0p aparecerão após o kernel reconhecerá que a partição foi particionada. Provavelmente isso é em parte qual é a intenção por trás do sleep 5 - mas isso deve ser quase um sync - ou ambos - em vez disso.

De qualquer forma, para demonstrar:

sudo sh -s <<\IN
    losetup -D                          
    fallocate "-l$((1024*1024*1024))" loop        
    printf %s\n n '' '' '' ''  w y | gdisk loop
    sync; losetup -f loop
    lsblk /dev/loop*
IN

Portanto, a seqüência acima primeiro -D mostra todos os dispositivos de loop atuais (se houver) fallocate sa 1GB tmp, grava uma tabela de partições GPT nela e faz uma única partição nela então sync s o sistema de arquivos e o atribui ao -f primeiro dispositivo de loop disponível antes de tentar listar com lsblk todos os dispositivos de loop disponíveis. Imprime:

NAME  MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0   7:0    0   1G  0 loop 

Mas se eu alterar a linha losetup para ler:

losetup -fP loop

... em vez disso, imprime:

NAME      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
loop0       7:0    0    1G  0 loop 
├─loop0p1 259:0    0 1023M  0 loop 
└─loop0p2 259:1    0 1007K  0 loop 

... porque losetup primeiro verifica o arquivo de apoio para uma tabela de partições. Como você pode ver, não é muito bom - em vez de observar o extra 1M (que é quase definitivamente a tabela de partições da última iteração) como espaço não alocado ele o interpreta como uma partição separada, mas provavelmente é porque estou escrevendo para um tmpfs (duas vezes seguidas) no topo de um arquivo de 1GB - trabalhando com dados reais será muito mais preciso (e zerando o apoio) arquivo como seu script faz com dd iria lidar com isso de qualquer maneira) . Em qualquer caso - eu posso livremente mkfs.whatever na partição real e depois mount . partx -u no /dev/loop0 alcançaria os mesmos resultados.

    
por 28.02.2015 / 06:36