【水羊羹】雪だるま作戦に思いを馳せながら雑談するスレッド Part4

このエントリーをはてなブックマークに追加
663▲ ◆cZfSunOs.U
まぁともあれ,乙でした.root さんも何回もカーネルパッチ当てたり奔走してましたが,
とりあえず一休みでごゆっくりと......といっても本業か......

で,余談.NFS で虫を踏んでいたかも知れない操作を Solaris 上で実験してみたらこんな結果でした.
----------------------------------------
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>

int main(int argc, char **argv)
{
    static const char oldstr[] = "old\n", newstr[] = "new new\n";
    int fd_c, fd_s;
    char *buf;
    struct stat st;

    fd_s = open("/tmp/nfs_s/test", O_WRONLY|O_CREAT|O_TRUNC, 0666);
    write(fd_s, oldstr, sizeof oldstr - 1);
    close(fd_s);
    fd_c = open("/tmp/nfs_c/test", O_RDONLY);
664▲ ◆cZfSunOs.U :2005/07/17(日) 04:14:46
    usleep(100000);
    fd_s = open("/tmp/nfs_s/.test", O_WRONLY|O_CREAT|O_TRUNC, 0666);
    write(fd_s, newstr, sizeof newstr - 1);
    close(fd_s);
    rename("/tmp/nfs_s/.test", "/tmp/nfs_s/test");
    usleep(100000);
    if (fstat(fd_c, &st)) {
        perror("fstat");
        return errno;
    }
    if ((buf = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd_c, 0)) == MAP_FAILED) {
        perror("mmap");
        return errno;
    }
    printf("%.*s", (int)st.st_size, buf);

    return 0;
}
----------------------------------------
# share -orw=localhost /tmp/nfs_s
# mount -Fnfs nfs://localhost/tmp/nfs_s /tmp/nfs_c
# ./a.out
fstat: Bad file number
665 ◆MUMUMUhnYI :2005/07/17(日) 04:18:18 BE:1276872-###
fstat() のところでEBADFですか。
666● ◆ANGLERlqvM :2005/07/17(日) 04:18:53 BE:4700276-###
>>663-664
おぉ、お疲れ様です。
667▲ ◆cZfSunOs.U :2005/07/17(日) 12:03:50
つうか >>663-664 ちょっとボケてましたね...... root のまま a.out 実行してて,
それだと NFS 経由では nobody 権限になってファイルが開けないから EBADF になってました.

改めてやったところ,mount 時にオプション指定なしだと printf() のところで SIGBUS でコケて,
noac オプション付きでやると fstat() が ESTALE という結果です.

この対策としては,ファイル更新時に別ファイル名で生成→rename()
というやり方ではなくロックを使うということのようですが,
ロックするとなると書き込み側の bbsd だけでやっても意味なくて,
読み出し側の httpd 等でもロックしてくれなきゃしょうがないんですよね......