X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=support%2Fnfs%2Fnfsexport.c;h=97de651ab080a1490cc2784ab0bd0874ee401a69;hp=ce8b867295671462b0557b26ea7c794ea0c22a5b;hb=77c32fa565d6af59cbeb8601e08efa9af6ef3d81;hpb=8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9 diff --git a/support/nfs/nfsexport.c b/support/nfs/nfsexport.c index ce8b867..97de651 100644 --- a/support/nfs/nfsexport.c +++ b/support/nfs/nfsexport.c @@ -9,13 +9,87 @@ #include "config.h" #include +#include +#include +#include +#include +#include + #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);