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
- Abre el descriptor de archivo, fd.
- Utiliza fstat(fd) para obtener información como el tamaño.
- 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
- Preguntar; lectura:4096 bytes.
- Se lee una cadena corta, es decir, 18 bytes.
nread == 18
read_size = read_size - nread (4096 - 18 = 4078)
- Preguntar; lectura:4078 bytes
- 0 bytes leídos (ya que la primera lectura consumió todos los bytes del archivo).
nread == 0
, línea 255- No se puede leer
4096
bytes Poner a cero el búfer. - Establecer error
ENODATA
. - Volver.
- Informe de error.
- Reintentar. (Arriba del bucle).
- Fallo.
- Informe de error.
- 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
- Abre el descriptor de archivo, fd.
- Utiliza fstat(fd) para obtener información como st_size (también utiliza lstat y stat).
-
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. -
Intenta leer el archivo por copia de extensión (una forma más eficiente de copiar normal archivos dispersos) y falla.
- Copiar por copia dispersa.
- Comienza con un tamaño máximo de lectura de MAXINT.
Normalmente18446744073709551615
bytes en un sistema de 32 bits. - Preguntar; leer 4096 bytes. (Tamaño del búfer asignado en la memoria a partir de la información estadística).
- Se lee una cadena corta, es decir, 18 bytes.
- Compruebe si se necesita un agujero, no.
- Escribe el búfer en el destino.
- Reste 18 del tamaño máximo de lectura.
- Preguntar; leer 4096 bytes.
- 0 bytes ya que todo se consumió en la primera lectura.
- Devuelve el éxito.
- Comienza con un tamaño máximo de lectura de MAXINT.
- Todo bien. Actualizar marcas para el archivo.
- 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).