1 /* Utility to start or stop system services. Requests are sent to the
2 * reincarnation server that does the actual work.
5 * Nov 22, 2009: added basic live update support (Cristiano Giuffrida)
6 * Jul 22, 2005: Created (Jorrit N. Herder)
19 #include <minix/config.h>
20 #include <minix/com.h>
21 #include <minix/const.h>
22 #include <minix/type.h>
23 #include <minix/ipc.h>
25 #include <minix/syslib.h>
26 #include <minix/sysinfo.h>
27 #include <minix/bitmap.h>
28 #include <minix/paths.h>
29 #include <minix/sef.h>
30 #include <minix/dmap.h>
31 #include <sys/types.h>
33 #include <configfile.h>
35 #include <machine/archtypes.h>
36 #include <minix/timers.h>
42 /* This array defines all known requests. */
43 static char *known_requests
[] = {
55 "catch for illegal requests"
57 static int known_request_types
[] = {
71 #define ILLEGAL_REQUEST sizeof(known_requests)/sizeof(char *)
73 /* Global error number set for failed system calls. */
77 #define RUN_SCRIPT "/etc/rs.single" /* Default script for 'run' */
78 #define SELF_BINARY "self"
79 #define SELF_REQ_PATH "/dev/null"
80 #define PATH_CONFIG _PATH_SYSTEM_CONF /* Default config file */
81 #define DEFAULT_LU_STATE SEF_LU_STATE_WORK_FREE /* Default lu state */
82 #define DEFAULT_LU_MAXTIME 0 /* Default lu max time */
84 /* Define names for options provided to this utility. */
85 #define OPT_COPY "-c" /* copy executable image */
86 #define OPT_REUSE "-r" /* reuse executable image */
87 #define OPT_NOBLOCK "-n" /* unblock caller immediately */
88 #define OPT_REPLICA "-p" /* create replica for the service */
89 #define OPT_NO_BIN_EXP "-b" /* no binary exponential backoff */
90 #define OPT_BATCH "-q" /* batch mode */
91 #define OPT_ASR_LU "-a" /* asr update */
92 #define OPT_PREPARE_ONLY_LU "-o" /* prepare-only update */
93 #define OPT_FORCE_SELF_LU "-s" /* force self update */
94 #define OPT_FORCE_INIT_CRASH "-x" /* force init crash (for debugging) */
95 #define OPT_FORCE_INIT_FAIL "-y" /* force init failure (for debugging) */
96 #define OPT_FORCE_INIT_TIMEOUT "-z" /* force init timeout (for debugging) */
97 #define OPT_FORCE_INIT_DEFCB "-d" /* force init default callback */
98 #define OPT_NOMMAP_LU "-m" /* don't inherit mmaped regions */
99 #define OPT_DETACH "-e" /* detach on update/restart */
100 #define OPT_NORESTART "-f" /* don't restart */
101 #define OPT_FORCE_INIT_ST "-t" /* force init state transfer */
103 /* Define names for arguments provided to this utility. The first few
104 * arguments are required and have a known index. Thereafter, some optional
105 * argument pairs like "-args arglist" follow.
107 #define ARG_NAME 0 /* own application name */
109 /* The following are relative to optind */
110 #define ARG_REQUEST 0 /* request to perform */
111 #define ARG_PATH 1 /* system service */
112 #define ARG_LABEL 1 /* name of system service */
113 #define ARG_SYSCTL_TYPE 1 /* sysctl action type */
116 #define MIN_ARG_COUNT 1 /* require an action */
118 #define ARG_ARGS "-args" /* list of arguments to be passed */
119 #define ARG_DEV "-dev" /* major device number for drivers */
120 #define ARG_MAJOR "-major" /* major number */
121 #define ARG_PERIOD "-period" /* heartbeat period in ticks */
122 #define ARG_SCRIPT "-script" /* name of the script to restart a
125 #define ARG_LABELNAME "-label" /* custom label name */
126 #define ARG_PROGNAME "-progname" /* custom program name */
127 #define ARG_CONFIG "-config" /* name of the file with the resource
131 #define ARG_LU_STATE "-state" /* the live update state required */
132 #define ARG_LU_MAXTIME "-maxtime" /* max time to prepare for the update */
133 #define ARG_DEVMANID "-devid" /* the id of the devman device this
134 driver should be able to access */
135 #define ARG_HEAP_PREALLOC "-heap-prealloc" /* preallocate heap regions */
136 #define ARG_MAP_PREALLOC "-map-prealloc" /* preallocate mmapped regions */
137 #define ARG_TRG_LABELNAME "-trg-label" /* target label name */
138 #define ARG_LU_IPC_BL "-ipc_bl" /* IPC blacklist filter */
139 #define ARG_LU_IPC_WL "-ipc_wl" /* IPC whitelist filter */
140 #define ARG_ASR_COUNT "-asr-count" /* number of ASR live updates */
141 #define ARG_RESTARTS "-restarts" /* number of restarts */
143 /* The function parse_arguments() verifies and parses the command line
144 * parameters passed to this utility. Request parameters that are needed
145 * are stored globally in the following variables:
148 static int do_run
= 0; /* 'run' command instead of 'up' */
149 static char *req_label
= NULL
;
150 static char *req_trg_label
= NULL
;
151 static char *req_path
= NULL
;
152 static char *req_path_self
= SELF_REQ_PATH
;
153 static char *req_progname
= NULL
;
154 static char *req_args
= "";
155 static int req_major
= 0;
156 static int devman_id
= 0;
157 static long req_period
= 0;
158 static char *req_script
= NULL
;
159 static char *req_config
= PATH_CONFIG
;
160 static int custom_config_file
= 0;
161 static int req_lu_state
= DEFAULT_LU_STATE
;
162 static int req_lu_maxtime
= DEFAULT_LU_MAXTIME
;
163 static int req_restarts
= 0;
164 static int req_asr_count
= -1;
165 static long req_heap_prealloc
= 0;
166 static long req_map_prealloc
= 0;
167 static int req_sysctl_type
= 0;
168 static struct rs_ipc_filter_el rs_ipc_filter_els
[RS_MAX_IPC_FILTERS
][IPCF_MAX_ELEMENTS
];
169 static int num_ipc_filters
= 0;
170 static char *req_state_eval
= NULL
;
172 /* Buffer to build "/command arg1 arg2 ..." string to pass to RS server. */
173 static char command
[4096];
175 /* An error occurred. Report the problem, print the usage, and exit.
177 static void print_usage(char *app_name
, char *problem
)
179 fprintf(stderr
, "Warning, %s\n", problem
);
180 fprintf(stderr
, "Usage:\n");
182 " %s [%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s] (up|run|edit|update) <binary|%s> [%s <args>] [%s <special>] [%s <major_nr>] [%s <dev_id>] [%s <ticks>] [%s <path>] [%s <name>] [%s <name>] [%s <path>] [%s <state value|eval_expression>] [%s <time>] [%s <bytes>] [%s <bytes>] [%s <name>] [(%s|%s <src_label1,src_type1:src_label2,:,src_type3:...>)*] [%s <count>] [%s <restarts>]\n",
183 app_name
, OPT_COPY
, OPT_REUSE
, OPT_NOBLOCK
, OPT_REPLICA
, OPT_NO_BIN_EXP
,
184 OPT_BATCH
, OPT_ASR_LU
, OPT_PREPARE_ONLY_LU
, OPT_FORCE_SELF_LU
,
185 OPT_FORCE_INIT_CRASH
, OPT_FORCE_INIT_FAIL
, OPT_FORCE_INIT_TIMEOUT
,
186 OPT_FORCE_INIT_DEFCB
, OPT_NOMMAP_LU
, OPT_DETACH
,
187 OPT_NORESTART
, OPT_FORCE_INIT_ST
, SELF_BINARY
,
188 ARG_ARGS
, ARG_DEV
, ARG_MAJOR
, ARG_DEVMANID
, ARG_PERIOD
,
189 ARG_SCRIPT
, ARG_LABELNAME
, ARG_PROGNAME
, ARG_CONFIG
, ARG_LU_STATE
, ARG_LU_MAXTIME
,
190 ARG_HEAP_PREALLOC
, ARG_MAP_PREALLOC
, ARG_TRG_LABELNAME
, ARG_LU_IPC_BL
, ARG_LU_IPC_WL
,
191 ARG_ASR_COUNT
, ARG_RESTARTS
);
192 fprintf(stderr
, " %s down <label>\n", app_name
);
193 fprintf(stderr
, " %s refresh <label>\n", app_name
);
194 fprintf(stderr
, " %s restart <label>\n", app_name
);
195 fprintf(stderr
, " %s clone <label>\n", app_name
);
196 fprintf(stderr
, " %s unclone <label>\n", app_name
);
197 fprintf(stderr
, " %s fi <label>\n", app_name
);
198 fprintf(stderr
, " %s sysctl <srv_status|upd_start|upd_run|upd_stop|upd_status>\n", app_name
);
199 fprintf(stderr
, " %s shutdown\n", app_name
);
200 fprintf(stderr
, " Options:\n");
201 fprintf(stderr
, " %s: copy executable image \n", OPT_COPY
);
202 fprintf(stderr
, " %s: reuse executable image \n", OPT_REUSE
);
203 fprintf(stderr
, " %s: unblock caller immediately \n", OPT_NOBLOCK
);
204 fprintf(stderr
, " %s: create replica for the service \n", OPT_REPLICA
);
205 fprintf(stderr
, " %s: batch mode \n", OPT_BATCH
);
206 fprintf(stderr
, " %s: asr update \n", OPT_ASR_LU
);
207 fprintf(stderr
, " %s: prepare-only update \n", OPT_PREPARE_ONLY_LU
);
208 fprintf(stderr
, " %s: force self update \n", OPT_FORCE_SELF_LU
);
209 fprintf(stderr
, " %s: force init crash (for debugging) \n", OPT_FORCE_INIT_CRASH
);
210 fprintf(stderr
, " %s: force init failure (for debugging)\n", OPT_FORCE_INIT_FAIL
);
211 fprintf(stderr
, " %s: force init timeout (for debugging)\n", OPT_FORCE_INIT_TIMEOUT
);
212 fprintf(stderr
, " %s: force init default callback \n", OPT_FORCE_INIT_DEFCB
);
213 fprintf(stderr
, " %s: don't inherit mmaped regions \n", OPT_NOMMAP_LU
);
214 fprintf(stderr
, " %s: detach on update/restart \n", OPT_DETACH
);
215 fprintf(stderr
, " %s: don't restart \n", OPT_NORESTART
);
216 fprintf(stderr
, " %s: force init state transfer \n", OPT_FORCE_INIT_ST
);
218 fprintf(stderr
, "\n");
221 /* A request to the RS server failed. Report and exit.
223 static void failure(int request
)
225 fprintf(stderr
, "Request 0x%x to RS failed: %s (error %d)\n", request
, strerror(errno
), errno
);
229 static int parse_ipc_filter(char* str
, int type_flag
)
231 char *el_str
, *label_str
, *type_str
;
232 char el_strings
[IPCF_MAX_ELEMENTS
][RS_MAX_IPCF_STR_LEN
];
233 int i
, num_els
, label_len
, type_len
;
234 struct rs_ipc_filter_el
*ipcf_el
;
235 if(num_ipc_filters
+1 > RS_MAX_IPC_FILTERS
) {
238 el_str
= (char*) strsep(&str
,":");
240 while (el_str
!= NULL
)
242 if(num_els
>= IPCF_MAX_ELEMENTS
) {
245 if(strlen(el_str
)>=RS_MAX_IPCF_STR_LEN
) {
248 strcpy(el_strings
[num_els
], el_str
);
249 el_str
= (char*) strsep(&str
, ":");
252 memset(rs_ipc_filter_els
[num_ipc_filters
],0,IPCF_MAX_ELEMENTS
);
253 for(i
=0;i
<num_els
;i
++) {
254 el_str
= el_strings
[i
];
255 ipcf_el
= &rs_ipc_filter_els
[num_ipc_filters
][i
];
256 label_str
= (char*) strsep(&el_str
,",");
257 type_str
= (char*) strsep(&el_str
,",");
258 if(!label_str
|| !type_str
|| strsep(&el_str
,",")) {
261 label_len
= strlen(label_str
);
262 type_len
= strlen(type_str
);
265 if(label_len
>= RS_MAX_LABEL_LEN
) {
268 strcpy(ipcf_el
->m_label
, label_str
);
269 ipcf_el
->flags
|= IPCF_MATCH_M_SOURCE
;
274 ipcf_el
->m_type
= strtol(type_str
, &buff
, 10);
275 if(errno
|| strcmp(buff
, "")) {
278 ipcf_el
->flags
|= IPCF_MATCH_M_TYPE
;
280 if(ipcf_el
->flags
== 0) {
283 ipcf_el
->flags
|= type_flag
;
289 /* Parse and verify correctness of arguments. Report problem and exit if an
290 * error is found. Store needed parameters in global variables.
292 static int parse_arguments(int argc
, char **argv
, u32_t
*rss_flags
)
294 struct stat stat_buf
;
298 int b_flag
, c_flag
, r_flag
, n_flag
, p_flag
, q_flag
,
299 a_flag
, o_flag
, s_flag
, x_flag
, y_flag
,
300 z_flag
, d_flag
, u_flag
, m_flag
, e_flag
,
322 while (c
= getopt(argc
, argv
, "rbcnpqaosxyzdumeft?"), c
!= -1)
327 print_usage(argv
[ARG_NAME
], "wrong number of arguments");
336 c_flag
= 1; /* -r implies -c */
385 fprintf(stderr
, "%s: getopt failed: %c\n",
391 /* Verify argument count. */
392 if (argc
< optind
+MIN_ARG_COUNT
) {
393 print_usage(argv
[ARG_NAME
], "wrong number of arguments");
397 if (strcmp(argv
[optind
+ARG_REQUEST
], RUN_CMD
) == 0)
404 /* Verify request type. */
405 for (req_type
=0; req_type
< ILLEGAL_REQUEST
; req_type
++) {
406 if (strcmp(known_requests
[req_type
],argv
[optind
+ARG_REQUEST
])==0)
409 if (req_type
== ILLEGAL_REQUEST
) {
410 print_usage(argv
[ARG_NAME
], "illegal request type");
413 req_nr
= known_request_types
[req_type
];
417 if (req_nr
== RS_UP
|| req_nr
== RS_UPDATE
|| req_nr
== RS_EDIT
) {
421 *rss_flags
|= RSS_COPY
;
424 *rss_flags
|= RSS_REUSE
;
427 *rss_flags
|= RSS_NOBLOCK
;
430 *rss_flags
|= RSS_REPLICA
;
433 *rss_flags
|= RSS_NO_BIN_EXP
;
436 *rss_flags
|= RSS_BATCH
;
439 *rss_flags
|= RSS_ASR_LU
;
442 *rss_flags
|= RSS_FORCE_SELF_LU
;
445 *rss_flags
|= RSS_PREPARE_ONLY_LU
;
448 *rss_flags
|= RSS_FORCE_INIT_CRASH
;
451 *rss_flags
|= RSS_FORCE_INIT_FAIL
;
454 *rss_flags
|= RSS_FORCE_INIT_TIMEOUT
;
457 *rss_flags
|= RSS_FORCE_INIT_DEFCB
;
460 *rss_flags
|= RSS_NOMMAP_LU
;
463 *rss_flags
|= RSS_DETACH
;
466 *rss_flags
|= RSS_NORESTART
;
469 *rss_flags
|= RSS_FORCE_INIT_ST
;
471 /* Verify argument count. */
472 if (argc
- 1 < optind
+ARG_PATH
) {
473 print_usage(argv
[ARG_NAME
], "action requires a binary to start");
477 if(req_nr
!= RS_UPDATE
&& q_flag
) {
478 print_usage(argv
[ARG_NAME
], "action does not support batch mode");
482 req_path
= argv
[optind
+ARG_PATH
];
483 if(req_nr
== RS_UPDATE
&& !strcmp(req_path
, SELF_BINARY
)) {
484 /* Self update needs no real path or configuration file. */
486 req_path
= req_path_self
;
487 *rss_flags
|= RSS_SELF_LU
;
492 /* Set default recovery script for RUN */
493 req_script
= RUN_SCRIPT
;
496 /* Verify the name of the binary of the system service. */
497 if(!(*rss_flags
& RSS_SELF_LU
)) {
498 if (req_path
[0] != '/') {
499 print_usage(argv
[ARG_NAME
], "binary should be absolute path");
502 if (stat(req_path
, &stat_buf
) == -1) {
504 fprintf(stderr
, "%s: couldn't get stat binary\n", argv
[ARG_NAME
]);
507 if (! (stat_buf
.st_mode
& S_IFREG
)) {
508 print_usage(argv
[ARG_NAME
], "binary is not a regular file");
514 system_hz
= (u32_t
) sysconf(_SC_CLK_TCK
);
516 /* Check optional arguments that come in pairs like "-args arglist". */
517 for (i
=optind
+MIN_ARG_COUNT
+1; i
<argc
; i
=i
+2) {
518 if (! (i
+1 < argc
)) {
519 print_usage(argv
[ARG_NAME
], "optional argument not complete");
522 if (strcmp(argv
[i
], ARG_ARGS
)==0) {
523 req_args
= argv
[i
+1];
525 else if (strcmp(argv
[i
], ARG_PERIOD
)==0) {
526 req_period
= strtol(argv
[i
+1], &hz
, 10);
527 if (strcmp(hz
,"HZ")==0) req_period
*= system_hz
;
528 if (req_period
< 0) {
529 print_usage(argv
[ARG_NAME
], "bad period argument");
533 else if (strcmp(argv
[i
], ARG_DEV
)==0) {
534 if (stat(argv
[i
+1], &stat_buf
) == -1) {
536 print_usage(argv
[ARG_NAME
], "couldn't get status of device");
539 if ( ! (stat_buf
.st_mode
& (S_IFBLK
| S_IFCHR
))) {
540 print_usage(argv
[ARG_NAME
], "special file is not a device");
543 if (req_major
!= 0) {
544 print_usage(argv
[ARG_NAME
], "major already set");
547 req_major
= major(stat_buf
.st_rdev
);
549 else if (strcmp(argv
[i
], ARG_MAJOR
)==0) {
550 if (req_major
!= 0) {
551 print_usage(argv
[ARG_NAME
], "major already set");
555 req_major
= atoi(argv
[i
+1]);
560 else if (strcmp(argv
[i
], ARG_SCRIPT
)==0) {
561 req_script
= argv
[i
+1];
563 else if (strcmp(argv
[i
], ARG_LABELNAME
)==0) {
564 req_label
= argv
[i
+1];
566 else if (strcmp(argv
[i
], ARG_TRG_LABELNAME
)==0) {
567 req_trg_label
= argv
[i
+1];
569 else if (strcmp(argv
[i
], ARG_PROGNAME
)==0) {
570 req_progname
= argv
[i
+1];
572 else if (strcmp(argv
[i
], ARG_CONFIG
)==0) {
573 req_config
= argv
[i
+1];
574 custom_config_file
= 1;
576 else if (strcmp(argv
[i
], ARG_LU_STATE
)==0) {
578 req_lu_state
= strtol(argv
[i
+1], &buff
, 10);
579 if(errno
|| strcmp(buff
, "")) {
580 /* State is not a number, assume it's an eval expression. */
581 req_lu_state
= SEF_LU_STATE_EVAL
;
582 req_state_eval
= argv
[i
+1];
584 else if(req_lu_state
== SEF_LU_STATE_NULL
) {
585 print_usage(argv
[ARG_NAME
], "null live update state");
589 else if (strcmp(argv
[i
], ARG_LU_MAXTIME
)==0) {
591 req_lu_maxtime
= strtol(argv
[i
+1], &hz
, 10);
592 if(errno
|| (strcmp(hz
, "") && strcmp(hz
, "HZ"))
593 || req_lu_maxtime
<0) {
594 print_usage(argv
[ARG_NAME
],
595 "bad live update max time");
598 if(req_lu_maxtime
== 0) {
599 /* no timeout requested. */
602 else if (strcmp(hz
,"HZ")==0) req_lu_maxtime
*= system_hz
;
604 else if (strcmp(argv
[i
], ARG_DEVMANID
) == 0) {
606 devman_id
= atoi(argv
[i
+1]);
611 else if (strcmp(argv
[i
], ARG_HEAP_PREALLOC
)==0) {
613 req_heap_prealloc
= strtol(argv
[i
+1], &buff
, 10);
614 if(errno
|| strcmp(buff
, "") || req_heap_prealloc
<= 0) {
615 print_usage(argv
[ARG_NAME
], "bad heap prealloc bytes");
619 else if (strcmp(argv
[i
], ARG_MAP_PREALLOC
)==0) {
621 req_map_prealloc
= strtol(argv
[i
+1], &buff
, 10);
622 if(errno
|| strcmp(buff
, "") || req_map_prealloc
<= 0) {
623 print_usage(argv
[ARG_NAME
], "bad heap prealloc bytes");
627 else if (strcmp(argv
[i
], ARG_LU_IPC_BL
)==0) {
628 if((r
=parse_ipc_filter(argv
[i
+1], IPCF_EL_BLACKLIST
)) != OK
) {
629 print_usage(argv
[ARG_NAME
], "bad IPC blacklist filter");
633 else if (strcmp(argv
[i
], ARG_LU_IPC_WL
)==0) {
634 if((r
=parse_ipc_filter(argv
[i
+1], IPCF_EL_WHITELIST
)) != OK
) {
635 print_usage(argv
[ARG_NAME
], "bad IPC whitelist filter");
639 else if (strcmp(argv
[i
], ARG_ASR_COUNT
)==0) {
641 req_asr_count
= strtol(argv
[i
+1], &buff
, 10);
642 if(errno
|| strcmp(buff
, "") || req_asr_count
<0) {
643 print_usage(argv
[ARG_NAME
], "bad ASR count");
647 else if (strcmp(argv
[i
], ARG_RESTARTS
)==0) {
649 req_restarts
= strtol(argv
[i
+1], &buff
, 10);
650 if(errno
|| strcmp(buff
, "") || req_restarts
<0) {
651 print_usage(argv
[ARG_NAME
], "bad number of restarts");
656 print_usage(argv
[ARG_NAME
], "unknown optional argument given");
661 else if (req_nr
== RS_DOWN
|| req_nr
== RS_REFRESH
|| req_nr
== RS_RESTART
662 || req_nr
== RS_CLONE
|| req_nr
== RS_UNCLONE
|| req_nr
== RS_FI
) {
664 /* Verify argument count. */
665 if (argc
- 1 < optind
+ARG_LABEL
) {
666 print_usage(argv
[ARG_NAME
], "action requires a target label");
669 req_label
= argv
[optind
+ARG_LABEL
];
671 else if (req_nr
== RS_SYSCTL
) {
672 char* sysctl_types
[] = { "srv_status", "upd_start", "upd_run", "upd_stop",
673 "upd_status", NULL
};
675 int sysctl_type_values
[] = { RS_SYSCTL_SRV_STATUS
, RS_SYSCTL_UPD_START
,
676 RS_SYSCTL_UPD_RUN
, RS_SYSCTL_UPD_STOP
, RS_SYSCTL_UPD_STATUS
};
678 /* Verify argument count. */
679 if (argc
- 1 < optind
+ARG_SYSCTL_TYPE
) {
680 print_usage(argv
[ARG_NAME
], "sysctl requires an action type");
684 sysctl_type
= argv
[optind
+ARG_SYSCTL_TYPE
];
685 for(i
=0;sysctl_types
[i
]!=NULL
;i
++) {
686 if(!strcmp(sysctl_types
[i
], sysctl_type
)) {
690 if(sysctl_types
[i
] == NULL
) {
691 print_usage(argv
[ARG_NAME
], "bad sysctl type");
694 req_sysctl_type
= sysctl_type_values
[i
];
696 else if (req_nr
== RS_SHUTDOWN
) {
697 /* no extra arguments required */
700 label_required
= (*rss_flags
& RSS_SELF_LU
) || (req_nr
== RS_EDIT
);
701 if(label_required
&& !req_label
) {
702 print_usage(argv
[ARG_NAME
], "label option mandatory for target action");
706 /* Return the request number if no error were found. */
712 int main(int argc
, char **argv
)
715 int result
= EXIT_SUCCESS
;
717 char *progname
= NULL
;
718 /* Arguments for RS to start a new service */
719 struct rs_config config
;
722 /* Verify and parse the command line arguments. All arguments are checked
723 * here. If an error occurs, the problem is reported and exit(2) is called.
724 * all needed parameters to perform the request are extracted and stored
727 request
= parse_arguments(argc
, argv
, &rss_flags
);
729 /* Arguments seem fine. Try to perform the request. Only valid requests
730 * should end up here. The default is used for not yet supported requests.
733 memset(&m
, 0, sizeof(m
));
736 m
.m_rs_update
.state
= req_lu_state
;
737 m
.m_rs_update
.prepare_maxtime
= req_lu_maxtime
;
741 /* Build space-separated command string to be passed to RS server. */
742 if (req_progname
!= NULL
) {
743 progname
= req_progname
;
745 progname
= strrchr(req_path
, '/');
746 assert(progname
); /* an absolute path was required */
747 progname
++; /* skip last slash */
749 strcpy(command
, req_path
);
750 command
[strlen(req_path
)] = ' ';
751 strcpy(command
+strlen(req_path
)+1, req_args
);
755 memset(&config
, 0, sizeof(config
));
756 if(!parse_config(progname
, custom_config_file
, req_config
, &config
))
757 errx(1, "couldn't parse config");
758 assert(config
.rs_start
.rss_priority
< NR_SCHED_QUEUES
);
759 assert(config
.rs_start
.rss_quantum
> 0);
763 config
.rs_start
.rss_cmd
= command
;
764 config
.rs_start
.rss_cmdlen
= strlen(command
);
765 config
.rs_start
.rss_progname
= progname
;
766 config
.rs_start
.rss_prognamelen
= strlen(progname
);
767 config
.rs_start
.rss_major
= req_major
;
768 config
.rs_start
.rss_period
= req_period
;
769 config
.rs_start
.rss_script
= req_script
;
770 config
.rs_start
.rss_asr_count
= req_asr_count
;
771 config
.rs_start
.rss_restarts
= req_restarts
;
772 config
.rs_start
.devman_id
= devman_id
;
773 config
.rs_start
.rss_heap_prealloc_bytes
= req_heap_prealloc
;
774 config
.rs_start
.rss_map_prealloc_bytes
= req_map_prealloc
;
775 config
.rs_start
.rss_flags
|= rss_flags
;
777 config
.rs_start
.rss_label
.l_addr
= req_label
;
778 config
.rs_start
.rss_label
.l_len
= strlen(req_label
);
780 config
.rs_start
.rss_label
.l_addr
= progname
;
781 config
.rs_start
.rss_label
.l_len
= strlen(progname
);
784 config
.rs_start
.rss_trg_label
.l_addr
= req_trg_label
;
785 config
.rs_start
.rss_trg_label
.l_len
= strlen(req_trg_label
);
787 config
.rs_start
.rss_trg_label
.l_addr
= 0;
788 config
.rs_start
.rss_trg_label
.l_len
= 0;
791 config
.rs_start
.rss_scriptlen
= strlen(req_script
);
793 config
.rs_start
.rss_scriptlen
= 0;
795 /* State-related data. */
796 config
.rs_start
.rss_state_data
.size
=
797 sizeof(config
.rs_start
.rss_state_data
);
798 if(num_ipc_filters
> 0) {
799 config
.rs_start
.rss_state_data
.ipcf_els
= rs_ipc_filter_els
;
800 config
.rs_start
.rss_state_data
.ipcf_els_size
=
801 num_ipc_filters
*sizeof(rs_ipc_filter_els
[0]);
804 config
.rs_start
.rss_state_data
.ipcf_els
= NULL
;
805 config
.rs_start
.rss_state_data
.ipcf_els_size
= 0;
808 config
.rs_start
.rss_state_data
.eval_addr
= req_state_eval
;
809 config
.rs_start
.rss_state_data
.eval_len
= strlen(req_state_eval
);
812 config
.rs_start
.rss_state_data
.eval_addr
= NULL
;
813 config
.rs_start
.rss_state_data
.eval_len
= 0;
816 m
.m_rs_req
.addr
= (char *) &config
.rs_start
;
824 m
.m_rs_req
.addr
= req_label
;
825 m
.m_rs_req
.len
= strlen(req_label
);
828 m
.m_rs_req
.subtype
= req_sysctl_type
;
833 print_usage(argv
[ARG_NAME
], "request is not yet supported");
837 /* Build request message and send the request. */
839 if (_syscall(RS_PROC_NR
, request
, &m
) == -1)