diff options
Diffstat (limited to 'support')
-rw-r--r-- | support/export/xtab.c | 47 | ||||
-rw-r--r-- | support/include/nfslib.h | 1 | ||||
-rw-r--r-- | support/nfs/cacheio.c | 36 |
3 files changed, 83 insertions, 1 deletions
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); + } + } +} |