आपने एनएफएस के बारे में पूछा। एनएफएस के तहत इस तरह के कोड के टूटने की संभावना है, क्योंकि चेक noclobber
में दो अलग-अलग एनएफएस ऑपरेशन शामिल हैं (चेक यदि फ़ाइल मौजूद है, तो नई फ़ाइल बनाएं) और दो अलग-अलग एनएफएस ग्राहकों से दो प्रक्रिया एक दौड़ की स्थिति में मिल सकती है जहां दोनों सफल होते हैं ( दोनों सत्यापित करते हैं कि B.part
अभी तक मौजूद नहीं है, फिर दोनों इसे सफलतापूर्वक बनाने के लिए आगे बढ़ते हैं, परिणामस्वरूप वे एक-दूसरे को अधिलेखित कर रहे हैं।)
वहाँ वास्तव में एक सामान्य जाँच करने के लिए नहीं है कि फाइलसिस्टम जो आप लिख रहे हैं वह noclobber
परमाणु रूप से कुछ का समर्थन करेगा या नहीं। आप फाइल सिस्टम प्रकार की जांच कर सकते हैं, चाहे वह एनएफएस हो, लेकिन यह एक अनुमानी होगा और जरूरी नहीं कि गारंटी हो। SMB / CIFS (सांबा) जैसे फाइलसिस्टम के समान समस्याओं से ग्रस्त होने की संभावना है। फ़ाइल सिस्टम FUSE के माध्यम से उजागर होता है या सही ढंग से व्यवहार नहीं कर सकता है, लेकिन यह ज्यादातर कार्यान्वयन पर निर्भर करता है।
संभवतः एक बेहतर दृष्टिकोण B.part
एक अद्वितीय फ़ाइल नाम (अन्य एजेंटों के साथ सहयोग के माध्यम से) के चरण में टकराव से बचने के लिए है , ताकि आपको इस पर निर्भर होने की आवश्यकता न हो noclobber
। उदाहरण के लिए, आप फ़ाइल नाम, अपने होस्टनाम, पीआईडी और टाइमस्टैम्प (+ एक यादृच्छिक संख्या।) के भाग के रूप में शामिल कर सकते हैं, क्योंकि किसी भी समय एक मेजबान में एक विशिष्ट पीआईडी के तहत चलने वाली एक ही प्रक्रिया होनी चाहिए, यह होना चाहिए। विशिष्टता की गारंटी।
तो या तो एक:
test -f B && continue # skip already existing
unique=$(hostname).$$.$(date +%s).$RANDOM
cp A B.part."$unique"
# Maybe check for existance of B again, remove
# the temporary file and bail out in that case.
mv B.part."$unique" B
# mv (rename) should always succeed, overwrite a
# previously copied B if one exists.
या:
test -f B && continue # skip already existing
unique=$(hostname).$$.$(date +%s).$RANDOM
cp A B.part."$unique"
if ln B.part."$unique" B ; then
echo "Success creating B"
else
echo "Failed creating B, already existed"
fi
# Both cases require cleanup.
rm B.part."$unique"
इसलिए यदि आपके पास दो एजेंटों के बीच एक दौड़ की स्थिति है, तो वे दोनों ऑपरेशन के साथ आगे बढ़ेंगे, लेकिन अंतिम ऑपरेशन परमाणु होगा, इसलिए या तो बी ए की पूरी प्रति के साथ मौजूद है, या बी मौजूद नहीं है।
आप प्रतिलिपि के बाद mv
या ln
ऑपरेशन से पहले फिर से जाँच करके दौड़ के आकार को कम कर सकते हैं , लेकिन वहाँ अभी भी एक छोटी दौड़ की स्थिति है। लेकिन, दौड़ की स्थिति की परवाह किए बिना, बी की सामग्री सुसंगत होनी चाहिए, यह मानते हुए कि दोनों प्रक्रियाएं इसे ए (या मूल के रूप में एक मान्य फ़ाइल से एक प्रति) बनाने की कोशिश कर रही हैं।
ध्यान दें कि पहली स्थिति में mv
, जब कोई दौड़ मौजूद होती है, तो अंतिम प्रक्रिया वही होती है जो जीतता है, क्योंकि नाम बदलकर (2) किसी मौजूदा फ़ाइल को बदल देगा।
यदि newpath पहले से मौजूद है, तो इसे परमाणु रूप से बदल दिया जाएगा, ताकि ऐसा कोई बिंदु न हो जिस पर newpath तक पहुंचने का प्रयास करने वाली अन्य प्रक्रिया उसे अनुपलब्ध लगेगी । [...]
यदि newpath मौजूद है, लेकिन ऑपरेशन किसी कारण से विफल हो जाता है, तो newpathrename()
का एक उदाहरण छोड़ने की गारंटी देता है।
तो, इस समय B का उपभोग करने वाली काफी संभव प्रक्रियाएं इस प्रक्रिया के दौरान इसके विभिन्न संस्करणों (अलग-अलग इनोड्स) को देख सकती हैं। यदि लेखक सिर्फ एक ही सामग्री को कॉपी करने की कोशिश कर रहे हैं, और पाठक बस फ़ाइल की सामग्री का उपभोग कर रहे हैं, तो यह ठीक हो सकता है, अगर उन्हें एक ही सामग्री के साथ फ़ाइलों के लिए अलग-अलग इनोड्स मिलते हैं, तो वे बस एक ही खुश होंगे।
हार्ड लिंक का उपयोग करने वाला दूसरा दृष्टिकोण बेहतर दिखता है, लेकिन मुझे याद है कि कई समवर्ती ग्राहकों से एनएफएस पर कड़ी लूप में हार्डलिंक के साथ प्रयोग करना और सफलता की गिनती करना और वहां अभी भी कुछ दौड़ की स्थिति दिख रही थी, जहां ऐसा लगता था कि दो ग्राहकों ने हार्डलिंक जारी किया था एक ही समय में, एक ही गंतव्य के साथ, दोनों सफल होते दिख रहे थे। (यह संभव है कि यह व्यवहार विशेष रूप से NFS सर्वर कार्यान्वयन, YMMV से संबंधित था।) किसी भी मामले में, शायद एक ही तरह की दौड़ की स्थिति है, जहाँ आप उन मामलों में एक ही फ़ाइल के लिए दो अलग-अलग इनोड्स प्राप्त कर सकते हैं, जहाँ भारी है इन दौड़ की स्थिति को ट्रिगर करने के लिए लेखकों के बीच सहमति। यदि आपके लेखक सुसंगत हैं (दोनों ए से बी की नकल कर रहे हैं), और आपके पाठक केवल सामग्री का उपभोग कर रहे हैं, तो यह पर्याप्त हो सकता है।
अंत में, आपने लॉकिंग का उल्लेख किया। दुर्भाग्य से लॉकिंग में गंभीर रूप से कमी है, कम से कम NFSv3 में (NFSv4 के बारे में निश्चित नहीं है, लेकिन मैं शर्त लगाऊंगा या तो अच्छा नहीं है।) यदि आप लॉकिंग पर विचार कर रहे हैं, तो आपको वितरित लॉकिंग के लिए अलग-अलग प्रोटोकॉल में देखना चाहिए, संभवतः बैंड के साथ बाहर। वास्तविक फ़ाइल प्रतियां, लेकिन यह विघटनकारी, जटिल और गतिरोध जैसे मुद्दों से ग्रस्त है, इसलिए मैं कहूंगा कि इससे बचना बेहतर है।
एनएफएस पर परमाणुता के विषय पर अधिक पृष्ठभूमि के लिए, आप मेलडिर मेलबॉक्स प्रारूप पर पढ़ना चाह सकते हैं , जो एनएफएस पर भी ताले से बचने और मज़बूती से काम करने के लिए बनाया गया था। यह हर जगह अद्वितीय फ़ाइल नाम रखकर ऐसा करता है (इसलिए आपको अंत में अंतिम बी भी नहीं मिलता है।)
शायद आपके विशेष मामले में कुछ और दिलचस्प है, Maildir ++ प्रारूप मेलबॉक्स कोटे के लिए समर्थन जोड़ने के लिए Maildir का विस्तार करता है और ऐसा करता है कि मेलबॉक्स के अंदर एक निश्चित नाम के साथ एक फ़ाइल को अद्यतन करके (ताकि आपके B. के करीब हो सकता है) I अपील करने के लिए, जो वास्तव में एनएफएस पर सुरक्षित नहीं है, लेकिन एक पुनर्गणना दृष्टिकोण है जो इस तरह की प्रक्रिया का उपयोग करता है और यह एक परमाणु प्रतिस्थापन के रूप में मान्य है।
उम्मीद है कि ये सभी संकेत उपयोगी होंगे!