8

I ran these commands:

VBoxManage clonehd d6b9f0a5-98df-48ca-83c8-91a0809ec349 --format RAW Debian.raw
sudo dd if=~/.VirtualBox/HardDisks/Debian.raw of=/dev/sda5

When I try to mount the partition, I get this complaint:

EXT4-fs (sda5): VFS: Can't find ext4 filesystem

Now I know that the VM had an ext4 partition. What did I do wrong?

Ciro Santilli OurBigBook.com
  • 18,092
  • 4
  • 117
  • 102
tshepang
  • 65,642
  • @ciro the first link you posted is a link to this post itself. Can you explain what is the usefulness of that in addition to wasting time of anyone clicking on that? – Anthon Sep 12 '15 at 13:35
  • @ciro If those three include selfreferences as well, you should delete those as well. – Anthon Sep 12 '15 at 17:51

2 Answers2

8

Your image is a disk image, not a filesystem image. The filesystem is on a partition inside that image (unless you did something really unusual). You can confirm this by running file Debian.raw and fdisk -l Debian.raw.

The easiest way to access this partition is to associate it with a loop device. If you can, make sure your loop driver supports and is loaded with the max_parts option; you may need to run rmmod loop; modprobe loop max_part=63. Then associate the disk image with a loop device, and voilà:

losetup -fs Debian.raw     # prints /dev/loop0 (or some other number)
mount /dev/loop0p1 /mnt    # 0 as above, 1 is the partition number

If you can't get the loop driver to use partitions, you need to find out the offset of the partition in the disk image. Run fdisk -lu Debian.raw to list the partitions and find out its starting sector S (a sector is 512 bytes). Then tell losetup you want the loop device to start at this offset:

fdisk -lu Debian.raw  # note starting sector $S
losetup -fs -o $(($S * 512)) Debian.raw
mount /dev/loop0 /mnt  # /dev/loop0 or whatever losetup prints

If you want to copy the partition from the VM image to your system, determine its starting ($S) and ending ($E) offsets with fdisk -lu as above. Then copy just the partition:

<Debian.raw tail -c +$((512*$S)) | dd of=/dev/sda5 bs=4M

(If the source and the destination are not on the same disk, don't bother with dd, just redirect tail's output to /dev/sda5. If they are on the same disk, dd with a large bs parameter is a lot faster.)

  • I'm attempting this exact procedure, and I've gotten the loop mount to work, but after using tail and dd, mount still cannot find a filesystem on the raw device. any ideas? – TREE May 01 '11 at 13:34
  • @TREE: Did you use the loop driver's partition support (/dev/loop0p1), or a user-specified offset (losetup -o)? What is the output of <Debian.raw file -, of <Debian.raw tail -c +$((512*s)) | file -, or file - on any relevant intermediate stage? – Gilles 'SO- stop being evil' May 01 '11 at 13:48
  • On Ubuntu 14.04, proc is a built-in module, so rmmod fails. Editing GRUB_CMDLINE_LINUX on /etc/default/grub works: http://unix.stackexchange.com/a/87189/32558 – Ciro Santilli OurBigBook.com Sep 12 '15 at 10:49
  • Excellent answer, helped me to mount a raspberry pi raspbian image https://www.raspberrypi.org/downloads/raspbian/ – aseq Nov 19 '15 at 01:23
2

losetup 2.21 -P option

losetup -P -f --show my.img

Creates one /dev/loopXpY per partition.

Advantage: executable pre-installed in many distros (util-linux package).

Disadvantage: quite recent option, not present in Ubuntu 14.04.

losetup -P automation

Usage:

$ los my.img
/dev/loop0
/mnt/loop0p1
/mnt/loop0p2

$ ls /mnt/loop0p1
/whatever
/files
/youhave
/there

$ sudo losetup -l
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE                                                                                      DIO
/dev/loop1         0      0         0  0 /full/path/to/my.img

$ # Cleanup.
$ losd 0
$ ls /mnt/loop0p1
$ ls /dev | grep loop0
loop0

Source:

los() (
  img="$1"
  dev="$(sudo losetup --show -f -P "$img")"
  echo "$dev"
  for part in "$dev"?*; do
    if [ "$part" = "${dev}p*" ]; then
      part="${dev}"
    fi
    dst="/mnt/$(basename "$part")"
    echo "$dst"
    sudo mkdir -p "$dst"
    sudo mount "$part" "$dst"
  done
)
losd() (
  dev="/dev/loop$1"
  for part in "$dev"?*; do
    if [ "$part" = "${dev}p*" ]; then
      part="${dev}"
    fi
    dst="/mnt/$(basename "$part")"
    sudo umount "$dst"
  done
  sudo losetup -d "$dev"
)

kpartx

sudo apt-get install kpartx
losetup -fs my.raw
sudo kpartx -a my.img
ls /dev/mapper

Output:

/dev/mapper/loop0
/dev/mapper/loop0p1

where loop0p1 is the first partition, so we can do:

mkdir -p d
sudo mount /dev/mapper/loop0p1 d

Advantage of this method: works on Ubuntu 14.04 without rebooting.

Ciro Santilli OurBigBook.com
  • 18,092
  • 4
  • 117
  • 102