]> Zhao Yanbai Git Server - minix.git/commitdiff
Share exec images in RS.
authorCristiano Giuffrida <cristiano@minix3.org>
Wed, 23 Dec 2009 14:05:20 +0000 (14:05 +0000)
committerCristiano Giuffrida <cristiano@minix3.org>
Wed, 23 Dec 2009 14:05:20 +0000 (14:05 +0000)
RS CHANGES:
- RS retains information on both labels and process names now. Labels for boot
processes are configured in the boot image priv table. Process names are
inherited from the in-kernel boot image table.
- When RS_REUSE is specified in do_up, RS looks for an existing slot having the
same process name as the one we are about to start. If one is found with
an in-memory copy of its executable image, the image is then shared between
the two processes, rather than copying it again. This behavior can be specified
by using 'service -r' when starting a system service from the command line.

drivers/memory/ramdisk/rc
servers/rs/main.c
servers/rs/manager.c
servers/rs/table.c
servers/rs/type.h

index 4ef68b53c89851cbd7d055c23d810c2f48701d7e..a03e4a914de0f9afea6ee28bd0ee48802744a732 100644 (file)
@@ -13,7 +13,7 @@ then
        /bin/service -c up /bin/bios_wini -dev /dev/c0d0
 else
        /bin/service -c up /bin/at_wini -dev /dev/c0d0 -config /etc/system.conf -label at_wini_0
-       /bin/service -c up /bin/at_wini -dev /dev/c1d0 -config /etc/system.conf -label at_wini_1 -args ata_instance=1
+       /bin/service -c -r up /bin/at_wini -dev /dev/c1d0 -config /etc/system.conf -label at_wini_1 -args ata_instance=1
 fi
 
 rootdev=`sysenv rootdev` || echo 'No rootdev?'
index 2b3a0a460b252c4afecde99988307b3fc8d97cc8..2986dc16946d835cddcf5fd865daea883429abc6 100644 (file)
@@ -453,6 +453,9 @@ PRIVATE void init_server(void)
        * service by using vm_set_priv(). We need a more uniform privilege
        * management scheme in VM for this change.
        */
+      /* Get label. */
+      strcpy(rp->r_label, boot_image_priv->label);
+
       /* Force a static privilege id for system services in the boot image. */
       rp->r_priv.s_id = static_priv_id(_ENDPOINT_P(boot_image_priv->endpoint));
 
@@ -489,8 +492,8 @@ PRIVATE void init_server(void)
       rp->r_dev_style = boot_image_dev->dev_style;    /* device style */
       rp->r_period = boot_image_dev->period;          /* heartbeat period */
 
-      /* Get label. */
-      strcpy(rp->r_label, ip->proc_name);
+      /* Get process name. */
+      strcpy(rp->r_proc_name, ip->proc_name);
 
       /* Get command settings. */
       rp->r_cmd[0]= '\0';
index 0fc66b166720646610d1893467290a5f27277216..053d137778d9b2d1cd52f18017b39bb443607f53 100644 (file)
@@ -29,8 +29,9 @@ FORWARD _PROTOTYPE( int start_service, (struct rproc *rp, int flags,
 FORWARD _PROTOTYPE( int stop_service, (struct rproc *rp,int how) );
 FORWARD _PROTOTYPE( int fork_nb, (void) );
 FORWARD _PROTOTYPE( int read_exec, (struct rproc *rp) );
-FORWARD _PROTOTYPE( int copy_exec, (struct rproc *rp_src,
+FORWARD _PROTOTYPE( int share_exec, (struct rproc *rp_src,
        struct rproc *rp_dst) );
+FORWARD _PROTOTYPE( void free_slot, (struct rproc *rp) );
 FORWARD _PROTOTYPE( void run_script, (struct rproc *rp) );
 FORWARD _PROTOTYPE( char *get_next_label, (char *ptr, char *label,
        char *caller_label) );
@@ -128,8 +129,6 @@ size_t dst_len;
 
   dst_label[len] = 0;
 
-  if (rs_verbose)
-       printf("RS: copy_label: using label (custom) '%s'\n", dst_label);
   return OK;
 }
 
@@ -203,6 +202,21 @@ message *m_ptr;                                    /* request message pointer */
   }
   rp->r_argv[arg_count] = NULL;                        /* end with NULL pointer */
   rp->r_argc = arg_count;
+  
+  /* Process name for the service. */
+  cmd_ptr = strrchr(rp->r_argv[0], '/');
+  if (cmd_ptr)
+       cmd_ptr++;
+  else
+       cmd_ptr= rp->r_argv[0];
+  len= strlen(cmd_ptr);
+  if (len > P_NAME_LEN-1)
+       len= P_NAME_LEN-1;      /* truncate name */
+  memcpy(rp->r_proc_name, cmd_ptr, len);
+  rp->r_proc_name[len]= '\0';
+  if(rs_verbose)
+      printf("RS: do_up: using proc_name (from binary %s) '%s'\n",
+          rp->r_argv[0], rp->r_proc_name);
 
   if(rs_start.rss_label.l_len > 0) {
        /* RS_UP caller has supplied a custom label for this service. */
@@ -214,19 +228,15 @@ message *m_ptr;                                   /* request message pointer */
          printf("RS: do_up: using label (custom) '%s'\n", rp->r_label);
   } else {
        /* Default label for the service. */
-       label= strrchr(rp->r_argv[0], '/');
-       if (label)
-               label++;
-       else
-               label= rp->r_argv[0];
+       label = rp->r_proc_name;
        len= strlen(label);
        if (len > MAX_LABEL_LEN-1)
                len= MAX_LABEL_LEN-1;   /* truncate name */
        memcpy(rp->r_label, label, len);
        rp->r_label[len]= '\0';
         if(rs_verbose)
-          printf("RS: do_up: using label (from binary %s) '%s'\n",
-               rp->r_argv[0], rp->r_label);
+          printf("RS: do_up: using label (from proc_name) '%s'\n",
+               rp->r_label);
   }
 
   if(rs_start.rss_nr_control > 0) {
@@ -302,12 +312,11 @@ message *m_ptr;                                   /* request message pointer */
        exst_cpy = 0;
        
        if(rs_start.rss_flags & RF_REUSE) {
-               char *cmd = rp->r_cmd;
                 int i;
-                
+
                 for(i = 0; i < NR_SYS_PROCS; i++) {
                        rp2 = &rproc[i];
-                        if(strcmp(rp->r_cmd, rp2->r_cmd) == 0 &&
+                        if(strcmp(rp->r_proc_name, rp2->r_proc_name) == 0 &&
                            (rp2->r_sys_flags & SF_USE_COPY)) {
                                 /* We have found the same binary that's
                                  * already been copied */
@@ -320,7 +329,7 @@ message *m_ptr;                                     /* request message pointer */
        if(!exst_cpy)
                s = read_exec(rp);
        else
-               s = copy_exec(rp, rp2); 
+               s = share_exec(rp, rp2);
 
        if (s != OK)
                return s;
@@ -463,15 +472,8 @@ PUBLIC int do_down(message *m_ptr)
        stop_service(rp,RS_EXITING);
        if (rp->r_pid == -1)
        {
-               /* Process is already gone */
-               rp->r_flags = 0;                        /* release slot */
-               if (rp->r_exec)
-               {
-                       free(rp->r_exec);
-                       rp->r_exec= NULL;
-               }
-               proc = _ENDPOINT_P(rp->r_proc_nr_e);
-               rproc_ptr[proc] = NULL;
+               /* Process is already gone, release slot. */
+               free_slot(rp);
                return(OK);
        }
 
@@ -860,12 +862,7 @@ PUBLIC void do_exit(message *m_ptr)
                  }
 
                  /* Release slot. */
-                 rp->r_flags = 0;
-                 if (rp->r_exec)
-                 {
-                       free(rp->r_exec);
-                       rp->r_exec= NULL;
-                 }
+                 free_slot(rp);
              }
              else if(rp->r_flags & RS_REFRESHING) {
                      short is_updating = rp->r_flags & RS_UPDATING;
@@ -1268,6 +1265,9 @@ message *m_ptr;
   return(OK);
 }
 
+/*===========================================================================*
+ *                              fork_nb                                     *
+ *===========================================================================*/
 PRIVATE pid_t fork_nb()
 {
   message m;
@@ -1275,65 +1275,109 @@ PRIVATE pid_t fork_nb()
   return(_syscall(PM_PROC_NR, FORK_NB, &m));
 }
 
-PRIVATE int copy_exec(rp_dst, rp_src)
+/*===========================================================================*
+ *                             share_exec                                   *
+ *===========================================================================*/
+PRIVATE int share_exec(rp_dst, rp_src)
 struct rproc *rp_dst, *rp_src;
 {
-       /* Copy binary from rp_src to rp_dst. */
-       rp_dst->r_exec_len = rp_src->r_exec_len;
-       rp_dst->r_exec = malloc(rp_dst->r_exec_len);
-       if(rp_dst->r_exec == NULL)
-               return ENOMEM;
-
-       memcpy(rp_dst->r_exec, rp_src->r_exec, rp_dst->r_exec_len);
-       if(rp_dst->r_exec_len != 0 && rp_dst->r_exec != NULL)
-               return OK;
-               
-        rp_dst->r_exec = NULL;
-        return EIO;
+  if(rs_verbose) {
+      printf("RS: share_exec: sharing exec image from %s to %s\n",
+          rp_src->r_label, rp_dst->r_label);
+  }
+
+  /* Share exec image from rp_src to rp_dst. */
+  rp_dst->r_exec_len = rp_src->r_exec_len;
+  rp_dst->r_exec = rp_src->r_exec;
+
+  return OK;
 }
 
+/*===========================================================================*
+ *                             read_exec                                    *
+ *===========================================================================*/
 PRIVATE int read_exec(rp)
 struct rproc *rp;
 {
-       int e, r, fd;
-       char *e_name;
-       struct stat sb;
+  int e, r, fd;
+  char *e_name;
+  struct stat sb;
+
+  e_name= rp->r_argv[0];
+  if(rs_verbose) {
+      printf("RS: read_exec: copying exec image from: %s\n", e_name);
+  }
 
+  r= stat(e_name, &sb);
+  if (r != 0) 
+      return -errno;
 
-       e_name= rp->r_argv[0];
-       r= stat(e_name, &sb);
-       if (r != 0) 
-               return -errno;
+  fd= open(e_name, O_RDONLY);
+  if (fd == -1)
+      return -errno;
 
-       fd= open(e_name, O_RDONLY);
-       if (fd == -1)
-               return -errno;
+  rp->r_exec_len= sb.st_size;
+  rp->r_exec= malloc(rp->r_exec_len);
+  if (rp->r_exec == NULL)
+  {
+      printf("RS: read_exec: unable to allocate %d bytes\n",
+          rp->r_exec_len);
+      close(fd);
+      return ENOMEM;
+  }
 
-       rp->r_exec_len= sb.st_size;
-       rp->r_exec= malloc(rp->r_exec_len);
-       if (rp->r_exec == NULL)
-       {
-               printf("RS: read_exec: unable to allocate %d bytes\n",
-                       rp->r_exec_len);
-               close(fd);
-               return ENOMEM;
-       }
+  r= read(fd, rp->r_exec, rp->r_exec_len);
+  e= errno;
+  close(fd);
+  if (r == rp->r_exec_len)
+      return OK;
 
-       r= read(fd, rp->r_exec, rp->r_exec_len);
-       e= errno;
-       close(fd);
-       if (r == rp->r_exec_len)
-               return OK;
+  printf("RS: read_exec: read failed %d, errno %d\n", r, e);
 
-       printf("RS: read_exec: read failed %d, errno %d\n", r, e);
+  free(rp->r_exec);
+  rp->r_exec= NULL;
 
-       free(rp->r_exec);
-       rp->r_exec= NULL;
+  if (r >= 0)
+      return EIO;
+  else
+      return -e;
+}
 
-       if (r >= 0)
-               return EIO;
-       else
-               return -e;
+/*===========================================================================*
+ *                             free_slot                                    *
+ *===========================================================================*/
+PRIVATE void free_slot(rp)
+struct rproc *rp;
+{
+  int slot_nr, has_shared_exec;
+  struct rproc *other_rp;
+
+  /* Free memory if necessary. */
+  if(rp->r_sys_flags & SF_USE_COPY) {
+      /* Search for some other slot sharing the same exec image. */
+      has_shared_exec = FALSE;
+      for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
+          other_rp = &rproc[slot_nr];          /* get pointer to slot */
+          if (other_rp->r_flags & RS_IN_USE && other_rp != rp
+              && other_rp->r_exec == rp->r_exec) {  /* found! */
+              has_shared_exec = TRUE;
+          }
+      }
+
+      /* If nobody uses our copy of the exec image, we can get rid of it. */
+      if(!has_shared_exec) {
+          if(rs_verbose) {
+              printf("RS: free_slot: free exec image from %s\n", rp->r_label);
+          }
+          free(rp->r_exec);
+          rp->r_exec = NULL;
+          rp->r_exec_len = 0;
+      }
+  }
+
+  /* Mark slot as no longer in use.. */
+  rp->r_flags = 0;
+  rproc_ptr[_ENDPOINT_P(rp->r_proc_nr_e)] = NULL;
 }
 
 /*===========================================================================*
index 4ed3d1a9c7ff5d3c553685dc60d04e69cba7b080..eca1a98bb1e774766b6979d9ad1151c9bc94c2ca 100644 (file)
@@ -35,23 +35,23 @@ PRIVATE int
 
 /* Definition of the boot image priv table. */
 PUBLIC struct boot_image_priv boot_image_priv_table[] = {
-  /*endpoint,    priv flags,  traps,  ipcto,  kcalls    */
-  { VM_PROC_NR,       VM_F,   SRV_T,  SRV_M,  vm_kc     },
-  { PM_PROC_NR,       SRV_F,  SRV_T,  SRV_M,  pm_kc     },
-  { FS_PROC_NR,       SRV_F,  SRV_T,  SRV_M,  fs_kc     },
-  { DS_PROC_NR,       SRV_F,  SRV_T,  SRV_M,  ds_kc     },
-  { TTY_PROC_NR,      SRV_F,  SRV_T,  SRV_M,  tty_kc    },
-  { MEM_PROC_NR,      SRV_F,  SRV_T,  SRV_M,  mem_kc    },
-  { LOG_PROC_NR,      SRV_F,  SRV_T,  SRV_M,  drv_kc    },
-  { MFS_PROC_NR,      SRV_F,  SRV_T,  SRV_M,  fs_kc     },
-  { PFS_PROC_NR,      SRV_F,  SRV_T,  SRV_M,  fs_kc     },
-  { INIT_PROC_NR,     RUSR_F, RUSR_T, RUSR_M, rusr_kc   },
-  { NULL_BOOT_NR,     0,      0,      0,      no_kc     } /* null entry */
+  /*endpoint,     label,      flags,  traps,  ipcto,  kcalls  */
+  { VM_PROC_NR,   "vm",       VM_F,   SRV_T,  SRV_M,  vm_kc   },
+  { PM_PROC_NR,   "pm",       SRV_F,  SRV_T,  SRV_M,  pm_kc   },
+  { FS_PROC_NR,   "vfs",      SRV_F,  SRV_T,  SRV_M,  fs_kc   },
+  { DS_PROC_NR,   "ds",       SRV_F,  SRV_T,  SRV_M,  ds_kc   },
+  { TTY_PROC_NR,  "tty",      SRV_F,  SRV_T,  SRV_M,  tty_kc  },
+  { MEM_PROC_NR,  "memory",   SRV_F,  SRV_T,  SRV_M,  mem_kc  },
+  { LOG_PROC_NR,  "log",      SRV_F,  SRV_T,  SRV_M,  drv_kc  },
+  { MFS_PROC_NR,  "fs_imgrd", SRV_F,  SRV_T,  SRV_M,  fs_kc   },
+  { PFS_PROC_NR,  "pfs",      SRV_F,  SRV_T,  SRV_M,  fs_kc   },
+  { INIT_PROC_NR, "init",     RUSR_F, RUSR_T, RUSR_M, rusr_kc },
+  { NULL_BOOT_NR, "",         0,      0,      0,      no_kc   } /* null entry */
 };
 
 /* Definition of the boot image sys table. */
 PUBLIC struct boot_image_sys boot_image_sys_table[] = {
-  /*endpoint,         sys flags                         */
+  /*endpoint,         flags                             */
   { LOG_PROC_NR,      SRVC_SF                           },
   { MFS_PROC_NR,      SRVC_SF                           },
   { PFS_PROC_NR,      SRVC_SF                           },
index 473bd511b1e557754b9eda493b3bff76a394a64e..aebd82224a4e58589b791c8687df4b3c1e8927bf 100644 (file)
@@ -6,6 +6,7 @@
 /* Definition of an entry of the boot image priv table. */
 struct boot_image_priv {
   endpoint_t endpoint;         /* process endpoint number */
+  char label[MAX_LABEL_LEN];   /* label to assign to this service */
 
   int flags;                   /* privilege flags */
   short trap_mask;             /* allowed system call traps */
@@ -50,7 +51,8 @@ struct rproc {
   char *r_exec;                        /* Executable image */ 
   size_t r_exec_len;           /* Length of image */
 
-  char r_label[MAX_LABEL_LEN]; /* unique name of this service */
+  char r_label[MAX_LABEL_LEN]; /* label of this service */
+  char r_proc_name[P_NAME_LEN];        /* process name of this service */
   char r_cmd[MAX_COMMAND_LEN]; /* raw command plus arguments */
   char r_script[MAX_SCRIPT_LEN]; /* name of the restart script executable */
   char *r_argv[MAX_NR_ARGS+2];  /* parsed arguments vector */