zfs again January 26
今天才發現我弄錯了,昨天那篇提到的只是不會 cache,不會導致 kmem_map too small。
http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/contrib/opensolaris/uts/common/fs/zfs/arc.c
version 1.4 調了一些參數試圖緩和 memory 用光的情形…
今天才發現我弄錯了,昨天那篇提到的只是不會 cache,不會導致 kmem_map too small。
http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/contrib/opensolaris/uts/common/fs/zfs/arc.c
version 1.4 調了一些參數試圖緩和 memory 用光的情形…
i386 跑 zfs 很容易會遇到 kmem_map too small,然後 panic。(搞錯了,不是這個 patch,請看下一篇)
剛才 rafan 貼了一段 message 給我
Change type of kmem_used() and kmem_size() functions to uint64_t, so it
doesn’t overflow in arc.c in this check:if (kmem_used() > (kmem_size() * 4) / 5)
return (1);With this bug ZFS almost doesn’t cache.
Only 32bit machines are affected that have vm.kmem_size set to values >=1GB.
src/sys/compat/opensolaris/kern/opensolaris_kmem.c#rev1.3,還有 diff。
搞笑 XD
這一兩個學期來,實驗室買了幾台 RAID 來裝大家實驗用的資料。幾個禮拜前,file system 爆炸,我們損失了不少資料
重點提要:
接 RAID 的機器是跑 FreeBSD 7.0-PRERELEASE。一開始發現異常,是 zfs 說他寫進去的資料跟讀出來的 checksum 不一樣,於是就爆了三個 zfs 的 partition。接在同一個 SCSI channel 的 RAID 共有四台,三台 proware 跟一台 festora(?),zfs 叫有 error 的是其中兩台 proware,所以我們懷疑是 RAID 本身有問題。
後來找了 proware 的工程師來幫我檢查 RAID,他說我們接四組 RAID 太多了… 小時候學到的 SCSI device 不就是要用串的嗎,可是沒想到四組就算太多 orz 而且最好不要把不同廠牌的 RAID 接在一起… 因為訊號可能會互相干擾 @@ (我以為這應該有標準,可是看起來接在一起的確不太好…)
於是我們把四台 RAID 分到兩張 scsi 卡上(之前因為某些原因沒這麼做),其中一個 channel 是一組 proware + 一組 festora。然後今天下午一直發現 zfs 又開始抱怨了… 一個月前這麼接還沒事的耶 orz 真是 ooxx 現在改成三組 proware 接同一張 scsi card,另一組自己接一張,zfs 就不叫了。
(%&$#@!*(%!#@^!)
我一直滿喜歡 FreeBSD 的 ports 的,但是比較習慣 Linux 的 kernel。至於 Gentoo 嘛,python-base 玩起來實在很慢,雖然有一些可以加速的 solution,但是我覺得還是滿慢的。所以我試著在 Debian 上玩 FreeBSD 的 ports。
首先,當然是先裝一下 cvsup (Debian 的 pool 就有了)。因為有些工具 FreeBSD 跟 Linux 不相容的關係,還得裝一下 freebsd5-buildutils。
然後找台 FreeBSD 把他的 /usr/share/examples/cvsup/standard-supfile 偷過來。裡面有些設定得改一下,例如像這樣:
*default host=freebsd.csie.ntu.edu.tw *default base=/home/victor/usr/var/db *default prefix=/home/victor/usr
檔名如果取成 ports-supfile 的話,就執行
cvsup -g -Z -L 2 ports-supfile
把 ports 拉回來。
另外,freebsd5-buildutils 的 /usr/share/freebsd5-buildutils/ports/bsd.port.mk 是沒辦法直接用的(version 5.3+2-2)。剛才把這個 bug report 上去了(URL),不知道他會不會理我 XD 如果不行的話,可以拿這個 patch 去用。裡面應該還有其他東西要改啦,不過這樣子已經夠 make 不少東西了。
由於 FreeBSD ports 本來就是設計給 FreeBSD 用的(?),所以有些參數得從 /etc/make.conf override 掉。例如:
ARCH=i686 OSVERSION=502123 PKGINSTALLVER=0 GNU_CONFIGURE=1 CONFIGURE_MAX_CMD_LEN!=/usr/bin/getconf ARG_MAX FETCH_CMD=/usr/bin/wget # override default SH=sh , 避免 configure 產生錯的 libtool SH=/bin/sh PREFIX=/home/victor/usr PORTSDIR=/home/victor PORT_DBDIR=$(PREFIX)/var/db/ports PKG_DBDIR=$(PREFEX)/var/db/pkg NO_DEPENDS=1 WITH_GLIB=2
最後就是真的 make install 啦。由於 make 版本不同的關係,必須用 freebsd5-buildutils 裡提供的 freebsd-make 來裝(pmake 是 NetBSD make)。如果沒意外的話,就可以 make 啦:
freebsd-make WITH_OPENSSL_BASE=1
至於 make install 的話,因為我懶得去追 sed(1) regular expression 格式有些不一樣的問題,所以沒去修。我在 bug report 裡面建議他生個 freebsd-sed 出來。
結論是,為什麼我要做這種事呢 XD 還是用之前寫的 debpatch 比較實在 XD 缺點就是 patch 們得自己 maintain 了。
在寫計網作業時,發現如果用 signal(2) 去 override default signal handler,當 accept(2) block 住時,接到了那個 signal,並不會 return 回來。這跟平常沒 override 時,會傳回 -1 並將 errno 設為 EINTR 的情形不同。翻了 > 才發現原因。
在 accept, read 這類的 /slow system call/ 裡面接到 signal 後,當 signal handler return 時,傳回 EINTR。“有些”系統會重新回到該 system call 執行 (現在的 Linux & FreeBSD 都是),我在想也是因為這個原因,我的 accept 不會 return。
後來,我用 sigaction(2) 取代 signal(2),sa_flags 不要設 SA_RESTART,就可以如我所願讓 blocked 的 accept 回來了。這個方法在 Linux 跟 FreeBSD 下都 work。