dd auf der gesamten Festplatte, aber keine leere Portion

33

Ich habe eine Festplatte, sagen wir / dev / sda.

Hier ist 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

Ich muss ein Image erstellen, das auf unserem Dateiserver gespeichert wird, damit andere Geräte, die wir herstellen, geflasht werden können. Daher möchte ich nur den verwendeten Speicherplatz (nur ca. 4 GB). Ich möchte die MBR usw. behalten, da dieses Gerät bootbereit sein sollte, sobald der Kopiervorgang abgeschlossen ist.

Irgendwelche Ideen? Ich hatte zuvor verwendet dd if=/dev/sda of=[//fileserver/file], aber zu diesem Zeitpunkt befand sich meine Masterkopie auf einem 4-GB-Flash-IDE.

Jonathan Henson
quelle
2
Alle Antworten unten sind falsch, mit Ausnahme von @sudoer. Die richtige Antwort ist zu verwenden dd conv=sparse.
Bahamat
@ Bahamat, nein, gzip ist besser, da es die Daten komprimiert.
Psusi
1
Das ist nicht dasselbe wie spärlich.
Bahamat
@ Bahamat, die Frage ist nicht speziell für Sprase gestellt; Nur, wie das Bild weniger Platz beansprucht.
Psusi

Antworten:

37

Früher hatte ich ein ähnliches Problem mit eingebetteten Linux-Distributionen: Beseitigen Sie den Müll, bevor Sie das Image komprimieren.

dd if=/dev/zero of=asdf.txt. Warten Sie, bis es stirbt. Löschen Sie asdf.txt.

Sie haben gerade Nullen in den gesamten freien Speicherplatz auf dem Gerät geschrieben.

Nehmen Sie nun ein Disk-Image und führen Sie es über gzip aus. Voila, spärliches Bild.

Vermutlich nicht sehr gut skalierbar und könnte Probleme verursachen, wenn Sie tatsächlich auf die Festplatte schreiben müssen, aber hey.

Sie können einen rsync-Schnappschuss der Festplatte auf ein anderes Volume erstellen, diesen auf Null setzen und dann das Festplatten-Image erstellen.

Hinweis: Dies kann eine Gefahr für die SSD darstellen. Der Benutzer sollte diesen Vorgang vor dem Festschreiben in Betracht ziehen.

Rob Bos
quelle
Muss ich es entpacken, bevor ich es verwende, wenn ich es über gzip ausführe? Und wenn ich es durch gzip leite, leite ich es einfach während des dd-Prozesses?
Jonathan Henson
3
Ja. dd if=sda2.gz | gunzip > /dev/sda2unddd if=/dev/sda2 | gzip > sda2.gz
Rob Bos
3
Msgstr "Sie haben gerade Nullen in den gesamten freien Speicherplatz auf dem Gerät geschrieben". Du meinst Partition, nicht Gerät, denke ich. Sie müssen diesen Befehl also mit einem ofPfad für jede Partition ausführen .
Jiggunjer
Wenn es sich bei dem physischen Medium um eine SSD handelt, wird jetzt möglicherweise angenommen, dass jeder Sektor auf dem Gerät verwendet wurde. Dies gibt der SSD weniger Ersatzsektoren für die Arbeit und verringert möglicherweise die Leistung. Wenn der Treiber und die Firmware TRIM unterstützen, gilt diese Bedingung nur, bis Sie die Datei erneut löschen. Wenn Sie die Datei beim Erstellen des Abbilds beibehalten, müssen Sie die Datei nach dem Wiederherstellen des Abbilds erneut löschen. Dies kann nützlich sein, wenn das Image auf der SSD wiederhergestellt wird.
Kasperd
Es gibt ein paar zusätzliche Bedenken zu beachten. Da für diese Methode das Dateisystem mit Lese- und Schreibzugriff bereitgestellt werden muss, besteht die Gefahr, dass Änderungen am zugrunde liegenden Dateisystem während des Kopiervorgangs zu einem inkonsistenten Image führen. Einmal habe ich gesehen, dass die resultierende Kopie so inkonsistent ist, dass fsck beim Versuch, die Inkonsistenzen auf der Kopie zu reparieren, tatsächlich einen Fehler macht. Auch das Befüllen des Geräts kann dazu führen, dass andere Prozesse, die auf das Medium schreiben müssen, fehlschlagen.
Kasperd
17

Angenommen , Sie speichern möchten /dev/sdXNzu /tgtfs/image.rawund Sie sind root:

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

  2. Verwenden Sie zerofill oder nur:, dd if=/dev/zero of=/srcfs/tmpzero.txtum nicht verwendete Blöcke mit Null zu füllen (warten Sie, bis das Dateisystem vollständig gefüllt ist rm /srcfs/tmpzero.txt).

  3. Nehmen Sie das Bild mit dd und verwenden Sie conv = sparse, um spontan Nullen zu setzen: dd conv=sparse if=/dev/sdxn of=/tgtfs/image.raw

Wenn Sie die Komprimierung verwenden möchten, müssen Sie die Nullen nicht mit dd setzen, da Nullblöcke stark komprimierbar sind:

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

PS: Sie sollten beachten, dass dies keine gute Idee auf einem Flash-Speicher-basierten Speichermedium ist (dh Ihr Quelldateisystem ist SSD).

Sudoer
quelle
5
Das ist die richtige Antwort. Verwenden Sie dd conv=sparse.
Bahamat
1
Was ist falsch daran, dies im Flash-Speicher zu tun?
Dan
2
@Dan (abhängig von Hard- und Software-Design und Konfiguration) kann es zu umfangreichen Schreibvorgängen auf Ihrer SSD kommen und deren Lebensdauer verkürzen. Außerdem ist es in Ordnung, Daten von einer alten Festplatte auf eine neue zu verschieben (oder was das OP tun wollte), aber die Sicherung auf Festplatten- / Partitionsebene ist keine gute Lösung für regelmäßige Sicherungen und Wiederherstellungen, selbst auf Festplatten. Ein Backup auf Dateiebene (dh das Kopieren von Dateien von einem Dateisystem auf ein anderes) oder ein Backup auf Dateisystemebene (mit Dateisystemen wie BTRFS mit btrfs snapshotund btrfs sendTools) ist meiner Meinung nach eine bessere Lösung.
Sudoer
Tipp: Wenn Sie gzIhre nicht haben PATH(wie ich es bei GParted Live nicht getan habe), können Sie gzip -cstattdessen verwenden.
XtraSimplicity
11

Verwenden Sie dd mit der Option count.

In Ihrem Fall haben Sie fdisk verwendet, daher werde ich diesen Ansatz wählen. Dein "sudo fdisk -l" erzeugt:

    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

Die beiden Dinge, die Sie beachten sollten, sind 1) die Einheitengröße und 2) die Spalte "Ende". In Ihrem Fall haben Sie Zylinder, die 8225280 Bytes entsprechen. In der Spalte "Ende" endet sda8 bei 525 (das sind 525 [Einheiten] * 16065 * 512 = ~ 4,3 GB)

dd kann viele Dinge tun, z. B. nach einem Versatz beginnen oder nach einer bestimmten Anzahl von Blöcken anhalten. Letzteres machen wir mit der count-Option in dd. Der Befehl würde folgendermaßen aussehen:

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

Wobei -bs die Blockgröße ist (es ist am einfachsten, die von fdisk verwendete Einheit zu verwenden, aber jede Einheit tut dies, solange die Option count in diesen Einheiten deklariert ist), und count ist die Anzahl der Einheiten, die wir kopieren möchten (Anmerkung) dass wir die Zählung um 1 erhöhen, um den letzten Block zu erfassen).

Tom Looby
quelle
Zu fdisk -l -u=cylinders /dev/sda
Ihrer Information
3
Warum ist das nicht die akzeptierte Antwort? Dies scheint die am wenigsten aufdringliche Option zu sein, da die Quelle nicht geändert wird.
user33326
@ user33326, da diese Antwort gut ist, um nicht partitionierten Speicherplatz auf einem Laufwerk nicht zu kopieren, nicht unbenutzten Speicherplatz innerhalb von Partitionen, worum es im OP geht.
GDorn
8

Während es möglich ist, /dev/zeroden freien Speicherplatz zu nutzen und dd conv=sparse/ zu nutzen, gz -cist es auf riesigen Festplatten mit einem leeren Speicherplatz von 100 GB /dev/zeroschmerzhaft langsam - ganz zu schweigen davon, dass /dev/zeroeine SDD bis EOF benötigt wird.

Folgendes habe ich getan, als ich auf diese Situation gestoßen bin:

  • Bei einer Lubuntu-Live-CD wird gparteddie Festplatte auf die kleinstmögliche Größe verkleinert, wobei der Rest des Speicherplatzes nicht zugewiesen wird

  • Wird
    dd bs=1M count=<size_in_MBs> if=/dev/sdX | gzip -c --fast| dd of=/path/to/image.gz zum Erstellen des schnell komprimierten Images verwendet (natürlich möchten Sie die Komprimierung möglicherweise überspringen, wenn Sie über ausreichend Speicherplatz zum Speichern von Rohdaten verfügen (oder auf andere Weise dazu neigen, die CPU-Belastung zu verringern).

  • Dient
    dd if=/path/to/image.gz | gunzip -c | dd bs=1M of=/dev/sdY zum Zurückkopieren der Daten auf eine andere Festplatte
  • Wird gpartederneut verwendet, um die Partition zu erweitern

Ich habe es nicht für mehrere Partitionen ausprobiert, aber ich glaube, der obige Prozess kann zum Kopieren von 'Partitionen' angepasst werden, wenn zuerst eine Partitionstabelle auf der Zieldisk erstellt wird und nur die in der Partition enthaltenen Daten über dd- Lesen / Schreiben von Offsets ( skip/ seekoption of dd, resp.) wäre gegebenenfalls erforderlich.

Ashish Chopra
quelle
1
Dies ist die eigentliche Antwort, verwenden Sie einfach den countParameter
Gordy
7

Das kannst du nicht. ddist ein sehr einfaches Tool und kann nicht zwischen Dateien und leerem Speicher unterscheiden.

Auf der anderen Seite wird der leere Raum sehr, sehr schön komprimiert. Wenn Sie sich also nur um den Speicherplatz kümmern, nicht zum Beispiel um die Schreibzeit, leiten Sie ihn einfach durch gzip.

c2h5oh
quelle
7
Angenommen, der freie Speicherplatz wurde zuvor nicht verwendet. Sie können den freien Speicherplatz zuerst mit Null füllen, um sicherzustellen, dass die Komprimierung wie erwartet funktioniert.
Sirex
1
Wahr. Das verkompliziert den Prozess und macht ihn noch länger.
c2h5oh
6

Angenommen, der Rest des Laufwerks ist leer (alle Nullen), könnten Sie Ihre DD durch gzip leiten, was den leeren Raum recht gut komprimieren sollte. Sie können ein Werkzeug wie nullfrei verwenden , um sicherzustellen, dass Ihr leerer Bereich tatsächlich leer ist, sodass er gut komprimiert wird.

Wenn Sie ein Tool wie partimage , clonezilla oder eines der anderen Linux-Klon-Tools verwenden, erledigen diese das meiste automatisch für Sie.

Zoredache
quelle
partimage und clonezilla sind eigentlich klug genug, um das Lesen des freien Speicherplatzes zu überspringen , anstatt sich darauf zu verlassen, dass Sie Nullen darauf schreiben, und dann dd oder gzip die Nullen nach dem Einlesen
ablegen
2

Die akzeptierte Antwort ist nicht richtig. Ich stimme dem obigen Kommentar zu. Ich benutze dd mit Parameter count , um meine Festplatte regelmäßig zu sichern. Ersetzen Sie einfach den BACKUP_FOLDER und den Buchstaben Ihres Geräts durch "X":

Definieren Sie den zuletzt verwendeten Block der Festplatte:

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

Dann klonen Sie die Festplatte (mit Ausnahme des leeren Speicherplatzes):

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