0

I have several VMs set up within Hyper-V using Ubuntu 17.10 and have found that they are not configured correctly - that is, they have been set up using the default block size for the VHDX files and are using much more space than they require and have a higher maximum VHDHX size than I would like. In one example, I have a drive which is ~50GB but only contains 15GB of data.

I am looking to create new VHDHX files using more sensible settings and clone everything that is on the drives on to the newly created drives, but I'm running into some problems. The existing drives are showing up as having 2 partitions as shown here, and then there are 2 logical volumes on the larger partition - one for data and one for swap.

drive info

The drive I am looking to clone this to will be a 30GB VHDHX file, and I need some advice on the best way to go about doing this. I initially tried using dd and encountered errors due to the source being larger than the destination. I then tried using gparted to resize the larger drive, but could not due to gparted seeing the LVM partition as having no free space. I also tried reducing the size of the LVM partition and then using gparted, but also ran into errors with this. I've been able to successfully reduce the size of the LVM partition and then use dd to clone the LVM volume to another LVM volume I have created on the new drive, though I am concerned that when I use lvreduce to resize the original partition I may be cutting off data if the data is not contiguous and is spread across the drive.

I am quite new to this, so do not know what I may be overlooking and may need to account for in doing it, but essentially I'm looking for some guidance on the required steps to ensure that the new drive contains everything that is on the old one and I can boot from it. If for example, I use lvreduce to resize the large volume to the size I need, how do I verify that I have not lost anything in doing this? Would this even be the correct approach?

So far my plan is:

  1. Create a new Ubuntu VM to use to perform this process.
  2. Attach the original drive + a new drive to be used for copying the data.
  3. Shrink the logical volume on the original drive.
  4. Create the same partitions & volumes on the new drive.
  5. Use dd to copy the logical volumes to the equivalent logical volumes on the new drive.

Is there a better way to do this, or anything I have missed?/pitfalls to be aware of?

2

If anyone comes across this and has the same problem, the solution which worked for me is mostly as was described above. In the example given below, my original drive has 2 partitions, a boot partition and a data partition with 2 logical volumes, and the destination drive starts out with a boot partition and a data partition with no logical volumes.

  1. Set up a VM with both disks attached and boot it using a Linux Live CD.
  2. Run a file system check on the source disk with sudo e2fsck -f /dev/mapper/ubuntu--1704--base--vg-root - the volume name can be found from the output of sudo fdisk -l
  3. Shrink the file system to the minimum size before we resize the logical volume. This can be done using sudo resize2fs -M /dev/mapper/ubuntu--1704--base--vg-root
  4. Resize the logical volume to the desired size, in this case 28.5 GiB: sudo lvreduce --resizefs -L 28.5G /dev/mapper/ubuntu--1704--base--vg-root
  5. Rename the volume group on the existing drive, as we will be using the same name on the new drive: sudo vgrename ubuntu-1704-base-vg ubuntu-1704-base-vg-2
  6. Create a new physical volume: sudo pvcreate /dev/sda2
  7. Create a new volume group, using the name taken from the original volume group on the source drive: sudo vgcreate ubuntu-1704-base-vg /dev/sda2
  8. Create the logical volumes on the new drive to match the ones on the old drive. In my case I had one used for swap and one for data. I took the size of the logical extents allocated to each from the 'Current LE' property reported by sudo lvdisplay and then used them as the input for the lvcreate command, e.g.:
    • sudo lvcreate --extents 7296 --stripes 1 --name root ubuntu-1704-base-vg
    • sudo lvcreate --extents 255 --stripes 1 --name swap_1 ubuntu-1704-base-vg
  9. Copy the data from the old drive to the new drive. I did this by copying the boot partition from the source drive over the boot partition on the new drive, then copied the logical volume for the data drive on to the new logical volume on the destination drive. e.g.:
    • sudo dd if=/dev/sdb1 of=/dev/sda1 bs=64M status=progress
    • sudo dd if=/dev/mapper/ubuntu--1704--base--vg--2-root of=/dev/mapper/ubuntu--1704--base--vg-root bs=64M status=progress

Finally, run a file system check to verify that the drives are ok. There may be errors which need to be repaired, though after doing this I was able to boot successfully from the copied drive and the contents were as expected. sudo e2fsck -f /dev/mapper/ubuntu--1704--base--vg-root

References used: https://blog.shadypixel.com/how-to-shrink-an-lvm-volume-safely/ https://docs.microsoft.com/en-us/azure/virtual-machines/linux/configure-lvm

0

If I understand, what you actually need to achieve is copying your VM image to a smaller footprint one, but still use this in Hyper-V (so use VHDX format).

In such case, I don't see the point of going through a new VM.

VM disk images can be created either with a fixed or dynamic size. When fixed size is use, the whole space is allocated on image creation, and VM image actually uses the final size. When dynamic format is used, the footprint on disk only grows with actual disk usage in the VM.

So you first should verify what format is actually used : your image file may expose 50Gb while actually using less (sparse files, if supported by your OS may cause this).

In case your image is a fixed one, you should look for a converter tool (e.g. StarWind V2V Converter or other ) in order to create a new dynamic image from your fixed one, without having to go through LVM or partitioning changes.

Note: This may require a step to clear all unused space first in each file system of the Ubuntu VM ( dd if=/dev/zero of=/zerofile ; rm -f /zerofile).

  • Thanks for answering. The reason for the new VM is because as I understand it, dd should not be used when the drive is mounted, so it's just to attach it to the new VM to do the copy. The VHDX is dynamic, but the issue I'm encountering affects dynamic disks. The maximum file size is currently 127GB, but the file has grown to 50GB despite only using 15GB of space. This is covered a bit here: bit.ly/2gKWtVn For comparison, a base OS install is ~4GB with the correct block size, and ~8GB with the incorrect block size. – PaulM Jul 2 '18 at 12:43
  • I still think you should look forward to VM images conversion tools... I'm not so much aware for VHDX format, but this is the kind of thing I use to do with qemu-img to reduce qcow2 images. – tonioc Jul 2 '18 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.