Linux: come formattare più file system all'interno di un file?


9

Devo creare un'immagine del disco con due file system vuoti. L'ho creato usando

dd if=/dev/zero of=./disk.img bs=1MiB count=1024

Successivamente, ho creato 2 partizioni primarie usando fdisk disk.img; uno è FAT32 e l'altro è EXT3. Ora, devo formattare entrambe le partizioni per creare file system da montare come -o loop devices. Ma non riesco a capire come formattarli? Non posso usare mkfs.vfatsu disk.img. Quindi sono totalmente confuso.

SOLUZIONE: grazie alla risposta di @ pjc50 ho trovato una soluzione molto semplice:

sudo aptitude install multipath-tools
sudo kpartx -a disk.img   #it maps (mounts) found partitions to /dev/mapper/loop...
sudo mkfs.vfat -F 32 -n boot /dev/mapper/loop0p1
sudo mkfs.ext3 -L rootfs /dev/mapper/loop0p2

Uno svantaggio di questa soluzione è il requisito dei diritti di superutente.


Dubito che tutti quei programmi saranno in grado di utilizzare le partizioni all'interno di un file. Puoi creare i due filesystem in file separati e poi unirli in un file di grandi dimensioni con dd?
Golimar,

@golimar: ma avrò bisogno di MBR su tale unità, non so come sia possibile unire diversi filesystem creati separatamente come file distinti
psihodelia

Puoi usare l'MBR del file originale che hai detto. dd consente gli offset con i comandi 'size' e 'skip'. Dovresti trovare gli offset esatti e poi sovrascrivere parte del file grande con i due più piccoli
golimar

Perdonami se sono ingenuo qui, ma perché non usare solo due file separati?
Garrett,

Risposte:


9

Sembra che tu possa usare gli strumenti kpartx: http://robert.penz.name/73/kpartx-a-tool-for-mounting-partitions-within-an-image-file/

Kpartx può essere usato per configurare i mapping dei dispositivi per le partizioni di qualsiasi dispositivo a blocchi partizionato. Fa parte degli strumenti multipath di Linux. Con kpartx -l file immagine si ottiene una panoramica delle partizioni nel file immagine e con kpartx -a file immagine le partizioni saranno accessibili tramite / dev / mapper / loop0pX (X è il numero della partizione). Ora puoi montarlo con mount / dev / mapper / loop0pX / mnt / -o loop, ro. Dopo aver smontato puoi disconnettere i dispositivi del mapper con kpartx -d imagefile.

Tuttavia, uno svantaggio di questa soluzione è il requisito dei diritti di superutente.
psihodelia,

1
Dubito che esista una soluzione che non richiede diritti di superutente! Cioè, questo è il tipo di operazione che non mi aspetto che i normali utenti possano fare a meno di uno specifico meccanismo impostato in anticipo dal superutente (ad esempio tramite sudo)
pjc50

2
@ pjc50: è possibile farlo senza i diritti di superutente: si deve prima creare ogni partizione come file separato, quindi creare manualmente l'immagine del disco e copiare le partizioni sull'immagine del disco dopo aver creato la tabella delle partizioni sull'immagine del disco.
Mikko Rantalainen,

1
@MikkoRantalainen esattamente. Ecco un esempio eseguibile minimo: superuser.com/a/1367534/128124
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

7

Puoi farlo montando prima le tue partizioni /dev/loop?usando losetupcon l' -oopzione per specificare un offset adatto alla tua partizione. L'offset può essere calcolato in base all'output di fdisk -l disk.img( start_sector * sector_size).

Per esempio:

losetup -o32256 /dev/loop1 ./disk.img   # mount first partition

Una volta montato, è quindi possibile procedere con la formattazione della partizione utilizzando mkfs.*:

mkfs.vfat -F32 /dev/loop1

Per maggiori dettagli ed esempi, vedere i seguenti articoli:


Bene, non funziona :(
psihodelia il

@psihodelia Dovrebbe. Qual è il risultato se lo fai?
Daniel Beck

Come non funziona? Ricevi un errore? Quale passo fallisce?
Shawn Chin,

$ sudo mkfs.vfat -F32 / dev / loop1 mkfs.vfat 3.0.9 (31 gen 2010) Il dispositivo loop non corrisponde a una dimensione floppy, usando i parametri hd predefiniti
psihodelia

1
Potrebbe essere utile se si specifica la dimensione del blocco durante la chiamata mkfs.vfat. Vedi il primo link che ho fornito. Anche menzionato nell'articolo, l'avviso floppy è previsto e può essere ignorato
Shawn Chin

1

Vorrei andare con gli strumenti che ho in mente:

  • creare una nuova macchina virtuale in Virtualbox con un disco, che normalmente sarebbe /dev/sda
  • avviare nella VM con un Live CD GParted
  • partizionare e formattare il disco nella VM in base alle proprie esigenze (2 partizioni, diversi file system, ecc.)
  • quindi utilizzare ddper esportare /dev/sdain un file

Con un'ipotesi istruita ci vorrebbero circa 15 minuti.


Soluzione intelligente astuta :) Ma non credo ci voglia meno di 15 minuti. A proposito, è difficile automatizzarlo, perché richiede un utente in un'interfaccia grafica (quindi, nessuno scripting è possibile = non un modo Unix).
psihodelia,

Non ci vuole molto :-) perché il disco virtuale è piccolo e non viene eseguita l'installazione del sistema operativo. La parte più lunga è il tempo di avvio di GParted.
Karatedog,

1

Eseguibile minimo sfdisk+ mke2fsesempio senzasudo

In questo esempio, creeremo, senza sudoo setsuid, un file immagine che contiene due partizioni ext2, ciascuna popolata con file da una directory host.

Useremo quindi sudo losetupsolo per montare le partizioni per testare che il kernel Linux può effettivamente leggerle come spiegato su: /programming/1419489/how-to-mount-one-partition-from-an-image -file-che-contiene-multiple-partizioni / 39.675.265 # 39675265

Per maggiori dettagli, vedi:

L'esempio:

#!/usr/bin/env bash

# Input params.
root_dir_1=root1
root_dir_2=root2
partition_file_1=part1.ext2
partition_file_2=part2.ext2
partition_size_1_megs=32
partition_size_2_megs=32
img_file=img.img
block_size=512

# Calculated params.
mega="$(echo '2^20' | bc)"
partition_size_1=$(($partition_size_1_megs * $mega))
partition_size_2=$(($partition_size_2_megs * $mega))

# Create a test directory to convert to ext2.
mkdir -p "$root_dir_1"
echo content-1 > "${root_dir_1}/file-1"
mkdir -p "$root_dir_2"
echo content-2 > "${root_dir_2}/file-2"

# Create the 2 raw ext2 images.
rm -f "$partition_file_1"
mke2fs \
  -d "$root_dir_1" \
  -r 1 \
  -N 0 \
  -m 5 \
  -L '' \
  -O ^64bit \
  "$partition_file_1" \
  "${partition_size_1_megs}M" \
;
rm -f "$partition_file_2"
mke2fs \
  -d "$root_dir_2" \
  -r 1 \
  -N 0 \
  -m 5 \
  -L '' \
  -O ^64bit \
  "$partition_file_2" \
  "${partition_size_2_megs}M" \
;

# Default offset according to
part_table_offset=$((2**20))
cur_offset=0
bs=1024
dd if=/dev/zero of="$img_file" bs="$bs" count=$((($part_table_offset + $partition_size_1 + $partition_size_2)/$bs)) skip="$(($cur_offset/$bs))"
printf "
type=83, size=$(($partition_size_1/$block_size))
type=83, size=$(($partition_size_2/$block_size))
" | sfdisk "$img_file"
cur_offset=$(($cur_offset + $part_table_offset))
# TODO: can we prevent this and use mke2fs directly on the image at an offset?
# Tried -E offset= but could not get it to work.
dd if="$partition_file_1" of="$img_file" bs="$bs" seek="$(($cur_offset/$bs))"
cur_offset=$(($cur_offset + $partition_size_1))
rm "$partition_file_1"
dd if="$partition_file_2" of="$img_file" bs="$bs" seek="$(($cur_offset/$bs))"
cur_offset=$(($cur_offset + $partition_size_2))
rm "$partition_file_2"

# Test the ext2 by mounting it with sudo.
# sudo is only used for testing, the image is completely ready at this point.

# losetup automation functions from:
# /programming/1419489/how-to-mount-one-partition-from-an-image-file-that-contains-multiple-partitions/39675265#39675265
loop-mount-partitions() (
  set -e
  img="$1"
  dev="$(sudo losetup --show -f -P "$img")"
  echo "$dev" | sed -E 's/.*[^[:digit:]]([[:digit:]]+$)/\1/g'
  for part in "${dev}p"*; do
    if [ "$part" = "${dev}p*" ]; then
      # Single partition image.
      part="${dev}"
    fi
    dst="/mnt/$(basename "$part")"
    echo "$dst" 1>&2
    sudo mkdir -p "$dst"
    sudo mount "$part" "$dst"
  done
)
loop-unmount-partitions() (
  set -e
  for loop_id in "$@"; do
    dev="/dev/loop${loop_id}"
    for part in "${dev}p"*; do
      if [ "$part" = "${dev}p*" ]; then
        part="${dev}"
      fi
      dst="/mnt/$(basename "$part")"
      sudo umount "$dst"
    done
    sudo losetup -d "$dev"
  done
)

loop_id="$(loop-mount-partitions "$img_file")"
sudo cmp /mnt/loop0p1/file-1 "${root_dir_1}/file-1"
sudo cmp /mnt/loop0p2/file-2 "${root_dir_2}/file-2"
loop-unmount-partitions "$loop_id"

Testato su Ubuntu 18.04. GitHub a monte .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.