एटमॉली को लूप डिवाइस कैसे आवंटित करें?


11

मैं कुछ डिस्क छवि सामग्री को संभालने के लिए कुछ शेल स्क्रिप्ट लिख रहा हूं, और मुझे कुछ डिस्क छवियों तक पहुंचने के लिए लूप डिवाइस का उपयोग करने की आवश्यकता है। हालांकि, मुझे यकीन नहीं है कि एक दौड़ हालत में अपने कार्यक्रम को उजागर किए बिना लूप डिवाइस को ठीक से कैसे आवंटित किया जाए।

मुझे पता है कि मैं losetup -fअगले बिना लूप डिवाइस प्राप्त करने के लिए उपयोग कर सकता हूं , और फिर उस लूप डिवाइस को इस तरह आवंटित कर सकता हूं :

ld=$(losetup -f)
sudo losetup $ld myfile.img
dostuffwith $ld

हालांकि, उस मामले में जहां मैं एक ही समय में कार्यक्रम के कई उदाहरणों को चलाना चाहता हूं, यह लगभग एक दौड़ की स्थिति का एक पाठ्यपुस्तक उदाहरण है, और यह मुझे काफी परेशान करता है। यदि मेरे पास इस प्रोग्राम के कई उदाहरण हैं, या अन्य प्रोग्राम भी लूप डिवाइस प्राप्त करने की कोशिश कर रहे हैं, तो प्रत्येक प्रक्रिया अगले एक कॉल से पहले लूप डिवाइस को आवंटित करने में सक्षम नहीं हो सकती है losetup -f, इस स्थिति में दोनों प्रक्रियाएं सोचेंगी कि एक ही लूप डिवाइस उपलब्ध है, लेकिन केवल एक ही इसे प्राप्त कर सकता है।

मैं इसके लिए बाहरी सिंक्रनाइज़ेशन का उपयोग कर सकता था, लेकिन मैं (यदि संभव हो तो) अतिरिक्त जटिलता से बचना चाहूंगा। इसके अलावा, अन्य प्रोग्राम जो लूप डिवाइस का उपयोग करते हैं, वे संभवत: उस समस्‍या का सम्‍मान नहीं करेंगे जो मेरे साथ आ सकती है।

मैं इस संभावित दौड़ की स्थिति से कैसे बच सकता हूं? आदर्श रूप से, मैं लूप डिवाइस को एटोमिक रूप से खोज और बाँधने में सक्षम होना चाहता हूँ, उदाहरण के लिए जैसे कमांड:

ld=$(sudo losetup -f myfile.img)
dostuffwith $ld

हालांकि, जब मैं ऐसा $ldकरता हूं, तो लूप डिवाइस पथ को असाइन नहीं किया जाता है, और अनुमति त्रुटियों के sudoरूप में, बाहर निकल रहा है sudo ld=$(losetup -f myfile.img)

जवाबों:


13

संगामिति में यह एक क्लासिक समस्या है: संसाधन आवंटित करते समय, आपको यह निर्धारित करने की आवश्यकता है कि संसाधन स्वतंत्र है और इसे आरक्षित रखें, अन्यथा एक और प्रक्रिया संसाधन को उस समय के बीच आरक्षित कर सकती है जब आप जांचते हैं कि यह मुफ़्त है और जिस समय आप इसे आरक्षित करते हैं।

उपयोग करते हैं losetupस्वचालित आवंटन मोड ( -f), और पारित --showयह पाश डिवाइस पथ प्रिंट करने का विकल्प।

ld=$(sudo losetup --show -f /tmp/1m)

यह विकल्प संस्करण 2.13 के बाद से उपयोग-लिनेक्स में मौजूद है ( शुरुआत में जैसा जोड़ा गया है-s , लेकिन --showसभी जारी किए गए संस्करणों में समर्थित है और हाल के संस्करणों ने -sविकल्प का नाम छोड़ दिया है )। दुर्भाग्य से बिजीबॉक्स संस्करण में यह नहीं है।

लिनक्स कर्नेल के संस्करण 3.1 ने लूप डिवाइस आवंटन ऑपरेशन को सीधे कर्नेल में, नए डिवाइस के माध्यम से करने के लिए एक विधि पेश की/dev/loop-control । यह विधि केवल उपयोग-लिनेक्स 2.21 के बाद से समर्थित है। कर्नेल <3.1 या उपयोग-लिनेक्स <2.21 के साथ, losetupप्रोग्राम एक आरक्षित करने के लिए लूप डिवाइस प्रविष्टियों की गणना करता है। मैं हालांकि कोड में एक दौड़ की स्थिति नहीं देख सकता; यह सुरक्षित होना चाहिए, लेकिन इसमें एक छोटी खिड़की हो सकती है, जिसके दौरान यह गलत रिपोर्ट करेगा कि सभी डिवाइस आवंटित किए गए हैं, हालांकि यह मामला नहीं है।


किस </dev/ttyलिए है?
स्टीफन चेज़लस

1
पिछली बार मैंने कोशिश की थी, losetup --find --showदौड़ भी । for i in {1..100}; do losetup -f -s $i & doneमुझे 100 लूप डिवाइस नहीं दिए। सामान्य रूप से बात नहीं करने के लिए लूप डिवाइस असामान्य हैं; यदि यह आपका एकमात्र विकल्प है कि आप अपने स्वयं के ताले और / या जाँच करें कि सही लूप डिवाइस को बाद में बनाया गया था।
फ्रॉस्ट्सचुट्ज़

@frostschutz losetupविफल हो सकता है (उदाहरण के लिए, क्योंकि आप लूप प्रविष्टियों से बाहर निकल चुके हैं), लेकिन अगर यह एक उपकरण का नाम बताता है, तो यह वह उपकरण है जिसे उसने सफलतापूर्वक आवंटित किया है। क्या पहले के संस्करणों में एक बग था, जिसके कारण यह एक उपकरण का नाम लिखने के लिए था, भले ही आवंटन विफल हो गया था? मैं स्रोत कोड में देखता हूं कि कर्नेल आवंटन के लिए इंटरफ़ेस केवल कर्नेल 3.1 के बाद से मौजूद है, क्या यह शायद पुराने इंटरफ़ेस के साथ एक बग losetupहै जिसे खोज करने के लिए उपयोगिता की आवश्यकता है ?
गिल्स एसओ- बुराई को रोकें '25

ओह, यह वास्तव में अधिक हाल के संस्करणों में तय किया गया लगता है। उपयोग- linux-2.26.2 काम करने लगता है, उपयोग-linux-2.24.1 बार-बार प्रिंट करता है /dev/loop14और इस तरह और डिवाइस अंत में पूरी तरह से गायब हो सकता है। शायद फिक्स शिष्टाचार है /dev/loop-control, यह सिर्फ देखने के लिए इस्तेमाल किया /proc/partitions...
frostschutz

@frostschutz losetupउपयोग -लिनेक्स 2.21 के बाद से, /dev/loop-controlमौजूद होने पर उपयोग करता है , और ऐसा नहीं लगता है कि यह एक दौड़ की स्थिति हो सकती है: आवंटन कर्नेल में होता है और डिवाइस पथ को प्रिंट करना अंतिम बात है जो उपयोगिता करती है।
गाइल्स का SO- बुराई पर रोक '25

6

मैं यह समझ गया। हालांकि मुझे यकीन नहीं है कि अनुमति के साथ समस्या कैसी है, मैं इसके बजाय पहले शूटिंग कर सकता हूं और बाद में इस तरह पूछ सकता हूं:

sudo losetup -f myfile.img
ld=$(losetup -j myfile.img | grep -o "/dev/loop[0-9]*")
dostuffwith $ld

2

आप उपयोग कर सकते हैं flock:

  tryagain=1
  while [[ $tryagain -ne 0 ]]; do
    ld=`losetup -f`
    flock -n $ld -c "losetup $ld myfile.img"
    tryagain=$?
  done

यहां विचार यह है कि आप कोशिश करते हैं और flockलूप डिवाइस फ़ाइल; यदि उसी स्क्रिप्ट का एक और उदाहरण इसे पहले प्राप्त कर लेता है, तो यह कॉल करेगा losetup $ld myfile.imgऔर flockवापस लौटेगा। 0. स्क्रिप्ट के लिए जो दौड़ खो देता है, losetupउसे कॉल नहीं किया flockजाएगा और 1 वापस आ जाएगा, जिससे लूप दोहराएगा।

अधिक देखने के लिए man flock


0

यदि आप सभी छवि के साथ करना चाहते हैं क्योंकि लूपबैक डिवाइस इसे फाइलसिस्टम के रूप में माउंट करता है और सामग्री के साथ काम करता है, तो mountकमांड स्वचालित रूप से इस पर ध्यान दे सकता है।

mount -o loop myfile.img /tmp/mountpoint

वास्तव में, मेरे मामले में, मैं विशेष रूप से चाहता हूं कि यह घुड़सवार न हो - मैं इसे एक ब्लॉक डिवाइस के रूप में उपयोग कर रहा हूं, फाइल सिस्टम नहीं।
AJMansfield

@AJMansfield इसे माउंट करने के अलावा, आप एक ब्लॉक डिवाइस के साथ क्या कर सकते हैं जो आप एक फाइल के साथ नहीं कर सकते हैं?
रैंडम 832

आप इसे फुल-डिस्क btrfs सेटअप पर स्वैप स्पेस के रूप में प्रारूपित नहीं कर सकते। मैं स्वैप स्थान के लिए फ़ाइल का उपयोग करने का इरादा कर रहा था, क्योंकि btrfs स्वैप फ़ाइलों के लिए आवश्यक संचालन का समर्थन नहीं करता है, और मेरे पास पूर्ण-डिस्क btrfs सेटअप के साथ वास्तविक स्वैप विभाजन नहीं हो सकता है।
AJMansfield
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.