लिनक्स में / sys से फाइल कॉपी करने में rsync क्यों विफल है?


12

मेरे पास एक बैश स्क्रिप्ट है जो rsyncआर्कलिनक्स में बैकअप फ़ाइलों का उपयोग करती है। मैंने देखा कि 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/?
ठंढकुट्ज़

1
@frostschutz मैं एक नेटवर्क कार्ड के मैक-एड्रेस (एक फ़ाइल के रूप में) की प्रतिलिपि बनाने के लिए ओपी में कमांड का उपयोग करता हूं
यूजीन यर्मश

@eugeney तो, क्यों यह मैक फ़ाइल जहां मैक पते से सेट है बैकअप फ़ाइल के लिए पर्याप्त नहीं है?
depquid

@eugeney क्या इसे लिखना संभव है /sys/class/net/*/address(जब मैं इसे आज़माता हूं तो मुझे "अनुमति अस्वीकृत" मिल जाती है)? यदि नहीं, तो आप वास्तविक / उपयोगी बैकअप नहीं बना रहे हैं क्योंकि यह पुनर्स्थापित नहीं किया जा सकता है।
depquid

जवाबों:


12

Rsync में कोड होता है जो विशेष रूप से जांचता है कि क्या कोई फ़ाइल पढ़ने के दौरान छोटा हो गया है और यह त्रुटि देता है - ENODATA। मुझे नहीं पता कि फाइलों में /sysयह व्यवहार क्यों है, लेकिन चूंकि वे वास्तविक फाइलें नहीं हैं, इसलिए मुझे लगता है कि यह बहुत आश्चर्य की बात नहीं है। इस विशेष जांच को छोड़ने के लिए rsync को बताने का कोई तरीका प्रतीत नहीं होता है।

मुझे लगता है कि आप संभवत: बेहतर नहीं हैं कि आप /sysविशिष्ट स्क्रिप्ट का उपयोग न करें और विशिष्ट स्क्रिप्ट का उपयोग करें, जो आप चाहते हैं (जैसे नेटवर्क नेटवर्क पता)।


Pfft, जहां विशेष रूप से rsync क्यों विफल में मज़ा नहीं है?
ब्राचली

क्षमा करें, मैं स्पष्ट नहीं था। Rsync विशेष रूप से पढ़ने के दौरान छंटनी की गई फ़ाइलों की जाँच करता है और इस त्रुटि को फेंकता है।
Mattdm

4
मुझे लगता है कि उनके पास यह व्यवहार है क्योंकि जब तक आप वास्तव में उन्हें नहीं पढ़ते, तब तक "वहाँ" बिल्कुल निश्चित नहीं है; रीड वास्तव में कर्नेल से गतिशील जानकारी के लिए एक अनुरोध है। तो कर्नेल अग्रिम में फ़ाइल विवरण, आदि के लिए सटीक विवरण WRT देने की कोशिश नहीं करता है, और जैसा कि आप बताते हैं, rsync इस तरह की विसंगति को एक बुरे संकेत के रूप में लेता है।
गोल्डीलॉक्स

11

सबसे पहले /sysएक छद्म फाइल सिस्टम है । यदि आप देखते हैं तो आपको /proc/filesystemsपंजीकृत फाइल सिस्टम की एक सूची मिलेगी, जहां काफी कुछ nodev सामने हैं। यह इंगित करता है कि वे छद्म फाइलसिस्टम हैं । इसका मतलब है कि वे एक रैम-आधारित फाइल सिस्टम के रूप में चल रहे कर्नेल पर मौजूद हैं। आगे उन्हें ब्लॉक डिवाइस की आवश्यकता नहीं है।

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

बूट पर कर्नेल इस सिस्टम को माउंट करता है और अनुकूल होने पर प्रविष्टियों को अपडेट करता है। उदाहरण के लिए, जब बूट या द्वारा नया हार्डवेयर पाया जाता है udev

में /etc/mtabआप आमतौर पर खोजने के द्वारा माउंट:

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

विषय पर एक अच्छे पेपर के लिए पैट्रिक मोशेल के - द साइफ्स फाइलसिस्टम पढ़ें ।


/ एसआईएस फाइलों की प्रतिमा

यदि आप एक निर्देशिका के तहत जाते हैं /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 ब्लॉक पर है। जड़ (स्टेट / एसआईएस) का /stat/fsभी इनोड है। आमतौर पर इनोड 2 है। आदि।

rsync बनाम cp

छद्म फ़ाइलों को सिंक्रनाइज़ करने की rsync विफलता के लिए सबसे आसान स्पष्टीकरण शायद उदाहरण के लिए है।

मान लें कि हमारे पास एक फाइल है जिसका नाम address18 बाइट्स है। फ़ाइल की एक lsया stat4096 बाइट्स की रिपोर्ट करती है।


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. St_size (lstat और stat का उपयोग करता है) जैसी जानकारी प्राप्त करने के लिए fstat (fd) का उपयोग करता है।
  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 के अधिकतम रीड आकार के साथ प्रारंभ होता है।
      आमतौर 18446744073709551615पर एक 32 बिट सिस्टम पर बाइट्स।
    2. पूछना; 4096 बाइट्स पढ़ें। (स्टेटम आकार जानकारी से स्मृति में आवंटित आकार।)
    3. एक छोटी स्ट्रिंग को 18 बाइट्स पढ़ा जाता है।
    4. जांच लें कि क्या छेद की जरूरत है, नहीं।
    5. लक्ष्य पर बफर लिखें।
    6. अधिकतम रीड साइज से 18 घटाएं।
    7. पूछना; 4096 बाइट्स पढ़ें।
    8. 0 बाइट्स के रूप में सभी पहले पढ़ने में भस्म हो गया।
    9. सफलता लौटाओ।
  6. सब ठीक है। फ़ाइल के लिए झंडे अपडेट करें।
  7. ठीक।

2

संबंधित हो सकते हैं, लेकिन विस्तारित विशेषता कॉल sysfs पर विफल होंगे:

[रूट @ हाइपरवाइजर eth0] # lsattr एड्रेस

lsattr: डिवाइस पर अनुचित ioctl पते पर झंडे पढ़ते समय

[रूट @ हाइपरवाइजर eth0] #

मेरे स्ट्रेस को देखकर ऐसा लग रहा है कि rsync डिफ़ॉल्ट रूप से विस्तारित विशेषताओं में खींचने की कोशिश करता है:

22964 <... getxattr फिर से शुरू>, 0x7fff42845110, 132) = -1 ENODATA (कोई डेटा उपलब्ध नहीं)

मैंने rsync देने के लिए एक ध्वज खोजने की कोशिश की, यह देखने के लिए कि क्या विस्तारित एक्सटेंशन समस्या को हल करता है, लेकिन कुछ भी खोजने में सक्षम नहीं था ( गंतव्य पर--xattrs उन्हें चालू करता है)।


0

Rsync सामान्य रूप से फ़ाइल की जानकारी को पढ़ते हैं, फ़ाइल सामग्री को स्थानांतरित करते हैं या गंतव्य निर्देशिका में एक अस्थायी फ़ाइल को डेल्टा करते हैं, फिर फ़ाइल के डेटा को सत्यापित करने के बाद इसे गंतव्य फ़ाइल नाम में बदल देते हैं।

मेरा मानना ​​है कि sysfs के साथ समस्या यह है कि सभी फाइलें 4k (एक मेमोरी पेज) के रूप में दिखाई देती हैं, फिर भी उनमें केवल कुछ बाइट्स हो सकते हैं। गंतव्य पर rsync के लिए संभावित रूप से दूषित फ़ाइल की प्रतिलिपि बनाने से बचने के लिए जब वह फ़ाइल के मेटाडेटा के बीच एक बेमेल देखता है और वास्तव में प्रतिलिपि बनाई गई थी, तो प्रतिलिपि को रद्द कर देता है।

कम से कम rsync v3.0.6 पर इस व्यवहार को --inplaceस्विच का उपयोग करके टाला जा सकता है । रुपीक्स अभी भी त्रुटियों का पता लगाएगा, लेकिन चूंकि गंतव्य फाइलें पहले ही अधिलेखित हो चुकी होंगी, जब ऐसा होता है तो यह संभावित रूप से भ्रष्ट फाइलों को छोड़ देगा।

ध्यान दें कि इसका एक पक्ष प्रभाव यह है कि फाइलें 4k तक शून्य-पैडेड हो जाती हैं क्योंकि यह आकार rsync लगता है कि फाइलें हैं। यह ज्यादातर मामलों में अंतर नहीं होना चाहिए क्योंकि अशक्त बाइट्स को आमतौर पर अनदेखा किया जाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.