13 #include <minix/config.h>
14 #include <minix/com.h>
15 #include <minix/const.h>
16 #include <minix/type.h>
17 #include <minix/ipc.h>
19 #include <minix/syslib.h>
20 #include <minix/bitmap.h>
22 #include <minix/sef.h>
23 #include <minix/dmap.h>
24 #include <sys/types.h>
26 #include <configfile.h>
28 #include <machine/archtypes.h>
30 #include "kernel/proc.h"
35 static int class_recurs
; /* Nesting level of class statements */
36 #define MAX_CLASS_RECURS 100 /* Max nesting level for classes */
40 static void do_service(config_t
*cpe
, config_t
*config
, struct rs_config
*);
42 static void do_class(config_t
*cpe
, config_t
*config
, struct rs_config
*rs_config
)
46 if (class_recurs
> MAX_CLASS_RECURS
)
49 "do_class: nesting level too high for class '%s' at %s:%d",
50 cpe
->word
, cpe
->file
, cpe
->line
);
55 for (; cpe
; cpe
= cpe
->next
)
57 if (cpe
->flags
& CFG_SUBLIST
)
59 fatal("do_class: unexpected sublist at %s:%d",
60 cpe
->file
, cpe
->line
);
62 if (cpe
->flags
& CFG_STRING
)
64 fatal("do_uid: unexpected string at %s:%d",
65 cpe
->file
, cpe
->line
);
68 /* Find entry for the class */
69 for (cp
= config
; cp
; cp
= cp
->next
)
71 if (!(cp
->flags
& CFG_SUBLIST
))
73 fatal("do_class: expected list at %s:%d",
77 if ((cp1
->flags
& CFG_STRING
) ||
78 (cp1
->flags
& CFG_SUBLIST
))
80 fatal("do_class: expected word at %s:%d",
81 cp1
->file
, cp1
->line
);
84 /* At this place we expect the word KW_SERVICE */
85 if (strcmp(cp1
->word
, KW_SERVICE
) != 0)
86 fatal("do_class: exected word '%S' at %s:%d",
87 KW_SERVICE
, cp1
->file
, cp1
->line
);
90 if ((cp1
->flags
& CFG_STRING
) ||
91 (cp1
->flags
& CFG_SUBLIST
))
93 fatal("do_class: expected word at %s:%d",
94 cp1
->file
, cp1
->line
);
97 /* At this place we expect the name of the service */
98 if (strcmp(cp1
->word
, cpe
->word
) == 0)
104 "do_class: no entry found for class '%s' at %s:%d",
105 cpe
->word
, cpe
->file
, cpe
->line
);
107 do_service(cp1
->next
, config
, rs_config
);
113 static void do_uid(config_t
*cpe
, struct rs_start
*rs_start
)
120 if (cpe
->next
!= NULL
)
122 fatal("do_uid: just one uid/login expected at %s:%d",
123 cpe
->file
, cpe
->line
);
126 if (cpe
->flags
& CFG_SUBLIST
)
128 fatal("do_uid: unexpected sublist at %s:%d",
129 cpe
->file
, cpe
->line
);
131 if (cpe
->flags
& CFG_STRING
)
133 fatal("do_uid: unexpected string at %s:%d",
134 cpe
->file
, cpe
->line
);
136 pw
= getpwnam(cpe
->word
);
141 if (!strncmp(cpe
->word
, KW_SELF
, strlen(KW_SELF
)+1))
143 uid
= getuid(); /* Real uid */
146 uid
= strtol(cpe
->word
, &check
, 0);
147 if (check
[0] != '\0')
149 fatal("do_uid: bad uid/login '%s' at %s:%d",
150 cpe
->word
, cpe
->file
, cpe
->line
);
155 rs_start
->rss_uid
= uid
;
158 static void do_sigmgr(config_t
*cpe
, struct rs_start
*rs_start
)
160 endpoint_t sigmgr_ep
;
163 /* Process a signal manager value */
164 if (cpe
->next
!= NULL
)
166 fatal("do_sigmgr: just one sigmgr value expected at %s:%d",
167 cpe
->file
, cpe
->line
);
171 if (cpe
->flags
& CFG_SUBLIST
)
173 fatal("do_sigmgr: unexpected sublist at %s:%d",
174 cpe
->file
, cpe
->line
);
176 if (cpe
->flags
& CFG_STRING
)
178 fatal("do_sigmgr: unexpected string at %s:%d",
179 cpe
->file
, cpe
->line
);
182 if(!strcmp(cpe
->word
, "SELF")) {
186 if((r
= minix_rs_lookup(cpe
->word
, &sigmgr_ep
))) {
187 fatal("do_sigmgr: unknown sigmgr %s at %s:%d",
188 cpe
->word
, cpe
->file
, cpe
->line
);
192 rs_start
->rss_sigmgr
= sigmgr_ep
;
195 static void do_type(config_t
*cpe
, struct rs_config
*rs_config
)
197 if (cpe
->next
!= NULL
)
199 fatal("do_type: just one type value expected at %s:%d",
200 cpe
->file
, cpe
->line
);
204 if (cpe
->flags
& CFG_SUBLIST
)
206 fatal("do_type: unexpected sublist at %s:%d",
207 cpe
->file
, cpe
->line
);
209 if ((cpe
->flags
& CFG_STRING
))
211 fatal("do_type: unexpected string at %s:%d",
212 cpe
->file
, cpe
->line
);
216 fatal("do_type: another type at %s:%d",
217 cpe
->file
, cpe
->line
);
219 if(!strcmp(cpe
->word
, KW_NET
))
220 rs_config
->type
= KW_NET
;
222 fatal("do_type: odd type at %s:%d",
223 cpe
->file
, cpe
->line
);
226 static void do_descr(config_t
*cpe
, struct rs_config
*rs_config
)
228 if (cpe
->next
!= NULL
)
230 fatal("do_descr: just one description expected at %s:%d",
231 cpe
->file
, cpe
->line
);
235 if (cpe
->flags
& CFG_SUBLIST
)
237 fatal("do_descr: unexpected sublist at %s:%d",
238 cpe
->file
, cpe
->line
);
240 if (!(cpe
->flags
& CFG_STRING
))
242 fatal("do_descr: expected string at %s:%d",
243 cpe
->file
, cpe
->line
);
247 fatal("do_descr: another descr at %s:%d",
248 cpe
->file
, cpe
->line
);
249 rs_config
->descr
= cpe
->word
;
252 static void do_scheduler(config_t
*cpe
, struct rs_start
*rs_start
)
254 endpoint_t scheduler_ep
;
257 /* Process a scheduler value */
258 if (cpe
->next
!= NULL
)
260 fatal("do_scheduler: just one scheduler value expected at %s:%d",
261 cpe
->file
, cpe
->line
);
265 if (cpe
->flags
& CFG_SUBLIST
)
267 fatal("do_scheduler: unexpected sublist at %s:%d",
268 cpe
->file
, cpe
->line
);
270 if (cpe
->flags
& CFG_STRING
)
272 fatal("do_scheduler: unexpected string at %s:%d",
273 cpe
->file
, cpe
->line
);
276 if(!strcmp(cpe
->word
, "KERNEL")) {
277 scheduler_ep
= KERNEL
;
280 if((r
= minix_rs_lookup(cpe
->word
, &scheduler_ep
))) {
281 fatal("do_scheduler: unknown scheduler %s at %s:%d",
282 cpe
->word
, cpe
->file
, cpe
->line
);
286 rs_start
->rss_scheduler
= scheduler_ep
;
289 static void do_priority(config_t
*cpe
, struct rs_start
*rs_start
)
294 /* Process a priority value */
295 if (cpe
->next
!= NULL
)
297 fatal("do_priority: just one priority value expected at %s:%d",
298 cpe
->file
, cpe
->line
);
302 if (cpe
->flags
& CFG_SUBLIST
)
304 fatal("do_priority: unexpected sublist at %s:%d",
305 cpe
->file
, cpe
->line
);
307 if (cpe
->flags
& CFG_STRING
)
309 fatal("do_priority: unexpected string at %s:%d",
310 cpe
->file
, cpe
->line
);
312 priority_val
= strtol(cpe
->word
, &check
, 0);
313 if (check
[0] != '\0')
315 fatal("do_priority: bad priority value '%s' at %s:%d",
316 cpe
->word
, cpe
->file
, cpe
->line
);
319 if (priority_val
< 0 || priority_val
>= NR_SCHED_QUEUES
)
321 fatal("do_priority: priority %d out of range at %s:%d",
322 priority_val
, cpe
->file
, cpe
->line
);
324 rs_start
->rss_priority
= priority_val
;
327 static void do_quantum(config_t
*cpe
, struct rs_start
*rs_start
)
332 /* Process a quantum value */
333 if (cpe
->next
!= NULL
)
335 fatal("do_quantum: just one quantum value expected at %s:%d",
336 cpe
->file
, cpe
->line
);
340 if (cpe
->flags
& CFG_SUBLIST
)
342 fatal("do_quantum: unexpected sublist at %s:%d",
343 cpe
->file
, cpe
->line
);
345 if (cpe
->flags
& CFG_STRING
)
347 fatal("do_quantum: unexpected string at %s:%d",
348 cpe
->file
, cpe
->line
);
350 quantum_val
= strtol(cpe
->word
, &check
, 0);
351 if (check
[0] != '\0')
353 fatal("do_quantum: bad quantum value '%s' at %s:%d",
354 cpe
->word
, cpe
->file
, cpe
->line
);
357 if (quantum_val
<= 0)
359 fatal("do_quantum: quantum %d out of range at %s:%d",
360 quantum_val
, cpe
->file
, cpe
->line
);
362 rs_start
->rss_quantum
= quantum_val
;
365 static void do_cpu(config_t
*cpe
, struct rs_start
*rs_start
)
370 /* Process a quantum value */
371 if (cpe
->next
!= NULL
)
373 fatal("do_cpu: just one value expected at %s:%d",
374 cpe
->file
, cpe
->line
);
378 if (cpe
->flags
& CFG_SUBLIST
)
380 fatal("do_cpu: unexpected sublist at %s:%d",
381 cpe
->file
, cpe
->line
);
383 if (cpe
->flags
& CFG_STRING
)
385 fatal("do_cpu: unexpected string at %s:%d",
386 cpe
->file
, cpe
->line
);
388 cpu
= strtol(cpe
->word
, &check
, 0);
389 if (check
[0] != '\0')
391 fatal("do_cpu: bad value '%s' at %s:%d",
392 cpe
->word
, cpe
->file
, cpe
->line
);
397 fatal("do_cpu: %d out of range at %s:%d",
398 cpu
, cpe
->file
, cpe
->line
);
400 rs_start
->rss_cpu
= cpu
;
403 static void do_irq(config_t
*cpe
, struct rs_start
*rs_start
)
409 /* Process a list of IRQs */
411 for (; cpe
; cpe
= cpe
->next
)
413 if (cpe
->flags
& CFG_SUBLIST
)
415 fatal("do_irq: unexpected sublist at %s:%d",
416 cpe
->file
, cpe
->line
);
418 if (cpe
->flags
& CFG_STRING
)
420 fatal("do_irq: unexpected string at %s:%d",
421 cpe
->file
, cpe
->line
);
424 /* No IRQ allowed? (default) */
425 if(!strcmp(cpe
->word
, KW_NONE
)) {
426 if(!first
|| cpe
->next
) {
427 fatal("do_irq: %s keyword not allowed in list",
433 /* All IRQs are allowed? */
434 if(!strcmp(cpe
->word
, KW_ALL
)) {
435 if(!first
|| cpe
->next
) {
436 fatal("do_irq: %s keyword not allowed in list",
439 rs_start
->rss_nr_irq
= RSS_IO_ALL
;
443 /* Set single IRQs as specified in the configuration. */
444 irq
= strtoul(cpe
->word
, &check
, 0);
445 if (check
[0] != '\0')
447 fatal("do_irq: bad irq '%s' at %s:%d",
448 cpe
->word
, cpe
->file
, cpe
->line
);
450 if (rs_start
->rss_nr_irq
>= RSS_NR_IRQ
)
451 fatal("do_irq: too many IRQs (max %d)", RSS_NR_IRQ
);
452 rs_start
->rss_irq
[rs_start
->rss_nr_irq
]= irq
;
453 rs_start
->rss_nr_irq
++;
458 static void do_io(config_t
*cpe
, struct rs_start
*rs_start
)
464 /* Process a list of I/O ranges */
466 for (; cpe
; cpe
= cpe
->next
)
468 if (cpe
->flags
& CFG_SUBLIST
)
470 fatal("do_io: unexpected sublist at %s:%d",
471 cpe
->file
, cpe
->line
);
473 if (cpe
->flags
& CFG_STRING
)
475 fatal("do_io: unexpected string at %s:%d",
476 cpe
->file
, cpe
->line
);
479 /* No range allowed? (default) */
480 if(!strcmp(cpe
->word
, KW_NONE
)) {
481 if(!first
|| cpe
->next
) {
482 fatal("do_io: %s keyword not allowed in list",
488 /* All ranges are allowed? */
489 if(!strcmp(cpe
->word
, KW_ALL
)) {
490 if(!first
|| cpe
->next
) {
491 fatal("do_io: %s keyword not allowed in list",
494 rs_start
->rss_nr_io
= RSS_IO_ALL
;
498 /* Set single ranges as specified in the configuration. */
499 base
= strtoul(cpe
->word
, &check
, 0x10);
503 len
= strtoul(check
+1, &check
, 0x10);
505 if (check
[0] != '\0')
507 fatal("do_io: bad I/O range '%s' at %s:%d",
508 cpe
->word
, cpe
->file
, cpe
->line
);
511 if (rs_start
->rss_nr_io
>= RSS_NR_IO
)
512 fatal("do_io: too many I/O ranges (max %d)", RSS_NR_IO
);
513 rs_start
->rss_io
[rs_start
->rss_nr_io
].base
= base
;
514 rs_start
->rss_io
[rs_start
->rss_nr_io
].len
= len
;
515 rs_start
->rss_nr_io
++;
520 static void do_pci_device(config_t
*cpe
, struct rs_start
*rs_start
)
523 char *check
, *check2
;
525 /* Process a list of PCI device IDs */
526 for (; cpe
; cpe
= cpe
->next
)
528 if (cpe
->flags
& CFG_SUBLIST
)
530 fatal("do_pci_device: unexpected sublist at %s:%d",
531 cpe
->file
, cpe
->line
);
533 if (cpe
->flags
& CFG_STRING
)
535 fatal("do_pci_device: unexpected string at %s:%d",
536 cpe
->file
, cpe
->line
);
538 vid
= strtoul(cpe
->word
, &check
, 0x10);
540 did
= strtoul(check
+1, &check2
, 0x10);
541 if (check
[0] != '/' || check2
[0] != '\0')
543 fatal("do_pci_device: bad ID '%s' at %s:%d",
544 cpe
->word
, cpe
->file
, cpe
->line
);
546 if (rs_start
->rss_nr_pci_id
>= RS_NR_PCI_DEVICE
)
548 fatal("do_pci_device: too many device IDs (max %d)",
551 rs_start
->rss_pci_id
[rs_start
->rss_nr_pci_id
].vid
= vid
;
552 rs_start
->rss_pci_id
[rs_start
->rss_nr_pci_id
].did
= did
;
553 rs_start
->rss_nr_pci_id
++;
557 static void do_pci_class(config_t
*cpe
, struct rs_start
*rs_start
)
559 u8_t baseclass
, subclass
, interface
;
560 u32_t class_id
, mask
;
563 /* Process a list of PCI device class IDs */
564 for (; cpe
; cpe
= cpe
->next
)
566 if (cpe
->flags
& CFG_SUBLIST
)
568 fatal("do_pci_device: unexpected sublist at %s:%d",
569 cpe
->file
, cpe
->line
);
571 if (cpe
->flags
& CFG_STRING
)
573 fatal("do_pci_device: unexpected string at %s:%d",
574 cpe
->file
, cpe
->line
);
577 baseclass
= strtoul(cpe
->word
, &check
, 0x10);
583 subclass
= strtoul(check
+1, &check
, 0x10);
587 interface
= strtoul(check
+1, &check
, 0x10);
592 if (check
[0] != '\0')
594 fatal("do_pci_class: bad class ID '%s' at %s:%d",
595 cpe
->word
, cpe
->file
, cpe
->line
);
597 class_id
= (baseclass
<< 16) | (subclass
<< 8) | interface
;
598 if (rs_start
->rss_nr_pci_class
>= RS_NR_PCI_CLASS
)
600 fatal("do_pci_class: too many class IDs (max %d)",
603 rs_start
->rss_pci_class
[rs_start
->rss_nr_pci_class
].pciclass
=
605 rs_start
->rss_pci_class
[rs_start
->rss_nr_pci_class
].mask
= mask
;
606 rs_start
->rss_nr_pci_class
++;
610 static void do_pci(config_t
*cpe
, struct rs_start
*rs_start
)
613 return; /* Empty PCI statement */
615 if (cpe
->flags
& CFG_SUBLIST
)
617 fatal("do_pci: unexpected sublist at %s:%d",
618 cpe
->file
, cpe
->line
);
620 if (cpe
->flags
& CFG_STRING
)
622 fatal("do_pci: unexpected string at %s:%d",
623 cpe
->file
, cpe
->line
);
626 if (strcmp(cpe
->word
, KW_DEVICE
) == 0)
628 do_pci_device(cpe
->next
, rs_start
);
631 if (strcmp(cpe
->word
, KW_CLASS
) == 0)
633 do_pci_class(cpe
->next
, rs_start
);
636 fatal("do_pci: unexpected word '%s' at %s:%d",
637 cpe
->word
, cpe
->file
, cpe
->line
);
640 static void do_ipc(config_t
*cpe
, struct rs_start
*rs_start
)
644 char *word_all
= RSS_IPC_ALL
;
645 char *word_all_sys
= RSS_IPC_ALL_SYS
;
646 size_t listsize
, wordlen
;
651 list
= malloc(listsize
);
653 fatal("do_ipc: unable to malloc %d bytes", listsize
);
656 /* Process a list of process names that are allowed to be
660 for (; cpe
; cpe
= cpe
->next
)
662 if (cpe
->flags
& CFG_SUBLIST
)
664 fatal("do_ipc: unexpected sublist at %s:%d",
665 cpe
->file
, cpe
->line
);
667 if (cpe
->flags
& CFG_STRING
)
669 fatal("do_ipc: unexpected string at %s:%d",
670 cpe
->file
, cpe
->line
);
674 /* All (system) ipc targets are allowed? */
675 if(!strcmp(word
, KW_ALL
) || !strcmp(word
, KW_ALL_SYS
)) {
676 if(!first
|| cpe
->next
) {
677 fatal("do_ipc: %s keyword not allowed in list",
680 word
= !strcmp(word
, KW_ALL
) ? word_all
: word_all_sys
;
683 wordlen
= strlen(word
);
685 listsize
+= 1 + wordlen
;
686 list
= realloc(list
, listsize
);
689 fatal("do_ipc: unable to realloc %d bytes",
697 printf("do_ipc: got list '%s'\n", list
);
700 if (rs_start
->rss_ipc
)
701 fatal("do_ipc: req_ipc is set");
702 rs_start
->rss_ipc
= list
+1;
703 rs_start
->rss_ipclen
= strlen(rs_start
->rss_ipc
);
716 { "EXEC_NEWMEM", VM_EXEC_NEWMEM
},
718 { "WILLEXIT", VM_WILLEXIT
},
719 { "ADDDMA", VM_ADDDMA
},
720 { "DELDMA", VM_DELDMA
},
721 { "GETDMA", VM_GETDMA
},
722 { "REMAP", VM_REMAP
},
723 { "REMAP_RO", VM_REMAP_RO
},
724 { "SHM_UNMAP", VM_SHM_UNMAP
},
725 { "GETPHYS", VM_GETPHYS
},
726 { "GETREF", VM_GETREF
},
727 { "RS_SET_PRIV", VM_RS_SET_PRIV
},
728 { "QUERY_EXIT", VM_QUERY_EXIT
},
729 { "WATCH_EXIT", VM_WATCH_EXIT
},
730 { "NOTIFY_SIG", VM_NOTIFY_SIG
},
732 { "RS_UPDATE", VM_RS_UPDATE
},
733 { "RS_MEMCTL", VM_RS_MEMCTL
},
734 { "PROCCTL", VM_PROCCTL
},
738 static void do_vm(config_t
*cpe
, struct rs_start
*rs_start
)
743 for (; cpe
; cpe
= cpe
->next
)
745 if (cpe
->flags
& CFG_SUBLIST
)
747 fatal("do_vm: unexpected sublist at %s:%d",
748 cpe
->file
, cpe
->line
);
750 if (cpe
->flags
& CFG_STRING
)
752 fatal("do_vm: unexpected string at %s:%d",
753 cpe
->file
, cpe
->line
);
756 /* Only basic calls allowed? (default). */
757 if(!strcmp(cpe
->word
, KW_BASIC
)) {
758 if(!first
|| cpe
->next
) {
759 fatal("do_vm: %s keyword not allowed in list",
765 /* No calls allowed? */
766 if(!strcmp(cpe
->word
, KW_NONE
)) {
767 if(!first
|| cpe
->next
) {
768 fatal("do_vm: %s keyword not allowed in list",
771 rs_start
->rss_flags
&= ~RSS_VM_BASIC_CALLS
;
775 /* All calls are allowed? */
776 if(!strcmp(cpe
->word
, KW_ALL
)) {
777 if(!first
|| cpe
->next
) {
778 fatal("do_vm: %s keyword not allowed in list",
781 for (i
= 0; i
< NR_VM_CALLS
; i
++)
782 SET_BIT(rs_start
->rss_vm
, i
);
786 /* Set single calls as specified in the configuration. */
787 for (i
= 0; vm_table
[i
].label
!= NULL
; i
++)
788 if (!strcmp(cpe
->word
, vm_table
[i
].label
))
790 if (vm_table
[i
].label
== NULL
)
791 fatal("do_vm: unknown call '%s' at %s:%d",
792 cpe
->word
, cpe
->file
, cpe
->line
);
794 if(vm_table
[i
].call_nr
) {
795 SET_BIT(rs_start
->rss_vm
,
796 vm_table
[i
].call_nr
- VM_RQ_BASE
);
809 { "PRIVCTL", SYS_PRIVCTL
},
810 { "TRACE", SYS_TRACE
},
811 { "KILL", SYS_KILL
},
812 { "UMAP", SYS_UMAP
},
813 { "VIRCOPY", SYS_VIRCOPY
},
814 { "PHYSCOPY", SYS_PHYSCOPY
},
815 { "UMAP_REMOTE", SYS_UMAP_REMOTE
},
816 { "VUMAP", SYS_VUMAP
},
817 { "IRQCTL", SYS_IRQCTL
},
818 { "INT86", SYS_INT86
},
819 { "DEVIO", SYS_DEVIO
},
820 { "SDEVIO", SYS_SDEVIO
},
821 { "VDEVIO", SYS_VDEVIO
},
822 { "ABORT", SYS_ABORT
},
823 { "IOPENABLE", SYS_IOPENABLE
},
824 { "READBIOS", SYS_READBIOS
},
825 { "STIME", SYS_STIME
},
826 { "VMCTL", SYS_VMCTL
},
827 { "MEMSET", SYS_MEMSET
},
831 static void do_system(config_t
*cpe
, struct rs_start
*rs_start
)
835 /* Process a list of 'system' calls that are allowed */
837 for (; cpe
; cpe
= cpe
->next
)
839 if (cpe
->flags
& CFG_SUBLIST
)
841 fatal("do_system: unexpected sublist at %s:%d",
842 cpe
->file
, cpe
->line
);
844 if (cpe
->flags
& CFG_STRING
)
846 fatal("do_system: unexpected string at %s:%d",
847 cpe
->file
, cpe
->line
);
850 /* Only basic calls allowed? (default). */
851 if(!strcmp(cpe
->word
, KW_BASIC
)) {
852 if(!first
|| cpe
->next
) {
853 fatal("do_system: %s keyword not allowed in list",
859 /* No calls allowed? */
860 if(!strcmp(cpe
->word
, KW_NONE
)) {
861 if(!first
|| cpe
->next
) {
862 fatal("do_system: %s keyword not allowed in list",
865 rs_start
->rss_flags
&= ~RSS_SYS_BASIC_CALLS
;
869 /* All calls are allowed? */
870 if(!strcmp(cpe
->word
, KW_ALL
)) {
871 if(!first
|| cpe
->next
) {
872 fatal("do_system: %s keyword not allowed in list",
875 for (i
= 0; i
< NR_SYS_CALLS
; i
++)
876 SET_BIT(rs_start
->rss_system
, i
);
880 /* Set single calls as specified in the configuration. */
881 for (i
= 0; system_tab
[i
].label
!= NULL
; i
++)
882 if (!strcmp(cpe
->word
, system_tab
[i
].label
))
884 if (system_tab
[i
].label
== NULL
)
885 fatal("do_system: unknown call '%s' at %s:%d",
886 cpe
->word
, cpe
->file
, cpe
->line
);
887 SET_BIT(rs_start
->rss_system
, system_tab
[i
].call_nr
- KERNEL_CALL
);
892 static void do_control(config_t
*cpe
, struct rs_start
*rs_start
)
896 /* Process a list of 'control' labels. */
897 for (; cpe
; cpe
= cpe
->next
)
899 if (cpe
->flags
& CFG_SUBLIST
)
901 fatal("do_control: unexpected sublist at %s:%d",
902 cpe
->file
, cpe
->line
);
904 if (cpe
->flags
& CFG_STRING
)
906 fatal("do_control: unexpected string at %s:%d",
907 cpe
->file
, cpe
->line
);
909 if (nr_control
>= RS_NR_CONTROL
)
912 "do_control: RS_NR_CONTROL is too small (%d needed)",
916 rs_start
->rss_control
[nr_control
].l_addr
= (char*) cpe
->word
;
917 rs_start
->rss_control
[nr_control
].l_len
= strlen(cpe
->word
);
918 rs_start
->rss_nr_control
= ++nr_control
;
922 static void do_service(config_t
*cpe
, config_t
*config
, struct rs_config
*rs_config
)
924 struct rs_start
*rs_start
= &rs_config
->rs_start
;
927 /* At this point we expect one sublist that contains the varios
928 * resource allocations
930 if (!(cpe
->flags
& CFG_SUBLIST
))
932 fatal("do_service: expected list at %s:%d",
933 cpe
->file
, cpe
->line
);
935 if (cpe
->next
!= NULL
)
938 fatal("do_service: expected end of list at %s:%d",
939 cpe
->file
, cpe
->line
);
943 /* Process the list */
944 for (cp
= cpe
; cp
; cp
= cp
->next
)
946 if (!(cp
->flags
& CFG_SUBLIST
))
948 fatal("do_service: expected list at %s:%d",
952 if ((cpe
->flags
& CFG_STRING
) || (cpe
->flags
& CFG_SUBLIST
))
954 fatal("do_service: expected word at %s:%d",
955 cpe
->file
, cpe
->line
);
958 if (strcmp(cpe
->word
, KW_CLASS
) == 0)
960 do_class(cpe
->next
, config
, rs_config
);
963 if (strcmp(cpe
->word
, KW_UID
) == 0)
965 do_uid(cpe
->next
, rs_start
);
968 if (strcmp(cpe
->word
, KW_SIGMGR
) == 0)
970 do_sigmgr(cpe
->next
, rs_start
);
973 if (strcmp(cpe
->word
, KW_TYPE
) == 0)
975 do_type(cpe
->next
, rs_config
);
978 if (strcmp(cpe
->word
, KW_DESCR
) == 0)
980 do_descr(cpe
->next
, rs_config
);
983 if (strcmp(cpe
->word
, KW_SCHEDULER
) == 0)
985 do_scheduler(cpe
->next
, rs_start
);
988 if (strcmp(cpe
->word
, KW_PRIORITY
) == 0)
990 do_priority(cpe
->next
, rs_start
);
993 if (strcmp(cpe
->word
, KW_QUANTUM
) == 0)
995 do_quantum(cpe
->next
, rs_start
);
998 if (strcmp(cpe
->word
, KW_CPU
) == 0)
1000 do_cpu(cpe
->next
, rs_start
);
1003 if (strcmp(cpe
->word
, KW_IRQ
) == 0)
1005 do_irq(cpe
->next
, rs_start
);
1008 if (strcmp(cpe
->word
, KW_IO
) == 0)
1010 do_io(cpe
->next
, rs_start
);
1013 if (strcmp(cpe
->word
, KW_PCI
) == 0)
1015 do_pci(cpe
->next
, rs_start
);
1018 if (strcmp(cpe
->word
, KW_SYSTEM
) == 0)
1020 do_system(cpe
->next
, rs_start
);
1023 if (strcmp(cpe
->word
, KW_IPC
) == 0)
1025 do_ipc(cpe
->next
, rs_start
);
1028 if (strcmp(cpe
->word
, KW_VM
) == 0)
1030 do_vm(cpe
->next
, rs_start
);
1033 if (strcmp(cpe
->word
, KW_CONTROL
) == 0)
1035 do_control(cpe
->next
, rs_start
);
1041 static const char *do_config(const char *label
, char *filename
, struct rs_config
*rs_config
)
1043 config_t
*config
, *cp
, *cpe
;
1045 struct rs_start
*rs_start
= &rs_config
->rs_start
;
1047 if(!(config
= config_read(filename
, 0, NULL
)))
1048 return NULL
; /* config file read failed. */
1050 /* Set clean rs_start defaults. */
1051 memset(rs_config
, 0, sizeof(*rs_config
));
1052 if(!(pw
= getpwnam(SERVICE_LOGIN
)))
1053 fatal("no passwd file entry for '%s'", SERVICE_LOGIN
);
1054 rs_start
->rss_uid
= pw
->pw_uid
;
1055 rs_start
->rss_sigmgr
= DSRV_SM
;
1056 rs_start
->rss_scheduler
= DSRV_SCH
;
1057 rs_start
->rss_priority
= DSRV_Q
;
1058 rs_start
->rss_quantum
= DSRV_QT
;
1059 rs_start
->rss_cpu
= DSRV_CPU
;
1060 rs_start
->rss_flags
= RSS_VM_BASIC_CALLS
| RSS_SYS_BASIC_CALLS
;
1062 /* Find an entry for our service */
1063 for (cp
= config
; cp
; cp
= cp
->next
)
1065 if (!(cp
->flags
& CFG_SUBLIST
))
1067 fatal("do_config: expected list at %s:%d",
1068 cp
->file
, cp
->line
);
1071 if ((cpe
->flags
& CFG_STRING
) || (cpe
->flags
& CFG_SUBLIST
))
1073 fatal("do_config: expected word at %s:%d",
1074 cpe
->file
, cpe
->line
);
1077 /* At this place we expect the word KW_SERVICE */
1078 if (strcmp(cpe
->word
, KW_SERVICE
) != 0)
1079 fatal("do_config: exected word '%S' at %s:%d",
1080 KW_SERVICE
, cpe
->file
, cpe
->line
);
1083 if ((cpe
->flags
& CFG_STRING
) || (cpe
->flags
& CFG_SUBLIST
))
1085 fatal("do_config: expected word at %s:%d",
1086 cpe
->file
, cpe
->line
);
1089 /* At this place we expect the name of the service. */
1090 if (!label
|| strcmp(cpe
->word
, label
) == 0) {
1097 fprintf(stderr
, "service: service '%s' not found in '%s'\n",
1104 do_service(cpe
, config
, rs_config
);
1107 char *default_ipc
= RSS_IPC_ALL_SYS
;
1108 if(!rs_start
->rss_ipc
) {
1109 rs_start
->rss_ipc
= default_ipc
;
1110 rs_start
->rss_ipclen
= strlen(default_ipc
);
1114 /* config file read ok. */
1118 /* returns failure */
1119 const char *parse_config(char *progname
, int custom_config
, char *req_config
,
1120 struct rs_config
*rs_config
)
1122 char *specificconfig
, *specific_pkg_config
;
1125 /* Config file specified? */
1127 return do_config(progname
, req_config
, rs_config
);
1129 /* No specific config file. */
1130 if(asprintf(&specificconfig
, "%s/%s", _PATH_SYSTEM_CONF_DIR
,
1132 errx(1, "no memory");
1135 if(asprintf(&specific_pkg_config
, "%s/%s", _PATH_SYSTEM_CONF_PKG_DIR
,
1137 errx(1, "no memory");
1140 /* Try specific config filename first, in base system
1141 * and package locations, * and only if it fails, the global
1144 if((l
=do_config(progname
, specific_pkg_config
, rs_config
))) return l
;
1145 if((l
=do_config(progname
, specificconfig
, rs_config
))) return l
;
1146 if((l
=do_config(progname
, req_config
, rs_config
))) return l
;