Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package nfs-utils for openSUSE:Factory checked in at 2021-06-01 10:32:54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/nfs-utils (Old) and /work/SRC/openSUSE:Factory/.nfs-utils.new.1898 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "nfs-utils" Tue Jun 1 10:32:54 2021 rev:163 rq:895272 version:unknown Changes: -------- --- /work/SRC/openSUSE:Factory/nfs-utils/nfs-utils.changes 2021-05-12 19:31:53.967117355 +0200 +++ /work/SRC/openSUSE:Factory/.nfs-utils.new.1898/nfs-utils.changes 2021-06-01 10:32:57.236352565 +0200 @@ -1,0 +2,33 @@ +Mon May 24 14:34:19 UTC 2021 - Petr Vorel <pvo...@suse.cz> + +- Update to version 2.5.4-rc4 to get all recent fixes: + - nfs-utils-2-5-4-rc4.patch + e4ce810a Move declaration of etab and rmtab into libraries + 7a4e2d1d Remove 'force' arg from cache_flush() + c5528f40 Fix NFSv4 export of tmpfs filesystems + ed83085f gssd: use mutex to protect decrement of refcount + - nfs-utils-2-5-4-rc3.patch + 972dba0f nfs-utils: Enable the retrieval of raw config settings without expansion + 964f4861 nfs-utils: Factor out common structure cleanup calls + 8219bdb0 Replace all /var/run with /run + 81727afe Fix `statx()` emulation breaking exports + a41afe9e mountd/exports: Fix typo in the man page + - nfs-utils-2-5-4-rc2.patch + 2f669b6f NFS server should enable RDMA by default + d77ece22 mountd/exportd: only log confirmed clients, and poll for updates + ac266e2e exportfs: fix unexporting of '/' + - nfs-utils-2-5-4-rc1.patch + 7abd15e3 nfsdclnts: Ignore SIGPIPE signal + edeb3815 mountd: add logging of NFSv4 clients attaching and detaching. + f8e2c8d4 mountd: make default ttl settable by option + cc150093 mountd: add --cache-use-ipaddr option to force use_ipaddr + c7a954ae mountd: add logging for authentication results for accesses. + 1a8156f8 mountd/exports: update man page + fec7347e mountd: Don't proactively add export info when fh info is requested. + a72c151f mountd: reject unknown client IP when !use_ipaddr. + 05bacfed gssd: Add options to rpc.gssd to allow for the use of $HOME/.k5identity files + 7e559dbd exportd: server-side gid management + +- 0001-Replace-all-var-run-with-run.patch is now part of nfs-utils-2-5-4-rc3.patch + +------------------------------------------------------------------- Old: ---- 0001-Replace-all-var-run-with-run.patch New: ---- nfs-utils-2-5-4-rc1.patch nfs-utils-2-5-4-rc2.patch nfs-utils-2-5-4-rc3.patch nfs-utils-2-5-4-rc4.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ nfs-utils.spec ++++++ --- /var/tmp/diff_new_pack.K21Vw6/_old 2021-06-01 10:32:57.876353654 +0200 +++ /var/tmp/diff_new_pack.K21Vw6/_new 2021-06-01 10:32:57.880353661 +0200 @@ -42,7 +42,10 @@ Source26: nfs.conf Source27: nfs-kernel-server.tmpfiles.conf Patch0: nfs-utils-1.0.7-bind-syntax.patch -Patch1: 0001-Replace-all-var-run-with-run.patch +Patch1: nfs-utils-2-5-4-rc1.patch +Patch2: nfs-utils-2-5-4-rc2.patch +Patch3: nfs-utils-2-5-4-rc3.patch +Patch4: nfs-utils-2-5-4-rc4.patch BuildRequires: e2fsprogs-devel BuildRequires: fedfs-utils-devel ++++++ nfs-utils-2-5-4-rc1.patch ++++++ ++++ 1256 lines (skipped) ++++++ nfs-utils-2-5-4-rc2.patch ++++++ Commits: 2f669b6f NFS server should enable RDMA by default d77ece22 mountd/exportd: only log confirmed clients, and poll for updates ac266e2e exportfs: fix unexporting of '/' diff --git a/nfs.conf b/nfs.conf index 9042d27d..31994f61 100644 --- a/nfs.conf +++ b/nfs.conf @@ -72,9 +72,9 @@ # vers4.0=y # vers4.1=y # vers4.2=y -# rdma=n -# rdma-port=20049 -# +rdma=y +rdma-port=20049 + [statd] # debug=0 # port=0 diff --git a/support/export/v4clients.c b/support/export/v4clients.c index 056ddc9b..dd985463 100644 --- a/support/export/v4clients.c +++ b/support/export/v4clients.c @@ -48,12 +48,15 @@ void v4clients_set_fds(fd_set *fdset) } static void *tree_root; +static int have_unconfirmed; struct ent { unsigned long num; char *clientid; char *addr; int vers; + int unconfirmed; + int wid; }; static int ent_cmp(const void *av, const void *bv) @@ -89,15 +92,14 @@ static char *dup_line(char *line) return ret; } -static void add_id(int id) +static void read_info(struct ent *key) { char buf[2048]; - struct ent **ent; - struct ent *key; char *path; + int was_unconfirmed = key->unconfirmed; FILE *f; - if (asprintf(&path, "/proc/fs/nfsd/clients/%d/info", id) < 0) + if (asprintf(&path, "/proc/fs/nfsd/clients/%lu/info", key->num) < 0) return; f = fopen(path, "r"); @@ -105,35 +107,64 @@ static void add_id(int id) free(path); return; } - key = calloc(1, sizeof(*key)); - if (!key) { - fclose(f); - free(path); - return; - } - key->num = id; + if (key->wid < 0) + key->wid = inotify_add_watch(clients_fd, path, IN_MODIFY); + while (fgets(buf, sizeof(buf), f)) { - if (strncmp(buf, "clientid: ", 10) == 0) + if (strncmp(buf, "clientid: ", 10) == 0) { + free(key->clientid); key->clientid = dup_line(buf+10); - if (strncmp(buf, "address: ", 9) == 0) + } + if (strncmp(buf, "address: ", 9) == 0) { + free(key->addr); key->addr = dup_line(buf+9); + } if (strncmp(buf, "minor version: ", 15) == 0) key->vers = atoi(buf+15); + if (strncmp(buf, "status: ", 8) == 0 && + strstr(buf, " unconfirmed") != NULL) { + key->unconfirmed = 1; + have_unconfirmed = 1; + } + if (strncmp(buf, "status: ", 8) == 0 && + strstr(buf, " confirmed") != NULL) + key->unconfirmed = 0; } fclose(f); free(path); - xlog(L_NOTICE, "v4.%d client attached: %s from %s", - key->vers, key->clientid, key->addr); + if (was_unconfirmed && !key->unconfirmed) + xlog(L_NOTICE, "v4.%d client attached: %s from %s", + key->vers, key->clientid ?: "-none-", + key->addr ?: "-none-"); + if (!key->unconfirmed && key->wid >= 0) { + inotify_rm_watch(clients_fd, key->wid); + key->wid = -1; + } +} + +static void add_id(int id) +{ + struct ent **ent; + struct ent *key; + + key = calloc(1, sizeof(*key)); + if (!key) { + return; + } + key->num = id; + key->wid = -1; ent = tsearch(key, &tree_root, ent_cmp); if (!ent || *ent != key) /* Already existed, or insertion failed */ free_ent(key); + else + read_info(key); } -static void del_id(int id) +static void del_id(unsigned long id) { struct ent key = {.num = id}; struct ent **e, *ent; @@ -143,11 +174,27 @@ static void del_id(int id) return; ent = *e; tdelete(ent, &tree_root, ent_cmp); - xlog(L_NOTICE, "v4.%d client detached: %s from %s", - ent->vers, ent->clientid, ent->addr); + if (!ent->unconfirmed) + xlog(L_NOTICE, "v4.%d client detached: %s from %s", + ent->vers, ent->clientid, ent->addr); + if (ent->wid >= 0) + inotify_rm_watch(clients_fd, ent->wid); free_ent(ent); } +static void check_id(unsigned long id) +{ + struct ent key = {.num = id}; + struct ent **e, *ent; + + e = tfind(&key, &tree_root, ent_cmp); + if (!e || !*e) + return; + ent = *e; + if (ent->unconfirmed) + read_info(ent); +} + int v4clients_process(fd_set *fdset) { char buf[4096] __attribute__((aligned(__alignof__(struct inotify_event)))); @@ -172,8 +219,9 @@ int v4clients_process(fd_set *fdset) add_id(id); if (ev->mask & IN_DELETE) del_id(id); + if (ev->mask & IN_MODIFY) + check_id(id); } } return 1; } - diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c index 262dd19a..25d757d8 100644 --- a/utils/exportfs/exportfs.c +++ b/utils/exportfs/exportfs.c @@ -383,7 +383,7 @@ unexportfs_parsed(char *hname, char *path, int verbose) * so need to deal with it. */ size_t nlen = strlen(path); - while (path[nlen - 1] == '/') + while ((nlen > 1) && (path[nlen - 1] == '/')) nlen--; for (exp = exportlist[htype].p_head; exp; exp = exp->m_next) { ++++++ nfs-utils-2-5-4-rc3.patch ++++++ Commits: 972dba0f nfs-utils: Enable the retrieval of raw config settings without expansion 964f4861 nfs-utils: Factor out common structure cleanup calls 8219bdb0 Replace all /var/run with /run 81727afe Fix `statx()` emulation breaking exports a41afe9e mountd/exports: Fix typo in the man page diff --git a/support/include/conffile.h b/support/include/conffile.h index 7d974fe9..c4a3ca62 100644 --- a/support/include/conffile.h +++ b/support/include/conffile.h @@ -61,6 +61,7 @@ extern _Bool conf_get_bool(const char *, const char *, _Bool); extern char *conf_get_str(const char *, const char *); extern char *conf_get_str_with_def(const char *, const char *, char *); extern char *conf_get_section(const char *, const char *, const char *); +extern char *conf_get_entry(const char *, const char *, const char *); extern int conf_init_file(const char *); extern void conf_cleanup(void); extern int conf_match_num(const char *, const char *, int); diff --git a/support/misc/xstat.c b/support/misc/xstat.c index a438fbcc..6f751f7f 100644 --- a/support/misc/xstat.c +++ b/support/misc/xstat.c @@ -85,6 +85,7 @@ int xlstat(const char *pathname, struct stat *statbuf) return 0; else if (errno != ENOSYS) return -1; + errno = 0; return fstatat(AT_FDCWD, pathname, statbuf, AT_NO_AUTOMOUNT | AT_SYMLINK_NOFOLLOW); } @@ -95,6 +96,7 @@ int xstat(const char *pathname, struct stat *statbuf) return 0; else if (errno != ENOSYS) return -1; + errno = 0; return fstatat(AT_FDCWD, pathname, statbuf, AT_NO_AUTOMOUNT); } diff --git a/support/nfs/conffile.c b/support/nfs/conffile.c index a4ea0676..fd4a17ad 100644 --- a/support/nfs/conffile.c +++ b/support/nfs/conffile.c @@ -132,6 +132,39 @@ conf_hash(const char *s) return hash; } +/* + * free all the component parts of a conf_binding struct + */ +static void free_confbind(struct conf_binding *cb) +{ + if (!cb) + return; + if (cb->section) + free(cb->section); + if (cb->arg) + free(cb->arg); + if (cb->tag) + free(cb->tag); + if (cb->value) + free(cb->value); + free(cb); +} + +static void free_conftrans(struct conf_trans *ct) +{ + if (!ct) + return; + if (ct->section) + free(ct->section); + if (ct->arg) + free(ct->arg); + if (ct->tag) + free(ct->tag); + if (ct->value) + free(ct->value); + free(ct); +} + /* * Insert a tag-value combination from LINE (the equal sign is at POS) */ @@ -147,11 +180,7 @@ conf_remove_now(const char *section, const char *tag) && strcasecmp(cb->tag, tag) == 0) { LIST_REMOVE(cb, link); xlog(LOG_INFO,"[%s]:%s->%s removed", section, tag, cb->value); - free(cb->section); - free(cb->arg); - free(cb->tag); - free(cb->value); - free(cb); + free_confbind(cb); return 0; } } @@ -171,11 +200,7 @@ conf_remove_section_now(const char *section) unseen = 0; LIST_REMOVE(cb, link); xlog(LOG_INFO, "[%s]:%s->%s removed", section, cb->tag, cb->value); - free(cb->section); - free(cb->arg); - free(cb->tag); - free(cb->value); - free(cb); + free_confbind(cb); } } return unseen; @@ -571,11 +596,7 @@ static void conf_free_bindings(void) for (; cb; cb = next) { next = LIST_NEXT(cb, link); LIST_REMOVE(cb, link); - free(cb->section); - free(cb->arg); - free(cb->tag); - free(cb->value); - free(cb); + free_confbind(cb); } LIST_INIT(&conf_bindings[i]); } @@ -774,11 +795,7 @@ conf_cleanup(void) for (node = TAILQ_FIRST(&conf_trans_queue); node; node = next) { next = TAILQ_NEXT(node, link); TAILQ_REMOVE (&conf_trans_queue, node, link); - if (node->section) free(node->section); - if (node->arg) free(node->arg); - if (node->tag) free(node->tag); - if (node->value) free(node->value); - free (node); + free_conftrans(node); } TAILQ_INIT(&conf_trans_queue); } @@ -874,6 +891,29 @@ conf_get_str_with_def(const char *section, const char *tag, char *def) return result; } +/* + * Retrieve an entry without interpreting its contents + */ +char * +conf_get_entry(const char *section, const char *arg, const char *tag) +{ + struct conf_binding *cb; + + cb = LIST_FIRST (&conf_bindings[conf_hash (section)]); + for (; cb; cb = LIST_NEXT (cb, link)) { + if (strcasecmp(section, cb->section) != 0) + continue; + if (arg && (cb->arg == NULL || strcasecmp(arg, cb->arg) != 0)) + continue; + if (!arg && cb->arg) + continue; + if (strcasecmp(tag, cb->tag) != 0) + continue; + return cb->value; + } + return 0; +} + /* * Find a section that may or may not have an argument */ @@ -1144,14 +1184,7 @@ conf_set(int transaction, const char *section, const char *arg, return 0; fail: - if (node->tag) - free(node->tag); - if (node->arg) - free(node->arg); - if (node->section) - free(node->section); - if (node) - free(node); + free_conftrans(node); return 1; } @@ -1177,10 +1210,7 @@ conf_remove(int transaction, const char *section, const char *tag) return 0; fail: - if (node && node->section) - free (node->section); - if (node) - free (node); + free_conftrans(node); return 1; } @@ -1201,8 +1231,7 @@ conf_remove_section(int transaction, const char *section) return 0; fail: - if (node) - free(node); + free_conftrans(node); return 1; } @@ -1233,15 +1262,7 @@ conf_end(int transaction, int commit) } } TAILQ_REMOVE (&conf_trans_queue, node, link); - if (node->section) - free(node->section); - if (node->arg) - free(node->arg); - if (node->tag) - free(node->tag); - if (node->value) - free(node->value); - free (node); + free_conftrans(node); } } return 0; diff --git a/support/nfs/getport.c b/support/nfs/getport.c index e458d8fe..813f7bf9 100644 --- a/support/nfs/getport.c +++ b/support/nfs/getport.c @@ -904,7 +904,7 @@ int nfs_getport_ping(struct sockaddr *sap, const socklen_t salen, * listen on AF_LOCAL. * * If that doesn't work (for example, if portmapper is running, or rpcbind - * isn't listening on /var/run/rpcbind.sock), send a query via UDP to localhost + * isn't listening on /run/rpcbind.sock), send a query via UDP to localhost * (UDP doesn't leave a socket in TIME_WAIT, and the timeout is a relatively * short 3 seconds). */ diff --git a/tests/test-lib.sh b/tests/test-lib.sh index 57af37b1..e47ad135 100644 --- a/tests/test-lib.sh +++ b/tests/test-lib.sh @@ -56,5 +56,5 @@ start_statd() { # shut down statd kill_statd() { - kill `cat /var/run/rpc.statd.pid` + kill `cat /run/rpc.statd.pid` } diff --git a/tools/nfsconf/nfsconf.man b/tools/nfsconf/nfsconf.man index 30791988..d44e86fb 100644 --- a/tools/nfsconf/nfsconf.man +++ b/tools/nfsconf/nfsconf.man @@ -11,6 +11,12 @@ nfsconf \- Query various NFS configuration settings .IR infile.conf ] .RI [ outfile ] .P +.B nfsconf \-\-entry +.RB [ \-\-arg +.IR subsection] +.IR section +.IR tag +.P .B nfsconf \-\-get .RB [ \-v | \-\-verbose ] .RB [ \-f | \-\-file @@ -58,6 +64,8 @@ from a range of nfs-utils configuration files. The following modes are available: .IP "\fB\-d, \-\-dump\fP" Output an alphabetically sorted dump of the current configuration in conf file format. Accepts an optional filename in which to write the output. +.IP "\fB\-e, \-\-entry\fP" +retrieve the config entry rather than its current expanded value .IP "\fB\-i, \-\-isset\fP" Test if a specific tag has a value set. .IP "\fB\-g, \-\-get\fP" @@ -75,7 +83,7 @@ Increase verbosity and print debugging information. .B \-f, \-\-file \fIinfile\fR Select a different config file to operate upon, default is .I /etc/nfs.conf -.SS Options only valid in \fB\-\-get\fR and \fB\-\-isset\fR modes. +.SS Options only valid in \fB\-\-entry\fR and \fB\-\-get\fR and \fB\-\-isset\fR modes. .TP .B \-a, \-\-arg \fIsubsection\fR Select a specific sub-section diff --git a/tools/nfsconf/nfsconfcli.c b/tools/nfsconf/nfsconfcli.c index 361d386e..b2ef96d1 100644 --- a/tools/nfsconf/nfsconfcli.c +++ b/tools/nfsconf/nfsconfcli.c @@ -11,6 +11,7 @@ typedef enum { MODE_NONE, MODE_GET, + MODE_ENTRY, MODE_ISSET, MODE_DUMP, MODE_SET, @@ -30,6 +31,8 @@ static void usage(const char *name) fprintf(stderr, " Outputs the configuration to the named file\n"); fprintf(stderr, " --get [--arg subsection] {section} {tag}\n"); fprintf(stderr, " Output one specific config value\n"); + fprintf(stderr, " --entry [--arg subsection] {section} {tag}\n"); + fprintf(stderr, " Output the uninterpreted config entry\n"); fprintf(stderr, " --isset [--arg subsection] {section} {tag}\n"); fprintf(stderr, " Return code indicates if config value is present\n"); fprintf(stderr, " --set [--arg subsection] {section} {tag} {value}\n"); @@ -55,6 +58,7 @@ int main(int argc, char **argv) int index = 0; struct option long_options[] = { {"get", no_argument, 0, 'g' }, + {"entry", no_argument, 0, 'e' }, {"set", no_argument, 0, 's' }, {"unset", no_argument, 0, 'u' }, {"arg", required_argument, 0, 'a' }, @@ -66,7 +70,7 @@ int main(int argc, char **argv) {NULL, 0, 0, 0 } }; - c = getopt_long(argc, argv, "gsua:id::f:vm:", long_options, &index); + c = getopt_long(argc, argv, "gesua:id::f:vm:", long_options, &index); if (c == -1) break; switch (c) { @@ -86,6 +90,9 @@ int main(int argc, char **argv) case 'g': mode = MODE_GET; break; + case 'e': + mode = MODE_ENTRY; + break; case 's': mode = MODE_SET; break; @@ -167,8 +174,8 @@ int main(int argc, char **argv) if (dumpfile) fclose(out); } else - /* --iset and --get share a lot of code */ - if (mode == MODE_GET || mode == MODE_ISSET) { + /* --isset and --get share a lot of code */ + if (mode == MODE_GET || mode == MODE_ISSET || mode == MODE_ENTRY) { char * section = NULL; char * tag = NULL; const char * val; @@ -186,14 +193,17 @@ int main(int argc, char **argv) tag = argv[optind++]; /* retrieve the specified tags value */ - val = conf_get_section(section, arg, tag); + if (mode == MODE_ENTRY) + val = conf_get_entry(section, arg, tag); + else + val = conf_get_section(section, arg, tag); if (val != NULL) { /* ret=0, success, mode --get wants to output the value as well */ - if (mode == MODE_GET) + if (mode != MODE_ISSET) printf("%s\n", val); } else { /* ret=1, no value found, tell the user if they asked */ - if (mode == MODE_GET && verbose) + if (mode != MODE_ISSET && verbose) fprintf(stderr, "Tag '%s' not found\n", tag); ret = 1; } diff --git a/utils/blkmapd/device-discovery.c b/utils/blkmapd/device-discovery.c index f5f9b10b..77ebe736 100644 --- a/utils/blkmapd/device-discovery.c +++ b/utils/blkmapd/device-discovery.c @@ -64,7 +64,7 @@ #define EVENT_BUFSIZE (1024 * EVENT_SIZE) #define RPCPIPE_DIR "/var/lib/nfs/rpc_pipefs" -#define PID_FILE "/var/run/blkmapd.pid" +#define PID_FILE "/run/blkmapd.pid" #define CONF_SAVE(w, f) do { \ char *p = f; \ diff --git a/utils/exportd/exportd.man b/utils/exportd/exportd.man index b238ff05..fae434b5 100644 --- a/utils/exportd/exportd.man +++ b/utils/exportd/exportd.man @@ -14,7 +14,7 @@ is used to manage NFSv4 exports. The NFS server .RI ( nfsd ) maintains a cache of authentication and authorization information which -is used to identify the source of each requent, and then what access +is used to identify the source of each request, and then what access permissions that source has to any local filesystem. When required information is not found in the cache, the server sends a request to .B nfsv4.exportd @@ -134,7 +134,7 @@ listing exports, export options, and access control lists .BR exports (5), .BR showmount (8), .BR nfs.conf (5), -.BR firwall-cmd (1), +.BR firewall-cmd (1), .sp RFC 7530 - "Network File System (NFS) Version 4 Protocol" .br diff --git a/utils/mountd/mountd.man b/utils/mountd/mountd.man index 1155cf94..77e6299a 100644 --- a/utils/mountd/mountd.man +++ b/utils/mountd/mountd.man @@ -19,7 +19,7 @@ clients and provides details of access permissions. The NFS server .RI ( nfsd ) maintains a cache of authentication and authorization information which -is used to identify the source of each requent, and then what access +is used to identify the source of each request, and then what access permissions that source has to any local filesystem. When required information is not found in the cache, the server sends a request to .B mountd diff --git a/utils/statd/sm-notify.c b/utils/statd/sm-notify.c index 606b912d..ed82b8f2 100644 --- a/utils/statd/sm-notify.c +++ b/utils/statd/sm-notify.c @@ -901,7 +901,7 @@ find_host(uint32_t xid) } /* - * Record pid in /var/run/sm-notify.pid + * Record pid in /run/sm-notify.pid * This file should remain until a reboot, even if the * program exits. * If file already exists, fail. @@ -913,7 +913,7 @@ static int record_pid(void) int fd; (void)snprintf(pid, sizeof(pid), "%d\n", (int)getpid()); - fd = open("/var/run/sm-notify.pid", O_CREAT|O_EXCL|O_WRONLY, 0600); + fd = open("/run/sm-notify.pid", O_CREAT|O_EXCL|O_WRONLY, 0600); if (fd < 0) return 0; diff --git a/utils/statd/start-statd b/utils/statd/start-statd index 54ced822..2baf73c3 100755 --- a/utils/statd/start-statd +++ b/utils/statd/start-statd @@ -1,18 +1,18 @@ #!/bin/sh # nfsmount calls this script when mounting a filesystem with locking # enabled, but when statd does not seem to be running (based on -# /var/run/rpc.statd.pid). +# /run/rpc.statd.pid). # It should run statd with whatever flags are apropriate for this # site. PATH="/sbin:/usr/sbin:/bin:/usr/bin" # Use flock to serialize the running of this script -exec 9> /var/run/rpc.statd.lock +exec 9> /run/rpc.statd.lock flock -e 9 -if [ -s /var/run/rpc.statd.pid ] && - [ 1`cat /var/run/rpc.statd.pid` -gt 1 ] && - kill -0 `cat /var/run/rpc.statd.pid` > /dev/null 2>&1 +if [ -s /run/rpc.statd.pid ] && + [ 1`cat /run/rpc.statd.pid` -gt 1 ] && + kill -0 `cat /run/rpc.statd.pid` > /dev/null 2>&1 then # statd already running - must have been slow to respond. exit 0 diff --git a/utils/statd/statd.c b/utils/statd/statd.c index 32169d47..a469a67a 100644 --- a/utils/statd/statd.c +++ b/utils/statd/statd.c @@ -161,7 +161,7 @@ usage(void) fprintf(stderr," -H Specify a high-availability callout program.\n"); } -static const char *pidfile = "/var/run/rpc.statd.pid"; +static const char *pidfile = "/run/rpc.statd.pid"; int pidfd = -1; static void create_pidfile(void) diff --git a/utils/statd/statd.man b/utils/statd/statd.man index ecd3e889..7441ffde 100644 --- a/utils/statd/statd.man +++ b/utils/statd/statd.man @@ -440,7 +440,7 @@ directory containing notify list .I /var/lib/nfs/state NSM state number for this host .TP 2.5i -.I /var/run/run.statd.pid +.I /run/run.statd.pid pid file .TP 2.5i .I /etc/netconfig ++++++ nfs-utils-2-5-4-rc4.patch ++++++ Commits: e4ce810a Move declaration of etab and rmtab into libraries 7a4e2d1d Remove 'force' arg from cache_flush() c5528f40 Fix NFSv4 export of tmpfs filesystems ed83085f gssd: use mutex to protect decrement of refcount diff --git a/support/export/auth.c b/support/export/auth.c index cea37630..03ce4b8a 100644 --- a/support/export/auth.c +++ b/support/export/auth.c @@ -41,8 +41,6 @@ static nfs_client my_client; extern int use_ipaddr; -extern struct state_paths etab; - /* void auth_init(void) @@ -80,7 +78,7 @@ check_useipaddr(void) use_ipaddr = 0; if (use_ipaddr != old_use_ipaddr) - cache_flush(1); + cache_flush(); } unsigned int diff --git a/support/export/cache.c b/support/export/cache.c index 3e4f53c0..a5823e92 100644 --- a/support/export/cache.c +++ b/support/export/cache.c @@ -981,7 +981,8 @@ static int dump_to_cache(int f, char *buf, int blen, char *domain, write_secinfo(&bp, &blen, exp, flag_mask); if (exp->e_uuid == NULL || different_fs) { char u[16]; - if (uuid_by_path(path, 0, 16, u)) { + if ((exp->e_flags & flag_mask & NFSEXP_FSID) == 0 && + uuid_by_path(path, 0, 16, u)) { qword_add(&bp, &blen, "uuid"); qword_addhex(&bp, &blen, u, 16); } diff --git a/support/export/export.c b/support/export/export.c index c753f68e..03390dfc 100644 --- a/support/export/export.c +++ b/support/export/export.c @@ -10,9 +10,11 @@ #include <config.h> #endif +#include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/param.h> +#include <fcntl.h> #include <netinet/in.h> #include <limits.h> #include <stdlib.h> @@ -420,3 +422,30 @@ export_hash(char *str) return num % HASH_TABLE_SIZE; } + +int export_test(struct exportent *eep, int with_fsid) +{ + char *path = eep->e_path; + int flags = eep->e_flags | (with_fsid ? NFSEXP_FSID : 0); + /* beside max path, buf size should take protocol str into account */ + char buf[NFS_MAXPATHLEN+1+64] = { 0 }; + char *bp = buf; + int len = sizeof(buf); + int fd, n; + + n = snprintf(buf, len, "-test-client- "); + bp += n; + len -= n; + qword_add(&bp, &len, path); + if (len < 1) + return 0; + snprintf(bp, len, " 3 %d 65534 65534 0\n", flags); + fd = open("/proc/net/rpc/nfsd.export/channel", O_WRONLY); + if (fd < 0) + return 0; + n = nfsd_path_write(fd, buf, strlen(buf)); + close(fd); + if (n < 0) + return 0; + return 1; +} diff --git a/support/export/v4root.c b/support/export/v4root.c index 3654bd7c..c12a7d85 100644 --- a/support/export/v4root.c +++ b/support/export/v4root.c @@ -20,6 +20,7 @@ #include <unistd.h> #include <errno.h> +#include <uuid/uuid.h> #include "xlog.h" #include "exportfs.h" @@ -89,11 +90,31 @@ v4root_create(char *path, nfs_export *export) strncpy(eep.e_path, path, sizeof(eep.e_path)-1); if (strcmp(path, "/") != 0) eep.e_flags &= ~NFSEXP_FSID; + + if (strcmp(path, "/") != 0 && + !export_test(&eep, 0)) { + /* Need a uuid - base it on path using a fixed seed that + * was generated randomly. + */ + const char seed_s[] = "39c6b5c1-3f24-4f4e-977c-7fe6546b8a25"; + uuid_t seed, uuid; + char uuid_s[UUID_STR_LEN]; + unsigned int i, j; + + uuid_parse(seed_s, seed); + uuid_generate_sha1(uuid, seed, path, strlen(path)); + uuid_unparse_upper(uuid, uuid_s); + /* strip hyhens */ + for (i = j = 0; uuid_s[i]; i++) + if (uuid_s[i] != '-') + uuid_s[j++] = uuid_s[i]; + eep.e_uuid = uuid_s; + } set_pseudofs_security(&eep); exp = export_create(&eep, 0); if (exp == NULL) return NULL; - xlog(D_CALL, "v4root_create: path '%s' flags 0x%x", + xlog(D_CALL, "v4root_create: path '%s' flags 0x%x", exp->m_export.e_path, exp->m_export.e_flags); return &exp->m_export; } diff --git a/support/export/xtab.c b/support/export/xtab.c index 00b25eaa..c888a80a 100644 --- a/support/export/xtab.c +++ b/support/export/xtab.c @@ -27,7 +27,7 @@ #include "misc.h" static char state_base_dirname[PATH_MAX] = NFS_STATEDIR; -extern struct state_paths etab; +struct state_paths etab; int v4root_needed; static void cond_rename(char *newfile, char *oldfile); diff --git a/support/include/exportfs.h b/support/include/exportfs.h index 81d13721..9edf0d04 100644 --- a/support/include/exportfs.h +++ b/support/include/exportfs.h @@ -145,6 +145,7 @@ nfs_export * export_create(struct exportent *, int canonical); void exportent_release(struct exportent *); void export_freeall(void); +extern struct state_paths etab; int xtab_export_read(void); int xtab_export_write(void); @@ -173,5 +174,6 @@ struct export_features { struct export_features *get_export_features(void); void fix_pseudoflavor_flags(struct exportent *ep); char *exportent_realpath(struct exportent *eep); +int export_test(struct exportent *eep, int with_fsid); #endif /* EXPORTFS_H */ diff --git a/support/include/nfslib.h b/support/include/nfslib.h index 84d8270b..6faba71b 100644 --- a/support/include/nfslib.h +++ b/support/include/nfslib.h @@ -106,6 +106,7 @@ void dupexportent(struct exportent *dst, struct exportent *src); int updateexportent(struct exportent *eep, char *options); +extern struct state_paths rmtab; int setrmtabent(char *type); struct rmtabent * getrmtabent(int log, long *pos); void putrmtabent(struct rmtabent *xep, long *pos); @@ -132,7 +133,7 @@ int wildmat(char *text, char *pattern); int qword_get(char **bpp, char *dest, int bufsize); int qword_get_int(char **bpp, int *anint); -void cache_flush(int force); +void cache_flush(void); void qword_add(char **bpp, int *lp, char *str); void qword_addhex(char **bpp, int *lp, char *buf, int blen); void qword_addint(char **bpp, int *lp, int n); diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c index 70ead94d..73f4be4a 100644 --- a/support/nfs/cacheio.c +++ b/support/nfs/cacheio.c @@ -32,8 +32,6 @@ #include <time.h> #include <errno.h> -extern struct state_paths etab; - void qword_add(char **bpp, int *lp, char *str) { char *bp = *bpp; @@ -213,7 +211,7 @@ int qword_get_uint(char **bpp, unsigned int *anint) */ void -cache_flush(int force) +cache_flush(void) { struct stat stb; int c; @@ -234,12 +232,13 @@ cache_flush(int force) NULL }; now = time(0); - if (force || - stat(etab.statefn, &stb) != 0 || - stb.st_mtime > now) - stb.st_mtime = time(0); - - sprintf(stime, "%" PRId64 "\n", (int64_t)stb.st_mtime); + + /* Since v4.16-rc2-3-g3b68e6ee3cbd the timestamp written is ignored. + * It is safest always to flush caches if there is any doubt. + * For earlier kernels, writing the next second from now is + * the best we can do. + */ + sprintf(stime, "%" PRId64 "\n", (int64_t)now+1); for (c=0; cachelist[c]; c++) { int fd; sprintf(path, "/proc/net/rpc/%s/flush", cachelist[c]); diff --git a/support/nfs/rmtab.c b/support/nfs/rmtab.c index 9f03167d..154b26fa 100644 --- a/support/nfs/rmtab.c +++ b/support/nfs/rmtab.c @@ -33,7 +33,7 @@ static FILE *rmfp = NULL; -extern struct state_paths rmtab; +struct state_paths rmtab; int setrmtabent(char *type) diff --git a/utils/exportd/Makefile.am b/utils/exportd/Makefile.am index eb521f15..c95bdee7 100644 --- a/utils/exportd/Makefile.am +++ b/utils/exportd/Makefile.am @@ -16,7 +16,7 @@ exportd_SOURCES = exportd.c exportd_LDADD = ../../support/export/libexport.a \ ../../support/nfs/libnfs.la \ ../../support/misc/libmisc.a \ - $(OPTLIBS) $(LIBBLKID) $(LIBPTHREAD) + $(OPTLIBS) $(LIBBLKID) $(LIBPTHREAD) -luuid exportd_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) \ -I$(top_srcdir)/support/export diff --git a/utils/exportd/exportd.c b/utils/exportd/exportd.c index f36f51d2..2dd12cb6 100644 --- a/utils/exportd/exportd.c +++ b/utils/exportd/exportd.c @@ -25,8 +25,6 @@ extern void my_svc_run(void); -struct state_paths etab; - /* Number of mountd threads to start. Default is 1 and * that's probably enough unless you need hundreds of * clients to be able to mount at once. */ diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c index 25d757d8..6ba615d1 100644 --- a/utils/exportfs/exportfs.c +++ b/utils/exportfs/exportfs.c @@ -52,13 +52,6 @@ static void release_lockfile(void); static const char *lockfile = EXP_LOCKFILE; static int _lockfd = -1; -struct state_paths etab; - -static ssize_t exportfs_write(int fd, const char *buf, size_t len) -{ - return nfsd_path_write(fd, buf, len); -} - /* * If we aren't careful, changes made by exportfs can be lost * when multiple exports process run at once: @@ -193,7 +186,7 @@ main(int argc, char **argv) if (optind == argc && ! f_all) { if (force_flush) { - cache_flush(1); + cache_flush(); free_state_path_names(&etab); return 0; } else { @@ -240,7 +233,7 @@ main(int argc, char **argv) unexportfs(argv[i], f_verbose); } xtab_export_write(); - cache_flush(force_flush); + cache_flush(); free_state_path_names(&etab); export_freeall(); @@ -510,33 +503,6 @@ static int can_test(void) return 1; } -static int test_export(nfs_export *exp, int with_fsid) -{ - char *path = exp->m_export.e_path; - int flags = exp->m_export.e_flags | (with_fsid ? NFSEXP_FSID : 0); - /* beside max path, buf size should take protocol str into account */ - char buf[NFS_MAXPATHLEN+1+64] = { 0 }; - char *bp = buf; - int len = sizeof(buf); - int fd, n; - - n = snprintf(buf, len, "-test-client- "); - bp += n; - len -= n; - qword_add(&bp, &len, path); - if (len < 1) - return 0; - snprintf(bp, len, " 3 %d 65534 65534 0\n", flags); - fd = open("/proc/net/rpc/nfsd.export/channel", O_WRONLY); - if (fd < 0) - return 0; - n = exportfs_write(fd, buf, strlen(buf)); - close(fd); - if (n < 0) - return 0; - return 1; -} - static void validate_export(nfs_export *exp) { @@ -568,12 +534,12 @@ validate_export(nfs_export *exp) if ((exp->m_export.e_flags & NFSEXP_FSID) || exp->m_export.e_uuid || fs_has_fsid) { - if ( !test_export(exp, 1)) { + if ( !export_test(&exp->m_export, 1)) { xlog(L_ERROR, "%s does not support NFS export", path); return; } - } else if ( !test_export(exp, 0)) { - if (test_export(exp, 1)) + } else if ( !export_test(&exp->m_export, 0)) { + if (export_test(&exp->m_export, 1)) xlog(L_ERROR, "%s requires fsid= for NFS export", path); else xlog(L_ERROR, "%s does not support NFS export", path); diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c index 28b60ba3..51e0c6a2 100644 --- a/utils/gssd/krb5_util.c +++ b/utils/gssd/krb5_util.c @@ -169,18 +169,28 @@ static int gssd_get_single_krb5_cred(krb5_context context, static int query_krb5_ccache(const char* cred_cache, char **ret_princname, char **ret_realm); -static void release_ple(krb5_context context, struct gssd_k5_kt_princ *ple) +static void release_ple_locked(krb5_context context, + struct gssd_k5_kt_princ *ple) { if (--ple->refcount) return; - printerr(3, "freeing cached principal (ccname=%s, realm=%s)\n", ple->ccname, ple->realm); + printerr(3, "freeing cached principal (ccname=%s, realm=%s)\n", + ple->ccname, ple->realm); krb5_free_principal(context, ple->princ); free(ple->ccname); free(ple->realm); free(ple); } +static void release_ple(krb5_context context, struct gssd_k5_kt_princ *ple) +{ + pthread_mutex_lock(&ple_lock); + release_ple_locked(context, ple); + pthread_mutex_unlock(&ple_lock); +} + + /* * Called from the scandir function to weed out potential krb5 * credentials cache files @@ -1420,7 +1430,7 @@ gssd_destroy_krb5_principals(int destroy_machine_creds) } } - release_ple(context, ple); + release_ple_locked(context, ple); } pthread_mutex_unlock(&ple_lock); krb5_free_context(context); diff --git a/utils/gssd/svcgssd.c b/utils/gssd/svcgssd.c index 3ab2100b..881207b3 100644 --- a/utils/gssd/svcgssd.c +++ b/utils/gssd/svcgssd.c @@ -67,7 +67,6 @@ #include "misc.h" #include "svcgssd_krb5.h" -struct state_paths etab; /* from cacheio.c */ static bool signal_received = false; static struct event_base *evbase = NULL; static int nullrpc_fd = -1; diff --git a/utils/mountd/Makefile.am b/utils/mountd/Makefile.am index 859f28ec..13b25c90 100644 --- a/utils/mountd/Makefile.am +++ b/utils/mountd/Makefile.am @@ -18,7 +18,7 @@ mountd_LDADD = ../../support/export/libexport.a \ ../../support/nfs/libnfs.la \ ../../support/misc/libmisc.a \ $(OPTLIBS) \ - $(LIBBSD) $(LIBWRAP) $(LIBNSL) $(LIBBLKID) $(LIBTIRPC) \ + $(LIBBSD) $(LIBWRAP) $(LIBNSL) $(LIBBLKID) -luuid $(LIBTIRPC) \ $(LIBPTHREAD) mountd_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) \ -I$(top_builddir)/support/include \ diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c index 39e85fd5..bcf749fa 100644 --- a/utils/mountd/mountd.c +++ b/utils/mountd/mountd.c @@ -43,9 +43,6 @@ int reverse_resolve = 0; int manage_gids; int use_ipaddr = -1; -struct state_paths etab; -struct state_paths rmtab; - /* PRC: a high-availability callout program can be specified with -H * When this is done, the program will receive callouts whenever clients * send mount or unmount requests -- the callout is not needed for 2.6 kernel */ diff --git a/utils/mountd/rmtab.c b/utils/mountd/rmtab.c index c8962439..2da97615 100644 --- a/utils/mountd/rmtab.c +++ b/utils/mountd/rmtab.c @@ -28,8 +28,6 @@ extern int reverse_resolve; -extern struct state_paths rmtab; - /* If new path is a link do not destroy it but place the * file where the link points. */