diff --git a/configure.ac b/configure.ac index 93a1202..58d1728 100644 --- a/configure.ac +++ b/configure.ac @@ -175,14 +175,14 @@ else fi AC_ARG_ENABLE(sbin-override, - [AS_HELP_STRING([--disable-sbin-override],[Don't force nfsdcltrack and mount helpers into /sbin: always honour --sbindir])], + [AS_HELP_STRING([--disable-sbin-override],[Do not force nfsdcltrack and mount helpers into /sbin: always honour --sbindir])], enable_sbin_override=$enableval, enable_sbin_override=yes) AM_CONDITIONAL(CONFIG_SBIN_OVERRIDE, [test "$enable_sbin_override" = "yes"]) AC_ARG_ENABLE(junction, - [AS_HELP_STRING([--enable-junction],[enable support for NFS junctions @<:@default=no@:>@])], + [AS_HELP_STRING([--enable-junction],[enable support for NFS junctions @<:@default=yes@:>@])], enable_junction=$enableval, - enable_junction=no) + enable_junction=yes) if test "$enable_junction" = yes; then AC_DEFINE(HAVE_JUNCTION_SUPPORT, 1, [Define this if you want junction support compiled in]) diff --git a/support/export/export.c b/support/export/export.c index 3e48c42..100912c 100644 --- a/support/export/export.c +++ b/support/export/export.c @@ -119,7 +119,7 @@ export_read(char *fname, int ignore_hosts) int reexport_found = 0; setexportent(fname, "r"); - while ((eep = getexportent(0,1)) != NULL) { + while ((eep = getexportent(0)) != NULL) { exp = export_lookup(eep->e_hostname, eep->e_path, ignore_hosts); if (!exp) { if (export_create(eep, 0)) diff --git a/support/export/xtab.c b/support/export/xtab.c index e210ca9..282f15b 100644 --- a/support/export/xtab.c +++ b/support/export/xtab.c @@ -47,7 +47,7 @@ xtab_read(char *xtab, char *lockfn, int is_export) setexportent(xtab, "r"); if (is_export == 1) v4root_needed = 1; - while ((xp = getexportent(is_export==0, 0)) != NULL) { + while ((xp = getexportent(is_export==0)) != NULL) { if (!(exp = export_lookup(xp->e_hostname, xp->e_path, is_export != 1)) && !(exp = export_create(xp, is_export!=1))) { if(xp->e_hostname) { diff --git a/support/include/conffile.h b/support/include/conffile.h index c4a3ca6..c04cd1e 100644 --- a/support/include/conffile.h +++ b/support/include/conffile.h @@ -62,7 +62,7 @@ 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_init_file(const char *); extern void conf_cleanup(void); extern int conf_match_num(const char *, const char *, int); extern int conf_remove(int, const char *, const char *); diff --git a/support/include/nfslib.h b/support/include/nfslib.h index bdbde78..eff2a48 100644 --- a/support/include/nfslib.h +++ b/support/include/nfslib.h @@ -111,7 +111,7 @@ struct rmtabent { * configuration file parsing */ void setexportent(char *fname, char *type); -struct exportent * getexportent(int,int); +struct exportent * getexportent(int); void secinfo_show(FILE *fp, struct exportent *ep); void xprtsecinfo_show(FILE *fp, struct exportent *ep); void putexportent(struct exportent *xep); diff --git a/support/junction/junction-internal.h b/support/junction/junction-internal.h index 3dff4cc..7abd45c 100644 --- a/support/junction/junction-internal.h +++ b/support/junction/junction-internal.h @@ -28,6 +28,7 @@ #include #include +#include /** ** Names of extended attributes that store junction data diff --git a/support/junction/xml.c b/support/junction/xml.c index 813110b..aef1cbb 100644 --- a/support/junction/xml.c +++ b/support/junction/xml.c @@ -290,7 +290,7 @@ junction_parse_xml_buf(const char *pathname, const char *name, { xmlDocPtr tmp; - tmp = xmlParseMemory(buf, (int)len); + tmp = xmlReadMemory(buf, (int)len, NULL, NULL, 0); if (tmp == NULL) { xlog(D_GENERAL, "Failed to parse XML in %s(%s)\n", pathname, name); @@ -387,7 +387,6 @@ junction_xml_write(const char *pathname, const char *name, xmlDocPtr doc) return retval; retval = FEDFS_ERR_SVRFAULT; - xmlIndentTreeOutput = 1; xmlDocDumpFormatMemoryEnc(doc, &buf, &len, "UTF-8", 1); if (len < 0) goto out; diff --git a/support/nfs/conffile.c b/support/nfs/conffile.c index fd4a17a..1e9c22b 100644 --- a/support/nfs/conffile.c +++ b/support/nfs/conffile.c @@ -658,7 +658,7 @@ conf_load_file(const char *conf_file) return 0; } -static void +static void conf_init_dir(const char *conf_file) { struct dirent **namelist = NULL; @@ -669,14 +669,14 @@ conf_init_dir(const char *conf_file) dname = malloc(strlen(conf_file) + 3); if (dname == NULL) { xlog(L_WARNING, "conf_init_dir: malloc: %s", strerror(errno)); - return; + return; } sprintf(dname, "%s.d", conf_file); n = scandir(dname, &namelist, NULL, versionsort); if (n < 0) { if (errno != ENOENT) { - xlog(L_WARNING, "conf_init_dir: scandir %s: %s", + xlog(L_WARNING, "conf_init_dir: scandir %s: %s", dname, strerror(errno)); } free(dname); @@ -691,7 +691,7 @@ conf_init_dir(const char *conf_file) for (i = 0; i < n; i++ ) { struct dirent *d = namelist[i]; - switch (d->d_type) { + switch (d->d_type) { case DT_UNKNOWN: case DT_REG: case DT_LNK: @@ -701,13 +701,13 @@ conf_init_dir(const char *conf_file) } if (*d->d_name == '.') continue; - + fname_len = strlen(d->d_name); path_len = (fname_len + dname_len); if (!fname_len || path_len > PATH_MAX) { xlog(L_WARNING, "conf_init_dir: Too long file name: %s in %s", d->d_name, dname); - continue; + continue; } /* @@ -715,7 +715,7 @@ conf_init_dir(const char *conf_file) * that end with CONF_FILE_EXT */ if (fname_len <= CONF_FILE_EXT_LEN) { - xlog(D_GENERAL, "conf_init_dir: %s: name too short", + xlog(D_GENERAL, "conf_init_dir: %s: name too short", d->d_name); continue; } @@ -746,41 +746,43 @@ conf_init_dir(const char *conf_file) free(namelist[i]); free(namelist); free(dname); - + return; } -int +void conf_init_file(const char *conf_file) { unsigned int i; - int ret; + int j; for (i = 0; i < sizeof conf_bindings / sizeof conf_bindings[0]; i++) LIST_INIT (&conf_bindings[i]); TAILQ_INIT (&conf_trans_queue); - if (conf_file == NULL) - conf_file=NFS_CONFFILE; + if (conf_file == NULL) + conf_file = NFS_CONFFILE; - /* - * First parse the give config file - * then parse the config.conf.d directory - * (if it exists) + /* If the config file is in /etc (normal) then check + * /usr/etc first. Also check config.conf.d for files + * names *.conf. * + * Content or later files always over-rides earlier + * files. */ - ret = conf_load_file(conf_file); - - /* - * When the same variable is set in both files - * the conf.d file will override the config file. - * This allows automated admin systems to - * have the final say. - */ + if (strncmp(conf_file, "/etc/", 5) == 0) { + char *usrconf = NULL; + + j = asprintf(&usrconf, "/usr%s", conf_file); + if (usrconf && j > 0) { + conf_load_file(usrconf); + conf_init_dir(usrconf); + free(usrconf); + } + } + conf_load_file(conf_file); conf_init_dir(conf_file); - - return ret; } /* diff --git a/support/nfs/exports.c b/support/nfs/exports.c index 15dc574..a6816e6 100644 --- a/support/nfs/exports.c +++ b/support/nfs/exports.c @@ -59,7 +59,7 @@ static int *squids = NULL, nsquids = 0, static int getexport(char *exp, int len); static int getpath(char *path, int len); -static int parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr); +static int parseopts(char *cp, struct exportent *ep, int *had_subtree_opt_ptr); static int parsesquash(char *list, int **idp, int *lenp, char **ep); static int parsenum(char **cpp); static void freesquash(void); @@ -109,7 +109,7 @@ static void init_exportent (struct exportent *ee, int fromkernel) } struct exportent * -getexportent(int fromkernel, int fromexports) +getexportent(int fromkernel) { static struct exportent ee, def_ee; char exp[512], *hostname; @@ -147,7 +147,7 @@ getexportent(int fromkernel, int fromexports) * we're not reading from the kernel. */ if (exp[0] == '-' && !fromkernel) { - if (parseopts(exp + 1, &def_ee, 0, &has_default_subtree_opts) < 0) + if (parseopts(exp + 1, &def_ee, &has_default_subtree_opts) < 0) return NULL; has_default_opts = 1; @@ -185,20 +185,20 @@ getexportent(int fromkernel, int fromexports) } ee.e_hostname = xstrdup(hostname); - if (parseopts(opt, &ee, fromexports && !has_default_subtree_opts, NULL) < 0) { - if(ee.e_hostname) - { - xfree(ee.e_hostname); - ee.e_hostname=NULL; - } - if(ee.e_uuid) - { - xfree(ee.e_uuid); - ee.e_uuid=NULL; - } + if (parseopts(opt, &ee, NULL) < 0) { + if(ee.e_hostname) + { + xfree(ee.e_hostname); + ee.e_hostname=NULL; + } + if(ee.e_uuid) + { + xfree(ee.e_uuid); + ee.e_uuid=NULL; + } return NULL; - } + } /* resolve symlinks */ if (realpath(ee.e_path, rpath) != NULL) { rpath[sizeof (rpath) - 1] = '\0'; @@ -433,7 +433,7 @@ mkexportent(char *hname, char *path, char *options) } strncpy(ee.e_path, path, sizeof (ee.e_path)); ee.e_path[sizeof (ee.e_path) - 1] = '\0'; - if (parseopts(options, &ee, 0, NULL) < 0) + if (parseopts(options, &ee, NULL) < 0) return NULL; return ⅇ } @@ -441,7 +441,7 @@ mkexportent(char *hname, char *path, char *options) int updateexportent(struct exportent *eep, char *options) { - if (parseopts(options, eep, 0, NULL) < 0) + if (parseopts(options, eep, NULL) < 0) return 0; return 1; } @@ -632,7 +632,7 @@ void fix_pseudoflavor_flags(struct exportent *ep) * Parse option string pointed to by cp and set mount options accordingly. */ static int -parseopts(char *cp, struct exportent *ep, int warn, int *had_subtree_opt_ptr) +parseopts(char *cp, struct exportent *ep, int *had_subtree_opt_ptr) { int had_subtree_opt = 0; char *flname = efname?efname:"command line"; @@ -852,13 +852,6 @@ bad_option: ep->e_nsqgids = nsqgids; out: - if (warn && !had_subtree_opt) - xlog(L_WARNING, "%s [%d]: Neither 'subtree_check' or 'no_subtree_check' specified for export \"%s:%s\".\n" - " Assuming default behaviour ('no_subtree_check').\n" - " NOTE: this default has changed since nfs-utils version 1.0.x\n", - - flname, flline, - ep->e_hostname, ep->e_path); if (had_subtree_opt_ptr) *had_subtree_opt_ptr = had_subtree_opt; diff --git a/support/nfsidmap/idmapd.conf.5 b/support/nfsidmap/idmapd.conf.5 index 87e39bb..58c2d97 100644 --- a/support/nfsidmap/idmapd.conf.5 +++ b/support/nfsidmap/idmapd.conf.5 @@ -37,7 +37,7 @@ Configuration file for libnfsidmap. Used by idmapd and svcgssd to map NFSv4 nam .SH DESCRIPTION The .B idmapd.conf -configuration file consists of several sections, initiated by strings of the +configuration files consists of several sections, initiated by strings of the form [General] and [Mapping]. Each section may contain lines of the form .nf variable = value @@ -398,6 +398,19 @@ LDAP_base = dc=org,dc=domain .\" Additional sections .\" ------------------------------------------------------------------- .\" +.SH FILES +.I /usr/etc/idmapd.conf +.br +.I /usr/etc/idmapd.conf.d/*.conf +.br +.I /etc/idmapd.conf +.br +.I /etc/idmapd.conf.d/*.conf +.br +.IP +Files are read in the order listed. Later settings override earlier +settings. + .SH SEE ALSO .BR idmapd (8) .BR svcgssd (8) diff --git a/support/reexport/fsidd.c b/support/reexport/fsidd.c index 3e62b3f..8a70b78 100644 --- a/support/reexport/fsidd.c +++ b/support/reexport/fsidd.c @@ -147,6 +147,7 @@ int main(void) { struct event *srv_ev; struct sockaddr_un addr; + socklen_t addr_len; char *sock_file; int srv; @@ -161,10 +162,12 @@ int main(void) memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, sock_file, sizeof(addr.sun_path) - 1); - if (addr.sun_path[0] == '@') + addr_len = sizeof(struct sockaddr_un); + if (addr.sun_path[0] == '@') { /* "abstract" socket namespace */ + addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path); addr.sun_path[0] = 0; - else + } else unlink(sock_file); srv = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK, 0); @@ -173,7 +176,7 @@ int main(void) return 1; } - if (bind(srv, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) { + if (bind(srv, (const struct sockaddr *)&addr, addr_len) == -1) { xlog(L_WARNING, "Unable to bind %s: %m\n", sock_file); return 1; } diff --git a/support/reexport/reexport.c b/support/reexport/reexport.c index 7851658..0fb49a4 100644 --- a/support/reexport/reexport.c +++ b/support/reexport/reexport.c @@ -21,6 +21,7 @@ static int fsidd_srv = -1; static bool connect_fsid_service(void) { struct sockaddr_un addr; + socklen_t addr_len; char *sock_file; int ret; int s; @@ -33,9 +34,12 @@ static bool connect_fsid_service(void) memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, sock_file, sizeof(addr.sun_path) - 1); - if (addr.sun_path[0] == '@') + addr_len = sizeof(struct sockaddr_un); + if (addr.sun_path[0] == '@') { /* "abstract" socket namespace */ + addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path); addr.sun_path[0] = 0; + } s = socket(AF_UNIX, SOCK_SEQPACKET, 0); if (s == -1) { @@ -43,7 +47,7 @@ static bool connect_fsid_service(void) return false; } - ret = connect(s, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)); + ret = connect(s, (const struct sockaddr *)&addr, addr_len); if (ret == -1) { xlog(L_WARNING, "Unable to connect %s: %m, is fsidd running?\n", sock_file); return false; diff --git a/systemd/nfs.conf.man b/systemd/nfs.conf.man index 866939a..d03fc88 100644 --- a/systemd/nfs.conf.man +++ b/systemd/nfs.conf.man @@ -2,10 +2,13 @@ .SH NAME nfs.conf \- general configuration for NFS daemons and tools .SH SYNOPSIS +.I /usr/etc/nfs.conf +.I /usr/etc/nfs.conf.d/ .I /etc/nfs.conf +.I /etc/nfs.conf.d/ .SH DESCRIPTION .PP -This file contains site-specific configuration for various NFS daemons +These files contain site-specific configuration for various NFS daemons and other processes. Most configuration can also be passed to processes via command line arguments, but it can be more convenient to have a central file. In particular, this encourages consistent @@ -314,15 +317,17 @@ See for deatils. .SH FILES -.TP 10n +.I /usr/etc/nfs.conf +.br +.I /usr/etc/nfs.conf.d/*.conf +.br .I /etc/nfs.conf -Default NFS client configuration file -.TP 10n -.I /etc/nfs.conf.d -When this directory exists and files ending -with ".conf" exist, those files will be -used to set configuration variables. These -files will override variables set in /etc/nfs.conf +.br +.I /etc/nfs.conf.d/*.conf +.br +.IP +Various configuration files read in order. Later settings override +earlier settings. .SH SEE ALSO .BR nfsdcltrack (8), .BR rpc.nfsd (8), diff --git a/systemd/nfs.systemd.man b/systemd/nfs.systemd.man index 46b476a..df89ddd 100644 --- a/systemd/nfs.systemd.man +++ b/systemd/nfs.systemd.man @@ -27,7 +27,9 @@ any command line arguments to daemons so as to configure their behavior. In many case such configuration can be performed by making changes to .I /etc/nfs.conf -or other configuration files. When that is not convenient, a +or other configuration files (see +.BR nfs.conf (5)). +When that is not convenient, a distribution might provide systemd "drop-in" files which replace the .B ExecStart= setting to start the program with different arguments. For example a @@ -171,6 +173,12 @@ running, it can be masked with /etc/nfsmount.conf .br /etc/idmapd.conf +.P +Also similar files in +.B /usr/etc +and in related +.I conf.d +drop-in directories. .SH SEE ALSO .BR systemd.unit (5), .BR nfs.conf (5), diff --git a/tools/locktest/testlk.c b/tools/locktest/testlk.c index ea51f78..c9bd6ba 100644 --- a/tools/locktest/testlk.c +++ b/tools/locktest/testlk.c @@ -81,8 +81,8 @@ main(int argc, char **argv) if (fl.l_type == F_UNLCK) { printf("%s: no conflicting lock\n", fname); } else { - printf("%s: conflicting lock by %d on (%zd;%zd)\n", - fname, fl.l_pid, fl.l_start, fl.l_len); + printf("%s: conflicting lock by %d on (%lld;%lld)\n", + fname, fl.l_pid, (long long)fl.l_start, (long long)fl.l_len); } return 0; } diff --git a/tools/nfsconf/nfsconfcli.c b/tools/nfsconf/nfsconfcli.c index b2ef96d..bd9d527 100644 --- a/tools/nfsconf/nfsconfcli.c +++ b/tools/nfsconf/nfsconfcli.c @@ -135,19 +135,8 @@ int main(int argc, char **argv) return 1; } - if (mode != MODE_SET && mode != MODE_UNSET) { - if (conf_init_file(confpath)) { - /* config file was missing or had an error, warn about it */ - if (verbose || mode != MODE_ISSET) { - fprintf(stderr, "Error loading config file %s\n", - confpath); - } - - /* this isnt fatal for --isset */ - if (mode != MODE_ISSET) - return 1; - } - } + if (mode != MODE_SET && mode != MODE_UNSET) + conf_init_file(confpath); /* --dump mode, output the current configuration */ if (mode == MODE_DUMP) { diff --git a/utils/mount/nfsmount.conf.man b/utils/mount/nfsmount.conf.man index 34879c8..10287cd 100644 --- a/utils/mount/nfsmount.conf.man +++ b/utils/mount/nfsmount.conf.man @@ -115,16 +115,17 @@ All mounts to the '/export/home' export will be performed in the background (i.e. done asynchronously). .RE .SH FILES -.TP 10n +.I /usr/etc/nfsmount.conf +.br +.I /usr/etc/nfsmount.conf.d/*.conf +.br .I /etc/nfsmount.conf -Default NFS mount configuration file -.TP 10n -.I /etc/nfsmount.conf.d -When this directory exists and files ending -with ".conf" exist, those files will be -used to set configuration variables. These -files will override variables set -in /etc/nfsmount.conf +.br +.I /etc/nfsmount.conf.d/*.conf +.br +.IP +Default NFS mount configuration files, variables set in the later file +over-ride those in the earlier file. .PD .SH SEE ALSO .BR nfs (5), diff --git a/utils/nfsref/nfsref.c b/utils/nfsref/nfsref.c index 7f97d01..aa8414b 100644 --- a/utils/nfsref/nfsref.c +++ b/utils/nfsref/nfsref.c @@ -24,8 +24,6 @@ */ #include -#include -#include #include #include diff --git a/utils/nfsref/nfsref.man b/utils/nfsref/nfsref.man index 1261549..1970f9d 100644 --- a/utils/nfsref/nfsref.man +++ b/utils/nfsref/nfsref.man @@ -53,33 +53,37 @@ nfsref \- manage NFS referrals NFS version 4 introduces the concept of .I file system referrals to NFS. -A file system referral is like a symbolic link on a file server -to another file system share, possibly on another file server. -On an NFS client, a referral behaves like an automounted directory. -The client, under the server's direction, mounts a new NFS export -automatically when an application first accesses that directory. .P -Referrals are typically used to construct a single file name space -across multiple file servers. -Because file servers control the shape of the name space, -no client configuration is required, -and all clients see the same referral information. +A file system referral is like a symbolic link +(or, +.IR symlink ) +to another file system share, typically on another file server. +An NFS client, under the server's direction, +mounts the referred-to NFS export +automatically when an application first accesses it. .P -The Linux NFS server supports NFS version 4 referrals. -Administrators can specify the -.B refer= -export option in -.I /etc/exports -to configure a list of exports from which the client can choose. -See -.BR exports (5) -for details. +NFSv4 referrals can be used to transparently redirect clients +to file systems that have been moved elsewhere, or +to construct a single file name space across multiple file servers. +Because file servers control the shape of the whole file name space, +no client configuration is required. .P .SH DESCRIPTION +A +.I junction +is a file system object on an NFS server that, +when an NFS client encounters it, triggers a referral. +Similar to a symlink, a junction contains one or more target locations +that the server sends to clients in the form of an NFSv4 referral. +.P +On Linux, an existing directory can be converted to a junction +and back atomically and without the loss of the directory contents. +When a directory acts as a junction, it's local content is hidden +from NFSv4 clients. +.P The .BR nfsref (8) -command is a simple way to get started managing junction metadata. -Other administrative commands provide richer access to junction information. +command is a simple way to get started managing junctions and their content. .SS Subcommands Valid .BR nfsref (8) @@ -135,6 +139,10 @@ For the .B add subcommand, the default value if this option is not specified is .BR nfs-basic . +The +.B nfs-fedfs +type is not used in this implementation. +.IP For the .B remove and @@ -163,18 +171,12 @@ you might issue this command as root: .sp # mkdir /home .br -# nfsref --type=nfs-basic add /home home.example.net / +# nfsref add /home home.example.net / .br Created junction /home. .sp .RE -.SH FILES -.TP -.I /etc/exports -NFS server export table .SH "SEE ALSO" -.BR exports (5) -.sp -RFC 5661 for a description of NFS version 4 referrals +RFC 8881 for a description of the NFS version 4 referral mechanism .SH "AUTHOR" Chuck Lever