Included upstream patches for 1.3.1 to 1.3.3 and modified debian/rules

to support better debugging by including a patch to the modules package.
This commit is contained in:
Joey Schulze 1997-06-13 07:42:20 +00:00
parent 8947ba8d2f
commit c05f39c39c
12 changed files with 584 additions and 147 deletions

View File

@ -1,6 +1,6 @@
On behalf of Martin Schulze, the beta-testers and other members of the
Linux INTERNET community who have helped shape and debug this package
I am pleased to announce version 1.3 of the sysklogd package.
On behalf of the beta-testers and other members of the Linux INTERNET
community who have helped shape and debug this package I am pleased to
announce version 1.3-pl3 of the sysklogd package.
This package implements two system log daemons. The syslogd daemon is
an enhanced version of the standard Berkeley utility program. This
@ -27,6 +27,9 @@ here:
translations. This requires that a valid kernel symbol map be
found at execution.
* klogd also supports debugging of protection faults which occur
in kernel loadable modules.
* syslogd has better handling of remote logging capabilities.
* both klogd and syslogd can be controlled through commandline

View File

@ -17,6 +17,9 @@ klogd.h: Global definitions required for the kernel log daemon.
ksym.c: Source module for the kernel log daemon which implements
kernel numeric address to symbol translations.
ksym_mod.c: Source module which contains functions which allow ksym.c
to resolve symbols found in loadable kernel modules.
syslogd.c: Source code for the system log daemon.
syslog.c: A slightly modified version of the syslog.c file found in
@ -46,3 +49,14 @@ klogd.8: Man page documenting the kernel log daemon.
kernel.patch: A source code patch which modifies the linux kernel to
delimit addresses for symbolic translation by klogd.
oops.c: C source for a loadable kernel module which can be used
to generate a kernel protection fault. This is used to
test the address resolution capabilities of klogd.
oops_test.c: A small driver program used in conjunction with the oops
module to generate a kernel protection fault.
modules.patch: A patch to the modules-2.0.0 package which provides for
automatic signalling of klogd whenever the kernel module
state changes.

View File

@ -3,11 +3,10 @@
CC= gcc
#CFLAGS= -g -DSYSV -Wall
#LDFLAGS= -g
CFLAGS= -O4 -DSYSV -fomit-frame-pointer -Wall
CFLAGS= -O3 -DSYSV -fomit-frame-pointer -Wall -fno-strength-reduce
LDFLAGS= -s
# Look where your install program is
#
# Look where your install program is.
INSTALL = /usr/bin/install
BINDIR = /usr/sbin
MANDIR = /usr/man
@ -17,6 +16,13 @@ MANDIR = /usr/man
# to try uncommenting the following define.
# LIBS = /usr/lib/libresolv.a
# A patch was forwarded which provided support for sysklogd under
# the ALPHA. This patch included a reference to a library which may be
# specific to the ALPHA. If you are attempting to build this package under
# an ALPHA and linking fails with unresolved references please try
# uncommenting the following define.
# LIBS = ${LIBS} -linux
# Define the following to impart start-up delay in klogd. This is
# useful if klogd is started simultaneously or in close-proximity to syslogd.
# KLOGD_START_DELAY = -DKLOGD_DELAY=5
@ -46,15 +52,18 @@ KLOGD_FLAGS = ${FSSTND} ${KLOGD_START_DELAY} -DDEBRELEASE=\"$(revision)\"
.c.o:
${CC} ${CFLAGS} -c $*.c
all: syslogd klogd syslog_tst
all: syslogd klogd
test: syslog_tst ksym oops_test
install: install_man install_exec
syslogd: syslogd.o pidfile.o
${CC} ${LDFLAGS} -o syslogd syslogd.o pidfile.o ${LIBS}
klogd: klogd.o syslog.o pidfile.o ksym.o
${CC} ${LDFLAGS} -o klogd klogd.o syslog.o pidfile.o ksym.o
klogd: klogd.o syslog.o pidfile.o ksym.o ksym_mod.o
${CC} ${LDFLAGS} -o klogd klogd.o syslog.o pidfile.o ksym.o \
ksym_mod.o ${LIBS}
syslog_tst: syslog_tst.o
${CC} ${LDFLAGS} -o syslog_tst syslog_tst.o
@ -71,18 +80,33 @@ klogd.o: klogd.c klogd.h version.h
ksym.o: ksym.c klogd.h
${CC} ${CFLAGS} ${KLOGD_FLAGS} -c ksym.c
ksym_mod.o: ksym_mod.c klogd.h
${CC} ${CFLAGS} ${KLOGD_FLAGS} -c ksym_mod.c
syslog_tst.o: syslog_tst.c
${CC} ${CFLAGS} -c syslog_tst.c
oops_test: oops.o
${CC} ${CFLAGS} -o oops_test oops_test.c
oops.o: oops.c
${CC} ${CFLAGS} -D__KERNEL__ -DMODULE -c oops.c
ksym: ksym_test.o ksym_mod.o
${CC} ${LDFLAGS} -o ksym ksym_test.o ksym_mod.o
ksym_test.o: ksym.c
${CC} ${CFLAGS} -DTEST -o ksym_test.o -c ksym.c
clean:
rm -f *.o *.log *~ *.orig;
rm -f *.o *.log *~ *.orig
clobber: clean
rm -f syslogd klogd syslog_tst TAGS;
rm -f syslogd klogd ksym syslog_tst oops_test TAGS
install_exec: syslogd klogd
${INSTALL} -m 500 -s syslogd ${BINDIR}/syslogd;
${INSTALL} -m 500 -s klogd ${BINDIR}/klogd;
${INSTALL} -m 500 -s syslogd ${BINDIR}/syslogd
${INSTALL} -m 500 -s klogd ${BINDIR}/klogd
install_man:
${INSTALL} -o ${MAN_OWNER} -g ${MAN_OWNER} -m 644 sysklogd.8 ${MANDIR}/man8/sysklogd.8

69
NEWS
View File

@ -1,3 +1,72 @@
Version 1.3 Patch Level 3
General. ------------------------------------------------------------------
Update to documentation including klogd.8 manpage to reflect new features.
Included patch for modules-2.0.0 package to provide support for signalling
klogd of changes in kernel module status.
klogd ---------------------------------------------------------------------
Provided support for signalling klogd to reload static and kernel module
symbol information via SIGUSR1 and SIGUSR2.
Implemented -p switch to cause a reload of kernel module symbol information
whenever a protection fault is detected.
Informative message is printed whenever klogd state change occurs.
Added -i and -I switches to signal the currently executing klogd daemon
to reload symbold information.
Version 1.3 Patch Level 2
General. ------------------------------------------------------------------
Added oops.c and oops_test.c. Oops.c implements a kernel loadable module
which will generate a general protection fault. The oops_test.c program
generates a test program for exercising the loadable module.
syslogd ------------------------------------------------------------------
Fixed bug resulting in file descriptors being orphaned when syslogd was
initialized via signal handler.
klogd ---------------------------------------------------------------------
Bug fix to prevent errors when reading symbol tables with 64 bit addresses.
Added support for debugging of protection faults occuring in kernel
loadable modules.
Version 1.3 Patch Level 1
General. ------------------------------------------------------------------
Cleanups in the Makefile.
Patches to support compilation in the ALPHA environment. I have not
been able to test these personally so if anyone has any feedback I
would be interested in hearing from the Linux ALPHA community.
Spelling and grammar corrections in the man pages.
syslogd ------------------------------------------------------------------
Patch to fix parsing of hostnames in syslogd.c.
The return value of gethostbyname is now properly checked. This should
fix the problems with core dumps when name resolution failed.
Bounds error fixed when setting the file descriptors for UNIX domain
sockets.
klogd ---------------------------------------------------------------------
Error checking and reporting enhanced. I have a couple of reports
that klogd is experiencing errors when reading the /proc filesystem.
Any additional information would be appreciated.
The sys_syslog function has been renamed to ksyslog. This was in a
set patches for ALPHA support so I am assuming that this is necessary
for that environment
Version 1.3
Numerous changes, performance enhancements, code cleanups and bug fixes.

View File

@ -12,6 +12,8 @@ Description: The sysklogd package implements two system log daemons. The
routes them to either output files or to syslogd. This
version of klogd will optionally translate kernel addresses
to their symbolic equivalents if provided with a system map.
The klogd daemon also provides support for debugging of
protection faults which occur in kernel loadable modules.
Keywords: logging, remote, kernel, syslogd, proc, daemon, klogd
Author: greg@wind.rmcc.com (Dr. G.W. Wettstein)
Maintained-by: greg@wind.rmcc.com (Dr. G.W. Wettstein)

162
klogd.8
View File

@ -2,6 +2,7 @@
.\" May be distributed under the GNU General Public License
.\" Sun Jul 30 01:35:55 MET: Martin Schulze: Updates
.\" Sun Nov 19 23:22:21 MET: Martin Schulze: Updates
.\" Mon Aug 19 09:42:08 CDT 1996: Dr. G.W. Wettstein: Updates
.\"
.TH KLOGD 8 "24 November 1995" "Version 1.3" "Linux System Administration"
.SH NAME
@ -16,8 +17,10 @@ klogd \- kernel log daemon.
.RB [ " \-f "
.I fname
]
.RB [ " \-iI " ]
.RB [ " \-n " ]
.RB [ " \-o " ]
.RB [ " \-p " ]
.RB [ " \-s " ]
.RB [ " \-k "
.I fname
@ -41,6 +44,12 @@ stderr.
.BI "\-f " file
Log messages to the specified filename rather than to the syslog facility.
.TP
.BI "\-i \-I"
Signal the currently executing klogd daemon. Both of these switches control
the loading/reloading of symbol information. The \-i switch signals the
daemon to reload the kernel module symbols. The \-I switch signals for a
reload of both the static kernel symbols and the kernel module symbols.
.TP
.B "\-n"
Avoid auto-backgrounding. This is needed especially if the
.B klogd
@ -52,6 +61,12 @@ Execute in 'one\-shot' mode. This causes \fBklogd\fP to read and log
all the messages that are found in the kernel message buffers. After
a single read and log cycle the daemon exits.
.TP
.B "-p"
Enable paranoia. This option controls when klogd loads kernel module symbol
information. Setting this switch causes klogd to load the kernel module
symbol information whenever an Oops string is detected in the kernel message
stream.
.TP
.B "-s"
Force \fBklogd\fP to use the system call interface to the kernel message
buffers.
@ -163,10 +178,43 @@ command would be given.
.fi
.PP
.SH KERNEL ADDRESS RESOLUTION
If the kernel detects an internal error condition a general protection
fault will be triggered. As part of the GPF handling procedure the
kernel prints out a status report indicating the state of the
processor at the time of the fault. Included in this display are the
contents of the microprocessor's registers, the contents of the kernel
stack and a tracing of what functions were being executed at the time
of the fault.
This information is
.B EXTREMELY IMPORTANT
in determining what caused the internal error condition. The
difficulty comes when a kernel developer attempts to analyze this
information. The raw numeric information present in the protection
fault printout is of very little use to the developers. This is due
to the fact that kernels are not identical and the addresses of
variable locations or functions will not be the same in all kernels.
In order to correctly diagnose the cause of failure a kernel developer
needs to know what specific kernel functions or variable locations
were involved in the error.
As part of the kernel compilation process a listing is created which
specified the address locations of important variables and function in
the kernel being compiled. This listing is saved in a file called
System.map in the top of the kernel directory source tree. Using this
listing a kernel developer can determine exactly what the kernel was
doing when the error condition occurred.
The process of resolving the numeric addresses from the protection
fault printout can be done manually or by using the
.B ksymoops
program which is included in the kernel sources.
As a convenience
.B klogd
will attempt to resolve kernel numeric addresses to their symbolic
forms if a kernel symbol table is available at execution time.
A symbol table may be specified by using the \fB\-k\fR switch on the
forms if a kernel symbol table is available at execution time. A
symbol table may be specified by using the \fB\-k\fR switch on the
command line. If a symbol file is not explicitly specified the
following filenames will be tried:
@ -192,19 +240,101 @@ Modern kernels as of 1.3.43 properly format important kernel addresses
so that they will be recognized and translated by klogd. Earlier
kernels require a source code patch be applied to the kernel sources.
This patch is supplied with the sysklogd sources.
The process of analyzing kernel protections faults works very well
with a static kernel. Additional difficulties are encountered when
attempting to diagnose errors which occur in loadable kernel modules.
Loadable kernel modules are used to implement kernel functionality in
a form which can be loaded or unloaded at will. The use of loadable
modules is useful from a debugging standpoint and can also be useful
in decreasing the amount of memory required by a kernel.
The difficulty with diagnosing errors in loadable modules is due to
the dynamic nature of the kernel modules. When a module is loaded the
kernel will allocate memory to hold the module, when the module is
unloaded this memory will be returned back to the kernel. This
dynamic memory allocation makes it impossible to produce a map file
which details the addresses of the variable and functions in a kernel
loadable module. Without this location map it is not possible for a
kernel developer to determine what went wrong if a protection fault
involves a kernel module.
.B klogd
has support for dealing with the problem of diagnosing protection
faults in kernel loadable modules. At program start time or in
response to a signal the daemon will interrogate the kernel for a
listing of all modules loaded and the addresses in memory they are
loaded at. Individual modules can also register the locations of
important functions when the module is loaded. The addresses of these
exported symbols are also determined during this interrogation
process.
When a protection fault occurs an attempt will be made to resolve
kernel addresses from the static symbol table. If this fails the
symbols from the currently loaded modules are examined in an attempt
to resolve the addresses. At the very minimum this allows klogd to
indicate which loadable module was responsible for generating the
protection fault. Additional information may be available if the
module developer chose to export symbol information from the module.
Proper and accurate resolution of addresses in kernel modules requires
that
.B klogd
be informed whenever the kernel module status changes. The
.B \-i
and
.B \-I
switches can be used to signal the currently executing daemon that
symbol information be reloaded. Of most importance to proper
resolution of module symbols is the
.B \-i
switch. Each time a kernel module is loaded or removed from the
kernel the following command should be executed:
.nf
.I klogd \-i
.fi
The
.B \-p
switch can also be used to insure that module symbol information is up
to date. This switch instructs
.B klogd
to reload the module symbol information whenever a protection fault
is detected. Caution should be used before invoking the program in
\'paranoid\' mode. The stability of the kernel and the operating
environment is always under question when a protection fault occurs.
Since the klogd daemon must execute system calls in order to read the
module symbol information there is the possibility that the system may
be too unstable to capture useful information. A much better policy
is to insure that klogd is updated whenever a module is loaded or
unloaded. Having uptodate symbol information loaded increases the
probability of properly resolving a protection fault if it should occur.
Included in the sysklogd source distribution is a patch to the
modules-2.0.0 package which allows the
.B insmod,
.B rmmod
and
.B modprobe
utilities to automatically signal
.B klogd
whenever a module is inserted or removed from the kernel. Using this
patch will insure that the symbol information maintained in klogd is
always consistent with the current kernel state.
.PP
.SH SIGNAL HANDLING
The
.B klogd
will respond to six signals:
.BR SIGHUP ", " SIGINT ", " SIGKILL ", " SIGTERM ", " SIGTSTP " and " SIGCONT ". The"
will respond to eight signals:
.BR SIGHUP ", " SIGINT ", " SIGKILL ", " SIGTERM ", " SIGTSTP ", " SIGUSR1 ", "SIGUSR2 " and " SIGCONT ". The"
.BR SIGINT ", " SIGKILL ", " SIGTERM " and " SIGHUP
signals will cause the daemon to close its kernel log sources and
terminate gracefully.
The
.BR SIGTSTP " and " SIGCONT
singals are used to start and stop kernel logging. Upon receipt of a
signals are used to start and stop kernel logging. Upon receipt of a
.B SIGTSTP
signal the daemon will close its
log sources and spin in an idle loop. Subsequent receipt of a
@ -229,6 +359,26 @@ Notations will be made in the system logs with
.B LOG_INFO
priority
documenting the start/stop of logging.
The
.BR SIGUSR1 " and " SIGUSR2
signals are used to initiate loading/reloading of kernel symbol information.
Receipt of the
.B SIGUSR1
signal will cause the kernel module symbols to be reloaded. Signaling the
daemon with
.B SIGUSR2
will cause both the static kernel symbols and the kernel module symbols to
be reloaded.
Provided that the System.map file is placed in an appropriate location the
signal of generally greatest usefulness is the
.B SIGUSR1
signal. This signal is designed to be used to signal the daemon when kernel
modules are loaded/unloaded. Sending this signal to the daemon after a
kernel module state change will insure that proper resolution of symbols will
occur if a protection fault occurs in the address space occupied by a kernel
module.
.LP
.SH FILES
.PD 0
@ -241,7 +391,7 @@ One Source for kernel messages
The file containing the process id of
.B klogd
.TP
.I /System.map, /usr/src/linux/System.map
.I /boot/System.map, /System.map, /usr/src/linux/System.map
Default locations for kernel system maps.
.PD
.SH BUGS

139
klogd.c
View File

@ -145,6 +145,19 @@
* Corrected incorrect/insecure use of strpbrk for a not necessarily
* null-terminated buffer. Used a patch from Chris Hanson
* (cph@martigny.ai.mit.edu), thanks.
*
* Wed Aug 21 09:13:03 CDT 1996: Dr. Wettstein
* Added ability to reload static symbols and kernel module symbols
* under control of SIGUSR1 and SIGUSR2 signals.
*
* Added -p switch to select 'paranoid' behavior with respect to the
* loading of kernel module symbols.
*
* Informative line now printed whenever a state change occurs due
* to signal reception by the daemon.
*
* Added the -i and -I command line switches to signal the currently
* executing daemon.
*/
@ -163,8 +176,10 @@
#define __LIBRARY__
#include <linux/unistd.h>
#define __NR_sys_syslog __NR_syslog
_syscall3(int,sys_syslog,int, type, char *, buf, int, len);
#ifndef __alpha__
# define __NR_ksyslog __NR_syslog
_syscall3(int,ksyslog,int, type, char *, buf, int, len);
#endif
#define LOG_BUFFER_SIZE 4096
#define LOG_LINE_LENGTH 1024
@ -179,13 +194,15 @@ static int kmsg,
change_state = 0,
terminate = 0,
caught_TSTP = 0,
reload_symbols = 0,
console_log_level = 6;
static int use_syscall = 0,
one_shot = 0,
NoFork = 0; /* don't fork - don't run in daemon mode */
static char log_buffer[LOG_BUFFER_SIZE];
static char *symfile = (char *) 0,
log_buffer[LOG_BUFFER_SIZE];
static FILE *output_file = (FILE *) 0;
@ -195,12 +212,15 @@ int debugging = 0;
/* Function prototypes. */
extern int sys_syslog(int type, char *buf, int len);
extern int ksyslog(int type, char *buf, int len);
static void CloseLogSrc(void);
extern void restart(int sig);
extern void stop_logging(int sig);
extern void stop_daemon(int sig);
extern void reload_daemon(int sig);
static void Terminate(void);
static void SignalDaemon(int);
static void ReloadSymbols(void);
static void ChangeLogging(void);
static enum LOGSRC GetKernelLogSrc(void);
static void LogLine(char *ptr, int len);
@ -213,14 +233,14 @@ static void CloseLogSrc()
{
/* Turn on logging of messages to console. */
sys_syslog(7, NULL, 0);
ksyslog(7, NULL, 0);
/* Shutdown the log sources. */
switch ( logsrc )
{
case kernel:
sys_syslog(0, 0, 0);
Syslog(LOG_INFO, "Kernel logging (sys_syslog) stopped.");
ksyslog(0, 0, 0);
Syslog(LOG_INFO, "Kernel logging (ksyslog) stopped.");
break;
case proc:
close(kmsg);
@ -271,6 +291,27 @@ void stop_daemon(sig)
}
void reload_daemon(sig)
int sig;
{
change_state = 1;
reload_symbols = 1;
if ( sig == SIGUSR2 )
{
++reload_symbols;
signal(SIGUSR2, reload_daemon);
}
else
signal(SIGUSR1, reload_daemon);
return;
}
static void Terminate()
{
@ -284,6 +325,28 @@ static void Terminate()
exit(1);
}
static void SignalDaemon(sig)
int sig;
{
auto int pid = check_pid(PidFile);
kill(pid, sig);
return;
}
static void ReloadSymbols()
{
if ( reload_symbols > 1 )
InitKsyms(symfile);
InitMsyms();
reload_symbols = change_state = 0;
return;
}
static void ChangeLogging(void)
@ -292,6 +355,17 @@ static void ChangeLogging(void)
if ( terminate == 1 )
Terminate();
/* Indicate that something is happening. */
Syslog(LOG_INFO, "klogd %s-%s, ---------- state change ----------\n", \
VERSION, PATCHLEVEL);
/* Reload symbols. */
if ( reload_symbols > 0 )
{
ReloadSymbols();
return;
}
/* Stop kernel logging. */
if ( caught_TSTP == 1 )
{
@ -330,7 +404,7 @@ static enum LOGSRC GetKernelLogSrc(void)
/* Set level of kernel console messaging.. */
if ( (sys_syslog(8, NULL, console_log_level) < 0) && \
if ( (ksyslog(8, NULL, console_log_level) < 0) && \
(errno == EINVAL) )
{
/*
@ -341,7 +415,7 @@ static enum LOGSRC GetKernelLogSrc(void)
*/
Syslog(LOG_WARNING, "Cannot set console log level - disabling "
"console output.");
sys_syslog(6, NULL, 0);
ksyslog(6, NULL, 0);
}
@ -353,12 +427,12 @@ static enum LOGSRC GetKernelLogSrc(void)
((stat(_PATH_KLOG, &sb) < 0) && (errno == ENOENT)) )
{
/* Initialize kernel logging. */
sys_syslog(1, NULL, 0);
ksyslog(1, NULL, 0);
#ifdef DEBRELEASE
Syslog(LOG_INFO, "klogd %s-%s#%s, log source = sys_syslog "
Syslog(LOG_INFO, "klogd %s-%s#%s, log source = ksyslog "
"started.", VERSION, PATCHLEVEL, DEBRELEASE);
#else
Syslog(LOG_INFO, "klogd %s-%s, log source = sys_syslog "
Syslog(LOG_INFO, "klogd %s-%s, log source = ksyslog "
"started.", VERSION, PATCHLEVEL);
#endif
return(kernel);
@ -366,8 +440,9 @@ static enum LOGSRC GetKernelLogSrc(void)
if ( (kmsg = open(_PATH_KLOG, O_RDONLY)) < 0 )
{
fputs("klogd: Cannot open proc file system.", stderr);
sys_syslog(7, NULL, 0);
fprintf(stderr, "klogd: Cannot open proc file system, " \
"%d - %s.\n", errno, strerror(errno));
ksyslog(7, NULL, 0);
exit(1);
}
@ -391,7 +466,7 @@ extern void Syslog(int priority, char *fmt, ...)
{
fputs("Logging line:\n", stderr);
fprintf(stderr, "\tLine: %s\n", fmt);
fprintf(stderr, "\tPriority: %c\n", *(fmt+1));
fprintf(stderr, "\tPriority: %d\n", priority);
}
/* Handle output to a file. */
@ -534,12 +609,12 @@ static void LogKernelLine(void)
* messages into this fresh buffer.
*/
memset(log_buffer, '\0', sizeof(log_buffer));
if ( (rdcnt = sys_syslog(2, log_buffer, sizeof(log_buffer))) < 0 )
if ( (rdcnt = ksyslog(2, log_buffer, sizeof(log_buffer))) < 0 )
{
if ( errno == EINTR )
return;
fprintf(stderr, "Error return from sys_sycall: %d - %s\n", \
errno, strerror(errno));
fprintf(stderr, "klogd: Error return from sys_sycall: " \
"%d - %s\n", errno, strerror(errno));
}
LogLine(log_buffer, rdcnt);
@ -563,7 +638,8 @@ static void LogProcLine(void)
{
if ( errno == EINTR )
return;
Syslog(LOG_ERR, "Cannot read proc file system.");
Syslog(LOG_ERR, "Cannot read proc file system: %d - %s.", \
errno, strerror(errno));
}
LogLine(log_buffer, rdcnt);
@ -579,14 +655,14 @@ int main(argc, argv)
char *argv[];
{
auto int ch, use_output = 0;
auto int ch,
use_output = 0;
auto char *symfile = (char *) 0,
*log_level = (char *) 0,
auto char *log_level = (char *) 0,
*output = (char *) 0;
/* Parse the command-line. */
while ((ch = getopt(argc, argv, "c:df:k:nosv")) != EOF)
while ((ch = getopt(argc, argv, "c:df:iIk:nopsv")) != EOF)
switch((char)ch)
{
case 'c': /* Set console message level. */
@ -599,6 +675,12 @@ int main(argc, argv)
output = optarg;
use_output++;
break;
case 'i': /* Reload module symbols. */
SignalDaemon(SIGUSR1);
return(0);
case 'I':
SignalDaemon(SIGUSR2);
return(0);
case 'k': /* Kernel symbol file. */
symfile = optarg;
break;
@ -608,6 +690,9 @@ int main(argc, argv)
case 'o': /* One-shot mode. */
one_shot = 1;
break;
case 'p':
SetParanoiaLevel(1); /* Load symbols on oops. */
break;
case 's': /* Use syscall interface. */
use_syscall = 1;
break;
@ -698,6 +783,8 @@ int main(argc, argv)
signal(SIGHUP, stop_daemon);
signal(SIGTSTP, stop_logging);
signal(SIGCONT, restart);
signal(SIGUSR1, reload_daemon);
signal(SIGUSR2, reload_daemon);
/* Open outputs. */
@ -707,8 +794,8 @@ int main(argc, argv)
output_file = stdout;
else if ( (output_file = fopen(output, "w")) == (FILE *) 0 )
{
fprintf(stderr, "klogd: Cannot open output file %s - "\
"%s\n", output, strerror(errno));
fprintf(stderr, "klogd: Cannot open output file " \
"%s - %s\n", output, strerror(errno));
return(1);
}
}
@ -720,6 +807,7 @@ int main(argc, argv)
if ( one_shot )
{
InitKsyms(symfile);
InitMsyms();
if ( (logsrc = GetKernelLogSrc()) == kernel )
LogKernelLine();
else
@ -733,6 +821,7 @@ int main(argc, argv)
#endif
logsrc = GetKernelLogSrc();
InitKsyms(symfile);
InitMsyms();
/* The main loop. */
while (1)

View File

@ -13,5 +13,7 @@
/* Function prototypes. */
extern int InitKsyms(char *);
extern int InitMsyms(void);
extern char * ExpandKadds(char *, char *);
extern void SetParanoiaLevel(int);
extern void Syslog(int priority, char *fmt, ...);

143
ksym.c
View File

@ -1,6 +1,7 @@
/*
ksym.c - functions for kernel address->symbol translation
Copyright (c) 1995 Dr. G.W. Wettstein <greg@wind.rmcc.com>
Copyright (c) 1995, 1996 Dr. G.W. Wettstein <greg@wind.rmcc.com>
Copyright (c) 1996 Enjellic Systems Development
This file is part of the sysklogd package, a kernel and system log daemon.
@ -61,10 +62,20 @@
* Added patch from beta-testers to allow for reading of both
* ELF and a.out map files.
*
* Wed Aug 21 09:15:49 CDT 1996: Dr. Wettstein
* Reloading of kernel module symbols is now turned on by the
* SetParanoiaLevel function. The default behavior is to NOT reload
* the kernel module symbols when a protection fault is detected.
*
* Added support for freeing of the current kernel module symbols.
* This was necessary to support reloading of the kernel module symbols.
*
* When a matching static symbol table is loaded the kernel version
* number is printed.
*
* Mon Jun 9 17:12:42 CST 1997: Martin Schulze
* Added #1 and #2 to some error messages in order to being able
* to divide them (ulmo@Q.Net)
*
*/
@ -73,27 +84,22 @@
#include <malloc.h>
#include <sys/utsname.h>
#include "klogd.h"
#include "ksyms.h"
#define VERBOSE_DEBUGGING 0
/* Variables, structures and type definitions static to this module. */
/* Variables static to this module. */
struct sym_table
{
unsigned long value;
char *name;
};
struct symbol
{
char *name;
int size;
int offset;
};
static struct sym_table *sym_array = (struct sym_table *) 0;
static int num_syms = 0;
static int i_am_paranoid = 0;
static char vstring[12];
static struct sym_table *sym_array = (struct sym_table *) 0;
static char *system_maps[] =
{
@ -107,7 +113,7 @@ static char *system_maps[] =
#if defined(TEST)
static int debugging = 1;
int debugging;
#else
extern int debugging;
#endif
@ -117,6 +123,7 @@ extern int debugging;
static char * FindSymbolFile(void);
static int AddSymbol(unsigned long, char*);
static char * LookupSymbol(unsigned long, struct symbol *);
static void FreeSymbols(void);
static int CheckVersion(char *);
@ -153,6 +160,11 @@ extern int InitKsyms(mapfile)
auto FILE *sym_file;
/* Check and make sure that we are starting with a clean slate. */
if ( num_syms > 0 )
FreeSymbols();
/*
* Search for and open the file containing the kernel symbols.
*/
@ -195,7 +207,7 @@ extern int InitKsyms(mapfile)
*/
while ( !feof(sym_file) )
{
if ( fscanf(sym_file, "%8lx %c %s\n", &address, &type, sym)
if ( fscanf(sym_file, "%lx %c %s\n", &address, &type, sym)
!= 3 )
{
Syslog(LOG_ERR, "Error in symbol table input (#1).");
@ -231,7 +243,7 @@ extern int InitKsyms(mapfile)
break;
case 1:
Syslog(LOG_INFO, "Symbols match kernel version.");
Syslog(LOG_INFO, "Symbols match kernel version %s.", vstring);
break;
}
@ -283,7 +295,7 @@ static char * FindSymbolFile()
auto int version;
auto struct utsname utsname;
char symfile[100];
static char symfile[100];
auto unsigned long int address;
@ -319,7 +331,7 @@ static char * FindSymbolFile()
version = 0;
while ( !feof(sym_file) && (version == 0) )
{
if ( fscanf(sym_file, "%8lx %c %s\n", &address, \
if ( fscanf(sym_file, "%lx %c %s\n", &address, \
&type, sym) != 3 )
{
Syslog(LOG_ERR, "Error in symbol table input (#2).");
@ -419,8 +431,6 @@ static int CheckVersion(version)
{
auto char vstring[12];
auto int vnum,
major,
minor,
@ -445,16 +455,15 @@ static int CheckVersion(version)
* things out by decoding the version string into its component
* parts.
*/
memset(vstring, '\0', sizeof(vstring));
strncpy(vstring, version + strlen(prefix), sizeof(vstring)-1);
vnum = atoi(vstring);
vnum = atoi(version + strlen(prefix));
major = vnum / 65536;
vnum -= (major * 65536);
minor = vnum / 256;
patch = vnum - (minor * 256);
if ( debugging )
fprintf(stderr, "Version string = %s, Major = %d, " \
"Minor = %d, Patch = %d.\n", vstring, major, minor, \
"Minor = %d, Patch = %d.\n", version +
strlen(prefix), major, minor, \
patch);
sprintf(vstring, "%d.%d.%d", major, minor, patch);
@ -543,7 +552,7 @@ static int AddSymbol(address, symbol)
* closely matching the address is returned.
**************************************************************************/
extern char * LookupSymbol(value, sym)
static char * LookupSymbol(value, sym)
unsigned long value;
@ -572,10 +581,44 @@ extern char * LookupSymbol(value, sym)
last = sym_array[lp].name;
}
if ( (last = LookupModuleSymbol(value, sym)) != (char *) 0 )
return(last);
return((char *) 0);
}
/**************************************************************************
* Function: FreeSymbols
*
* Purpose: This function is responsible for freeing all memory which
* has been allocated to hold the static symbol table. It
* also initializes the symbol count and in general prepares
* for a re-read of a static symbol table.
*
* Arguements: void
*
* Return: void
**************************************************************************/
static void FreeSymbols()
{
auto int lp;
/* Free each piece of memory allocated for symbol names. */
for(lp= 0; lp < num_syms; ++lp)
free(sym_array[lp].name);
/* Whack the entire array and initialize everything. */
free(sym_array);
sym_array = (struct sym_table *) 0;
num_syms = 0;
return;
}
/**************************************************************************
* Function: LogExpanded
*
@ -612,6 +655,28 @@ extern char * ExpandKadds(line, el)
auto struct symbol sym;
/*
* This is as handy a place to put this as anyplace.
*
* Since the insertion of kernel modules can occur in a somewhat
* dynamic fashion we need some mechanism to insure that the
* kernel symbol tables get read just prior to when they are
* needed.
*
* To accomplish this we look for the Oops string and use its
* presence as a signal to load the module symbols.
*
* This is not the best solution of course, especially if the
* kernel is rapidly going out to lunch. What really needs to
* be done is to somehow generate a callback from the
* kernel whenever a module is loaded or unloaded. I am
* open for patches.
*/
if ( i_am_paranoid &&
(strstr(line, "Oops:") != (char *) 0) && !InitMsyms() )
Syslog(LOG_WARNING, "Cannot load kernel module symbols.\n");
/*
* Early return if there do not appear to be any kernel
* messages in this line.
@ -671,6 +736,30 @@ extern char * ExpandKadds(line, el)
}
/**************************************************************************
* Function: SetParanoiaLevel
*
* Purpose: This function is an interface function for setting the
* mode of loadable module symbol lookups. Probably overkill
* but it does slay another global variable.
*
* Arguements: (int) level
*
* level:-> The amount of paranoia which is to be
* present when resolving kernel exceptions.
* Return: void
**************************************************************************/
extern void SetParanoiaLevel(level)
int level;
{
i_am_paranoid = level;
return;
}
/*
* Setting the -DTEST define enables the following code fragment to
* be compiled. This produces a small standalone program which will
@ -686,14 +775,10 @@ extern int main(int, char **);
extern int main(int argc, char *argv[])
{
auto long int value;
auto char line[1024], eline[2048];
debugging = 1;
#if 0
value = atol(argv[1]);
fprintf(stdout, "Value of %ld: %s\n", value, LookupSymbol(value));
#endif
if ( !InitKsyms((char *) 0) )
{

View File

@ -39,7 +39,7 @@ System logging is provided by a version of
.BR syslogd (8)
derived from the
stock BSD sources. Support for kernel logging is provided by the
.BR syslogd (8)
.BR klogd (8)
utility which allows kernel logging to be conducted in either a
standalone fashion or as a client of syslogd.
@ -91,7 +91,7 @@ defined.
.TP
.BI "\-l " "hostlist"
Specify a hostname that should be logged only with its simple hostname
and not the the fqdn. Multiple hosts may be specified using the colon
and not the fqdn. Multiple hosts may be specified using the colon
(``:'') separator.
.TP
.BI "\-m " "interval"
@ -195,8 +195,8 @@ will also match) to go into
.PP
Under the new scheme this behavior remains the same. The difference
is the addition of four new specifiers, the asterisk (\fB*\fR)
wildcard the equation sign (\fB=\fR), the exclamation mark
(\fB!\fR) and the minus sign (\fB-\fR).
wildcard, the equation sign (\fB=\fR), the exclamation mark
(\fB!\fR), and the minus sign (\fB-\fR).
The \fB*\fR specifies that all messages for the
specified facility are to be directed to the destination. Note that
@ -215,7 +215,7 @@ file.
.IP
.nf
# Sample syslog.conf
daemon.=debug /usr/adm/debug
*.=debug /usr/adm/debug
.fi
.PP
.\" The \fB!\fR as the first character of a priority inverts the above
@ -456,11 +456,11 @@ dealing with the occasional recalcitrant or belligerent individual.
.SH DEBUGGING
When debugging is turned on using
.B "\-d"
option the
option then
.B syslogd
will very verbose by writing much of what it does on stdout. Whenever
will be very verbose by writing much of what it does on stdout. Whenever
the configuration file is reread and re-parsed you'll see a tabular,
corresponding on the internal data structure. This tabular consists of
corresponding to the internal data structure. This tabular consists of
four fields:
.TP
.I number
@ -489,7 +489,7 @@ manpage for all possible actions.
This field shows additional arguments to the actions in the last
field. For file-logging this is the filename for the logfile; for
user-logging this is a list of users; for remote logging this is the
the hostname of the machine to log to; for console-logging this is the
hostname of the machine to log to; for console-logging this is the
used console; for tty-logging this is the specified tty; wall has no
additional arguments.
.SH FILES

View File

@ -270,6 +270,14 @@ static char sccsid[] = "@(#)syslogd.c 5.27 (Berkeley) 10/10/88";
*
* Minor code cleanups.
*
* Thu May 2 15:15:33 CDT 1996: Dr. Wettstein
* Fixed bug in init function which resulted in file descripters
* being orphaned when syslogd process was re-initialized with SIGHUP
* signal. Thanks to Edvard Tuinder
* (Edvard.Tuinder@praseodymium.cistron.nl) for putting me on the
* trail of this bug. I am amazed that we didn't catch this one
* before now.
*
* Tue May 14 00:03:35 MET DST 1996: Martin Schulze
* Corrected a mistake that causes the syslogd to stop logging at
* some virtual consoles under Linux. This was caused by checking
@ -305,7 +313,6 @@ static char sccsid[] = "@(#)syslogd.c 5.27 (Berkeley) 10/10/88";
* Tue Jun 10 12:51:41 MET DST 1997: Martin Schulze
* Removed sleep(10) from parent process. This has caused a slow
* startup in former times - and I don't see any reason for this.
*
*/
@ -752,10 +759,14 @@ int main(argc, argv)
* should return the simple hostname or the fqdn. A
* good piece of software should be aware of both and
* we want to distribute good software. Joey
*
* Good software also always checks its return values...
* If syslogd starts up before DNS is up & /etc/hosts
* doesn't have LocalHostName listed, gethostbyname will
* return NULL.
*/
hent = gethostbyname(LocalHostName);
if (hent != NULL)
{
if ( hent )
sprintf(LocalHostName, "%s", hent->h_name);
if ( (p = index(LocalHostName, '.')) )
{
@ -763,7 +774,6 @@ int main(argc, argv)
LocalDomain = p;
}
}
}
/*
* Convert to lower case to recognize the correct domain laterly
@ -926,7 +936,7 @@ int main(argc, argv)
dprintf("%d ", nfds);
dprintf("\n");
}
for (fd= 0; fd <= FD_SETSIZE; ++fd)
for (fd= 0; fd < FD_SETSIZE; ++fd)
if ( FD_ISSET(fd, &readfds) && FD_ISSET(fd, &unixm) ) {
dprintf("Message from UNIX socket #%d.\n", fd);
memset(line, '\0', sizeof(line));
@ -1015,9 +1025,8 @@ char **
crunch_list(list)
char *list;
{
int count;
int i;
char *p;
int count, i;
char *p, *q;
char **result = NULL;
p = list;
@ -1048,15 +1057,15 @@ crunch_list(list)
* so we don't have to care about this.
*/
count = 0;
while ((i=(int)index(p, LIST_DELIMITER))) {
if ((result[count] = \
(char *)malloc(sizeof(char) * i - (int)p +1)) == NULL) {
while ((q=index(p, LIST_DELIMITER))) {
result[count] = (char *) malloc((q - p + 1) * sizeof(char));
if (result[count] == NULL) {
printf ("Sorry, can't get enough memory, exiting.\n");
exit(0);
}
strncpy(result[count],p, i - (int)p);
result[count][i - (int)p] = '\0';
p = (char *)i;p++;
strncpy(result[count], p, q - p);
result[count][q - p] = '\0';
p = q; p++;
count++;
}
if ((result[count] = \
@ -1918,23 +1927,18 @@ void init()
char cline[BUFSIZ];
#endif
dprintf("Called init.\n");
/*
* Close all open log files.
*
* This is needed especially when HUPing syslogd as the
* structure would grow infinitively.
*
* Close all open log files and free log descriptor array.
*/
dprintf("Called init.\n");
Initialized = 0;
if ( nlogs > -1 )
{
dprintf("Initializing log structures.\n");
#ifdef SYSV
for (lognum = 0; lognum <= nlogs; lognum++ ) {
f = &Files[lognum];
#else
for (f = Files; f != NULL; f = next) {
#endif
/* flush any pending output */
if (f->f_prevcount)
fprintlog(f, LocalHostName, 0, (char *)NULL);
@ -1947,22 +1951,17 @@ void init()
(void) close(f->f_file);
break;
}
#ifdef SYSV
f->f_type = F_UNUSED; /* clear entry - ASP */
}
if ( nlogs > -1 )
{
dprintf("Freeing log structures.\n");
/*
* This is needed especially when HUPing syslogd as the
* structure would grow infinitively. -Joey
*/
nlogs = -1;
free((void *) Files);
}
Files = (struct filed *) 0;
#else
next = f->f_next;
free((char *) f);
}
nextp = &OBFiles;
#endif
/* open the configuration file */
if ((cf = fopen(ConfFile, "r")) == NULL) {

View File

@ -1,2 +1,2 @@
#define VERSION "1.3"
#define PATCHLEVEL "0"
#define PATCHLEVEL "3"