SSD Nodes Learn 🎉 VPS $5.50/माह से
गाइड Matt Connorलेखक: Matt Connor

df डिस्क फुल दिखाता है पर du नहीं: जगह कैसे खाली करें

VPS पर df और du के अलग आंकड़ों का कारण जानें। यह गाइड बताती है कि कैसे lsof कमांड से उन डिलीट की गई फाइलों को ढूंढें जिन्हें प्रोसेस अभी भी होल्ड किए हुए हैं और जगह खाली करें।

df डिस्क फुल क्यों बताता है और du अलग परिणाम क्यों देता है

df डिस्क को फुल रिपोर्ट करता है जबकि du जगह नहीं ढूंढ पाता क्योंकि कोई process अभी भी एक ऐसी फ़ाइल को होल्ड किए हुए है जिसे delete किया जा चुका है। किसी फ़ाइल को delete करने से उसका नाम directory से हट जाता है। डेटा ब्लॉक्स केवल तभी रिलीज़ होते हैं जब उस inode को पॉइंट करने वाला अंतिम open file descriptor बंद हो जाता है। du नामों को ट्रैक करता है, इसलिए यह कुछ भी काउंट नहीं करता। df फ़ाइल सिस्टम से पूछता है कि कितने ब्लॉक्स आवंटित हैं, इसलिए यह अभी भी उस फ़ाइल को काउंट करता है जिसका अब कोई नाम नहीं है।

यह गाइड एक साधारण Ubuntu VPS पर इसे दोहराती है, पहले से इंस्टॉल किए गए टूल्स का उपयोग करती है, /proc के माध्यम से होल्ड करने वाली process को ढूंढती है, और बिना रीबूट किए जगह खाली करती है। इसी लक्षण के अन्य कारण निम्नलिखित हैं: बिना किसी खाली एंट्री वाली inode टेबल, माउंट पॉइंट के नीचे दबी हुई फ़ाइलें, और root के लिए आरक्षित ब्लॉक्स।

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

What df counts and what du counts

df (disk free) asks each mounted filesystem for its own accounting: how many blocks exist, how many are allocated, how many are free. It never opens a directory. The answer covers every allocated block, including blocks belonging to a file that no directory entry points at.

du (disk usage) does the opposite. It starts at a path you give it, reads directories, stats every entry it finds, and adds up the blocks. A file with no name is invisible to it. So is any directory it is not allowed to read, which is why an ordinary user gets a smaller total than root does. Run du under sudo before you conclude anything from the comparison.

Two options matter every time you compare the two.

  • -x keeps du on one filesystem. Without it, du / walks into every filesystem mounted below / and produces a total that df / was never measuring.
  • -s prints one summary line per argument instead of one line per directory.

That gives the pair to run side by side on the filesystem you care about.

df -h /
sudo du -xhs / 2>/dev/null

df answers immediately. du takes minutes on a large filesystem, because it stats every file on the way. When the two totals are far apart, and du ran as root with -x, the missing space is allocated to something that has no name.

मिसमैच को जानबूझकर दोहराना

इसे एक test VPS पर करें। नीचे दिए गए सभी निर्देश bash और coreutils का उपयोग करते हैं, इसलिए कुछ भी नया install करने की आवश्यकता नहीं है।

उस filesystem की शुरुआती स्थिति रिकॉर्ड करें जो /var/tmp को होल्ड करता है।

cd /var/tmp
df -h .
df --output=used -B1 .

दूसरा command बिना rounding के उपयोग किए गए bytes को print करता है, जिससे अंत में की गई जाँच सटीक रहती है।

अब एक file बनाएँ। इसका आकार उस free space से निर्धारित होता है जिसे मशीन स्वयं रिपोर्ट करती है, इसलिए यह प्रदर्शन आपके पास मौजूद किसी भी disk पर काम करेगा।

free=$(df --output=avail -B1 . | tail -n 1)
fallocate -l $((free / 10)) ghost.bin
ls -l ghost.bin
df -h .

$(...) command substitution है: shell इसके अंदर दिए गए command को चलाता है, और उसका output free का मान बन जाता है। यदि यह syntax आपके लिए नया है, तो bash में command substitution इसे विस्तार से समझाता है। fallocate बिना डेटा लिखे वास्तविक blocks को reserve करता है, इसीलिए यह तुरंत पूरा हो जाता है। जिस filesystem पर यह समर्थित नहीं है, वहाँ यह command fail हो जाता है, और head -c $((free / 10)) /dev/zero > ghost.bin वही काम bytes लिखकर करता है।

इस df -h . की तुलना उस स्थिति से करें जिसे आपने रिकॉर्ड किया था। 'used' कॉलम बढ़ गया है और 'available' कॉलम घट गया है।

अब file को किसी अन्य process से open रखें, फिर उसे delete कर दें।

sleep infinity < ghost.bin &
holder=$!
rm ghost.bin
ls -l ghost.bin
df -h .
sudo du -xhs . 2>/dev/null

redirection ही पूरी तरकीब है। sleep infinity < ghost.bin & एक background process शुरू करता है जिसका standard input वह file है, इसलिए shell file को open करता है और descriptor को sleep को सौंप देता है, जो इसे open रखता है। $! उस background job की process ID को होल्ड करता है। rm फिर file के नाम को हटा देता है जबकि descriptor अभी भी open रहता है।

output पढ़ें। ls file को नहीं ढूँढ सकता, क्योंकि नाम हट चुका है। du वापस वहीं पहुँच गया है जहाँ से शुरू हुआ था, क्योंकि यह नामों को ट्रैक करता है। df नहीं बदला है, क्योंकि blocks अभी भी allocated हैं। Filesystem और directory tree अब एक-दूसरे से असहमत हैं, और उनके बीच का अंतर वही file है जिसे आपने अभी delete किया है।

डिलीट की गई फाइल को होल्ड करने वाली प्रोसेस ढूँढें

हर ओपन फाइल डिस्क्रिप्टर /proc/<pid>/fd/ के अंतर्गत एक सिम्बॉलिक लिंक के रूप में दिखाई देता है जो उस फाइल को संदर्भित करता है। जब फाइल को unlink कर दिया जाता है, तो kernel उस लिंक के लक्ष्य को 'deleted' के रूप में चिह्नित कर देता है। इसलिए, होल्डर को खोजने का अर्थ है एक ऐसा लिंक खोजना जिसका लक्ष्य यह मार्कर रखता हो।

sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null

-lname सिम्बॉलिक लिंक के नाम के बजाय उसके लक्ष्य से मिलान करता है, %p डिस्क्रिप्टर पाथ को प्रिंट करता है, और %l यह प्रिंट करता है कि वह कहाँ पॉइंट कर रहा है। प्रोसेस ID उसके द्वारा प्रिंट किए गए पाथ का दूसरा तत्व है। इसे sudo के साथ चलाएं, क्योंकि अन्यथा आप केवल अपनी स्वयं की प्रोसेस के लिए /proc/<pid>/fd पढ़ पाएंगे। stderr रीडायरेक्ट उन प्रोसेस से आने वाले शोर को हटा देता है जो find के चलने के दौरान समाप्त हो जाती हैं।

एक व्यस्त सर्वर पर किसी भी समय कई डिलीट की गई फाइलें होल्ड पर रहती हैं, और उनमें से अधिकांश छोटी और हानिरहित होती हैं। उन्हें आकार के अनुसार क्रमबद्ध करें ताकि केवल महत्वपूर्ण फाइलें ही सबसे ऊपर रहें।

sudo bash -c 'for fd in /proc/[0-9]*/fd/*; do
  target=$(readlink "$fd" 2>/dev/null) || continue
  case "$target" in
    *"(deleted)") echo "$(stat -Lc %s "$fd" 2>/dev/null) $fd $target" ;;
  esac
done' | sort -rn | head

stat -L लिंक का अनुसरण सीधे inode तक करता है, इसलिए %s उस फाइल का आकार रिपोर्ट करता है जिसका अब कोई नाम नहीं है। उस संख्या पर सॉर्ट करने से सबसे बड़ी फाइल सबसे पहले आ जाती है।

फिर जीतने वाले डिस्क्रिप्टर के पीछे की प्रोसेस की पहचान करें। उस सूची के शीर्ष पर मौजूद पाथ में वे दोनों संख्याएं होती हैं जिनकी आपको आवश्यकता है, इसलिए उन्हें पहले वेरिएबल्स में डालें, और PID तथा N को अपनी लिस्टिंग द्वारा प्रिंट की गई संख्याओं से बदलें।

pid=PID
n=N
ps -o pid,user,etime,args -p "$pid"
sudo stat -L "/proc/$pid/fd/$n"

ps प्रोग्राम का नाम बताता है और दिखाता है कि वह कितने समय से चल रहा है। stat -L डिलीट किए गए inode का आकार और आवंटित ब्लॉक काउंट प्रिंट करता है। साथ मिलकर, वे उस महत्वपूर्ण प्रश्न का उत्तर देते हैं: कौन सी सर्विस इस फाइल को जीवित रख रही है।

यदि मशीन पर पहले से ही lsof मौजूद है, तो sudo lsof +L1 उन ओपन फाइलों को सूचीबद्ध करता है जिनका लिंक काउंट शून्य हो गया है और एक टेबल में उनका आकार दिखाता है। यह एक न्यूनतम Ubuntu इमेज पर मौजूद नहीं होता है, और बिना खाली जगह वाले फाइलसिस्टम पर पैकेज इंस्टॉल करना स्वयं विफल हो सकता है, इसलिए /proc वॉक वह संस्करण है जो हमेशा काम करता है।

Reboot किए बिना जगह खाली करना

Reboot करने से समस्या हल हो जाती है, लेकिन यह पहला कदम नहीं होना चाहिए: इससे service बंद हो जाती है और सबूत नष्ट हो जाते हैं। चार आसान विकल्प मौजूद हैं, जिन्हें आप इस क्रम में आजमा सकते हैं।

सबसे पहले, यदि आपको डेटा की आवश्यकता है तो उसे कॉपी कर लें। Descriptor path को पढ़ने का अर्थ है live inode को पढ़ना।

sudo cp /proc/<pid>/fd/<n> /root/recovered.log

यह एकमात्र स्थिति है जहाँ delete की गई file को वापस पाना आसान होता है, इसीलिए rm -rf से delete की गई files को recover करना इस सवाल से शुरू होता है कि क्या किसी process ने अभी भी file को open रखा है। एक बार आखिरी descriptor बंद हो जाने पर, यह रास्ता खत्म हो जाता है।

दूसरा, descriptor के माध्यम से file को खाली करें। /proc path उसी inode की ओर ले जाता है, इसलिए इसे truncate करने से blocks मुक्त हो जाते हैं जबकि process चलती रहती है।

sudo truncate -s 0 "/proc/$pid/fd/$n"
df -h /

यह तब ठीक से काम करता है जब writer ने file को append mode में open किया हो, क्योंकि हर write operation file के अंत में होता है। यदि ऐसा नहीं है, तो process अपना पुराना write offset बनाए रखती है, जिससे उसका अगला write file में काफी आगे होता है और शुरुआत में एक hole बन जाता है। Hole allocate नहीं होता, इसलिए blocks खाली रहते हैं और df उस जगह को बनाए रखता है जिसे उसने अभी वापस किया है। जो वापस आता है वह केवल size है: process के write करने के बाद फिर से sudo stat -L "/proc/$pid/fd/$n" चलाएं, तो यह पुराने size को block count के साथ दिखाएगा जो अब उससे मेल नहीं खाता। जब आप चाहते हैं कि size भी शून्य से शुरू हो, तो process को restart करें।

तीसरा, service से उसकी logs को फिर से open करने के लिए कहें। जिस daemon की log file उसके नीचे से delete कर दी गई हो, वह इस समस्या का एक सामान्य वास्तविक उदाहरण है। कई daemons signal मिलने पर अपनी log files को फिर से open करते हैं: nginx SIGUSR1 का उपयोग करता है और rsyslog SIGHUP का। अनुमान लगाने के बजाय अपने सामने मौजूद daemon के लिए documentation देखें, क्योंकि गलत daemon को गलत signal भेजने से वह बंद हो सकता है।

sudo systemctl kill -s USR1 nginx

चौथा, unit को restart करें। sudo systemctl restart <unit> पुरानी process द्वारा रखे गए हर descriptor को बंद कर देता है, इसलिए blocks निश्चित रूप से वापस आ जाते हैं। ऊपर दिए गए प्रदर्शन के लिए holder एक sleep है जिसे आपने खुद शुरू किया था, इसलिए उसे समाप्त करना ही काफी है।

kill $holder
df -h .
df --output=used -B1 .
sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null

उपयोग किए गए bytes की तुलना उस मान से करें जिसे आपने file बनाने से पहले record किया था। वे फिर से मेल खाते हैं, और find अब आपके descriptor की रिपोर्ट नहीं करता है। जिस command से समस्या मिली थी, उसी से पुष्टि करने की आदत डालना फायदेमंद है।

उस मान को बदलते हुए देखना, बार-बार हाथ से df चलाने से आसान है। watch एक निश्चित अंतराल पर command को दोहराता है और output को उसी स्थान पर फिर से print करता है, इसलिए watch df -h / दिखाता है कि जैसे-जैसे जगह वापस आती है, used column बदलता रहता है।

जब totals मेल खाते हैं और disk फिर भी full है

यदि df और root du -x एक-दूसरे से सहमत हैं, तो कोई भी deleted file समस्या का कारण नहीं है। शेष कारण अलग प्रकार के हैं, और प्रत्येक की अपनी जांच प्रक्रिया है।

Inodes समाप्त होना, न कि blocks समाप्त होना

एक inode किसी एक file के metadata को सुरक्षित रखता है। filesystem बनाते समय ext4 में inodes की एक निश्चित संख्या तय हो जाती है, इसलिए filesystem में inodes समाप्त हो सकते हैं जबकि blocks अभी भी खाली हों। ऐसी स्थिति में नई files नहीं बन पातीं, भले ही df -h में जगह दिखाई दे रही हो।

df -h /
df -i /

पहली command blocks की गणना करती है और दूसरी inodes की। प्रत्येक के use column की तुलना करें। यदि block का उपयोग कम है और inode का उपयोग अपनी सीमा पर है, तो इसका अर्थ है कि बहुत अधिक संख्या में बहुत छोटी files मौजूद हैं।

df एक ही invocation में -i और --output को स्वीकार नहीं करता है, इसलिए जब आप raw counts को पढ़ना चाहते हैं या किसी अन्य command को देना चाहते हैं, तो inode fields को नाम से चुनें और -i को हटा दें।

df --output=itotal,iused,iavail,ipcent /

ये columns वही accounting प्रदान करते हैं जिसे df -i print करता है, एक ऐसे format में जिसे आप अलग-अलग कर सकते हैं।

bytes के बजाय entries की गणना करके files को ढूँढें।

sudo du --inodes -x -d 1 / 2>/dev/null | sort -rn | head

जो directory सबसे ऊपर आए, उस पर एक स्तर नीचे जाकर वही command दोहराएँ, जब तक कि आप उस tree तक न पहुँच जाएँ जहाँ ये files बन रही हैं। यदि आपका du, --inodes को support नहीं करता है, तो sudo find /var -xdev -type f | wc -l subtree की गणना धीमी गति से करता है।

इसका समाधान उन files को delete करना या move करना है। आप किसी मौजूदा ext4 filesystem में inodes नहीं जोड़ सकते, क्योंकि यह संख्या mkfs के समय ही निश्चित कर दी जाती है। इसलिए इसे बढ़ाने का अर्थ है filesystem को फिर से बनाना और backup से restore करना। XFS आवश्यकतानुसार inodes allocate करता है, इसलिए इसमें इस तरह की निश्चित सीमा नहीं होती। containers चलाने वाली machine अन्य की तुलना में इन सीमाओं तक जल्दी पहुँच जाती है, क्योंकि image layers में बहुत सारी छोटी files होती हैं। ऐसी machine पर VPS पर Docker के disk usage को prune करना इसका सटीक समाधान है, और यह filesystem की सामान्य सफाई की तुलना में कहीं अधिक जगह खाली करता है।

माउंट पॉइंट के नीचे छिपा हुआ स्पेस

किसी डायरेक्टरी पर कुछ भी माउंट करने से पहले उसमें फाइलें हो सकती हैं। उस डायरेक्टरी पर एक फाइलसिस्टम माउंट करें और नीचे मौजूद फाइलें वहीं बनी रहती हैं: वे अभी भी एलोकेटेड हैं, df द्वारा गिनी जाती हैं, और अब नाम से उन तक नहीं पहुँचा जा सकता। du उन्हें नहीं देख सकता क्योंकि माउंट उन्हें ढक लेता है।

इसे tmpfs के साथ दिखाएं, जिसके लिए किसी अतिरिक्त डिस्क की आवश्यकता नहीं होती। इस भाग के लिए एक ऐसी मशीन की आवश्यकता है जहाँ आपको माउंट करने की अनुमति हो, इसलिए यह KVM VPS पर काम करता है।

sudo mkdir -p /srv/covered
sudo cp /etc/services /srv/covered/
ls /srv/covered
sudo mount -t tmpfs tmpfs /srv/covered
ls /srv/covered
sudo umount /srv/covered
ls /srv/covered

बीच वाला ls एक खाली डायरेक्टरी दिखाता है। कॉपी कहीं नहीं गई: यह अभी भी रूट फाइलसिस्टम पर है, और अनमाउंट करते ही यह वापस आ जाती है। अब एक ऐसी सर्विस की कल्पना करें जिसने किसी के द्वारा उस पर वॉल्यूम माउंट करने से पहले एक महीने तक उस पाथ पर लॉग किया हो।

चल रहे सर्वर पर वास्तविक स्थिति खोजने के लिए, रूट फाइलसिस्टम को कहीं और दूसरी बार माउंट करें। एक bind mount उन फाइलसिस्टम्स के बिना एक फाइलसिस्टम दिखाता है जो उसके अंदर माउंट किए गए हैं।

sudo mkdir -p /mnt/rootcheck
sudo mount --bind / /mnt/rootcheck
sudo du -xhs /mnt/rootcheck/* 2>/dev/null | sort -h
sudo umount /mnt/rootcheck

जो कुछ भी उस लिस्टिंग में दिखाई देता है लेकिन सामान्य पाथ के नीचे नहीं, वह एक माउंट पॉइंट के नीचे दबा हुआ है। काम पूरा होने पर bind mount को अनमाउंट करें, अन्यथा -x के बिना किया गया बाद का du उन्हीं फाइलों को दो बार गिन लेगा।

root के लिए आरक्षित ब्लॉक्स

ext4 फाइलसिस्टम root यूजर के लिए ब्लॉक्स का एक हिस्सा आरक्षित रखता है। इससे डिस्क भर जाने पर भी root यूजर लॉगिन कर सकता है और मशीन को रिपेयर कर सकता है। एक सामान्य यूजर के रूप में चलने वाली प्रोसेस पहले इस सीमा से टकराती है, जबकि df अभी भी थोड़ी जगह खाली दिखाता है। डिफॉल्ट मान मानने के बजाय अपने फाइलसिस्टम पर सेटिंग को पढ़ें।

dev=$(df --output=source / | tail -n 1)
sudo tune2fs -l "$dev" | grep -i 'block count'

यह कमांड कुल ब्लॉक संख्या और आरक्षित ब्लॉक संख्या को समान इकाइयों में प्रिंट करता है, इसलिए उनके बीच का अनुपात सीधा होता है। df उपलब्ध कॉलम को उस स्थान के रूप में रिपोर्ट करता है जिसे एक सामान्य यूजर अभी भी उपयोग कर सकता है, यही कारण है कि 'used' और 'available' का योग कुल आकार से कम आता है। यह अंतर ही आरक्षित हिस्सा है।

इसे sudo tune2fs -m <percent> "$dev" के साथ बदलें। यह बदलाव तुरंत लागू होता है और इसके लिए remount की आवश्यकता नहीं होती। एक अलग डेटा फाइलसिस्टम पर आरक्षित हिस्से को कम करना उचित है। रूट फाइलसिस्टम पर, इतनी जगह जरूर छोड़ें कि root लिख सके, क्योंकि पूरी तरह से भरी हुई रूट फाइलसिस्टम को रिपेयर करना बहुत कठिन होता है। tune2fs, ext2, ext3 और ext4 पर काम करता है। XFS में इसके समकक्ष कोई सेटिंग नहीं है।

Where du misleads you on its own

Four habits of du produce totals that look wrong.

  • Hard links: du counts an inode once even when several names point at it, so a tree full of hard links reports less than the sum of its files.
  • Sparse files: du reports the blocks actually allocated, while ls -l reports the apparent size. Add --apparent-size to see the other number.
  • Permissions: run as an ordinary user, du skips what it cannot read and under-reports. The errors it prints are the ones people redirect to /dev/null and stop reading.
  • Filesystem boundaries: without -x, du / counts every filesystem mounted below /, so its total can exceed what df / reports.

df has one habit worth knowing as well. It reports each filesystem separately, so run it against the exact path the failing write targets. A separate /boot fills on its own schedule as kernel packages accumulate, and removing old kernels on Ubuntu is a different job from clearing space on /.

किसी वास्तविक incident के लिए कार्यप्रणाली

  1. df -h <path> और df -i <path> को उस filesystem पर चलाएं जहाँ failed write हो रही थी, न कि केवल reflex के तौर पर / पर।
  2. sudo du -xh -d 1 <mountpoint> 2>/dev/null | sort -h चलाएं, और फिर सबसे बड़ी directory के भीतर जाएं।
  3. यदि du उस डेटा का हिसाब नहीं दे पा रहा है जिसे df उपयोग में दिखा रहा है, तो /proc में उन deleted files को खोजें जो अभी भी open हैं।
  4. यदि दोनों के आंकड़े मेल खाते हैं, तो filesystem को कहीं और bind mount करें और mount point के नीचे छिपी files की जांच करें।
  5. यदि समस्या inode की सीमा तक पहुँचने की है, तो bytes के बजाय files की संख्या गिनें।

यहाँ हर चरण में एक command है जिसका output आप पढ़ सकते हैं। यही समस्या को ठीक करने और केवल अनुमान लगाने के बीच का अंतर है।

FAQ

df डिस्क को फुल क्यों दिखाता है जबकि du बहुत कम जगह दिखाता है?

इसका सामान्य कारण वह फाइल है जिसे डिलीट तो कर दिया गया है, लेकिन किसी प्रोसेस ने उसे अभी भी ओपन रखा है। फाइल को हटाने से उसकी directory entry खत्म हो जाती है, इसलिए du के पास गिनने के लिए कोई नाम नहीं बचता और वह उसे काउंट करना बंद कर देता है। inode और उसके ब्लॉक्स तब तक आवंटित (allocated) रहते हैं जब तक कि आखिरी डिस्क्रिप्टर बंद न हो जाए, और df आवंटित ब्लॉक्स को ही गिनता है। उन सिम्बॉलिक लिंक्स के लिए /proc/<pid>/fd को सर्च करें जिनका टारगेट डिलीटेड मार्क है; इससे आपको फाइल और उसे होल्ड करने वाला प्रोसेस दोनों मिल जाएंगे। तुलना पर भरोसा करने से पहले सुनिश्चित करें कि आपने du को root के रूप में और -x के साथ चलाया है, क्योंकि एक सामान्य यूजर उन डायरेक्टरीज को चुपचाप छोड़ देता है जिन्हें वह पढ़ नहीं सकता।

lsof के बिना डिलीट की गई फाइल को कैसे ढूंढें जो अभी भी ओपन है?

कर्नेल के ओपन डिस्क्रिप्टर्स के रिकॉर्ड का उपयोग करें। sudo find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null उन सभी डिस्क्रिप्टर्स को लिस्ट करता है जो ऐसी फाइल की ओर इशारा कर रहे हैं जिसका कोई नाम नहीं है, और प्रोसेस ID उसके द्वारा प्रिंट किए गए पाथ के अंदर होती है। उन डिस्क्रिप्टर पाथ्स में से किसी एक पर sudo stat -Lc %s चलाने से उसका साइज पता चल जाता है, जिससे आप उन्हें सॉर्ट करके जरूरी फाइल चुन सकते हैं। इसके लिए किसी पैकेज की आवश्यकता नहीं होती, जो तब महत्वपूर्ण होता है जब बिना फ्री स्पेस वाले फाइलसिस्टम पर नया पैकेज इंस्टॉल करना विफल हो सकता है।

क्या मैं प्रोसेस को किल किए बिना स्पेस खाली कर सकता हूँ?

कभी-कभी। sudo truncate -s 0 /proc/<pid>/fd/<n> डिस्क्रिप्टर के माध्यम से उसी inode तक पहुँचता है और प्रोसेस के चलते रहने के दौरान ही उसके ब्लॉक्स को रिलीज कर देता है। यह तब सबसे अच्छा काम करता है जब प्रोसेस ने फाइल को append मोड में ओपन किया हो, क्योंकि उसका राइट हमेशा वर्तमान अंत (end) पर होता है। यदि ऐसा नहीं है, तो राइट ऑफसेट वहीं रहता है और अगला राइट फाइल को शुरुआत में एक होल (hole) के साथ फिर से बना देता है, जिससे रिपोर्ट किया गया साइज वापस बढ़ जाता है जबकि होल के नीचे के ब्लॉक्स फ्री रहते हैं। यूनिट को रीस्टार्ट करना, या उसके डॉक्यूमेंटेशन में बताए गए सिग्नल के साथ उसे लॉग्स फिर से ओपन करने का निर्देश देना, वह समाधान है जिससे कोई स्पार्स फाइल पीछे नहीं बचती।

df फ्री स्पेस दिखाता है लेकिन राइट ऑपरेशन विफल हो जाता है। इसका और क्या कारण हो सकता है?

उसी पाथ पर df -i के साथ inodes की जाँच करें, क्योंकि जिस फाइलसिस्टम में फ्री ब्लॉक्स तो हैं लेकिन फ्री inodes नहीं हैं, वह नई फाइलों को रिजेक्ट कर देता है। जाँचें कि क्या राइट ऑपरेशन किसी नॉन-root यूजर द्वारा ext4 फाइलसिस्टम पर चलाया जा रहा है जहाँ केवल रिजर्व्ड ब्लॉक्स बचे हैं, जिसे डिवाइस पर sudo tune2fs -l चलाने से देखा जा सकता है। यह भी सुनिश्चित करें कि आप उसी फाइलसिस्टम को पढ़ रहे हैं जिसे राइट ऑपरेशन टारगेट कर रहा है, क्योंकि एक अलग /boot या /var, / से स्वतंत्र रूप से भरता है।

du, df की तुलना में बड़ा टोटल क्यों दिखाता है?

-x के बिना du आपके द्वारा दिए गए पाथ के अंतर्गत माउंट किए गए हर फाइलसिस्टम में चला जाता है, इसलिए यह कई फाइलसिस्टम्स को जोड़ देता है जबकि df केवल एक का विवरण देता है। Bind mounts इसे और खराब कर देते हैं, क्योंकि एक ही फाइल हर उस पाथ के तहत एक बार गिनी जाती है जहाँ वह दिखाई देती है। du को एक ही फाइलसिस्टम पर रखने के लिए -x जोड़ें, और df को वही पाथ दें, ताकि दोनों कमांड्स एक ही चीज का विवरण दे रहे हों।