Skip to content

Commit

Permalink
OS-6155 NFSv4 locking not working if rpcbind or rpc.statd not running
Browse files Browse the repository at this point in the history
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Approved by: Patrick Mooney <patrick.mooney@joyent.com>
  • Loading branch information
jjelinek committed Jun 7, 2017
1 parent 2b9d6c0 commit 3a5445f
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 33 deletions.
15 changes: 9 additions & 6 deletions usr/src/cmd/fs.d/nfs/lockd/lockd.c
Expand Up @@ -23,6 +23,7 @@
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
* Copyright 2017 Joyent, Inc.
*/

/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
Expand Down Expand Up @@ -88,7 +89,7 @@
struct lm_svc_args lmargs = {
.version = LM_SVC_CUR_VERS,
/* fd, n_fmly, n_proto, n_rdev (below) */
.debug = 0,
.n_v4_only = 0,
.timout = 5 * 60,
.grace = 90,
.retransmittimeout = 5
Expand Down Expand Up @@ -137,6 +138,8 @@ int (*Mysvc)(int, struct netbuf, struct netconfig *) = nlmsvc;
/* used by cots_listen_event() */
int max_conns_allowed = -1; /* used by cots_listen_event() */

int debug = 0;

int
main(int ac, char *av[])
{
Expand Down Expand Up @@ -238,7 +241,7 @@ main(int ac, char *av[])
break;

case 'd': /* debug */
lmargs.debug = atoi(optarg);
debug = atoi(optarg);
break;

case 'g': /* grace_period */
Expand Down Expand Up @@ -288,12 +291,12 @@ main(int ac, char *av[])
if (optind != ac)
usage();

if (lmargs.debug) {
if (debug != 0) {
printf("%s: debug= %d, conn_idle_timout= %d,"
" grace_period= %d, listen_backlog= %d,"
" max_connections= %d, max_servers= %d,"
" retrans_timeout= %d\n",
MyName, lmargs.debug, lmargs.timout,
MyName, debug, lmargs.timout,
lmargs.grace, listen_backlog,
max_conns_allowed, max_servers,
lmargs.retransmittimeout);
Expand All @@ -309,7 +312,7 @@ main(int ac, char *av[])
}

/* Daemonize, if not debug. */
if (lmargs.debug == 0)
if (debug == 0)
pipe_fd = daemonize_init();

openlog(MyName, LOG_PID | LOG_NDELAY, LOG_DAEMON);
Expand Down Expand Up @@ -405,7 +408,7 @@ main(int ac, char *av[])
/*
* lockd is up and running as far as we are concerned.
*/
if (lmargs.debug == 0)
if (debug == 0)
daemonize_fini(pipe_fd);

/*
Expand Down
32 changes: 21 additions & 11 deletions usr/src/lib/brand/lx/lx_lockd/lockd.c
Expand Up @@ -112,7 +112,7 @@
struct lm_svc_args lmargs = {
.version = LM_SVC_CUR_VERS,
/* fd, n_fmly, n_proto, n_rdev (below) */
.debug = 0,
.n_v4_only = 0,
.timout = 5 * 60,
.grace = 90, /* How long to wait for clients to re-establish locks. */
.retransmittimeout = 5
Expand Down Expand Up @@ -163,6 +163,8 @@ int listen_backlog = 32; /* used by bind_to_{provider,proto}() */
int max_conns_allowed = -1; /* used by cots_listen_event() */
int (*Mysvc)(int, struct netbuf, struct netconfig *) = nlmsvc;

boolean_t debug = B_FALSE;

#define LX_PMAP_VERS 4

/*
Expand Down Expand Up @@ -334,7 +336,7 @@ main(int ac, char *av[])

(void) enable_extended_FILE_stdio(-1, -1);

while ((c = getopt(ac, av, "c:d:g:l:t:")) != EOF)
while ((c = getopt(ac, av, "c:dg:l:t:")) != EOF)
switch (c) {
case 'c': /* max_connections */
if ((val = atoi(optarg)) <= 0)
Expand All @@ -343,7 +345,7 @@ main(int ac, char *av[])
break;

case 'd': /* debug */
lmargs.debug = atoi(optarg);
debug = B_TRUE;
break;

case 'g': /* grace_period */
Expand All @@ -365,12 +367,12 @@ main(int ac, char *av[])
break;

badval:
if (lmargs.debug) {
if (debug) {
fprintf(stderr, "Invalid -%c option value", c);
}
/* FALLTHROUGH */
default:
if (lmargs.debug) {
if (debug) {
usage();
}
exit(1);
Expand All @@ -380,7 +382,7 @@ main(int ac, char *av[])
if (optind < ac) {
val = atoi(av[optind]);
if (val <= 0) {
if (lmargs.debug) {
if (debug) {
fprintf(stderr, "Invalid max_servers argument");
usage();
}
Expand All @@ -391,18 +393,18 @@ main(int ac, char *av[])
}
/* If there are two or more arguments, then this is a usage error. */
if (optind != ac) {
if (lmargs.debug) {
if (debug) {
usage();
}
exit(1);
}

if (lmargs.debug) {
if (debug) {
printf("lx_lockd: debug=%d, conn_idle_timout=%d, "
"grace_period=%d, listen_backlog=%d, "
"max_connections=%d, max_servers=%d, "
"retrans_timeout=%d\n",
lmargs.debug, lmargs.timout, lmargs.grace, listen_backlog,
debug, lmargs.timout, lmargs.grace, listen_backlog,
max_conns_allowed, max_servers, lmargs.retransmittimeout);
}

Expand All @@ -412,7 +414,7 @@ main(int ac, char *av[])
exit(1);
}

if (lmargs.debug == 0) {
if (!debug) {
/* Block all signals if not debugging. */
sigset_t set;

Expand Down Expand Up @@ -543,6 +545,14 @@ nlmsvc(int fd, struct netbuf addrmask, struct netconfig *nconf)
lma.n_proto = nctype_to_lmprot(nconf->nc_semantics);
lma.n_rdev = ncdev_to_rdev(nconf->nc_device);

if (!have_rpcbind) {
/*
* Inform the kernel NLM code to run without rpcbind and
* rpc.statd.
*/
lma.n_v4_only = -1;
}

return (_nfssys(LM_SVC, &lma));
}

Expand All @@ -551,7 +561,7 @@ usage(void)
{
(void) fprintf(stderr, "usage: lx_lockd [options] [max_servers]\n");
(void) fprintf(stderr, "\t-c max_connections\n");
(void) fprintf(stderr, "\t-d debug_level\n");
(void) fprintf(stderr, "\t-d enable debugging\n");
(void) fprintf(stderr, "\t-g grace_period\n");
(void) fprintf(stderr, "\t-l listen_backlog\n");
(void) fprintf(stderr, "\t-t retransmit_timeout\n");
Expand Down
24 changes: 12 additions & 12 deletions usr/src/lib/brand/lx/lx_lockd/nfs_tbind.c
Expand Up @@ -599,6 +599,7 @@ nlm_do_one(char *provider, int (*svc)(int, struct netbuf, struct netconfig *))
struct netbuf addrmask;
int vers;
int err;
static boolean_t elogged = B_FALSE;

sock = nlm_bind_to_provider(provider, &retaddr, &retnconf);
if (sock == -1) {
Expand All @@ -619,16 +620,17 @@ nlm_do_one(char *provider, int (*svc)(int, struct netbuf, struct netconfig *))
for (vers = NLM_VERS; vers <= NLM4_VERS; vers++) {
lx_rpcb_unset(vers, retnconf->nc_netid);
have_rpcbind = lx_rpcb_set(vers, retnconf, retaddr);
if (!have_rpcbind) {
if (!have_rpcbind && !elogged) {
/*
* No rpcbind running. The kernel NFS locking
* code depends on connecting to rpcbind for
* the _nfssys() call to enable locking to
* succeed. Bail out now.
* code interacts with rpcbind & rpc.statd for
* NFSv3 locking. We warn about this but
* proceed since NFSv4 locking is still usable.
*/
lx_syslog("rpcbind is not running, but is "
"required for NFS locking");
exit(1);
lx_syslog("Warning: rpcbind is not running, "
"but is required for NFSv3 locking");
elogged = B_TRUE;
break;
}
}
}
Expand Down Expand Up @@ -675,7 +677,7 @@ nlm_do_one(char *provider, int (*svc)(int, struct netbuf, struct netconfig *))
*/
int
do_all(struct protob *protobp,
int (*svc)(int, struct netbuf, struct netconfig *))
int (*svc)(int, struct netbuf, struct netconfig *))
{
struct netconfig *nconf;
NCONF_HANDLE *nc;
Expand Down Expand Up @@ -1716,7 +1718,7 @@ nlm_bind_to_provider(char *provider, struct netbuf **addr,

static int
bind_to_proto(NETSELDECL(proto), char *serv, struct netbuf **addr,
struct netconfig **retnconf)
struct netconfig **retnconf)
{
struct netconfig *nconf;
NCONF_HANDLE *nc = NULL;
Expand Down Expand Up @@ -1754,9 +1756,7 @@ bind_to_proto(NETSELDECL(proto), char *serv, struct netbuf **addr,
* to all-ones. The port number part of the mask is zeroes.
*/
static int
set_addrmask(int fd,
struct netconfig *nconf,
struct netbuf *mask)
set_addrmask(int fd, struct netconfig *nconf, struct netbuf *mask)
{
struct t_info info;

Expand Down
3 changes: 2 additions & 1 deletion usr/src/uts/common/fs/nfs/nfs_sys.c
Expand Up @@ -21,6 +21,7 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2017 Joyent, Inc.
*
* Copyright (c) 1983,1984,1985,1986,1987,1988,1989 AT&T.
* All rights reserved.
Expand Down Expand Up @@ -247,7 +248,7 @@ nfssys(enum nfssys_op opcode, void *arg)
lsa.n_fmly = STRUCT_FGET(ulsa, n_fmly);
lsa.n_proto = STRUCT_FGET(ulsa, n_proto);
lsa.n_rdev = expldev(STRUCT_FGET(ulsa, n_rdev));
lsa.debug = STRUCT_FGET(ulsa, debug);
lsa.n_v4_only = STRUCT_FGET(ulsa, n_v4_only);
lsa.timout = STRUCT_FGET(ulsa, timout);
lsa.grace = STRUCT_FGET(ulsa, grace);
lsa.retransmittimeout = STRUCT_FGET(ulsa,
Expand Down
5 changes: 5 additions & 0 deletions usr/src/uts/common/klm/klmmod.c
Expand Up @@ -12,6 +12,7 @@
/*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright 2017 Joyent, Inc.
*/

/*
Expand Down Expand Up @@ -278,6 +279,10 @@ lm_svc(struct lm_svc_args *args)
rfs4_lease_time = args->grace;
}

if (args->n_v4_only == -1) {
g->nlm_v4_only = B_TRUE;
}

mutex_exit(&g->lock);
err = nlm_svc_starting(g, fp, netid, &knc);
mutex_enter(&g->lock);
Expand Down
12 changes: 11 additions & 1 deletion usr/src/uts/common/klm/nlm_impl.c
Expand Up @@ -2370,6 +2370,13 @@ nlm_svc_starting(struct nlm_globals *g, struct file *fp,
VERIFY(g->run_status == NLM_ST_STARTING);
VERIFY(g->nlm_gc_thread == NULL);

if (g->nlm_v4_only) {
NLM_WARN("Zone %d has no rpcbind, NLM is v4 only", getzoneid());
bzero(&g->nlm_nsm, sizeof (struct nlm_nsm));
g->nlm_nsm.ns_addr_handle = (void *)-1;
goto v4_only;
}

error = nlm_nsm_init_local(&g->nlm_nsm);
if (error != 0) {
NLM_ERR("Failed to initialize NSM handler "
Expand Down Expand Up @@ -2406,6 +2413,7 @@ nlm_svc_starting(struct nlm_globals *g, struct file *fp,
"(rpcerr=%d)\n", stat);
goto shutdown_lm;
}
v4_only:

g->grace_threshold = ddi_get_lbolt() +
SEC_TO_TICK(g->grace_period);
Expand Down Expand Up @@ -2529,7 +2537,9 @@ nlm_svc_stopping(struct nlm_globals *g)

ASSERT(TAILQ_EMPTY(&g->nlm_slocks));

nlm_nsm_fini(&g->nlm_nsm);
/* If started with rpcbind (the normal case) */
if (g->nlm_nsm.ns_addr_handle != (void *)-1)
nlm_nsm_fini(&g->nlm_nsm);
g->lockd_pid = 0;
g->run_status = NLM_ST_DOWN;
}
Expand Down
2 changes: 2 additions & 0 deletions usr/src/uts/common/klm/nlm_impl.h
Expand Up @@ -30,6 +30,7 @@
/*
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright 2016 Joyent, Inc.
*/

/*
Expand Down Expand Up @@ -459,6 +460,7 @@ struct nlm_globals {
int cn_idle_tmo; /* (z) */
int grace_period; /* (z) */
int retrans_tmo; /* (z) */
boolean_t nlm_v4_only; /* (z) */
kmutex_t clean_lock; /* (c) */
TAILQ_ENTRY(nlm_globals) nlm_link; /* (g) */
};
Expand Down
12 changes: 10 additions & 2 deletions usr/src/uts/common/nfs/nfssys.h
Expand Up @@ -21,6 +21,7 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2017 Joyent, Inc.
*/

/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
Expand Down Expand Up @@ -122,13 +123,20 @@ struct nfs_revauth_args32 {
enum lm_fmly { LM_INET, LM_INET6, LM_LOOPBACK };
enum lm_proto { LM_TCP, LM_UDP };

/*
* The 'n_v4_only' member was formerly called 'debug'. This member is not used
* in the kernel. To avoid a new version of this user/kernel interface
* structure, the member was renamed in a binary compatible way. It is now used
* by the user-level code to indicate that the zone is not running
* rpcbind/rpc.statd and that only NFSv4 locking is needed.
*/
struct lm_svc_args {
int version; /* keep this first */
int fd;
enum lm_fmly n_fmly; /* protocol family */
enum lm_proto n_proto; /* protocol */
dev_t n_rdev; /* device ID */
int debug; /* debugging level */
int n_v4_only; /* NFSv4 locking only */
time_t timout; /* client handle life (asynch RPCs) */
int grace; /* secs in grace period */
time_t retransmittimeout; /* retransmission interval */
Expand All @@ -141,7 +149,7 @@ struct lm_svc_args32 {
enum lm_fmly n_fmly; /* protocol family */
enum lm_proto n_proto; /* protocol */
dev32_t n_rdev; /* device ID */
int32_t debug; /* debugging level */
int32_t n_v4_only; /* NFSv4 locking only */
time32_t timout; /* client handle life (asynch RPCs) */
int32_t grace; /* secs in grace period */
time32_t retransmittimeout; /* retransmission interval */
Expand Down

0 comments on commit 3a5445f

Please sign in to comment.