Rsync memiliki kode yang secara khusus memeriksa apakah file terpotong saat dibaca dan memberikan kesalahan ini — ENODATA
. Saya tidak tahu mengapa file di /sys
memiliki perilaku ini, tetapi karena itu bukan file asli, saya kira itu tidak terlalu mengejutkan. Sepertinya tidak ada cara untuk memberi tahu rsync untuk melewati pemeriksaan khusus ini.
Saya pikir Anda mungkin lebih baik tidak melakukan rsyncing /sys
dan menggunakan skrip khusus untuk memilih informasi tertentu yang Anda inginkan (seperti alamat kartu jaringan).
Pertama /sys
adalah sistem file semu . Jika Anda melihat /proc/filesystems
Anda akan menemukan daftar sistem file terdaftar di mana beberapa memiliki nodev
di depan. Ini menunjukkan bahwa mereka adalah sistem file semu . Ini berarti mereka ada pada kernel yang sedang berjalan sebagai sistem file berbasis RAM. Selanjutnya mereka tidak memerlukan perangkat blokir.
$ cat /proc/filesystems
nodev sysfs
nodev rootfs
nodev bdev
...
Saat boot, kernel memasang sistem ini dan memperbarui entri jika sesuai. Misalnya. ketika perangkat keras baru ditemukan selama boot atau dengan udev
.
Di /etc/mtab
Anda biasanya menemukan mount dengan:
sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0
Untuk makalah bagus tentang subjek, baca Patric Mochel's – The sysfs Filesystem.
stat file /sys
Jika Anda masuk ke direktori di bawah /sys
dan lakukan ls -l
Anda akan melihat bahwa semua file memiliki satu ukuran. Biasanya 4096 byte. Ini dilaporkan oleh 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
...
Selanjutnya Anda dapat melakukan stat
pada file dan perhatikan fitur lain yang berbeda; ini menempati 0 blok. Juga inode root (stat /sys) adalah 1. /stat/fs
biasanya memiliki inode 2. dll.
rsync vs. cp
Penjelasan termudah untuk kegagalan rsync dalam menyinkronkan file semu mungkin dengan contoh.
Katakanlah kita memiliki file bernama address
yaitu 18 byte. Sebuah ls
atau stat
dari file melaporkan 4096 byte.
rsync
- Membuka deskriptor file, fd.
- Menggunakan fstat(fd) untuk mendapatkan informasi seperti ukuran.
- Atur untuk membaca ukuran byte, yaitu 4096. Itu akan menjadi baris 253 dari kode yang ditautkan oleh @mattdm.
read_size == 4096
- Tanyakan; baca:4096 byte.
- String pendek dibaca yaitu 18 byte.
nread == 18
read_size = read_size - nread (4096 - 18 = 4078)
- Tanyakan; baca:4078 byte
- Pembacaan 0 byte (saat pembacaan pertama menggunakan semua byte dalam file).
nread == 0
, baris 255- Tidak dapat membaca
4096
byte. Nol buffer. - Tetapkan kesalahan
ENODATA
. - Kembali.
- Laporkan kesalahan.
- Coba lagi. (Di atas putaran).
- Gagal.
- Laporkan kesalahan.
- BAIK.
Selama proses ini sebenarnya membaca seluruh file. Namun tanpa ukuran yang tersedia, hasil tidak dapat divalidasi – sehingga kegagalan hanyalah pilihan.
cp
- Membuka deskriptor file, fd.
- Menggunakan fstat(fd) untuk mendapatkan informasi seperti st_size (juga menggunakan lstat dan stat).
-
Periksa apakah file cenderung jarang. Itu adalah file yang berlubang dll.
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);
Sebagai
stat
laporan file memiliki nol blok itu dikategorikan sebagai jarang. -
Mencoba membaca file berdasarkan salinan ekstensi (cara yang lebih efisien untuk menyalin normal file jarang), dan gagal.
- Salin dengan salinan jarang.
- Dimulai dengan ukuran baca maksimal MAXINT.
Biasanya18446744073709551615
byte pada sistem 32 bit. - Tanyakan; baca 4096 byte. (Ukuran buffer dialokasikan di memori dari informasi stat.)
- String pendek dibaca yaitu 18 byte.
- Periksa apakah diperlukan lubang, tidak.
- Tulis buffer ke target.
- Kurangi 18 dari ukuran baca maksimum.
- Tanyakan; baca 4096 byte.
- 0 byte karena semuanya terpakai pada pembacaan pertama.
- Kembali sukses.
- Dimulai dengan ukuran baca maksimal MAXINT.
- Semua baik-baik saja. Perbarui flag untuk file.
- BAIK.
Mungkin terkait, tetapi panggilan atribut yang diperluas akan gagal pada sysfs:
[[email protected] eth0]# alamat lsattr
lsattr:ioctl yang tidak sesuai untuk perangkat Saat membaca bendera di alamat
[[email protected] eth0]#
Melihat strace saya, sepertinya rsync mencoba menarik atribut tambahan secara default:
22964 <... getxattr resume> , 0x7fff42845110, 132) =-1 ENODATA (Data tidak tersedia)
Saya mencoba menemukan bendera untuk memberi rsync untuk melihat apakah melewatkan atribut yang diperluas menyelesaikan masalah tetapi tidak dapat menemukan apa pun (--xattrs
menyalakannya mengaktifkan di tempat tujuan).