diff options
author | Simon Cheng <Simon.S.Cheng@Sun.COM> | 2008-10-24 14:23:54 -0500 |
---|---|---|
committer | Simon Cheng <Simon.S.Cheng@Sun.COM> | 2008-10-24 14:23:54 -0500 |
commit | 4f2e01b27b6f050ac264ee29e4fea7a9045ce86e (patch) | |
tree | 8db070cf0876d06798853132313b08bd71534803 | |
parent | af71cc4ed6be914d26e9de3a90a2bb56e4bbe78d (diff) | |
download | illumos-gate-4f2e01b27b6f050ac264ee29e4fea7a9045ce86e.tar.gz |
6631129 More descriptive error codes required in begin-end response
-rw-r--r-- | usr/src/cmd/mms/mm/common/mm.c | 2 | ||||
-rw-r--r-- | usr/src/cmd/mms/mm/common/mm.h | 20 | ||||
-rw-r--r-- | usr/src/cmd/mms/mm/common/mm_lmp_sql.c | 7 | ||||
-rw-r--r-- | usr/src/cmd/mms/mm/common/mm_mmp_mount.c | 171 | ||||
-rw-r--r-- | usr/src/cmd/mms/mm/common/mm_msg.c | 20 | ||||
-rw-r--r-- | usr/src/cmd/mms/mm/common/mm_task.c | 340 | ||||
-rw-r--r-- | usr/src/cmd/mms/mm/common/mm_util.c | 490 | ||||
-rw-r--r-- | usr/src/cmd/mms/mm/common/mm_util.h | 14 | ||||
-rw-r--r-- | usr/src/common/mms/mms/mms_mm_msg.h | 4 |
9 files changed, 885 insertions, 183 deletions
diff --git a/usr/src/cmd/mms/mm/common/mm.c b/usr/src/cmd/mms/mm/common/mm.c index ec6e8e6376..3561890c0a 100644 --- a/usr/src/cmd/mms/mm/common/mm.c +++ b/usr/src/cmd/mms/mm/common/mm.c @@ -984,6 +984,8 @@ mm_destroy_cmd(mm_command_t *cmd) mms_list_destroy(&cmd->cmd_const_list); mm_free_list(&cmd->cmd_resp_list); mms_list_destroy(&cmd->cmd_resp_list); + mm_free_err_list(cmd); + mms_list_destroy(&cmd->cmd_err_list); } /* Message */ diff --git a/usr/src/cmd/mms/mm/common/mm.h b/usr/src/cmd/mms/mm/common/mm.h index 182c6d0ffc..706f37e8aa 100644 --- a/usr/src/cmd/mms/mm/common/mm.h +++ b/usr/src/cmd/mms/mm/common/mm.h @@ -276,6 +276,7 @@ struct cmi_cart_list { int cmi_remove_cart; int cmi_cart_not_ready; int cmi_cart_loaded; + int cmi_cart_used; }; typedef struct cmi_drive_list cmi_drive_list_t; @@ -292,6 +293,7 @@ struct cmi_drive_list { int cmi_drive_not_ready; int cmi_dm_shape_priority; int cmi_dm_density_priority; + int cmi_drive_used; }; #define MM_MOUNT 0 @@ -311,6 +313,7 @@ struct cmd_mount_info { char *cmi_handle; mms_list_t cmi_cart_list; int cmi_total_carts; + int cmi_mount_ok; /* Recovery */ int cmi_retries; @@ -433,6 +436,19 @@ struct mm_msg { int msg_flags; }; +typedef struct mm_cmd_err mm_cmd_err_t; +struct mm_cmd_err { + mms_list_node_t mm_cmd_err_next; + char *ecode; + char *eclass; + char *err_buf; + int err_bufsize; + char *retry_drive; + char *retry_cart; + char *retry_lib; + int err_already_used; +}; + typedef struct mm_wka { cci_t wka_conn; mms_list_node_t wka_next; @@ -499,6 +515,10 @@ struct mm_command { mms_list_t cmd_source_list; mms_list_t cmd_dest_list; mms_list_t cmd_const_list; + /* error list */ + mms_list_t cmd_err_list; + mm_cmd_err_t *cmd_err_ptr; + mms_list_t cmd_beginend_list; int cmd_begin_has_end; diff --git a/usr/src/cmd/mms/mm/common/mm_lmp_sql.c b/usr/src/cmd/mms/mm/common/mm_lmp_sql.c index 7c276d2a84..168199ca4b 100644 --- a/usr/src/cmd/mms/mm/common/mm_lmp_sql.c +++ b/usr/src/cmd/mms/mm/common/mm_lmp_sql.c @@ -772,7 +772,12 @@ mm_lmp_activate_cmd_func(mm_wka_t *mm_wka, mm_command_t *cmd) } } - mms_trace(MMS_ERR, "lm activate %d failed", flag); + mms_trace(MMS_ERR, "lm activate %d failed, set LM to present", flag); + if (mm_lm_state_soft(mm_wka, "present")) { + mms_trace(MMS_ERR, + "mm_lmp_activate_cmd_func: " + "LM state changed failed"); + } cmd->cmd_remove = 1; return (MM_CMD_ERROR); } diff --git a/usr/src/cmd/mms/mm/common/mm_mmp_mount.c b/usr/src/cmd/mms/mm/common/mm_mmp_mount.c index 68f7c2d7c6..da2b7409aa 100644 --- a/usr/src/cmd/mms/mm/common/mm_mmp_mount.c +++ b/usr/src/cmd/mms/mm/common/mm_mmp_mount.c @@ -510,18 +510,28 @@ mm_candidate_drive_ok(mm_wka_t *mm_wka, " DriveStateSoft != ready ", candidate_drive); drive->cmi_drive_not_ready = 1; + mm_response_error(cmd, + ECLASS_RETRY, + "EDRVINUSE", + MM_5025_MSG, + "drive", candidate_drive, + NULL); + mm_set_retry_drive(cmd, + candidate_drive); if (mount_info->cmi_when == MM_IMMEDIATE) { + rc = 0; goto end; + } else { + mms_trace(MMS_DEVP, + "drive in use, keep as" + " candidate for blocking mounts"); mm_response_error(cmd, ECLASS_RETRY, "EDRVINUSE", MM_5025_MSG, "drive", candidate_drive, NULL); - rc = 0; goto end; - } else { - mms_trace(MMS_DEVP, - "drive in use, keep as" - " candidate for blocking mounts"); + mm_set_retry_drive(cmd, + candidate_drive); } /* Keep this drive as a candidate for blocking mounts */ @@ -543,14 +553,15 @@ mm_candidate_drive_ok(mm_wka_t *mm_wka, "This drive is in the process of " "unloading/loading"); drive->cmi_drive_not_ready = 1; + mm_response_error(cmd, + ECLASS_RETRY, + "EDRVUNLOADING", + MM_5102_MSG, + "drive", candidate_drive, + NULL); + mm_set_retry_drive(cmd, + candidate_drive); if (mount_info->cmi_when == MM_IMMEDIATE) { - /* make a real error message for this */ - mm_response_error(cmd, - ECLASS_RETRY, - "EDRVUNLOADING", - MM_5102_MSG, - "drive", candidate_drive, - NULL); rc = 0; goto end; } } else { @@ -564,13 +575,15 @@ mm_candidate_drive_ok(mm_wka_t *mm_wka, drive->cmi_drive_not_ready = 1; mms_trace(MMS_DEVP, "drive is loaded with a non-mms tape"); + mm_response_error(cmd, + ECLASS_RETRY, + "EDRVINUSE", + MM_5028_MSG, + "drive", candidate_drive, + NULL); + mm_set_retry_drive(cmd, + candidate_drive); if (mount_info->cmi_when == MM_IMMEDIATE) { - mm_response_error(cmd, - ECLASS_RETRY, - "EDRVINUSE", - MM_5028_MSG, - "drive", candidate_drive, - NULL); rc = 0; goto end; } } @@ -677,28 +690,29 @@ mm_candidate_drive_ok(mm_wka_t *mm_wka, "drive", candidate_drive, NULL); + mm_set_retry_drive(cmd, + candidate_drive); rc = 0; goto end; } else if (strcmp(dm_stat->dm_stat_soft, "not ready") == 0) { /* drive is not ready for blocked */ drive->cmi_drive_not_ready = 1; + mm_response_error(cmd, + ECLASS_RETRY, + "EDMSTILLBOOTING", + MM_5034_MSG, + "dm", + dm_stat->dm_stat_name, + "drive", + candidate_drive, + NULL); if (mount_info->cmi_when == MM_IMMEDIATE) { - mm_response_error(cmd, - ECLASS_RETRY, - "EDMSTILLBOOTING", - MM_5034_MSG, - "dm", - dm_stat->dm_stat_name, - "drive", - candidate_drive, - NULL); rc = 0; goto end; } } else if (strcmp(dm_stat->dm_stat_soft, "present") == 0) { /* drive is not ready for blocked */ drive->cmi_drive_not_ready = 1; - if (mount_info->cmi_when == MM_IMMEDIATE) { mm_response_error(cmd, ECLASS_CONFIG, "EDRVNODMCONFIGURED", @@ -708,6 +722,9 @@ mm_candidate_drive_ok(mm_wka_t *mm_wka, "drive", candidate_drive, NULL); + mm_set_retry_drive(cmd, + candidate_drive); + if (mount_info->cmi_when == MM_IMMEDIATE) { rc = 0; goto end; } } else if ((mount_info->cmi_operation == MM_MOUNT) && @@ -715,14 +732,16 @@ mm_candidate_drive_ok(mm_wka_t *mm_wka, "reserved") == 0)) { /* drive is not ready for blocked */ drive->cmi_drive_not_ready = 1; + mm_response_error(cmd, + ECLASS_RETRY, + "EDRVINUSE", + MM_5098_MSG, + "dm", + dm_stat->dm_stat_name, + NULL); + mm_set_retry_drive(cmd, + candidate_drive); if (mount_info->cmi_when == MM_IMMEDIATE) { - mm_response_error(cmd, - ECLASS_RETRY, - "EDRVINUSE", - MM_5098_MSG, - "dm", - dm_stat->dm_stat_name, - NULL); rc = 0; goto end; } } @@ -873,16 +892,17 @@ mm_candidate_cartridge_ok(mm_wka_t *mm_wka, /* mark this cartridge not ready */ /* for blocked mounts */ cart_struct->cmi_cart_not_ready = 1; - + /* State is 'in use' */ + mm_response_error(cmd, + ECLASS_RETRY, + "ECARTINUSE", + MM_5038_MSG, + "cart", + candidate_cartid, + NULL); + mm_set_retry_cart(cmd, + (char *)candidate_cartid); if (mount_info->cmi_when == MM_IMMEDIATE) { - /* State is 'in use' */ - mm_response_error(cmd, - ECLASS_RETRY, - "ECARTINUSE", - MM_5038_MSG, - "cart", - candidate_cartid, - NULL); rc = 0; goto end; } } @@ -1115,6 +1135,8 @@ mm_candidate_library_ok(mm_command_t *cmd, mm_db_t *db, "lib", lib_stat->lib_stat_name, NULL); + mm_set_retry_lib(cmd, + candidate_library); } if (strcmp(lm_stat->lm_stat_soft, "present") == 0) { @@ -1127,6 +1149,8 @@ mm_candidate_library_ok(mm_command_t *cmd, mm_db_t *db, "lib", lib_stat->lib_stat_name, NULL); + mm_set_retry_lib(cmd, + candidate_library); } if (strcmp(lm_stat->lm_stat_soft, "disconnected") == 0) { @@ -1152,6 +1176,8 @@ mm_candidate_library_ok(mm_command_t *cmd, mm_db_t *db, "lib", lib_stat->lib_stat_name, NULL); + mm_set_retry_lib(cmd, + candidate_library); } rc = 0; goto end; } @@ -1297,6 +1323,7 @@ mm_setup_drive_unmount(mm_command_t *cmd, strdup(candidate_drive); drive->cmi_mode_valid = 1; drive->cmi_drive_not_ready = 0; + drive->cmi_drive_used = 0; drive->cmi_dm_name = mms_strapp(drive->cmi_dm_name, dm_name); drive->cmi_dm_shape_priority = 0; @@ -1503,6 +1530,7 @@ mm_setup_drive(mm_command_t *cmd, strdup(candidate_drive); drive->cmi_mode_valid = 1; drive->cmi_drive_not_ready = drive_not_ready; + drive->cmi_drive_used = 0; drive->cmi_dm_name = strdup(PQgetvalue(dm, @@ -1606,6 +1634,7 @@ mm_setup_cart(mm_command_t *cmd, bit_format); cart->cmi_cart_not_ready = 0; + cart->cmi_cart_used = 0; cart->cmi_cart_priority = atoi(candidate_priority); cart->cmi_cart_num_mounts = atoi(candidate_num_mounts); @@ -1657,11 +1686,13 @@ mm_mount_candidate_loaded(mm_command_t *cmd) { cur_cartid = cart->cmi_cart_id; /* The list should already be ordered */ /* select the 1st available */ - if (cart->cmi_cart_not_ready) { + if (cart->cmi_cart_not_ready || + cart->cmi_cart_used) { continue; } mms_list_foreach(&cart->cmi_drive_list, drive) { - if (drive->cmi_drive_not_ready) { + if (drive->cmi_drive_not_ready || + drive->cmi_drive_used) { continue; } if (drive->cmi_drive_loaded) { @@ -1711,7 +1742,8 @@ mm_mount_open_drive(mm_command_t *cmd) { /* The list should already be ordered */ /* select the 1st available */ mms_list_foreach(&mount_info->cmi_cart_list, cart) { - if (cart->cmi_cart_not_ready) { + if (cart->cmi_cart_not_ready || + cart->cmi_cart_used) { continue; } cur_library = cart->cmi_library; @@ -1723,7 +1755,8 @@ mm_mount_open_drive(mm_command_t *cmd) { /* The list should already be ordered */ /* select the 1st available */ mms_list_foreach(&cart->cmi_drive_list, drive) { - if (drive->cmi_drive_not_ready) { + if (drive->cmi_drive_not_ready || + drive->cmi_drive_used) { continue; } /* only look at non-loaded drives */ @@ -1770,14 +1803,16 @@ mm_unmount_2_drive(mm_command_t *cmd, mm_db_t *db) { "mm_unmount_2_drive: "); mms_list_foreach(&mount_info->cmi_cart_list, cart) { - if (cart->cmi_cart_not_ready) { + if (cart->cmi_cart_not_ready || + cart->cmi_cart_used) { continue; } cur_library = cart->cmi_library; cur_cartid = cart->cmi_cart_id; cur_pcl = cart->cmi_cart_pcl; mms_list_foreach(&cart->cmi_drive_list, drive) { - if (drive->cmi_drive_not_ready) { + if (drive->cmi_drive_not_ready || + drive->cmi_drive_used) { continue; } cur_drive = drive->cmi_drive_name; @@ -1874,7 +1909,8 @@ mm_mount_loaded_drive(mm_command_t *cmd, mm_db_t *db, /* The list should already be ordered */ /* select the 1st available */ mms_list_foreach(&mount_info->cmi_cart_list, cart) { - if (cart->cmi_cart_not_ready) { + if (cart->cmi_cart_not_ready || + cart->cmi_cart_used) { continue; } cur_library = cart->cmi_library; @@ -1887,7 +1923,8 @@ mm_mount_loaded_drive(mm_command_t *cmd, mm_db_t *db, /* select the 1st available */ mms_list_foreach(&cart->cmi_drive_list, drive) { - if (drive->cmi_drive_not_ready) { + if (drive->cmi_drive_not_ready || + drive->cmi_drive_used) { continue; } cur_drive = drive->cmi_drive_name; @@ -2141,6 +2178,8 @@ void mm_set_mount_objs(mm_command_t *cmd, mm_db_t *db) { cmd_mount_info_t *mount_info = &cmd->cmd_mount_info; + + if (mm_db_exec(HERE, db, "delete from \"TASK\" " "where \"TaskID\" = '%s';", cmd->cmd_uuid) != MM_DB_OK) { @@ -2149,12 +2188,6 @@ mm_set_mount_objs(mm_command_t *cmd, mm_db_t *db) { "db error deleting TASK"); } - if (mm_new_tm_task(db, cmd, "dispatched") != MM_DB_OK) { - mms_trace(MMS_ERR, - "mm_set_mount_objs: " - "db error inserting TASK"); - } - /* Delete all old TASK objects and create them anew */ if (mm_db_exec(HERE, db, "delete from \"TASKDRIVE\" " "where \"TaskID\" = '%s';", @@ -2178,6 +2211,24 @@ mm_set_mount_objs(mm_command_t *cmd, mm_db_t *db) { "db error deleting TASKCARTRIDGE"); } + if ((mount_info->cmi_drive == NULL) || + (mount_info->cmi_library == NULL) || + (mount_info->cmi_cartridge == NULL) || + (mount_info->cmi_dm == NULL)) { + mms_trace(MMS_ERR, + "mm_set_mount_objs: " + "mount info incomplete"); + mm_system_error(cmd, + "internal error setting task info, " + "mount info incomplete"); + return; + } + + if (mm_new_tm_task(db, cmd, "dispatched") != MM_DB_OK) { + mms_trace(MMS_ERR, + "mm_set_mount_objs: " + "db error inserting TASK"); + } if (mm_set_tm_drive(db, cmd->cmd_uuid, @@ -3485,6 +3536,8 @@ mm_mount_ready(mm_wka_t *mm_wka, mm_command_t *cmd, mm_db_t *db, int is_retry) { "No candidate " "cartridge/library/drive " "combination found"); + /* set least severe error */ + mm_set_least_severe(cmd); return (MM_MOUNT_ERROR); } if (found_ready_cart_drive == 0) { @@ -3527,6 +3580,8 @@ mm_mount_ready(mm_wka_t *mm_wka, mm_command_t *cmd, mm_db_t *db, int is_retry) { if (rc == MM_CMD_ERROR) { mms_trace(MMS_ERR, "error setting up immediate mount"); + /* set least severe error */ + mm_set_least_severe(cmd); return (MM_MOUNT_ERROR); } else if (rc == MM_DISPATCH_DEPEND) { /* this immediate mount needs to */ diff --git a/usr/src/cmd/mms/mm/common/mm_msg.c b/usr/src/cmd/mms/mm/common/mm_msg.c index 0125c9186e..1624df481d 100644 --- a/usr/src/cmd/mms/mm/common/mm_msg.c +++ b/usr/src/cmd/mms/mm/common/mm_msg.c @@ -1320,6 +1320,9 @@ mm_response_error(mm_command_t *cmd, char *eclass, char *ecode, char *buf; char *text; + mm_cmd_err_t *err = NULL; + + mms_trace(MMS_ERR, "mm_response_error"); mms_trace(MMS_ERR, "Class:: %s", eclass); @@ -1355,6 +1358,23 @@ mm_response_error(mm_command_t *cmd, char *eclass, char *ecode, SQL_CHK_LEN(&cmd->cmd_buf, 0, &cmd->cmd_bufsize, strlen(buf) + 1); strcpy(cmd->cmd_buf, buf); free(buf); + + /* insert this error into the cmd's err_list */ + if ((err = mm_alloc_err()) == NULL) { + mms_trace(MMS_ERR, + "mm_response_error: " + "could not allocate err struct"); + return; + } + err->eclass = strdup(eclass); + err->ecode = strdup(ecode); + err->err_bufsize = cmd->cmd_bufsize; + err->err_buf = strdup(cmd->cmd_buf); + err->retry_drive = NULL; + err->retry_cart = NULL; + err->retry_lib = NULL; + mms_list_insert_tail(&cmd->cmd_err_list, err); + return; no_mem: diff --git a/usr/src/cmd/mms/mm/common/mm_task.c b/usr/src/cmd/mms/mm/common/mm_task.c index 886451a1e2..273e13487b 100644 --- a/usr/src/cmd/mms/mm/common/mm_task.c +++ b/usr/src/cmd/mms/mm/common/mm_task.c @@ -395,6 +395,8 @@ tm_be_mount_ready(mm_wka_t *mm_wka, mm_command_t *cmd, mm_db_t *db, int found_cart_drive = 0; int found_ready_cart_drive = 0; + char *err_text = NULL; + /* Need to set end_cmd buf correctly for any MM_MOUNT_ERROR return */ @@ -499,13 +501,14 @@ tm_be_mount_ready(mm_wka_t *mm_wka, mm_command_t *cmd, mm_db_t *db, NULL); return (MM_MOUNT_ERROR); } - + err_text = mm_return_err_text(cmd->cmd_err_ptr); mm_response_error(end_cmd, ECLASS_EXPLICIT, "ENOSOLUTIONS", - MM_5105_MSG, + MM_5110_MSG, + "err_text", err_text, NULL); - + free(err_text); return (MM_MOUNT_ERROR); } if (found_ready_cart_drive == 0) { @@ -557,7 +560,7 @@ tm_be_cancel_all(mm_command_t *cmd) { } int -tm_be_set_mount(mm_wka_t *mm_wka, mm_command_t *cmd, mm_db_t *db, +tm_be_set_mount(mm_command_t *cmd, mm_db_t *db, mm_command_t *end_cmd) { cmd_mount_info_t *mount_info = &cmd->cmd_mount_info; @@ -630,22 +633,18 @@ tm_be_set_mount(mm_wka_t *mm_wka, mm_command_t *cmd, mm_db_t *db, MM_UNSET_FLAG(cmd->cmd_flags, MM_CMD_DISPATCHABLE); } else { - mms_trace(MMS_ERR, "no drives found due to other candidates"); - if (mm_wka->wka_begin_end.be_mode == - ACCESS_MODE_BLOCKING) { - return (MM_BE_BLOCKING); + mm_set_least_severe(cmd); + if (cmd->cmd_err_ptr == NULL) { + mms_trace(MMS_ERR, + "cmd has no errors, set ENOMATCH"); + mm_response_error(end_cmd, + ECLASS_EXPLICIT, ENOMATCH, + MM_5052_MSG, + NULL); } - /* May want to add additional arg's to this message? */ - mm_response_error(end_cmd, - ECLASS_RETRY, - "ETMPUNAVAIL", - MM_5104_MSG, - NULL); - return (MM_BE_ERROR); - } /* Select Is done - print the results */ @@ -661,6 +660,17 @@ tm_be_set_mount(mm_wka_t *mm_wka, mm_command_t *cmd, mm_db_t *db, mms_trace(MMS_DEVP, "DM is %s", mount_info->cmi_dm); + /* since this mount will work, clear the error flags for it */ + if (cmd->cmd_eclass != NULL) { + free(cmd->cmd_eclass); + cmd->cmd_eclass = NULL; + } + if (cmd->cmd_ecode != NULL) { + free(cmd->cmd_ecode); + cmd->cmd_ecode = NULL; + } + cmd->cmd_mount_info.cmi_mount_ok = 1; + return (MM_BE_DISPATCH); } @@ -745,6 +755,86 @@ tm_be_set_unmount(mm_wka_t *mm_wka, mm_command_t *cmd, } void +tm_be_rm_error_candidates(mm_command_t *cmd, mm_command_t *err_cmd) { + /* remove candidates set in err_cmd */ + /* from the beginend candidatea list in cmd */ + + mm_cmd_err_t *err = err_cmd->cmd_err_ptr; + mm_command_t *cur_cmd; + cmd_mount_info_t *cur_mount_info; + + cmi_cart_list_t *cart = NULL; + cmi_drive_list_t *drive = NULL; + + mms_list_t *cart_list; + + int seen_same = 0; + mm_cmd_err_t *cur_err = NULL; + + mms_trace(MMS_DEVP, + "tm_be_rm_error_candidates: "); + if (err == NULL) { + mms_trace(MMS_ERR, + "tm_be_rm_error_candidates: " + "error ptr set to NULL"); + return; + } + + mms_trace(MMS_DEVP, + " Error to remove:"); + mm_print_err(err); + + mms_list_foreach(&cmd->cmd_beginend_list, cur_cmd) { + /* same command */ + if (cur_cmd == err_cmd) { + seen_same = 1; + continue; + } + if (seen_same == 0) { + continue; + } + + /* check cur_cmd's error */ + mms_list_foreach(&cur_cmd->cmd_err_list, cur_err) { + if (mm_same_err(err, cur_err)) { + cur_err->err_already_used = 1; + mms_trace(MMS_DEVP, + " matched an err"); + } + } + cur_cmd->cmd_err_ptr = NULL; + mm_set_least_severe(cur_cmd); + + cur_mount_info = &cur_cmd->cmd_mount_info; + cart_list = &cur_mount_info->cmi_cart_list; + mms_list_foreach(cart_list, cart) { + /* Check this cart */ + if ((err->retry_cart != NULL) && + (cart->cmi_cart_id != NULL) && + (strcmp(err->retry_cart, + cart->cmi_cart_id) == 0)) { + cart->cmi_cart_used = 1; + mms_trace(MMS_DEVP, + "tm_be_rm_error_candidates: " + "set a cart as used"); + } + mms_list_foreach(&cart->cmi_drive_list, drive) { + /* check this drive */ + if ((err->retry_drive != NULL) && + (drive->cmi_drive_name != NULL) && + (strcmp(err->retry_drive, + drive->cmi_drive_name) == 0)) { + drive->cmi_drive_used = 1; + mms_trace(MMS_DEVP, + "tm_be_rm_error_candidates: " + "set a drive as used"); + } + } + } + } +} + +void tm_be_rm_mount_candidates(mm_command_t *cmd, mm_command_t *set_cmd) { /* remove candidates set in set_cmd */ /* from the beginend candidatea list in cmd */ @@ -760,7 +850,7 @@ tm_be_rm_mount_candidates(mm_command_t *cmd, mm_command_t *set_cmd) { int seen_same = 0; mms_trace(MMS_DEVP, - "remove %s and %s from candidate lists", + "set %s and %s as used candidates", set_mount_info->cmi_cartridge, set_mount_info->cmi_drive); mms_list_foreach(&cmd->cmd_beginend_list, cur_cmd) { @@ -777,16 +867,15 @@ tm_be_rm_mount_candidates(mm_command_t *cmd, mm_command_t *set_cmd) { mms_list_foreach(cart_list, cart) { if (strcmp(set_mount_info->cmi_cartridge, cart->cmi_cart_id) == 0) { - cart->cmi_remove_cart = 1; + cart->cmi_cart_used = 1; } mms_list_foreach(&cart->cmi_drive_list, drive) { if (strcmp(set_mount_info->cmi_drive, drive->cmi_drive_name) == 0) { - drive->cmi_remove_drive = 1; + drive->cmi_drive_used = 1; } } } - mm_mount_clean_candidates(cur_cmd); } } @@ -1280,9 +1369,8 @@ tm_be_mounts(mm_command_t *cmd, mm_data_t *mm_data) { /* Errors */ int mount_has_error = 0; - int mount_would_block = 0; - int only_retry = 1; - int retry_in_use = 1; + + char *err_text = NULL; /* This is the function can return */ /* MM_BE_ERROR */ @@ -1298,12 +1386,14 @@ tm_be_mounts(mm_command_t *cmd, mm_data_t *mm_data) { /* Instead of returning set mount_has_error or mount_would_block */ /* After calling for ever mount generate the correct error code */ mms_list_foreach(&cmd->cmd_beginend_list, cur_cmd) { + cur_cmd->cmd_mount_info.cmi_mount_ok = 0; rc = tm_be_mount_ready(cur_cmd->wka_ptr, cur_cmd, db, cmd); switch (rc) { case MM_MOUNT_ERROR: /* Error code should be set */ mms_trace(MMS_ERR, + "tm_be_mounts: " "internal error, tm_be_mount_ready"); mount_has_error = 1; break; @@ -1312,36 +1402,31 @@ tm_be_mounts(mm_command_t *cmd, mm_data_t *mm_data) { /* The mount is ready, mount_info should be set */ /* continue to state 1 */ mms_trace(MMS_DEVP, + "tm_be_mounts: " "mount is ready to go "); + cur_cmd->cmd_mount_info.cmi_mount_ok = 1; break; case MM_MOUNT_NEED_UNLOAD: /* this immediate mount needs to */ /* wait for an unload */ mms_trace(MMS_DEVP, + "tm_be_mounts: " "mount needs to wait " "for unload to complete"); + cur_cmd->cmd_mount_info.cmi_mount_ok = 1; break; case MM_MOUNT_NOT_READY: - if (mm_wka->wka_begin_end.be_mode == - ACCESS_MODE_IMMEDIATE) { - /* Error code should be set */ - mms_trace(MMS_ERR, - "immediate begin-end group " - "is not ready"); - mount_has_error = 1; - break; - } - /* Error code should be set */ + mount_has_error = 1; mms_trace(MMS_ERR, - "blocking mount not ready, " + "tm_be_mounts: " + "mount not ready, " "wait longer and try later"); - mount_would_block = 1; - break; - + break; default: mms_trace(MMS_ERR, + "tm_be_mounts: " "bad rc mm_mount_ready"); mm_system_error(cmd, "bad rc mm_mount_ready"); @@ -1356,107 +1441,120 @@ tm_be_mounts(mm_command_t *cmd, mm_data_t *mm_data) { mms_trace(MMS_ERR, "at least one mount had " "an error for this begin-end"); - /* Check every command's error class */ - /* If there are only retry errors use the retry class */ + + /* at least one mount had an error */ + /* for each mount set the least sever errror */ + /* if any mount has a error more severe than retry */ + /* return error for the end command */ + /* since this mount will not work for immediate or blocking */ mms_list_foreach(&cmd->cmd_beginend_list, cur_cmd) { - if ((cur_cmd->cmd_eclass != NULL) && - (strcmp(cur_cmd->cmd_eclass, ECLASS_RETRY) != 0)) { - /* found a mount where class is not retry */ - only_retry = 0; - } else if ((cur_cmd->cmd_eclass != NULL) && - (strcmp(cur_cmd->cmd_eclass, - ECLASS_RETRY) == 0)) { - /* This is a retry class */ - /* Check if this is an inuse error */ - if ((strcmp(cur_cmd->cmd_ecode, - "EDRVINUSE") == 0) || - (strcmp(cur_cmd->cmd_ecode, - "ECARTINUSE") == 0)) { - retry_in_use = 1; + if (cur_cmd->cmd_mount_info.cmi_mount_ok) { + mms_trace(MMS_ERR, + "tm_be_mounts: " + "this mount is ok, no errors"); + } else { + mms_trace(MMS_ERR, + "tm_be_mounts: " + "this mount has errors, set least severe"); + + mm_set_least_severe(cur_cmd); + if (strcmp(cur_cmd->cmd_eclass, + ECLASS_RETRY) != 0) { + /* this is not a retry error class */ + /* return error for this end command */ + mms_trace(MMS_ERR, + "at least one mount's " + "least severe error is" + " more severe than retry, " + "this begin-end group " + "will not work"); + /* One or more mount has errors */ + /* that are non retry */ + err_text = + mm_return_err_text(cur_cmd-> + cmd_err_ptr); + mm_response_error(cmd, + ECLASS_EXPLICIT, + "ENOSOLUTIONS", + MM_5110_MSG, + "err_text", err_text, + NULL); + free(err_text); + return (MM_BE_ERROR); } } + } - if ((cur_cmd->cmd_eclass != NULL) && - (strcmp(cur_cmd->cmd_eclass, - ECLASS_INTERNAL) == 0)) { - /* This mount had a system error */ - /* Set system error and return */ - mm_system_error(cmd, - "internal error processing " - "a begin-end mount cmd"); - return (MM_BE_ERROR); - } + + } + + /* All mounts are either ok or retry */ + /* Determine which error to return/block */ + /* for immediate, return retry or nosolutions */ + /* for blocking, block or return nosolutions */ + + + /* Mount candidate lists have been set up, */ + /* divide the resources and set up the exact */ + /* Drive/cartridge combination */ + + mount_has_error = 0; + mms_list_foreach(&cmd->cmd_beginend_list, cur_cmd) { + + mms_trace(MMS_DEVP, "set up a mount for dispatch"); + + /* tm_be_set_mount returns MM_BE_ERROR or MM_BE_DISPATCH */ + + if (cur_cmd->cmd_mount_info.cmi_mount_ok) { + rc = tm_be_set_mount(cur_cmd, + db, cmd); + } else { + rc = MM_BE_ERROR; } - if (only_retry) { - mms_trace(MMS_ERR, - "all mounts have retry error class "); - if (retry_in_use) { + if (rc == MM_BE_ERROR) { + mount_has_error = 1; + /* If the cur err ptr is null or */ + /* pointing to a non-retry error class */ + /* This begin-end group cannot succeede */ + if ((cur_cmd->cmd_err_ptr == NULL) || + (strcmp(cur_cmd->cmd_err_ptr->eclass, + ECLASS_RETRY) != 0)) { mms_trace(MMS_ERR, - "at least one mount " - "has an in-use error"); - /* Set error for retry */ - mm_response_error(cmd, - ECLASS_RETRY, - "ETMPINUSE", - MM_5104_MSG, - NULL); + "tm_be_mounts: " + "There are no valid " + "solutions to this mount "); - } else { - /* Set error for retry */ + err_text = + mm_return_err_text(cur_cmd-> + cmd_err_ptr); mm_response_error(cmd, - ECLASS_RETRY, - "ETMPUNAVAIL", - MM_5104_MSG, + ECLASS_EXPLICIT, + "ENOSOLUTIONS", + MM_5110_MSG, + "err_text", err_text, NULL); + free(err_text); + return (MM_BE_ERROR); } + tm_be_rm_error_candidates(cmd, cur_cmd); } else { - mms_trace(MMS_ERR, - "at least one mount had a eclass" - " more severe than retry "); - /* One or more mount has errors */ - /* that are non retry */ - mm_response_error(cmd, - ECLASS_EXPLICIT, - "ENOSOLUTIONS", - MM_5105_MSG, - NULL); + tm_be_rm_mount_candidates(cmd, cur_cmd); } - return (MM_BE_ERROR); } - if (mount_would_block) { - mms_trace(MMS_ERR, - "at least one mount has " - "to block for this begin-end"); + + if (mount_has_error) { + /* If this is immediate, return retry error class for the end */ + /* if this is blocking, then block for the whole group */ + /* Set error for retry */ + mm_response_error(cmd, + ECLASS_RETRY, + "ETMPUNAVAIL", + MM_5104_MSG, + NULL); return (MM_BE_BLOCKING); } - /* Mount candidate lists have been set up, */ - /* divide the resources and set up the exact */ - /* Drive/cartridge combination */ - mms_list_foreach(&cmd->cmd_beginend_list, cur_cmd) { - mms_trace(MMS_DEVP, "set up a mount for dispatch"); - rc = tm_be_set_mount(cur_cmd->wka_ptr, - cur_cmd, db, cmd); - if (rc == MM_BE_ERROR) { - mms_trace(MMS_ERR, "error setting up mount"); - /* error set for end command already */ - return (MM_BE_ERROR); - } else if (rc == MM_BE_BLOCKING) { - mms_trace(MMS_ERR, - "blocking mount not ready, " - "wait longer and try later"); - return (MM_BE_BLOCKING); - } - /* remove cmi_cart and cmi_drive from */ - /* above from the remaining */ - /* unmount candidates */ - tm_be_rm_mount_candidates(cmd, cur_cmd); - } - - - /* Need to remove all dispatch releated stuff from the functions */ - /* used by tm_be_set_mount or mm_set_immediate_mount */ mms_list_foreach(&cmd->cmd_beginend_list, cur_cmd) { if (mm_dispatch_now(mm_wka, cur_cmd, db)) { /* error should be set */ diff --git a/usr/src/cmd/mms/mm/common/mm_util.c b/usr/src/cmd/mms/mm/common/mm_util.c index d749104bb1..0c151dd0f1 100644 --- a/usr/src/cmd/mms/mm/common/mm_util.c +++ b/usr/src/cmd/mms/mm/common/mm_util.c @@ -72,9 +72,328 @@ extern void uuid_generate_random(uuid_t uu); extern void uuid_generate(uuid_t uu); /* hits bug id 6397009 */ extern void uuid_unparse(uuid_t uu, char *out); +/* + * mm_err_eclass_rank + * return int of the rank of this eclass + * higher numbers mean more severe + */ +int +mm_err_eclass_rank(char *eclass) +{ + /* 13 total error classes */ + + if (strcmp(eclass, ECLASS_LANGUAGE) == 0) + return (13); + if (strcmp(eclass, ECLASS_EXPLICIT) == 0) + return (12); + if (strcmp(eclass, ECLASS_INTERNAL) == 0) + return (11); + if (strcmp(eclass, ECLASS_INVALID) == 0) + return (10); + if (strcmp(eclass, ECLASS_DM_INVALID) == 0) + return (9); + if (strcmp(eclass, ECLASS_DM_CONFIG) == 0) + return (8); + if (strcmp(eclass, ECLASS_EXIST) == 0) + return (7); + if (strcmp(eclass, ECLASS_SUBOP) == 0) + return (6); + if (strcmp(eclass, ECLASS_CONFIG) == 0) + return (5); + if (strcmp(eclass, ECLASS_STATE) == 0) + return (4); + if (strcmp(eclass, ECLASS_PERMPRIV) == 0) + return (3); + if (strcmp(eclass, ECLASS_COMPAT) == 0) + return (2); + if (strcmp(eclass, ECLASS_RETRY) == 0) + return (1); + return (0); +} + +char * +mm_return_err_text(mm_cmd_err_t *err) { + /* Generate a quick text for this error */ + /* to be used as error text for an end command */ + char *buf = NULL; + + mms_trace(MMS_DEVP, + "mm_return_err_text: "); + + if (err == NULL) { + mms_trace(MMS_DEVP, + "err ptr is NULL"); + buf = mms_strapp(buf, + "none"); + return (buf); + } + + if (err->eclass != NULL) { + buf = mms_strapp(buf, + "%s ", err->eclass); + mms_trace(MMS_DEVP, + " %s", err->eclass); + + } + if (err->ecode != NULL) { + buf = mms_strapp(buf, + "%s ", err->ecode); + mms_trace(MMS_DEVP, + " %s", err->ecode); + } + if (err->retry_cart != NULL) { + buf = mms_strapp(buf, + "%s ", err->retry_cart); + mms_trace(MMS_DEVP, + " %s", err->retry_cart); + } + if (err->retry_drive != NULL) { + buf = mms_strapp(buf, + "%s ", err->retry_drive); + mms_trace(MMS_DEVP, + " %s", err->retry_drive); + } + if (err->retry_lib != NULL) { + buf = mms_strapp(buf, + "%s ", err->retry_lib); + mms_trace(MMS_DEVP, + " %s", err->retry_lib); + } + if (buf == NULL) { + buf = mms_strapp(buf, + "none"); + mms_trace(MMS_DEVP, + "err ptr not NULL, but empty"); + } + return (buf); +} + + + +int +mm_same_err_helper(char *str1, char *str2) { + if (str1 == NULL) { + if (str2 == NULL) { + /* both ptrs are NULL, return 0 */ + return (0); + } else { + /* str1 is NULL, str2 is not */ + return (1); + } + } else { + /* str1 is not NULL */ + if (str2 == NULL) { + /* str1 is not, str2 is NULL */ + return (1); + } + } + + /* both str's are not NULL */ + return (strcmp(str1, str2)); +} + + +int +mm_same_err(mm_cmd_err_t *err1, mm_cmd_err_t *err2) { + + if ((err1 == NULL) || + (err2 == NULL)) { + mms_trace(MMS_DEVP, + "mm_same_err: " + "err1 or err2 is NULL"); + return (0); + } + if ((err1->eclass == NULL) || + (err2->eclass == NULL)) { + mms_trace(MMS_DEVP, + "mm_same_err: " + "one or both err class was NULL"); + return (0); + } + if (strcmp(err1->eclass, err2->eclass) != 0) { + mms_trace(MMS_DEVP, + "mm_same_err: " + "eclasses are different"); + return (0); + } + + if (mm_same_err_helper(err1->retry_cart, + err2->retry_cart) != 0) { + mms_trace(MMS_DEVP, + "mm_same_err: " + "retry cart is different"); + return (0); + } + if (mm_same_err_helper(err1->retry_drive, + err2->retry_drive) != 0) { + mms_trace(MMS_DEVP, + "mm_same_err: " + "retry drive is different"); + return (0); + } + if (mm_same_err_helper(err1->retry_lib, + err2->retry_lib) != 0) { + mms_trace(MMS_DEVP, + "mm_same_err: " + "retry lib is different"); + return (0); + } + mms_trace(MMS_DEVP, + "mm_same_err: " + "errors are the same"); + return (1); +} void -mm_clear_db(PGresult **results) { +mm_set_buf_to_err(mm_command_t *cmd, mm_cmd_err_t *err) +{ + + /* set current cmd_buf to least_err */ + if (cmd->cmd_buf != NULL) { + free(cmd->cmd_buf); + cmd->cmd_buf = NULL; + } + cmd->cmd_buf = strdup(err->err_buf); + cmd->cmd_bufsize = err->err_bufsize; + if (cmd->cmd_ecode != NULL) { + free(cmd->cmd_ecode); + cmd->cmd_ecode = NULL; + } + if (cmd->cmd_eclass != NULL) { + free(cmd->cmd_eclass); + cmd->cmd_eclass = NULL; + } + cmd->cmd_ecode = strdup(err->ecode); + cmd->cmd_eclass = strdup(err->eclass); +} + +void +mm_clear_cur_err(mm_command_t *cmd) +{ + if (cmd->cmd_ecode != NULL) { + free(cmd->cmd_ecode); + cmd->cmd_ecode = NULL; + } + if (cmd->cmd_eclass != NULL) { + free(cmd->cmd_eclass); + cmd->cmd_eclass = NULL; + } + if (cmd->cmd_buf != NULL) { + free(cmd->cmd_buf); + cmd->cmd_buf = NULL; + } + cmd->cmd_bufsize = 0; + +} + + +void +mm_set_least_severe(mm_command_t *cmd) +{ + + mm_cmd_err_t *err = NULL; + mm_cmd_err_t *least_err = NULL; + int cur_rank = 0; + int least_rank = 0; + int first = 1; + + + mms_list_foreach(&cmd->cmd_err_list, err) { + if (err->err_already_used) { + continue; + } + if (err->eclass == NULL) + continue; + if (first) { + least_err = err; + least_rank = + mm_err_eclass_rank(least_err->eclass); + first = 0; + continue; + } + cur_rank = mm_err_eclass_rank(err->eclass); + if (cur_rank < least_rank) { + least_rank = cur_rank; + least_err = err; + } + + } + if (first) { + mms_trace(MMS_ERR, + "mm_set_least_severe: " + "there are no unused " + "errors in the list"); + cmd->cmd_err_ptr = NULL; + return; + } + mms_trace(MMS_ERR, + "mm_set_least_severe: " + "setting error %s %s", + least_err->eclass, + least_err->ecode); + mm_set_buf_to_err(cmd, least_err); + cmd->cmd_err_ptr = least_err; +} + +void +mm_set_retry_drive(mm_command_t *cmd, char *drive) +{ + mm_cmd_err_t *err = NULL; + if ((err = mms_list_tail(&cmd->cmd_err_list)) == NULL) { + return; + } + if (err->retry_drive != NULL) { + free(err->retry_drive); + err->retry_drive = NULL; + } + if (drive == NULL) { + return; + } + err->retry_drive = + mms_strapp(err->retry_drive, + drive); +} + +void +mm_set_retry_lib(mm_command_t *cmd, char *lib) +{ + mm_cmd_err_t *err = NULL; + if ((err = mms_list_tail(&cmd->cmd_err_list)) == NULL) { + return; + } + if (err->retry_lib != NULL) { + free(err->retry_lib); + err->retry_lib = NULL; + } + if (lib == NULL) { + return; + } + err->retry_lib= + mms_strapp(err->retry_lib, + lib); +} +void +mm_set_retry_cart(mm_command_t *cmd, char *cart) +{ + mm_cmd_err_t *err = NULL; + if ((err = mms_list_tail(&cmd->cmd_err_list)) == NULL) { + return; + } + if (err->retry_cart != NULL) { + free(err->retry_cart); + err->retry_cart = NULL; + } + if (cart == NULL) { + return; + } + err->retry_cart = + mms_strapp(err->retry_cart, + cart); +} + +void +mm_clear_db(PGresult **results) +{ if (*results != NULL) { PQclear(*results); *results = NULL; @@ -82,7 +401,74 @@ mm_clear_db(PGresult **results) { } void -mm_system_error(mm_command_t *cmd, char *fmt, ...) { +mm_rm_err(mm_command_t *cmd, mm_cmd_err_t *err) +{ + mm_cmd_err_t *cur_err = NULL; + mm_cmd_err_t *next_err = NULL; + + for (cur_err = mms_list_head(&cmd->cmd_err_list); + cur_err != NULL; + cur_err = next_err) { + next_err = mms_list_next(&cmd->cmd_err_list, + cur_err); + if (mm_same_err(err, cur_err)) { + cur_err->err_already_used = 1; + mms_trace(MMS_DEVP, + "mm_rm_err: " + "an error marked as used"); + } + + } + + +} + +void +mm_print_err(mm_cmd_err_t *err) +{ + + mms_trace(MMS_DEVP, + " %s, %s %s", + err->eclass, + err->ecode, + err->err_buf); + if (err->retry_drive != NULL) + mms_trace(MMS_DEVP, + " retry_drive = %s", + err->retry_drive); + if (err->retry_cart != NULL) + mms_trace(MMS_DEVP, + " retry_cart = %s", + err->retry_cart); + if (err->retry_lib != NULL) + mms_trace(MMS_DEVP, + " retry_lib = %s", + err->retry_lib); +} + +void +mm_print_err_list(mm_command_t *cmd) +{ + mm_cmd_err_t *err = NULL; + int err_count = 1; + + mms_trace(MMS_DEVP, + "mm_print_err_list: " + "error list is :"); + mms_list_foreach(&cmd->cmd_err_list, err) { + if (err->err_already_used) + continue; + mms_trace(MMS_DEVP, + " Error # %d:", + err_count); + mm_print_err(err); + err_count ++; + } +} + +void +mm_system_error(mm_command_t *cmd, char *fmt, ...) +{ va_list args; char *text; @@ -336,6 +722,7 @@ mm_alloc_cmd(mm_wka_t *mm_wka) { mm_cmd->cmd_task = NULL; mm_cmd->cmd_textcmd = NULL; mm_cmd->cmd_report = NULL; + mm_cmd->cmd_err_ptr = NULL; /* mount command info */ mm_cmd->cmd_mount_info.cmi_dm = NULL; @@ -370,6 +757,11 @@ mm_alloc_cmd(mm_wka_t *mm_wka) { offsetof(mm_char_list_t, mm_char_list_next)); mms_list_create(&mm_cmd->cmd_resp_list, sizeof (mm_char_list_t), offsetof(mm_char_list_t, mm_char_list_next)); + /* error list */ + + mms_list_create(&mm_cmd->cmd_err_list, sizeof (mm_cmd_err_t), + offsetof(mm_cmd_err_t, mm_cmd_err_next)); + /* Initalize the access mode list */ mms_list_create(&mm_cmd->cmd_mount_info.cmi_mode_list, @@ -1080,3 +1472,97 @@ mm_add_to_const(mm_command_t *cmd, char *str) { } return (1); } + +/* + * mm_free_err: + * -free's memory inside mm_cmd_err_t + * -caller should free the struct itself + */ + +void +mm_free_err(mm_cmd_err_t *cmd_error) { + if (cmd_error->ecode != NULL) { + free(cmd_error->ecode); + cmd_error->ecode = NULL; + } + if (cmd_error->eclass != NULL) { + free(cmd_error->eclass); + cmd_error->eclass = NULL; + } + if (cmd_error->err_buf != NULL) { + free(cmd_error->err_buf); + cmd_error->err_buf = NULL; + } + if (cmd_error->retry_drive != NULL) { + free(cmd_error->retry_drive); + cmd_error->retry_drive = NULL; + } + if (cmd_error->retry_cart != NULL) { + free(cmd_error->retry_cart); + cmd_error->retry_cart = NULL; + } + if (cmd_error->retry_lib != NULL) { + free(cmd_error->retry_lib); + cmd_error->retry_lib = NULL; + } + cmd_error->err_bufsize = 0; +} + +/* + * mm_free_err_list: + * -free's an entire cmd's err list + * -caller should call list destroy on the actual list + */ +void +mm_free_err_list(mm_command_t *cmd) { + + mm_cmd_err_t *cur_err; + mm_cmd_err_t *next_err; + + mms_list_t *err_list; + + err_list = &cmd->cmd_err_list; + + /* If the obj is already in the list, skip */ + for (cur_err = mms_list_head(err_list); + cur_err != NULL; + cur_err = next_err) { + next_err = mms_list_next(err_list, cur_err); + /* remove this from the list and free */ + mms_list_remove(err_list, + cur_err); + mm_free_err(cur_err); + free(cur_err); + } + +} + +/* + * mm_alloc_err: + * -allocates and initializes a new mm_cmd_err_t struct + */ + +mm_cmd_err_t * +mm_alloc_err() { + + mm_cmd_err_t *err = NULL; + + err = (mm_cmd_err_t *)calloc(1, sizeof (mm_cmd_err_t)); + if (err == NULL) { + mms_trace(MMS_ERR, + "mm_alloc_err: " + "Unable to malloc mm_cmd_err_t: %s", + strerror(errno)); + return (NULL); + } + err->eclass = NULL; + err->ecode = NULL; + err->err_buf = NULL; + err->err_bufsize = 0; + err->retry_drive = NULL; + err->retry_cart = NULL; + err->retry_lib = NULL; + err->err_already_used = 0; + + return (err); +} diff --git a/usr/src/cmd/mms/mm/common/mm_util.h b/usr/src/cmd/mms/mm/common/mm_util.h index e8375c7143..d8716a27ce 100644 --- a/usr/src/cmd/mms/mm/common/mm_util.h +++ b/usr/src/cmd/mms/mm/common/mm_util.h @@ -22,10 +22,10 @@ * Use is subject to license terms. */ - #ifndef _MM_UTIL_H #define _MM_UTIL_H + /* * Parser command xml text file line callback structure */ @@ -103,4 +103,16 @@ extern int mm_in_char_list(mms_list_t *list, char *str); extern char *mm_return_char(mms_list_t *list, int index); extern void mm_free_list(mms_list_t *list); extern char *mm_ret_response_msg(mm_command_t *cmd); +extern void mm_free_err_list(mm_command_t *cmd); +extern mm_cmd_err_t *mm_alloc_err(); +extern void mm_print_err_list(mm_command_t *cmd); +extern void mm_print_err(mm_cmd_err_t *err); +extern void mm_set_retry_drive(mm_command_t *cmd, char *drive); +extern void mm_set_retry_lib(mm_command_t *cmd, char *lib); +extern void mm_set_retry_cart(mm_command_t *cmd, char *cart); +extern void mm_set_least_severe(mm_command_t *cmd); +extern int mm_same_err(mm_cmd_err_t *err1, mm_cmd_err_t *err2); +extern void mm_clear_cur_err(mm_command_t *cmd); +extern void mm_rm_err(mm_command_t *cmd, mm_cmd_err_t *err); +extern char *mm_return_err_text(mm_cmd_err_t *err); #endif /* _MM_UTIL_H */ diff --git a/usr/src/common/mms/mms/mms_mm_msg.h b/usr/src/common/mms/mms/mms_mm_msg.h index 511cfa6435..5e65fa7b46 100644 --- a/usr/src/common/mms/mms/mms_mm_msg.h +++ b/usr/src/common/mms/mms/mms_mm_msg.h @@ -377,6 +377,10 @@ MM_MSG(MM_5108_MSG, gettext("Standard privilege client may not modify " \ MM_MSG(MM_5109_MSG, gettext("Administrator privilege client may not modify " \ "object $object$ attribute $attribute$.")) +#define MM_5110_MSG 5110 +MM_MSG(MM_5110_MSG, gettext("No solutions to this begin-end group, " \ + "one or more mounts cannot complete - $err_text$")) + #ifdef __cplusplus } #endif |