Um ein SD-Kartenimage zu erstellen wird eine Sparse-Datei angelegt mit einer Größe von knapp 16 GB und darin verschiedene Dateisysteme angelegt:
dd if=/dev/zero of=$$IMAGE_FILE bs=1 count=0 seek=15900MB losetup /dev/loop0 $IMAGE_FILE { ... echo 6277120,,0x83 } | sfdisk -u S -f --no-reread -L ${/dev/loop0} partprobe /dev/loop4 mke2fs /dev/loop0p4
Im Gegensatz zu einer Nicht-Sparse-Datei bzw. einem physikalischen Datenträger bleibt der mke2fs-Vorgang nahezu vollständig stehen.
Dabei nutzt der System-Prozeß [loop0]
das System I/O-mäßig fast vollständig aus und verbringt die meiste Zeit im “uninterruptable sleep” (D
in ps), obwohl sich die Platte kaum bewegt. Ein Strace auf mke2fs
bringt recht zögerliche Zugriffe folgender Art zutage:
_llseek(3, <start>, <ende>, SEEK_SET) = 0 write(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0"..., 32768) = 32768
Es stellt sich heraus, daß dies zeitlich mit dem Erzeugen der inode tables in mke2fs zusammenfällt. Offenbar ist die sparse-File-Implementierung zumindest des Kernels unter Ubuntu 12.04 für diesen Anwendungsfall recht ungünstig.
Die Lösung ist mke2fs über die Umgebungsvariable MKE2FS_SYNC
zu einem selteneren sync zu zwingen:
export MKE2FS_SYNC=10
Dabei hat sich der schon woanders dokumentierte Wert von 10 bewährt. Interessanterweise führt ein größerer Wert zu dem gleichen Effekt (hängendes mke2fs
) wie der Standardwert MKE2FS_SYNC=1
.