1 August 2009 - 13:42Mount LVM-based volumes from loopback full disk images

Recently I needed to extract some files from the root partition in a full disk backup image taken with dd. I didn’t notice when I took the disk image, but the disk only contained two primary partitions: /boot and an LVM physical volume containing the rest of the partitions as LVM logical volumes. I don’t work with LVM much manually, so I had to look up the commands to get it to find physical volumes and activate volume groups. Here’s the full process of mounting LVM logical volumes from a full disk image:

  • There are two ways to get to the LVM partition on this disk, and I’ll cover both: 1) the manual offset finding way and 2) the easy way.
  • First, the easy way: make sure the loopback module is inserted with the max_part parameter, which causes the automatic creation of loopback subdevices for individual partitions. An easy way to make sure is to remove it and re-insert with the right parameter: modprobe -r loop && modprobe loop max_part=63
  • Next, mount the whole disk image loopback: losetup /dev/loop0 sda.img. Now you should see /dev/loop0p1,/dev/loop0p2, etc. for all of the individual partitions. Now you’re already done — you can go directly to the next section to deal with LVM directly.
  • If you can’t do the easy method, mount the whole disk image loopback to look at the partition offsets: losetup /dev/loop0 sda.img
  • Now that /dev/loop0 looks just like the block device image, so check out the partition table sector offsets with fdisk: fdisk -u -l /dev/loop0. I use sector offsets (-u flag) rather than cylinders because they are easier to work with and some partitions may not fall on cylinder boundaries. My image shows something like this:
  • Disk /dev/loop0: 250 GB, 250056737280 bytes
    255 heads, 63 sectors/track, 30401 cylinders, total 488392065 sectors
    Units = sectors of 1 * 512 = 512 bytes
    
         Device Boot      Start         End      Blocks   Id  System 
    /dev/loop0p1   *          63      401624      200781   83  Linux
    /dev/loop0p2          401625   488392064   243987187   8e  Linux LVM
    
    
  • Now, remove the whole disk image from /dev/loop0: losetup -d /dev/loop0 and set /dev/loop0 to just the LVM partition by adding the partition offset. Here, the second partition starts at sector 401625, and each sector is 512 bytes, so the offset is 205632000. Run losetup /dev/loop0 sda.img -o205632000

Now whichever method you used, you have a loopback device with the LVM physical volume partition: /dev/loop0p? (2 in my case) if you used the easy way, or /dev/loop0 if you used the manual offset method. Get LVM to recognize the physical volume and activate the volume groups:

  • Tell LVM to scan for new physical volumes: lvm pvscan
  • Activate the volume groups: lvm vgchange -ay (it will print something like 2 logical volume(s) in volume group "VolGroup00" now active).
  • Now you can finally mount the LVM logical volumes. Run lvm lvs to list the logical volumes. Each should appear in /dev/mapper, typically with the device name (volume group name)-(logical volume name), like VolGroup00-LogVol00.
  • When you are done, unmount all logical volumes and deactivate the volume groups with lvm vgchange -an. Now you can reclaim the loopback device by using losetup -d /dev/loop0.

25 Comments | Tags: Linux

Comments:

  1. Ross Golder says;
    11 Mar 2010 - 0:55

    Handy tip to avoid the need to unload/reload ‘loop’ module (i.e. it’s compiled in!)…

    Find the offset of the LVM partition in the file image using the ‘file’ command…

    root@zeus:/data/kvm# file hermes.img
    hermes.img: x86 boot sector; GRand Unified Bootloader, stage1 version 0×3, boot drive 0×80, 1st sector stage2 0x11c41; partition 1: ID=0×83, active, starthead 1, startsector 63, 208782 sectors; partition 2: ID=0x8e, starthead 0, startsector 208845, 104647410 sectors, code offset 0×48

    Then, setup the loop device with an appropriate offset into the file, based on the start sector of the partition multiplied by the block size…

    root@zeus:/data/kvm# losetup -v -o $[512*208845] /dev/loop0 hermes.img
    Loop device is /dev/loop0

    Now, go get LVM to recognise it…

    root@zeus:/data/kvm# lvm pvscan
    PV /dev/loop0 VG VolGroup00 lvm2 [49.88 GB / 0 free]
    Total: 1 [49.88 GB] / in use: 1 [49.88 GB] / in no VG: 0 [0 ]

  2. Thanks for the tip Ross.

  3. Marcin says;
    01 May 2010 - 5:42

    Hi,

    I’ve chosen easy way and worked for me perfectly.
    I would like to thank you for this post, helped me recovery files from full dd image (LVM2+ext3) which I wasn’t able to solve in different ways.

    Thank you very much.

  4. Hi,
    this post is very useful and helped me a lot. I have one more question: how to work with fact that VG have same name as primary VG on running machine?
    I have 2GB file image and then main partition – both with LVM:
    [root@master xen]# lvm pvscan
    WARNING: Duplicate VG name VolGroup00: Existing eo4yt2-hfId-9gMg-WNl2-yByT-K0Z e-77yWBw (created here) takes precedence over 1ZpcbA-WewQ-kyb0-7qyy-kMEH-8clS-46 Sfe8
    PV /dev/mapper/loop0p2 VG VolGroup00 lvm2 [1.84 GB / 0 free]
    PV /dev/sda2 VG VolGroup00 lvm2 [148.78 GB / 93.75 GB free]
    Total: 2 [150.62 GB] / in use: 2 [150.62 GB] / in no VG: 0 [0 ]
    [root@master xen]# vgscan
    Reading all physical volumes. This may take a while…
    WARNING: Duplicate VG name VolGroup00: Existing eo4yt2-hfId-9gMg-WNl2-yByT-K0Ze-77yWBw (created here) t akes precedence over 1ZpcbA-WewQ-kyb0-7qyy-kMEH-8clS-46Sfe8
    WARNING: Duplicate VG name VolGroup00: Existing eo4yt2-hfId-9gMg-WNl2-yByT-K0Ze-77yWBw (created here) t akes precedence over 1ZpcbA-WewQ-kyb0-7qyy-kMEH-8clS-46Sfe8
    Found volume group “VolGroup00″ using metadata type lvm2
    Found volume group “VolGroup00″ using metadata type lvm2
    [root@master xen]# lvscan
    WARNING: Duplicate VG name VolGroup00: Existing eo4yt2-hfId-9gMg-WNl2-yByT-K0Ze-77yWBw (created here) t akes precedence over 1ZpcbA-WewQ-kyb0-7qyy-kMEH-8clS-46Sfe8
    WARNING: Duplicate VG name VolGroup00: eo4yt2-hfId-9gMg-WNl2-yByT-K0Ze-77yWBw (created here) takes prec edence over 1ZpcbA-WewQ-kyb0-7qyy-kMEH-8clS-46Sfe8
    ACTIVE ‘/dev/VolGroup00/LogVol00′ [30.22 GB] inherit
    ACTIVE ‘/dev/VolGroup00/LogVol01′ [5.81 GB] inherit

    Do you have some tips how to mount LV on second VG?
    Thank you in advance.

    Dave

  5. Depending on what your situation is, you could do the following:

    * Back up your lvm.conf
    * Edit the lvm.conf default filter to only scan a subset of block devices (/dev/loop* only, for example) for volumes (or temporarily reject the ones you want to ignore)
    * Use vgrename to change the name of one of them
    * Restore your original lvm.conf

    You might have to do this from a rescue disk if the volume group with precedence can’t be stopped and contains a critical partition for the running system.

  6. Andrey says;
    11 Jun 2010 - 1:11

    Thank you!
    The way described works perfectly.

    I’ll never-never use LVM on my development host.

  7. This blog entry came up on the Fedora users mailing list today. I’d like to point out that this whole process can be done more simply and without root by using libguestfs and guestfish.

  8. Thanks for the note Rich. libguestfs looks very useful, and it certainly fits an emerging need for better disk image tools. This blog entry was posted quite a while ago, and at the time I wasn’t aware of libguestfs. A great thing about blogs with open comments is that you can keep abreast of current “best practices” for tasks like this if someone stumbles upon the entry in the future and leaves a comment. So thanks for that!

  9. I do this using kpartx.
    losetup $LOOP IMAGE MOUNT
    kpartx -av $LOOP
    fdisk -lu $LOOP
    mount ${LOOP}p1 /tmp/part1
    ls /tmp/part1 # see files

    LVM?
    lvdisplay -c
    (find /dev/mapper equivalent)
    mount /dev/mapper/$LV /tmp/lv
    ls /tmp/lv # see files

  10. Followup:

    On some systems instead of:
    mount ${LOOP}p1 /tmp/part1

    You may need to do:
    mount ${LOOP/\/dev/\/dev\/mapper}p1 /tmp/part1

  11. Thanks a lot. Your article is extremely helpful.

  12. Mike O'Connor says;
    03 Mar 2011 - 21:18

    ..and another heart-felt thank you here from Brisbane, Australia. This post helped me recover from a nightmare scenario of a corrupt VMWare snapshot, which contained our company’s shared file server. I love the internet! :)

  13. Hey, it’s 2011 and this post is still helping! Just want to say thanks from an lvm2 noob.

  14. Another thanks from me – saved me a tonne of time and effort gaining access to a LVM volume in a volume!

  15. Andres Nogueiras says;
    07 Sep 2011 - 13:14

    Thanks! Nice instructions to put the lvm disks in other machines.

  16. Just wanna say thanks. With this I was able to recover files from Xen based physical device.

  17. Trent Shea says;
    27 Dec 2011 - 12:26

    Excellent! I love the easy way. Worked like a charm on Debian Squeeze.

  18. Robert Strickler says;
    19 Apr 2012 - 13:43

    Here is a quick in dirty script for the manual method after locating the image (virt-manager puts mine on a GPT partitioned disk

    # set the LVM image name (vmg=virtual machine guest)
    VMG=vmg1
    # unmount complete disk image (vmd=virtual machine disks)
    sudo losetup /dev/loop0 /dev/vg_vmd/$(VMG).img

    # assume the partition holding the LVM is the last fdisk line
    # stash the sector offset in a variable offset for subsequent computation
    SECTORZ=`sudo fdisk -u -l /dev/loop0 | tail –lines=1 | cut -c 19-28`

    # unmount complete disk image
    sudo losetup -d /dev/loop0

    #mount the LVM stuff by computing the character offset
    sudo losetup /dev/loop0 /dev/vg_vmd/vmg1.img -o$(( $SECTORZ * 512 ))
    sudo lvm pvscan
    sudo lvm vgchange –available y $(VMG)
    sudo lvm lvs
    #
    #do your thing on the LV
    #
    #release the LV so unmounting the loopback succeeds
    sudo lvm vgchange –available n $(VMG)
    # unmount complete disk image
    sudo losetup -d /dev/loop0

  19. max_part=63 – how damn cool is that? Impressed by Linux once again (after having used loop devices for years…)

  20. Very helpful! im thinking of mounting my virtualized images in order to backup them with rdiff-backup (i’ve tried to rdiff-backup directly the vm.img file but it takes forever and sometimes the files are too large) and i was just wondering should i just:

    dd if=/media/bk_mounted_vm of=/media/vm.img to recreate a working virtual image on KVM?

    thanks !!!

  21. Excellent article — really saved my bacon today. Thanks!

  22. Indispensable post – yanked an old hard drive from a CentOS box, USB to MacBook Pro – OSX 10.6, dd to disk.img on local file system, mounted local file system using VirtualBox/Ubuntu and was at a dead end until I found this article. Thanks!

Add a Comment