Rsync neden Linux'ta / sys'den dosya kopyalayamıyor?


12

rsyncArchlinux dosyaları yedeklemek için kullanılan bir bash komut dosyası var . Sadece iyi çalışırken, rsyncbir dosyayı kopyalamak başarısız olduğunu fark ettim :/syscp

# 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

Acaba neden rsyncbaşarısız oluyor ve dosyayı onunla kopyalamak mümkün mü?


4
Neden kopyalamak istiyorsun /sys/?
frostschutz

1
@frostschutz Bir ağ kartının MAC adresini (dosya olarak) kopyalamak için OP'deki komutu kullanıyorum
Eugene Yarmash

@eugeney Peki, MAC adresinin ayarlandığı yapılandırma dosyasını yedeklemek neden yeterli değil?
depquid

@ eugeney Yazmak bile mümkün mü /sys/class/net/*/address(denediğimde "izin reddedildi")? Değilse, geri yüklenemeyeceği için gerçek / yararlı bir yedekleme yapmazsınız.
depquid

Yanıtlar:


12

Rsync, bir dosyanın okuma sırasında kesilip kesilmediğini kontrol eden ve bu hatayı veren bir koda sahiptir ENODATA. Dosyaların neden/sys bu davranışa sahip olduğunu bilmiyorum , ancak gerçek dosyalar olmadıklarından, sanırım çok şaşırtıcı değil. Rsync'e bu özel denetimi atlamasını söylemenin bir yolu yok gibi görünüyor.

Ben muhtemelen /sysistediğiniz belirli bilgileri (ağ kartı adresi gibi) kiraz almak için rsyncing ve belirli komutları kullanarak daha iyi kapalı olduğunu düşünüyorum .


Pfft, özellikle rsync'in neden başarısız olduğunu anlayamamanın eğlencesi nerede?
Bratchley

Üzgünüm, net değildim. Rsync özellikle okuma sırasında kesilen dosyaları kontrol eder ve bu hatayı atar.
mattdm

4
Bu davranışa sahip olduklarını varsayıyorum çünkü siz onları gerçekten okuyana kadar, "orada" olan şey kesinlikle kesin değildir; okuma gerçekten çekirdekten gelen dinamik bilgi talebidir. Çekirdek, dosya boyutuna, vb. Doğru ayrıntıları WRT vermeye çalışmaz ve işaret ettiğiniz gibi, rsync kötü bir işaret gibi bir tutarsızlık alır.
goldilocks

11

Öncelikle /sysbir olduğunu sözde dosya sistemi . Eğer bakarsanız, /proc/filesystemsbirkaçının nodev önünde kayıtlı dosya sistemlerinin bir listesini bulacaksınız . Bu, sözde dosya sistemleri olduklarını gösterir . Bu, çalışan bir çekirdeğe RAM tabanlı bir dosya sistemi olarak var oldukları anlamına gelir. Ayrıca bir blok cihaz gerektirmezler.

$ cat /proc/filesystems
nodev   sysfs
nodev   rootfs
nodev   bdev
...

Çekirdek açılışta bu sistemi monte eder ve uygun olduğunda girişleri günceller. Örneğin, önyükleme sırasında veya tarafından yeni bir donanım bulunduğunda udev.

Gelen /etc/mtabgenellikle bulmak tarafından monte:

sysfs /sys sysfs rw,noexec,nosuid,nodev 0 0

Konuyla ilgili güzel bir makale için Patric Mochel's - sysfs Dosya Sistemi'ni okuyun .


stat / sys dosyaları

Altında bir dizine gidip /sysbir ls -lyaparsanız, tüm dosyaların bir boyutu olduğunu fark edeceksiniz. Genellikle 4096 bayt. Bu tarafından bildirilir 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
...

Ayrıca statbir dosya üzerinde bir yapabilir ve başka bir belirgin özelliği fark edebilirsiniz; 0 blok kaplar. Ayrıca kök inode (stat / sys) 1'dir. /stat/fsTipik olarak inode 2 vardır.

rsync vs. cp

Sahte dosyaları senkronize etmede rsync hatası için en kolay açıklama belki örnek olarak verilebilir.

Diyelim ki address18 bayt adlı bir dosyamız var . Bir lsveya statdosyanın 4096 bayt bildirir.


rsync

  1. Dosya tanımlayıcıyı açar, fd.
  2. Boyut gibi bilgileri almak için fstat (fd) kullanır.
  3. Olacağını boyutu bayt, yani 4096. okumak için yola hat 253 ile bağlantılı kod @mattdm .read_size == 4096
    1. Sor; okuma: 4096 bayt.
    2. Kısa bir dize okunur, yani 18 bayt. nread == 18
    3. read_size = read_size - nread (4096 - 18 = 4078)
    4. Sor; okuma: 4078 bayt
    5. 0 bayt okundu (ilk okunduğunda dosyadaki tüm baytları tüketir).
    6. nread == 0, satır 255
    7. 4096Bayt okunamıyor . Sıfır tamponu.
    8. Hata ayarlayın ENODATA.
    9. Dönüş.
  4. Hata bildir.
  5. Tekrar dene. (Döngünün üstünde).
  6. Başarısız.
  7. Hata bildir.
  8. İNCE.

Bu işlem sırasında dosyanın tamamını okur. Ancak hiçbir boyut mevcut olmadığında sonucu doğrulayamaz - bu nedenle hata sadece seçenektir.

cp

  1. Dosya tanımlayıcıyı açar, fd.
  2. St_size gibi bilgileri almak için fstat (fd) kullanır (ayrıca lstat ve stat kullanır).
  3. Dosyanın seyrek olup olmadığını kontrol edin. Dosyanın delikleri vb.

    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);
    

    Gibi statraporlar dosya sıfır bloğuna sahip olacak o seyrek olarak kategorize edilir.

  4. Dosyayı kapsamlı kopyalamaya ( normal seyrek dosyaları kopyalamanın daha etkili bir yolu) göre okumaya çalışır ve başarısız olur.

  5. Seyrek kopya ile kopyalayın.
    1. MAXINT maksimum okuma boyutu ile başlar.
      Tipik olarak 1844674407370955161532 bit sistemdeki bayt sayısı.
    2. Sor; 4096 bayt oku. (Bellek bilgilerinde stat bilgilerinden ayrılan arabellek boyutu.)
    3. Kısa bir dize okunur, yani 18 bayt.
    4. Bir deliğin gerekli olup olmadığını kontrol edin, hayır.
    5. Hedefe tampon yaz.
    6. Maksimum okuma boyutundan 18 çıkartın.
    7. Sor; 4096 bayt oku.
    8. İlk okunuşta tüketildiği gibi 0 bayt.
    9. Geri dönüş başarısı.
  6. Her şey yolunda. Dosya bayraklarını güncelle.
  7. İNCE.

2

İlişkili olabilir, ancak genişletilmiş öznitelik çağrıları sysfs'de başarısız olur:

[root @ hypervisor eth0] # lsattr adresi

lsattr: Aygıt için uygun ioctl Adresdeki bayrakları okurken

[kök @ hipervizör eth0] #

Benim strace bakarak rsync varsayılan olarak genişletilmiş öznitelikleri çekmeye çalışıyor gibi görünüyor:

22964 <... getxattr devam>> 0x7fff42845110, 132) = -1 ENODATA (Veri yok)

Ben genişletilmiş özelliklerini atlama sorunu çözüp çözmediğini görmek için rsync vermek için bir bayrak bulmakta çalıştı ama herhangi bir şey (bulmak mümkün değildi --xattrsdönüşler onları üzerinde hedefe).


0

Rsync normalde dosyanın bilgilerini okur, dosya içeriğini veya deltaları hedef dizindeki geçici bir dosyaya aktarır, ardından dosyanın verilerini doğruladıktan sonra dosyayı hedef dosya adına yeniden adlandırır.

Sysfs ile ilgili sorun, tüm dosyaların 4k (bir bellek sayfası) olarak gösterildiğine inanıyorum, ancak sadece birkaç bayt içerebilirler. Potansiyel olarak bozuk bir dosyayı hedefe kopyalamaktan kaçınmak için rsync, dosyanın meta verileri ile gerçekte kopyalananlar arasında bir uyumsuzluk gördüğünde kopyayı iptal eder.

En azından rsync v3.0.6 sürümünde bu davranış --inplaceanahtar kullanılarak önlenebilir . Rsync yine de hataları algılayacaktır, ancak hedef dosyalar zaten üzerine yazıldığından, potansiyel olarak bozuk dosyaları orada bırakacaktır.

Bununla birlikte, bunun bir yan etkisi, dosyaların rsync'in dosyaların olduğunu düşündüğü boyutta 4k'ye sıfır doldurulmasıdır. Boş baytlar genellikle yok sayıldığı için çoğu durumda fark yaratmamalıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.