Convierta la imagen de una partición en imagen de un disco con tabla de particiones

20

Tengo una imagen de una partición existente generada con dd if=/dev/sdXN of=image.bin. Ahora quiero usar esta imagen como base para una máquina virtual. Sé cómo convertir la imagen a un formato que VirtualBox pueda usar.

El problema es que la imagen del "disco" es realmente solo la imagen de una partición y, por lo tanto, no contiene un MBR o una tabla de particiones. Esto hace que sea muy difícil arrancar la VM.

¿Existe una manera simple, dada una imagen de una partición, de crear una imagen de disco adecuada, incluida una tabla de partición?

Mika Fischer
fuente

Respuestas:

13

Puede hacer esto en la máquina host. La mayoría de las herramientas como fdiskoperan en archivos y kpartxle da acceso a particiones en un archivo.

  1. Cree una nueva imagen dispersa vacía de 100GiB (haga esto un poco más grande que el tamaño de la imagen de partición)

    dd if=/dev/zero of=myvm.img bs=1G count=0 seek=100
    
  2. Particionar el archivo de imagen con fdisk

    fdisk myvm.img
    
  3. Hacer que las particiones en el archivo de imagen estén disponibles en dispositivos individuales

    sudo kpartx -a myvm.img
    
  4. Copie la imagen de la partición en la partición

    sudo cp image.bin /dev/mapper/loop0p1
    
  5. Extienda el sistema de archivos para llenar toda la partición

    sudo resize2fs /dev/mapper/loop0p1
    
  6. Cerrar las particiones

    sudo kpartx -d myvm.img
    
  7. Desmontar el dispositivo loopback

    sudo losetup -D
    
mgorven
fuente
¿No haría esto que la partición creada en la imagen "no coincida" con la longitud de la partición con imagen? ¿Y hay alguna manera de resolver eso? Y, ¿podría un administrador de sistema de archivos "lo suficientemente inteligente" saber que no está utilizando todo el tamaño de la partición y expandirse para adaptarse?
Killermist
@killermist Respuesta actualizada.
mgorven
Esta es una buena respuesta. ¿Conoces alguna forma de evitar copiar todo el proceso?
Mika Fischer
@MikaFischer Desafortunadamente no, porque la tabla de particiones debe existir antes de la partición, y no conozco ningún mecanismo para anteponer datos a un archivo.
mgorven
Creo que la respuesta de Harun es mejor porque es fácil de hacer y puede ser programada.
philcolbourn
9

Estoy seguro de que el problema original se resolvió hace mucho tiempo, pero para cualquiera con un problema similar:

Una forma de evitar copiar toda la imagen sería crear una imagen en formato .vmdk que haga referencia a archivos de extensión separados para la tabla de particiones y para el contenido de la partición.

Tengo este fragmento en un archivo .vmdk de una prueba que hice hace un tiempo:

RW 63 FLAT "parttable.bin" 0
RW 585937489 FLAT "partition-image.bin" 63

Esto significa que los 63 sectores que comienzan desde el desplazamiento 0 se leen desde el archivo sin formato "parttable.bin", pero el sector 63 y hacia arriba provienen del volcado de partición sin formato "division-image.bin". (Por supuesto, reemplace 63 con el desplazamiento real de la primera partición, generalmente 2048 en estos días).

El resultado final es que, desde dentro de VBox, parece que ha colocado la tabla de particiones en el frente de la imagen de la partición, sin tener que hacer la operación de copia larga.

Particione la unidad desde dentro de la VM y, si obtiene sus correcciones correctas, debería ver el contenido de su imagen de partición dentro de la partición recién creada.

Harun
fuente
2
Creo que el '63' en la segunda línea debe ser 0 si la partición-imagen.bin es una imagen de partición. Acabo de hacer algo como esto y necesitaba establecer este desplazamiento en el archivo de imagen de partición a cero. philatwarrimoo.blogspot.com.au/2014/01/…
philcolbourn
Genio. Sólo tenía que hacer esto para utilizar una partición de Windows para una máquina virtual en un host Linux, y esto es lo único que funcionaba, siguiendo los pasos de @philcolbourn: superuser.com/a/804396/93066
bmaupin
¿Qué debería haber en el resto del archivo vmdk?
gozzilli
1
@gozzilli El resto del archivo es un montón de detalles como números de versión del archivo, tipo de adaptador de disco, uuids y geometría del disco. No sé cómo escribir esos bits. Recomendaría simplemente usar una herramienta para crear un vmdk apuntando a la imagen del disco y luego modificar solo las líneas que describen de dónde obtener el encabezado de partición adicional.
Harun
3

Interesante problema Esto es lo que haría:

  1. Cree la VM con un disco adecuadamente grande y luego inícielo desde un CD de recuperación.
  2. Obtenga acceso a su imagen de disco existente de alguna manera (nfs, cifs, etc.).
  3. Cree las particiones que necesitará en el disco local de la VM.
  4. Use dd para escribir la imagen de la partición en la partición del disco vm.

Una vez hecho esto, deberá actualizar su gestor de arranque. Suponiendo que está utilizando GRUB, monte la partición recién escrita, luego haga un chroot en ella y ejecútela update-grub(tenga cuidado, sin embargo, es posible que deba ajustar sus archivos de configuración antes de que funcione correctamente).

¡Buena suerte!

bahamat
fuente
2

Puede cambiar el tamaño del sistema de archivos en su lugar, con GParted.

Crea la imagen de prueba:

dd if=/dev/zero of=extfs bs=1M count=20
mkfs.ext4 extfs

No estoy usando resize2fs, porque cambia el tamaño del archivo, en lugar de dejar espacio libre.

sudo losetup /dev/loop0 extfs
sudo ln -s /dev/loop0 /dev/loop0p1 # needed for GParted to be able to resize it
gksudo gparted /dev/loop0

1 MB gratis al inicio.

sudo rm /dev/loop0p1
sudo losetup -d /dev/loop0

Finalmente, cree la tabla de particiones.

fdisk extfs

Establezca el primer sector en 2048 (2048 sectores * 512 B / sector = 1 MB), el último sector es el predeterminado (es decir, el final de la imagen).

ignis
fuente
1

Personalmente prefiero agregar usando dd.

Estoy asumiendo sectores de 512 bytes aquí. Puede haber un caso para los sectores de 2048 bytes, así que simplemente intercambie los números y haga los cálculos.

En cada caso, estoy usando un archivo de prueba de 512 MB, por ejemplo:

dd if=/dev/zero of=testfs.img bs=512 count=1M mkfs.ext4 testfs.img

MBR

Componiendo la imagen

Personalmente prefiero agregar el primer MB (2048 sectores) a su comienzo:

dd if=testfs.img skip=2048 bs=512 of=full.img

Finalmente ejecute fdisk para crear la tabla de particiones (o copie la suya propia), creé 1 partición usando los valores predeterminados.

Verificando

Para verificar, crear particiones de bucle y autodetectar:

sudo losetup -fP full.img

Y ejecutar fileen el dispositivo de loopback particionado resultante:

sudo file -s /dev/loop2p1 /dev/loop2p1: Linux rev 1.0 ext4 filesystem data, UUID=ae2945fd-54b5-486f-8dd0-9b18d6ae01b4 (extents) (large files) (huge files)

GPT

Componiendo la imagen

Personalmente, prefiero agregar los primeros MB (2048 sectores, ya que gdisk usará de forma predeterminada este número, ya que está alineado con 1 MB) al comienzo para el MBR inicial y 34 sectores hasta el final (o 2048 para un MB completo) para el final GPT (el sector final puede ser diferente). Omitir el GPT final puede perder sus datos:

dd if=testfs.img skip=2048 bs=512 of=full.img dd if=/dev/zero seek=1050624 bs=512 of=full.img count=34

Finalmente ejecute gdisk para crear la tabla de particiones (o copie la suya propia), creé 1 partición usando los valores predeterminados.

Verificando

Para verificar, crear particiones de bucle y autodetectar:

sudo losetup -fP full.img

Y ejecutar fileen el dispositivo de loopback particionado resultante:

sudo file -s /dev/loop2p1 /dev/loop2p1: Linux rev 1.0 ext4 filesystem data, UUID=ae2945fd-54b5-486f-8dd0-9b18d6ae01b4 (extents) (large files) (huge files) Este método garantiza no adivinar, cambiar el tamaño o alinear manualmente.

Dan Dart
fuente
¿Cómo encontrar el sector final de la imagen en gpt?
Anwar
Cuando corro esto sudo file -s /dev/loop11p1lo tengo /dev/loop11p1: data. Que anteriormente era un sistema de archivos ext4. Y el full.img resultante es más pequeño. Creo que tienes la solución invertida.
Anwar
Creo que quieres decir seek=2048en este comando dd if = testfs.img skip = 2048 bs = 512 of = full.img
Anwar