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
7 changed files with 244 additions and 62 deletions
|
@ -1,3 +1,6 @@
|
|||
#ifndef RS_H
|
||||
#define RS_H
|
||||
|
||||
/*
|
||||
minix/rs.h
|
||||
|
||||
|
@ -11,6 +14,14 @@ Interface to the reincarnation server
|
|||
#define RSS_NR_PCI_ID 32
|
||||
#define RSS_NR_PCI_CLASS 4
|
||||
#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 */
|
||||
struct rs_start
|
||||
|
@ -33,12 +44,13 @@ struct rs_start
|
|||
int 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];
|
||||
char *rss_label;
|
||||
size_t rss_labellen;
|
||||
struct rss_label rss_label;
|
||||
char *rss_ipc;
|
||||
size_t rss_ipclen;
|
||||
#define RSS_VM_CALL_SIZE BITMAP_CHUNKS(VM_NCALLS)
|
||||
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
|
||||
|
@ -64,3 +76,4 @@ struct rs_pci
|
|||
|
||||
_PROTOTYPE( int minix_rs_lookup, (const char *name, endpoint_t *value));
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "inc.h"
|
||||
#include <timers.h>
|
||||
#include <minix/rs.h>
|
||||
#include "../../kernel/priv.h"
|
||||
#include "../rs/manager.h"
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <minix/sysutil.h>
|
||||
#include <minix/keymap.h>
|
||||
#include <minix/bitmap.h>
|
||||
#include <minix/rs.h>
|
||||
|
||||
#include <archtypes.h>
|
||||
#include <timers.h> /* For priv.h */
|
||||
|
|
|
@ -38,7 +38,6 @@ PUBLIC int main(void)
|
|||
int result; /* result to return */
|
||||
sigset_t sigset; /* system signal set */
|
||||
int s;
|
||||
uid_t euid;
|
||||
|
||||
/* Initialize the server, then go to work. */
|
||||
init_server();
|
||||
|
@ -73,8 +72,12 @@ PUBLIC int main(void)
|
|||
sig_handler();
|
||||
continue;
|
||||
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;
|
||||
} else {
|
||||
printf("Warning, RS got unexpected notify message from %d\n",
|
||||
m.m_source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,17 +94,7 @@ PUBLIC int main(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Only root can make calls to rs. unless it's RS_LOOKUP. */
|
||||
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;
|
||||
}
|
||||
|
||||
/* Handler functions are responsible for permission checking. */
|
||||
switch(call_nr) {
|
||||
case RS_UP: result = do_up(&m, FALSE, 0); break;
|
||||
case RS_UP_COPY: result = do_up(&m, TRUE, 0); break;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Changes:
|
||||
* Mar 02, 2009: Extended isolation policies (Jorrit N. Herder)
|
||||
* Jul 22, 2005: Created (Jorrit N. Herder)
|
||||
*/
|
||||
|
||||
|
@ -15,7 +16,6 @@
|
|||
#include <minix/ds.h>
|
||||
#include <minix/endpoint.h>
|
||||
#include <minix/vm.h>
|
||||
#include <minix/rs.h>
|
||||
#include <lib.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 */
|
||||
|
||||
/* 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,
|
||||
endpoint_t *ep) );
|
||||
FORWARD _PROTOTYPE( int stop_service, (struct rproc *rp,int how) );
|
||||
|
@ -48,7 +53,95 @@ PRIVATE int shutting_down = FALSE;
|
|||
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)
|
||||
message *m_ptr; /* request message pointer */
|
||||
|
@ -70,6 +163,9 @@ int flags; /* extra flags, if any */
|
|||
int r;
|
||||
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. */
|
||||
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
|
||||
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)
|
||||
message *m_ptr; /* request message pointer */
|
||||
|
@ -169,10 +265,8 @@ message *m_ptr; /* request message pointer */
|
|||
struct rproc *tmp_rp;
|
||||
struct rs_start rs_start;
|
||||
|
||||
/* 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);
|
||||
/* 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. */
|
||||
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
|
||||
|
@ -186,6 +280,11 @@ message *m_ptr; /* request message pointer */
|
|||
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
|
||||
* 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_argc = arg_count;
|
||||
|
||||
if(rs_start.rss_label) {
|
||||
int len;
|
||||
if(rs_start.rss_label.l_len > 0) {
|
||||
/* RS_START caller has supplied a custom label for this driver. */
|
||||
len = MIN(sizeof(rp->r_label)-1, rs_start.rss_labellen);
|
||||
s=sys_datacopy(m_ptr->m_source, (vir_bytes) rs_start.rss_label,
|
||||
SELF, (vir_bytes) rp->r_label, len);
|
||||
int s = copy_label(m_ptr->m_source, &rs_start.rss_label,
|
||||
rp->r_label, sizeof(rp->r_label));
|
||||
if(s != OK)
|
||||
return s;
|
||||
rp->r_label[len] = '\0';
|
||||
if(rs_verbose)
|
||||
printf("RS: do_start: using label (custom) '%s'\n", rp->r_label);
|
||||
} else {
|
||||
|
@ -243,6 +339,29 @@ message *m_ptr; /* request message pointer */
|
|||
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 */
|
||||
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
|
||||
tmp_rp = &rproc[slot_nr]; /* get pointer to slot */
|
||||
|
@ -349,7 +468,7 @@ message *m_ptr; /* request message pointer */
|
|||
#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");
|
||||
return EINVAL;
|
||||
|
@ -363,7 +482,7 @@ message *m_ptr; /* request message pointer */
|
|||
printf("RS: do_start: PCI %04x/%04x\n",
|
||||
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");
|
||||
return EINVAL;
|
||||
|
@ -428,6 +547,9 @@ PUBLIC int do_down(message *m_ptr)
|
|||
int s, proc;
|
||||
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;
|
||||
if (len >= sizeof(label))
|
||||
return EINVAL; /* Too long */
|
||||
|
@ -487,6 +609,12 @@ PUBLIC int do_restart(message *m_ptr)
|
|||
if (s != OK) return(s);
|
||||
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++) {
|
||||
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);
|
||||
|
@ -530,6 +658,12 @@ PUBLIC int do_refresh(message *m_ptr)
|
|||
if (s != OK) return(s);
|
||||
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++) {
|
||||
if (rp->r_flags & RS_IN_USE && strcmp(rp->r_label, label) == 0) {
|
||||
#if VERBOSE
|
||||
|
@ -550,6 +684,9 @@ PUBLIC int do_refresh(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. */
|
||||
shutting_down = TRUE;
|
||||
return(OK);
|
||||
|
@ -814,7 +951,7 @@ endpoint_t *endpoint;
|
|||
|
||||
case 0: /* child process */
|
||||
/* 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.
|
||||
*/
|
||||
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 */
|
||||
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);
|
||||
slot_nr= rp-rproc;
|
||||
|
@ -857,6 +994,7 @@ endpoint_t *endpoint;
|
|||
rp->r_check_tm = 0; /* not checked yet */
|
||||
getuptime(&rp->r_alive_tm); /* currently alive */
|
||||
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 */
|
||||
|
||||
/* 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;
|
||||
int s;
|
||||
|
||||
/* This call requires special privileges. */
|
||||
if (!caller_is_root(m_ptr->m_source)) return(EPERM);
|
||||
|
||||
switch(m_ptr->m1_i1) {
|
||||
case SI_PROC_TAB:
|
||||
src_addr = (vir_bytes) rproc;
|
||||
|
@ -1329,7 +1470,7 @@ struct priv *privp;
|
|||
|
||||
src_bits_per_word= 8*sizeof(rp->r_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++)
|
||||
{
|
||||
|
|
|
@ -12,9 +12,6 @@
|
|||
#define MAX_NR_ARGS 4 /* maximum number of arguments */
|
||||
#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
|
||||
* process names
|
||||
*/
|
||||
|
@ -56,14 +53,15 @@ extern struct rproc {
|
|||
uid_t r_uid;
|
||||
int r_nice;
|
||||
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 */
|
||||
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];
|
||||
#define R_VM_CALL_SIZE BITMAP_CHUNKS(VM_NCALLS)
|
||||
bitchunk_t r_vm[R_VM_CALL_SIZE];
|
||||
bitchunk_t r_vm[RSS_VM_CALL_SIZE];
|
||||
int r_nr_control;
|
||||
char r_control[RSS_NR_CONTROL][MAX_LABEL_LEN];
|
||||
} rproc[NR_SYS_PROCS];
|
||||
|
||||
/* Mapping for fast access to the system process table. */
|
||||
|
|
|
@ -336,6 +336,7 @@ PRIVATE void fatal(char *fmt, ...)
|
|||
#define KW_SYSTEM "system"
|
||||
#define KW_IPC "ipc"
|
||||
#define KW_VM "vm"
|
||||
#define KW_CONTROL "control"
|
||||
|
||||
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))
|
||||
{
|
||||
fatal("do_class: expected list at %s:%d\n",
|
||||
fatal("do_class: expected list at %s:%d",
|
||||
cp->file, cp->line);
|
||||
}
|
||||
cp1= cp->list;
|
||||
if ((cp1->flags & CFG_STRING) ||
|
||||
(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);
|
||||
}
|
||||
|
||||
/* At this place we expect the word 'driver' */
|
||||
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);
|
||||
|
||||
cp1= cp1->next;
|
||||
if ((cp1->flags & CFG_STRING) ||
|
||||
(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);
|
||||
}
|
||||
|
||||
|
@ -401,7 +402,7 @@ PRIVATE void do_class(config_t *cpe, config_t *config)
|
|||
if (cp == NULL)
|
||||
{
|
||||
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);
|
||||
}
|
||||
do_driver(cp1->next, config);
|
||||
|
@ -838,7 +839,7 @@ PRIVATE void do_system(config_t *cpe)
|
|||
if (call_nr < KERNEL_CALL)
|
||||
{
|
||||
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 -= KERNEL_CALL;
|
||||
|
@ -849,13 +850,43 @@ PRIVATE void do_system(config_t *cpe)
|
|||
if (word >= RSS_NR_SYSTEM)
|
||||
{
|
||||
fatal(
|
||||
"do_system: RSS_NR_SYSTEM is too small (%d needed)\n",
|
||||
"do_system: RSS_NR_SYSTEM is too small (%d needed)",
|
||||
word+1);
|
||||
}
|
||||
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)
|
||||
{
|
||||
config_t *cp;
|
||||
|
@ -865,13 +896,13 @@ PRIVATE void do_driver(config_t *cpe, config_t *config)
|
|||
*/
|
||||
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);
|
||||
}
|
||||
if (cpe->next != NULL)
|
||||
{
|
||||
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= cpe->list;
|
||||
|
@ -881,13 +912,13 @@ PRIVATE void do_driver(config_t *cpe, config_t *config)
|
|||
{
|
||||
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);
|
||||
}
|
||||
cpe= cp->list;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -936,7 +967,11 @@ PRIVATE void do_driver(config_t *cpe, config_t *config)
|
|||
do_vm(cpe->next);
|
||||
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))
|
||||
{
|
||||
fatal("do_config: expected list at %s:%d\n",
|
||||
fatal("do_config: expected list at %s:%d",
|
||||
cp->file, cp->line);
|
||||
}
|
||||
cpe= cp->list;
|
||||
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);
|
||||
}
|
||||
|
||||
/* At this place we expect the word 'driver' */
|
||||
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);
|
||||
|
||||
cpe= cpe->next;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -987,7 +1022,7 @@ PRIVATE void do_config(char *label, char *filename)
|
|||
{
|
||||
fprintf(stderr, "service: driver '%s' not found in config\n",
|
||||
label);
|
||||
return;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cpe= cpe->next;
|
||||
|
@ -1052,11 +1087,11 @@ PUBLIC int main(int argc, char **argv)
|
|||
rs_start.rss_period= req_period;
|
||||
rs_start.rss_script= req_script;
|
||||
if(req_label) {
|
||||
rs_start.rss_label = req_label;
|
||||
rs_start.rss_labellen = strlen(req_label);
|
||||
rs_start.rss_label.l_addr = req_label;
|
||||
rs_start.rss_label.l_len = strlen(req_label);
|
||||
} else {
|
||||
rs_start.rss_label = progname;
|
||||
rs_start.rss_labellen = strlen(progname);
|
||||
rs_start.rss_label.l_addr = progname;
|
||||
rs_start.rss_label.l_len = strlen(progname);
|
||||
}
|
||||
if (req_script)
|
||||
rs_start.rss_scriptlen= strlen(req_script);
|
||||
|
|
Loading…
Reference in a new issue