There are two ways to currently mount disk images on Linux. Both of them involve using QEMU in different aspects. Both of them support the image formats that are supported by QEMU itself. I won’t enumerate that list, but for practical sake, it’s whatever images you’re used to working with when using hypervisors like VirtualBox, Hyper-V, KVM, et al.
Perhaps you’re in a situation where you need to mount an image to extract something from it, but you can’t or don’t want to mess around with network shares like NFS or Samba, and you need a way to transfer data to and from the virtual machine.
Perhaps you have a failing hard drive that is dubious at best with transferring large amounts of data at once. You could attempt to use
rsync -P and chip away at transferring the image, in hopes that it runs and has your data intact on the destination, or you could mount it as described below and target the important data immediately.
libguestfs-tools are available on your operating system, I would suggest going with this method as it was specifically intended to be used for the aforementioned task. The latter method is more of a hack taking advantage of the NBD protocol.
Both methods involve what amounts to starting an on-the-fly virtual machine (via qemu) to read the image and export the data. Verify with
ps aux | grep qemu in the midst of one of the following methods if you’re curious.
The following method (#1) also has the ability to attach to a live system. This could be useful if you just want to transfer something simple that you know will not intersect with anything on the running system. This implies a strict warning. I mean it, the man page (ctrl+f “ATTACH”) literally says:
Note (1): This is highly experimental and has a tendency to eat babies. Use with caution.
--live at the guestmount man page for more information.
$ sudo dnf install libguestfs-tools
Being that we now have
libguestfs-tools, we have the
virt-*suite at our disposal. Let’s take a look at what partitions are available to mount on a test
$ sudo -i # cd /var/lib/libvirt/images # virt-filesystems -a fedora25.qcow2 /dev/sda1 btrfsvol:/dev/sda3/root btrfsvol:/dev/sda3/home /dev/sda3
We can see here that our mountable options are
sda3- and we’re probably after
sda3since that contains our important data. Let’s mount it with
# guestmount -r -a fedora25.qcow2 -m /dev/sda3 /mnt/point # ls -l /mnt/point total 0 drwxr-xr-x. 1 root root 12 Jun 3 18:12 home dr-xr-xr-x. 1 root root 132 Jun 3 19:38 root
-ris to mount the image read-only,
-mis the internal partition you want to mount, and
/mnt/pointis a directory on the host filesystem that you want to mount the internal partition to.
Here we see
rootdirectories that contain the
btrfshome and root subvolumes. That’s because we mounted
/dev/sda3directly and the default subvolume to mount on a
subvolid=5. If that’s not relevant or doesn’t make sense to you, just note that this would ordinarily be the root of the filesystem (i.e.
etc, etc live) were it not
That’s it! Now, when you’re done, simply use
guestunmountto un-mount the device much in the same way you would use
# exit $ cd # in case we're in /mnt/point $ sudo guestunmount /mnt/point
Start off by installing
$ sudo dnf install qemu-img nbd
nbdkernel module with option
max_part=8. This option is basically a required option unless your images are flat and have no internal partitions because we need that in order for it to create
nbdNis linked to an image:
$ sudo modprobe nbd max_part=8
Now let’s attach the virtual image to one of the nbd devices:
$ sudo qemu-nbd -c /dev/nbd0 /var/lib/libvirt/images/fedora25.qcow2 $ # check dmesg for partitions indicating it was loaded properly $ dmesg | grep nbd0 [348950.439938] nbd0: p1 p2 p3
Note: Optionally use
-rto export the image read-only. Or you can also use
mount -o roin one of the following steps. It’s probably best to be read-only at the lowest level, however.
Here we can see
p3are active, let’s explore that further next
Optional: check partitions with
$ sudo fdisk -l /dev/nbd0 Disk /dev/nbd0: 20 GiB, 21474836480 bytes, 41943040 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xf4520513 Device Boot Start End Sectors Size Id Type /dev/nbd0p1 * 2048 2099199 2097152 1G 83 Linux /dev/nbd0p2 2099200 6293503 4194304 2G 82 Linux swap / Solaris /dev/nbd0p3 6293504 41943039 35649536 17G 83 Linux $ sudo parted /dev/nbd0 print Model: Unknown (unknown) Disk /dev/nbd0: 21.5GB Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 1 1049kB 1075MB 1074MB primary ext4 boot 2 1075MB 3222MB 2147MB primary linux-swap(v1) 3 3222MB 21.5GB 18.3GB primary btrfs
We will select
/dev/nbd0p3as our mount target, this corresponds to
/dev/sda3from inside the virtual machine, and is the
btrfsfilesystem we’re interested in:
$ sudo mount /dev/nbd0p3 /mnt/point $ ls -l /mnt/point total 0 drwxr-xr-x. 1 root root 12 Jun 3 18:12 home dr-xr-xr-x. 1 root root 132 Jun 3 19:38 root
/mnt/pointis any directory on the filesystem you would like to mount on.
Success! Now when you’re done clean up with:
$ cd # in case we're under /mnt/point $ sudo umount /mnt/point $ sudo qemu-nbd -d /dev/nbd0 $ sudo modprobe -r nbd
libguestfs: error: invalid value for backingformat parameter ‘vdi’: Edit: Actually, this is a bug that I apparently found and reported on IRC that was fixed here, thanks to Richard Jones for fixing it! The gist is that it was caused by a stringent whitelist that didn’t account for all image types.
For reasons unknown to me
libguestfs‘s tools sometimes work fine with images other than
raw, and sometimes not. For example,
guestmountseem to work with most image formats, but
virt-filesystemsseems to support only the abovementioned two. In case you run up agasint this when intending to use
virt-rescueinstead and utilize the rescue shell to enumerate partitions as described during 1. on the next caveat.
Read only file system: You may get to the point after you mount the filesystem, especially with ones like
ntfs, where the dirty bit has been set by an unclean shutdown and the surrogate ad-hoc virtual machine that is created by
guestmountmounts it read-only under the hood forcefully. This is very hard to notice unless you add
-v | --verboseto
guestmount, and then you can clearly see what is going on (by contrast with method 2, when you go to manually mount it will be quite evident). Amidst all the other output, you should find toward the end:
commandrvf: mount -o /dev/sda2 /sysroot/ [ 0.982901] fuse init (API version 7.26) The disk contains an unclean file system (0, 0). Metadata kept in Windows cache, refused to mount. Falling back to read-only mount because the NTFS partition is in an unsafe state. Please resume and shutdown Windows fully (no hibernation or fast restarting.) guestfsd: main_loop: proc 74 (mount_options) took 0.13 seconds
In this case, use the
ntfsfixcommand in order to make the filesystem properly mount. Be aware that this can be potentially dangerous, and the instructions to use windows for this should be heeded. That being said, I haven’t really had any issues with it myself:
Manually start the rescue shell:
virt-rescue -a Windows.vdi ... ... ><rescue> lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sdb 8:16 0 4G 0 disk / sda 8:0 0 50G 0 disk |-sda2 8:2 0 49.5G 0 part `-sda1 8:1 0 500M 0 part
ntfsfixto reset the filesystem:
><rescue> ntfsfix /dev/sda2 Mounting volume... The disk contains an unclean file system (0, 0). Metadata kept in Windows cache, refused to mount. FAILED Attempting to correct errors... Processing $MFT and $MFTMirr... Reading $MFT... OK Reading $MFTMirr... OK Comparing $MFTMirr to $MFT... OK Processing of $MFT and $MFTMirr completed successfully. Setting required flags on partition... OK Going to empty the journal ($LogFile)... OK Checking the alternate boot sector... OK NTFS volume version is 3.1. NTFS partition /dev/sda2 was processed successfully.
qemu-nbd -c /dev/nbd0 <image_file>do the following:
$ ntfsfix /dev/nbd0p2 Mounting volume... The disk contains an unclean file system (0, 0). Metadata kept in Windows cache, refused to mount. FAILED Attempting to correct errors... Processing $MFT and $MFTMirr... Reading $MFT... OK Reading $MFTMirr... OK Comparing $MFTMirr to $MFT... OK Processing of $MFT and $MFTMirr completed successfully. Setting required flags on partition... OK Going to empty the journal ($LogFile)... OK Checking the alternate boot sector... OK NTFS volume version is 3.1. NTFS partition /dev/nbd0p2 was processed successfully.
You should then be able to (with both methods) mount the
ntfsfilesystem read-write and continue on.