n0derunner

    QCOW 3 Ways

    Published: (Updated: ) in Linux Virtualization by .

    How to mount QCOW images as Linux block devices

    tl;dr

    Mounting qcow guest disks on KVM host with guestmount

    If you are working with vanilla kvm and are on the KVM host, the easiest way to mount disks (at least disks with standard Linux fileystems) is to use guestmount – which is installed with libguestfs-tools. Assume we have a mountpoint /a, a vm called vm3-full-kernel-20G whose disk is located at /vmdisks/ubuntu-20.10-server-cloudimg-amd64_VM1_root-full-kernel-20G.qcow2

    mount disks READ ONLY from a running domain (VM)
    $ mount | grep /a
    /dev/fuse on /a type fuse (rw,nosuid,nodev,relatime,user_id=0,group_id=0)
    mount disks READ/WRITE for a shutdown VM (domain)

    Example – write a file in the guest FS from the virtualization host

    # Virtualization host
    $ sudo guestmount -d vm3-full-kernel-20G -i /a
    $ sudo touch /a/gary
    $ sudo umount /a
    $ virsh start vm3-full-kernel-20G
    $ virsh console vm3-full-kernel-20G
    
    # Guest vm (vm3-full-kernel-20G)
    ubuntu@ubuntu:~$ date
    Thu Sep  8 19:21:56 UTC 2022
    ubuntu@ubuntu:~$ ls -l /gary
    -rw-r--r-- 1 root root 0 Sep  8 19:20 /gary

    Mounting qcow disks with nbd

    nbd is usually used to access remote disks – but with the qemu-nbd utility you can use the nbd driver to mount qcow files.

    # modprobe nbd max_part=8
    # qemu-nbd --connect=/dev/nbd0 /vmdisks/ubuntu-20.10-server-cloudimg-amd64_VM1_root-full-kernel-20G.qcow2
    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: gpt
    Disk identifier: D0DABDE9-0E22-4536-BA44-05BCDE0661E9
    
    Device        Start      End  Sectors  Size Type
    /dev/nbd0p1  227328 41943006 41715679 19.9G Linux filesystem
    /dev/nbd0p14   2048    10239     8192    4M BIOS boot
    /dev/nbd0p15  10240   227327   217088  106M EFI System
    
    Partition table entries are not in disk order.

    Example mounting NTFS guest disk to Linux

    root@aws-i3en-jump:/home/ubuntu# modprobe nbd max_part=8
    root@aws-i3en-jump:/home/ubuntu# qemu-nbd --connect=/dev/nbd0 sqlservertpcc3-disk-index-3.qcow2
    
    root@aws-i3en-jump:/home/ubuntu# fdisk /dev/nbd0 -l
    Disk /dev/nbd0: 50 GiB, 53687091200 bytes, 104857600 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: gpt
    Disk identifier: DDA58512-CF96-417F-AEDE-1B787E1247AB
    
    Device       Start       End   Sectors  Size Type
    /dev/nbd0p1     34    262177    262144  128M Microsoft reserved
    /dev/nbd0p2 264192 104855551 104591360 49.9G Microsoft basic data
    
    root@aws-i3en-jump:/home/ubuntu# mount -t ntfs /dev/nbd0p2 /a
    root@aws-i3en-jump:/home/ubuntu# cd /a
    
    root@aws-i3en-jump:/a# ls
    '$RECYCLE.BIN'                tempdb.mdf           tempdb_mssql_5.ndf
    'System Volume Information'   tempdb_mssql_3.ndf   tempdb_mssql_7.ndf

    Mounting raw disks with losetup

    If the guest disk is raw either natively or having been converted using something like below. The name used in the mount table will be the name of the ‘volume’ in the image not the name of the image file itself.

    qemu-img convert ubuntu-clone-no-resize.qcow2 -f qcow2 -O raw ubuntu-clone-no-resize.raw

    The disk can be mounted simply by using losetup – on my ubuntu running losetup also mounted the drive under /media/gary/cloudimg-rootfs

    Run the command losetup -f find the next free /dev/loop slot and -P scan for partitions

    # losetup -f -P ubuntu-clone-no-resize.raw

    Find the loopback device

    # losetup -l | grep ubuntu-clone-no-resize.raw
    /dev/loop99         0      0         1  0 /vmdisks/ubuntu-clone-no-resize.raw                      0     512

    Confirm – the partitions will not show up under /dev/loop – look under /dev/mapper.

    # ls -l /dev/loop99*
    brw-rw---- 1 root disk 7, 99 Sep  8 16:35 /dev/loop99
    
    # ls /dev/mapper/loop99*
    /dev/mapper/loop99p1  /dev/mapper/loop99p14  /dev/mapper/loop99p15

    Mount the device (if not automounted)

    # mount /dev/mapper/loop99p1 /a

    Find the mountpoint if automounted – else cd to the mount point

    # mount | grep loop
    /dev/mapper/loop99p1 on /media/gary/cloudimg-rootfs type ext4 (rw,nosuid,nodev,relatime,errors=remount-ro,uhelper=udisks2)

    Access the mounted file/filesystem

    # ls -l /media/gary/cloudimg-rootfs/
    total 80
    lrwxrwxrwx  1 root root     7 Jul 20  2021 bin -> usr/bin
    drwxr-xr-x  4 root root  4096 Jul 20  2021 boot
    drwxr-xr-x  4 root root  4096 Jul 20  2021 dev
    drwxr-xr-x 90 root root  4096 Sep  8 12:16 etc
    drwxr-xr-x  3 root root  4096 Sep  8 12:16 home
    lrwxrwxrwx  1 root root     7 Jul 20  2021 lib -> usr/lib
    lrwxrwxrwx  1 root root     9 Jul 20  2021 lib32 -> usr/lib32
    lrwxrwxrwx  1 root root     9 Jul 20  2021 lib64 -> usr/lib64
    lrwxrwxrwx  1 root root    10 Jul 20  2021 libx32 -> usr/libx32
    drwx------  2 root root 16384 Jul 20  2021 lost+found
    drwxr-xr-x  2 root root  4096 Jul 20  2021 media
    drwxr-xr-x  2 root root  4096 Jul 20  2021 mnt
    drwxr-xr-x  2 root root  4096 Jul 20  2021 opt
    drwxr-xr-x  2 root root  4096 Oct 16  2020 proc
    drwx------  4 root root  4096 Sep  8 12:16 root
    drwxr-xr-x  3 root root  4096 Jul 20  2021 run
    lrwxrwxrwx  1 root root     8 Jul 20  2021 sbin -> usr/sbin

    Unmount and release the loopback device

    # umount /a
    # losetup -d /dev/loop99

    If you got into some weird dm situation – use dmsetup info them dmsetup remove <device>

    root@rodney:/# dmsetup info
    Name:              loop99p1
    State:             ACTIVE
    Read Ahead:        256
    Tables present:    LIVE
    Open count:        0
    Event number:      0
    Major, minor:      253, 2
    Number of targets: 1
    UUID: part1-devnode_7:99_Wh5pYvM
    ...
    Name:              loop99p14
    ...
    Name:              loop99p15
    
    
    root@rodney:/# dmsetup remove loop99p1
    root@rodney:/# dmsetup remove loop99p14
    root@rodney:/# dmsetup remove loop99p15

    Then the loopback device is removed

    #  losetup -l
    NAME        SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE                                              DIO LOG-SEC
    /dev/loop1          0      0         1  1 /var/lib/snapd/snaps/core_13425.snap                     0     512
    /dev/loop15         0      0         1  1 /var/lib/snapd/snaps/snap-store_558.snap                 0     512
    /dev/loop6          0      0         1  1 /var/lib/snapd/snaps/firefox_1775.snap                   0     512
    /dev/loop4          0      0         1  1 /var/lib/snapd/snaps/core20_1611.snap                    0     512
    /dev/loop11         0      0         1  1 /var/lib/snapd/snaps/gnome-3-38-2004_115.snap            0     512
    /dev/loop16         0      0         1  1 /var/lib/snapd/snaps/snapd-desktop-integration_14.snap   0     512
    /dev/loop14         0      0         1  1 /var/lib/snapd/snaps/gtk-common-themes_1535.snap         0     512

    Comments

    Leave a Comment