สามารถเรียกไฟล์จาก inode ได้หรือไม่?


27

ฉันรันคำสั่งต่อไปนี้ตามลำดับที่ระบุ:

$ln a b
$ls -i a b
523669 a 523669 b
$rm -f a
$ls -i b
523669 b

ฉันได้ข้อสรุปจากการทดสอบนี้ว่าคำสั่งrmจริงลบเฉพาะชื่อไฟล์ ( aในการทดสอบนี้) แทนไฟล์เนื่องจาก inode ยังคงอยู่และสามารถดึงผ่านชื่อไฟล์อื่น ( b)

คำถามของฉันคือถ้าไฟล์ยากที่จะเชื่อมโยงกับชื่อไฟล์เดียวเมื่อrmถูกดำเนินการกับไฟล์เป็นไฟล์จริง (เช่น inode) ลบออกอย่างสมบูรณ์? และถ้าไม่สามารถเรียกใช้ไฟล์ inode ได้โดยไม่มีชื่อไฟล์และผ่าน inode เท่านั้น


ฟังเฉพาะ OS ฉัน
Ignacio Vazquez-Abrams

@Ignacio Vazquez-Abrams คุณหมายถึงมันขึ้นอยู่กับรุ่น?
user43312

ไม่ฉันหมายถึงมันขึ้นอยู่กับระบบปฏิบัติการ แต่ละวิธีมีวิธีการแตะที่แตกต่างกัน (ถ้ามี ) ใน VFS
Ignacio Vazquez-Abrams

@Ignacio Vazquez-Abrams คุณมีความคิดเห็นเกี่ยวกับ RHL หรือ RHEL หรือไม่?
user43312

1
@ BruceEdiger Os X เรียงลำดับของไม่ว่า คุณสามารถเข้าถึงวัตถุระบบไฟล์โดยใช้ "URL อ้างอิงไฟล์" ซึ่งเป็นพื้นฐานที่สร้างขึ้นจากหมายเลขระบบไฟล์และหมายเลขโหนด อย่างไรก็ตามยังไม่ได้รับการสนับสนุนอย่างเป็นทางการในการสร้างด้วยตนเอง แต่คุณได้รับ "URL อ้างอิงไฟล์" สำหรับไฟล์จากนั้นใช้แทนชื่อพา ธ สำหรับการเข้าถึงครั้งต่อไปในเซสชันรันไทม์เดียวกันเพื่อให้แอปพลิเคชันของคุณหลงลืมไฟล์ที่ถูกย้ายไปที่อื่นในปริมาณเดียวกัน
ไฟล์อะนาล็อก

คำตอบ:


29

หากคุณพยายามที่จะเปิดไฟล์ผ่านทาง inode มันจะข้ามไดเรกทอรีใด ๆ การสำรวจเส้นทางไดเรกทอรีเป็นสิ่งจำเป็นในการพิจารณาสิทธิ์ของไฟล์และไดเรกทอรีที่นำไปสู่มัน เคอร์เนลไม่มีวิธีการตรวจสอบว่ากระบวนการเรียกได้รับอนุญาตให้เข้าถึงไฟล์หรือไม่

มีความเป็นแพทช์เสนอให้ลินุกซ์ที่จะช่วยให้การสร้างการเชื่อมโยงไปยังแฟ้มจากอธิบายไฟล์ มันถูกปฏิเสธเพราะการใช้สิ่งนี้อย่างปลอดภัยจะเป็นเรื่องยากมาก

ภายใต้ Linux (และอาจแตกต่างจากยูนิกซ์อื่น ๆ ด้วยเหตุผลเดียวกัน) คุณไม่สามารถสร้างลิงก์ไปยังไฟล์ที่ถูกลบได้ดังนั้นหากไฟล์ไม่มีชื่ออีกต่อไปคุณจะไม่สามารถเพิ่มอีกครั้งได้¹คุณสามารถเปิดลบได้ /proc/$pid/fd/ไฟล์โดยการเปิดการเชื่อมโยงความมหัศจรรย์ใต้

หากไฟล์ไม่มีลิงก์ใด ๆ อีกต่อไปและไม่เปิดอีกต่อไปไฟล์จะไม่มีอยู่อีกต่อไปและพื้นที่ที่เคยใช้โดยข้อมูลนั้นอาจถูกเรียกคืนได้ตลอดเวลา

¹ คุณอาจจะสามารถที่จะทำเช่นนี้โดย twiddling ไบต์โดยตรงในระบบแฟ้มในทางระบบแฟ้มขึ้นอยู่กับที่เช่นกับdebugfsสำหรับ ext2 / ext3 / ext4 สิ่งนี้ต้องการการเข้าถึงอุปกรณ์ที่ติดตั้งระบบไฟล์ (เช่นโดยทั่วไปแล้วสามารถลองรูทได้) อย่างไรก็ตามในขณะที่ debugfs สามารถเข้าถึงไฟล์โดย inode นี้ไม่ได้ช่วยถ้าไฟล์ถูกลบ: ไฟล์จะถูกลบอย่างแท้จริงหากแอปพลิเคชันปิดมันและการทำงาน debugfs ในโหมดอ่านเขียนบนระบบไฟล์ที่ติดตั้งเป็นสูตรสำหรับ ภัยพิบัติ


11

บน Linux, debugfsดีบักเกอร์ระบบไฟล์ ext2 / ext3 / ext4 แบบโต้ตอบจัดเตรียมlnคำสั่งที่สามารถใช้หมายเลขไอโหนดเป็นfilespecและสร้างฮาร์ดลิงก์ใหม่ไปยังไฟล์ที่เกี่ยวข้อง ในทางปฏิบัติ แต่นี้ต้องว่าไฟล์ยกเลิกการเชื่อมโยงจะถูกเก็บไว้เปิดโดยกระบวนการที่ , /proc/[pid]/fd/[n]การบำรุงรักษาอธิบายไฟล์ที่เปิดใน ความพยายามนี้เป็นไฟล์ที่ถูกลบมักจะนำไปสู่ความเสียหายของระบบไฟล์

นี่เป็นเพราะเพื่อให้แน่ใจว่า ext3 (และในส่วนขยาย ext4) สามารถดำเนินการยกเลิกการเชื่อมโยงได้อย่างปลอดภัยหลังจากการขัดข้องจริง ๆ แล้วมันเป็นศูนย์ตัวชี้บล็อกใน inodeในขณะที่ ext2 เพียงทำเครื่องหมายบล็อกเหล่านี้ว่าไม่ได้ใช้ในบล็อกบิตแมป inode เป็น "ถูกลบ" และปล่อยให้ตัวชี้บล็อกอยู่คนเดียว อย่างไรก็ตามเนื่องจากระบบไฟล์จำเป็นต้องติดตั้งแบบอ่าน - เขียนเพื่อสร้างฮาร์ดลิงก์บล็อกที่สงวนไว้สำหรับไฟล์ที่ถูกลบอาจถูกจัดสรรใหม่แล้ว

ก่อนหน้าเคอร์เนลเวอร์ชัน 2.6.39 เคยเป็นตัวเลือกที่แนะนำใน GNU coreutils v8.0สามารถใช้ในการกู้คืนไฟล์ที่ไม่เชื่อมโยงผ่านตัวอธิบายไฟล์แบบเปิดหากทั้งไฟล์ที่ไม่ได้เชื่อมโยงและฮาร์ดลิงก์ใหม่อาศัยอยู่ในระบบไฟล์tmpfs ความสามารถนี้ได้ถูกปิดใช้งานเนื่องจากGillesชี้ให้เห็นถึงข้อควรพิจารณาด้านความปลอดภัยที่เกี่ยวข้องในการอนุญาตให้สร้างฮาร์ดลิงก์โดยตรงจากตัวให้คำอธิบายไฟล์ln -L|--logical/proc/[pid]/fd/[n]


ฉันพยายามใช้ln -Lเพื่อกู้คืนไฟล์ที่ถูกลบจาก / proc และได้รับข้อผิดพลาด: "ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว" ดังนั้นฉันจึงไม่คิดว่ามันจะรองรับไฟล์นี้ ฉันมี coreutils 8.21
wingedsubmariner

1
ln -Lไม่ทำในสิ่งที่คุณพูด มันบอกlnว่าถ้าแหล่งที่มาเป็นลิงค์สัญลักษณ์มันควรจะเชื่อมโยงเป้าหมายอย่างหนัก ลิงก์สัญลักษณ์/proc/$pid/fdเป็นพิเศษและการเชื่อมโยงอย่างหนัก(deleted)ไม่สามารถใช้งานได้
Gilles 'หยุดชั่วร้าย'

และdebugfsจะไม่ช่วยถ้าไฟล์นั้นถูกลบไปด้วยเว้นแต่ว่าคุณต้องการเสี่ยงที่จะรันมันในโหมดอ่าน - เขียนบนระบบไฟล์ที่เมาท์ซึ่งมีแนวโน้มที่จะรวมระบบไฟล์ทั้งหมด
Gilles 'หยุดชั่วร้าย'

ln -Lปรับปรุงคำตอบในเรื่องที่เกี่ยวกับ มันเคยเป็นไปได้ที่จะสร้างฮาร์ดลิงก์จากการ/proc/[pid]/fd/[n]ใช้มันในบางสถานการณ์พิเศษ แต่มันก็ถูกแก้ไขแล้ว
Thomas Nyman

1
debugfs's lnเป็นระดับต่ำจริงๆและเพียง แต่จะสร้างชื่อไม่ปรับปรุงการนับมิได้ unmarks บล็อกเป็นที่ไม่ได้ใช้จึงเป็นอันตรายอย่างยิ่ง ชอบdebugfs's undelซึ่ง des ทุกที่ คำเตือน: debugfsจะไม่ถูกเรียกใช้บนระบบไฟล์ที่เมาท์ยกเว้นว่าคุณต้องการใช้โอกาสนี้ในการเบิร์น FS เป็นขี้เถ้า
Lloeki

9

คำสั่ง 'ln' และ 'rm' ได้ทำงานอย่างนี้ในทุกระบบไฟล์ UNIX ตั้งแต่ต้นปี 1970 Mac OSX, BSD และ Linux ล้วน แต่สืบทอดการออกแบบดั้งเดิมนี้

โดยตัวมันเองไฟล์ UNIX ไม่มีชื่อมีเพียงหมายเลขinodeหรือ inum เท่านั้น แต่คุณสามารถเข้าถึงได้ผ่านรายการในไฟล์ "ไดเรกทอรี" พิเศษที่เชื่อมโยงชื่อกับ inum ที่เป็นปัญหา คุณไม่สามารถระบุ inum โดยตรง

ไดเรกทอรีเป็นตัวเองไฟล์เพื่อให้คุณยังต้องเข้าถึงมันผ่าน (อื่น) ไดเรกทอรีและอื่น ๆ ผ่านชุดของชื่อไดเรกทอรีคั่นด้วยเครื่องหมายทับ (/) เรียกว่า "ชื่อเส้นทาง" พา ธ เริ่มต้นใน "ไดเรกทอรีการทำงานปัจจุบัน" ของกระบวนการเว้นแต่ชื่อจะเริ่มต้นด้วย "/" ซึ่งในกรณีนี้มันจะเริ่มต้นด้วยไดเรกทอรีรากของระบบไฟล์ เช่นถ้าชื่อพา ธ ไม่มีอักขระ "/" ก็คาดว่าจะเป็นรายการในไดเรกทอรีปัจจุบัน

ไฟล์ที่ไม่ใช่ไดเรกทอรีสามารถมีจำนวนของชื่อเส้นทางที่เรียกว่า "การเชื่อมโยงยาก" ใด ๆ และมันจะยังคงอยู่จนกว่าทั้งหมดของชื่อเส้นทางของมันได้ถูกลบออกและขั้นตอนสุดท้ายที่มีการปิดไฟล์ จากนั้นไฟล์จะถูกลบและพื้นที่ที่ถูกทำเครื่องหมายว่าพร้อมใช้งานเพื่อนำมาใช้ซ้ำ นั่นคือคุณสามารถสร้าง () หรือเปิด () ไฟล์ที่เชื่อมโยงเดี่ยว ๆ แล้วยกเลิกการเชื่อมโยง () เพื่อไม่ให้ปรากฏในพื้นที่ชื่อระบบไฟล์อีกต่อไป แต่ไฟล์จะยังคงอยู่จนกว่าคุณจะปิดมัน สิ่งนี้มีประโยชน์สำหรับไฟล์เริ่มต้นชั่วคราวที่โปรแกรมอื่นไม่สามารถอ่านได้

แม้ว่าไดเร็กทอรีจะมีหมายเลขไอโหนด แต่ระบบไฟล์ส่วนใหญ่ไม่อนุญาตให้ลิงก์ไปยังไฟล์เหล่านั้น สามารถปรากฏในไดเรกทอรีอื่นเพียงไดเรกทอรีเดียว (ข้อยกเว้นที่ผิดปกติอย่างหนึ่งคือระบบไฟล์ Mac OSX HFS + ซึ่งช่วยให้การสำรองข้อมูล Time Machine ทำงานได้) คุณยังสามารถสร้าง "soft links" ไปยังไดเรกทอรี (หรือไฟล์อื่น ๆ ) ซอฟต์ลิงก์มีลักษณะคล้ายกับรายการไดเร็กทอรียกเว้นว่ามีชื่อพา ธ อื่นแทนที่จะเป็น inum

ไฟล์ UNIX ทุกไฟล์มีเจ้าของกลุ่มและสิทธิ์การเข้าถึง มีความจำเป็น แต่ไม่เพียงพอที่จะให้คุณเปิดไฟล์ คุณจะต้องมีสิทธิ์ดำเนินการอย่างน้อยสำหรับทุกไดเรกทอรีในชื่อพา ธ ที่คุณใช้อ้างอิง นั่นเป็นสาเหตุที่ไม่มีวิธีมาตรฐานในการเปิดไฟล์ UNIX ด้วยหมายเลขไอโหนด ที่จะหลีกเลี่ยงกลไกความปลอดภัยที่สำคัญและใช้กันอย่างแพร่หลาย

แต่นี่ไม่ได้อธิบายว่าทำไมไม่มีวิธีมาตรฐานสำหรับผู้ใช้รูท (มีสิทธิพิเศษ) ในการเปิดไฟล์ด้วยหมายเลขไอโหนดเนื่องจากการตรวจสอบสิทธิ์ถูกข้ามไป สิ่งนี้จะมีประโยชน์มากสำหรับฟังก์ชั่นการจัดการระบบบางอย่างเช่นการสำรองข้อมูล สำหรับความรู้ของฉันกลไกดังกล่าวมีอยู่จริง แต่ทั้งหมดนี้เป็นระบบไฟล์เฉพาะ ไม่มีวิธีการทั่วไปสำหรับระบบไฟล์ UNIX


1
ข้างใน/นั้นเงียบดังนั้นจึงออกเสียงว่า "ทับ"
ctrl-alt-delor

4

คำถามสามารถนำมาใช้ในทางทฤษฎี (ซึ่งสามารถทำได้ด้วยdebugfs) หรือในทางปฏิบัติ (สถานการณ์ฉุกเฉิน) ในกรณีหลังนี้ฉันถือว่าความตั้งใจนั้นช่วยประหยัดทั้งวันและกู้คืนเนื้อหาของไฟล์ซึ่งอาจเป็นสิ่งเร่งด่วน (ซึ่งเป็นวิธีที่ฉันใช้กับคำถามนี้ดังนั้นฉันคิดว่ามันยังเกี่ยวข้องและมีประโยชน์)

เนื่องจากไม่มีเคอร์เนล API debugfsจึงไม่ควรรันบนระบบไฟล์สดเพราะใช้งานโครงสร้าง FS โดยตรง ดังนั้นในการใช้งานคุณต้องได้รับชื่อไฟล์อื่น สมมติว่าไฟล์นั้นยังคงเปิดอยู่โดยบางกระบวนการ (กระบวนการใด ๆ ) ใคร ๆ ก็สามารถเข้าถึงตัวอธิบายไฟล์ที่สะดวกได้ใน/proc:

$ lsof -F pf "$PWD/a" | sed 's/^p//' # find pid and file descriptor number of any process having the file open
$ pid=1234
$ ls -l /proc/$pid/fd/* | grep "$PWD/a" # find file descriptor number
$ fd=42
$ cat /proc/$pid/fd/$fd > "$PWD/a.restored" # read contents to a new filename

เคล็ดลับ:

  • หากคุณมีข้อสงสัยเกี่ยวกับ fd ที่ถูกต้องคุณสามารถเรียกใช้คำสั่งเช่นfileนั้นได้
  • หากมีกระบวนการเขียนไฟล์ให้แน่ใจว่าได้หยุดกระบวนการดังกล่าวโดยเร็วมิฉะนั้นคุณจะไม่ได้รับข้อมูลล่าสุด เคล็ดลับ (ยังไม่ทดลอง) อาจเป็นการเปิดไฟล์ที่อ่านผ่าน fd ด้วยกระบวนการอื่น ๆ (ลองtail -f < /proc/$pid/fd/$fd > /dev/nullออกจากกระบวนการเขียนเพื่อให้มันออกมาอย่างหมดจดและใช้ fd ของกระบวนการใหม่

2
นั่นควรอยู่tail -f < /proc/...ในเคล็ดลับที่สอง
เมอเรย์เซ่น

หรือใช้ tail -c +0 -fเพื่อคัดลอกในตอนแรกแทนcatหากกระบวนการเขียนเป็นเพียงการต่อท้าย (ไม่ค้นหาและเขียนใหม่) ออกจากกระบวนการอื่นก่อนหน้าtailจากนั้นรอtailให้ถึงจุดสิ้นสุดไฟล์
Peter Cordes
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.