Rsync ha un codice che controlla specificamente se un file viene troncato durante la lettura e dà questo errore — ENODATA
. Non so perché i file in /sys
hanno questo comportamento, ma dal momento che non sono file reali, immagino che non sia troppo sorprendente. Non sembra esserci un modo per dire a rsync di saltare questo particolare controllo.
Penso che probabilmente faresti meglio a non sincronizzare /sys
e utilizzando script specifici per selezionare con cura le informazioni particolari che desideri (come l'indirizzo della scheda di rete).
Prima di tutto /sys
è uno pseudo file system . Se guardi /proc/filesystems
troverai un elenco di file system registrati in cui alcuni hanno nodev
di fronte. Questo indica che sono pseudo filesystem . Ciò significa che esistono su un kernel in esecuzione come file system basato su RAM. Inoltre non richiedono un dispositivo di blocco.
$ cat /proc/filesystems
nodev sysfs
nodev rootfs
nodev bdev
...
All'avvio il kernel monta questo sistema e aggiorna le voci quando lo desidera. Per esempio. quando viene trovato un nuovo hardware durante l'avvio o tramite udev
.
In /etc/mtab
in genere trovi la montatura per:
sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0
Per un bel documento sull'argomento leggi Patrick Mochel's – The sysfs Filesystem.
Statistiche dei file /sys
Se vai in una directory sotto /sys
e fai un ls -l
noterai che tutti i file hanno una dimensione. Tipicamente 4096 byte. Questo è riportato da 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
...
Inoltre puoi fare un stat
su un file e notare un'altra caratteristica distinta; occupa 0 blocchi. Anche l'inode di root (stat /sys) è 1. /stat/fs
tipicamente ha inode 2. ecc.
rsync contro cp
La spiegazione più semplice per il fallimento di rsync nella sincronizzazione degli pseudo file è forse con un esempio.
Diciamo che abbiamo un file chiamato address
ovvero 18 byte. Un ls
o stat
del file riporta 4096 byte.
rsync
- Apre il descrittore di file, fd.
- Utilizza fstat(fd) per ottenere informazioni come la dimensione.
- Iniziato a leggere size byte, ad esempio 4096. Sarebbe la riga 253 del codice linkato da @mattdm.
read_size == 4096
- Chiedi; letto:4096 byte.
- Viene letta una stringa breve, ad esempio 18 byte.
nread == 18
read_size = read_size - nread (4096 - 18 = 4078)
- Chiedi; letto:4078 byte
- 0 byte letti (poiché la prima lettura ha consumato tutti i byte nel file).
nread == 0
, riga 255- Impossibile leggere
4096
byte. Buffer azzerato. - Imposta errore
ENODATA
. - Ritorna.
- Segnala errore.
- Riprova. (Sopra il ciclo).
- Fallire.
- Segnala errore.
- BENE.
Durante questo processo legge effettivamente l'intero file. Ma senza dimensioni disponibili non può convalidare il risultato, quindi il fallimento è solo un'opzione.
cp
- Apre il descrittore di file, fd.
- Utilizza fstat(fd) per ottenere informazioni come st_size (usa anche lstat e stat).
-
Controlla se è probabile che il file sia sparse. Cioè il file ha buchi ecc.
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);
Come
stat
report per avere zero blocchi è classificato come sparse. -
Tenta di leggere il file tramite extent-copy (un modo più efficiente per copiare normal file sparse) e fallisce.
- Copia per copia sparsa.
- Inizia con la dimensione massima di lettura di MAXINT.
Tipicamente18446744073709551615
byte su un sistema a 32 bit. - Chiedi; leggere 4096 byte. (Dimensioni del buffer allocate in memoria dalle informazioni statistiche.)
- Viene letta una stringa breve, ovvero 18 byte.
- Controlla se è necessario un foro, no.
- Scrivi buffer nel target.
- Sottrai 18 dalla dimensione massima di lettura.
- Chiedi; leggere 4096 byte.
- 0 byte poiché tutti sono stati consumati in prima lettura.
- Ritorno riuscito.
- Inizia con la dimensione massima di lettura di MAXINT.
- Tutto OK. Aggiorna flag per file.
- BENE.
Potrebbe essere correlato, ma le chiamate agli attributi estesi falliranno su sysfs:
[[email protected] eth0]# indirizzo lsattr
lsattr:ioctl inappropriato per il dispositivo Durante la lettura dei flag sull'indirizzo
[[email protected] eth0]#
Guardando il mio strace sembra che rsync tenti di inserire attributi estesi per impostazione predefinita:
22964 <... getxattr resumed> , 0x7fff42845110, 132) =-1 ENODATA (nessun dato disponibile)
Ho provato a trovare un flag per dare rsync per vedere se saltare gli attributi estesi risolve il problema ma non sono riuscito a trovare nulla (--xattrs
li attiva a destinazione).