Create a virtual hard drive volume within a file in Linux

If you are not familiar with the concept of virtual hard drive volumes, sometimes called file containers, they are basically regular looking files that can be used by your computer as if they were real hard drives. So for example you could have a file called MyDrive.img on your computer and with a few quick actions it would appear as though you had just plugged in an external USB stick or hard drive into your computer. It acts just like a normal, physical, drive but whenever you copy anything to that location the copied files are actually being written to the MyDrive.img file behind the scenes. This is not unlike the dmg files you would find on a Mac or even something akin to TrueCrypt file containers.

Why would I want this?

There are a number of reasons why you may be interested in creating virtual volumes. From adding additional swap space to your computer (i.e. something similar to a page file on Windows without needing to create a new hard drive partition) to creating portable virtual disk drives to back up files to, or even just doing it because this is Linux and it’s kind of a neat thing to do.

What are the steps to creating a file container?

The process seems a bit strange but it’s actually really straight forward.

  1. Create a new file to hold the virtual drive volume
      (Optional) Initialize it by filling it with data
  2. Format the volume
  3. Mount the volume and use it

Create a new file to hold the virtual drive volume

There are probably a million different ways to do this but I think the most simple way is to run the following command from a terminal:

fallocate -l <size> <file to create>

So let’s say you wanted to create a virtual volume in a file called MyDrive.img in the current directory with a size of 500MiB. You would simply run the following command:

fallocate -l 500M MyDrive.img

You may notice that this command finishes almost instantly. That’s because while the system created a 500MiB file it didn’t actually write 500MiB worth of data to the file.

This is where the optional step of ‘initializing’ the file comes into play. To be clear you do not need to do this step at all but it can be good practice if you want to clean out the contents of the allocated space. For instance if you wanted to prevent someone from easily noticing when you write data to that file you may pre-fill the space with random data to make it more difficult to see or you may simply want to zero out that part of the hard drive first.

Anyway if you choose to pre-fill the file with data the easiest method is to use the dd command. PLEASE BE CAREFUL – dd is often nicknamed disk destroyer because it will happily overwrite any data you tell it to, including the stuff you wanted to keep if you make a mistake typing the command!

To fill the file with all zeros simply run this command:

dd if=/dev/zero of=<your file> bs=1M count=<your file size in MiB>

So for the above file you would run:

dd if=/dev/zero of=MyDrive.img bs=1M count=500

If you want to fill it with random data instead just swap /dev/zero for /dev/urandom or /dev/random in the command:

dd if=/dev/urandom of=MyDrive.img bs=1M count=500

Format and mount the virtual volume

Next up we need to give the volume a filesystem. You can either do this via the command line or using a graphical tool. I’ll show you an example of both.

From the terminal you would run the appropriate mkfs command on the file. As an example this will format the file above using the ext3 filesystem:

mkfs -t ext3 MyDrive.img

You may get a warning that looks like this

MyDrive.img is not a block special device.
Proceed anyway? (y,n)

Simply type the letter ‘y’ and press Enter. With any luck you’ll see a bunch of text telling you exactly what happened and you now have a file that is formatted with ext3!

If you would rather do things the graphical way you could use a tool like Disks (gnome-disk-utility) to format the file.

From the menu in Disks, select Disks -> Attach Disk Image and browse to your newly created file (i.e. MyDrive.img).

Don't forget to uncheck the box!
Don’t forget to uncheck the box!

Be sure to uncheck “Set up read-only loop device”. If you leave this checked you won’t be able to format or write anything to the volume. Select the file and click Attach.

This will attach the file, as if it were a real hard drive, to your computer:

MyDriveAttached

Next we need to format the volume. Press the little button with two gears right below the attached volume and click Format. Make sure you do this for the correct ‘drive’ so that you don’t accidentally format your real hard drive!

Make sure you're formatting the correct drive!
Make sure you’re formatting the correct drive!

From this popup you can select the filesystem type and even name the drive. You may also use the “Erase” option to write zeros to the file if you wanted to do it here instead of via the terminal as shown previously. In the image above the settings will format the drive using the ext4 filesystem. Click Format, confirm the action and you’re done. Disks will format the file and even auto-mount it for you. You can now copy files to your mounted virtual drive. When you’re done simply eject the drive like normal or press the square Stop button in Disks. To use that same volume again in the future just re-attach the disk image using the steps above.

To mount the formatted file from the terminal you will need to first create a folder to mount it to. Let’s say we wanted to mount it to the folder /media/MyDrive. First create the folder there:

sudo mkdir /media/MyDrive

Next mount the file to the folder:

sudo mount -t auto -o loop MyDrive.img /media/MyDrive/

Now you can copy files to the drive just like before. When you’re finished unmount the volume by running this command:

sudo umount /media/MyDrive/

And there you have it. Now you know how to create virtual volume files that you can use for just about anything and easily move from computer to computer.

This post originally appeared on my personal website here.



7 Comments

  1. @beegii
    All advantages and limitations of standard file containers and LUKS partitions apply. There is likely some way to extend these in a l337 way but for the average user it may be easier to create a new larger volume and move the files from the smaller one to the larger one.

  2. @Tyler B
    Tnx Tyler B and I found one. Example increase 5G.
    1. unmount
    2. dd if=/dev/zero bs=1G count=5 >> MyDrive.img
    3. e2fsck -f MyDrive.img
    4. resize2fs MyDrive.img
    5. mount again
    Is it right one?

  3. beegii :

    @Tyler B
    Tnx Tyler B and I found one. Example increase 5G.
    1. unmount
    2. dd if=/dev/zero bs=1G count=5 >> MyDrive.img
    3. e2fsck -f MyDrive.img
    4. resize2fs MyDrive.img
    5. mount again
    Is it right one?

    I haven’t personally tried it but it seems like it could work.

  4. Thank you so much for sharing this! Believe it or not, this knowledge was crucial to solve a problem with my phone. It’d lost its imei one year ago and although I had a backup (it was ok but) it couldn’t be restored. Simply, it didn’t work.
    Long story short: I mounted this backup (EFS Explore) and a new one I did with a different method (dd). I compared them. “If only I could transfer the data from one to another…” and then this article came to my mind!
    “Let’s see…” and I tried to copy one file from the old backup to the new one… and surprisingly, it worked! Exactly as you described in your article.
    Thank goodness! Otherwise I would still be walking in circles because I’d never have thought it might be possible!
    I proceeded to finish the entire copy, then I restored this (modified) new backup in the phone and voila! It’s alive!
    Thx again!

3 Trackbacks / Pingbacks

  1. Create a virtual hard drive in a file | 0ddn1x: tricks with *nix
  2. Top 5 posts of 2017 – #1: Create a virtual hard drive volume within a file in Linux – The Linux Experiment
  3. The Linux Experiment Year in Review 2018 – The Linux Experiment

Leave a Reply

Your email address will not be published.


*