หากผู้ใช้ทำงานกับแอปพลิเคชันที่เชื่อมโยงแบบไดนามิกและระบบกำลังอัปเกรดมีกลไกการป้องกันใดที่ป้องกันความเสียหายของแอปพลิเคชันหรือไม่
หรือมันขึ้นอยู่กับการใช้งาน?
หากผู้ใช้ทำงานกับแอปพลิเคชันที่เชื่อมโยงแบบไดนามิกและระบบกำลังอัปเกรดมีกลไกการป้องกันใดที่ป้องกันความเสียหายของแอปพลิเคชันหรือไม่
หรือมันขึ้นอยู่กับการใช้งาน?
คำตอบ:
ตามที่ @Kusalananda กล่าวถึงการอัปเกรดจะทำได้โดยการลบไฟล์เก่าและสร้างไฟล์ใหม่ด้วยชื่อเดียวกัน การดำเนินการนี้จะสร้างไฟล์ใหม่ด้วย inode ใหม่โดยปล่อยให้ระบบใช้ไฟล์เก่าได้ฟรีตราบเท่าที่เปิดอยู่
เป็นตัวอย่างง่าย ๆ สิ่งที่ชอบ
rm /bin/cat
cp /new/version/of/cat /bin/cat
จะสร้างไฟล์ใหม่อย่างมีเหตุผลและทำงานได้แม้ว่าcat
อาจจะกำลังทำงานอยู่ กันไปสำหรับห้องสมุด (ตัวอย่างข้างต้นเป็นตัวอย่างไม่ใช่วิธีที่แข็งแกร่งในการอัปเกรดไฟล์ในโลกแห่งความเป็นจริง)
ใครบางคนอาจลองเปลี่ยนไบนารีเข้าแทนที่แทนการสร้างขึ้นใหม่ด้วยชื่อเดียวกัน ในกรณีนี้อย่างน้อยลีนุกซ์จริง ๆ ป้องกันการเปลี่ยนแปลงการปฏิบัติการที่ใช้:
window 1 # ./cat
window 2 # echo foobar > cat
-bash: cat: Text file busy
อย่างไรก็ตามดูเหมือนจะไม่ทำงานกับห้องสมุดที่โหลดแบบไดนามิก ...
ฉันทำสำเนาของlibc.so.6
การทดสอบและเติมเต็มด้วยศูนย์ในขณะที่ใช้งานอยู่:
window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ldd ./cat
linux-vdso.so.1 (0x00007ffcfaf30000)
libc.so.6 => /tmp/lib/libc.so.6 (0x00007f1145e67000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1146212000)
window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ./cat
foo
foo
Segmentation fault
(ในหน้าต่างอื่นหลังจากfoo
, ก่อนหน้า, segfault)
window 2 /tmp/lib# dd if=/dev/zero of=libc.so.6 bs=1024 count=2000
ไม่มีอะไรจริงๆที่โปรแกรมสามารถทำสิ่งนี้ได้เนื่องจากฉันแก้ไขโค้ดออนไลน์ได้อย่างมีประสิทธิภาพ
(สิ่งนี้น่าจะขึ้นอยู่กับระบบผมทดสอบ Debian Jessie 8.5, Linux 3.16.7-ckt25-2 + deb8u3 โดยเฉพาะระบบ IIRC Windows โดยเฉพาะอย่างยิ่งมีความก้าวร้าวมากขึ้นเกี่ยวกับการป้องกันไม่ให้แก้ไขไฟล์ที่ใช้งานอยู่)
ดังนั้นฉันเดาคำตอบคือการอัพเกรดมักจะทำในลักษณะที่หลีกเลี่ยงปัญหาใด ๆ และสิ่งนี้ได้รับการช่วยเหลือจากระบบไฟล์ภายใน แต่ (บนลีนุกซ์) ดูเหมือนจะไม่มีการป้องกันการทำลายไลบรารีไดนามิก
install
ยูทิลิตี้เป็นที่นิยมใช้สำหรับสิ่งเช่นนี้ คุณไม่จำเป็นต้องระบุrm
ไฟล์ปลายทางอย่างชัดเจน รวมทั้งรักษาสิทธิ์ของไฟล์ที่มีอยู่สามารถทำการสำรองข้อมูลตั้งค่าโหมดใหม่และอื่น ๆ ตัวอย่างการใช้งาน:install /new/version/of/cat /bin/cat
rm
+ cp
ก็หมายความว่าเป็นตัวอย่าง อาจเป็นการดีที่จะวางไฟล์ใหม่ด้วยการเปลี่ยนชื่ออะตอมมิให้หลีกเลี่ยงหน้าต่างสั้น ๆ ที่ไม่มีเวอร์ชั่นให้ใช้ (แม้ว่า GNU install
จะไม่ทำเช่นนั้น hmpf.)
rm
) แล้วมันยังไม่ถูกลบ มันจะมีอยู่บนดิสก์และยังสามารถอ่านได้โดยกระบวนการทั้งหมดที่เปิดอยู่ มันจะถูกลบเมื่อจำนวนฮาร์ดลิงค์ถึงศูนย์และจำนวนของกระบวนการที่มีไฟล์เปิดถึงศูนย์
install
ยูทิลิตี้ไม่ปลอดภัยเป็นพิเศษ! มันเขียนทับไฟล์เป้าหมายแทนการแทนที่ด้วยอะตอม mv
(ด้วยซอร์สและปลายทางในไดเรกทอรีเดียวกันซอร์สมักจะเป็นไฟล์ชั่วคราว) เป็นวิธีเดียวที่ปลอดภัยในการติดตั้งไฟล์
strace
บอกinstall
ใน GNU coreutils ลิงก์ไฟล์เป้าหมายแล้วคัดลอกใหม่ในสถานที่ ซึ่งหมายความว่ามีหน้าต่างสั้น ๆ ในระหว่างที่ไฟล์บางส่วน ไม่ได้ตั้งค่าไฟล์แบบอะตอมมิด้วยการเปลี่ยนชื่อ
ไฟล์จะไม่ "ถูกลบอย่างถูกต้อง" หากไม่ได้เชื่อมโยงในขณะที่ยังคงเปิดอยู่ เมื่อปิดแล้วพื้นที่ดิสก์ที่ใช้จะถูกพิจารณาว่าเป็น "ฟรี" อีกครั้ง สิ่งนี้ใช้สำหรับแอปพลิเคชันที่กำลังทำงานและไลบรารีที่แบ่งใช้ของพวกเขาเช่นกัน
สิ่งเดียวที่ฉันเห็นได้ว่าล้มเหลวก็คือหากโปรแกรมที่ใช้dlopen()
ในการโหลดไลบรารีแบบแบ่งใช้ตามต้องการหรือหากโปรแกรมนั้นต้องเข้าถึงไฟล์อื่นตามต้องการเช่นพจนานุกรมไฟล์ธีมหรือไฟล์อื่น ๆ ที่หายไปในทันที
ตัวอย่าง: การรันvim
ในหนึ่งเซสชั่นเชลล์ในขณะที่ลบการติดตั้งvim
ในเซสชั่นเชลล์อื่นจะไม่ "เสียหาย" หรือยุติvim
เซสชั่นที่กำลังทำงานอยู่ แต่บางสิ่งจะเริ่มล้มเหลวเช่นการตรวจสอบการสะกดคำเช่นต้องการvim
เปิดไฟล์ในการติดตั้ง
ln -sf
เมื่อทำการแลกเปลี่ยนไลบรารีเพราะ-f
อนุญาตให้คุณ "เขียนทับ" ปลายทางที่มีอยู่ของลิงก์สัญลักษณ์ด้วยหนังสือเล่มใหม่โดยที่ไม่ได้ "เสีย" (ต่างจากที่คุณเคยทำrm
ตามมาด้วย) กln -s
) ดังนั้นก่อนที่คำสั่งlibrary.soจะชี้ไปที่เวอร์ชันเก่าเช่น library.so.4 ... หลังจากคำสั่งมันจะชี้ไปที่library.so.5 (หรืออะไรก็ตาม) แทน - โดยไม่ต้องไม่ชี้ไปยังไลบรารีที่ถูกต้อง