SYSLOG
Andrew Hume
andrew at alice.UUCP
Fri Jan 12 14:39:13 AEST 1990
In article <10319 at alice.UUCP>, andrew at alice.UUCP (Andrew Hume) writes:
>
>
> has anyone running 3.2 (or 3.2.1) persuaded the syslog system to
> log disk errors? despite the obvious and default conf file,
> nothing gets logged but some whining by some networking daemons.
> i wrote a user program to log stuff; it worked.
I have a solution for anyone who wants to log their kernel printfs
(such as disk erors etc). I am running it on a 4D/240 but it should apply
to other power series. Many thanks are due to dave olson who was kind
enough to help me understand some fine points.
basically, i have a program called syslogger (spawned from S20sysetup)
that constantly scans the kernel buffer and logs any messages found there.
(isn't this what syslogd should be doing?) i made the kernel buffer
larger than normal (the define is CONBUFSIZE in master.d/kernel: default
is 1024 - mine is 4096) and i scan the buffer every minute. (in less paranoid
circumstances, say on our vaxes, we do this less often, say every 15 mins.)
to compile the following source, i use
$CC $CFLAGS -I/usr/include/bsd -o syslogger syslogger.c -lmld -lbsd
there is some crap at the start to try and do the right thing for a daemon
process (disconnect the controlling tty etc); i never ran into any trouble
before i put it in and have no idea why it is necessary but it is apparently
the right thing to do. if i bungled, tell me.
any complaints, comments or suggestions should be sent to andrew at research.att.com
the source is:
#include <stdio.h>
#include <sys/param.h>
#include <nlist.h>
#include <signal.h>
#include <syslog.h>
#include <sys/termio.h>
struct nlist nl[] = {
{ "conbuf" },
{ "conbufndx" },
{ "conbufsz" },
{ 0 }
};
int mem;
char *whoami;
main(argc, argv)
char **argv;
{
int i;
int size, amt;
int ndx;
char *buf;
extern errno;
whoami = argv[0];
/*
fork off and find myself
*/
if(fork())
exit(0);
for(i = 0; i < 20; i++)
close(i); /* close a bunch */
i = open("/dev/null", 0); /* set std descriptors to something */
dup2(i, 2); /* hope i isn't 2 */
close(i);
dup2(2, 0);
dup2(2, 1);
chdir("/");
i = open("/dev/tty", 2);
if(i > 0){
ioctl(i, TIOCNOTTY, (char *)0);
close(i);
}
setpgrp();
/*
do something with my life
*/
signal(SIGHUP, SIG_IGN);
nlist("/unix", nl);
mem = 0;
for(i = 0; nl[i].n_name; i++)
if(nl[i].n_type == 0){
mem = 1;
syslog(LOG_ERR, "can't find %s\n", nl[1].n_name);
}
else
nl[i].n_value &= ~0x80000000;
if(mem)
done("namelist problems", 1);
if((mem = open("/dev/kmem", 0)) < 0)
done("/dev/kmem\n", -1);
if(getval(&nl[2], &size, sizeof(size)) != sizeof(size))
done("reading size");
syslog(LOG_INFO, "kernel monitor: buffer = %d bytes", size);
if((buf = (char *)malloc(3*size)) == 0)
done("malloc failure", 1);
ndx = 0; /* assume we are starting from start of the buffer */
do {
ndx = dobuf(ndx, size, buf);
} while(sleep(60) >= 0);
exit(0);
}
dobuf(ostart, size, buffer)
char *buffer;
{
int out;
int ndx;
if(getval(&nl[1], &ndx, sizeof(ndx)) != sizeof(ndx))
done("reading ndx");
ndx = ndx%size; /* it should be anyway */
if(ndx == ostart) /* most common case: nothing happened */
return(ostart);
if(getval(&nl[0], buffer, size) != size)
done("reading buf");
/* make it a contiguous region */
memcpy(buffer+size, buffer, size);
if(ndx < ostart)
ndx += size;
out = 2*size;
while(ostart < ndx)
switch(buffer[ostart++])
{
case 0: /* apparently not uncommon */
break;
case '\n':
buffer[out] = 0;
out = 2*size;
syslog(LOG_ERR, "%s", buffer+out);
break;
default:
buffer[out++] = buffer[ostart-1];
break;
}
buffer[out] = 0;
out = 2*size;
if(buffer[out])
syslog(LOG_ERR, "%s <partial line>", buffer+out);
return(ndx%size);
}
done(s, ec)
char *s;
{
if(ec < 0)
syslog(LOG_ERR, "%s: %s: %m", whoami, s);
else
syslog(LOG_ERR, "%s: %s", whoami, s);
exit(1);
}
getval(nl, buf, cnt)
struct nlist *nl;
char *buf;
int cnt;
{
if(lseek(mem, (long)nl->n_value, 0) != (long)nl->n_value){
fprintf(stderr, "lseek to %x for %s", nl[0].n_value, nl[0].n_name);
return(-1);
}
/* printf("will read %d from %#x for %s\n", cnt, nl[0].n_value, nl[0].n_name);
/* should be min of cnt and sizeof(buf) */
return read(mem, buf, cnt);
}
More information about the Comp.sys.sgi
mailing list