Mikor virtuális gépekkel dolgozunk, lépten-nyomon beleakadunk abba a problémába, hogy a különféle virtualizációs megoldásoknak más és igényei vannak a virtuális lemez image-ek szerkezetére vonatkozóan. Egyesek az image-eket mint teljes merevlemezt (partíciós táblával, partíciókkal együtt) kezelik (pl.: qemu), míg mások egy partíciónak tekintik azt. Ebben az írásban összefoglaljuk, hogyan készíthetünk és kezelhetünk különféle elvárásoknak megfelelő virtuális lemez image-eket Linux alatt.

Virtuális lemez partíciók

A legegyszerűbb esetben a virtualizációs megoldás úgy tekint a virtális lemez image-re, mint egy partícióra. Ekkor az image tartalma semmi más nem kell, hogy legyen csak a nyers adat, például az állományrendszer.

A dd paranccsal könnyen és gyorsan létrehozhatunk tetszőleges nagyságú üres virtuális lemez image-et, az alábbi módon:

dd if=/dev/zero of=disk1.img bs=1M count=1 seek=512

A fenti parancs hatására egy 512M nagyságú állomány keletkezik disk1.img néven a parancs kiadásának helyén. Az állomány még nem foglalja el a teljes 512M-t a fizikai lemezen, mivel ez egy úgynevezett ritka (sparse) állomány. Amint elkezdjük használni, a felhasználás mértékével arányosan, maximum 512M méretig folyamatosan foglalja majd a helyet az operációs rendszer a fizikai lemezen.

A Linux loop modulja teszi lehetővé, hogy tetszőleges állományokat, mint blokk eszközöket kezelhessünk. Ehhez először az állományt csatolni kell egy blokk eszköz meghajtóhoz. Ezt az összerendelést az alábbi parancs segítségével végezhetjük el:

losetup -f disk1.img

Ez a legkisebb szabad /dev/loopX (ahol X=0,1,2…) blokk eszköz állományon keresztül elérhetővé teszi a megadott állományt. Sajnos a parancs nem mondja meg, ki lett a kiválasztott blokk eszköz állomány, ezért érdemes a fenti parancs előtt a

losetup -f

parancsot kiadni, ami megmondja, hogy mi a neve a következő szabad /dev/loopX állománynak, vagy a parancs kiadása után a

cat /proc/partitions

megmutatja a partíciókat, köztük a loopokat is. Ha nem egyértelmű a helyzet, akkor a

# losetup /dev/loop0
/dev/loop0: [0303]:5560165 (/home/tudor/work/uml/raid1.bin)

parancs tisztázhatja, hogy melyik blokkeszközhöz melyik fájl tartozik.

A létrejött blokkeszközzel most már pontosan úgy járhatunk el, mintha valódi fizikai partíció lenne. Például az alábbi utasítással készíthetünk állomány rendszert rá:

mkfs.ext3 /dev/loop0

Valójában attól lesz egy tetszőleges image állomány virtuális lemez image, hogy állományrendszert tettünk rá.

A keletkezett új állományrendszerre például Debian linux rendszeren az alábbi parancsokkal telepíthetünk egy Etch változatú alaprendszert:

mount /dev/loop0 /mnt
debootstrap --arch i386 etch /mnt http://ftp.debian.org/debian
umount /mnt

Ha nem alkarjuk tovább használni a image állományt blokk eszközként, akkor szüntessük meg az összerendelést az alábbi paranccsal:

losetup -d /dev/loop0

Figyelmeztetés: mielőtt egy adott virtualizációs megoldással használatba vennénk a virtuális lemez image-et, mindenképpen csatoljuk le (umount) és szüntessük meg az összerendelést a blokk eszköz állománnyal. Ellenkező esetben adatvesztéssel járó hibát is elkövethetünk véletlen írással.

Teljes virtuális lemezek

Amikor az image állománnyal, mint teljes lemezzel dolgozunk, ugyanúgy kell a méreteket meghatározni, mint a fizikai lemezek esetén. Azaz a CHS (cylinder, head, sector) rendszerben kell gondolkoznunk.

Történelmileg úgy alakult, hogy a korai PC-k BIOS-ai maximum 63 szektort kezeltek, az IDE interfész esetén pedig maximum 16 fejet lehetett használni. Mára ezeknek az adatok elvesztették tényleges jelentésüket. Ennek ellenére kompatibilitási okokból elterjedt megoldás e két limitet felhasználva a virtuális lemezek geometriáját így kialakítani. A leírás további részében mi is ezt követjük, azaz továbbiakban mindig: head=16, sector=63.

Ahhoz, hogy jól kezelhető virtuális lemez image-ket kapjunk, célszerű cilinderre pontos méretű image állományt készíteni. Rövid számolás után megkapjuk, hogy 512 byte méretű blokkok esetén egy cilinder 512*16*63=516096 byte méretű. Egy 512 MB méretű merevlemez hozzávetőlegesen 1040 cilindert tartalmaz. Ennek megfelelően az eredeti dd parancsunkat az alábbiak szerint módosíthatjuk:

dd if=/dev/zero of=disk1.img bs=516096c count=1 seek=1040

Ezen a lemezen az alábbi módszerrel tudunk érvényes partíciós táblát kialakítani (egy partíciót fogunk készíteni, de a módszer kellő körültekintéssel általánosítható több partícióra is):

# losetup -f
/dev/loop0
# losetup -f disk1.img
# fdisk -u -C1040 -H16 -S63 /dev/loop0
o
n
p
1
<enter>
<enter>
a
1
w

A partíciónálás jobban automatizálható az sfdisk parancs segítségével. A fenti fdisk parancs megfelelője az alábbi:

sfdisk -D -C1040 -H16 -S63 /dev/loop0 <<EOF
,,,*
EOF

A művelet elvégzése után az eredményt az alábbi utasítással tekinthetjük meg:

# fdisk -ul /dev/loop0

Disk /dev/loop0: 537 MB, 537255936 bytes
16 heads, 63 sectors/track, 1041 cylinders, total 1049328 sectors
Units = sectors of 1 * 512 = 512 bytes

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1   *          63     1048319      524128+  83  Linux

Jól látható, hogy a partíció nem az első szektortól indul, így erre az image-re a korábban bemutatott módszerrel nem tudunk állományrendszert készíteni és aztán csatolni (mount) azt, egy kis trükkhöz kell folyamodni.

Az állományban az első partíció a 63*512=32256 bytenál kezdődik. Ezért a losetup parancsot az alábbiak szerint kell módosítani:

losetup -f -o32256 disk1.img

Ezek után az így kapott /dev/loopX-el úgy tudunk dolgozni, ahogy eddig.

A teljes virtuális lemezek esetén haszons lehet, ha tudjuk, hogyan kell egy boot loadert telepíteni azokra. Példának okáert most a grub telepítését mutatjuk be röviden.

Első szüntessük meg az összerendelést az állomány és a loopback eszköz között.

losetup -d /dev/loop0

Ezt követően indítsunk grub shellt:

grub --no-floppy

majd a grub shellben adjuk ki az alábbi parancsokat:

grub> device (hd0) disk1.img
grub> geometry (hd0) 1040 16 63
grub> root (hd0,0)
grub> setup (hd0)

Itt feltételeztük, hogy a disk1.img lesz az eszköz, amiről a rendszer bootolni fog és ez az eszköz lesz az első a biosban (hd0). A geometry paranccsnál a korábban kiszámolt cilinder, fej és szektor méreteket használtuk.

Forrás: Avaxio