1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/*
* support/nfs/export.c
*
* Add or delete an NFS export in knfsd.
*
* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string.h>
#include <sys/types.h>
#include <asm/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "nfslib.h"
#include "misc.h"
#include "xcommon.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)
{
char buf[RPC_CHAN_BUF_SIZE], *bp;
struct stat stb;
__u32 fsid;
char fsidstr[8];
__u16 dev;
__u32 inode;
int err = 0, f, blen;
f = open("/proc/net/rpc/nfsd.export/channel", O_WRONLY);
if (f < 0) return -1;
bp = buf; blen = sizeof(buf);
qword_add(&bp, &blen, exp->ex_client);
qword_add(&bp, &blen, exp->ex_path);
if (export) {
qword_addint(&bp, &blen, 0x7fffffff);
qword_addint(&bp, &blen, exp->ex_flags);
qword_addint(&bp, &blen, exp->ex_anon_uid);
qword_addint(&bp, &blen, exp->ex_anon_gid);
qword_addint(&bp, &blen, exp->ex_dev);
} else
qword_addint(&bp, &blen, 1);
qword_addeol(&bp, &blen);
if (blen <= 0 || write(f, buf, bp - buf) != bp - buf)
err = -1;
close(f);
if (stat(exp->ex_path, &stb) != 0)
return -1;
f = open("/proc/net/rpc/nfsd.fh/channel", O_WRONLY);
if (f < 0) return -1;
if (exp->ex_flags & NFSEXP_FSID) {
bp = buf; blen = sizeof(buf);
qword_add(&bp, &blen, exp->ex_client);
qword_addint(&bp, &blen, 1);
fsid = exp->ex_dev;
qword_addhex(&bp, &blen, (char*)&fsid, 4);
if (export) {
qword_addint(&bp, &blen, 0x7fffffff);
qword_add(&bp, &blen, exp->ex_path);
} else
qword_addint(&bp, &blen, 1);
qword_addeol(&bp, &blen);
if (blen <= 0 || write(f, buf, bp - buf) != bp - buf)
err = -1;
}
bp = buf; blen = sizeof(buf);
qword_add(&bp, &blen, exp->ex_client);
qword_addint(&bp, &blen, 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_addhex(&bp, &blen, fsidstr, 8);
if (export) {
qword_addint(&bp, &blen, 0x7fffffff);
qword_add(&bp, &blen, exp->ex_path);
} else
qword_addint(&bp, &blen, 1);
qword_addeol(&bp, &blen);
if (blen <= 0 || write(f, buf, bp - buf) != bp - buf)
err = -1;
close(f);
return err;
}
int
nfsexport(struct nfsctl_export *exp)
{
struct nfsctl_arg arg;
int fd;
if ((fd=open("/proc/net/rpc/nfsd.fh/channel", O_WRONLY))>= 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);
}
int
nfsunexport(struct nfsctl_export *exp)
{
struct nfsctl_arg arg;
int fd;
if ((fd=open("/proc/net/rpc/nfsd.fh/channel", O_WRONLY))>= 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);
}
|