enhance exportfs to use new cache/upcall stuff nfs-utils-1-1-0-pre3
authorneilbrown <neilbrown>
Wed, 21 May 2003 06:44:50 +0000 (06:44 +0000)
committerneilbrown <neilbrown>
Wed, 21 May 2003 06:44:50 +0000 (06:44 +0000)
ChangeLog
support/export/xtab.c
support/include/nfslib.h
support/nfs/cacheio.c
utils/exportfs/exportfs.c

index 654469b..b7da691 100644 (file)
--- 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.
index 3ef3661..d9265a2 100644 (file)
@@ -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;
+}
index 5112b91..5864305 100644 (file)
@@ -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. */
index 2af4fa3..77facb1 100644 (file)
@@ -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);
+               }
+       }
+}
index 05ace88..936dff5 100644 (file)
@@ -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;
        }