From: neilbrown Date: Wed, 21 May 2003 06:44:50 +0000 (+0000) Subject: enhance exportfs to use new cache/upcall stuff X-Git-Tag: nfs-utils-1-1-0-pre3^0 X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=commitdiff_plain;h=2d33968c66860ad772aac918992986fe4865b3a4 enhance exportfs to use new cache/upcall stuff --- diff --git a/ChangeLog b/ChangeLog index 654469b..b7da691 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2003-05-21 NeilBrown + + * 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 * support/export/client.c: Add client_compose, client_member to 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; }