Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NFS mount System Call in linux

I am trying to mount a source directory from nfs server to a destination directory in embedded board having linux. The following command works perfectly as expected in shell prompt in the board.

mount -t nfs -o nolock 10.126.62.45:/vol/home/avinoba/Sky /mnt

What is the equivalent system call to be used in program for the command above? I tried the below call but the mount failed with "Invalid Argument"

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));
}

Please suggest what is the solution for it.

Thanks

like image 517
Avinob Aich Avatar asked Dec 08 '22 04:12

Avinob Aich


1 Answers

I'm quite surprised here knowing that how this is not covered by any man page regarding NFS mounts. Diving into the kernel code, in the function nfs_validate_text_mount_data, the function nfs_parse_mount_options is responsible for parsing the multiple comma separated options passed as the fifth argument in the mount system call.

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;

In the above code block, the last if statement checks whether the nfs server address and socket family is defined to valid values. If they are not updated within nfs_parse_mount_options, mount would end up returning invalid parameter.

If the implementation of nfs_parse_mount_options is walked through, it can be seen that, only for the case Opt_addr, the nfs server address and the socket family is updated by parsing the options argument.

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;

The case Opt_addr corresponds to the option "addr=nfs server ip". So for the system call to work, defining this option is a must. As far as I have searched, this is completely missing from all the man pages which describes nfs mounts.

So now considering the problem statement, please try by changing to the below code

if(mount(":/vol/home/avinoba/Sky","/mnt","nfs",0,"nolock,addr=10.126.62.45") == -1)
{
     printf("ERROR: mount failed: %s \n",strerror(errno));
}

Also note that when the addr option is put in the argument, the ip address in front of the nfs server path becomes optional. However the ':' is must,as this acts as the delimiter to parse the nfs server path.

like image 200
Abhijit Avatar answered Jan 12 '23 08:01

Abhijit