Linux에서 rsync가 / sys에서 파일을 복사하지 못하는 이유는 무엇입니까?


12

rsyncArchlinux에서 파일을 백업 하는 데 사용하는 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실패 하는지 궁금 하고 파일을 복사 할 수 있습니까?


4
왜 복사 /sys/하시겠습니까?
frostschutz

1
@frostschutz OP의 명령을 사용하여 네트워크 카드의 MAC 주소를 파일로 복사합니다
Eugene Yarmash

@eugeney 그렇다면 MAC 주소가 설정된 구성 파일을 백업하는 것만으로는 충분하지 않은 이유는 무엇입니까?
depquid

@eugeney 글을 쓰는 것도 가능 /sys/class/net/*/address합니까 (사용할 때 "권한이 거부되었습니다")? 그렇지 않으면 복원 할 수 없으므로 실제 / 유용한 백업을 작성하지 않은 것입니다.
depquid

답변:


12

Rsync에는 파일을 읽는 동안 파일이 잘 렸는지 확인하고이 오류를 발생시키는 코드있습니다ENODATA . 파일 /sys에이 동작이 있는지 모르겠지만 실제 파일이 아니기 때문에 너무 놀라운 것은 아닙니다. rsync 에게이 특정 검사를 건너 뛰도록 지시하는 방법이없는 것 같습니다.

/sys네트워크 카드 주소와 같은 원하는 특정 정보를 선택하기 위해 재 동기화하지 않고 특정 스크립트를 사용하는 것이 좋습니다 .


Pfft, 특히 rsync가 실패한 이유를 알지 못하는 재미는 어디에 있습니까?
Bratchley

죄송합니다. 확실하지 않았습니다. Rsync는 특히 읽기 도중 잘린 파일을 검사하여이 오류를 발생시킵니다.
mattdm

4
나는 그들이 당신이 실제로 읽을 때까지 "있는"것이 절대적으로 확실하지 않기 때문에 그들이 이런 행동을하는 것으로 추정합니다; 읽기는 실제로 커널에서 동적 정보를 요청하는 것입니다. 따라서 커널은 파일 크기 등에 대한 정확한 WRT 정보를 미리 제공하려고 시도하지 않으며, rsync는 이러한 불일치를 잘못된 부호로 간주합니다.
goldilocks

11

우선은 /sysA는 가상 파일 시스템 . 살펴보면 /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 's – sysfs Filesystem을 읽으십시오 .


/ sys 파일의 통계

아래 디렉토리에 들어가서 /sys수행하면 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 블록을 차지합니다. 또한 루트의 inode (stat / sys)는 1입니다. /stat/fs일반적으로 inode 2가 있습니다.

rsync 대 cp

의사 파일 동기화의 rsync 실패에 대한 가장 쉬운 설명은 예입니다.

이름 address이 18 바이트 인 파일이 있다고 가정하십시오 . ls또는 stat파일은 4096 바이트를보고합니다.


rsync

  1. 파일 디스크립터 fd를 엽니 다.
  2. fstat (fd)를 사용하여 크기와 같은 정보를 얻습니다.
  3. 읽은 크기 바이트, 즉 4096을 설정하십시오 . @mattdm으로 연결된 코드의 253 행 입니다.read_size == 4096
    1. 물어보기; 읽기 : 4096 바이트
    2. 짧은 문자열을 읽습니다 (예 : 18 바이트). nread == 18
    3. read_size = read_size - nread (4096 - 18 = 4078)
    4. 물어보기; 읽기 : 4078 바이트
    5. 읽은 0 바이트 (처음 읽었을 때 파일의 모든 바이트가 소비 됨)
    6. nread == 0, 255 라인
    7. 4096바이트 를 읽을 수 없습니다 . 제로 아웃 버퍼.
    8. 오류를 설정하십시오 ENODATA.
    9. 반환.
  4. 오류를보고하십시오.
  5. 다시 해 보다. (위 루프).
  6. 불합격.
  7. 오류를보고하십시오.
  8. 좋아.

이 과정에서 실제로 전체 파일을 읽습니다. 그러나 사용 가능한 크기가 없으면 결과를 확인할 수 없으므로 실패는 옵션 일뿐입니다.

cp

  1. 파일 디스크립터 fd를 엽니 다.
  2. fstat (fd)를 사용하여 st_size와 같은 정보를 얻습니다 (lstat 및 stat도 사용).
  3. 파일이 희박한지 확인하십시오. 즉 파일에 구멍이 있습니다.

    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보고서 파일이 제로 블록을 가지고 그것은 드문 드문로 분류된다.

  4. 익스텐트 복사 ( 일반 스파 스 파일 을 복사하는보다 효율적인 방법)로 파일을 읽으려고 시도했지만 실패합니다.

  5. 스파 스 복사로 복사합니다.
    1. MAXINT의 최대 읽기 크기로 시작합니다.
      일반적으로 1844674407370955161532 비트 시스템의 바이트입니다.
    2. 물어보기; 4096 바이트를 읽습니다. (통계 정보로부터 메모리에 할당 된 버퍼 크기)
    3. 짧은 문자열을 읽습니다 (예 : 18 바이트).
    4. 구멍이 필요한지 확인하십시오.
    5. 대상에 버퍼를 씁니다.
    6. 최대 읽기 크기에서 18을 뺍니다.
    7. 물어보기; 4096 바이트를 읽습니다.
    8. 처음 읽을 때 모두 0 바이트가 소비되었습니다.
    9. 성공을 돌려줍니다.
  6. 다 괜찮아. 파일의 업데이트 플래그.
  7. 좋아.

2

관련이있을 수 있지만 sysfs에서 확장 된 속성 호출이 실패합니다.

[root @ hypervisor eth0] # lsattr 주소

lsattr : 주소에서 플래그를 읽는 동안 장치에 부적절한 ioctl

[root @ hypervisor eth0] #

내 strace를 보면 rsync가 기본적으로 확장 된 속성을 가져 오는 것처럼 보입니다.

22964 <... getxattr resumed>, 0x7fff42845110, 132) = -1 ENODATA (데이터 없음)

나는 확장 된 속성을 생략하면 문제가 해결되는지 확인하기 위해 rsync를 제공하기 위해 깃발을 찾는 시도했지만 아무것도 (찾을 수 없습니다 --xattrs회전을 목적지에서 참조).


0

Rsync는 일반적으로 파일 정보를 읽고 파일 내용 또는 델타를 대상 디렉토리의 임시 파일로 전송 한 다음 파일의 데이터를 확인한 후 파일 이름을 대상 파일 이름으로 바꿉니다.

sysfs의 문제는 모든 파일이 4k (하나의 메모리 페이지)로 표시되지만 몇 바이트 만 포함 할 수 있다고 생각합니다. 잠재적으로 손상된 파일을 대상으로 복사하지 않도록 rsync는 파일의 메타 데이터와 실제로 복사 된 내용이 일치하지 않을 때 사본을 취소합니다.

rsync v3.0.6 이상에서는 --inplace스위치를 사용하여이 동작을 피할 수 있습니다 . Rsync는 여전히 오류를 감지하지만 대상 파일이 이미 덮어 쓰기 되었기 때문에 잠재적으로 손상된 파일이 남아 있습니다.

그 부작용은 rsync가 파일이 생각하는 크기이므로 파일이 4k로 0으로 채워지는 것입니다. 널 바이트는 일반적으로 무시되므로 대부분의 경우 차이를 만들지 않아야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.