Category Archive作業系統



作業系統 &程式語言 dada on 十一月 20, 2007

消失的硬碟空間

話說某一天,一位同事發現某個在 UNIX 上用 C 寫的程式,跑一陣子後似乎會吃掉很多硬碟空間,吃掉的硬碟空間用 du 去算卻跟 df 的結果差異很大,而且把 process 停掉後,空間竟然又自動恢復正常了

最後,用 fstat 去仔細分析,終於找到原因:

已經開啟的檔案,即使開啟中被強制砍掉(unlink),對原 file descriptor 持續寫入的部份仍會繼續佔用硬碟空間,寫得越多,佔用的空間也越多

實務上最常遇到這種狀況的就是 log rotation,尤其是 rotation 後的舊 LOG 是壓縮過的情況。因為經過 gzip 壓縮過後,原始的 LOG 會被刪除,只留下 XXX.gz。這個時候如果沒有人通知原來寫 LOG 的程式要重新開啟一次 LOG (重新寫一個檔案),就會導致程式在不知情狀況下繼續寫 LOG,然後空間就莫名其妙被用掉了!

例如 FreeBSD 下專門作 log rotation 的 newsyslog 設定檔 (newsyslog.conf) 就有個欄位可以設定在 log rotation 後送一個 signal 給 process,而 apache (httpd) 就接受 SIGUSR1 來當作重新開啟 LOG 檔案的訊號(事實上對 apache 而言是 graceful restart)。很多人以為這只是為了讓 LOG 能繼續寫不會漏掉,但其實更重要的是:如果不這麼作,你的硬碟可能很快就爆掉啦...

我們可以寫個簡單的程式來測試一下這種狀況:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <fcntl.h>
int main()
{
        int     fd, i;
        char    cmd[32], buf[1024];
        memset( buf, 0, 1024);
        snprintf(cmd,sizeof(cmd),"df .");
 
        printf("==> open file for write and delete it ...\n");
        fd = open( "test-file.log", O_CREAT|O_WRONLY|O_TRUNC );
        unlink("test-file.log");
        system(cmd);
 
        printf("\n==> write 100MB to file ...\n");
        for( i = 0 ; i < 1000*100 ; i++ )
                write( fd, buf, 1024);
        system(cmd);
 
        printf("\n==> close file ...\n");
        close(fd);
        system(cmd);
}

首先,這個小程式會先開啟一個檔案,然後馬上砍掉它(但先不關閉檔案),接下來執行 "df ." 來查看目前硬碟用量。第二步驟是寫入100MB的垃圾資料到這個已開啟的檔案(file descriptor)中,然後再執行 "df ." 來取得硬碟用量。最後關閉檔案後,再執行一次 "df ."。執行結果如下:

==> open file for write and delete it ...
Filesystem  1K-blocks     Used     Avail Capacity  Mounted on
/dev/ad8s1d 144520482 28011428 104947416    21%    /home

==> write 100MB to file ...
Filesystem  1K-blocks     Used     Avail Capacity  Mounted on
/dev/ad8s1d 144520482 28111508 104847336    21%    /home

==> close file ...
Filesystem  1K-blocks     Used     Avail Capacity  Mounted on
/dev/ad8s1d 144520482 28011428 104947416    21%    /home

我們可以看到程式寫了100MB之後,空間真的被佔掉了,即使我們已經刪除這個檔案,且從目錄的檔案列表中無法直接看到這個檔案了。而當被開啟的檔案關掉後,這些空間也立即被釋放回來了

接下來我們把程式中的 df 改成 fstat,可以更清楚看到狀況

1
        snprintf(cmd,sizeof(cmd),"fstat -f -p %d .", getpid());

這是最後的結果:

==> open file for write and delete it ...
USER     CMD     PID   FD MOUNT     INUM MODE         SZ|DV R/W
cdsheen  a.out 91475   wd /home 12694528 drwxr-xr-x    2048  r
cdsheen  a.out 91475 text /home 12694672 -rwxr-xr-x    7910  r
cdsheen  a.out 91475    3 /home 12694673 ----r-x--x       0  w

==> write 100MB to file ...
USER     CMD     PID   FD MOUNT     INUM MODE         SZ|DV R/W
cdsheen  a.out 91475   wd /home 12694528 drwxr-xr-x    2048  r
cdsheen  a.out 91475 text /home 12694672 -rwxr-xr-x    7910  r
cdsheen  a.out 91475    3 /home 12694673 ----r-x--x  102400000  w

==> close file ...
USER     CMD     PID   FD MOUNT     INUM MODE         SZ|DV R/W
cdsheen  a.out 91475   wd /home 12694528 drwxr-xr-x    2048  r
cdsheen  a.out 91475 text /home 12694672 -rwxr-xr-x    7910  r

作業系統 dada on 十一月 02, 2007

OpenBSD 4.2 - 有官方安裝光碟了

OpenBSD 4.2 just released on Nov 1, 2007!

從這版開始,官方也提供幾個主要硬體的安裝光碟了,
不再像之前一樣需要自己辛苦地製作安裝光碟

http://ftp.giga.net.tw/OS/OpenBSD/4.2/i386/install42.iso
http://ftp.giga.net.tw/OS/OpenBSD/4.2/amd64/install42.iso
http://ftp.giga.net.tw/OS/OpenBSD/4.2/macppc/install42.iso
http://ftp.giga.net.tw/OS/OpenBSD/4.2/sparc/install42.iso
http://ftp.giga.net.tw/OS/OpenBSD/4.2/sparc64/install42.iso

讓大家方便安裝之餘,也請大家有能力的話,多多贊助一下吧

作業系統 dada on 五月 15, 2007

OpenBSD 4.1 - Unofficial ISO Image

OpenBSD 4.1 released!

關於 OpenBSD 4.1 的相關資訊請參考: http://www.openbsd.org/41.html

照例製作了兩份安裝光碟 (包含 i386 與 amd64 兩種平台),想用的人可以到以下網址抓取

OpenBSD 4.1 Unofficial Images: http://ftp.giga.net.tw/#openbsd

這份光碟是從 OpenBSD 4.1-RELEASE 製作的… 也有用 VMware 裝過沒問題了

同樣的還是要聲明一點,以上可以下載的安裝光碟都是 OpenBSD 官方的安裝光碟,官方的安裝光碟是要賣錢的,如果你想幫助 OpenBSD 的開發團隊,請考慮購買一份官方的安裝光碟,訂購的資訊請詳閱:

http://www.openbsd.org/orders.html

作業系統 dada on 十一月 02, 2006

OpenBSD 4.0 - Unofficial ISO Image

OpenBSD 4.0 released!

關於 OpenBSD 4.0 的相關資訊請參考: http://www.openbsd.org/40.html

昨天下午把檔案 mirror 回來後(ftp.giga.net.tw ~當然 packages 沒有全抓,硬碟空間不夠^^||),就照例製作了兩份安裝光碟 (包含 i386 與 amd64 兩種平台),想用的人可以到以下網址抓取

OpenBSD 4.0 Unofficial Images: http://ftp.giga.net.tw/#openbsd

這份光碟是從 OpenBSD 4.0-RELEASE 製作的...
昨天還嘗試用 VMware 裝過沒問題,或許應該把裝好的 VMware Image 也丟上來,可能會造福更多人...

同樣的還是要聲明一點,以上可以下載的安裝光碟都是 OpenBSD 官方的安裝光碟,官方的安裝光碟是要賣錢的,如果你想幫助 OpenBSD 的開發團隊,請考慮購買一份官方的安裝光碟,訂購的資訊請詳閱:

http://www.openbsd.org/orders.html

其實 OpenBSD 4.0 早在九月底十月初就 Ready 了,mirror 的時候就可以發現很多檔案的日期都是一個月前的,隔一個月才把 binary 放出來大概是希望留點時間可以製作官方光碟吧... 有能力的人(或者有辦法決定公司採購預算的人^^)可以考慮贊助個幾張光碟吧

作業系統 dada on 十月 24, 2006

踩到 FreeBSD 6.1 的地雷...

昨天裝了台機器,由於有兩台相同容量的 18G 硬碟,此裝好之後順手替 root partition 加上了 Software RAID....

沒想到一時疏忽,修改 fstab 時忘了加上 /mirror/ ...

/dev/mirror/gm0s1b none swap sw 0 0
/dev/mirror/gm0s1a / ufs rw 1 1

所以重開機時開不起來了...
原本根據 這篇 的說明,只要在 mountroot> prompt 下,重新指定 root partition 位置就可以進去修正了...

但是,沒想到好像踩到 FreeBSD 6.1 的地雷了:
kern/98910: [kbd] keyboard not working at mountroot prompt on IBM T42P

也就是 mountroot> 下鍵盤不能動了.... 我用的是研華的伺服器,問題跟上面這個 PR 一模一樣...

偏偏我這台機器的光碟和軟碟又都壞了.... 只好很苦命的再把機器搬出機櫃來拆開,外接光碟重新修正了事....

« 前一頁後一頁 »