GNU/Linux >> Belajar Linux >  >> Linux

Mengapa rsync gagal menyalin file dari /sys di Linux?

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

  1. Membuka deskriptor file, fd.
  2. Menggunakan fstat(fd) untuk mendapatkan informasi seperti ukuran.
  3. Atur untuk membaca ukuran byte, yaitu 4096. Itu akan menjadi baris 253 dari kode yang ditautkan oleh @mattdm. read_size == 4096
    1. Tanyakan; baca:4096 byte.
    2. String pendek dibaca yaitu 18 byte. nread == 18
    3. read_size = read_size - nread (4096 - 18 = 4078)
    4. Tanyakan; baca:4078 byte
    5. Pembacaan 0 byte (saat pembacaan pertama menggunakan semua byte dalam file).
    6. nread == 0 , baris 255
    7. Tidak dapat membaca 4096 byte. Nol buffer.
    8. Tetapkan kesalahan ENODATA .
    9. Kembali.
  4. Laporkan kesalahan.
  5. Coba lagi. (Di atas putaran).
  6. Gagal.
  7. Laporkan kesalahan.
  8. BAIK.

Selama proses ini sebenarnya membaca seluruh file. Namun tanpa ukuran yang tersedia, hasil tidak dapat divalidasi – sehingga kegagalan hanyalah pilihan.

cp

  1. Membuka deskriptor file, fd.
  2. Menggunakan fstat(fd) untuk mendapatkan informasi seperti st_size (juga menggunakan lstat dan stat).
  3. 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.

  4. Mencoba membaca file berdasarkan salinan ekstensi (cara yang lebih efisien untuk menyalin normal file jarang), dan gagal.

  5. Salin dengan salinan jarang.
    1. Dimulai dengan ukuran baca maksimal MAXINT.
      Biasanya18446744073709551615 byte pada sistem 32 bit.
    2. Tanyakan; baca 4096 byte. (Ukuran buffer dialokasikan di memori dari informasi stat.)
    3. String pendek dibaca yaitu 18 byte.
    4. Periksa apakah diperlukan lubang, tidak.
    5. Tulis buffer ke target.
    6. Kurangi 18 dari ukuran baca maksimum.
    7. Tanyakan; baca 4096 byte.
    8. 0 byte karena semuanya terpakai pada pembacaan pertama.
    9. Kembali sukses.
  6. Semua baik-baik saja. Perbarui flag untuk file.
  7. 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).


Linux
  1. Apa itu file /dev/zero dan /dev/null di Linux?

  2. Bagaimana cara membuat file di Linux dari jendela terminal?

  3. Mengapa rsync tidak menggunakan delta-transfer untuk file lokal?

  1. Mengapa Windows tidak mengenali file di dalam partisi Linux?

  2. menyalin file dari windows ke Linux

  3. Mengapa dd from /dev/random memberikan ukuran file yang berbeda?

  1. Salin file di terminal Linux

  2. [Diselesaikan]:Mengapa rsync tidak menyalin file/direktori Tersembunyi dan Mengapa tanda bintang tidak menyertakan file tersembunyi (titik) di Linux?

  3. Salin file besar dari satu server Linux ke yang lain