-1

I want to know the free space and total space on a nfs share.
I am using ubuntu linux computers for this.
I can do that through commands but I need a C program for this.
I looked into libnfs.h, it contains some functions declarations that I think can be used :

EXTERN int nfs_stat(struct nfs_context *nfs, const char *path, struct stat *st);
EXTERN int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, struct stat *st);
EXTERN int nfs_statvfs(struct nfs_context *nfs, const char *path, struct statvfs *svfs);

But I don't know which one should be used and what to pass for the first parameter(what is context?)

Please help.
Thanks for help in advance.


As @remyabel suggested, I wrote following:
#include<sys/time.h>
#include<stdio.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/statvfs.h>
#include<nfsc/libnfs.h>
#define MAX 63
int main()
{
  struct nfs_context *nfs = NULL;
  struct statvfs st;
  char path[MAX];
  strcpy(path,"nfs://192.168.2.73/home/sumit/music2/");

  nfs = nfs_init_context();

  int ret;
  ret = nfs_mount(nfs, "192.168.2.73", path);
  perror("Err1");
  ret = nfs_statvfs(nfs, "//", &st);

  printf("\nret=%d",ret);
  printf("\nf_bsize= %lu",st.f_bsize);
  printf("\nf_frsize= %lu",st.f_frsize);
  printf("\nf_blocks= %lu",st.f_blocks);
  printf("\nf_bfree= %lu\n",st.f_bfree);

  return 0;
}

Now it works :)

Sumit
  • 1,485
  • 11
  • 24
  • If you are looking for a C answer, don't tag for C++. – crashmstr Nov 21 '13 at 20:06
  • The third parameter `statvfs` has the information you want. The return value is whether or not it was successful. –  Nov 21 '13 at 20:11
  • Be aware that nfs_statvfs() et. al. is part of the [libnfs](https://github.com/sahlberg/libnfs) package. The libnfs package may not be available or installed on all platforms. An ordinary statvfs() call will get the information you want without adding a dependency. – Brad Lanam Nov 21 '13 at 20:30
  • 1
    @BradLanam , statvfs() does not work for nfs share until we mount the share, for mounting libnfs is required – Sumit Nov 22 '13 at 06:42
  • A `#include ` should fix that compile error. That would be a bug in the libnfs headers. – Brad Lanam Nov 22 '13 at 16:12
  • @Brad Lanam, I included but still the same error – Sumit Nov 22 '13 at 17:54
  • Works for me. That is, it fixes the time errors. Your , and should be listed before the other more specialized includes. `bll-desktop:bll$ cc -I$HOME/local/libnfs-1.8.0/include -c z.c z.c: In function ‘main’: z.c:16:17: error: storage size of ‘client1’ isn’t known` From the examples included with libnfs, it appears they declared struct client themselves. It's not in the include files. You actually don't need that. Just pass in your host and the remote path to nfs_mount(). Just `nfs_mount (nfs, "192.168.2.50", "/remotes/mynfs");`. – Brad Lanam Nov 22 '13 at 18:15
  • @BradLanam I edited the code and output above, what is meant by Operation now in progress. I am using nfs_mount instead of nfs_mount_async so it should be blocking. Also rest of the output is not correct. What wrong I am doing here. – Sumit Dec 11 '13 at 09:28

2 Answers2

2

There's a lot more to it, waiting for responses and so on. I had exactly the same problem a few months ago when i wanted to write a nagios plugin to check the space on a filesystem that isn't already mounted. The source code is available at http://www.gbl-software.de/nagiosbinaries/check_nfs/check_nfs-src.tgz, feel free to use and modify as you wish. This uses the NFS libraries from nfsreplay and has the advantage that it's ready to compile for Linux, Solaris and AIX.

Note that, for most NFS servers, your program needs to be suid root to be able to use a reserved port (<1024), because NFS servers won't talk to any port for security reasons.

Guntram Blohm
  • 9,667
  • 2
  • 24
  • 31
1

First you declare the context at the beginning of your program:

struct nfs_context *nfs = NULL;

Here we'll hold the information you want:

struct statvfs st;

Then we initialize the context:

nfs = nfs_init_context();

Mount the share:

struct client client;
client.server = server;
client.export = path;
client.is_finished = 0;
ret = nfs_mount(nfs, client.server, client.export);

And you can use nfs_statvfs like so;

ret = nfs_statvfs(nfs, path, &st);

Where nfs is the context from earlier, path is some filename or directory, and st is the struct that will hold the information. ret contains errno if there was a problem.

Here's statvfs:

struct statvfs {

uint32_t    f_bsize;

uint32_t    f_frsize;

uint64_t    f_blocks;

uint64_t    f_bfree;