Linux - як відформатувати кілька файлових систем в одному файлі?


9

Мені потрібно створити образ диска з двома порожніми файловими системами. Я створив це за допомогою

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

Далі я створив 2 основні розділи, використовуючи fdisk disk.img; один - 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: але мені знадобиться MBR на такому диску, я не знаю, як можна об'єднати різні файлові системи, створені окремо, як окремі файли
— psihodelia

Ви можете використовувати MBR оригінального файла, який ви сказали. dd дозволяє здійснювати компенсації за допомогою команд 'size' та 'skip'. Вам потрібно буде знайти точні компенсації, а потім перезаписати частину великого файлу двома меншими
— golimar

Пробачте, якщо я тут наївний, але чому б просто не використати два окремих файли?
— Гаррет

Відповіді:


9

Здається, ви можете використовувати інструменти kpartx: http://robert.penz.name/73/kpartx-a-tool-for-mounting-partitions-within-an-image-file/

Kpartx можна використовувати для налаштування відображень пристрою для розділів будь-якого блокованого пристрою. Він є частиною багатофункціональних інструментів Linux. За допомогою kpartx -l imagefile ви отримуєте огляд розділів у файлі зображень, а з kpartx -a imagefile розділи будуть доступні через / dev / mapper / loop0pX (X - номер розділу). Ви можете встановити його зараз за допомогою mount / dev / mapper / loop0pX / mnt / -o loop, ro. Після відключення ви можете від'єднати пристрої відображення за допомогою файлу зображень kpartx -d.

Однак недоліком цього рішення є вимога прав суперпользователя.
— психоделія

1
Я сумніваюся, що існує рішення, яке не потребує прав суперпользователя! Тобто, це така операція, яку я не сподіваюся, що звичайні користувачі зможуть обійтися без конкретного механізму, встановленого суперкористувачем заздалегідь (наприклад, через sudo)
— pjc50

2
@ pjc50: це можна зробити без прав суперпользователя: спочатку потрібно створити кожен розділ як окремий файл, потім створити образ диска вручну та скопіювати розділи на образ диска після створення таблиці розділів на образ диска.
— Мікко Ранталайнен

1
@MikkoRantalainen точно. Ось мінімальний приклад для
— запуску

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 Слід. Який результат, якщо ви це зробите?
— Даніель Бек

Як це не працює? Ви отримуєте помилку? Який крок не вдається?
— Шон Чін

$ sudo mkfs.vfat -F32 / dev / loop1 mkfs.vfat 3.0.9 (31 січня 2010) Пристрій циклу не відповідає розміру дискети, використовуючи параметри hd за замовчуванням
— psihodelia

1
Може допомогти, якщо ви визначаєте розмір блоку під час дзвінка mkfs.vfat. Дивіться перше я надане посилання. Також у статті згадується, що дискета попередження очікується і може бути проігнорована
— Шон Чин

1

Я б хотів використовувати інструменти, які маю на увазі:

  • створити новий VM у Virtualbox за допомогою одного диска, який, як правило, буде /dev/sda
  • завантажтеся в VM за допомогою GParted Live CD
  • розділіть і відформатуйте диск у віртуальній машині для потреб (2 розділу, різні файлові системи тощо)
  • потім використовуйте ddдля експорту /dev/sdaдо файлу

З освіченою здогадкою це займе близько 15 хвилин.


Розумне хитромудре рішення :) Але я не вірю, що це займає менше 15 хвилин. До речі, його важко автоматизувати, тому що він вимагає користувача в графічному інтерфейсі (так, ніякі сценарії неможливі = не спосіб Unix).
— психоделія

Це не займе багато часу :-), оскільки віртуальний диск невеликий, і не встановлюється ОС. Найдовша частина - час завантаження GParted.
— karatedog

1

Мінімальний цикл sfdisk+ mke2fsприклад безsudo

У цьому прикладі ми створимо без sudoабо 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"

Тестовано на Ubuntu 18.04. GitHub вище за течією .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.