]> Zhao Yanbai Git Server - minix.git/commitdiff
service clone command to clone system services on demand.
authorCristiano Giuffrida <cristiano@minix3.org>
Mon, 28 Jun 2010 21:38:29 +0000 (21:38 +0000)
committerCristiano Giuffrida <cristiano@minix3.org>
Mon, 28 Jun 2010 21:38:29 +0000 (21:38 +0000)
commands/service/service.c
include/minix/com.h
servers/rs/main.c
servers/rs/proto.h
servers/rs/request.c

index 8ff08c2c817be05d19e75e76cbf5eacdeb88492a..b885df96170f409a023796e0754ebea5e2c0b2b0 100644 (file)
@@ -41,6 +41,7 @@ PRIVATE char *known_requests[] = {
   "restart",
   "shutdown", 
   "update",
+  "clone",
   "catch for illegal requests"
 };
 #define ILLEGAL_REQUEST  sizeof(known_requests)/sizeof(char *)
@@ -130,6 +131,7 @@ PRIVATE void print_usage(char *app_name, char *problem)
   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");
 }
@@ -351,11 +353,12 @@ PRIVATE int parse_arguments(int argc, char **argv)
           }
       }
   }
-  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];
@@ -1122,6 +1125,7 @@ PUBLIC int main(int argc, char **argv)
   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;
index bb7820b9ce2ceb81e5009bab51f85c3e89639c6d..4b3c1df34ee15ffd999af9b975c6d245d46781c4 100644 (file)
 #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 */
 
index 02214e0eb75a3e9bc708e425d09464ace71c5f2e..e862e6ffb6d94415e22d3fa005506deba570a618 100644 (file)
@@ -112,6 +112,7 @@ PUBLIC int main(void)
           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. */
index 89d37174d69d29f086b08b51391ee291aa8c9147..03d075ac6f44023f6304fa918e9bf0b11418bb62 100644 (file)
@@ -15,6 +15,7 @@ _PROTOTYPE( int do_up, (message *m));
 _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));
index d18d25ccd6ee40abdb28cfb6860a388217715d3e..ad3de02ddc66363ebeaa2818b4d155ab831f1156 100755 (executable)
@@ -174,6 +174,51 @@ PUBLIC int do_restart(message *m_ptr)
   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                                   *
@@ -516,7 +561,7 @@ message *m_ptr;
    */
   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;