리눅스-하나의 파일에서 여러 파일 시스템을 포맷하는 방법?


9

두 개의 빈 파일 시스템으로 디스크 이미지를 만들어야합니다. 나는 그것을 사용하여 그것을 만들었다

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

다음으로 fdisk disk.img;을 사용하여 2 개의 기본 파티션을 만들었습니다 . 하나는 FAT32이고 다른 하나는 EXT3입니다. 이제로 마운트 할 파일 시스템을 만들려면 두 파티션을 모두 포맷해야합니다 -o loop devices. 그러나 형식을 지정하는 방법을 이해할 수 없습니까? 내가 사용할 수 없습니다 mkfs.vfatdisk.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

@golimar :하지만 그런 드라이브에는 MBR이 필요하지만, 별개의 파일로 개별적으로 생성 된 다른 파일 시스템을 병합하는 방법을 모르겠습니다
psihodelia

말한 원본 파일의 MBR을 사용할 수 있습니다. dd는 'size'및 'skip'명령으로 오프셋을 허용합니다. 정확한 오프셋을 찾은 다음 큰 파일의 일부를 두 개의 작은 파일로 덮어
써야

내가 순진한 경우 용서하지만 왜 두 개의 별도 파일을 사용하지 않습니까?
개렛

답변:


9

다음과 같이 kpartx 도구를 사용할 수 있습니다. http://robert.penz.name/73/kpartx-a-tool-for-mounting-partitions-within-an-image-file/

Kpartx는 파티션 된 블록 장치의 파티션에 대한 장치 매핑을 설정하는 데 사용할 수 있습니다. Linux multipath-tools의 일부입니다. kpartx -l imagefile을 사용하면 이미지 파일의 파티션에 대한 개요를 얻을 수 있고 kpartx -a imagefile을 사용하면 / dev / mapper / loop0pX (X는 파티션 수)를 통해 파티션에 액세스 할 수 있습니다. mount / dev / mapper / loop0pX / mnt / -o loop, ro로 마운트 할 수 있습니다. 마운트 해제 후 kpartx -d imagefile을 사용하여 매퍼 장치의 연결을 끊을 수 있습니다.

그러나이 솔루션의 단점은 수퍼 유저 권한의 요구 사항입니다.
psihodelia

1
수퍼 유저 권한이 필요없는 솔루션이 존재하는지 의심합니다! 즉, 일반 사용자가 수퍼 유저가 미리 설정 한 특정 메커니즘없이 (예 : sudo를 통해) 수행 할 수없는 일종의 작업입니다.
pjc50

2
@ pjc50 : 수퍼 유저 권한없이이 작업을 수행 할 수 있습니다. 먼저 각 파티션을 별도의 파일로 생성 한 다음 수동으로 디스크 이미지를 생성하고 파티션 테이블을 디스크 이미지에 생성 한 후 디스크 이미지에 파티션을 복사해야합니다.
Mikko Rantalainen

1
@MikkoRantalainen 정확하게. 최소 실행 가능한 예는 다음과 같습니다. superuser.com/a/1367534/128124
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

7

먼저 파티션에 적합한 오프셋을 지정하는 옵션을 /dev/loop?사용 하여 파티션을 마운트 losetup하면 -o됩니다. fdisk -l disk.img( start_sector * sector_size) 의 출력을 기반으로 오프셋을 계산할 수 있습니다 .

예를 들면 다음과 같습니다.

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

마운트되면 다음을 사용하여 파티션 포맷을 진행할 수 있습니다 mkfs.*.

mkfs.vfat -F32 /dev/loop1

자세한 내용과 예는 다음 기사를 참조하십시오.


음, :( 작동하지 않습니다
psihodelia

@psihodelia 그래야한다. 이렇게하면 결과는 어떻습니까?
Daniel Beck

어떻게 작동하지 않습니까? 오류가 있습니까? 어느 단계가 실패합니까?
Shawn Chin

$ sudo를 mkfs.vfat -F32는 / dev / loop1은 mkfs.vfat 3.0.9 (2010년 1월 31일) 기본의 HD PARAMS를 사용하여 플로피 크기와 일치하지 않는 루프 장치
psihodelia

1
호출 할 때 블록 크기를 지정하면 도움이 될 수 있습니다 mkfs.vfat. 내가 제공 한 첫 번째 링크를 참조하십시오. 또한이 기사에서 언급 한 플로피 경고가 예상되며 무시할 수 있습니다
Shawn Chin

1

내가 생각한 도구를 사용합니다.

  • 하나의 디스크로 Virtualbox에 새 VM을 만듭니다. /dev/sda
  • GParted Live CD를 사용하여 VM으로 부팅
  • VM의 디스크를 필요에 따라 분할하고 포맷합니다 (2 개의 파티션, 다른 파일 시스템 등).
  • 그런 다음 파일 dd로 내보내는 /dev/sda데 사용

교육받은 추측으로는 약 15 분이 걸립니다.


똑똑한 까다로운 솔루션 :) 그러나 15 분 미만이 걸리지 않는다고 생각합니다. 그런데 그래픽 인터페이스에 사용자가 필요하기 때문에 자동화하기가 어렵습니다 (따라서 유닉스 방식이 아닙니다).
psihodelia

가상 디스크가 작고 OS 설치가 완료되지 않기 때문에 시간이 오래 걸리지 않습니다. 가장 긴 부분은 GParted 부팅 시간입니다.
karatedog December

1

최소 실행 가능 sfdisk+ mke2fs예 미포함sudo

이 예에서는 sudoor 없이 setsuid, 호스트 디렉토리의 파일로 각각 채워진 두 개의 ext2 파티션을 포함하는 이미지 파일을 작성합니다.

그런 다음 sudo losetup파티션을 마운트하여 Linux 커널이 실제로 읽을 수 있는지 테스트하기 위해 /programming/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"

우분투 18.04에서 테스트되었습니다. GitHub의 상류 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.