GNU/Linux >> Linux Esercitazione >  >> Linux

Perché rsync non riesce a copiare i file da /sys in Linux?

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

  1. Apre il descrittore di file, fd.
  2. Utilizza fstat(fd) per ottenere informazioni come la dimensione.
  3. Iniziato a leggere size byte, ad esempio 4096. Sarebbe la riga 253 del codice linkato da @mattdm. read_size == 4096
    1. Chiedi; letto:4096 byte.
    2. Viene letta una stringa breve, ad esempio 18 byte. nread == 18
    3. read_size = read_size - nread (4096 - 18 = 4078)
    4. Chiedi; letto:4078 byte
    5. 0 byte letti (poiché la prima lettura ha consumato tutti i byte nel file).
    6. nread == 0 , riga 255
    7. Impossibile leggere 4096 byte. Buffer azzerato.
    8. Imposta errore ENODATA .
    9. Ritorna.
  4. Segnala errore.
  5. Riprova. (Sopra il ciclo).
  6. Fallire.
  7. Segnala errore.
  8. 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

  1. Apre il descrittore di file, fd.
  2. Utilizza fstat(fd) per ottenere informazioni come st_size (usa anche lstat e stat).
  3. 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.

  4. Tenta di leggere il file tramite extent-copy (un modo più efficiente per copiare normal file sparse) e fallisce.

  5. Copia per copia sparsa.
    1. Inizia con la dimensione massima di lettura di MAXINT.
      Tipicamente18446744073709551615 byte su un sistema a 32 bit.
    2. Chiedi; leggere 4096 byte. (Dimensioni del buffer allocate in memoria dalle informazioni statistiche.)
    3. Viene letta una stringa breve, ovvero 18 byte.
    4. Controlla se è necessario un foro, no.
    5. Scrivi buffer nel target.
    6. Sottrai 18 dalla dimensione massima di lettura.
    7. Chiedi; leggere 4096 byte.
    8. 0 byte poiché tutti sono stati consumati in prima lettura.
    9. Ritorno riuscito.
  6. Tutto OK. Aggiorna flag per file.
  7. 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).


Linux
  1. In che modo Linux gestisce più separatori di percorsi consecutivi (/home////nomeutente///file)?

  2. Linux:la differenza tra /sys/block/sda1/stat e /sys/block/xvda1/stat?

  3. Come creare un file in Linux dalla finestra del terminale?

  4. Perché select è usato in Linux

  5. pscp copia il file in remoto da Windows a Linux

Copiare file in Linux

Come copiare file e directory in Linux

Comando Cp in Linux (copia file)

Copia un file in più directory dalla riga di comando su Linux

/proc/cpuinfo e /proc/meminfo in Linux

Perché rsync non utilizza il trasferimento delta per i file locali?