"restart",
"shutdown",
"update",
+ "clone",
"catch for illegal requests"
};
#define ILLEGAL_REQUEST sizeof(known_requests)/sizeof(char *)
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");
}
}
}
}
- else if (req_nr == RS_DOWN || req_nr == RS_REFRESH || req_nr == RS_RESTART) {
+ else if (req_nr == RS_DOWN || req_nr == RS_REFRESH || req_nr == RS_RESTART
+ || req_nr == RS_CLONE) {
/* Verify argument count. */
if (argc - 1 < optind+ARG_LABEL) {
- print_usage(argv[ARG_NAME], "action requires a label to stop");
+ print_usage(argv[ARG_NAME], "action requires a target label");
exit(EINVAL);
}
req_label= argv[optind+ARG_LABEL];
case RS_DOWN:
case RS_REFRESH:
case RS_RESTART:
+ case RS_CLONE:
m.RS_CMD_ADDR = req_label;
m.RS_CMD_LEN = strlen(req_label);
break;
#define RS_RESTART (RS_RQ_BASE + 3) /* restart system service */
#define RS_SHUTDOWN (RS_RQ_BASE + 4) /* alert about shutdown */
#define RS_UPDATE (RS_RQ_BASE + 5) /* update system service */
+#define RS_CLONE (RS_RQ_BASE + 6) /* clone system service */
#define RS_LOOKUP (RS_RQ_BASE + 8) /* lookup server name */
case RS_RESTART: result = do_restart(&m); break;
case RS_SHUTDOWN: result = do_shutdown(&m); break;
case RS_UPDATE: result = do_update(&m); break;
+ case RS_CLONE: result = do_clone(&m); break;
case GETSYSINFO: result = do_getsysinfo(&m); break;
case RS_LOOKUP: result = do_lookup(&m); break;
/* Ready messages. */
_PROTOTYPE( int do_down, (message *m));
_PROTOTYPE( int do_refresh, (message *m));
_PROTOTYPE( int do_restart, (message *m));
+_PROTOTYPE( int do_clone, (message *m));
_PROTOTYPE( int do_shutdown, (message *m));
_PROTOTYPE( void do_period, (message *m));
_PROTOTYPE( int do_init_ready, (message *m));
return OK;
}
+/*===========================================================================*
+ * do_clone *
+ *===========================================================================*/
+PUBLIC int do_clone(message *m_ptr)
+{
+ struct rproc *rp;
+ struct rprocpub *rpub;
+ int s, r;
+ char label[RS_MAX_LABEL_LEN];
+ char script[MAX_SCRIPT_LEN];
+
+ /* Copy label. */
+ s = copy_label(m_ptr->m_source, m_ptr->RS_CMD_ADDR,
+ m_ptr->RS_CMD_LEN, label, sizeof(label));
+ if(s != OK) {
+ return s;
+ }
+
+ /* Lookup slot by label. */
+ rp = lookup_slot_by_label(label);
+ if(!rp) {
+ if(rs_verbose)
+ printf("RS: do_clone: service '%s' not found\n", label);
+ return(ESRCH);
+ }
+ rpub = rp->r_pub;
+
+ /* Check if the call can be allowed. */
+ if((r = check_call_permission(m_ptr->m_source, RS_CLONE, rp)) != OK)
+ return r;
+
+ /* Don't clone if a replica is already available. */
+ if(rp->r_next_rp) {
+ return EEXIST;
+ }
+
+ /* Clone the service as requested. */
+ rpub->sys_flags |= SF_USE_REPL;
+ if ((r = clone_service(rp)) != OK) {
+ rpub->sys_flags &= ~SF_USE_REPL;
+ return r;
+ }
+
+ return OK;
+}
/*===========================================================================*
* do_refresh *
*/
for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
rpub = rp->r_pub;
- if ((rp->r_flags & RS_IN_USE) && !(rp->r_flags & RS_UPDATING)) {
+ if ((rp->r_flags & RS_ACTIVE) && !(rp->r_flags & RS_UPDATING)) {
/* Compute period. */
period = rpub->period;