/* * 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 <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <pthread.h> #include <syslog.h> #include <mms_list.h> #include <mms_parser.h> #include <mms_par_impl.h> #include <libpq-fe.h> #include <mms_trace.h> #include <mms_strapp.h> #include "mm_db.h" #include "mm.h" #include "mm_util.h" #include "mm_commands.h" #include "mm_sql.h" #include "mm_sql_impl.h" static char *_SrcFile = __FILE__; #define INS_DMCAPABILITYGROUP "INSERT INTO \"DMCAPABILITYGROUP\" "\ "(\"DriveName\", \"DMName\", "\ "\"DMCapabilityGroupName\", \"DMCapabilityGroupDefaultName\", "\ "\"DMCapabilityGroupType\") "\ "VALUES ('%s', '%s', '%s', '%s' , '%s');" #define INS_DMCAPABILITYGROUPTOKEN "INSERT INTO \"DMCAPABILITYGROUPTOKEN\" "\ "(\"DriveName\", \"DMName\", "\ "\"DMCapabilityGroupName\", \"DMCapabilityToken\") "\ "VALUES ('%s', '%s', '%s', '%s'); " #define INS_DMCAPABILITY "INSERT INTO \"DMCAPABILITY\" (\"DriveName\", "\ "\"DMName\", "\ "\"DMCapabilityName\") "\ "VALUES ('%s', '%s', '%s'); " #define INS_DMCAPABILITYTOKEN "INSERT INTO \"DMCAPABILITYTOKEN\" "\ "(\"DriveName\", "\ "\"DMName\", \"DMCapabilityName\", \"DMCapabilityToken\") "\ "VALUES ('%s', '%s', '%s', '%s'); " #define INS_DMBITFORMAT "INSERT INTO \"DMBITFORMAT\" "\ "(\"DriveName\", \"DMName\", \"DMBitFormatName\", "\ "\"DMBitFormatDefaultToken\") "\ "VALUES('%s', '%s', '%s', '%s');" #define INS_DMBITFORMATTOKEN "INSERT INTO \"DMBITFORMATTOKEN\" "\ "(\"DriveName\", "\ "\"DMName\", \"DMBitFormatName\", "\ "\"DMCapabilityToken\") "\ "VALUES('%s', '%s', '%s', '%s');" #define INS_BITFORMATDEFAULTTOKEN "UPDATE \"DMBITFORMAT\" SET "\ "\"DMBitFormatDefaultToken\" = '%s' WHERE "\ "( \"DriveName\" = '%s' AND \"DMName\" = '%s' AND "\ "\"DMBitFormatName\" = '%s');" #define INS_ATTR "UPDATE \"DMCAPABILITY\" SET \"%s\" = '%s' WHERE "\ "( \"DriveName\" = '%s' AND \"DMName\" = '%s' AND "\ "\"DMCapabilityName\" = '%s');" #define DEL_DMCAPABILITYGROUPTOKEN "DELETE FROM \"DMCAPABILITYGROUPTOKEN\" "\ "WHERE ((\"DMCAPABILITYGROUPTOKEN\".\"DriveName\" = '%s') AND "\ "(\"DMCAPABILITYGROUPTOKEN\".\"DMName\" = '%s'));" #define DEL_DMCAPABILITYGROUP "DELETE FROM \"DMCAPABILITYGROUP\" "\ "WHERE ((\"DMCAPABILITYGROUP\".\"DriveName\" = '%s') AND "\ "(\"DMCAPABILITYGROUP\".\"DMName\" = '%s'));" #define DEL_DMCAPABILITYTOKEN "DELETE FROM \"DMCAPABILITYTOKEN\" "\ "WHERE ((\"DMCAPABILITYTOKEN\".\"DriveName\" = '%s') "\ "AND (\"DMCAPABILITYTOKEN\".\"DMName\" = '%s'));" #define DEL_DMCAPABILITY "DELETE FROM \"DMCAPABILITY\" WHERE "\ "((\"DMCAPABILITY\".\"DriveName\" = '%s') AND "\ "(\"DMCAPABILITY\".\"DMName\" = '%s'));" #define DEL_DMBITFORMATTOKEN "DELETE FROM \"DMBITFORMATTOKEN\" WHERE "\ "((\"DMBITFORMATTOKEN\".\"DriveName\" = '%s') AND "\ "(\"DMBITFORMATTOKEN\".\"DMName\" = '%s'));" #define DEL_DMBITFORMAT "DELETE FROM \"DMBITFORMAT\" WHERE "\ "((\"DMBITFORMAT\".\"DriveName\" = '%s') AND "\ "(\"DMBITFORMAT\".\"DMName\" = '%s'));" int mm_dmp_clear_at_enable(mm_wka_t *mm_wka) { /* Check if DM has a STALEHANDLE */ /* Clear drive if the session for */ /* stale handle is no longer connected */ mm_db_t *db = &mm_wka->mm_data->mm_db; cci_t *conn = &mm_wka->wka_conn; char *DriveName = conn->cci_client; char *DMName = conn->cci_instance; PGresult *cartid; char *CartridgeID = NULL; PGresult *session; char *AppName = NULL; char *AIName = NULL; if (mm_db_exec(HERE, db, "select \"CartridgeID\" from \"STALEHANDLE\" " "where \"DMName\" = '%s' and" "\"DriveName\" = '%s';", DMName, DriveName) != MM_DB_DATA) { mms_trace(MMS_ERR, "db error in mm_dmp_has_stalehandle"); mm_clear_db(&db->mm_db_results); return (0); } cartid = db->mm_db_results; if (PQntuples(cartid) != 0) { CartridgeID = PQgetvalue(cartid, 0, 0); /* DM has a stale handle */ mms_trace(MMS_DEBUG, "%s %s, has STALEHANDLE for cart %s", DMName, DriveName, CartridgeID); /* Check if mounting session is still connected */ if (mm_db_exec(HERE, db, "select \"SESSION\".\"ApplicationName\"," "\"SESSION\".\"AIName\" " " from \"SESSION\",\"MOUNTPHYSICAL\" " "where \"SESSION\".\"SessionID\" = " "\"MOUNTPHYSICAL\".\"SessionID\" and " "\"MOUNTPHYSICAL\".\"CartridgeID\" = '%s';", CartridgeID) != MM_DB_DATA) { mms_trace(MMS_ERR, "db error in mm_dmp_has_stalehandle"); mm_clear_db(&db->mm_db_results); mm_clear_db(&cartid); return (0); } session = db->mm_db_results; if (PQntuples(session) != 0) { AppName = PQgetvalue(session, 0, 0); AIName = PQgetvalue(session, 0, 1); mms_trace(MMS_DEBUG, "%s %s session still active, " "skip clear and reserve DM, %s %s %s", AppName, AIName, DMName, DriveName, CartridgeID); /* Add activate command */ if (mm_dmp_add_cmd(mm_wka, NULL, DMName, MM_DMP_RESERVE) == NULL) { mms_trace(MMS_ERR, "mm_dmp_clear_at_enable: " "error adding dmp reserve"); } mm_clear_db(&session); mm_clear_db(&cartid); return (0); } mms_trace(MMS_DEBUG, "no active client session " "found, clear drive, %s %s", DMName, DriveName); mm_clear_db(&session); mm_clear_db(&cartid); return (1); } mms_trace(MMS_DEBUG, "no STALEHANDLE found, %s %s", DMName, DriveName); mm_clear_db(&cartid); return (0); } int inc_current(int current[100], int num_cap_groups, int num_group_tokens[100]) { int least_sig = num_cap_groups; current[least_sig-1] ++; if (current[least_sig-1] < num_group_tokens[least_sig-1]) { /* Ok */ return (0); } if (least_sig == 1) { current[least_sig-1] --; return (1); } current[least_sig-1] = 0; least_sig --; return (inc_current(current, least_sig, num_group_tokens)); } int mm_drive_dm_activate_disable(mm_wka_t *mm_wka) { int rc; uuid_text_t task; mm_db_t *db = &mm_wka->mm_data->mm_db; mm_command_t *cmd; char *dmname = mm_wka->wka_conn.cci_instance; char *drivename = mm_wka->wka_conn.cci_client; /* * Determine if activate disable can be sent * return 1 for fail, 0 for success */ rc = mm_db_exec(HERE, db, "select \"DM\".\"DMStateHard\"," "\"DM\".\"DMStateSoft\"," "\"DRIVE\".\"DriveBroken\"," "\"DRIVE\".\"DriveStateSoft\"," "\"DRIVE\".\"DriveDisabled\", " "\"DRIVE\".\"DriveOnline\" " "from \"DM\",\"DRIVE\" where " "\"DM\".\"DriveName\" = " "\"DRIVE\".\"DriveName\" and " "\"DM\".\"DMName\" = '%s';", dmname); if ((rc != MM_DB_DATA) || (PQntuples(db->mm_db_results) != 1)) { mms_trace(MMS_ERR, "db error getting DM/DRIVE info, " "skip DM disable"); return (1); } mms_trace(MMS_DEVP, "DM/DRIVE info:"); mms_trace(MMS_DEVP, " DMStateHard = %s", PQgetvalue(db->mm_db_results, 0, 0)); mms_trace(MMS_DEVP, " DMStateSoft = %s", PQgetvalue(db->mm_db_results, 0, 1)); mms_trace(MMS_DEVP, " DriveBroken = %s", PQgetvalue(db->mm_db_results, 0, 2)); mms_trace(MMS_DEVP, " DriveStateSoft = %s", PQgetvalue(db->mm_db_results, 0, 3)); mms_trace(MMS_DEVP, " DriveDisabled = %s", PQgetvalue(db->mm_db_results, 0, 4)); mms_trace(MMS_DEVP, " DriveOnline = %s", PQgetvalue(db->mm_db_results, 0, 5)); if (strcmp(PQgetvalue(db->mm_db_results, 0, 0), "ready") != 0) { mms_trace(MMS_DEVP, "DMStateHard != ready, skip disable"); mm_clear_db(&db->mm_db_results); return (1); } if (strcmp(PQgetvalue(db->mm_db_results, 0, 1), "ready") != 0) { mms_trace(MMS_DEVP, "DMStateSoft != ready, skip disable"); mm_clear_db(&db->mm_db_results); return (1); } if (strcmp(PQgetvalue(db->mm_db_results, 0, 2), "f") != 0) { mms_trace(MMS_DEVP, "DriveBroken != f, skip disable"); mm_clear_db(&db->mm_db_results); return (1); } if (strcmp(PQgetvalue(db->mm_db_results, 0, 3), "ready") != 0) { mms_trace(MMS_DEVP, "DriveStateSoft != f, skip disable"); mm_clear_db(&db->mm_db_results); return (1); } if (strcmp(PQgetvalue(db->mm_db_results, 0, 4), "false") != 0) { mms_trace(MMS_DEVP, "DriveDisabled != false, skip disable"); mm_clear_db(&db->mm_db_results); return (1); } if (strcmp(PQgetvalue(db->mm_db_results, 0, 5), "f") != 0) { mms_trace(MMS_DEVP, "DriveOnline != f, skip disable"); mm_clear_db(&db->mm_db_results); return (1); } mm_clear_db(&db->mm_db_results); mms_trace(MMS_DEBUG, "Add an activate disable for %s %s", dmname, drivename); /* Allocate and add an activate command to the queue */ /* * Build an activate disable command */ if ((cmd = mm_alloc_cmd(mm_wka)) == NULL) { mms_trace(MMS_ERR, "Unable to malloc mm_command_t: %s", strerror(errno)); return (1); } mm_get_uuid(task); cmd->cmd_textcmd = mms_strnew(ACTIVATE_DISABLE, task); cmd->cmd_root = mm_text_to_par_node(cmd->cmd_textcmd, mms_dmpm_parse); cmd->cmd_task = mm_get_task(cmd->cmd_root); cmd->cmd_func = mm_dmp_activate_cmd_func; cmd->cmd_name = strdup("dmp activate disable"); if (cmd->cmd_textcmd == NULL || cmd->cmd_root == NULL) { MM_ABORT_NO_MEM(); return (1); } pthread_mutex_lock(&mm_wka->mm_data->mm_queue_mutex); mms_list_insert_tail(&mm_wka->mm_data->mm_cmd_queue, cmd); pthread_mutex_unlock(&mm_wka->mm_data->mm_queue_mutex); /* * Activate dm is inprogress. */ return (0); } mm_command_t * mm_alloc_dm_enable(mm_wka_t *mm_wka) { uuid_text_t task; mm_command_t *cmd; /* Allocate and add an activate command to the queue */ /* * Build an activate enable command */ if ((cmd = mm_alloc_cmd(mm_wka)) == NULL) { mms_trace(MMS_ERR, "Unable to malloc mm_command_t: %s", strerror(errno)); return (NULL); } mm_get_uuid(task); cmd->cmd_textcmd = mms_strnew(ACTIVATE_ENABLE, task); cmd->cmd_root = mm_text_to_par_node(cmd->cmd_textcmd, mms_dmpm_parse); cmd->cmd_task = mm_get_task(cmd->cmd_root); cmd->cmd_func = mm_dmp_activate_cmd_func; cmd->cmd_name = strdup("dmp activate enable"); if (cmd->cmd_textcmd == NULL || cmd->cmd_root == NULL) { MM_ABORT_NO_MEM(); return (NULL); } pthread_mutex_lock(&mm_wka->mm_data->mm_queue_mutex); mms_list_insert_tail(&mm_wka->mm_data->mm_cmd_queue, cmd); pthread_mutex_unlock(&mm_wka->mm_data->mm_queue_mutex); /* * Activate dm is inprogress. */ return (cmd); } mm_command_t * mm_drive_dm_activate_enable(mm_wka_t *mm_wka) { int rc; mm_db_t *db = &mm_wka->mm_data->mm_db; mm_command_t *cmd; char *dmname = mm_wka->wka_conn.cci_instance; char *drivename = mm_wka->wka_conn.cci_client; /* * Determine if activate enable can be sent * return NULL for fail, pointer to the enable command for success */ rc = mm_db_exec(HERE, db, "select \"DM\".\"DMStateHard\"," "\"DM\".\"DMStateSoft\"," "\"DRIVE\".\"DriveBroken\"," "\"DRIVE\".\"DriveStateSoft\"," "\"DRIVE\".\"DriveDisabled\", " "\"DRIVE\".\"DriveOnline\" " "from \"DM\",\"DRIVE\" where " "\"DM\".\"DriveName\" = " "\"DRIVE\".\"DriveName\" and " "\"DM\".\"DMName\" = '%s';", dmname); if ((rc != MM_DB_DATA) || (PQntuples(db->mm_db_results) != 1)) { mms_trace(MMS_ERR, "db error getting DM/DRIVE info, " "skip DM enable"); return (NULL); } mms_trace(MMS_DEVP, "DM/DRIVE info:"); mms_trace(MMS_DEVP, " DMStateHard = %s", PQgetvalue(db->mm_db_results, 0, 0)); mms_trace(MMS_DEVP, " DMStateSoft = %s", PQgetvalue(db->mm_db_results, 0, 1)); mms_trace(MMS_DEVP, " DriveBroken = %s", PQgetvalue(db->mm_db_results, 0, 2)); mms_trace(MMS_DEVP, " DriveStateSoft = %s", PQgetvalue(db->mm_db_results, 0, 3)); mms_trace(MMS_DEVP, " DriveDisabled = %s", PQgetvalue(db->mm_db_results, 0, 4)); mms_trace(MMS_DEVP, " DriveOnline = %s", PQgetvalue(db->mm_db_results, 0, 5)); if (strcmp(PQgetvalue(db->mm_db_results, 0, 0), "ready") != 0) { mms_trace(MMS_DEVP, "DMStateHard != ready, skip enable"); mm_clear_db(&db->mm_db_results); return (NULL); } if (strcmp(PQgetvalue(db->mm_db_results, 0, 1), "present") != 0) { mms_trace(MMS_DEVP, "DMStateSoft != present, skip enable"); mm_clear_db(&db->mm_db_results); return (NULL); } if (strcmp(PQgetvalue(db->mm_db_results, 0, 2), "f") != 0) { mms_trace(MMS_DEVP, "DriveBroken != f, skip enable"); mm_clear_db(&db->mm_db_results); return (NULL); } if (strcmp(PQgetvalue(db->mm_db_results, 0, 3), "unavailable") == 0) { mms_trace(MMS_DEVP, "DriveStateSoft == unavailable, " "wait on DM activate"); mm_clear_db(&db->mm_db_results); return (NULL); } if (strcmp(PQgetvalue(db->mm_db_results, 0, 3), "ready") != 0) { mms_trace(MMS_DEVP, "DriveStateSoft != ready"); } if (strcmp(PQgetvalue(db->mm_db_results, 0, 4), "false") != 0) { mms_trace(MMS_DEVP, "DriveDisabled != false, skip enable"); mm_clear_db(&db->mm_db_results); return (NULL); } if (strcmp(PQgetvalue(db->mm_db_results, 0, 5), "t") != 0) { mms_trace(MMS_DEVP, "DriveOnline != t, skip enable"); mm_clear_db(&db->mm_db_results); return (NULL); } mm_clear_db(&db->mm_db_results); mms_trace(MMS_DEBUG, "Add an activate enable for %s %s", dmname, drivename); cmd = mm_alloc_dm_enable(mm_wka); if (cmd == NULL) { mms_trace(MMS_ERR, "unable to malloc dm enable cmd"); return (NULL); } /* * Activate dm is inprogress. */ return (cmd); } /* * This function deletes the config for a DM * who's wka is mm_wka * db should be the calling thread's * database pointer */ void delete_dm_config(mm_wka_t *mm_wka, mm_db_t *db) { if (mm_db_exec(HERE, db, "delete from "\ "\"DMSHAPEPRIORITY\" " \ "where \"DMName\" = '%s'", mm_wka->wka_conn.cci_instance) != MM_DB_OK) { mms_trace(MMS_ERR, "Error removing "\ "DMSHAPEPRIORITY"); } if (mm_db_exec(HERE, db, "delete from "\ "\"DMDENSITYPRIORITY\" " \ "where \"DMName\" = '%s'", mm_wka->wka_conn.cci_instance) != MM_DB_OK) { mms_trace(MMS_ERR, "Error removing "\ "DMDENSITYPRIORITY"); } if (mm_db_exec(HERE, db, "delete from "\ "\"DMCAPABILITYGROUP\" " \ "where \"DMName\" = '%s'", mm_wka->wka_conn.cci_instance) != MM_DB_OK) { mms_trace(MMS_ERR, "Error removing "\ "DMCAPABILITYGROUP"); } if (mm_db_exec(HERE, db, "delete from "\ "\"DMCAPABILITY\" " \ "where \"DMName\" = '%s'", mm_wka->wka_conn.cci_instance) != MM_DB_OK) { mms_trace(MMS_ERR, "Error removing DMCAPABILITY"); } if (mm_db_exec(HERE, db, "delete from "\ "\"DMBITFORMAT\" " \ "where \"DMName\" = '%s'", mm_wka->wka_conn.cci_instance) != MM_DB_OK) { mms_trace(MMS_ERR, "Error removing DMBITFORMAT"); } if (mm_db_exec(HERE, db, "delete from "\ "\"DMBITFORMATTOKEN\" " \ "where \"DMName\" = '%s'", mm_wka->wka_conn.cci_instance) != MM_DB_OK) { mms_trace(MMS_ERR, "Error removing "\ "DMBITFORMATTOKEN"); } } int mm_dmp_config_cmd_func(mm_wka_t *mm_wka, mm_command_t *cmd) { mms_par_node_t *arg; mms_par_node_t *value; int scope_full; mms_par_node_t *work = NULL; mms_par_node_t *item = NULL; int go; int count; mms_par_node_t *cap_list_work; mms_par_node_t *group; char *group_name; char *group_type; char *default_cap_token; char *group_cap_token[512]; mms_par_node_t *cap; char *cap_name; mms_par_node_t *cap_list; char *cap_list_cap_token[512]; mms_par_node_t *attr; char *attr_name; char *attr_value; mms_par_node_t *bitformat; char *bit_name; char *default_bit_token; char *bit_cap_token[512]; mms_par_node_t *shapepriority; mms_par_node_t *densitypriority; mm_db_t *db = &mm_wka->mm_data->mm_db; cci_t *conn = &mm_wka->wka_conn; char *DriveName = conn->cci_client; char *DMName = conn->cci_instance; char *send_buf = NULL; int shape_count = 1; int density_count = 1; int i; /* * buf = mms_strapp(buf, DMP_PRIVATE_BLOCKSIZE, * mount_info->cmi_blocksize); */ mms_trace(MMS_DEVP, "dmp sql trans config cmd"); if (cmd->cmd_state == 100) { /* Response for DM debug Config Command */ if (cmd->cmd_flags & MM_CMD_DEPEND_ERROR) { /* * Error In Debug Config * return MMS_ERROR response and * delete config from DataBase */ delete_dm_config(mm_wka, &mm_wka->mm_data->mm_db); mms_trace(MMS_ERR, "DEBUG CONFIG " \ "ERROR"); /* * cmd->cmd_remove = 1; * mm_sql_db_err_rsp_new(cmd, db); * mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); */ goto not_found; } else { /* Config is MMS_OK */ SQL_CHK_LEN(&cmd->cmd_buf, 0, &cmd->cmd_bufsize, strlen(RESPONSE_SUCCESS) + strlen(cmd->cmd_task) + 1); (void) snprintf(cmd->cmd_buf, cmd->cmd_bufsize, RESPONSE_SUCCESS, cmd->cmd_task); cmd->cmd_remove = 1; mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); mms_trace(MMS_INFO, "DM Connected and Configured"); return (MM_DISPATCH_AGAIN); } } /* Begin Parsing Config Command */ MMS_PN_LOOKUP(arg, cmd->cmd_root, "scope", MMS_PN_CLAUSE, NULL); MMS_PN_LOOKUP(value, arg, NULL, MMS_PN_KEYWORD, NULL); if (strcmp(value->pn_string, "full") == 0) { scope_full = 1; mms_trace(MMS_DEVP, "scope: full"); } else if (strcmp(value->pn_string, "partial") == 0) { scope_full = 0; mms_trace(MMS_DEVP, "scope: partial"); } else { mm_response_error(cmd, ECLASS_LANGUAGE, ENOTFOUND, MM_5062_MSG, NULL); cmd->cmd_remove = 1; mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } /* * If scope is 'full' then remove all existing config entries * in db for the current dm and drive */ if (scope_full) { /* Remove DMBITFORMATTOKEN from db */ if (mm_db_exec(HERE, db, DEL_DMBITFORMATTOKEN, DriveName, DMName) != MM_DB_OK) { mms_trace(MMS_ERR, "Error removing " "DMBITFORMATTOKEN"); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } /* Remove DMBITFORMAT from db */ if (mm_db_exec(HERE, db, DEL_DMBITFORMAT, DriveName, DMName) != MM_DB_OK) { mms_trace(MMS_ERR, "Error removing " "DMBITFORMAT"); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } /* Revomve DMCAPABILITYGROUPTOKEN from db */ if (mm_db_exec(HERE, db, DEL_DMCAPABILITYGROUPTOKEN, DriveName, DMName) != MM_DB_OK) { mms_trace(MMS_ERR, "Error removing "\ "DMCAPABILITYGROUPTOKEN"); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } /* Revomve DMCAPABILITYGROUP from db */ if (mm_db_exec(HERE, db, DEL_DMCAPABILITYGROUP, DriveName, DMName) != MM_DB_OK) { mms_trace(MMS_ERR, "Error removing "\ "DMCAPABILITYGROUP"); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } /* Revomve DMCAPABILITYTOKEN from db */ if (mm_db_exec(HERE, db, DEL_DMCAPABILITYTOKEN, DriveName, DMName) != MM_DB_OK) { mms_trace(MMS_ERR, "Error removing "\ "DMCAPABILITYTOKEN"); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } /* Revomve DMCAPABILITY from db */ if (mm_db_exec(HERE, db, DEL_DMCAPABILITY, DriveName, DMName) != MM_DB_OK) { mms_trace(MMS_ERR, "Error removing "\ "DMCAPABILITY"); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } } /* Get Group Config */ /* mms_trace(MMS_DEVP, "group"); */ work = NULL; for (group = mms_pn_lookup(cmd->cmd_root, "group", MMS_PN_CLAUSE, &work); group != NULL; group = mms_pn_lookup(cmd->cmd_root, "group", MMS_PN_CLAUSE, &work)) { int i; item = NULL; MMS_PN_LOOKUP(value, group, NULL, MMS_PN_STRING, &item); group_name = value->pn_string; MMS_PN_LOOKUP(value, group, NULL, MMS_PN_STRING, &item); group_type = value->pn_string; MMS_PN_LOOKUP(value, group, NULL, MMS_PN_STRING, &item); default_cap_token = value->pn_string; /* Insert DMCAPABILITYGROUP into db */ if (mm_db_exec(HERE, db, INS_DMCAPABILITYGROUP, DriveName, DMName, group_name, default_cap_token, group_type) != MM_DB_OK) { mms_trace(MMS_ERR, "Error adding cap group " "%s %s %s %s %s", DriveName, DMName, group_name, default_cap_token, group_type); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } /* Get the Other Group Cap Tokens */ count = 0; go = 1; while (go) { if ((value = mms_pn_lookup(group, NULL, MMS_PN_STRING, &item)) == NULL) { go = 0; } else { group_cap_token[count] = value->pn_string; count ++; } } /* Insert DMCAPABILITYGROUPTOKEN into db */ /* Insert the default token */ if (mm_db_exec(HERE, db, INS_DMCAPABILITYGROUPTOKEN, DriveName, DMName, group_name, default_cap_token) != MM_DB_OK) { mms_trace(MMS_ERR, "Error adding cap group token" "%s %s %s %s", DriveName, DMName, group_name, default_cap_token); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } /* Insert the other tokens */ for (i = 0; i < count; i++) { if (mm_db_exec(HERE, db, INS_DMCAPABILITYGROUPTOKEN, DriveName, DMName, group_name, group_cap_token[i]) != MM_DB_OK) { mms_trace(MMS_ERR, "Error adding cap group token" "%s %s %s %s", DriveName, DMName, group_name, group_cap_token[i]); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } } } /* Capabilities */ mms_trace(MMS_DEVP, "Parsing cap clauses"); work = NULL; for (cap = mms_pn_lookup(cmd->cmd_root, "cap", MMS_PN_CLAUSE, &work); cap != NULL; cap = mms_pn_lookup(cmd->cmd_root, "cap", MMS_PN_CLAUSE, &work)) { item = NULL; MMS_PN_LOOKUP(value, cap, NULL, MMS_PN_STRING, &item); cap_name = value->pn_string; /* Insert DMCAPABILITY into db */ if (mm_db_exec(HERE, db, INS_DMCAPABILITY, DriveName, DMName, cap_name) != MM_DB_OK) { mms_trace(MMS_ERR, "Error adding cap " "%s %s %s", DriveName, DMName, cap_name); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } mms_trace(MMS_DEVP, " cap: %s", cap_name); /* Get the tokens in the CapList */ if ((cap_list = mms_pn_lookup(cap, "caplist", MMS_PN_CLAUSE, &item)) == NULL) { mms_trace(MMS_ERR, "No caplist found"); } mms_trace(MMS_DEVP, " caplist"); value = NULL; count = 0; go = 1; cap_list_work = NULL; while (go) { if ((value = mms_pn_lookup(cap_list, NULL, MMS_PN_STRING, &cap_list_work)) == NULL) { go = 0; } else { cap_list_cap_token[count] = value->pn_string; count ++; } } /* Insert DMCAPABILITYTOKEN into db */ for (i = 0; i < count; i++) { if (mm_db_exec(HERE, db, INS_DMCAPABILITYTOKEN, DriveName, DMName, cap_name, cap_list_cap_token[i]) != MM_DB_OK) { mms_trace(MMS_ERR, "Error adding cap " "%s %s %s %s", DriveName, DMName, cap_name, cap_list_cap_token[i]); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } } /* Get the attribute name/value pairs */ cap_list_work = NULL; for (attr = mms_pn_lookup(cap, "attr", MMS_PN_CLAUSE, &cap_list_work); attr != NULL; attr = mms_pn_lookup(cap, "attr", MMS_PN_CLAUSE, &cap_list_work)) { mms_trace(MMS_DEVP, " attr"); item = NULL; MMS_PN_LOOKUP(value, attr, NULL, MMS_PN_STRING, &item); attr_name = value->pn_string; MMS_PN_LOOKUP(value, attr, NULL, MMS_PN_STRING, &item); attr_value = value->pn_string; if (mm_db_create_attribute2(db, "DMCAPABILITY", attr_name, &send_buf) != MM_DB_OK) { mms_trace(MMS_ERR, "Error creating new attribute"); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } send_buf = mms_strapp(send_buf, INS_ATTR, attr_name, attr_value, DriveName, DMName, cap_name); mms_trace(MMS_DEVP, "attr_name: %s , attr_value: %s", attr_name, attr_value); } } if (send_buf != NULL) { if (mm_db_exec(HERE, db, send_buf) != MM_DB_OK) { mms_trace(MMS_ERR, "Error adding " \ "config"); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } free(send_buf); send_buf = NULL; } mms_trace(MMS_DEVP, "bitformat"); work = NULL; for (bitformat = mms_pn_lookup(cmd->cmd_root, "bitformat", MMS_PN_CLAUSE, &work); bitformat != NULL; bitformat = mms_pn_lookup(cmd->cmd_root, "bitformat", MMS_PN_CLAUSE, &work)) { item = NULL; MMS_PN_LOOKUP(value, bitformat, NULL, MMS_PN_STRING, &item); bit_name = value->pn_string; MMS_PN_LOOKUP(value, bitformat, NULL, MMS_PN_STRING, &item); default_bit_token = value->pn_string; /* Insert DMBITFORMAT into db */ send_buf = mms_strapp(send_buf, INS_DMBITFORMAT, DriveName, DMName, bit_name, default_bit_token); mms_trace(MMS_DEVP, "Bit name is %s, Default token is %s", bit_name, default_bit_token); /* Get the remaining tokens */ count = 0; go = 1; while (go) { if ((value = mms_pn_lookup(bitformat, NULL, MMS_PN_STRING, &item)) == NULL) { go = 0; } else { bit_cap_token[count] = value->pn_string; count ++; } } /* Insert DMBITFORMATTOKEN into db */ /* Insert the default token */ send_buf = mms_strapp(send_buf, INS_DMBITFORMATTOKEN, DriveName, DMName, bit_name, default_bit_token); /* Insert the rest */ for (i = 0; i < count; i++) { send_buf = mms_strapp(send_buf, INS_DMBITFORMATTOKEN, DriveName, DMName, bit_name, bit_cap_token[i]); mms_trace(MMS_DEVP, "BitToken %d: %s", i, bit_cap_token[i]); } } /* Add the send_buf */ if (mm_db_exec(HERE, db, send_buf) != MM_DB_OK) { mms_trace(MMS_ERR, "Error adding " \ "config"); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } free(send_buf); /* Cartridge Shape and Density Priority */ /* Shape priority */ mms_trace(MMS_DEVP, "shapepriority"); work = NULL; if ((shapepriority = mms_pn_lookup(cmd->cmd_root, "shapepriority", MMS_PN_CLAUSE, NULL)) == NULL) { mms_trace(MMS_ERR, "DM config is missing the shapepriority clause"); } else { item = NULL; while ((item = mms_pn_lookup(shapepriority, NULL, MMS_PN_STRING, &work)) != NULL) { if (mm_db_exec(HERE, db, "insert into \"DMSHAPEPRIORITY\" " "(\"DMName\", \"DMShapePriority\", " "\"DMShapeName\") " "values('%s', '%d', '%s');", DMName, shape_count, item->pn_string) != MM_DB_OK) { mms_trace(MMS_ERR, "Error adding " "shapepriority"); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } if (shape_count == 1) { /* set DriveShapeName */ if (mm_db_exec(HERE, db, "update \"DRIVE\" " "set \"DriveShapeName\" = '%s'" " where \"DriveName\" = '%s'", item->pn_string, DriveName) != MM_DB_OK) { mms_trace(MMS_ERR, "Error setting" "DriveShapeName"); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } } shape_count ++; } } /* Density priority */ mms_trace(MMS_DEVP, "densitypriority"); work = NULL; if ((densitypriority = mms_pn_lookup(cmd->cmd_root, "densitypriority", MMS_PN_CLAUSE, NULL)) == NULL) { mms_trace(MMS_ERR, "DM config is missing the densitypriority clause"); } else { item = NULL; while ((item = mms_pn_lookup(densitypriority, NULL, MMS_PN_STRING, &work)) != NULL) { if (mm_db_exec(HERE, db, "insert into \"DMDENSITYPRIORITY\" " "(\"DMName\", \"DMDensityPriority\", " "\"DMDensityName\") " "values('%s', '%d', '%s');", DMName, density_count, item->pn_string) != MM_DB_OK) { mms_trace(MMS_ERR, "Error adding " "densitypriority"); cmd->cmd_remove = 1; mm_sql_db_err_rsp_new(cmd, db); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; } density_count ++; } } /* Done Parsing */ SQL_CHK_LEN(&cmd->cmd_buf, 0, &cmd->cmd_bufsize, strlen(RESPONSE_SUCCESS) + strlen(cmd->cmd_task) + 1); (void) snprintf(cmd->cmd_buf, cmd->cmd_bufsize, RESPONSE_SUCCESS, cmd->cmd_task); cmd->cmd_remove = 1; mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); mms_trace(MMS_INFO, "DM Connected and Configured -> %s", mm_wka->wka_conn.cci_instance); return (MM_DISPATCH_AGAIN); no_mem: MM_ABORT_NO_MEM(); goto error; not_found: mm_response_error(cmd, ECLASS_LANGUAGE, ENOTFOUND, MM_5062_MSG, NULL); cmd->cmd_remove = 1; mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); goto error; error: mm_sql_update_state(mm_wka->mm_data, "DM", "DMStateSoft", "not ready", "DMName", DMName); return (MM_CMD_ERROR); } #define DMP_SEND_ATTACH "attach task [\"%s\"] " \ "modename [\"%s\"];" int mm_dmp_attach_cmd_func(mm_wka_t *mm_wka, mm_command_t *cmd) { cci_t *conn = &mm_wka->wka_conn; char *DMName = conn->cci_instance; mms_par_node_t *work = NULL; mms_par_node_t *arg; mms_par_node_t *value; char *task = cmd->cmd_task; char *buf = NULL; int bufsize = 0; mm_response_t response; mm_command_t *parent = NULL; cmd_mount_info_t *mount_info = NULL; mms_trace(MMS_DEVP, "mm_dmp_attach_cmd_func"); parent = mm_first_parent(cmd); mount_info = &parent->cmd_mount_info; if (cmd->cmd_state == 0) { /* send the attach to DM */ mms_trace(MMS_DEVP, "DM Name is %s, task id is %s", DMName, task); if (mount_info->cmi_capability == NULL) { mms_trace(MMS_DEVP, "No capability found..."); return (MM_CMD_ERROR); } SQL_CHK_LEN(&buf, 0, &bufsize, strlen(DMP_SEND_ATTACH) + strlen(task) + strlen(mount_info->cmi_capability) + 1); (void) snprintf(buf, bufsize, DMP_SEND_ATTACH, task, mount_info->cmi_capability); mms_trace(MMS_DEVP, "send buf is '%s' to fd %d ", buf, mm_wka->mm_wka_conn->mms_fd); mm_send_text(mm_wka->mm_wka_conn, buf); cmd->cmd_state = 1; MM_SET_FLAG(cmd->cmd_flags, MM_CMD_NEED_ACCEPT); free(buf); return (MM_ACCEPT_NEEDED); } else if (cmd->cmd_state == 1) { /* revieved accept */ mms_trace(MMS_DEVP, "ATTACH STATE 1"); if (mm_parse_response(cmd->cmd_response, &response) != 0 || response.response_type != MM_RESPONSE_ACCEPTED) { cmd->cmd_remove = 1; return (MM_CMD_ERROR); } mms_trace(MMS_DEVP, "PARSE RESPONSE DONE!!"); cmd->cmd_flags &= ~MM_CMD_NEED_ACCEPT; cmd->cmd_flags |= MM_CMD_ACCEPTED; cmd->cmd_state = 2; mms_trace(MMS_DEVP, "ATTACH STATE 1 DONE!!"); return (MM_DISPATCH_DEPEND); } else if (cmd->cmd_state == 2) { /* recieved success */ mms_trace(MMS_DEVP, "ATTACH STATE 2!"); if (mm_parse_response(cmd->cmd_response, &response) != 0 || response.response_type != MM_RESPONSE_SUCCESS) { cmd->cmd_remove = 1; return (MM_CMD_ERROR); } /* Get text */ work = NULL; arg = mms_pn_lookup(cmd->cmd_response, "text", MMS_PN_CLAUSE, &work); if (arg != NULL) { MMS_PN_LOOKUP(value, arg, NULL, MMS_PN_STRING, NULL); if (value->pn_string != NULL) { mms_trace(MMS_DEVP, "Response text is %s", value->pn_string); } else { mms_trace(MMS_DEVP, "Response text was NULL"); } } else { mms_trace(MMS_DEVP, "Response text clause missing"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } mount_info->cmi_handle = strdup(value->pn_string); if (mount_info->cmi_handle == NULL) { mms_trace(MMS_ERR, "Error malloc cmi_handle"); return (MM_CMD_ERROR); } cmd->cmd_remove = 1; return (MM_DEPEND_DONE); } else { mms_trace(MMS_DEVP, "Bad command state"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } no_mem: MM_ABORT_NO_MEM(); return (MM_CMD_ERROR); not_found: mms_trace(MMS_ERR, "Not Found!!"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } #define DMP_SEND_IDENTIFY "identify task [\"%s\"] type [\"none\"];" int mm_dmp_identify_cmd_func(mm_wka_t *mm_wka, mm_command_t *cmd) { cci_t *conn = &mm_wka->wka_conn; char *DMName = conn->cci_instance; mms_par_node_t *work = NULL; mms_par_node_t *value; mms_par_node_t *arg; char *task = cmd->cmd_task; char *buf = NULL; int bufsize = 0; mm_response_t response; mms_trace(MMS_DEVP, "mm_dmp_identify_cmd_func"); if (cmd->cmd_state == 0) { /* send the load to DM */ mms_trace(MMS_DEVP, "DM Name is %s, task id is %s", DMName, task); SQL_CHK_LEN(&buf, 0, &bufsize, strlen(DMP_SEND_IDENTIFY) + strlen(task) + 1); (void) snprintf(buf, bufsize, DMP_SEND_IDENTIFY, task); mms_trace(MMS_DEVP, "send buf is '%s' to fd %d ", buf, mm_wka->mm_wka_conn->mms_fd); mm_send_text(mm_wka->mm_wka_conn, buf); cmd->cmd_state = 1; MM_SET_FLAG(cmd->cmd_flags, MM_CMD_NEED_ACCEPT); free(buf); return (MM_ACCEPT_NEEDED); } else if (cmd->cmd_state == 1) { /* revieved accept */ mms_trace(MMS_DEVP, "IDENTIFY STATE 1"); if (mm_parse_response(cmd->cmd_response, &response) != 0 || response.response_type != MM_RESPONSE_ACCEPTED) { cmd->cmd_remove = 1; return (MM_CMD_ERROR); } mms_trace(MMS_DEVP, "PARSE RESPONSE DONE!!"); cmd->cmd_flags &= ~MM_CMD_NEED_ACCEPT; cmd->cmd_flags |= MM_CMD_ACCEPTED; cmd->cmd_state = 2; mms_trace(MMS_DEVP, "IDENTIFY STATE 1 DONE!!"); return (MM_DISPATCH_DEPEND); } else if (cmd->cmd_state == 2) { /* recieved success */ mms_trace(MMS_DEVP, "IDENTIFY STATE 2!"); if (mm_parse_response(cmd->cmd_response, &response) != 0 || response.response_type != MM_RESPONSE_SUCCESS) { cmd->cmd_remove = 1; return (MM_CMD_ERROR); } /* Get text */ work = NULL; arg = mms_pn_lookup(cmd->cmd_response, "text", MMS_PN_CLAUSE, &work); if (arg != NULL) { MMS_PN_LOOKUP(value, arg, NULL, MMS_PN_STRING, NULL); if (value->pn_string != NULL) { mms_trace(MMS_DEVP, "Response text is %s", value->pn_string); } else { mms_trace(MMS_DEVP, "Response text was NULL"); } } else { mms_trace(MMS_DEVP, "Response text clause missing"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } cmd->cmd_remove = 1; return (MM_DEPEND_DONE); } else { mms_trace(MMS_DEVP, "Bad command state"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } no_mem: MM_ABORT_NO_MEM(); return (MM_CMD_ERROR); not_found: mms_trace(MMS_ERR, "Not Found!!"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } #define DMP_SEND_ACT "activate task[\"%s\"] enable;" int mm_dmp_activate_cmd_func(mm_wka_t *mm_wka, mm_command_t *cmd) { mm_db_t *db = &mm_wka->mm_data->mm_db; cci_t *conn = &mm_wka->wka_conn; char *DriveName = conn->cci_client; char *DMName = conn->cci_instance; char *task = cmd->cmd_task; mm_response_t response; mms_trace(MMS_DEVP, "dmp activate cmd"); if (cmd->cmd_state == 0) { mms_trace(MMS_DEVP, "DM Name is %s, task id is %s", DMName, task); /* set "DMStateSoft" to notready */ mm_sql_update_state(mm_wka->mm_data, "DM", "DMStateSoft", "not ready", "DMName", DMName); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_textcmd); cmd->cmd_state = 1; MM_SET_FLAG(cmd->cmd_flags, MM_CMD_NEED_ACCEPT); return (MM_ACCEPT_NEEDED); } if (cmd->cmd_state == 1) { mms_trace(MMS_DEVP, "ACTIVATE STATE 1"); if (mm_parse_response(cmd->cmd_response, &response) != 0 || response.response_type != MM_RESPONSE_ACCEPTED) { cmd->cmd_remove = 1; return (MM_CMD_ERROR); } cmd->cmd_flags &= ~MM_CMD_NEED_ACCEPT; cmd->cmd_flags |= MM_CMD_ACCEPTED; cmd->cmd_state = 2; mms_trace(MMS_DEVP, "End of activate state = 1"); return (MM_NO_DISPATCH); } if (cmd->cmd_state == 2) { mms_trace(MMS_DEVP, "ACTIVATE STATE 2!"); if (mm_parse_response(cmd->cmd_response, &response) != 0 || response.response_type != MM_RESPONSE_SUCCESS) { if (mm_errorcode_eq(cmd->cmd_response, "DM_E_ENABLED")) { /* DM has aleady been enabled */ mms_trace(MMS_DEBUG, "%s %s already enabled", DMName, DriveName); mm_sql_update_state(mm_wka->mm_data, "DM", "DMStateSoft", "ready", "DMName", DMName); /* Add a DMUP event */ mm_notify_add_dmup(mm_wka, cmd); /* Check if this DM has any handles */ mms_trace(MMS_DEVP, "check if %s has any STALEHANDLE", DMName); if (mm_dmp_clear_at_enable(mm_wka)) { /* DM has a stale handle */ /* The client session is */ /* not connected */ /* Need to clear the drive */ mms_trace(MMS_DEBUG, "Adding clear drive for %s %s", DMName, DriveName); if (mm_add_clear_drive(DriveName, mm_wka->mm_data, db, NULL, NULL, 1, 0) == NULL) { mms_trace(MMS_ERR, "mm_dmp_activate_cmd_func: " "unable to add a " "clear drive cmd"); } } } else { mms_trace(MMS_ERR, "DM activate command error"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } } /* Set the correct DMSoftState */ if ((mms_pn_lookup(cmd->cmd_root, "enable", MMS_PN_KEYWORD, NULL)) != NULL) { mms_trace(MMS_DEBUG, "%s %s enabled", DMName, DriveName); mm_sql_update_state(mm_wka->mm_data, "DM", "DMStateSoft", "ready", "DMName", DMName); /* Add a DMUP event */ mm_notify_add_dmup(mm_wka, cmd); if (mm_dmp_clear_at_enable(mm_wka)) { /* DM has a stale handle */ /* The client session is not connected */ /* Need to clear the drive */ mms_trace(MMS_DEBUG, "Adding clear drive for %s %s", DMName, DriveName); if (mm_add_clear_drive(DriveName, mm_wka->mm_data, db, NULL, NULL, 1, 0) == NULL) { mms_trace(MMS_ERR, "mm_dmp_activate_cmd_func: " "unable to add a clear drive cmd"); } } } else if ((mms_pn_lookup(cmd->cmd_root, "disable", MMS_PN_KEYWORD, NULL)) != NULL) { mms_trace(MMS_DEBUG, "%s %s disabled", DMName, DriveName); mm_sql_update_state(mm_wka->mm_data, "DM", "DMStateSoft", "present", "DMName", DMName); delete_dm_config(mm_wka, &mm_wka->mm_data->mm_db); /* Add a DMDOWN event */ mm_notify_add_dmdown(mm_wka, cmd); } else if ((mms_pn_lookup(cmd->cmd_root, "reserve", MMS_PN_KEYWORD, NULL)) != NULL) { mms_trace(MMS_DEBUG, "%s reserved %s", DMName, DriveName); mm_sql_update_state(mm_wka->mm_data, "DM", "DMStateSoft", "reserved", "DMName", DMName); } else if ((mms_pn_lookup(cmd->cmd_root, "release", MMS_PN_KEYWORD, NULL)) != NULL) { mms_trace(MMS_DEBUG, "%s released %s", DMName, DriveName); mm_sql_update_state(mm_wka->mm_data, "DM", "DMStateSoft", "ready", "DMName", DMName); if (mm_db_exec(HERE, db, "update \"DRIVE\" set " "\"DMName\" = DEFAULT " "where \"DMName\" = '%s';", DMName) != MM_DB_OK) { mms_trace(MMS_ERR, "Error udating DRIVE.DMName"); } } else { mms_trace(MMS_ERR, "Unknown type - %s", cmd->cmd_textcmd); return (MM_CMD_ERROR); } cmd->cmd_remove = 1; if (mm_has_depend(cmd)) { return (MM_DEPEND_DONE); } return (MM_CMD_DONE); } no_mem: MM_ABORT_NO_MEM(); return (MM_CMD_ERROR); } #define DMP_PRIVATE "private task['%s'] " \ "set['cap' '%s' " \ "'filename' '%s' " \ "'volumeid' '%s' " \ "'CartridgePCL' '%s' " \ "'VolumeName' '%s' " #define DMP_PRIVATE_PRIVILEGE "'privileged' '%s' " #define DMP_PRIVATE_BLOCKSIZE "'blocksize' '%s' " #define DMP_PRIVATE_FSEQ "'filesequence' '%s'" #define DMP_PRIVATE_USER "'user' '%s'" #define DMP_PRIVATE_RETENTION "'retention' '%s'" #define DMP_RESERVE_DRIVE "select \"ReserveDrive\" "\ "from \"DRIVE\" where \"DriveName\" = '%s';" #define DMP_DEFAULT_FILENAME "select \"VolumeName\" "\ "from \"VOLUME\" where "\ "\"CartridgeID\" = '%s';" #define DMP_DEFAULT_VOLID "select \"CartridgePCL\" "\ "from \"CARTRIDGE\" where " \ "\"CartridgeID\" = '%s';" int mm_dmp_private_cmd_func(mm_wka_t *mm_wka, mm_command_t *cmd) { mm_db_t *db = &mm_wka->mm_data->mm_db; cci_t *conn = &mm_wka->wka_conn; char *DriveName = conn->cci_client; char *DMName = conn->cci_instance; char *task = cmd->cmd_task; char *buf = NULL; int bufsize = 0; mm_response_t response; mm_command_t *parent = NULL; mm_wka_t *parent_wka = NULL; cmi_mode_list_t *mode; cmd_mount_info_t *mount_info = NULL; char *cap_tokens = NULL; int rc; PGresult *reserve_drive; PGresult *default_filename; PGresult *default_volumeid; int a_mode = 0; char *VolumeName = NULL; /* Send a DM mount information */ mms_trace(MMS_DEVP, "mm_dmp_private_cmd_func"); parent = mm_first_parent(cmd); parent_wka = parent->wka_ptr; mount_info = &parent->cmd_mount_info; mms_trace(MMS_DEVP, "DM PRIVATE CMD FUNC STATE IS %d", cmd->cmd_state); if (MM_IS_SET(cmd->cmd_flags, MM_CMD_NEED_ACCEPT)) { mms_trace(MMS_DEVP, "MM_CMD_NEED_ACCEPT is set!"); } else { mms_trace(MMS_DEVP, "MM_CMD_NEED_ACCEPT not set!"); } if (cmd->cmd_state == 0) { mms_trace(MMS_DEVP, "DM Name is %s, task id is %s", DMName, task); mms_list_foreach(&mount_info->cmi_mode_list, mode) { a_mode = 1; cap_tokens = (char *)mm_check_mode(parent_wka, parent, DriveName, mode, mount_info->cmi_cartridge, db); if (cap_tokens != NULL) { /* mode is ok */ break; } } if (!a_mode) { cap_tokens = (char *)mm_check_mode(parent_wka, parent, DriveName, NULL, mount_info->cmi_cartridge, db); } if (cap_tokens == NULL) { mms_trace(MMS_ERR, "couldn't create capability token string," " verify DM connected/configured"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } mms_trace(MMS_DEVP, "cap tokens are %s", cap_tokens); /* quert DRIVE for reserve drive */ rc = mm_db_exec(HERE, db, DMP_RESERVE_DRIVE, DriveName); if (rc != MM_DB_DATA) { mms_trace(MMS_DEVP, "Exec returned with no Data"); cmd->cmd_remove = 1; free(cap_tokens); mm_clear_db(&db->mm_db_results); return (MM_CMD_ERROR); } reserve_drive = db->mm_db_results; /* * file name not specified use default * 1st 17 chars of VolumeName */ rc = mm_db_exec(HERE, db, DMP_DEFAULT_FILENAME, mount_info->cmi_cartridge); if (rc != MM_DB_DATA) { mms_trace(MMS_DEVP, "Exec returned with no Data"); cmd->cmd_remove = 1; mm_clear_db(&reserve_drive); mm_clear_db(&db->mm_db_results); free(cap_tokens); return (MM_CMD_ERROR); } default_filename = db->mm_db_results; VolumeName = strdup(PQgetvalue(default_filename, 0, 0)); if (mount_info->cmi_filename == NULL) { mount_info->cmi_filename = strdup(PQgetvalue(default_filename, 0, 0)); } rc = mm_db_exec(HERE, db, DMP_DEFAULT_VOLID, mount_info->cmi_cartridge); if (rc != MM_DB_DATA) { mms_trace(MMS_DEVP, "Exec returned with no Data"); cmd->cmd_remove = 1; mm_clear_db(&reserve_drive); mm_clear_db(&default_filename); mm_clear_db(&db->mm_db_results); free(cap_tokens); free(VolumeName); return (MM_CMD_ERROR); } default_volumeid = db->mm_db_results; if (mount_info->cmi_volumeid == NULL) { /* * volumeid not specifed use default * CartridgePCL */ mount_info->cmi_volumeid = strdup(PQgetvalue(default_volumeid, 0, 0)); } /* ***************************** */ SQL_CHK_LEN(&buf, 0, &bufsize, strlen(DMP_PRIVATE) + strlen(task) + strlen(cap_tokens) + strlen(mount_info->cmi_filename) + strlen(mount_info->cmi_volumeid) + strlen(PQgetvalue(default_volumeid, 0, 0)) + strlen(VolumeName) + 1); (void) snprintf(buf, bufsize, DMP_PRIVATE, task, cap_tokens, mount_info->cmi_filename, mount_info->cmi_volumeid, PQgetvalue(default_volumeid, 0, 0), VolumeName); free(VolumeName); if (mount_info->cmi_blocksize != NULL) { /* if we were passed a blocksize, include it */ buf = mms_strapp(buf, DMP_PRIVATE_BLOCKSIZE, mount_info->cmi_blocksize); } if (mount_info->cmi_retention != NULL) { /* if we were passed a retention, include it */ buf = mms_strapp(buf, DMP_PRIVATE_RETENTION, mount_info->cmi_retention); } /* Add the new privleged name/value pair */ if (parent_wka->wka_privilege == MM_PRIV_STANDARD) { buf = mms_strapp(buf, DMP_PRIVATE_PRIVILEGE, "false"); } else { buf = mms_strapp(buf, DMP_PRIVATE_PRIVILEGE, "true"); } /* Always include the default blocksize */ /* find default blocksize for this drive */ rc = mm_db_exec(HERE, db, "select \"DefaultBlocksize\" " "from \"DRIVE\" where " "\"DriveName\" = '%s';", DriveName); if (rc != MM_DB_DATA) { mms_trace(MMS_DEVP, "Exec returned with no Data"); cmd->cmd_remove = 1; mm_clear_db(&reserve_drive); mm_clear_db(&default_filename); mm_clear_db(&default_volumeid); mm_clear_db(&db->mm_db_results); free(cap_tokens); return (MM_CMD_ERROR); } if (mount_info->cmi_filesequence != NULL) { buf = mms_strapp(buf, DMP_PRIVATE_FSEQ, mount_info->cmi_filesequence); } if (mount_info->cmi_user != NULL) { buf = mms_strapp(buf, DMP_PRIVATE_USER, mount_info->cmi_user); } buf = mms_strapp(buf, " ];"); /* * mms_trace(MMS_DEVP, "send buf is '%s' to * fd %d ", buf, mm_wka->mm_wka_conn->mms_fd); */ mm_send_text(mm_wka->mm_wka_conn, buf); /* ***************************** */ cmd->cmd_state = 1; MM_SET_FLAG(cmd->cmd_flags, MM_CMD_NEED_ACCEPT); free(buf); free(cap_tokens); mm_clear_db(&reserve_drive); mm_clear_db(&default_filename); mm_clear_db(&default_volumeid); mm_clear_db(&db->mm_db_results); return (MM_ACCEPT_NEEDED); } if (cmd->cmd_state == 1) { mms_trace(MMS_DEVP, "PRIVATE STATE 1"); if (mm_parse_response(cmd->cmd_response, &response) != 0 || response.response_type != MM_RESPONSE_ACCEPTED) { cmd->cmd_remove = 1; return (MM_CMD_ERROR); } mms_trace(MMS_DEVP, "PARSE RESPONSE DONE!!"); cmd->cmd_flags &= ~MM_CMD_NEED_ACCEPT; cmd->cmd_flags |= MM_CMD_ACCEPTED; cmd->cmd_state = 2; mms_trace(MMS_DEVP, "PRIVATE STATE 1 DONE!!"); return (MM_DISPATCH_DEPEND); } if (cmd->cmd_state == 2) { mms_trace(MMS_DEVP, "PRIVATE STATE 2!"); if (mm_parse_response(cmd->cmd_response, &response) != 0 || response.response_type != MM_RESPONSE_SUCCESS) { cmd->cmd_remove = 1; return (MM_CMD_ERROR); } cmd->cmd_remove = 1; return (MM_DEPEND_DONE); } no_mem: MM_ABORT_NO_MEM(); return (MM_CMD_ERROR); } #define DMP_SEND_LOAD "load task[\"%s\"];" int mm_dmp_load_cmd_func(mm_wka_t *mm_wka, mm_command_t *cmd) { cci_t *conn = &mm_wka->wka_conn; char *DMName = conn->cci_instance; char *task = cmd->cmd_task; char *buf = NULL; int bufsize = 0; mm_response_t response; mm_command_t *parent = NULL; cmd_mount_info_t *mount_info = NULL; mms_trace(MMS_DEVP, "mm_dmp_load_cmd_func"); parent = mm_first_parent(cmd); mount_info = &parent->cmd_mount_info; if (cmd->cmd_state == 0) { /* send the load to DM */ mms_trace(MMS_DEVP, "DM Name is %s, task id is %s", DMName, task); SQL_CHK_LEN(&buf, 0, &bufsize, strlen(DMP_SEND_LOAD) + strlen(task) + 1); (void) snprintf(buf, bufsize, DMP_SEND_LOAD, task); mms_trace(MMS_DEVP, "send buf is '%s' to fd %d ", buf, mm_wka->mm_wka_conn->mms_fd); mm_send_text(mm_wka->mm_wka_conn, buf); cmd->cmd_state = 1; MM_SET_FLAG(cmd->cmd_flags, MM_CMD_NEED_ACCEPT); free(buf); return (MM_ACCEPT_NEEDED); } else if (cmd->cmd_state == 1) { /* revieved accept */ mms_trace(MMS_DEVP, "LOAD STATE 1"); if (mm_parse_response(cmd->cmd_response, &response) != 0 || response.response_type != MM_RESPONSE_ACCEPTED) { cmd->cmd_remove = 1; return (MM_CMD_ERROR); } /* set "DriveStateHard" to loading */ mm_sql_update_state(mm_wka->mm_data, "DRIVE", "DriveStateHard", "loading", "DriveName", mount_info->cmi_drive); mms_trace(MMS_DEVP, "PARSE RESPONSE DONE!!"); cmd->cmd_flags &= ~MM_CMD_NEED_ACCEPT; cmd->cmd_flags |= MM_CMD_ACCEPTED; cmd->cmd_state = 2; mms_trace(MMS_DEVP, "LOAD STATE 1 DONE!!"); return (MM_DISPATCH_DEPEND); } else if (cmd->cmd_state == 2) { /* recieved success */ mms_trace(MMS_DEVP, "LOAD STATE 2!"); if (mm_parse_response(cmd->cmd_response, &response) != 0 || response.response_type != MM_RESPONSE_SUCCESS) { cmd->cmd_remove = 1; return (MM_CMD_ERROR); } /* set "DriveStateHard" to loaded */ mm_sql_update_state(mm_wka->mm_data, "DRIVE", "DriveStateHard", "loaded", "DriveName", mount_info->cmi_drive); cmd->cmd_remove = 1; return (MM_DEPEND_DONE); } else { mms_trace(MMS_DEVP, "Bad command state"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } no_mem: MM_ABORT_NO_MEM(); return (MM_CMD_ERROR); } int mm_dmp_ready_cmd_func(mm_wka_t *mm_wka, mm_command_t *cmd) { mms_par_node_t *message; mms_par_node_t *work = NULL; mms_par_node_t *text_work = NULL; int go; int name; mms_par_node_t *value; mms_par_node_t *id; mms_par_node_t *args; mms_par_node_t *text; cci_t *conn = &mm_wka->wka_conn; char *DMName = conn->cci_instance; mm_db_t *db = &cmd->wka_ptr->mm_data->mm_db; mms_trace(MMS_DEVP, "mm_dmp_ready_cmd_func"); if ((value = mms_pn_lookup(cmd->cmd_root, "broken", MMS_PN_KEYWORD, NULL)) != NULL) { mms_trace(MMS_DEVP, "ready broken"); mm_sql_update_state(mm_wka->mm_data, "DM", "DMStateSoft", "not ready", "DMName", DMName); mm_sql_update_state(mm_wka->mm_data, "DM", "DMStateHard", "broken", "DMName", DMName); } else if ((value = mms_pn_lookup(cmd->cmd_root, "not", MMS_PN_KEYWORD, NULL)) != NULL) { mms_trace(MMS_DEVP, "ready not"); mm_sql_update_state(mm_wka->mm_data, "DM", "DMStateSoft", "not ready", "DMName", DMName); } else if ((value = mms_pn_lookup(cmd->cmd_root, "disconnected", MMS_PN_KEYWORD, NULL)) != NULL) { mms_trace(MMS_DEVP, "ready disconnected"); mm_sql_update_state(mm_wka->mm_data, "DM", "DMStateSoft", "disconnected", "DMName", DMName); } else { /* Drive is READY! */ mm_sql_update_state(mm_wka->mm_data, "DM", "DMStateSoft", "ready", "DMName", DMName); mm_path_match_report(cmd, db); mm_send_response(mm_wka->mm_wka_conn, cmd); cmd->cmd_remove = 1; return (MM_CMD_DONE); } message = mms_pn_lookup(cmd->cmd_root, "message", MMS_PN_CLAUSE, &work); if (message != NULL) { work = NULL; id = mms_pn_lookup(message, "id", MMS_PN_CLAUSE, &work); if (id != NULL) { work = NULL; MMS_PN_LOOKUP(value, id, NULL, MMS_PN_STRING, &work); mms_trace(MMS_DEVP, "Manufacturer identifer -> %s", value->pn_string); MMS_PN_LOOKUP(value, id, NULL, MMS_PN_STRING, &work); mms_trace(MMS_DEVP, "Catalog -> %s", value->pn_string); MMS_PN_LOOKUP(value, id, NULL, MMS_PN_STRING, &work); mms_trace(MMS_DEVP, "Message ID -> %s", value->pn_string); } else { mms_trace(MMS_DEVP, "Missing an id clause"); } work = NULL; args = mms_pn_lookup(message, "arguments", MMS_PN_CLAUSE, &work); if (args != NULL) { mms_trace(MMS_DEVP, "Name, Value"); work = NULL; go = 1; name = 0; while (go) { if ((value = mms_pn_lookup(args, NULL, MMS_PN_STRING, &work)) == NULL) { go = 0; } else { if (name == 0) { /* got name */ name = 1; mms_trace(MMS_DEVP, "Name -> %s", value->pn_string); } else { name = 0; mms_trace(MMS_DEVP, " Value -> %s", value->pn_string); } } } if (name == 1) { /* got name and are missing a value */ mms_trace(MMS_DEVP, "Missing value "\ "in argument clause"); goto not_found; } } else { mms_trace(MMS_DEVP, "Missing an arguements clause"); } text_work = NULL; text = mms_pn_lookup(message, "loctext", MMS_PN_CLAUSE, &text_work); while (text != NULL) { work = NULL; MMS_PN_LOOKUP(value, text, NULL, MMS_PN_STRING, &work); mms_trace(MMS_DEVP, "Language -> %s", value->pn_string); MMS_PN_LOOKUP(value, text, NULL, MMS_PN_STRING, &work); mms_trace(MMS_DEVP, "Format -> %s", value->pn_string); text = mms_pn_lookup(message, "loctext", MMS_PN_CLAUSE, &text_work); } } else { mms_trace(MMS_DEVP, "Didn't find a message..."); } mm_path_match_report(cmd, db); mm_send_response(mm_wka->mm_wka_conn, cmd); cmd->cmd_remove = 1; return (MM_CMD_DONE); no_mem: MM_ABORT_NO_MEM(); return (MM_CMD_ERROR); not_found: mm_response_error(cmd, ECLASS_LANGUAGE, ENOTFOUND, MM_5062_MSG, NULL); cmd->cmd_remove = 1; mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); return (MM_CMD_ERROR); } #define DMP_SEND_UNLOAD "unload task [\"%s\"];" int mm_dmp_unload_cmd_func(mm_wka_t *mm_wka, mm_command_t *cmd) { cci_t *conn = &mm_wka->wka_conn; char *DriveName = conn->cci_client; char *DMName = conn->cci_instance; char *task = cmd->cmd_task; char *buf = NULL; int bufsize = 0; mm_response_t response; mms_par_node_t *work = NULL; int go; int name; mms_par_node_t *value; mms_par_node_t *text; mms_trace(MMS_DEVP, "mm_dmp_unload_cmd_func"); if (cmd->cmd_state == 0) { /* send the unload to DM */ mms_trace(MMS_DEVP, "DM Name is %s, task id is %s", DMName, task); SQL_CHK_LEN(&buf, 0, &bufsize, strlen(DMP_SEND_UNLOAD) + strlen(task) + 1); (void) snprintf(buf, bufsize, DMP_SEND_UNLOAD, task); mms_trace(MMS_DEVP, "send buf is '%s' to fd %d ", buf, mm_wka->mm_wka_conn->mms_fd); /* Set DriveStateHard to UNLOADING */ mm_sql_update_state(mm_wka->mm_data, "DRIVE", "DriveStateHard", "unloading", "DriveName", DriveName); mm_send_text(mm_wka->mm_wka_conn, buf); cmd->cmd_state = 1; MM_SET_FLAG(cmd->cmd_flags, MM_CMD_NEED_ACCEPT); free(buf); return (MM_ACCEPT_NEEDED); } else if (cmd->cmd_state == 1) { /* revieved accept */ mms_trace(MMS_DEVP, "UNLOAD STATE 1"); if (mm_parse_response(cmd->cmd_response, &response) != 0 || response.response_type != MM_RESPONSE_ACCEPTED) { cmd->cmd_remove = 1; return (MM_CMD_ERROR); } cmd->cmd_flags &= ~MM_CMD_NEED_ACCEPT; cmd->cmd_flags |= MM_CMD_ACCEPTED; cmd->cmd_state = 2; return (MM_DISPATCH_DEPEND); } else if (cmd->cmd_state == 2) { /* recieved success */ mms_trace(MMS_DEVP, "UNLOAD STATE 2!"); if (mm_parse_response(cmd->cmd_response, &response) != 0 || response.response_type != MM_RESPONSE_SUCCESS) { cmd->cmd_remove = 1; return (MM_CMD_ERROR); } work = NULL; text = mms_pn_lookup(cmd->cmd_response, "text", MMS_PN_CLAUSE, &work); if (text != NULL) { mms_trace(MMS_DEVP, "Name, Value"); work = NULL; go = 1; name = 0; while (go) { if ((value = mms_pn_lookup(text, NULL, MMS_PN_STRING, &work)) == NULL) { go = 0; } else { if (name == 0) { /* got name */ name = 1; mms_trace(MMS_DEVP, "Name -> %s", value->pn_string); } else { name = 0; mms_trace(MMS_DEVP, " Value -> %s", value->pn_string); } } } if (name == 1) { /* got name and are missing a value */ mms_trace(MMS_DEVP, "Missing value "\ "in text clause"); goto not_found; } } else { mms_trace(MMS_DEVP, "Missing an text clause"); } cmd->cmd_remove = 1; return (MM_DEPEND_DONE); } else { mms_trace(MMS_DEVP, "Bad command state"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } no_mem: MM_ABORT_NO_MEM(); return (MM_CMD_ERROR); not_found: mms_trace(MMS_ERR, "Not Found!!"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } #define DMP_SEND_DETACH "detach task [\"%s\"] "\ "drivehandle [\"%s\"] stale [\"%s\"];" int mm_dmp_detach_cmd_func(mm_wka_t *mm_wka, mm_command_t *cmd) { mm_db_t *db = &mm_wka->mm_data->mm_db; cci_t *conn = &mm_wka->wka_conn; char *DriveName = conn->cci_client; char *DMName = conn->cci_instance; char *task = cmd->cmd_task; char *buf = NULL; int bufsize = 0; mm_response_t response; mm_command_t *parent = NULL; cmd_mount_info_t *mount_info = NULL; int rc; PGresult *handle; int stale = 0; mms_trace(MMS_DEVP, "mm_dmp_detach_cmd_func"); parent = mm_first_parent(cmd); mount_info = &parent->cmd_mount_info; if (cmd->cmd_state == 0) { /* send the detach to DM */ mms_trace(MMS_DEVP, "DM Name is %s, task id is %s", DMName, task); /* Get the handle from MOUNTLOGICAL */ rc = mm_db_exec(HERE, db, "select \"MountLogicalHandle\" "\ "from \"MOUNTLOGICAL\" where "\ "\"DriveName\" = '%s' and \"DMName\" = '%s';", DriveName, DMName); if (rc != MM_DB_DATA) { mms_trace(MMS_ERR, "Exec returned with no Data"); return (MM_CMD_ERROR); } handle = db->mm_db_results; if (PQntuples(handle) == 0) { /* NO handle found */ mms_trace(MMS_NOTICE, "No MOUNTLOGICAL handle found..."); /* No MOUNLOGICAL handle, check for STALEHANDLE */ rc = mm_db_exec(HERE, db, "select \"MountLogicalHandle\" " "from \"STALEHANDLE\" where " "\"DriveName\" = '%s' " "and \"DMName\" = '%s';", DriveName, DMName); if (rc != MM_DB_DATA) { mms_trace(MMS_DEVP, "Exec returned with no Data"); mm_clear_db(&handle); return (MM_CMD_ERROR); } mm_clear_db(&handle); handle = db->mm_db_results; if (PQntuples(handle) == 0) { /* NO handle found */ mms_trace(MMS_NOTICE, "No STALEHANDLE or "\ "MOUNTLOGICAL found, skipping detach"); mm_clear_db(&handle); return (MM_DEPEND_DONE); } else { stale = 1; } } mount_info->cmi_handle = strdup(PQgetvalue(handle, 0, 0)); if (stale) { SQL_CHK_LEN(&buf, 0, &bufsize, strlen(DMP_SEND_DETACH) + strlen(task) + strlen(mount_info->cmi_handle) + 4 + 1); (void) snprintf(buf, bufsize, DMP_SEND_DETACH, task, mount_info->cmi_handle, "true"); } else { SQL_CHK_LEN(&buf, 0, &bufsize, strlen(DMP_SEND_DETACH) + strlen(task) + strlen(mount_info->cmi_handle) + 5 + 1); (void) snprintf(buf, bufsize, DMP_SEND_DETACH, task, mount_info->cmi_handle, "false"); } mms_trace(MMS_DEVP, "send buf is '%s' to fd %d ", buf, mm_wka->mm_wka_conn->mms_fd); mm_send_text(mm_wka->mm_wka_conn, buf); cmd->cmd_state = 1; MM_SET_FLAG(cmd->cmd_flags, MM_CMD_NEED_ACCEPT); free(buf); mm_clear_db(&handle); return (MM_ACCEPT_NEEDED); } else if (cmd->cmd_state == 1) { /* revieved accept */ mms_trace(MMS_DEVP, "DETACH STATE 1"); if (mm_parse_response(cmd->cmd_response, &response) != 0 || response.response_type != MM_RESPONSE_ACCEPTED) { cmd->cmd_remove = 1; return (MM_CMD_ERROR); } cmd->cmd_flags &= ~MM_CMD_NEED_ACCEPT; cmd->cmd_flags |= MM_CMD_ACCEPTED; cmd->cmd_state = 2; return (MM_DISPATCH_DEPEND); } else if (cmd->cmd_state == 2) { /* recieved success */ mms_trace(MMS_DEVP, "DETACH STATE 2!"); if (mm_parse_response(cmd->cmd_response, &response) != 0 || response.response_type != MM_RESPONSE_SUCCESS) { mms_trace(MMS_ERR, "DM Detach - %s %s", response.error_class, response.error_code); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } cmd->cmd_remove = 1; return (MM_DEPEND_DONE); } else { mms_trace(MMS_DEVP, "Bad command state"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } no_mem: MM_ABORT_NO_MEM(); return (MM_CMD_ERROR); not_found: mms_trace(MMS_ERR, "Not Found!!"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } mm_command_t * mm_dmp_add_cmd(mm_wka_t *mm_wka, mm_command_t *mnt_cmd, char *dm_name, int type) { mm_command_t *cmd; mm_data_t *mm_data = mm_wka->mm_data; mm_wka_t *dm_wka; uuid_text_t uuid; int recover = 0; mms_trace(MMS_DEVP, "mm_dmp_add_cmd"); switch (type) { case MM_DMP_RESERVE: mms_trace(MMS_DEVP, "About to add activate reserve command "); break; case MM_DMP_PRIV: mms_trace(MMS_DEVP, "About to add private command "); break; case MM_DMP_LOAD: mms_trace(MMS_DEVP, "About to add load command "); break; case MM_DMP_ATTACH: mms_trace(MMS_DEVP, "About to add attach command "); break; case MM_DMP_IDENTIFY: mms_trace(MMS_DEVP, "About to add identify command "); break; case MM_DMP_DETACH: mms_trace(MMS_DEVP, "About to add detach command "); break; case MM_DMP_UNLOAD: mms_trace(MMS_DEVP, "About to add unload command "); break; case MM_DMP_RELEASE: mms_trace(MMS_DEVP, "About to add activate release command "); break; } /* Set cmd->wka_ptr to point to the dm's wka */ dm_wka = NULL; if (!recover) { mms_list_foreach(&mm_data->mm_wka_list, dm_wka) { if (strcmp(dm_wka->wka_conn.cci_instance, dm_name) == 0) { /* Found the wka of dm */ break; } } if ((dm_wka == NULL) || (strcmp(dm_wka->wka_conn.cci_instance, dm_name) != 0)) { /* bad wka */ mms_trace(MMS_DEVP, "DM not connected!!"); return (NULL); } } else { dm_wka = mm_wka; } if ((cmd = mm_alloc_cmd(dm_wka)) == NULL) { mms_trace(MMS_ERR, "Unable to malloc mm_command_t: %s", strerror(errno)); return (NULL); } mm_get_uuid(uuid); mm_add_depend(cmd, mnt_cmd); cmd->cmd_task = NULL; cmd->cmd_task = strdup(uuid); if (cmd->cmd_task == NULL) { mms_trace(MMS_ERR, "Error malloc cmd_task in add cmd"); return (NULL); } switch (type) { case MM_DMP_RESERVE: cmd->cmd_func = mm_dmp_activate_cmd_func; cmd->cmd_name = strdup("dmp activate reserve"); cmd->cmd_textcmd = mms_strnew(ACTIVATE_RESERVE, cmd->cmd_task); cmd->cmd_root = mm_text_to_par_node(cmd->cmd_textcmd, mms_dmpm_parse); break; case MM_DMP_PRIV: cmd->cmd_func = mm_dmp_private_cmd_func; cmd->cmd_name = strdup("dmp private"); break; case MM_DMP_LOAD: cmd->cmd_func = mm_dmp_load_cmd_func; cmd->cmd_name = strdup("dmp load"); break; case MM_DMP_ATTACH: cmd->cmd_func = mm_dmp_attach_cmd_func; cmd->cmd_name = strdup("dmp attach"); break; case MM_DMP_IDENTIFY: cmd->cmd_func = mm_dmp_identify_cmd_func; cmd->cmd_name = strdup("dmp identify"); break; case MM_DMP_DETACH: cmd->cmd_func = mm_dmp_detach_cmd_func; cmd->cmd_name = strdup("dmp detach"); break; case MM_DMP_UNLOAD: cmd->cmd_func = mm_dmp_unload_cmd_func; cmd->cmd_name = strdup("dmp unload"); break; case MM_DMP_RELEASE: cmd->cmd_func = mm_dmp_activate_cmd_func; cmd->cmd_name = strdup("dmp activate release"); cmd->cmd_textcmd = mms_strnew(ACTIVATE_RELEASE, cmd->cmd_task); cmd->cmd_root = mm_text_to_par_node(cmd->cmd_textcmd, mms_dmpm_parse); break; } pthread_mutex_lock(&mm_data-> mm_queue_mutex); mms_list_insert_tail(&mm_wka->mm_data->mm_cmd_queue, cmd); pthread_mutex_unlock(&mm_data-> mm_queue_mutex); mms_trace(MMS_DEVP, "DMP Command Added to Queue - %d", mm_wka->mm_wka_conn); return (cmd); } int mm_dmp_cancel_cmd_func(mm_wka_t *mm_wka, mm_command_t *cmd) { mms_par_node_t *value; mms_par_node_t *arg; mm_data_t *data = mm_wka->mm_data; char *taskid; mm_db_t *db = &mm_wka->mm_data->mm_db; mm_command_t *cmd_p; mm_command_t *cmd_q; char *cmd_name = NULL; uuid_text_t cmd_reqid; mms_trace(MMS_DEVP, "mm_dmp_cancel_cmd_func"); MMS_PN_LOOKUP(arg, cmd->cmd_root, "whichtask", MMS_PN_CLAUSE, NULL); MMS_PN_LOOKUP(value, arg, NULL, MMS_PN_STRING, NULL); taskid = value->pn_string; pthread_mutex_lock(&data->mm_queue_mutex); mms_list_foreach(&data->mm_cmd_queue, cmd_p) { if (strcmp(cmd_p->wka_ptr->wka_conn.cci_uuid, cmd->wka_ptr->wka_conn.cci_uuid) == 0 && strcmp(cmd_p->cmd_task, taskid) == 0) { /* is this a command we know how to cancel */ if (strcmp(mms_pn_token(cmd_p->cmd_root), "request") == 0) { cmd_name = strdup("request"); strcpy(cmd_reqid, cmd_p->cmd_reqid); } break; } } pthread_mutex_unlock(&data->mm_queue_mutex); /* command not found */ if (cmd_p == NULL) { SQL_CHK_LEN(&cmd->cmd_buf, 0, &cmd->cmd_bufsize, strlen(RESPONSE_ERROR) + strlen(cmd->cmd_task) + strlen(ECLASS_INVALID) + strlen(EDM_E_NOTASK) + 1); (void) snprintf(cmd->cmd_buf, cmd->cmd_bufsize, RESPONSE_ERROR, cmd->cmd_task, ECLASS_INVALID, EDM_E_NOTASK); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } /* cancel command */ if (strcmp(cmd_name, "request") == 0) { free(cmd_name); if (mm_db_exec(HERE, db, "select \"RequestState\" " "from \"REQUEST\" where \"RequestID\" = '%s';", cmd_reqid) != MM_DB_DATA || PQntuples(db->mm_db_results) != 1) { mm_clear_db(&db->mm_db_results); SQL_CHK_LEN(&cmd->cmd_buf, 0, &cmd->cmd_bufsize, strlen(RESPONSE_ERROR) + strlen(cmd->cmd_task) + strlen(ECLASS_INTERNAL) + strlen(EDATABASE) + 1); (void) snprintf(cmd->cmd_buf, cmd->cmd_bufsize, RESPONSE_ERROR, cmd->cmd_task, ECLASS_INTERNAL, EDATABASE); cmd->cmd_remove = 1; mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); return (MM_CMD_ERROR); } if (strcmp(PQgetvalue(db->mm_db_results, 0, 0), "responded") == 0) { mm_clear_db(&db->mm_db_results); SQL_CHK_LEN(&cmd->cmd_buf, 0, &cmd->cmd_bufsize, strlen(RESPONSE_ERROR) + strlen(cmd->cmd_task) + strlen(ECLASS_INVALID) + strlen(EDM_E_NOCANC) + 1); (void) snprintf(cmd->cmd_buf, cmd->cmd_bufsize, RESPONSE_ERROR, cmd->cmd_task, ECLASS_INVALID, EDM_E_NOCANC); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } mm_clear_db(&db->mm_db_results); /* remove the request */ if (mm_db_exec(HERE, db, "delete from \"REQUEST\" where " "\"RequestID\" = '%s';", cmd_reqid) != MM_DB_OK) { mm_clear_db(&db->mm_db_results); SQL_CHK_LEN(&cmd->cmd_buf, 0, &cmd->cmd_bufsize, strlen(RESPONSE_ERROR) + strlen(cmd->cmd_task) + strlen(ECLASS_INTERNAL) + strlen(EDATABASE) + 1); (void) snprintf(cmd->cmd_buf, cmd->cmd_bufsize, RESPONSE_ERROR, cmd->cmd_task, ECLASS_INTERNAL, EDATABASE); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } } else { free(cmd_name); SQL_CHK_LEN(&cmd->cmd_buf, 0, &cmd->cmd_bufsize, strlen(RESPONSE_ERROR) + strlen(cmd->cmd_task) + strlen(ECLASS_INVALID) + strlen(EDM_E_NOCANC) + 1); (void) snprintf(cmd->cmd_buf, cmd->cmd_bufsize, RESPONSE_ERROR, cmd->cmd_task, ECLASS_INVALID, EDM_E_NOCANC); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } /* send cancelled command's final-command response */ pthread_mutex_lock(&data->mm_queue_mutex); mms_list_foreach(&data->mm_cmd_queue, cmd_q) { if (cmd_q == cmd_p) { /* send cancelled command response */ SQL_CHK_LEN(&cmd_p->cmd_buf, 0, &cmd_p->cmd_bufsize, strlen(RESPONSE_CANCELLED) + strlen(cmd_p->cmd_task) + 1); (void) snprintf(cmd_p->cmd_buf, cmd_p->cmd_bufsize, RESPONSE_CANCELLED, cmd_p->cmd_task); mm_send_text(mm_wka->mm_wka_conn, cmd_p->cmd_buf); cmd_p->cmd_remove = 1; break; } } pthread_mutex_unlock(&data->mm_queue_mutex); /* same command not found or error sending cancelled response */ if (cmd_q == NULL) { SQL_CHK_LEN(&cmd->cmd_buf, 0, &cmd->cmd_bufsize, strlen(RESPONSE_ERROR) + strlen(cmd->cmd_task) + strlen(ECLASS_INVALID) + strlen(ELM_E_NOTASK) + 1); (void) snprintf(cmd->cmd_buf, cmd->cmd_bufsize, RESPONSE_ERROR, cmd->cmd_task, ECLASS_INVALID, ELM_E_NOTASK); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } SQL_CHK_LEN(&cmd->cmd_buf, 0, &cmd->cmd_bufsize, strlen(RESPONSE_SUCCESS) + strlen(cmd->cmd_task) + 1); (void) snprintf(cmd->cmd_buf, cmd->cmd_bufsize, RESPONSE_SUCCESS, cmd->cmd_task); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); cmd->cmd_remove = 1; return (MM_CMD_DONE); not_found: mm_response_error(cmd, ECLASS_LANGUAGE, ENOTFOUND, MM_5062_MSG, NULL); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_buf); cmd->cmd_remove = 1; return (MM_CMD_ERROR); no_mem: MM_ABORT_NO_MEM(); return (MM_CMD_ERROR); } int mm_dmp_reset_cmd_func(mm_wka_t *mm_wka, mm_command_t *cmd) { cci_t *conn = &mm_wka->wka_conn; mm_response_t response; mms_trace(MMS_DEBUG, "dmp reset, state %d, %s", cmd->cmd_state, cmd->cmd_textcmd); if (cmd->cmd_state == 0) { mms_trace(MMS_INFO, "Issuing reset for %s %s", conn->cci_instance, conn->cci_client); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_textcmd); cmd->cmd_flags |= MM_CMD_NEED_ACCEPT; cmd->cmd_state = 1; return (MM_ACCEPT_NEEDED); } else if (cmd->cmd_state == 1) { if (mm_parse_response(cmd->cmd_response, &response) == 0 && response.response_type == MM_RESPONSE_ACCEPTED) { mms_trace(MMS_DEVP, "dmp reset accepted"); cmd->cmd_flags &= ~MM_CMD_NEED_ACCEPT; cmd->cmd_flags |= MM_CMD_ACCEPTED; cmd->cmd_state = 2; return (MM_NO_DISPATCH); } else { mms_trace(MMS_ERR, "dmp cmd not accepted"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } } else if (cmd->cmd_state == 2) { if (mm_parse_response(cmd->cmd_response, &response) == 0 && response.response_type == MM_RESPONSE_SUCCESS) { mms_trace(MMS_DEVP, "dmp reset success"); cmd->cmd_remove = 1; return (MM_DEPEND_DONE); } } mms_trace(MMS_DEVP, "dmp reset failed"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } int mm_dmp_exit_cmd_func(mm_wka_t *mm_wka, mm_command_t *cmd) { cci_t *conn = &mm_wka->wka_conn; mm_response_t response; mms_trace(MMS_DEBUG, "dmp exit, state %d, %s", cmd->cmd_state, cmd->cmd_textcmd); if (cmd->cmd_state == 0) { mms_trace(MMS_INFO, "Issuing exit for %s %s", conn->cci_instance, conn->cci_client); mm_send_text(mm_wka->mm_wka_conn, cmd->cmd_textcmd); cmd->cmd_flags |= MM_CMD_NEED_ACCEPT; cmd->cmd_state = 1; return (MM_ACCEPT_NEEDED); } else if (cmd->cmd_state == 1) { if (mm_parse_response(cmd->cmd_response, &response) == 0 && response.response_type == MM_RESPONSE_ACCEPTED) { mms_trace(MMS_DEVP, "dmp exit accepted"); cmd->cmd_flags &= ~MM_CMD_NEED_ACCEPT; cmd->cmd_flags |= MM_CMD_ACCEPTED; cmd->cmd_state = 2; return (MM_NO_DISPATCH); } else { mms_trace(MMS_ERR, "dmp cmd not accepted"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); } } else if (cmd->cmd_state == 2) { if (mm_parse_response(cmd->cmd_response, &response) == 0 && response.response_type == MM_RESPONSE_SUCCESS) { mms_trace(MMS_DEVP, "dmp exit success"); cmd->cmd_remove = 1; return (MM_DEPEND_DONE); } } mms_trace(MMS_DEVP, "dmp exit failed"); cmd->cmd_remove = 1; return (MM_CMD_ERROR); }