Linux-如何在一个文件中格式化多个文件系统?


9

我需要用两个空文件系统创建一个磁盘映像。我已经使用创建了它

dd if=/dev/zero of=./disk.img bs=1MiB count=1024

接下来,我使用fdisk disk.img;创建了2个主分区。一个是FAT32,另一个是EXT3。现在,我必须格式化两个分区,以创建要挂载为的文件系统-o loop devices。但是我不明白如何格式化它们?我不能mkfs.vfat在上使用disk.img。所以我很困惑。

解决方案:感谢@ pjc50的回答,我找到了一个非常简单的解决方案:

sudo aptitude install multipath-tools
sudo kpartx -a disk.img   #it maps (mounts) found partitions to /dev/mapper/loop...
sudo mkfs.vfat -F 32 -n boot /dev/mapper/loop0p1
sudo mkfs.ext3 -L rootfs /dev/mapper/loop0p2

该解决方案的缺点是需要超级用户权限。


我怀疑所有这些程序都将能够使用文件中的分区。您可以在单独的文件中创建两个文件系统,然后将它们合并到带有dd的大文件中吗?
golimar 2011年

@golimar:但我将需要在这种驱动器上使用MBR,我不知道如何合并单独创建为不同文件的不同文件系统
psihodelia 2011年

您可以使用您说的原始文件的MBR。dd允许使用'size'和'skip'命令进行偏移。您需要找到精确的偏移量,然后用两个较小的文件覆盖大文件的一部分
golimar 2011年

如果我在这里太天真,请原谅我,但为什么不只使用两个单独的文件呢?
加勒特

Answers:


9

看来您可以使用kpartx工具:http ://robert.penz.name/73/kpartx-a-tool-for-mounting-partitions-within-an-image-file/

Kpartx可用于为任何分区块设备的分区设置设备映射。它是Linux多路径工具的一部分。使用kpartx -l映像文件,您可以大致了解映像文件中的分区,而使用kpartx -a映像文件,则可以通过/ dev / mapper / loop0pX访问分区(X是分区号)。您现在可以使用mount / dev / mapper / loop0pX / mnt / -o loop,ro来安装它。卸载后,可以使用kpartx -d imagefile断开映射器设备的连接。

但是,该解决方案的缺点是需要超级用户权限。
psihodelia 2011年

1
我怀疑是否存在不需要超级用户权限的解决方案!也就是说,如果没有超级用户事先设置的特定机制(例如通过sudo),我不希望普通用户能够执行这种操作
pjc50 2011年

2
@ pjc50:可以在没有超级用户权限的情况下执行此操作:必须先将每个分区创建为单独的文件,然后手动创建磁盘映像,然后在将分区表创建到磁盘映像之后将分区复制到磁盘映像。
Mikko Rantalainen

1
完全是@MikkoRantalainen。这是一个最小的可运行示例:superuser.com/a/1367534/128124
Ciro Santilli冠状病毒审查六四事件法轮功

7

为此,您可以先将分区挂载到以/dev/loop?使用losetup,并使用-o选项指定适当的分区偏移量。可以根据fdisk -l disk.imgstart_sector * sector_size)的输出来计算偏移量。

例如:

losetup -o32256 /dev/loop1 ./disk.img   # mount first partition

挂载后,您可以使用mkfs.*以下命令继续格式化分区:

mkfs.vfat -F32 /dev/loop1

有关更多详细信息和示例,请参阅以下文章:


好吧,它不起作用:(
psihodelia 2011年

@psihodelia应该。如果这样做,结果如何?
丹尼尔·贝克

它怎么不起作用?收到错误消息吗?哪一步失败?
肖恩·

$ sudo mkfs.vfat -F32 / dev / loop1 mkfs.vfat 3.0.9(2010年1月31日),循环设备与软盘大小不匹配,使用默认的高清参数
psihodelia 2011年

1
如果在调用时指定块大小,可能会有所帮助mkfs.vfat。请参阅我提供的第一个链接。在文章中还提到过,软盘警告是可以预料的,可以忽略
Shawn Chin

1

我会考虑以下工具:

  • 用一个磁盘在Virtualbox中创建一个新的VM,通常是 /dev/sda
  • 使用GParted Live CD引导到VM
  • 根据需要对VM中的磁盘进行分区和格式化(2个分区,不同的文件系统等)
  • 然后用于dd导出/dev/sda到文件

凭有根据的猜测,大约需要15分钟。


聪明的棘手解决方案:)但是,我认为它不会少于15分钟。顺便说一下,它很难实现自动化,因为它要求用户使用图形界面(因此,不可能编写脚本=不是Unix方式)。
psihodelia 2011年

它不会花很长时间:-),因为虚拟磁盘很小,并且没有完成操作系统安装。最长的部分是GParted引导时间。
karatedog

1

最小可运行sfdisk+ mke2fs示例不带sudo

在此示例中,我们将创建不包含sudosetsuid的映像文件,该映像文件包含两个ext2分区,每个分区都填充有主机目录中的文件。

然后,我们将sudo losetup仅使用安装分区来测试Linux内核是否可以实际读取它们,如以下所述:https : //stackoverflow.com/questions/1419489/how-to-mount-one-partition-from-an-image包含多个分区的文件/ 39675265#39675265

有关更多详细信息,请参见:

这个例子:

#!/usr/bin/env bash

# Input params.
root_dir_1=root1
root_dir_2=root2
partition_file_1=part1.ext2
partition_file_2=part2.ext2
partition_size_1_megs=32
partition_size_2_megs=32
img_file=img.img
block_size=512

# Calculated params.
mega="$(echo '2^20' | bc)"
partition_size_1=$(($partition_size_1_megs * $mega))
partition_size_2=$(($partition_size_2_megs * $mega))

# Create a test directory to convert to ext2.
mkdir -p "$root_dir_1"
echo content-1 > "${root_dir_1}/file-1"
mkdir -p "$root_dir_2"
echo content-2 > "${root_dir_2}/file-2"

# Create the 2 raw ext2 images.
rm -f "$partition_file_1"
mke2fs \
  -d "$root_dir_1" \
  -r 1 \
  -N 0 \
  -m 5 \
  -L '' \
  -O ^64bit \
  "$partition_file_1" \
  "${partition_size_1_megs}M" \
;
rm -f "$partition_file_2"
mke2fs \
  -d "$root_dir_2" \
  -r 1 \
  -N 0 \
  -m 5 \
  -L '' \
  -O ^64bit \
  "$partition_file_2" \
  "${partition_size_2_megs}M" \
;

# Default offset according to
part_table_offset=$((2**20))
cur_offset=0
bs=1024
dd if=/dev/zero of="$img_file" bs="$bs" count=$((($part_table_offset + $partition_size_1 + $partition_size_2)/$bs)) skip="$(($cur_offset/$bs))"
printf "
type=83, size=$(($partition_size_1/$block_size))
type=83, size=$(($partition_size_2/$block_size))
" | sfdisk "$img_file"
cur_offset=$(($cur_offset + $part_table_offset))
# TODO: can we prevent this and use mke2fs directly on the image at an offset?
# Tried -E offset= but could not get it to work.
dd if="$partition_file_1" of="$img_file" bs="$bs" seek="$(($cur_offset/$bs))"
cur_offset=$(($cur_offset + $partition_size_1))
rm "$partition_file_1"
dd if="$partition_file_2" of="$img_file" bs="$bs" seek="$(($cur_offset/$bs))"
cur_offset=$(($cur_offset + $partition_size_2))
rm "$partition_file_2"

# Test the ext2 by mounting it with sudo.
# sudo is only used for testing, the image is completely ready at this point.

# losetup automation functions from:
# /programming/1419489/how-to-mount-one-partition-from-an-image-file-that-contains-multiple-partitions/39675265#39675265
loop-mount-partitions() (
  set -e
  img="$1"
  dev="$(sudo losetup --show -f -P "$img")"
  echo "$dev" | sed -E 's/.*[^[:digit:]]([[:digit:]]+$)/\1/g'
  for part in "${dev}p"*; do
    if [ "$part" = "${dev}p*" ]; then
      # Single partition image.
      part="${dev}"
    fi
    dst="/mnt/$(basename "$part")"
    echo "$dst" 1>&2
    sudo mkdir -p "$dst"
    sudo mount "$part" "$dst"
  done
)
loop-unmount-partitions() (
  set -e
  for loop_id in "$@"; do
    dev="/dev/loop${loop_id}"
    for part in "${dev}p"*; do
      if [ "$part" = "${dev}p*" ]; then
        part="${dev}"
      fi
      dst="/mnt/$(basename "$part")"
      sudo umount "$dst"
    done
    sudo losetup -d "$dev"
  done
)

loop_id="$(loop-mount-partitions "$img_file")"
sudo cmp /mnt/loop0p1/file-1 "${root_dir_1}/file-1"
sudo cmp /mnt/loop0p2/file-2 "${root_dir_2}/file-2"
loop-unmount-partitions "$loop_id"

在Ubuntu 18.04上测试。GitHub上游

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.