lm.c revision d1d2228c6cf3ec632d28262810ab7902932a5d33
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * CDDL HEADER START
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * The contents of this file are subject to the terms of the
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Common Development and Distribution License (the "License").
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * You may not use this file except in compliance with the License.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * See the License for the specific language governing permissions
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * and limitations under the License.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * When distributing Covered Code, include this CDDL HEADER in each
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * If applicable, add the following below this CDDL HEADER, with the
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * fields enclosed by brackets "[]" replaced with your own identifying
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * information: Portions Copyright [yyyy] [name of copyright owner]
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * CDDL HEADER END
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Use is subject to license terms.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk/* Globals */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenklm_t lm; /* The global library management structure. Only one */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* exists per library manager. */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenklm_queue_t lm_cmdq; /* The global work queue for processing LMPM cmds */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenklmpl_rsp_t lm_rspq; /* The global response structure. This keeps track */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* of which cmds are waiting on responses from MM */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkpthread_mutex_t lm_acc_mutex; /* Mutex to protect cmd waiting on a accept */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* This mutex allows only one cmd to be sent */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* to MM at a time until MM responses with */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* a accept or unaccept response */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkpthread_mutex_t lm_write_mutex; /* Mutex to protect from multiple writes */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* occuring at one time from different */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* threads */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkint lm_daemon_mode = 1; /* Indicates if running in daemon mode */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkint lm_message_level = MMS_MSG_SEV_WARN; /* LM's message level from MM */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkint lm_state = LM_NOT_ACTIVE; /* Global indicator of LM's state */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkint exit_code = LM_NORMAL; /* Global to tell what exit code should */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* be used when LM exits */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkint lm_internal_error = LM_OK; /* Indicates that a fatal internal LM system */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* error was detected. LM will shutdown */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* processing and exit */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* Structure that is updated to contain the */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* dynamic entry points to the commands that */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* interface with a specific library */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* Commands that also need a general */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* part as well as a library specific part */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* This general part will get called frist */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* and then the library specific part will be called */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk "activate", "lm_common_activate", lm_common_activate,
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk "private", "lm_common_private", lm_common_private,
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk "internal", "lm_common_internal", lm_common_internal,
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * signal_waiter
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Parameters:
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * None - arg exists only to match argument in pthread_create
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * This routine is spawned as a separate thread created to wait for masked
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * signals. Any masked signaled will be delivered to this thread.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Return Values:
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * None - Return value exists only to match return value in pthread_create
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk/* LINTED arg in signal_waiter (E_FUNC_ARG_UNUSED) */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* LINTED constant in conditional context */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk mms_trace(MMS_OPER, "signal_waiter: Received SIGHUP "
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk "signal, ignoring signal");
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk mms_trace(MMS_OPER, "signal_waiter: Received SIGINT "
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk "signal, restarting LM");
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk mms_trace(MMS_OPER, "signal_waiter: Received SIGPIPE "
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk "signal, shutting down LM");
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk mms_trace(MMS_OPER, "signal_waiter: Received SIGTERM "
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk "signal, shutting down LM");
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk "signal_waiter: Received a signal that "
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk /* LINTED Function has no return statement */
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * set_signal_handling()
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Paramters:
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Mask signals to catch. All threads inherit the signal mask
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * from their creator (this thread). The semantics of sigwait
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * (see signal_waiter function) requires that all threads have
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * the signal masked. Otherwise a signal that arrives while the
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * signal_waiter is not blocked in sigwait might be delivered to
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * another thread.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Return Values:
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk if ((rc = pthread_sigmask(SIG_BLOCK, &signalSet, NULL)) != 0) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk lm_log(LOG_ERR, "%s:%d set_signal_handling: pthread_sigmask "
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Create signal waiter thread.
NULL)) != 0) {
int err;
char *hello;
char *welcome;
char *corename;
mms_cat_open();
if (lm_daemon_mode) {
MMS_HERE);
if (getuid() != 0) {
for (i = 0; i < OPEN_MAX; i++)
(void) close(i);
if (setsid() < 0) {
(void) umask(0);
#ifdef MMS_OPENSSL
#ifdef MMSDEBUG
#ifdef JDP
return (LM_ERROR);
return (LM_ERROR);
return (LM_ERROR);
return (LM_ERROR);
return (LM_ERROR);
return (LM_OK);
return (rc);
return (rc);
return (rc);
return (rc);
int class;
int code;
tvp);
if (rc < 0) {
} else if (rc == 0) {
if (lm_internal_error) {
if (lm_internal_error) {
if (rc == 0) {
== LM_NOMEM) {
goto parse_ok;
switch (rc) {
case LM_NOMEM:
NULL);
msg_str);
case LM_SYNTAX_ERR:
NULL);
msg_str);
case LM_SYNTAX_RSP:
sizeof (msg_str),
msg_str);
case LM_SYNTAX_CMD:
msg_str);
NULL);
msg_str);
/* accept/unacceptable response and place command onto work */
input);
lm_write_mutex)) {
rsp_str);
msg_str);
lm_write_mutex)) {
code = 0;
class = 0;
switch (rc) {
case LM_C_RESET:
case LM_C_EXIT:
case LM_C_PRIVATE:
case LM_BARRIER:
case LM_CANCEL:
case LM_C_ACTIVATE:
case LM_MOUNT:
case LM_UNMOUNT:
case LM_MOVE:
case LM_INJECT:
case LM_SCAN:
case LM_EJECT:
case MMS_LM_E_DEVCMDILLEGAL:
if (code) {
lm_write_mutex)) {
!= LM_OK) {
* lm.h for a complete description of the elements of
int rc;
&ret_msg[0]);
lm_daemon_mode = 0;
if (lm_internal_error) {
return (exit_code);