Warum kann rsync unter Linux keine Dateien von / sys kopieren?


12

Ich habe ein Bash-Skript, mit dem ich rsyncDateien in Archlinux sichern kann. Mir ist aufgefallen, dass rsyncdas Kopieren einer Datei fehlgeschlagen ist /sys, während es einwandfrei cpfunktioniert hat:

# rsync /sys/class/net/enp3s1/address /tmp    
rsync: read errors mapping "/sys/class/net/enp3s1/address": No data available (61)
rsync: read errors mapping "/sys/class/net/enp3s1/address": No data available (61)
ERROR: address failed verification -- update discarded.
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1052) [sender=3.0.9]

# cp  /sys/class/net/enp3s1/address /tmp   ## this works

Ich frage mich, warum dies rsyncfehlschlägt und ist es möglich, die Datei damit zu kopieren?


4
Warum willst du kopieren /sys/?
Frostschutz

1
@ Frostschutz Ich benutze den Befehl im OP, um die MAC-Adresse einer Netzwerkkarte (als Datei) zu kopieren
Eugene Yarmash

@eugeney Warum reicht es nicht aus, die Konfigurationsdatei zu sichern, in der die MAC-Adresse festgelegt ist?
Depquid

@eugeney Kann /sys/class/net/*/addressich überhaupt schreiben (ich bekomme "Erlaubnis verweigert", wenn ich es versuche)? Wenn nicht, dann machen Sie kein echtes / nützliches Backup, da es nicht wiederhergestellt werden kann.
Depquid

Antworten:


12

Rsync hat Code, der speziell prüft, ob eine Datei während des Lesens abgeschnitten wird, und diesen Fehler ausgibt ENODATA. Ich weiß nicht, warum die Dateien in /sysdieses Verhalten haben, aber da es sich nicht um echte Dateien handelt, ist es wohl nicht allzu überraschend. Es scheint keine Möglichkeit zu geben, rsync anzuweisen, diese bestimmte Prüfung zu überspringen.

Ich denke, Sie sind wahrscheinlich besser dran, wenn Sie nicht rsynchen /sysund bestimmte Skripte verwenden, um die gewünschten Informationen (wie die Netzwerkkartenadresse) herauszusuchen.


Pfft, wo ist der Spaß daran, nicht herauszufinden, warum Rsync insbesondere fehlschlägt?
Bratchley

Entschuldigung, ich war nicht klar. Rsync sucht speziell nach Dateien, die beim Lesen abgeschnitten wurden, und löst diesen Fehler aus.
Mattdm

4
Ich gehe davon aus, dass sie dieses Verhalten haben, denn bis Sie sie tatsächlich lesen, ist nicht absolut sicher, was "da" ist. Das Lesen ist wirklich eine Anfrage nach dynamischen Informationen vom Kernel. Daher versucht der Kernel nicht, die Dateigröße usw. im Voraus mit genauen WRT-Angaben zu versehen, und wie Sie bereits betont haben, nimmt rsync eine solche Diskrepanz als schlechtes Zeichen.
Goldlöckchen

11

Zunächst einmal /sysist ein Pseudo-Dateisystem . Wenn Sie sich das ansehen /proc/filesystems, werden Sie eine Liste der registrierten Dateisysteme finden, bei denen einige nodev vor Ihnen liegen . Dies zeigt an, dass es sich um Pseudodateisysteme handelt . Dies bedeutet, dass sie auf einem laufenden Kernel als RAM-basiertes Dateisystem existieren. Außerdem benötigen sie kein Blockgerät.

$ cat /proc/filesystems
nodev   sysfs
nodev   rootfs
nodev   bdev
...

Beim Booten stellt der Kernel dieses System bereit und aktualisiert die Einträge, wenn dies angebracht ist. ZB wenn neue Hardware beim Booten oder durch gefunden wird udev.

In der /etc/mtabRegel finden Sie die Montierung durch:

sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0

Lesen Sie Patric Mochels - Das sysfs-Dateisystem, um eine schöne Abhandlung zu diesem Thema zu erhalten .


stat von / sys Dateien

Wenn Sie in ein Verzeichnis unter gehen /sysund a ls -lausführen, werden Sie feststellen, dass alle Dateien eine Größe haben. Normalerweise 4096 Bytes. Dies wird berichtet von sysfs.

:/sys/devices/pci0000:00/0000:00:19.0/net/eth2$ ls -l
-r--r--r-- 1 root root 4096 Apr 24 20:09 addr_assign_type
-r--r--r-- 1 root root 4096 Apr 24 20:09 address
-r--r--r-- 1 root root 4096 Apr 24 20:09 addr_len
...

Außerdem können Sie eine statDatei bearbeiten und eine weitere Besonderheit feststellen. Es belegt 0 Blöcke. Auch Inode von root (stat / sys) ist 1. hat /stat/fstypischerweise Inode 2. usw.

rsync vs. cp

Die einfachste Erklärung für rsync-Fehler beim Synchronisieren von Pseudodateien ist möglicherweise ein Beispiel.

Angenommen, wir haben eine Datei mit dem Namen address18 Byte. Eine lsoder statder Datei meldet 4096 Bytes.


rsync

  1. Öffnet den Dateideskriptor fd.
  2. Verwendet fstat (fd), um Informationen wie Größe abzurufen.
  3. Lies die Größe von Bytes, also 4096. Das wäre Zeile 253 des durch @mattdm verknüpften Codes .read_size == 4096
    1. Fragen; gelesen: 4096 Bytes.
    2. Ein kurzer String wird gelesen, dh 18 Bytes. nread == 18
    3. read_size = read_size - nread (4096 - 18 = 4078)
    4. Fragen; gelesen: 4078 Bytes
    5. 0 gelesene Bytes (beim ersten Lesen wurden alle Bytes in der Datei verbraucht).
    6. nread == 0, Linie 255
    7. 4096Bytes können nicht gelesen werden . Puffer auf Null setzen.
    8. Fehler einstellen ENODATA.
    9. Rückkehr.
  4. Fehler melden.
  5. Wiederholen. (Über Schleife).
  6. Scheitern.
  7. Fehler melden.
  8. FEIN.

Während dieses Vorgangs wird die gesamte Datei gelesen. Da jedoch keine Größe verfügbar ist, kann das Ergebnis nicht validiert werden. Ein Fehlschlag ist daher nur die Option.

cp

  1. Öffnet den Dateideskriptor fd.
  2. Verwendet fstat (fd), um Informationen wie st_size abzurufen (verwendet auch lstat und stat).
  3. Überprüfen Sie, ob die Datei wahrscheinlich spärlich ist. Das heißt die Feile hat Löcher etc.

    copy.c:1010
    /* Use a heuristic to determine whether SRC_NAME contains any sparse
     * blocks.  If the file has fewer blocks than would normally be
     * needed for a file of its size, then at least one of the blocks in
     * the file is a hole.  */
    sparse_src = is_probably_sparse (&src_open_sb);
    

    Als statBerichtsdatei mit null Blöcken wird sie als dünn eingestuft.

  4. Versucht, die Datei durch Extent-Copy zu lesen (eine effizientere Methode zum Kopieren normaler Dateien mit geringer Dichte), und schlägt fehl.

  5. Kopie durch Sparse-Copy.
    1. Beginnt mit der maximalen Lesegröße von MAXINT.
      In der Regel 18446744073709551615Bytes auf einem 32-Bit-System.
    2. Fragen; liest 4096 Bytes. (Puffergröße wird aus den stat-Informationen im Speicher zugewiesen.)
    3. Ein kurzer String wird gelesen, dh 18 Bytes.
    4. Überprüfen Sie, ob ein Loch benötigt wird, nein.
    5. Schreibe Puffer zum Ziel.
    6. Subtrahieren Sie 18 von der maximalen Lesegröße.
    7. Fragen; liest 4096 Bytes.
    8. 0 Bytes, da alle beim ersten Lesen verbraucht wurden.
    9. Rückkehr zum Erfolg.
  6. Alles ok. Aktualisieren Sie die Flags für die Datei.
  7. FEIN.

2

Könnte verwandt sein, aber erweiterte Attributaufrufe schlagen auf sysfs fehl:

[root @ hypervisor eth0] # lsattr address

lsattr: Unangemessenes ioctl für Gerät Beim Lesen von Flags auf Adresse

[root @ hypervisor eth0] #

Wenn ich mir meine Position ansehe, sieht es so aus, als würde rsync standardmäßig versuchen, erweiterte Attribute einzuspielen:

22964 <... getxattr resumed>, 0x7fff42845110, 132) = -1 ENODATA (Keine Daten verfügbar)

Ich habe versucht, ein Flag zu finden, mit dem rsync ausgeführt werden kann, um festzustellen, ob das Überspringen erweiterter Attribute das Problem behebt, konnte aber nichts finden ( --xattrsaktiviert sie am Zielort).


0

Normalerweise liest Rsync die Dateiinformationen, überträgt den Dateiinhalt oder das Delta in eine temporäre Datei im Zielverzeichnis und benennt sie nach Überprüfung der Dateidaten in den Zieldateinamen um.

Ich glaube, das Problem mit sysfs ist, dass alle Dateien als 4k (eine Speicherseite) angezeigt werden, aber möglicherweise nur wenige Bytes enthalten. Um zu vermeiden, dass eine möglicherweise beschädigte Datei auf das Ziel kopiert wird, bricht rsync die Kopie ab, wenn ein Konflikt zwischen den Metadaten der Datei und den tatsächlich kopierten Daten festgestellt wird.

Zumindest in rsync v3.0.6 kann dieses Verhalten mithilfe des --inplaceSchalters vermieden werden . Rsync erkennt weiterhin Fehler. Da die Zieldateien jedoch bereits überschrieben wurden, verbleiben die möglicherweise beschädigten Dateien dort.

Beachten Sie jedoch, dass der Nebeneffekt darin besteht, dass Dateien auf 4 KB mit Nullen aufgefüllt werden, da dies die Größe ist, die rsync für die Dateien hält. In den meisten Fällen sollte dies keinen Unterschied machen, da Null-Bytes normalerweise ignoriert werden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.