partitionmasker

Aus LaborWiki
Wechseln zu: Navigation, Suche
           
partitionmasker

Release status: beta [box doku]

LaborLogo2.png
Description ro/rw mappings eines partitionierten Geräts erstellen
Author(s)  Thomas
Last Version  0.0.2 ()
Platform  Linux 2.6/Ruby
License  GPL v3+
Download  https://www.das-labor.org/trac/browser/tools/partitionmasker





Über partitionmasker[Bearbeiten | Quelltext bearbeiten]

Partitionmasker erstellt eine Gerätedatei (das Target), die ein Echtzeit-Abbild eines vorhandenen Geräts (der Source) darstellt. Lese-/Schreiboperationen auf das Target werden im Kernel auf den Source umgebogen. Dabei ist der Inhalt nur lesbar -- einzelne Partitionen können/sollen auch als schreibbar konfiguriert werden.

Dies ist praktisch, um ein auf einer Festplatte bootbar installiertes System auch in einer Virtualisierungsumgebung booten zu können. Man erstellt mit der Festplatte als Source ein Target und gibt dies dem Virtualisierer als Festplattenquelle an, und kann sichergehen, dass das virtuelle System nur auf die als schreibberechtigt angegebenen Teile (Partitionen) schreiben kann.

WARNUNG: Es ist möglich, dass sich Gast und Host-Kernel nicht einig sind über das Partitionssetup. Erkennbar ist dies an Log-Einträgen im dmesg des Gastes. Prinzipiell kann dies schwerstenfalls zu Datenverlust führen (ein Dual-Boot setup hat aber das gleiche Problem). Es empfiehlt sich, Partitionsgrenzen an "Zylindern" zu legen, auch wenn dies nicht immer auszureichen scheint.

Es ist möglich, für einzelne Partitionen die erwartete UUID des Dateisystems/Swaps anzugeben. Partitionmasker prüft diese und bricht ab, falls sie nicht stimmt. Dadurch können Fehlkonfigurationen nach Umpartitionierungen vermieden werden.

Es ist möglich, einzelne Partitionen "null" zu mappen, d.h. auf dem Target liest man an dieser Stelle nur Nullen, und Schreibvorgänge werden fallengelassen. Hiermit kann z.B. verhindert werden, dass der Gast ein LVM physical volume nutzt.

Arbeitsweise[Bearbeiten | Quelltext bearbeiten]

Partitionmasker erwartet, dass der Source partitioniert ist, und zwar nach dem MBR/BIOS-Schema.

Es wird benutzt

  • sfdisk, um die Partitionierung herauszufinden
  • losetup, um zunächst (als "Zwischenschicht") ein nur-lesen- und ein auch-schreiben-Abbild (Loop-Gerät) der Source zu erstellen
  • blockdev, um die Größe der Source und die Daten evtl. vorhandener Loop-Geräte zu erfragen
  • dmsetup für das auf die beiden Loop-Geräte abbildende zusammengesetzte Target.

dmsetup konfiguriert den kernel device mapper zur Erzeugung des Target.

Die beiden Loop-Geräte werden benötigt, um den Zugriff auf die nicht als schreibberechtigt markierten Bereiche auf nur Lesen einzuschränken, und weil dmsetup sich weigert, auf im Kernel als "in Gebrauch" markierte Geräte (was ohne diesen Umweg bei der Source der Fall sein könnte) abzubilden.

Details findet man in den Quellen (die Datei partitionmasker enthält neben dem Code auch die vollständige Hilfe).

Beispiel[Bearbeiten | Quelltext bearbeiten]

Hier eine fiktive Konfigurationsdatei:

Device.create do
  source("/dev/sda")
  target "virthd"

  #map first primary partition read-write
  add_rw_mapping("/dev/sda1")

  #hide second primary partition by replacing it virtually with zeroes
  add_null_mapping("/dev/sda2")

  #map first logical partition read-write
  add_rw_mapping("/dev/sda5") do
    #...but only if file system/swap/LVM physical volume
    #has the expected UUID
    is_uuid("01234567-89ab-cdef-0123-4567890abcde")
    #this will check if "/dev/disks/by-uuid/<uuid above>" is a symlink
    #to "/dev/sda5", refusing operation if not.
  end
end

Die Festplatte /dev/sda (Source) wird auf /dev/mapper/virthd (Target) abgebildet. Dabei wird der komplette Inhalt nur lesbar zugänglich gemacht, mit Ausnahme der Partitionen

  • /dev/sda1 und /dev/sda5: sie werden schreibbar zugänglich gemacht.
  • /dev/sda2: diese Partition wird "ausgeblendet", lesen auf die Partition im Target liefert Nullen.

Zusätzlich wird sichergestellt, dass sich auf /dev/sda5 ein Dateisystem (oder Swap etc.) befindet, das die angegebene UUID trägt.

aktueller Zustand[Bearbeiten | Quelltext bearbeiten]

Bei mir funktioniert es! ;-)

Links und weiterführende Hinweise[Bearbeiten | Quelltext bearbeiten]