Comment formater une partition à l'intérieur d'un fichier img?


12

J'ai créé un imgfichier via la commande suivante:

dd if=/dev/zero bs=2M count=200 > binary.img

C'est juste un fichier avec des zéros, mais je peux l'utiliser fdisket créer une table de partition:

# fdisk binary.img

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x51707f21.

Command (m for help): p
Disk binary.img: 400 MiB, 419430400 bytes, 819200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x51707f21

et, disons, une partition:

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 
First sector (2048-819199, default 2048): 
Last sector, +sectors or +size{K,M,G,T,P} (2048-819199, default 819199): 

Created a new partition 1 of type 'Linux' and of size 399 MiB.

Command (m for help): w
The partition table has been altered.
Syncing disks.

Lorsque je vérifie la table des partitions, j'obtiens le résultat suivant:

Command (m for help): p
Disk binary.img: 400 MiB, 419430400 bytes, 819200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x7f3a8a6a

Device      Boot Start    End Sectors  Size Id Type
binary.img1       2048 819199  817152  399M 83 Linux

La partition existe donc. Lorsque j'essaie de formater cette partition via gparted, j'obtiens l'erreur suivante:

entrez la description de l'image ici

Je ne sais pas pourquoi il cherche binary.img1, et je n'ai aucune idée comment formater la partition à partir de la commande en direct.

Est-ce que quelqu'un sait comment le formater en utilisant le système de fichiers ext4?


2
Une option consiste à exécuter l'astuce losetup à partir de cette réponse , puis à exécuter mkfs.ext4 sur le périphérique de bouclage.
Miikka

J'ai trouvé ce lien unix.stackexchange.com/a/87189/52763 . Et c'est en fait ce que je voulais. Le problème est que lorsque je vérifie l'appareil dans gparted, j'obtiens Couldn't find valid filesystem superblock.. Voici la photo: i.imgur.com/dl7XAC4.png. Est-ce une sorte de bogue?
Mikhail Morfikov

Réponses:


13

Vous pouvez accéder à l'image disque et à ses partitions individuelles via la fonction de bouclage. Vous avez déjà découvert que certains utilitaires de disque fonctionneront (raisonnablement) avec bonheur sur les images de disque. Cependant, mkfsn'en fait pas partie (mais étrangement l' mountest).

Voici la sortie de fdisk -lu binary.img:

Disk binary.img: 400 MiB, 419430400 bytes, 819200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
...

Device           Boot Start    End Sectors  Size Id Type
binary.img1            2048 819199  817152  399M 83 Linux

Pour accéder à la partition que vous avez créée, vous avez deux choix

  1. La route explicite

    losetup --offset $((512*2048)) --sizelimit $((512*817152)) --show --find binary.img
    /dev/loop0
    

    La sortie /dev/loop0est le nom du périphérique de boucle qui a été alloué. Le --offsetparamètre est juste le décalage de la partition ( Start) multiplié par la taille du secteur ( 512). Alors que --sizelimitc'est la taille de la partition, vous pouvez la calculer de la manière suivante: End-Start + 1, qui est 819199-2048 + 1 = 817152, et ce nombre doit également être multiplié par la taille du secteur.

    Vous pouvez ensuite utiliser /dev/loop0comme référence à la partition:

    mkfs -t ext4 -L img1 /dev/loop0
    mkdir -p /mnt/img1
    mount /dev/loop0 /mnt/img1
    ...
    umount /mnt/img1
    losetup -d /dev/loop0
    
  2. La route implicite

    losetup --partscan --show --find binary.img
    /dev/loop0
    

    La sortie /dev/loop0est le nom du périphérique de boucle principal qui a été alloué. De plus, l' --partscanoption indique au noyau de rechercher dans le périphérique une table de partition et d'attribuer automatiquement des périphériques de boucle subsidiaire. Dans votre cas, avec la seule partition que vous obtenez également /dev/loop0p1, que vous pouvez ensuite utiliser comme référence à la partition:

    mkfs -t ext4 -L img1 /dev/loop0p1
    mkdir -p /mnt/img1
    mount /dev/loop0p1 /mnt/img1
    ...
    umount /mnt/img1
    losetup -d /dev/loop0
    

@Mikhail curieux de voir que vous avez calculé la taille de la partition alors qu'elle était déjà donnée dans le cadre de la fdisksortie.
roaima

2
Quel est le problème avec certains mathématiques? De plus, il est bon de savoir que vous pouvez facilement obtenir le bon numéro de secteur de cette façon, juste au cas où ...
Mikhail Morfikov

Juste une observation rapide: "mkfs frontend est déconseillé au profit de mkfs spécifiques au système de fichiers. <type> utils", cité dans les pages de manuel de mkfs.
gmagno

@gmagno c'est correct maintenant, certainement. Mais pour autant que je puisse déterminer sans creuser trop longtemps ou trop fort, cet avis n'a été publié que pour la première fois avec util-linux 2.25-rc1, et n'est entré dans Debian stable que longtemps après juin 2015. N'hésitez pas pour mettre à jour la réponse avec les informations actuelles.
roaima

11

Il y a une autre façon de le faire en général, utilisez kpartx( pas lié à kde)

sudo kpartx -a binary.img

et maintenant vous devriez avoir tous les dispositifs de séparation définis sous /dev/mappercomme loop0p1 , loop0p2 , ...

puis

sudo mkfs.ext4 /dev/mapper/loop0p1

En option, lorsque vous avez terminé, vous pouvez également exécuter

sudo kpartx -d binary.img

se débarrasser de la loop0p? deivce


2
Je ne sais pas pourquoi cela n'a pas plus de votes. OMI c'est la meilleure réponse ...!
Jeremy Davis

Fonctionne avec les partitions GPT, par exemple, si vous souhaitez modifier la partition EFI d'un disque entier.
Russ

3

Je ne sais pas pourquoi il cherche binary.img1

(… Et plus tard pour avoir été binary.img2enterré dans le commentaire.)

En effet, les outils s'attendent à ce que les noms de fichiers suivent un modèle spécifique. Ce modèle est celui utilisé par les fichiers de périphérique pour les disques et volumes de disque réels sur votre système, à savoir:

  • Un fichier de périphérique englobant tout le disque est nommé sda(ou autre chose). C'est ce fdiskà quoi on s'attend.
  • Les fichiers de périphériques pour les tranches individuelles du disque, décrit par sa répartition, sont nommés sda1, sda2, sda3, et ainsi de suite. C'est ce que des outils tels que gparteds'attendent à utiliser lorsqu'ils disent mkfsde faire des choses sur des volumes de disque individuels .

Bien sûr, les fichiers ordinaires ne se chevauchent pas de la même manière que les fichiers des périphériques de disque. Les discussions portant sur le système de fichiers de réalimentation que vous avez vu sont à prendre un seul fichier d'image disque entier et en utilisant réalimentation pour créer les 1, 2, 3et ainsi de suite les fichiers qui reflètent les tranches individuelles à l' intérieur, une fois la mise en page de partition souhaitée a été écrite à la table de partition.


Ça a du sens!
Mikhail Morfikov

0

Bien que ce sujet ne soit pas directement lié, il mentionne beaucoup d'informations identiques et connexes.

Wiki Debian | Raspberry Pi et qemu-user-static

Si vous ne pouvez pas utiliser aptpour installer certaines des commandes mentionnées dans cet article, essayez d'utiliser apt-cache search [package_name]. Cela peut ne produire aucun résultat si la commande provient d'un package d'un nom différent.

Par exemple, losetuppouvait auparavant être installé en losetuputilisant apt install losetup, mais il fait maintenant partie du util-linuxréférentiel d'Ubuntu. La façon dont vous découvrez quel package agit comme conteneur pour un autre package, vous devez utiliser la recherche du référentiel en ligne pour votre distribution Linux. Ou, si vous devez l'installer à partir d'une autre source, utilisez un moteur de recherche Web.

Quelques packages à découvrir ...

util-linux genisoimage dosfstools squashfs-tools fsarchiver xfsprogs reiserfsprogs reiser4progs jfsutils ntfsprogs btrfs-tools

Chaque distribution Linux possède également ses propres pages de manuel en ligne. Parfois, il est plus facile d'utiliser les pages de manuel qu'un didacticiel. Les pages de manuel vous indiqueront également toutes les options et paramètres de commande. Un tutoriel ne se concentrera généralement que sur ceux utilisés.


0

Exécution minimale sfdisk+ mke2fsexemple sanssudo

Dans cet exemple, nous allons créer, sans sudoou setsuid, un fichier image contenant deux partitions ext2, chacune remplie de fichiers provenant d'un répertoire hôte.

Nous utiliserons ensuite sudo losetupsimplement pour monter les partitions pour tester que le noyau Linux peut réellement les lire comme expliqué sur: /programming/1419489/how-to-mount-one-partition-from-an-image -file-that-contains-multiple-partitions / 39675265 # 39675265

Pour plus de détails, voir:

L'exemple:

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

Testé sur Ubuntu 18.04. GitHub en amont .

Aide à envelopper un fichier de système de fichiers brut existant dans une image

Extrait de ce qui précède, les éléments suivants peuvent être utiles:

# Put a raw filesystem file into a disk image with a partition table.
#
# /unix/209566/how-to-format-a-partition-inside-of-an-img-file/527132#527132
#
# Usage:
#
#     sfdisk-fs-to-img root.ext2
#
# Creates a file:
#
#     sfdisk-fs-to-img root.ext2.img
#
sfdisk-fs-to-img() (
  partition_file_1="$1"
  img_file="${partition_file_1}.img"
  block_size=512
  partition_size_1="$(wc -c "$partition_file_1" | awk '{print $1}')"
  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)/$bs)) skip="$(($cur_offset/$bs))"
  printf "
  type=83, size=$(($partition_size_1/$block_size))
  " | sfdisk "$img_file"
  cur_offset=$(($cur_offset + $part_table_offset))
  dd if="$partition_file_1" of="$img_file" bs="$bs" seek="$(($cur_offset/$bs))"
  cur_offset=$(($cur_offset + $partition_size_1))
)

GitHub en amont .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.