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
This commit is contained in:
Sean Eric Fagan 2019-02-16 00:15:54 +00:00
parent 95e310720d
commit 025816d9ce
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=344192
3 changed files with 30 additions and 9 deletions

View File

@ -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"

View File

@ -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

View File

@ -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') {