summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--support/export/xtab.c47
-rw-r--r--support/include/nfslib.h1
-rw-r--r--support/nfs/cacheio.c36
-rw-r--r--utils/exportfs/exportfs.c27
5 files changed, 118 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 654469b..b7da691 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
2003-05-21 NeilBrown <neilb@cse.unsw.edu.au>
+ * utils/exportfs/exportfs.c: Use check_new_cache and cache_flush
+ Don't actually talk to kernel when new cache is in effect, except
+ to flush
+ * utils/exportfs/exportfs.c: add -f option to fully flush cache.
+ * support/export/xtab.c: Only rename new xtab into place if it has
+ changed, thus preserving modify date for exportfs to use when
+ flushing.
+ * support/nfs/cacheio.c: Add cache_flush
+ * support/export/xtab.c: Only rename new xtab into place if it has
+ changed, thus preserving modify date for exportfs to use when
+ flushing.
+
+2003-05-21 NeilBrown <neilb@cse.unsw.edu.au>
+
* support/export/client.c: Add client_compose, client_member to
handle new composite client names
* support/include/exportfs.h: Declare above functions.
diff --git a/support/export/xtab.c b/support/export/xtab.c
index 3ef3661..d9265a2 100644
--- a/support/export/xtab.c
+++ b/support/export/xtab.c
@@ -18,6 +18,8 @@
#include "xio.h"
#include "xlog.h"
+static void cond_rename(char *newfile, char *oldfile);
+
static int
xtab_read(char *xtab, int is_export)
{
@@ -104,7 +106,7 @@ xtab_write(char *xtab, char *xtabtmp, int is_export)
}
endexportent();
- rename(xtabtmp, xtab);
+ cond_rename(xtabtmp, xtab);
xfunlock(lockid);
@@ -142,3 +144,46 @@ xtab_append(nfs_export *exp)
exp->m_xtabent = 1;
}
+/*
+ * rename newfile onto oldfile unless
+ * they are identical
+ */
+static void cond_rename(char *newfile, char *oldfile)
+{
+ int nfd, ofd;
+ char nbuf[4096], obuf[4096];
+ int ncnt, ocnt;
+
+ nfd = open(newfile, 0);
+ if (nfd < 0)
+ return;
+ ofd = open(oldfile, 0);
+ if (ofd < 0) {
+ close(nfd);
+ rename(newfile, oldfile);
+ return;
+ }
+
+ do {
+ ncnt = read(nfd, nbuf, sizeof(nbuf));
+ if (ncnt < 0)
+ break;
+ ocnt = read(ofd, obuf, sizeof(obuf));
+ if (ocnt < 0)
+ break;
+ if (ncnt != ocnt)
+ break;
+ if (ncnt == 0) {
+ close(nfd);
+ close(ofd);
+ unlink(newfile);
+ return;
+ }
+ } while (memcmp(obuf, nbuf, ncnt) == 0);
+
+ /* some mis-match */
+ close(nfd);
+ close(ofd);
+ rename(newfile, oldfile);
+ return;
+}
diff --git a/support/include/nfslib.h b/support/include/nfslib.h
index 5112b91..5864305 100644
--- a/support/include/nfslib.h
+++ b/support/include/nfslib.h
@@ -129,6 +129,7 @@ void qword_eol(FILE *f);
int readline(int fd, char **buf, int *lenp);
int qword_get(char **bpp, char *dest, int bufsize);
int qword_get_int(char **bpp, int *anint);
+void cache_flush(int force);
int check_new_cache(void);
/* lockd. */
diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c
index 2af4fa3..77facb1 100644
--- a/support/nfs/cacheio.c
+++ b/support/nfs/cacheio.c
@@ -230,3 +230,39 @@ check_new_cache(void)
return (stat("/proc/fs/nfs/filehandle", &stb) == 0);
}
+
+/* flush the kNFSd caches.
+ * Set the flush time to the mtime of _PATH_ETAB or
+ * if force, to now.
+ * the caches to flush are:
+ * auth.unix.ip nfsd.export nfsd.fh
+ */
+
+void
+cache_flush(int force)
+{
+ struct stat stb;
+ int c;
+ char stime[20];
+ char path[200];
+ static char *cachelist[] = {
+ "auth.unix.ip",
+ "nfsd.export",
+ "nfsd.fh",
+ NULL
+ };
+ stb.st_mtime = time(0);
+ if (!force)
+ stat(_PATH_ETAB, &stb);
+
+ sprintf(stime, "%ld\n", stb.st_mtime);
+ for (c=0; cachelist[c]; c++) {
+ int fd;
+ sprintf(path, "/proc/net/rpc/%s/flush", cachelist[c]);
+ fd = open(path, O_RDWR);
+ if (fd) {
+ write(fd, stime, strlen(stime));
+ close(fd);
+ }
+ }
+}
diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
index 05ace88..936dff5 100644
--- a/utils/exportfs/exportfs.c
+++ b/utils/exportfs/exportfs.c
@@ -42,12 +42,14 @@ main(int argc, char **argv)
int f_reexport = 0;
int f_ignore = 0;
int i, c;
+ int new_cache = 0;
+ int force_flush = 0;
xlog_open("exportfs");
export_errno = 0;
- while ((c = getopt(argc, argv, "aio:ruv")) != EOF) {
+ while ((c = getopt(argc, argv, "aio:ruvf")) != EOF) {
switch(c) {
case 'a':
f_all = 1;
@@ -68,6 +70,9 @@ main(int argc, char **argv)
case 'v':
f_verbose = 1;
break;
+ case 'f':
+ force_flush = 1;
+ break;
default:
usage();
break;
@@ -92,6 +97,8 @@ main(int argc, char **argv)
return 0;
}
+ new_cache = check_new_cache();
+
if (f_export && ! f_ignore)
export_read(_PATH_EXPORTS);
if (f_export) {
@@ -116,10 +123,15 @@ main(int argc, char **argv)
unexportfs(argv[i], f_verbose);
rmtab_read();
}
- xtab_mount_read();
- exports_update(f_verbose);
+ if (!new_cache) {
+ xtab_mount_read();
+ exports_update(f_verbose);
+ }
xtab_export_write();
- xtab_mount_write();
+ if (new_cache)
+ cache_flush(force_flush);
+ if (!new_cache)
+ xtab_mount_write();
return export_errno;
}
@@ -267,19 +279,22 @@ unexportfs(char *arg, int verbose)
hname)))
continue;
if (verbose) {
+#if 0
if (exp->m_exported) {
printf("unexporting %s:%s from kernel\n",
exp->m_client->m_hostname,
exp->m_export.e_path);
}
- else {
+ else
+#endif
printf("unexporting %s:%s\n",
exp->m_client->m_hostname,
exp->m_export.e_path);
- }
}
+#if 0
if (exp->m_exported && !export_unexport(exp))
error(exp, errno);
+#endif
exp->m_xtabent = 0;
exp->m_mayexport = 0;
}