สมมุติฐาน: ลบแล้ว แต่ยังเปิดไฟล์อยู่
จากข้อมูลที่ให้ไว้จนถึงตอนนี้ และบอกใบ้ถึงการมีอยู่ของไฟล์ที่เกี่ยวข้องกับนักเทียบท่าจำนวนมาก ฉันสงสัยว่าสิ่งนี้เกิดจากไฟล์ที่ถูกลบแต่ยังคงเปิดอยู่ นั่นคือไฟล์ที่สร้างขึ้นโดยโปรแกรม จากนั้น โปรแกรมจะลบเส้นทางของระบบไฟล์ในขณะที่ยังคงเปิดไฟล์อธิบายไว้
นี่อาจเป็นผลมาจากกิจกรรม Docker ในระบบไฟล์
หลักการแก้ปัญหา
- เปิดเผยไฟล์ที่ถูกลบซึ่งยังคงอ้างอิงโดยกระบวนการ (ดูวิธีด้านล่าง)
- เปิดเผยชื่อกระบวนการและ/หรือ ID เพื่อให้คุณมีคำแนะนำเกี่ยวกับสิ่งที่เกิดขึ้น
- ปิดกระบวนการเหล่านั้น สังเกตพื้นที่ว่าง
- หากทั้งหมดล้มเหลว ให้รีบูตเครื่องใหม่ ถ้าว่างก็เป็นไปตามสมมุติฐาน
วิธีการเปิดเผยข้อมูล
คำสั่งด้านล่างจะทดสอบสมมติฐานโดยการค้นหาและแสดงว่าไฟล์ใดใช้พื้นที่ใด
แวบแรก
สำหรับภาพรวมเบื้องต้น คุณสามารถออกสิ่งนี้:
lsof -n | egrep -w "ลบแล้ว|^คำสั่ง"
แต่สิ่งนี้จะแสดงรายการไฟล์หลอกในหน่วยความจำเท่านั้นจำนวนมากที่ไม่ใช้พื้นที่จัดเก็บจริง
ตัวอย่าง:
คำสั่ง PID TID TASKCMD ผู้ใช้ FD ประเภท ขนาดอุปกรณ์/ปิด ชื่อโหนด
Xorg 1183 รูท 78u REG 0,1 4 2058 /memfd:xshmfence (ลบแล้ว)
Xorg 1183 รูท 85u REG 0,1 4 7182 /memfd:xshmfence (ลบแล้ว)
Xorg 1183 รูท 92u REG 0,1 4 7137 /memfd:xshmfence (ลบแล้ว)
Xorg 1183 รูท 94u REG 0,1 4 7870 /memfd:xshmfence (ลบแล้ว)
รายการง่าย ๆ ที่กรองแล้ว
สิ่งนี้กรองและแสดงไฟล์จริงเป็นส่วนใหญ่:
lsof -F "sn" -lnPX -M | sed -n 's|^n/|/|p' | ลบ grep | egrep -v '^/(dev/shm|memfd:|proc)' | LC_ALL=C เรียงลำดับ -n | ยูนิค
ตัวอย่าง:
/tmp/#someinodenumber (ลบแล้ว)
ข้อมูลที่สมบูรณ์พร้อมขนาด กระบวนการ และชื่องาน
สิ่งนี้น่าสนใจกว่า: มันจะแสดงรายการไฟล์ทั้งหมดพร้อมกับพื้นที่ที่พวกเขาครอบครองเป็นไบต์และอีกมากมาย
ขั้นแรก ส่วนที่ช้า รวบรวมข้อมูล
# คุณอาจต้องการเรียกใช้ส่วนนี้ในฐานะรูทเพื่อให้แน่ใจว่ามีการรายงานทั้งหมด
lsof -F "ctsupMin" -lnPX -M >|/tmp/lfosoutput
จากนั้นประมวลผลและจัดรูปแบบสำหรับการแสดงผลที่สวยงาม เสร็จสิ้นและจัดเรียงตามขนาดที่เพิ่มขึ้น
#สามารถเรียกใช้เป็นผู้ใช้ปกติไม่จำเป็นต้องรูท
{ echo "SIZE^UID^PID^ชื่อกระบวนการ^ชื่องาน^INODE^PATH"
</tmp/lfosoutput \
python3 -c $'import sys ; ฉ={}
def g(c): กลับ f.get(c,"(ไม่ทราบ)")
สำหรับบรรทัดใน sys.stdin:
ค=บรรทัด[0] ; r=บรรทัด[1:].rstrip() ; ฉ[ค]=ร
ถ้า c=="n" และ f["t"]=="REG" \
และ "(ถูกลบ)" ใน f["n"] \
และไม่ใช่ f["n"].startswith("/memfd:") \
และไม่ใช่ f["n"].startswith("/dev/shm") :
พิมพ์(f'\''{g("s")}^{g("u")}^{g("p")}^\"{g("c")}\"^\"{ g("M")}\"^{g("i")}^{g("n")}'\'')
ฉ={}' \
| LC_ALL=C เรียงลำดับ -n | ยูนิค
echo "SIZE^UID^PID^ชื่อกระบวนการ^ชื่องาน^INODE^PATH"
} | คอลัมน์ -t -s '^'
เอาต์พุตตัวอย่าง: ไฟล์ขนาด 36 เมกะไบต์ที่ Firefox ใช้
ขนาด UID PID ชื่อกระบวนการ ชื่องาน INODE PATH
36012032 1234 12345 "Isolated Web Co" "StyleThread#2" 1234567 /tmp/mozilla-temp-12345 (ลบแล้ว)
ขนาด UID PID ชื่อกระบวนการ ชื่องาน INODE PATH
(จริงๆมีหลายบรรทัดแบบนี้นี่แค่บรรทัดตัวอย่างนะครับ)
ทดสอบว่าสคริปต์เปิดเผยไฟล์ดังกล่าวจริงหรือไม่โดยสร้างไฟล์ขึ้นมา
ในเทอร์มินัลอื่น ให้คัดลอกและวางสิ่งนี้:
# เรียกใช้ล่ามแบบโต้ตอบของ Python
หลาม3
# ตอนนี้อยู่ใน Python
n="/tmp/whatever_file_name_you_want"
f=open(n,mode='a')
นำเข้าระบบปฏิบัติการ
os.unlink(n)
f.write("บางประโยค")
ฉ.flush()
#อย่าออกตอนนี้ไม่งั้นไฟล์จะหายไปจริงๆ
ในเทอร์มินัลแรก คุณสามารถเรียกใช้ทั้งสองขั้นตอนข้างต้น (การช้า lsof แล้วส่วนการจัดรูปแบบ)
และตราบใดที่กระบวนการงูหลามด้านบนยังมีชีวิตอยู่ บรรทัดนี้จะถูกรายงาน:
ขนาด UID PID ชื่อกระบวนการ ชื่องาน INODE PATH
13 1000 1387343 "python3" "gdbus" 1308894 /tmp/whatever_file_name_you_want (ลบแล้ว)
ขนาด UID PID ชื่อกระบวนการ ชื่องาน INODE PATH
จากนั้นคุณสามารถออกจากตัวแปลภาษาไพ ธ อนด้านบน (กด คอนโทรล-ดี
หรือพิมพ์ ทางออก (0)
). หากคุณเรียกใช้ทั้งสองส่วน (ส่วน lsof ที่ช้าและส่วนการจัดรูปแบบ) คุณจะสังเกตเห็นว่าไฟล์ทดสอบไม่ปรากฏขึ้นอีกต่อไป
สคริปต์ด้านบนสามารถแก้ไขเพื่อเขียนข้อมูลจำนวนมาก (เช่น หลายร้อยกิกะไบต์) และใช้เครื่องมือตามปกติของคุณ คุณจะเห็นว่าพื้นที่นั้นว่างจริง ๆ ก็ต่อเมื่อกระบวนการสร้างปิดตัวอธิบายไฟล์แล้วเท่านั้น การสิ้นสุดกระบวนการก็เพียงพอแล้วเพื่อให้แน่ใจว่าตัวอธิบายไฟล์ปิดอยู่
กลับไปที่กรณีของคุณ
เมื่อเรียกใช้สิ่งนี้ คุณอาจเห็นชื่อกระบวนการ ชื่องาน และไฟล์เป็นส่วนใหญ่ ไม่ว่าจะเป็นไฟล์ขนาดใหญ่สองสามไฟล์ เช่น รูปภาพที่ Docker ดึงมาจากเครือข่าย หรือไฟล์ขนาดเล็กจำนวนมากจาก Docker อีกครั้ง
หรืออย่างอื่น.
โปรดบอกว่าสิ่งนี้ช่วยคุณได้หรือไม่