dd en todo el disco, pero no quiere una porción vacía

33

Tengo un disco, digamos / dev / sda.

Aquí está fdisk -l:

 Disk /dev/sda: 64.0 GB, 64023257088 bytes
255 heads, 63 sectors/track, 7783 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0000e4b5

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          27      209920   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              27         525     4000768    5  Extended
Partition 2 does not end on cylinder boundary.
/dev/sda5              27         353     2621440   83  Linux
/dev/sda6             353         405      416768   83  Linux
/dev/sda7             405         490      675840   83  Linux
/dev/sda8             490         525      282624   83  Linux

Necesito hacer una imagen para almacenarla en nuestro servidor de archivos para usarla en otros dispositivos que estamos fabricando, así que solo quiero el espacio utilizado (solo alrededor de 4 gb). Quiero mantener el mbr, etc., ya que este dispositivo debe estar listo para el arranque tan pronto como finalice la copia.

¿Algunas ideas? Anteriormente había estado usando dd if=/dev/sda of=[//fileserver/file], pero en ese momento, mi copia maestra estaba en una memoria flash de 4 gb.

Jonathan Henson
fuente
2
Todas las respuestas a continuación son incorrectas, excepto @sudoer. La respuesta correcta es usar dd conv=sparse.
bahamat
@bahamat, no, gzip es mejor ya que comprimirá los datos.
psusi
1
Eso no es lo mismo que escaso.
bahamat
@bahamat, la pregunta no es pedir específicamente sprase; cómo hacer que la imagen ocupe menos espacio.
psusi

Respuestas:

37

En el pasado me encontré con un problema similar con las distribuciones de Linux integradas: deshazte de toda la basura antes de comprimir la imagen.

dd if=/dev/zero of=asdf.txt. Espera hasta que muera. Eliminar asdf.txt.

Acaba de escribir ceros en todo el espacio libre del dispositivo.

Ahora tome una imagen de disco y ejecútela a través de gzip. Voila, imagen escasa.

Probablemente no se escala muy bien y podría causar problemas si realmente necesita escribir en el disco, pero bueno.

Podría llevar una instantánea rsync del disco a otro volumen, poner a cero y luego tomar esa imagen de disco.

Nota: Podría ser peligroso para SSD, el usuario debe considerar esta operación antes de comprometerse.

Rob Bos
fuente
si lo ejecuto a través de gzip, ¿tendré que descomprimirlo antes de usarlo? Y al ejecutarlo a través de gzip, ¿solo lo canalizo durante el proceso de dd?
Jonathan Henson el
3
Sí. dd if=sda2.gz | gunzip > /dev/sda2ydd if=/dev/sda2 | gzip > sda2.gz
Rob Bos
3
"Acaba de escribir ceros en todo el espacio libre del dispositivo". Te refieres a la partición, no al dispositivo, creo. Por lo tanto, deberá ejecutar ese comando con una ofruta para cada partición.
jiggunjer
Si el medio físico es un SSD, ahora puede pensar que se han utilizado todos los sectores del dispositivo. Esto le dará al SSD menos sectores de repuesto para trabajar y posiblemente disminuirá el rendimiento como resultado. Si el controlador y el firmware tienen soporte TRIM, esa condición solo se aplicará hasta que elimine el archivo nuevamente. Si mantiene el archivo en su lugar mientras crea la imagen, tendrá que eliminar el archivo nuevamente después de restaurar la imagen. Eso puede ser útil si la imagen se restaura a SSD.
kasperd
Hay algunas preocupaciones adicionales a tener en cuenta. Dado que este método requiere que el sistema de archivos se monte lectura-escritura, existe el riesgo de que los cambios en el sistema de archivos subyacente mientras la copia está en curso conduzca a una imagen inconsistente. En una ocasión, he visto que la copia resultante es tan inconsistente que fsck realmente se daña al intentar reparar las inconsistencias en la copia. Además, llenar el dispositivo puede provocar que otros procesos que necesiten escribir en los medios fallen.
kasperd
17

Suponiendo que desea guardar /dev/sdXNa /tgtfs/image.rawy que sea root:

  1. mkdir /srcfs && mount /dev/sdXN /srcfs

  2. Use zerofill o simplemente: dd if=/dev/zero of=/srcfs/tmpzero.txtpara llenar los bloques no utilizados con cero (espere a que llene el sistema de archivos por completo entonces rm /srcfs/tmpzero.txt)

  3. Tome la imagen con dd y use conv = sparse para marcar ceros sobre la marcha: dd conv=sparse if=/dev/sdxn of=/tgtfs/image.raw

Si desea utilizar la compresión, no necesita marcar los ceros con dd, ya que los bloques cero son altamente compresibles:

dd if=/dev/sdxn | gz -c | dd of=/tgtfs/image.raw

PD: debe tener en cuenta que esta no es una buena idea en un medio de almacenamiento basado en memoria flash (es decir, su sistema de archivos de origen sea SSD)

Sudoer
fuente
55
Esta es la respuesta correcta. Uso dd conv=sparse.
bahamat
1
¿Qué tiene de malo hacer esto en el almacenamiento flash?
Dan
2
@Dan (según el diseño y la configuración del hardware y el software) puede causar una escritura extensa en su SSD y reducir su vida útil. y, en general, está bien mover datos del disco viejo al nuevo (o lo que quería hacer el OP), pero la copia de seguridad a nivel de disco / partición no es una buena solución para la copia de seguridad y restauración regulares, incluso en HDD. la copia de seguridad a nivel de archivo (es decir, archivos de copia de un sistema de archivos a otro), o la copia de seguridad a nivel de sistema de archivos (con sistemas de archivos como BTRFS con btrfs snapshoty btrfs sendherramientas) es una mejor solución en mi humilde opinión.
Sudoer
Sugerencia: si no tiene gzen su PATH(como no lo hice, en GParted Live), puede usar gzip -cen su lugar.
XtraSimplicity
11

Use dd, con la opción de conteo.

En su caso, estaba usando fdisk, así que adoptaré ese enfoque. Su "sudo fdisk -l" produjo:

    Disk /dev/sda: 64.0 GB, 64023257088 bytes
    255 heads, 63 sectors/track, 7783 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x0000e4b5

    Device Boot      Start         End      Blocks   Id  System
    /dev/sda1   *           1          27      209920   83  Linux
    Partition 1 does not end on cylinder boundary.
    /dev/sda2              27         525     4000768    5  Extended
    Partition 2 does not end on cylinder boundary.
    /dev/sda5              27         353     2621440   83  Linux
    /dev/sda6             353         405      416768   83  Linux
    /dev/sda7             405         490      675840   83  Linux
    /dev/sda8             490         525      282624   83  Linux

Las dos cosas que debe tener en cuenta son: 1) el tamaño de la unidad y 2) la columna "Fin". En su caso, tiene cilindros que son iguales a 8225280 Bytes. En la columna "Fin", sda8 termina en 525 (que es 525 [unidades] * 16065 * 512 = ~ 4.3GB)

dd puede hacer muchas cosas, como comenzar después de un desplazamiento o detenerse después de un número específico de bloques. Haremos lo último usando la opción de conteo en dd. El comando aparecería de la siguiente manera:

    sudo dd if=/dev/sda of=/your_directory/image_name.iso bs=8225280 count=526

Donde -bs es el tamaño del bloque (es más fácil usar la unidad que usa fdisk, pero cualquier unidad lo hará siempre que la opción de conteo se declare en estas unidades), y contar es el número de unidades que queremos copiar (nota que incrementemos el recuento en 1 para capturar el último bloque).

Tom Looby
fuente
FYI: para mostrar unidades en cilindros, usefdisk -l -u=cylinders /dev/sda
xinthose
3
¿Por qué no es esta la respuesta aceptada? Parece ser la opción menos intrusiva ya que no modifica la fuente.
user33326
@ user33326 porque esta respuesta es buena para no copiar espacio no particionado en una unidad, no espacio no utilizado dentro de particiones, que es lo que le importa al OP.
GDorn
8

Si bien /dev/zeroel espacio libre en disco y el uso dd conv=sparse/ gz -ces posible, en discos enormes con espacio vacío ejecutándose en cientos de GB, /dev/zeroing es dolorosamente lento, por no mencionar que, como lo señalaron otras respuestas, /dev/zeroun SDD hasta EOF.

Esto es lo que hice cuando me encontré con esta situación:

  • En un CD en vivo de lubuntu, se usa gpartedpara 'reducir' el disco al tamaño mínimo posible, dejando el resto del espacio sin asignar

  • Se utiliza
    dd bs=1M count=<size_in_MBs> if=/dev/sdX | gzip -c --fast| dd of=/path/to/image.gz para crear la imagen comprimida rápidamente (no hace falta decir que es posible que desee omitir la compresión si tiene espacio suficiente para almacenar datos sin procesar (o si por lo demás está inclinado a reducir la carga de la CPU)

  • Se utiliza
    dd if=/path/to/image.gz | gunzip -c | dd bs=1M of=/dev/sdY para copiar los datos nuevamente en un disco diferente
  • Se usa gpartednuevamente para 'expandir' la partición

No lo he probado para varias particiones, pero creo que el proceso anterior se puede adaptar para copiar 'particiones' si la tabla de particiones en el disco de destino se crea primero y solo se copian los datos contenidos en la partición dd: compensación de lectura / escritura ( skip/ seekopción de dd, respectivamente) se requeriría según corresponda.

Ashish Chopra
fuente
1
esta es la respuesta real, solo use el countparámetro
Gordy
7

No puedes ddes una herramienta de muy bajo nivel y no tiene forma de distinguir entre archivos y espacios vacíos.

Por otro lado, el espacio vacío se comprimirá muy, muy bien, por lo que si solo le preocupa el espacio de almacenamiento, no, por ejemplo, el tiempo de escritura, simplemente póngalo a través de gzip.

c2h5oh
fuente
77
Suponiendo que el espacio libre no se haya utilizado previamente. Puede llenar cero el espacio libre primero para asegurarse de que la compresión funcione como se espera.
Sirex
1
Cierto. Y solo complica el proceso y hace que demore aún más.
c2h5oh
6

Suponiendo que el resto de la unidad está vacía (todos ceros), podría canalizar su DD a través de gzip, lo que debería comprimir el espacio vacío bastante bien. Puede usar una herramienta como zerofree para asegurarse de que su espacio vacío esté realmente en blanco para que se comprima bien.

Si usa una herramienta como partimage , clonezilla o alguna de las otras herramientas de clonación de Linux, manejarán la mayor parte de esto automáticamente.

Zoredache
fuente
partimage y Clonezilla en realidad son lo suficientemente inteligentes como para omitir la lectura del espacio libre, en lugar de confiar en usted a ceros escribir en él, y luego tener dd gzip o gota o comprimir los ceros después de leerlos en.
psusi
2

La respuesta aceptada no es correcta. Estoy de acuerdo con el comentario anterior. Utilizo dd con el parámetro count para hacer una copia de seguridad de mi disco de forma regular. Simplemente reemplace el BACKUP_FOLDER y la letra de su dispositivo con "X":

Defina el último bloque usado del disco:

ct=$(fdisk -l | awk '$1 == "/dev/sdX" { print $3 }')

Luego clonando el disco (excluyendo su espacio vacío):

dd if=/dev/sdX bs=512 count=$ct | gzip > BACKUP_FOLDER/sdX_$(date +"%Y-%m-%d").img.gz >>"$LOG"
Aloha D
fuente