diff --git a/.gitignore b/.gitignore index 5164637..126d12c 100644 --- a/.gitignore +++ b/.gitignore @@ -69,6 +69,9 @@ tests/nsm_client/nlm_sm_inter_clnt.c tests/nsm_client/nlm_sm_inter_svc.c tests/nsm_client/nlm_sm_inter_xdr.c utils/nfsidmap/nfsidmap +systemd/nfs-server-generator +systemd/nfs-config.service +systemd/rpc-gssd.service # cscope database files cscope.* # generic editor backup et al diff --git a/Makefile.am b/Makefile.am index 4a2edc6..e1f39aa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,7 +23,6 @@ ACLOCAL_AMFLAGS = -I aclocal install-data-hook: if [ ! -d $(DESTDIR)$(statedir) ]; then mkdir -p $(DESTDIR)$(statedir); fi - touch $(DESTDIR)$(statedir)/xtab; chmod 644 $(DESTDIR)$(statedir)/xtab touch $(DESTDIR)$(statedir)/etab; chmod 644 $(DESTDIR)$(statedir)/etab touch $(DESTDIR)$(statedir)/rmtab; chmod 644 $(DESTDIR)$(statedir)/rmtab mkdir -p $(DESTDIR)$(statdpath)/sm $(DESTDIR)$(statdpath)/sm.bak @@ -32,7 +31,7 @@ install-data-hook: -chown $(statduser) $(DESTDIR)$(statdpath)/sm $(DESTDIR)$(statdpath)/sm.bak $(DESTDIR)$(statdpath)/state uninstall-hook: - rm $(DESTDIR)$(statedir)/xtab + rm -f $(DESTDIR)$(statedir)/xtab rm $(DESTDIR)$(statedir)/etab rm $(DESTDIR)$(statedir)/rmtab rm $(DESTDIR)$(statdpath)/state diff --git a/configure.ac b/configure.ac index 1daf5b8..8a5aa2e 100644 --- a/configure.ac +++ b/configure.ac @@ -24,6 +24,12 @@ AC_ARG_WITH(statedir, statedir=$withval, statedir=/var/lib/nfs) AC_SUBST(statedir) +AC_ARG_WITH(nfsconfig, + [AC_HELP_STRING([--with-nfsconfig=/config/file], + [use general config file /config/file @<:@default=/etc/nfs.conf@:>@])], + nfsconfig=$withval, + nfsconfig=/etc/nfs.conf) + AC_SUBST(nfsconfig) AC_ARG_WITH(statdpath, [AC_HELP_STRING([--with-statdpath=/foo], [define the statd state dir as /foo instead of the NFS statedir @<:@default=/var/lib/nfs@:>@])], @@ -468,6 +474,7 @@ dnl Export some path names to config.h dnl ************************************************************* AC_DEFINE_UNQUOTED(NFS_STATEDIR, "$statedir", [This defines the location of the NFS state files. Warning: this must match definitions in config.mk!]) AC_DEFINE_UNQUOTED(NSM_DEFAULT_STATEDIR, "$statdpath", [Define this to the pathname where statd keeps its state file]) +AC_DEFINE_UNQUOTED(NFS_CONFFILE, "$nfsconfig", [This defines the location of NFS daemon config file]) if test "x$cross_compiling" = "xno"; then CFLAGS_FOR_BUILD=${CFLAGS_FOR_BUILD-"$CFLAGS"} @@ -511,8 +518,20 @@ AC_SUBST([AM_CFLAGS], ["$my_am_cflags"]) # Make sure that $ACLOCAL_FLAGS are used during a rebuild AC_SUBST([ACLOCAL_AMFLAGS], ["-I $ac_macro_dir \$(ACLOCAL_FLAGS)"]) +# make libexecdir available for substituion in config files +# 2 "evals" needed late to expand variable names. +AC_SUBST([_libexecdir]) +AC_CONFIG_COMMANDS_PRE([eval eval _libexecdir=$libexecdir]) + +# make _sysconfdir available for substituion in config files +# 2 "evals" needed late to expand variable names. +AC_SUBST([_sysconfdir]) +AC_CONFIG_COMMANDS_PRE([eval eval _sysconfdir=$sysconfdir]) + AC_CONFIG_FILES([ Makefile + systemd/nfs-config.service + systemd/rpc-gssd.service linux-nfs/Makefile support/Makefile support/export/Makefile diff --git a/support/export/export.c b/support/export/export.c index e1bebce..15e91cb 100644 --- a/support/export/export.c +++ b/support/export/export.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include "xmalloc.h" #include "nfslib.h" #include "exportfs.h" @@ -68,11 +70,15 @@ static void warn_duplicated_exports(nfs_export *exp, struct exportent *eep) /** * export_read - read entries from /etc/exports * @fname: name of file to read from + * @ignore_hosts: don't check validity of host names * * Returns number of read entries. + * @ignore_hosts can be set when the host names won't be used + * and when getting delays or errors due to problems with + * hostname looking is not acceptable. */ int -export_read(char *fname) +export_read(char *fname, int ignore_hosts) { struct exportent *eep; nfs_export *exp; @@ -81,7 +87,7 @@ export_read(char *fname) setexportent(fname, "r"); while ((eep = getexportent(0,1)) != NULL) { - exp = export_lookup(eep->e_hostname, eep->e_path, 0); + exp = export_lookup(eep->e_hostname, eep->e_path, ignore_hosts); if (!exp) { if (export_create(eep, 0)) /* possible complaints already logged */ @@ -96,6 +102,70 @@ export_read(char *fname) } /** + * export_d_read - read entries from /etc/exports. + * @fname: name of directory to read from + * @ignore_hosts: don't check validity of host names + * + * Returns number of read entries. + * Based on mnt_table_parse_dir() in + * util-linux-ng/shlibs/mount/src/tab_parse.c + */ +int +export_d_read(const char *dname, int ignore_hosts) +{ + int n = 0, i; + struct dirent **namelist = NULL; + int volumes = 0; + + + n = scandir(dname, &namelist, NULL, versionsort); + if (n < 0) { + if (errno == ENOENT) + /* Silently return */ + return volumes; + xlog(L_NOTICE, "scandir %s: %s", dname, strerror(errno)); + } else if (n == 0) + return volumes; + + for (i = 0; i < n; i++) { + struct dirent *d = namelist[i]; + size_t namesz; + char fname[PATH_MAX + 1]; + int fname_len; + + + if (d->d_type != DT_UNKNOWN + && d->d_type != DT_REG + && d->d_type != DT_LNK) + continue; + if (*d->d_name == '.') + continue; + +#define _EXT_EXPORT_SIZ (sizeof(_EXT_EXPORT) - 1) + namesz = strlen(d->d_name); + if (!namesz + || namesz < _EXT_EXPORT_SIZ + 1 + || strcmp(d->d_name + (namesz - _EXT_EXPORT_SIZ), + _EXT_EXPORT)) + continue; + + fname_len = snprintf(fname, PATH_MAX +1, "%s/%s", dname, d->d_name); + if (fname_len > PATH_MAX) { + xlog(L_WARNING, "Too long file name: %s in %s", d->d_name, dname); + continue; + } + + volumes += export_read(fname, ignore_hosts); + } + + for (i = 0; i < n; i++) + free(namelist[i]); + free(namelist); + + return volumes; +} + +/** * export_create - create an in-core nfs_export record from an export entry * @xep: export entry to lookup * @canonical: if set, e_hostname is known to be canonical DNS name diff --git a/support/export/xtab.c b/support/export/xtab.c index e953071..10d9dbc 100644 --- a/support/export/xtab.c +++ b/support/export/xtab.c @@ -1,7 +1,7 @@ /* * support/export/xtab.c * - * Interface to the xtab file. + * Interface to the etab/exports file. * * Copyright (C) 1995, 1996 Olaf Kirch */ @@ -29,7 +29,6 @@ xtab_read(char *xtab, char *lockfn, int is_export) { /* is_export == 0 => reading /proc/fs/nfs/exports - we know these things are exported to kernel * is_export == 1 => reading /var/lib/nfs/etab - these things are allowed to be exported - * is_export == 2 => reading /var/lib/nfs/xtab - these things might be known to kernel */ struct exportent *xp; nfs_export *exp; @@ -55,9 +54,6 @@ xtab_read(char *xtab, char *lockfn, int is_export) if ((xp->e_flags & NFSEXP_FSID) && xp->e_fsid == 0) v4root_needed = 0; break; - case 2: - exp->m_exported = -1;/* may be exported */ - break; } } endexportent(); @@ -79,7 +75,7 @@ xtab_mount_read(void) return xtab_read(_PATH_PROC_EXPORTS_ALT, _PATH_PROC_EXPORTS_ALT, 0); } else - return xtab_read(_PATH_XTAB, _PATH_XTABLCK, 2); + return 0; } int @@ -135,29 +131,6 @@ xtab_export_write() return xtab_write(_PATH_ETAB, _PATH_ETABTMP, _PATH_ETABLCK, 1); } -int -xtab_mount_write() -{ - return xtab_write(_PATH_XTAB, _PATH_XTABTMP, _PATH_XTABLCK, 0); -} - -void -xtab_append(nfs_export *exp) -{ - struct exportent xe; - int lockid; - - if ((lockid = xflock(_PATH_XTABLCK, "w")) < 0) - return; - setexportent(_PATH_XTAB, "a"); - xe = exp->m_export; - xe.e_hostname = exp->m_client->m_hostname; - putexportent(&xe); - endexportent(); - xfunlock(lockid); - exp->m_xtabent = 1; -} - /* * rename newfile onto oldfile unless * they are identical diff --git a/support/include/exportfs.h b/support/include/exportfs.h index 4cac203..08ef30a 100644 --- a/support/include/exportfs.h +++ b/support/include/exportfs.h @@ -96,7 +96,7 @@ typedef struct mexport { struct mexport * m_next; struct mclient * m_client; struct exportent m_export; - int m_exported; /* known to knfsd. -1 means not sure */ + int m_exported; /* known to knfsd. */ int m_xtabent : 1, /* xtab entry exists */ m_mayexport: 1, /* derived from xtabbed */ m_changed : 1, /* options (may) have changed */ @@ -134,7 +134,8 @@ struct addrinfo * client_resolve(const struct sockaddr *sap); int client_member(const char *client, const char *name); -int export_read(char *fname); +int export_read(char *fname, int ignore_hosts); +int export_d_read(const char *dname, int ignore_hosts); void export_reset(nfs_export *); nfs_export * export_lookup(char *hname, char *path, int caconical); nfs_export * export_find(const struct addrinfo *ai, @@ -149,9 +150,7 @@ int export_unexport(nfs_export *); int xtab_mount_read(void); int xtab_export_read(void); -int xtab_mount_write(void); int xtab_export_write(void); -void xtab_append(nfs_export *); int secinfo_addflavor(struct flav_info *, struct exportent *); diff --git a/support/include/nfslib.h b/support/include/nfslib.h index ddd71ac..777f398 100644 --- a/support/include/nfslib.h +++ b/support/include/nfslib.h @@ -35,15 +35,6 @@ #ifndef _PATH_IDMAPDCONF #define _PATH_IDMAPDCONF "/etc/idmapd.conf" #endif -#ifndef _PATH_XTAB -#define _PATH_XTAB NFS_STATEDIR "/xtab" -#endif -#ifndef _PATH_XTABTMP -#define _PATH_XTABTMP NFS_STATEDIR "/xtab.tmp" -#endif -#ifndef _PATH_XTABLCK -#define _PATH_XTABLCK NFS_STATEDIR "/.xtab.lock" -#endif #ifndef _PATH_ETAB #define _PATH_ETAB NFS_STATEDIR "/etab" #endif diff --git a/systemd/Makefile.am b/systemd/Makefile.am index 03f96e9..49c9b8d 100644 --- a/systemd/Makefile.am +++ b/systemd/Makefile.am @@ -39,8 +39,16 @@ endif EXTRA_DIST = $(unit_files) unit_dir = /usr/lib/systemd/system +generator_dir = /usr/lib/systemd/system-generators + +EXTRA_PROGRAMS = nfs-server-generator +genexecdir = $(generator_dir) +nfs_server_generator_LDADD = ../support/export/libexport.a \ + ../support/nfs/libnfs.a \ + ../support/misc/libmisc.a if INSTALL_SYSTEMD +genexec_PROGRAMS = nfs-server-generator install-data-hook: $(unit_files) mkdir -p $(DESTDIR)/$(unitdir) cp $(unit_files) $(DESTDIR)/$(unitdir) diff --git a/systemd/nfs-config.service b/systemd/nfs-config.service deleted file mode 100644 index bd69e84..0000000 --- a/systemd/nfs-config.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Preprocess NFS configuration -After=local-fs.target -DefaultDependencies=no - -[Service] -Type=oneshot -# This service needs to run any time any nfs service -# is started, so changes to local config files get -# incorporated. Having "RemainAfterExit=no" (the default) -# ensures this happens. -RemainAfterExit=no -ExecStart=/usr/libexec/nfs-utils/nfs-utils_env.sh diff --git a/systemd/nfs-config.service.in b/systemd/nfs-config.service.in new file mode 100644 index 0000000..e89dc54 --- /dev/null +++ b/systemd/nfs-config.service.in @@ -0,0 +1,13 @@ +[Unit] +Description=Preprocess NFS configuration +After=local-fs.target +DefaultDependencies=no + +[Service] +Type=oneshot +# This service needs to run any time any nfs service +# is started, so changes to local config files get +# incorporated. Having "RemainAfterExit=no" (the default) +# ensures this happens. +RemainAfterExit=no +ExecStart=@_libexecdir@/nfs-utils/nfs-utils_env.sh diff --git a/systemd/nfs-server-generator.c b/systemd/nfs-server-generator.c new file mode 100644 index 0000000..7c40b3f --- /dev/null +++ b/systemd/nfs-server-generator.c @@ -0,0 +1,150 @@ +/* + * nfs-server-generator: + * systemd generator to create ordering dependencies between + * nfs-server and various filesystem mounts + * + * 1/ nfs-server should start Before any 'nfs' mountpoints are + * mounted, in case they are loop-back mounts. This ordering is particularly + * important for the shutdown side, so the nfs-server is stopped + * after the filesystems are unmounted. + * 2/ nfs-server should start After all exported filesystems are mounted + * so there is no risk of exporting the underlying directory. + * This is particularly important for _net mounts which + * are not caught by "local-fs.target". + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "misc.h" +#include "nfslib.h" +#include "exportfs.h" + +/* A simple "set of strings" to remove duplicates + * found in /etc/exports + */ +struct list { + struct list *next; + char *name; +}; +static int is_unique(struct list **lp, char *path) +{ + struct list *l = *lp; + + while (l) { + if (strcmp(l->name, path) == 0) + return 0; + l = l->next; + } + l = malloc(sizeof(*l)); + if (l == NULL) + return 0; + l->name = path; + l->next = *lp; + *lp = l; + return 1; +} + +/* We need to convert a path name to a systemd unit + * name. This requires some translation ('/' -> '-') + * and some escaping. + */ +static void systemd_escape(FILE *f, char *path) +{ + while (*path == '/') + path++; + if (!*path) { + /* "/" becomes "-", otherwise leading "/" is ignored */ + fputs("-", f); + return; + } + while (*path) { + char c = *path++; + + if (c == '/') { + /* multiple non-trailing slashes become '-' */ + while (*path == '/') + path++; + if (*path) + fputs("-", f); + } else if (isalnum(c) || c == ':' || c == '.') + fputc(c, f); + else + fprintf(f, "\\x%02x", c & 0xff); + } +} + +int main(int argc, char *argv[]) +{ + char *path; + char dirbase[] = "/nfs-server.service.d"; + char filebase[] = "/order-with-mounts.conf"; + nfs_export *exp; + int i; + struct list *list = NULL; + FILE *f, *fstab; + struct mntent *mnt; + + if (argc != 4 || argv[1][0] != '/') { + fprintf(stderr, "nfs-server-generator: create systemd dependencies for nfs-server\n"); + fprintf(stderr, "Usage: normal-dir early-dir late-dir\n"); + exit(1); + } + + path = malloc(strlen(argv[1]) + sizeof(dirbase) + sizeof(filebase)); + if (!path) + exit(2); + if (export_read(_PATH_EXPORTS, 1) + + export_d_read(_PATH_EXPORTS_D, 1) == 0) + /* Nothing is exported, so nothing to do */ + exit(0); + + strcat(strcpy(path, argv[1]), dirbase); + mkdir(path, 0755); + strcat(path, filebase); + f = fopen(path, "w"); + if (!f) + exit(1); + fprintf(f, "# Automatically generated by nfs-server-generator\n\n[Unit]\n"); + + for (i = 0; i < MCL_MAXTYPES; i++) { + for (exp = exportlist[i].p_head; exp; exp = exp->m_next) { + if (!is_unique(&list, exp->m_export.e_path)) + continue; + if (strchr(exp->m_export.e_path, ' ')) + fprintf(f, "RequiresMountsFor=\"%s\"\n", + exp->m_export.e_path); + else + fprintf(f, "RequiresMountsFor=%s\n", + exp->m_export.e_path); + } + } + + fstab = setmntent("/etc/fstab", "r"); + if (!fstab) + exit(1); + + while ((mnt = getmntent(fstab)) != NULL) { + if (strcmp(mnt->mnt_type, "nfs") != 0 && + strcmp(mnt->mnt_type, "nfs4") != 0) + continue; + fprintf(f, "Before= "); + systemd_escape(f, mnt->mnt_dir); + fprintf(f, ".mount\n"); + } + + fclose(fstab); + fclose(f); + + exit(0); +} diff --git a/systemd/nfs-server.service b/systemd/nfs-server.service index 2ccdc63..196c818 100644 --- a/systemd/nfs-server.service +++ b/systemd/nfs-server.service @@ -16,9 +16,6 @@ Before= rpc-statd-notify.service Wants=auth-rpcgss-module.service After=rpc-gssd.service gssproxy.service rpc-svcgssd.service -# start/stop server before/after client -Before=remote-fs-pre.target - Wants=nfs-config.service After=nfs-config.service diff --git a/systemd/rpc-gssd.service b/systemd/rpc-gssd.service deleted file mode 100644 index d4a3819..0000000 --- a/systemd/rpc-gssd.service +++ /dev/null @@ -1,19 +0,0 @@ -[Unit] -Description=RPC security service for NFS client and server -DefaultDependencies=no -Conflicts=umount.target -Requires=var-lib-nfs-rpc_pipefs.mount -After=var-lib-nfs-rpc_pipefs.mount - -ConditionPathExists=/etc/krb5.keytab - -PartOf=nfs-utils.service - -Wants=nfs-config.service -After=nfs-config.service - -[Service] -EnvironmentFile=-/run/sysconfig/nfs-utils - -Type=forking -ExecStart=/usr/sbin/rpc.gssd $GSSDARGS diff --git a/systemd/rpc-gssd.service.in b/systemd/rpc-gssd.service.in new file mode 100644 index 0000000..1a7911c --- /dev/null +++ b/systemd/rpc-gssd.service.in @@ -0,0 +1,19 @@ +[Unit] +Description=RPC security service for NFS client and server +DefaultDependencies=no +Conflicts=umount.target +Requires=var-lib-nfs-rpc_pipefs.mount +After=var-lib-nfs-rpc_pipefs.mount + +ConditionPathExists=@_sysconfdir@/krb5.keytab + +PartOf=nfs-utils.service + +Wants=nfs-config.service +After=nfs-config.service + +[Service] +EnvironmentFile=-/run/sysconfig/nfs-utils + +Type=forking +ExecStart=/usr/sbin/rpc.gssd $GSSDARGS diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py index 4ca4bc4..88ccdae 100644 --- a/tools/mountstats/mountstats.py +++ b/tools/mountstats/mountstats.py @@ -412,6 +412,8 @@ class DeviceData: print(' short reads: %d short writes: %d' % \ (self.__nfs_data['shortreads'], self.__nfs_data['shortwrites'])) print(' NFSERR_DELAYs from server: %d' % self.__nfs_data['delay']) + print(' pNFS READs: %d' % self.__nfs_data['pnfsreads']) + print(' pNFS WRITEs: %d' % self.__nfs_data['pnfswrites']) def display_nfs_bytes(self): """Pretty-print the NFS event counters diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c index a00b5ea..98368a5 100644 --- a/utils/exportfs/exportfs.c +++ b/utils/exportfs/exportfs.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -47,7 +46,6 @@ static void error(nfs_export *exp, int err); static void usage(const char *progname, int n); static void validate_export(nfs_export *exp); static int matchhostname(const char *hostname1, const char *hostname2); -static int export_d_read(const char *dname); static void grab_lockfile(void); static void release_lockfile(void); @@ -185,8 +183,8 @@ main(int argc, char **argv) atexit(release_lockfile); if (f_export && ! f_ignore) { - if (! (export_read(_PATH_EXPORTS) + - export_d_read(_PATH_EXPORTS_D))) { + if (! (export_read(_PATH_EXPORTS, 0) + + export_d_read(_PATH_EXPORTS_D, 0))) { if (f_verbose) xlog(L_WARNING, "No file systems exported!"); } @@ -221,8 +219,6 @@ main(int argc, char **argv) xtab_export_write(); if (new_cache) cache_flush(force_flush); - if (!new_cache) - xtab_mount_write(); return export_errno; } @@ -240,7 +236,7 @@ exports_update_one(nfs_export *exp, int verbose) exp->m_export.e_path, exp->m_export.e_mountpoint); exp->m_mayexport = 0; } - if (exp->m_mayexport && ((exp->m_exported<1) || exp->m_changed)) { + if (exp->m_mayexport && exp->m_changed) { if (verbose) printf("%sexporting %s:%s to kernel\n", exp->m_exported ?"re":"", @@ -700,63 +696,6 @@ out: return result; } -/* Based on mnt_table_parse_dir() in - util-linux-ng/shlibs/mount/src/tab_parse.c */ -static int -export_d_read(const char *dname) -{ - int n = 0, i; - struct dirent **namelist = NULL; - int volumes = 0; - - - n = scandir(dname, &namelist, NULL, versionsort); - if (n < 0) { - if (errno == ENOENT) - /* Silently return */ - return volumes; - xlog(L_NOTICE, "scandir %s: %s", dname, strerror(errno)); - } else if (n == 0) - return volumes; - - for (i = 0; i < n; i++) { - struct dirent *d = namelist[i]; - size_t namesz; - char fname[PATH_MAX + 1]; - int fname_len; - - - if (d->d_type != DT_UNKNOWN - && d->d_type != DT_REG - && d->d_type != DT_LNK) - continue; - if (*d->d_name == '.') - continue; - -#define _EXT_EXPORT_SIZ (sizeof(_EXT_EXPORT) - 1) - namesz = strlen(d->d_name); - if (!namesz - || namesz < _EXT_EXPORT_SIZ + 1 - || strcmp(d->d_name + (namesz - _EXT_EXPORT_SIZ), - _EXT_EXPORT)) - continue; - - fname_len = snprintf(fname, PATH_MAX +1, "%s/%s", dname, d->d_name); - if (fname_len > PATH_MAX) { - xlog(L_WARNING, "Too long file name: %s in %s", d->d_name, dname); - continue; - } - - volumes += export_read(fname); - } - - for (i = 0; i < n; i++) - free(namelist[i]); - free(namelist); - - return volumes; -} - static char dumpopt(char c, char *fmt, ...) { diff --git a/utils/idmapd/idmapd.man b/utils/idmapd/idmapd.man index b9200c7..d4ab894 100644 --- a/utils/idmapd/idmapd.man +++ b/utils/idmapd/idmapd.man @@ -23,6 +23,29 @@ is the NFSv4 ID <-> name mapping daemon. It provides functionality to the NFSv4 kernel client and server, to which it communicates via upcalls, by translating user and group IDs to names, and vice versa. .Pp +The system derives the +.I user +part of the string by performing a password or group lookup. +The lookup mechanism is configured in +.Pa /etc/idmapd.conf +.Pp +By default, the +.I domain +part of the string is the system's DNS domain name. +It can also be specified in +.Pa /etc/idmapd.conf +if the system is multi-homed, +or if the system's DNS domain name does +not match the name of the system's Kerberos realm. +.Pp +When the domain is not specified in /etc/idmapd.conf +the local DNS server will be queried for the +.Sy _nfsv4idmapdomain +text record. If the record exists +that will be used as the domain. When the record +does not exist, the domain part of the DNS domain +will used. +.Pp Note that on more recent kernels only the NFSv4 server uses .Nm . The NFSv4 client instead uses diff --git a/utils/mount/stropts.c b/utils/mount/stropts.c index 9de6794..d5dfb5e 100644 --- a/utils/mount/stropts.c +++ b/utils/mount/stropts.c @@ -948,6 +948,7 @@ static int nfs_is_permanent_error(int error) case ETIMEDOUT: case ECONNREFUSED: case EHOSTUNREACH: + case EOPNOTSUPP: /* aka RPC_PROGNOTREGISTERED */ case EAGAIN: return 0; /* temporary */ default: @@ -1019,8 +1020,7 @@ static int nfsmount_parent(struct nfsmount_info *mi) if (nfs_try_mount(mi)) return EX_SUCCESS; - /* retry background mounts when the server is not up */ - if (nfs_is_permanent_error(errno) && errno != EOPNOTSUPP) { + if (nfs_is_permanent_error(errno)) { mount_error(mi->spec, mi->node, errno); return EX_FAIL; } @@ -1055,8 +1055,7 @@ static int nfsmount_child(struct nfsmount_info *mi) if (nfs_try_mount(mi)) return EX_SUCCESS; - /* retry background mounts when the server is not up */ - if (nfs_is_permanent_error(errno) && errno != EOPNOTSUPP) + if (nfs_is_permanent_error(errno)) break; if (time(NULL) > timeout) diff --git a/utils/mountd/auth.c b/utils/mountd/auth.c index 0881d9a..b612d88 100644 --- a/utils/mountd/auth.c +++ b/utils/mountd/auth.c @@ -46,7 +46,6 @@ void auth_init(void) { auth_reload(); - xtab_mount_write(); } /* diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c index 7a51b09..981abd4 100644 --- a/utils/mountd/mountd.c +++ b/utils/mountd/mountd.c @@ -107,7 +107,6 @@ unregister_services (void) static void cleanup_lockfiles (void) { - unlink(_PATH_XTABLCK); unlink(_PATH_ETABLCK); unlink(_PATH_RMTABLCK); } @@ -289,7 +288,7 @@ mount_umntall_1_svc(struct svc_req *rqstp, void *UNUSED(argp), xlog(D_CALL, "Received UMNTALL request from %s", host_ntop(sap, buf, sizeof(buf))); - /* Reload /etc/xtab if necessary */ + /* Reload /etc/exports if necessary */ auth_reload(); mountlist_del_all(nfs_getrpccaller(rqstp->rq_xprt)); @@ -350,7 +349,7 @@ mount_pathconf_2_svc(struct svc_req *rqstp, dirpath *path, ppathcnf *res) if (*p == '\0') p = "/"; - /* Reload /etc/xtab if necessary */ + /* Reload /etc/exports if necessary */ auth_reload(); /* Resolve symlinks */ @@ -531,12 +530,6 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret, } else { int did_export = 0; retry: - if (exp->m_exported<1) { - export_export(exp); - did_export = 1; - } - if (!exp->m_xtabent) - xtab_append(exp); if (v3) fh = getfh_size((struct sockaddr_in *)sap, p, 64); diff --git a/utils/nfsdcltrack/nfsdcltrack.c b/utils/nfsdcltrack/nfsdcltrack.c index fcdda7f..e6e514b 100644 --- a/utils/nfsdcltrack/nfsdcltrack.c +++ b/utils/nfsdcltrack/nfsdcltrack.c @@ -43,6 +43,7 @@ #include #endif +#include "conffile.h" #include "xlog.h" #include "sqlite.h" @@ -55,6 +56,8 @@ /* defined by RFC 3530 */ #define NFS4_OPAQUE_LIMIT 1024 +char *conf_path = NFS_CONFFILE; + /* private data structures */ struct cltrack_cmd { char *name; @@ -553,6 +556,7 @@ int main(int argc, char **argv) { char arg; + char *val; int rc = 0; char *progname, *cmdarg = NULL; struct cltrack_cmd *cmd; @@ -562,6 +566,14 @@ main(int argc, char **argv) xlog_syslog(1); xlog_stderr(0); + conf_init(); + val = conf_get_str("nfsdcltrack", "storagedir"); + if (val) + storagedir = val; + rc = conf_get_num("nfsdcltrack", "debug", 0); + if (rc > 0) + xlog_config(D_ALL, 1); + /* process command-line options */ while ((arg = getopt_long(argc, argv, "hdfs:", longopts, NULL)) != EOF) { diff --git a/utils/nfsdcltrack/nfsdcltrack.man b/utils/nfsdcltrack/nfsdcltrack.man index 4b8f4d7..cc24b7a 100644 --- a/utils/nfsdcltrack/nfsdcltrack.man +++ b/utils/nfsdcltrack/nfsdcltrack.man @@ -67,6 +67,20 @@ Check to see if a nfs_client_id4 is allowed to reclaim. This command requires a .IP "\fBgracedone\fR" 4 .IX Item "gracedone" Remove any unreclaimed client records from the database. This command requires a epoch boot time as an argument. +.SH "EXTERNAL CONFIGURATION" +The directory for stable storage information can be set via the file +.B /etc/nfs.conf +by setting the +.B storagedir +value in the +.B nfsdcltrack +section. For example: +.in +5 +[nfsdcltrack] +.br + storagedir = /shared/nfs/nfsdcltrack +.in -5 +Debuging to syslog can also be enabled by setting "debug = 1" in this file. .SH "LEGACY TRANSITION MECHANISM" .IX Header "LEGACY TRANSITION MECHANISM" The Linux kernel NFSv4 server has historically tracked this information diff --git a/utils/nfsidmap/nfsidmap.man b/utils/nfsidmap/nfsidmap.man index 2f17cf2..2af16f3 100644 --- a/utils/nfsidmap/nfsidmap.man +++ b/utils/nfsidmap/nfsidmap.man @@ -39,6 +39,15 @@ if the system is multi-homed, or if the system's DNS domain name does not match the name of the system's Kerberos realm. .PP +When the domain is not specified in +.I /etc/idmapd.conf +the local DNS server will be queried for the +.I _nfsv4idmapdomain +text record. If the record exists +that will be used as the domain. When the record +does not exist, the domain part of the DNS domain +will used. +.PP The .I /usr/sbin/nfsidmap program performs translations on behalf of the kernel.