Kernel: make SIGKMESS target process list dynamic
The set of processes to which a SIGKMESS signal is sent whenever new diagnostics messages are added to the kernel's message buffer, is now no longer hardcoded. Instead, processes can (un)register themselves to receive such notifications, by means of sys_diagctl(). Change-Id: I9d6ac006a5d9bbfad2757587a068fc1ec3cc083e
This commit is contained in:
@@ -411,7 +411,7 @@ kinfo_t *pre_init(int argc, char **argv)
|
||||
* ensure this). The following methods are used in that context. Once we jump to kmain they are no
|
||||
* longer used and the "real" implementations are visible
|
||||
*/
|
||||
int send_sig(endpoint_t proc_nr, int sig_nr) { return 0; }
|
||||
void send_diag_sig(void) { }
|
||||
void minix_shutdown(minix_timer_t *t) { arch_shutdown(RBT_PANIC); }
|
||||
void busy_delay_ms(int x) { }
|
||||
int raise(int n) { panic("raise(%d)\n", n); }
|
||||
|
||||
@@ -245,7 +245,7 @@ kinfo_t *pre_init(u32_t magic, u32_t ebx)
|
||||
return &kinfo;
|
||||
}
|
||||
|
||||
int send_sig(endpoint_t proc_nr, int sig_nr) { return 0; }
|
||||
void send_diag_sig(void) { }
|
||||
void minix_shutdown(minix_timer_t *t) { arch_shutdown(RBT_PANIC); }
|
||||
void busy_delay_ms(int x) { }
|
||||
int raise(int sig) { panic("raise(%d)\n", sig); }
|
||||
|
||||
@@ -45,6 +45,8 @@ struct priv {
|
||||
minix_timer_t s_alarm_timer; /* synchronous alarm timer */
|
||||
reg_t *s_stack_guard; /* stack guard word for kernel tasks */
|
||||
|
||||
char s_diag_sig; /* send a SIGKMESS when diagnostics arrive? */
|
||||
|
||||
int s_nr_io_range; /* allowed I/O ports */
|
||||
struct io_range s_io_tab[NR_IO_RANGE];
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ void fill_sendto_mask(const struct proc *rc, sys_map_t *map);
|
||||
int send_sig(endpoint_t proc_nr, int sig_nr);
|
||||
void cause_sig(proc_nr_t proc_nr, int sig_nr);
|
||||
void sig_delay_done(struct proc *rp);
|
||||
void send_diag_sig(void);
|
||||
void kernel_call(message *m_user, struct proc * caller);
|
||||
void system_init(void);
|
||||
void clear_endpoint(struct proc *rc);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* send_sig: send a signal directly to a system process
|
||||
* cause_sig: take action to cause a signal to occur via a signal mgr
|
||||
* sig_delay_done: tell PM that a process is not sending
|
||||
* send_diag_sig: send a diagnostics signal to interested processes
|
||||
* get_randomness: accumulate randomness in a buffer
|
||||
* clear_endpoint: remove a process' ability to send and receive messages
|
||||
* sched_proc: schedule a process
|
||||
@@ -464,6 +465,25 @@ void sig_delay_done(struct proc *rp)
|
||||
cause_sig(proc_nr(rp), SIGSNDELAY);
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* send_diag_sig *
|
||||
*===========================================================================*/
|
||||
void send_diag_sig(void)
|
||||
{
|
||||
/* Send a SIGKMESS signal to all processes in receiving updates about new
|
||||
* diagnostics messages.
|
||||
*/
|
||||
struct priv *privp;
|
||||
endpoint_t ep;
|
||||
|
||||
for (privp = BEG_PRIV_ADDR; privp < END_PRIV_ADDR; privp++) {
|
||||
if (privp->s_proc_nr != NONE && privp->s_diag_sig == TRUE) {
|
||||
ep = proc_addr(privp->s_proc_nr)->p_endpoint;
|
||||
send_sig(ep, SIGKMESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
* clear_ipc *
|
||||
*===========================================================================*/
|
||||
|
||||
@@ -42,6 +42,21 @@ int do_diagctl(struct proc * caller, message * m_ptr)
|
||||
return EINVAL;
|
||||
proc_stacktrace(proc_addr(proc_nr));
|
||||
return OK;
|
||||
case DIAGCTL_CODE_REGISTER:
|
||||
if (!(priv(caller)->s_flags & SYS_PROC))
|
||||
return EPERM;
|
||||
priv(caller)->s_diag_sig = TRUE;
|
||||
/* If the message log is not empty, send a first notification
|
||||
* immediately. After bootup the log is basically never empty.
|
||||
*/
|
||||
if (kmess.km_size > 0 && !kinfo.do_serial_debug)
|
||||
send_sig(caller->p_endpoint, SIGKMESS);
|
||||
return OK;
|
||||
case DIAGCTL_CODE_UNREGISTER:
|
||||
if (!(priv(caller)->s_flags & SYS_PROC))
|
||||
return EPERM;
|
||||
priv(caller)->s_diag_sig = FALSE;
|
||||
return OK;
|
||||
default:
|
||||
printf("do_diagctl: invalid request %d\n", m_ptr->DIAGCTL_CODE);
|
||||
return(EINVAL);
|
||||
|
||||
@@ -116,6 +116,7 @@ int do_privctl(struct proc * caller, message * m_ptr)
|
||||
reset_kernel_timer(&priv(rp)->s_alarm_timer); /* - alarm */
|
||||
priv(rp)->s_asyntab= -1; /* - asynsends */
|
||||
priv(rp)->s_asynsize= 0;
|
||||
priv(rp)->s_diag_sig = FALSE; /* no request for diag sigs */
|
||||
|
||||
/* Set defaults for privilege bitmaps. */
|
||||
priv(rp)->s_flags= DSRV_F; /* privilege flags */
|
||||
|
||||
@@ -161,6 +161,7 @@ static void adjust_priv_slot(struct priv *privp, struct priv *from_privp)
|
||||
privp->s_int_pending = from_privp->s_int_pending;
|
||||
privp->s_sig_pending = from_privp->s_sig_pending;
|
||||
privp->s_alarm_timer = from_privp->s_alarm_timer;
|
||||
privp->s_diag_sig = from_privp->s_diag_sig;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
||||
@@ -55,7 +55,7 @@ void kputc(c)
|
||||
int c; /* character to append */
|
||||
{
|
||||
/* Accumulate a single character for a kernel message. Send a notification
|
||||
* to the output driver if an END_OF_KMESS is encountered.
|
||||
* to the output drivers if an END_OF_KMESS is encountered.
|
||||
*/
|
||||
if (c != END_OF_KMESS) {
|
||||
int maxblpos = sizeof(kmess.kmess_buf) - 2;
|
||||
@@ -75,18 +75,9 @@ int c; /* character to append */
|
||||
memmove(kmess.kmess_buf,
|
||||
kmess.kmess_buf+1, sizeof(kmess.kmess_buf)-1);
|
||||
} else kmess.blpos++;
|
||||
} else {
|
||||
int p;
|
||||
endpoint_t outprocs[] = OUTPUT_PROCS_ARRAY;
|
||||
if(!(kinfo.minix_panicing || kinfo.do_serial_debug)) {
|
||||
for(p = 0; outprocs[p] != NONE; p++) {
|
||||
if(isokprocn(outprocs[p])) {
|
||||
send_sig(outprocs[p], SIGKMESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!(kinfo.minix_panicing || kinfo.do_serial_debug)) {
|
||||
send_diag_sig();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
||||
Reference in New Issue
Block a user