Diagnosing Disk and inodes
Goal
You look at disk capacity problems along two axes, blocks and inodes, and deliberately create, diagnose and recover from the situation "I deleted it but the space didn't shrink".
Why it matters
No space left on device does not mean "there are no blocks" but "the kernel has no resource to accommodate this write." That resource may be blocks, inodes, or free space excluding the space reserved for root. So you have to look at df -h and df -i together, and when df and du disagree, you must suspect deleted-but-open files. In particular, the situation you create in steps 5–6 is the form you meet most often in practice - and the moment you restart the process in that situation, your chance of recovery disappears with it. The order is the skill.
Steps
Work in the /root/disk directory.
- Write the inode usage (%) of the filesystem that
/rootbelongs to, as a number only, to/root/disk/inode_pct.txt. - Write the actual usage of the
/etcdirectory as a number in KB only to/root/disk/etc_kb.txt. - Write the file name of the largest regular file directly under
/usr/binto/root/disk/biggest.txt. - Create the
/root/disk/manydirectory and put exactly 500 files of size 0 in it. Then write thedu -skvalue of that directory to/root/disk/many_kb.txt. - Create
/root/disk/ghost.logof 10MB or more, and while some process keeps that file open, delete only the file name. Write that process's PID to/root/disk/ghost_pid.txt. That process must be alive at grading time. - Recover the contents of the file that the process from step 5 is holding to
/root/disk/recovered.log. The size must be the same as the original. - Create
/root/disk/findghosts.sh <최소바이트>(the argument is the minimum number of bytes). Across the whole system, it finds deleted-but-open files of at least that size and prints them one per line in the formpid=<PID> bytes=<크기>. - Create
/root/disk/diskreport.sh <디렉터리>(the argument is a directory). It prints the number of regular files and the total bytes anywhere under that directory as the following two lines. For a directory that doesn't exist, it must exit with a non-zero code.files=<개수>bytes=<합계>
Notes
readlink /proc/<PID>/fd/<N>shows what an fd points to. A deleted file has(deleted)appended.stat -L -c %s /proc/<PID>/fd/<N>follows the symlink and tells you the actual size.find "$d" -type f -printf '%s\n'gives you a list of sizes that you can add up.- Common mistake 1: if the process holding the file open in step 5 dies, the ghost disappears and steps 6–7 all fail.
- Common mistake 2: in step 7, be careful not to count
/proc/selfor the grader's own fds.
Read inode usage
Write the inode usage (%) of the filesystem that /root belongs to, as a number only, to /root/disk/inode_pct.txt.
df has a separate option that shows inodes instead of blocks. Write only the number, without the % sign.
Measure the actual usage of a directory
Write the actual usage of the /etc directory as a number in KB only to /root/disk/etc_kb.txt.
du walks the path and counts the blocks actually occupied. There is a combination of options that summarizes it in KB.
Find the largest file
Write the file name of the largest regular file directly under /usr/bin to /root/disk/biggest.txt.
Use find's -printf to extract size and name together and sort them. You need only the file name, not the path.
Create 500 empty files
Create the /root/disk/many directory and put exactly 500 files of size 0 in it. Then write the du -sk value of that directory to /root/disk/many_kb.txt.
You can create them all at once with brace expansion or seq. Confirm that the content is 0 bytes but du is not 0.
Create a deleted-but-open file
Create /root/disk/ghost.log of 10MB or more, and while some process keeps that file open, delete only the file name. Write that process's PID to /root/disk/ghost_pid.txt. That process must be alive at grading time.
Create the file, make some process keep it open, and delete only the name. tail -f is suitable.
Recover the ghost file
Recover the contents of the file that the process from step 5 is holding to /root/disk/recovered.log. The size must be the same as the original.
/proc//fd/ is a symlink that points to that file. Copy from that path as it is.
Ghost file detection script
Create /root/disk/findghosts.sh <최소바이트> (the argument is the minimum number of bytes). Across the whole system, it finds deleted-but-open files of at least that size and prints them one per line in the form pid=<PID> bytes=<크기>.
readlink /proc//fd/ and pick only those ending in (deleted). Measure the size with stat -L.
Recursive size aggregation script
Create /root/disk/diskreport.sh <디렉터리> (the argument is a directory). It prints the number of regular files and the total bytes anywhere under that directory as the following two lines. For a directory that doesn't exist, it must exit with a non-zero code.
files=<개수>bytes=<합계>
Find the regular files with find and compute the count and the sum of sizes. Treat a directory that doesn't exist as an error.