Dd: Unterschied zwischen den Versionen

Aus Linupedia.org
Wechseln zu: Navigation, Suche
K (Grobgliederung)
(Partitionen und Platten Teil 1)
Zeile 1: Zeile 1:
{{UnderConstruction}}  --[[Benutzer:Robi|Robi]] 19:40, 7. Jul 2007 (CEST)
+
==== einzelne Partitionen und ganze Platten mit dd ====
 
 
= das Kommando dd =
 
 
 
 
 
== allgemeines zum Kommando dd ==
 
 
 
dd ist ein Kommando das noch aus der Urzeit von UNIX stammt. Der Name sollte früher ''Copy and Convert'' bedeuten, das Programmkürzel cc war jedoch schon an den C-Compiler vergeben. Daher kam es wohl kurzerhand zu dd. Heute wird dieses Kürzel oftmals als '''disk dump''' oder ähnlich übersetzt, ursprünglich sollte es wohl doch mehr an das [http://de.wikipedia.org/wiki/Job_Control_Language JCL]-Kommando "Data Definition" erinnern, auch die für UNIX-Befehle doch sonderbaren Optionensschreibweisen erinnern noch sehr stark an diese Abstammung.
 
 
 
Das UNIX-Kommando dd dient dem Umleiten von Datenstömen. Dabei kann es diese Datenströme Byteweise bearbeiten und universell blocken. Als Quelle und Ziel der Datenströme können sowohl normale Dateien, die normalen Ein- und Ausgabekanäle der Prozesse und auch Geräteknoten verwendet werden. In früherer Zeit benötigte man das Programm dd , um inkompatible Formate und Zeichensätze zwischen unterschiedlichen Betriebssystemen und Geräten zu kopieren, und um Daten auf externen Peripheriegeräten (oftmals Bandgeräte) lesen und schreiben zu können.
 
 
Typischen Beispielaufgaben aus dieser Zeit könnten heute auf Linux etwa so ausgesehen:
 
*  Auslesen eines [http://de.wikipedia.org/wiki/EBCDIC EBCDIC]-Bandes (80 Zeichen pro Record, 10 Records pro Block, Dichte 1600 bpi) Ausgabe als [http://de.wikipedia.org/wiki/ASCII Ascii]-Datei:
 
    dd if=/dev/nst1 of=/datei ibs=800 cbs=80 conv=ascii,lcase
 
 
 
Für Konvertierungsaufgaben benötigt man heute dd nur noch wenig. Dort wo noch mit solchen inkompatiblen Daten gearbeitet wird, benutzt man heute meist Programme die schon die entsprechende Ein- und Ausgabefilter mitbringen. Wohl aber benötigt man auch heute noch die universellen Bockungsmöglichkeiten von dd in Bezug auf Datenströme und Geräteknoten sowie die Möglichkeit im Datenstrom gezielt zu positionieren. Besondere "Berühmtheit" hat heutzutage jedoch die Möglichkeit erlangt, Partitionen und ganze Festplatten bytegenau zu kopieren, was fälschlicher Weise dazu verleitet mag dd auch noch in den Rang eines [[Liste_von_Backupprogrammen|Backuptools]] zu erheben.
 
 
 
 
 
 
 
 
 
== die Optionen von dd ==
 
 
 
Die Optionen von dd unterscheiden sich grundlegend von denen der meisten UNIX/Linux Kommandos. Eine Übersicht erhaltet ihr mit der Option '''--help''' oder der
 
[http://usr-share-man.org/man1/dd.html Manpage von dd] ''( Achtung: evtl. sind nicht alle Optionen in eurer installierten Version vorhanden)''. Auch eine Infoseite "'''info:/coreutils/dd invocation'''" sollte bei vielen installiert sein.
 
 
Die genaue '''SYNOPSIS''' ''(ältere Version)''<br>
 
dd [--help] [--version] [if=file] [of=file] [ibs=bytes] [obs=bytes] [bs=bytes] [cbs=bytes] [skip=blocks]
 
[seek=blocks] [count=blocks] [conv={ascii, ebcdic, ibm, block, unblock, lcase, ucase, swab, noerror, notrunc, sync}]
 
 
 
{| border="0"
 
|+ ''' Die wichtigsten Optionen im Überblick '''
 
 
 
!''if=Datei''
 
||
 
Der Datenstrom, der umgeleitet werden soll. Das kann eine Datei oder Gerätedatei, also auch eine Festplatte oder ein anderes Gerät sein.  Wird ''if'' weggelassen liest dd von der Standardeingabe.
 
|-
 
!''of=Datei''
 
||
 
Die Datei, auf die geschrieben werden soll. Dies kann wieder eine Datei oder ein Gerät sein. Wird ''of'' weggelassen schreibt ''dd'' auf die Standardausgabe.
 
|-
 
!''ibs=Bytes'' 
 
||
 
Eingabe-Blockgröße (''input block size''), gibt an, wie viele Bytes auf ein Mal gelesen werden sollen.
 
|-
 
!''obs=Bytes'' 
 
||
 
Ausgabe-Blockgröße (''output block size''), gibt an, wie viele Bytes auf ein Mal geschrieben werden sollen.
 
|-
 
!''bs=bytes''
 
||
 
Kurzschreibweise für ''ibs=bytes obs=bytes''. Der Standardwert bei Nichtangabe ist 512 Bytes.
 
|-
 
!''count=Blocks'' 
 
||
 
Angabe, um nur eine begrenzte Menge Blöcke zu kopieren.
 
|-
 
!''skip=Blocks'' 
 
||
 
Angabe, um eine Anzahl Blocks zu überspringen.
 
|-
 
!''seek=blocks'' 
 
||
 
Überspringt diese Anzahl Blöcke beim schreiben auf die Ausgabe.
 
|-
 
!''conv=Schlüsselwörter '' 
 
||
 
Wandelt den Datenstrom entsprechend einer Kommagetrennten Liste von Schlüsselwörtern.
 
|-
 
!''cbs=Bytes'' 
 
||
 
Umwandlungs-Blockgröße (convert block size): Größe der Blöcke zum Umwandeln auf ein Mal.
 
|}
 
  
 +
Das kopieren, klonen, oder als Image ablegen und wieder zurückschreiben von einzelnen Partitionen und ganzen Platten mittels dd, so wie es in unzähligen  Beiträgen beschrieben ist, ist und bleibt eine riskante Angelegenheit, solange man sich nicht bewußt ist, was man da eigentlich genau macht.<br>
 +
Es werden genau genommen jedes Byte der Festplatte oder der Partition genau so gelesen, wie sie derzeit auf der Platte gespeichert sind, und wieder zurückgeschrieben wie sie zum jeweiligen Zeitpunkt des Lesens auf der Festplatte vorhanden waren. [[# Allgemeine Bemerkungen und Warnungen| (siehe auch die allgemeinen Warnungen)]] Somit benötigt man ein zweites Medium, das auch groß genug ist, diese Daten auch wirklich aufzunehmen, den ein Image einer 200GB Festplatte ist nun einmal 200GB groß, auch wenn nur 10% davon mit Dateien belegt sind. Pinzipiell ist es demnach umso interessanter, je kleiner die Festplatte oder die Partition ist, und um so mehr Daten darauf aktuell abgelegt sind.  Solange man ein solches Image dann auch wieder auf die gleiche Festplatte oder in die gleiche Partition zurück schreibt, ist das auch relativ ungefählich. Wird eine größere Festplatte zum zurückspielen benutzt, dann wird die größere Festplatte auf die Orginalgröße der ursprünglichen Festplatte "herunterkonfiguriert", ein Benutzen des übrigen unbenutzten Festplattenplatzes ist erst einmal ausgeschlossen und Versuche diesen doch noch nutzbar zu machen, sind sehr riskant für die Daten auf dieser Platte. Eine zu kleine Festplatte würde dann mindestens ein unvollständiges Filesystem ergeben, das sich gar nicht mounten läßt. Das selbe gilt für Partitionen analog. Sehr gefährlich ist zB. ein zurückschreiben von erweiterten und logischen Partitionen, wenn sich die Partitionstabelle geändert hat, bzw auf eine andere logische oder erweiterte Partition. Hierbei ist es durchaus möglich, das nach dem nächsten booten ein Teil der Daten auf der  Platte gar nicht mehr  aufzufinden sind. 
  
=== die Ein- und Ausgabefile ===
 
  
Beide Filenamen werden in den Optionen angegeben nach folgenem Prinzip
+
===== Beispiele Clonen, Backup und Sicherung =====
if=/PATH/EINGABEDATEI  #die Datei oder Gerät aus dem gelesen wird
 
of=/PATH/AUSGABEDATEI  #die Datei oder Gerät auf das geschrieben wird
 
sollte einer oder beide nicht explizid so angegeben werden, dann wird von dd automatisch mit dem entsprechenden Standard-Ein/Ausgabe-kanal gearbeitet. Man kann immer jeweils nur einen Dateinamen angeben es geht also weder eine Space- noch Kommaseparierte Kiste und auch die Shell übernimmt hier keine Path- oder Filenamensexpansionen. Nur relative und absolute Dateiadressierung sowie die '''tilde expansion''' sind zulässig, ansonsten sind immer komplette Path und Dateinamen anzugeben. Auf den Inhalt von Variablen für die Dateinamen kann zugegriffen werden, soweit im Dateinamen Sonderzeichen enthalten sind muß das aber im dd-Komando unbedingt berücksichtigt werden.<br>
 
Beispiel:
 
NULL=/dev/null                 
 
INFILE="/home/user/datei orginal"
 
dd if="$INFILE" of=$NULL
 
  
{{Box Achtung||
+
Es gilt, möglichst alle Filesysteme ungemountet auslesen, wo das nicht möglich ist, zumindestens '''Readonly''' gemountet auslesen und dann auf das Image einen [http://www.phpman.info/index.php?parameter=fsck.ext3&mode=man Filesystemcheck] machen.  
Beim Zugriff auf Geräteknoten, also zB Festplatten, Partitionen, Bandgeräte usw. immer einmal mehr prüfen ob nicht doch '''if''' und '''of''' verwechselt wurden. Es droht hier bei Verwechslungen unter Userkennung root Datenverlust.  
 
}}
 
  
=== die Blockgröße ===
+
einzelne Partition als Image ablegen / Image temporär mounten / zurückschreiben
 +
# dd if=/dev/hda2 of=/PATH/DATEI.IMAGE bs=8K
 +
# mount -o loop /PATH/DATEI.IMAGE /mnt      # eventuell weitere Mountoptionen notwendig
 +
# dd if=/PATH/DATEI.IMAGE of=/dev/hda2 bs=8K
  
Die Blockgröße gibt an, wieviele Byte bei einem read- oder write-Kommando gleichzeitig verarbeitet werden. Im Normalfall ist man unter Linux ja gewohnt, dass man sich darum überhaupt nicht kümmern muss, das macht Linux im Hintergrund für uns immer richtig. Da wird zB von der Tastatur jedes einzelne Zeichen gelesen, Eingaben werden Zeilenweise nach Bestätigung der ENTER-Taste verarbeitet, auf die Festplatte wird mittels des Caches mit 4KB Blockgröße lesend und schreibend zugegriffen, über Internet werden Pakete mit maximaler Größe von 1500 Byte gesendet usw. Alles Dinge von denen wir gar nichts mitbekommen, und von denen wir auch die meisten überhaupt nicht beeinflussen könnten, selbst wenn wir das wollten.
+
Filesystemtype und Zustand eines Images ermitteln/korrieren (Konsolauszug)
 
 
Anders jedoch beim Befehl dd. Hier arbeitet der Befehl, sollten wir nichts anderes angeben, immer mit 512 Byte lesend und schreibend und hier können wir das sowohl beim lesenden- wie auch den schreibenden-Zugriff und sogar getrennt beeinflussen.<br>
 
 
 
'''Zu was soll das gut sein, werden sich die meisten fragen'''.<br>
 
Eine Regentonne voll mit Wasser kann man sowohl mit einem Eimer, mit einer Suppenkelle aber auch mit einem Kaffeelöffelchen leerschaufeln, was ist wohl die schnellste und rückenschonendste Methode? Ähnlich verhalten sich viele Geräte wenn wir direkt zB über dd auf sie zugreifen.
 
 
 
Im folgende Beispiel wird eine kleine Partition einer SCSI-Platte mit "NULLEN" überschrieben, wobei mit der Blockgröße von dd gespielt wird. <br>
 
  time dd if=/dev/zero of=/dev/sdb1 bs=512
 
(wobei bei bs= die Werte 16 64 512 2K 8K 32K und 128K zum Einsatz kamen)
 
 
{| border="1"
 
! width="20%" | Blockgröße
 
! width="20%" | real time
 
! width="20%" | user time
 
! width="20%" | sys time
 
|-
 
!16 Byte
 
|| 2m26.593s|| 0m7.898s || 1m2.839s
 
|-
 
!64 Byte
 
|| 1m39.600s ||0m2.734s  || 0m23.812s
 
|-
 
!512 Byte
 
|| 1m18.710s||0m0.465s  ||  0m6.942s
 
|-
 
! 2 KByte
 
||1m16.131s  ||0m0.100s || 0m3.552s
 
|-
 
! 8 KByte
 
|| 0m29.137s || 0m0.016s  ||  0m1.299s
 
|-
 
! 32 KByte
 
|| 0m29.159s || 0m0.012s ||  0m1.507s
 
|-
 
! 128 KByte
 
|| 0m29.115s || 0m0.003s || 0m1.474s
 
|}
 
Wir erkennen, die default Einstellung von dd (512 Byte) ist zwar auf dieser Platte nicht die Allerschlechteste, aber es geht durchaus noch 3 Mal schneller. Da moderne Festplatten in der Regel heute einen Cache haben der zumindestens beim Lesen genutzt ist, ergeben sich beim Lesen von Partitionen oder ganzen Festplatten oftmals ganz andere (weniger unterschiedliche) Werte.
 
 
 
Wesentlich gravierender sind die Unterschiede jedoch bei Bandlaufwerken, es gibt verschiedene Möglichkeiten wie  das Laufwerk die ihm übertragene Blockgröße interpretieren soll, man muss prinzipiell jeden Block mit der selben Blocksize lesen mit der der Block auch geschrieben wurde, eine ungünstige Blockgröße kostet nicht nur Zeit sondern bedeutet auch erhöhten Verschleiß an Bandmaterial und Laufwerk und nicht zuletzt auch noch ein höheres Fehlerrisiko. Wer sich näher damit befassen will oder muss kann unter [[Bandlaufwerke_und_LINUX|Bandlaufwerke und Linux]] und speziell über die  [[Bandlaufwerke_und_LINUX#Die_richtige_Blockgröße|richtige Blockgröße bei Bandlaufwerken]] im Wiki näher infomieren.
 
 
 
 
 
Es gibt im Internet die abendteuerlichsten Berechnungsmodelle für die "richtige Blockgröße" von dd für den Zugriff auf Festplatten. Man geht dabei von der Ausgabe des [http://www.die.net/doc/linux/man/man8/fdisk.8.html fdisk-Befehles] aus, und errechnet aus den dort ausgegebenen Werten der Köpfen, Sektoren, Cylindern und Units irgendwie eine "optimale Blockgröße" und kommt dann auf solche Werte wie zB. 16065 Byte.[http://linuxwiki.de/dd ] <br>
 
Abgesehen, dass solche Werte dann manchmal nicht einmal durch 512 (die kleinste Speichereinheit auf einer Festplatte) teilbar sind, schon eine einfache Überlegung müsste den völligen Unsinn eines solchen Unterfangens aufzeigen. <br>
 
 
<pre>
 
<pre>
LINUX:~ # fdisk -l /dev/sdb
+
LINUX:/ # file DATEI.IMAGE
 +
DATEI.IMAGE: Linux rev 1.0 ext2 filesystem data (mounted or unclean)
 +
LINUX:/ # fsck /PATH/DATEI.IMAGE  # evtl. weitere Optionen notwendig ; kompletten Path des Images
 +
fsck 1.38 (30-Jun-2005)
 +
e2fsck 1.38 (30-Jun-2005)
 +
/PATH/DATEI.IMAGE was not cleanly unmounted, check forced.
 +
Pass 1: Checking inodes, blocks, and sizes
 +
Pass 2: Checking directory structure
 +
Pass 3: Checking directory connectivity
 +
Pass 4: Checking reference counts
 +
Pass 5: Checking group summary information
 +
/PATH/DATEI.IMAGE: 72/16632 files (12.5% non-contiguous), 24776/66432 blocks
 +
LINUX:/ # file DATEI.IMAGE
 +
DATEI.IMAGE: Linux rev 1.0 ext2 filesystem data
 +
</pre>
  
Disk /dev/sdb: 18.2 GB, 18275768320 bytes
+
einzelne Partition auf eine Festplatte mit identischem Partitionstabelle kopieren
255 heads, 63 sectors/track, 2221 cylinders
+
# dd if=/dev/hda2 of=/dev/hdb2 bs=8K
Units = cylinders of 16065 * 512 = 8225280 bytes
 
.......
 
</pre>
 
Diese Festplatte, die laut Hersteller 5 Scheiben mit je 2 Köpfen hat, sollte jetzt plötzlich 255 Köpfe haben. Damit müsste sie nach heutiger Bauweise in etwa 30 bis 35 cm dick sein und hätte ein stattliches Gewicht von einigen kg. Also absolute Vorsicht mit solchen Berechnungen. Die heutigen Platten verwalten intern ihre eigene [http://de.wikipedia.org/wiki/Festplattengeometrie Geometrie] und werden von außen nur über [http://de.wikipedia.org/wiki/Logical_Block_Addressing LBA] angesprochen. Die Geometrie die uns zB ''fdisk'' nach außen zeigt ist eine reine logische die mit der tatsächlichen nur eines gemein hat, die ungefähre (etwas kleiner) Gesamtgröße, und kann mit Befehlen wie zB. ''fdisk'' bei Bedarf auch angepasst oder geändert werden.
 
  
Die optimalsten Werte sind von eine Vielzahl von vor allem baulichen Faktoren abhängig und werden heute in vielen Geräten obendrein noch über Cache in den Geräten gepuffert, womit man mit größeren Werten nie falsch liegen kann.<br>
+
ganze Festplatte als Image ablegen / zurückschreiben
Prinzipiell, (wenn keine anderen Faktoren dagegen sprechen- siehe Positionierung im Datenstrom) nur Werte die durch 512 teilbar sind, für Disketten, kleine Speicherkarten und kleine Sticks und ganz alte oder schon teilweise defekte Platten 512 Byte, für die restlichen Platten 4 oder 8 KByte, bei CD-ROM und DVD 1 oder 2 KByte und für [http://de.wikipedia.org/wiki/Magneto_Optical_Disk MO-Disk] [http://de.wikipedia.org/wiki/Ultra_Density_Optical UDO] und andere [http://de.wikipedia.org/wiki/WORM WORM], nur die vom Hersteller und der jeweiligen Technologie vorgeschriebenen Blockgröße, und man sollte auf der richtigen Spur sein.
+
# dd if=/dev/hda of=/PATH/DATEI.IMAGE bs=8K
 +
# dd if=/PATH/DATEI.IMAGE of=/dev/hda bs=8K
 +
man kann von einem solchem Image auch [http://www.linux-club.de/viewtopic.php?t=79797 einzelne Partitionen temporär gemounten], dabei muss für das [http://www.phpman.info/index.php?parameter=mount&mode=man mount] der jeweilige Offset benutzt werden.  
  
  
=== Positionierung innerhalb des Datenstrom ===
+
Festplatte auf einen andere Festplatte klonen
 +
# dd if=/dev/hda of=/dev/hdb bs=8K
  
Als Datenstrom bezeichnen wir hier mal alles, womit dd arbeiten kann, also zB. Pipe, Datei, Gerät,... <br>
 
DD kennt als Bezugspunkt immer nur den Anfang von Eingangsstrom und Anfang vom Ausgangsstrom. Da man aber nicht immer den kompletten Eingangsstrom bis zum Ende auf Ausgangsstrom von Anfang an kopieren will, muss man innerhalb dieser beide Datenströme auch positionieren können. Das geht mit den Optionen '''skip= seek=''' und '''count=''' und diese sind jeweils von den gesetzten Blockgrössen abhängig.
 
  
Wenn wir dd ohne solche Positionierungs-Optionen starten, dann kopiert dd den Eingangsdatenstrom von Anfang bis ein EOF ('''E'''nd '''O'''f '''F'''ile) kommt, komplett auf den Ausgangsdatenstrom. Bei Lese- oder Schreibfehlern wird an dieser Stelle dd abgebrochen. Ein EOF kann das Ende einer normalen File sein, aber auch zB der Abbruch eines am Eingang über Pipe verbundenen Befehles. Auch der Versuch zB. über eine Gerätegrenze (zB Partition zu Ende) zu lesen oder schreiben, führt zu einen EOF Fehler.
 
  
Die Gesamtanzahl der zu kopierenden Blöcke kann mit der Option '''count=''' begrenzt werden. <br>
+
===== Problem Komprimierung von dd-Image =====
count=100   
 
kopiert genau 100 Blöcke ( Eingangsblockgröße )
 
 
 
Es können am Eingangsstrom anfänglich Blöcke (Eingangsblockgröße) übersprungen werden, die dann nicht mit kopiert werden, und die auch nicht von einem eventuell gesetzem count-Wert abgezogen werden. Die Option dazu ist '''skip='''<br>
 
skip=100 count=50 
 
kopiert genau 50 Blöcke (Eingangsblockgröße) wobei am Anfang 100 (Eingangsblockgröße) übersprungen werden, bevor mit dem kopieren begonnen wird.
 
 
 
Es können am Ausgangsstrom anfänglich Blöcke (Ausgangsblockgröße) übersprungen werden bevor der erste Block dorthin kopiert wird. Diese Option ist '''seek='''.<br>
 
seek=100 count=50
 
kopiert die ersten 50 Blöcke (Eingangsblockgröße) vom Eingangstrom  ab dem 101 Block (Ausgangsblockgröße) in den Ausgangsstrom. (''Die ersten 100 Blocke der Größe obs= bleiben also im Ausgangsstrom unberührt, erst danach kommt der erste kopierte Block'') Diese Option macht nicht mit allen Ausgangsdatenströmen Sinn, und führt zB. in Verbindung mit der Standardausgabe zum "hängenbleiben" des Befehles, da ja erstmal auf Daten gewartet werden muss, die gar nicht kommen können. Beim Anwenden auf normale Dateien führt ein zu großer seek-Wert (größer als Ausgangsdatei) zum weiterschreiben der Datei am Ende.
 
 
 
 
 
Soweit zur Theorie und zu den wichtigsten Optionen
 
 
 
 
 
 
 
 
 
== die Ausgaben von dd ==
 
 
 
Wir untersuchen dazu einmal exemplarisch eine Ausgabe eines dd-Befehls, hier wurde von der Partition /dev/sda2 mit einer Blockgröße von 8KByte gelesen und auf ein Tape /dev/nst0 mit 256 KByte Blockgröße geschrieben.
 
<pre>
 
LINUX:~ # dd if=/dev/sda2 of=/dev/nst0 ibs=8K obs=256K
 
262256+0 records in
 
8195+1 records out
 
2148401152 bytes (2.1 GB) copied, 74.8721 seconds, 28.7 MB/s
 
</pre>
 
; 262256+0 records in :
 
es wurden '''262256''' Blöcke a. 8K gelesen, die '''+0''' bedeuten, es gab am Ende keine Rest, also der letzte Block hatte wirklich auch 8K Größe.
 
 
 
 
 
; 8195+1 records out :
 
es wurden '''8195''' Blöcke a. 256K geschrieben, die '''+1''' bedeutet, es wurde zusätzlich noch ein Restbock geschreiben, der nicht die volle Größe von 256K hatte. Wenn mit der Option "bs=" gearbeitet wird, oder die Blockgrößen sonst wie für Ein/Ausgabe gleich sind, dann sollten bei einem ordnungsgemäßen Ablauf des Befehls beide Werte immer gleich ausfallen.
 
 
 
 
 
;2148401152 bytes (2.1 GB) copied, 74.8721 seconds, 28.7 MB/s :
 
die Schlußzeile erhalten wir nur in neueren Versionen von dd. Sie beinhaltet hier die Gesamtanzahl der übertragenen Byte die Zeit und die durchschnittliche Geschwindigkeit.
 
 
 
 
 
Solange der Befehl dd läuft erhalten wir ansonsten von ihm keinerlei Ausgaben. Wir können uns aber den Status der aktuell übertragenen Daten in der oben beschriebenen Form anzeigen lassen, wenn wir dem dd-Prozess ein Signal 10 '''(SIGUSR1)''' senden. Alle diese Ausgaben kommen über den Standardfehlerausgabekanal des Prozesses dd.
 
 
 
 
 
 
 
 
 
== Anwendungsgebiete und Beispiele ==
 
 
 
=== mit dd Dateien erzeugen ===
 
 
   
 
   
Hin und wieder benötigt man spezielle Dateien in bestimmter Größe und mit typischen oder speziellen Inhalt. Das können einfach Dateien sein, die man zum testen benötigt oder auch Dateien um darin Filesysteme anzulegen oder oder oder.<br>
+
Hin und wieder besteht die Notwendigkeit ein solches Image zu komprimieren, weil eben nur wenige wirkliche Daten auf der Platte/Partition liegen. Dabei wird man auf das Problem stoßen, das kann recht gut funktionieren aber muss nicht. Das liegt dann meistens an den zur Zeit nicht benutzten oder gelöschten Datenblöcken. Sind diese zum großen Teil nicht oder nicht richtig komprimierbar, dann wird man auch wenig Erfolg bei der Komprimierung der gesamten Platte/Partition haben.<br>
Das geht mit dd sehr einfach. Wir benötigen nur einen Quelldatenstrom dazu. Auf die Blockgrößen brauchen wir hier meistens gar nicht zu achten (eventuell/selten könnte aber der gewünschte Quelldatenstrom eine Blockgröße fordern), da das Filesystem in das wir unsere Datei schreiben sowieso gebuffert ist, also können wir mit '''bs=''' und '''count=''' unsere gewünschte eindeutige Dateigröße sehr schön festlegen.
+
Nachfolgend eine Möglichkeit wie man die leeren/unbenutzten Datenblöcke einer Partition sehr gut komprimierbar machen kann, ohne das die richtigen Daten dabei beschädigt werden. Man legt einfach neue "NULL"-Dateien an bis das Filesystem fast voll ist, danach löscht man sie wieder. Wir machen uns hier zum Vorteil, dass ein normaler User im Normalfall auf LINUX-Filesystemen nur bis zu 95% voll auf ein Filesystem schreiben kann. Ausnahme natürlich wenn [[Disk Quota]] eingerichtet ist.
Blockgröße x Count = Dateigröße
 
 
 
 
 
 
 
==== Erzeugen einer mit Nullen gefüllten Datei ====
 
  
Als Quelldatenstrom nutzen wir dazu '''/dev/zero''' ( nicht /dev/null , da beim lesen von /dev/null nur ein EOF zurückgeliefert wird und wir eine Datei mit Länge Null erhalten würden)
+
Als root in das Filesystem ein neues Verzeichnis anlegen und für Schreibrechte des Users sorgen
<pre>
+
# mkdir /PATH/test
robi@LINUX:~/test> dd if=/dev/zero of=file.leer bs=1M count=1024
+
# chmod a+w /PATH/test
1024+0 Datensätze ein
 
1024+0 Datensätze aus
 
</pre>
 
erzeugt eine 1GB große (ergibt sich aus 1MByte x 1024) Datei voller Nullen
 
  
==== Erzeugen von Sparse Dateien ====
+
Danach als User folgendes Script ausführen
 
<pre>
 
<pre>
robi@LINUX:~/test> dd if=/dev/zero of=file.sparse count=0 obs=1 seek=1G
+
#!/bin/bash
0+0 Datensätze ein
+
VERZEICHNIS=/PATH/test
0+0 Datensätze aus
 
robi@LINUX:~/test> ls -l file.*
 
-rw-r--r--  1 robi users 1073741824 2007-06-29 23:37 file.leer
 
-rw-r--r--  1 robi users 1073741824 2007-06-30 01:24 file.sparse
 
-rw-r--r--  1 robi users 1073741824 2007-06-30 00:12 file.zufall
 
robi@LINUX:~/test> stat file.sparse
 
  File: ,,file.sparse"
 
  Size: 1073741824      Blocks: 0          IO Block: 4096  reguläre Datei
 
Device: 802h/2050d      Inode: 1038268    Links: 1
 
Access: (0644/-rw-r--r--)  Uid: ( 1001/    robi)  Gid: (  100/  users)
 
Access: 2007-06-30 01:24:39.168204352 +0200
 
Modify: 2007-06-30 01:24:39.168204352 +0200
 
Change: 2007-06-30 01:24:39.168204352 +0200
 
</pre>
 
Schreibt 0 Mal 1 Byte  ab Position 1073741824 und erzeugt somit ein 1GB große [http://de.wikipedia.org/wiki/Sparse-Datei Sparse Datei]
 
Man erkennt es eindeutig an der scheinbaren Differenz zwischen '''Size''' und der Anzahl der benutzen '''Blocks''' mit [http://www.die.net/doc/linux/man/man1/stat.1.html stat]
 
  
{{Box Achtung||
+
dd if=/dev/zero of=/tmp/file.null count=1024 bs=1K 2>/dev/null
An solchen sparse Dateien ist schon mancher Adim zB bei Backups verzweifelt, man kann ein solches File durch umkopieren mit cp in ein normales Files umwandeln.
+
echo "anlegen von Dateien bitte warten"
}}
+
for i in {a..z}{a..z}{a..z}
 
+
  do
==== Erzeugen einer Datei gefüllte mit Zufallszahlen ====
+
  for j in {0..9}{0..9}{0..9}{0..9}
 
+
  do
Als Quelldatenstrom nutzen wir dazu unter Linux '''/dev/urandom''' (nicht /dev/random , das dauert sonst viel viel zu lange und bringt auch nur das selbe Ergebnis)
+
      NAME=${VERZEICHNIS}/leer$i$j
<pre>
+
      cp /tmp/file.null $NAME 2>/dev/null || break 2
robi@LINUX:~/test> dd if=/dev/urandom of=file.zufall bs=1M count=1024
+
  done
1024+0 Datensätze ein
+
done
1024+0 Datensätze aus
+
rm /tmp/file.null
robi@LINUX:~/test> hexdump -C file.zufall | more
 
00000000  60 b2 03 a4 f5 13 46 d0  25 a4 f2 09 1c 31 9f 3f  |`².€õ.FÐ%€ò..1.?|
 
00000010  17 b0 8e 32 af a0 87 67  cf 87 2c 4f 6d 92 de 4d |.°.2¯ .gÏ.,Om.ÞM|
 
00000020  38 3c a2 29 58 09 fd b7 ........
 
.......
 
</pre>
 
Als Größe wurde hier wieder wie schon oben 1GByte festgelegt. Mit [http://bashcurescancer.com/man/cmd/hexdump hexdump] haben wir gleich mal hineingeschaut, ob auch alles schön zufällig ist. ;-)
 
 
 
 
 
==== Erzeugen einer Datei mit typischen Eigenschaften und genau definierter Länge ====
 
 
 
Die unterschiedlichen Dateien haben unterschiedliche Eigenschaften zB beim Komprimieren. ZB. Zufallsdateien lassen sich überhaupt nicht komprimieren, Dateien mit lauter Nullen dagegen extrem, Logdateien sehr gut, Textdateien auch noch gut, aber Binärdateien nicht besonders gut. Wenn wir jetzt so eine Datei mit solchen typischen Komprimierungseigenschaften zu Testzwecken benötigen, dann können wir und mit dd eine solche mit genaue definierter Länge erzeugen.
 
 
 
Als Beispiel wollen wir hier eine genau 5MByte große Datei aus einigen Bilddateien erzeugen.
 
<pre>
 
robi@LINUX:~/test> ls -l bild*.jpg
 
-rw-r--r--  1 robi users 277960 2007-06-29 22:34 bild0.jpg
 
-rw-r--r--  1 robi users 312872 2007-06-29 22:48 bild10.jpg
 
-rw-r--r--  1 robi users 120061 2007-06-29 22:08 bild1.jpg
 
-rw-r--r--  1 robi users 164171 2007-06-29 22:10 bild2.jpg
 
-rw-r--r--  1 robi users 179737 2007-06-29 22:13 bild3.jpg
 
-rw-r--r--  1 robi users 173341 2007-06-29 22:13 bild4.jpg
 
-rw-r--r--  1 robi users 165532 2007-06-29 22:14 bild5.jpg
 
-rw-r--r--  1 robi users 161892 2007-06-29 22:16 bild6.jpg
 
-rw-r--r--  1 robi users 126340 2007-06-29 22:17 bild7.jpg
 
-rw-r--r--  1 robi users 125396 2007-06-29 22:19 bild8.jpg
 
-rw-r--r--  1 robi users 289134 2007-06-29 22:21 bild9.jpg
 
robi@LINUX:~/test> cat bild*.jpg bild*.jpg bild*.jpg bild*.jpg | dd of=file.bild bs=1024K count=5
 
5+0 Datensätze ein
 
5+0 Datensätze aus
 
robi@LINUX:~/test> ls -l file.bild
 
-rw-r--r--  1 robi users 5242880 2007-06-30 00:40 file.bild
 
 
</pre>  
 
</pre>  
Unsere Bilddateien haben zusammen nicht ganz 2 MB Größe, Wir Nutzen desshalb [http://linuxreviews.org/man/cat/index.html.de cat] , um die Dateien aneinander zu hängen, und da die Gesammtgröße aller Dateien nicht ausreichen würde, haben wir sie einfach durch  '''"bild*.jpg bild*.jpg bild*.jpg bild*.jpg"''' mehrere Male angegeben, (4 Mal sollte dann hier dicke reichen). ''(wenn man hier bei anderer Gelegenheit einmal zu viele Dateien dazu verwenden müsste, könnte eventuell die Bash einen Fehler bringen, zu viele Argumente, dann kann man schrittweise vorgehen)'' <br>
+
Als VERZEICHNIS ist hier genau das eben von root angelegte Verzeichnis anzugeben. Je nach Größe und Benutzungsgrad des Filesystems kann das schon seine Zeit dauern. Es werden 1MByte große Dateien in diesem Verzeichnis angelegt.<br>
Den so erzeugten Datenstrom von '''cat''' leiten wir per Pipe an '''dd''' weiter und mit '''"bs=1024K count=5"''' erzeugen wir dann ein genau 5MB großes File daraus, die typische Eigenschaften eines solchen JPEG Bilddatei hat, obwohl sie selbst kein (ein fehlerbehaftes) Bild ist.
+
Ist das Script fertig, muss erst einmal der Cache des Filesystems die Daten alle auf Platte schreiben, also entweder abwarten oder wenn möglich das Filesystem [http://www.phpman.info/index.php?parameter=umount&mode=man umounten] und anschließend wieder [http://www.phpman.info/index.php?parameter=mount&mode=man mounten]. ( Das ist vor allem wichtig bei sehr kleinen Filesystemen die eventuell sogar komplett im Speicher gecacht sein könnten.)
 
 
 
 
 
 
=== dd auf Partitionen und ganze Festplatten anwenden ===
 
 
 
==== Allgemeine Bemerkungen und Warnungen ====
 
 
 
Was passiert wenn wir mit dd auf eine Partition oder einer Festplatte zugreifen? <br>
 
* Die Byte werden alle sequentiell von der Festplatte gelesen. Dabei werden nicht nur die Inhalte der Dateien sondern auch die Verwaltungsdaten und die Struktur der Partitionen und der Filesysteme mit gelesen, Ebenfalls mitgelesen werden natürlich auch derzeit unbenutzte- und leere Böcke, und Blöcke die derzeit zu gelöschten Dateien gehören. Die gesamte Partition oder Festplatte wird also Byte für Byte gelesen und so gegebenfalls auch Byte für Byte kopiert.
 
 
 
* DD greift dabei direkt auf die Festplatte zu, also unter Umgehung des Cache der Filesysteme und des Swap. Das Filesystem bekommt das auch gar nicht mit. Wir sollten aus diesem Grunde auch für dd eine geeignete Blockgröße für die Zugriffe angeben (oder mit den default 512 Byte leben). Es ist also keinesfalls immer sichergestellt, dass zu jedem Zeitpunkt wirklich das mit dd gelesen wird, was auch wirklich im Filesystem in diesem Moment aktuell ist.  
 
 
 
* Werden Filesysteme mit dd kopiert die aktuell noch '''readonly gemountet''' sind, dann ist das Ergebnis ein Image von diesem Filesystem das nicht sauber ausgehängt ist. Bevor wir es mounten können, muss erst ein [http://www.die.net/doc/linux/man/man8/fsck.8.html fsck] gemacht werden.
 
 
 
* Werden Filesysteme mit dd kopiert die aktuell noch '''read-write gemountet''' sind, dann '''muss vor dem mounten des Images oder der Kopie ein kompletter Filesystemcheck gemacht werden'''. Ansonsten wird bei fsck nur das Journal abgearbeitet ( die Daten im Journal sind aber weder aktuell noch wirklich gültig und zutreffend) und entstandene Inkonsitenzen und Fehler werden nicht behoben. Solche Fehler und Inkonsitenzen entstehen, da dd ein Filesystem nicht innerhalb eines Bruchteiles von Sekunden lesen kann, sondern dazu einige Minuten oder gar Stunden benötigt. In dieser Zeit arbeitet aber der Cache vom Filesystem ganz normal weiter und ändert auch den Inhalt auf der Platte. Wird jetzt zB. während dd eine Partition ließt, ein Cronjob gestartet der die Logdateien großflächig umorganisiert. Dann kann es natürlich sein, das bestimmte Blöcke von dd schon verarbeitet sind, die später jedoch ungültig werden oder durch andere Blöcke ersetzt werden die dd erst dann ließt wenn sie schon geändert sind. Es ist also durchaus möglich, das selbst nach einem kompletten Filesystemcheck eines so entstandenen Images einige Dateien fehlen, oder einfach einen falschen Inhalt haben, oder im Extremfall, das das Filesystem so defekt ist, das es nur unter enormen Datenverlust wiederhergestellt werden kann. Besonders gefährlich wird das, wenn man bei einem Filesystemcheck nur das Journal abarbeitet, und dann ganz normal unwissentlich  mit einem  strukturdefektem Filesystem weiterarbeitet. Man denkt alles in Ordnung, und plötzlich geht irgendwas nicht richtig oder es geht gar nichts mehr. Jetzt kann ein kompletter Filesystemcheck richtig böse Sachen aufzeigen.
 
 
 
* Zu den Verwaltungsdaten auf den Festplatte und Partitionen gehören natürlich auch die Partitionstabellen und gegebenenfalls Bootloader und auch Kennungs- Zustands- und Verwaltungsdaten von Softwareraid oder Virtuellen Laufwerken. Werden diese auf andere Festplatten kopiert und es sich nicht um eine identischen Festplatte handeln sollte, die die ursprüngliche Festplatte ersetzen soll, sollte man sich hier sehr genau überlegen was man da macht.
 
 
 
 
 
==== Festplatte testen durch Lesen ====
 
 
 
* Hin und wieder muss man mal eine Festplatte testen, ob denn diese überhaupt noch richtig angesprochen werden kann.
 
dd if=/dev/hdb of=/dev/null bs=4K count=1000
 
:dieser Test dauert nur eine Sekunde, reicht aber aus, um zu erkennen ob die Platte überhaupt noch was tut.
 
 
 
* Hat man viele SCSI-Platten im System, dann kann es hin und wieder vorkommen, man muss unbedingt wissen. welche physikalische Platte ist zB. /dev/sdf <br>
 
:solange die Platte bisher nicht mit Fehlern oder Totalausfall geglänzt hat:
 
dd if=/dev/sdf of=/dev/null bs=8K count=100000
 
:dieser Test könnte so 30 bis 60 Sekunden laufen, in dieser Zeit sollte die Aktivitäts-LED dieser Platte permanet an sein. Sobald der Befehl beendet ist, oder mit "STRG + C" abgebrochen wird, ist sie aus, oder flackert sporatisch wieder wie eventuell die anderen auch. Wenn diese Platte aber Probleme bereitet, dann ist es meist besser diese nicht direkt anzusprechen, sondern die benachbarten Platten , hier im Beispiel also /dev/sde und /dev/sdg, die Platte zwischen diesen Beiden sollte dann die gesucht /dev/sdf sein.
 
 
 
* Sollte es Busprobleme geben, zB wegen defekten oder ungeeigneten Kabel oder falschen DMA-Einstellungen oder Unverträglichkeit von 2 Geräten am Bus, kann man Lesetests über mehrere Minuten machen, gegebenenfalls über mehrere Geräte am selben Kontroller. Dabei die /var/log/messages auf Einträge beobachten. (Bei IDE Geräten: Fehler- und Befehlsbeschreibung [[Linux mit hdparm beschleunigen|hdparm]]) 
 
 
 
* Steht eine Platte in Verdacht auf sporatische oder gelegentliche Leseprobleme. und ist der erste kurze Ansprechtest erfolgreich gewesen, kann man einmal die gesamte Platte oder die entsprechend fehlerverdächtige Partition auslesen. '''(Achtung kann eventuell die Performance des Systems über einen längeren Zeitraum sehr negativ beeinflussen, je nachdem welche Filesysteme sich auf dieser Platte befinden)'''
 
dd if=/dev/hda of=/dev/null bs=4k
 
:kommt es zum Abbruch des Befehles wegen Lesefehler, dann wird es allerhöchste Eisenbahn sich eine Reserve Platte zu besorgen, und das letzte Backup auf Vollständigkeit zu prüfen. Eventuell gleich noch ein Backup dieser Platte versuchen. Einige Backup-Programme haben auch Optionen die bei Lesefehlern nicht gleich abbrechen, sondern versuchen erstmal noch weiterzumachen. Fehlerhafte Dateien oder Abschnitte werden übersprungen.
 
 
 
{{Box Achtung ||
 
Sollte die Elektonik des Kontrollers oder die Elektronik der Festplatte der Verursacher der zu untersuchenden Fehler gewesen sein, dann kann es in  Einzelfällen dazu führen, dass der dd-Befehl hängen bleibt, aber weder eine Fehlermeldung ausgibt, noch sich mit [http://www.die.net/doc/linux/man/man1/kill.1.html kill] beenden läßt. Mit [http://www.die.net/doc/linux/man/man1/top.1.html top] oder [http://www.die.net/doc/linux/man/man1/ps.1.html ps] ist der Prozessstatus '''"D"''' beim dd-Prozess zu erkennen. Hier einfach erst einmal einige Minuten warten, eventuell greift doch noch ein Befehlstimeout oder eines der Geräte am Bus forciert einen Busreset. Wenn dem nicht so ist und es nach 15 Minuten keine Änderung ergeben hat, dann hilft hier dann oft nur noch ein reboot, um den hängenden dd-Befehl loszuwerden. 
 
}}
 
 
 
 
 
 
 
 
 
==== der MBR und dd ====
 
 
 
 
 
===== mit dd den Master Boot Record auf Festpatten lesen und schreiben =====
 
 
 
Auf sehr vielen Seiten im Internet wird aufgezeigt wie man mit ''dd'' den [http://de.wikipedia.org/wiki/Master_Boot_Record MBR] ('''M'''aster '''B'''oot '''R'''ecord) einer Festplatte sichern und wieder zurückschreiben kann. Was auf vielen Seiten allerdings meistens fehlt, sind genauere Erklärungen dazu, was sich dort alles befindet, damit man besser abschätzen kann, unter welchen Bedingungen man was damit genau machen kann oder besser lassen sollte, und welche Alternativen es für einzelne Bereiche bzw. Abschnitte gibt. Aus diesem Grunde werden wir das hier einmal etwas ausführlicher behandeln.
 
 
 
{{ Box Anmerkung ||
 
Wir sprechen im Weiteren hier von [http://de.wikipedia.org/wiki/BIOS BIOS]-basierten Computern der [http://de.wikipedia.org/wiki/X86-Prozessor x86-Architektur], es gibt durchaus bei anderen Betriebssystemen und Plattformen auch noch ganz andere Architekturen und Strukturen, aber wir bleiben hier mal bei der typischen IBM-kompatiblen PC-Technik, mit der wohl bis auf ganz wenige Ausnahmen hier alle ihr Linux installiert haben werden
 
}}
 
 
 
Sichern könnte man den MBR von zB der Festplatte /dev/hda folgend:
 
dd if=/dev/hda of=/PATH/DATEI bs=512 count=1
 
Zurückspielen dieser Datei wieder in den MBR dieser Festplatte
 
dd if=/PATH/DATEI of=/dev/hda bs=512 count=1
 
Sich nur den Inhalt einmal [http://de.wikipedia.org/wiki/Hexadezimalsystem hexadezimal] anschauen, kann man zB so hier
 
dd if=/dev/hda bs=512 count=1 | hexdump -C | more
 
 
 
Wie wir aus den Befehlen herauslesen können, es handelt sich hier beim MBR um die ersten 512 Byte der Festplatte. Wie der Name es schon vermuten läßt, es hat irgend etwas mit dem booten zu tun. Und in der Tat, beim Start des Rechners, schaut der BIOS welches Medium soll ich booten, und dann läd er von diesem Medium genau diese 512 ersten Byte. Findet er darin etwas für ihn interessantes, dann versucht er damit den Bootvorgang zu starten.
 
findet er nichts interessantes, dann schaut er ob noch weitere Medien konfiguriert und vorhanden sind, von denen er booten soll, und versucht dort sein Glück. Findet er dabei gar nichts brauchbares, dann kommt die Fehlermeldung, er hat kein Betriebssystem zum booten gefunden. 
 
 
 
 
 
 
 
===== Was befindet sich nun in diesen ersten 512  Byte einer Festplatte? =====
 
 
 
Wir werden das hier mal von hinten aufrollen. ''( Das erste Byte bezeichnen wir als Byte 0 demnach umfasst der Bereich den wir untersuchen Byte 0 bis Byte 511 )''<br>
 
# '''Byte 510''' (0x1fe) und '''Byte 511''' (0x1ff) enthalten eine Kennung (auch MBR-Signatur genannt) die dem BIOS mitteilt, das was hier im MBR steht, ist für dich ein gültiger MBR oder nicht gültig. Der BIOS erkennt den MBR als gültig nur dann an, wenn dort '''0x55 0xAA''' steht. Bei nicht bootfähigen Platten darf hier auch etwas anderes stehen, allerdings wurden schon BIOSe erwischt, die vorsichtshalber eine solche Platte dann gleich mal mit geringer Geschwindigkeit bedient haben, so dass hier prinzipiell immer dieser Wert stehen sollte, wenn eine gültige Partitionstabelle vorliegt.
 
# Die 64 Byte, '''Byte 446 bis Byte 509''' (0x1be bis 0x1fd) dort befindet sich prinzipiell immer die [http://de.wikipedia.org/wiki/Partitionstabelle Partitionstabelle] für die Partitionen 1 bis 4 . Pro Partition 16 Byte das ganze 4 Mal. Nicht definierte Partitionen sind mit NULLEN gefüllt.
 
# Die '''Byte 444''' (0x1bc) '''und Byte 445''' (0x1bd) enthalten den Wert '''0x0000''' und dienen nur zur Trennung und dem Schutz der einzelnen Bereiche
 
# Der Bereich von '''Byte 0 bis Byte 443''' (0x000 - 0x1bb) ist reserviert für einen [http://de.wikipedia.org/wiki/Boot-Loader Bootloader] ( wobei in einigen Windowssystemen noch ein Teilbereich davon fest definiert ist '''Byte 440-443''' (0x1b8 -0x1bb). hier befindet sich eine Disk-Signatur, mit deren Hilfe zB die Zuordnung zu den Laufwerksbuchstaben vorgenommen wird.) Es sind also in diesem Bereich maximal 444 Byte für einen Bootloader möglich, Es handelt sich dabei um ein kleines mittels [http://de.wikipedia.org/wiki/Assemblersprache Assemblerprogrammierung] geschriebenes ausführbares Programm. Dieser Bereich kann aber auch leer sein (alles NULL) es können aber auch zB. Bootloader dort installiert sein, die bei Versuch diesen zu starten nur ausgeben, dass das Medium nicht bootfähig ist, oder Bootloader die nur einen anderen Bootloader von einer der  Partitionen laden und diesen dann starten oder nur ein Auswahlmenu bringen, um daraus dann auf andere Bootloader zu verzweigen. Aber auch Bootvieren sind dort möglich. Wie die einzelnen Bootloader arbeiten ist sehr unterschiedlich. Jedoch können sie nur auf die wenigen Funktionen des BIOS zugreifen und ihre Aufgabe ist es damit den Betriebssystemkern auf der Platte in den Arbeitsspeicher zu laden und zu starten, oder ein oder mehrere (größere) Programme zu laden, die genau das können. In vielen Bootloadern ist desshalb genau hinterlegt, in welchen pysikalischem Bereich (genauer Block) der Festplatte sich die Datei befindet, die als nächstes geladen werden soll, denn die komplizierten Strukturen von Filesystemen würden natürlich in diese 444 Byte nicht hinein zu programmieren sein.
 
 
 
 
 
 
 
===== Schlußfolgerungen für das kopieren des MBR mittels dd =====
 
 
 
Daraus ergeben sich jetzt eine ganze Reihe von Beschränkungen für das so schön einfache kopieren des MBR wie es oben angegeben ist. Prinzipiell gilt, es wird mit dd direkt in einen sehr sensieblen Bereich der Festplatte hineinschreiben, und dabei kann keinerlei logische Überprüfung vorgenommen werden. Solche Vorgehensweisen und Methoden sollten möglichst immer erst das letzte Mittel der Wahl darstellen.
 
* Das kopieren eines solchen MBR (512 Byte) auf die selbe Platte bringt nur Erfolg, wenn sich in der Zwischenzeit weder die Partitionstabelle noch der physikalische Ort (Block auf Festplatte) der Dateien geändert hat, die dieser Bootloader über den BIOS laden soll.
 
* Das kopieren eines solchen MBR (512 Byte) auf eine andere Platte macht nur dann Sinn, wenn es sich auch wirklich um eine identische Platte handelt. (Ausnahme wenn wir eine Platte durch eine größere Platte ersetzen müssten, und wir die Differnenz sowieso nie benutzen möchten)
 
* Baugleiche Platten könnten ( im PC-Bereich ehr die Ausnahmen) logisch anders organisiert sein, da die [http://de.wikipedia.org/wiki/Festplattengeometrie Festplattengeometie] wie wir sie sehen nicht mit dem physikalischen Aufbau der Platte gleich ist und die Platte das selbst verwaltet. Solche Differenzen könnten in Ausnahmefällen schon beim Erwerb gleicher Platten aus unterschiedlichen Bezugsquellen vorliegen, oder irgendwann einmal über Software manuell geändert worden sein. Es ist auch nicht gänzlich auszuschließen, daß der eine oder andere Raidkontroller durchaus auch einmal so eine logische Plattengeometrie geändert haben könnte. Ein kopieren einer Partitionstabelle mit andere logischer Geometie könnte uU. durchaus dann zu defekten oder ungültigen Partitionstabellen führen.
 
* Wenn wir 512 Byte anfassen, sollten wir bedenken das damit immer die Partitionstabelle der Partitionen 1-4 enthalten ist. Die logischen Partitionen jedoch nicht, und somit beim neu Beschreiben des MBR sogar verloren gehen können.
 
* Im Windowsumfeld könnten unter Umständen geklonte MBR (also gleiche Disk-Signatur auf unterschiedlichen Platten) im gleichen System zu instabilem Betrieb oder Bootproblemen führen.
 
 
 
 
 
 
 
===== Anwendungsbeispiele und Alternativen =====
 
 
 
Den Bootloader sollte man nach dem kopieren oder verschieben der Rootpartition am besten wieder mit den dafür vorgesehen Tools neu schreiben. Siehe dazu [http://www.die.net/doc/linux/man/man8/grub-install.8.html grub-install] oder [[Grub-Install via "chroot" und Knoppix]] hier im Wiki, bei LILO gilt das gleiche, immer am Besten mit [http://www.die.net/doc/linux/man/man8/lilo.8.html lilo] wieder installieren, hilfreich sicher auch [[Lilo wieder herstellen]] hier im Wiki<br>
 
Die Partitionstabelle sollte man wenn möglich immer komplett (also auch die eventuellen logischen Partitionen) sichern und gegebenenfalls zurückschreiben oder clonen. Obwohl es nicht unmöglich ist, auch die logischen Partitionen mittels dd zu kopieren und wieder zurückzuschreiben, ist es so kompliziert, dass darauf verzichtet wird, es an dieser Stelle vorzustellen. Statt dessen soll hier auf den Artikel [[Partitionstabelle sichern und wiederherstellen]] verwiesen werden. Dort wird erklärt wie man die komplette Partitionstabelle mittels des Befehles [http://www.die.net/doc/linux/man/man8/sfdisk.8.html sfdisk] einfach und sicher speichern und wieder zurückschreiben kann.<br>
 
 
 
 
 
Für die jetzt nur noch ganz wenigen verbleibenden Ausnahmen hier einige Beispiele (auf eigenen Gefahr) wie man mittels dd im MBR bestimmte Dinge erledigen kann.
 
{{Box Wichtig||
 
nach jeder geschriebenen Manipulation an der Partitionstabelle mittels dd wird der Kernel so lange mit der alten Partitionstabelle weiterarbeiten, bis der Rechner wieder neu gebootet wurde, oder wir dem Kernel explizied dazu gezwungen haben die jetzt neue Partitionstabelle von der Platte neu einzulesen. Dazu darf keine Partition dieser Platte mehr gemountet sein und auch kein Swap auf dieser Platte aktiv, dann '''sfdisk -R /dev/PLATTE''' }}
 
 
 
'''Bootloader als Datei sichern und zurückschreiben'''
 
dd if=/dev/hda of=/PATH/DATEI bs=1 count=444
 
dd if=/PATH/DATEI of=/dev/hda bs=1 count=444
 
'''Bootloader mit Nullen überschreiben'''
 
dd if=/dev/zero of=/dev/hda bs=1 count=444
 
'''Partitionstabelle (nur Partitionen 1 bis 4) hexadezimal anschauen'''
 
dd if=/dev/hda bs=1 count=66 skip=446 | hexdump -C
 
'''Partitionstabelle (nur Partitionen 1 bis 4) als Datei sichern /zurückschreiben'''
 
dd if=/dev/hda of=/PATH/DATEI bs=1 count=66 skip=446
 
dd if=/PATH/DATEI of=/dev/hda bs=1 count=66 seek=446
 
'''Partitionstabelle (nur Partitionen 1 bis 4) auf andere Platte direkt kopieren (hda -> hdb)'''
 
dd if=/dev/hda of=/dev/hdb bs=1 count=66 skip=446 seek=446
 
'''Partitionstabelle löschen'''
 
dd if=/dev/zero of=/dev/hda bs=1 count=64 seek=446
 
'''Windows Disk-Signatur mit Nullen überschreiben'''
 
dd if=/dev/zero of=/dev/hdb bs=1 count=4 seek=440
 
'''MBR-Signatur wieder mit 0x55 0xAA beschreiben ( MBR wieder gültig machen)'''
 
echo -en "\x55\xaa" | dd of=/dev/hda bs=1 count=2 seek=510
 
 
 
 
 
==== einzelne Partitionen und ganze Platten mit dd ====
 
 
 
  
=== CD DVD und Floppy mit dd ===
+
Root kann jetzt das komplette Verzeichnis löschen (Achtung "'''rm *'''" im Verzeichnis wird meist wegen zu vieler Argumente nicht funktionieren)
 +
rm -rf  /PATH/test
  
 +
Jetzt muss erst einmal wieder der Cache das Filesystem neu mit der Platte abgleichen, also hier auch am Besten umount / mount (der [http://www.phpman.info/index.php?parameter=sync&mode=man sync] Befehl hat hier erstaunlicherweise bei meinen Tests nicht immer das erhoffte Resultat gebracht)
  
=== Bandlaufwerke und dd ===
+
Jetzt ist diese Partition bereit zum Erstellen eines effektiven komprimierten Images.
 +
dd if=/dev/hda2 bs=4K | gzip > /PATH/DATEI.IMAGE.gz
 +
Zurückschreiben könnte man dieses komprimierte Images zB.:
 +
zcat /PATH/DATEI.IMAGE.gz | dd of=/dev/hda2 bs=4K
  
 +
Mit ganzen Platten geht das analog, nur sollte man für optimale Ergebnisse eben alle Filesysteme vorher "aufräumen".
  
=== mit dd über Rechnergrenzen ===
 
  
  
== Alternative Programme ==
+
===== Beispiel: dd nach einem Super-GAU im Filesystem =====
  
  
== weiterführende Links ==
+
===== Beispiel: mit dd nach verlorenen Dateiinhalten suchen =====

Version vom 14. Juli 2007, 12:38 Uhr

einzelne Partitionen und ganze Platten mit dd

Das kopieren, klonen, oder als Image ablegen und wieder zurückschreiben von einzelnen Partitionen und ganzen Platten mittels dd, so wie es in unzähligen Beiträgen beschrieben ist, ist und bleibt eine riskante Angelegenheit, solange man sich nicht bewußt ist, was man da eigentlich genau macht.
Es werden genau genommen jedes Byte der Festplatte oder der Partition genau so gelesen, wie sie derzeit auf der Platte gespeichert sind, und wieder zurückgeschrieben wie sie zum jeweiligen Zeitpunkt des Lesens auf der Festplatte vorhanden waren. (siehe auch die allgemeinen Warnungen) Somit benötigt man ein zweites Medium, das auch groß genug ist, diese Daten auch wirklich aufzunehmen, den ein Image einer 200GB Festplatte ist nun einmal 200GB groß, auch wenn nur 10% davon mit Dateien belegt sind. Pinzipiell ist es demnach umso interessanter, je kleiner die Festplatte oder die Partition ist, und um so mehr Daten darauf aktuell abgelegt sind. Solange man ein solches Image dann auch wieder auf die gleiche Festplatte oder in die gleiche Partition zurück schreibt, ist das auch relativ ungefählich. Wird eine größere Festplatte zum zurückspielen benutzt, dann wird die größere Festplatte auf die Orginalgröße der ursprünglichen Festplatte "herunterkonfiguriert", ein Benutzen des übrigen unbenutzten Festplattenplatzes ist erst einmal ausgeschlossen und Versuche diesen doch noch nutzbar zu machen, sind sehr riskant für die Daten auf dieser Platte. Eine zu kleine Festplatte würde dann mindestens ein unvollständiges Filesystem ergeben, das sich gar nicht mounten läßt. Das selbe gilt für Partitionen analog. Sehr gefährlich ist zB. ein zurückschreiben von erweiterten und logischen Partitionen, wenn sich die Partitionstabelle geändert hat, bzw auf eine andere logische oder erweiterte Partition. Hierbei ist es durchaus möglich, das nach dem nächsten booten ein Teil der Daten auf der Platte gar nicht mehr aufzufinden sind.


Beispiele Clonen, Backup und Sicherung

Es gilt, möglichst alle Filesysteme ungemountet auslesen, wo das nicht möglich ist, zumindestens Readonly gemountet auslesen und dann auf das Image einen Filesystemcheck machen.

einzelne Partition als Image ablegen / Image temporär mounten / zurückschreiben

# dd if=/dev/hda2 of=/PATH/DATEI.IMAGE bs=8K
# mount -o loop /PATH/DATEI.IMAGE /mnt      # eventuell weitere Mountoptionen notwendig
# dd if=/PATH/DATEI.IMAGE of=/dev/hda2 bs=8K

Filesystemtype und Zustand eines Images ermitteln/korrieren (Konsolauszug)

LINUX:/ # file DATEI.IMAGE
DATEI.IMAGE: Linux rev 1.0 ext2 filesystem data (mounted or unclean)
LINUX:/ # fsck /PATH/DATEI.IMAGE  # evtl. weitere Optionen notwendig ; kompletten Path des Images
fsck 1.38 (30-Jun-2005)
e2fsck 1.38 (30-Jun-2005)
/PATH/DATEI.IMAGE was not cleanly unmounted, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/PATH/DATEI.IMAGE: 72/16632 files (12.5% non-contiguous), 24776/66432 blocks
LINUX:/ # file DATEI.IMAGE
DATEI.IMAGE: Linux rev 1.0 ext2 filesystem data

einzelne Partition auf eine Festplatte mit identischem Partitionstabelle kopieren

# dd if=/dev/hda2 of=/dev/hdb2 bs=8K

ganze Festplatte als Image ablegen / zurückschreiben

# dd if=/dev/hda of=/PATH/DATEI.IMAGE bs=8K
# dd if=/PATH/DATEI.IMAGE of=/dev/hda bs=8K

man kann von einem solchem Image auch einzelne Partitionen temporär gemounten, dabei muss für das mount der jeweilige Offset benutzt werden.


Festplatte auf einen andere Festplatte klonen

# dd if=/dev/hda of=/dev/hdb bs=8K


Problem Komprimierung von dd-Image

Hin und wieder besteht die Notwendigkeit ein solches Image zu komprimieren, weil eben nur wenige wirkliche Daten auf der Platte/Partition liegen. Dabei wird man auf das Problem stoßen, das kann recht gut funktionieren aber muss nicht. Das liegt dann meistens an den zur Zeit nicht benutzten oder gelöschten Datenblöcken. Sind diese zum großen Teil nicht oder nicht richtig komprimierbar, dann wird man auch wenig Erfolg bei der Komprimierung der gesamten Platte/Partition haben.
Nachfolgend eine Möglichkeit wie man die leeren/unbenutzten Datenblöcke einer Partition sehr gut komprimierbar machen kann, ohne das die richtigen Daten dabei beschädigt werden. Man legt einfach neue "NULL"-Dateien an bis das Filesystem fast voll ist, danach löscht man sie wieder. Wir machen uns hier zum Vorteil, dass ein normaler User im Normalfall auf LINUX-Filesystemen nur bis zu 95% voll auf ein Filesystem schreiben kann. Ausnahme natürlich wenn Disk Quota eingerichtet ist.

Als root in das Filesystem ein neues Verzeichnis anlegen und für Schreibrechte des Users sorgen

# mkdir /PATH/test
# chmod a+w /PATH/test

Danach als User folgendes Script ausführen

#!/bin/bash
VERZEICHNIS=/PATH/test

dd if=/dev/zero of=/tmp/file.null count=1024 bs=1K 2>/dev/null
echo "anlegen von Dateien bitte warten" 
for i in {a..z}{a..z}{a..z}
 do
   for j in {0..9}{0..9}{0..9}{0..9}
   do
      NAME=${VERZEICHNIS}/leer$i$j
      cp /tmp/file.null $NAME 2>/dev/null || break 2
   done
done
rm /tmp/file.null

Als VERZEICHNIS ist hier genau das eben von root angelegte Verzeichnis anzugeben. Je nach Größe und Benutzungsgrad des Filesystems kann das schon seine Zeit dauern. Es werden 1MByte große Dateien in diesem Verzeichnis angelegt.
Ist das Script fertig, muss erst einmal der Cache des Filesystems die Daten alle auf Platte schreiben, also entweder abwarten oder wenn möglich das Filesystem umounten und anschließend wieder mounten. ( Das ist vor allem wichtig bei sehr kleinen Filesystemen die eventuell sogar komplett im Speicher gecacht sein könnten.)

Root kann jetzt das komplette Verzeichnis löschen (Achtung "rm *" im Verzeichnis wird meist wegen zu vieler Argumente nicht funktionieren)

rm -rf  /PATH/test

Jetzt muss erst einmal wieder der Cache das Filesystem neu mit der Platte abgleichen, also hier auch am Besten umount / mount (der sync Befehl hat hier erstaunlicherweise bei meinen Tests nicht immer das erhoffte Resultat gebracht)

Jetzt ist diese Partition bereit zum Erstellen eines effektiven komprimierten Images.

dd if=/dev/hda2 bs=4K | gzip > /PATH/DATEI.IMAGE.gz

Zurückschreiben könnte man dieses komprimierte Images zB.:

zcat /PATH/DATEI.IMAGE.gz | dd of=/dev/hda2 bs=4K 

Mit ganzen Platten geht das analog, nur sollte man für optimale Ergebnisse eben alle Filesysteme vorher "aufräumen".


Beispiel: dd nach einem Super-GAU im Filesystem
Beispiel: mit dd nach verlorenen Dateiinhalten suchen