Anhang A. Der Device-Mapper

Der Device-Mapper ist ein Kernel-Treiber, der ein Framework zur Verwaltung von Datenträgern bietet. Er bietet einen generischen Weg zur Erstellung von gemappten Geräten, die ggf. als logische Datenträger verwendet werden. Er hat jedoch keine Kenntnis von Datenträgergruppen oder Metadaten-Formaten.
Der Device-Mapper liefert die Grundlage für eine Reihe von anspruchsvollen Technologien. Zusätzlich zu LVM verwenden Device-Mapper multipath und der dmraid-Befehl den Device-Mapper. Die Applikationsschnittstelle zum Device Mapper ist der ioctl-Systemaufruf. Die Benutzerschnittstelle ist der dmsetup-Befehl.
Logische LVM-Datenträger werden unter Verwendung des Device-Mappers aktiviert. Jeder logischer Datenträger wird in ein gemapptes Gerät übersetzt, jedem Segment wird eine Zeile in der Mapping-Tabelle zugewiesen, die das Gerät beschreibt. Der Device-Mapper unterstützt eine Vielzahl von Mapping-Zielen, unter anderem lineares Mapping, Striped Mapping und Fehler-Mapping. So können beispielsweise zwei Platten können mit einem Paar linearer Mappings pro Platte in einem logischen Datenträger zusammengefasst werden. Wenn LVM einen Datenträger erstellt, erzeugt es ein zugrunde liegendes Device-Mapper-Gerät, das mit dem dmsetup-Befehl abgerufen werde kann. Werfen Sie bitte einen Blick auf Abschnitt A.1, »Gerätetabelle-Mappings« für Informationen über das Format von Geräten in einer Mapping-Tabelle. Informationen über die Verwendung des dmsetup-Befehls zum Abruf eines Geräts finden Sie in Abschnitt A.2, »Der dmsetup-Befehl«.

A.1. Gerätetabelle-Mappings

Ein gemapptes Gerät ist definiert durch eine Tabelle, die spezifiziert, wie jeder Bereich logischer Sektoren auf dem Gerät mithilfe eines unterstützten Gerätetabelle-Mappings zugewiesen wird. Die Tabelle für ein gemapptes Gerät setzt sich aus einer Reihe von Zeilen im folgenden Format zusammen:
start length mapping [mapping_parameters...]
In der ersten Zeile einer Device-Mapper-Tabelle muss der start-Parameter 0 entsprechen. Die start + length-Parameter in einer Zeile müssen dem start-Parameter in der folgenden Zeile entsprechen. Welche Mapping-Parameter in einer Zeile der Mapping-Tabelle angegeben sind, hängt davon ab, welcher mapping-Typ in der Zeile spezifiziert ist.
Größen im Device-Mapper werden immer in Sektoren (512 Bytes) angegeben.
Wenn ein Gerät als ein Mapping-Parameter im Device-Mapper spezifiziert ist, kann es anhand seines Gerätenamens im Dateisystem referenziert werden (z.B. /dev/hda) oder anhand seiner Major- und Minor-Nummern im Format major:minor. Das Major:Minor-Format ist dabei vorzuziehen, da auf diese Weise Pfadnamen-Aufrufe vermieden werden.
Sehen Sie nachfolgend ein Beispiel einer Mapping-Tabelle für ein Gerät. Diese Tabelle enthält vier lineare Ziele:
0 35258368 linear 8:48 65920
35258368 35258368 linear 8:32 65920
70516736 17694720 linear 8:16 17694976
88211456 17694720 linear 8:16 256
Die ersten zwei Parameter jeder Zeile stellen den Startblock und die Länge des Segments dar. Das nächste Schlüsselwort ist das Mapping-Ziel, was in allen Fällen unseren Beispiels linear ist. Der Rest der Zeile besteht aus den Parametern für ein linear-Ziel.
Die folgenden Unterabschnitte beschreiben das Format der folgenden Mappings:
  • linear
  • striped
  • mirror
  • snapshot und snapshot-origin
  • error
  • zero
  • multipath
  • crypt

A.1.1. Das "linear" Mapping-Ziel

Ein lineares Mapping-Ziel weist einem anderen Blockgerät einen zusammenhängenden Bereich von Blöcken zu. Das Format eines linearen Ziels sieht folgendermaßen aus:
start length linear device offset
start
Startblock im virtuellen Gerät
length
Länge dieses Segments
device
Blockgerät, referenziert anhand des Gerätenamens im Dateisystem oder anhand der Major- und Minor-Nummern im Format major:minor
offset
Start-Offset des Mappings auf dem Gerät
Das folgende Beispiel zeigt ein lineares Ziel mit dem Startblock 0 im virtuellen Gerät, einer Segmentlänge von 1638400, einem Major:Minor-Nummernpaar von 8:2, und einem Start-Offset für das Gerät von 41146992.
0 16384000 linear 8:2 41156992
Das folgende Beispiel zeigt ein lineares Ziel mit dem Geräteparameter spezifiziert als Gerät /dev/hda.
0 20971520 linear /dev/hda 384

A.1.2. Das "striped" Mapping-Ziel

Das striped Mapping-Ziel unterstützt Striping (Verteilung der Daten) über physische Geräte. Es akzeptiert als Parameter die Anzahl der Stripes und die Striping-Chunk-Größe, gefolgt von einer Liste mit Gerätenamen/Sektor-Paaren. Das Format eines Striped-Ziels sieht folgendermaßen aus:
start length striped #stripes chunk_size device1 offset1 ... deviceN offsetN
Es gibt ein Set mit device und offset-Parametern für jeden Stripe.
start
Startblock im virtuellen Gerät
length
Länge dieses Segments
#stripes
Anzahl der Stripes für das virtuelle Gerät
chunk_size
Anzahl der Sektoren, die auf jeden Stripe geschrieben werden, bevor zum nächsten gewechselt wird; muss eine Zweierpotenz sein, die mindestens so groß wie die Kernel-Seitengröße ist
device
Blockgerät, referenziert anhand des Gerätenamens im Dateisystem oder anhand der Major- und Minor-Nummern im Format major:minor
offset
Start-Offset des Mappings auf dem Gerät
Das folgende Beispiel zeigt ein Striped-Ziel mit drei Stripes und einer Chunk-Größe von 128:
0 73728 striped 3 128 8:9 384 8:8 384 8:7 9789824
0
Startblock im virtuellen Gerät
73728
Länge dieses Segments
striped 3 128
Striping über drei Geräte mit einer Chunk-Größe von 128 Blöcken
8:9
Major:Minor-Nummern des ersten Geräts
384
Start-Offset des Mappings auf dem ersten Gerät
8:8
Major:Minor-Nummern des zweiten Geräts
384
Start-Offset des Mappings auf dem zweiten Gerät
8:7
Major:Minor-Nummern des dritten Geräts
9789824
Start-Offset des Mappings auf dem dritten Gerät
Das folgende Beispiel zeigt ein Striped-Ziel mit zwei Stripes und einer Chunk-Größe von 256 KiB, mit den Geräteparametern spezifiziert durch die Gerätenamen im Dateisystemen anstelle der Major- und Minor-Nummern:
0 65536 striped 2 512 /dev/hda 0 /dev/hdb 0

A.1.3. Das "mirror" Mapping-Ziel

Das "mirror" Mapping-Ziel unterstützt das Mapping eines gespiegelten logischen Geräts. Das Format eines Mirrored-Ziels sieht folgendermaßen aus:
start length mirror log_type #logargs logarg1 ... logargN #devs device1 offset1 ... deviceN offsetN
start
Startblock im virtuellen Gerät
length
Länge dieses Segments
log_type
Die möglichen Protokolltypen und deren Parameter lauten wie folgt:
core
Der Mirror ist lokal und das Mirror-Protokoll wird im Kernspeicher bewahrt. Dieser Protokolltyp akzeptiert 1 - 3 Parameter:
regionsize [[no]sync] [block_on_error]
disk
Der Mirror ist lokal und das Mirror-Protokoll wird auf der Festplatte bewahrt. Dieser Protokolltyp akzeptiert 2 - 4 Parameter:
logdevice regionsize [[no]sync] [block_on_error]
clustered_core
Der Mirror ist geclustert und das Mirror-Protokoll wird im Kernspeicher bewahrt. Dieser Protokolltyp akzeptiert 2 - 4 Parameter:
regionsize UUID [[no]sync] [block_on_error]
clustered_disk
Der Mirror ist geclustert und das Mirror-Protokoll wird auf der Festplatte bewahrt. Dieser Protokolltyp akzeptiert 3 - 5 Parameter:
logdevice regionsize UUID [[no]sync] [block_on_error]
LVM pflegt eine kleine Protokolldatei, in der festgehalten wird, welche Bereiche mit dem (den) Mirror(s) synchron sind. Der regionsize-Parameter bestimmt die Größe dieser Bereiche.
In einer geclusterten Umgebung ist der UUID-Parameter ein eindeutiger Bezeichner, der dem Mirror-Protokollgerät zugewiesen ist, so dass der Protokollzustand über den Cluster hinweg bewahrt werden kann.
Der optionale [no]sync-Parameter kann dazu verwendet werden, den Mirror als "in-sync" oder "out-of-sync" zu spezifizieren. Mithilfe des block_on_error-Parameters wird der Mirror angewiesen, auf Fehler zu antworten statt diese zu ignorieren.
#log_args
Anzahl der Protokollparameter, die im Mapping spezifiziert werden.
logargs
Die Protokollparameter für den Mirror; die Anzahl der angegebenen Protokollparameter wird durch den #log-args-Parameter spezifiziert und die gültigen Protokollparameter werden durch den log_type-Parameter bestimmt.
#devs
Die Anzahl der Standbeine des Mirrors; ein Gerät und ein Offset wird für jedes Standbein spezifiziert.
device
Blockgerät für jedes Mirror-Standbein, referenziert anhand des Gerätenamens im Dateisystem oder anhand der Major- und Minor-Nummern im Format major:minor. Ein Blockgerät und ein Offset wird für jedes Standbein spezifiziert, das vom #devs-Parameter angegeben ist.
offset
Start-Offset des Mappings auf dem Gerät. Ein Blockgerät und ein Offset wird für jedes Standbein spezifiziert, das vom #devs-Parameter angegeben ist.
Das folgende Beispiel zeigt ein Mirror-Mapping-Ziel für einen geclusterten Mirror mit einem auf der Festplatte bewahrten Mirror-Protokoll.
0 52428800 mirror clustered_disk 4 253:2 1024 UUID block_on_error 3 253:3 0 253:4 0 253:5 0
0
Startblock im virtuellen Gerät
52428800
Länge dieses Segments
mirror clustered_disk
Mirror-Ziel mit einem Protokolltyp, der spezifiziert, dass der Mirror gespiegelt wird und das Mirror-Protokoll auf Festplatte bewahrt wird
4
4 Mirror-Protokollparameter folgen
253:2
Major:Minor-Nummern des Protokollgeräts
1024
Bereichsgröße, die das Mirror-Protokoll verwendet um nachzuverfolgen, was synchron ist
UUID
UUID des Mirror-Protokollgeräts, um Protokolldaten für den gesamten Cluster zu bewahren
block_on_error
Mirror sollte auf Fehler antworten
3
Anzahl der Standbeine im Mirror
253:3 0 253:4 0 253:5 0
Major:Minor-Nummern und Offset für die Geräte, aus denen jedes Standbein des Mirrors besteht

A.1.4. Snapshot und Snapshot-Quelle der Mapping-Ziele

Wenn Sie den ersten LVM-Snapshot eines Datenträgers erstellen, werden vier Device-Mapper-Geräte verwendet:
  1. Ein Gerät mit einem linear Mapping, das die ursprüngliche Mapping-Tabelle des Quelldatenträgers enthält.
  2. Ein Gerät mit einem linear Mapping, das als "copy-on-write" (kurz COW) Gerät für den Quelldatenträger dient; bei jedem Schreibvorgang werden die originalen Daten im COW-Gerät eines jeden Snapshots gespeichert, um dessen sichtbaren Inhalt unverändert zu lassen (bis das COW-Gerät voll ist).
  3. Ein Gerät mit einem snapshot-Mapping, das #1 und #2 kombiniert, was den sichtbaren Snapshot-Datenträger bildet.
  4. Der "Original"-Datenträger (der die Gerätenummer des originalen Quelldatenträgers verwendet), dessen Tabelle durch ein "Snapshot-Quell"-Mapping von Gerät #1 ersetzt wird.
Bei der Erstellung dieser Geräte wird ein festes Namensschema verwendet, z.B. können Sie die folgenden Befehle verwenden, um einen LVM-Datenträger namens base und einen Snapshot-Datenträger namens snap basierend auf diesem Datenträger zu erstellen.
# lvcreate -L 1G -n base volumeGroup
# lvcreate -L 100M --snapshot -n snap volumeGroup/base
Daraus entstehen vier Geräte, die Sie sich mit dem folgenden Befehl anzeigen lassen können:
# dmsetup table|grep volumeGroup
volumeGroup-base-real: 0 2097152 linear 8:19 384
volumeGroup-snap-cow: 0 204800 linear 8:19 2097536
volumeGroup-snap: 0 2097152 snapshot 254:11 254:12 P 16
volumeGroup-base: 0 2097152 snapshot-origin 254:11

# ls -lL /dev/mapper/volumeGroup-*
brw-------  1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real
brw-------  1 root root 254, 12 29 ago 18:15 /dev/mapper/volumeGroup-snap-cow
brw-------  1 root root 254, 13 29 ago 18:15 /dev/mapper/volumeGroup-snap
brw-------  1 root root 254, 10 29 ago 18:14 /dev/mapper/volumeGroup-base
Das Format des snapshot-origin-Ziels lautet folgendermaßen:
start length snapshot-origin origin
start
Startblock im virtuellen Gerät
length
Länge dieses Segments
origin
Basisdatenträger des Snapshots
Auf dem snapshot-origin basieren normalerweise ein oder mehrere weitere Snapshots. Lesevorgänge werden direkt auf das dahinter liegende Gerät gemappt. Bei jedem Schreibvorgang werden die originalen Daten im COW-Gerät eines jeden Snapshots gespeichert, um dessen sichtbaren Inhalt unverändert zu lassen, bis das COW-Gerät voll ist.
Das Format des snapshot-Ziels sieht folgendermaßen aus:
start length snapshot origin COW-device P|N chunksize
start
Startblock im virtuellen Gerät
length
Länge dieses Segments
origin
Basisdatenträger des Snapshots
COW-device
Gerät, auf dem veränderte Datenblöcke gespeichert werden
P|N
P (Persistent) oder N (Nicht persistent); gibt an, ob ein Snapshot über einen Neustart hinweg bestehen bleibt. Für transiente Snapshots (N) müssen weniger Metadaten auf der Festplatte gespeichert werden; sie können vom Kernel im Hauptspeicher bewahrt werden.
chunksize
Größe in Sektoren der veränderten Datenblöcke ("Chunks"), die auf dem COW-Gerät gespeichert werden
Das folgende Beispiel zeigt ein snapshot-origin-Ziel mit dem originalen Gerät 254:11.
0 2097152 snapshot-origin 254:11
Das folgende Beispiel zeigt ein snapshot-Ziel mit dem originalen Gerät 254:11 und dem COW-Gerät 254:12. Dieses Snapshot-Gerät ist über Neustarts hinweg persistent und die Chunk-Größe für die auf dem COW-Gerät gespeicherten Daten beträgt 16 Sektoren.
0 2097152 snapshot 254:11 254:12 P 16

A.1.5. Das "error" Mapping-Ziel

Mit einem "error" Mapping-Ziel schlägt jede I/O-Operation auf dem gemappten Sektor fehl.
Ein Error-Mapping-Ziel kann zu Testzwecken eingesetzt werden. Um zu testen, wie sich ein Gerät im Fehlerfall verhält, können Sie ein Geräte-Mapping mit einem fehlerhaften Sektor in der Mitte des Geräts erstellen, oder Sie können ein Standbein eines Mirrors auslagern und dieses Standbein durch ein Error-Ziel ersetzen.
Ein Error-Ziel kann anstelle eines fehlerhaften Geräts verwendet werden, um Zeitüberschreitungen und Neuversuche auf dem eigentlichen Gerät zu vermeiden. Es kann als Zwischenziel dienen, während Sie die LVM-Metadaten bei Ausfällen neu anordnen.
Das error Mapping-Ziel akzeptiert außer den start und length-Parametern keine weiteren Parameter.
Das folgende Beispiel zeigt ein error-Ziel.
0 65536 error

A.1.6. Das "zero" Mapping-Ziel

Das zero Mapping-Ziel ist ein Blockgerät-Äquivalent zu /dev/zero. Eine Leseoperation auf diesem Mapping gibt Blöcke von Nullen zurück. Auf dieses Mapping geschriebene Daten werden verworfen, der Schreibvorgang ist jedoch erfolgreich. Das zero Mapping-Ziel akzeptiert außer den start und length-Parametern keine weiteren Parameter.
Das folgende Beispiel zeigt ein zero-Ziel für ein 16 TB Gerät.
0 65536 zero

A.1.7. Das "multipath" Mapping-Ziel

Das "multipath" Mapping-Ziel unterstützt das Mapping eines Multipath-Geräts. Das Format eines multipath-Ziels sieht folgendermaßen aus:
start length  multipath  #features [feature1 ... featureN] #handlerargs [handlerarg1 ... handlerargN] #pathgroups pathgroup pathgroupargs1 ... pathgroupargsN
Es gibt ein Set mit pathgroupargs-Parametern für jede Pfadgruppe.
start
Startblock im virtuellen Gerät
length
Länge dieses Segments
#features
Die Anzahl von Multipath-Features, gefolgt von diesen Features. Ist dieser Parameter Null, gibt es keinen feature-Parameter und der nächste Geräte-Mapping-Parameter ist #handlerargs. Derzeit gibt es ein unterstütztes Multipath-Feature, queue_if_no_path. Dies gibt an, dass dieses Multipath-Gerät derzeit darauf eingestellt ist, I/O-Operationen in eine Warteschlange zu stellen, wenn kein Pfad verfügbar ist.
Ist beispielsweise die no_path_retry-Option in der multipath.conf-Datei darauf eingestellt, I/O-Operationen nur solange in eine Warteschlange zu stellen, bis alle Pfade als fehlerhaft markiert wurden, nachdem eine festgelegte Anzahl an Versuchen unternommen wurde, diese Pfade zu verwenden, würde das Mapping folgendermaßen erscheinen, bis für alle Pfadüberprüfungen die festgelegte Anzahl von Prüfungen fehlschlugen.
0 71014400 multipath 1 queue_if_no_path 0 2 1 round-robin 0 2 1 66:128 \
1000 65:64 1000 round-robin 0 2 1 8:0 1000 67:192 1000
Nachdem für alle Pfadüberprüfungen die festgelegte Anzahl von Prüfungen fehlschlugen, würde das Mapping folgendermaßen erscheinen.
0 71014400 multipath 0 0 2 1 round-robin 0 2 1 66:128 1000 65:64 1000 \
round-robin 0 2 1 8:0 1000 67:192 1000
#handlerargs
Die Anzahl von Hardware-Handler-Parametern, gefolgt von diesen Parametern. Ein Hardware-Handler spezifiziert ein Modul, das zur Durchführung von hardwarespezifischen Aktionen verwendet wird beim Wechseln von Pfadgruppen oder bei der Handhabung von I/O-Fehlern. Ist dies auf 0 gesetzt, ist der nächste Parameter #pathgroups.
#pathgroups
Die Anzahl von Pfadgruppen. Eine Pfadgruppe ist die Gruppe von Pfaden, über die ein Multipath-Gerät lastverteilt. Es gibt eine Gruppe von pathgroupargs-Parametern für jede Pfadgruppe.
pathgroup
Die nächste zu versuchende Pfadgruppe.
pathgroupsargs
Jede Pfadgruppe umfasst die folgenden Parameter:
pathselector #selectorargs #paths #pathargs device1 ioreqs1 ... deviceN ioreqsN 
Es gibt eine Gruppe von Pfadparametern für jeden Pfad in der Pfadgruppe.
pathselector
Spezifiziert den verwendeten Algorithmus um zu bestimmen, welcher Pfad in dieser Pfadgruppe für die nächste I/O-Operation zu verwenden ist.
#selectorargs
Die Anzahl der Pfadauswahl-Parameter, die diesem Parameter im Multipath-Mapping folgen. Derzeit ist der Wert dieses Parameters immer 0.
#paths
Die Anzahl von Pfaden in dieser Pfadgruppe.
#pathargs
Die Anzahl der Pfadparameter, die für jeden Pfad in dieser Gruppe spezifiziert sind. Derzeit ist diese Anzahl immer 1, der ioreqs-Parameter.
device
Die Blockgerätenummer des Pfads, referenziert durch die Major- und Minor-Nummern im Format major:minor
ioreqs
Die Anzahl von I/O-Anfragen, die auf diesen Pfad geleitet werden, bevor zum nächsten Pfad in der aktuellen Gruppe gewechselt wird.
Abbildung A.1, »"Multipath" Mapping-Ziel« veranschaulicht das Format eines Multipath-Ziels mit zwei Pfadgruppen.
"Multipath" Mapping-Ziel

Abbildung A.1. "Multipath" Mapping-Ziel

Das folgende Beispiel zeigt eine reine Failover-Zieldefinition für dasselbe Multipath-Gerät. In diesem Ziel gibt es vier Pfadgruppen mit je einem offenen Pfad pro Pfadgruppe, so dass das Multipath-Gerät zu jeder Zeit nur einen Pfad verwendet.
0 71014400 multipath 0 0 4 1 round-robin 0 1 1 66:112 1000 \
round-robin 0 1 1 67:176 1000 round-robin 0 1 1 68:240 1000 \
round-robin 0 1 1 65:48 1000
Das folgende Beispiel zeigt eine vollständig verteilte (multibus) Zieldefinition für dasselbe Multipath-Gerät. In diesem Ziel gibt es nur eine Pfadgruppe, die alle Pfade umfasst. Bei diesem Aufbau verteilt Multipath die Last gleichmäßig über alle Pfade.
0 71014400 multipath 0 0 1 1 round-robin 0 4 1 66:112 1000 \
 67:176 1000 68:240 1000 65:48 1000
Weitere Informationen über den Einsatz von Multipath finden Sie im Dokument Verwendung von Device Mapper Multipath.

A.1.8. Das "crypt" Mapping-Ziel

Das crypt-Ziel verschlüsselt die Daten, die das angegebene Gerät durchlaufen. Es verwendet die Kernel-Crypto-API.
Das Format für das crypt-Ziel sieht folgendermaßen aus:
start length crypt cipher key IV-offset device offset
start
Startblock im virtuellen Gerät
length
Länge dieses Segments
cipher
Cipher (Schlüssel) besteht aus cipher[-chainmode]-ivmode[:iv options].
cipher
Die verfügbaren Cipher (Schlüssel) sind in /proc/crypto aufgelistet (z.B. aes).
chainmode
Verwenden Sie stets cbc. Verwenden Sie nicht ebc, da es keinen initialen Vektor (IV) einsetzt.
ivmode[:iv options]
IV ist ein initialer Vektor, der zum Variieren der Verschlüsselung eingesetzt wird. Der IV-Modus ist plain oder essiv:hash. Der ivmode -plain verwendet die Sektorennummer (zuzüglich IV-Offset) als den IV. Der ivmode -essiv ist eine Verbesserung, um mögliche Wasserzeichenangriffe zu vermeiden.
key
Verschlüsselungs-Code, angegeben in hex
IV-offset
Offset für den initialen Vektor (IV)
device
Blockgerät, referenziert anhand des Gerätenamens im Dateisystem oder anhand der Major- und Minor-Nummern im Format major:minor
offset
Start-Offset des Mappings auf dem Gerät
Im Folgenden sehen Sie ein Beispiel für ein crypt-Ziel.
0 2097152 crypt aes-plain 0123456789abcdef0123456789abcdef 0 /dev/hda 0