ipmi: Make IPMI panic strings always available
They were set by config items, but people complained that they were never turned on. So have them always available and enabled by a module parameter. Signed-off-by: Corey Minyard <cminyard@mvista.com>
This commit is contained in:
parent
b72fce52a1
commit
1c9f98d1bf
@ -81,7 +81,9 @@ If you want the driver to put an event into the event log on a panic,
|
||||
enable the 'Generate a panic event to all BMCs on a panic' option. If
|
||||
you want the whole panic string put into the event log using OEM
|
||||
events, enable the 'Generate OEM events containing the panic string'
|
||||
option.
|
||||
option. You can also enable these dynamically by setting the module
|
||||
parameter named "panic_op" in the ipmi_msghandler module to "event"
|
||||
or "string". Setting that parameter to "none" disables this function.
|
||||
|
||||
Basic Design
|
||||
------------
|
||||
|
@ -25,21 +25,28 @@ if IPMI_HANDLER
|
||||
config IPMI_PANIC_EVENT
|
||||
bool 'Generate a panic event to all BMCs on a panic'
|
||||
help
|
||||
When a panic occurs, this will cause the IPMI message handler to
|
||||
generate an IPMI event describing the panic to each interface
|
||||
registered with the message handler.
|
||||
When a panic occurs, this will cause the IPMI message handler to,
|
||||
by default, generate an IPMI event describing the panic to each
|
||||
interface registered with the message handler. This is always
|
||||
available, the module parameter for ipmi_msghandler named
|
||||
panic_op can be set to "event" to chose this value, this config
|
||||
simply causes the default value to be set to "event".
|
||||
|
||||
config IPMI_PANIC_STRING
|
||||
bool 'Generate OEM events containing the panic string'
|
||||
depends on IPMI_PANIC_EVENT
|
||||
help
|
||||
When a panic occurs, this will cause the IPMI message handler to
|
||||
generate IPMI OEM type f0 events holding the IPMB address of the
|
||||
panic generator (byte 4 of the event), a sequence number for the
|
||||
string (byte 5 of the event) and part of the string (the rest of the
|
||||
event). Bytes 1, 2, and 3 are the normal usage for an OEM event.
|
||||
You can fetch these events and use the sequence numbers to piece the
|
||||
string together.
|
||||
When a panic occurs, this will cause the IPMI message handler to,
|
||||
by default, generate IPMI OEM type f0 events holding the IPMB
|
||||
address of the panic generator (byte 4 of the event), a sequence
|
||||
number for the string (byte 5 of the event) and part of the
|
||||
string (the rest of the event). Bytes 1, 2, and 3 are the normal
|
||||
usage for an OEM event. You can fetch these events and use the
|
||||
sequence numbers to piece the string together. This config
|
||||
parameter sets the default value to generate these events,
|
||||
the module parameter for ipmi_msghandler named panic_op can
|
||||
be set to "string" to chose this value, this config simply
|
||||
causes the default value to be set to "string".
|
||||
|
||||
config IPMI_DEVICE_INTERFACE
|
||||
tristate 'Device interface for IPMI'
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/moduleparam.h>
|
||||
|
||||
#define PFX "IPMI message handler: "
|
||||
|
||||
@ -61,6 +62,74 @@ static int handle_one_recv_msg(ipmi_smi_t intf,
|
||||
|
||||
static int initialized;
|
||||
|
||||
enum ipmi_panic_event_op {
|
||||
IPMI_SEND_PANIC_EVENT_NONE,
|
||||
IPMI_SEND_PANIC_EVENT,
|
||||
IPMI_SEND_PANIC_EVENT_STRING
|
||||
};
|
||||
#ifdef CONFIG_IPMI_PANIC_STRING
|
||||
#define IPMI_PANIC_DEFAULT IPMI_SEND_PANIC_EVENT_STRING
|
||||
#elif defined(CONFIG_IPMI_PANIC_EVENT)
|
||||
#define IPMI_PANIC_DEFAULT IPMI_SEND_PANIC_EVENT
|
||||
#else
|
||||
#define IPMI_PANIC_DEFAULT IPMI_SEND_PANIC_EVENT_NONE
|
||||
#endif
|
||||
static enum ipmi_panic_event_op ipmi_send_panic_event = IPMI_PANIC_DEFAULT;
|
||||
|
||||
static int panic_op_write_handler(const char *val,
|
||||
const struct kernel_param *kp)
|
||||
{
|
||||
char valcp[16];
|
||||
char *s;
|
||||
|
||||
strncpy(valcp, val, 16);
|
||||
valcp[15] = '\0';
|
||||
|
||||
s = strstrip(valcp);
|
||||
|
||||
if (strcmp(s, "none") == 0)
|
||||
ipmi_send_panic_event = IPMI_SEND_PANIC_EVENT_NONE;
|
||||
else if (strcmp(s, "event") == 0)
|
||||
ipmi_send_panic_event = IPMI_SEND_PANIC_EVENT;
|
||||
else if (strcmp(s, "string") == 0)
|
||||
ipmi_send_panic_event = IPMI_SEND_PANIC_EVENT_STRING;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int panic_op_read_handler(char *buffer, const struct kernel_param *kp)
|
||||
{
|
||||
switch (ipmi_send_panic_event) {
|
||||
case IPMI_SEND_PANIC_EVENT_NONE:
|
||||
strcpy(buffer, "none");
|
||||
break;
|
||||
|
||||
case IPMI_SEND_PANIC_EVENT:
|
||||
strcpy(buffer, "event");
|
||||
break;
|
||||
|
||||
case IPMI_SEND_PANIC_EVENT_STRING:
|
||||
strcpy(buffer, "string");
|
||||
break;
|
||||
|
||||
default:
|
||||
strcpy(buffer, "???");
|
||||
break;
|
||||
}
|
||||
|
||||
return strlen(buffer);
|
||||
}
|
||||
|
||||
static const struct kernel_param_ops panic_op_ops = {
|
||||
.set = panic_op_write_handler,
|
||||
.get = panic_op_read_handler
|
||||
};
|
||||
module_param_cb(panic_op, &panic_op_ops, NULL, 0600);
|
||||
MODULE_PARM_DESC(panic_op, "Sets if the IPMI driver will attempt to store panic information in the event log in the event of a panic. Set to 'none' for no, 'event' for a single event, or 'string' for a generic event and the panic string in IPMI OEM events.");
|
||||
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static struct proc_dir_entry *proc_ipmi_root;
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
@ -4271,8 +4340,6 @@ void ipmi_free_recv_msg(struct ipmi_recv_msg *msg)
|
||||
}
|
||||
EXPORT_SYMBOL(ipmi_free_recv_msg);
|
||||
|
||||
#ifdef CONFIG_IPMI_PANIC_EVENT
|
||||
|
||||
static atomic_t panic_done_count = ATOMIC_INIT(0);
|
||||
|
||||
static void dummy_smi_done_handler(struct ipmi_smi_msg *msg)
|
||||
@ -4320,7 +4387,6 @@ static void ipmi_panic_request_and_wait(ipmi_smi_t intf,
|
||||
ipmi_poll(intf);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IPMI_PANIC_STRING
|
||||
static void event_receiver_fetcher(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
|
||||
{
|
||||
if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE)
|
||||
@ -4347,7 +4413,6 @@ static void device_id_fetcher(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
|
||||
intf->local_event_generator = (msg->msg.data[6] >> 5) & 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void send_panic_events(char *str)
|
||||
{
|
||||
@ -4357,6 +4422,9 @@ static void send_panic_events(char *str)
|
||||
struct ipmi_system_interface_addr *si;
|
||||
struct ipmi_addr addr;
|
||||
|
||||
if (ipmi_send_panic_event == IPMI_SEND_PANIC_EVENT_NONE)
|
||||
return;
|
||||
|
||||
si = (struct ipmi_system_interface_addr *) &addr;
|
||||
si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
|
||||
si->channel = IPMI_BMC_CHANNEL;
|
||||
@ -4385,20 +4453,19 @@ static void send_panic_events(char *str)
|
||||
|
||||
/* For every registered interface, send the event. */
|
||||
list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
|
||||
if (!intf->handlers)
|
||||
/* Interface is not ready. */
|
||||
if (!intf->handlers || !intf->handlers->poll)
|
||||
/* Interface is not ready or can't run at panic time. */
|
||||
continue;
|
||||
|
||||
/* Send the event announcing the panic. */
|
||||
ipmi_panic_request_and_wait(intf, &addr, &msg);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IPMI_PANIC_STRING
|
||||
/*
|
||||
* On every interface, dump a bunch of OEM event holding the
|
||||
* string.
|
||||
*/
|
||||
if (!str)
|
||||
if (ipmi_send_panic_event != IPMI_SEND_PANIC_EVENT_STRING || !str)
|
||||
return;
|
||||
|
||||
/* For every registered interface, send the event. */
|
||||
@ -4507,9 +4574,7 @@ static void send_panic_events(char *str)
|
||||
ipmi_panic_request_and_wait(intf, &addr, &msg);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_IPMI_PANIC_STRING */
|
||||
}
|
||||
#endif /* CONFIG_IPMI_PANIC_EVENT */
|
||||
|
||||
static int has_panicked;
|
||||
|
||||
@ -4547,12 +4612,12 @@ static int panic_event(struct notifier_block *this,
|
||||
spin_unlock(&intf->waiting_rcv_msgs_lock);
|
||||
|
||||
intf->run_to_completion = 1;
|
||||
intf->handlers->set_run_to_completion(intf->send_info, 1);
|
||||
if (intf->handlers->set_run_to_completion)
|
||||
intf->handlers->set_run_to_completion(intf->send_info,
|
||||
1);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IPMI_PANIC_EVENT
|
||||
send_panic_events(ptr);
|
||||
#endif
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user