Assume you have created a Xen virtual machine, and its data are stored on a file. You might want to access the files stored inside the machine (even when the machine is not running) for one reason or another:
- inspect them;
- change some of them, as an example you copy the virtual machine imagine file to another physical host and you need to change some settings (e.g. network-related) in order to fit the virtual machine for the new host;
- doing some post-mortem analysis and/or recovery;
If you search on the net, you may find this document from IBM that will give you some hints, assuming that on the virtual machine you don’t use LVM. I will move a step further, with the the procedure for dealing with virtual machine image file containing a LVM partition.
For the rest of the discussion, I assume you know what a loop backed file system is and how LVM works. Instead of saying “virtual machine file”, i.e. a file on the host that is the disk of the virtual machine, I would say “virtual disk”.
1. Be sure the virtual machine it’s shutted down
This is required to avoid metadata corruption.
2. Use losetup to associate the virtual disk to a block device
$ losetup -d /dev/loop0 virtual-disk
3. Use fdisk to get information about the block device
$ fdisk -l -u /dev/loop0
Disk /dev/loop0: 8388 MB, 8388608000 bytes
255 heads, 63 sectors/track, 1019 cylinders, total 16384000 sectors
Units = sectors of 1 * 512 = 512 bytes
Device Boot Start End Blocks Id System
/dev/loop0p1 * 63 208844 104391 83 Linux
/dev/loop0p2 208845 16370234 8080695 8e Linux LVM
This shows that the virtual machine has a tiny initial partition (probably the /boot) and a LVM partition.
4. Use losetup, again, to associate a specific partition of the virtual disk to a specific block device.
If you want the /boot partition:
$ losetup -o $((512*63)) /dev/loop1 /dev/loop0
$ mount /dev/loop1 /mnt
the magic here is the -o parameter, which defines the offset from the beginning of /dev/loop0: 63 sectors, as seen above from the fdisk output. If you want the files in the LVM partition, see next point.
5. Accessing LVM inside a loop device.
$ mount -o $$(208845*512) /dev/loop2 /dev/loop0
To scan the volume groups and the logical volumes, you need to tell to LVM that the /dev/loop<n> devices may contain LVM data. So, edit /etc/lvm/lvm.conf, find the line that defines the “types” parameter:
# types = [ "fd", 16]
it’s a comment, showing the default value. Immediately after, put this line:
types = [ "fd", 16, "loop", 1]
and see what happens:
ACTIVE '/dev/system/root' [14.62 GB] inherit
ACTIVE '/dev/system/home' [97.66 GB] inherit
ACTIVE '/dev/system/tmp' [512.00 MB] inherit
ACTIVE '/dev/system/swap' [4.00 GB] inherit
inactive '/dev/VolGroup00/LogVol00' [5.75 GB] inherit
inactive '/dev/VolGroup00/LogVol01' [1.94 GB] inherit
So we eventually can access the LogVol00 which contains data (someone tells me that LogVol01 is a swap partition):
$ vgchange -a y
4 logical volume(s) in volume group "system" now active
2 logical volume(s) in volume group "VolGroup00" now active
$ mount /dev/VolGroup00/LogVol01 /mnt/
Now the files of the virtual machine are accessible from the /mnt mount point.
6. Unmount all
$ umount /mnt
$ vgchange –activate n VolGroup00
$ losetup -d /dev/loop2
$ losetup -d /dev/loop1
$ losetup -d /dev/loop0
Remove the type parameter from /etc/lvm/lvm.conf if you feel you won’t need it anymore (if it’s present it does not hurt, though).
7. Some notes
- Remember that the LVM namespace is unique across the system, so your virtual machine must use volume group name and logical volume name different from the ones of the physical host;
- If you need to change the UUID of the virtual disk, see the uuidgen.py from the Xen distribution for some hints.
- A different approach, based on kpartx, is available in the Fedora Wiki.
Filed under: virtualization, virtualization, xen