LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   "Invalid argument" error while mounting NFS partition (https://www.linuxquestions.org/questions/programming-9/invalid-argument-error-while-mounting-nfs-partition-660529/)

montylee 08-05-2008 01:41 AM

"Invalid argument" error while mounting NFS partition
 
I am trying to mount a local folder through NFS on the same machine.

Here's my code:

Code:

#include <stdio.h>
#include <errno.h>
#include <sys/mount.h>

int main ()
{
        int retval;

        retval = mount ((const char *) "127.0.0.1:/home/test", (const char *) "/tmp/test", "nfs", MS_RDONLY, ""); 

        if (retval != 0) {
                printf(" Mount system call failed  and return value is %d\n", errno) ;
                perror("mount");
        } else {
                printf(" Mount system call successfull \n");
        }
        return 0;
}

I am getting the following error:
Quote:

Mount system call failed and return value is 22
mount: Invalid argument
I have made appropriate changes in the /etc/exports file and restarted the NFS server. The NFS mount command works from the terminal but not from the above program.

Is it not possible to mount NFS partitions using the mount() API in code?

irishbitte 08-05-2008 06:20 PM

well, you know that NFS comes in two parts, nfs-server and nfs-client! you need to have the nfs-client package or nfs-common package installed on your client machine for NFS to work!

In ubuntu install nfs-common and portmap:

Code:


sudo apt-get install portmap nfs-common

then try your program again.

montylee 08-06-2008 12:23 AM

As i already stated that NFS mount is working on the command prompt. So, my NFS server is up and working. It's only in the program that I am getting this error.

BTW, i am using Fedora Core 9 and Ubuntu 7.10

Mr. C. 08-06-2008 12:53 AM

Argument 3 of mount is an int, not a string. It is a mount flag, such as MNT_RDONLY. Hence an invalid argument. See man 2 mount.

montylee 08-06-2008 07:09 AM

Quote:

Originally Posted by Mr. C. (Post 3238284)
Argument 3 of mount is an int, not a string. It is a mount flag, such as MNT_RDONLY. Hence an invalid argument. See man 2 mount.

I checked the man page of mount API before writing my code. It says that the argument 3 is "const char *". Here's the link to the man page:

http://linux.die.net/man/2/mount

and here's the syntax given in the man page:

Quote:

int mount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data);

In the man page itself, they have given examples of 3rd argument i.e. "ext2", "nfs", so i used that.

There is not much documentation on the internet about mount API.

Please help...

irishbitte 08-06-2008 12:29 PM

Well, montylee, I'm sure it can't hurt to at least try out Mr. C's suggestion? It might be your solution! especially if your NFS man page is out of date.

Mr. C. 08-06-2008 04:51 PM

Oops, darn, looks like a surprising difference in BSD v. Linux:

BSD
Code:

    int
    mount(const char *type, const char *dir, int flags, void *data);

I usually check for Linux specific man pages; don't know why I relied on my BSD system yesterday for documentation.

Your fifth argument should not be a string, it should be pointer to a struct nfs_mount_data.

man 2 mount:
Quote:

The data argument is interpreted by the different file systems. Typically it is a string of comma-separated options understood by this file system. See mount(8) for details of the options available for each filesystem type.
man 8 mount
Quote:

Mount options for nfs
Instead of a textual option string, parsed by the kernel, the nfs file system expects a binary argument of type struct nfs_mount_data. The program mount itself parses the following options of the form 'tag=value', and puts them in the structure mentioned: rsize=n, wsize=n, timeo=n, retrans=n, acregmin=n, acregmax=n, acdirmin=n, acdirmax=n, actimeo=n, retry=n, port=n, mountport=n, mounthost=name, mountprog=n, mountvers=n, nfsprog=n, nfsvers=n, namlen=n. The option addr=n is accepted but ignored. Also the following Boolean options, possibly preceded by no are recognized: bg, fg, soft, hard, intr, posix, cto, ac, tcp, udp, lock. For details, see nfs(5).

montylee 08-07-2008 01:48 AM

Thanks for the reply Mr. C.
I tried to declare struct nfs_mount_data in my program, but it gives the following error:

Quote:

error: storage size of ‘nfs_mount_data’ isn’t known
So, i guess my program is not able to get the struct declaration of nfs_mount_data.
The nfs_mount_data struct is defined in /usr/include/linux/nfs_mount.h. When i include this header in my code, i get the following error:

Quote:

In file included from /usr/include/linux/nfs_mount.h:11,
from mount_test.c:7:
/usr/include/linux/in.h:182: error: expected specifier-qualifier-list before ‘sa_family_t’
This error comes as nfs_mount.h includes linux/in.h and that file is giving an error.

Any ideas?

Mr. C. 08-07-2008 01:52 AM

sa_family_t is a typedef (it is a socket address family type). That is defined in <sys/socket.h>, which you need to include before nfs_mount.h.

montylee 08-07-2008 01:56 AM

ok, i pasted the nfs_mount_data struct inside my file itself. But i am still getting invalid argument error. Here's my code:

Quote:

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

#include <errno.h>
#include <linux/nfs.h>

#include <sys/mount.h>
//#include <linux/nfs_mount.h>
#include <netdb.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>
#include <linux/nfs.h>
#include <linux/nfs2.h>
#include <linux/nfs3.h>

#define NFS_MOUNT_VERSION 6
#define NFS_MAX_CONTEXT_LEN 256

struct nfs_mount_data {
int version; /* 1 */
int fd; /* 1 */
struct nfs2_fh old_root; /* 1 */
int flags; /* 1 */
int rsize; /* 1 */
int wsize; /* 1 */
int timeo; /* 1 */
int retrans; /* 1 */
int acregmin; /* 1 */
int acregmax; /* 1 */
int acdirmin; /* 1 */
int acdirmax; /* 1 */
struct sockaddr_in addr; /* 1 */
char hostname[NFS_MAXNAMLEN + 1]; /* 1 */
int namlen; /* 2 */
unsigned int bsize; /* 3 */
struct nfs3_fh root; /* 4 */
int pseudoflavor; /* 5 */
char context[NFS_MAX_CONTEXT_LEN + 1]; /* 6 */
};

int main ()
{
int retval;
struct nfs_mount_data data;

//memset(&data, 0, sizeof(data));
//data.retrans = 3;
// data.flags = NFS_MOUNT_SOFT;



retval = mount ((const char *) "127.0.0.1:/home/test", (const char *) "/tmp/test", "nfs", MS_RDONLY, &data);

if (retval != 0) {
printf(" Mount system call failed and return value is %d\n", errno);
perror("mount");
} else {
printf(" Mount system call successfull \n");
}

return 0;
}
Now, do i need to fill everything in the nfs_mount_data structure? This link might be of some help:

http://www.koders.com/c/fid838F9F103...D0F99DF4D.aspx

Mr. C. 08-07-2008 01:58 AM

Sure, the data has to be valid! Otherwise it is filled with garbage, and the kernel tries to interpret. It doesn't know what you want in there.

montylee 08-07-2008 03:56 AM

I included the <sys/socket.h>, it fixed the sa_family_t error.

Now, even if the data in nfs_mount_data is not valid, why am i getting the same error i.e. "invalid argument".

I'll try filling some data in the nfs_mount_data structure.

bigoperm 07-23-2009 12:36 PM

I'm running across this same problem: the normal mount command works (/bin/mount), but the C system call doesn't. Did this issue ever get resolved?


All times are GMT -5. The time now is 04:45 PM.