如何从整个磁盘映像文件中读取一个文件系统?

如何从整个磁盘映像文件中读取一个文件系统?

我运行了这些命令:

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

当我尝试安装分区时,我收到以下投诉:

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

现在我知道虚拟机有一个 ext4 分区。我做错了什么?

答案1

您的映像是磁盘映像,而不是文件系统映像。文件系统位于该映像内的分区上(除非您做了一些非常不寻常的事情)。您可以通过运行file Debian.raw和 来确认这一点fdisk -l Debian.raw

访问此分区的最简单方法是将其与循环设备关联。如果可以的话,请确保您的loop驱动程序支持并加载了该max_parts选项;你可能需要运行rmmod loop; modprobe loop max_part=63。然后将磁盘映像与循环设备关联起来,瞧:

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

如果您无法让循环驱动程序使用分区,则需要找出磁盘映像中分区的偏移量。运行fdisk -lu Debian.raw以列出分区并找出其起始扇区 S(一个扇区为 512 字节)。然后告诉losetup您希望循环设备从此偏移量启动:

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

如果要将分区从 VM 映像复制到系统,请按上述方式确定其起始 ( $S) 和结束 ( $E) 偏移量。fdisk -lu然后只复制分区:

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

(如果源和目标不在同一磁盘上,则不必理会dd,只需将tail的输出重定向到/dev/sda5。如果它们在同一磁盘上,则dd使用较大的bs参数会快得多。)

答案2

losetup 2.21 -P 选项

losetup -P -f --show my.img

/dev/loopXpY每个分区创建一个。

优点:许多发行版中都预装了可执行文件(util-linux 软件包)。

缺点:这是最近的选项,Ubuntu 14.04 中不存在。

losetup -P自动化

用法:

$ 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

来源:

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"
)

克帕特克斯

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

输出:

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

loop0p1第一个分区在哪里,所以我们可以这样做:

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

此方法的优点:适用于 Ubuntu 14.04,无需重新启动。

相关内容