RS changes:
- add new "control" config directive, to let drivers restart drivers (by Jorrit Herder) - fix bug causing system processes to be started twice sometimes
This commit is contained in:
parent
7c0cdc61bc
commit
4924d1a9b5
@ -1,3 +1,6 @@
|
|||||||
|
#ifndef RS_H
|
||||||
|
#define RS_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
minix/rs.h
|
minix/rs.h
|
||||||
|
|
||||||
@ -11,6 +14,14 @@ Interface to the reincarnation server
|
|||||||
#define RSS_NR_PCI_ID 32
|
#define RSS_NR_PCI_ID 32
|
||||||
#define RSS_NR_PCI_CLASS 4
|
#define RSS_NR_PCI_CLASS 4
|
||||||
#define RSS_NR_SYSTEM 2
|
#define RSS_NR_SYSTEM 2
|
||||||
|
#define RSS_NR_CONTROL 8
|
||||||
|
|
||||||
|
/* Labels are copied over separately. */
|
||||||
|
struct rss_label
|
||||||
|
{
|
||||||
|
char *l_addr;
|
||||||
|
size_t l_len;
|
||||||
|
};
|
||||||
|
|
||||||
/* Arguments needed to start a new driver or server */
|
/* Arguments needed to start a new driver or server */
|
||||||
struct rs_start
|
struct rs_start
|
||||||
@ -33,12 +44,13 @@ struct rs_start
|
|||||||
int rss_nr_pci_class;
|
int rss_nr_pci_class;
|
||||||
struct { u32_t class; u32_t mask; } rss_pci_class[RSS_NR_PCI_CLASS];
|
struct { u32_t class; u32_t mask; } rss_pci_class[RSS_NR_PCI_CLASS];
|
||||||
u32_t rss_system[RSS_NR_SYSTEM];
|
u32_t rss_system[RSS_NR_SYSTEM];
|
||||||
char *rss_label;
|
struct rss_label rss_label;
|
||||||
size_t rss_labellen;
|
|
||||||
char *rss_ipc;
|
char *rss_ipc;
|
||||||
size_t rss_ipclen;
|
size_t rss_ipclen;
|
||||||
#define RSS_VM_CALL_SIZE BITMAP_CHUNKS(VM_NCALLS)
|
#define RSS_VM_CALL_SIZE BITMAP_CHUNKS(VM_NCALLS)
|
||||||
bitchunk_t rss_vm[RSS_VM_CALL_SIZE];
|
bitchunk_t rss_vm[RSS_VM_CALL_SIZE];
|
||||||
|
int rss_nr_control;
|
||||||
|
struct rss_label rss_control[RSS_NR_CONTROL];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RF_COPY 0x01 /* Copy the brinary into RS to make it possible
|
#define RF_COPY 0x01 /* Copy the brinary into RS to make it possible
|
||||||
@ -64,3 +76,4 @@ struct rs_pci
|
|||||||
|
|
||||||
_PROTOTYPE( int minix_rs_lookup, (const char *name, endpoint_t *value));
|
_PROTOTYPE( int minix_rs_lookup, (const char *name, endpoint_t *value));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "inc.h"
|
#include "inc.h"
|
||||||
#include <timers.h>
|
#include <timers.h>
|
||||||
|
#include <minix/rs.h>
|
||||||
#include "../../kernel/priv.h"
|
#include "../../kernel/priv.h"
|
||||||
#include "../rs/manager.h"
|
#include "../rs/manager.h"
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <minix/sysutil.h>
|
#include <minix/sysutil.h>
|
||||||
#include <minix/keymap.h>
|
#include <minix/keymap.h>
|
||||||
#include <minix/bitmap.h>
|
#include <minix/bitmap.h>
|
||||||
|
#include <minix/rs.h>
|
||||||
|
|
||||||
#include <archtypes.h>
|
#include <archtypes.h>
|
||||||
#include <timers.h> /* For priv.h */
|
#include <timers.h> /* For priv.h */
|
||||||
|
@ -38,7 +38,6 @@ PUBLIC int main(void)
|
|||||||
int result; /* result to return */
|
int result; /* result to return */
|
||||||
sigset_t sigset; /* system signal set */
|
sigset_t sigset; /* system signal set */
|
||||||
int s;
|
int s;
|
||||||
uid_t euid;
|
|
||||||
|
|
||||||
/* Initialize the server, then go to work. */
|
/* Initialize the server, then go to work. */
|
||||||
init_server();
|
init_server();
|
||||||
@ -73,8 +72,12 @@ PUBLIC int main(void)
|
|||||||
sig_handler();
|
sig_handler();
|
||||||
continue;
|
continue;
|
||||||
default: /* heartbeat notification */
|
default: /* heartbeat notification */
|
||||||
if (rproc_ptr[who_p] != NULL) /* mark heartbeat time */
|
if (rproc_ptr[who_p] != NULL) { /* mark heartbeat time */
|
||||||
rproc_ptr[who_p]->r_alive_tm = m.NOTIFY_TIMESTAMP;
|
rproc_ptr[who_p]->r_alive_tm = m.NOTIFY_TIMESTAMP;
|
||||||
|
} else {
|
||||||
|
printf("Warning, RS got unexpected notify message from %d\n",
|
||||||
|
m.m_source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,17 +94,7 @@ PUBLIC int main(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only root can make calls to rs. unless it's RS_LOOKUP. */
|
/* Handler functions are responsible for permission checking. */
|
||||||
euid= getnuid(m.m_source);
|
|
||||||
if (euid != 0 && call_nr != RS_LOOKUP)
|
|
||||||
{
|
|
||||||
printf("RS: got unauthorized request %d from endpoint %d\n",
|
|
||||||
call_nr, m.m_source);
|
|
||||||
m.m_type = EPERM;
|
|
||||||
reply(who_e, &m);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(call_nr) {
|
switch(call_nr) {
|
||||||
case RS_UP: result = do_up(&m, FALSE, 0); break;
|
case RS_UP: result = do_up(&m, FALSE, 0); break;
|
||||||
case RS_UP_COPY: result = do_up(&m, TRUE, 0); break;
|
case RS_UP_COPY: result = do_up(&m, TRUE, 0); break;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Changes:
|
* Changes:
|
||||||
|
* Mar 02, 2009: Extended isolation policies (Jorrit N. Herder)
|
||||||
* Jul 22, 2005: Created (Jorrit N. Herder)
|
* Jul 22, 2005: Created (Jorrit N. Herder)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -15,7 +16,6 @@
|
|||||||
#include <minix/ds.h>
|
#include <minix/ds.h>
|
||||||
#include <minix/endpoint.h>
|
#include <minix/endpoint.h>
|
||||||
#include <minix/vm.h>
|
#include <minix/vm.h>
|
||||||
#include <minix/rs.h>
|
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
|
|
||||||
#include <timers.h> /* For priv.h */
|
#include <timers.h> /* For priv.h */
|
||||||
@ -26,6 +26,11 @@ struct rproc rproc[NR_SYS_PROCS]; /* system process table */
|
|||||||
struct rproc *rproc_ptr[NR_PROCS]; /* mapping for fast access */
|
struct rproc *rproc_ptr[NR_PROCS]; /* mapping for fast access */
|
||||||
|
|
||||||
/* Prototypes for internal functions that do the hard work. */
|
/* Prototypes for internal functions that do the hard work. */
|
||||||
|
FORWARD _PROTOTYPE( int caller_is_root, (endpoint_t endpoint) );
|
||||||
|
FORWARD _PROTOTYPE( int caller_can_control, (endpoint_t endpoint,
|
||||||
|
char *label) );
|
||||||
|
FORWARD _PROTOTYPE( int copy_label, (endpoint_t src_e,
|
||||||
|
struct rss_label *src_label, char *dst_label, size_t dst_len) );
|
||||||
FORWARD _PROTOTYPE( int start_service, (struct rproc *rp, int flags,
|
FORWARD _PROTOTYPE( int start_service, (struct rproc *rp, int flags,
|
||||||
endpoint_t *ep) );
|
endpoint_t *ep) );
|
||||||
FORWARD _PROTOTYPE( int stop_service, (struct rproc *rp,int how) );
|
FORWARD _PROTOTYPE( int stop_service, (struct rproc *rp,int how) );
|
||||||
@ -48,7 +53,95 @@ PRIVATE int shutting_down = FALSE;
|
|||||||
extern int rs_verbose;
|
extern int rs_verbose;
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* do_up *
|
* caller_is_root *
|
||||||
|
*===========================================================================*/
|
||||||
|
PRIVATE int caller_is_root(endpoint)
|
||||||
|
endpoint_t endpoint; /* caller endpoint */
|
||||||
|
{
|
||||||
|
uid_t euid;
|
||||||
|
|
||||||
|
/* Check if caller has root user ID. */
|
||||||
|
euid = getnuid(endpoint);
|
||||||
|
if (rs_verbose && euid != 0)
|
||||||
|
{
|
||||||
|
printf("RS: got unauthorized request from endpoint %d\n", endpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
return euid == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* caller_can_control *
|
||||||
|
*===========================================================================*/
|
||||||
|
PRIVATE int caller_can_control(endpoint, label)
|
||||||
|
endpoint_t endpoint;
|
||||||
|
char *label;
|
||||||
|
{
|
||||||
|
int control_allowed = 0;
|
||||||
|
register struct rproc *rp;
|
||||||
|
int c;
|
||||||
|
char *progname;
|
||||||
|
|
||||||
|
/* Find name of binary for given label. */
|
||||||
|
for (rp = BEG_RPROC_ADDR; rp < END_RPROC_ADDR; rp++) {
|
||||||
|
if (strcmp(rp->r_label, label) == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rp == END_RPROC_ADDR) return 0;
|
||||||
|
progname = strrchr(rp->r_argv[0], '/');
|
||||||
|
if (progname != NULL)
|
||||||
|
progname++;
|
||||||
|
else
|
||||||
|
progname = rp->r_argv[0];
|
||||||
|
|
||||||
|
/* Check if label is listed in caller's isolation policy. */
|
||||||
|
for (rp = BEG_RPROC_ADDR; rp < END_RPROC_ADDR; rp++) {
|
||||||
|
if (rp->r_proc_nr_e == endpoint) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rp == END_RPROC_ADDR) return 0;
|
||||||
|
if (rp->r_nr_control > 0) {
|
||||||
|
for (c = 0; c < rp->r_nr_control; c++) {
|
||||||
|
if (strcmp(rp->r_control[c], progname) == 0)
|
||||||
|
control_allowed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rs_verbose) {
|
||||||
|
printf("RS: allowing %u control over %s via policy: %s\n",
|
||||||
|
endpoint, label, control_allowed ? "yes" : "no");
|
||||||
|
}
|
||||||
|
return control_allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* copy_label *
|
||||||
|
*===========================================================================*/
|
||||||
|
PRIVATE int copy_label(src_e, src_label, dst_label, dst_len)
|
||||||
|
endpoint_t src_e;
|
||||||
|
struct rss_label *src_label;
|
||||||
|
char *dst_label;
|
||||||
|
size_t dst_len;
|
||||||
|
{
|
||||||
|
int s, len;
|
||||||
|
|
||||||
|
len = MIN(dst_len-1, src_label->l_len);
|
||||||
|
|
||||||
|
s = sys_datacopy(src_e, (vir_bytes) src_label->l_addr,
|
||||||
|
SELF, (vir_bytes) dst_label, len);
|
||||||
|
if (s != OK) return s;
|
||||||
|
|
||||||
|
dst_label[len] = 0;
|
||||||
|
|
||||||
|
if (rs_verbose)
|
||||||
|
printf("RS: do_start: using label (custom) '%s'\n", dst_label);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* do_up *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC int do_up(m_ptr, do_copy, flags)
|
PUBLIC int do_up(m_ptr, do_copy, flags)
|
||||||
message *m_ptr; /* request message pointer */
|
message *m_ptr; /* request message pointer */
|
||||||
@ -70,6 +163,9 @@ int flags; /* extra flags, if any */
|
|||||||
int r;
|
int r;
|
||||||
endpoint_t ep; /* new endpoint no. */
|
endpoint_t ep; /* new endpoint no. */
|
||||||
|
|
||||||
|
/* This call requires special privileges. */
|
||||||
|
if (!caller_is_root(m_ptr->m_source)) return(EPERM);
|
||||||
|
|
||||||
/* 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 */
|
||||||
@ -148,7 +244,7 @@ int flags; /* extra flags, if any */
|
|||||||
|
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* do_start *
|
* do_start *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC int do_start(m_ptr)
|
PUBLIC int do_start(m_ptr)
|
||||||
message *m_ptr; /* request message pointer */
|
message *m_ptr; /* request message pointer */
|
||||||
@ -169,10 +265,8 @@ message *m_ptr; /* request message pointer */
|
|||||||
struct rproc *tmp_rp;
|
struct rproc *tmp_rp;
|
||||||
struct rs_start rs_start;
|
struct rs_start rs_start;
|
||||||
|
|
||||||
/* Get the request structure */
|
/* This call requires special privileges. */
|
||||||
s= sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->RS_CMD_ADDR,
|
if (!caller_is_root(m_ptr->m_source)) return(EPERM);
|
||||||
SELF, (vir_bytes) &rs_start, sizeof(rs_start));
|
|
||||||
if (s != OK) return(s);
|
|
||||||
|
|
||||||
/* 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++) {
|
||||||
@ -186,6 +280,11 @@ message *m_ptr; /* request message pointer */
|
|||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Ok, there is space. Get the request structure. */
|
||||||
|
s= sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->RS_CMD_ADDR,
|
||||||
|
SELF, (vir_bytes) &rs_start, sizeof(rs_start));
|
||||||
|
if (s != OK) return(s);
|
||||||
|
|
||||||
/* 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.
|
||||||
*/
|
*/
|
||||||
@ -215,15 +314,12 @@ message *m_ptr; /* request message pointer */
|
|||||||
rp->r_argv[arg_count] = NULL; /* end with NULL pointer */
|
rp->r_argv[arg_count] = NULL; /* end with NULL pointer */
|
||||||
rp->r_argc = arg_count;
|
rp->r_argc = arg_count;
|
||||||
|
|
||||||
if(rs_start.rss_label) {
|
if(rs_start.rss_label.l_len > 0) {
|
||||||
int len;
|
|
||||||
/* RS_START caller has supplied a custom label for this driver. */
|
/* RS_START caller has supplied a custom label for this driver. */
|
||||||
len = MIN(sizeof(rp->r_label)-1, rs_start.rss_labellen);
|
int s = copy_label(m_ptr->m_source, &rs_start.rss_label,
|
||||||
s=sys_datacopy(m_ptr->m_source, (vir_bytes) rs_start.rss_label,
|
rp->r_label, sizeof(rp->r_label));
|
||||||
SELF, (vir_bytes) rp->r_label, len);
|
|
||||||
if(s != OK)
|
if(s != OK)
|
||||||
return s;
|
return s;
|
||||||
rp->r_label[len] = '\0';
|
|
||||||
if(rs_verbose)
|
if(rs_verbose)
|
||||||
printf("RS: do_start: using label (custom) '%s'\n", rp->r_label);
|
printf("RS: do_start: using label (custom) '%s'\n", rp->r_label);
|
||||||
} else {
|
} else {
|
||||||
@ -243,6 +339,29 @@ message *m_ptr; /* request message pointer */
|
|||||||
rp->r_argv[0], rp->r_label);
|
rp->r_argv[0], rp->r_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(rs_start.rss_nr_control > 0) {
|
||||||
|
int i, s;
|
||||||
|
if (rs_start.rss_nr_control > RSS_NR_CONTROL)
|
||||||
|
{
|
||||||
|
printf("RS: do_start: too many control labels\n");
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
for (i=0; i<rs_start.rss_nr_control; i++) {
|
||||||
|
s = copy_label(m_ptr->m_source, &rs_start.rss_control[i],
|
||||||
|
rp->r_control[i], sizeof(rp->r_control[i]));
|
||||||
|
if(s != OK)
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
rp->r_nr_control = rs_start.rss_nr_control;
|
||||||
|
|
||||||
|
if (rs_verbose) {
|
||||||
|
printf("RS: do_start: control labels:");
|
||||||
|
for (i=0; i<rp->r_nr_control; i++)
|
||||||
|
printf(" %s", rp->r_control[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for duplicates */
|
/* Check for duplicates */
|
||||||
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
|
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
|
||||||
tmp_rp = &rproc[slot_nr]; /* get pointer to slot */
|
tmp_rp = &rproc[slot_nr]; /* get pointer to slot */
|
||||||
@ -349,7 +468,7 @@ message *m_ptr; /* request message pointer */
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rs_start.rss_nr_pci_id > MAX_NR_PCI_ID)
|
if (rs_start.rss_nr_pci_id > RSS_NR_PCI_ID)
|
||||||
{
|
{
|
||||||
printf("RS: do_start: too many PCI device IDs\n");
|
printf("RS: do_start: too many PCI device IDs\n");
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
@ -363,7 +482,7 @@ message *m_ptr; /* request message pointer */
|
|||||||
printf("RS: do_start: PCI %04x/%04x\n",
|
printf("RS: do_start: PCI %04x/%04x\n",
|
||||||
rp->r_pci_id[i].vid, rp->r_pci_id[i].did);
|
rp->r_pci_id[i].vid, rp->r_pci_id[i].did);
|
||||||
}
|
}
|
||||||
if (rs_start.rss_nr_pci_class > MAX_NR_PCI_CLASS)
|
if (rs_start.rss_nr_pci_class > RSS_NR_PCI_CLASS)
|
||||||
{
|
{
|
||||||
printf("RS: do_start: too many PCI class IDs\n");
|
printf("RS: do_start: too many PCI class IDs\n");
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
@ -428,6 +547,9 @@ PUBLIC int do_down(message *m_ptr)
|
|||||||
int s, proc;
|
int s, proc;
|
||||||
char label[MAX_LABEL_LEN];
|
char label[MAX_LABEL_LEN];
|
||||||
|
|
||||||
|
/* This call requires special privileges. */
|
||||||
|
if (!caller_is_root(m_ptr->m_source)) return(EPERM);
|
||||||
|
|
||||||
len= m_ptr->RS_CMD_LEN;
|
len= m_ptr->RS_CMD_LEN;
|
||||||
if (len >= sizeof(label))
|
if (len >= sizeof(label))
|
||||||
return EINVAL; /* Too long */
|
return EINVAL; /* Too long */
|
||||||
@ -487,6 +609,12 @@ PUBLIC int do_restart(message *m_ptr)
|
|||||||
if (s != OK) return(s);
|
if (s != OK) return(s);
|
||||||
label[len]= '\0';
|
label[len]= '\0';
|
||||||
|
|
||||||
|
/* This call requires special privileges. */
|
||||||
|
if (! (caller_can_control(m_ptr->m_source, label) ||
|
||||||
|
caller_is_root(m_ptr->m_source))) {
|
||||||
|
return(EPERM);
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
@ -530,6 +658,12 @@ PUBLIC int do_refresh(message *m_ptr)
|
|||||||
if (s != OK) return(s);
|
if (s != OK) return(s);
|
||||||
label[len]= '\0';
|
label[len]= '\0';
|
||||||
|
|
||||||
|
/* This call requires special privileges. */
|
||||||
|
if (! (caller_can_control(m_ptr->m_source, label) ||
|
||||||
|
caller_is_root(m_ptr->m_source))) {
|
||||||
|
return(EPERM);
|
||||||
|
}
|
||||||
|
|
||||||
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 VERBOSE
|
#if VERBOSE
|
||||||
@ -550,6 +684,9 @@ PUBLIC int do_refresh(message *m_ptr)
|
|||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC int do_shutdown(message *m_ptr)
|
PUBLIC int do_shutdown(message *m_ptr)
|
||||||
{
|
{
|
||||||
|
/* This call requires special privileges. */
|
||||||
|
if (m_ptr != NULL && !caller_is_root(m_ptr->m_source)) return(EPERM);
|
||||||
|
|
||||||
/* Set flag so that RS server knows services shouldn't be restarted. */
|
/* Set flag so that RS server knows services shouldn't be restarted. */
|
||||||
shutting_down = TRUE;
|
shutting_down = TRUE;
|
||||||
return(OK);
|
return(OK);
|
||||||
@ -814,7 +951,7 @@ endpoint_t *endpoint;
|
|||||||
|
|
||||||
case 0: /* child process */
|
case 0: /* child process */
|
||||||
/* Try to execute the binary that has an absolute path. If this fails,
|
/* Try to execute the binary that has an absolute path. If this fails,
|
||||||
* e.g., because the root file system cannot be read, try to strip of
|
* e.g., because the root file system cannot be read, try to strip off
|
||||||
* the path, and see if the command is in RS' current working dir.
|
* the path, and see if the command is in RS' current working dir.
|
||||||
*/
|
*/
|
||||||
nice(rp->r_nice); /* Nice before setuid, to allow negative
|
nice(rp->r_nice); /* Nice before setuid, to allow negative
|
||||||
@ -826,7 +963,7 @@ endpoint_t *endpoint;
|
|||||||
{
|
{
|
||||||
execve(rp->r_argv[0], rp->r_argv, &null_env); /* POSIX execute */
|
execve(rp->r_argv[0], rp->r_argv, &null_env); /* POSIX execute */
|
||||||
file_only = strrchr(rp->r_argv[0], '/') + 1;
|
file_only = strrchr(rp->r_argv[0], '/') + 1;
|
||||||
execve(file_only, rp->r_argv, &null_env); /* POSIX execute */
|
execve(file_only, rp->r_argv, &null_env); /* 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);
|
||||||
slot_nr= rp-rproc;
|
slot_nr= rp-rproc;
|
||||||
@ -857,6 +994,7 @@ endpoint_t *endpoint;
|
|||||||
rp->r_check_tm = 0; /* not checked yet */
|
rp->r_check_tm = 0; /* not checked yet */
|
||||||
getuptime(&rp->r_alive_tm); /* currently alive */
|
getuptime(&rp->r_alive_tm); /* currently alive */
|
||||||
rp->r_stop_tm = 0; /* not exiting yet */
|
rp->r_stop_tm = 0; /* not exiting yet */
|
||||||
|
rp->r_backoff = 0; /* not to be restarted */
|
||||||
rproc_ptr[child_proc_nr_n] = rp; /* mapping for fast access */
|
rproc_ptr[child_proc_nr_n] = rp; /* mapping for fast access */
|
||||||
|
|
||||||
/* If any of the calls below fail, the RS_EXITING flag is set. This implies
|
/* If any of the calls below fail, the RS_EXITING flag is set. This implies
|
||||||
@ -994,6 +1132,9 @@ message *m_ptr;
|
|||||||
size_t len;
|
size_t len;
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
|
/* This call requires special privileges. */
|
||||||
|
if (!caller_is_root(m_ptr->m_source)) return(EPERM);
|
||||||
|
|
||||||
switch(m_ptr->m1_i1) {
|
switch(m_ptr->m1_i1) {
|
||||||
case SI_PROC_TAB:
|
case SI_PROC_TAB:
|
||||||
src_addr = (vir_bytes) rproc;
|
src_addr = (vir_bytes) rproc;
|
||||||
@ -1329,7 +1470,7 @@ struct priv *privp;
|
|||||||
|
|
||||||
src_bits_per_word= 8*sizeof(rp->r_call_mask[0]);
|
src_bits_per_word= 8*sizeof(rp->r_call_mask[0]);
|
||||||
dst_bits_per_word= 8*sizeof(privp->s_k_call_mask[0]);
|
dst_bits_per_word= 8*sizeof(privp->s_k_call_mask[0]);
|
||||||
for (src_word= 0; src_word < MAX_NR_SYSTEM; src_word++)
|
for (src_word= 0; src_word < RSS_NR_SYSTEM; src_word++)
|
||||||
{
|
{
|
||||||
for (src_bit= 0; src_bit < src_bits_per_word; src_bit++)
|
for (src_bit= 0; src_bit < src_bits_per_word; src_bit++)
|
||||||
{
|
{
|
||||||
|
@ -12,9 +12,6 @@
|
|||||||
#define MAX_NR_ARGS 4 /* maximum number of arguments */
|
#define MAX_NR_ARGS 4 /* maximum number of arguments */
|
||||||
#define MAX_RESCUE_DIR_LEN 64 /* maximum rescue dir length */
|
#define MAX_RESCUE_DIR_LEN 64 /* maximum rescue dir length */
|
||||||
|
|
||||||
#define MAX_NR_PCI_ID 32 /* maximum number of PCI device IDs */
|
|
||||||
#define MAX_NR_PCI_CLASS 4 /* maximum number of PCI class IDs */
|
|
||||||
#define MAX_NR_SYSTEM 2 /* should match RSS_NR_SYSTEM */
|
|
||||||
#define MAX_IPC_LIST 256 /* Max size of list for IPC target
|
#define MAX_IPC_LIST 256 /* Max size of list for IPC target
|
||||||
* process names
|
* process names
|
||||||
*/
|
*/
|
||||||
@ -56,14 +53,15 @@ extern struct rproc {
|
|||||||
uid_t r_uid;
|
uid_t r_uid;
|
||||||
int r_nice;
|
int r_nice;
|
||||||
int r_nr_pci_id; /* Number of PCI devices IDs */
|
int r_nr_pci_id; /* Number of PCI devices IDs */
|
||||||
struct { u16_t vid; u16_t did; } r_pci_id[MAX_NR_PCI_ID];
|
struct { u16_t vid; u16_t did; } r_pci_id[RSS_NR_PCI_ID];
|
||||||
int r_nr_pci_class; /* Number of PCI class IDs */
|
int r_nr_pci_class; /* Number of PCI class IDs */
|
||||||
struct { u32_t class; u32_t mask; } r_pci_class[MAX_NR_PCI_CLASS];
|
struct { u32_t class; u32_t mask; } r_pci_class[RSS_NR_PCI_CLASS];
|
||||||
|
|
||||||
u32_t r_call_mask[MAX_NR_SYSTEM];
|
u32_t r_call_mask[RSS_NR_SYSTEM];
|
||||||
char r_ipc_list[MAX_IPC_LIST];
|
char r_ipc_list[MAX_IPC_LIST];
|
||||||
#define R_VM_CALL_SIZE BITMAP_CHUNKS(VM_NCALLS)
|
bitchunk_t r_vm[RSS_VM_CALL_SIZE];
|
||||||
bitchunk_t r_vm[R_VM_CALL_SIZE];
|
int r_nr_control;
|
||||||
|
char r_control[RSS_NR_CONTROL][MAX_LABEL_LEN];
|
||||||
} rproc[NR_SYS_PROCS];
|
} rproc[NR_SYS_PROCS];
|
||||||
|
|
||||||
/* Mapping for fast access to the system process table. */
|
/* Mapping for fast access to the system process table. */
|
||||||
|
@ -336,6 +336,7 @@ PRIVATE void fatal(char *fmt, ...)
|
|||||||
#define KW_SYSTEM "system"
|
#define KW_SYSTEM "system"
|
||||||
#define KW_IPC "ipc"
|
#define KW_IPC "ipc"
|
||||||
#define KW_VM "vm"
|
#define KW_VM "vm"
|
||||||
|
#define KW_CONTROL "control"
|
||||||
|
|
||||||
FORWARD void do_driver(config_t *cpe, config_t *config);
|
FORWARD void do_driver(config_t *cpe, config_t *config);
|
||||||
|
|
||||||
@ -370,27 +371,27 @@ PRIVATE void do_class(config_t *cpe, config_t *config)
|
|||||||
{
|
{
|
||||||
if (!(cp->flags & CFG_SUBLIST))
|
if (!(cp->flags & CFG_SUBLIST))
|
||||||
{
|
{
|
||||||
fatal("do_class: expected list at %s:%d\n",
|
fatal("do_class: expected list at %s:%d",
|
||||||
cp->file, cp->line);
|
cp->file, cp->line);
|
||||||
}
|
}
|
||||||
cp1= cp->list;
|
cp1= cp->list;
|
||||||
if ((cp1->flags & CFG_STRING) ||
|
if ((cp1->flags & CFG_STRING) ||
|
||||||
(cp1->flags & CFG_SUBLIST))
|
(cp1->flags & CFG_SUBLIST))
|
||||||
{
|
{
|
||||||
fatal("do_class: expected word at %s:%d\n",
|
fatal("do_class: expected word at %s:%d",
|
||||||
cp1->file, cp1->line);
|
cp1->file, cp1->line);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* At this place we expect the word 'driver' */
|
/* At this place we expect the word 'driver' */
|
||||||
if (strcmp(cp1->word, KW_DRIVER) != 0)
|
if (strcmp(cp1->word, KW_DRIVER) != 0)
|
||||||
fatal("do_class: exected word '%S' at %s:%d\n",
|
fatal("do_class: exected word '%S' at %s:%d",
|
||||||
KW_DRIVER, cp1->file, cp1->line);
|
KW_DRIVER, cp1->file, cp1->line);
|
||||||
|
|
||||||
cp1= cp1->next;
|
cp1= cp1->next;
|
||||||
if ((cp1->flags & CFG_STRING) ||
|
if ((cp1->flags & CFG_STRING) ||
|
||||||
(cp1->flags & CFG_SUBLIST))
|
(cp1->flags & CFG_SUBLIST))
|
||||||
{
|
{
|
||||||
fatal("do_class: expected word at %s:%d\n",
|
fatal("do_class: expected word at %s:%d",
|
||||||
cp1->file, cp1->line);
|
cp1->file, cp1->line);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,7 +402,7 @@ PRIVATE void do_class(config_t *cpe, config_t *config)
|
|||||||
if (cp == NULL)
|
if (cp == NULL)
|
||||||
{
|
{
|
||||||
fatal(
|
fatal(
|
||||||
"do_class: no entry found for class '%s' at %s:%d\n",
|
"do_class: no entry found for class '%s' at %s:%d",
|
||||||
cpe->word, cpe->file, cpe->line);
|
cpe->word, cpe->file, cpe->line);
|
||||||
}
|
}
|
||||||
do_driver(cp1->next, config);
|
do_driver(cp1->next, config);
|
||||||
@ -838,7 +839,7 @@ PRIVATE void do_system(config_t *cpe)
|
|||||||
if (call_nr < KERNEL_CALL)
|
if (call_nr < KERNEL_CALL)
|
||||||
{
|
{
|
||||||
fatal(
|
fatal(
|
||||||
"do_system: bad call number %d in system tab for '%s'\n",
|
"do_system: bad call number %d in system tab for '%s'",
|
||||||
call_nr, system_tab[i].label);
|
call_nr, system_tab[i].label);
|
||||||
}
|
}
|
||||||
call_nr -= KERNEL_CALL;
|
call_nr -= KERNEL_CALL;
|
||||||
@ -849,13 +850,43 @@ PRIVATE void do_system(config_t *cpe)
|
|||||||
if (word >= RSS_NR_SYSTEM)
|
if (word >= RSS_NR_SYSTEM)
|
||||||
{
|
{
|
||||||
fatal(
|
fatal(
|
||||||
"do_system: RSS_NR_SYSTEM is too small (%d needed)\n",
|
"do_system: RSS_NR_SYSTEM is too small (%d needed)",
|
||||||
word+1);
|
word+1);
|
||||||
}
|
}
|
||||||
rs_start.rss_system[word] |= mask;
|
rs_start.rss_system[word] |= mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PRIVATE void do_control(config_t *cpe)
|
||||||
|
{
|
||||||
|
int nr_control = 0;
|
||||||
|
|
||||||
|
/* Process a list of 'control' labels. */
|
||||||
|
for (; cpe; cpe= cpe->next)
|
||||||
|
{
|
||||||
|
if (cpe->flags & CFG_SUBLIST)
|
||||||
|
{
|
||||||
|
fatal("do_control: unexpected sublist at %s:%d",
|
||||||
|
cpe->file, cpe->line);
|
||||||
|
}
|
||||||
|
if (cpe->flags & CFG_STRING)
|
||||||
|
{
|
||||||
|
fatal("do_control: unexpected string at %s:%d",
|
||||||
|
cpe->file, cpe->line);
|
||||||
|
}
|
||||||
|
if (nr_control >= RSS_NR_CONTROL)
|
||||||
|
{
|
||||||
|
fatal(
|
||||||
|
"do_control: RSS_NR_CONTROL is too small (%d needed)",
|
||||||
|
nr_control+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
rs_start.rss_control[nr_control].l_addr = cpe->word;
|
||||||
|
rs_start.rss_control[nr_control].l_len = strlen(cpe->word);
|
||||||
|
rs_start.rss_nr_control = ++nr_control;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PRIVATE void do_driver(config_t *cpe, config_t *config)
|
PRIVATE void do_driver(config_t *cpe, config_t *config)
|
||||||
{
|
{
|
||||||
config_t *cp;
|
config_t *cp;
|
||||||
@ -865,13 +896,13 @@ PRIVATE void do_driver(config_t *cpe, config_t *config)
|
|||||||
*/
|
*/
|
||||||
if (!(cpe->flags & CFG_SUBLIST))
|
if (!(cpe->flags & CFG_SUBLIST))
|
||||||
{
|
{
|
||||||
fatal("do_driver: expected list at %s:%d\n",
|
fatal("do_driver: expected list at %s:%d",
|
||||||
cpe->file, cpe->line);
|
cpe->file, cpe->line);
|
||||||
}
|
}
|
||||||
if (cpe->next != NULL)
|
if (cpe->next != NULL)
|
||||||
{
|
{
|
||||||
cpe= cpe->next;
|
cpe= cpe->next;
|
||||||
fatal("do_driver: expected end of list at %s:%d\n",
|
fatal("do_driver: expected end of list at %s:%d",
|
||||||
cpe->file, cpe->line);
|
cpe->file, cpe->line);
|
||||||
}
|
}
|
||||||
cpe= cpe->list;
|
cpe= cpe->list;
|
||||||
@ -881,13 +912,13 @@ PRIVATE void do_driver(config_t *cpe, config_t *config)
|
|||||||
{
|
{
|
||||||
if (!(cp->flags & CFG_SUBLIST))
|
if (!(cp->flags & CFG_SUBLIST))
|
||||||
{
|
{
|
||||||
fatal("do_driver: expected list at %s:%d\n",
|
fatal("do_driver: expected list at %s:%d",
|
||||||
cp->file, cp->line);
|
cp->file, cp->line);
|
||||||
}
|
}
|
||||||
cpe= cp->list;
|
cpe= cp->list;
|
||||||
if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
|
if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
|
||||||
{
|
{
|
||||||
fatal("do_driver: expected word at %s:%d\n",
|
fatal("do_driver: expected word at %s:%d",
|
||||||
cpe->file, cpe->line);
|
cpe->file, cpe->line);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -936,7 +967,11 @@ PRIVATE void do_driver(config_t *cpe, config_t *config)
|
|||||||
do_vm(cpe->next);
|
do_vm(cpe->next);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (strcmp(cpe->word, KW_CONTROL) == 0)
|
||||||
|
{
|
||||||
|
do_control(cpe->next);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,25 +992,25 @@ PRIVATE void do_config(char *label, char *filename)
|
|||||||
{
|
{
|
||||||
if (!(cp->flags & CFG_SUBLIST))
|
if (!(cp->flags & CFG_SUBLIST))
|
||||||
{
|
{
|
||||||
fatal("do_config: expected list at %s:%d\n",
|
fatal("do_config: expected list at %s:%d",
|
||||||
cp->file, cp->line);
|
cp->file, cp->line);
|
||||||
}
|
}
|
||||||
cpe= cp->list;
|
cpe= cp->list;
|
||||||
if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
|
if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
|
||||||
{
|
{
|
||||||
fatal("do_config: expected word at %s:%d\n",
|
fatal("do_config: expected word at %s:%d",
|
||||||
cpe->file, cpe->line);
|
cpe->file, cpe->line);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* At this place we expect the word 'driver' */
|
/* At this place we expect the word 'driver' */
|
||||||
if (strcmp(cpe->word, KW_DRIVER) != 0)
|
if (strcmp(cpe->word, KW_DRIVER) != 0)
|
||||||
fatal("do_config: exected word '%S' at %s:%d\n",
|
fatal("do_config: exected word '%S' at %s:%d",
|
||||||
KW_DRIVER, cpe->file, cpe->line);
|
KW_DRIVER, cpe->file, cpe->line);
|
||||||
|
|
||||||
cpe= cpe->next;
|
cpe= cpe->next;
|
||||||
if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
|
if ((cpe->flags & CFG_STRING) || (cpe->flags & CFG_SUBLIST))
|
||||||
{
|
{
|
||||||
fatal("do_config: expected word at %s:%d\n",
|
fatal("do_config: expected word at %s:%d",
|
||||||
cpe->file, cpe->line);
|
cpe->file, cpe->line);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -987,7 +1022,7 @@ PRIVATE void do_config(char *label, char *filename)
|
|||||||
{
|
{
|
||||||
fprintf(stderr, "service: driver '%s' not found in config\n",
|
fprintf(stderr, "service: driver '%s' not found in config\n",
|
||||||
label);
|
label);
|
||||||
return;
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpe= cpe->next;
|
cpe= cpe->next;
|
||||||
@ -1052,11 +1087,11 @@ PUBLIC int main(int argc, char **argv)
|
|||||||
rs_start.rss_period= req_period;
|
rs_start.rss_period= req_period;
|
||||||
rs_start.rss_script= req_script;
|
rs_start.rss_script= req_script;
|
||||||
if(req_label) {
|
if(req_label) {
|
||||||
rs_start.rss_label = req_label;
|
rs_start.rss_label.l_addr = req_label;
|
||||||
rs_start.rss_labellen = strlen(req_label);
|
rs_start.rss_label.l_len = strlen(req_label);
|
||||||
} else {
|
} else {
|
||||||
rs_start.rss_label = progname;
|
rs_start.rss_label.l_addr = progname;
|
||||||
rs_start.rss_labellen = strlen(progname);
|
rs_start.rss_label.l_len = strlen(progname);
|
||||||
}
|
}
|
||||||
if (req_script)
|
if (req_script)
|
||||||
rs_start.rss_scriptlen= strlen(req_script);
|
rs_start.rss_scriptlen= strlen(req_script);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user