GNU/Linux >> Tutoriales Linux >  >> Linux

¿Por qué rsync no puede copiar archivos de /sys en Linux?

Rsync tiene un código que verifica específicamente si un archivo se trunca durante la lectura y da este error:ENODATA . No sé por qué los archivos en /sys tienen este comportamiento, pero como no son archivos reales, supongo que no es demasiado sorprendente. No parece haber una forma de decirle a rsync que omita esta verificación en particular.

Creo que es mejor que no rsyncing /sys y usar secuencias de comandos específicas para seleccionar la información particular que desea (como la dirección de la tarjeta de red).


En primer lugar /sys es un pseudosistema de archivos . Si miras /proc/filesystems encontrará una lista de sistemas de archivos registrados donde bastantes tienen nodev Al frente. Esto indica que son pseudosistemas de archivos . Esto significa que existen en un kernel en ejecución como un sistema de archivos basado en RAM. Además, no requieren un dispositivo de bloqueo.

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

En el arranque, el kernel monta este sistema y actualiza las entradas cuando sea adecuado. P.ej. cuando se encuentra nuevo hardware durante el arranque o por udev .

En /etc/mtab normalmente encuentras la montura por:

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

Para un buen artículo sobre el tema, lea Patric Mochel's – The sysfs Filesystem.

estadística de archivos /sys

Si ingresa a un directorio bajo /sys y haz un ls -l notará que todos los archivos tienen un tamaño. Típicamente 4096 bytes. Esto es informado por 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
...

Además puedes hacer un stat en un archivo y observe otra característica distinta; ocupa 0 bloques. También el inodo de raíz (stat /sys) es 1. /stat/fs normalmente tiene el inodo 2, etc.

rsync frente a cp

La explicación más fácil para la falla de rsync en la sincronización de pseudo archivos es quizás con un ejemplo.

Digamos que tenemos un archivo llamado address eso es 18 bytes. Un ls o stat del archivo informa 4096 bytes.

rsync

  1. Abre el descriptor de archivo, fd.
  2. Utiliza fstat(fd) para obtener información como el tamaño.
  3. Prepárese para leer bytes de tamaño, es decir, 4096. Esa sería la línea 253 del código vinculado por @mattdm. read_size == 4096
    1. Preguntar; lectura:4096 bytes.
    2. Se lee una cadena corta, es decir, 18 bytes. nread == 18
    3. read_size = read_size - nread (4096 - 18 = 4078)
    4. Preguntar; lectura:4078 bytes
    5. 0 bytes leídos (ya que la primera lectura consumió todos los bytes del archivo).
    6. nread == 0 , línea 255
    7. No se puede leer 4096 bytes Poner a cero el búfer.
    8. Establecer error ENODATA .
    9. Volver.
  4. Informe de error.
  5. Reintentar. (Arriba del bucle).
  6. Fallo.
  7. Informe de error.
  8. BIEN.

Durante este proceso, en realidad lee todo el archivo. Pero sin un tamaño disponible, no puede validar el resultado; por lo tanto, fallar es la única opción.

cp

  1. Abre el descriptor de archivo, fd.
  2. Utiliza fstat(fd) para obtener información como st_size (también utiliza lstat y stat).
  3. Compruebe si es probable que el archivo sea escaso. Ese es el archivo tiene agujeros, 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);
    

    Como stat el archivo de informes tiene cero bloques, se clasifica como escaso.

  4. Intenta leer el archivo por copia de extensión (una forma más eficiente de copiar normal archivos dispersos) y falla.

  5. Copiar por copia dispersa.
    1. Comienza con un tamaño máximo de lectura de MAXINT.
      Normalmente 18446744073709551615 bytes en un sistema de 32 bits.
    2. Preguntar; leer 4096 bytes. (Tamaño del búfer asignado en la memoria a partir de la información estadística).
    3. Se lee una cadena corta, es decir, 18 bytes.
    4. Compruebe si se necesita un agujero, no.
    5. Escribe el búfer en el destino.
    6. Reste 18 del tamaño máximo de lectura.
    7. Preguntar; leer 4096 bytes.
    8. 0 bytes ya que todo se consumió en la primera lectura.
    9. Devuelve el éxito.
  6. Todo bien. Actualizar marcas para el archivo.
  7. BIEN.

Puede estar relacionado, pero las llamadas a atributos extendidos fallarán en sysfs:

[[email protected] eth0]# dirección lsattr

lsattr:ioctl inapropiado para el dispositivo al leer indicadores en la dirección

[[email protected] eth0]#

Mirando mi strace, parece que rsync intenta obtener atributos extendidos de forma predeterminada:

22964 <... getxattr reanudado>, 0x7fff42845110, 132) =-1 ENODATA (sin datos disponibles)

Intenté encontrar un indicador para dar rsync para ver si omitir los atributos extendidos resuelve el problema, pero no pude encontrar nada (--xattrs los enciende encender en el destino).


Linux
  1. [Resuelto]:¿Por qué rsync no copió archivos/directorios ocultos y por qué Asterisk no incluye archivos ocultos (puntos) en Linux?

  2. Linux:¿la diferencia entre /sys/block/sda1/stat y /sys/block/xvda1/stat?

  3. ¿Qué son los archivos /dev/zero y /dev/null en Linux?

  4. ¿Por qué se usa select en Linux?

  5. ¿Por qué rsync no usa transferencia delta para archivos locales?

Copiar archivos en Linux

Cómo copiar archivos y directorios en Linux

Comando Cp en Linux (Copiar archivos)

Copie un archivo a varios directorios desde la línea de comandos en Linux

Archivos /proc/cpuinfo y /proc/meminfo en Linux

Copie archivos grandes de un servidor Linux a otro