|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
310c69 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
310c69 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
310c69 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
310c69 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
310c69 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
310c69 |
* GNU General Public License for more details.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
310c69 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
310c69 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
310c69 |
* 02110-1301, USA.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* $Id: //eng/uds-releases/jasper/kernelLinux/uds/loggerLinuxKernel.c#2 $
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include <linux/delay.h>
|
|
Packit Service |
310c69 |
#include <linux/hardirq.h>
|
|
Packit Service |
310c69 |
#include <linux/module.h>
|
|
Packit Service |
310c69 |
#include <linux/sched.h>
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
#include "logger.h"
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static const char *priorityToLogLevel(int priority)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
switch (priority) {
|
|
Packit Service |
310c69 |
case LOG_EMERG:
|
|
Packit Service |
310c69 |
case LOG_ALERT:
|
|
Packit Service |
310c69 |
case LOG_CRIT:
|
|
Packit Service |
310c69 |
return KERN_CRIT;
|
|
Packit Service |
310c69 |
case LOG_ERR:
|
|
Packit Service |
310c69 |
return KERN_ERR;
|
|
Packit Service |
310c69 |
case LOG_WARNING:
|
|
Packit Service |
310c69 |
return KERN_WARNING;
|
|
Packit Service |
310c69 |
case LOG_NOTICE:
|
|
Packit Service |
310c69 |
return KERN_NOTICE;
|
|
Packit Service |
310c69 |
case LOG_INFO:
|
|
Packit Service |
310c69 |
return KERN_INFO;
|
|
Packit Service |
310c69 |
case LOG_DEBUG:
|
|
Packit Service |
310c69 |
return KERN_DEBUG;
|
|
Packit Service |
310c69 |
default:
|
|
Packit Service |
310c69 |
return "";
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
static const char *getCurrentInterruptType(void)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (in_nmi()) {
|
|
Packit Service |
310c69 |
return "NMI";
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
if (in_irq()) {
|
|
Packit Service |
310c69 |
return "HI";
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
if (in_softirq()) {
|
|
Packit Service |
310c69 |
return "SI";
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
return "INTR";
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
void logMessagePack(int priority,
|
|
Packit Service |
310c69 |
const char *prefix,
|
|
Packit Service |
310c69 |
const char *fmt1,
|
|
Packit Service |
310c69 |
va_list args1,
|
|
Packit Service |
310c69 |
const char *fmt2,
|
|
Packit Service |
310c69 |
va_list args2)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (priority > getLogLevel()) {
|
|
Packit Service |
310c69 |
return;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* The kernel's printk has some magic for indirection to a secondary
|
|
Packit Service |
310c69 |
* va_list. It wants us to supply a pointer to the va_list.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* However, va_list varies across platforms and can be an array
|
|
Packit Service |
310c69 |
* type, which makes passing it around as an argument kind of
|
|
Packit Service |
310c69 |
* tricky, due to the automatic conversion to a pointer. This makes
|
|
Packit Service |
310c69 |
* taking the address of the argument a dicey thing; if we use "&a"
|
|
Packit Service |
310c69 |
* it works fine for non-array types, but for array types we get the
|
|
Packit Service |
310c69 |
* address of a pointer. Functions like va_copy and sprintf don't
|
|
Packit Service |
310c69 |
* care as they get "va_list" values passed and are written to do
|
|
Packit Service |
310c69 |
* the right thing, but printk explicitly wants the address of the
|
|
Packit Service |
310c69 |
* va_list.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* So, we copy the va_list values to ensure that "&" consistently
|
|
Packit Service |
310c69 |
* works the way we want.
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
va_list args1Copy;
|
|
Packit Service |
310c69 |
va_copy(args1Copy, args1);
|
|
Packit Service |
310c69 |
va_list args2Copy;
|
|
Packit Service |
310c69 |
va_copy(args2Copy, args2);
|
|
Packit Service |
310c69 |
struct va_format vaf1 = {
|
|
Packit Service |
310c69 |
.fmt = (fmt1 != NULL) ? fmt1 : "",
|
|
Packit Service |
310c69 |
.va = &args1Copy,
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
struct va_format vaf2 = {
|
|
Packit Service |
310c69 |
.fmt = (fmt2 != NULL) ? fmt2 : "",
|
|
Packit Service |
310c69 |
.va = &args2Copy,
|
|
Packit Service |
310c69 |
};
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
if (prefix == NULL) {
|
|
Packit Service |
310c69 |
prefix = "";
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/*
|
|
Packit Service |
310c69 |
* Context info formats:
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* interrupt: uds[NMI]: blah
|
|
Packit Service |
310c69 |
* process: uds: myprog: blah
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* Fields: module name, interrupt level or process name.
|
|
Packit Service |
310c69 |
*
|
|
Packit Service |
310c69 |
* XXX need the equivalent of VDO's deviceInstance here
|
|
Packit Service |
310c69 |
*/
|
|
Packit Service |
310c69 |
if (in_interrupt()) {
|
|
Packit Service |
310c69 |
printk("%s%s[%s]: %s%pV%pV\n", priorityToLogLevel(priority),
|
|
Packit Service |
310c69 |
THIS_MODULE->name, getCurrentInterruptType(), prefix, &vaf1, &vaf2);
|
|
Packit Service |
310c69 |
} else {
|
|
Packit Service |
310c69 |
printk("%s%s: %s: %s%pV%pV\n", priorityToLogLevel(priority),
|
|
Packit Service |
310c69 |
THIS_MODULE->name, current->comm, prefix, &vaf1, &vaf2);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
va_end(args1Copy);
|
|
Packit Service |
310c69 |
va_end(args2Copy);
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
void logBacktrace(int priority)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
if (priority > getLogLevel()) {
|
|
Packit Service |
310c69 |
return;
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
logMessage(priority, "[backtrace]");
|
|
Packit Service |
310c69 |
dump_stack();
|
|
Packit Service |
310c69 |
}
|
|
Packit Service |
310c69 |
|
|
Packit Service |
310c69 |
/**********************************************************************/
|
|
Packit Service |
310c69 |
void pauseForLogger(void)
|
|
Packit Service |
310c69 |
{
|
|
Packit Service |
310c69 |
// Hopefully, a few milliseconds of sleep will be large enough
|
|
Packit Service |
310c69 |
// for the kernel log buffer to be flushed.
|
|
Packit Service |
310c69 |
msleep(4);
|
|
Packit Service |
310c69 |
}
|