Share exec images in RS.
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.
This commit is contained in:
parent
123683d4a5
commit
6f912993ff
@ -13,7 +13,7 @@ then
|
|||||||
/bin/service -c up /bin/bios_wini -dev /dev/c0d0
|
/bin/service -c up /bin/bios_wini -dev /dev/c0d0
|
||||||
else
|
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/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
|
fi
|
||||||
|
|
||||||
rootdev=`sysenv rootdev` || echo 'No rootdev?'
|
rootdev=`sysenv rootdev` || echo 'No rootdev?'
|
||||||
|
@ -453,6 +453,9 @@ PRIVATE void init_server(void)
|
|||||||
* service by using vm_set_priv(). We need a more uniform privilege
|
* service by using vm_set_priv(). We need a more uniform privilege
|
||||||
* management scheme in VM for this change.
|
* 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. */
|
/* 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));
|
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_dev_style = boot_image_dev->dev_style; /* device style */
|
||||||
rp->r_period = boot_image_dev->period; /* heartbeat period */
|
rp->r_period = boot_image_dev->period; /* heartbeat period */
|
||||||
|
|
||||||
/* Get label. */
|
/* Get process name. */
|
||||||
strcpy(rp->r_label, ip->proc_name);
|
strcpy(rp->r_proc_name, ip->proc_name);
|
||||||
|
|
||||||
/* Get command settings. */
|
/* Get command settings. */
|
||||||
rp->r_cmd[0]= '\0';
|
rp->r_cmd[0]= '\0';
|
||||||
|
@ -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 stop_service, (struct rproc *rp,int how) );
|
||||||
FORWARD _PROTOTYPE( int fork_nb, (void) );
|
FORWARD _PROTOTYPE( int fork_nb, (void) );
|
||||||
FORWARD _PROTOTYPE( int read_exec, (struct rproc *rp) );
|
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) );
|
struct rproc *rp_dst) );
|
||||||
|
FORWARD _PROTOTYPE( void free_slot, (struct rproc *rp) );
|
||||||
FORWARD _PROTOTYPE( void run_script, (struct rproc *rp) );
|
FORWARD _PROTOTYPE( void run_script, (struct rproc *rp) );
|
||||||
FORWARD _PROTOTYPE( char *get_next_label, (char *ptr, char *label,
|
FORWARD _PROTOTYPE( char *get_next_label, (char *ptr, char *label,
|
||||||
char *caller_label) );
|
char *caller_label) );
|
||||||
@ -128,8 +129,6 @@ size_t dst_len;
|
|||||||
|
|
||||||
dst_label[len] = 0;
|
dst_label[len] = 0;
|
||||||
|
|
||||||
if (rs_verbose)
|
|
||||||
printf("RS: copy_label: using label (custom) '%s'\n", dst_label);
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,6 +203,21 @@ message *m_ptr; /* request message pointer */
|
|||||||
rp->r_argv[arg_count] = NULL; /* end with NULL pointer */
|
rp->r_argv[arg_count] = NULL; /* end with NULL pointer */
|
||||||
rp->r_argc = arg_count;
|
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) {
|
if(rs_start.rss_label.l_len > 0) {
|
||||||
/* RS_UP caller has supplied a custom label for this service. */
|
/* RS_UP caller has supplied a custom label for this service. */
|
||||||
int s = copy_label(m_ptr->m_source, &rs_start.rss_label,
|
int s = copy_label(m_ptr->m_source, &rs_start.rss_label,
|
||||||
@ -214,19 +228,15 @@ message *m_ptr; /* request message pointer */
|
|||||||
printf("RS: do_up: using label (custom) '%s'\n", rp->r_label);
|
printf("RS: do_up: using label (custom) '%s'\n", rp->r_label);
|
||||||
} else {
|
} else {
|
||||||
/* Default label for the service. */
|
/* Default label for the service. */
|
||||||
label= strrchr(rp->r_argv[0], '/');
|
label = rp->r_proc_name;
|
||||||
if (label)
|
|
||||||
label++;
|
|
||||||
else
|
|
||||||
label= rp->r_argv[0];
|
|
||||||
len= strlen(label);
|
len= strlen(label);
|
||||||
if (len > MAX_LABEL_LEN-1)
|
if (len > MAX_LABEL_LEN-1)
|
||||||
len= MAX_LABEL_LEN-1; /* truncate name */
|
len= MAX_LABEL_LEN-1; /* truncate name */
|
||||||
memcpy(rp->r_label, label, len);
|
memcpy(rp->r_label, label, len);
|
||||||
rp->r_label[len]= '\0';
|
rp->r_label[len]= '\0';
|
||||||
if(rs_verbose)
|
if(rs_verbose)
|
||||||
printf("RS: do_up: using label (from binary %s) '%s'\n",
|
printf("RS: do_up: using label (from proc_name) '%s'\n",
|
||||||
rp->r_argv[0], rp->r_label);
|
rp->r_label);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rs_start.rss_nr_control > 0) {
|
if(rs_start.rss_nr_control > 0) {
|
||||||
@ -302,12 +312,11 @@ message *m_ptr; /* request message pointer */
|
|||||||
exst_cpy = 0;
|
exst_cpy = 0;
|
||||||
|
|
||||||
if(rs_start.rss_flags & RF_REUSE) {
|
if(rs_start.rss_flags & RF_REUSE) {
|
||||||
char *cmd = rp->r_cmd;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for(i = 0; i < NR_SYS_PROCS; i++) {
|
for(i = 0; i < NR_SYS_PROCS; i++) {
|
||||||
rp2 = &rproc[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)) {
|
(rp2->r_sys_flags & SF_USE_COPY)) {
|
||||||
/* We have found the same binary that's
|
/* We have found the same binary that's
|
||||||
* already been copied */
|
* already been copied */
|
||||||
@ -320,7 +329,7 @@ message *m_ptr; /* request message pointer */
|
|||||||
if(!exst_cpy)
|
if(!exst_cpy)
|
||||||
s = read_exec(rp);
|
s = read_exec(rp);
|
||||||
else
|
else
|
||||||
s = copy_exec(rp, rp2);
|
s = share_exec(rp, rp2);
|
||||||
|
|
||||||
if (s != OK)
|
if (s != OK)
|
||||||
return s;
|
return s;
|
||||||
@ -463,15 +472,8 @@ PUBLIC int do_down(message *m_ptr)
|
|||||||
stop_service(rp,RS_EXITING);
|
stop_service(rp,RS_EXITING);
|
||||||
if (rp->r_pid == -1)
|
if (rp->r_pid == -1)
|
||||||
{
|
{
|
||||||
/* Process is already gone */
|
/* Process is already gone, release slot. */
|
||||||
rp->r_flags = 0; /* release slot */
|
free_slot(rp);
|
||||||
if (rp->r_exec)
|
|
||||||
{
|
|
||||||
free(rp->r_exec);
|
|
||||||
rp->r_exec= NULL;
|
|
||||||
}
|
|
||||||
proc = _ENDPOINT_P(rp->r_proc_nr_e);
|
|
||||||
rproc_ptr[proc] = NULL;
|
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -860,12 +862,7 @@ PUBLIC void do_exit(message *m_ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Release slot. */
|
/* Release slot. */
|
||||||
rp->r_flags = 0;
|
free_slot(rp);
|
||||||
if (rp->r_exec)
|
|
||||||
{
|
|
||||||
free(rp->r_exec);
|
|
||||||
rp->r_exec= NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(rp->r_flags & RS_REFRESHING) {
|
else if(rp->r_flags & RS_REFRESHING) {
|
||||||
short is_updating = rp->r_flags & RS_UPDATING;
|
short is_updating = rp->r_flags & RS_UPDATING;
|
||||||
@ -1268,6 +1265,9 @@ message *m_ptr;
|
|||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* fork_nb *
|
||||||
|
*===========================================================================*/
|
||||||
PRIVATE pid_t fork_nb()
|
PRIVATE pid_t fork_nb()
|
||||||
{
|
{
|
||||||
message m;
|
message m;
|
||||||
@ -1275,65 +1275,109 @@ PRIVATE pid_t fork_nb()
|
|||||||
return(_syscall(PM_PROC_NR, FORK_NB, &m));
|
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;
|
struct rproc *rp_dst, *rp_src;
|
||||||
{
|
{
|
||||||
/* Copy binary from rp_src to rp_dst. */
|
if(rs_verbose) {
|
||||||
rp_dst->r_exec_len = rp_src->r_exec_len;
|
printf("RS: share_exec: sharing exec image from %s to %s\n",
|
||||||
rp_dst->r_exec = malloc(rp_dst->r_exec_len);
|
rp_src->r_label, rp_dst->r_label);
|
||||||
if(rp_dst->r_exec == NULL)
|
}
|
||||||
return ENOMEM;
|
|
||||||
|
|
||||||
memcpy(rp_dst->r_exec, rp_src->r_exec, rp_dst->r_exec_len);
|
/* Share exec image from rp_src to rp_dst. */
|
||||||
if(rp_dst->r_exec_len != 0 && rp_dst->r_exec != NULL)
|
rp_dst->r_exec_len = rp_src->r_exec_len;
|
||||||
return OK;
|
rp_dst->r_exec = rp_src->r_exec;
|
||||||
|
|
||||||
rp_dst->r_exec = NULL;
|
return OK;
|
||||||
return EIO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* read_exec *
|
||||||
|
*===========================================================================*/
|
||||||
PRIVATE int read_exec(rp)
|
PRIVATE int read_exec(rp)
|
||||||
struct rproc *rp;
|
struct rproc *rp;
|
||||||
{
|
{
|
||||||
int e, r, fd;
|
int e, r, fd;
|
||||||
char *e_name;
|
char *e_name;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
|
||||||
|
e_name= rp->r_argv[0];
|
||||||
|
if(rs_verbose) {
|
||||||
|
printf("RS: read_exec: copying exec image from: %s\n", e_name);
|
||||||
|
}
|
||||||
|
|
||||||
e_name= rp->r_argv[0];
|
r= stat(e_name, &sb);
|
||||||
r= stat(e_name, &sb);
|
if (r != 0)
|
||||||
if (r != 0)
|
return -errno;
|
||||||
return -errno;
|
|
||||||
|
|
||||||
fd= open(e_name, O_RDONLY);
|
fd= open(e_name, O_RDONLY);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
rp->r_exec_len= sb.st_size;
|
rp->r_exec_len= sb.st_size;
|
||||||
rp->r_exec= malloc(rp->r_exec_len);
|
rp->r_exec= malloc(rp->r_exec_len);
|
||||||
if (rp->r_exec == NULL)
|
if (rp->r_exec == NULL)
|
||||||
{
|
{
|
||||||
printf("RS: read_exec: unable to allocate %d bytes\n",
|
printf("RS: read_exec: unable to allocate %d bytes\n",
|
||||||
rp->r_exec_len);
|
rp->r_exec_len);
|
||||||
close(fd);
|
close(fd);
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
r= read(fd, rp->r_exec, rp->r_exec_len);
|
r= read(fd, rp->r_exec, rp->r_exec_len);
|
||||||
e= errno;
|
e= errno;
|
||||||
close(fd);
|
close(fd);
|
||||||
if (r == rp->r_exec_len)
|
if (r == rp->r_exec_len)
|
||||||
return OK;
|
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);
|
free(rp->r_exec);
|
||||||
rp->r_exec= NULL;
|
rp->r_exec= NULL;
|
||||||
|
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
return EIO;
|
return EIO;
|
||||||
else
|
else
|
||||||
return -e;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
@ -35,23 +35,23 @@ PRIVATE int
|
|||||||
|
|
||||||
/* Definition of the boot image priv table. */
|
/* Definition of the boot image priv table. */
|
||||||
PUBLIC struct boot_image_priv boot_image_priv_table[] = {
|
PUBLIC struct boot_image_priv boot_image_priv_table[] = {
|
||||||
/*endpoint, priv flags, traps, ipcto, kcalls */
|
/*endpoint, label, flags, traps, ipcto, kcalls */
|
||||||
{ VM_PROC_NR, VM_F, SRV_T, SRV_M, vm_kc },
|
{ VM_PROC_NR, "vm", VM_F, SRV_T, SRV_M, vm_kc },
|
||||||
{ PM_PROC_NR, SRV_F, SRV_T, SRV_M, pm_kc },
|
{ PM_PROC_NR, "pm", SRV_F, SRV_T, SRV_M, pm_kc },
|
||||||
{ FS_PROC_NR, SRV_F, SRV_T, SRV_M, fs_kc },
|
{ FS_PROC_NR, "vfs", SRV_F, SRV_T, SRV_M, fs_kc },
|
||||||
{ DS_PROC_NR, SRV_F, SRV_T, SRV_M, ds_kc },
|
{ DS_PROC_NR, "ds", SRV_F, SRV_T, SRV_M, ds_kc },
|
||||||
{ TTY_PROC_NR, SRV_F, SRV_T, SRV_M, tty_kc },
|
{ TTY_PROC_NR, "tty", SRV_F, SRV_T, SRV_M, tty_kc },
|
||||||
{ MEM_PROC_NR, SRV_F, SRV_T, SRV_M, mem_kc },
|
{ MEM_PROC_NR, "memory", SRV_F, SRV_T, SRV_M, mem_kc },
|
||||||
{ LOG_PROC_NR, SRV_F, SRV_T, SRV_M, drv_kc },
|
{ LOG_PROC_NR, "log", SRV_F, SRV_T, SRV_M, drv_kc },
|
||||||
{ MFS_PROC_NR, SRV_F, SRV_T, SRV_M, fs_kc },
|
{ MFS_PROC_NR, "fs_imgrd", SRV_F, SRV_T, SRV_M, fs_kc },
|
||||||
{ PFS_PROC_NR, SRV_F, SRV_T, SRV_M, fs_kc },
|
{ PFS_PROC_NR, "pfs", SRV_F, SRV_T, SRV_M, fs_kc },
|
||||||
{ INIT_PROC_NR, RUSR_F, RUSR_T, RUSR_M, rusr_kc },
|
{ INIT_PROC_NR, "init", RUSR_F, RUSR_T, RUSR_M, rusr_kc },
|
||||||
{ NULL_BOOT_NR, 0, 0, 0, no_kc } /* null entry */
|
{ NULL_BOOT_NR, "", 0, 0, 0, no_kc } /* null entry */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Definition of the boot image sys table. */
|
/* Definition of the boot image sys table. */
|
||||||
PUBLIC struct boot_image_sys boot_image_sys_table[] = {
|
PUBLIC struct boot_image_sys boot_image_sys_table[] = {
|
||||||
/*endpoint, sys flags */
|
/*endpoint, flags */
|
||||||
{ LOG_PROC_NR, SRVC_SF },
|
{ LOG_PROC_NR, SRVC_SF },
|
||||||
{ MFS_PROC_NR, SRVC_SF },
|
{ MFS_PROC_NR, SRVC_SF },
|
||||||
{ PFS_PROC_NR, SRVC_SF },
|
{ PFS_PROC_NR, SRVC_SF },
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
/* Definition of an entry of the boot image priv table. */
|
/* Definition of an entry of the boot image priv table. */
|
||||||
struct boot_image_priv {
|
struct boot_image_priv {
|
||||||
endpoint_t endpoint; /* process endpoint number */
|
endpoint_t endpoint; /* process endpoint number */
|
||||||
|
char label[MAX_LABEL_LEN]; /* label to assign to this service */
|
||||||
|
|
||||||
int flags; /* privilege flags */
|
int flags; /* privilege flags */
|
||||||
short trap_mask; /* allowed system call traps */
|
short trap_mask; /* allowed system call traps */
|
||||||
@ -50,7 +51,8 @@ struct rproc {
|
|||||||
char *r_exec; /* Executable image */
|
char *r_exec; /* Executable image */
|
||||||
size_t r_exec_len; /* Length of 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_cmd[MAX_COMMAND_LEN]; /* raw command plus arguments */
|
||||||
char r_script[MAX_SCRIPT_LEN]; /* name of the restart script executable */
|
char r_script[MAX_SCRIPT_LEN]; /* name of the restart script executable */
|
||||||
char *r_argv[MAX_NR_ARGS+2]; /* parsed arguments vector */
|
char *r_argv[MAX_NR_ARGS+2]; /* parsed arguments vector */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user