rsync
Archlinux에서 파일을 백업하기 위한 bash 스크립트가 있습니다 . rsync
파일을 에서 복사할 수 없지만 /sys
정상적으로 cp
작동하는 것으로 나타났습니다 .
# 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
rsync
왜 실패하는지, 파일 복사에 사용할 수 있는지 알고 싶습니다 .
답변1
첫 번째 /sys
는의사 파일 시스템. 살펴보면 /proc/filesystems
등록된 파일 시스템 목록을 찾을 수 있으며 그 목록이 nodev
앞에 꽤 많이 있습니다. 이것은 그들이의사 파일 시스템. 이는 실행 중인 커널에 RAM 기반 파일 시스템으로 존재한다는 의미입니다. 또한 블록 장치가 필요하지 않습니다.
$ cat /proc/filesystems
nodev sysfs
nodev rootfs
nodev bdev
...
시작 시 커널은 시스템을 마운트하고 적절한 경우 항목을 업데이트합니다. 예를 들어 부팅 중이거나 udev
.
일반적으로 다음 /etc/mtab
을 통해 마운트를 찾을 수 있습니다.
sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0
이 주제에 대한 좋은 논문을 읽으려면 Patric Mochel의 – sysfs 파일 시스템.
/sys 파일 통계
아래 디렉토리로 가서 /sys
a를 하면 ls -l
모든 파일에 크기가 있다는 것을 알 수 있습니다. 일반적으로 4096바이트입니다. 이것은 에 의해 보고되었습니다 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
...
stat
게다가, 파일을 조작하면 0 블록을 차지한다는 또 다른 분명한 특징을 발견할 수 있습니다. 또한 루트 노드(stat /sys)의 inode는 1이다. /stat/fs
일반적으로 inode 2가 있습니다. 등.
rsync 및 cp
아마도 rsync의 의사 파일 동기화 실패에 대한 가장 간단한 설명은 예제를 통해서일 것입니다.
address
18바이트라는 파일이 있다고 가정해 보겠습니다 . 파일은 ls
4096바이트를 보고합니다.stat
동기화
- 파일 설명자 fd를 엽니다.
- 크기 및 기타 정보를 얻으려면 fstat(fd)를 사용하십시오.
- 4096인 size 바이트 읽기를 시작합니다. 그럴 것이다253호선링크된 코드@mattdem.
read_size == 4096
- Q;읽기: 4096바이트입니다.
- 18바이트의 짧은 문자열을 읽습니다.
nread == 18
read_size = read_size - nread (4096 - 18 = 4078)
- Q;읽기: 4078바이트
- 0바이트를 읽습니다(첫 번째 읽기에서 파일의 모든 바이트를 소비하기 때문).
nread == 0
,255번 국도- 바이트를 읽을 수 없습니다
4096
. 버퍼를 0으로 만듭니다. - 설정 오류입니다
ENODATA
. - 반품.
- 오류를 신고하세요.
- 다시 해 보다. (위 루프).
- 실패하다.
- 오류를 신고하세요.
- 아름다운.
이 프로세스 동안 실제로 전체 파일을 읽습니다. 그러나 사용 가능한 차원이 없기 때문에 결과를 확인할 수 없으므로 실패가 유일한 옵션입니다.
CP
- 파일 설명자 fd를 엽니다.
- st_size와 같은 정보를 얻으려면 fstat(fd)를 사용하십시오(lstat 및 stat도 사용함).
파일이 희박한지 확인하세요. 이는 파일 등에 허점이 있음을 의미합니다.
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);
보고된 파일에는 블록이 없으므로
stat
희소 파일로 분류됩니다.범위 복사를 통해 파일을 읽어 보십시오(더 효율적인 복사 방법)정상 스파스 파일), 실패합니다.
- 스파스 복제를 통해 복제합니다.
- 최대 읽기 크기 MAXINT부터 시작합니다. 일반적으로 32비트 시스템의
바이트입니다 .18446744073709551615
- Q;4096바이트를 읽었습니다. (통계를 기준으로 메모리에 할당된 버퍼 크기입니다.)
- 18바이트의 짧은 문자열을 읽습니다.
- 드릴링이 필요한지 확인하십시오.
- 대상에 버퍼를 씁니다.
- 최대 읽기 크기에서 18을 뺍니다.
- Q;4096바이트를 읽었습니다.
- 첫 번째 읽기에서 모두 소비되므로 0바이트입니다.
- 반환 성공.
- 최대 읽기 크기 MAXINT부터 시작합니다. 일반적으로 32비트 시스템의
- 모든 것이 잘되었습니다. 파일 플래그를 업데이트합니다.
- 아름다운.
답변2
재동기화는암호특히 읽는 동안 파일이 잘렸는지 확인하고 다음 오류를 표시합니다 ENODATA
. 나는 전혀 모른다왜의 파일에는 /sys
이러한 동작이 있지만 실제 파일이 아니기 때문에 그리 놀라운 일은 아닙니다. rsync에게 이 특정 검사를 건너뛰도록 지시할 수 있는 방법은 없는 것 같습니다.
/sys
rsync를 수행하지 않고 특정 스크립트를 사용하여 원하는 특정 정보(예: 네트워크 카드 주소)를 선택하는 것이 더 낫다고 생각합니다 .
답변3
관련이 있을 수 있지만 확장된 속성 호출은 sysfs에서 실패합니다.
[root@hypervisor eth0]# lsattr 주소
lsattr: 주소에서 플래그를 읽을 때 장치에 대한 부적절한 ioctl
[루트@하이퍼바이저 eth0]#
내 strace를 보면 rsync가 기본적으로 확장 속성을 가져오려고 시도하는 것 같습니다.
22964 <... getxattr Recovery> , 0x7fff42845110, 132) = -1 ENODATA(사용 가능한 데이터 없음)
확장 속성을 건너뛰면 문제가 해결되는지 확인하기 위해 rsync를 제공하는 플래그를 찾으려고 했지만 아무 것도 찾을 수 없습니다 --xattrs
.존재하다목적지에 도달).
답변4
Rsync는 일반적으로 파일 정보를 읽고 파일 내용이나 델타를 대상 디렉터리의 임시 파일로 전송한 다음 유효성을 검사한 후 파일 데이터의 이름을 대상 파일 이름으로 바꿉니다.
내 생각에 sysfs의 문제는 모든 파일이 4k(메모리 한 페이지)로 보이지만 몇 바이트만 포함할 수 있다는 것입니다. 잠재적으로 손상될 수 있는 파일이 대상에 복사되는 것을 방지하기 위해 rsync는 파일의 메타데이터가 실제로 복사된 것과 일치하지 않는 것을 발견하면 복사를 취소합니다.
최소한 rsync v3.0.6에서는 --inplace
스위치를 사용하여 이 동작을 방지하는 것이 가능합니다. Rsync는 여전히 오류를 감지하지만 감지 시 대상 파일을 덮어썼기 때문에 잠재적으로 손상된 파일이 그대로 남아 있게 됩니다.
이것의 부작용은 파일이 4k로 0으로 채워지는 것입니다. 왜냐하면 rsync가 파일의 크기를 생각하는 크기이기 때문입니다. 대부분의 경우 널 바이트는 일반적으로 무시되므로 아무런 효과가 없습니다.