TT Lab
Get started
Learn Learning paths Courses

Linux Incident Response

Diagnosing Disk and inodes

Continue in TT Lab

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.

  1. Write the inode usage (%) of the filesystem that /root belongs to, as a number only, to /root/disk/inode_pct.txt.
  2. Write the actual usage of the /etc directory as a number in KB only to /root/disk/etc_kb.txt.
  3. Write the file name of the largest regular file directly under /usr/bin to /root/disk/biggest.txt.
  4. 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.
  5. 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.
  6. 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.
  7. 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=<크기>.
  8. 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

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.

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.