mm_notify.c revision cee0fb94c0d4227de0a00efc162fb2739844b641
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/types.h>
#include <mms_list.h>
#include <mms_parser.h>
#include <libpq-fe.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <mms_trace.h>
#include <mms_strapp.h>
#include "mm_db.h"
#include "mm.h"
#include "mm_util.h"
#include "mm_sql.h"
#include "mm_commands.h"
#include "mm_sql.h"
static char *_SrcFile = __FILE__;
/* Event table notification types */
#define ETABLE_STATUS 0
#define ETABLE_REQUEST 1
#define ETABLE_MESSAGE 2
#define ETABLE_CARTRIDGE 3
#define ETABLE_VOLUME 4
/* All possible Notification Levels */
#define NOTIFY_OFF 0
#define NOTIFY_GLOBAL 1
#define NOTIFY_APPLICATION 2
#define NOTIFY_INSTANCE 3
#define NOTIFY_SESSION 4
#define NOTIFY_HOST 5
typedef struct notify notify_t; /* sql table notify object as a structure */
struct notify {
char *n_uuid;
char *n_client;
char *n_inst;
char *n_cfgchg;
char *n_newdrive;
char *n_newcartridge;
char *n_volumeinject;
char *n_volumeeject;
char *n_volumeadd;
char *n_volumedelete;
char *n_dmup;
char *n_dmdown;
char *n_driveonline;
char *n_driveoffline;
char *n_lmup;
char *n_lmdown;
char *n_librarycreate;
char *n_librarydelete;
char *n_drivedelete;
};
static pthread_mutex_t notify_lock;
static mm_db_t notify_db;
static mms_list_t notify_list;
static mm_data_t *notify_data;
static void notify_results(PGresult *results, int row, notify_t *notify);
static void notify_client(mm_wka_t *mm_wka, notify_t *notify,
notify_cmd_t *event);
static int notify_etable(int etable);
/* Initialize notify. */
int
mm_notify_init(mm_data_t *data)
{
mms_trace(MMS_DEVP, "mm_notify_init");
mms_list_create(&notify_list, sizeof (notify_cmd_t),
offsetof(notify_cmd_t, evt_next));
notify_data = data;
memset(&notify_db, 0, sizeof (mm_db_t));
notify_db.mm_db_cfg = data->mm_db.mm_db_cfg;
notify_db.mm_db_has_list = 0;
notify_db.mm_db_resending = 0;
if (mm_db_connect(&notify_db) != MM_DB_OK) {
mms_trace(MMS_ERR, "notify db connection failed");
return (1);
}
mms_list_create(&notify_db.mm_db_cmds, sizeof (mm_char_list_t),
offsetof(mm_char_list_t, mm_char_list_next));
notify_db.mm_db_has_list = 1;
pthread_mutex_init(&notify_lock, NULL);
data->mm_notify_list_mutex = &notify_lock;
data->mm_notify_list_ptr = &notify_list;
return (0);
}
/* Close notify. */
void
mm_notify_close(void)
{
mms_trace(MMS_DEVP, "mm_notify_close");
mm_db_disconnect(&notify_db);
}
void
notify_set_cli_uuid(notify_cmd_t *event, uuid_text_t uuid) {
strncpy(event->evt_cli_uuid,
uuid,
UUID_PRINTF_SIZE);
}
void
notify_set_session_uuid(notify_cmd_t *event, uuid_text_t uuid) {
strncpy(event->evt_session_uuid,
uuid,
UUID_PRINTF_SIZE);
}
void
notify_set_cmd_uuid(notify_cmd_t *event, uuid_text_t uuid) {
strncpy(event->evt_cmd_uuid,
uuid,
UUID_PRINTF_SIZE);
}
void
notify_set_cli_name(notify_cmd_t *event, char *name) {
event->evt_cli_name = mms_strapp(event->evt_cli_name,
name);
}
void
notify_set_cli_instance(notify_cmd_t *event, char *instance) {
event->evt_cli_instance = mms_strapp(event->evt_cli_instance,
instance);
}
void
notify_set_evt_obj_name(notify_cmd_t *event, char *name) {
event->evt_obj_name = mms_strapp(event->evt_obj_name,
name);
}
void
notify_set_evt_obj_instance(notify_cmd_t *event, char *instance) {
event->evt_obj_instance = mms_strapp(event->evt_obj_instance,
instance);
}
void
notify_set_evt_obj_host(notify_cmd_t *event, char *host) {
event->evt_obj_host = mms_strapp(event->evt_obj_host,
host);
}
void
notify_set_evt_obj_library(notify_cmd_t *event, char *library) {
event->evt_obj_library = mms_strapp(event->evt_obj_library,
library);
}
void
notify_set_evt_obj_cartid(notify_cmd_t *event, char *cartid) {
event->evt_obj_cartid = mms_strapp(event->evt_obj_cartid,
cartid);
}
void
notify_set_evt_obj_drive(notify_cmd_t *event, char *drive) {
event->evt_obj_drive = mms_strapp(event->evt_obj_drive,
drive);
}
void
mm_notify_send_status(mm_wka_t *notify_wka, PGresult *results) {
char *event_buf = NULL;
int num_events = PQntuples(results);
char *obj_name;
cci_t *conn = &notify_wka->wka_conn;
char *info1;
char *info2;
char *info3;
int i;
for (i = 0; i < num_events; i++) {
obj_name = PQgetvalue(results, i, 0);
info1 = NULL;
/* This ordering depends on the */
/* select statement in the funtion below */
if (strcmp(obj_name, "LIBRARY") == 0) {
/* library event */
info1 = PQgetvalue(results, i, 1);
} else if (strcmp(obj_name, "DRIVE") == 0) {
/* drive event */
info1 = PQgetvalue(results, i, 1);
} if (strcmp(obj_name, "DM") == 0) {
/* dm event */
info1 = PQgetvalue(results, i, 1);
} else if (strcmp(obj_name, "LM") == 0) {
/* lm event */
info1 = PQgetvalue(results, i, 1);
} else if (strcmp(obj_name, "REQUEST") == 0) {
/* request event */
info1 = PQgetvalue(results, i, 1);
info2 = PQgetvalue(results, i, 2);
info3 = PQgetvalue(results, i, 3);
if (info1 == NULL || info2 == NULL || info3 == NULL) {
info1 = NULL;
}
} else if (strcmp(obj_name, "MESSAGE") == 0) {
/* message event */
info1 = PQgetvalue(results, i, 1);
info2 = PQgetvalue(results, i, 2);
info3 = PQgetvalue(results, i, 3);
if (info1 == NULL || info2 == NULL || info3 == NULL) {
info1 = NULL;
}
} else if (strcmp(obj_name, "CARTRIDGE") == 0) {
/* cartridge event */
info1 = PQgetvalue(results, i, 1);
info2 = PQgetvalue(results, i, 2);
if (info1 == NULL || info2 == NULL) {
info1 = NULL;
}
} else if (strcmp(obj_name, "VOLUME") == 0) {
/* message event */
info1 = PQgetvalue(results, i, 1);
info2 = PQgetvalue(results, i, 2);
info3 = PQgetvalue(results, i, 3);
if (info1 == NULL || info2 == NULL || info3 == NULL) {
info1 = NULL;
}
}
if (info1 != NULL) {
if (strcmp(obj_name, "REQUEST") == 0) {
event_buf = mms_strapp(event_buf,
"event request[\"%s\" \"%s\" \"%s\"];",
info1,
info2,
info3);
} else if (strcmp(obj_name, "MESSAGE") == 0) {
event_buf = mms_strapp(event_buf,
"event message[\"%s\" \"%s\" \"%s\"];",
info1,
info2,
info3);
} else if (strcmp(obj_name, "CARTRIDGE") == 0) {
event_buf = mms_strapp(event_buf,
"event cartridge[\"%s\" \"%s\"];",
info1,
info2);
} else if (strcmp(obj_name, "VOLUME") == 0) {
event_buf = mms_strapp(event_buf,
"event volume[\"%s\" \"%s\" \"%s\"];",
info1,
info2,
info3);
} else {
event_buf = mms_strapp(event_buf,
"event status[\"%s\" \"%s\"];",
obj_name,
info1);
}
mms_trace(MMS_INFO,
"Send event to %s %s, %s",
conn->cci_client,
conn->cci_instance,
event_buf);
mm_send_text(notify_wka->mm_wka_conn,
event_buf);
} else {
mms_trace(MMS_ERR,
"bad status event");
}
if (event_buf) {
free(event_buf);
event_buf = NULL;
}
}
}
char *
mm_write_event(char *notify_obj, PGresult *notify_results,
PGresult *event_results, int i) {
char *event_buf = NULL;
int wrote_data = 0;
int j;
/* same wka */
event_buf = mms_strapp(event_buf,
"event tag[\"%s\"] "
"object[%s]",
PQgetvalue(notify_results, 0, 1),
notify_obj);
for (j = 2; j < 7; j++) {
if (j == 2 &&
strcmp(PQgetvalue(event_results,
i, j), "") == 0) {
continue;
} else if (j == 2) {
wrote_data = 1;
event_buf = mms_strapp(event_buf,
"data[\"%s\" ",
PQgetvalue(event_results,
i, j));
} else if (strcmp(PQgetvalue(event_results,
i, j), "") != 0) {
event_buf = mms_strapp(event_buf,
"\"%s\" ",
PQgetvalue(event_results,
i, j));
}
}
if (wrote_data) {
event_buf = mms_strapp(event_buf, "]");
}
event_buf = mms_strapp(event_buf, ";");
return (event_buf);
}
int
/* LINTED:mm_data may be needed in the future */
mm_notify_event_rules(mm_data_t *mm_data) {
mm_db_t *db = &notify_db;
PGresult *event_results;
int num_events = 0;
PGresult *notify_results;
int i;
char *notify_id;
char *notify_obj;
char *event_buf = NULL;
mm_wka_t *notify_wka;
mm_wka_t *next_notify_wka;
/* Send all events in rule table */
if (mm_db_exec(HERE, db,
"select distinct \"NotifyID\",\"NotifyObject\","
"\"Data1\",\"Data2\",\"Data3\",\"Data4\",\"Data5\" "
" from \"EVENTRULES\";") != MM_DB_DATA) {
mms_trace(MMS_ERR,
"error getting events "
"from EVENTRULES");
return (1);
}
event_results = db->mm_db_results;
num_events = PQntuples(event_results);
mms_trace(MMS_DEVP,
"%d events found",
num_events);
if (num_events == 0) {
mm_clear_db(&event_results);
return (0);
}
for (i = 0; i < num_events; i ++) {
notify_id = PQgetvalue(event_results, i, 0);
notify_obj = PQgetvalue(event_results, i, 1);
if (mm_db_exec(HERE, db,
"select \"ConnectionID\",\"NotifyTag\""
" from \"NOTIFYRULES\" where \"NotifyID\" = '%s';",
notify_id) != MM_DB_DATA) {
mms_trace(MMS_ERR,
"error getting results "
"from NOTIFYRULES");
mm_clear_db(&event_results);
return (1);
}
notify_results = db->mm_db_results;
if (PQntuples(notify_results) == 0) {
/* no notify row for this */
char *savepoint = NULL;
savepoint = mms_strnew("\"%s\"", notify_id);
if (mm_db_txn_savepoint(db,
savepoint) != MM_DB_OK) {
mms_trace(MMS_ERR,
"mm_notify_event_rules: "
"db error setting savepoint");
}
if (mm_db_exec(HERE, db,
"drop rule \"%s\" on \"%s\";", notify_id,
notify_obj) !=
MM_DB_OK) {
if (mm_db_txn_savepoint_rollback(db,
savepoint) != MM_DB_OK) {
mms_trace(MMS_ERR,
"mm_notify_event_rules: "
"db error rollingback savepoint");
}
}
if (mm_db_txn_release_savepoint(db,
savepoint) != MM_DB_OK) {
mms_trace(MMS_ERR,
"mm_notify_event_rules: "
"db error releaseing savepoint");
}
free(savepoint);
} else {
mms_trace(MMS_DEVP,
"send event to %s, %s",
PQgetvalue(notify_results, 0, 0),
PQgetvalue(notify_results, 0, 1));
pthread_mutex_lock(&notify_data->mm_wka_mutex);
for (notify_wka =
mms_list_head(&notify_data->mm_wka_list);
notify_wka != NULL;
notify_wka = next_notify_wka) {
pthread_mutex_lock(&notify_wka->wka_local_lock);
pthread_mutex_unlock(&notify_data->
mm_wka_mutex);
if (strcmp(notify_wka->wka_conn.cci_uuid,
PQgetvalue(notify_results, 0, 0)) == 0) {
/* same wka */
if ((event_buf =
mm_write_event(notify_obj,
notify_results,
event_results, i)) == NULL) {
mms_trace(MMS_ERR,
"error writing "
"event buffer");
} else {
mm_send_text(notify_wka->
mm_wka_conn,
event_buf);
free(event_buf);
event_buf = NULL;
}
}
pthread_mutex_lock(&notify_data->
mm_wka_mutex);
next_notify_wka =
mms_list_next(&notify_data->mm_wka_list,
notify_wka);
pthread_mutex_unlock(&notify_wka->
wka_local_lock);
}
pthread_mutex_unlock(&notify_data->mm_wka_mutex);
}
if (mm_db_exec(HERE, db,
"delete from \"EVENTRULES\""
" where \"NotifyID\" = '%s';",
notify_id) != MM_DB_OK) {
mms_trace(MMS_ERR,
"error deleting "
"from NOTIFYRULES");
mm_clear_db(&event_results);
mm_clear_db(&notify_results);
return (1);
}
}
mm_clear_db(&event_results);
mm_clear_db(&notify_results);
return (0);
}
int
/* LINTED:mm_data maybe used in the future */
mm_notify_event_table(mm_data_t *mm_data) {
mm_db_t *db = &notify_db;
int rc;
rc = notify_etable(ETABLE_STATUS);
if (rc == 0) {
rc = notify_etable(ETABLE_REQUEST);
}
if (rc == 0) {
rc = notify_etable(ETABLE_MESSAGE);
}
if (rc == 0) {
rc = notify_etable(ETABLE_CARTRIDGE);
}
if (rc == 0) {
rc = notify_etable(ETABLE_VOLUME);
}
mms_trace(MMS_DEVP,
"clear event table of processed events");
if (mm_db_exec(HERE, db, "delete from \"EVENT\" "
"where \"Seen\" = 't';") != MM_DB_OK) {
mms_trace(MMS_ERR, "clear event table");
rc = 1;
}
return (rc);
}
static int
notify_etable(int etable) {
mm_db_t *db = &notify_db;
/* Event results */
PGresult *event_results;
int num_events = 0;
/* Client results */
PGresult *client_results;
int num_clients = 0;
int i;
/* Wka lookup */
mm_wka_t *notify_wka;
mm_wka_t *next_notify_wka;
char *cur_uuid = NULL;
/* Event specific */
char *where;
char *what;
switch (etable) {
case ETABLE_STATUS:
where = "where (\"ObjectName\" = 'LIBRARY' or "
"\"ObjectName\" = 'LM' or "
"\"ObjectName\" = 'DRIVE' or "
"\"ObjectName\" = 'DM')";
what = "NotifyStatus";
break;
case ETABLE_REQUEST:
where = "where (\"ObjectName\" = 'REQUEST')";
what = "NotifyRequest";
break;
case ETABLE_MESSAGE:
where = "where (\"ObjectName\" = 'MESSAGE')";
what = "NotifyMessage";
break;
case ETABLE_CARTRIDGE:
where = "where (\"ObjectName\" = 'CARTRIDGE')";
what = "NotifyCartridge";
break;
case ETABLE_VOLUME:
where = "where (\"ObjectName\" = 'VOLUME')";
what = "NotifyVolume";
break;
default:
mms_trace(MMS_ERR,
"unknown event table type %d", etable);
return (1);
}
/* flag events we're going to process */
if (mm_db_exec(HERE, db,
"update \"EVENT\" set \"Seen\" = 't' %s;",
where) != MM_DB_OK) {
mms_trace(MMS_ERR,
"error setting event seen");
return (1);
}
/* Get all the events */
/* send_status_event is dependent */
/* on the ordering of the */
/* attributes in this select */
if (mm_db_exec(HERE, db,
"select distinct \"ObjectName\","
"\"Info1\",\"Info2\",\"Info3\",\"Info4\" from "
"\"EVENT\" %s and (\"Seen\" = 't');",
where) != MM_DB_DATA) {
mms_trace(MMS_ERR,
"error getting event data from db");
mm_clear_db(&db->mm_db_results);
return (1);
}
event_results = db->mm_db_results;
num_events = PQntuples(event_results);
if (num_events == 0) {
mms_trace(MMS_DEVP,
"No events found in event table");
mm_clear_db(&event_results);
return (0);
}
mms_trace(MMS_DEVP, "num status events %d", num_events);
/* Get all the subscribers */
if (mm_db_exec(HERE, db,
"select \"ConnectionID\" from "
"\"NOTIFY\" where "
"\"%s\" != "
"'off';", what) != MM_DB_DATA) {
mm_clear_db(&event_results);
mms_trace(MMS_ERR,
"error getting client data from db");
return (1);
}
client_results = db->mm_db_results;
num_clients = PQntuples(client_results);
if (num_clients == 0) {
mms_trace(MMS_DEVP,
"No clients subscribed to status events");
mm_clear_db(&event_results);
mm_clear_db(&client_results);
return (0);
}
mms_trace(MMS_DEVP, "num subscribed clients %d", num_clients);
/* Send the events to the subscribers */
pthread_mutex_lock(&notify_data->mm_wka_mutex);
for (notify_wka = mms_list_head(&notify_data->mm_wka_list);
notify_wka != NULL;
notify_wka = next_notify_wka) {
pthread_mutex_lock(&notify_wka->wka_local_lock);
pthread_mutex_unlock(&notify_data->mm_wka_mutex);
for (i = 0; i < num_clients; i ++) {
cur_uuid = PQgetvalue(client_results, i, 0);
if (strcmp(notify_wka->wka_conn.cci_uuid,
cur_uuid) == 0) {
/* This client needs the events */
mm_notify_send_status(notify_wka,
event_results);
}
}
pthread_mutex_lock(&notify_data->mm_wka_mutex);
next_notify_wka = mms_list_next(&notify_data->mm_wka_list,
notify_wka);
pthread_mutex_unlock(&notify_wka->wka_local_lock);
}
pthread_mutex_unlock(&notify_data->mm_wka_mutex);
mm_clear_db(&event_results);
mm_clear_db(&client_results);
return (0);
}
int
mm_notify_add_driveonline(mm_wka_t *mm_wka, mm_command_t *cmd,
char *drivename) {
notify_cmd_t *event = NULL;
if (drivename == NULL) {
mms_trace(MMS_ERR,
"drivename cannot be NULL, "
"mm_notify_add_driveonline");
return (1);
}
if ((event = mm_notify_add("event driveonline[\"%s\"];",
drivename)) == NULL) {
mms_trace(MMS_ERR, "Error adding notify event");
return (1);
} else {
mms_trace(MMS_DEBUG, "Added notify event event");
notify_set_cli_uuid(event,
mm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
mm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
mm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "DRIVE");
notify_set_evt_obj_instance(event, drivename);
notify_set_cmd_uuid(event, cmd->cmd_uuid);
}
return (0);
}
int
mm_notify_add_driveoffline(mm_wka_t *mm_wka, mm_command_t *cmd,
char *drivename) {
notify_cmd_t *event = NULL;
if (drivename == NULL) {
mms_trace(MMS_ERR,
"drivename cannot be NULL, "
"mm_notify_add_driveoffline");
return (1);
}
if ((event = mm_notify_add("event driveoffline[\"%s\"];",
drivename)) == NULL) {
mms_trace(MMS_ERR, "Error adding notify event");
return (1);
} else {
mms_trace(MMS_DEBUG, "Added notify event event");
notify_set_cli_uuid(event,
mm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
mm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
mm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "DRIVE");
notify_set_evt_obj_instance(event, drivename);
notify_set_cmd_uuid(event, cmd->cmd_uuid);
}
return (0);
}
void
mm_notify_add_dmdown(mm_wka_t *dm_wka, mm_command_t *cmd) {
notify_cmd_t *event = NULL;
char *drivename = dm_wka->wka_conn.cci_client;
char *dmhost = dm_wka->wka_conn.cci_host;
char *dmname = dm_wka->wka_conn.cci_instance;
if ((event = mm_notify_add("event dmdown[\"%s\" \"%s\" \"%s\"];",
dmname,
drivename,
dmhost)) == NULL) {
mms_trace(MMS_ERR, "Error adding notify event");
} else {
mms_trace(MMS_DEBUG, "Added notify event event");
notify_set_cli_uuid(event,
dm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
dm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
dm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "DM");
notify_set_evt_obj_instance(event, dmname);
notify_set_evt_obj_host(event, dmhost);
notify_set_evt_obj_drive(event, drivename);
if (cmd != NULL) {
notify_set_cmd_uuid(event, cmd->cmd_uuid);
} else {
event->evt_can_dispatch = 1;
}
}
}
int
mm_notify_add_dmdown_dc(mm_wka_t *dm_wka, mm_db_t *db) {
/* This function is called by the main thread, not the worker */
/* So it will need to use the main thread's db connection */
/* If dm is in a ready state, add an event */
if (mm_db_exec(HERE, db,
"select \"DMName\" from "
"\"DMCAPABILITYGROUP\" where "
"\"DMName\" = '%s';",
dm_wka->wka_conn.cci_instance) != MM_DB_DATA) {
mms_trace(MMS_ERR,
"db error, mm_notify_add_dmdown_dc");
mm_clear_db(&db->mm_db_results);
return (1);
}
if (PQntuples(db->mm_db_results) == 0) {
mms_trace(MMS_ERR,
"rows != 1, mm_notify_add_dmdown_dc");
mm_clear_db(&db->mm_db_results);
return (1);
}
mm_notify_add_dmdown(dm_wka, NULL);
mm_clear_db(&db->mm_db_results);
return (0);
}
void
mm_notify_add_dmup(mm_wka_t *dm_wka, mm_command_t *cmd) {
notify_cmd_t *event = NULL;
char *drivename = dm_wka->wka_conn.cci_client;
char *dmhost = dm_wka->wka_conn.cci_host;
char *dmname = dm_wka->wka_conn.cci_instance;
/* Get DMTargetHost and DriveName */
if ((event = mm_notify_add("event dmup[\"%s\" \"%s\" \"%s\"];",
dmname,
drivename,
dmhost)) == NULL) {
mms_trace(MMS_ERR, "Error adding notify event");
} else {
mms_trace(MMS_DEBUG, "Added notify event event");
notify_set_cli_uuid(event,
dm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
dm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
dm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "DM");
notify_set_evt_obj_instance(event, dmname);
notify_set_evt_obj_host(event, dmhost);
notify_set_evt_obj_drive(event, drivename);
notify_set_cmd_uuid(event, cmd->cmd_uuid);
}
}
void
mm_notify_add_librarycreate(mm_wka_t *mm_wka, mm_command_t *cmd,
char *libraryname) {
notify_cmd_t *event = NULL;
if ((event = mm_notify_add("event librarycreate[\"%s\"];",
libraryname)) == NULL) {
mms_trace(MMS_ERR, "Error adding notify event");
} else {
mms_trace(MMS_DEBUG, "Added notify event event");
notify_set_cli_uuid(event,
mm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
mm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
mm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "LIBRARY");
notify_set_evt_obj_library(event, libraryname);
notify_set_cmd_uuid(event, cmd->cmd_uuid);
}
}
void
mm_notify_add_librarydelete(mm_db_t *db, mm_wka_t *mm_wka,
mm_command_t *cmd, int match_off) {
notify_cmd_t *event = NULL;
PGresult *results;
int rows;
int row;
char *libraryname = NULL;
if (mm_db_exec(HERE, db, "SELECT \"LibraryName\""
" FROM \"LIBRARY\" %s",
&cmd->cmd_buf[match_off]) != MM_DB_DATA) {
mms_trace(MMS_ERR,
"data base error getting library name");
return;
}
results = db->mm_db_results;
rows = PQntuples(results);
if (rows == 0) {
mms_trace(MMS_DEVP, "Didn't match any library for delete");
mm_clear_db(&results);
return;
}
for (row = 0; row < rows; row ++) {
event = NULL;
libraryname = PQgetvalue(results, row, 0);
if ((event = mm_notify_add("event librarydelete[\"%s\"];",
libraryname)) == NULL) {
mms_trace(MMS_ERR, "Error adding notify event");
} else {
mms_trace(MMS_DEBUG, "Added librarydelete event for %s",
libraryname);
notify_set_cli_uuid(event,
mm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
mm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
mm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "LIBRARY");
notify_set_evt_obj_library(event, libraryname);
notify_set_cmd_uuid(event, cmd->cmd_uuid);
}
}
mm_clear_db(&results);
}
void
mm_notify_add_drivedelete(mm_db_t *db, mm_wka_t *mm_wka,
mm_command_t *cmd, int match_off) {
notify_cmd_t *event = NULL;
PGresult *results;
int rows;
int row;
char *drivename = NULL;
if (mm_db_exec(HERE, db, "SELECT \"DriveName\""
" FROM \"DRIVE\" %s",
&cmd->cmd_buf[match_off]) != MM_DB_DATA) {
mms_trace(MMS_ERR,
"data base error getting drive name");
return;
}
results = db->mm_db_results;
rows = PQntuples(results);
if (rows == 0) {
mms_trace(MMS_DEVP, "Didn't match any drive for delete");
mm_clear_db(&results);
return;
}
for (row = 0; row < rows; row ++) {
event = NULL;
drivename = PQgetvalue(results, row, 0);
if ((event = mm_notify_add("event drivedelete[\"%s\"];",
drivename)) == NULL) {
mms_trace(MMS_ERR, "Error adding notify event");
} else {
mms_trace(MMS_DEBUG, "Added drivedelete event for %s",
drivename);
notify_set_cli_uuid(event,
mm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
mm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
mm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "DRIVE");
notify_set_cmd_uuid(event, cmd->cmd_uuid);
}
}
mm_clear_db(&results);
}
void
mm_notify_add_newcartridge(mm_wka_t *mm_wka, mm_command_t *cmd,
char *cartridgepcl,
char *libraryname) {
notify_cmd_t *event = NULL;
if ((event = mm_notify_add("event newcartridge[\"%s\" \"%s\"];",
cartridgepcl,
libraryname)) == NULL) {
mms_trace(MMS_ERR, "Error adding notify event");
} else {
mms_trace(MMS_DEBUG, "Added notify event event");
notify_set_cli_uuid(event,
mm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
mm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
mm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "CARTRIDGE");
notify_set_evt_obj_instance(event, cartridgepcl);
notify_set_evt_obj_library(event, libraryname);
notify_set_cmd_uuid(event, cmd->cmd_uuid);
}
}
void
mm_notify_add_newdrive(mm_wka_t *mm_wka, mm_command_t *cmd,
char *drivename, char *libraryname) {
notify_cmd_t *event = NULL;
if ((event = mm_notify_add("event newdrive[\"%s\" \"%s\"];",
drivename,
libraryname)) == NULL) {
mms_trace(MMS_ERR, "Error adding newdrive event");
} else {
mms_trace(MMS_DEBUG, "Added newdrive event");
notify_set_cli_uuid(event,
mm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
mm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
mm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "DRIVE");
notify_set_evt_obj_instance(event, drivename);
notify_set_evt_obj_library(event, libraryname);
notify_set_cmd_uuid(event, cmd->cmd_uuid);
}
}
int
mm_notify_add_volumedelete(mm_wka_t *mm_wka, mm_command_t *cmd,
char *cartid, mm_db_t *db) {
notify_cmd_t *event = NULL;
if (cartid == NULL) {
mms_trace(MMS_ERR,
"cannot have null cartid"
", mm_notify_add_volumedelete");
return (1);
}
/* First find this cartridge type */
if (mm_db_exec(HERE, db,
"select "
"\"CARTRIDGE\".\"CartridgeTypeName\","
"\"VOLUME\".\"VolumeName\" from "
"\"CARTRIDGE\",\"VOLUME\" where "
"\"VOLUME\".\"CartridgeID\" ="
"\"CARTRIDGE\".\"CartridgeID\" and "
"\"VOLUME\".\"CartridgeID\" = '%s';",
cartid) != MM_DB_DATA) {
mm_clear_db(&db->mm_db_results);
mms_trace(MMS_ERR,
"db error getting cartridge "
"type for %s, volumedelete event",
cartid);
return (1);
}
if (PQntuples(db->mm_db_results) != 1) {
mms_trace(MMS_ERR,
"db error getting cartridge type, "
"%d rows returned, volumedelete event",
PQntuples(db->mm_db_results));
mm_clear_db(&db->mm_db_results);
return (1);
}
if ((event = mm_notify_add("event "
"volumedelete[\"%s\" \"%s\"];",
PQgetvalue(db->mm_db_results, 0, 1),
PQgetvalue(db->mm_db_results, 0, 0))) == NULL) {
mms_trace(MMS_ERR, "Error adding volumedelete event");
mm_clear_db(&db->mm_db_results);
return (1);
} else {
mms_trace(MMS_DEBUG, "Added volumedelete event event");
notify_set_cli_uuid(event,
mm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
mm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
mm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "VOLUME");
notify_set_evt_obj_instance(event,
PQgetvalue(db->mm_db_results, 0, 1));
notify_set_evt_obj_cartid(event,
cartid);
notify_set_cmd_uuid(event, cmd->cmd_uuid);
mm_clear_db(&db->mm_db_results);
}
return (0);
}
int
mm_notify_add_volumeeject(mm_wka_t *lm_wka, mm_command_t *cmd,
char *pcl, mm_db_t *db) {
notify_cmd_t *event = NULL;
char *library_name = lm_wka->wka_conn.cci_client;
char *volname = NULL;
char *carttype = NULL;
char *cartid = NULL;
int num_vols = 0;
int i;
if (mm_db_exec(HERE, db,
"select "
"\"CARTRIDGE\".\"CartridgeTypeName\","
"\"VOLUME\".\"VolumeName\", "
"\"CARTRIDGE\".\"CartridgeID\" "
"from "
"\"CARTRIDGE\",\"VOLUME\" "
"where ( "
"(\"VOLUME\".\"CartridgeID\" = "
"\"CARTRIDGE\".\"CartridgeID\") "
"and "
"(\"CARTRIDGE\".\"LibraryName\" = '%s') "
"and "
"(\"CARTRIDGE\".\"CartridgePCL\" = '%s'));",
library_name,
pcl) != MM_DB_DATA) {
mm_clear_db(&db->mm_db_results);
mms_trace(MMS_ERR,
"db error getting cartridge "
"type for %s, volumeeject event",
pcl);
return (1);
}
num_vols = PQntuples(db->mm_db_results);
mms_trace(MMS_DEBUG,
"%d volume(s) for cart, %s %s",
num_vols,
pcl,
library_name);
for (i = 0; i < num_vols; i ++) {
carttype = PQgetvalue(db->mm_db_results, i, 0);
volname = PQgetvalue(db->mm_db_results, i, 1);
cartid = PQgetvalue(db->mm_db_results, i, 2);
event = NULL;
if ((event = mm_notify_add("event "
"volumeeject[\"%s\" \"%s\"];",
volname,
carttype)) == NULL) {
mms_trace(MMS_ERR, "Error adding volumeeject event");
mm_clear_db(&db->mm_db_results);
return (1);
} else {
mms_trace(MMS_DEBUG, "Added volumeeject event event");
notify_set_cli_uuid(event,
lm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
lm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
lm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "VOLUME");
notify_set_evt_obj_cartid(event,
cartid);
notify_set_evt_obj_instance(event,
volname);
notify_set_cmd_uuid(event, cmd->cmd_uuid);
}
}
mm_clear_db(&db->mm_db_results);
return (0);
}
int
mm_notify_add_volumeinject(mm_wka_t *lm_wka, mm_command_t *cmd,
char *pcl, mm_db_t *db) {
notify_cmd_t *event = NULL;
char *library_name = lm_wka->wka_conn.cci_client;
char *volname = NULL;
char *carttype = NULL;
char *cartid = NULL;
int num_vols = 0;
int i;
if (mm_db_exec(HERE, db,
"select "
"\"CARTRIDGE\".\"CartridgeTypeName\","
"\"VOLUME\".\"VolumeName\", "
"\"CARTRIDGE\".\"CartridgeID\" "
"from "
"\"CARTRIDGE\",\"VOLUME\" "
"where ( "
"(\"VOLUME\".\"CartridgeID\" = "
"\"CARTRIDGE\".\"CartridgeID\") "
"and "
"(\"CARTRIDGE\".\"LibraryName\" = '%s') "
"and "
"(\"CARTRIDGE\".\"CartridgePCL\" = '%s'));",
library_name,
pcl) != MM_DB_DATA) {
mm_clear_db(&db->mm_db_results);
mms_trace(MMS_ERR,
"db error getting cartridge "
"type for %s, volumeinject event",
pcl);
return (1);
}
num_vols = PQntuples(db->mm_db_results);
mms_trace(MMS_DEBUG,
"%d volume(s) for cart, %s %s",
num_vols,
pcl,
library_name);
for (i = 0; i < num_vols; i ++) {
carttype = PQgetvalue(db->mm_db_results, i, 0);
volname = PQgetvalue(db->mm_db_results, i, 1);
cartid = PQgetvalue(db->mm_db_results, i, 2);
event = NULL;
if ((event = mm_notify_add("event "
"volumeinject[\"%s\" \"%s\"];",
volname,
carttype)) == NULL) {
mms_trace(MMS_ERR, "Error adding volumeinject event");
mm_clear_db(&db->mm_db_results);
return (1);
} else {
mms_trace(MMS_DEBUG, "Added volumeinject event event");
notify_set_cli_uuid(event,
lm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
lm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
lm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "VOLUME");
notify_set_evt_obj_cartid(event,
cartid);
notify_set_evt_obj_instance(event,
volname);
notify_set_cmd_uuid(event, cmd->cmd_uuid);
}
}
mm_clear_db(&db->mm_db_results);
return (0);
}
int
mm_notify_add_volumeadd(mm_wka_t *mm_wka, mm_command_t *cmd,
char *volumename, char *cartid, mm_db_t *db) {
notify_cmd_t *event = NULL;
if (volumename == NULL) {
mms_trace(MMS_ERR,
"cannot have null volumename"
", mm_notify_add_volumeadd");
return (1);
}
if (cartid == NULL) {
mms_trace(MMS_ERR,
"cannot have null cartid"
", mm_notify_add_volumeadd");
return (1);
}
/* First find this cartridge type */
if (mm_db_exec(HERE, db,
"select "
"\"CARTRIDGE\".\"CartridgeTypeName\" "
"from \"CARTRIDGE\" "
"where "
"\"CARTRIDGE\".\"CartridgeID\" = '%s';",
cartid) != MM_DB_DATA) {
mm_clear_db(&db->mm_db_results);
mms_trace(MMS_ERR,
"db error getting cartridge "
"type for %s, volumeadd event",
volumename);
return (1);
}
if (PQntuples(db->mm_db_results) != 1) {
mms_trace(MMS_ERR,
"db error getting cartridge type, "
"%d rows returned, volumeadd event",
PQntuples(db->mm_db_results));
mm_clear_db(&db->mm_db_results);
return (1);
}
if ((event = mm_notify_add("event "
"volumeadd[\"%s\" \"%s\"];",
volumename,
PQgetvalue(db->mm_db_results, 0, 0))) == NULL) {
mms_trace(MMS_ERR, "Error adding volumeadd event");
mm_clear_db(&db->mm_db_results);
return (1);
} else {
mm_clear_db(&db->mm_db_results);
mms_trace(MMS_DEBUG, "Added volumeadd event event");
notify_set_cli_uuid(event,
mm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
mm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
mm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "VOLUME");
notify_set_evt_obj_instance(event,
volumename);
notify_set_evt_obj_cartid(event,
cartid);
notify_set_cmd_uuid(event, cmd->cmd_uuid);
}
return (0);
}
int
mm_notify_add_lmup(mm_wka_t *lm_wka, mm_command_t *cmd) {
/* This adds an lmready event to the event queue */
/* lm_wka should be the wka of the lm who is ready */
/* Library Ready event */
notify_cmd_t *event = NULL;
if ((event = mm_notify_add("event "
"lmup[\"%s\" \"%s\"];",
lm_wka->wka_conn.cci_instance,
lm_wka->wka_conn.cci_client)) == NULL) {
mms_trace(MMS_ERR, "Error adding lmready event");
return (1);
} else {
mms_trace(MMS_DEBUG, "Added lmup event event");
notify_set_cli_uuid(event,
lm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
lm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
lm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "LM");
notify_set_evt_obj_instance(event,
lm_wka->wka_conn.cci_instance);
notify_set_evt_obj_library(event,
lm_wka->wka_conn.cci_client);
notify_set_cmd_uuid(event, cmd->cmd_uuid);
}
return (0);
}
int
mm_notify_add_lmdown_dc(mm_wka_t *lm_wka, mm_db_t *db) {
/* This function is called by the main thread, not the worker */
/* So it will need to use the main thread's db connection */
/* If lm is in a ready state, add an event */
if (mm_db_exec(HERE, db,
"select \"LMStateSoft\" "
"from \"LM\" where "
"\"LMName\" = '%s';",
lm_wka->wka_conn.cci_instance) != MM_DB_DATA) {
mms_trace(MMS_ERR,
"db error, mm_notify_add_lmdown_dc");
mm_clear_db(&db->mm_db_results);
return (1);
}
if (PQntuples(db->mm_db_results) != 1) {
mms_trace(MMS_ERR,
"rows != 1, mm_notify_add_lmdown_dc");
mm_clear_db(&db->mm_db_results);
return (1);
}
if (strcmp(PQgetvalue(db->mm_db_results, 0, 0),
"ready") == 0) {
mms_trace(MMS_DEBUG,
"lm dissconnected in ready state, add event");
if (mm_notify_add_lmdown(lm_wka, NULL)) {
mms_trace(MMS_ERR,
"mm_notify_add_lmdown_dc: "
"error adding lm down event");
}
}
mm_clear_db(&db->mm_db_results);
return (0);
}
int
mm_notify_add_lmdown(mm_wka_t *lm_wka, mm_command_t *cmd) {
/* This adds an lmready event to the event queue */
/* lm_wka should be the wka of the lm who is ready */
/* Library Ready event */
notify_cmd_t *event = NULL;
if ((event = mm_notify_add("event "
"lmdown[\"%s\" \"%s\"];",
lm_wka->wka_conn.cci_instance,
lm_wka->wka_conn.cci_client)) == NULL) {
mms_trace(MMS_ERR, "Error adding lmready event");
return (1);
} else {
mms_trace(MMS_DEBUG, "Added lmup event event");
notify_set_cli_uuid(event,
lm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
lm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
lm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, "LM");
notify_set_evt_obj_instance(event,
lm_wka->wka_conn.cci_instance);
notify_set_evt_obj_library(event,
lm_wka->wka_conn.cci_client);
if (cmd != NULL) {
notify_set_cmd_uuid(event, cmd->cmd_uuid);
} else {
event->evt_can_dispatch = 1;
}
}
return (0);
}
int
mm_notify_add_config(mm_wka_t *mm_wka, mm_command_t *cmd,
char *type, char *name, char *instance,
char *host) {
notify_cmd_t *event = NULL;
if (strcmp(type, "change") == 0) {
if ((event = mm_notify_add(NOTIFY_EVENT_CFG_CHG,
name,
instance,
instance)) == NULL) {
mms_trace(MMS_ERR, "Error adding config event");
return (1);
}
} else {
if ((event = mm_notify_add(NOTIFY_EVENT_CFG, name,
type, instance)) == NULL) {
mms_trace(MMS_ERR, "Error adding config event");
return (1);
}
}
mms_trace(MMS_DEBUG, "Added config event");
notify_set_cli_uuid(event,
mm_wka->wka_conn.cci_uuid);
notify_set_cli_name(event,
mm_wka->wka_conn.cci_client);
notify_set_cli_instance(event,
mm_wka->wka_conn.cci_instance);
notify_set_evt_obj_name(event, name);
notify_set_evt_obj_instance(event, instance);
notify_set_evt_obj_host(event, host);
notify_set_cmd_uuid(event, cmd->cmd_uuid);
return (0);
}
/* Add event to pending event list for client. */
notify_cmd_t *
mm_notify_add(char *event_fmt, ...)
{
va_list args;
notify_cmd_t *event = NULL;
mms_trace(MMS_DEVP, "mm_notify_add");
if ((event = (notify_cmd_t *)calloc(1,
sizeof (notify_cmd_t))) == NULL) {
return (NULL);
}
va_start(args, event_fmt);
event->evt_cmd = mms_vstrapp(NULL, event_fmt, args);
va_end(args);
if (event->evt_cmd == NULL) {
free(event);
return (NULL);
}
event->evt_can_dispatch = 0;
event->evt_cli_name = NULL;
event->evt_cli_instance = NULL;
event->evt_obj_name = NULL;
event->evt_obj_host = NULL;
event->evt_obj_library = NULL;
event->evt_obj_cartid = NULL;
event->evt_obj_drive = NULL;
event->evt_obj_app = NULL;
event->evt_obj_appinst = NULL;
mms_trace(MMS_DEBUG,
"Added event, %s",
event->evt_cmd);
pthread_mutex_lock(&notify_lock);
mms_list_insert_tail(&notify_list, event);
pthread_mutex_unlock(&notify_lock);
return (event);
}
void
mm_notify_destroy(notify_cmd_t *event) {
/* clean up the event */
if (event->evt_cmd != NULL)
free(event->evt_cmd);
if (event->evt_cli_name != NULL)
free(event->evt_cli_name);
if (event->evt_obj_name != NULL)
free(event->evt_obj_name);
if (event->evt_obj_instance != NULL)
free(event->evt_obj_instance);
if (event->evt_obj_host != NULL)
free(event->evt_obj_host);
if (event->evt_obj_library != NULL)
free(event->evt_obj_library);
if (event->evt_obj_cartid != NULL)
free(event->evt_obj_cartid);
if (event->evt_obj_drive != NULL)
free(event->evt_obj_drive);
if (event->evt_obj_app != NULL)
free(event->evt_obj_app);
if (event->evt_obj_appinst != NULL)
free(event->evt_obj_appinst);
if (event->evt_cli_instance != NULL)
free(event->evt_cli_instance);
free(event);
}
/* Command or action was successful, send client events. */
void
mm_notify_commit(char *cmd_uuid) {
notify_cmd_t *event;
mms_trace(MMS_DEVP,
"mm_notify_commit");
pthread_mutex_lock(&notify_lock);
mms_list_foreach(&notify_list, event) {
if (strcmp(event->evt_cmd_uuid, cmd_uuid) == 0) {
mms_trace(MMS_DEVP,
"commit event %s",
event->evt_cmd);
event->evt_can_dispatch = 1;
}
}
pthread_mutex_unlock(&notify_lock);
}
void
mm_notify_rollback(char *cmd_uuid) {
notify_cmd_t *event;
notify_cmd_t *next_event;
mms_trace(MMS_DEVP,
"mm_notify_rollback");
pthread_mutex_lock(&notify_lock);
for (event = mms_list_head(&notify_list);
event != NULL;
event = next_event) {
next_event = mms_list_next(&notify_list, event);
if (strcmp(event->evt_cmd_uuid, cmd_uuid) == 0) {
mms_list_remove(&notify_list, event);
mms_trace(MMS_DEVP, "remove event, %s",
event->evt_cmd);
mm_notify_destroy(event);
}
}
pthread_mutex_unlock(&notify_lock);
}
/* Send event now. */
int
mm_notify_now(char *cli_uuid, char *event_fmt, ...)
{
va_list args;
notify_cmd_t *event;
mms_trace(MMS_DEVP, "mm_notify_now");
if ((event = (notify_cmd_t *)calloc(1,
sizeof (notify_cmd_t))) == NULL) {
return (1);
}
va_start(args, event_fmt);
event->evt_cmd = mms_vstrapp(NULL, event_fmt, args);
va_end(args);
if (event->evt_cmd == NULL) {
free(event);
return (1);
}
if (cli_uuid) {
/* not mm event */
strncpy(event->evt_cli_uuid, cli_uuid, UUID_PRINTF_SIZE);
/* Find session, application and instance for this client */
}
event->evt_can_dispatch = 1;
mms_trace(MMS_DEVP,
"adding event for immediate dispatch, %s",
event->evt_cmd);
pthread_mutex_lock(&notify_lock);
mms_list_insert_tail(&notify_list, event);
pthread_mutex_unlock(&notify_lock);
return (0);
}
int
notify_send(notify_cmd_t *event)
{
notify_t notify;
int rows;
mm_wka_t *notify_wka;
mm_wka_t *next_notify_wka;
int print_message = 0;
mm_db_t *db = &notify_db;
char *cli_name = event->evt_cli_name;
char *cli_instance = event->evt_cli_instance;
char *obj_name = event->evt_obj_name;
char *obj_instance = event->evt_obj_instance;
char *obj_host = event->evt_obj_host;
char *obj_library = event->evt_obj_library;
char *obj_cartid = event->evt_obj_cartid;
char *obj_drive = event->evt_obj_drive;
PGresult *results;
mms_trace(MMS_DEBUG,
"notify_send");
mms_trace(MMS_DEBUG,
"send event %s",
event->evt_cmd);
if (cli_name)
mms_trace(MMS_DEBUG,
" client name, %s",
cli_name);
if (cli_instance)
mms_trace(MMS_DEBUG,
" client instance, %s",
cli_instance);
if (obj_name)
mms_trace(MMS_DEBUG,
" object name, %s",
obj_name);
if (obj_instance)
mms_trace(MMS_DEBUG,
" object instance, %s",
obj_instance);
if (obj_host)
mms_trace(MMS_DEBUG,
" object host, %s",
obj_host);
if (obj_library)
mms_trace(MMS_DEBUG,
" object library, %s",
obj_library);
if (obj_cartid)
mms_trace(MMS_DEBUG,
" object cartid, %s",
obj_cartid);
if (obj_drive)
mms_trace(MMS_DEBUG,
" object drive, %s",
obj_drive);
/*
* Send event to mm subsribers.
*/
pthread_mutex_lock(&notify_data->mm_wka_mutex);
for (notify_wka = mms_list_head(&notify_data->mm_wka_list);
notify_wka != NULL;
notify_wka = next_notify_wka) {
pthread_mutex_lock(&notify_wka->wka_local_lock);
pthread_mutex_unlock(&notify_data->mm_wka_mutex);
if (print_message)
mms_trace(MMS_INFO, "examining a client, %s",
notify_wka->wka_conn.cci_uuid);
if (mm_db_exec(HERE, db, "SELECT \"ConnectionID\","
"\"ConnectionClientName\","
"\"ConnectionClientInstance\","
"\"NotifyConfigChange\","
"\"NotifyNewDrive\", "
"\"NotifyNewCartridge\", "
"\"NotifyVolumeAdd\", "
"\"NotifyVolumeDelete\", "
"\"NotifyDMUp\", "
"\"NotifyDMDown\", "
"\"NotifyDriveOnline\", "
"\"NotifyDriveOffline\", "
"\"NotifyLMUp\", "
"\"NotifyLMDown\", "
"\"NotifyVolumeInject\", "
"\"NotifyVolumeEject\", "
"\"NotifyLibraryCreate\", "
"\"NotifyLibraryDelete\", "
"\"NotifyDriveDelete\" "
"FROM \"NOTIFY\""
"where \"ConnectionID\" = '%s';",
notify_wka->wka_conn.cci_uuid) != MM_DB_DATA) {
mm_clear_db(&db->mm_db_results);
mms_trace(MMS_DEBUG, "notify db select failed");
return (1);
}
rows = PQntuples(db->mm_db_results);
results = db->mm_db_results;
if (rows != 0) {
mms_trace(MMS_DEVP,
"notify a client");
/* NOTIFY entry for this connection */
/* Set up the notify struct */
notify_results(results, 0, &notify);
/* Notify the client */
notify_client(notify_wka, &notify,
event);
} else {
mms_trace(MMS_DEVP,
"client has no notification settings");
}
pthread_mutex_lock(&notify_data->mm_wka_mutex);
next_notify_wka = mms_list_next(&notify_data->mm_wka_list,
notify_wka);
pthread_mutex_unlock(&notify_wka->wka_local_lock);
mm_clear_db(&results);
}
pthread_mutex_unlock(&notify_data->mm_wka_mutex);
return (0);
}
static void
notify_results(PGresult *results, int row, notify_t *notify)
{
notify->n_uuid = PQgetvalue(results, row, 0);
notify->n_client = PQgetvalue(results, row, 1);
notify->n_inst = PQgetvalue(results, row, 2);
notify->n_cfgchg = PQgetvalue(results, row, 3);
notify->n_newdrive = PQgetvalue(results, row, 4);
notify->n_newcartridge = PQgetvalue(results, row, 5);
notify->n_volumeadd = PQgetvalue(results, row, 6);
notify->n_volumedelete = PQgetvalue(results, row, 7);
notify->n_dmup = PQgetvalue(results, row, 8);
notify->n_dmdown = PQgetvalue(results, row, 9);
notify->n_driveonline = PQgetvalue(results, row, 10);
notify->n_driveoffline = PQgetvalue(results, row, 11);
notify->n_lmup = PQgetvalue(results, row, 12);
notify->n_lmdown = PQgetvalue(results, row, 13);
notify->n_volumeinject = PQgetvalue(results, row, 14);
notify->n_volumeeject = PQgetvalue(results, row, 15);
notify->n_librarycreate = PQgetvalue(results, row, 16);
notify->n_librarydelete = PQgetvalue(results, row, 17);
notify->n_drivedelete = PQgetvalue(results, row, 18);
}
int
notify_return_scope(char *scope) {
if (scope == NULL) {
mms_trace(MMS_ERR, "notify_return_scope "
"passed a NULL scope");
return (NOTIFY_OFF);
}
if (strcmp(scope, "off") == 0) {
mms_trace(MMS_DEVP, " off scope");
return (NOTIFY_OFF);
} else if (strcmp(scope, "global") == 0) {
mms_trace(MMS_DEVP, " global scope");
return (NOTIFY_GLOBAL);
} else if (strcmp(scope, "application") == 0) {
mms_trace(MMS_DEVP, " application scope");
return (NOTIFY_APPLICATION);
} else if (strcmp(scope, "instance") == 0) {
mms_trace(MMS_DEVP, " instance scope");
return (NOTIFY_INSTANCE);
} else if (strcmp(scope, "session") == 0) {
mms_trace(MMS_DEVP, " session scope");
return (NOTIFY_SESSION);
} else if (strcmp(scope, "host") == 0) {
mms_trace(MMS_DEVP, " host scope");
return (NOTIFY_HOST);
} else {
mms_trace(MMS_ERR, "notify_return_scope "
"passed an unknown scope, %s",
scope);
return (NOTIFY_OFF);
}
}
int
/* LINTED: notify may be needed in the future */
notify_check_session_event(mm_wka_t *mm_wka, notify_t *notify,
notify_cmd_t *event_cmd,
int event_scope) {
cci_t *conn = &mm_wka->wka_conn;
char *event_text = event_cmd->evt_cmd;
mms_trace(MMS_DEBUG,
"notify_check_session_event");
mms_trace(MMS_DEVP,
"%s",
event_text);
/* Use this check for any event of this type */
/* Allowed scope values for a session event */
/* Global- all */
/* Application- application == client app */
/* Instance- app and inst == client app, inst */
/* Session- session id == client session */
/* Client does not have this event 'off' */
/* Check scope */
if (event_scope == NOTIFY_GLOBAL) {
mms_trace(MMS_DEVP, " global scope");
} else if ((event_scope == NOTIFY_APPLICATION) &&
(event_cmd->evt_cli_name != NULL)) {
mms_trace(MMS_DEVP, " application scope");
mms_trace(MMS_DEVP, " event app is %s, "
"client app is %s",
event_cmd->evt_cli_name,
conn->cci_client);
if (strcmp(event_cmd->evt_cli_name,
conn->cci_client) == 0) {
/* App name matches */
mms_trace(MMS_DEVP, "App name matches");
} else {
mms_trace(MMS_DEVP, " skip event");
return (0);
}
} else if ((event_scope == NOTIFY_INSTANCE) &&
(event_cmd->evt_cli_name != NULL) &&
(event_cmd->evt_cli_instance != NULL)) {
mms_trace(MMS_DEVP, " instance scope");
mms_trace(MMS_DEVP, " event app is %s %s, "
"client app is %s %s",
event_cmd->evt_cli_name,
event_cmd->evt_cli_instance,
conn->cci_client,
conn->cci_instance);
if ((strcmp(event_cmd->evt_cli_name,
conn->cci_client) == 0) &&
(strcmp(event_cmd->evt_cli_instance,
conn->cci_instance) == 0)) {
/* App and instance match */
mms_trace(MMS_DEVP, "App and instance match");
} else {
mms_trace(MMS_DEVP, " skip event");
return (0);
}
} else if ((event_scope == NOTIFY_SESSION) &&
(event_cmd->evt_session_uuid != NULL)) {
mms_trace(MMS_DEVP, " session scope");
mms_trace(MMS_DEVP,
" event session is %s, ",
event_cmd->evt_session_uuid);
mms_trace(MMS_DEVP,
" client session is %s",
mm_wka->session_uuid);
if (strcmp(event_cmd->evt_session_uuid,
mm_wka->session_uuid) != 0) {
/* Session ID does not match */
mms_trace(MMS_DEVP, " skip event");
return (0);
}
/* Session ID matches */
} else {
mms_trace(MMS_ERR,
"Passed an unsupported event "
"scope for this event type");
mms_trace(MMS_DEVP, " skip event");
return (0);
}
return (1);
}
int
/* LINTED: notify may be needed in the future */
notify_check_dmup(mm_wka_t *mm_wka, notify_t *notify,
notify_cmd_t *event_cmd,
int event_scope) {
cci_t *conn = &mm_wka->wka_conn;
mm_db_t *db = &notify_db;
char *dmhost = event_cmd->evt_obj_host;
/* Event has global and host scope */
if (event_scope == NOTIFY_GLOBAL) {
return (1);
} else if (event_scope == NOTIFY_HOST) {
/* Confirm hosts are the same */
if (mm_db_exec(HERE, db,
"select * from "
"pg_host_ident('%s') "
"where pg_host_ident('%s') = "
"pg_host_ident('%s');",
dmhost,
dmhost,
conn->cci_host) != MM_DB_DATA) {
mms_trace(MMS_ERR,
"db error, notify_check_dmup");
mm_clear_db(&db->mm_db_results);
return (0);
}
if (PQntuples(db->mm_db_results) == 0) {
mms_trace(MMS_DEVP,
"client host != dm host");
mm_clear_db(&db->mm_db_results);
return (0);
}
mm_clear_db(&db->mm_db_results);
return (1);
} else {
mms_trace(MMS_ERR,
"unknown scope for dmup event");
return (0);
}
}
int
/* LINTED: notify may be needed in the future */
notify_check_dmdown(mm_wka_t *mm_wka, notify_t *notify,
notify_cmd_t *event_cmd,
int event_scope) {
cci_t *conn = &mm_wka->wka_conn;
mm_db_t *db = &notify_db;
char *dmhost = event_cmd->evt_obj_host;
/* Event has global and host scope */
if (event_scope == NOTIFY_GLOBAL) {
return (1);
} else if (event_scope == NOTIFY_HOST) {
/* Confirm hosts are the same */
if (mm_db_exec(HERE, db,
"select * from "
"pg_host_ident('%s') "
"where pg_host_ident('%s') = "
"pg_host_ident('%s');",
dmhost,
dmhost,
conn->cci_host) != MM_DB_DATA) {
mms_trace(MMS_ERR,
"db error, notify_check_dmup");
mm_clear_db(&db->mm_db_results);
return (0);
}
if (PQntuples(db->mm_db_results) == 0) {
mms_trace(MMS_DEVP,
"client host != dm host");
mm_clear_db(&db->mm_db_results);
return (0);
}
mm_clear_db(&db->mm_db_results);
return (1);
} else {
mms_trace(MMS_ERR,
"unknown scope for dmup event");
return (0);
}
}
int
/* LINTED: notify may be needed in the future */
notify_check_driveonline(mm_wka_t *mm_wka, notify_t *notify,
notify_cmd_t *event_cmd,
int event_scope) {
cci_t *conn = &mm_wka->wka_conn;
mm_db_t *db = &notify_db;
char *drivename = event_cmd->evt_obj_instance;
/* driveonline event */
/* global -all */
/* application - client has DRIVEGROUP access */
if (event_scope == NOTIFY_GLOBAL) {
return (1);
} else if (event_scope == NOTIFY_APPLICATION) {
/* Check this client and drive group */
if (mm_db_exec(HERE, db,
"select distinct \"DRIVE\".* from \"DRIVE\" "
"cross join \"DRIVEGROUPAPPLICATION\" "
"where "
"(\"DRIVE\".\"DriveGroupName\" = "
"\"DRIVEGROUPAPPLICATION\".\"DriveGroupName\") "
"and "
"(\"DRIVE\".\"DriveName\" = '%s') AND "
"(\"DRIVEGROUPAPPLICATION\"."
"\"ApplicationName\" = '%s');",
drivename,
conn->cci_client) != MM_DB_DATA) {
mms_trace(MMS_ERR,
"db error, notify_check_driveonline");
mm_clear_db(&db->mm_db_results);
return (0);
}
if (PQntuples(db->mm_db_results) == 0) {
mms_trace(MMS_DEVP,
"client does not have drive access");
mm_clear_db(&db->mm_db_results);
return (0);
}
mm_clear_db(&db->mm_db_results);
return (1);
} else {
mms_trace(MMS_ERR,
"unknown scope for driveonline event");
return (0);
}
}
int
/* LINTED: notify may be needed in the future */
notify_check_driveoffline(mm_wka_t *mm_wka, notify_t *notify,
notify_cmd_t *event_cmd,
int event_scope) {
cci_t *conn = &mm_wka->wka_conn;
mm_db_t *db = &notify_db;
char *drivename = event_cmd->evt_obj_instance;
/* driveoffline event */
/* global -all */
/* application - client has DRIVEGROUP access */
if (event_scope == NOTIFY_GLOBAL) {
return (1);
} else if (event_scope == NOTIFY_APPLICATION) {
/* Check this client and drive group */
if (mm_db_exec(HERE, db,
"select distinct \"DRIVE\".* from \"DRIVE\" "
"cross join \"DRIVEGROUPAPPLICATION\" "
"where "
"(\"DRIVE\".\"DriveGroupName\" = "
"\"DRIVEGROUPAPPLICATION\".\"DriveGroupName\") "
"and "
"(\"DRIVE\".\"DriveName\" = '%s') AND "
"(\"DRIVEGROUPAPPLICATION\"."
"\"ApplicationName\" = '%s');",
drivename,
conn->cci_client) != MM_DB_DATA) {
mms_trace(MMS_ERR,
"db error, notify_check_driveoffline");
mm_clear_db(&db->mm_db_results);
return (0);
}
if (PQntuples(db->mm_db_results) == 0) {
mms_trace(MMS_DEVP,
"client does not have drive access");
mm_clear_db(&db->mm_db_results);
return (0);
}
mm_clear_db(&db->mm_db_results);
return (1);
} else {
mms_trace(MMS_ERR,
"unknown scope for driveoffline event");
return (0);
}
}
int
/* LINTED: notify may be needed in the future */
notify_check_volumeevent(mm_wka_t *mm_wka, notify_t *notify,
notify_cmd_t *event_cmd,
int event_scope) {
cci_t *conn = &mm_wka->wka_conn;
char *event_text = event_cmd->evt_cmd;
mm_db_t *db = &notify_db;
char *volumename = event_cmd->evt_obj_instance;
char *cartid = event_cmd->evt_obj_cartid;
int app_ok = 0;
int instance_ok = 0;
mms_trace(MMS_DEBUG,
"notify_check_volumeevent");
mms_trace(MMS_DEVP,
"%s",
event_text);
/* Allowed scope values for SIA volume event */
/* Global - all */
/* Application - VOLUME.AppName = cci_client */
/* Instance - VOLUME.AIName = cci_instance */
if (event_scope == NOTIFY_GLOBAL) {
mms_trace(MMS_DEVP, " global scope");
} else if ((event_scope == NOTIFY_APPLICATION) ||
(event_scope == NOTIFY_INSTANCE)) {
mms_trace(MMS_DEVP, " application or instance scope");
/* This volume's application should match the clients app */
if (mm_db_exec(HERE, db,
"select "
"\"VOLUME\".\"ApplicationName\", "
"\"VOLUME\".\"AIName\" "
"from \"VOLUME\" where "
"\"CartridgeID\" = '%s'",
cartid) != MM_DB_DATA) {
mms_trace(MMS_ERR,
"db error getting app name for %s, "
"notify_check_volumeevent",
volumename);
mm_clear_db(&db->mm_db_results);
return (0);
}
if (PQntuples(db->mm_db_results) != 1) {
mms_trace(MMS_ERR,
"db returned %d rows != 1 "
"notify_check_volumeevent",
PQntuples(db->mm_db_results));
mm_clear_db(&db->mm_db_results);
return (0);
}
/* compare the apps */
if (strcmp(conn->cci_client,
PQgetvalue(db->mm_db_results, 0, 0)) == 0) {
mms_trace(MMS_DEVP,
"app name matches");
app_ok = 1;
} else {
mms_trace(MMS_DEVP,
"app name does not match");
}
/* compare the instance */
if (strcmp(conn->cci_instance,
PQgetvalue(db->mm_db_results, 0, 1)) == 0) {
mms_trace(MMS_DEVP,
"instance matches");
instance_ok = 1;
} else {
mms_trace(MMS_DEVP,
"instance does not match");
}
mm_clear_db(&db->mm_db_results);
} else {
mms_trace(MMS_ERR,
"Passed an unsupported event "
"scope for volumeevent");
mms_trace(MMS_DEVP, " skip event");
return (0);
}
if (event_scope == NOTIFY_APPLICATION) {
if (app_ok) {
return (1);
} else {
return (0);
}
}
if (event_scope == NOTIFY_INSTANCE) {
if (app_ok && instance_ok) {
return (1);
} else {
return (0);
}
}
return (1);
}
int
/* LINTED: notify may be needed in the future */
notify_check_lmup(mm_wka_t *mm_wka, notify_t *notify,
notify_cmd_t *event_cmd,
int event_scope) {
char *event_text = event_cmd->evt_cmd;
/* Allowed scope for lmready */
/* Global- all */
mms_trace(MMS_DEBUG,
"notify_check_lmup");
mms_trace(MMS_DEVP,
"%s",
event_text);
if (event_scope == NOTIFY_GLOBAL) {
/* Global is the only scope currently implemeneted, */
return (1);
} else {
mms_trace(MMS_ERR,
"unknown scope, notify_check_lmup");
return (0);
}
}
int
/* LINTED: notify may be needed in the future */
notify_check_lmdown(mm_wka_t *mm_wka, notify_t *notify,
notify_cmd_t *event_cmd,
int event_scope) {
char *event_text = event_cmd->evt_cmd;
/* Allowed scope for lmready */
/* Global- all */
mms_trace(MMS_DEBUG,
"notify_check_lmdown");
mms_trace(MMS_DEVP,
"%s",
event_text);
/* Global is the only scope currently implemeneted, */
if (event_scope == NOTIFY_GLOBAL) {
/* Global is the only scope currently implemeneted, */
return (1);
} else {
mms_trace(MMS_ERR,
"unknown scope, notify_check_lmdown");
return (0);
}
}
int
/* LINTED: notify may be needed in the future */
notify_check_newdrive(mm_wka_t *mm_wka, notify_t *notify,
notify_cmd_t *event_cmd,
int event_scope) {
cci_t *conn = &mm_wka->wka_conn;
char *event_text = event_cmd->evt_cmd;
char *db_buf = NULL;
mm_db_t *db = &notify_db;
char *drivename = event_cmd->evt_obj_instance;
char *libraryname = event_cmd->evt_obj_library;
mms_trace(MMS_DEBUG,
"notify_check_newdrive");
mms_trace(MMS_DEVP,
"%s",
event_text);
if ((drivename == NULL) || (libraryname == NULL)) {
mms_trace(MMS_ERR,
"bad drivename or libraryname in event struct");
return (0);
}
/* Allowed scope values for a config change event */
/* Global- all */
/* Application- client application has DRIVEGROUPAPPLICATION */
if (event_scope == NOTIFY_GLOBAL) {
mms_trace(MMS_DEVP, " global scope");
} else if (event_scope == NOTIFY_APPLICATION) {
db_buf = mms_strapp(db_buf,
"select distinct "
"\"DRIVEGROUPAPPLICATION\".* from "
"\"DRIVEGROUPAPPLICATION\" "
"cross join \"DRIVE\" where ( "
"(\"DRIVEGROUPAPPLICATION\"."
"\"DriveGroupName\" = "
"\"DRIVE\".\"DriveGroupName\") "
"and ((\"DRIVE\".\"DriveName\" = "
"'%s') AND "
"(\"DRIVE\".\"LibraryName\" = '%s') AND "
"(\"DRIVEGROUPAPPLICATION\"."
"\"ApplicationName\" = '%s')) "
");",
drivename,
libraryname,
conn->cci_client);
if (mm_db_exec(HERE, db, db_buf) != MM_DB_DATA) {
mm_clear_db(&db->mm_db_results);
free(db_buf);
mms_trace(MMS_ERR,
"error getting db info");
return (0);
}
free(db_buf);
if (PQntuples(db->mm_db_results) == 0) {
mms_trace(MMS_DEVP,
"%s has no access to %s, skip event",
conn->cci_client,
drivename);
mm_clear_db(&db->mm_db_results);
return (0);
}
mm_clear_db(&db->mm_db_results);
} else {
mms_trace(MMS_ERR,
"Passed an unsupported event "
"scope for this event type");
mms_trace(MMS_DEVP, " skip event");
return (0);
}
return (1);
}
int
/* LINTED: notify may be needed in the future */
notify_check_newcartridge(mm_wka_t *mm_wka, notify_t *notify,
notify_cmd_t *event_cmd,
int event_scope) {
cci_t *conn = &mm_wka->wka_conn;
char *event_text = event_cmd->evt_cmd;
char *db_buf = NULL;
mm_db_t *db = &notify_db;
char *pcl = event_cmd->evt_obj_instance;
char *library = event_cmd->evt_obj_library;
mms_trace(MMS_DEBUG,
"notify_check_newcartridge");
mms_trace(MMS_DEVP,
"%s",
event_text);
if ((pcl == NULL) || (library == NULL)) {
mms_trace(MMS_ERR,
"bad pcl or library name in event struct");
return (0);
}
/* Allowed scope values for a config change event */
/* Global- all */
/* Application- client application has CARTRIDGEGROUPAPPLICATION */
if (event_scope == NOTIFY_GLOBAL) {
mms_trace(MMS_DEVP, " global scope");
} else if (event_scope == NOTIFY_APPLICATION) {
db_buf = mms_strapp(db_buf,
"select distinct "
"\"CARTRIDGEGROUPAPPLICATION\".* from "
"\"CARTRIDGEGROUPAPPLICATION\" "
"cross join \"CARTRIDGE\" where ( "
"(\"CARTRIDGEGROUPAPPLICATION\"."
"\"CartridgeGroupName\" = "
"\"CARTRIDGE\".\"CartridgeGroupName\") "
"and ((\"CARTRIDGE\".\"CartridgePCL\" = "
"'%s') AND "
"(\"CARTRIDGE\".\"LibraryName\" = '%s') AND "
"(\"CARTRIDGEGROUPAPPLICATION\"."
"\"ApplicationName\" = '%s')) "
");",
pcl,
library,
conn->cci_client);
if (mm_db_exec(HERE, db, db_buf) != MM_DB_DATA) {
mm_clear_db(&db->mm_db_results);
free(db_buf);
mms_trace(MMS_ERR,
"error getting db info");
return (0);
}
free(db_buf);
if (PQntuples(db->mm_db_results) == 0) {
mms_trace(MMS_DEVP,
"%s has no access to %s, skip event",
conn->cci_client,
pcl);
mm_clear_db(&db->mm_db_results);
return (0);
}
mm_clear_db(&db->mm_db_results);
} else {
mms_trace(MMS_ERR,
"Passed an unsupported event "
"scope for this event type");
mms_trace(MMS_DEVP, " skip event");
return (0);
}
return (1);
}
int
/* LINTED: notify may be needed in the future */
notify_check_cfgchg(mm_wka_t *mm_wka, notify_t *notify, notify_cmd_t *event_cmd,
int event_scope) {
cci_t *conn = &mm_wka->wka_conn;
char *event_text = event_cmd->evt_cmd;
char *db_buf = NULL;
mm_db_t *db = &notify_db;
mms_trace(MMS_DEBUG,
"notify_check_cfgchg");
mms_trace(MMS_DEVP,
"%s",
event_text);
/* Allowed scope values for a config change event */
/* Global- all */
/* Host- client host == DM/LM host */
if (event_scope == NOTIFY_GLOBAL) {
mms_trace(MMS_DEVP, " global scope");
} else if (event_scope == NOTIFY_HOST) {
mms_trace(MMS_DEVP, " host scope");
/* Check that our event has the proper struct */
if (event_cmd->evt_obj_name == NULL) {
/* This would be LM or DM */
mms_trace(MMS_ERR,
"bad evt_obj_name "
"in notify_check_cfgchg");
return (0);
}
if (event_cmd->evt_obj_instance == NULL) {
/* This is the LM/DM's name */
mms_trace(MMS_ERR,
"bad evt_obj_instance "
"in notify_check_cfgchg");
return (0);
}
if (event_cmd->evt_obj_host == NULL) {
/* This is the LM/DM's host */
mms_trace(MMS_ERR,
"bad evt_obj_host "
"in notify_check_cfgchg");
return (0);
}
if (conn->cci_host == NULL) {
/* Host of client we are */
/* sending event to */
mms_trace(MMS_ERR,
"bad cci_host "
"in notify_check_cfgchg");
return (0);
}
/* For this event the LM/LM name */
/* is stored in event client instance */
/* Event type is in client name */
db_buf = mms_strapp(db_buf,
"select * from "
"pg_host_ident('%s') "
"where pg_host_ident('%s') = "
"pg_host_ident('%s')",
conn->cci_host,
event_cmd->evt_obj_host,
conn->cci_host);
if (mm_db_exec(HERE, db, db_buf) != MM_DB_DATA) {
mm_clear_db(&db->mm_db_results);
free(db_buf);
mms_trace(MMS_ERR,
"error getting db info");
return (0);
}
free(db_buf);
if (PQntuples(db->mm_db_results) == 0) {
mms_trace(MMS_DEVP,
"%s %s not configured of %s, skip event",
event_cmd->evt_obj_name,
event_cmd->evt_obj_instance,
conn->cci_host);
mm_clear_db(&db->mm_db_results);
return (0);
}
mm_clear_db(&db->mm_db_results);
} else {
mms_trace(MMS_ERR,
"Passed an unsupported event "
"scope for this event type");
mms_trace(MMS_DEVP, " skip event");
return (0);
}
return (1);
}
static void
notify_client(mm_wka_t *mm_wka, notify_t *notify, notify_cmd_t *event_cmd)
{
int do_notify = 0;
mms_par_node_t *event;
cci_t *conn = &mm_wka->wka_conn;
char *event_text = event_cmd->evt_cmd;
int event_scope = 0;
mms_trace(MMS_DEVP, "notify_client %s %s",
conn->cci_client,
conn->cci_instance);
if ((event = mm_text_to_par_node(event_text,
mms_mmp_parse)) == NULL) {
if (event_text != NULL) {
mms_trace(MMS_ERR, "cannot parse event, %s",
event_text);
} else {
mms_trace(MMS_ERR,
"event_text was NULL, cannot parse");
}
return;
}
/* Match the event up with this connection's notify setting */
/* All working events must be listed here */
if (mms_pn_lookup(event, "driveoffline", MMS_PN_CLAUSE, 0) &&
((event_scope =
notify_return_scope(notify->n_driveoffline)) != 0)) {
mms_trace(MMS_DEVP, "Check scope for driveoffline event");
if (notify_check_driveoffline(mm_wka, notify,
event_cmd, event_scope)) {
do_notify = 1;
}
} else if (mms_pn_lookup(event, "driveonline", MMS_PN_CLAUSE, 0) &&
((event_scope =
notify_return_scope(notify->n_driveonline)) != 0)) {
mms_trace(MMS_DEVP, "Check scope for driveonline event");
if (notify_check_driveonline(mm_wka, notify,
event_cmd, event_scope)) {
do_notify = 1;
}
} else if (mms_pn_lookup(event, "dmdown", MMS_PN_CLAUSE, 0) &&
((event_scope =
notify_return_scope(notify->n_dmdown)) != 0)) {
mms_trace(MMS_DEVP, "Check scope for dmdown event");
if (notify_check_dmdown(mm_wka, notify,
event_cmd, event_scope)) {
do_notify = 1;
}
} else if (mms_pn_lookup(event, "dmup", MMS_PN_CLAUSE, 0) &&
((event_scope =
notify_return_scope(notify->n_dmup)) != 0)) {
mms_trace(MMS_DEVP, "Check scope for dmup event");
if (notify_check_dmup(mm_wka, notify,
event_cmd, event_scope)) {
do_notify = 1;
}
} else if (mms_pn_lookup(event, "volumedelete", MMS_PN_CLAUSE, 0) &&
((event_scope =
notify_return_scope(notify->n_volumedelete)) != 0)) {
mms_trace(MMS_DEVP, "Check scope for volumedelete event");
if (notify_check_volumeevent(mm_wka, notify,
event_cmd, event_scope)) {
do_notify = 1;
}
} else if (mms_pn_lookup(event, "volumeadd", MMS_PN_CLAUSE, 0) &&
((event_scope =
notify_return_scope(notify->n_volumeadd)) != 0)) {
mms_trace(MMS_DEVP, "Check scope for volumeadd event");
if (notify_check_volumeevent(mm_wka, notify,
event_cmd, event_scope)) {
do_notify = 1;
}
} else if (mms_pn_lookup(event, "volumeinject", MMS_PN_CLAUSE, 0) &&
((event_scope =
notify_return_scope(notify->n_volumeinject)) != 0)) {
mms_trace(MMS_DEVP, "Check scope for volumeinject event");
if (notify_check_volumeevent(mm_wka, notify,
event_cmd, event_scope)) {
do_notify = 1;
}
} else if (mms_pn_lookup(event, "volumeeject", MMS_PN_CLAUSE, 0) &&
((event_scope =
notify_return_scope(notify->n_volumeeject)) != 0)) {
mms_trace(MMS_DEVP, "Check scope for volumeeject event");
if (notify_check_volumeevent(mm_wka, notify,
event_cmd, event_scope)) {
do_notify = 1;
}
} else if (mms_pn_lookup(event, "lmup", MMS_PN_CLAUSE, 0) &&
((event_scope =
notify_return_scope(notify->n_lmup)) != 0)) {
mms_trace(MMS_DEVP, "Check scope for lmup event");
if (notify_check_lmup(mm_wka, notify,
event_cmd, event_scope)) {
do_notify = 1;
}
} else if (mms_pn_lookup(event, "lmdown", MMS_PN_CLAUSE, 0) &&
((event_scope =
notify_return_scope(notify->n_lmdown)) != 0)) {
mms_trace(MMS_DEVP, "Check scope for lmdown event");
if (notify_check_lmdown(mm_wka, notify,
event_cmd, event_scope)) {
do_notify = 1;
}
} else if (mms_pn_lookup(event, "newdrive", MMS_PN_CLAUSE, NULL) &&
((event_scope =
notify_return_scope(notify->n_newdrive)) != 0)) {
mms_trace(MMS_DEVP, "Check scope for newdrive event");
if (notify_check_newdrive(mm_wka, notify,
event_cmd, event_scope)) {
do_notify = 1;
}
} else if (mms_pn_lookup(event, "newcartridge", MMS_PN_CLAUSE,
NULL) &&
((event_scope =
notify_return_scope(notify->n_newcartridge)) != 0)) {
mms_trace(MMS_DEVP, "Check scope for newcartridge event");
if (notify_check_newcartridge(mm_wka, notify,
event_cmd, event_scope)) {
do_notify = 1;
}
} else if (mms_pn_lookup(event, "config", MMS_PN_CLAUSE, NULL) &&
((event_scope =
notify_return_scope(notify->n_cfgchg)) != 0)) {
mms_trace(MMS_DEVP, "Check scope for config event");
if (notify_check_cfgchg(mm_wka, notify,
event_cmd, event_scope)) {
do_notify = 1;
}
} else if (mms_pn_lookup(event, "librarycreate",
MMS_PN_CLAUSE, NULL) &&
((event_scope =
notify_return_scope(notify->n_librarycreate)) != 0)) {
mms_trace(MMS_DEVP, "Global scope for library create event");
do_notify = 1;
} else if (mms_pn_lookup(event, "librarydelete",
MMS_PN_CLAUSE, NULL) &&
((event_scope =
notify_return_scope(notify->n_librarydelete)) != 0)) {
mms_trace(MMS_DEVP, "Global scope for library delete event");
do_notify = 1;
} else if (mms_pn_lookup(event, "drivedelete",
MMS_PN_CLAUSE, NULL) &&
((event_scope =
notify_return_scope(notify->n_drivedelete)) != 0)) {
mms_trace(MMS_DEVP, "Global scope for drive delete event");
do_notify = 1;
}
if (do_notify) {
/*
* Forward event to client.
*/
mms_trace(MMS_INFO,
"Send event to %s %s, %s",
conn->cci_client,
conn->cci_instance,
event_text);
mm_send_text(mm_wka->mm_wka_conn, event_text);
} else {
mms_trace(MMS_DEVP, "skip event %s %s, %s",
conn->cci_client,
conn->cci_instance,
event_text);
}
not_found:
mms_pn_destroy(event);
}