Report and detect exec failures using a pipe.
XXX Hardcoded values for s_ipc_to and s_ipc_sendrec.
This commit is contained in:
parent
727ce18aa8
commit
b613f5cb4b
@ -33,8 +33,6 @@ FORWARD _PROTOTYPE( void init_pci, (struct rproc *rp, int endpoint) );
|
|||||||
|
|
||||||
PRIVATE int shutting_down = FALSE;
|
PRIVATE int shutting_down = FALSE;
|
||||||
|
|
||||||
#define EXEC_FAILED 49 /* recognizable status */
|
|
||||||
|
|
||||||
extern int rs_verbose;
|
extern int rs_verbose;
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
@ -166,9 +164,14 @@ message *m_ptr; /* request message pointer */
|
|||||||
/* See if there is a free entry in the table with system processes. */
|
/* See if there is a free entry in the table with system processes. */
|
||||||
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
|
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
|
||||||
rp = &rproc[slot_nr]; /* get pointer to slot */
|
rp = &rproc[slot_nr]; /* get pointer to slot */
|
||||||
if (! rp->r_flags & RS_IN_USE) /* check if available */
|
if (!(rp->r_flags & RS_IN_USE)) /* check if available */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (slot_nr >= NR_SYS_PROCS)
|
||||||
|
{
|
||||||
|
printf("rs`do_start: driver table full\n");
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
/* Obtain command name and parameters. This is a space-separated string
|
/* Obtain command name and parameters. This is a space-separated string
|
||||||
* that looks like "/sbin/service arg1 arg2 ...". Arguments are optional.
|
* that looks like "/sbin/service arg1 arg2 ...". Arguments are optional.
|
||||||
@ -422,7 +425,7 @@ PUBLIC int do_restart(message *m_ptr)
|
|||||||
label[len]= '\0';
|
label[len]= '\0';
|
||||||
|
|
||||||
for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
|
for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
|
||||||
if (rp->r_flags & RS_IN_USE && strcmp(rp->r_label, label) == 0) {
|
if ((rp->r_flags & RS_IN_USE) && strcmp(rp->r_label, label) == 0) {
|
||||||
if(rs_verbose) printf("RS: restarting '%s' (%d)\n", label, rp->r_pid);
|
if(rs_verbose) printf("RS: restarting '%s' (%d)\n", label, rp->r_pid);
|
||||||
if (rp->r_pid >= 0)
|
if (rp->r_pid >= 0)
|
||||||
{
|
{
|
||||||
@ -433,6 +436,7 @@ PUBLIC int do_restart(message *m_ptr)
|
|||||||
}
|
}
|
||||||
rp->r_flags &= ~(RS_EXITING|RS_REFRESHING|RS_NOPINGREPLY);
|
rp->r_flags &= ~(RS_EXITING|RS_REFRESHING|RS_NOPINGREPLY);
|
||||||
r = start_service(rp, 0, &ep);
|
r = start_service(rp, 0, &ep);
|
||||||
|
if (r != OK) printf("do_restart: start_service failed: %d\n", r);
|
||||||
m_ptr->RS_ENDPOINT = ep;
|
m_ptr->RS_ENDPOINT = ep;
|
||||||
return(r);
|
return(r);
|
||||||
}
|
}
|
||||||
@ -495,7 +499,7 @@ PUBLIC void do_exit(message *m_ptr)
|
|||||||
{
|
{
|
||||||
register struct rproc *rp;
|
register struct rproc *rp;
|
||||||
pid_t exit_pid;
|
pid_t exit_pid;
|
||||||
int exit_status, r;
|
int exit_status, r, slot_nr;
|
||||||
endpoint_t ep;
|
endpoint_t ep;
|
||||||
|
|
||||||
if(rs_verbose)
|
if(rs_verbose)
|
||||||
@ -518,6 +522,32 @@ PUBLIC void do_exit(message *m_ptr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read from the exec pipe */
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
r= read(exec_pipe[0], &slot_nr, sizeof(slot_nr));
|
||||||
|
if (r == -1)
|
||||||
|
{
|
||||||
|
if (errno == -EAGAIN) /* Negative error defines */
|
||||||
|
break; /* No data */
|
||||||
|
panic("RS", "do_exit: read from exec pipe failed",
|
||||||
|
errno);
|
||||||
|
}
|
||||||
|
if (r != sizeof(slot_nr))
|
||||||
|
{
|
||||||
|
panic("RS", "do_exit: unaligned read from exec pipe",
|
||||||
|
r);
|
||||||
|
}
|
||||||
|
printf("do_exit: got slot %d\n", slot_nr);
|
||||||
|
if (slot_nr < 0 || slot_nr >= NR_SYS_PROCS)
|
||||||
|
{
|
||||||
|
panic("RS", "do_exit: bad slot number from exec pipe",
|
||||||
|
slot_nr);
|
||||||
|
}
|
||||||
|
rp= &rproc[slot_nr];
|
||||||
|
rp->r_flags |= RS_EXECFAILED;
|
||||||
|
}
|
||||||
|
|
||||||
/* Search the system process table to see who exited.
|
/* Search the system process table to see who exited.
|
||||||
* This should always succeed.
|
* This should always succeed.
|
||||||
*/
|
*/
|
||||||
@ -529,6 +559,8 @@ PUBLIC void do_exit(message *m_ptr)
|
|||||||
rproc_ptr[proc] = NULL; /* invalidate */
|
rproc_ptr[proc] = NULL; /* invalidate */
|
||||||
rp->r_pid= -1;
|
rp->r_pid= -1;
|
||||||
|
|
||||||
|
pci_del_acl(rp->r_proc_nr_e); /* Ignore errors */
|
||||||
|
|
||||||
if ((rp->r_flags & RS_EXITING) || shutting_down) {
|
if ((rp->r_flags & RS_EXITING) || shutting_down) {
|
||||||
/* No reply sent to RS_DOWN yet. */
|
/* No reply sent to RS_DOWN yet. */
|
||||||
if(rp->r_flags & RS_LATEREPLY) {
|
if(rp->r_flags & RS_LATEREPLY) {
|
||||||
@ -556,8 +588,7 @@ PUBLIC void do_exit(message *m_ptr)
|
|||||||
m_ptr->RS_ENDPOINT = ep;
|
m_ptr->RS_ENDPOINT = ep;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (WIFEXITED(exit_status) &&
|
else if (rp->r_flags & RS_EXECFAILED) {
|
||||||
WEXITSTATUS(exit_status) == EXEC_FAILED) {
|
|
||||||
rp->r_flags = 0; /* release slot */
|
rp->r_flags = 0; /* release slot */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -574,7 +605,7 @@ rp->r_restarts= 0;
|
|||||||
switch(WTERMSIG(exit_status))
|
switch(WTERMSIG(exit_status))
|
||||||
{
|
{
|
||||||
case SIGKILL: rp->r_flags |= RS_KILLED; break;
|
case SIGKILL: rp->r_flags |= RS_KILLED; break;
|
||||||
default: rp->r_flags |= RS_CRASHED; break;
|
default: rp->r_flags |= RS_SIGNALED; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -692,7 +723,7 @@ endpoint_t *endpoint;
|
|||||||
int child_proc_nr_e, child_proc_nr_n; /* child process slot */
|
int child_proc_nr_e, child_proc_nr_n; /* child process slot */
|
||||||
pid_t child_pid; /* child's process id */
|
pid_t child_pid; /* child's process id */
|
||||||
char *file_only;
|
char *file_only;
|
||||||
int s, use_copy;
|
int s, use_copy, slot_nr;
|
||||||
struct priv *privp;
|
struct priv *privp;
|
||||||
message m;
|
message m;
|
||||||
|
|
||||||
@ -718,6 +749,7 @@ endpoint_t *endpoint;
|
|||||||
* nice values.
|
* nice values.
|
||||||
*/
|
*/
|
||||||
setuid(rp->r_uid);
|
setuid(rp->r_uid);
|
||||||
|
cpf_reload(); /* Tell kernel about grant table */
|
||||||
if (!use_copy)
|
if (!use_copy)
|
||||||
{
|
{
|
||||||
execve(rp->r_argv[0], rp->r_argv, NULL); /* POSIX execute */
|
execve(rp->r_argv[0], rp->r_argv, NULL); /* POSIX execute */
|
||||||
@ -725,7 +757,11 @@ endpoint_t *endpoint;
|
|||||||
execve(file_only, rp->r_argv, NULL); /* POSIX execute */
|
execve(file_only, rp->r_argv, NULL); /* POSIX execute */
|
||||||
}
|
}
|
||||||
printf("RS: exec failed for %s: %d\n", rp->r_argv[0], errno);
|
printf("RS: exec failed for %s: %d\n", rp->r_argv[0], errno);
|
||||||
exit(EXEC_FAILED); /* terminate child */
|
slot_nr= rp-rproc;
|
||||||
|
s= write(exec_pipe[1], &slot_nr, sizeof(slot_nr));
|
||||||
|
if (s != sizeof(slot_nr))
|
||||||
|
printf("RS: write to exec pipe failed: %d/%d\n", s, errno);
|
||||||
|
exit(1); /* terminate child */
|
||||||
|
|
||||||
default: /* parent process */
|
default: /* parent process */
|
||||||
child_proc_nr_e = getnprocnr(child_pid); /* get child slot */
|
child_proc_nr_e = getnprocnr(child_pid); /* get child slot */
|
||||||
@ -914,6 +950,8 @@ struct rproc *rp;
|
|||||||
reason= "killed";
|
reason= "killed";
|
||||||
else if (rp->r_flags & RS_CRASHED)
|
else if (rp->r_flags & RS_CRASHED)
|
||||||
reason= "crashed";
|
reason= "crashed";
|
||||||
|
else if (rp->r_flags & RS_SIGNALED)
|
||||||
|
reason= "signaled";
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
@ -969,8 +1007,9 @@ struct rproc *rp;
|
|||||||
struct priv *privp;
|
struct priv *privp;
|
||||||
{
|
{
|
||||||
int i, src_bits_per_word, dst_bits_per_word, src_word, dst_word,
|
int i, src_bits_per_word, dst_bits_per_word, src_word, dst_word,
|
||||||
src_bit, call_nr;
|
src_bit, call_nr, chunk, bit, priv_id, slot_nr;
|
||||||
unsigned long mask;
|
unsigned long mask;
|
||||||
|
struct rproc *tmp_rp;
|
||||||
|
|
||||||
/* Clear s_k_call_mask */
|
/* Clear s_k_call_mask */
|
||||||
memset(privp->s_k_call_mask, '\0', sizeof(privp->s_k_call_mask));
|
memset(privp->s_k_call_mask, '\0', sizeof(privp->s_k_call_mask));
|
||||||
@ -998,6 +1037,144 @@ struct priv *privp;
|
|||||||
privp->s_k_call_mask[dst_word] |= mask;
|
privp->s_k_call_mask[dst_word] |= mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear s_ipc_to and s_ipc_sendrec */
|
||||||
|
memset(&privp->s_ipc_to, '\0', sizeof(privp->s_ipc_to));
|
||||||
|
memset(&privp->s_ipc_sendrec, '\0', sizeof(privp->s_ipc_sendrec));
|
||||||
|
|
||||||
|
if (strcmp(rp->r_label, "dp8390") == 0)
|
||||||
|
{
|
||||||
|
printf("init_privs: special code for dp8390\n");
|
||||||
|
|
||||||
|
/* Try to find inet */
|
||||||
|
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++)
|
||||||
|
{
|
||||||
|
tmp_rp = &rproc[slot_nr];
|
||||||
|
if (!(tmp_rp->r_flags & RS_IN_USE))
|
||||||
|
continue;
|
||||||
|
if (strcmp(tmp_rp->r_label, "inet") == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (slot_nr >= NR_SYS_PROCS)
|
||||||
|
{
|
||||||
|
printf("init_privs: unable to find inet\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv_id= sys_getprivid(tmp_rp->r_proc_nr_e);
|
||||||
|
if (priv_id < 0)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"init_privs: unable to get priv_id for inet: %d\n",
|
||||||
|
priv_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
||||||
|
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
||||||
|
privp->s_ipc_to.chunk[chunk] |= (1 << bit);
|
||||||
|
|
||||||
|
priv_id= sys_getprivid(RS_PROC_NR);
|
||||||
|
if (priv_id < 0)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"init_privs: unable to get priv_id for RS: %d\n",
|
||||||
|
priv_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
||||||
|
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
||||||
|
privp->s_ipc_to.chunk[chunk] |= (1 << bit);
|
||||||
|
|
||||||
|
priv_id= sys_getprivid(SYSTEM);
|
||||||
|
if (priv_id < 0)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"init_privs: unable to get priv_id for SYSTEM: %d\n",
|
||||||
|
priv_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
||||||
|
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
||||||
|
privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
|
||||||
|
|
||||||
|
priv_id= sys_getprivid(PM_PROC_NR);
|
||||||
|
if (priv_id < 0)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"init_privs: unable to get priv_id for PM: %d\n",
|
||||||
|
priv_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
||||||
|
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
||||||
|
privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
|
||||||
|
|
||||||
|
priv_id= sys_getprivid(LOG_PROC_NR);
|
||||||
|
if (priv_id < 0)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"init_privs: unable to get priv_id for LOG: %d\n",
|
||||||
|
priv_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
||||||
|
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
||||||
|
privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
|
||||||
|
|
||||||
|
priv_id= sys_getprivid(TTY_PROC_NR);
|
||||||
|
if (priv_id < 0)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"init_privs: unable to get priv_id for TTY: %d\n",
|
||||||
|
priv_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
||||||
|
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
||||||
|
privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
|
||||||
|
|
||||||
|
/* Try to find PCI */
|
||||||
|
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++)
|
||||||
|
{
|
||||||
|
tmp_rp = &rproc[slot_nr];
|
||||||
|
if (!(tmp_rp->r_flags & RS_IN_USE))
|
||||||
|
continue;
|
||||||
|
if (strcmp(tmp_rp->r_label, "pci") == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (slot_nr >= NR_SYS_PROCS)
|
||||||
|
{
|
||||||
|
printf("init_privs: unable to find PCI\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv_id= sys_getprivid(tmp_rp->r_proc_nr_e);
|
||||||
|
if (priv_id < 0)
|
||||||
|
{
|
||||||
|
printf(
|
||||||
|
"init_privs: unable to get priv_id for PCI: %d\n",
|
||||||
|
priv_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chunk= (priv_id / (sizeof(bitchunk_t)*8));
|
||||||
|
bit= (priv_id % (sizeof(bitchunk_t)*8));
|
||||||
|
privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i= 0; i<sizeof(privp->s_ipc_to)*8; i++)
|
||||||
|
{
|
||||||
|
chunk= (i / (sizeof(bitchunk_t)*8));
|
||||||
|
bit= (i % (sizeof(bitchunk_t)*8));
|
||||||
|
privp->s_ipc_to.chunk[chunk] |= (1 << bit);
|
||||||
|
}
|
||||||
|
for (i= 0; i<sizeof(privp->s_ipc_sendrec)*8; i++)
|
||||||
|
{
|
||||||
|
chunk= (i / (sizeof(bitchunk_t)*8));
|
||||||
|
bit= (i % (sizeof(bitchunk_t)*8));
|
||||||
|
privp->s_ipc_sendrec.chunk[chunk] |= (1 << bit);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user