Linux - wie formatiere ich mehrere Dateisysteme in einer Datei?


9

Ich muss ein Disk-Image mit zwei leeren Dateisystemen erstellen. Ich habe es mit erstellt

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

Als nächstes habe ich 2 primäre Partitionen mit erstellt fdisk disk.img; einer ist FAT32 und der andere ist EXT3. Jetzt muss ich beide Partitionen formatieren, um Dateisysteme zu erstellen, als die gemountet werden sollen -o loop devices. Aber ich kann nicht verstehen, wie man sie formatiert? Ich kann nicht verwenden , mkfs.vfatauf disk.img. Ich bin also total verwirrt.

LÖSUNG: Dank der Antwort von @ pjc50 habe ich eine sehr einfache Lösung gefunden:

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

Ein Nachteil dieser Lösung ist das Erfordernis von Superuser-Rechten.


Ich bezweifle, dass all diese Programme Partitionen in einer Datei verwenden können. Können Sie die beiden Dateisysteme in separaten Dateien erstellen und sie dann in einer großen Datei mit dd zusammenführen?
Golimar

@ Golimar: aber ich werde MBR auf einem solchen Laufwerk benötigen, ich weiß nicht, wie es möglich ist, verschiedene Dateisysteme, die separat als unterschiedliche Dateien erstellt wurden, zusammenzuführen
psihodelia

Sie können den MBR der Originaldatei verwenden, die Sie angegeben haben. dd erlaubt Offsets mit den Befehlen 'size' und 'skip'. Sie müssten die genauen Offsets finden und dann einen Teil der großen Datei mit den beiden kleineren überschreiben
Golimar

Verzeihen Sie mir, wenn ich hier naiv bin, aber warum nicht einfach zwei separate Dateien verwenden?
Garrett

Antworten:


9

Anscheinend können Sie die kpartx-Tools verwenden: http://robert.penz.name/73/kpartx-a-tool-for-mounting-partitions-within-an-image-file/

Mit Kpartx können Gerätezuordnungen für die Partitionen eines partitionierten Blockgeräts eingerichtet werden. Es ist Teil der Linux Multipath-Tools. Mit kpartx -l imagefile erhalten Sie einen Überblick über die Partitionen in der Image-Datei und mit kpartx -a imagefile können Sie auf die Partitionen über / dev / mapper / loop0pX zugreifen (X ist die Nummer der Partition). Sie können es jetzt mit mount / dev / mapper / loop0pX / mnt / -o loop, ro mounten. Nach dem Aufheben der Bereitstellung können Sie die Mapper-Geräte mit der kpartx -d-Image-Datei trennen.

Ein Nachteil dieser Lösung ist jedoch das Erfordernis von Superuser-Rechten.
Psihodelia

1
Ich bezweifle, dass es eine Lösung gibt, die keine Superuser-Rechte erfordert! Das heißt, dies ist die Art von Operation, von der ich nicht erwarte, dass normale Benutzer auf einen bestimmten Mechanismus verzichten können, den der
Superuser

2
@ pjc50: Dies ist ohne Superuser-Rechte möglich: Zuerst muss jede Partition als separate Datei erstellt werden, dann muss das Disk-Image manuell erstellt und die Partitionen auf das Disk-Image kopiert werden, nachdem eine Partitionstabelle auf das Disk-Image erstellt wurde.
Mikko Rantalainen

1
@ MikkoRantalainen genau. Hier ist ein minimales lauffähiges Beispiel: superuser.com/a/1367534/128124
Ciro Santilli 法轮功 病毒 审查 六四 六四

7

Sie können dies tun , indem zuerst die Partitionen Montag /dev/loop?mit losetupder -oOption , um ein geeignet , um Ihre Partition Offset angeben. Der Offset kann basierend auf der Ausgabe von fdisk -l disk.img( start_sector * sector_size) berechnet werden .

Zum Beispiel:

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

Nach dem Mounten können Sie die Partition folgendermaßen formatieren mkfs.*:

mkfs.vfat -F32 /dev/loop1

Weitere Details und Beispiele finden Sie in den folgenden Artikeln:


Nun, es funktioniert nicht :(
Psihodelia

@psihodelia Es sollte. Was ist das Ergebnis, wenn Sie dies tun?
Daniel Beck

Wie funktioniert es nicht? Erhalten Sie einen Fehler? Welcher Schritt schlägt fehl?
Shawn Chin

$ sudo mkfs.vfat -F32 / dev / loop1 mkfs.vfat 3.0.9 (31. Januar 2010) Das Loop-Gerät entspricht nicht der Diskettengröße und verwendet die Standard-HD-Parameter
psihodelia

1
Könnte hilfreich sein, wenn Sie beim Aufruf die Blockgröße angeben mkfs.vfat. Siehe den ersten Link, den ich bereitgestellt habe. Ebenfalls in dem Artikel erwähnt, wird die Diskettenwarnung erwartet und kann ignoriert werden
Shawn Chin

1

Ich würde mit den Werkzeugen gehen, die ich im Sinn habe:

  • Erstellen Sie normalerweise eine neue VM in Virtualbox mit einer Festplatte /dev/sda
  • Starten Sie die VM mit einer GParted Live-CD
  • Partitionieren und formatieren Sie die Festplatte in der VM nach Ihren Wünschen (2 Partitionen, verschiedene Dateisysteme usw.).
  • Verwenden Sie danndd , um /dev/sdain eine Datei zu exportieren

Mit einer fundierten Vermutung würde es ungefähr 15 Minuten dauern.


Intelligente knifflige Lösung :) Aber ich glaube nicht, dass es weniger als 15 Minuten dauert. Übrigens ist es schwierig, es zu automatisieren, da ein Benutzer eine grafische Oberfläche benötigt (daher ist kein Scripting möglich = kein Unix-Weg).
Psihodelia

Es dauert nicht lange :-), da die virtuelle Festplatte klein ist und keine Betriebssysteminstallation durchgeführt wird. Der längste Teil ist die GParted-Startzeit.
Karatedog

1

Minimal lauffähig sfdisk+ mke2fsBeispiel ohnesudo

In diesem Beispiel erstellen wir ohne sudooder ohne setsuideine Image-Datei, die zwei ext2-Partitionen enthält, die jeweils mit Dateien aus einem Host-Verzeichnis gefüllt sind.

Wir werden dann sudo losetupnur die Partitionen mounten, um zu testen, ob der Linux-Kernel sie tatsächlich lesen kann, wie unter /programming/1419489/how-to-mount-one-partition-from-an-image erläutert -Datei-die-mehrere-Partitionen enthält / 39675265 # 39675265

Weitere Einzelheiten finden Sie unter:

Das Beispiel:

#!/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"

Getestet unter Ubuntu 18.04. GitHub stromaufwärts .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.