¿Cómo formatear una partición dentro de un archivo img?


12

Creé un imgarchivo mediante el siguiente comando:

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

Es solo un archivo con ceros, pero puedo usarlo fdisky crear una tabla de partición:

# 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

y, digamos, una partición:

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.

Cuando reviso la tabla de particiones, obtengo el siguiente resultado:

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

Entonces la partición existe. Cuando intento formatear esta partición a través de gparted, aparece el siguiente error:

ingrese la descripción de la imagen aquí

No sé por qué lo busca binary.img1, y no tengo idea de cómo formatear la partición desde el comando live.

¿Alguien sabe cómo formatearlo usando el sistema de archivos ext4?


2
Una opción es hacer el truco de pérdida de configuración de esta respuesta y luego ejecutar mkfs.ext4 contra el dispositivo de bucle invertido.
Miikka

Encontré este enlace unix.stackexchange.com/a/87189/52763 . Y esto es realmente lo que quería. El problema es que, cuando verifico el dispositivo en gparted, me sale Couldn't find valid filesystem superblock.. Aquí está la foto: i.imgur.com/dl7XAC4.png . ¿ Es algún tipo de error?
Mikhail Morfikov

Respuestas:


13

Puede acceder a la imagen del disco y sus particiones individuales a través de la función de bucle invertido. Ya ha descubierto que algunas utilidades de disco funcionarán (razonablemente) felizmente en imágenes de disco. Sin embargo, mkfsno es uno de ellos (pero extrañamente lo mountes).

Aquí está la salida 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

Para acceder a la partición que ha creado, tiene un par de opciones

  1. La ruta explícita

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

    La salida /dev/loop0es el nombre del dispositivo de bucle que se ha asignado. El --offsetparámetro es solo el desplazamiento de la partición ( Start) multiplicado por el tamaño del sector ( 512). Mientras que --sizelimites el tamaño de la partición, y puede calcularlo de la siguiente manera: Fin-Inicio + 1, que es 819199-2048 + 1 = 817152, y ese número también debe multiplicarse por el tamaño del sector.

    Luego puede usar /dev/loop0como referencia a la partición:

    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 ruta implícita

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

    La salida /dev/loop0es el nombre del dispositivo de bucle primario que se ha asignado. Además, la --partscanopción le dice al núcleo que escanee el dispositivo en busca de una tabla de partición y asigne dispositivos de bucle subsidiarios automáticamente. En su caso con la única partición que también obtiene /dev/loop0p1, que luego puede usar como referencia para la partición:

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

@Mikhail siente curiosidad por ver que calculó el tamaño de la partición cuando ya se había dado como parte de la fdisksalida.
roaima

2
¿Qué hay de malo con algunas matemáticas? Además, es bueno saber que puede obtener fácilmente el número de sector correcto de esa manera, por si acaso ...
Mikhail Morfikov

Solo una observación rápida: "mkfs frontend está en desuso a favor de mkfs. <type> utils específicos del sistema de archivos", citado en las páginas de manual de mkfs.
gmagno

@gmagno eso es correcto ahora, ciertamente. Pero por lo que puedo determinar sin excavar durante demasiado tiempo o demasiado, ese aviso solo se lanzó por primera vez con util-linux 2.25-rc1, y eso no llegó a Debian estable hasta bastante tiempo después de junio de 2015. Siéntase libre para actualizar la respuesta con la información actual sin embargo.
Roaima

11

Hay otra forma de hacer esto en general, usando kpartx( no relacionado con kde)

sudo kpartx -a binary.img

y ahora debería tener todos los dispositivos de partición definidos /dev/mappercomo loop0p1 , loop0p2 , ...

y entonces

sudo mkfs.ext4 /dev/mapper/loop0p1

Opcionalmente, cuando haya terminado, puede ejecutar también

sudo kpartx -d binary.img

deshacerse del loop0p? deivce


2
No estoy seguro de por qué esto no tiene más votos. OMI es la mejor respuesta ...!
Jeremy Davis

Funciona con particiones GPT, por ejemplo, si desea modificar la partición EFI fuera de un dd de disco completo.
Russ

3

No sé por qué busca binary.img1

(... y más tarde por binary.img2enterrado en el comentario).

Esto se debe a que las herramientas esperan que los nombres de los archivos sigan un patrón específico. Ese patrón es el utilizado por los archivos del dispositivo para discos y volúmenes de disco reales en su sistema, a saber:

  • Se nombra un archivo de dispositivo que abarca todo el disco sda(o algo más). Esto es lo que fdiskespera utilizar.
  • Los archivos de dispositivo para cortes individuales del disco, descrito por su partición, se nombran sda1, sda2, sda3, y así sucesivamente. Esto es lo que las herramientas, como los que gpartedesperan usar, cuando le dicen mkfsque haga cosas en volúmenes de discos individuales .

Por supuesto, los archivos ordinarios no se superponen de la manera que lo hacen los archivos de los dispositivos de disco. Las discusiones que involucran el sistema de archivos de bucle invertido que has visto son todos acerca de tomar un solo archivo de imagen de todo el disco y el uso de bucle invertido para crear los 1, 2, 3, y así sucesivamente archivos que reflejan las rebanadas individuales dentro de ella, una vez que la partición deseada se ha escrito a la mesa de partición.


¡Eso tiene sentido!
Mikhail Morfikov

0

Aunque este tema no está directamente relacionado, menciona mucha información similar y relacionada.

Wiki de Debian | Raspberry Pi y qemu-user-static

Si no puede usar aptpara instalar algunos de los comandos mencionados en esta publicación, intente usar apt-cache search [package_name]. Es posible que esto no muestre ningún resultado si el comando proviene de un paquete con un nombre diferente.

Por ejemplo, losetupanteriormente se podía instalar losetupusando apt install losetup, pero ahora forma parte del util-linuxrepositorio de Ubuntu. Para saber qué paquete actúa como contenedor de otro paquete, debe utilizar la búsqueda del repositorio en línea para su distribución de Linux. O, si debe instalarlo desde otra fuente, use un motor de búsqueda web.

Algunos paquetes que vale la pena ver ...

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

Cada distribución de Linux también tiene sus propias páginas de manual en línea. A veces es más fácil usar las páginas de manual que un tutorial. Las páginas del manual también le indicarán todas las opciones de comando y parámetros. Un tutorial generalmente solo se enfocará en los que se usan.


0

Ejecutable mínimo sfdisk+ mke2fsejemplo sinsudo

En este ejemplo, crearemos, sin sudoo setsuid, un archivo de imagen que contiene dos particiones ext2, cada una de ellas con archivos de un directorio de host.

Luego usaremos sudo losetupsolo para montar las particiones para probar que el kernel de Linux realmente puede leerlas como se explica en: /programming/1419489/how-to-mount-one-partition-from-an-image -archivo-que-contiene-particiones-múltiples / 39675265 # 39675265

Para más detalles, ver:

El ejemplo:

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

Probado en Ubuntu 18.04. GitHub aguas arriba .

Ayuda para ajustar un archivo de sistema de archivos sin formato existente en una imagen

Extraído de lo anterior, lo siguiente puede ser útil:

# 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 aguas arriba .

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.