在Linux中NFS挂载系统调用

7
我正在尝试将来自NFS服务器的源目录挂载到嵌入式Linux板上的目标目录。以下命令在板子的shell提示符中完美地按预期工作。
mount -t nfs -o nolock 10.126.62.45:/vol/home/avinoba/Sky /mnt

什么是程序中用于上述命令的等效系统调用? 我尝试了下面的调用,但挂载失败并显示“无效参数”。
if(mount("10.126.62.45:/vol/home/avinoba/Sky","/mnt","nfs",MS_MGC_VAL,"nolock") == -1)
{
     printf("ERROR: mount failed: %s \n",strerror(errno));
}

请提供建议,如何解决这个问题。
谢谢。

你可以使用 strace 命令来追踪 mount 命令,以找到它所执行的确切系统调用。 - Basile Starynkevitch
3个回答

17

我很惊讶这里没有任何man页面介绍如何挂载NFS。深入研究内核代码,在函数nfs_validate_text_mount_data中,函数nfs_parse_mount_options负责解析作为第五个参数传递的多个逗号分隔选项。

struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;

if (nfs_parse_mount_options((char *)options, args) == 0)
    return -EINVAL;

if (!nfs_verify_server_address(sap))
    goto out_no_address;
在上面的代码块中,最后一个if语句检查nfs服务器地址和套接字族是否定义为有效值。如果它们没有在中更新,那么挂载将返回无效参数。
如果深入研究的实现,可以看到,只有对于的情况,才通过解析参数来更新nfs服务器地址和套接字族。
case Opt_addr:
    string = match_strdup(args);
    if (string == NULL)
        goto out_nomem;
    mnt->nfs_server.addrlen =
        rpc_pton(mnt->net, string, strlen(string),
            (struct sockaddr *)
            &mnt->nfs_server.address,
            sizeof(mnt->nfs_server.address));
    kfree(string);
    if (mnt->nfs_server.addrlen == 0)
        goto out_invalid_address;
    break;

案例Opt_addr对应选项"addr=nfs服务器ip"。因此,为了使系统调用工作,必须定义此选项。就我所搜寻的资料而言,所有描述nfs挂载的手册都完全没有提及此问题。

考虑到问题陈述,请尝试将代码更改为以下内容:

if(mount(":/vol/home/avinoba/Sky","/mnt","nfs",0,"nolock,addr=10.126.62.45") == -1)
{
     printf("ERROR: mount failed: %s \n",strerror(errno));
}
同样需要注意的是,当在参数中加入 addr选项时,nfs 服务器路径前面的 IP 地址变为可选。但是必须要有 ':',因为它充当分隔符来解析 nfs 服务器路径。

1
真的很有帮助。现在它按预期工作了。看来mount(2)的man页面需要更新,否则就像你所做的那样,有人必须查看内核源代码。谢谢Abhijit。 - Avinob Aich
当addr是主机名时,这会失败。有什么办法可以避免主机名/FQDN的问题吗? - AAB

0

如果需要,MS_MGC_VAL 应该在前 16 位而不是后 16 位。如果您的内核版本大于 2.4,则根本不需要它。


是的,你说得对。我没有找到任何适合的mountflag。尝试传递0,但没有帮助。内核版本为2.6。 - Avinob Aich

0

现在对我来说,它通过以下调用得到解决。

if(system("mount -t nfs -o nolock 10.126.62.45:/vol/home/avinoba/Sky /mnt")==-1);
{
     printf("ERROR: mount failed \n");
}

但仍在寻找使用mount()调用的答案,因为它接受"filesystemtype"参数作为"nfs"。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接