Using linux box to shrink and separate virtual disks

I have some virtual machines with partitions on their vmdk. This makes it terribly difficult to be resized.

I am going to use old dd linux command to copy all data.

In the hipervisor, I’m using a linux box, actually Debian box, to map all disks, and do all the block writing commands.

vmware_shrink2

I also have to take care of the first blocks of the disks, which contains the booting mark. Otherwise, I will have a copy of my data, but my disk won’t be bootable.

vmware_shrink1

Let’s get started.

I will assign to my linux box, all my disks. Old and new ones.

OS disk: Writing boot sector

#
# Copy boot blocks and old partition tables
#
dd if=/dev/sdb of=/dev/sdc bs=16 count=200

OS disk: writing data

I have to re-do partition table (using fdisk) and then copy all data.

As I copied from the original source disk the first sector, a fake partition table is also writen on my new OS disk. It’s time to repartition.

fdisk /dev/sdc
Welcome to fdisk (util-linux 2.25.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): p
Disk /dev/sdc: 15 GiB, 16106127360 bytes, 31457280 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: 0xfe1387ed
Device Boot Start End Sectors Size Id Type
/dev/sdc1 * 63 31471334 31471272 15G 7 HPFS/NTFS/exFAT
/dev/sdc2 31471335 52452224 20980890 10G 7 HPFS/NTFS/exFAT

Delete second partition

Command (m for help): d 2
(...)
Command (m for help): p
(...)
Device Boot Start End Sectors Size Id Type
/dev/sdc1 * 63 31471334 31471272 15G 7 HPFS/NTFS/exFAT
(...)
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

To write the data, the dd command has to be invoked partitions name (sdb1) and not entire disk (sdb). Entire disk was used just for the boot mark.

dd if=/dev/sdb1 of=/dev/sdc1

Data disk: writing data

I have 2 options here. As it is data, I can either write blocks (dd) or just ordinary file copying.

I created the partition table.

fdisk /dev/sdd

Command (m for help): t
Selected partition 1
Hex code (type L to list all codes): 7
Changed type of partition 'HPFS/NTFS/exFAT' to 'HPFS/NTFS/exFAT'.

Command (m for help): p
Disk /dev/sdd: 10 GiB, 10737418240 bytes, 20971520 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: 0x00c7e39c
Device Boot Start End Sectors Size Id Type
/dev/sdd1 2048 20971519 20969472 10G 7 HPFS/NTFS/exFAT

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

If we are going to use file system operations, I need to give it ntfs format:

apt-get install ntfs-3g
mkfs.ntfs /dev/sdd1

Now, it is time to mount both partitions and copy!

mkdir /mnt/old_data
mkdir /mnt/new_data
mount /dev/sdb2 /mnt/old_data/
mount /dev/sdd1 /mnt/new_data/
cp -rfp /mnt/old_data/* /mnt/new_data/

If ntfs permissions are not correctly written, you can use again old dd:

dd if=/dev/sdb2 of=/dev/sdd1