2 #define _MINIX_SYSTEM 1
15 #include <minix/config.h>
16 #include <minix/com.h>
17 #include <minix/const.h>
18 #include <minix/type.h>
19 #include <minix/ipc.h>
21 #include <minix/syslib.h>
22 #include <minix/bitmap.h>
23 #include <minix/paths.h>
24 #include <minix/sef.h>
25 #include <minix/dmap.h>
26 #include <minix/priv.h>
27 #include <sys/types.h>
29 #include <configfile.h>
31 #include <machine/archtypes.h>
32 #include <minix/timers.h>
37 static int class_recurs
; /* Nesting level of class statements */
38 #define MAX_CLASS_RECURS 100 /* Max nesting level for classes */
42 static void do_service(config_t
*cpe
, config_t
*config
, struct rs_config
*);
44 static void do_class(config_t
*cpe
, config_t
*config
, struct rs_config
*rs_config
)
48 if (class_recurs
> MAX_CLASS_RECURS
)
51 "do_class: nesting level too high for class '%s' at %s:%d",
52 cpe
->word
, cpe
->file
, cpe
->line
);
57 for (; cpe
; cpe
= cpe
->next
)
59 if (cpe
->flags
& CFG_SUBLIST
)
61 fatal("do_class: unexpected sublist at %s:%d",
62 cpe
->file
, cpe
->line
);
64 if (cpe
->flags
& CFG_STRING
)
66 fatal("do_uid: unexpected string at %s:%d",
67 cpe
->file
, cpe
->line
);
70 /* Find entry for the class */
71 for (cp
= config
; cp
; cp
= cp
->next
)
73 if (!(cp
->flags
& CFG_SUBLIST
))
75 fatal("do_class: expected list at %s:%d",
79 if ((cp1
->flags
& CFG_STRING
) ||
80 (cp1
->flags
& CFG_SUBLIST
))
82 fatal("do_class: expected word at %s:%d",
83 cp1
->file
, cp1
->line
);
86 /* At this place we expect the word KW_SERVICE */
87 if (strcmp(cp1
->word
, KW_SERVICE
) != 0)
88 fatal("do_class: exected word '%S' at %s:%d",
89 KW_SERVICE
, cp1
->file
, cp1
->line
);
92 if ((cp1
->flags
& CFG_STRING
) ||
93 (cp1
->flags
& CFG_SUBLIST
))
95 fatal("do_class: expected word at %s:%d",
96 cp1
->file
, cp1
->line
);
99 /* At this place we expect the name of the service */
100 if (strcmp(cp1
->word
, cpe
->word
) == 0)
106 "do_class: no entry found for class '%s' at %s:%d",
107 cpe
->word
, cpe
->file
, cpe
->line
);
109 do_service(cp1
->next
, config
, rs_config
);
115 static void do_uid(config_t
*cpe
, struct rs_start
*rs_start
)
122 if (cpe
->next
!= NULL
)
124 fatal("do_uid: just one uid/login expected at %s:%d",
125 cpe
->file
, cpe
->line
);
128 if (cpe
->flags
& CFG_SUBLIST
)
130 fatal("do_uid: unexpected sublist at %s:%d",
131 cpe
->file
, cpe
->line
);
133 if (cpe
->flags
& CFG_STRING
)
135 fatal("do_uid: unexpected string at %s:%d",
136 cpe
->file
, cpe
->line
);
138 pw
= getpwnam(cpe
->word
);
143 if (!strncmp(cpe
->word
, KW_SELF
, strlen(KW_SELF
)+1))
145 uid
= getuid(); /* Real uid */
148 uid
= strtol(cpe
->word
, &check
, 0);
149 if (check
[0] != '\0')
151 fatal("do_uid: bad uid/login '%s' at %s:%d",
152 cpe
->word
, cpe
->file
, cpe
->line
);
157 rs_start
->rss_uid
= uid
;
160 static void do_sigmgr(config_t
*cpe
, struct rs_start
*rs_start
)
162 endpoint_t sigmgr_ep
;
165 /* Process a signal manager value */
166 if (cpe
->next
!= NULL
)
168 fatal("do_sigmgr: just one sigmgr value expected at %s:%d",
169 cpe
->file
, cpe
->line
);
173 if (cpe
->flags
& CFG_SUBLIST
)
175 fatal("do_sigmgr: unexpected sublist at %s:%d",
176 cpe
->file
, cpe
->line
);
178 if (cpe
->flags
& CFG_STRING
)
180 fatal("do_sigmgr: unexpected string at %s:%d",
181 cpe
->file
, cpe
->line
);
184 if(!strcmp(cpe
->word
, "SELF")) {
188 if((r
= minix_rs_lookup(cpe
->word
, &sigmgr_ep
))) {
189 fatal("do_sigmgr: unknown sigmgr %s at %s:%d",
190 cpe
->word
, cpe
->file
, cpe
->line
);
194 rs_start
->rss_sigmgr
= sigmgr_ep
;
197 static void do_type(config_t
*cpe
, struct rs_config
*rs_config
)
199 if (cpe
->next
!= NULL
)
201 fatal("do_type: just one type value expected at %s:%d",
202 cpe
->file
, cpe
->line
);
206 if (cpe
->flags
& CFG_SUBLIST
)
208 fatal("do_type: unexpected sublist at %s:%d",
209 cpe
->file
, cpe
->line
);
211 if ((cpe
->flags
& CFG_STRING
))
213 fatal("do_type: unexpected string at %s:%d",
214 cpe
->file
, cpe
->line
);
218 fatal("do_type: another type at %s:%d",
219 cpe
->file
, cpe
->line
);
221 if(!strcmp(cpe
->word
, KW_NET
))
222 rs_config
->type
= KW_NET
;
224 fatal("do_type: odd type at %s:%d",
225 cpe
->file
, cpe
->line
);
228 static void do_descr(config_t
*cpe
, struct rs_config
*rs_config
)
230 if (cpe
->next
!= NULL
)
232 fatal("do_descr: just one description expected at %s:%d",
233 cpe
->file
, cpe
->line
);
237 if (cpe
->flags
& CFG_SUBLIST
)
239 fatal("do_descr: unexpected sublist at %s:%d",
240 cpe
->file
, cpe
->line
);
242 if (!(cpe
->flags
& CFG_STRING
))
244 fatal("do_descr: expected string at %s:%d",
245 cpe
->file
, cpe
->line
);
249 fatal("do_descr: another descr at %s:%d",
250 cpe
->file
, cpe
->line
);
251 rs_config
->descr
= cpe
->word
;
254 static void do_scheduler(config_t
*cpe
, struct rs_start
*rs_start
)
256 endpoint_t scheduler_ep
;
259 /* Process a scheduler value */
260 if (cpe
->next
!= NULL
)
262 fatal("do_scheduler: just one scheduler value expected at %s:%d",
263 cpe
->file
, cpe
->line
);
267 if (cpe
->flags
& CFG_SUBLIST
)
269 fatal("do_scheduler: unexpected sublist at %s:%d",
270 cpe
->file
, cpe
->line
);
272 if (cpe
->flags
& CFG_STRING
)
274 fatal("do_scheduler: unexpected string at %s:%d",
275 cpe
->file
, cpe
->line
);
278 if(!strcmp(cpe
->word
, "KERNEL")) {
279 scheduler_ep
= KERNEL
;
282 if((r
= minix_rs_lookup(cpe
->word
, &scheduler_ep
))) {
283 fatal("do_scheduler: unknown scheduler %s at %s:%d",
284 cpe
->word
, cpe
->file
, cpe
->line
);
288 rs_start
->rss_scheduler
= scheduler_ep
;
291 static void do_priority(config_t
*cpe
, struct rs_start
*rs_start
)
296 /* Process a priority value */
297 if (cpe
->next
!= NULL
)
299 fatal("do_priority: just one priority value expected at %s:%d",
300 cpe
->file
, cpe
->line
);
304 if (cpe
->flags
& CFG_SUBLIST
)
306 fatal("do_priority: unexpected sublist at %s:%d",
307 cpe
->file
, cpe
->line
);
309 if (cpe
->flags
& CFG_STRING
)
311 fatal("do_priority: unexpected string at %s:%d",
312 cpe
->file
, cpe
->line
);
314 priority_val
= strtol(cpe
->word
, &check
, 0);
315 if (check
[0] != '\0')
317 fatal("do_priority: bad priority value '%s' at %s:%d",
318 cpe
->word
, cpe
->file
, cpe
->line
);
321 if (priority_val
< 0 || priority_val
>= NR_SCHED_QUEUES
)
323 fatal("do_priority: priority %d out of range at %s:%d",
324 priority_val
, cpe
->file
, cpe
->line
);
326 rs_start
->rss_priority
= priority_val
;
329 static void do_quantum(config_t
*cpe
, struct rs_start
*rs_start
)
334 /* Process a quantum value */
335 if (cpe
->next
!= NULL
)
337 fatal("do_quantum: just one quantum value expected at %s:%d",
338 cpe
->file
, cpe
->line
);
342 if (cpe
->flags
& CFG_SUBLIST
)
344 fatal("do_quantum: unexpected sublist at %s:%d",
345 cpe
->file
, cpe
->line
);
347 if (cpe
->flags
& CFG_STRING
)
349 fatal("do_quantum: unexpected string at %s:%d",
350 cpe
->file
, cpe
->line
);
352 quantum_val
= strtol(cpe
->word
, &check
, 0);
353 if (check
[0] != '\0')
355 fatal("do_quantum: bad quantum value '%s' at %s:%d",
356 cpe
->word
, cpe
->file
, cpe
->line
);
359 if (quantum_val
<= 0)
361 fatal("do_quantum: quantum %d out of range at %s:%d",
362 quantum_val
, cpe
->file
, cpe
->line
);
364 rs_start
->rss_quantum
= quantum_val
;
367 static void do_cpu(config_t
*cpe
, struct rs_start
*rs_start
)
372 /* Process a quantum value */
373 if (cpe
->next
!= NULL
)
375 fatal("do_cpu: just one value expected at %s:%d",
376 cpe
->file
, cpe
->line
);
380 if (cpe
->flags
& CFG_SUBLIST
)
382 fatal("do_cpu: unexpected sublist at %s:%d",
383 cpe
->file
, cpe
->line
);
385 if (cpe
->flags
& CFG_STRING
)
387 fatal("do_cpu: unexpected string at %s:%d",
388 cpe
->file
, cpe
->line
);
390 cpu
= strtol(cpe
->word
, &check
, 0);
391 if (check
[0] != '\0')
393 fatal("do_cpu: bad value '%s' at %s:%d",
394 cpe
->word
, cpe
->file
, cpe
->line
);
399 fatal("do_cpu: %d out of range at %s:%d",
400 cpu
, cpe
->file
, cpe
->line
);
402 rs_start
->rss_cpu
= cpu
;
405 static void do_irq(config_t
*cpe
, struct rs_start
*rs_start
)
411 /* Process a list of IRQs */
413 for (; cpe
; cpe
= cpe
->next
)
415 if (cpe
->flags
& CFG_SUBLIST
)
417 fatal("do_irq: unexpected sublist at %s:%d",
418 cpe
->file
, cpe
->line
);
420 if (cpe
->flags
& CFG_STRING
)
422 fatal("do_irq: unexpected string at %s:%d",
423 cpe
->file
, cpe
->line
);
426 /* No IRQ allowed? (default) */
427 if(!strcmp(cpe
->word
, KW_NONE
)) {
428 if(!first
|| cpe
->next
) {
429 fatal("do_irq: %s keyword not allowed in list",
435 /* All IRQs are allowed? */
436 if(!strcmp(cpe
->word
, KW_ALL
)) {
437 if(!first
|| cpe
->next
) {
438 fatal("do_irq: %s keyword not allowed in list",
441 rs_start
->rss_nr_irq
= RSS_IO_ALL
;
445 /* Set single IRQs as specified in the configuration. */
446 irq
= strtoul(cpe
->word
, &check
, 0);
447 if (check
[0] != '\0')
449 fatal("do_irq: bad irq '%s' at %s:%d",
450 cpe
->word
, cpe
->file
, cpe
->line
);
452 if (rs_start
->rss_nr_irq
>= RSS_NR_IRQ
)
453 fatal("do_irq: too many IRQs (max %d)", RSS_NR_IRQ
);
454 rs_start
->rss_irq
[rs_start
->rss_nr_irq
]= irq
;
455 rs_start
->rss_nr_irq
++;
460 static void do_io(config_t
*cpe
, struct rs_start
*rs_start
)
466 /* Process a list of I/O ranges */
468 for (; cpe
; cpe
= cpe
->next
)
470 if (cpe
->flags
& CFG_SUBLIST
)
472 fatal("do_io: unexpected sublist at %s:%d",
473 cpe
->file
, cpe
->line
);
475 if (cpe
->flags
& CFG_STRING
)
477 fatal("do_io: unexpected string at %s:%d",
478 cpe
->file
, cpe
->line
);
481 /* No range allowed? (default) */
482 if(!strcmp(cpe
->word
, KW_NONE
)) {
483 if(!first
|| cpe
->next
) {
484 fatal("do_io: %s keyword not allowed in list",
490 /* All ranges are allowed? */
491 if(!strcmp(cpe
->word
, KW_ALL
)) {
492 if(!first
|| cpe
->next
) {
493 fatal("do_io: %s keyword not allowed in list",
496 rs_start
->rss_nr_io
= RSS_IO_ALL
;
500 /* Set single ranges as specified in the configuration. */
501 base
= strtoul(cpe
->word
, &check
, 0x10);
505 len
= strtoul(check
+1, &check
, 0x10);
507 if (check
[0] != '\0')
509 fatal("do_io: bad I/O range '%s' at %s:%d",
510 cpe
->word
, cpe
->file
, cpe
->line
);
513 if (rs_start
->rss_nr_io
>= RSS_NR_IO
)
514 fatal("do_io: too many I/O ranges (max %d)", RSS_NR_IO
);
515 rs_start
->rss_io
[rs_start
->rss_nr_io
].base
= base
;
516 rs_start
->rss_io
[rs_start
->rss_nr_io
].len
= len
;
517 rs_start
->rss_nr_io
++;
522 static void do_pci_device(config_t
*cpe
, struct rs_start
*rs_start
)
524 u16_t vid
, did
, sub_vid
, sub_did
;
525 char *check
, *check2
;
527 /* Process a list of PCI device IDs */
528 for (; cpe
; cpe
= cpe
->next
)
530 if (cpe
->flags
& CFG_SUBLIST
)
532 fatal("do_pci_device: unexpected sublist at %s:%d",
533 cpe
->file
, cpe
->line
);
535 if (cpe
->flags
& CFG_STRING
)
537 fatal("do_pci_device: unexpected string at %s:%d",
538 cpe
->file
, cpe
->line
);
540 vid
= strtoul(cpe
->word
, &check
, 0x10);
541 if (check
[0] != ':' && /* LEGACY: */ check
[0] != '/') {
542 fatal("do_pci_device: bad ID '%s' at %s:%d",
543 cpe
->word
, cpe
->file
, cpe
->line
);
545 did
= strtoul(check
+1, &check
, 0x10);
546 if (check
[0] == '/') {
547 sub_vid
= strtoul(check
+1, &check
, 0x10);
549 sub_did
= strtoul(check
+1, &check2
, 0x10);
550 if (check
[0] != ':' || check2
[0] != '\0') {
551 fatal("do_pci_device: bad ID '%s' at %s:%d",
552 cpe
->word
, cpe
->file
, cpe
->line
);
554 } else if (check
[0] != '\0') {
555 fatal("do_pci_device: bad ID '%s' at %s:%d",
556 cpe
->word
, cpe
->file
, cpe
->line
);
558 sub_vid
= NO_SUB_VID
;
559 sub_did
= NO_SUB_DID
;
561 if (rs_start
->rss_nr_pci_id
>= RS_NR_PCI_DEVICE
)
563 fatal("do_pci_device: too many device IDs (max %d)",
566 rs_start
->rss_pci_id
[rs_start
->rss_nr_pci_id
].vid
= vid
;
567 rs_start
->rss_pci_id
[rs_start
->rss_nr_pci_id
].did
= did
;
568 rs_start
->rss_pci_id
[rs_start
->rss_nr_pci_id
].sub_vid
= sub_vid
;
569 rs_start
->rss_pci_id
[rs_start
->rss_nr_pci_id
].sub_did
= sub_did
;
570 rs_start
->rss_nr_pci_id
++;
574 static void do_pci_class(config_t
*cpe
, struct rs_start
*rs_start
)
576 u8_t baseclass
, subclass
, interface
;
577 u32_t class_id
, mask
;
580 /* Process a list of PCI device class IDs */
581 for (; cpe
; cpe
= cpe
->next
)
583 if (cpe
->flags
& CFG_SUBLIST
)
585 fatal("do_pci_device: unexpected sublist at %s:%d",
586 cpe
->file
, cpe
->line
);
588 if (cpe
->flags
& CFG_STRING
)
590 fatal("do_pci_device: unexpected string at %s:%d",
591 cpe
->file
, cpe
->line
);
594 baseclass
= strtoul(cpe
->word
, &check
, 0x10);
600 subclass
= strtoul(check
+1, &check
, 0x10);
604 interface
= strtoul(check
+1, &check
, 0x10);
609 if (check
[0] != '\0')
611 fatal("do_pci_class: bad class ID '%s' at %s:%d",
612 cpe
->word
, cpe
->file
, cpe
->line
);
614 class_id
= (baseclass
<< 16) | (subclass
<< 8) | interface
;
615 if (rs_start
->rss_nr_pci_class
>= RS_NR_PCI_CLASS
)
617 fatal("do_pci_class: too many class IDs (max %d)",
620 rs_start
->rss_pci_class
[rs_start
->rss_nr_pci_class
].pciclass
=
622 rs_start
->rss_pci_class
[rs_start
->rss_nr_pci_class
].mask
= mask
;
623 rs_start
->rss_nr_pci_class
++;
627 static void do_pci(config_t
*cpe
, struct rs_start
*rs_start
)
630 return; /* Empty PCI statement */
632 if (cpe
->flags
& CFG_SUBLIST
)
634 fatal("do_pci: unexpected sublist at %s:%d",
635 cpe
->file
, cpe
->line
);
637 if (cpe
->flags
& CFG_STRING
)
639 fatal("do_pci: unexpected string at %s:%d",
640 cpe
->file
, cpe
->line
);
643 if (strcmp(cpe
->word
, KW_DEVICE
) == 0)
645 do_pci_device(cpe
->next
, rs_start
);
648 if (strcmp(cpe
->word
, KW_CLASS
) == 0)
650 do_pci_class(cpe
->next
, rs_start
);
653 fatal("do_pci: unexpected word '%s' at %s:%d",
654 cpe
->word
, cpe
->file
, cpe
->line
);
657 static void do_ipc(config_t
*cpe
, struct rs_start
*rs_start
)
661 char *word_all
= RSS_IPC_ALL
;
662 char *word_all_sys
= RSS_IPC_ALL_SYS
;
663 size_t listsize
, wordlen
;
668 list
= malloc(listsize
);
670 fatal("do_ipc: unable to malloc %d bytes", listsize
);
673 /* Process a list of process names that are allowed to be
677 for (; cpe
; cpe
= cpe
->next
)
679 if (cpe
->flags
& CFG_SUBLIST
)
681 fatal("do_ipc: unexpected sublist at %s:%d",
682 cpe
->file
, cpe
->line
);
684 if (cpe
->flags
& CFG_STRING
)
686 fatal("do_ipc: unexpected string at %s:%d",
687 cpe
->file
, cpe
->line
);
691 /* All (system) ipc targets are allowed? */
692 if(!strcmp(word
, KW_ALL
) || !strcmp(word
, KW_ALL_SYS
)) {
693 if(!first
|| cpe
->next
) {
694 fatal("do_ipc: %s keyword not allowed in list",
697 word
= !strcmp(word
, KW_ALL
) ? word_all
: word_all_sys
;
700 wordlen
= strlen(word
);
702 listsize
+= 1 + wordlen
;
703 list
= realloc(list
, listsize
);
706 fatal("do_ipc: unable to realloc %d bytes",
714 printf("do_ipc: got list '%s'\n", list
);
717 if (rs_start
->rss_ipc
)
718 fatal("do_ipc: req_ipc is set");
719 rs_start
->rss_ipc
= list
+1;
720 rs_start
->rss_ipclen
= strlen(rs_start
->rss_ipc
);
732 { "EXEC_NEWMEM", VM_EXEC_NEWMEM
},
734 { "WILLEXIT", VM_WILLEXIT
},
735 { "ADDDMA", VM_ADDDMA
},
736 { "DELDMA", VM_DELDMA
},
737 { "GETDMA", VM_GETDMA
},
738 { "REMAP", VM_REMAP
},
739 { "REMAP_RO", VM_REMAP_RO
},
740 { "SHM_UNMAP", VM_SHM_UNMAP
},
741 { "GETPHYS", VM_GETPHYS
},
742 { "GETREF", VM_GETREF
},
743 { "RS_SET_PRIV", VM_RS_SET_PRIV
},
745 { "RS_UPDATE", VM_RS_UPDATE
},
746 { "RS_MEMCTL", VM_RS_MEMCTL
},
747 { "PROCCTL", VM_PROCCTL
},
748 { "MAPCACHEPAGE", VM_MAPCACHEPAGE
},
749 { "SETCACHEPAGE", VM_SETCACHEPAGE
},
750 { "FORGETCACHEPAGE", VM_FORGETCACHEPAGE
},
751 { "CLEARCACHE", VM_CLEARCACHE
},
752 { "VFS_MMAP", VM_VFS_MMAP
},
753 { "VFS_REPLY", VM_VFS_REPLY
},
754 { "GETRUSAGE", VM_GETRUSAGE
},
755 { "RS_PREPARE", VM_RS_PREPARE
},
759 static void do_vm(config_t
*cpe
, struct rs_start
*rs_start
)
764 for (; cpe
; cpe
= cpe
->next
)
766 if (cpe
->flags
& CFG_SUBLIST
)
768 fatal("do_vm: unexpected sublist at %s:%d",
769 cpe
->file
, cpe
->line
);
771 if (cpe
->flags
& CFG_STRING
)
773 fatal("do_vm: unexpected string at %s:%d",
774 cpe
->file
, cpe
->line
);
777 /* Only basic calls allowed? (default). */
778 if(!strcmp(cpe
->word
, KW_BASIC
)) {
779 if(!first
|| cpe
->next
) {
780 fatal("do_vm: %s keyword not allowed in list",
786 /* No calls allowed? */
787 if(!strcmp(cpe
->word
, KW_NONE
)) {
788 if(!first
|| cpe
->next
) {
789 fatal("do_vm: %s keyword not allowed in list",
792 rs_start
->rss_flags
&= ~RSS_VM_BASIC_CALLS
;
796 /* All calls are allowed? */
797 if(!strcmp(cpe
->word
, KW_ALL
)) {
798 if(!first
|| cpe
->next
) {
799 fatal("do_vm: %s keyword not allowed in list",
802 for (i
= 0; i
< NR_VM_CALLS
; i
++)
803 SET_BIT(rs_start
->rss_vm
, i
);
807 /* Set single calls as specified in the configuration. */
808 for (i
= 0; vm_table
[i
].label
!= NULL
; i
++)
809 if (!strcmp(cpe
->word
, vm_table
[i
].label
))
811 if (vm_table
[i
].label
== NULL
) {
812 warning("do_vm: ignoring unknown call '%s' at %s:%d",
813 cpe
->word
, cpe
->file
, cpe
->line
);
814 } else if(vm_table
[i
].call_nr
) {
815 SET_BIT(rs_start
->rss_vm
,
816 vm_table
[i
].call_nr
- VM_RQ_BASE
);
829 { "PRIVCTL", SYS_PRIVCTL
},
830 { "TRACE", SYS_TRACE
},
831 { "KILL", SYS_KILL
},
832 { "UMAP", SYS_UMAP
},
833 { "VIRCOPY", SYS_VIRCOPY
},
834 { "PHYSCOPY", SYS_PHYSCOPY
},
835 { "UMAP_REMOTE", SYS_UMAP_REMOTE
},
836 { "VUMAP", SYS_VUMAP
},
837 { "IRQCTL", SYS_IRQCTL
},
838 { "DEVIO", SYS_DEVIO
},
839 { "SDEVIO", SYS_SDEVIO
},
840 { "VDEVIO", SYS_VDEVIO
},
841 { "ABORT", SYS_ABORT
},
842 { "IOPENABLE", SYS_IOPENABLE
},
843 { "READBIOS", SYS_READBIOS
},
844 { "STIME", SYS_STIME
},
845 { "VMCTL", SYS_VMCTL
},
846 { "MEMSET", SYS_MEMSET
},
847 { "PADCONF", SYS_PADCONF
},
851 static void do_system(config_t
*cpe
, struct rs_start
*rs_start
)
855 /* Process a list of 'system' calls that are allowed */
857 for (; cpe
; cpe
= cpe
->next
)
859 if (cpe
->flags
& CFG_SUBLIST
)
861 fatal("do_system: unexpected sublist at %s:%d",
862 cpe
->file
, cpe
->line
);
864 if (cpe
->flags
& CFG_STRING
)
866 fatal("do_system: unexpected string at %s:%d",
867 cpe
->file
, cpe
->line
);
870 /* Only basic calls allowed? (default). */
871 if(!strcmp(cpe
->word
, KW_BASIC
)) {
872 if(!first
|| cpe
->next
) {
873 fatal("do_system: %s keyword not allowed in list",
879 /* No calls allowed? */
880 if(!strcmp(cpe
->word
, KW_NONE
)) {
881 if(!first
|| cpe
->next
) {
882 fatal("do_system: %s keyword not allowed in list",
885 rs_start
->rss_flags
&= ~RSS_SYS_BASIC_CALLS
;
889 /* All calls are allowed? */
890 if(!strcmp(cpe
->word
, KW_ALL
)) {
891 if(!first
|| cpe
->next
) {
892 fatal("do_system: %s keyword not allowed in list",
895 for (i
= 0; i
< NR_SYS_CALLS
; i
++)
896 SET_BIT(rs_start
->rss_system
, i
);
900 /* Set single calls as specified in the configuration. */
901 for (i
= 0; system_tab
[i
].label
!= NULL
; i
++)
902 if (!strcmp(cpe
->word
, system_tab
[i
].label
))
904 if (system_tab
[i
].label
== NULL
) {
905 warning("do_system: ignoring unknown call '%s' at %s:%d",
906 cpe
->word
, cpe
->file
, cpe
->line
);
908 SET_BIT(rs_start
->rss_system
,
909 system_tab
[i
].call_nr
- KERNEL_CALL
);
915 static void do_control(config_t
*cpe
, struct rs_start
*rs_start
)
919 /* Process a list of 'control' labels. */
920 for (; cpe
; cpe
= cpe
->next
)
922 if (cpe
->flags
& CFG_SUBLIST
)
924 fatal("do_control: unexpected sublist at %s:%d",
925 cpe
->file
, cpe
->line
);
927 if (cpe
->flags
& CFG_STRING
)
929 fatal("do_control: unexpected string at %s:%d",
930 cpe
->file
, cpe
->line
);
932 if (nr_control
>= RS_NR_CONTROL
)
935 "do_control: RS_NR_CONTROL is too small (%d needed)",
939 rs_start
->rss_control
[nr_control
].l_addr
= (char*) cpe
->word
;
940 rs_start
->rss_control
[nr_control
].l_len
= strlen(cpe
->word
);
941 rs_start
->rss_nr_control
= ++nr_control
;
945 static void do_service(config_t
*cpe
, config_t
*config
, struct rs_config
*rs_config
)
947 struct rs_start
*rs_start
= &rs_config
->rs_start
;
950 /* At this point we expect one sublist that contains the varios
951 * resource allocations
953 if (!(cpe
->flags
& CFG_SUBLIST
))
955 fatal("do_service: expected list at %s:%d",
956 cpe
->file
, cpe
->line
);
958 if (cpe
->next
!= NULL
)
961 fatal("do_service: expected end of list at %s:%d",
962 cpe
->file
, cpe
->line
);
966 /* Process the list */
967 for (cp
= cpe
; cp
; cp
= cp
->next
)
969 if (!(cp
->flags
& CFG_SUBLIST
))
971 fatal("do_service: expected list at %s:%d",
975 if ((cpe
->flags
& CFG_STRING
) || (cpe
->flags
& CFG_SUBLIST
))
977 fatal("do_service: expected word at %s:%d",
978 cpe
->file
, cpe
->line
);
981 if (strcmp(cpe
->word
, KW_CLASS
) == 0)
983 do_class(cpe
->next
, config
, rs_config
);
986 if (strcmp(cpe
->word
, KW_UID
) == 0)
988 do_uid(cpe
->next
, rs_start
);
991 if (strcmp(cpe
->word
, KW_SIGMGR
) == 0)
993 do_sigmgr(cpe
->next
, rs_start
);
996 if (strcmp(cpe
->word
, KW_TYPE
) == 0)
998 do_type(cpe
->next
, rs_config
);
1001 if (strcmp(cpe
->word
, KW_DESCR
) == 0)
1003 do_descr(cpe
->next
, rs_config
);
1006 if (strcmp(cpe
->word
, KW_SCHEDULER
) == 0)
1008 do_scheduler(cpe
->next
, rs_start
);
1011 if (strcmp(cpe
->word
, KW_PRIORITY
) == 0)
1013 do_priority(cpe
->next
, rs_start
);
1016 if (strcmp(cpe
->word
, KW_QUANTUM
) == 0)
1018 do_quantum(cpe
->next
, rs_start
);
1021 if (strcmp(cpe
->word
, KW_CPU
) == 0)
1023 do_cpu(cpe
->next
, rs_start
);
1026 if (strcmp(cpe
->word
, KW_IRQ
) == 0)
1028 do_irq(cpe
->next
, rs_start
);
1031 if (strcmp(cpe
->word
, KW_IO
) == 0)
1033 do_io(cpe
->next
, rs_start
);
1036 if (strcmp(cpe
->word
, KW_PCI
) == 0)
1038 do_pci(cpe
->next
, rs_start
);
1041 if (strcmp(cpe
->word
, KW_SYSTEM
) == 0)
1043 do_system(cpe
->next
, rs_start
);
1046 if (strcmp(cpe
->word
, KW_IPC
) == 0)
1048 do_ipc(cpe
->next
, rs_start
);
1051 if (strcmp(cpe
->word
, KW_VM
) == 0)
1053 do_vm(cpe
->next
, rs_start
);
1056 if (strcmp(cpe
->word
, KW_CONTROL
) == 0)
1058 do_control(cpe
->next
, rs_start
);
1064 static const char *do_config(const char *label
, char *filename
, struct rs_config
*rs_config
)
1066 config_t
*config
, *cp
, *cpe
;
1068 struct rs_start
*rs_start
= &rs_config
->rs_start
;
1070 if(!(config
= config_read(filename
, 0, NULL
)))
1071 return NULL
; /* config file read failed. */
1073 /* Set clean rs_start defaults. */
1074 memset(rs_config
, 0, sizeof(*rs_config
));
1075 if(!(pw
= getpwnam(SERVICE_LOGIN
)))
1076 fatal("no passwd file entry for '%s'", SERVICE_LOGIN
);
1077 rs_start
->rss_uid
= pw
->pw_uid
;
1078 rs_start
->rss_sigmgr
= DSRV_SM
;
1079 rs_start
->rss_scheduler
= DSRV_SCH
;
1080 rs_start
->rss_priority
= DSRV_Q
;
1081 rs_start
->rss_quantum
= DSRV_QT
;
1082 rs_start
->rss_cpu
= DSRV_CPU
;
1083 rs_start
->rss_flags
= RSS_VM_BASIC_CALLS
| RSS_SYS_BASIC_CALLS
;
1085 /* Find an entry for our service */
1086 for (cp
= config
; cp
; cp
= cp
->next
)
1088 if (!(cp
->flags
& CFG_SUBLIST
))
1090 fatal("do_config: expected list at %s:%d",
1091 cp
->file
, cp
->line
);
1094 if ((cpe
->flags
& CFG_STRING
) || (cpe
->flags
& CFG_SUBLIST
))
1096 fatal("do_config: expected word at %s:%d",
1097 cpe
->file
, cpe
->line
);
1100 /* At this place we expect the word KW_SERVICE */
1101 if (strcmp(cpe
->word
, KW_SERVICE
) != 0)
1102 fatal("do_config: exected word '%S' at %s:%d",
1103 KW_SERVICE
, cpe
->file
, cpe
->line
);
1106 if ((cpe
->flags
& CFG_STRING
) || (cpe
->flags
& CFG_SUBLIST
))
1108 fatal("do_config: expected word at %s:%d",
1109 cpe
->file
, cpe
->line
);
1112 /* At this place we expect the name of the service. */
1113 if (!label
|| strcmp(cpe
->word
, label
) == 0) {
1120 fprintf(stderr
, "service: service '%s' not found in '%s'\n",
1127 do_service(cpe
, config
, rs_config
);
1130 char *default_ipc
= RSS_IPC_ALL_SYS
;
1131 if(!rs_start
->rss_ipc
) {
1132 rs_start
->rss_ipc
= default_ipc
;
1133 rs_start
->rss_ipclen
= strlen(default_ipc
);
1137 /* config file read ok. */
1141 /* returns failure */
1142 const char *parse_config(char *progname
, int custom_config
, char *req_config
,
1143 struct rs_config
*rs_config
)
1145 char *specificconfig
, *specific_pkg_config
;
1148 /* Config file specified? */
1150 return do_config(progname
, req_config
, rs_config
);
1152 /* No specific config file. */
1153 if(asprintf(&specificconfig
, "%s/%s", _PATH_SYSTEM_CONF_DIR
,
1155 errx(1, "no memory");
1158 if(asprintf(&specific_pkg_config
, "%s/%s", _PATH_SYSTEM_CONF_PKG_DIR
,
1160 errx(1, "no memory");
1163 /* Try specific config filename first, in base system
1164 * and package locations, * and only if it fails, the global
1167 if((l
=do_config(progname
, specific_pkg_config
, rs_config
))) return l
;
1168 if((l
=do_config(progname
, specificconfig
, rs_config
))) return l
;
1169 if((l
=do_config(progname
, req_config
, rs_config
))) return l
;