不知道是我最近EQ太差還是怎樣.
寫這麼久的程式, 做這麼久的系統, 還是會碰到一些鳥事情. 之前這個libmysqlclient.so.14的天才問題已經扯斷一次我的理性了, 這次碰到的問題又再度挑戰我的極限.
首先從Solaris 7開始就知道, Solaris該死的不支援flock, 所以也就只能用fcntl或dotlock的dirty hack去模擬. 然後也知道NFS配上lockd時會弄出一些.nfsXXXX的檔案作stateless FS下充當lockfile用.
有幸或不幸, 在借用某軟體的maildir-scan/maildir-parse lib後, 掛上NFS下場就是namespace掛點, select掛點, 永遠停readdir, 不會timeout, 不會segment fault, 不會core dump, 當然也永遠不會停: 這些還是硬把gdb掛上去才看出來的, 這年頭竟然有軟體開發不做debug的?
認命! 慢慢啃source codes, 找到了lock state的部分, 一切正常. 自己寫個a.out去嘗試呼叫也都沒問題, 彷彿教科書般的標準.
那為什麼會readdir到dead lock? 而且是很神奇的dead lock!
然後我在 opendir後, while readdir之中看到了這個東西.
/* On Solaris/SunOS, use fcntl to lock file but flock */
下面呢? 下面沒有了, 還是一樣用flock, 而且還很聰明的先檢查flock能不能用. 意思就是, Solaris/SunOS沒flock可以用喔, 改用fcntl, 所以….沒有了.
更經典的在後頭….
while [1]d = readdir(dirp != NULL) {
/* skip . & .. */
if (d->d_name[0] == ‘.’ &&
(d->d_name[1] == ‘\0’ || (d->d_name[1] == ‘.’ && d->d_name[2] == ‘\0’)))
continue;
/* skip .nfs???? if under NFS */
}
對, 寫了註解告訴我們, .nfs???? 要跳過, 然後下面呢? 下面又沒有了.
我又不是紀曉嵐, 也不是被他調侃的太監, 只是補上一個
if (d->d_name[0] == ‘.’ &&
d->d_name[1] == ‘n’ &&
d->d_name[2] == ‘f’ &&
d->d_name[3] == ‘s’ &&
d->d_name[8] == ‘\0’)
continue;
都不肯嗎?
喵的, 能夠當人, 誰還去寫程式! 給這些亂搞的人糟蹋!
References
↑1 | d = readdir(dirp |
---|
[…] 這篇剛好也可以用來回應 nekobe 的這篇《能夠當人, 誰還要來寫程式?》,我承認,我必須這樣亂搞的時候,都會在註解裡加上 TODO 的字樣。唉,亂搞的原因千百種,也許時程上來不及,也許是政治的因素[2],也許是奇蒙子的因素,也許是道德上的考量[3],也或許,原始的需求根本沒有這一項…… […]