From 9fb40dda0a553c6e9243d2f483623672cc5c9bfa Mon Sep 17 00:00:00 2001 From: sef Date: Sat, 16 Feb 2019 00:15:54 +0000 Subject: [PATCH] Add support for a virtual hostname to nfsd Specifically, this allows (via "-V vhostname") telling nfsd what principal to use, instead of the hostname. This is used at iXsystems for fail-over in HA systems. Reviewed by: macklem Sponsored by: iXsystems Inc. Differential Revision: https://reviews.freebsd.org/D19191 --- libexec/rc/rc.d/nfsd | 5 +++++ usr.sbin/nfsd/nfsd.8 | 6 +++++- usr.sbin/nfsd/nfsd.c | 28 ++++++++++++++++++++-------- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/libexec/rc/rc.d/nfsd b/libexec/rc/rc.d/nfsd index 33ad356e05e9..3c16416f23d9 100755 --- a/libexec/rc/rc.d/nfsd +++ b/libexec/rc/rc.d/nfsd @@ -13,6 +13,7 @@ name="nfsd" desc="Remote NFS server" rcvar="nfs_server_enable" command="/usr/sbin/${name}" +nfs_server_vhost="" load_rc_config $name start_precmd="nfsd_precmd" @@ -20,6 +21,7 @@ sig_stop="USR1" nfsd_precmd() { + local _vhost rc_flags="${nfs_server_flags}" # Load the modules now, so that the vfs.nfsd sysctl @@ -46,6 +48,9 @@ nfsd_precmd() force_depend rpcbind || return 1 force_depend mountd || return 1 + if [ -n "${nfs_server_vhost}" ]; then + command_args="-V \"${nfs_server_vhost}\"" + fi } run_rc_command "$1" diff --git a/usr.sbin/nfsd/nfsd.8 b/usr.sbin/nfsd/nfsd.8 index 6e5157bae969..156925b8fcca 100644 --- a/usr.sbin/nfsd/nfsd.8 +++ b/usr.sbin/nfsd/nfsd.8 @@ -28,7 +28,7 @@ .\" @(#)nfsd.8 8.4 (Berkeley) 3/29/95 .\" $FreeBSD$ .\" -.Dd August 5, 2018 +.Dd February 14, 2019 .Dt NFSD 8 .Os .Sh NAME @@ -43,6 +43,7 @@ server .Op Fl h Ar bindip .Op Fl p Ar pnfs_setup .Op Fl m Ar mirror_level +.Op Fl V Ar virtual_hostname .Op Fl Fl maxthreads Ar max_threads .Op Fl Fl minthreads Ar min_threads .Sh DESCRIPTION @@ -78,6 +79,9 @@ Unregister the service with .Xr rpcbind 8 without creating any servers. +.It Fl V Ar virtual_hostname +Specifies a hostname to be used as a principal name, instead of +the default hostname. .It Fl n Ar threads Specifies how many servers to create. This option is equivalent to specifying .Fl Fl maxthreads diff --git a/usr.sbin/nfsd/nfsd.c b/usr.sbin/nfsd/nfsd.c index c4a4396264d1..2325a10f804d 100644 --- a/usr.sbin/nfsd/nfsd.c +++ b/usr.sbin/nfsd/nfsd.c @@ -122,7 +122,7 @@ static void nonfs(int); static void reapchild(int); static int setbindhost(struct addrinfo **ia, const char *bindhost, struct addrinfo hints); -static void start_server(int, struct nfsd_nfsd_args *); +static void start_server(int, struct nfsd_nfsd_args *, const char *vhost); static void unregistration(void); static void usage(void); static void open_stable(int *, int *); @@ -176,6 +176,7 @@ main(int argc, char **argv) char **bindhost = NULL; pid_t pid; struct nfsd_nfsd_args nfsdargs; + const char *vhostname = NULL; nfsdargs.mirrorcnt = 1; nfsdargs.addr = NULL; @@ -183,16 +184,24 @@ main(int argc, char **argv) nfsdcnt = DEFNFSDCNT; unregister = reregister = tcpflag = maxsock = 0; bindanyflag = udpflag = connect_type_cnt = bindhostc = 0; - getopt_shortopts = "ah:n:rdtuep:m:"; + getopt_shortopts = "ah:n:rdtuep:m:V:"; getopt_usage = "usage:\n" " nfsd [-ardtue] [-h bindip]\n" " [-n numservers] [--minthreads #] [--maxthreads #]\n" - " [-p/--pnfs dsserver0:/dsserver0-mounted-on-dir,...," - "dsserverN:/dsserverN-mounted-on-dir] [-m mirrorlevel]\n"; + " [-p/--pnfs dsserver0:/dsserver0-mounted-on-dir,...,\n" + " [-V virtual_hostname]\n" + " dsserverN:/dsserverN-mounted-on-dir] [-m mirrorlevel]\n"; while ((ch = getopt_long(argc, argv, getopt_shortopts, longopts, &longindex)) != -1) switch (ch) { + case 'V': + if (strlen(optarg) <= MAXHOSTNAMELEN) + vhostname = optarg; + else + warnx("Virtual host name (%s) is too long", + optarg); + break; case 'a': bindanyflag = 1; break; @@ -473,7 +482,7 @@ main(int argc, char **argv) } else { (void)signal(SIGUSR1, child_cleanup); setproctitle("server"); - start_server(0, &nfsdargs); + start_server(0, &nfsdargs, vhostname); } } @@ -790,7 +799,7 @@ main(int argc, char **argv) * a "server" too. start_server will not return. */ if (!tcpflag) - start_server(1, &nfsdargs); + start_server(1, &nfsdargs, vhostname); /* * Loop forever accepting connections and passing the sockets @@ -987,7 +996,7 @@ get_tuned_nfsdcount(void) } static void -start_server(int master, struct nfsd_nfsd_args *nfsdargp) +start_server(int master, struct nfsd_nfsd_args *nfsdargp, const char *vhost) { char principal[MAXHOSTNAMELEN + 5]; int status, error; @@ -995,7 +1004,10 @@ start_server(int master, struct nfsd_nfsd_args *nfsdargp) struct addrinfo *aip, hints; status = 0; - gethostname(hostname, sizeof (hostname)); + if (vhost == NULL) + gethostname(hostname, sizeof (hostname)); + else + strlcpy(hostname, vhost, sizeof (hostname)); snprintf(principal, sizeof (principal), "nfs@%s", hostname); if ((cp = strchr(hostname, '.')) == NULL || *(cp + 1) == '\0') {