Driver mapping refactory.

VFS CHANGES:
- dmap table no longer statically initialized in VFS
- Dropped FSSIGNON svrctl call no longer used by INET

INET CHANGES:
- INET announces its presence to VFS just like any other driver

RS CHANGES:
- The boot image dev table contains all the data to initialize VFS' dmap table
- RS interface supports asynchronous up and update operations now
- RS interface extended to support driver style and flags
This commit is contained in:
Cristiano Giuffrida
2010-04-09 21:56:44 +00:00
parent c1bfcc9119
commit 65ef539739
34 changed files with 357 additions and 280 deletions

View File

@@ -88,5 +88,9 @@
#define DSRV_SF (0) /* dynamic system services */
#define VM_SF (SRV_SF | SF_SYNCH_BOOT) /* vm */
/* Define device flags for the various process types. */
#define SRV_DF (DRV_FORCED) /* system services */
#define DSRV_DF (SRV_DF) /* dynamic system services */
#endif /* RS_CONST_H */

View File

@@ -287,6 +287,9 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
/* Get label. */
strcpy(rpub->label, boot_image_priv->label);
/* Get heartbeat period. */
rpub->period = boot_image_priv->period;
if(boot_image_priv->endpoint != RS_PROC_NR) {
/* Force a static priv id for system services in the boot image. */
rp->r_priv.s_id = static_priv_id(
@@ -323,9 +326,10 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
/*
* Set dev properties.
*/
rpub->dev_flags = boot_image_dev->flags; /* device flags */
rpub->dev_nr = boot_image_dev->dev_nr; /* major device number */
rpub->dev_style = boot_image_dev->dev_style; /* device style */
rpub->period = boot_image_dev->period; /* heartbeat period */
rpub->dev_style2 = boot_image_dev->dev_style2; /* device style 2 */
/* Get process name. */
strcpy(rpub->proc_name, ip->proc_name);

View File

@@ -503,7 +503,8 @@ struct rproc *rp; /* pointer to service slot */
/* If the service is a driver, map it. */
if (rpub->dev_nr > 0) {
if (mapdriver(rpub->label, rpub->dev_nr, rpub->dev_style, 1) != OK) {
if (mapdriver(rpub->label, rpub->dev_nr, rpub->dev_style,
rpub->dev_flags) != OK) {
return kill_service(rp, "couldn't map driver", errno);
}
}
@@ -996,8 +997,10 @@ struct rproc *rp;
rpub = rp->r_pub;
/* Device settings. These properties cannot change. */
rpub->dev_flags = def_rpub->dev_flags;
rpub->dev_nr = def_rpub->dev_nr;
rpub->dev_style = def_rpub->dev_style;
rpub->dev_style2 = def_rpub->dev_style2;
/* Period. */
if(!rpub->period && def_rpub->period) {
@@ -1349,10 +1352,18 @@ endpoint_t source;
fill_call_mask(basic_kc, NR_SYS_CALLS,
rp->r_priv.s_k_call_mask, KERNEL_CALL, FALSE);
/* Device driver properties. */
rpub->dev_flags = DSRV_DF;
rpub->dev_nr = rs_start->rss_major;
rpub->dev_style = rs_start->rss_dev_style;
if(rpub->dev_nr && !IS_DEV_STYLE(rs_start->rss_dev_style)) {
printf("RS: init_slot: bad device style\n");
return EINVAL;
}
rpub->dev_style2 = STYLE_NDEV;
/* Initialize some fields. */
rpub->period = rs_start->rss_period;
rpub->dev_nr = rs_start->rss_major;
rpub->dev_style = STYLE_DEV;
rp->r_restarts = -1; /* will be incremented */
rp->r_set_resources= 1; /* set resources */
@@ -1533,6 +1544,34 @@ PUBLIC struct rproc* lookup_slot_by_pid(pid_t pid)
return NULL;
}
/*===========================================================================*
* lookup_slot_by_dev_nr *
*===========================================================================*/
PUBLIC struct rproc* lookup_slot_by_dev_nr(dev_t dev_nr)
{
/* Lookup a service slot matching the given device number. */
int slot_nr;
struct rproc *rp;
struct rprocpub *rpub;
if(dev_nr <= 0) {
return NULL;
}
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
rp = &rproc[slot_nr];
rpub = rp->r_pub;
if (!(rp->r_flags & RS_IN_USE)) {
continue;
}
if (rpub->dev_nr == dev_nr) {
return rp;
}
}
return NULL;
}
/*===========================================================================*
* alloc_slot *
*===========================================================================*/

View File

@@ -73,6 +73,7 @@ _PROTOTYPE( int clone_slot, (struct rproc *rp, struct rproc **clone_rpp) );
_PROTOTYPE( void swap_slot, (struct rproc **src_rpp, struct rproc **dst_rpp) );
_PROTOTYPE( struct rproc* lookup_slot_by_label, (char *label) );
_PROTOTYPE( struct rproc* lookup_slot_by_pid, (pid_t pid) );
_PROTOTYPE( struct rproc* lookup_slot_by_dev_nr, (dev_t dev_nr) );
_PROTOTYPE( int alloc_slot, (struct rproc **rpp) );
_PROTOTYPE( void free_slot, (struct rproc *rp) );
_PROTOTYPE( char *get_next_label, (char *ptr, char *label, char *caller_label));

View File

@@ -16,6 +16,7 @@ message *m_ptr; /* request message pointer */
struct rprocpub *rpub;
int r;
struct rs_start rs_start;
int noblock;
/* Check if the call can be allowed. */
if((r = check_call_permission(m_ptr->m_source, RS_UP, NULL)) != OK)
@@ -34,6 +35,7 @@ message *m_ptr; /* request message pointer */
if (r != OK) {
return r;
}
noblock = (rs_start.rss_flags & RSS_NOBLOCK);
/* Initialize the slot as requested. */
r = init_slot(rp, &rs_start, m_ptr->m_source);
@@ -44,8 +46,13 @@ message *m_ptr; /* request message pointer */
/* Check for duplicates */
if(lookup_slot_by_label(rpub->label)) {
printf("RS: service '%s' (%d) has duplicate label\n", rpub->label,
rpub->endpoint);
printf("RS: service with the same label '%s' already exists\n",
rpub->label);
return EBUSY;
}
if(rpub->dev_nr>0 && lookup_slot_by_dev_nr(rpub->dev_nr)) {
printf("RS: service with the same device number %d already exists\n",
rpub->dev_nr);
return EBUSY;
}
@@ -56,6 +63,11 @@ message *m_ptr; /* request message pointer */
return r;
}
/* Unblock the caller immediately if requested. */
if(noblock) {
return OK;
}
/* Late reply - send a reply when service completes initialization. */
rp->r_flags |= RS_LATEREPLY;
rp->r_caller = m_ptr->m_source;
@@ -311,6 +323,7 @@ PUBLIC int do_update(message *m_ptr)
struct rproc *new_rp;
struct rprocpub *rpub;
struct rs_start rs_start;
int noblock;
int s;
char label[RS_MAX_LABEL_LEN];
int lu_state;
@@ -321,6 +334,7 @@ PUBLIC int do_update(message *m_ptr)
if (s != OK) {
return s;
}
noblock = (rs_start.rss_flags & RSS_NOBLOCK);
/* Copy label. */
s = copy_label(m_ptr->m_source, rs_start.rss_label.l_addr,
@@ -414,6 +428,11 @@ PUBLIC int do_update(message *m_ptr)
m_ptr->m_type = RS_LU_PREPARE;
asynsend3(rpub->endpoint, m_ptr, AMF_NOREPLY);
/* Unblock the caller immediately if requested. */
if(noblock) {
return OK;
}
/* Late reply - send a reply when the new version completes initialization. */
rp->r_flags |= RS_LATEREPLY;
rp->r_caller = m_ptr->m_source;

View File

@@ -27,6 +27,7 @@
#include <minix/bitmap.h>
#include <minix/paths.h>
#include <minix/sef.h>
#include <minix/dmap.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <configfile.h>
@@ -53,6 +54,11 @@ PRIVATE char *known_requests[] = {
#define DEFAULT_LU_STATE SEF_LU_STATE_WORK_FREE /* Default lu state */
#define DEFAULT_LU_MAXTIME 0 /* Default lu max time */
/* Define names for options provided to this utility. */
#define OPT_COPY "-c" /* copy executable image */
#define OPT_REUSE "-r" /* reuse executable image */
#define OPT_NOBLOCK "-n" /* unblock caller immediately */
/* Define names for arguments provided to this utility. The first few
* arguments are required and have a known index. Thereafter, some optional
* argument pairs like "-args arglist" follow.
@@ -68,6 +74,7 @@ PRIVATE char *known_requests[] = {
#define ARG_ARGS "-args" /* list of arguments to be passed */
#define ARG_DEV "-dev" /* major device number for drivers */
#define ARG_DEVSTYLE "-devstyle" /* device style */
#define ARG_PERIOD "-period" /* heartbeat period in ticks */
#define ARG_SCRIPT "-script" /* name of the script to restart a
* system service
@@ -90,13 +97,14 @@ PRIVATE char *known_requests[] = {
*/
PRIVATE int req_type;
PRIVATE int do_run= 0; /* 'run' command instead of 'up' */
PRIVATE char *req_label;
PRIVATE char *req_path;
PRIVATE char *req_label = NULL;
PRIVATE char *req_path = NULL;
PRIVATE char *req_args = "";
PRIVATE int req_major;
PRIVATE long req_period;
PRIVATE char *req_script;
PRIVATE char *req_ipc;
PRIVATE int req_major = 0;
PRIVATE int req_dev_style = STYLE_NDEV;
PRIVATE long req_period = 0;
PRIVATE char *req_script = NULL;
PRIVATE char *req_ipc = NULL;
PRIVATE char *req_config = PATH_CONFIG;
PRIVATE int class_recurs; /* Nesting level of class statements */
PRIVATE int req_lu_state = DEFAULT_LU_STATE;
@@ -115,9 +123,10 @@ PRIVATE void print_usage(char *app_name, char *problem)
fprintf(stderr, "Warning, %s\n", problem);
fprintf(stderr, "Usage:\n");
fprintf(stderr,
" %s [-c -r] (up|run|update) <binary> [%s <args>] [%s <special>] [%s <ticks>] [%s <path>] [%s <name>] [%s <path>] [%s <state>] [%s <time>]\n",
app_name, ARG_ARGS, ARG_DEV, ARG_PERIOD, ARG_SCRIPT, ARG_LABELNAME,
ARG_CONFIG, ARG_LU_STATE, ARG_LU_MAXTIME);
" %s [%s %s %s] (up|run|update) <binary> [%s <args>] [%s <special>] [%s <style>] [%s <ticks>] [%s <path>] [%s <name>] [%s <path>] [%s <state>] [%s <time>]\n",
app_name, OPT_COPY, OPT_REUSE, OPT_NOBLOCK,
ARG_ARGS, ARG_DEV, ARG_DEVSTYLE, ARG_PERIOD, ARG_SCRIPT,
ARG_LABELNAME, ARG_CONFIG, ARG_LU_STATE, ARG_LU_MAXTIME);
fprintf(stderr, " %s down label\n", app_name);
fprintf(stderr, " %s refresh label\n", app_name);
fprintf(stderr, " %s restart label\n", app_name);
@@ -142,12 +151,13 @@ PRIVATE int parse_arguments(int argc, char **argv)
struct stat stat_buf;
char *hz, *buff;
int req_nr;
int c, i;
int c_flag, r_flag;
int c, i, j;
int c_flag, r_flag, n_flag;
c_flag = 0;
r_flag = 0;
while (c= getopt(argc, argv, "rci?"), c != -1)
n_flag = 0;
while (c= getopt(argc, argv, "rcn?"), c != -1)
{
switch(c)
{
@@ -161,10 +171,8 @@ PRIVATE int parse_arguments(int argc, char **argv)
c_flag = 1; /* -r implies -c */
r_flag = 1;
break;
case 'i':
/* Legacy - remove later */
fputs("WARNING: obsolete -i flag passed to service(8)\n",
stderr);
case 'n':
n_flag = 1;
break;
default:
fprintf(stderr, "%s: getopt failed: %c\n",
@@ -198,6 +206,7 @@ PRIVATE int parse_arguments(int argc, char **argv)
req_nr = RS_RQ_BASE + req_type;
}
rs_start.rss_flags = 0;
if (req_nr == RS_UP || req_nr == RS_UPDATE) {
u32_t system_hz;
@@ -207,7 +216,10 @@ PRIVATE int parse_arguments(int argc, char **argv)
if(r_flag)
rs_start.rss_flags |= RSS_REUSE;
if(n_flag)
rs_start.rss_flags |= RSS_NOBLOCK;
if (do_run)
{
/* Set default recovery script for RUN */
@@ -274,6 +286,25 @@ PRIVATE int parse_arguments(int argc, char **argv)
exit(EINVAL);
}
req_major = (stat_buf.st_rdev >> MAJOR) & BYTE;
if(req_dev_style == STYLE_NDEV) {
req_dev_style = STYLE_DEV;
}
}
else if (strcmp(argv[i], ARG_DEVSTYLE)==0) {
char* dev_style_keys[] = { "STYLE_DEV", "STYLE_DEVA", "STYLE_TTY",
"STYLE_CTTY", "STYLE_CLONE", NULL };
int dev_style_values[] = { STYLE_DEV, STYLE_DEVA, STYLE_TTY,
STYLE_CTTY, STYLE_CLONE };
for(j=0;dev_style_keys[j]!=NULL;j++) {
if(!strcmp(dev_style_keys[j], argv[i+1])) {
break;
}
}
if(dev_style_keys[j] == NULL) {
print_usage(argv[ARG_NAME], "bad device style");
exit(EINVAL);
}
req_dev_style = dev_style_values[j];
}
else if (strcmp(argv[i], ARG_SCRIPT)==0) {
req_script = argv[i+1];
@@ -288,13 +319,11 @@ PRIVATE int parse_arguments(int argc, char **argv)
errno=0;
req_lu_state = strtol(argv[i+1], &buff, 10);
if(errno || strcmp(buff, "")) {
print_usage(argv[ARG_NAME],
"bad live update state");
print_usage(argv[ARG_NAME], "bad live update state");
exit(EINVAL);
}
if(req_lu_state == SEF_LU_STATE_NULL) {
print_usage(argv[ARG_NAME],
"null live update state.");
print_usage(argv[ARG_NAME], "null live update state");
exit(EINVAL);
}
}
@@ -1045,6 +1074,7 @@ PUBLIC int main(int argc, char **argv)
rs_start.rss_cmd= command;
rs_start.rss_cmdlen= strlen(command);
rs_start.rss_major= req_major;
rs_start.rss_dev_style= req_dev_style;
rs_start.rss_period= req_period;
rs_start.rss_script= req_script;
if(req_label) {

View File

@@ -58,19 +58,19 @@ PRIVATE int
* at boot time.
*/
PUBLIC struct boot_image_priv boot_image_priv_table[] = {
/*endpoint, label, flags, traps, ipcto, sigmgr, kcalls, vmcalls */
{RS_PROC_NR, "rs", RSYS_F, RSYS_T, RSYS_M, RSYS_SM, rs_kc, rs_vmc },
{VM_PROC_NR, "vm", VM_F, SRV_T, SRV_M, SRV_SM, vm_kc, vm_vmc },
{PM_PROC_NR, "pm", SRV_F, SRV_T, SRV_M, SRV_SM, pm_kc, pm_vmc },
{VFS_PROC_NR, "vfs", SRV_F, SRV_T, SRV_M, SRV_SM, vfs_kc, vfs_vmc },
{DS_PROC_NR, "ds", SRV_F, SRV_T, SRV_M, SRV_SM, ds_kc, ds_vmc },
{TTY_PROC_NR, "tty", SRV_F, SRV_T, SRV_M, SRV_SM, tty_kc, tty_vmc },
{MEM_PROC_NR, "memory", SRV_F, SRV_T, SRV_M, SRV_SM, mem_kc, mem_vmc },
{LOG_PROC_NR, "log", SRV_F, SRV_T, SRV_M, SRV_SM, log_kc, log_vmc },
{MFS_PROC_NR, "fs_imgrd", SRV_F, SRV_T, SRV_M, SRV_SM, mfs_kc, mfs_vmc },
{PFS_PROC_NR, "pfs", SRV_F, SRV_T, SRV_M, SRV_SM, pfs_kc, pfs_vmc },
{INIT_PROC_NR, "init", RUSR_F, RUSR_T, RUSR_M, RUSR_SM, rusr_kc, rusr_vmc },
{NULL_BOOT_NR, "", 0, 0, 0, 0, no_kc, no_vmc }
/*endpoint, label, flags, traps, ipcto, sigmgr, kcalls, vmcalls, T */
{RS_PROC_NR, "rs", RSYS_F, RSYS_T, RSYS_M, RSYS_SM, rs_kc, rs_vmc, 0 },
{VM_PROC_NR, "vm", VM_F, SRV_T, SRV_M, SRV_SM, vm_kc, vm_vmc, 0 },
{PM_PROC_NR, "pm", SRV_F, SRV_T, SRV_M, SRV_SM, pm_kc, pm_vmc, 0 },
{VFS_PROC_NR, "vfs", SRV_F, SRV_T, SRV_M, SRV_SM, vfs_kc, vfs_vmc, 0 },
{DS_PROC_NR, "ds", SRV_F, SRV_T, SRV_M, SRV_SM, ds_kc, ds_vmc, 0 },
{TTY_PROC_NR, "tty", SRV_F, SRV_T, SRV_M, SRV_SM, tty_kc, tty_vmc, 0 },
{MEM_PROC_NR, "memory", SRV_F, SRV_T, SRV_M, SRV_SM, mem_kc, mem_vmc, 0 },
{LOG_PROC_NR, "log", SRV_F, SRV_T, SRV_M, SRV_SM, log_kc, log_vmc, 0 },
{MFS_PROC_NR,"fs_imgrd", SRV_F, SRV_T, SRV_M, SRV_SM, mfs_kc, mfs_vmc, 0 },
{PFS_PROC_NR, "pfs", SRV_F, SRV_T, SRV_M, SRV_SM, pfs_kc, pfs_vmc, 0 },
{INIT_PROC_NR, "init", RUSR_F, RUSR_T, RUSR_M, RUSR_SM, rusr_kc, rusr_vmc,0 },
{NULL_BOOT_NR, "", 0, 0, 0, 0, no_kc, no_vmc, 0 }
};
/* Definition of the boot image sys table. */
@@ -86,10 +86,12 @@ PUBLIC struct boot_image_sys boot_image_sys_table[] = {
/* Definition of the boot image dev table. */
PUBLIC struct boot_image_dev boot_image_dev_table[] = {
/*endpoint, dev_nr, dev_style, period */
{ TTY_PROC_NR, TTY_MAJOR, STYLE_TTY, 0 },
{ MEM_PROC_NR, MEMORY_MAJOR, STYLE_DEV, 0 },
{ LOG_PROC_NR, LOG_MAJOR, STYLE_DEV, 0 },
{ DEFAULT_BOOT_NR, 0, STYLE_NDEV, 0 } /* default entry */
/*endpoint, flags, dev_nr, dev_style, dev_style2 */
{ TTY_PROC_NR, SRV_DF, TTY_MAJOR, STYLE_TTY, STYLE_CTTY },
{ MEM_PROC_NR, SRV_DF, MEMORY_MAJOR, STYLE_DEV, STYLE_NDEV },
{ LOG_PROC_NR, SRV_DF, LOG_MAJOR, STYLE_DEVA, STYLE_NDEV },
{ DEFAULT_BOOT_NR, SRV_DF, 0, STYLE_NDEV, STYLE_NDEV } /* default
* entry
*/
};

View File

@@ -14,6 +14,7 @@ struct boot_image_priv {
endpoint_t sig_mgr; /* signal manager */
int *k_calls; /* allowed kernel calls */
int *vm_calls; /* allowed vm calls */
long period; /* heartbeat period (or zero) */
};
/* Definition of an entry of the boot image sys table. */
@@ -27,9 +28,10 @@ struct boot_image_sys {
struct boot_image_dev {
endpoint_t endpoint; /* process endpoint number */
int flags; /* device flags */
dev_t dev_nr; /* major device number */
int dev_style; /* device style */
long period; /* heartbeat period (or zero) */
int dev_style2; /* device style for next major device number */
};
/* Definition of an entry of the system process table. */