From 65ef5397392cdcd3d28f3e16caedfcefa11890b0 Mon Sep 17 00:00:00 2001 From: Cristiano Giuffrida Date: Fri, 9 Apr 2010 21:56:44 +0000 Subject: [PATCH] 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 --- docs/UPDATING | 3 + drivers/memory/ramdisk/rc | 10 +- etc/rc | 8 +- etc/usr/rc | 17 +++- include/minix/const.h | 3 + include/minix/dmap.h | 53 ++++++---- include/minix/rs.h | 6 +- include/sys/svrctl.h | 10 -- include/unistd.h | 2 +- lib/libc/other/_mapdriver.c | 6 +- man/man2/svrctl.2 | 3 - servers/inet/Makefile | 4 +- servers/inet/inet.c | 17 ++-- servers/is/dmp_fs.c | 31 ++++-- servers/mfs/const.h | 1 - servers/pfs/const.h | 1 - servers/rs/const.h | 4 + servers/rs/main.c | 6 +- servers/rs/manager.c | 45 +++++++- servers/rs/proto.h | 1 + servers/rs/request.c | 23 ++++- servers/rs/service/service.c | 72 +++++++++---- servers/rs/table.c | 38 +++---- servers/rs/type.h | 4 +- servers/vfs/const.h | 1 - servers/vfs/device.c | 4 +- servers/vfs/dmap.c | 192 +++++++++++++++-------------------- servers/vfs/dmap.h | 5 +- servers/vfs/fs.h | 1 + servers/vfs/main.c | 20 +++- servers/vfs/misc.c | 33 +----- servers/vfs/param.h | 6 +- servers/vfs/proto.h | 4 +- servers/vfs/type.h | 9 -- 34 files changed, 360 insertions(+), 283 deletions(-) delete mode 100644 servers/vfs/type.h diff --git a/docs/UPDATING b/docs/UPDATING index 2f63a02d9..410346eea 100644 --- a/docs/UPDATING +++ b/docs/UPDATING @@ -1,3 +1,6 @@ +20100610: + /usr/src/etc/usr/rc updated: copy it (or merge it) to /usr/etc/rc. + /usr/src/etc/rc updated: copy it (or merge it) to /etc/rc. 20100408: /usr/src/etc/usr/rc updated: copy it (or merge it) to /usr/etc/rc. 20100318: diff --git a/drivers/memory/ramdisk/rc b/drivers/memory/ramdisk/rc index 6e23c4a13..56df0902b 100644 --- a/drivers/memory/ramdisk/rc +++ b/drivers/memory/ramdisk/rc @@ -5,15 +5,15 @@ exec >/dev/log exec 2>/dev/log exec #include -enum dev_style { STYLE_DEV, STYLE_NDEV, STYLE_TTY, STYLE_CLONE }; +enum dev_style { STYLE_NDEV, STYLE_DEV, STYLE_DEVA, STYLE_TTY, STYLE_CTTY, + STYLE_CLONE }; +#define IS_DEV_STYLE(s) (s>=STYLE_NDEV && s<=STYLE_CLONE) /*===========================================================================* * Major and minor device numbers * *===========================================================================*/ /* Total number of different devices. */ -#define NR_DEVICES 32 /* number of (major) devices */ - -#define NONE_MAJOR 0 /* pseudo device for mounting file - * systems without a real block device - */ - -/* Major and minor device numbers for MEMORY driver. */ -#define MEMORY_MAJOR 1 /* major device for memory devices */ +#define NR_DEVICES NR_SYS_PROCS /* number of (major) devices */ + +/* Major device numbers. */ +#define NONE_MAJOR 0 /* 0 = not used */ +#define MEMORY_MAJOR 1 /* 1 = /dev/mem (memory devices) */ +#define FLOPPY_MAJOR 2 /* 2 = /dev/fd0 (floppy disks) */ + /* 3 = /dev/c0 */ +#define TTY_MAJOR 4 /* 4 = /dev/tty00 (ttys) */ +#define CTTY_MAJOR 5 /* 5 = /dev/tty */ +#define PRINTER_MAJOR 6 /* 6 = /dev/lp (printer driver) */ +#define INET_MAJOR 7 /* 7 = /dev/ip (inet) */ + /* 8 = /dev/c1 */ + /* 9 = not used */ + /* 10 = /dev/c2 */ +#define FILTER_MAJOR 11 /* 11 = /dev/filter (filter driver) */ + /* 12 = /dev/c3 */ +#define AUDIO_MAJOR 13 /* 13 = /dev/audio (audio driver) */ + /* 14 = not used */ +#define LOG_MAJOR 15 /* 15 = /dev/klog (log driver) */ +#define RANDOM_MAJOR 16 /* 16 = /dev/random (random driver) */ +#define HELLO_MAJOR 17 /* 17 = /dev/hello (hello driver) */ + + +/* Minor device numbers for memory driver. */ # define RAM_DEV_OLD 0 /* minor device for /dev/ram */ # define MEM_DEV 1 /* minor device for /dev/mem */ # define KMEM_DEV 2 /* minor device for /dev/kmem */ @@ -30,21 +48,12 @@ enum dev_style { STYLE_DEV, STYLE_NDEV, STYLE_TTY, STYLE_CLONE }; #define CTRLR(n) ((n)==0 ? 3 : (8 + 2*((n)-1))) /* magic formula */ +/* Minor device numbers for log driver. */ +# define IS_KLOG_DEV 0 /* minor device for /dev/klog */ + /* Full device numbers that are special to the boot monitor and FS. */ # define DEV_RAM 0x0100 /* device number of /dev/ram */ # define DEV_IMGRD 0x0106 /* device number of /dev/imgrd */ -#define FLOPPY_MAJOR 2 /* major device for floppy disks */ -#define TTY_MAJOR 4 /* major device for ttys */ -#define CTTY_MAJOR 5 /* major device for /dev/tty */ - -#define INET_MAJOR 7 /* major device for inet */ - -#define FILTER_MAJOR 11 /* major device for filter driver */ - -#define LOG_MAJOR 15 /* major device for log driver */ -# define IS_KLOG_DEV 0 /* minor device for /dev/klog */ - -#define HELLO_MAJOR 17 /* major device for hello driver */ - #endif /* _DMAP_H */ + diff --git a/include/minix/rs.h b/include/minix/rs.h index a508de847..4bc28bb7c 100644 --- a/include/minix/rs.h +++ b/include/minix/rs.h @@ -20,6 +20,7 @@ Interface to the reincarnation server */ #define RSS_IPC_VALID 0x02 /* rss_ipc and rss_ipclen are valid */ #define RSS_REUSE 0x04 /* Try to reuse previously copied binary */ +#define RSS_NOBLOCK 0x08 /* unblock caller immediately */ /* Common definitions. */ #define RS_NR_CONTROL 8 @@ -43,6 +44,7 @@ struct rs_start uid_t rss_uid; int rss_nice; int rss_major; + int rss_dev_style; long rss_period; char *rss_script; size_t rss_scriptlen; @@ -79,10 +81,12 @@ struct rprocpub { short in_use; /* set when the entry is in use */ unsigned sys_flags; /* sys flags */ endpoint_t endpoint; /* process endpoint number */ + long period; /* heartbeat period (or zero) */ + int dev_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 dev number */ char label[RS_MAX_LABEL_LEN]; /* label of this service */ char proc_name[RS_MAX_LABEL_LEN]; /* process name of this service */ diff --git a/include/sys/svrctl.h b/include/sys/svrctl.h index 097c060c0..b60279225 100644 --- a/include/sys/svrctl.h +++ b/include/sys/svrctl.h @@ -18,16 +18,6 @@ Created: Feb 15, 1994 by Philip Homburg #define MMGETPARAM _IOW('M', 5, struct sysgetenv) #define MMSETPARAM _IOR('M', 7, struct sysgetenv) -/* FS controls. */ -#define FSSIGNON _IOW('F', 2, struct fssignon) - -/* A proper system call must be created later. */ -#include -struct fssignon { - dev_t dev; /* Device to manage. */ - enum dev_style style; /* Management style. */ -}; - struct sysgetenv { char *key; /* Name requested. */ size_t keylen; /* Length of name including \0. */ diff --git a/include/unistd.h b/include/unistd.h index 5c4b81549..6746043d6 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -191,7 +191,7 @@ _PROTOTYPE( int getnprocnr, (pid_t pid) ); _PROTOTYPE( int getpprocnr, (void) ); _PROTOTYPE( int _pm_findproc, (char *proc_name, int *proc_nr) ); _PROTOTYPE( int mapdriver, (char *label, int major, int style, - int force) ); + int flags) ); _PROTOTYPE(int adddma, (endpoint_t proc_e, phys_bytes start, phys_bytes size) ); _PROTOTYPE(int deldma, (endpoint_t proc_e, diff --git a/lib/libc/other/_mapdriver.c b/lib/libc/other/_mapdriver.c index fd659e25a..19ded8d29 100644 --- a/lib/libc/other/_mapdriver.c +++ b/lib/libc/other/_mapdriver.c @@ -4,18 +4,18 @@ #include -PUBLIC int mapdriver(label, major, dev_style, force) +PUBLIC int mapdriver(label, major, dev_style, flags) char *label; int major; int dev_style; -int force; +int flags; { message m; m.m2_p1 = label; m.m2_l1 = strlen(label); m.m2_i1 = major; m.m2_i2 = dev_style; - m.m2_i3 = force; + m.m2_i3 = flags; if (_syscall(FS, MAPDRIVER, &m) < 0) return(-1); return(0); } diff --git a/man/man2/svrctl.2 b/man/man2/svrctl.2 index 90abba37c..9463bcf4f 100644 --- a/man/man2/svrctl.2 +++ b/man/man2/svrctl.2 @@ -33,9 +33,6 @@ Request the value of one or all boot parameters. Can be used by non-root. .TP .B MMSETPARAM Set an override for a value of a boot parameter. Can be used by non-root. -.TP -.B FSSIGNON -Register a new device with FS. .SH "RETURN VALUES" .B Svrctl returns 0 upon success and -1 upon failure. diff --git a/servers/inet/Makefile b/servers/inet/Makefile index 1285617e1..3481cecd1 100644 --- a/servers/inet/Makefile +++ b/servers/inet/Makefile @@ -12,8 +12,8 @@ SRCS= buf.c clock.c inet.c inet_config.c \ .PATH: ${.CURDIR}/generic -DPADD+= ${LIBSYS} -LDADD+= -lsys +DPADD+= ${LIBDRIVER} ${LIBSYS} +LDADD+= -ldriver -lsys MAN= diff --git a/servers/inet/inet.c b/servers/inet/inet.c index 469e40232..7f32c41ad 100644 --- a/servers/inet/inet.c +++ b/servers/inet/inet.c @@ -51,6 +51,8 @@ from DL_ETH: #include #include #include +#include +#include #include "mq.h" #include "qp.h" @@ -215,7 +217,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) int r; int timerand, fd; endpoint_t tasknr; - struct fssignon device; u8_t randbits[32]; struct timeval tv; char my_name[32]; @@ -272,15 +273,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) ip_panic(("inet: sys_whoami failed for 'inet': %d", r)); this_proc= tasknr; - /* Register the device group. */ - device.dev= ip_dev; - device.style= STYLE_CLONE; - if (svrctl(FSSIGNON, (void *) &device) == -1) { - printf("inet: error %d on registering ethernet devices\n", - errno); - pause(); - } - #ifdef BUF_CONSISTENCY_CHECK inet_buf_debug= (getenv("inetbufdebug") && (strcmp(getenv("inetbufdebug"), "on") == 0)); @@ -305,6 +297,11 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) ip_panic(("inet: can't subscribe to driver events")); } + /* Announce we are up. INET announces its presence to VFS just like + * any other driver. + */ + driver_announce(); + return(OK); } diff --git a/servers/is/dmp_fs.c b/servers/is/dmp_fs.c index 004e577e6..630af6709 100644 --- a/servers/is/dmp_fs.c +++ b/servers/is/dmp_fs.c @@ -59,11 +59,29 @@ PUBLIC void fproc_dmp() PRIVATE char * dmap_flags(int flags) { static char fl[10]; - strcpy(fl, "---"); - if(flags & DMAP_MUTABLE) fl[0] = 'M'; + strcpy(fl, "-----"); + if(flags & DRV_FORCED) fl[0] = 'F'; return fl; } +/*===========================================================================* + * dmap_style * + *===========================================================================*/ +PRIVATE char * dmap_style(int dev_style) +{ + static char str[16]; + switch(dev_style) { + case STYLE_DEV: strcpy(str, "STYLE_DEV"); break; + case STYLE_DEVA: strcpy(str, "STYLE_DEVA"); break; + case STYLE_TTY: strcpy(str, "STYLE_TTY"); break; + case STYLE_CTTY: strcpy(str, "STYLE_CTTY"); break; + case STYLE_CLONE: strcpy(str, "STYLE_CLONE"); break; + default: strcpy(str, "UNKNOWN"); break; + } + + return str; +} + /*===========================================================================* * dtab_dmp * *===========================================================================*/ @@ -74,12 +92,13 @@ PUBLIC void dtab_dmp() getsysinfo(FS_PROC_NR, SI_DMAP_TAB, dmap); printf("File System (FS) device <-> driver mappings\n"); - printf("Major Driver ept Flags\n"); - printf("----- ---------- -----\n"); + printf(" Label Major Driver ept Flags Style \n"); + printf("------------- ----- ---------- ----- -------------\n"); for (i=0; ilabel, 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); diff --git a/servers/rs/manager.c b/servers/rs/manager.c index b419f8fa8..335a55248 100644 --- a/servers/rs/manager.c +++ b/servers/rs/manager.c @@ -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 * *===========================================================================*/ diff --git a/servers/rs/proto.h b/servers/rs/proto.h index c574e030d..d6c824a99 100644 --- a/servers/rs/proto.h +++ b/servers/rs/proto.h @@ -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)); diff --git a/servers/rs/request.c b/servers/rs/request.c index 4a9d3820d..cfe696acf 100755 --- a/servers/rs/request.c +++ b/servers/rs/request.c @@ -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; diff --git a/servers/rs/service/service.c b/servers/rs/service/service.c index 8c9fd7e39..0bc0c2eaa 100644 --- a/servers/rs/service/service.c +++ b/servers/rs/service/service.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -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) [%s ] [%s ] [%s ] [%s ] [%s ] [%s ] [%s ] [%s