So I just bought myself a new laptop (an Asus N76VB-T4038H) which I love so far. It’s a great machine and real value for money. Of course it comes preloaded with Windows 8 — which I hate so far, but am holding on to for the occasional multimedia thingie and because I might have to install Microsoft Office at some point. But my main OS is still Linux and in particular OpenSuSE. And given the way I want to use this laptop in the near future, the idea hit me that it would be a good idea to virtualize my Linux machines so that I can clone them and set up new and separate environments when needed. So I installed VirtualBox on my guest OS, downloaded the OpenSuSE 12.3 ISO, set up a new machine to create a golden image, pointed it to the ISO and installed OpenSuSE. Smooth sailing, no problems. Even set up an encrypted home partition without any pain. And then I tried to clone the machine in VirtalBox and start the clone… and found that it couldn’t find my cloned hard drive.

This is actually a reasonably well-known problem in OpenSuSE and some other Linux distros. You’ll find another blog about what is going on here and there are several forum posts. But none of the ones I found cover a solution involving GRUB2, so I thought I’d post my experiences here.

The problem

The basic problem is this: Linux has a single file system tree which spans all of the available hard drives, partitions and so on in one, large virtual structure. To make this happen different parts of the physical storage infrastructure of your machine are mapped to branches of the file system tree (so called mount point). So, for example, the /home directory in your file system may be designated a mount point for the second partition on you primary SCSI drive. Which means that you can type /home and under water the OS will start looking at the partition also known as /dev/sda2. This trick can be applied at any time by the way, using the mount command. This is also what happens, for instance, when you insert a USB drive or DVD: a previously normal directory like /media/USB suddenly and magically becomes the file system location for the USB drive.

Now, recently, Linux has acquired different ways of naming partitions and drives. It all used to be /dev/hdaX and /dev/sdaX, but nowadays several partitions have introduced additional naming schemes using symlinks. For example, on my system, there is a directory /dev/disk which includes several subdirectories containing symlinks to actual device files, all using different naming schemes:

bzt@linux-akf6:/dev/disk> ll
total 0
drwxr-xr-x 2 root root 260 Aug 19 11:27 by-id
drwxr-xr-x 2 root root 140 Aug 19 11:27 by-path
drwxr-xr-x 2 root root 120 Aug 19 11:27 by-uuid

The by-id directory for instance includes symbolic names for the device files:

bzt@linux-akf6:/dev/disk> ll by-id/
total 0
lrwxrwxrwx 1 root root  9 Aug 19 11:27 ata-VBOX_CD-ROM_VB2-01700376 -> ../../sr0
lrwxrwxrwx 1 root root  9 Aug 19 11:27 ata-VBOX_HARDDISK_VB3ceba069-ef9ac38e -> ../../sda
lrwxrwxrwx 1 root root 10 Aug 19 11:27 ata-VBOX_HARDDISK_VB3ceba069-ef9ac38e-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 Aug 19 11:27 ata-VBOX_HARDDISK_VB3ceba069-ef9ac38e-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 Aug 19 11:27 ata-VBOX_HARDDISK_VB3ceba069-ef9ac38e-part3 -> ../../sda3
lrwxrwxrwx 1 root root 10 Aug 19 11:27 dm-name-cr_home -> ../../dm-0
lrwxrwxrwx 1 root root 10 Aug 19 11:27 dm-uuid-CRYPT-LUKS1-22b6b0f3ad0c433e855383ca2e64bef1-cr_home -> ../../dm-0
lrwxrwxrwx 1 root root  9 Aug 19 11:27 scsi-SATA_VBOX_HARDDISK_VB3ceba069-ef9ac38e -> ../../sda
lrwxrwxrwx 1 root root 10 Aug 19 11:27 scsi-SATA_VBOX_HARDDISK_VB3ceba069-ef9ac38e-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 Aug 19 11:27 scsi-SATA_VBOX_HARDDISK_VB3ceba069-ef9ac38e-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 Aug 19 11:27 scsi-SATA_VBOX_HARDDISK_VB3ceba069-ef9ac38e-part3 -> ../../sda3

Some of these mount points are fixed, meaning that the operating system automatically remounts them on system reboot. These mount points are recorded in the /etc/fstab file (file system table, a tab-separated table of the information needed to mount the mount points) and in the boot loader (because the boot loader has to know where to start the operating system from). The boot loader files are in /boot/grub2 if you are using GRUB2.

Now, some Linux distributions (including OpenSuSE 12.3) have chosen to generate these configuration files using the new, symbolic names for device files (found in /dev/disk/by-id) rather than the actual device file names (e.g. /dev/sda2). Which is usually no problem. Except when you are on a virtual computer which has been cloned and is using a virtual disk which has also been cloned. Because when you clone a disk, its symbolic name changes. But the configuration files are not magically updated during cloning to reflect this change.

The solution

The solution to this problem is to switch back to the device file names (because those are correct, even after cloning).

To make your Linux virtual machine with GRUB2 clone-ready, perform the following steps:

  1. Take a snapshot of your virtual machine.
  2. Become root on your machine.
  3. Examine the /etc/fstab file. Find all the symbolic names that occur in that file.
  4. Refer to the /dev/disk/by-id directory and examine the symlinks to figure out which device file is equivalent to which symbolic name.
  5. Use vi to edit the /etc/fstab file.
  6. Replace all symbolic names with the correct device file names.
  7. Save the new /etc/fstab file.
  8. Go to the /boot/grub2 directory.
  9. Make the same changes to the and grub.cfg files.
You should now be able to clone the machine and boot the clone and have it find your drives.

Encrypted partitions

There is one exception though: if you have encrypted partitions, they still will not work. This is because Linux uses some indirection in the file system table for crypted file systems. To get your encrypted partitions to work, you have to edit the /etc/crypttab file and make the same symbolic-for-device-file name substitutions there.

Cloning an OpenSuSE 12.3 virtual machine using GRUB2, VirtualBox and cryptfs