diff --git a/.gitignore b/.gitignore index df791a83..682153d5 100644 --- a/.gitignore +++ b/.gitignore @@ -86,3 +86,5 @@ systemd/rpc-gssd.service cscope.* # generic editor backup et al *~ +# file generated by ctags +tags diff --git a/NEWS b/NEWS index e70ae8ab..77872c5a 100644 --- a/NEWS +++ b/NEWS @@ -1,32 +1,32 @@ Significant changes for nfs-utils 1.1.0 - March/April 2007 - - rpc.lockd is gone. One 3 old kernel releases need it. - - rpc.rquotad is gone. Use the one from the 'quota' package. - Everone else does. + - rpc.lockd is gone. One 3 old kernel releases need it. + - rpc.rquotad is gone. Use the one from the 'quota' package. + Everyone else does. - /sbin/{u,}mount.nfs{,4} are now installed so 'mount' will use these to mount nfs filesystems instead of internal code. + mount.nfs will check for 'statd' to be running when mounting - a filesystem which requires it. If it is not running it will + a filesystem which requires it. If it is not running it will run "/usr/sbin/start-statd" to try to start it. If statd is not running and cannot be started, mount.nfs will refuse to mount the filesystem and will suggest the 'nolock' option. - Substantial changes to statd + The 'notify' process that must happen at boot has been split - into a separate program "sm-notify". It ensures that it - only runs once even if you restart statd. This is correct + into a separate program "sm-notify". It ensures that it + only runs once even if you restart statd. This is correct behaviour. + statd stores state in the files in /var/lib/nfs/sm/ so that if you kill and restart it, it will restore that state and continue working correctly. + statd makes more use of DNS lookup and should handle - multi-homed peers better. In particular, files in + multi-homed peers better. In particular, files in /var/lib/nfs/sm/ are named with the Full Qualified Domain Name if available. - If you export a directory as 'crossmnt', all filesystems mounted beneath are automatically exported with the same options (unless explicitly exported with different options). - - subtree_check is no-longer the default. The default is now + - subtree_check is no-longer the default. The default is now no_subtree_check. - By default the system 'rpcgen' is used while building nfs-utils rather than the internal one. @@ -43,14 +43,14 @@ Significant changes for nfs-utils 1.1.0 - March/April 2007 - A new option, -n, was added to rpc.gssd which specifies that accesses by root should not use 'machine credentials' when - accessing NFS file systems mounted with Kerberos. Using this + accessing NFS file systems mounted with Kerberos. Using this option allows the root user to access the NFS space using any Kerberos principal, rather than always using the machine - credentials. However, its use also requires that root manually + credentials. However, its use also requires that root manually authenticate before attempting a mount with Kerberos. When rpc.gssd uses machine credentials, the selection algorithm has - been changed. Instead of simply using the first "nfs/*" key in the + been changed. Instead of simply using the first "nfs/*" key in the keytab, the keytab is now searched for keys in the following defined order: diff --git a/README b/README index 5e982409..3b0e771f 100644 --- a/README +++ b/README @@ -25,7 +25,7 @@ Unpack the sources and run these commands: # ./configure # make -To install binaries and documenation, run this command: +To install binaries and documentation, run this command: # make install @@ -40,7 +40,7 @@ Updating to the latest head after you've already got it. git pull -Building requires that autotools be installed. To invoke them +Building requires that autotools be installed. To invoke them simply sh autogen.sh @@ -70,7 +70,7 @@ scripts can be written to work correctly. 3.1. SERVER STARTUP - A/ mount -t nfsd /proc/fs/nfsd + A/ mount -t nfsd nfsd /proc/fs/nfsd This filesystem needs to be mount before most daemons, particularly exportfs, mountd, svcgssd, idmapd. It could be mounted once, or the script that starts each daemon @@ -95,27 +95,27 @@ scripts can be written to work correctly. D/ rpc.statd --no-notify It is best if statd is started before nfsd though this isn't - critical. Certainly it should be at most a few seconds after + critical. Certainly, it should be at most a few seconds after nfsd. When nfsd starts it will start lockd. If lockd then receives a - lock request it will communicate with statd. If statd is not + lock request, it will communicate with statd. If statd is not running lockd will retry, but it won't wait forever for a reply. Note that if statd is started before nfsd, the --no-notify - option must be used. If notify requests are sent out before + option must be used. If notify requests are sent out before nfsd start, clients may try to reclaim locks and, on finding that lockd isn't running, they will give up and never reclaim the lock. rpc.statd is only needed for NFSv2 and NFSv3 support. E/ rpc.nfsd - Starting nfsd will automatically start lockd. The nfs server + Starting nfsd will automatically start lockd. The nfs server will now be fully active and respond to any requests from clients. F/ sm-notify This will notify any client which might have locks from before - a reboot to try to reclaim their locks. This should start + a reboot to try to reclaim their locks. This should start immediately after rpc.nfsd is started so that clients have a chance to reclaim locks within the 90 second grace period. sm-notify is only needed for NFSv2 and NFSv3 support. diff --git a/configure.ac b/configure.ac index f1c46c5c..7672a760 100644 --- a/configure.ac +++ b/configure.ac @@ -71,18 +71,6 @@ AC_ARG_WITH(systemd, AM_CONDITIONAL(INSTALL_SYSTEMD, [test "$use_systemd" = 1]) AC_SUBST(unitdir) -modprobedir=/usr/lib/modprobe.d -AC_ARG_WITH(modprobedir, - [AS_HELP_STRING([--with-modprobedir@<:@=modprobe-dir-path@:>@],[install modprobe config files @<:@Default: /usr/lib/modprobe.d@:>@])], - if test "$withval" != "no" ; then - modprobedir=$withval - else - modprobedir= - fi - ) - AM_CONDITIONAL(INSTALL_MODPROBEDIR, [test -n "$modprobedir"]) - AC_SUBST(modprobedir) - AC_ARG_ENABLE(nfsv4, [AS_HELP_STRING([--disable-nfsv4],[disable support for NFSv4 @<:@default=no@:>@])], enable_nfsv4=$enableval, @@ -249,6 +237,16 @@ AC_ARG_ENABLE(nfsdcld, enable_nfsdcld=$enableval, enable_nfsdcld="yes") +AC_ARG_ENABLE(nfsrahead, + [AS_HELP_STRING([--disable-nfsrahead],[disable nfsrahead command @<:@default=no@:>@])], + enable_nfsrahead=$enableval, + enable_nfsrahead="yes") + AM_CONDITIONAL(CONFIG_NFSRAHEAD, [test "$enable_nfsrahead" = "yes" ]) + if test "$enable_nfsrahead" = yes; then + dnl Check for -lmount + PKG_CHECK_MODULES([LIBMOUNT], [mount]) + fi + AC_ARG_ENABLE(nfsdcltrack, [AS_HELP_STRING([--disable-nfsdcltrack],[disable NFSv4 clientid tracking programs @<:@default=no@:>@])], enable_nfsdcltrack=$enableval, @@ -678,12 +676,12 @@ AC_SUBST([AM_CFLAGS], ["$my_am_cflags $flg1 $flg2 $flg3 $flg4 $flg5"]) # Make sure that $ACLOCAL_FLAGS are used during a rebuild AC_SUBST([ACLOCAL_AMFLAGS], ["-I $ac_macro_dir \$(ACLOCAL_FLAGS)"]) -# make _sysconfdir available for substituion in config files +# make _sysconfdir available for substitution in config files # 2 "evals" needed late to expand variable names. AC_SUBST([_sysconfdir]) AC_CONFIG_COMMANDS_PRE([eval eval _sysconfdir=$sysconfdir]) -# make _statedir available for substituion in config files +# make _statedir available for substitution in config files # 2 "evals" needed late to expand variable names. AC_SUBST([_statedir]) AC_CONFIG_COMMANDS_PRE([eval eval _statedir=$statedir]) @@ -695,7 +693,7 @@ else fi AC_SUBST(rpc_pipefsmount) -# make _rpc_pipefsmount available for substituion in config files +# make _rpc_pipefsmount available for substitution 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]) diff --git a/support/export/auth.c b/support/export/auth.c index 03ce4b8a..2d7960f1 100644 --- a/support/export/auth.c +++ b/support/export/auth.c @@ -82,7 +82,7 @@ check_useipaddr(void) } unsigned int -auth_reload() +auth_reload(void) { struct stat stb; static ino_t last_inode; diff --git a/support/export/v4clients.c b/support/export/v4clients.c index 5f15b614..32302512 100644 --- a/support/export/v4clients.c +++ b/support/export/v4clients.c @@ -26,7 +26,7 @@ void v4clients_init(void) { struct stat sb; - if (!stat("/proc/fs/nfsd/clients", &sb) == 0 || + if (stat("/proc/fs/nfsd/clients", &sb) != 0 || !S_ISDIR(sb.st_mode)) return; if (clients_fd >= 0) diff --git a/support/export/v4root.c b/support/export/v4root.c index c12a7d85..fbb0ad5f 100644 --- a/support/export/v4root.c +++ b/support/export/v4root.c @@ -198,7 +198,7 @@ static int v4root_add_parents(nfs_export *exp) * looking for components of the v4 mount. */ void -v4root_set() +v4root_set(void) { nfs_export *exp; int i; diff --git a/support/export/xtab.c b/support/export/xtab.c index c888a80a..e210ca99 100644 --- a/support/export/xtab.c +++ b/support/export/xtab.c @@ -135,7 +135,7 @@ xtab_write(char *xtab, char *xtabtmp, char *lockfn, int is_export) } int -xtab_export_write() +xtab_export_write(void) { return xtab_write(etab.statefn, etab.tmpfn, etab.lockfn, 1); } diff --git a/support/nfs/xlog.c b/support/nfs/xlog.c index e5861b9d..fa125cef 100644 --- a/support/nfs/xlog.c +++ b/support/nfs/xlog.c @@ -46,11 +46,13 @@ int export_errno = 0; static void xlog_toggle(int sig); static struct xlog_debugfac debugnames[] = { + { "0", 0, }, { "general", D_GENERAL, }, { "call", D_CALL, }, { "auth", D_AUTH, }, { "parse", D_PARSE, }, { "all", D_ALL, }, + { "1", D_ALL, }, { NULL, 0, }, }; @@ -119,13 +121,14 @@ xlog_sconfig(char *kind, int on) { struct xlog_debugfac *tbl = debugnames; - while (tbl->df_name != NULL && strcasecmp(tbl->df_name, kind)) + while (tbl->df_name != NULL && strcasecmp(tbl->df_name, kind)) tbl++; if (!tbl->df_name) { xlog (L_WARNING, "Invalid debug facility: %s\n", kind); return; } - xlog_config(tbl->df_fac, on); + if (tbl->df_fac) + xlog_config(tbl->df_fac, on); } void diff --git a/support/nfsidmap/regex.c b/support/nfsidmap/regex.c index 958b4ac8..8424179f 100644 --- a/support/nfsidmap/regex.c +++ b/support/nfsidmap/regex.c @@ -542,7 +542,7 @@ struct trans_func regex_trans = { .gss_princ_to_grouplist = regex_gss_princ_to_grouplist, }; -struct trans_func *libnfsidmap_plugin_init() +struct trans_func *libnfsidmap_plugin_init(void) { return (®ex_trans); } diff --git a/systemd/50-nfs.conf b/systemd/50-nfs.conf deleted file mode 100644 index 19e8ee73..00000000 --- a/systemd/50-nfs.conf +++ /dev/null @@ -1,16 +0,0 @@ -# Ensure all NFS systctl settings get applied when modules load - -# sunrpc module supports "sunrpc.*" sysctls -install sunrpc /sbin/modprobe --ignore-install sunrpc $CMDLINE_OPTS && { /sbin/sysctl -q --pattern sunrpc --system; exit 0; } - -# rpcrdma module supports sunrpc.svc_rdma.* -install rpcrdma /sbin/modprobe --ignore-install rpcrdma $CMDLINE_OPTS && { /sbin/sysctl -q --pattern sunrpc.svc_rdma --system; exit 0; } - -# lockd module supports "fs.nfs.nlm*" and "fs.nfs.nsm*" sysctls -install lockd /sbin/modprobe --ignore-install lockd $CMDLINE_OPTS && { /sbin/sysctl -q --pattern fs.nfs.n[sl]m --system; exit 0; } - -# nfsv4 module supports "fs.nfs.*" sysctls (nfs_callback_tcpport and idmap_cache_timeout) -install nfsv4 /sbin/modprobe --ignore-install nfsv4 $CMDLINE_OPTS && { /sbin/sysctl -q --pattern 'fs.nfs.(nfs_callback_tcpport|idmap_cache_timeout)' --system; exit 0; } - -# nfs module supports "fs.nfs.*" sysctls -install nfs /sbin/modprobe --ignore-install nfs $CMDLINE_OPTS && { /sbin/sysctl -q --pattern fs.nfs --system; exit 0; } diff --git a/systemd/60-nfs.rules b/systemd/60-nfs.rules new file mode 100644 index 00000000..188423c1 --- /dev/null +++ b/systemd/60-nfs.rules @@ -0,0 +1,21 @@ +# Ensure all NFS systctl settings get applied when modules load + +# sunrpc module supports "sunrpc.*" sysctls +ACTION=="add", SUBSYSTEM=="module", KERNEL=="sunrpc", \ + RUN+="/sbin/sysctl -q --pattern ^sunrpc --system" + +# rpcrdma module supports sunrpc.svc_rdma.* +ACTION=="add", SUBSYSTEM=="module", KERNEL=="rpcrdma", \ + RUN+="/sbin/sysctl -q --pattern ^sunrpc.svc_rdma --system" + +# lockd module supports "fs.nfs.nlm*" and "fs.nfs.nsm*" sysctls +ACTION=="add", SUBSYSTEM=="module", KERNEL=="lockd", \ + RUN+="/sbin/sysctl -q --pattern ^fs.nfs.n[sl]m --system" + +# nfsv4 module supports "fs.nfs.*" sysctls (nfs_callback_tcpport and idmap_cache_timeout) +ACTION=="add", SUBSYSTEM=="module", KERNEL=="nfsv4", \ + RUN+="/sbin/sysctl -q --pattern ^fs.nfs.(nfs_callback_tcpport|idmap_cache_timeout) --system" + +# nfs module supports "fs.nfs.*" sysctls +ACTION=="add", SUBSYSTEM=="module", KERNEL=="nfs", \ + RUN+="/sbin/sysctl -q --pattern ^fs.nfs --system" diff --git a/systemd/Makefile.am b/systemd/Makefile.am index 7b5ab84b..577c6a22 100644 --- a/systemd/Makefile.am +++ b/systemd/Makefile.am @@ -2,7 +2,8 @@ MAINTAINERCLEANFILES = Makefile.in -modprobe_files = 50-nfs.conf +udev_rulesdir = /usr/lib/udev/rules.d/ +udev_files = 60-nfs.rules unit_files = \ nfs-client.target \ @@ -53,7 +54,7 @@ endif man5_MANS = nfs.conf.man man7_MANS = nfs.systemd.man -EXTRA_DIST = $(unit_files) $(modprobe_files) $(man5_MANS) $(man7_MANS) +EXTRA_DIST = $(unit_files) $(udev_files) $(man5_MANS) $(man7_MANS) generator_dir = $(unitdir)/../system-generators @@ -75,14 +76,10 @@ rpc_pipefs_generator_LDADD = ../support/nfs/libnfs.la if INSTALL_SYSTEMD genexec_PROGRAMS = nfs-server-generator rpc-pipefs-generator -install-data-hook: $(unit_files) $(modprobe_files) +install-data-hook: $(unit_files) $(udev_files) mkdir -p $(DESTDIR)/$(unitdir) cp $(unit_files) $(DESTDIR)/$(unitdir) cp $(rpc_pipefs_mount_file) $(DESTDIR)/$(unitdir)/$(rpc_pipefsmount) -else -install-data-hook: $(modprobe_files) -endif -if INSTALL_MODPROBEDIR - mkdir -p $(DESTDIR)$(modprobedir) - cp $(modprobe_files) $(DESTDIR)$(modprobedir) + mkdir -p $(DESTDIR)/$(udev_rulesdir) + cp $(udev_files) $(DESTDIR)/$(udev_rulesdir) endif diff --git a/systemd/auth-rpcgss-module.service b/systemd/auth-rpcgss-module.service index 45482833..25c9de80 100644 --- a/systemd/auth-rpcgss-module.service +++ b/systemd/auth-rpcgss-module.service @@ -10,6 +10,7 @@ DefaultDependencies=no Before=gssproxy.service rpc-svcgssd.service rpc-gssd.service Wants=gssproxy.service rpc-svcgssd.service rpc-gssd.service ConditionPathExists=/etc/krb5.keytab +ConditionVirtualization=!container [Service] Type=oneshot diff --git a/systemd/nfs.conf.man b/systemd/nfs.conf.man index e74083e9..bfd3380f 100644 --- a/systemd/nfs.conf.man +++ b/systemd/nfs.conf.man @@ -98,6 +98,12 @@ value, which can be one or more from the list .BR parse , .BR all . When a list is given, the members should be comma-separated. +The values +.BR 0 +and +.BR 1 +are also accepted, with '0' making no changes to the debug level, and '1' equivalent to specifying 'all'. + .TP .B general Recognized values: @@ -166,6 +172,7 @@ for details. Recognized values: .BR threads , .BR host , +.BR scope , .BR port , .BR grace-time , .BR lease-time , diff --git a/tools/Makefile.am b/tools/Makefile.am index 40c17c37..48fd0cdf 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -12,6 +12,10 @@ if CONFIG_NFSDCLD OPTDIRS += nfsdclddb endif -SUBDIRS = locktest rpcdebug nlmtest mountstats nfs-iostat rpcctl nfsdclnts nfsrahead $(OPTDIRS) +if CONFIG_NFSRAHEAD +OPTDIRS += nfsrahead +endif + +SUBDIRS = locktest rpcdebug nlmtest mountstats nfs-iostat rpcctl nfsdclnts $(OPTDIRS) MAINTAINERCLEANFILES = Makefile.in diff --git a/tools/nfs-iostat/nfs-iostat.py b/tools/nfs-iostat/nfs-iostat.py index 1df74ba8..85294fb9 100755 --- a/tools/nfs-iostat/nfs-iostat.py +++ b/tools/nfs-iostat/nfs-iostat.py @@ -43,7 +43,7 @@ NfsEventCounters = [ 'vfspermission', 'vfsupdatepage', 'vfsreadpage', - 'vfsreadpages', + 'vfsreadpages', # or vfsreadahead in statvers=1.2 or above 'vfswritepage', 'vfswritepages', 'vfsreaddir', @@ -86,14 +86,14 @@ class DeviceData: self.__nfs_data['export'] = words[1] self.__nfs_data['mountpoint'] = words[4] self.__nfs_data['fstype'] = words[7] - if words[7] == 'nfs': - self.__nfs_data['statvers'] = words[8] + if words[7] == 'nfs' or words[7] == 'nfs4': + self.__nfs_data['statvers'] = float(words[8].split('=',1)[1]) elif 'nfs' in words or 'nfs4' in words: self.__nfs_data['export'] = words[0] self.__nfs_data['mountpoint'] = words[3] self.__nfs_data['fstype'] = words[6] if words[6] == 'nfs': - self.__nfs_data['statvers'] = words[7] + self.__nfs_data['statvers'] = float(words[7].split('=',1)[1]) elif words[0] == 'age:': self.__nfs_data['age'] = int(words[1]) elif words[0] == 'opts:': @@ -294,8 +294,11 @@ class DeviceData: print() print('%d nfs_readpage() calls read %d pages' % \ (vfsreadpage, vfsreadpage)) - print('%d nfs_readpages() calls read %d pages' % \ - (vfsreadpages, pages_read - vfsreadpage)) + multipageread = "readpages" + if self.__nfs_data['statvers'] >= 1.2: + multipageread = "readahead" + print('%d nfs_%s() calls read %d pages' % \ + (vfsreadpages, multipageread, pages_read - vfsreadpage)) if vfsreadpages != 0: print('(%.1f pages per call)' % \ (float(pages_read - vfsreadpage) / vfsreadpages)) diff --git a/tools/nfsrahead/Makefile.am b/tools/nfsrahead/Makefile.am index 845ea0d5..7e08233a 100644 --- a/tools/nfsrahead/Makefile.am +++ b/tools/nfsrahead/Makefile.am @@ -1,6 +1,6 @@ libexec_PROGRAMS = nfsrahead nfsrahead_SOURCES = main.c -nfsrahead_LDFLAGS= -lmount +nfsrahead_LDFLAGS= $(LIBMOUNT_LIBS) nfsrahead_LDADD = ../../support/nfs/libnfsconf.la man5_MANS = nfsrahead.man diff --git a/utils/blkmapd/device-discovery.c b/utils/blkmapd/device-discovery.c index 2736ac89..a565fdbd 100644 --- a/utils/blkmapd/device-discovery.c +++ b/utils/blkmapd/device-discovery.c @@ -187,10 +187,7 @@ static void bl_add_disk(char *filepath) } if (disk && diskpath) { - if (serial) { - free(serial->data); - free(serial); - } + bl_free_scsi_string(serial); return; } @@ -228,10 +225,7 @@ static void bl_add_disk(char *filepath) disk->size = size; disk->valid_path = path; } - if (serial) { - free(serial->data); - free(serial); - } + bl_free_scsi_string(serial); } return; @@ -241,10 +235,7 @@ static void bl_add_disk(char *filepath) free(path->full_path); free(path); } - if (serial) { - free(serial->data); - free(serial); - } + bl_free_scsi_string(serial); return; } @@ -462,7 +453,7 @@ static void sig_die(int signal) unlink(PID_FILE); } BL_LOG_ERR("exit on signal(%d)\n", signal); - exit(1); + exit(0); } static void usage(void) { @@ -507,28 +498,44 @@ int main(int argc, char **argv) if (fg) { openlog("blkmapd", LOG_PERROR, 0); } else { - if (daemon(0, 0) != 0) { - fprintf(stderr, "Daemonize failed\n"); + pid_t pid = fork(); + if (pid < 0) { + BL_LOG_ERR("fork error\n"); exit(1); + } else if (pid != 0) { + pidfd = open(PID_FILE, O_WRONLY | O_CREAT, 0644); + if (pidfd < 0) { + BL_LOG_ERR("Create pid file %s failed\n", PID_FILE); + exit(1); + } + + if (lockf(pidfd, F_TLOCK, 0) < 0) { + BL_LOG_ERR("Already running; Exiting!"); + close(pidfd); + exit(1); + } + if (ftruncate(pidfd, 0) < 0) + BL_LOG_ERR("ftruncate on %s failed: m\n", PID_FILE); + sprintf(pidbuf, "%d\n", pid); + if (write(pidfd, pidbuf, strlen(pidbuf)) != (ssize_t)strlen(pidbuf)) + BL_LOG_ERR("write on %s failed: m\n", PID_FILE); + exit(0); } - openlog("blkmapd", LOG_PID, 0); - pidfd = open(PID_FILE, O_WRONLY | O_CREAT, 0644); - if (pidfd < 0) { - BL_LOG_ERR("Create pid file %s failed\n", PID_FILE); - exit(1); + (void)setsid(); + if (chdir("/")) { + BL_LOG_ERR("chdir error\n"); } + int fd = open("/dev/null", O_RDWR, 0); + if (fd >= 0) { + (void)dup2(fd, STDIN_FILENO); + (void)dup2(fd, STDOUT_FILENO); + (void)dup2(fd, STDERR_FILENO); - if (lockf(pidfd, F_TLOCK, 0) < 0) { - BL_LOG_ERR("Already running; Exiting!"); - close(pidfd); - exit(1); + (void)close(fd); } - if (ftruncate(pidfd, 0) < 0) - BL_LOG_WARNING("ftruncate on %s failed: m\n", PID_FILE); - sprintf(pidbuf, "%d\n", getpid()); - if (write(pidfd, pidbuf, strlen(pidbuf)) != (ssize_t)strlen(pidbuf)) - BL_LOG_WARNING("write on %s failed: m\n", PID_FILE); + + openlog("blkmapd", LOG_PID, 0); } signal(SIGINT, sig_die); diff --git a/utils/blkmapd/device-discovery.h b/utils/blkmapd/device-discovery.h index a86eed99..462aa943 100644 --- a/utils/blkmapd/device-discovery.h +++ b/utils/blkmapd/device-discovery.h @@ -151,6 +151,8 @@ uint64_t process_deviceinfo(const char *dev_addr_buf, extern ssize_t atomicio(ssize_t(*f) (int, void *, size_t), int fd, void *_s, size_t n); +extern struct bl_serial *bl_create_scsi_string(int len, const char *bytes); +extern void bl_free_scsi_string(struct bl_serial *str); extern struct bl_serial *bldev_read_serial(int fd, const char *filename); extern enum bl_path_state_e bldev_read_ap_state(int fd); extern int bl_discover_devices(void); diff --git a/utils/blkmapd/device-inq.c b/utils/blkmapd/device-inq.c index c7952c3e..9e5749ef 100644 --- a/utils/blkmapd/device-inq.c +++ b/utils/blkmapd/device-inq.c @@ -53,7 +53,7 @@ #define DEF_ALLOC_LEN 255 #define MX_ALLOC_LEN (0xc000 + 0x80) -static struct bl_serial *bl_create_scsi_string(int len, const char *bytes) +struct bl_serial *bl_create_scsi_string(int len, const char *bytes) { struct bl_serial *s; @@ -66,7 +66,7 @@ static struct bl_serial *bl_create_scsi_string(int len, const char *bytes) return s; } -static void bl_free_scsi_string(struct bl_serial *str) +void bl_free_scsi_string(struct bl_serial *str) { if (str) free(str); diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c index 6ba615d1..0897b229 100644 --- a/utils/exportfs/exportfs.c +++ b/utils/exportfs/exportfs.c @@ -69,14 +69,14 @@ static int _lockfd = -1; * need these additional lockfile() routines. */ static void -grab_lockfile() +grab_lockfile(void) { _lockfd = open(lockfile, O_CREAT|O_RDWR, 0666); if (_lockfd != -1) lockf(_lockfd, F_LOCK, 0); } static void -release_lockfile() +release_lockfile(void) { if (_lockfd != -1) { lockf(_lockfd, F_ULOCK, 0); diff --git a/utils/idmapd/idmapd.c b/utils/idmapd/idmapd.c index e79c124d..cd9a965f 100644 --- a/utils/idmapd/idmapd.c +++ b/utils/idmapd/idmapd.c @@ -867,7 +867,7 @@ nfsdreopen_one(struct idmap_client *ic) } static void -nfsdreopen() +nfsdreopen(void) { nfsdreopen_one(&nfsd_ic[IC_NAMEID]); nfsdreopen_one(&nfsd_ic[IC_IDNAME]); diff --git a/utils/mount/network.c b/utils/mount/network.c index ed2f8253..01ead49f 100644 --- a/utils/mount/network.c +++ b/utils/mount/network.c @@ -179,7 +179,7 @@ static const unsigned long probe_mnt3_only[] = { static const unsigned int *nfs_default_proto(void); #ifdef MOUNT_CONFIG -static const unsigned int *nfs_default_proto() +static const unsigned int *nfs_default_proto(void) { extern unsigned long config_default_proto; /* diff --git a/utils/mount/parse_dev.c b/utils/mount/parse_dev.c index 0d3bcb95..2ade5d5d 100644 --- a/utils/mount/parse_dev.c +++ b/utils/mount/parse_dev.c @@ -170,7 +170,8 @@ static int nfs_parse_square_bracket(const char *dev, if (pathname) { *pathname = strndup(cbrace, path_len); if (*pathname == NULL) { - free(*hostname); + if (hostname) + free(*hostname); return nfs_pdn_nomem_err(); } } diff --git a/utils/nfsd/nfsd.c b/utils/nfsd/nfsd.c index 4016a761..249df00b 100644 --- a/utils/nfsd/nfsd.c +++ b/utils/nfsd/nfsd.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "conffile.h" #include "nfslib.h" @@ -39,6 +40,7 @@ static void usage(const char *); static struct option longopts[] = { { "host", 1, 0, 'H' }, + { "scope", 1, 0, 'S'}, { "help", 0, 0, 'h' }, { "no-nfs-version", 1, 0, 'N' }, { "nfs-version", 1, 0, 'V' }, @@ -69,6 +71,7 @@ main(int argc, char **argv) int count = NFSD_NPROC, c, i, error = 0, portnum, fd, found_one; char *p, *progname, *port, *rdma_port = NULL; char **haddr = NULL; + char *scope = NULL; int hcounter = 0; struct conf_list *hosts; int socket_up = 0; @@ -168,8 +171,9 @@ main(int argc, char **argv) hcounter++; } } + scope = conf_get_str("nfsd", "scope"); - while ((c = getopt_long(argc, argv, "dH:hN:V:p:P:stTuUrG:L:", longopts, NULL)) != EOF) { + while ((c = getopt_long(argc, argv, "dH:S:hN:V:p:P:stTuUrG:L:", longopts, NULL)) != EOF) { switch(c) { case 'd': xlog_config(D_ALL, 1); @@ -190,6 +194,9 @@ main(int argc, char **argv) haddr[hcounter] = optarg; hcounter++; break; + case 'S': + scope = optarg; + break; case 'P': /* XXX for nfs-server compatibility */ case 'p': /* only the last -p option has any effect */ @@ -367,6 +374,14 @@ main(int argc, char **argv) if (lease > 0) nfssvc_set_time("lease", lease); + if (scope) { + if (unshare(CLONE_NEWUTS) < 0 || + sethostname(scope, strlen(scope)) < 0) { + xlog(L_ERROR, "Unable to set server scope: %m"); + error = -1; + goto out; + } + } i = 0; do { error = nfssvc_set_sockets(protobits, haddr[i], port); diff --git a/utils/nfsd/nfsd.man b/utils/nfsd/nfsd.man index 634b8a63..dc05f362 100644 --- a/utils/nfsd/nfsd.man +++ b/utils/nfsd/nfsd.man @@ -35,9 +35,17 @@ Note that .B lockd (which performs file locking services for NFS) may still accept request on all known network addresses. This may change in future -releases of the Linux Kernel. This option can be used multiple time +releases of the Linux Kernel. This option can be used multiple times to listen to more than one interface. .TP +.B \S " or " \-\-scope scope +NFSv4.1 and later require the server to report a "scope" which is used +by the clients to detect if two connections are to the same server. +By default Linux NFSD uses the host name as the scope. +.sp +It is particularly important for high-availablity configurations to ensure +that all potential server nodes report the same server scope. +.TP .B \-p " or " \-\-port port specify a different port to listen on for NFS requests. By default, .B rpc.nfsd @@ -134,6 +142,9 @@ will listen on. Use of the .B --host option replaces all host names listed here. .TP +.B scope +Set the server scope. +.TP .B grace-time The grace time, for both NFSv4 and NLM, in seconds. .TP @@ -159,7 +170,9 @@ Enable or disable TCP support. .B vers3 .TP .B vers4 -Enable or disable a major NFS version. 3 and 4 are normally enabled +Enable or disable +.B all +NFSv4 versions. All versions are normally enabled by default. .TP .B vers4.1