blog · git · desktop · images · contact & privacy · gopher


Handhabung von Festplattenimages mit modernem Linux

Das Internet ist voll von Fragen, wie man denn jetzt eine einzelne Partition aus einem kompletten Festplattenimage mountet. Ein „komplettes“ Festplattenimage meint ein solches, das auch den Boot-Record, die Partitionstabelle und daher mehrere Partitionen beinhaltet. Die meisten Antworten behaupten, man müsse die Offsets manuell berechnen: Wo innerhalb des Images fängt die gewünschte Partition an? Wo hört sie auf? Genau das habe ich auch die ganze Zeit gemacht.

Stellt sich aber heraus, dass man das mit einem modernen Linux nicht mehr machen muss. Das ist jetzt alles viel einfacher.

Komplette Festplattenimages

Schauen wir uns die Erstellung eines leeren Images „from scratch“ an.

Zuerst erzeugt man eine 100MB große, leere Datei:

$ dd if=/dev/zero of=disk.img bs=1M count=100

Darin kann man nun mehrere Partitionen erstellen. Um das zu tun, muss man lediglich fdisk aufrufen:

$ fdisk disk.img

Nun kann man Loop-Devices für dieses Image und seine Partitionen erzeugen:

# losetup -Pf --show disk.img
/dev/loop0

Was passiert hier?

  1. -f lässt nach dem nächsten freien Loop-Device suchen. --show zeigt an, welches Device dabei gefunden und benutzt wurde. Darum muss man sich also schon nicht mehr selbst kümmern.
  2. -P veranlasst einen „Partition Scan“ nach der Erzeugung des Devices.

Das heißt, man hat am Ende nicht nur /dev/loop0, sondern auch zusätzliche Device-Nodes pro Partition. In meinem Beispiel habe ich zwei Partitionen erstellt:

$ ls -al /dev/loop0*
brw-rw---- 1 root disk   7, 0 Feb 18 19:17 /dev/loop0
brw-rw---- 1 root disk 259, 0 Feb 18 19:17 /dev/loop0p1
brw-rw---- 1 root disk 259, 1 Feb 18 19:17 /dev/loop0p2

$ cat /proc/partitions
major minor  #blocks  name

...

   7        0     102400 loop0
 259        0      20480 loop0p1
 259        1      80896 loop0p2

Der Partition Scan findet also heraus, wo die Partitionen anfangen und aufhören.

Anzumerken ist noch, dass es standardmäßig nach dem Booten die Device-Nodes /dev/loop0 bis /dev/loop7 gibt. Toll ist aber: Wenn die aufgebraucht sind, dann werden automatisch neue Device-Nodes „on the fly“ erzeugt. In einer VM habe ich problemlos mehrere tausend Loop-Devices benutzt. Früher musste man noch an den Parametern des Kernelmoduls loop drehen, um mehr als acht Devices zu erhalten. Heute funktioniert das einfach so.

Man kann jetzt /dev/loop0p1 und /dev/loop0p2 wie gewöhnliche Block-Devices benutzen. Zum Beispiel kann man Dateisysteme darin erstellen:

# mkfs.ext4 /dev/loop0p1

Und das Ding mounten:

# mount /dev/loop0p1 /mnt

Das war’s!

Wenn man fertig ist, muss man es unmounten und das Loop-Device wieder detachen:

# umount /mnt
# losetup -d /dev/loop0

So komfortabel funktioniert das alles seit der Einführung von /dev/loop-control. Das war ungefähr in Linux 3.1 und util-linux 2.21, also vor ungefähr 3-4 Jahren.

Images mit nur einem Dateisystem darin

Hat man ein Image mit nur einem Dateisystem (also ohne Partitionstabelle), dann wird es noch einfacher:

# mount -o loop disk.img /mnt

Fertig.