如何同时从磁盘映像挂载多个分区?

如何同时从磁盘映像挂载多个分区?

我在尝试着挂载根分区和启动分区树莓派图像:

mount -v -o offset="70254592" -t ext4 /mnt/X/raspbian-jessie.img /tmp/raspbian
mount -v -o offset="4194304" -t vfat /mnt/X/raspbian-jessie.img /tmp/boot

当 root 被挂载时,挂载 boot 会导致:

mount: /mnt/X/raspbian-jessie.img: overlapping loop device exists

如何在一个磁盘映像上同时挂载多个分区? (对于磁盘来说显然是可能的,为什么对于文件不行呢?)

答案1

您需要指定分区的长度以避免重叠。选项sizelimit,参见man mountman losetup

答案2

losetup 2.21 -P 选项

losetup -P -f --show my.img

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

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

缺点:这是最近的选项,Ubuntu 14.04 中不存在,在此之前只需使用 kpartx:https://unix.stackexchange.com/a/405639/32558

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

答案3

使用kpartx工具。它将映射映像分区,/dev/mapper您可以使用它直接挂载。

$ sudo kpartx -a disk.img
$ sudo mount -o loop /dev/mapper/loop0p2 /mnt

附言。完成后不要忘记删除映射:sudo kpartx -d disk.img

答案4

我想这里的其他答案都是正确的,但在我看来它们是简洁的- 或者走得远一点。losetup很棒,但对于一些刚刚开始的人来说可能会感到困惑。所以 - 这是我的答案:

由于OP没有开始他的问题,fdisk -lu <file.img>我将使用我自己的RPi作为例子。这是因为fdisk -lu <file.img>提供“号码”来完成该示例。

在我的圆周率上:

$ fdisk -lu ./back.img
Disk ./back.img: 2.89 GiB, 3099590656 bytes, 6053888 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00f24f4c

Device      Boot  Start     End Sectors  Size Id Type
./back.img1        2048  526335  524288  256M  c W95 FAT32 (LBA)
./back.img2      526336 6053887 5527552  2.6G 83 Linux

正如我们所看到的,有两 (2) 个分区,一个 FAT32(从 2048 到 526335)和一个 Linux/ ext4(从 526336 到 6053887)——或者两个分区 524,288 和 5,527,552部门(512 字节/扇区)分别。

当我尝试mount这两个分区时,我也遇到了“重叠”错误:

$ sudo mount -o loop,offset=1048576 ./back.img /mnt/loopy/boot
$ sudo mount -o loop,offset=269484032 ./back.img /mnt/loopy/root
mount: /mnt/loopy/root: overlapping loop device exists for /home/pi/back.img.

正如上面的答案所暗示的,解决方案确实是一个sizelimit选择,但至少就我而言,它有点微妙:

$ sudo umount /mnt/loopy/boot /mnt/loopy/root 
$ sudo mount -o loop,offset=1048576,sizelimit=268435456 ./back.img /mnt/loopy/boot 

# NOTE: sizelimit = 512 bytes/sector * 524288 sectors = 268435456 bytes 

$ sudo mount -o loop,offset=269484032,sizelimit=2830106624 ./back.img /mnt/loopy/root 

# NOTE: sizelimit = 512 bytes/sector * 5527552 sectors = 2830106624 bytes 

成功安装了两个分区后back.img,我现在可以进行所需的更改。我使用编辑器修改了/mnt/loopy/root/etc:hostnamehosts中的三个文件dhcpcd.conf。完成后,我卸载了两者并将修改后的back.img文件传输到我的 NAS:

$ sudo umount /mnt/loopy/root /mnt/loopy/boot 
$ rsync -avi ./back.img /mnt/SynologyNAS/rpi_share/raspberrypi3a 
sending incremental file list
>f.st...... back.img

sent 3,100,347,489 bytes  received 35 bytes  10,897,530.84 bytes/sec
total size is 3,099,590,656  speedup is 1.00 

# NOTE: don't use `cp` for this! 

最后 - 作为一切顺利的证明 - 我曾经Etcher“刻录”back.img到新的 SD 卡,然后用它启动我的新 RPi 3A+。

相关内容