Mount VMWare disk partitions

This is helpful if you want VMWare Player to use a raw disk that you can later mount & manipulate from /dev/loop* in your host machine - even with partitions or LVM’s.

This will require you to compile & install a block device wrapper library cited in this how-to. You will have to consult the respective README & instructions for the two different libs cited. In this post I’m only explaining how to use the stand-alone block device wrapper.

I’ve tested this on VMWare Player v. 3.1.0 build-261024 & it should work with VMWare Workstation. However, I do not own a copy of VMWare Workstation but the block dev wrapper was written to work specifically with VMWare Workstation.

There are two block device wrappers for VMWare:

The original (and simpler, IMO) ioctl block device wrapper “vmware-bdwrapper” - simply builds a small set of libs that provide block device wrapping for VMWare, providing ioctl interfaces for loop devices that VMWare expects to find on the host OS. It can be downloaded from:
vmware-bdwrapper

The other ioctl b.d. wrapper is available at:
vmgbd: VMware generic block device patch. It applies binary patches to the VMWare executable files in /opt/vmware/workstation (or wherever /etc/vmware/locations indicates). Although more tightly integrated it relies on patching the VMWare installation & may be dependent on previous versions of VMWare Workstation. I can’t offer any guidance here, I haven’t tried this one.

You may prefer to log into a root shell account to do compile the source code, install the compiled machine binary & manipulate the loop device.

First… acquire the latest libvmware-bdwrapper tarball (see above).

Untar libvmware-bdwrapper-xxxx.tar.gz to an appropriate directory in your filesystem & go to that directory.

$ tar -xvzf vmware-bdwrapper-20060304-0.tar.gz
$ cd vmware-bdwrapper-20060304-0 
$ make
$ make install 

( if you get an error from “make” about libtools being absent (not installed) you’ll have to install libtools –

zypper install libtools

will do it… )

The instructions for vmware-bdwrapper suggest changing permissions for the loop device that’ll emulate the virtual harddrive.

$ chown root:users /dev/loop7 
$ chmod g+rw /dev/loop7
$ ls -al /dev/loop7

The library author also indicates that VMWare expects to see a /dev/sd* or /dev/hd* path for the raw harddrive it’s accessing:


$ mkdir /dev/sdz
# (or)
$ mkdir /dev/hdz
# (or)
$ mkdir /dev/sd-whatever-you-wanna-call-it

Within the /dev/sd* path, make a symlink to the actual /dev/loop(n) block device. This creates fully pathed /dev/sd* path for vmware’s sake.

In my example I’m going to use the 7th loop device /dev/loop7. Linux supports up to 250 loop devices, which can be created readily using the mknod command & removed using the unlink command. I will also use the /dev/sdz subdirectory as the folder for the symbolic link that VMWare will access directly.

(see bottom for instructions on how to create new loop block devices)

In my example I’m not going to create a new loop block device & will simply exploit the already stock (preinstalled) /dev/loop7, using a newly created subdirectory in the newly created /dev directory called “/dev/sdz” where I will create a symbolic link (symlink) to the actual block loop device /dev/loop7:


$ mkdir /dev/sdz
$ ln -s /dev/loop7 /dev/sdz/loopdev-ztest7
$ ls -al /dev/sdz/*
....]
lrwxrwxrwx  1 root root 10 2010-08-22 00:26 loopdev-ztest7 -> /dev/loop7
 

n.b.: /dev/loop7 & /dev/sdz*… *

And we need an actual disk image file for the loop device (in this case /dev/loop7). If we do not already have a disk image file handy, we can just make one, creating a sparse (null or empty) disk image. I’m going to put the file in /opt.


$ cd /opt
$ dd of=./loopdev-ztest07.img bs=1M count=0 seek=4000  if=/dev/zero

The above dd (diskdump) command is creating a sparse (null) file (of=./loopdev-ztest07.img) of about 4 gigabytes (seek=4000) but of ZERO (count=0) blocks of size 1 megabyte (1M), using /dev/zero as a source ( if=/dev/zero). Just like a VMWare virtual harddisk file (.vmdk) this file will only take up as much room on the filesystem as bytes actually reside within the file. At this point this files takes up no additional space on the filesystem.

Now we’re ready to set up the block device for use by VMWare Player.

check for existing loop devices using lo-setup (not lose-tup… ) :wink:

$ losetup -a   

( This will probably be null at first… )

set up the loop dev

$ losetup  /dev/sdz/loopdev-ztest07 /opt/loopdev-ztest07.img

check to see it’s there

$ losetup -a
/dev/loop7: [0811]:5152770 (/opt/loopdev-ztest07.img)
 

Yeedawg.

Right.

Now we can bring this virtual HDD loop device into VMWare Player by adding an existing “physical” harddrive as /dev/sdz/loopdev-ztest01 . To do this we have to start VMPlayer from the shell prompt, runing VMWare Player with the lib preloaded & pointing to the raw block loop device:

$ LD_PRELOAD=libvmware-bdwrapper.so.0 VMWARE_BDWRAPPER_DEVICES=/dev/sdz/loopdev-ztest01 vmplayer

I’ll assume you know what to do in VMWare Player at this point. At some point in setting up the Guest OS this harddisk will be partitioned and - if you use it as the main harddisk in the VMWare Guest - loaded up with an entire OS.

What’s next? After exiting the VMWare Player Guest we want to be able to access & manipulate the filesystem built by the VMWare Guest OS. Some care is required not to muck up the guest filesystem (accessing it from outside the Guest OS may/will force checks in the Guest OS in subsequent boot cycles)

From here we’ll need to treat our loop block dev differently, as it will now have actually disk partitions on it as well. Using the kpartx utility we can list the partitions in the block device & also provide them as individually mapped subdevices of loop7:



$ losetup -a
/dev/loop7: [0811]:5152770 (/opt/loopdev-ztest07.img)

$ kpartx -lv /dev/sdz/loopdev-ztest07
loopdev-ztest07p1 : 0 497664 /dev/sdz/loopdev-ztest07 2048
loopdev-ztest07p2 : 0 15880194 /dev/sdz/loopdev-ztest07 501758

# now map the actual partitions as subdevice in /dev/mapper
$ kpartx -av /dev/sdz/loopdev-ztest07
add map loopdev-ztest01p1 (253:0): 0 497664 linear /dev/sdz/loopdev-ztest07 2048
add map loopdev-ztest07p2 (253:1): 0 15880194 linear /dev/sdz/loopdev-ztest01 501758
$ ls /dev/mapper/*
....]
/dev/mapper/loopdev-ztest07p1 (partition 1 from the guest OS install)
/dev/mapper/loopdev-ztest07p2 (partition 2 from the guest OS install)

# FYI ... can also list the partitions directly from loop7 ...
kpartx -lv /dev/loop7   


mount the correct partition in /dev/mapper into an overmount dir

mkdir ./mnt1
mount -t ext2 /dev/mapper/loopdev-ztest01p1 ./mnt1

list the newly mounted dev

mount | grep -i “mnt1”

go there & play in the mounted loop dev filesystem

cd mnt1

reversing all the fun

cd ~
umount /dev/mapper/dev/mapper/loopdev-ztest01p1
kpartx -vd /dev/sdz/loopdev-ztest01
losetup -d /dev/sdz/loopdev-ztest01
losetup -a

Creating New Block Loop Devices:

$ ls -al /dev/loop*
brw-rw---- 1 root disk 7, **0** 2010-08-21 22:57 loop**0**
brw-rw---- 1 root disk 7, **1** 2010-08-21 22:57 loop**1**
brw-rw---- 1 root disk 7, **2** 2010-08-21 22:57 loop**2**
brw-rw---- 1 root disk 7, **3** 2010-08-21 22:57 loop**3**
brw-rw---- 1 root disk 7, **4** 2010-08-21 22:57 loop**4**
brw-rw---- 1 root disk 7, **5** 2010-08-21 22:57 loop**5**
brw-rw---- 1 root disk 7, **6** 2010-08-21 22:57 loop**6**
brw-rw---- 1 root disk 7, **7** 2010-08-21 22:57 loop**7**

$ mknod -m660 /dev/loop250 b *7* 250
$ chgrp users /dev/loop250
$ ls -al /dev/loop250
brw-rw---- 1 root users *7*, **250** 2010-08-22 00:01 loop**250**
# & remove the loop block device:
$ unlink /dev/loop250 


Note the *major*:**minor** numbers in creating the loop device. I looked at the existing major-minor number pattern already on my system, following the pattern *7*, **n** ... loop**(n)**. It may differ on other distros or unix systems, so it's best to check for the major number first & make sure you aren't duplicating an already existing minor number for any new loop dev you create.

Also note the permissions listing, that "b" precedes the permissions:
**b**rw-rw----
indicating a **b**lock device.

Errata:
All occurances of “loopdev-ztest01” should be “loopdev-ztest07”

The next-to-last section should read as follows:

Now we can actually MOUNT the blasted thing somewhere on our filesystem so we can play with the Guest OS’s root filesystem. Sounding a bit dangerous? Could be, so if you value what’s in your VMWare Guest OS, be really careful, do a backup of the .img file before monkeying around in it, et cetera & so on, so forth…


# mount the correct partition in /dev/mapper into an overmount dir
$ mkdir ./mnt1
$ mount -t ext2 /dev/mapper/loopdev-ztest07p1 ./mnt1
# list the newly mounted device
$ mount | grep -i "mnt1"
$ cd ./mnt1
$  do whatever & be careful doing it.... ]


And finally, when all done, reversing all the fun:


cd ~
umount /dev/mapper/dev/mapper/loopdev-ztest07p1
kpartx -vd /dev/sdz/loopdev-ztest07 
losetup -d /dev/sdz/loopdev-ztest07
losetup -a <should return nothing...>

Sorry for the errors. I inadvertently posted too soon, tried editing OL but got caught by the BBS limit on edits 10 minutes after initial post.

And for those already using logical disk volumes in their VM’s:

RedHat:
30.7. Accessing data from a guest disk image

Mounting LVM vmware disks | Callum Macdonald

Mount LVM-based volumes from loopback full disk images | /dev/rant

And for the very brave, the old way of mounting partitioned loopback devices, using cylinder/sector offsets (!) in the mount command:

guide:mount_loopback [Open Source ™ Guides & Tutorials]

( there’s no school like the old school… )

And finally, the best 'blog posting about mounting LVMs partitions off a loop block device:

Archive:FedoraXenQuickstartFC6 - FedoraProject

or it’s long lost twin …

Fedora Core 6 Xen Virtualization - Accessing data on a guest disk image