dd su tutto il disco, ma non vuoi porzione vuota


33

Ho un disco, ad esempio / dev / sda.

Ecco 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

Devo creare un'immagine da archiviare sul nostro file server per utilizzarla per il flashing di altri dispositivi che stiamo producendo, quindi desidero solo lo spazio utilizzato (solo circa 4 GB). Voglio mantenere il mbr ecc ... poiché questo dispositivo dovrebbe essere pronto all'avvio non appena la copia è terminata.

Qualche idea? In precedenza avevo usato dd if=/dev/sda of=[//fileserver/file], ma a quel tempo, la mia copia principale era su un ide flash da 4 GB.


2
Tutte le risposte di seguito sono errate tranne @sudoer. La risposta corretta è usare dd conv=sparse.
Bahamat,

@bahamat, no, gzip è migliore poiché comprime i dati.
psusi,

1
Non è la stessa cosa di rado.
Bahamat,

@bahamat, la domanda non è specifica per sprase; solo come fare in modo che l'immagine occupi meno spazio.
psusi

Risposte:


37

In passato ho riscontrato un problema simile con le distribuzioni Linux integrate: sbarazzarsi di tutta la spazzatura prima di comprimere l'immagine.

dd if=/dev/zero of=asdf.txt. Aspetta che muoia. Elimina asdf.txt.

Hai appena scritto zeri in tutto lo spazio libero sul dispositivo.

Ora prendi un'immagine del disco ed eseguila tramite gzip. Voila, immagine sparsa.

Probabilmente non si adatta molto bene e potrebbe causare problemi se in realtà è necessario scrivere sul disco, ma ehi.

È possibile eseguire un'istantanea rsync del disco su un altro volume, azzerarlo, quindi acquisire l'immagine del disco.

Nota: potrebbe essere pericoloso per SSD, l'utente deve considerare questa operazione prima di impegnarsi.


se lo eseguo tramite gzip, dovrò decomprimerlo prima di usarlo? E eseguendolo tramite gzip, lo installo solo durante il processo dd?
Jonathan Henson,

3
Sì. dd if=sda2.gz | gunzip > /dev/sda2edd if=/dev/sda2 | gzip > sda2.gz
Rob Bos,

3
"Hai appena scritto zeri in tutto lo spazio libero sul dispositivo". Intendi dire partizione, non dispositivo, credo. Quindi avresti bisogno di eseguire quel comando con un ofpercorso per ogni partizione.
jiggunjer,

Se il supporto fisico è un SSD, ora può pensare che sia stato utilizzato ogni settore sul dispositivo. Ciò darà all'SSD un minor numero di settori di riserva con cui lavorare e, di conseguenza, diminuirà le prestazioni. Se il driver e il firmware dispongono del supporto TRIM, tale condizione si applica solo fino a quando non si elimina nuovamente il file. Se si mantiene il file in posizione mentre si crea l'immagine, sarà necessario eliminare nuovamente il file dopo aver ripristinato l'immagine. Ciò può essere utile se l'immagine viene ripristinata su SSD.
Kasperd,

Ci sono alcune preoccupazioni aggiuntive da tenere a mente. Poiché questo metodo richiede che il file system sia montato in lettura-scrittura, esiste il rischio che le modifiche al file system sottostante durante la copia porteranno a un'immagine incoerente. In un'occasione ho visto la copia risultante essere così incoerente che fsck sarebbe effettivamente segfault quando tentava di riparare le incoerenze sulla copia. Anche il riempimento del dispositivo può causare il fallimento di altri processi che necessitano di scrivere sul supporto.
Kasperd,

17

Supponendo che si desidera salvare /dev/sdXNper /tgtfs/image.rawe siete root:

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

  2. Usa zerofill o semplicemente: dd if=/dev/zero of=/srcfs/tmpzero.txtper riempire zero blocchi inutilizzati (attendi che riempia completamente il file system, quindi rm /srcfs/tmpzero.txt)

  3. Prendi l'immagine con dd e usa conv = sparse per dare un pugno agli zeri al volo: dd conv=sparse if=/dev/sdxn of=/tgtfs/image.raw

Se si desidera utilizzare la compressione non è necessario punzonare gli zeri con dd poiché i blocchi zero sono altamente comprimibili:

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

PS: dovresti notare che questa non è una buona idea su un supporto di archiviazione basato su memoria flash (cioè il tuo file system di origine è SSD)


5
Questa è la risposta corretta Usa dd conv=sparse.
Bahamat,

1
Cosa c'è di sbagliato nel fare questo su memoria flash?
Dan

2
@Dan (a seconda del design e della configurazione hardware e software) può causare una scrittura estesa sull'unità SSD e ridurne la durata. e soprattutto, è OK per spostare i dati dal vecchio disco a quello nuovo (o quello che l'OP voleva fare), ma il backup a livello di disco / partizione non è una buona soluzione per il backup e il ripristino regolari, anche su HDD. il backup a livello di file (ovvero la copia di file da un file system a un altro) o il backup a livello di file system (con file system come BTRFS con btrfs snapshote btrfs sendstrumenti) è una soluzione IMHO migliore.
Sudoer

Suggerimento: se non hai gzil tuo PATH(come non ho fatto io, su GParted Live), puoi usare gzip -cinvece.
XtraSimplicity

11

Usa dd, con l'opzione count.

Nel tuo caso stavi usando fdisk, quindi seguirò questo approccio. Il tuo "sudo fdisk -l" prodotto:

    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

Le due cose che dovresti prendere in considerazione sono 1) la dimensione dell'unità e 2) la colonna "Fine". Nel tuo caso hai cilindri che sono pari a 8225280 byte. Nella colonna "Fine" sda8 termina a 525 (ovvero 525 [unità] * 16065 * 512 = ~ 4.3 GB)

dd può fare molte cose, come iniziare dopo un offset o fermarsi dopo un numero specifico di blocchi. Faremo quest'ultimo usando l'opzione count in dd. Il comando appare come segue:

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

Dove -bs è la dimensione del blocco (è più facile usare l'unità utilizzata da fdisk, ma qualsiasi unità lo farà fino a quando l'opzione di conteggio è dichiarata in queste unità), e count è il numero di unità che vogliamo copiare (nota che incrementiamo il conteggio di 1 per catturare l'ultimo blocco).


A proposito: per mostrare le unità in cilindri, utilizzarefdisk -l -u=cylinders /dev/sda
xinthose,

3
Perché questa non è la risposta accettata? Sembra essere l'opzione meno invadente in quanto non modifica l'origine.
user33326

@ user33326 perché questa risposta è utile per non copiare lo spazio non partizionato su un'unità, non lo spazio non utilizzato all'interno delle partizioni, che è ciò che interessa all'OP.
GDorn

8

Mentre è possibile /dev/zeroutilizzare lo spazio libero su disco e utilizzare dd conv=sparse/ gz -cè possibile, su enormi dischi con spazio vuoto in esecuzione in centinaia di GB, l' /dev/zeroing è dolorosamente lento - per non parlare del fatto che, come notato da altre risposte, è possibile utilizzare /dev/zeroun SDD fino a EOF.

Ecco cosa ho fatto quando mi sono imbattuto in questa situazione:

  • Su un CD live di Lubuntu, utilizzato gpartedper "ridurre" il disco alla dimensione minima possibile, lasciando il resto dello spazio non allocato

  • Utilizzato
    dd bs=1M count=<size_in_MBs> if=/dev/sdX | gzip -c --fast| dd of=/path/to/image.gz per creare l'immagine a compressione rapida (inutile dirlo, potresti voler saltare la compressione se hai spazio sufficiente per archiviare i dati grezzi (o sei altrimenti incline a ridurre il caricamento della CPU)

  • Utilizzato
    dd if=/path/to/image.gz | gunzip -c | dd bs=1M of=/dev/sdY per copiare nuovamente i dati su un altro disco
  • Usato di gpartednuovo per 'espandere' la partizione

Non l'ho provato per più partizioni ma credo che il processo sopra descritto possa essere adattato per copiare le "partizioni" se la tabella delle partizioni sul disco di destinazione viene creata per prima e solo i dati contenuti nella partizione vengono copiati tramite dd- offset di lettura / scrittura ( skip/ seekopzione di dd, rispettivamente) sarebbe richiesto come appropriato.


1
questa è la vera risposta, basta usare il countparametro
Gordy

7

Non puoi. ddè uno strumento di livello molto basso e non ha mezzi per distinguere tra file e spazio vuoto.

D'altra parte lo spazio vuoto si comprimerà molto, molto bene, quindi se ti preoccupi solo dello spazio di archiviazione, non ad esempio il tempo di scrittura, allora esegui semplicemente il pipe attraverso gzip.


7
Supponendo che lo spazio libero non sia stato precedentemente utilizzato. È possibile zero riempire prima lo spazio libero per assicurarsi che la compressione funzioni come previsto.
Sirex,

1
Vero. E complica solo il processo e lo rende ancora più lungo.
c2h5oh,

6

Supponendo che il resto dell'unità sia vuoto (tutti zeri), è possibile reindirizzare il DD tramite gzip, che dovrebbe comprimere lo spazio vuoto abbastanza bene. Puoi usare uno strumento come zerofree per assicurarti che il tuo spazio vuoto sia effettivamente vuoto in modo da comprimersi bene.

Se usi uno strumento come partimage , clonezilla o alcuni degli altri strumenti di clonazione di Linux, questi gestiranno la maggior parte di questo automaticamente.


partimage e clonezilla sono in realtà abbastanza intelligenti da saltare la lettura dello spazio libero, piuttosto che fare affidamento su di te per scrivere zero su di esso, e quindi far cadere o comprimere zeri o comprimere gli zeri dopo averli letti.
psusi

2

La risposta accettata non è giusta. Sono d'accordo con il commento sopra. Uso dd con il parametro count per eseguire il backup del mio disco su base regolare. Sostituisci semplicemente BACKUP_FOLDER e la lettera del tuo dispositivo con "X":

Definisci l'ultimo blocco utilizzato del disco:

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

Quindi clonare il disco (escluso il suo spazio vuoto):

dd if=/dev/sdX bs=512 count=$ct | gzip > BACKUP_FOLDER/sdX_$(date +"%Y-%m-%d").img.gz >>"$LOG"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.