Linux - jak sformatować wiele systemów plików w jednym pliku?

9

Muszę utworzyć obraz dysku z dwoma pustymi systemami plików. Stworzyłem to za pomocą

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

Następnie utworzyłem 2 partycje podstawowe przy użyciu fdisk disk.img; jeden to FAT32, a drugi to EXT3. Teraz muszę sformatować obie partycje, aby utworzyć systemy plików do zamontowania jako -o loop devices. Ale nie rozumiem, jak je sformatować? Nie mogę używać mkfs.vfatna disk.img. Więc jestem całkowicie zdezorientowany.

ROZWIĄZANIE: Dzięki odpowiedzi z @ pjc50 znalazłem bardzo proste rozwiązanie:

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

Wadą tego rozwiązania jest wymóg posiadania uprawnień administratora.

psihodelia
źródło
Wątpię, czy wszystkie te programy będą mogły używać partycji w pliku. Czy możesz utworzyć dwa systemy plików w osobnych plikach, a następnie połączyć je w duży plik z dd?
golimar,
@gimarimar: ale będę potrzebować MBR na takim dysku, nie wiem, jak można łączyć różne systemy plików utworzone osobno jako osobne pliki
psihodelia
Możesz użyć MBR oryginalnego pliku, który powiedziałeś. dd pozwala na przesunięcia za pomocą poleceń „rozmiar” i „pomiń”. Trzeba będzie znaleźć dokładne przesunięcia, a następnie zastąpić część dużego pliku dwoma mniejszymi
golimar
Wybacz mi, jeśli jestem tu naiwny, ale dlaczego nie użyć dwóch osobnych plików?
Garrett

Odpowiedzi:

9

Wygląda na to, że możesz użyć narzędzi kpartx: http://robert.penz.name/73/kpartx-a-tool-for-mounting-partitions-within-an-image-file/

Kpartx może być używany do konfigurowania mapowań urządzeń dla partycji dowolnego urządzenia blokowego podzielonego na partycje. Jest częścią wielościeżkowych narzędzi systemu Linux. Z kpartx -l plik_pliku otrzymujesz przegląd partycji w pliku obrazu, a z kpartx -a plik_pliku, partycje będą dostępne poprzez / dev / mapper / loop0pX (X to numer partycji). Możesz go teraz zamontować za pomocą pętli mount / dev / mapper / loop0pX / mnt / -o, ro. Po odmontowaniu możesz odłączyć urządzenia mapujące za pomocą pliku obrazu kpartx -d.
pjc50
źródło
Jednak wadą tego rozwiązania jest wymóg uprawnień administratora.
psihodelia,
1
Wątpię, czy istnieje rozwiązanie, które nie wymaga uprawnień administratora! Oznacza to, że jest to rodzaj operacji, której nie oczekuję, że normalni użytkownicy będą w stanie obejść się bez określonego mechanizmu skonfigurowanego wcześniej przez superużytkownika (np. Przez sudo)
pjc50,
2
@ pjc50: można to zrobić bez uprawnień administratora: najpierw należy utworzyć każdą partycję jako osobny plik, a następnie ręcznie utworzyć obraz dysku i skopiować partycje na obraz dysku po utworzeniu tablicy partycji na obraz dysku.
Mikko Rantalainen
1
@MikkoRantalainen dokładnie. Oto minimalny
możliwy do uruchomienia
7

Można to zrobić przez pierwszy montaż partycje do /dev/loop?korzystania losetupz -oopcji, aby określić odpowiedni offset partycji. Przesunięcie można obliczyć na podstawie wyniku fdisk -l disk.img( start_sector * sector_size).

Na przykład:

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

Po zamontowaniu możesz następnie sformatować partycję, używając mkfs.*:

mkfs.vfat -F32 /dev/loop1

Aby uzyskać więcej informacji i przykładów, zobacz następujące artykuły:

Shawn Chin
źródło
Cóż, to nie działa :(
psihodelia,
@psihodelia Powinno. Jaki jest wynik, jeśli to zrobisz?
Daniel Beck
Jak to nie działa? Czy pojawia się błąd? Który krok kończy się niepowodzeniem?
Shawn Chin,
$ sudo mkfs.vfat -F32 / dev / loop1 mkfs.vfat 3.0.9 (31 stycznia 2010) Urządzenie pętli nie pasuje do rozmiaru dyskietki, używając domyślnych parametrów hd
psihodelia
1
Może pomóc, jeśli określisz rozmiar bloku podczas połączenia mkfs.vfat. Zobacz pierwszy link, który podałem. Wspomniano również w artykule, że ostrzeżenie o dyskietce jest oczekiwane i można je zignorować
Shawn Chin,
1

Wybrałbym narzędzia, które mam na myśli:

  • utwórz nową maszynę wirtualną w Virtualbox z jednym dyskiem, co zwykle byłoby /dev/sda
  • uruchom maszynę wirtualną z GParted Live CD
  • partycjonuj i sformatuj dysk w maszynie wirtualnej do swoich potrzeb (2 partycje, różne systemy plików itp.)
  • następnie użyj, ddaby wyeksportować /dev/sdado pliku

Z wykształconym przypuszczeniem zajmie to około 15 minut.

karatedog
źródło
Inteligentne podchwytliwe rozwiązanie :) Ale nie sądzę, że zajmuje to mniej niż 15 minut. Nawiasem mówiąc, trudno go zautomatyzować, ponieważ wymaga użytkownika w interfejsie graficznym (więc żadne skrypty nie są możliwe = nie w Uniksie).
psihodelia,
Nie trwa to długo :-), ponieważ dysk wirtualny jest mały i nie jest wykonywana instalacja systemu operacyjnego. Najdłuższą częścią jest czas rozruchu GParted.
karatedog,
1

Minimalne uruchamianie sfdisk+ mke2fsprzykład bezsudo

W tym przykładzie utworzymy plik obrazu bez sudolub setsuidz dwiema partycjami ext2, z których każda zawiera pliki z katalogu hosta.

Następnie użyjemy sudo losetuptylko do zamontowania partycji w celu przetestowania, czy jądro Linux może je odczytać, jak wyjaśniono na stronie : /programming/1419489/how-to-mount-one-partition-from-an-image -plik-zawierający-wiele partycji / 39675265 # 39675265

Aby uzyskać więcej informacji, zobacz:

Przykład:

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

Testowane na Ubuntu 18.04. GitHub w górę .

Ciro Santilli
źródło