00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <errno.h>
00035 #include <string.h>
00036 #include <ctype.h>
00037 #include <stdlib.h>
00038 #include <stdio.h>
00039 #include <OpenIPMI/ipmiif.h>
00040 #include <OpenIPMI/ipmi_cmdlang.h>
00041 #include <OpenIPMI/ipmi_mc.h>
00042
00043
00044 #include <OpenIPMI/internal/ipmi_malloc.h>
00045
00046 static int
00047 discrete_event_handler(ipmi_sensor_t *sensor,
00048 enum ipmi_event_dir_e dir,
00049 int offset,
00050 int severity,
00051 int prev_severity,
00052 void *cb_data,
00053 ipmi_event_t *event)
00054 {
00055 ipmi_cmd_info_t *cmd_info = cb_data;
00056 char sensor_name[IPMI_SENSOR_NAME_LEN];
00057
00058 ipmi_sensor_get_name(sensor, sensor_name, sizeof(sensor_name));
00059
00060 ipmi_cmdlang_out(cmd_info, "Object Type", "Sensor");
00061 ipmi_cmdlang_out(cmd_info, "Name", sensor_name);
00062 ipmi_cmdlang_out(cmd_info, "Operation", "Event");
00063 ipmi_cmdlang_out_int(cmd_info, "Offset", offset);
00064 ipmi_cmdlang_out(cmd_info, "Direction", ipmi_get_event_dir_string(dir));
00065 ipmi_cmdlang_out_int(cmd_info, "Severity", severity);
00066 ipmi_cmdlang_out_int(cmd_info, "Previous Severity", prev_severity);
00067 return IPMI_EVENT_NOT_HANDLED;
00068 }
00069
00070 static int
00071 threshold_event_handler(ipmi_sensor_t *sensor,
00072 enum ipmi_event_dir_e dir,
00073 enum ipmi_thresh_e threshold,
00074 enum ipmi_event_value_dir_e high_low,
00075 enum ipmi_value_present_e value_present,
00076 unsigned int raw_value,
00077 double value,
00078 void *cb_data,
00079 ipmi_event_t *event)
00080 {
00081 ipmi_cmd_info_t *cmd_info = cb_data;
00082 char sensor_name[IPMI_SENSOR_NAME_LEN];
00083
00084 ipmi_sensor_get_name(sensor, sensor_name, sizeof(sensor_name));
00085
00086 ipmi_cmdlang_out(cmd_info, "Object Type", "Sensor");
00087 ipmi_cmdlang_out(cmd_info, "Name", sensor_name);
00088 ipmi_cmdlang_out(cmd_info, "Operation", "Event");
00089 ipmi_cmdlang_out(cmd_info, "Threshold",
00090 ipmi_get_threshold_string(threshold));
00091 ipmi_cmdlang_out(cmd_info, "High/Low",
00092 ipmi_get_value_dir_string(high_low));
00093 ipmi_cmdlang_out(cmd_info, "Direction", ipmi_get_event_dir_string(dir));
00094 switch (value_present) {
00095 case IPMI_BOTH_VALUES_PRESENT:
00096 ipmi_cmdlang_out_double(cmd_info, "Value", value);
00097
00098 case IPMI_RAW_VALUE_PRESENT:
00099 ipmi_cmdlang_out_int(cmd_info, "Raw Value", raw_value);
00100 break;
00101
00102 default:
00103 break;
00104 }
00105 return IPMI_EVENT_NOT_HANDLED;
00106 }
00107
00108 static void
00109 sel_list(ipmi_domain_t *domain, void *cb_data)
00110 {
00111 ipmi_cmd_info_t *cmd_info = cb_data;
00112 char domain_name[IPMI_DOMAIN_NAME_LEN];
00113 int rv;
00114 unsigned int count1, count2;
00115 ipmi_event_t *event, *event2;
00116 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00117 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00118 int argc = ipmi_cmdlang_get_argc(cmd_info);
00119 char **argv = ipmi_cmdlang_get_argv(cmd_info);
00120 int interp = 0;
00121 ipmi_event_handlers_t *h = NULL;
00122
00123 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
00124
00125 if ((argc - curr_arg) >= 1) {
00126 if (strcmp(argv[curr_arg], "interp") == 0)
00127 interp = 1;
00128 else {
00129 cmdlang->errstr = "Invalid parameter";
00130 cmdlang->err = EINVAL;
00131 goto out_err;
00132 }
00133 }
00134
00135 if (interp) {
00136 h = ipmi_event_handlers_alloc();
00137 if (!h) {
00138 cmdlang->errstr = "Out of memory";
00139 cmdlang->err = ENOMEM;
00140 goto out_err;
00141 }
00142 ipmi_event_handlers_set_threshold(h, threshold_event_handler);
00143 ipmi_event_handlers_set_discrete(h, discrete_event_handler);
00144 }
00145
00146 ipmi_cmdlang_out(cmd_info, "Domain", NULL);
00147 ipmi_cmdlang_down(cmd_info);
00148 ipmi_cmdlang_out(cmd_info, "Name", domain_name);
00149 rv = ipmi_domain_sel_count(domain, &count1);
00150 if (rv)
00151 return;
00152 rv = ipmi_domain_sel_entries_used(domain, &count2);
00153 if (rv)
00154 return;
00155 ipmi_cmdlang_out_int(cmd_info, "Entries", count1);
00156 ipmi_cmdlang_out_int(cmd_info, "Slots in use", count2);
00157
00158 event = ipmi_domain_first_event(domain);
00159 while (event) {
00160 ipmi_cmdlang_out(cmd_info, "Event", NULL);
00161 ipmi_cmdlang_down(cmd_info);
00162 ipmi_cmdlang_event_out(event, cmd_info);
00163 if (h)
00164 ipmi_event_call_handler(domain, h, event, cmd_info);
00165 ipmi_cmdlang_up(cmd_info);
00166 event2 = ipmi_domain_next_event(domain, event);
00167 ipmi_event_free(event);
00168 event = event2;
00169 }
00170 ipmi_cmdlang_up(cmd_info);
00171 if (h)
00172 ipmi_event_handlers_free(h);
00173 return;
00174
00175 out_err:
00176 ipmi_domain_get_name(domain, cmdlang->objstr,
00177 cmdlang->objstr_len);
00178 cmdlang->location = "cmd_sel.c(sel_list)";
00179 if (h)
00180 ipmi_event_handlers_free(h);
00181 }
00182
00183 static void
00184 mc_sel_list(ipmi_mc_t *mc, void *cb_data)
00185 {
00186 ipmi_cmd_info_t *cmd_info = cb_data;
00187 char mc_name[IPMI_MC_NAME_LEN];
00188 ipmi_event_t *event, *event2;
00189 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00190 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00191 int argc = ipmi_cmdlang_get_argc(cmd_info);
00192 char **argv = ipmi_cmdlang_get_argv(cmd_info);
00193 int interp = 0;
00194 ipmi_event_handlers_t *h = NULL;
00195 ipmi_domain_t *domain = ipmi_mc_get_domain(mc);
00196
00197 ipmi_mc_get_name(mc, mc_name, sizeof(mc_name));
00198
00199 if ((argc - curr_arg) >= 1) {
00200 if (strcmp(argv[curr_arg], "interp") == 0)
00201 interp = 1;
00202 else {
00203 cmdlang->errstr = "Invalid parameter";
00204 cmdlang->err = EINVAL;
00205 goto out_err;
00206 }
00207 }
00208
00209 if (interp) {
00210 h = ipmi_event_handlers_alloc();
00211 if (!h) {
00212 cmdlang->errstr = "Out of memory";
00213 cmdlang->err = ENOMEM;
00214 goto out_err;
00215 }
00216 ipmi_event_handlers_set_threshold(h, threshold_event_handler);
00217 ipmi_event_handlers_set_discrete(h, discrete_event_handler);
00218 }
00219
00220 ipmi_cmdlang_out(cmd_info, "MC", NULL);
00221 ipmi_cmdlang_down(cmd_info);
00222 ipmi_cmdlang_out(cmd_info, "Name", mc_name);
00223 ipmi_cmdlang_out_int(cmd_info, "Entries", ipmi_mc_sel_count(mc));
00224 ipmi_cmdlang_out_int(cmd_info, "Slots in use",
00225 ipmi_mc_sel_entries_used(mc));
00226
00227 event = ipmi_mc_first_event(mc);
00228 while (event) {
00229 ipmi_cmdlang_out(cmd_info, "Event", NULL);
00230 ipmi_cmdlang_down(cmd_info);
00231 ipmi_cmdlang_event_out(event, cmd_info);
00232 if (h)
00233 ipmi_event_call_handler(domain, h, event, cmd_info);
00234 ipmi_cmdlang_up(cmd_info);
00235 event2 = ipmi_mc_next_event(mc, event);
00236 ipmi_event_free(event);
00237 event = event2;
00238 }
00239 ipmi_cmdlang_up(cmd_info);
00240 if (h)
00241 ipmi_event_handlers_free(h);
00242 return;
00243
00244 out_err:
00245 ipmi_mc_get_name(mc, cmdlang->objstr,
00246 cmdlang->objstr_len);
00247 cmdlang->location = "cmd_sel.c(mc_sel_list)";
00248 if (h)
00249 ipmi_event_handlers_free(h);
00250 }
00251
00252 typedef struct sel_delete_s
00253 {
00254 ipmi_cmd_info_t *cmd_info;
00255 int record;
00256 char mc_name[IPMI_MC_NAME_LEN];
00257 } sel_delete_t;
00258
00259 static void
00260 sel_delete_done(ipmi_domain_t *domain, int err, void *cb_data)
00261 {
00262 sel_delete_t *info = cb_data;
00263 ipmi_cmd_info_t *cmd_info = info->cmd_info;
00264 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00265
00266 ipmi_cmdlang_lock(cmd_info);
00267 if (err) {
00268 cmdlang->errstr = "Error deleting SEL entry";
00269 cmdlang->err = err;
00270 ipmi_domain_get_name(domain, cmdlang->objstr,
00271 cmdlang->objstr_len);
00272 cmdlang->location = "cmd_sel.c(sel_delete_done)";
00273 goto out;
00274 }
00275
00276 ipmi_cmdlang_out(cmd_info, "Event deleted", NULL);
00277 ipmi_cmdlang_down(cmd_info);
00278 ipmi_cmdlang_out(cmd_info, "MC", info->mc_name);
00279 ipmi_cmdlang_out_int(cmd_info, "Record", info->record);
00280 ipmi_cmdlang_up(cmd_info);
00281
00282 out:
00283 ipmi_mem_free(info);
00284 ipmi_cmdlang_unlock(cmd_info);
00285 ipmi_cmdlang_cmd_info_put(cmd_info);
00286 }
00287
00288 static void
00289 sel_delete(ipmi_mc_t *mc, void *cb_data)
00290 {
00291 ipmi_cmd_info_t *cmd_info = cb_data;
00292 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00293 int rv;
00294 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00295 int argc = ipmi_cmdlang_get_argc(cmd_info);
00296 char **argv = ipmi_cmdlang_get_argv(cmd_info);
00297 ipmi_event_t *event = NULL;
00298 int record_id;
00299 sel_delete_t *info;
00300
00301 if ((argc - curr_arg) < 1) {
00302 cmdlang->errstr = "Not enough parameters";
00303 cmdlang->err = EINVAL;
00304 goto out_err;
00305 }
00306
00307 ipmi_cmdlang_get_int(argv[curr_arg], &record_id, cmd_info);
00308 if (cmdlang->err) {
00309 cmdlang->errstr = "Record id invalid";
00310 goto out_err;
00311 }
00312 curr_arg++;
00313
00314 event = ipmi_mc_event_by_recid(mc, record_id);
00315 if (!event) {
00316 cmdlang->errstr = "Event not found";
00317 cmdlang->err = EINVAL;
00318 goto out_err;
00319 }
00320
00321 info = ipmi_mem_alloc(sizeof(*info));
00322 if (!info) {
00323 cmdlang->errstr = "Out of memory";
00324 cmdlang->err = ENOMEM;
00325 goto out_err;
00326 }
00327 info->cmd_info = cmd_info;
00328 info->record = record_id;
00329 ipmi_mc_get_name(mc, info->mc_name, sizeof(info->mc_name));
00330
00331 ipmi_cmdlang_cmd_info_get(cmd_info);
00332 rv = ipmi_event_delete(event, sel_delete_done, info);
00333 if (rv) {
00334 ipmi_cmdlang_cmd_info_put(cmd_info);
00335 cmdlang->errstr = "Error deleting event";
00336 cmdlang->err = rv;
00337 ipmi_mem_free(info);
00338 goto out_err;
00339 }
00340 ipmi_event_free(event);
00341 return;
00342
00343 out_err:
00344 ipmi_mc_get_name(mc, cmdlang->objstr,
00345 cmdlang->objstr_len);
00346 cmdlang->location = "cmd_sel.c(sel_delete)";
00347 if (event)
00348 ipmi_event_free(event);
00349 }
00350
00351 static void
00352 sel_add_done(ipmi_mc_t *mc,
00353 unsigned int record_id,
00354 int err,
00355 void *cb_data)
00356 {
00357 ipmi_cmd_info_t *cmd_info = cb_data;
00358 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00359
00360 ipmi_cmdlang_lock(cmd_info);
00361 if (err) {
00362 cmdlang->errstr = "Error adding SEL entry";
00363 cmdlang->err = err;
00364 ipmi_mc_get_name(mc, cmdlang->objstr,
00365 cmdlang->objstr_len);
00366 cmdlang->location = "cmd_sel.c(sel_add_done)";
00367 } else {
00368 char mc_name[IPMI_MC_NAME_LEN];
00369
00370 ipmi_mc_get_name(mc, mc_name, sizeof(mc_name));
00371 ipmi_cmdlang_out(cmd_info, "MC", NULL);
00372 ipmi_cmdlang_down(cmd_info);
00373 ipmi_cmdlang_out(cmd_info, "Name", mc_name);
00374 ipmi_cmdlang_out_int(cmd_info, "Record ID", record_id);
00375 ipmi_cmdlang_up(cmd_info);
00376 }
00377 ipmi_cmdlang_unlock(cmd_info);
00378 ipmi_cmdlang_cmd_info_put(cmd_info);
00379 }
00380
00381 static void
00382 sel_add(ipmi_mc_t *mc, void *cb_data)
00383 {
00384 ipmi_cmd_info_t *cmd_info = cb_data;
00385 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00386 int rv;
00387 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00388 int argc = ipmi_cmdlang_get_argc(cmd_info);
00389 char **argv = ipmi_cmdlang_get_argv(cmd_info);
00390 ipmi_event_t *event = NULL;
00391 int type;
00392 unsigned char data[13];
00393 int i;
00394
00395 if ((argc - curr_arg) < 14) {
00396 cmdlang->errstr = "Not enough parameters";
00397 cmdlang->err = EINVAL;
00398 goto out_err;
00399 }
00400
00401 ipmi_cmdlang_get_int(argv[curr_arg], &type, cmd_info);
00402 if (cmdlang->err) {
00403 cmdlang->errstr = "Record type invalid";
00404 goto out_err;
00405 }
00406 curr_arg++;
00407
00408 i = 0;
00409 while (curr_arg < argc) {
00410 ipmi_cmdlang_get_uchar(argv[curr_arg], &data[i], cmd_info);
00411 if (cmdlang->err) {
00412 cmdlang->errstr = "data invalid";
00413 goto out_err;
00414 }
00415 curr_arg++;
00416 i++;
00417 }
00418
00419 event = ipmi_event_alloc(ipmi_mc_convert_to_id(mc),
00420 0, type, 0, data, 13);
00421 if (!event) {
00422 cmdlang->errstr = "Out of memory";
00423 cmdlang->err = ENOMEM;
00424 goto out_err;
00425 }
00426
00427 ipmi_cmdlang_cmd_info_get(cmd_info);
00428 rv = ipmi_mc_add_event_to_sel(mc, event, sel_add_done, cmd_info);
00429 if (rv) {
00430 ipmi_cmdlang_cmd_info_put(cmd_info);
00431 cmdlang->errstr = "Error adding event";
00432 cmdlang->err = rv;
00433 goto out_err;
00434 }
00435 ipmi_event_free(event);
00436 return;
00437
00438 out_err:
00439 ipmi_mc_get_name(mc, cmdlang->objstr,
00440 cmdlang->objstr_len);
00441 cmdlang->location = "cmd_sel.c(sel_add)";
00442 if (event)
00443 ipmi_event_free(event);
00444 }
00445
00446 static void
00447 sel_clear(ipmi_domain_t *domain, void *cb_data)
00448 {
00449 ipmi_cmd_info_t *cmd_info = cb_data;
00450 ipmi_event_t *event, *event2;
00451 char domain_name[IPMI_DOMAIN_NAME_LEN];
00452
00453 ipmi_domain_get_name(domain, domain_name, sizeof(domain_name));
00454
00455 event = ipmi_domain_first_event(domain);
00456 while (event) {
00457 event2 = event;
00458 event = ipmi_domain_next_event(domain, event2);
00459 ipmi_domain_del_event(domain, event2, NULL, NULL);
00460 ipmi_event_free(event2);
00461 }
00462 ipmi_cmdlang_out(cmd_info, "SEL Clear done", domain_name);
00463 return;
00464 }
00465
00466 static void
00467 sel_force_clear_done(ipmi_mc_t *mc,
00468 int err,
00469 void *cb_data)
00470 {
00471 ipmi_cmd_info_t *cmd_info = cb_data;
00472 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00473
00474 ipmi_cmdlang_lock(cmd_info);
00475 if (err) {
00476 cmdlang->errstr = "Error forcing SEL clear";
00477 cmdlang->err = err;
00478 ipmi_mc_get_name(mc, cmdlang->objstr,
00479 cmdlang->objstr_len);
00480 cmdlang->location = "cmd_sel.c(sel_force_clear_done)";
00481 } else {
00482 char mc_name[IPMI_MC_NAME_LEN];
00483
00484 ipmi_mc_get_name(mc, mc_name, sizeof(mc_name));
00485 ipmi_cmdlang_out(cmd_info, "MC force clear done", mc_name);
00486 }
00487 ipmi_cmdlang_unlock(cmd_info);
00488 ipmi_cmdlang_cmd_info_put(cmd_info);
00489 }
00490
00491 static void
00492 sel_force_clear(ipmi_mc_t *mc, void *cb_data)
00493 {
00494 ipmi_cmd_info_t *cmd_info = cb_data;
00495 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
00496 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
00497 int argc = ipmi_cmdlang_get_argc(cmd_info);
00498 char **argv = ipmi_cmdlang_get_argv(cmd_info);
00499 ipmi_event_t *event = NULL;
00500 char mc_name[IPMI_MC_NAME_LEN];
00501 int rv;
00502 int force = 0;
00503
00504 if (curr_arg < argc) {
00505 if (strcmp(argv[curr_arg], "nocheck") == 0)
00506 force = 1;
00507 else {
00508 cmdlang->err = EINVAL;
00509 cmdlang->errstr = "Invalid parameter";
00510 goto out_err;
00511 }
00512 curr_arg++;
00513 }
00514
00515 ipmi_mc_get_name(mc, mc_name, sizeof(mc_name));
00516
00517 if (force)
00518 event = NULL;
00519 else {
00520 event = ipmi_mc_last_event(mc);
00521 if (!event) {
00522 ipmi_cmdlang_out(cmd_info,
00523 "SEL force clear done, SEL already empty",
00524 mc_name);
00525 return;
00526 }
00527 }
00528
00529 ipmi_cmdlang_cmd_info_get(cmd_info);
00530 rv = ipmi_mc_sel_clear(mc, event, sel_force_clear_done, cmd_info);
00531 if (rv) {
00532 ipmi_cmdlang_cmd_info_put(cmd_info);
00533 cmdlang->errstr = "Error forcing clear";
00534 cmdlang->err = rv;
00535 goto out_err;
00536 }
00537 if (event)
00538 ipmi_event_free(event);
00539 return;
00540
00541 out_err:
00542 ipmi_mc_get_name(mc, cmdlang->objstr,
00543 cmdlang->objstr_len);
00544 cmdlang->location = "cmd_sel.c(mc_force_clear)";
00545 if (event)
00546 ipmi_event_free(event);
00547 }
00548
00549 static ipmi_cmdlang_cmd_t *sel_cmds;
00550
00551 static ipmi_cmdlang_init_t cmds_sel[] =
00552 {
00553 { "sel", NULL,
00554 "- Commands dealing with the SEL",
00555 NULL, NULL, &sel_cmds},
00556 { "list", &sel_cmds,
00557 "<domain> [interp] - List all the events in the domain. If interp is"
00558 " specified, then interpret the event data if possible",
00559 ipmi_cmdlang_domain_handler, sel_list, NULL },
00560 { "mc_list", &sel_cmds,
00561 "<domain> - List all the events in the given MC's SEL",
00562 ipmi_cmdlang_mc_handler, mc_sel_list, NULL },
00563 { "delete", &sel_cmds,
00564 "<mc> <record id> - Delete the given event.",
00565 ipmi_cmdlang_mc_handler, sel_delete, NULL },
00566 { "add", &sel_cmds,
00567 "<mc> <record type> <13 data bytes> - add the given event to the"
00568 " MC's sel.",
00569 ipmi_cmdlang_mc_handler, sel_add, NULL },
00570 { "clear", &sel_cmds,
00571 "<domain> - Delete all events in the domain.",
00572 ipmi_cmdlang_domain_handler, sel_clear, NULL },
00573 { "force_clear", &sel_cmds,
00574 "<mc> [nocheck] - Force a clear of the SEL in the MC. nocheck means"
00575 " don't check that any events were added during the clear, just force a"
00576 " clear.",
00577 ipmi_cmdlang_mc_handler, sel_force_clear, NULL },
00578 };
00579 #define CMDS_SEL_LEN (sizeof(cmds_sel)/sizeof(ipmi_cmdlang_init_t))
00580
00581 int
00582 ipmi_cmdlang_sel_init(os_handler_t *os_hnd)
00583 {
00584 return ipmi_cmdlang_reg_table(cmds_sel, CMDS_SEL_LEN);
00585 }