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.