diff options
author | Gordon Ross <Gordon.Ross@Sun.COM> | 2010-06-04 16:34:40 -0400 |
---|---|---|
committer | Gordon Ross <Gordon.Ross@Sun.COM> | 2010-06-04 16:34:40 -0400 |
commit | a547be5daca7e465ca82df6d179f6b1f8e0cda72 (patch) | |
tree | 1de43ca9ce086e2e22f5d71d8dc2c9f96ae8c0d2 /usr/src/lib/libsmbfs | |
parent | bc6a100fe6399f4a72c84c38df0fc9a960ded814 (diff) | |
download | illumos-joyent-a547be5daca7e465ca82df6d179f6b1f8e0cda72.tar.gz |
6944209 Let smbiod run as a service
6948083 Better logging of bad SMB signatures
Diffstat (limited to 'usr/src/lib/libsmbfs')
-rw-r--r-- | usr/src/lib/libsmbfs/netsmb/smb_lib.h | 8 | ||||
-rw-r--r-- | usr/src/lib/libsmbfs/smb/iod_cl.c | 112 | ||||
-rw-r--r-- | usr/src/lib/libsmbfs/smb/nbns_rq.c | 6 |
3 files changed, 81 insertions, 45 deletions
diff --git a/usr/src/lib/libsmbfs/netsmb/smb_lib.h b/usr/src/lib/libsmbfs/netsmb/smb_lib.h index 2f7d986adf..1933fdbb6b 100644 --- a/usr/src/lib/libsmbfs/netsmb/smb_lib.h +++ b/usr/src/lib/libsmbfs/netsmb/smb_lib.h @@ -33,8 +33,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. */ #ifndef _NETSMB_SMB_LIB_H_ @@ -188,6 +187,11 @@ int smb_ctx_newvc(struct smb_ctx *); * I/O daemon stuff */ +#define SMBIOD_RUNDIR "/var/run/smbiod" +#define SMBIOD_SVC_DOOR SMBIOD_RUNDIR "/.svc" +#define SMBIOD_USR_DOOR SMBIOD_RUNDIR "/%d" +#define SMBIOD_START 1 + int smb_iod_cl_newvc(smb_ctx_t *ctx); char *smb_iod_door_path(void); int smb_iod_open_door(int *); diff --git a/usr/src/lib/libsmbfs/smb/iod_cl.c b/usr/src/lib/libsmbfs/smb/iod_cl.c index 7449d68ed5..dbc2931807 100644 --- a/usr/src/lib/libsmbfs/smb/iod_cl.c +++ b/usr/src/lib/libsmbfs/smb/iod_cl.c @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -54,30 +53,29 @@ #include <netsmb/nb_lib.h> #include <netsmb/smb_dev.h> +#include <assert.h> + #include "charsets.h" #include "private.h" -static const char smbiod_path[] = "/usr/lib/smbfs/smbiod"; - /* * This is constant for the life of a process, * and initialized at startup, so no locks. */ -static char door_path[40]; +static char door_path[64]; static int iod_start_timeout = 10; /* seconds */ char * smb_iod_door_path(void) { - static const char fmtR[] = "/var/run/smbiod-%d"; - static const char fmtU[] = "/tmp/.smbiod-%d"; - const char *fmt; uid_t uid; + int x; if (door_path[0] == '\0') { uid = getuid(); - fmt = (uid == 0) ? fmtR : fmtU; - snprintf(door_path, sizeof (door_path), fmt, uid); + x = snprintf(door_path, sizeof (door_path), + SMBIOD_USR_DOOR, uid); + assert(x <= sizeof (door_path)); } return (door_path); @@ -126,56 +124,86 @@ smb_iod_open_door(int *fdp) } /* - * Start the IOD (if not already running) and - * wait until its door service is ready. + * Request the creation of our per-user smbiod + * via door call to the "main" IOD service. + */ +static int +start_iod(void) +{ + const char *svc_door = SMBIOD_SVC_DOOR; + door_arg_t da; + int32_t cmd, err; + int fd, rc; + + fd = open(svc_door, O_RDONLY, 0); + if (fd < 0) { + err = errno; + DPRINT("%s: open failed, err %d", svc_door, err); + return (err); + } + cmd = SMBIOD_START; + memset(&da, 0, sizeof (da)); + da.data_ptr = (void *) &cmd; + da.data_size = sizeof (cmd); + da.rbuf = (void *) &err; + da.rsize = sizeof (err); + rc = door_call(fd, &da); + close(fd); + if (rc < 0) { + err = errno; + DPRINT("door_call, err %d", err); + return (err); + } + + return (err); +} + +/* + * Get a door handle to the IOD, starting it if necessary. * On success, sets ctx->ct_door_fd */ int smb_iod_start(smb_ctx_t *ctx) { - int err, pid, tmo; + int err, tmo; int fd = -1; - err = smb_iod_open_door(&fd); - if (err == 0) - goto OK; - - pid = vfork(); - if (pid < 0) - return (errno); - - /* - * child: start smbiod - */ - if (pid == 0) { - char *argv[2]; - argv[0] = "smbiod"; - argv[1] = NULL; - (void) execv(smbiod_path, argv); - _exit(1); - } - - /* - * parent: wait for smbiod to start - */ tmo = iod_start_timeout; - while (--tmo >= 0) { + while ((err = smb_iod_open_door(&fd)) != 0) { + if (--tmo <= 0) + goto errout; + + /* + * We have no per-user IOD yet. Request one. + * Do this request every time through the loop + * because the master IOD will only start our + * per-user IOD if we don't have one, and our + * first requst could have happened while we + * had an IOD that was doing shutdown. + * (Prevents a shutdown/startup race). + */ + err = start_iod(); + if (err != 0) + goto errout; + /* + * Wait for it to get ready. + */ (void) sleep(1); - err = smb_iod_open_door(&fd); - if (err == 0) - goto OK; } - return (err); -OK: /* Save the door fd. */ if (ctx->ct_door_fd != -1) close(ctx->ct_door_fd); ctx->ct_door_fd = fd; return (0); -} +errout: + smb_error(dgettext(TEXT_DOMAIN, + "Could not contact service: %s"), + 0, "svc:/network/smb/client"); + return (ENOTACTIVE); +} /* * Ask the IOD to connect using the info in ctx. diff --git a/usr/src/lib/libsmbfs/smb/nbns_rq.c b/usr/src/lib/libsmbfs/smb/nbns_rq.c index 7dc46f3983..d28be4b0f9 100644 --- a/usr/src/lib/libsmbfs/smb/nbns_rq.c +++ b/usr/src/lib/libsmbfs/smb/nbns_rq.c @@ -32,6 +32,10 @@ * $Id: nbns_rq.c,v 1.9 2005/02/24 02:04:38 lindak Exp $ */ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + */ + #include <sys/param.h> #include <sys/socket.h> #include <sys/time.h> @@ -351,7 +355,7 @@ nbns_getnodestatus(struct nb_ctx *ctx, foundserver = 1; } } - if (!foundserver) + if (foundserver == 0 && retname != NULL) strlcpy(system, retname, NB_NAMELEN); ctx->nb_lastns = rqp->nr_sender; |