+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:
exec 2>/dev/log
exec </dev/null
-/bin/service -c up /bin/pci -config /etc/system.conf
-/bin/service -c up /bin/floppy -config /etc/system.conf -dev /dev/fd0
+/bin/service -cn up /bin/pci -config /etc/system.conf
+/bin/service -cn up /bin/floppy -config /etc/system.conf -dev /dev/fd0
if [ X`/bin/sysenv bios_wini` = Xyes ]
then
echo Using bios_wini.
- /bin/service -c up /bin/bios_wini -dev /dev/c0d0
+ /bin/service -cn 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 -r up /bin/at_wini -dev /dev/c1d0 -config /etc/system.conf -label at_wini_1 -args ata_instance=1
+ /bin/service -cn up /bin/at_wini -dev /dev/c0d0 -config /etc/system.conf -label at_wini_0
+ /bin/service -cnr 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?'
exec intr sh
}
-up()
+upopt()
{
+ opt=$1
+ shift
service=$1
shift
# Function to dynamically start a system service
echo -n " $service"
- service up /sbin/$service "$@"
+ service $opt up /sbin/$service "$@"
}
while getopts 'saf' opt
if [ "`sysenv debug_fkeys`" != 0 ]
then
- up is -period 5HZ
+ upopt -n is -period 5HZ
fi
echo .
up()
{
+ upopt " " "$@"
+}
+
+upopt()
+{
+ opt=$1
+ shift
service=$1
shift
# Service is not disabled. Try to bring it up.
echo -n " $service"
- service up /usr/sbin/$service "$@"
+ service $opt up /usr/sbin/$service "$@"
}
# Start servers and drivers set at the boot monitor.
echo -n "Starting services:"
- up random -dev /dev/random -period 3HZ
+ upopt -n random -dev /dev/random -devstyle STYLE_DEVA -period 3HZ
# load random number generator
if [ -f $RANDOM_FILE ]
eval up $driver $arg -period 5HZ
fi
done
- up inet -script /etc/rs.inet
- up printer -dev /dev/lp -period 10HZ
- up ipc
+ upopt -n inet -script /etc/rs.inet -dev /dev/ip -devstyle STYLE_CLONE
+ upopt -n printer -dev /dev/lp -period 10HZ
+ upopt -n ipc
echo .
# Network initialization.
#define CHECK_IRQ 0x40 /* check if IRQ can be used */
#define CHECK_MEM 0x80 /* check if (VM) mem map request is allowed */
+/* Bits for device driver flags managed by RS and VFS. */
+#define DRV_FORCED 0x01 /* driver is mapped even if not alive yet */
+
/* Values for the "verbose" boot monitor variable */
#define VERBOSEBOOT_QUIET 0
#define VERBOSEBOOT_BASIC 1
#include <minix/sys_config.h>
#include <minix/ipc.h>
-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 */
#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 */
+
*/
#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
uid_t rss_uid;
int rss_nice;
int rss_major;
+ int rss_dev_style;
long rss_period;
char *rss_script;
size_t rss_scriptlen;
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 */
#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 <minix/dmap.h>
-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. */
_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,
#include <unistd.h>
-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);
}
.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.
.PATH: ${.CURDIR}/generic
-DPADD+= ${LIBSYS}
-LDADD+= -lsys
+DPADD+= ${LIBDRIVER} ${LIBSYS}
+LDADD+= -ldriver -lsys
MAN=
#include <sys/svrctl.h>
#include <minix/ds.h>
#include <minix/endpoint.h>
+#include <minix/drivers.h>
+#include <minix/driver.h>
#include "mq.h"
#include "qp.h"
int r;
int timerand, fd;
endpoint_t tasknr;
- struct fssignon device;
u8_t randbits[32];
struct timeval tv;
char my_name[32];
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));
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);
}
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 *
*===========================================================================*/
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; i<NR_DEVICES; i++) {
if (dmap[i].dmap_driver == NONE) continue;
- printf("%5d %10d %s\n",
- i, dmap[i].dmap_driver, dmap_flags(dmap[i].dmap_flags));
+ printf("%13s %5d %10d %s %-13s\n",
+ dmap[i].dmap_label, i, dmap[i].dmap_driver,
+ dmap_flags(dmap[i].dmap_flags), dmap_style(dmap[i].dmap_style));
}
}
/* Miscellaneous constants */
#define SU_UID ((uid_t) 0) /* super_user's uid_t */
-#define SERVERS_UID ((uid_t) 11) /* who may do FSSIGNON */
#define SYS_UID ((uid_t) 0) /* uid_t for processes MM and INIT */
#define SYS_GID ((gid_t) 0) /* gid_t for processes MM and INIT */
#define NORMAL 0 /* forces get_block to do disk read */
/* Miscellaneous constants */
#define SU_UID ((uid_t) 0) /* super_user's uid_t */
-#define SERVERS_UID ((uid_t) 11) /* who may do FSSIGNON */
#define SYS_UID ((uid_t) 0) /* uid_t for processes MM and INIT */
#define SYS_GID ((gid_t) 0) /* gid_t for processes MM and INIT */
#define NORMAL 0 /* forces get_block to do disk read */
#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 */
/* 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(
/*
* 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);
/* 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);
}
}
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) {
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 */
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 *
*===========================================================================*/
_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));
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)
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);
/* 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;
}
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;
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;
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,
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;
#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>
#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.
#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
*/
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;
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);
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)
{
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",
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;
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 */
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];
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);
}
}
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) {
* 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. */
/* 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
+ */
};
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. */
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. */
/* Miscellaneous constants */
#define SU_UID ((uid_t) 0) /* super_user's uid_t */
-#define SERVERS_UID ((uid_t) 11) /* who may do FSSIGNON */
#define SYS_UID ((uid_t) 0) /* uid_t for system processes and INIT */
#define SYS_GID ((gid_t) 0) /* gid_t for system processes and INIT */
break;
if (d >= NR_DEVICES) return;
- if (dmap[d].dmap_async_driver) {
+ if (dmap[d].dmap_style == STYLE_DEVA) {
printf("dev_status: not doing dev_status for async driver %d\n",
m->m_source);
return;
/* fp is uninitialized at init time. */
if(!fp) panic("SUSPEND on NULL fp");
- if ((flags & O_NONBLOCK) && !dp->dmap_async_driver) {
+ if ((flags & O_NONBLOCK) && !(dp->dmap_style == STYLE_DEVA)) {
/* Not supposed to block. */
dev_mess.m_type = CANCEL;
dev_mess.IO_ENDPT = ioproc;
#include <minix/ds.h>
#include "param.h"
-/* Some devices may or may not be there in the next table. */
-#define DT(enable, opcl, io, driver, flags, label) \
- { (enable?(opcl):no_dev), (enable?(io):0), \
- (enable?(driver):0), (flags), label, FALSE },
#define NC(x) (NR_CTRLRS >= (x))
-/* The order of the entries here determines the mapping between major device
- * numbers and tasks. The first entry (major device 0) is not used. The
- * next entry is major device 1, etc. Character and block devices can be
- * intermixed at random. The ordering determines the device numbers in /dev/.
- * Note that FS knows the device number of /dev/ram/ to load the RAM disk.
- * Also note that the major device numbers used in /dev/ are NOT the same as
- * the process numbers of the device drivers.
+/* The order of the entries in the table determines the mapping between major
+ * device numbers and device drivers. Character and block devices
+ * can be intermixed at random. The ordering determines the device numbers in
+ * /dev. Note that the major device numbers used in /dev are NOT the same as
+ * the process numbers of the device drivers. See <minix/dmap.h> for mappings.
*/
-/*
- Driver enabled Open/Cls I/O Driver # Flags Device File
- -------------- -------- ------ ----------- ----- ------ ----
- */
-struct dmap dmap[NR_DEVICES]; /* actual map */
-PRIVATE struct dmap init_dmap[] = {
- DT(1, no_dev, 0, 0, 0, "") /* 0 = not used */
- DT(1, gen_opcl, gen_io, MEM_PROC_NR, 0, "memory") /* 1 = /dev/mem */
- DT(0, no_dev, 0, 0, DMAP_MUTABLE, "") /* 2 = /dev/fd0 */
- DT(0, no_dev, 0, 0, DMAP_MUTABLE, "") /* 3 = /dev/c0 */
- DT(1, tty_opcl, gen_io, TTY_PROC_NR, 0, "") /* 4 = /dev/tty00 */
- DT(1, ctty_opcl,ctty_io, TTY_PROC_NR, 0, "") /* 5 = /dev/tty */
- DT(0, no_dev, 0, NONE, DMAP_MUTABLE, "") /* 6 = /dev/lp */
-
-#if (MACHINE == IBM_PC)
- DT(1, no_dev, 0, 0, DMAP_MUTABLE, "") /* 7 = /dev/ip */
- DT(0, no_dev, 0, NONE, DMAP_MUTABLE, "") /* 8 = /dev/c1 */
- DT(0, 0, 0, 0, DMAP_MUTABLE, "") /* 9 = not used */
- DT(0, no_dev, 0, 0, DMAP_MUTABLE, "") /*10 = /dev/c2 */
- DT(0, no_dev, 0, 0, DMAP_MUTABLE, "") /*11 = /dev/filter*/
- DT(0, no_dev, 0, NONE, DMAP_MUTABLE, "") /*12 = /dev/c3 */
- DT(0, no_dev, 0, NONE, DMAP_MUTABLE, "") /*13 = /dev/audio */
- DT(0, 0, 0, 0, DMAP_MUTABLE, "") /*14 = not used */
- DT(1, gen_opcl, gen_io, LOG_PROC_NR, 0, "") /*15 = /dev/klog */
- DT(0, no_dev, 0, NONE, DMAP_MUTABLE, "") /*16 = /dev/random*/
- DT(0, no_dev, 0, 0, DMAP_MUTABLE, "") /*17 = /dev/hello */
- DT(0, 0, 0, 0, DMAP_MUTABLE, "") /*18 = not used */
-#endif /* IBM_PC */
-};
+
+struct dmap dmap[NR_DEVICES];
+
+#define DT_EMPTY { no_dev, no_dev_io, NONE, "", 0, STYLE_NDEV, NULL }
/*===========================================================================*
* do_mapdriver *
*===========================================================================*/
PUBLIC int do_mapdriver()
{
- int r, force, major, proc_nr_n;
+ int r, flags, major;
endpoint_t endpoint;
vir_bytes label_vir;
size_t label_len;
char label[LABEL_MAX];
- if (!super_user)
+ /* Only RS can map drivers. */
+ if (who_e != RS_PROC_NR)
{
- printf("FS: unauthorized call of do_mapdriver by proc %d\n",
+ printf("vfs: unauthorized call of do_mapdriver by proc %d\n",
who_e);
- return(EPERM); /* only su (should be only RS or some drivers)
- * may call do_mapdriver.
- */
+ return(EPERM);
}
/* Get the label */
return EINVAL;
}
- if (isokendpt(endpoint, &proc_nr_n) != OK)
- {
- printf("vfs:do_mapdriver: bad endpoint %d\n", endpoint);
- return(EINVAL);
- }
-
/* Try to update device mapping. */
major= m_in.md_major;
- force= m_in.md_force;
- r= map_driver(label, major, endpoint, m_in.md_style, force);
+ flags= m_in.md_flags;
+ r= map_driver(label, major, endpoint, m_in.md_style, flags);
return(r);
}
/*===========================================================================*
* map_driver *
*===========================================================================*/
-PUBLIC int map_driver(label, major, proc_nr_e, style, force)
+PUBLIC int map_driver(label, major, proc_nr_e, style, flags)
char *label; /* name of the driver */
int major; /* major number of the device */
endpoint_t proc_nr_e; /* process number of the driver */
int style; /* style of the device */
-int force;
+int flags; /* device flags */
{
-/* Set a new device driver mapping in the dmap table. Given that correct
- * arguments are given, this only works if the entry is mutable and the
- * current driver is not busy. If the proc_nr is set to NONE, we're supposed
- * to unmap it.
- *
- * Normal error codes are returned so that this function can be used from
- * a system call that tries to dynamically install a new driver.
+/* Set a new device driver mapping in the dmap table.
+ * If the proc_nr is set to NONE, we're supposed to unmap it.
*/
int proc_nr_n;
size_t len;
if (major < 0 || major >= NR_DEVICES) return(ENODEV);
dp = &dmap[major];
- /* Check if we're supposed to unmap it. If so, do it even
- * if busy or unmutable, as unmap is called when driver has
- * exited.
- */
+ /* Check if we're supposed to unmap it. */
if(proc_nr_e == NONE) {
dp->dmap_opcl = no_dev;
dp->dmap_io = no_dev_io;
dp->dmap_driver = NONE;
- dp->dmap_flags = DMAP_MUTABLE; /* When gone, not busy or reserved. */
+ dp->dmap_flags = flags;
return(OK);
}
-
- /* See if updating the entry is allowed. */
- if (! (dp->dmap_flags & DMAP_MUTABLE)) return(EPERM);
- if (!force)
+ /* Check process number of new driver if requested. */
+ if (! (flags & DRV_FORCED))
{
- /* Check process number of new driver. */
if (isokendpt(proc_nr_e, &proc_nr_n) != OK)
return(EINVAL);
}
/* Try to update the entry. */
switch (style) {
- case STYLE_DEV: dp->dmap_opcl = gen_opcl; break;
- case STYLE_TTY: dp->dmap_opcl = tty_opcl; break;
- case STYLE_CLONE: dp->dmap_opcl = clone_opcl; break;
- default: return(EINVAL);
+ case STYLE_DEV:
+ dp->dmap_opcl = gen_opcl;
+ dp->dmap_io = gen_io;
+ break;
+ case STYLE_DEVA:
+ dp->dmap_opcl = gen_opcl;
+ dp->dmap_io = asyn_io;
+ break;
+ case STYLE_TTY:
+ dp->dmap_opcl = tty_opcl;
+ dp->dmap_io = gen_io;
+ break;
+ case STYLE_CTTY:
+ dp->dmap_opcl = ctty_opcl;
+ dp->dmap_io = ctty_io;
+ break;
+ case STYLE_CLONE:
+ dp->dmap_opcl = clone_opcl;
+ dp->dmap_io = gen_io;
+ break;
+ default:
+ return(EINVAL);
}
- dp->dmap_io = gen_io;
dp->dmap_driver = proc_nr_e;
-
- if (dp->dmap_async_driver)
- dp->dmap_io= asyn_io;
+ dp->dmap_flags = flags;
+ dp->dmap_style = style;
return(OK);
}
}
+/*===========================================================================*
+ * map_service *
+ *===========================================================================*/
+PUBLIC int map_service(struct rprocpub *rpub)
+{
+/* Map a new service by storing its device driver properties. */
+ int r;
+
+ /* Not a driver, nothing more to do. */
+ if(!rpub->dev_nr) {
+ return OK;
+ }
+
+ /* Map driver. */
+ r = map_driver(rpub->label, rpub->dev_nr, rpub->endpoint,
+ rpub->dev_style, rpub->dev_flags);
+ if(r != OK) {
+ return r;
+ }
+
+ /* If driver has two major numbers associated, also map the other one. */
+ if(rpub->dev_style2 != STYLE_NDEV) {
+ r = map_driver(rpub->label, rpub->dev_nr+1, rpub->endpoint,
+ rpub->dev_style2, rpub->dev_flags);
+ if(r != OK) {
+ return r;
+ }
+ }
+
+ return OK;
+}
+
/*===========================================================================*
* build_dmap *
*===========================================================================*/
PUBLIC void build_dmap()
{
-/* Initialize the table with all device <-> driver mappings. Then, map
- * the boot driver to a controller and update the dmap table to that
- * selection. The boot driver and the controller it handles are set at
- * the boot monitor.
- */
+/* Initialize the table with empty device <-> driver mappings. */
int i;
- struct dmap *dp;
+ struct dmap dmap_default = DT_EMPTY;
- /* Build table with device <-> driver mappings. */
for (i=0; i<NR_DEVICES; i++) {
- dp = &dmap[i];
- if (i < sizeof(init_dmap)/sizeof(struct dmap) &&
- init_dmap[i].dmap_opcl != no_dev) { /* a preset driver */
- dp->dmap_opcl = init_dmap[i].dmap_opcl;
- dp->dmap_io = init_dmap[i].dmap_io;
- dp->dmap_driver = init_dmap[i].dmap_driver;
- dp->dmap_flags = init_dmap[i].dmap_flags;
- strcpy(dp->dmap_label, init_dmap[i].dmap_label);
- dp->dmap_async_driver= FALSE;
- } else { /* no default */
- dp->dmap_opcl = no_dev;
- dp->dmap_io = no_dev_io;
- dp->dmap_driver = NONE;
- dp->dmap_flags = DMAP_MUTABLE;
- }
+ dmap[i] = dmap_default;
}
-
- dmap[13].dmap_async_driver= TRUE; /* Audio */
- dmap[15].dmap_async_driver= TRUE; /* Log */
- dmap[15].dmap_io= asyn_io;
- dmap[16].dmap_async_driver= TRUE; /* Random */
-
}
/*===========================================================================*
* The table can be update dynamically. The field 'dmap_flags' describe an
* entry's current status and determines what control options are possible.
*/
-#define DMAP_MUTABLE 0x01 /* mapping can be overtaken */
extern struct dmap {
int _PROTOTYPE ((*dmap_opcl), (int, Dev_t, int, int) );
int _PROTOTYPE ((*dmap_io), (int, message *) );
endpoint_t dmap_driver;
- int dmap_flags;
char dmap_label[LABEL_MAX];
- int dmap_async_driver;
+ int dmap_flags;
+ int dmap_style;
struct filp *dmap_sel_filp;
} dmap[];
#include <minix/type.h>
#include <minix/dmap.h>
#include <minix/ds.h>
+#include <minix/rs.h>
#include <limits.h>
#include <errno.h>
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the virtual file server. */
- int s;
+ int s, i;
register struct fproc *rfp;
struct vmnt *vmp;
struct vnode *root_vp;
message mess;
+ struct rprocpub rprocpub[NR_BOOT_PROCS];
/* Clear endpoint field */
last_login_fs_e = NONE;
fp = (struct fproc *) NULL;
who_e = who_p = FS_PROC_NR;
- build_dmap(); /* build device table and map boot driver */
+ /* Initialize device table. */
+ build_dmap();
+
+ /* Map all the services in the boot image. */
+ if((s = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0,
+ (vir_bytes) rprocpub, sizeof(rprocpub), S)) != OK) {
+ panic("sys_safecopyfrom failed: %d", s);
+ }
+ for(i=0;i < NR_BOOT_PROCS;i++) {
+ if(rprocpub[i].in_use) {
+ if((s = map_service(&rprocpub[i])) != OK) {
+ panic("unable to map service: %d", s);
+ }
+ }
+ }
+
init_root(); /* init root device and load super block */
init_select(); /* init select() structures */
PUBLIC int do_svrctl()
{
switch (m_in.svrctl_req) {
- case FSSIGNON: {
- /* A server in user space calls in to manage a device. */
- struct fssignon device;
- int r, major, proc_nr_n;
-
- if (fp->fp_effuid != SU_UID && fp->fp_effuid != SERVERS_UID)
- return(EPERM);
-
- /* Try to copy request structure to FS. */
- if ((r = sys_datacopy(who_e, (vir_bytes) m_in.svrctl_argp,
- FS_PROC_NR, (vir_bytes) &device,
- (phys_bytes) sizeof(device))) != OK)
- return(r);
-
- if (isokendpt(who_e, &proc_nr_n) != OK)
- return(EINVAL);
-
- /* Try to update device mapping. */
- major = (device.dev >> MAJOR) & BYTE;
- r=map_driver(NULL, major, who_e, device.style, 0 /* !force */);
- if (r == OK)
- {
- /* If a driver has completed its exec(), it can be announced
- * to be up.
- */
- reply(who_e, r);
- dev_up(major);
- r= SUSPEND;
- }
-
- return(r);
- }
+ /* No control request implemented yet. */
default:
return(EINVAL);
}
#define offset_lo m2_l1
#define offset_high m2_l2
#define ctl_req m4_l1
-#define driver_nr m4_l2
-#define dev_nr m4_l3
-#define dev_style m4_l4
-#define m_force m4_l5
#define mount_flags m1_i3
#define request m1_i2
#define sig m1_i2
#define md_label_len m2_l1
#define md_major m2_i1
#define md_style m2_i2
-#define md_force m2_i3
+#define md_flags m2_i3
/* The following names are synonyms for the variables in the output message. */
#define reply_type m_type
#include "timers.h"
#include "request.h"
+#include <minix/rs.h>
/* Structs used in prototypes must be declared as such first. */
struct filp;
/* dmap.c */
_PROTOTYPE( int do_mapdriver, (void) );
+_PROTOTYPE( int map_service, (struct rprocpub *rpub) );
_PROTOTYPE( void build_dmap, (void) );
_PROTOTYPE( int map_driver, (char *label, int major, int proc_nr,
- int dev_style, int force) );
+ int dev_style, int flags) );
_PROTOTYPE( int dmap_driver_match, (endpoint_t proc, int major) );
_PROTOTYPE( void dmap_unmap_by_endpt, (int proc_nr) );
_PROTOTYPE( void dmap_endpt_up, (int proc_nr) );
+++ /dev/null
-#if 1
-extern struct dmap {
- int _PROTOTYPE ((*dmap_opcl), (int, Dev_t, int, int) );
- int _PROTOTYPE ((*dmap_io), (int, message *) );
- int dmap_driver;
- int dmap_flags;
-} dmap[];
-#endif
-