From 42050e39f89d1d78aa206157dc41737c6f6396de Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Fri, 8 Jul 2005 17:30:01 +0000 Subject: [PATCH] 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. --- commands/scripts/MAKEDEV.sh | 8 +- etc/mtree/minix.tree | 3 + etc/usr/rc | 1 + kernel/klibc.c | 11 +-- kernel/table.c | 1 + lib/utils/kputc.c | 2 +- servers/fs/device.c | 20 +++-- servers/fs/dmap.c | 2 +- servers/fs/select.c | 170 +++++++++++++++++++----------------- servers/is/diag.c | 42 +++++++++ test/select/test00.c | 12 +++ tools/Makefile | 1 + 12 files changed, 176 insertions(+), 97 deletions(-) diff --git a/commands/scripts/MAKEDEV.sh b/commands/scripts/MAKEDEV.sh index 18f8693f8..cb62494d3 100755 --- a/commands/scripts/MAKEDEV.sh +++ b/commands/scripts/MAKEDEV.sh @@ -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 <&2 ex=1 diff --git a/etc/mtree/minix.tree b/etc/mtree/minix.tree index 0ab0e7376..d9e056ba4 100644 --- a/etc/mtree/minix.tree +++ b/etc/mtree/minix.tree @@ -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 diff --git a/etc/usr/rc b/etc/usr/rc index 097f8f30e..ccccd13a1 100644 --- a/etc/usr/rc +++ b/etc/usr/rc @@ -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..) diff --git a/kernel/klibc.c b/kernel/klibc.c index 07a5cb861..7d8bb8167 100644 --- a/kernel/klibc.c +++ b/kernel/klibc.c @@ -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 /* need TTY process number */ + +#include #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); } } diff --git a/kernel/table.c b/kernel/table.c index 823c2dac5..ca2401052 100755 --- a/kernel/table.c +++ b/kernel/table.c @@ -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" }, }; diff --git a/lib/utils/kputc.c b/lib/utils/kputc.c index 1c4f4ed7d..62db5326f 100644 --- a/lib/utils/kputc.c +++ b/lib/utils/kputc.c @@ -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; diff --git a/servers/fs/device.c b/servers/fs/device.c index aa8105475..ca0c213a4 100644 --- a/servers/fs/device.c +++ b/servers/fs/device.c @@ -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); } diff --git a/servers/fs/dmap.c b/servers/fs/dmap.c index 3c4e3f7c5..542ff3a0c 100644 --- a/servers/fs/dmap.c +++ b/servers/fs/dmap.c @@ -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 * *===========================================================================*/ diff --git a/servers/fs/select.c b/servers/fs/select.c index 67f9129d6..4706b3a17 100644 --- a/servers/fs/select.c +++ b/servers/fs/select.c @@ -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 #include @@ -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: @@ -123,56 +130,50 @@ PRIVATE int select_request_tty(struct filp *f, int *ops, int block) } /*===========================================================================* - * select_match_tty * + * select_request_inet * *===========================================================================*/ -PRIVATE int select_match_tty(struct filp *file) +PRIVATE int select_request_inet(struct filp *f, int *ops, int block) { - 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; + 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); + printf("select_request_inet: got reply %d from inet for %d on %d\n", + *ops, rops, f->filp_ino->i_zone[0]); + if(*ops < 0) + return SEL_ERR; + return SEL_OK; } /*===========================================================================* - * select_request_inet * + * select_request_log * *===========================================================================*/ -PRIVATE int select_request_inet(struct filp *f, int *ops, int block) +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); - printf("select_request_inet: got reply %d from inet for %d on %d\n", - *ops, rops, f->filp_ino->i_zone[0]); if(*ops < 0) return SEL_ERR; return SEL_OK; } /*===========================================================================* - * select_match_inet * + * select_major_match * *===========================================================================*/ -PRIVATE int select_match_inet(struct filp *file) +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; } diff --git a/servers/is/diag.c b/servers/is/diag.c index 96d34d938..5dd0b6e60 100644 --- a/servers/is/diag.c +++ b/servers/is/diag.c @@ -1,7 +1,30 @@ + +#include +#include + #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; diff --git a/test/select/test00.c b/test/select/test00.c index c49fb89d9..f25a9cd8c 100644 --- a/test/select/test00.c +++ b/test/select/test00.c @@ -23,6 +23,18 @@ int main(int argc, char *argv[]) { int i,j; FD_ZERO(&fds); + for (i=0;i