如何稳健地写入慢速&不可靠的NFS

时间:2017-08-20 14:26:15

标签: c linux file nfs

我不是C的专家,我正在寻找一些建议,以使我的程序更健壮和可靠。只是为了给出一些背景信息:我编写了一个程序来做一些科学计算,需要花费很长时间(大约20小时)才能在大型HPC linux集群上使用SLRUM调度系统和NFS挂载文件系统执行。似乎发生的事情是,在20小时的某个时间,与文件系统的连接变得陈旧(在整个机器上;独立于我的程序)和第一次打开&写一个文件需要很长时间,这会导致我迄今为止无法精确跟踪的段错误转储错误。下面是一个至少在概念上重现错误的最小文件:程序启动,打开文件,一切正常。该程序进行了一些长时间的计算(由sleep()模拟),试图打开&再次写入同一文件,它失败了。什么是一些约定,使我的代码更健壮,可靠地将我的结果写入文件而不会崩溃?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char **argv) {
    // Declare variables
    FILE *outfile;
    char outname[150] = "result.csv";

    // Open file for writing
    printf("CHECKING if output file '%s' is writable?", outname);
    outfile=fopen(outname, "w");
    if (outfile == NULL) {
        perror("Failed: ");
        exit(EXIT_FAILURE);
    }
    fclose(outfile);
    printf(" PASSED.\n");

    // Do some computation that takes really long (around 19h)
    sleep(3);

    // Open file again and Write results
    printf("Writing results to %s ...", outname);
    outfile=fopen(outname, "w");
    if (outfile == NULL) {
        perror("Failed writing in tabulate_vector_new: ");
        exit(EXIT_FAILURE);
    }
    fprintf( outfile, "This is the important result.\n");
    fclose(outfile);

    printf(" DONE.\n");
    return 0;
}

1 个答案:

答案 0 :(得分:0)

由于NFS问题,您的程序会出现段错误,这似乎很奇怪。我希望它能无限期地挂起,而不是崩溃。话虽如此,我建议请求一个新的进程来检查NFS挂载是否正常工作。这样,您的重要代码就不会直接参与测试有问题的文件系统。类似以下方法的东西可能有用:

pid_t pid = fork();

if (pid == -1)
{
    // error, failed to fork(). should probably give up now. something is really wrong.
} 
else if (pid > 0)
{
    // if the child exits, it has successfully interacted with the NFS file system
    wait(NULL);
    // proceed with attempting to write important data
}
else 
{
    // we are the child; fork df in order to test the NFS file system
    execlp("df", "df", "/mnt", (char *)NULL)
    // the child has been replaced by df, which will try to statfs(2) /mnt for us
}

这里的一般概念是我们利用df命令检查NFS文件系统(我假设是/mnt)是否正常工作。如果它暂时不起作用,df应该挂起,直到它再次开始工作,然后退出,将控制权返回给您的程序。如果您怀疑df可能会永远挂起,可以使用alarm(2)等待一段时间(可能至少几分钟)来增强我的示例,之后您可以重试df 。请注意,这可能会导致僵尸df进程停留。

最后,正确的解决方案是尝试获得更可靠的NFS服务器,但在此之前,我希望这有用。