วิธีการจัดสรรอุปกรณ์ลูปแบบอะตอม?


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)

ตัวเลือกนี้มีอยู่ใน util-linux ตั้งแต่รุ่น 2.13 ( เพิ่มในตอนแรก-sแต่--showได้รับการสนับสนุนในทุกรุ่นที่วางจำหน่ายและรุ่นล่าสุดได้ลบ-sชื่อตัวเลือก) น่าเสียดายที่รุ่น BusyBox ไม่มีอยู่

เคอร์เนลเวอร์ชัน 3.1 แนะนำวิธีการดำเนินการจัดสรรอุปกรณ์ลูปโดยตรงในเคอร์เนลผ่าน/dev/loop-controlอุปกรณ์ใหม่ วิธีการนี้รองรับตั้งแต่ util-linux 2.21 เท่านั้น ด้วยเคอร์เนล <3.1 หรือ util-linux <2.21 losetupโปรแกรมจะระบุรายการอุปกรณ์ลูปเพื่อจองหนึ่งรายการ ฉันไม่เห็นสภาพการแข่งขันในรหัส มันควรจะปลอดภัย แต่อาจมีหน้าต่างเล็ก ๆ ระหว่างที่มันจะรายงานอย่างไม่ถูกต้องว่าอุปกรณ์ทั้งหมดได้รับการจัดสรรแม้ว่าจะไม่เป็นเช่นนั้นก็ตาม


อะไร</dev/ttyหา?
Stéphane Chazelas

1
ครั้งสุดท้ายที่ฉันพยายามแม้แต่การlosetup --find --showแข่งขัน for i in {1..100}; do losetup -f -s $i & doneไม่ได้ให้ 100 อุปกรณ์ลูป อุปกรณ์ลูปนั้นผิดปกติมากพอที่จะไม่เป็นเรื่องปกติ ถ้ามันเป็นตัวเลือกเดียวของคุณคือการล็อคของคุณเองและ / หรือตรวจสอบว่าอุปกรณ์ห่วงที่ถูกต้องถูกสร้างขึ้นภายหลัง
frostschutz

@frostschutz losetupอาจล้มเหลว (เช่นเนื่องจากคุณมีรายการวนซ้ำ) แต่ถ้ารายงานชื่ออุปกรณ์นั่นคืออุปกรณ์ที่จัดสรรได้สำเร็จ รุ่นก่อนหน้ามีข้อผิดพลาดที่ทำให้มันเขียนชื่ออุปกรณ์แม้ว่าการจัดสรรล้มเหลวหรือไม่? ฉันเห็นในซอร์สโค้ดที่มีอินเทอร์เฟซสำหรับการจัดสรรในเคอร์เนลเท่านั้นตั้งแต่เคอร์เนล 3.1 มันอาจเป็นข้อผิดพลาดกับอินเทอร์เฟซเก่าที่ต้องใช้losetupโปรแกรมอรรถประโยชน์เพื่อทำการค้นหาหรือไม่
Gilles 'หยุดความชั่วร้าย' ใน

โอ้ดูเหมือนว่าจะได้รับการแก้ไขในรุ่นที่ใหม่กว่าแน่นอน util-linux-2.26.2 ดูเหมือนว่าจะทำงานได้, util-linux-2.24.1 พิมพ์ซ้ำ ๆ/dev/loop14และอุปกรณ์ดังกล่าวอาจหายไปในท้ายที่สุด อาจจะแก้ไขเป็นมารยาทของ/dev/loop-controlมันใช้ในการดูเพียงแค่/proc/partitions...
frostschutz

@frostschutz ตั้งแต่ util-linux 2.21 losetupจะใช้/dev/loop-controlถ้ามีอยู่และนั่นก็ไม่ได้ดูเหมือนว่าจะมีสภาพการแข่งขัน: การจัดสรรที่เกิดขึ้นในเคอร์เนลและการพิมพ์เส้นทางอุปกรณ์เป็นสิ่งสุดท้ายที่ยูทิลิตี้ทำ
Gilles 'ดังนั้นหยุดความชั่วร้าย'

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 นอกจากเมาแล้วคุณสามารถทำอะไรกับอุปกรณ์บล็อกที่คุณไม่สามารถทำได้กับไฟล์
Random832

คุณไม่สามารถฟอร์แมตเป็นพื้นที่สว็อปในการตั้งค่า btrfs แบบเต็มดิสก์ ฉันตั้งใจจะใช้ไฟล์สำหรับพื้นที่สว็อปเนื่องจาก btrfs ไม่สนับสนุนการดำเนินการที่จำเป็นสำหรับไฟล์สว็อปและฉันไม่สามารถมีพาร์ติชั่นสว็อปจริงที่มีการตั้งค่า btrfs เต็มดิสก์
AJMansfield
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.