kernel and servers send diagnostic messages to IS; IS sends them to TTY

and the new log driver if enabled.

new usyslogd is started from /usr/etc/rc. New device created by
MAKEDEV.sh. /var/log created by etc/mtree/minix.tree (on root for
now). Made select() slightly more generic, with less code duplication.
This commit is contained in:
Ben Gras 2005-07-08 17:30:01 +00:00
parent dd31785aa6
commit 42050e39f8
12 changed files with 177 additions and 98 deletions

View file

@ -12,7 +12,7 @@ case $#:$1 in
set -$- mem fd0 fd1 fd0p0 fd1p0 \
c0d0 c0d0p0 c0d0p0s0 c0d1 c0d1p0 c0d1p0s0 \
c0d2 c0d2p0 c0d2p0s0 c0d3 c0d3p0 c0d3p0s0 \
tty ttyc1 ttyc2 ttyc3 tty00 tty01 ttyp0 ttyp1 ttyp2 ttyp3 eth
tty ttyc1 ttyc2 ttyc3 tty00 tty01 ttyp0 ttyp1 ttyp2 ttyp3 eth klog
;;
0:|1:-\?)
cat >&2 <<EOF
@ -32,6 +32,7 @@ Where key is one of the following:
ttyp0 ... ttyq0 ... # Make tty, pty pairs
eth ip tcp udp # One of these makes some TCP/IP devices
audio mixer # Make audio devices
klog # Make /dev/klog
std # All standard devices
EOF
exit 1
@ -217,6 +218,11 @@ do
$e mknod mixer c 14 0
$e chmod 666 audio mixer
;;
klog)
# IS devices.
$e mknod klog c 15 0
$e chmod 600 klog
;;
*)
echo "$0: don't know about $dev" >&2
ex=1

View file

@ -62,3 +62,6 @@
700 daemon daemon /usr/spool/lpd
755 bin operator /usr/src
1777 root operator /usr/tmp
755 root operator /var
755 root operator /var/log
755 root operator /var/run

View file

@ -45,6 +45,7 @@ start)
echo -n "Starting daemons:"
daemonize update
daemonize usyslogd
# Ugly error message when starting cron from CD.
# (and cron unnecessary then so..)

View file

@ -14,13 +14,14 @@
*
* This file contains the routines that take care of kernel messages, i.e.,
* diagnostic output within the kernel. Kernel messages are not directly
* displayed on the console, because this must be done by the TTY driver.
* displayed on the console, because this must be done by the PRINT driver.
* Instead, the kernel accumulates characters in a buffer and notifies the
* TTY driver when a new message is ready.
* PRINT driver when a new message is ready.
*/
#include "kernel.h"
#include <minix/com.h> /* need TTY process number */
#include <minix/com.h>
#define isdigit(c) ((unsigned) ((c) - '0') < (unsigned) 10)
#define END_OF_KMESS -1
@ -151,7 +152,7 @@ PRIVATE void kputc(c)
int c; /* character to append */
{
/* Accumulate a single character for a kernel message. Send a notification
* the to TTY driver if an END_OF_KMESS is encountered.
* the to PRINTF_PROC driver if an END_OF_KMESS is encountered.
*/
message m;
if (c != END_OF_KMESS) {
@ -161,7 +162,7 @@ int c; /* character to append */
kmess.km_next = (kmess.km_next + 1) % KMESS_BUF_SIZE;
} else {
m.NOTIFY_TYPE = NEW_KMESS;
lock_notify(TTY, &m);
lock_notify(PRINTF_PROC, &m);
}
}

View file

@ -96,6 +96,7 @@ PUBLIC struct system_image image[] = {
#if ENABLE_DPETH
{ DPETH, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "DPETH" },
#endif
{ LOG_PROC_NR, 0, SYS_F, SYS_T, 2, 0, SYSTEM_CALL_MASK, ALLOW_ALL_MASK, "LOG" },
{ INIT_PROC_NR, 0, USER_F, USER_T, USER_Q, 0, USER_CALL_MASK, USER_PROC_SENDMASK, "INIT" },
};

View file

@ -32,7 +32,7 @@ int c;
m.DIAG_PRINT_BUF = print_buf;
m.DIAG_PROC_NR = SELF;
m.m_type = DIAGNOSTICS;
if (_sendrec(IS_PROC_NR, &m) != 0) {
if (_sendrec(PRINT_PROC, &m) != 0) {
m.m1_i1 = 2;
m.m1_i2 = buf_count;
m.m1_p1 = print_buf;

View file

@ -25,6 +25,9 @@
#include "inode.h"
#include "param.h"
#define ELEMENTS(a) (sizeof(a)/sizeof((a)[0]))
extern int dmap_size;
/*===========================================================================*
* dev_open *
@ -59,7 +62,6 @@ dev_t dev; /* device to close */
(void) (*dmap[(dev >> MAJOR) & BYTE].dmap_opcl)(DEV_CLOSE, dev, 0, 0);
}
/*===========================================================================*
* dev_io *
*===========================================================================*/
@ -297,7 +299,7 @@ message *mess_ptr; /* pointer to message for task */
/* Otherwise it should be a REVIVE. */
if (local_m.m_type != REVIVE) {
printf(
"fs: strange device reply from %d, type = %d, proc = %d\n",
"fs: strange device reply from %d, type = %d, proc = %d (1)\n",
local_m.m_source,
local_m.m_type, local_m.REP_PROC_NR);
continue;
@ -320,15 +322,19 @@ message *mess_ptr; /* pointer to message for task */
break;
}
/* Otherwise it should be a REVIVE. */
if (mess_ptr->m_type != REVIVE) {
if(mess_ptr->m_type == DEV_SELECTED) {
/* select() became possible.. This can happen. */
select_notified(mess_ptr);
} else if(mess_ptr->m_type == REVIVE) {
/* Otherwise it should be a REVIVE. */
revive(mess_ptr->REP_PROC_NR, mess_ptr->REP_STATUS);
} else {
printf(
"fs: strange device reply from %d, type = %d, proc = %d\n",
"fs: strange device reply from %d, type = %d, proc = %d (2)\n",
mess_ptr->m_source,
mess_ptr->m_type, mess_ptr->REP_PROC_NR);
continue;
continue; /* XXX should this be a continue?? */
}
revive(mess_ptr->REP_PROC_NR, mess_ptr->REP_STATUS);
r = receive(task_nr, mess_ptr);
}

View file

@ -51,10 +51,10 @@ struct dmap dmap[NR_DEVICES] = {
DT(NR_CTRLRS >= 4, gen_opcl, gen_io, CTRLR(3), DMAP_MUTABLE) /*12 = /dev/c3 */
DT(ENABLE_SB16, gen_opcl, gen_io, NONE, 0) /*13 = /dev/audio */
DT(ENABLE_SB16, gen_opcl, gen_io, NONE, 0) /*14 = /dev/mixer */
DT(1, gen_opcl, gen_io, LOG_PROC_NR, 0) /* 15 = /dev/klog */
#endif /* IBM_PC */
};
/*===========================================================================*
* map_driver *
*===========================================================================*/

View file

@ -4,6 +4,9 @@
* do_select: perform the SELECT system call
* select_callback: notify select system of possible fd operation
* select_notified: low-level entry for device notifying select
*
* Changes:
* 6 june 2005 Created (Ben Gras)
*/
@ -15,13 +18,14 @@
* make select cancel disappearing fp's
*/
#define DEBUG_SELECT 1
#define DEBUG_SELECT 0
#include "fs.h"
#include "select.h"
#include "file.h"
#include "inode.h"
#include "fs_timers.h"
#include "dmap.h"
#include <sys/time.h>
#include <sys/select.h>
@ -48,7 +52,8 @@ PRIVATE struct selectentry {
#define SELFD_PIPE 1
#define SELFD_TTY 2
#define SELFD_INET 3
#define SEL_FDS 4
#define SELFD_LOG 4
#define SEL_FDS 5
FORWARD _PROTOTYPE(int select_reevaluate, (struct filp *fp));
@ -56,10 +61,9 @@ FORWARD _PROTOTYPE(int select_request_file, (struct filp *f, int *ops, int block
FORWARD _PROTOTYPE(int select_match_file, (struct filp *f));
FORWARD _PROTOTYPE(int select_request_tty, (struct filp *f, int *ops, int block));
FORWARD _PROTOTYPE(int select_match_tty, (struct filp *f));
FORWARD _PROTOTYPE(int select_request_inet, (struct filp *f, int *ops, int block));
FORWARD _PROTOTYPE(int select_match_inet, (struct filp *f));
FORWARD _PROTOTYPE(int select_request_log, (struct filp *f, int *ops, int block));
FORWARD _PROTOTYPE(int select_major_match, (int match_major, struct filp *file));
FORWARD _PROTOTYPE(void select_cancel_all, (struct selectentry *e));
FORWARD _PROTOTYPE(int select_wakeup, (struct selectentry *e));
@ -73,15 +77,18 @@ FORWARD _PROTOTYPE(int select_wakeup, (struct selectentry *e));
PRIVATE struct fdtype {
int (*select_request)(struct filp *, int *ops, int block);
int (*select_match)(struct filp *);
int select_major;
} fdtypes[SEL_FDS] = {
/* SELFD_FILE */
{ select_request_file, select_match_file },
{ select_request_file, select_match_file, 0 },
/* SELFD_TTY (also PTY) */
{ select_request_tty, select_match_tty },
{ select_request_tty, NULL, TTY_MAJOR },
/* SELFD_INET */
{ select_request_inet, select_match_inet },
{ select_request_inet, NULL, INET_MAJOR },
/* SELFD_PIPE (pipe(2) pipes and FS FIFOs) */
{ select_request_pipe, select_match_pipe },
{ select_request_pipe, select_match_pipe, 0 },
/* SELFD_LOG (/dev/klog) */
{ select_request_log, NULL, LOG_MAJOR },
};
/* Open Group:
@ -122,21 +129,6 @@ PRIVATE int select_request_tty(struct filp *f, int *ops, int block)
return SEL_OK;
}
/*===========================================================================*
* select_match_tty *
*===========================================================================*/
PRIVATE int select_match_tty(struct filp *file)
{
int major;
if(!(file && file->filp_ino &&
(file->filp_ino->i_mode & I_TYPE) == I_CHAR_SPECIAL))
return 0;
major = (file->filp_ino->i_zone[0] >> MAJOR) & BYTE;
if(major == TTY_MAJOR || major == CTTY_MAJOR)
return 1;
return 0;
}
/*===========================================================================*
* select_request_inet *
*===========================================================================*/
@ -154,25 +146,34 @@ PRIVATE int select_request_inet(struct filp *f, int *ops, int block)
}
/*===========================================================================*
* select_match_inet *
* select_request_log *
*===========================================================================*/
PRIVATE int select_match_inet(struct filp *file)
PRIVATE int select_request_log(struct filp *f, int *ops, int block)
{
int r, rops;
rops = *ops;
if(block) rops |= SEL_NOTIFY;
*ops = dev_io(DEV_SELECT, f->filp_ino->i_zone[0], rops, NULL, 0, 0, 0);
if(*ops < 0)
return SEL_ERR;
return SEL_OK;
}
/*===========================================================================*
* select_major_match *
*===========================================================================*/
PRIVATE int select_major_match(int match_major, struct filp *file)
{
int major;
if(!(file && file->filp_ino &&
(file->filp_ino->i_mode & I_TYPE) == I_CHAR_SPECIAL))
return 0;
major = (file->filp_ino->i_zone[0] >> MAJOR) & BYTE;
if(major == INET_MAJOR)
{
printf("inet minor: %d\n",
(file->filp_ino->i_zone[0] & BYTE));
if(major == match_major)
return 1;
}
return 0;
}
PRIVATE int tab2ops(int fd, struct selectentry *e)
{
return (FD_ISSET(fd, &e->readfds) ? SEL_RD : 0) |
@ -183,7 +184,7 @@ PRIVATE int tab2ops(int fd, struct selectentry *e)
PRIVATE void ops2tab(int ops, int fd, struct selectentry *e)
{
if((ops & SEL_RD) && e->vir_readfds && FD_ISSET(fd, &e->readfds)
&& !FD_ISSET(fd, &e->ready_readfds)) {
&& !FD_ISSET(fd, &e->ready_readfds)) {
FD_SET(fd, &e->ready_readfds);
e->nreadyfds++;
}
@ -249,6 +250,7 @@ PUBLIC int do_select(void)
FD_ZERO(&selecttab[s].ready_writefds);
FD_ZERO(&selecttab[s].ready_errorfds);
selecttab[s].vir_readfds = (fd_set *) m_in.SEL_READFDS;
selecttab[s].vir_writefds = (fd_set *) m_in.SEL_WRITEFDS;
selecttab[s].vir_errorfds = (fd_set *) m_in.SEL_ERRORFDS;
@ -300,18 +302,21 @@ PUBLIC int do_select(void)
continue;
if(!(filp = selecttab[s].filps[fd] = get_filp(fd))) {
select_cancel_all(&selecttab[s]);
printf("do_select: get_filp failed\n");
return EBADF;
}
for(t = 0; t < SEL_FDS; t++) {
if(fdtypes[t].select_match(filp)) {
if(fdtypes[t].select_match) {
if(fdtypes[t].select_match(filp)) {
#if DEBUG_SELECT
printf("select: fd %d is type %d ", fd, t);
#endif
if(type != -1)
printf("select: double match\n");
type = t;
}
} else if(select_major_match(fdtypes[t].select_major, filp)) {
type = t;
}
}
@ -327,7 +332,9 @@ PUBLIC int do_select(void)
*/
if(type == -1)
{
#if DEBUG_SELECT
printf("do_select: bad type\n");
#endif
return EBADF;
}
@ -396,9 +403,15 @@ PUBLIC int do_select(void)
* functions shall return the total number of bits
* set in the bit masks."
*/
#if DEBUG_SELECT
printf("returning\n");
#endif
return selecttab[s].nreadyfds;
}
#if DEBUG_SELECT
printf("not returning (%d, %d)\n", selecttab[s].nreadyfds, block);
#endif
/* Convert timeval to ticks and set the timer. If it fails, undo
* all, return error.
@ -563,58 +576,43 @@ restart_callback:
*===========================================================================*/
PUBLIC int select_notified(message *m)
{
int s, f;
int s, f, d, t;
switch(m->m_source) {
case TTY:
#if DEBUG_SELECT
printf("fs: select: tty notification\n");
#endif
for(s = 0; s < MAXSELECTS; s++) {
int line, ops;
if(!selecttab[s].requestor)
continue;
for(f = 0; f < selecttab[s].nfds; f++) {
if(!selecttab[s].filps[f] ||
!select_match_tty(selecttab[s].filps[f]))
continue;
ops = tab2ops(f, &selecttab[s]);
line = selecttab[s].filps[f]->filp_ino->i_zone[0] & BYTE;
if((line == m->NOTIFY_ARG) &&
(m->NOTIFY_FLAGS & ops)) {
#if DEBUG_SELECT
printf("fs: select: tty notification matched\n");
#endif
select_callback(selecttab[s].filps[f], ops);
}
}
}
for(d = 0; d < NR_DEVICES; d++)
if(dmap[d].dmap_driver == m->m_source)
break;
default:
#if DEBUG_SELECT
printf("fs: select: default notification\n");
#endif
for(s = 0; s < MAXSELECTS; s++) {
int line, ops;
if(!selecttab[s].requestor)
continue;
for(f = 0; f < selecttab[s].nfds; f++) {
if(!selecttab[s].filps[f] ||
!select_match_inet(selecttab[s].filps[f]))
continue;
ops = tab2ops(f, &selecttab[s]);
line = selecttab[s].filps[f]->filp_ino->i_zone[0] & BYTE;
if((line == m->NOTIFY_ARG) &&
(m->NOTIFY_FLAGS & ops)) {
#if DEBUG_SELECT
printf("fs: select: inet notification matched\n");
#endif
select_callback(selecttab[s].filps[f], ops);
}
}
if(d >= NR_DEVICES)
return OK;
for(t = 0; t < SEL_FDS; t++)
if(!fdtypes[t].select_match && fdtypes[t].select_major == d)
break;
if(t >= SEL_FDS)
return OK;
/* We have a select callback from major device no.
* d, which corresponds to our select type t.
*/
for(s = 0; s < MAXSELECTS; s++) {
int line, ops;
if(!selecttab[s].requestor)
continue;
for(f = 0; f < selecttab[s].nfds; f++) {
if(!selecttab[s].filps[f] ||
!select_major_match(d, selecttab[s].filps[f]))
continue;
ops = tab2ops(f, &selecttab[s]);
line = selecttab[s].filps[f]->filp_ino->i_zone[0] & BYTE;
if((line == m->NOTIFY_ARG) &&
(m->NOTIFY_FLAGS & ops)) {
select_callback(selecttab[s].filps[f], ops);
}
break;
}
}
return OK;
}
@ -637,7 +635,9 @@ PUBLIC void select_forget(int proc)
}
if(s >= MAXSELECTS) {
#if DEBUG_SELECT
printf("select: cancelled select() not found");
#endif
return;
}
@ -658,17 +658,23 @@ PUBLIC void select_timeout_check(timer_t *timer)
s = tmr_arg(timer)->ta_int;
if(s < 0 || s >= MAXSELECTS) {
#if DEBUG_SELECT
printf("select: bogus slot arg to watchdog %d\n", s);
#endif
return;
}
if(!selecttab[s].requestor) {
#if DEBUG_SELECT
printf("select: no requestor in watchdog\n");
#endif
return;
}
if(selecttab[s].expiry <= 0) {
#if DEBUG_SELECT
printf("select: strange expiry value in watchdog\n", s);
#endif
return;
}

View file

@ -1,7 +1,30 @@
#include <stdio.h>
#include <fcntl.h>
#include "is.h"
#include "../../kernel/const.h"
#include "../../kernel/type.h"
/*==========================================================================*
* log_message *
*==========================================================================*/
PRIVATE void log_message(char *buf)
{
#if ENABLE_LOG
message m;
m.m_type = DIAGNOSTICS;
m.DIAG_PRINT_BUF = buf;
m.DIAG_BUF_COUNT = strlen(buf);
_sendrec(LOG_PROC_NR, &m);
#endif
return;
}
/*==========================================================================*
* do_new_kmess *
*==========================================================================*/
@ -42,6 +65,9 @@ message *m; /* notification message */
/* Now terminate the new message and print it. */
print_buf[i] = 0;
printf(print_buf);
/* Also send message to log device. */
log_message(print_buf);
}
/* Almost done, store 'next' so that we can determine what part of the
@ -67,6 +93,8 @@ PUBLIC int do_diagnostics(message *m)
vir_bytes src;
int count;
char c;
int i = 0;
static char diagbuf[1024];
/* Forward the message to the TTY driver. Inform the TTY driver about the
* original sender, so that it knows where the buffer to be printed is.
@ -87,6 +115,20 @@ PUBLIC int do_diagnostics(message *m)
diag_putc(c); /* accumulate character */
src ++;
count --;
diagbuf[i++] = c;
if(i == sizeof(diagbuf) - 1) {
diagbuf[i] = '\0';
log_message(diagbuf);
i = 0;
}
}
if(i > 0) {
/* This is safe; if i were too large,
* this would have been done above.
*/
diagbuf[i] = '\0';
log_message(diagbuf);
}
return result;

View file

@ -23,6 +23,18 @@ int main(int argc, char *argv[]) {
int i,j;
FD_ZERO(&fds);
for (i=0;i<FD_SETSIZE;i++) {
/* see if SET works */
FD_SET(i, &fds);
if(!FD_ISSET(i, &fds))
return 1;
}
FD_ZERO(&fds);
for (i=0;i<FD_SETSIZE;i++) {
/* see if ZERO works */
if(FD_ISSET(i, &fds))
return 1;
}
for (i=0;i<FD_SETSIZE;i++) {
FD_SET(i, &fds);
for(j = 0; j <= i; j++)

View file

@ -19,6 +19,7 @@ PROGRAMS= ../kernel/kernel \
../drivers/rtl8139/rtl8139 \
../drivers/fxp/fxp \
../drivers/dpeth/dpeth \
../drivers/log/log \
../servers/init/init \
# bootdev.img