PRIVATE char command[4096];
/* Arguments for RS to start a new service */
-PRIVATE endpoint_t rss_scheduler;
-PRIVATE unsigned rss_priority;
-PRIVATE unsigned rss_quantum;
PRIVATE struct rs_start rs_start;
/* An error occurred. Report the problem, print the usage, and exit.
app_name, OPT_COPY, OPT_REUSE, OPT_NOBLOCK, OPT_REPLICA, SELF_BINARY,
ARG_ARGS, ARG_DEV, ARG_DEVSTYLE, ARG_PERIOD, ARG_SCRIPT,
ARG_LABELNAME, ARG_CONFIG, ARG_LU_STATE, ARG_LU_MAXTIME);
- fprintf(stderr, " %s down label\n", app_name);
- fprintf(stderr, " %s refresh label\n", app_name);
- fprintf(stderr, " %s restart label\n", app_name);
- fprintf(stderr, " %s clone label\n", app_name);
+ fprintf(stderr, " %s down <label>\n", app_name);
+ fprintf(stderr, " %s refresh <label>\n", app_name);
+ fprintf(stderr, " %s restart <label>\n", app_name);
+ fprintf(stderr, " %s clone <label>\n", app_name);
fprintf(stderr, " %s shutdown\n", app_name);
fprintf(stderr, "\n");
}
req_nr = RS_RQ_BASE + req_type;
}
- rs_start.rss_flags = 0;
+ rs_start.rss_flags = RSS_SYS_BASIC_CALLS | RSS_VM_BASIC_CALLS;
if (req_nr == RS_UP || req_nr == RS_UPDATE || req_nr == RS_EDIT) {
u32_t system_hz;
- rs_start.rss_flags= RSS_IPC_VALID;
if (c_flag)
rs_start.rss_flags |= RSS_COPY;
rs_start.rss_flags |= RSS_SELF_LU;
}
- if(req_nr == RS_EDIT) {
- /* Edit action needs no configuration file. */
- req_config = NULL;
- }
-
if (do_run)
{
/* Set default recovery script for RUN */
#define KW_SERVICE "service"
#define KW_UID "uid"
+#define KW_SIGMGR "sigmgr"
#define KW_SCHEDULER "scheduler"
#define KW_PRIORITY "priority"
#define KW_QUANTUM "quantum"
#define KW_IPC "ipc"
#define KW_VM "vm"
#define KW_CONTROL "control"
+#define KW_ALL "ALL"
+#define KW_ALL_SYS "ALL_SYS"
+#define KW_NONE "NONE"
+#define KW_BASIC "BASIC"
FORWARD void do_service(config_t *cpe, config_t *config);
rs_start.rss_uid= uid;
}
+PRIVATE void do_sigmgr(config_t *cpe)
+{
+ endpoint_t sigmgr_ep;
+ int r;
+
+ /* Process a signal manager value */
+ if (cpe->next != NULL)
+ {
+ fatal("do_sigmgr: just one sigmgr value expected at %s:%d",
+ cpe->file, cpe->line);
+ }
+
+
+ if (cpe->flags & CFG_SUBLIST)
+ {
+ fatal("do_sigmgr: unexpected sublist at %s:%d",
+ cpe->file, cpe->line);
+ }
+ if (cpe->flags & CFG_STRING)
+ {
+ fatal("do_sigmgr: unexpected string at %s:%d",
+ cpe->file, cpe->line);
+ }
+
+ if(!strcmp(cpe->word, "SELF")) {
+ sigmgr_ep = SELF;
+ }
+ else {
+ r = minix_rs_lookup(cpe->word, &sigmgr_ep);
+ if(r != OK) {
+ fatal("do_sigmgr: unknown sigmgr %s at %s:%d",
+ cpe->word, cpe->file, cpe->line);
+ }
+ }
+
+ rs_start.rss_sigmgr= sigmgr_ep;
+}
+
PRIVATE void do_scheduler(config_t *cpe)
{
- int scheduler_val;
- char *check;
+ endpoint_t scheduler_ep;
+ int r;
/* Process a scheduler value */
if (cpe->next != NULL)
fatal("do_scheduler: unexpected string at %s:%d",
cpe->file, cpe->line);
}
- scheduler_val= strtol(cpe->word, &check, 0);
- if (check[0] != '\0')
- {
- fatal("do_scheduler: bad scheduler value '%s' at %s:%d",
+
+ if(!strcmp(cpe->word, "KERNEL")) {
+ scheduler_ep = KERNEL;
+ }
+ else {
+ r = minix_rs_lookup(cpe->word, &scheduler_ep);
+ if(r != OK) {
+ fatal("do_scheduler: unknown scheduler %s at %s:%d",
cpe->word, cpe->file, cpe->line);
+ }
}
- if (scheduler_val != KERNEL &&
- (scheduler_val < 0 || scheduler_val > LAST_SPECIAL_PROC_NR))
- {
- fatal("do_scheduler: scheduler %d out of range at %s:%d",
- scheduler_val, cpe->file, cpe->line);
- }
- rss_scheduler= (endpoint_t) scheduler_val;
+ rs_start.rss_scheduler= scheduler_ep;
}
PRIVATE void do_priority(config_t *cpe)
fatal("do_priority: priority %d out of range at %s:%d",
priority_val, cpe->file, cpe->line);
}
- rss_priority= (unsigned) priority_val;
+ rs_start.rss_priority= (unsigned) priority_val;
}
PRIVATE void do_quantum(config_t *cpe)
fatal("do_quantum: quantum %d out of range at %s:%d",
quantum_val, cpe->file, cpe->line);
}
- rss_quantum= (unsigned) quantum_val;
+ rs_start.rss_quantum= (unsigned) quantum_val;
}
PRIVATE void do_irq(config_t *cpe)
{
int irq;
+ int first;
char *check;
/* Process a list of IRQs */
+ first = TRUE;
for (; cpe; cpe= cpe->next)
{
if (cpe->flags & CFG_SUBLIST)
fatal("do_irq: unexpected string at %s:%d",
cpe->file, cpe->line);
}
+
+ /* No IRQ allowed? (default) */
+ if(!strcmp(cpe->word, KW_NONE)) {
+ if(!first || cpe->next) {
+ fatal("do_irq: %s keyword not allowed in list",
+ KW_NONE);
+ }
+ break;
+ }
+
+ /* All IRQs are allowed? */
+ if(!strcmp(cpe->word, KW_ALL)) {
+ if(!first || cpe->next) {
+ fatal("do_irq: %s keyword not allowed in list",
+ KW_ALL);
+ }
+ rs_start.rss_nr_irq = RSS_IO_ALL;
+ break;
+ }
+
+ /* Set single IRQs as specified in the configuration. */
irq= strtoul(cpe->word, &check, 0);
if (check[0] != '\0')
{
fatal("do_irq: too many IRQs (max %d)", RSS_NR_IRQ);
rs_start.rss_irq[rs_start.rss_nr_irq]= irq;
rs_start.rss_nr_irq++;
+ first = FALSE;
}
}
PRIVATE void do_io(config_t *cpe)
{
unsigned base, len;
+ int first;
char *check;
/* Process a list of I/O ranges */
+ first = TRUE;
for (; cpe; cpe= cpe->next)
{
if (cpe->flags & CFG_SUBLIST)
fatal("do_io: unexpected string at %s:%d",
cpe->file, cpe->line);
}
+
+ /* No range allowed? (default) */
+ if(!strcmp(cpe->word, KW_NONE)) {
+ if(!first || cpe->next) {
+ fatal("do_io: %s keyword not allowed in list",
+ KW_NONE);
+ }
+ break;
+ }
+
+ /* All ranges are allowed? */
+ if(!strcmp(cpe->word, KW_ALL)) {
+ if(!first || cpe->next) {
+ fatal("do_io: %s keyword not allowed in list",
+ KW_ALL);
+ }
+ rs_start.rss_nr_io = RSS_IO_ALL;
+ break;
+ }
+
+ /* Set single ranges as specified in the configuration. */
base= strtoul(cpe->word, &check, 0x10);
len= 1;
if (check[0] == ':')
rs_start.rss_io[rs_start.rss_nr_io].base= base;
rs_start.rss_io[rs_start.rss_nr_io].len= len;
rs_start.rss_nr_io++;
+ first = FALSE;
}
}
cpe->word, cpe->file, cpe->line);
}
-struct
-{
- char *label;
- int call_nr;
-} system_tab[]=
-{
- { "PRIVCTL", SYS_PRIVCTL },
- { "TRACE", SYS_TRACE },
- { "KILL", SYS_KILL },
- { "UMAP", SYS_UMAP },
- { "VIRCOPY", SYS_VIRCOPY },
- { "IRQCTL", SYS_IRQCTL },
- { "INT86", SYS_INT86 },
- { "DEVIO", SYS_DEVIO },
- { "SDEVIO", SYS_SDEVIO },
- { "VDEVIO", SYS_VDEVIO },
- { "READBIOS", SYS_READBIOS },
- { "STIME", SYS_STIME },
- { "VMCTL", SYS_VMCTL },
- { NULL, 0 }
-};
-
PRIVATE void do_ipc(config_t *cpe)
{
- char *list;
+ char *list, *word;
+ char *word_all = RSS_IPC_ALL;
+ char *word_all_sys = RSS_IPC_ALL_SYS;
size_t listsize, wordlen;
+ int first;
list= NULL;
listsize= 1;
/* Process a list of process names that are allowed to be
* contacted
*/
+ first = TRUE;
for (; cpe; cpe= cpe->next)
{
if (cpe->flags & CFG_SUBLIST)
fatal("do_ipc: unexpected string at %s:%d",
cpe->file, cpe->line);
}
+ word = cpe->word;
+
+ /* All (system) ipc targets are allowed? */
+ if(!strcmp(word, KW_ALL) || !strcmp(word, KW_ALL_SYS)) {
+ if(!first || cpe->next) {
+ fatal("do_ipc: %s keyword not allowed in list",
+ word);
+ }
+ word = !strcmp(word, KW_ALL) ? word_all : word_all_sys;
+ }
- wordlen= strlen(cpe->word);
+ wordlen= strlen(word);
listsize += 1 + wordlen;
list= realloc(list, listsize);
listsize);
}
strcat(list, " ");
- strcat(list, cpe->word);
+ strcat(list, word);
+ first = FALSE;
}
#if 0
printf("do_ipc: got list '%s'\n", list);
int call_nr;
} vm_table[] =
{
+ { "EXIT", VM_EXIT },
+ { "FORK", VM_FORK },
+ { "BRK", VM_BRK },
+ { "EXEC_NEWMEM", VM_EXEC_NEWMEM },
+ { "PUSH_SIG", VM_PUSH_SIG },
+ { "WILLEXIT", VM_WILLEXIT },
+ { "ADDDMA", VM_ADDDMA },
+ { "DELDMA", VM_DELDMA },
+ { "GETDMA", VM_GETDMA },
{ "REMAP", VM_REMAP },
- { "UNREMAP", VM_SHM_UNMAP },
+ { "SHM_UNMAP", VM_SHM_UNMAP },
{ "GETPHYS", VM_GETPHYS },
- { "GETREFCNT", VM_GETREF },
- { "QUERYEXIT", VM_QUERY_EXIT },
+ { "GETREF", VM_GETREF },
+ { "RS_SET_PRIV", VM_RS_SET_PRIV },
+ { "QUERY_EXIT", VM_QUERY_EXIT },
+ { "NOTIFY_SIG", VM_NOTIFY_SIG },
{ "INFO", VM_INFO },
+ { "RS_UPDATE", VM_RS_UPDATE },
+ { "RS_MEMCTL", VM_RS_MEMCTL },
{ NULL, 0 },
};
PRIVATE void do_vm(config_t *cpe)
{
- int i;
+ int i, first;
+ first = TRUE;
for (; cpe; cpe = cpe->next)
{
if (cpe->flags & CFG_SUBLIST)
cpe->file, cpe->line);
}
+ /* Only basic calls allowed? (default). */
+ if(!strcmp(cpe->word, KW_BASIC)) {
+ if(!first || cpe->next) {
+ fatal("do_vm: %s keyword not allowed in list",
+ KW_NONE);
+ }
+ break;
+ }
+
+ /* No calls allowed? */
+ if(!strcmp(cpe->word, KW_NONE)) {
+ if(!first || cpe->next) {
+ fatal("do_vm: %s keyword not allowed in list",
+ KW_NONE);
+ }
+ rs_start.rss_flags &= ~RSS_VM_BASIC_CALLS;
+ break;
+ }
+
+ /* All calls are allowed? */
+ if(!strcmp(cpe->word, KW_ALL)) {
+ if(!first || cpe->next) {
+ fatal("do_vm: %s keyword not allowed in list",
+ KW_ALL);
+ }
+ for (i = 0; i < NR_VM_CALLS; i++)
+ SET_BIT(rs_start.rss_vm, i);
+ break;
+ }
+
+ /* Set single calls as specified in the configuration. */
for (i = 0; vm_table[i].label != NULL; i++)
if (!strcmp(cpe->word, vm_table[i].label))
break;
fatal("do_vm: unknown call '%s' at %s:%d",
cpe->word, cpe->file, cpe->line);
SET_BIT(rs_start.rss_vm, vm_table[i].call_nr - VM_RQ_BASE);
+ first = FALSE;
}
}
+struct
+{
+ char *label;
+ int call_nr;
+} system_tab[]=
+{
+ { "PRIVCTL", SYS_PRIVCTL },
+ { "TRACE", SYS_TRACE },
+ { "KILL", SYS_KILL },
+ { "SEGCTL", SYS_SEGCTL },
+ { "UMAP", SYS_UMAP },
+ { "VIRCOPY", SYS_VIRCOPY },
+ { "PHYSCOPY", SYS_PHYSCOPY },
+ { "IRQCTL", SYS_IRQCTL },
+ { "INT86", SYS_INT86 },
+ { "DEVIO", SYS_DEVIO },
+ { "SDEVIO", SYS_SDEVIO },
+ { "VDEVIO", SYS_VDEVIO },
+ { "ABORT", SYS_ABORT },
+ { "IOPENABLE", SYS_IOPENABLE },
+ { "READBIOS", SYS_READBIOS },
+ { "STIME", SYS_STIME },
+ { "VMCTL", SYS_VMCTL },
+ { NULL, 0 }
+};
+
PRIVATE void do_system(config_t *cpe)
{
- int i;
+ int i, first;
/* Process a list of 'system' calls that are allowed */
+ first = TRUE;
for (; cpe; cpe= cpe->next)
{
if (cpe->flags & CFG_SUBLIST)
cpe->file, cpe->line);
}
+ /* Only basic calls allowed? (default). */
+ if(!strcmp(cpe->word, KW_BASIC)) {
+ if(!first || cpe->next) {
+ fatal("do_system: %s keyword not allowed in list",
+ KW_NONE);
+ }
+ break;
+ }
+
+ /* No calls allowed? */
+ if(!strcmp(cpe->word, KW_NONE)) {
+ if(!first || cpe->next) {
+ fatal("do_system: %s keyword not allowed in list",
+ KW_NONE);
+ }
+ rs_start.rss_flags &= ~RSS_SYS_BASIC_CALLS;
+ break;
+ }
+
+ /* All calls are allowed? */
+ if(!strcmp(cpe->word, KW_ALL)) {
+ if(!first || cpe->next) {
+ fatal("do_system: %s keyword not allowed in list",
+ KW_ALL);
+ }
+ for (i = 0; i < NR_SYS_CALLS; i++)
+ SET_BIT(rs_start.rss_system, i);
+ break;
+ }
+
+ /* Set single calls as specified in the configuration. */
for (i = 0; system_tab[i].label != NULL; i++)
if (!strcmp(cpe->word, system_tab[i].label))
break;
fatal("do_system: unknown call '%s' at %s:%d",
cpe->word, cpe->file, cpe->line);
SET_BIT(rs_start.rss_system, system_tab[i].call_nr - KERNEL_CALL);
+ first = FALSE;
}
}
do_uid(cpe->next);
continue;
}
+ if (strcmp(cpe->word, KW_SIGMGR) == 0)
+ {
+ do_sigmgr(cpe->next);
+ continue;
+ }
if (strcmp(cpe->word, KW_SCHEDULER) == 0)
{
do_scheduler(cpe->next);
fatal("no passwd file entry for '%s'", SERVICE_LOGIN);
rs_start.rss_uid= pw->pw_uid;
- rss_scheduler= SCHED_PROC_NR;
- rss_priority= USER_Q;
- rss_quantum= 200;
+ rs_start.rss_sigmgr= DSRV_SM;
+ rs_start.rss_scheduler= DSRV_SCH;
+ rs_start.rss_priority= DSRV_Q;
+ rs_start.rss_quantum= DSRV_QT;
if (req_config) {
assert(progname);
do_config(progname, req_config);
}
- assert(rss_priority < NR_SCHED_QUEUES);
- assert(rss_quantum > 0);
- if (rss_nice_encode(&rs_start.rss_nice, rss_scheduler,
- rss_priority, rss_quantum) != OK) {
- fatal("cannot encode scheduling parameters %d, %u, %u",
- rss_scheduler, rss_priority, rss_quantum);
- }
+
+ assert(rs_start.rss_priority < NR_SCHED_QUEUES);
+ assert(rs_start.rss_quantum > 0);
if (req_ipc)
{
}
else
{
- rs_start.rss_ipc= NULL;
- rs_start.rss_ipclen= 0;
+ char *default_ipc = RSS_IPC_ALL_SYS;
+ rs_start.rss_ipc= default_ipc;
+ rs_start.rss_ipclen= strlen(default_ipc);
}
m.RS_CMD_ADDR = (char *) &rs_start;
+20100713:
+ /usr/src/etc/rc updated: copy it (or merge it) to /etc/rc.
+ /usr/src/etc/system.conf updated to include boot sys services: copy
+ it (or merge it) to /etc/system.conf.
+ *** WARNING ***: this change breaks binary compatibility with
+ old images. Use only newly compiled images (make clean world
+ the first time) or download and install the latest ISO.
20100705:
/usr/src/etc/usr/rc updated: copy it (or merge it) to /usr/etc/rc.
/usr/src/etc/rc updated: copy it (or merge it) to /etc/rc.
fi
# Edit settings for boot system services
- edit rs
- edit vm
- edit pm
- edit sched
- edit vfs
- edit ds
- edit tty
- edit memory
- edit -p log
- edit -c pfs
+ if [ "`sysenv skip_boot_config`" != 1 ]
+ then
+ edit rs
+ edit vm
+ edit pm
+ edit sched
+ edit vfs
+ edit ds
+ edit tty
+ edit memory
+ edit -p log
+ edit -c pfs
+ edit init
+ fi
if [ ! -z "$home" ]
then mount $bin_img $home /home || echo "WARNING: couldn't mount $home on /home"
+#
+# Boot system services in the boot image
+#
+
+service rs
+{
+ uid 0;
+ ipc ALL; # ALL ipc targets allowed
+ system ALL; # ALL kernel calls allowed
+ vm # Extra VM calls allowed:
+ RS_SET_PRIV # 37
+ RS_UPDATE # 41
+ RS_MEMCTL # 42
+ ;
+ io NONE; # No I/O range allowed
+ irq NONE; # No IRQ allowed
+ sigmgr SELF; # Signal manager is SELF
+ scheduler KERNEL; # Scheduler is KERNEL
+ priority 4; # priority queue 4
+ quantum 500; # default server quantum
+};
+
+service ds
+{
+ uid 0;
+ ipc ALL; # ALL ipc targets allowed
+ system ALL; # ALL kernel calls allowed
+ vm BASIC; # Only basic VM calls allowed
+ io NONE; # No I/O range allowed
+ irq NONE; # No IRQ allowed
+ sigmgr rs; # Signal manager is RS
+ scheduler KERNEL; # Scheduler is KERNEL
+ priority 4; # priority queue 4
+ quantum 500; # default server quantum
+};
+
+service vm
+{
+ uid 0;
+ ipc ALL; # ALL ipc targets allowed
+ system ALL; # ALL kernel calls allowed
+ vm NONE; # No VM calls allowed
+ io NONE; # No I/O range allowed
+ irq NONE; # No IRQ allowed
+ sigmgr rs; # Signal manager is RS
+ scheduler KERNEL; # Scheduler is KERNEL
+ priority 2; # priority queue 2
+ quantum 500; # default server quantum
+};
+
+service pm
+{
+ uid 0;
+ ipc ALL; # ALL ipc targets allowed
+ system ALL; # ALL kernel calls allowed
+ vm # Extra VM calls allowed:
+ EXIT # 00
+ FORK # 01
+ BRK # 02
+ EXEC_NEWMEM # 03
+ PUSH_SIG # 04
+ WILLEXIT # 05
+ ADDDMA # 12
+ DELDMA # 13
+ GETDMA # 14
+ NOTIFY_SIG # 39
+ ;
+ io NONE; # No I/O range allowed
+ irq NONE; # No IRQ allowed
+ sigmgr rs; # Signal manager is RS
+ scheduler KERNEL; # Scheduler is KERNEL
+ priority 4; # priority queue 4
+ quantum 500; # default server quantum
+};
+
+service sched
+{
+ uid 0;
+ ipc ALL; # ALL ipc targets allowed
+ system ALL; # ALL kernel calls allowed
+ vm BASIC; # Only basic VM calls allowed
+ io NONE; # No I/O range allowed
+ irq NONE; # No IRQ allowed
+ sigmgr rs; # Signal manager is RS
+ scheduler KERNEL; # Scheduler is KERNEL
+ priority 4; # priority queue 4
+ quantum 500; # default server quantum
+};
+
+service vfs
+{
+ uid 0;
+ ipc ALL; # ALL ipc targets allowed
+ system # Extra kernel calls allowed:
+ KILL # 06
+ UMAP # 14
+ VIRCOPY # 15
+ ;
+ vm BASIC; # Only basic VM calls allowed
+ io NONE; # No I/O range allowed
+ irq NONE; # No IRQ allowed
+ sigmgr rs; # Signal manager is RS
+ scheduler KERNEL; # Scheduler is KERNEL
+ priority 5; # priority queue 5
+ quantum 500; # default server quantum
+};
+
+service mfs
+{
+ uid 0;
+ ipc ALL; # ALL ipc targets allowed
+ system BASIC; # Only basic kernel calls allowed
+ vm BASIC; # Only basic VM calls allowed
+ io NONE; # No I/O range allowed
+ irq NONE; # No IRQ allowed
+ sigmgr rs; # Signal manager is RS
+ scheduler sched; # Scheduler is sched
+ priority 5; # priority queue 5
+ quantum 500; # default server quantum
+};
+
+service pfs
+{
+ uid 0;
+ ipc ALL; # ALL ipc targets allowed
+ system BASIC; # Only basic kernel calls allowed
+ vm BASIC; # Only basic VM calls allowed
+ io NONE; # No I/O range allowed
+ irq NONE; # No IRQ allowed
+ sigmgr rs; # Signal manager is RS
+ scheduler sched; # Scheduler is sched
+ priority 5; # priority queue 5
+ quantum 500; # default server quantum
+};
+
+service tty
+{
+ uid 0;
+ ipc ALL; # ALL ipc targets allowed
+ system # Extra kernel calls allowed:
+ KILL # 06
+ SEGCTL # 12
+ UMAP # 14
+ VIRCOPY # 15
+ PHYSCOPY # 16
+ IRQCTL # 19
+ INT86 # 20
+ DEVIO # 21
+ SDEVIO # 22
+ VDEVIO # 23
+ ABORT # 27
+ IOPENABLE # 28
+ READBIOS # 35
+ ;
+ vm BASIC; # Only basic VM calls allowed
+ io ALL; # ALL I/O ranges allowed
+ irq NONE; # No IRQ allowed
+ sigmgr rs; # Signal manager is RS
+ scheduler sched; # Scheduler is sched
+ priority 1; # priority queue 1
+ quantum 50; # default driver quantum
+};
+
+service memory
+{
+ uid 0;
+ ipc ALL; # ALL ipc targets allowed
+ system # Extra kernel calls allowed:
+ SEGCTL # 12
+ UMAP # 14
+ VIRCOPY # 15
+ PHYSCOPY # 16
+ IRQCTL # 19
+ INT86 # 20
+ DEVIO # 21
+ SDEVIO # 22
+ VDEVIO # 23
+ IOPENABLE # 28
+ ;
+ vm BASIC; # Only basic VM calls allowed
+ io NONE; # No I/O range allowed
+ irq NONE; # No IRQ allowed
+ sigmgr rs; # Signal manager is RS
+ scheduler KERNEL; # Scheduler is KERNEL
+ priority 3; # priority queue 3
+ quantum 50; # default driver quantum
+};
+
+service log
+{
+ uid 0;
+ ipc ALL; # ALL ipc targets allowed
+ system # Extra kernel calls allowed:
+ SEGCTL # 12
+ UMAP # 14
+ VIRCOPY # 15
+ IRQCTL # 19
+ INT86 # 20
+ DEVIO # 21
+ SDEVIO # 22
+ VDEVIO # 23
+ ;
+ vm BASIC; # Only basic VM calls allowed
+ io NONE; # No I/O range allowed
+ irq NONE; # No IRQ allowed
+ sigmgr rs; # Signal manager is RS
+ scheduler sched; # Scheduler is sched
+ priority 2; # priority queue 2
+ quantum 50; # default driver quantum
+};
+
+service init
+{
+ uid 0;
+ ipc # ipc targets allowed:
+ pm vfs rs vm
+ ;
+ system NONE; # No kernel calls allowed
+ vm BASIC; # Only basic VM calls allowed
+ io NONE; # No I/O range allowed
+ irq NONE; # No IRQs allowed
+ sigmgr pm; # Signal manager is PM
+};
+
+#
+# Dynamically started system services
+#
+
service floppy
{
irq 6;
io 3f0:8
- 0:10 # XXX DMA controller
+ 0:10 # DMA controller
81 # Also DMA
;
system
pci device 1743/8139;
pci device 4033/1360;
ipc
- SYSTEM PM RS LOG TTY DS VM
+ SYSTEM pm rs log tty ds vm
pci inet amddev
;
};
pci device 8086/1229;
pci device 8086/2449;
ipc
- SYSTEM PM RS LOG TTY DS VM
+ SYSTEM pm rs log tty ds vm
pci inet amddev
;
};
;
};
-service mfs
-{
- uid 0;
-};
-
service isofs
{
system
service hgfs
{
ipc
- SYSTEM PM VFS RS VM
+ SYSTEM pm vfs rs vm
;
};
;
uid 0;
ipc
- SYSTEM
- PM
- RS
- LOG
- TTY
- DS
- VM
- USER
+ SYSTEM USER pm rs log tty ds vm
;
vm
REMAP
- UNREMAP
+ SHM_UNMAP
GETPHYS
- GETREFCNT
- QUERYEXIT
+ GETREF
+ QUERY_EXIT
;
};
4/1 # Multimedia / Audio device
;
ipc
- SYSTEM PM RS LOG TTY DS VFS VM
+ SYSTEM pm rs log tty ds vfs vm
pci inet amddev
;
uid 0;
pci device 16ec/0116;
pci device 1737/1032;
ipc
- SYSTEM PM RS LOG TTY DS VM
+ SYSTEM pm rs log tty ds vm
pci inet amddev
;
};
service filter
{
ipc
- SYSTEM PM VFS RS DS VM
+ SYSTEM pm vfs rs ds vm
at_wini
bios_wini
;
pci device 8086/107c;
pci device 8086/10cd;
ipc
- SYSTEM PM RS LOG TTY DS VM
+ SYSTEM pm rs log tty ds vm
pci inet ;
};
;
pci device 1969/2048;
ipc
- SYSTEM PM RS TTY DS VM
+ SYSTEM pm rs tty ds vm
pci inet
;
};
;
pci device 1011/0009;
ipc
- SYSTEM PM RS LOG TTY DS VM
+ SYSTEM pm rs log tty ds vm
pci inet
;
};
DEVIO # 21
;
ipc
- SYSTEM PM RS LOG TTY DS VM VFS
+ SYSTEM pm rs log tty ds vm vfs
pci inet amddev
;
uid 0;
#define CHECK_IRQ 0x040 /* check if IRQ can be used */
#define CHECK_MEM 0x080 /* check if (VM) mem map request is allowed */
#define ROOT_SYS_PROC 0x100 /* this is a root system process instance */
-#define LU_SYS_PROC 0x200 /* this is a live updated sys proc instance */
-#define RST_SYS_PROC 0x400 /* this is a restarted sys proc instance */
+#define VM_SYS_PROC 0x200 /* this is a vm system process instance */
+#define LU_SYS_PROC 0x400 /* this is a live updated sys proc instance */
+#define RST_SYS_PROC 0x800 /* this is a restarted sys proc instance */
/* Bits for device driver flags managed by RS and VFS. */
#define DRV_FORCED 0x01 /* driver is mapped even if not alive yet */
#include <minix/com.h>
#include <minix/config.h>
+/* Static privilege id definitions. */
+#define NR_STATIC_PRIV_IDS NR_BOOT_PROCS
+#define is_static_priv_id(id) (id >= 0 && id < NR_STATIC_PRIV_IDS)
+#define static_priv_id(n) (NR_TASKS + (n))
+
+/* Unprivileged user processes all share the privilege structure of the
+ * user processesess.
+ * This id must be fixed because it is used to check send mask entries.
+ */
+#define USER_PRIV_ID static_priv_id(ROOT_USR_PROC_NR)
+/* Specifies a null privilege id.
+ */
+#define NULL_PRIV_ID (-1)
+
+/* Allowed calls. */
+#define NO_C (-1) /* no calls allowed */
+#define ALL_C (-2) /* all calls allowed */
+#define NULL_C (-3) /* null call entry */
+
+/*
+ * Default privilege settings used in the system
+ */
+/* privilege flags */
+#define IDL_F (SYS_PROC | BILLABLE) /* idle task is not preemptible as we
+ * don't want it to interfere with the
+ * timer tick interrupt handler code.
+ * Unlike other processes idle task is
+ * handled in a special way and is
+ * preempted always if timer tick occurs
+ * and there is another runnable process
+ */
+#define TSK_F (SYS_PROC) /* other kernel tasks */
+#define SRV_F (SYS_PROC | PREEMPTIBLE) /* system services */
+#define DSRV_F (SRV_F | DYN_PRIV_ID) /* dynamic system services */
+#define RSYS_F (SRV_F | ROOT_SYS_PROC) /* root sys proc */
+#define VM_F (SYS_PROC | VM_SYS_PROC) /* vm */
+#define USR_F (BILLABLE | PREEMPTIBLE) /* user processes */
+#define IMM_F (ROOT_SYS_PROC | VM_SYS_PROC | PREEMPTIBLE) /* immutable */
+
+/* allowed traps */
+#define CSK_T (1 << RECEIVE) /* clock and system */
+#define TSK_T 0 /* other kernel tasks */
+#define SRV_T (~0) /* system services */
+#define DSRV_T (~0) /* dynamic system services */
+#define USR_T (1 << SENDREC) /* user processes */
+
+/* allowed targets */
+#define TSK_M 0 /* all kernel tasks */
+#define SRV_M (~0) /* system services */
+#define DSRV_M (~0) /* dynamic system services */
+#define USR_M (~0) /* user processes */
+
+/* allowed kernel calls */
+#define TSK_KC NO_C /* all kernel tasks */
+#define SRV_KC ALL_C /* dynamic system services */
+#define DSRV_KC ALL_C /* default sys proc */
+#define USR_KC NO_C /* user processes */
+
+/* allowed vm calls */
+#define SRV_VC ALL_C /* dynamic system services */
+#define DSRV_VC ALL_C /* default sys proc */
+#define USR_VC ALL_C /* user processes */
+
+/* signal manager */
+#define SRV_SM ROOT_SYS_PROC_NR /* system services */
+#define DSRV_SM ROOT_SYS_PROC_NR /* dynamic system services */
+#define USR_SM PM_PROC_NR /* user processes */
+
/* scheduler */
#define SRV_SCH KERNEL /* system services */
#define DSRV_SCH SCHED_PROC_NR /* dynamic system services */
/* RSS definitions. */
#define RSS_NR_IRQ 16
#define RSS_NR_IO 16
+#define RSS_IRQ_ALL (RSS_NR_IRQ+1)
+#define RSS_IO_ALL (RSS_NR_IO+1)
+#define RSS_IPC_ALL "IPC_ALL"
+#define RSS_IPC_ALL_SYS "IPC_ALL_SYS"
/* RSS flags. */
#define RSS_COPY 0x01 /* keep an in-memory copy of the binary */
-#define RSS_IPC_VALID 0x02 /* rss_ipc and rss_ipclen are valid */
#define RSS_REUSE 0x04 /* Try to reuse previously copied binary */
#define RSS_NOBLOCK 0x08 /* unblock caller immediately */
#define RSS_REPLICA 0x10 /* keep a replica of the service */
#define RSS_SELF_LU 0x20 /* perform self update */
+#define RSS_SYS_BASIC_CALLS 0x40 /* include basic kernel calls */
+#define RSS_VM_BASIC_CALLS 0x80 /* include basic vm calls */
/* Common definitions. */
#define RS_NR_CONTROL 8
char *rss_cmd;
size_t rss_cmdlen;
uid_t rss_uid;
- int rss_nice; /* use rss_nice_encode and _decode */
+ endpoint_t rss_sigmgr;
+ endpoint_t rss_scheduler;
+ unsigned rss_priority;
+ unsigned rss_quantum;
int rss_major;
int rss_dev_style;
long rss_period;
};
_PROTOTYPE( int minix_rs_lookup, (const char *name, endpoint_t *value));
-_PROTOTYPE(int rss_nice_encode, (int *nice, endpoint_t scheduler,
- unsigned priority, unsigned quantum));
-_PROTOTYPE(int rss_nice_decode, (int nice, endpoint_t *scheduler,
- unsigned *priority, unsigned *quantum));
#endif
}
/* Priviliges for the root system process. */
else if(isrootsysn(proc_nr)) {
- priv(rp)->s_flags= RSYS_F; /* privilege flags */
- priv(rp)->s_trap_mask= RSYS_T; /* allowed traps */
- ipc_to_m = RSYS_M; /* allowed targets */
- kcalls = RSYS_KC; /* allowed kernel calls */
- priv(rp)->s_sig_mgr = RSYS_SM; /* signal manager */
- priv(rp)->s_bak_sig_mgr = NONE; /* backup signal manager */
+ priv(rp)->s_flags= RSYS_F; /* privilege flags */
+ priv(rp)->s_trap_mask= SRV_T; /* allowed traps */
+ ipc_to_m = SRV_M; /* allowed targets */
+ kcalls = SRV_KC; /* allowed kernel calls */
+ priv(rp)->s_sig_mgr = SRV_SM; /* signal manager */
+ rp->p_priority = SRV_Q; /* priority queue */
+ rp->p_quantum_size_ms = SRV_QT; /* quantum size */
rp->p_priority = SRV_Q; /* priority queue */
rp->p_quantum_size_ms = SRV_QT; /* quantum size */
}
/* Guard word for task stacks. */
#define STACK_GUARD ((reg_t) (sizeof(reg_t) == 2 ? 0xBEEF : 0xDEADBEEF))
-/* Static privilege id definitions. */
-#define NR_STATIC_PRIV_IDS NR_BOOT_PROCS
-#define is_static_priv_id(id) (id >= 0 && id < NR_STATIC_PRIV_IDS)
-#define static_priv_id(n) (NR_TASKS + (n))
-
/* Magic system structure table addresses. */
#define BEG_PRIV_ADDR (&priv[0])
#define END_PRIV_ADDR (&priv[NR_SYS_PROCS])
#define may_send_to(rp, nr) (get_sys_bit(priv(rp)->s_ipc_to, nr_to_id(nr)))
-/* Privilege management shorthands. */
-#define spi_to(n) (1 << (static_priv_id(n)))
-#define unset_usr_to(m) ((m) & ~(1 << USER_PRIV_ID))
-
/* The system structures table and pointers to individual table slots. The
* pointers allow faster access because now a process entry can be found by
* indexing the psys_addr array, while accessing an element i requires a
EXTERN struct priv priv[NR_SYS_PROCS]; /* system properties table */
EXTERN struct priv *ppriv_addr[NR_SYS_PROCS]; /* direct slot pointers */
-/* Unprivileged user processes all share the privilege structure of the
- * root user process.
- * This id must be fixed because it is used to check send mask entries.
- */
-#define USER_PRIV_ID static_priv_id(ROOT_USR_PROC_NR)
-/* Specifies a null privilege id.
- */
-#define NULL_PRIV_ID (-1)
-
/* Make sure the system can boot. The following sanity check verifies that
* the system privileges table is large enough for the number of processes
* in the boot image.
#error NR_SYS_PROCS must be larger than NR_BOOT_PROCS
#endif
-/*
- * Privileges masks used by the kernel.
- */
-#define IDL_F (SYS_PROC | BILLABLE) /* idle task is not preemptible as we
- * don't want it to interfere with the
- * timer tick interrupt handler code.
- * Unlike other processes idle task is
- * handled in a special way and is
- * preempted always if timer tick occurs
- * and there is another runnable process
- */
-#define TSK_F (SYS_PROC) /* other kernel tasks */
-#define RSYS_F (SYS_PROC | PREEMPTIBLE | ROOT_SYS_PROC) /* root sys proc */
-#define DEF_SYS_F (RSYS_F | DYN_PRIV_ID) /* default sys proc */
-
-/* allowed traps */
-#define CSK_T (1 << RECEIVE) /* clock and system */
-#define TSK_T 0 /* other kernel tasks */
-#define RSYS_T (~0) /* root system proc */
-#define DEF_SYS_T RSYS_T /* default sys proc */
-
-/* allowed targets */
-#define TSK_M 0 /* all kernel tasks */
-#define RSYS_M (~0) /* root system proc */
-#define DEF_SYS_M unset_usr_to(RSYS_M) /* default sys proc */
-
-/* allowed kernel calls */
-#define NO_C 0 /* no calls allowed */
-#define ALL_C 1 /* all calls allowed */
-#define TSK_KC NO_C /* all kernel tasks */
-#define RSYS_KC ALL_C /* root system proc */
-#define DEF_SYS_KC RSYS_KC /* default sys proc */
-
-/* signal manager */
-#define RSYS_SM SELF /* root system proc */
-#define DEF_SYS_SM ROOT_SYS_PROC_NR /* default sys proc */
-
#endif /* PRIV_H */
priv(rp)->s_asynsize= 0;
/* Set defaults for privilege bitmaps. */
- priv(rp)->s_flags= DEF_SYS_F; /* privilege flags */
- priv(rp)->s_trap_mask= DEF_SYS_T; /* allowed traps */
- ipc_to_m = DEF_SYS_M; /* allowed targets */
+ priv(rp)->s_flags= DSRV_F; /* privilege flags */
+ priv(rp)->s_trap_mask= DSRV_T; /* allowed traps */
+ ipc_to_m = DSRV_M; /* allowed targets */
fill_sendto_mask(rp, ipc_to_m);
- kcalls = DEF_SYS_KC; /* allowed kernel calls */
+ kcalls = DSRV_KC; /* allowed kernel calls */
for(i = 0; i < SYS_CALL_MASK_SIZE; i++) {
priv(rp)->s_k_call_mask[i] = (kcalls == NO_C ? 0 : (~0));
}
/* Set the default signal managers. */
- priv(rp)->s_sig_mgr = DEF_SYS_SM;
+ priv(rp)->s_sig_mgr = DSRV_SM;
priv(rp)->s_bak_sig_mgr = NONE;
/* Set defaults for resources: no I/O resources, no memory resources,
priv(rp)->s_trap_mask = priv->s_trap_mask;
/* Copy target mask. */
+#if PRIV_DEBUG
+ printf("do_privctl: Setting ipc target mask for %d:");
+ for (i=0; i < NR_SYS_PROCS; i += BITCHUNK_BITS) {
+ printf(" %04x", get_sys_bits(priv->s_ipc_to, i));
+ }
+ printf("\n");
+#endif
+
memcpy(&ipc_to_m, &priv->s_ipc_to, sizeof(ipc_to_m));
fill_sendto_mask(rp, ipc_to_m);
+#if PRIV_DEBUG
+ printf("do_privctl: Set ipc target mask for %d:");
+ for (i=0; i < NR_SYS_PROCS; i += BITCHUNK_BITS) {
+ printf(" %04x", get_sys_bits(priv(rp)->s_ipc_to, i));
+ }
+ printf("\n");
+#endif
+
/* Copy kernel call mask. */
memcpy(priv(rp)->s_k_call_mask, priv->s_k_call_mask,
sizeof(priv(rp)->s_k_call_mask));
realpath.c \
rindex.c \
rlimit.c \
- rss_nice.c \
setenv.c \
setmode.c \
settimeofday.c \
+++ /dev/null
-#define _SYSTEM 1
-
-#include <assert.h>
-#include <errno.h>
-#include <minix/com.h>
-#include <minix/config.h>
-#include <minix/const.h>
-#include <minix/ipc.h>
-#include <minix/rs.h>
-#include <minix/type.h>
-#include <stdlib.h>
-#include <timers.h>
-#include <unistd.h>
-
-#include <machine/archtypes.h>
-#include "../../../kernel/priv.h"
-#include "../../../kernel/proc.h"
-
-#define SCHED_BITS 9
-#define PRIO_BITS 8
-#define QUANTUM_BITS 14
-
-#define SCHED_SHIFT 0
-#define PRIO_SHIFT (SCHED_BITS + SCHED_SHIFT)
-#define QUANTUM_SHIFT (PRIO_SHIFT + PRIO_BITS)
-#define ABI_SHIFT (QUANTUM_SHIFT + QUANTUM_BITS)
-
-#define MAXU(bits) ((unsigned) ((1 << (bits)) - 1))
-#define MINS(bits) ((int) (-(1 << ((bits) - 1))))
-#define MAXS(bits) ((int) ((1 << ((bits) - 1)) - 1))
-
-#define ENCODE(value, shift, bits) \
- ((((unsigned) (value)) & ((1 << (bits)) - 1)) << (shift))
-#define DECODE(value, shift, bits) \
- ((((unsigned) (value)) >> (shift)) & ((1 << (bits)) - 1))
-
-PUBLIC int rss_nice_encode(int *nice, endpoint_t scheduler,
- unsigned priority, unsigned quantum)
-{
- unsigned scheduler_u;
-
- assert(ABI_SHIFT == 31);
-
- /* check whether values fit */
- if (!nice) return EINVAL;
- *nice = 0;
- scheduler_u = (unsigned) (scheduler + NR_TASKS);
- if (scheduler_u > MAXU(SCHED_BITS)) return EINVAL;
- if (priority > MAXU(PRIO_BITS)) return EINVAL;
- if (quantum > MAXU(QUANTUM_BITS)) return EINVAL;
-
- /* encode */
- *nice = ENCODE(scheduler_u, SCHED_SHIFT, SCHED_BITS) |
- ENCODE(priority, PRIO_SHIFT, PRIO_BITS) |
- ENCODE(quantum, QUANTUM_SHIFT, QUANTUM_BITS) |
- ENCODE(1, ABI_SHIFT, 1);
-
- return OK;
-}
-
-PUBLIC int rss_nice_decode(int nice, endpoint_t *scheduler,
- unsigned *priority, unsigned *quantum)
-{
- unsigned scheduler_u;
-
- assert(ABI_SHIFT == 31);
-
- /* check arguments */
- if (!scheduler) return EINVAL;
- if (!priority) return EINVAL;
- if (!quantum) return EINVAL;
-
- /* accept either old or new ABI */
- if (nice & (1 << ABI_SHIFT)) {
- /* new ABI, decode */
- scheduler_u = DECODE(nice, SCHED_SHIFT, SCHED_BITS);
- *scheduler = (int) scheduler_u - NR_TASKS;
- *priority = DECODE(nice, PRIO_SHIFT, PRIO_BITS);
- *quantum = DECODE(nice, QUANTUM_SHIFT, QUANTUM_BITS);
- } else {
- /* old ABI, not useful so just take defaults */
- *scheduler = SCHED_PROC_NR;
- *priority = USER_Q;
- *quantum = USER_QUANTUM;
- }
-
- return OK;
-}
#ifndef RS_CONST_H
#define RS_CONST_H
-#define DEBUG_DEFAULT 0
+#define DEBUG_DEFAULT 0
+#define PRIV_DEBUG_DEFAULT 0
#ifndef DEBUG
#define DEBUG DEBUG_DEFAULT
#endif
+#ifndef PRIV_DEBUG
+#define PRIV_DEBUG PRIV_DEBUG_DEFAULT
+#endif
+
/* Space reserved for program and arguments. */
#define MAX_COMMAND_LEN 512 /* maximum argument string length */
#define MAX_SCRIPT_LEN 256 /* maximum restart script name length */
#define SF_USE_COPY 0x008 /* set when process has a copy in memory */
#define SF_NEED_REPL 0x010 /* set when process needs replica to start */
#define SF_USE_REPL 0x020 /* set when process has a replica */
+#define IMM_SF \
+ (SF_CORE_SRV | SF_SYNCH_BOOT | SF_NEED_COPY | SF_NEED_REPL) /* immutable */
/* Constants determining RS period and binary exponential backoff. */
#define RS_INIT_T (system_hz * 10) /* allow T ticks for init */
/* Definitions for boot info tables. */
#define NULL_BOOT_NR NR_BOOT_PROCS /* marks a null boot entry */
#define DEFAULT_BOOT_NR NR_BOOT_PROCS /* marks the default boot entry */
-#define SYS_ALL_C (-1) /* specifies all calls */
-#define SYS_NULL_C (-2) /* marks a null call entry */
-
-/* Define privilege flags for the various process types. */
-#define SRV_F (SYS_PROC | PREEMPTIBLE) /* system services */
-#define DSRV_F (SRV_F | DYN_PRIV_ID | CHECK_IO_PORT | CHECK_IRQ)
- /* dynamic system services */
-#define VM_F (SYS_PROC) /* vm */
-#define RUSR_F (BILLABLE | PREEMPTIBLE) /* root user proc */
-
-/* Define system call traps for the various process types. These call masks
- * determine what system call traps a process is allowed to make.
- */
-#define SRV_T (~0) /* system services */
-#define DSRV_T SRV_T /* dynamic system services */
-#define RUSR_T (1 << SENDREC) /* root user proc */
-
-/* Send masks determine to whom processes can send messages or notifications. */
-#define SRV_M (~0) /* system services */
-#define RUSR_M \
- ( spi_to(PM_PROC_NR) | spi_to(VFS_PROC_NR) | spi_to(RS_PROC_NR) \
- | spi_to(VM_PROC_NR) ) /* root user proc */
-
-/* Define the signal manager for the various process types. */
-#define SRV_SM RS_PROC_NR /* system services */
-#define DSRV_SM RS_PROC_NR /* dynamic system services */
-#define RUSR_SM PM_PROC_NR /* root user proc */
/* Define sys flags for the various process types. */
#define SRV_SF (SF_CORE_SRV) /* system services */
#include <minix/ds.h>
#include <minix/minlib.h>
#include <minix/sched.h>
+#include <minix/priv.h>
#include <machine/archtypes.h>
#include <timers.h> /* For priv.h */
struct boot_image_dev *boot_image_dev;
int pid, replica_pid;
endpoint_t replica_endpoint;
+ int ipc_to;
+ int *calls;
+ int all_c[] = { ALL_C, NULL_C };
+ int no_c[] = { NULL_C };
/* See if we run in verbose mode. */
env_parse("rs_verbose", "d", 0, &rs_verbose, 0, 1);
_ENDPOINT_P(boot_image_priv->endpoint));
/* Initialize privilege bitmaps and signal manager. */
- rp->r_priv.s_flags = boot_image_priv->flags; /* priv flags */
- rp->r_priv.s_trap_mask = boot_image_priv->trap_mask; /* traps */
- memcpy(&rp->r_priv.s_ipc_to, &boot_image_priv->ipc_to,
- sizeof(rp->r_priv.s_ipc_to)); /* targets */
- rp->r_priv.s_sig_mgr = boot_image_priv->sig_mgr; /* sig mgr */
- rp->r_priv.s_bak_sig_mgr = NONE; /* backup sig mgr */
+ rp->r_priv.s_flags = boot_image_priv->flags; /* priv flags */
+ rp->r_priv.s_trap_mask= SRV_OR_USR(rp, SRV_T, USR_T); /* traps */
+ ipc_to = SRV_OR_USR(rp, SRV_M, USR_M); /* targets */
+ memcpy(&rp->r_priv.s_ipc_to, &ipc_to, sizeof(rp->r_priv.s_ipc_to));
+ rp->r_priv.s_sig_mgr= SRV_OR_USR(rp, SRV_SM, USR_SM); /* sig mgr */
+ rp->r_priv.s_bak_sig_mgr = NONE; /* backup sig mgr */
- /* Initialize kernel call mask bitmap from unordered set. */
- fill_call_mask(boot_image_priv->k_calls, NR_SYS_CALLS,
+ /* Initialize kernel call mask bitmap. */
+ calls = SRV_OR_USR(rp, SRV_KC, USR_KC) == ALL_C ? all_c : no_c;
+ fill_call_mask(calls, NR_SYS_CALLS,
rp->r_priv.s_k_call_mask, KERNEL_CALL, TRUE);
/* Set the privilege structure. */
rp->r_script[0]= '\0';
build_cmd_dep(rp);
- /* Initialize vm call mask bitmap from unordered set. */
- fill_call_mask(boot_image_priv->vm_calls, NR_VM_CALLS,
- rpub->vm_call_mask, VM_RQ_BASE, TRUE);
+ /* Initialize vm call mask bitmap. */
+ calls = SRV_OR_USR(rp, SRV_VC, USR_VC) == ALL_C ? all_c : no_c;
+ fill_call_mask(calls, NR_VM_CALLS, rpub->vm_call_mask, VM_RQ_BASE, TRUE);
/* Scheduling parameters. */
rp->r_scheduler = SRV_OR_USR(rp, SRV_SCH, USR_SCH);
getuptime(&rp->r_alive_tm); /* currently alive */
rp->r_stop_tm = 0; /* not exiting yet */
rp->r_restarts = 0; /* no restarts so far */
- rp->r_set_resources = 0; /* don't set resources */
rp->r_period = 0; /* no period yet */
rp->r_exec = NULL; /* no in-memory copy yet */
rp->r_exec_len = 0;
if(rp) {
rpub = rp->r_pub;
- /* Disallow the call if the target is a user process. */
+ /* Only allow RS_EDIT if the target is a user process. */
if(!(rp->r_priv.s_flags & SYS_PROC)) {
- return EPERM;
+ if(call != RS_EDIT) return EPERM;
}
/* Disallow the call if another call is in progress for the service. */
- if(rp->r_flags & RS_LATEREPLY || rp->r_flags & RS_INITIALIZING) {
+ if((rp->r_flags & RS_LATEREPLY)
+ || (rp->r_flags & RS_INITIALIZING) || (rp->r_flags & RS_UPDATING)) {
return EBUSY;
}
rproc_ptr[child_proc_nr_n] = rp; /* mapping for fast access */
rpub->in_use = TRUE; /* public entry is now in use */
- /* Set resources when asked to. */
- if (rp->r_set_resources) {
- /* Initialize privilege structure. */
- init_privs(rp, &rp->r_priv);
- }
-
/* Set and synch the privilege structure for the new service. */
if ((s = sys_privctl(child_proc_nr_e, SYS_PRIV_SET_SYS, &rp->r_priv)) != OK
|| (s = sys_getpriv(&rp->r_priv, child_proc_nr_e)) != OK) {
- printf("unable to set privilege structure: %d\n", s);
+ printf("RS: unable to set privilege structure: %d\n", s);
cleanup_service(rp);
vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
return ENOMEM;
/* Set the scheduler for this process */
if ((s = sched_init_proc(rp)) != OK) {
- printf("unable to start scheduling: %d\n", s);
+ printf("RS: unable to start scheduling: %d\n", s);
cleanup_service(rp);
vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
return s;
}
else {
if ((s = read_exec(rp)) != OK) {
- printf("read_exec failed: %d\n", s);
+ printf("RS: read_exec failed: %d\n", s);
cleanup_service(rp);
vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
return s;
s = srv_execve(child_proc_nr_e, rp->r_exec, rp->r_exec_len, rp->r_argv,
environ);
vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
-
if (s != OK) {
- printf("srv_execve failed: %d\n", s);
+ printf("RS: srv_execve failed: %d\n", s);
cleanup_service(rp);
return s;
}
*/
setuid(0);
+ /* Tell VM about allowed calls. */
+ if ((s = vm_set_priv(rpub->endpoint, &rpub->vm_call_mask[0])) != OK) {
+ printf("RS: vm_set_priv failed: %d\n", s);
+ cleanup_service(rp);
+ return s;
+ }
+
if(rs_verbose)
printf("RS: %s created\n", srv_to_string(rp));
if((r = clone_slot(rp, &replica_rp)) != OK) {
return r;
}
+ replica_rpub = replica_rp->r_pub;
/* Clone is a live updated or restarted service instance? */
if(instance_flag == LU_SYS_PROC) {
return r;
}
- /* Tell VM about allowed calls, if any. */
- replica_rpub = replica_rp->r_pub;
- if(replica_rpub->vm_call_mask[0]) {
- r = vm_set_priv(replica_rpub->endpoint, &replica_rpub->vm_call_mask[0]);
- if (r != OK) {
- *rp_link = NULL;
- return kill_service(replica_rp, "vm_set_priv call failed", r);
- }
- }
-
/* If this instance is for restarting RS, set up a backup signal manager. */
rs_flags = (ROOT_SYS_PROC | RST_SYS_PROC);
if((replica_rp->r_priv.s_flags & rs_flags) == rs_flags) {
}
}
- /* Tell VM about allowed calls, if any. */
- if(rpub->vm_call_mask[0]) {
- r = vm_set_priv(rpub->endpoint, &rpub->vm_call_mask[0]);
- if (r != OK) {
- return kill_service(rp, "vm_set_priv call failed", r);
- }
- }
-
/* If PCI properties are set, inform the PCI driver about the new service. */
if(rpub->pci_acl.rsp_nr_device || rpub->pci_acl.rsp_nr_class) {
pci_acl = rpub->pci_acl;
def_rpub = def_rp->r_pub;
rpub = rp->r_pub;
- /* Device settings. These properties cannot change. */
+ /* Device and PCI settings. These properties cannot change. */
rpub->dev_flags = def_rpub->dev_flags;
rpub->dev_nr = def_rpub->dev_nr;
rpub->dev_style = def_rpub->dev_style;
rpub->dev_style2 = def_rpub->dev_style2;
+ rpub->pci_acl = def_rpub->pci_acl;
- /* Service type flags. */
- rp->r_priv.s_flags |= rp->r_priv.s_flags & ROOT_SYS_PROC;
+ /* Immutable system and privilege flags. */
+ rpub->sys_flags &= ~IMM_SF;
+ rpub->sys_flags |= (def_rpub->sys_flags & IMM_SF);
+ rp->r_priv.s_flags &= ~IMM_F;
+ rp->r_priv.s_flags |= (def_rp->r_priv.s_flags & IMM_F);
- /* Period. */
- if(!rp->r_period && def_rp->r_period) {
- rp->r_period = def_rp->r_period;
- }
+ /* Allowed traps. They cannot change. */
+ rp->r_priv.s_trap_mask = def_rp->r_priv.s_trap_mask;
}
/*===========================================================================*
struct rprocpub *rpub;
char *label;
int len;
- int s;
+ int s, i;
+ int basic_kc[] = { SYS_BASIC_CALLS, NULL_C };
+ int basic_vmc[] = { VM_BASIC_CALLS, NULL_C };
rpub = rp->r_pub;
- /* Update command and arguments */
+ /* Update IPC target list. */
+ if (rs_start->rss_ipclen==0 || rs_start->rss_ipclen+1>sizeof(rp->r_ipc_list)){
+ printf("RS: edit_slot: ipc list empty or long for '%s'\n", rpub->label);
+ return EINVAL;
+ }
+ s=sys_datacopy(source, (vir_bytes) rs_start->rss_ipc,
+ SELF, (vir_bytes) rp->r_ipc_list, rs_start->rss_ipclen);
+ if (s != OK) return(s);
+ rp->r_ipc_list[rs_start->rss_ipclen]= '\0';
+
+ /* Update IRQs. */
+ if(rs_start->rss_nr_irq == RSS_IRQ_ALL) {
+ rs_start->rss_nr_irq = 0;
+ }
+ else {
+ rp->r_priv.s_flags |= CHECK_IRQ;
+ }
+ if (rs_start->rss_nr_irq > NR_IRQ) {
+ printf("RS: edit_slot: too many IRQs requested\n");
+ return EINVAL;
+ }
+ rp->r_priv.s_nr_irq= rs_start->rss_nr_irq;
+ for (i= 0; i<rp->r_priv.s_nr_irq; i++) {
+ rp->r_priv.s_irq_tab[i]= rs_start->rss_irq[i];
+ if(rs_verbose)
+ printf("RS: edit_slot: IRQ %d\n", rp->r_priv.s_irq_tab[i]);
+ }
+
+ /* Update I/O ranges. */
+ if(rs_start->rss_nr_io == RSS_IO_ALL) {
+ rs_start->rss_nr_io = 0;
+ }
+ else {
+ rp->r_priv.s_flags |= CHECK_IO_PORT;
+ }
+ if (rs_start->rss_nr_io > NR_IO_RANGE) {
+ printf("RS: edit_slot: too many I/O ranges requested\n");
+ return EINVAL;
+ }
+ rp->r_priv.s_nr_io_range= rs_start->rss_nr_io;
+ for (i= 0; i<rp->r_priv.s_nr_io_range; i++) {
+ rp->r_priv.s_io_tab[i].ior_base= rs_start->rss_io[i].base;
+ rp->r_priv.s_io_tab[i].ior_limit=
+ rs_start->rss_io[i].base+rs_start->rss_io[i].len-1;
+ if(rs_verbose)
+ printf("RS: edit_slot: I/O [%x..%x]\n",
+ rp->r_priv.s_io_tab[i].ior_base,
+ rp->r_priv.s_io_tab[i].ior_limit);
+ }
+
+ /* Update kernel call mask. Inherit basic kernel calls when asked to. */
+ memcpy(rp->r_priv.s_k_call_mask, rs_start->rss_system,
+ sizeof(rp->r_priv.s_k_call_mask));
+ if(rs_start->rss_flags & RSS_SYS_BASIC_CALLS) {
+ fill_call_mask(basic_kc, NR_SYS_CALLS,
+ rp->r_priv.s_k_call_mask, KERNEL_CALL, FALSE);
+ }
+
+ /* Update VM call mask. Inherit basic VM calls. */
+ memcpy(rpub->vm_call_mask, rs_start->rss_vm,
+ sizeof(rpub->vm_call_mask));
+ if(rs_start->rss_flags & RSS_VM_BASIC_CALLS) {
+ fill_call_mask(basic_vmc, NR_VM_CALLS,
+ rpub->vm_call_mask, VM_RQ_BASE, FALSE);
+ }
+
+ /* Update control labels. */
+ if(rs_start->rss_nr_control > 0) {
+ int i, s;
+ if (rs_start->rss_nr_control > RS_NR_CONTROL) {
+ printf("RS: edit_slot: too many control labels\n");
+ return EINVAL;
+ }
+ for (i=0; i<rs_start->rss_nr_control; i++) {
+ s = copy_label(source, rs_start->rss_control[i].l_addr,
+ rs_start->rss_control[i].l_len, 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: edit_slot: control labels:");
+ for (i=0; i<rp->r_nr_control; i++)
+ printf(" %s", rp->r_control[i]);
+ printf("\n");
+ }
+ }
+
+ /* Update signal manager. */
+ rp->r_priv.s_sig_mgr = rs_start->rss_sigmgr;
+
+ /* Update scheduling properties if possible. */
+ if(rp->r_scheduler != NONE) {
+ rp->r_scheduler = rs_start->rss_scheduler;
+ rp->r_priority = rs_start->rss_priority;
+ rp->r_quantum = rs_start->rss_quantum;
+ }
+
+ /* Update command and arguments. */
if (rs_start->rss_cmdlen > MAX_COMMAND_LEN-1) return(E2BIG);
s=sys_datacopy(source, (vir_bytes) rs_start->rss_cmd,
- SELF, (vir_bytes) rp->r_cmd, rs_start->rss_cmdlen);
+ SELF, (vir_bytes) rp->r_cmd, rs_start->rss_cmdlen);
if (s != OK) return(s);
rp->r_cmd[rs_start->rss_cmdlen] = '\0'; /* ensure it is terminated */
if (rp->r_cmd[0] != '/') return(EINVAL); /* insist on absolute path */
/* Update recovery script. */
if (rs_start->rss_scriptlen > MAX_SCRIPT_LEN-1) return(E2BIG);
- if (rs_start->rss_script != NULL && !(rpub->sys_flags & SF_CORE_SRV))
- {
- s=sys_datacopy(source, (vir_bytes) rs_start->rss_script,
- SELF, (vir_bytes) rp->r_script, rs_start->rss_scriptlen);
- if (s != OK) return(s);
- rp->r_script[rs_start->rss_scriptlen] = '\0';
+ if (rs_start->rss_script != NULL && !(rpub->sys_flags & SF_CORE_SRV)) {
+ s=sys_datacopy(source, (vir_bytes) rs_start->rss_script,
+ SELF, (vir_bytes) rp->r_script, rs_start->rss_scriptlen);
+ if (s != OK) return(s);
+ rp->r_script[rs_start->rss_scriptlen] = '\0';
}
/* Update system flags and in-memory copy. */
if ((rs_start->rss_flags & RSS_COPY) && !(rpub->sys_flags & SF_USE_COPY)) {
- int exst_cpy;
- struct rproc *rp2;
- struct rprocpub *rpub2;
- exst_cpy = 0;
-
- if(rs_start->rss_flags & RSS_REUSE) {
- int i;
-
- for(i = 0; i < NR_SYS_PROCS; i++) {
- rp2 = &rproc[i];
- rpub2 = rproc[i].r_pub;
- if(strcmp(rpub->proc_name, rpub2->proc_name) == 0 &&
- (rpub2->sys_flags & SF_USE_COPY)) {
- /* We have found the same binary that's
- * already been copied */
- exst_cpy = 1;
- break;
- }
- }
- }
-
- s = OK;
- if(!exst_cpy)
- s = read_exec(rp);
- else
- share_exec(rp, rp2);
-
- if (s != OK)
- return s;
+ int exst_cpy;
+ struct rproc *rp2;
+ struct rprocpub *rpub2;
+ exst_cpy = 0;
+
+ if(rs_start->rss_flags & RSS_REUSE) {
+ int i;
+
+ for(i = 0; i < NR_SYS_PROCS; i++) {
+ rp2 = &rproc[i];
+ rpub2 = rproc[i].r_pub;
+ if(strcmp(rpub->proc_name, rpub2->proc_name) == 0 &&
+ (rpub2->sys_flags & SF_USE_COPY)) {
+ /* We have found the same binary that's
+ * already been copied */
+ exst_cpy = 1;
+ break;
+ }
+ }
+ }
+
+ s = OK;
+ if(!exst_cpy)
+ s = read_exec(rp);
+ else
+ share_exec(rp, rp2);
+
+ if (s != OK)
+ return s;
- rpub->sys_flags |= SF_USE_COPY;
+ rpub->sys_flags |= SF_USE_COPY;
}
if (rs_start->rss_flags & RSS_REPLICA) {
- rpub->sys_flags |= SF_USE_REPL;
+ rpub->sys_flags |= SF_USE_REPL;
}
/* Update period. */
rp->r_period = rs_start->rss_period;
}
+ /* (Re)initialize privilege settings. */
+ init_privs(rp, &rp->r_priv);
+
return OK;
}
/* Initialize a slot as requested by the client. */
struct rprocpub *rpub;
int i;
- int s;
- int basic_kc[] = { SYS_BASIC_CALLS, SYS_NULL_C };
- int basic_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C };
rpub = rp->r_pub;
- /* All dynamically created services get the same sys and privilege flags,
- * allowed traps, and signal manager. Other privilege settings can be
- * specified at runtime. The privilege id is dynamically allocated by
- * the kernel.
+ /* All dynamically created services get the same sys and privilege flags, and
+ * allowed traps. Other privilege settings can be specified at runtime. The
+ * privilege id is dynamically allocated by the kernel.
*/
rpub->sys_flags = DSRV_SF; /* system flags */
rp->r_priv.s_flags = DSRV_F; /* privilege flags */
rp->r_priv.s_trap_mask = DSRV_T; /* allowed traps */
- rp->r_priv.s_sig_mgr = DSRV_SM; /* signal manager */
rp->r_priv.s_bak_sig_mgr = NONE; /* backup signal manager */
- /* Initialize control labels. */
- if(rs_start->rss_nr_control > 0) {
- int i, s;
- if (rs_start->rss_nr_control > RS_NR_CONTROL)
- {
- printf("RS: init_slot: too many control labels\n");
- return EINVAL;
- }
- for (i=0; i<rs_start->rss_nr_control; i++) {
- s = copy_label(source, rs_start->rss_control[i].l_addr,
- rs_start->rss_control[i].l_len, 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: init_slot: control labels:");
- for (i=0; i<rp->r_nr_control; i++)
- printf(" %s", rp->r_control[i]);
- printf("\n");
- }
- }
-
- /* Initialize IPC list. */
- if (rs_start->rss_flags & RSS_IPC_VALID)
- {
- if (rs_start->rss_ipclen+1 > sizeof(rp->r_ipc_list))
- {
- printf("RS: ipc list too long for '%s'\n", rpub->label);
- return EINVAL;
- }
- s=sys_datacopy(source, (vir_bytes) rs_start->rss_ipc,
- SELF, (vir_bytes) rp->r_ipc_list, rs_start->rss_ipclen);
- if (s != OK) return(s);
- rp->r_ipc_list[rs_start->rss_ipclen]= '\0';
- }
- else
- rp->r_ipc_list[0]= '\0';
-
- /* Initialize granted resources */
- if (rs_start->rss_nr_irq > NR_IRQ)
- {
- printf("RS: init_slot: too many IRQs requested\n");
- return EINVAL;
- }
- rp->r_priv.s_nr_irq= rs_start->rss_nr_irq;
- for (i= 0; i<rp->r_priv.s_nr_irq; i++)
- {
- rp->r_priv.s_irq_tab[i]= rs_start->rss_irq[i];
- if(rs_verbose)
- printf("RS: init_slot: IRQ %d\n", rp->r_priv.s_irq_tab[i]);
- }
-
- if (rs_start->rss_nr_io > NR_IO_RANGE)
- {
- printf("RS: init_slot: too many I/O ranges requested\n");
- return EINVAL;
- }
- rp->r_priv.s_nr_io_range= rs_start->rss_nr_io;
- for (i= 0; i<rp->r_priv.s_nr_io_range; i++)
- {
- rp->r_priv.s_io_tab[i].ior_base= rs_start->rss_io[i].base;
- rp->r_priv.s_io_tab[i].ior_limit=
- rs_start->rss_io[i].base+rs_start->rss_io[i].len-1;
- if(rs_verbose)
- printf("RS: init_slot: I/O [%x..%x]\n",
- rp->r_priv.s_io_tab[i].ior_base,
- rp->r_priv.s_io_tab[i].ior_limit);
- }
-
- if (rs_start->rss_nr_pci_id > RS_NR_PCI_DEVICE)
- {
- printf("RS: init_slot: too many PCI device IDs\n");
- return EINVAL;
- }
- rpub->pci_acl.rsp_nr_device = rs_start->rss_nr_pci_id;
- for (i= 0; i<rpub->pci_acl.rsp_nr_device; i++)
- {
- rpub->pci_acl.rsp_device[i].vid= rs_start->rss_pci_id[i].vid;
- rpub->pci_acl.rsp_device[i].did= rs_start->rss_pci_id[i].did;
- if(rs_verbose)
- printf("RS: init_slot: PCI %04x/%04x\n",
- rpub->pci_acl.rsp_device[i].vid,
- rpub->pci_acl.rsp_device[i].did);
- }
- if (rs_start->rss_nr_pci_class > RS_NR_PCI_CLASS)
- {
- printf("RS: init_slot: too many PCI class IDs\n");
- return EINVAL;
- }
- rpub->pci_acl.rsp_nr_class= rs_start->rss_nr_pci_class;
- for (i= 0; i<rpub->pci_acl.rsp_nr_class; i++)
- {
- rpub->pci_acl.rsp_class[i].pciclass=rs_start->rss_pci_class[i].pciclass;
- rpub->pci_acl.rsp_class[i].mask= rs_start->rss_pci_class[i].mask;
- if(rs_verbose)
- printf("RS: init_slot: PCI class %06x mask %06x\n",
- (unsigned int) rpub->pci_acl.rsp_class[i].pciclass,
- (unsigned int) rpub->pci_acl.rsp_class[i].mask);
- }
+ /* Initialize uid. */
rp->r_uid= rs_start->rss_uid;
- s = rss_nice_decode(rs_start->rss_nice, &rp->r_scheduler,
- &rp->r_priority, &rp->r_quantum);
- if (s != OK) return(s);
-
- /* Initialize kernel call mask. Inherit basic kernel calls. */
- memcpy(rp->r_priv.s_k_call_mask, rs_start->rss_system,
- sizeof(rp->r_priv.s_k_call_mask));
- fill_call_mask(basic_kc, NR_SYS_CALLS,
- rp->r_priv.s_k_call_mask, KERNEL_CALL, FALSE);
-
- /* Initialize device driver properties. */
+ /* Initialize device driver settings. */
rpub->dev_flags = DSRV_DF;
rpub->dev_nr = rs_start->rss_major;
rpub->dev_style = rs_start->rss_dev_style;
}
rpub->dev_style2 = STYLE_NDEV;
+ /* Initialize pci settings. */
+ if (rs_start->rss_nr_pci_id > RS_NR_PCI_DEVICE) {
+ printf("RS: init_slot: too many PCI device IDs\n");
+ return EINVAL;
+ }
+ rpub->pci_acl.rsp_nr_device = rs_start->rss_nr_pci_id;
+ for (i= 0; i<rpub->pci_acl.rsp_nr_device; i++) {
+ rpub->pci_acl.rsp_device[i].vid= rs_start->rss_pci_id[i].vid;
+ rpub->pci_acl.rsp_device[i].did= rs_start->rss_pci_id[i].did;
+ if(rs_verbose)
+ printf("RS: init_slot: PCI %04x/%04x\n",
+ rpub->pci_acl.rsp_device[i].vid,
+ rpub->pci_acl.rsp_device[i].did);
+ }
+ if (rs_start->rss_nr_pci_class > RS_NR_PCI_CLASS) {
+ printf("RS: init_slot: too many PCI class IDs\n");
+ return EINVAL;
+ }
+ rpub->pci_acl.rsp_nr_class= rs_start->rss_nr_pci_class;
+ for (i= 0; i<rpub->pci_acl.rsp_nr_class; i++) {
+ rpub->pci_acl.rsp_class[i].pciclass=rs_start->rss_pci_class[i].pciclass;
+ rpub->pci_acl.rsp_class[i].mask= rs_start->rss_pci_class[i].mask;
+ if(rs_verbose)
+ printf("RS: init_slot: PCI class %06x mask %06x\n",
+ (unsigned int) rpub->pci_acl.rsp_class[i].pciclass,
+ (unsigned int) rpub->pci_acl.rsp_class[i].mask);
+ }
+
/* Initialize some fields. */
rp->r_restarts = 0; /* no restarts yet */
- rp->r_set_resources= 1; /* set resources */
rp->r_old_rp = NULL; /* no old version yet */
rp->r_new_rp = NULL; /* no new version yet */
rp->r_prev_rp = NULL; /* no prev replica yet */
rp->r_exec_len = 0;
rp->r_script[0]= '\0'; /* no recovery script yet */
rpub->label[0]= '\0'; /* no label yet */
-
- /* Initialize VM call mask. Inherit basic VM calls. */
- memcpy(rpub->vm_call_mask, rs_start->rss_vm,
- sizeof(rpub->vm_call_mask));
- fill_call_mask(basic_vmc, NR_VM_CALLS,
- rpub->vm_call_mask, VM_RQ_BASE, FALSE);
+ rp->r_scheduler = -1; /* no scheduler yet */
+ rp->r_priv.s_sig_mgr = -1; /* no signal manager yet */
/* Initialize editable slot settings. */
- s = edit_slot(rp, rs_start, source);
- if(s != OK) {
- return s;
- }
-
- return OK;
+ return edit_slot(rp, rs_start, source);
}
/*===========================================================================*
endpoint= SYSTEM;
else if (strcmp(label, "USER") == 0)
endpoint= INIT_PROC_NR; /* all user procs */
- else if (strcmp(label, "PM") == 0)
- endpoint= PM_PROC_NR;
- else if (strcmp(label, "VFS") == 0)
- endpoint= VFS_PROC_NR;
- else if (strcmp(label, "RS") == 0)
- endpoint= RS_PROC_NR;
- else if (strcmp(label, "LOG") == 0)
- endpoint= LOG_PROC_NR;
- else if (strcmp(label, "TTY") == 0)
- endpoint= TTY_PROC_NR;
- else if (strcmp(label, "DS") == 0)
- endpoint= DS_PROC_NR;
- else if (strcmp(label, "VM") == 0)
- endpoint= VM_PROC_NR;
else
{
/* Try to find process */
label, r);
continue;
}
+#if PRIV_DEBUG
+ printf(" RS: add_forward_ipc: setting sendto bit for %d...\n",
+ endpoint);
+#endif
priv_id= priv.s_id;
set_sys_bit(privp->s_ipc_to, priv_id);
}
if (!found)
continue;
+#if PRIV_DEBUG
+ printf(" RS: add_backward_ipc: setting sendto bit for %d...\n",
+ rrpub->endpoint);
+#endif
+ priv_id= rrp->r_priv.s_id;
+ set_sys_bit(privp->s_ipc_to, priv_id);
}
-
- priv_id= rrp->r_priv.s_id;
-
- set_sys_bit(privp->s_ipc_to, priv_id);
}
}
struct priv *privp;
{
int i;
+ int is_ipc_all, is_ipc_all_sys;
/* Clear s_ipc_to */
memset(&privp->s_ipc_to, '\0', sizeof(privp->s_ipc_to));
- if (strlen(rp->r_ipc_list) != 0)
+ is_ipc_all = !strcmp(rp->r_ipc_list, RSS_IPC_ALL);
+ is_ipc_all_sys = !strcmp(rp->r_ipc_list, RSS_IPC_ALL_SYS);
+
+#if PRIV_DEBUG
+ printf(" RS: init_privs: ipc list is '%s'...\n", rp->r_ipc_list);
+#endif
+
+ if (!is_ipc_all && !is_ipc_all_sys)
{
add_forward_ipc(rp, privp);
add_backward_ipc(rp, privp);
{
for (i= 0; i<NR_SYS_PROCS; i++)
{
- if (i != USER_PRIV_ID)
+ if (is_ipc_all || i != USER_PRIV_ID)
set_sys_bit(privp->s_ipc_to, i);
}
}
if(rs_verbose)
printf("RS: %s edits settings\n", srv_to_string(rp));
+ /* Synch the privilege structure with the kernel. */
+ if ((r = sys_getpriv(&rp->r_priv, rpub->endpoint)) != OK) {
+ printf("RS: do_edit: unable to synch privilege structure: %d\n", r);
+ return r;
+ }
+
+ /* Tell scheduler this process is finished */
+ if ((r = sched_stop(rp->r_scheduler, rpub->endpoint)) != OK) {
+ printf("RS: do_edit: scheduler won't give up process: %d\n", r);
+ return r;
+ }
+
/* Edit the slot as requested. */
- r = edit_slot(rp, &rs_start, m_ptr->m_source);
- if(r != OK) {
+ if((r = edit_slot(rp, &rs_start, m_ptr->m_source)) != OK) {
printf("RS: do_edit: unable to edit the existing slot: %d\n", r);
return r;
}
+ /* Update privilege structure. */
+ r = sys_privctl(rpub->endpoint, SYS_PRIV_UPDATE_SYS, &rp->r_priv);
+ if(r != OK) {
+ printf("RS: do_edit: unable to update privilege structure: %d\n", r);
+ return r;
+ }
+
+ /* Update VM calls. */
+ if ((r = vm_set_priv(rpub->endpoint, &rpub->vm_call_mask[0])) != OK) {
+ printf("RS: do_edit: failed: %d\n", r);
+ return r;
+ }
+
+ /* Reinitialize scheduling. */
+ if ((r = sched_init_proc(rp)) != OK) {
+ printf("RS: do_edit: unable to reinitialize scheduling: %d\n", r);
+ return r;
+ }
+
/* Cleanup old replicas and create a new one, if necessary. */
if(rpub->sys_flags & SF_USE_REPL) {
if(rp->r_next_rp) {
*===========================================================================*/
PRIVATE int check_request(struct rs_start *rs_start)
{
- int s;
- endpoint_t rss_scheduler;
- unsigned rss_priority, rss_quantum;
-
- s = rss_nice_decode(rs_start->rss_nice, &rss_scheduler,
- &rss_priority, &rss_quantum);
- if (s != OK) return s;
-
/* Verify scheduling parameters */
- if (rss_scheduler != KERNEL &&
- (rss_scheduler < 0 ||
- rss_scheduler > LAST_SPECIAL_PROC_NR)) {
+ if (rs_start->rss_scheduler != KERNEL &&
+ (rs_start->rss_scheduler < 0 ||
+ rs_start->rss_scheduler > LAST_SPECIAL_PROC_NR)) {
printf("RS: check_request: invalid scheduler %d\n",
- rss_scheduler);
+ rs_start->rss_scheduler);
return EINVAL;
}
- if (rss_priority >= NR_SCHED_QUEUES) {
+ if (rs_start->rss_priority >= NR_SCHED_QUEUES) {
printf("RS: check_request: priority %u out of range\n",
- rss_priority);
+ rs_start->rss_priority);
return EINVAL;
}
- if (rss_quantum <= 0) {
+ if (rs_start->rss_quantum <= 0) {
printf("RS: check_request: quantum %u out of range\n",
- rss_quantum);
+ rs_start->rss_quantum);
+ return EINVAL;
+ }
+
+ /* Verify signal manager. */
+ if (rs_start->rss_sigmgr != SELF &&
+ (rs_start->rss_sigmgr < 0 ||
+ rs_start->rss_sigmgr > LAST_SPECIAL_PROC_NR)) {
+ printf("RS: check_request: invalid signal manager %d\n",
+ rs_start->rss_sigmgr);
return EINVAL;
}
#include "inc.h"
-/* Define kernel calls that processes are allowed to make.
- *
- * Calls are unordered lists, converted by RS to bitmasks
- * once at runtime.
- */
-#define FS_KC SYS_BASIC_CALLS, SYS_TRACE, SYS_UMAP, SYS_VIRCOPY, SYS_KILL
-#define DRV_KC SYS_BASIC_CALLS, SYS_TRACE, SYS_UMAP, SYS_VIRCOPY, SYS_SEGCTL, \
- SYS_IRQCTL, SYS_INT86, SYS_DEVIO, SYS_SDEVIO, SYS_VDEVIO
-
-PRIVATE int
- pm_kc[] = { SYS_ALL_C, SYS_NULL_C },
- sched_kc[] ={ SYS_ALL_C, SYS_NULL_C },
- vfs_kc[] = { FS_KC, SYS_NULL_C },
- rs_kc[] = { SYS_ALL_C, SYS_NULL_C },
- ds_kc[] = { SYS_ALL_C, SYS_NULL_C },
- vm_kc[] = { SYS_ALL_C, SYS_NULL_C },
- tty_kc[] = { DRV_KC, SYS_KILL, SYS_PHYSCOPY, SYS_ABORT, SYS_IOPENABLE,
- SYS_READBIOS, SYS_NULL_C },
- mem_kc[] = { DRV_KC, SYS_PHYSCOPY, SYS_IOPENABLE, SYS_NULL_C},
- log_kc[] = { DRV_KC, SYS_NULL_C },
- mfs_kc[] = { FS_KC, SYS_NULL_C },
- pfs_kc[] = { FS_KC, SYS_NULL_C },
- rusr_kc[] = { SYS_NULL_C },
- no_kc[] = { SYS_NULL_C }; /* no kernel call */
-
-/* Define VM calls that processes are allowed to make.
- *
- * Calls are unordered lists, converted by RS to bitmasks
- * once at runtime.
- */
-PRIVATE int
- pm_vmc[] = { VM_BASIC_CALLS, VM_EXIT, VM_FORK, VM_BRK, VM_EXEC_NEWMEM,
- VM_PUSH_SIG, VM_WILLEXIT, VM_ADDDMA, VM_DELDMA, VM_GETDMA,
- VM_NOTIFY_SIG, SYS_NULL_C },
- sched_vmc[] ={ VM_BASIC_CALLS, SYS_NULL_C },
- vfs_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
- rs_vmc[] = { VM_BASIC_CALLS, VM_RS_SET_PRIV, VM_RS_UPDATE, VM_RS_MEMCTL,
- SYS_NULL_C },
- ds_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
- vm_vmc[] = { SYS_NULL_C },
- tty_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
- mem_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
- log_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
- mfs_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
- pfs_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
- rusr_vmc[] = { VM_BASIC_CALLS, SYS_NULL_C },
- no_vmc[] = { SYS_NULL_C }; /* no vm call */
-
/* Definition of the boot image priv table. The order of entries in this table
* reflects the order boot system services are made runnable and initialized
* at boot time.
*/
PUBLIC struct boot_image_priv boot_image_priv_table[] = {
-/*endpoint, label, flags, traps, ipcto, sigmgr, kcalls, vmcalls */
-{RS_PROC_NR, "rs", RSYS_F, RSYS_T, RSYS_M, RSYS_SM, rs_kc, rs_vmc },
-{VM_PROC_NR, "vm", VM_F, SRV_T, SRV_M, SRV_SM, vm_kc, vm_vmc },
-{PM_PROC_NR, "pm", SRV_F, SRV_T, SRV_M, SRV_SM, pm_kc, pm_vmc },
-{SCHED_PROC_NR,"sched", SRV_F, SRV_T, SRV_M, SRV_SM, sched_kc, sched_vmc },
-{VFS_PROC_NR, "vfs", SRV_F, SRV_T, SRV_M, SRV_SM, vfs_kc, vfs_vmc },
-{DS_PROC_NR, "ds", SRV_F, SRV_T, SRV_M, SRV_SM, ds_kc, ds_vmc },
-{TTY_PROC_NR, "tty", SRV_F, SRV_T, SRV_M, SRV_SM, tty_kc, tty_vmc },
-{MEM_PROC_NR, "memory", SRV_F, SRV_T, SRV_M, SRV_SM, mem_kc, mem_vmc },
-{LOG_PROC_NR, "log", SRV_F, SRV_T, SRV_M, SRV_SM, log_kc, log_vmc },
-{MFS_PROC_NR,"fs_imgrd", SRV_F, SRV_T, SRV_M, SRV_SM, mfs_kc, mfs_vmc },
-{PFS_PROC_NR, "pfs", SRV_F, SRV_T, SRV_M, SRV_SM, pfs_kc, pfs_vmc },
-{INIT_PROC_NR, "init", RUSR_F, RUSR_T, RUSR_M, RUSR_SM, rusr_kc, rusr_vmc },
-{NULL_BOOT_NR, "", 0, 0, 0, 0, no_kc, no_vmc }
+/*endpoint, label, flags, */
+{RS_PROC_NR, "rs", RSYS_F },
+{VM_PROC_NR, "vm", VM_F },
+{PM_PROC_NR, "pm", SRV_F },
+{SCHED_PROC_NR,"sched", SRV_F },
+{VFS_PROC_NR, "vfs", SRV_F },
+{DS_PROC_NR, "ds", SRV_F },
+{TTY_PROC_NR, "tty", SRV_F },
+{MEM_PROC_NR, "memory", SRV_F },
+{LOG_PROC_NR, "log", SRV_F },
+{MFS_PROC_NR,"fs_imgrd", SRV_F },
+{PFS_PROC_NR, "pfs", SRV_F },
+{INIT_PROC_NR, "init", USR_F },
+{NULL_BOOT_NR, "", 0, } /* null entry */
};
/* Definition of the boot image sys table. */
char label[RS_MAX_LABEL_LEN]; /* label to assign to this service */
int flags; /* privilege flags */
- short trap_mask; /* allowed system call traps */
- int ipc_to; /* send mask protection */
- endpoint_t sig_mgr; /* signal manager */
- int *k_calls; /* allowed kernel calls */
- int *vm_calls; /* allowed vm calls */
};
/* Definition of an entry of the boot image sys table. */
char *r_exec; /* Executable image */
size_t r_exec_len; /* Length of image */
- int r_set_resources; /* set when resources must be set. */
struct priv r_priv; /* Privilege structure to be passed to the
* kernel.
*/
/* Count the number of calls to fill in. */
nr_calls = 0;
- for(i=0; calls[i] != SYS_NULL_C; i++) {
+ for(i=0; calls[i] != NULL_C; i++) {
nr_calls++;
}
/* See if all calls are allowed and call mask must be completely filled. */
- if(nr_calls == 1 && calls[0] == SYS_ALL_C) {
+ if(nr_calls == 1 && calls[0] == ALL_C) {
for(i=0; i < call_mask_size; i++) {
call_mask[i] = (~0);
}