Cant free space

From FBSD_tips

Jump to: navigation, search

Because of the way the UFS filesystem works, you may rm a file to liberate space on a critically full disk only to see the disk usage remain changeless. When a process opens a file, it gets a pointer to a thing called an inode (the structure in the filesystem that holds data associated with a file). This structure has a number of things that refer to it in the filesystem (e.g. hardlinks). There are also counts of processes with that inode open in the kernel. When you rm the file you are unlinking the file name reference to that inode, but if something else refers to it either in the file system or in a running process, the space will not be freed. The space doesn't become available or freed up until all processes that use the file are closed, and all links that point to the file are removed

[edit] hard links

Demonstration of hardlinking problem. I will cd to /usr, create a 50 MB file, hardlink it, delete the original and the space is not freed, as you can see until I delete the second link to the file. All hardlinks are peer to each other, there is no 'parent' or 'child', just a link count.

# cd /usr
# df /usr
Filesystem  1K-blocks     Used Avail Capacity  Mounted on
/dev/ad0s1d  28920716 26513702 93358   100%    /usr
# dd if=/dev/zero of=test.dd bs=1M count=50 
50+0 records in
50+0 records out
52428800 bytes transferred in 2.057953 secs (25476188 bytes/sec)
# ln test.dd test2.dd
# df /usr
Filesystem  1K-blocks     Used Avail Capacity  Mounted on
/dev/ad0s1d  28920716 26564950 42110   100%    /usr
# ls -l
-rw-r--r--   2 root  wheel     52428800 Oct  1 23:27 test.dd
-rw-r--r--   2 root  wheel     52428800 Oct  1 23:27 test2.dd
# rm test.dd
# df /usr
Filesystem  1K-blocks     Used Avail Capacity  Mounted on
/dev/ad0s1d  28920716 26564950 42110   100%    /usr
# rm test2.dd
#df /usr
Filesystem  1K-blocks     Used Avail Capacity  Mounted on
/dev/ad0s1d  28920716 26513702 93358   100%    /usr

Solution : Find the Inode number BEFORE you rm the file. Then if the space does npt free up after you rm it, you can search the filesystem for another file with the same Inode number and rm it too.

# ls -li 
36 -rw-r--r--   2 root  wheel     52428800 Oct  3 15:21 test.dd
36 -rw-r--r--   2 root  wheel     52428800 Oct  3 15:21 test2.dd
# find ./ -inum 36
./test.dd
./test2.dd

[edit] Running process

Demonstration of the 'running process with the file open problem. i will creat the same 50 MB file, fork tail -f into the background (with < /dev/null to keep it from waiting to the tty for input), rm the test file and show that it does not release until the process is terminated.

# cd /usr
# df /usr
Filesystem  1K-blocks     Used Avail Capacity  Mounted on
/dev/ad0s1d  28920716 26513702 93358   100%    /usr
# dd if=/dev/zero of=test.dd bs=1M count=50 
50+0 records in
50+0 records out
52428800 bytes transferred in 2.057953 secs (25476188 bytes/sec)
# df /usr
Filesystem  1K-blocks     Used Avail Capacity  Mounted on
/dev/ad0s1d  28920716 26564950 42110   100%    /usr
# tail -f test.dd < /dev/null &
[1] 78478
# rm test.dd
# df /usr
Filesystem  1K-blocks     Used Avail Capacity  Mounted on
/dev/ad0s1d  28920716 26564950 42110   100%    /usr
#  fg 1
tail -f test.dd </dev/null
^C
# df /usr
Filesystem  1K-blocks     Used Avail Capacity  Mounted on
/dev/ad0s1d  28920716 26513702 93358   100%    /usr

Solution: Before you rm the file, use fstat to find out if it is opened by a process, then take apropriate action. (Many servers are coded to re-read configuration files and close and re-open log files and other similar 'reset' types of behaviors upon recieving a HUP signal)

# tail -f test.dd < /dev/null > /dev/null &
# fstat test.dd
USER     CMD          PID   FD MOUNT      INUM MODE         SZ|DV R/W NAME
root     tail        1613    3 /usr         36 -rw-r--r--  52428800  r  test.dd
# kill -TERM 1613
# rm test.dd

Gongo 06:11, 2 October 2007 (UTC)

Personal tools