diff --git a/configure.ac b/configure.ac index 93520a80..bc2d0f02 100644 --- a/configure.ac +++ b/configure.ac @@ -688,9 +688,28 @@ AC_SUBST([ACLOCAL_AMFLAGS], ["-I $ac_macro_dir \$(ACLOCAL_FLAGS)"]) AC_SUBST([_sysconfdir]) AC_CONFIG_COMMANDS_PRE([eval eval _sysconfdir=$sysconfdir]) +# make _statedir available for substituion in config files +# 2 "evals" needed late to expand variable names. +AC_SUBST([_statedir]) +AC_CONFIG_COMMANDS_PRE([eval eval _statedir=$statedir]) + +if test "$statedir" = "/var/lib/nfs"; then + rpc_pipefsmount="var-lib-nfs-rpc_pipefs.mount" +else + rpc_pipefsmount="$(systemd-escape -p "$statedir/rpc_pipefs").mount" +fi +AC_SUBST(rpc_pipefsmount) + +# make _rpc_pipefsmount available for substituion in config files +# 2 "evals" needed late to expand variable names. +AC_SUBST([_rpc_pipefsmount]) +AC_CONFIG_COMMANDS_PRE([eval eval _rpc_pipefsmount=$rpc_pipefsmount]) + AC_CONFIG_FILES([ Makefile systemd/rpc-gssd.service + systemd/rpc_pipefs.target + systemd/var-lib-nfs-rpc_pipefs.mount linux-nfs/Makefile support/Makefile support/export/Makefile diff --git a/install-dep b/install-dep new file mode 100755 index 00000000..4698d44a --- /dev/null +++ b/install-dep @@ -0,0 +1,21 @@ +#!/bin/bash +#install dependencies for compiling from source code + +#RHEL/Fedora/CentOS-Stream/Rocky +command -v dnf >/dev/null || command -v yum >/dev/null && { + yum install -y automake libtool make gcc rpcgen libtirpc-devel libevent-devel sqlite-devel device-mapper-devel \ + libblkid-devel krb5-devel libuuid-devel +} + +#Debian/ubuntu +command -v apt >/dev/null && { + apt install -o APT::Install-Suggests=0 -o APT::Install-Recommends=0 --ignore-missing -y \ + autotools-dev automake make libtool pkg-config libtirpc-dev libevent-dev libsqlite3-dev \ + libdevmapper-dev libblkid-dev libkrb5-dev libkeyutils-dev uuid-dev +} + +#openSUSE Leap +command -v zypper >/dev/null && { + zypper in --no-recommends -y automake libtool make gcc rpcgen libtirpc-devel libevent-devel sqlite-devel \ + device-mapper-devel libblkid-devel krb5-devel libuuid-devel +} diff --git a/support/export/v4clients.c b/support/export/v4clients.c index dd985463..5e4f1058 100644 --- a/support/export/v4clients.c +++ b/support/export/v4clients.c @@ -10,6 +10,7 @@ #include #include #include "export.h" +#include "version.h" /* search.h declares 'struct entry' and nfs_prot.h * does too. Easiest fix is to trick search.h into @@ -23,6 +24,8 @@ static int clients_fd = -1; void v4clients_init(void) { + if (linux_version_code() < MAKE_VERSION(5, 3, 0)) + return; if (clients_fd >= 0) return; clients_fd = inotify_init1(IN_NONBLOCK); diff --git a/support/include/version.h b/support/include/version.h new file mode 120000 index 00000000..b7db0bbb --- /dev/null +++ b/support/include/version.h @@ -0,0 +1 @@ +../../utils/mount/version.h \ No newline at end of file diff --git a/support/nfs/cacheio.c b/support/nfs/cacheio.c index 73f4be4a..bd4da0e5 100644 --- a/support/nfs/cacheio.c +++ b/support/nfs/cacheio.c @@ -213,7 +213,6 @@ int qword_get_uint(char **bpp, unsigned int *anint) void cache_flush(void) { - struct stat stb; int c; char stime[32]; char path[200]; diff --git a/support/nfsidmap/nss.c b/support/nfsidmap/nss.c index 669760b7..0f43076e 100644 --- a/support/nfsidmap/nss.c +++ b/support/nfsidmap/nss.c @@ -365,10 +365,8 @@ static int _nss_name_to_gid(char *name, gid_t *gid, int dostrip) out_buf: free(buf); out_name: - if (dostrip) - free(localname); - if (get_reformat_group()) - free(ref_name); + free(localname); + free(ref_name); out: return err; } diff --git a/support/nfsidmap/regex.c b/support/nfsidmap/regex.c index fdbb2e2f..958b4ac8 100644 --- a/support/nfsidmap/regex.c +++ b/support/nfsidmap/regex.c @@ -157,6 +157,7 @@ again: IDMAP_LOG(4, ("regexp_getpwnam: name '%s' mapped to '%s'", name, localname)); + free(localname); *err_p = 0; return pw; diff --git a/systemd/Makefile.am b/systemd/Makefile.am index 650ad25c..e7f5d818 100644 --- a/systemd/Makefile.am +++ b/systemd/Makefile.am @@ -12,7 +12,9 @@ unit_files = \ rpc-statd-notify.service \ rpc-statd.service \ \ - proc-fs-nfsd.mount \ + proc-fs-nfsd.mount + +rpc_pipefs_mount_file = \ var-lib-nfs-rpc_pipefs.mount if CONFIG_NFSV4 @@ -51,8 +53,7 @@ man5_MANS = nfs.conf.man man7_MANS = nfs.systemd.man EXTRA_DIST = $(unit_files) $(man5_MANS) $(man7_MANS) -unit_dir = /usr/lib/systemd/system -generator_dir = /usr/lib/systemd/system-generators +generator_dir = $(unitdir)/../system-generators EXTRA_PROGRAMS = nfs-server-generator rpc-pipefs-generator genexecdir = $(generator_dir) @@ -75,4 +76,5 @@ genexec_PROGRAMS = nfs-server-generator rpc-pipefs-generator install-data-hook: $(unit_files) mkdir -p $(DESTDIR)/$(unitdir) cp $(unit_files) $(DESTDIR)/$(unitdir) + cp $(rpc_pipefs_mount_file) $(DESTDIR)/$(unitdir)/$(rpc_pipefsmount) endif diff --git a/systemd/rpc-pipefs-generator.c b/systemd/rpc-pipefs-generator.c index 8e218aa7..c24db567 100644 --- a/systemd/rpc-pipefs-generator.c +++ b/systemd/rpc-pipefs-generator.c @@ -21,7 +21,7 @@ #include "conffile.h" #include "systemd.h" -#define RPC_PIPEFS_DEFAULT "/var/lib/nfs/rpc_pipefs" +#define RPC_PIPEFS_DEFAULT NFS_STATEDIR "/rpc_pipefs" static int generate_mount_unit(const char *pipefs_path, const char *pipefs_unit, const char *dirname) diff --git a/systemd/rpc_pipefs.target.in b/systemd/rpc_pipefs.target.in new file mode 100644 index 00000000..332f62b6 --- /dev/null +++ b/systemd/rpc_pipefs.target.in @@ -0,0 +1,3 @@ +[Unit] +Requires=@_rpc_pipefsmount@ +After=@_rpc_pipefsmount@ diff --git a/systemd/var-lib-nfs-rpc_pipefs.mount.in b/systemd/var-lib-nfs-rpc_pipefs.mount.in new file mode 100644 index 00000000..4c5d6ce4 --- /dev/null +++ b/systemd/var-lib-nfs-rpc_pipefs.mount.in @@ -0,0 +1,10 @@ +[Unit] +Description=RPC Pipe File System +DefaultDependencies=no +After=systemd-tmpfiles-setup.service +Conflicts=umount.target + +[Mount] +What=sunrpc +Where=@_statedir@/rpc_pipefs +Type=rpc_pipefs diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py index 23876fc4..8e129c83 100755 --- a/tools/mountstats/mountstats.py +++ b/tools/mountstats/mountstats.py @@ -482,8 +482,11 @@ class DeviceData: count = stats[1] if count != 0: print('%s:' % stats[0]) + ops_pcnt = 0 + if sends != 0: + ops_pcnt = (count * 100) / sends print('\t%d ops (%d%%)' % \ - (count, ((count * 100) / sends)), end=' ') + (count, ops_pcnt), end=' ') retrans = stats[2] - count if retrans != 0: print('\t%d retrans (%d%%)' % (retrans, ((retrans * 100) / count)), end=' ') diff --git a/utils/blkmapd/device-discovery.c b/utils/blkmapd/device-discovery.c index 77ebe736..2736ac89 100644 --- a/utils/blkmapd/device-discovery.c +++ b/utils/blkmapd/device-discovery.c @@ -63,7 +63,7 @@ #define EVENT_SIZE (sizeof(struct inotify_event)) #define EVENT_BUFSIZE (1024 * EVENT_SIZE) -#define RPCPIPE_DIR "/var/lib/nfs/rpc_pipefs" +#define RPCPIPE_DIR NFS_STATEDIR "/rpc_pipefs" #define PID_FILE "/run/blkmapd.pid" #define CONF_SAVE(w, f) do { \ diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c index 4113cbab..833d8e01 100644 --- a/utils/gssd/gssd.c +++ b/utils/gssd/gssd.c @@ -1016,7 +1016,7 @@ read_gss_conf(void) keytabfile = s; s = conf_get_str("gssd", "cred-cache-directory"); if (s) - ccachedir = s; + ccachedir = strdup(s); s = conf_get_str("gssd", "preferred-realm"); if (s) preferred_realm = s; @@ -1070,7 +1070,8 @@ main(int argc, char *argv[]) keytabfile = optarg; break; case 'd': - ccachedir = optarg; + free(ccachedir); + ccachedir = strdup(optarg); break; case 't': context_timeout = atoi(optarg); @@ -1133,7 +1134,6 @@ main(int argc, char *argv[]) } if (ccachedir) { - char *ccachedir_copy; char *ptr; for (ptr = ccachedir, i = 2; *ptr; ptr++) @@ -1141,8 +1141,7 @@ main(int argc, char *argv[]) i++; ccachesearch = malloc(i * sizeof(char *)); - ccachedir_copy = strdup(ccachedir); - if (!ccachedir_copy || !ccachesearch) { + if (!ccachesearch) { printerr(0, "malloc failure\n"); exit(EXIT_FAILURE); } @@ -1274,6 +1273,7 @@ main(int argc, char *argv[]) free(preferred_realm); free(ccachesearch); + free(ccachedir); return rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/utils/gssd/gssd.h b/utils/gssd/gssd.h index c52c5b48..519dc431 100644 --- a/utils/gssd/gssd.h +++ b/utils/gssd/gssd.h @@ -39,7 +39,7 @@ #include #ifndef GSSD_PIPEFS_DIR -#define GSSD_PIPEFS_DIR "/var/lib/nfs/rpc_pipefs" +#define GSSD_PIPEFS_DIR NFS_STATEDIR "/rpc_pipefs" #endif #define DNOTIFY_SIGNAL (SIGRTMIN + 3) diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c index c5f1152e..e3f270e9 100644 --- a/utils/gssd/krb5_util.c +++ b/utils/gssd/krb5_util.c @@ -673,8 +673,8 @@ get_full_hostname(const char *inhost, char *outhost, int outhostlen) *c = tolower(*c); if (get_verbosity() && strcmp(inhost, outhost)) - printerr(1, "%s(0x%0lx): inhost '%s' different than outhost'%s'\n", - inhost, outhost); + printerr(1, "%s(0x%0lx): inhost '%s' different than outhost '%s'\n", + __func__, tid, inhost, outhost); retval = 0; out: @@ -1129,6 +1129,12 @@ query_krb5_ccache(const char* cred_cache, char **ret_princname, *str = '\0'; *ret_princname = strdup(princstring); *ret_realm = strdup(str+1); + if (!*ret_princname || !*ret_realm) { + free(*ret_princname); + free(*ret_realm); + *ret_princname = NULL; + *ret_realm = NULL; + } } k5_free_unparsed_name(context, princstring); } @@ -1350,15 +1356,19 @@ gssd_get_krb5_machine_cred_list(char ***list) if (retval) continue; if (i + 1 > listsize) { + char **tmplist; listsize += listinc; - l = (char **) + tmplist = (char **) realloc(l, listsize * sizeof(char *)); - if (l == NULL) { + if (tmplist == NULL) { + gssd_free_krb5_machine_cred_list(l); retval = ENOMEM; goto out_lock; } + l = tmplist; } if ((l[i++] = strdup(ple->ccname)) == NULL) { + gssd_free_krb5_machine_cred_list(l); retval = ENOMEM; goto out_lock; } diff --git a/utils/gssd/svcgssd_krb5.c b/utils/gssd/svcgssd_krb5.c index 305d4751..2503c384 100644 --- a/utils/gssd/svcgssd_krb5.c +++ b/utils/gssd/svcgssd_krb5.c @@ -46,7 +46,7 @@ #include "gss_oids.h" #include "err_util.h" #include "svcgssd_krb5.h" -#include "../mount/version.h" +#include "version.h" #define MYBUFLEN 1024 diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c index 51c71fbb..e2c160e8 100644 --- a/utils/idmapd/idmapd.c +++ b/utils/idmapd/idmapd.c @@ -73,7 +73,7 @@ #include "nfslib.h" #ifndef PIPEFS_DIR -#define PIPEFS_DIR "/var/lib/nfs/rpc_pipefs/" +#define PIPEFS_DIR NFS_STATEDIR "/rpc_pipefs/" #endif #ifndef NFSD_DIR diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man index f98cb47d..57a693fd 100644 --- a/utils/mount/nfs.man +++ b/utils/mount/nfs.man @@ -416,6 +416,19 @@ Note that the option may also be used by some pNFS drivers to decide how many connections to set up to the data servers. .TP 1.5i +.BR max_connect= n +While +.BR nconnect +option sets a limit on the number of connections that can be established +to a given server IP, +.BR max_connect +option allows the user to specify maximum number of connections to different +server IPs that belong to the same NFSv4.1+ server (session trunkable +connections) up to a limit of 16. When client discovers that it established +a client ID to an already existing server, instead of dropping the newly +created network transport, the client will add this new connection to the +list of available transports for that RPC client. +.TP 1.5i .BR rdirplus " / " nordirplus Selects whether to use NFS v3 or v4 READDIRPLUS requests. If this option is not specified, the NFS client uses READDIRPLUS requests @@ -555,6 +568,13 @@ using the FS-Cache facility. See cachefilesd(8) and /Documentation/filesystems/caching for detail on how to configure the FS-Cache facility. Default value is nofsc. +.TP 1.5i +.B sloppy +The +.B sloppy +option is an alternative to specifying +.BR mount.nfs " -s " option. + .SS "Options for NFS versions 2 and 3 only" Use these options, along with the options in the above subsection, for NFS versions 2 and 3 only. diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c index 82b054a5..fa67a66f 100644 --- a/utils/mount/stropts.c +++ b/utils/mount/stropts.c @@ -339,11 +339,19 @@ static int nfs_verify_lock_option(struct mount_options *options) static int nfs_insert_sloppy_option(struct mount_options *options) { - if (!sloppy || linux_version_code() < MAKE_VERSION(2, 6, 27)) + if (linux_version_code() < MAKE_VERSION(2, 6, 27)) return 1; - if (po_insert(options, "sloppy") == PO_FAILED) - return 0; + if (po_contains(options, "sloppy")) { + po_remove_all(options, "sloppy"); + sloppy++; + } + + if (sloppy) { + if (po_insert(options, "sloppy") == PO_FAILED) + return 0; + } + return 1; } diff --git a/utils/mountd/rmtab.c b/utils/mountd/rmtab.c index 2da97615..752fdb66 100644 --- a/utils/mountd/rmtab.c +++ b/utils/mountd/rmtab.c @@ -233,6 +233,9 @@ mountlist_list(void) m->ml_directory = strdup(rep->r_path); if (m->ml_hostname == NULL || m->ml_directory == NULL) { + free(m->ml_hostname); + free(m->ml_directory); + free(m); mountlist_freeall(mlist); mlist = NULL; xlog(L_ERROR, "%s: memory allocation failed", diff --git a/utils/nfsd/nfssvc.c b/utils/nfsd/nfssvc.c index 720bdd97..46452d97 100644 --- a/utils/nfsd/nfssvc.c +++ b/utils/nfsd/nfssvc.c @@ -25,7 +25,7 @@ #include "nfslib.h" #include "xlog.h" #include "nfssvc.h" -#include "../mount/version.h" +#include "version.h" #ifndef NFSD_FS_DIR #define NFSD_FS_DIR "/proc/fs/nfsd" diff --git a/utils/nfsdcld/nfsdcld.c b/utils/nfsdcld/nfsdcld.c index 636c3983..dbc7a57f 100644 --- a/utils/nfsdcld/nfsdcld.c +++ b/utils/nfsdcld/nfsdcld.c @@ -45,7 +45,7 @@ #include "cld.h" #include "cld-internal.h" #include "sqlite.h" -#include "../mount/version.h" +#include "version.h" #include "conffile.h" #include "legacy.h" diff --git a/utils/nfsdcltrack/nfsdcltrack.c b/utils/nfsdcltrack/nfsdcltrack.c index e926f1c0..7c1c4bcc 100644 --- a/utils/nfsdcltrack/nfsdcltrack.c +++ b/utils/nfsdcltrack/nfsdcltrack.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -507,7 +508,7 @@ cltrack_gracedone(const char *timestr) { int ret; char *tail; - time_t gracetime; + uint64_t gracetime; ret = sqlite_prepare_dbh(storagedir); @@ -525,7 +526,7 @@ cltrack_gracedone(const char *timestr) if (*tail) return -EINVAL; - xlog(D_GENERAL, "%s: grace done. gracetime=%ld", __func__, gracetime); + xlog(D_GENERAL, "%s: grace done. gracetime=%"PRIu64, __func__, gracetime); ret = sqlite_remove_unreclaimed(gracetime); diff --git a/utils/nfsdcltrack/sqlite.c b/utils/nfsdcltrack/sqlite.c index f79aebb3..cf0c6a45 100644 --- a/utils/nfsdcltrack/sqlite.c +++ b/utils/nfsdcltrack/sqlite.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -539,12 +540,12 @@ out_err: * remove any client records that were not reclaimed since grace_start. */ int -sqlite_remove_unreclaimed(time_t grace_start) +sqlite_remove_unreclaimed(uint64_t grace_start) { int ret; char *err = NULL; - ret = snprintf(buf, sizeof(buf), "DELETE FROM clients WHERE time < %ld", + ret = snprintf(buf, sizeof(buf), "DELETE FROM clients WHERE time < %"PRIu64, grace_start); if (ret < 0) { return ret; diff --git a/utils/nfsdcltrack/sqlite.h b/utils/nfsdcltrack/sqlite.h index 06e7c044..ba8cdfa8 100644 --- a/utils/nfsdcltrack/sqlite.h +++ b/utils/nfsdcltrack/sqlite.h @@ -26,7 +26,7 @@ int sqlite_insert_client(const unsigned char *clname, const size_t namelen, int sqlite_remove_client(const unsigned char *clname, const size_t namelen); int sqlite_check_client(const unsigned char *clname, const size_t namelen, const bool has_session); -int sqlite_remove_unreclaimed(const time_t grace_start); +int sqlite_remove_unreclaimed(const uint64_t grace_start); int sqlite_query_reclaiming(const time_t grace_start); #endif /* _SQLITE_H */