
Ich habe einige gespeicherte ZFS-Sendeströme (d. h. sie wurden durch Umleiten der Ausgabe zfs send
in eine Datei erstellt). Ich möchte den Inhalt dieser Ströme untersuchen, ohne sie zu empfangen und in ein Dateisystem zu schreiben – ich möchte beispielsweise eine Liste der Dateinamen im Strom anzeigen. Gibt es eine Möglichkeit, dies zu tun?
Ich habe einiges gelesen und gesucht, aber nichts gefunden, das dem ähnelt, wovon ich spreche. Ich verwende sowohl dieFreeBSDund dasZFS unter LinuxImplementierungen von ZFS.
Antwort1
Sie können einige Informationen erhalten, indem Sie sie in weiterleiten zstreamdump -d
, aber das gibt Ihnen keine direkten Informationen zu Dateinamen, da sich im Stream keine Dateien befinden. Der Stream ist ein reiner Unterschied zwischen zwei in Blöcken beschriebenen Bäumen. Der Code ist jedoch öffentlich, wenn Sie also ZFS-Strukturerkennung und -Analyse hinzufügen können, können Sie mehr daraus machen.
Interne Struktur von ZFSIstein Baum intern und alle Operationen werden über diesen Baum ausgeführt. Dateien, Verzeichnisse, Dateinamen, Attribute und alles andere sind nur Daten in diesem Baum. Snapshots, Volumes und FS sind die Baumwurzeln und wenn Sie einen weiteren Snapshot machen, speichern Sie einfach irgendwo die aktuelle Wurzel. Live-Systeme generieren für jede Transaktion neue Wurzeln und entfernen sich dabei ständig von den alten Wurzeln, während viele Datenblätter des vorherigen Baums intakt bleiben. Der Stream stellt eine Liste von Operationen dar, die an Baum A ausgeführt werden sollten, um zu B zu werden.
Ich möchte nur sagen, dass Sie die gesuchten Daten möglicherweise nicht im Stream sehen, weil sie dort nicht vorhanden sein müssen. Wenn die Datei gelöscht wird, werden die entsprechenden Blöcke einfach freigegeben, sodass Sie weder den Dateinamen noch den Inhalt erkennen können. Wenn die Datei geändert wird, wird sie über die Objekt-ID referenziert, sodass Sie nichts aus dem Stream erhalten würden, selbst wenn die Datei von Grund auf neu geschrieben wurde, der Verzeichniseintrag jedoch nicht aktualisiert wurde.
Sie können von Glück reden, wenn der Stream kein Differenzstrom ist oder Sie noch Daten über seinen vorherigen Zustand haben. Das liegt aber nur daran, dass ein vollständiger Stream eine leere Wurzel in den Zielbaum umwandelt und somit alle erforderlichen Daten enthält. Daher können Sie den Blockanalysecode hinzufügen, um zstreamdump
ZFS-interne Daten zu erkennen und zu verarbeiten.
Antwort2
Kurze Antwort:
Ich glaube nicht, dass es eine sinnvolle Möglichkeit gibt, den Inhalt eines Sendedatenstroms zu katalogisieren, die weniger Gewicht hat, als ihn an den ZFS-Empfang weiterzuleiten, um ihn als Datensatz neu zu erstellen.
Viel längere Antwort:
Ein Sendestrom ist eine Datensammlung auf Speicherblockebene,nichteine Datensammlung auf Dateisystemebene. Ein Sendestrom kennt und kümmert sich nicht um einzelne Dateien; er ist dafür ausgelegt, im Wesentlichen Rohblockgeräte zu replizieren. Während ein Benutzer es ausschließlich zum zfs send
Replizieren von ZFS-Datensätzen mit direkt darauf gespeicherten Dateien verwenden könnte, könnte ein anderer es zum Replizieren von ZVOLs verwenden, die mit ext4, ntfs oder sogar einem verschlüsselten System wie LUKS formatiert sind – in diesen Fällen hat ZFS absolut keine Kenntnis über den Inhalt des Datenträgers, sondern speichert lediglich die Rohblöcke für sie.
zfs send
funktioniert genau gleich, egal ob Sie einen Datensatz oder ein Roh-Zvol replizieren, da es sich einfach nicht um alles unterhalb der Rohblockspeicherebene kümmert. Es kennt keine Dateinamen, Dateigrößen, Pfade oder sonst etwas - es weiß, welche Blöcke zu einem bestimmten Snapshot eines Zvols oder Snapshots gehören, aber esnichtwissen, wie diese Blöcke miteinander in Beziehung stehen.
Es gibt also keine einfache Möglichkeit, den Dateiinhalt eines zfs send
Streams zu katalogisieren, daIstkein interner Katalog der Dateien in einem. Selbst wenn Sie sicher wissen, dass dieser bestimmte Stream eine vollständige (keine inkrementelle) Replikation eines unverschlüsselten ZFS-Datensatzes ist, müssten Sie jeden Block davon Zeile für Zeile analysieren, um herauszufinden, welche Blöcke davon Dateinamen enthalten.
Um die Dateinamen aus einem Sendedatenstrom zu extrahieren, würden Sie im Wesentlichen dieselbe Arbeit erledigen, die Sie zfs receive
erledigen, wenn Sie diesen Datenstrom zunächst auf einen Datensatz anwenden.