Virtual Drives

Table of Contents

Creating Virtual Drives using 'dd' and loopback devices 
virtual filesytsem 
virtual disk image 
Disk Images Under Linux 
Floppy Disk Images 
Hard Disk Images 

Creating Virtual Drives using 'dd' and loopback devices

virtual filesytsem 

A virtual filesystem is filesystem that exists in a file, which in turn exists on a physical disk. There's a lot of great things you can do with virtual file systems; the reason I was messing with them was to configure a virtual machine on a linux host. Other uses include encrypting filesystems without encrypting entire disks; Mac OS X's File Vault encrypts users home directories this way. Maybe you went ahead and made yourself one giant partition and then realized for one reason or another that you want multiple partitions! Virtual filesystems can help (to some extent) with that as well.

So how do you make a virtual file system? Easy. The first thing you need to do is make a file for the filesystem to live in. This is where 'dd' starts to come in. Consider, for example, the following command:

dd if=/dev/zero of=~/myFileSystem.img bs=1024 count=1048576

This command will read 1,048,576 blocks from /dev/zero and write them to ~/myFileSystem.img; each block is 1024 bytes, resulting in a 1 gigabyte file containing all zeroes. The actual values that you use for the blocksize (bs) and count aren't really important, the key is to get your math right: bs * count = imageSize.

So now you have your file; great. It's time to make a file system! this part is even easier… we'll create an EXT2 filesystem, using the following command:

mke2fs myFileSystem.img

You may notice a warning prompt, saying that myFileSystem.img is not a block device, would you like to proceed? We'll get to that in just a second, for now, go ahead and say yes. Everything should go smooth, it'll look just as if you'd created a filesystem on an actual disk drive. You now have a virtual file system! The only thing left to do is mount your filesystem so you can access it…

mkdir /mnt/virtualmount -o loop ~/myFileSystem.img /mnt/virtual

Now any file you put into /mnt/virtual is actually being put directly into myFileSystem.img! Wasn't that easy?

virtual disk image 

Fantastic. Now that you know how to make a virtual filesytsem, why not make a while virtual disk image? What's the difference you ask? A disk image is going to have a partition table that defines some number of partitions, and each partition contains its own filesystem; so a virtual filesystem is essentially a \"virtual partition\" of a virtual disk image; the virtual disk image contains multiple virtual filesystems, and a virtual partition table that describes where the bounds of each partition are.

Creating a virtual disk image starts out the same; the first thing you need is a big empty file, just you created above. This time, though, instead of making a file system, we'll want to partition the file using fdisk. To make things a little nicer though, we're going to throw loopback devices into the mix. You should make sure you have loopback device support enabled in your kernel (most distributions do by default; but if you're a kernel compiling linux junky, you might wanna check :)). So we'll create a big file, and attach it to a loopback device, as follows:

dd if=/dev/zero of=~/myDisk.img bs=1024 count=1048576
losetup /dev/loop0 ~/myDisk.img

By attaching the disk image to the loopback device, we can use /dev/loop0 the same way we would use ~/myDisk.img; the main difference is that /dev/loop0 is a what's known as a \"block device\". You'd have to ask someone with more experience than I've got what precisely this gets you, but what I do know is that the filesystem utilities work better with block devices than they do with the flat files. Plus, it's fun.

So good, we've got a big empty file attached to a loopback device (/dev/loop0)… now it's time to create partitions in the disk image. To do this, we'll run fdisk on our loopback device:

fdisk /dev/loop0

Lets create three partitions… if you're following this, you should already be familiar with fdisk, so go ahead and create the following:

Device Boot      Start         End      Blocks   Id  System/dev/loop0p1               1          17      136521   83  Linux/dev/loop0p2              18          80      506047+  82  Linux swap/dev/loop0p3              81         130      401625   83  Linux

Once you've made your partitions, write your changes and quit fdisk. What we'll need to do next is create filesystems on each partition. Remember how easy that was back with Virtual Filesystems? Not quite so much anymore…

Not to panic though… the trouble is that \"mkfs\" can't \"reach into\" our virtual disk image and make a filesystem just on individual partition. Infact, if you try, you'll probably wind up wiping our your virtual disk image and having to rerun fdisk :). So what to do… what to do?? Loopback devices to the rescue. What we'll do is attach a loopback device to the myDisk.img file at the specific offsets where each partition begins.

It's helpful then to look at the partitions in terms of blocks. Execute the following command:

fdisk -ul /dev/loop0

should look (hopefully exactly) like this:

Disk /dev/loop0: 1073 MB, 1073741824 bytes255 heads, 63 sectors/track, 130 cylinders, total 2097152 sectorsUnits = sectors of 1 * 512 = 512 bytes
Device Boot Start End Blocks Id System/dev/loop0p1 63 273104 136521 83 Linux/dev/loop0p2 273105 1285199 506047+ 82 Linux swap/dev/loop0p3 1285200 2088449 401625 83 Linux

These numbers are important for the math… we'll use the losetup command like we did before, only this time we'll reach in specifically to the start of each of the three partitions. losetup takes offsets as the number of bytes to skip at the beginning of the file. The output from fdisk -ul /dev/loop0 shows us that the first partition starts at block 63, and that each block is 512 bytes. So partition 1 starts at byte 32,256

losetup -o 32256 /dev/loop1 /dev/loop0

That command reaches 32,256 bytes into /dev/loop0 and mounts it at /dev/loop1. Remember that since /dev/loop0 is attached the myDisk.img file, this is the same as reaching 32,256 bytes into that file… follow? Ok, good. Same logic for partitions 2 and 3:

losetup -o 139829760 /dev/loop2 /dev/loop0losetup -o 658022400 /dev/loop3 /dev/loop0

So now we have four loopback devices set up; /dev/loop0 is attached to the myDisk.img file. /dev/loop1 is the first partition of the virtual disk represented by /dev/loop0; /dev/loop2 is the 2'nd, and /dev/loop3 is the 3'rd.

Now it's finally time to make those file systems! This is now just as easy as making a regular filesystem, since that's all we're doing. Remember, mkfs doesn't know the device isn't a physical device! We'll make three kinds of file systems, an ext2 file system for partition 1, a swap filesystem for partition 2, and an XFS fileystem for partition 3:

mkfs /dev/loop1mkswap /dev/loop2mkfs.xfs /dev/loop3

Since loop1, loop2, and loop3 are tied directly to loop0, and loop0 is ~/myDisk.img, everything that we just did to loop1, loop2, and loop3 affected myDisk.img directly! We can now mount /dev/loop3, for instance, on /mnt/virtual as an XFS file system, and use it as a regular file system!

So I hope you found that helpful… you can do some pretty neat things with virtual file systems and virtual disk images; and loopback devices make a world of difference for making things go smooth.