SEL is often rather limited in size.  This looks like it could
dump unlimited amount of console messages into the SEL if you
have a verbose OOPS.

I don't have a very good suggestion to help with this.  Maybe
some sort of inline filtering?

Anticipating a reaction of "we'll deal with that when we see
it happen" -- I think it's an easily anticipated problem and
should be dealt with while the code is fresh.

>Bela<

> -----Original Message-----
> From: Hiroshi Shimamoto [mailto:[EMAIL PROTECTED] 
> Sent: Wednesday, December 10, 2008 9:10 AM
> To: Corey Minyard
> Cc: [email protected]
> Subject: [Openipmi-developer] [RFC] ipmi: introduce oops_console
> 
> From: Hiroshi Shimamoto <[EMAIL PROTECTED]>
> 
> Console messages on oops or panic are very important to 
> investigate problem.
> Logging oops or panic messages to SEL is useful because SEL is a non
> volatile memory.
> 
> Implement a console driver to log messages to SEL when 
> oops_in_progress is
> not zero. The message is logging as OEM event without timestamp.
> 
> Enable config IPMI_OOPS_CONSOLE and add console=ttyIPMI to 
> kernel command
> line to log panic or oops messages to IPMI SEL.
> 
> Signed-off-by: Hiroshi Shimamoto <[EMAIL PROTECTED]>
> ---
>  drivers/char/ipmi/Kconfig             |    5 +
>  drivers/char/ipmi/Makefile            |    1 +
>  drivers/char/ipmi/ipmi_oops_console.c |  219 
> +++++++++++++++++++++++++++++++++
>  3 files changed, 225 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/char/ipmi/ipmi_oops_console.c
> 
> diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
> index 0baa8fa..ce55ea7 100644
> --- a/drivers/char/ipmi/Kconfig
> +++ b/drivers/char/ipmi/Kconfig
> @@ -61,4 +61,9 @@ config IPMI_POWEROFF
>           This enables a function to power off the system with IPMI if
>        the IPMI management controller is capable of this.
>  
> +config IPMI_OOPS_CONSOLE
> +       tristate 'IPMI oops console'
> +       help
> +         This enables the IPMI oops console.
> +
>  endif # IPMI_HANDLER
> diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile
> index eb8a1a8..cbbac18 100644
> --- a/drivers/char/ipmi/Makefile
> +++ b/drivers/char/ipmi/Makefile
> @@ -9,3 +9,4 @@ obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o
>  obj-$(CONFIG_IPMI_SI) += ipmi_si.o
>  obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
>  obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o
> +obj-$(CONFIG_IPMI_OOPS_CONSOLE) += ipmi_oops_console.o
> diff --git a/drivers/char/ipmi/ipmi_oops_console.c 
> b/drivers/char/ipmi/ipmi_oops_console.c
> new file mode 100644
> index 0000000..249bbb0
> --- /dev/null
> +++ b/drivers/char/ipmi/ipmi_oops_console.c
> @@ -0,0 +1,219 @@
> +/*
> + * ipmi_oops_console.c
> + *
> + * IPMI Oops Console
> + * Logging console message to SEL on oops
> + *
> + * Author: Hiroshi Shimamoto <[EMAIL PROTECTED]>
> + *
> + * Copyright (C) 2008 NEC Corporation
> + *
> + *  This program is free software; you can redistribute it 
> and/or modify it
> + *  under the terms of the GNU General Public License as 
> published by the
> + *  Free Software Foundation; either version 2 of the 
> License, or (at your
> + *  option) any later version.
> + *
> + *
> + *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
> + *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
> WARRANTIES OF
> + *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
> DISCLAIMED.
> + *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
> + *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
> (INCLUDING,
> + *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
> SERVICES; LOSS
> + *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
> HOWEVER CAUSED AND
> + *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
> LIABILITY, OR
> + *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 
> WAY OUT OF THE
> + *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
> OF SUCH DAMAGE.
> + *
> + *  You should have received a copy of the GNU General 
> Public License along
> + *  with this program; if not, write to the Free Software 
> Foundation, Inc.,
> + *  675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/ipmi.h>
> +#include <linux/ipmi_smi.h>
> +#include <linux/console.h>
> +#include <asm/atomic.h>
> +
> +#define PFX "IPMI oops_console: "
> +
> +static ipmi_user_t oops_user;
> +static int oops_intf = -1;
> +
> +static atomic_t oops_counter;
> +
> +#define OOPS_MSGSIZE (13U)
> +
> +static char oops_msg[OOPS_MSGSIZE];
> +static int msg_len;
> +
> +static void oops_smi_msg_done(struct ipmi_smi_msg *msg)
> +{
> +     atomic_dec(&oops_counter);
> +}
> +static struct ipmi_smi_msg oops_smi_msg = {
> +     .done = oops_smi_msg_done
> +};
> +
> +static void oops_recv_msg_done(struct ipmi_recv_msg *msg)
> +{
> +     atomic_dec(&oops_counter);
> +}
> +static struct ipmi_recv_msg oops_recv_msg = {
> +     .done = oops_recv_msg_done
> +};
> +
> +static void ipmi_oops_console_sync(void)
> +{
> +     unsigned int len = msg_len;
> +     struct ipmi_system_interface_addr si;
> +     struct kernel_ipmi_msg msg;
> +     unsigned char data[16];
> +     unsigned char my_addr;
> +
> +     if (!oops_user || len == 0)
> +             return;
> +
> +     msg_len = 0;
> +
> +     si.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
> +     si.channel = IPMI_BMC_CHANNEL;
> +     si.lun = 0;
> +
> +     msg.netfn = IPMI_NETFN_STORAGE_REQUEST;
> +     msg.cmd = IPMI_ADD_SEL_ENTRY_CMD;
> +     msg.data = data;
> +     msg.data_len = 16;
> +
> +     memset(data, 0, sizeof(data));
> +     data[2] = 0xf1; /* OEM event without timestamp */
> +     memcpy(data + 3, oops_msg, len);
> +
> +     preempt_disable();
> +
> +     if (ipmi_get_my_address(oops_user, 0, &my_addr))
> +             goto out;
> +
> +     atomic_set(&oops_counter, 2);
> +     if (ipmi_request_supply_msgs(oops_user, (struct ipmi_addr *)&si,
> +                                  0, &msg, NULL, &oops_smi_msg,
> +                                  &oops_recv_msg, 1) < 0)
> +             goto out;
> +     while (atomic_read(&oops_counter) > 0) {
> +             ipmi_poll_interface(oops_user);
> +             cpu_relax();
> +     }
> +out:
> +     preempt_enable();
> +}
> +
> +static void
> +ipmi_oops_console_write(struct console *con, const char *s, 
> unsigned int count)
> +{
> +     unsigned int size;
> +
> +     if (likely(!oops_in_progress)) {
> +             ipmi_oops_console_sync();
> +             return;
> +     }
> +
> +     if (unlikely(!oops_user))
> +             return;
> +
> +     while (count > 0) {
> +             size = min(OOPS_MSGSIZE - msg_len, count);
> +             memcpy(oops_msg + msg_len, s, size);
> +             msg_len += size;
> +             s += size;
> +             if (msg_len >= OOPS_MSGSIZE)
> +                     ipmi_oops_console_sync();
> +
> +             count -= size;
> +     }
> +}
> +
> +static struct console oops_console = {
> +     .name   = "ttyIPMI",
> +     .write  = ipmi_oops_console_write,
> +     .unblank = ipmi_oops_console_sync,
> +     .index  = -1,
> +};
> +
> +static void ipmi_oops_recv(struct ipmi_recv_msg *msg, void *data)
> +{
> +     ipmi_free_recv_msg(msg);
> +}
> +
> +static struct ipmi_user_hndl ipmi_handler = {
> +     .ipmi_recv_hndl = ipmi_oops_recv,
> +};
> +
> +static void ipmi_register_oops_console(int intf)
> +{
> +     int ret;
> +
> +     ret = ipmi_create_user(intf, &ipmi_handler, NULL, &oops_user);
> +     if (ret < 0) {
> +             printk(KERN_ERR PFX "unable to create user\n");
> +             return;
> +     }
> +
> +     oops_intf = intf;
> +
> +     register_console(&oops_console);
> +
> +     printk(KERN_INFO PFX "ready\n");
> +}
> +
> +static void ipmi_unregister_oops_console(int intf)
> +{
> +     unregister_console(&oops_console);
> +
> +     ipmi_destroy_user(oops_user);
> +     oops_user = NULL;
> +     oops_intf = -1;
> +}
> +
> +static void ipmi_new_smi(int if_num, struct device *dev)
> +{
> +     ipmi_register_oops_console(if_num);
> +}
> +
> +static void ipmi_smi_gone(int if_num)
> +{
> +     ipmi_unregister_oops_console(if_num);
> +}
> +
> +static struct ipmi_smi_watcher smi_watcher = {
> +     .owner          = THIS_MODULE,
> +     .new_smi        = ipmi_new_smi,
> +     .smi_gone       = ipmi_smi_gone,
> +};
> +
> +static int __init ipmi_oops_console_init(void)
> +{
> +     int ret;
> +
> +     ret = ipmi_smi_watcher_register(&smi_watcher);
> +     if (ret) {
> +             printk(KERN_ERR PFX "unable to register smi watcher\n");
> +             return ret;
> +     }
> +
> +     printk(KERN_INFO PFX "driver initialized\n");
> +
> +     return ret;
> +}
> +module_init(ipmi_oops_console_init);
> +
> +static void __exit ipmi_oops_console_exit(void)
> +{
> +     if (oops_intf >= 0)
> +             ipmi_unregister_oops_console(oops_intf);
> +}
> +module_exit(ipmi_oops_console_exit);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Hiroshi Shimamoto <[EMAIL PROTECTED]>");
> +MODULE_DESCRIPTION("oops console handler based upon the IPMI 
> interface.");
> -- 
> 1.6.0.4
> 
> 
> --------------------------------------------------------------
> ----------------
> SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las 
> Vegas, Nevada.
> The future of the web can't happen without you.  Join us at 
> MIX09 to help
> pave the way to the Next Web now. Learn more and register at
> http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009
> .visitmix.com/
> _______________________________________________
> Openipmi-developer mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/openipmi-developer
> 
------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you.  Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
_______________________________________________
Openipmi-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openipmi-developer

Reply via email to