]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - support/nfs/nfsexport.c
Define and use get_reliable_hostbyname
[nfs-utils.git] / support / nfs / nfsexport.c
index ce8b867295671462b0557b26ea7c794ea0c22a5b..97de651ab080a1490cc2784ab0bd0874ee401a69 100644 (file)
@@ -9,13 +9,87 @@
 #include "config.h"
 
 #include <string.h>
+#include <sys/types.h>
+#include <asm/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
 #include "nfslib.h"
 
+       /* if /proc/net/rpc/... exists, then 
+        * write to it, as that interface is more stable.
+        * Write:
+        *  client fsidtype fsid path
+        * to /proc/net/rpc/nfsd.fh/channel
+        * and
+        *  client path expiry flags anonuid anongid fsid
+        * to /proc/net/rpc/nfsd.export/channel
+        */
+
+static int
+exp_unexp(struct nfsctl_export *exp, int export)
+{
+       FILE *f;
+       struct stat stb;
+       __u32 fsid;
+       char fsidstr[8];
+       __u16 dev;
+       __u32 inode;
+
+
+       f = fopen("/proc/net/rpc/nfsd.export/channel", "w");
+       if (f == NULL) return -1;
+       qword_print(f, exp->ex_client);
+       qword_print(f, exp->ex_path);
+       qword_printint(f, 0x7fffffff);
+       if (export) {
+               qword_printint(f, exp->ex_flags);
+               qword_printint(f, exp->ex_anon_uid);
+               qword_printint(f, exp->ex_anon_gid);
+               qword_printint(f, exp->ex_dev);
+       }
+       qword_eol(f);
+       fclose(f);
+
+       if (stat(exp->ex_path, &stb) != 0)
+               return -1;
+       f = fopen("/proc/net/rpc/nfsd.fh/channel", "w");
+       if (f==NULL) return -1;
+       if (exp->ex_flags & NFSEXP_FSID) {
+               qword_print(f,exp->ex_client);
+               qword_printint(f,1);
+               fsid = exp->ex_dev;
+               qword_printhex(f, (char*)&fsid, 4);
+               qword_printint(f, 0x7fffffff);
+               if (export)
+                       qword_print(f, exp->ex_path);
+               qword_eol(f);
+       }
+       qword_print(f,exp->ex_client);
+       qword_printint(f,0);
+       dev = htons(major(stb.st_dev)); memcpy(fsidstr, &dev, 2);
+       dev = htons(minor(stb.st_dev)); memcpy(fsidstr+2, &dev, 2);
+       inode = stb.st_ino; memcpy(fsidstr+4, &inode, 4);
+       
+       qword_printhex(f, fsidstr, 8);
+       qword_printint(f, 0x7fffffff);
+       if (export)
+               qword_print(f, exp->ex_path);
+       qword_eol(f);
+       fclose(f);
+       return 0;
+}
+
 int
 nfsexport(struct nfsctl_export *exp)
 {
        struct nfsctl_arg       arg;
-
+       int fd;
+       if ((fd=open("/proc/net/rpc/nfsd.fh/channel", O_RDWR))>= 0) {
+               close(fd);
+               return exp_unexp(exp, 1);
+       }
        arg.ca_version = NFSCTL_VERSION;
        memcpy(&arg.ca_export, exp, sizeof(arg.ca_export));
        return nfsctl(NFSCTL_EXPORT, &arg, NULL);
@@ -26,6 +100,12 @@ nfsunexport(struct nfsctl_export *exp)
 {
        struct nfsctl_arg       arg;
 
+       int fd;
+       if ((fd=open("/proc/net/rpc/nfsd.fh/channel", O_RDWR))>= 0) {
+               close(fd);
+               return exp_unexp(exp, 0);
+       }
+
        arg.ca_version = NFSCTL_VERSION;
        memcpy(&arg.ca_export, exp, sizeof(arg.ca_export));
        return nfsctl(NFSCTL_UNEXPORT, &arg, NULL);