My Profile Photo


Using liberty-minded opensource tools, and using them well

Virtualizing an HDD

After my old-as-hell laptop decided to quit working, I was stuck with only a HDD remaining of the effort that I had taken to craft a build environment for my 'RESPIN' ISO. So I decided to virtualize it.

So I yanked the HDD with the 32-bit OS out of my old-as-hell laptop and figured the first thing I’d do was get the image onto Virtualizor (my resident KVM machine) I am loosely following Manuel Kiessling’s tutorial with a couple tweaks. 1

dd to the rescue

This in itself was the easiest part because I already had a powered HDD reader (sue me, I don’t know what they’re called. The ones you get when you pay for an external HDD. It’s just an HDD connected to a powered stand.) So I hooked the other end (the USB end) into the machine, and dd‘d the entire block device to a .raw file.

Yeah, I probably could’ve saved some space somehow, but I just wanted to get it working. Right now it’s at around 120GB, with most of that being unused space in the /home partition. Anyways, I have a big enough harddrive in Virtualizor so I figured I’d just go ahead and claim that space while it was still available (Planning big stuff coming up here soon).

Virt-install fail

So, in Kiessling’s tutorial, it says

If we could stop the server, this would actually be quite simple: shutdown the machine, boot from a linux rescue cd, and dd every single byte from /dev/sda into a raw image file.

Well…huh. Let’s skip 90% of the easy stuff (like harddisk layout) for now - but don’t worry, we’ll have to come back to it eventually. So skipping down, he recommends that once the .raw image is finished (after dd is done…) then we can try to boot it:

# virt-install \
    -n ghost \
    -r 2048 \
    --disk /var/lib/libvirt/images/ghost.raw,device=disk,bus=virtio,cache=none \
    --nonetworks \

I pared it down a bit - apparently --prompt is deprecated, I didn’t need any graphics with virt-manager on my workstation laptop, and the --os-varient was Debian Jessie, not RHEL5.4 - which turned out to be critical, but we’ll touch on that later. I also want to get around to defining a network, and getting the graphics to work, but once again, I just wanted a POC that I could make this work.

Alas, it didn’t. It hung at (paraphrasing) “setting up domain installation”, so I just figured it wasn’t going to work that way. So I read on.

The reason why I did everything following


In case the VM does not boot, one reason could be that its initrd does not have the virtio drivers and thus cannot access the virtual drive. In this case, you must build a new initrd.

I don’t have a mirror, but my face probably fell after reading that.

Fdisk and the letter ‘l’

Xathrya seems like they really know what they’re talking about2. They’ve got good explanations around the CS theory and the ways to go about getting things done using that knowledge.

However, they keep forgetting the switch -l. It took me a minute to remember why fdisk wasn’t actually showing me anything. I even tried cfdisk and was like “yep, there’s definitely something here.”

Anyways, once I got fdisk to show the partition layout of ghost.raw (which for some reason I had changed to ghost.img by that time - just a heads up) to show the partition layout of ghost.img and got the offset bytes.

Mounting the damn thing

Why did I need the offset bytes? To mount the damn thing.

Actually it wasn’t that bad. Once I converted the sectors that fdisk gave me to bytes (hint: multiply by 512) I was about to successfully mount the first partition (the root / partition - excluding /home) and then subsequently the fourth (/home) onto a mount point I made up (/mnt/images). Pretty much just as in the end of xathrya’s post.


Now, I need to chroot into the system. Since that OS was 32-bit and Virtualizor is a 64-bit machine, we are perfectly OK. Yes, really! Something was easy. Don’t drop your coffee or anything. Anyways…

However, (there’s always a “however”) after the chroot, I did a typical ls and got greeted with:

# ls
bash: ls: command not found


# pwd

# echo "hi"

# which ls

# echo $PATH

Oops…it’s not in our path:

# export PATH=$PATH:/bin

Yay…now I have commands again. Imagine being without ls for a moment. It was really scary guyz.

Always copy, never rm without a backup

So the original Kiessling tutorial started talking about building a new initrd. Which I thought I’d try, because I’ve done all of this up to now I might as well finish it. Unfortunately, he was working with RHEL and I’m on Debian - there are two different ways to remake the kernel there.

Long story short, I backed up the old initrd locally before removing it from the chroot like was explained. Then I found out that RHEL uses a mkinitrd script while Debian uses a mkinitramfs command. Hmmm.

The Debian Way

I hopped on the wiki3 (not the ArchWiki for once) and saw that I can just update the initramfs with the virtio kernel moduels by adding them to /etc/initramfs-tools/modules. The syntax was scathingly difficult though:


And the last thing from within the chroot that I had to do was update-initramfs -u


Just a little side note here, I did have a little trouble untangling myself from that chroot/mounting scheme that I had going on there. I don’t know where I got messed up, but I had to force the unmount by passing the -l switch (again with the ‘l’s!) for lazy unmounting, because nothing showed up with lsof | grep /dev/loop0 or any usage of fuser. At that point I was sweating bullets.


I won’t beat around the bush, it worked straight off the bat. It didn’t look like it worked, but I was able to connect to it with virt-manager and right now I still have virt-install ... running backgrounded as I’m afraid to lose it yet, I want to play around a little bit.

Once again, there’s still no network access, console access, or any real use to it (I had to break out my password manager to remember the password to the damn thing) but now I have my custom environment where I can continue the development of my custom ‘RESPIN’ ISO - coming soon to a store near you!


  • console access
  • Compress image
  • install on qcow2
  • network access
  • work on getting the yaml heading correct to be able to deal with footnotes