diff options
Diffstat (limited to 'usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c')
-rw-r--r-- | usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c | 149 |
1 files changed, 68 insertions, 81 deletions
diff --git a/usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c b/usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c index 1afb19d3ff..5296cb2be9 100644 --- a/usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c +++ b/usr/src/cmd/fs.d/smbclnt/smbiod/smbiod.c @@ -24,7 +24,7 @@ */ /* - * SMBFS I/O Deamon (smbiod) + * SMBFS I/O Daemon (Per-user IOD) */ #include <sys/types.h> @@ -43,26 +43,20 @@ #include <time.h> #include <unistd.h> #include <ucred.h> - #include <err.h> #include <door.h> +#include <libscf.h> +#include <locale.h> #include <thread.h> #include <netsmb/smb_lib.h> -#define EXIT_FAIL 1 -#define EXIT_OK 0 - -#if defined(DEBUG) || defined(__lint) #define DPRINT(...) do \ { \ if (smb_debug) \ fprintf(stderr, __VA_ARGS__); \ _NOTE(CONSTCOND) \ } while (0) -#else -#define DPRINT(...) ((void)0) -#endif mutex_t iod_mutex = DEFAULTMUTEX; int iod_thr_count; /* threads, excluding main */ @@ -77,13 +71,16 @@ void * iod_work(void *arg); int main(int argc, char **argv) { - static const int door_attrs = - DOOR_REFUSE_DESC | DOOR_NO_CANCEL; sigset_t oldmask, tmpmask; char *env, *door_path = NULL; - int door_fd = -1, tmp_fd = -1; - int err, i, sig; - int rc = EXIT_FAIL; + int door_fd = -1; + int err, sig; + int rc = SMF_EXIT_ERR_FATAL; + boolean_t attached = B_FALSE; + + /* set locale and text domain for i18n */ + (void) setlocale(LC_ALL, ""); + (void) textdomain(TEXT_DOMAIN); /* Debugging support. */ if ((env = getenv("SMBFS_DEBUG")) != NULL) { @@ -94,75 +91,42 @@ main(int argc, char **argv) } /* - * Find out if an IOD is already running. - * If so, we lost a harmless startup race. - * An IOD did start, so exit success. + * If a user runs this command (i.e. by accident) + * don't interfere with any already running IOD. */ err = smb_iod_open_door(&door_fd); if (err == 0) { close(door_fd); door_fd = -1; - DPRINT("main: already running\n"); - exit(EXIT_OK); + DPRINT("%s: already running\n", argv[0]); + exit(SMF_EXIT_OK); } /* - * Create a file for the door. - */ - door_path = smb_iod_door_path(); - unlink(door_path); - tmp_fd = open(door_path, O_RDWR|O_CREAT|O_EXCL, 0600); - if (tmp_fd < 0) { - perror(door_path); - exit(EXIT_FAIL); - } - close(tmp_fd); - tmp_fd = -1; - - - /* - * Close FDs 0,1,2 so we don't have a TTY, and - * re-open them on /dev/null so they won't be - * used for device handles (etc.) later, and - * we don't have to worry about printf calls - * or whatever going to these FDs. - */ - for (i = 0; i < 3; i++) { - /* Exception: If smb_debug, keep stderr */ - if (smb_debug && i == 2) - break; - close(i); - tmp_fd = open("/dev/null", O_RDWR); - if (tmp_fd < 0) - perror("/dev/null"); - if (tmp_fd != i) - DPRINT("Open /dev/null - wrong fd?\n"); - } - - /* - * Become session leader. - */ - setsid(); - - /* - * Create door service threads with signals blocked. + * Want all signals blocked, as we're doing + * synchronous delivery via sigwait below. */ sigfillset(&tmpmask); sigprocmask(SIG_BLOCK, &tmpmask, &oldmask); /* Setup the door service. */ - door_fd = door_create(iod_dispatch, NULL, door_attrs); - if (door_fd < 0) { - fprintf(stderr, "%s: door_create failed\n", argv[0]); - rc = EXIT_FAIL; - goto errout; + door_path = smb_iod_door_path(); + door_fd = door_create(iod_dispatch, NULL, + DOOR_REFUSE_DESC | DOOR_NO_CANCEL); + if (door_fd == -1) { + perror("iod door_create"); + goto out; } fdetach(door_path); if (fattach(door_fd, door_path) < 0) { - fprintf(stderr, "%s: fattach failed\n", argv[0]); - rc = EXIT_FAIL; - goto errout; + fprintf(stderr, "%s: fattach failed, %s\n", + door_path, strerror(errno)); + goto out; } + attached = B_TRUE; + + /* Initializations done. */ + rc = SMF_EXIT_OK; /* * Post the initial alarm, and then just @@ -172,25 +136,48 @@ main(int argc, char **argv) again: sig = sigwait(&tmpmask); DPRINT("main: sig=%d\n", sig); + switch (sig) { + case SIGCONT: + goto again; - /* - * If a door call races with the alarm, ignore the alarm. - * It will be rescheduled when the threads go away. - */ - mutex_lock(&iod_mutex); - if (sig == SIGALRM && iod_thr_count > 0) { + case SIGALRM: + /* No threads active for a while. */ + mutex_lock(&iod_mutex); + if (iod_thr_count > 0) { + /* + * Door call thread creation raced with + * the alarm. Ignore this alaram. + */ + mutex_unlock(&iod_mutex); + goto again; + } + /* Prevent a race with iod_thr_count */ + iod_terminating = 1; mutex_unlock(&iod_mutex); - goto again; + break; + + case SIGINT: + case SIGTERM: + break; /* normal termination */ + + default: + /* Unexpected signal. */ + fprintf(stderr, "iod_main: unexpected sig=%d\n", sig); + break; } + +out: iod_terminating = 1; - mutex_unlock(&iod_mutex); - rc = EXIT_OK; + if (attached) + fdetach(door_path); + if (door_fd != -1) + door_revoke(door_fd); -errout: - fdetach(door_path); - door_revoke(door_fd); - door_fd = -1; - unlink(door_path); + /* + * We need a reference in -lumem to satisfy check_rtime, + * else we get build hoise. This is sufficient. + */ + free(NULL); return (rc); } @@ -226,7 +213,7 @@ iod_dispatch(void *cookie, char *argp, size_t argsz, /* * The library uses a NULL arg call to check if - * the deamon is running. Just return zero. + * the daemon is running. Just return zero. */ if (argp == NULL) { rc = 0; |