VFS: further cleanup of device code

- all TTY-related exceptions have now been merged into the regular
  code paths, allowing non-TTY drivers to expose TTY-like devices;
- as part of this, CTTY_MAJOR is now fully managed by VFS instead of
  being an ugly stepchild of the TTY driver;
- device styles have become completely obsolete, support for them has
  been removed throughout the system; same for device flags, which had
  already become useless a while ago;
- device map open/close and I/O function pointers have lost their use,
  thus finally making the VFS device code actually readable;
- the device-unrelated pm_setsid has been moved to misc.c;
- some other small cleanup-related changes.

Change-Id: If90b10d1818e98a12139da3e94a15d250c9933da
This commit is contained in:
David van Moolenbroek 2013-10-06 15:58:54 +02:00 committed by Lionel Sambuc
parent cf12dbac0d
commit 664b726cd3
25 changed files with 274 additions and 564 deletions

View file

@ -5,7 +5,7 @@ service \- Manage an operating system service.
.PP
\fBservice [-b -c -n -p -r] (up|run|edit|update)\fR \fI<binary|self>\fR
[\fB-args\fR \fI<args>\fR] [\fB-dev\fR \fI<special>\fR]
[\fB-devstyle\fR \fI<style>\fR] [\fB-period\fR \fI<ticks>\fR]
[\fB-period\fR \fI<ticks>\fR]
[\fB-script\fR \fI<path>\fR] [\fB-label\fR \fI<name>\fR]
[\fB-config\fR \fI<path>\fR] [\fB-state\fR \fI<state>\fR]
[\fB-maxtime\fR \fI<time>\fR]
@ -103,12 +103,6 @@ given by \fI<binary>\fR. The default is to use no arguments.
specifies the device file to associate to the system service (used only for
device drivers). The default is to associate no device file to the service.
.TP
.BI \-devstyle " <style>"
specifies the device style to associate to the system service (used only for
device drivers). The list of supported device styles is available in
the header file \fB<minix/dmap.h>\fR.
The default is to associate no device style (\fBSTYLE_NDEV\fR) to the service.
.TP
.BI \-period " <ticks>"
specifies the period to use for the system service.
When a period is specified, \fBRS\fR sends a ping request to
@ -160,7 +154,7 @@ label \fI<name>\fR. This action can be used to dynamically update the
properties of any system service, including those contained in the
boot image (e.g. \fBVM\fR). There are a few exceptions to the properties
that can be actually overridden dynamically. For example, the device file
and the device style associated to the service will no be updated. This
associated to the service will no be updated. This
action takes the same options supported by the \fBup\fR action.
.PP
.SS

View file

@ -86,7 +86,6 @@ static char *known_requests[] = {
#define ARG_ARGS "-args" /* list of arguments to be passed */
#define ARG_DEV "-dev" /* major device number for drivers */
#define ARG_MAJOR "-major" /* major number */
#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
@ -113,7 +112,6 @@ static char *req_path_self = SELF_REQ_PATH;
static char *req_args = "";
static int req_major = 0;
static int devman_id = 0;
static int req_dev_style = STYLE_NDEV;
static long req_period = 0;
static char *req_script = NULL;
static char *req_config = PATH_CONFIG;
@ -131,9 +129,9 @@ static void print_usage(char *app_name, char *problem)
fprintf(stderr, "Warning, %s\n", problem);
fprintf(stderr, "Usage:\n");
fprintf(stderr,
" %s [%s %s %s %s] (up|run|edit|update) <binary|%s> [%s <args>] [%s <special>] [%s <style>] [%s <major_nr>] [%s <dev_id>] [%s <ticks>] [%s <path>] [%s <name>] [%s <path>] [%s <state>] [%s <time>]\n",
" %s [%s %s %s %s] (up|run|edit|update) <binary|%s> [%s <args>] [%s <special>] [%s <major_nr>] [%s <dev_id>] [%s <ticks>] [%s <path>] [%s <name>] [%s <path>] [%s <state>] [%s <time>]\n",
app_name, OPT_COPY, OPT_REUSE, OPT_NOBLOCK, OPT_REPLICA, SELF_BINARY,
ARG_ARGS, ARG_DEV, ARG_DEVSTYLE, ARG_MAJOR, ARG_DEVMANID, ARG_PERIOD, ARG_SCRIPT,
ARG_ARGS, ARG_DEV, ARG_MAJOR, ARG_DEVMANID, 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);
@ -315,9 +313,6 @@ static int parse_arguments(int argc, char **argv, u32_t *rss_flags)
exit(EINVAL);
}
req_major = major(stat_buf.st_rdev);
if(req_dev_style == STYLE_NDEV) {
req_dev_style = STYLE_DEV;
}
}
else if (strcmp(argv[i], ARG_MAJOR)==0) {
if (req_major != 0) {
@ -329,26 +324,7 @@ static int parse_arguments(int argc, char **argv, u32_t *rss_flags)
} else {
exit(EINVAL);
}
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_TTY",
"STYLE_CTTY", NULL };
int dev_style_values[] = { STYLE_DEV, STYLE_TTY,
STYLE_CTTY };
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];
}
@ -466,7 +442,6 @@ int main(int argc, char **argv)
config.rs_start.rss_cmd= command;
config.rs_start.rss_cmdlen= strlen(command);
config.rs_start.rss_major= req_major;
config.rs_start.rss_dev_style= req_dev_style;
config.rs_start.rss_period= req_period;
config.rs_start.rss_script= req_script;
config.rs_start.devman_id= devman_id;

View file

@ -40,7 +40,7 @@ int getprocnr(void);
int getnprocnr(pid_t pid);
int getpprocnr(void);
int _pm_findproc(char *proc_name, int *proc_nr);
int mapdriver(char *label, int major, int style, int flags);
int mapdriver(char *label, int major);
pid_t getnpid(endpoint_t proc_ep);
uid_t getnuid(endpoint_t proc_ep);
gid_t getngid(endpoint_t proc_ep);

View file

@ -149,9 +149,6 @@
#define LU_SYS_PROC 0x400 /* this is a live updated sys proc instance */
#define RST_SYS_PROC 0x800 /* this is a restarted sys proc instance */
/* 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

View file

@ -4,9 +4,6 @@
#include <minix/sys_config.h>
#include <minix/ipc.h>
enum dev_style { STYLE_NDEV, STYLE_DEV, STYLE_TTY, STYLE_CTTY };
#define IS_DEV_STYLE(s) (s>=STYLE_NDEV && s<=STYLE_CTTY)
/*===========================================================================*
* Major and minor device numbers *
*===========================================================================*/

View file

@ -73,7 +73,6 @@ struct rs_start
int rss_priority;
int rss_quantum;
int rss_major;
int rss_dev_style;
long rss_period;
char *rss_script;
size_t rss_scriptlen;
@ -119,10 +118,7 @@ struct rprocpub {
unsigned sys_flags; /* sys flags */
endpoint_t endpoint; /* process endpoint number */
int dev_flags; /* device flags */
dev_t dev_nr; /* major device number */
int dev_style; /* device style */
int dev_style2; /* device style for next major dev number */
dev_t dev_nr; /* major device number or NO_DEV */
char label[RS_MAX_LABEL_LEN]; /* label of this service */
char proc_name[RS_MAX_LABEL_LEN]; /* process name of this service */

View file

@ -3,18 +3,14 @@
#include <unistd.h>
int mapdriver(label, major, dev_style, flags)
int mapdriver(label, major)
char *label;
int major;
int dev_style;
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 = flags;
if (_syscall(VFS_PROC_NR, MAPDRIVER, &m) < 0) return(-1);
return(0);
}

View file

@ -58,30 +58,6 @@ void fproc_dmp()
prev_i = i;
}
/*===========================================================================*
* dmap_flags *
*===========================================================================*/
static char * dmap_flags(int flags)
{
static char fl[10];
strlcpy(fl, "-----", sizeof(fl));
if(flags & DRV_FORCED) fl[0] = 'F';
return fl;
}
/*===========================================================================*
* dmap_style *
*===========================================================================*/
static char * dmap_style(int dev_style)
{
switch(dev_style) {
case STYLE_DEV: return "STYLE_DEV";
case STYLE_TTY: return "STYLE_TTY";
case STYLE_CTTY: return "STYLE_CTTY";
default: return "UNKNOWN";
}
}
/*===========================================================================*
* dtab_dmp *
*===========================================================================*/
@ -95,13 +71,10 @@ void dtab_dmp()
}
printf("File System (FS) device <-> driver mappings\n");
printf(" Label Major Driver ept Flags Style \n");
printf("------------- ----- ---------- ----- -------------\n");
printf(" Label Major Driver ept\n");
printf("------------- ----- ----------\n");
for (i=0; i<NR_DEVICES; i++) {
if (dmap[i].dmap_driver == NONE) continue;
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));
printf("%13s %5d %10d\n", dmap[i].dmap_label, i, dmap[i].dmap_driver);
}
}

View file

@ -42,10 +42,10 @@ void rproc_dmp()
rpub = &rprocpub[i];
if (! (rp->r_flags & RS_IN_USE)) continue;
if (++n > 22) break;
printf("%13s %9d %5d %6s %3d/%1d %3ld %8lu %5dx %s",
printf("%13s %9d %5d %6s %4d %4ld %8lu %5dx %s",
rpub->label, rpub->endpoint, rp->r_pid,
s_flags_str(rp->r_flags, rpub->sys_flags), rpub->dev_nr,
rpub->dev_style, rp->r_period, rp->r_alive_tm, rp->r_restarts,
rp->r_period, rp->r_alive_tm, rp->r_restarts,
rp->r_args
);
printf("\n");

View file

@ -71,10 +71,6 @@
#define DSRV_SF (0) /* dynamic system services */
#define VM_SF (SRVR_SF) /* vm */
/* Define device flags for the various process types. */
#define SRV_DF (DRV_FORCED) /* system services */
#define DSRV_DF (SRV_DF) /* dynamic system services */
/* Shorthands. */
#define SRV_OR_USR(rp, X, Y) (rp->r_priv.s_flags & SYS_PROC ? X : Y)

View file

@ -299,10 +299,7 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(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->dev_style2 = boot_image_dev->dev_style2; /* device style 2 */
/* Build command settings. This will also set the process name. */
strlcpy(rp->r_cmd, ip->proc_name, sizeof(rp->r_cmd));

View file

@ -677,8 +677,7 @@ struct rproc *rp; /* pointer to service slot */
*/
setuid(0);
if (mapdriver(rpub->label, rpub->dev_nr, rpub->dev_style,
rpub->dev_flags) != OK) {
if (mapdriver(rpub->label, rpub->dev_nr) != OK) {
return kill_service(rp, "couldn't map driver", errno);
}
}
@ -1225,10 +1224,7 @@ struct rproc *rp;
rpub = rp->r_pub;
/* Device and PCI 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;
rpub->pci_acl = def_rpub->pci_acl;
/* Immutable system and privilege flags. */
@ -1608,15 +1604,8 @@ endpoint_t source;
rp->r_uid= rs_start->rss_uid;
/* Initialize device driver settings. */
rpub->dev_flags = DSRV_DF;
rpub->dev_nr = rs_start->rss_major;
rpub->dev_style = rs_start->rss_dev_style;
rpub->devman_id = rs_start->devman_id;
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 pci settings. */
if (rs_start->rss_nr_pci_id > RS_NR_PCI_DEVICE) {

View file

@ -42,11 +42,8 @@ struct boot_image_sys boot_image_sys_table[] = {
/* Definition of the boot image dev table. */
struct boot_image_dev boot_image_dev_table[] = {
/*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 },
{ DEFAULT_BOOT_NR, SRV_DF, 0, STYLE_NDEV, STYLE_NDEV } /* default
* entry
*/
/*endpoint, dev_nr */
{ TTY_PROC_NR, TTY_MAJOR },
{ MEM_PROC_NR, MEMORY_MAJOR },
{ DEFAULT_BOOT_NR, 0 } /* default entry */
};

View file

@ -22,10 +22,7 @@ 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 */
int dev_style2; /* device style for next major device number */
};
/* Definition of an entry of the system process table. */

View file

@ -135,11 +135,11 @@ struct rproc *rp; /* pointer to process slot */
((rp)->r_old_rp || (rp)->r_prev_rp ? "+" : " "))
#if DEBUG
sprintf(srv_string, "service '%s'%s%s(slot %d, ep %d, pid %d, cmd %s, script %s, proc %s, major %d, style %d, flags 0x%03x, sys_flags 0x%02x)",
sprintf(srv_string, "service '%s'%s%s(slot %d, ep %d, pid %d, cmd %s, script %s, proc %s, major %d, flags 0x%03x, sys_flags 0x%02x)",
rpub->label, srv_active_str(rp), srv_version_str(rp),
slot_nr, rpub->endpoint, rp->r_pid, srv_str(rp->r_cmd),
srv_str(rp->r_script), srv_str(rpub->proc_name), rpub->dev_nr,
rpub->dev_style, rp->r_flags, rpub->sys_flags);
rp->r_flags, rpub->sys_flags);
#else
sprintf(srv_string, "service '%s'%s%s(slot %d, ep %d, pid %d)",
rpub->label, srv_active_str(rp), srv_version_str(rp),

View file

@ -89,6 +89,16 @@ int drv_sendrec(endpoint_t drv_e, message *reqmp)
int r;
struct dmap *dp;
/* For the CTTY_MAJOR case, we would actually have to lock the device
* entry being redirected to. However, the CTTY major only hosts a
* character device while this function is used only for block devices.
* Thus, we can simply deny the request immediately.
*/
if (drv_e == CTTY_ENDPT) {
printf("VFS: /dev/tty is not a block device!\n");
return EIO;
}
if ((dp = get_dmap(drv_e)) == NULL)
panic("driver endpoint %d invalid", drv_e);

View file

@ -42,4 +42,7 @@
#define SEL_ERR CDEV_OP_ERR
#define SEL_NOTIFY CDEV_NOTIFY /* not a real select operation */
/* special driver endpoint for CTTY_MAJOR; must be able to pass isokendpt() */
#define CTTY_ENDPT VFS_PROC_NR
#endif

View file

@ -12,14 +12,6 @@
* bdev_close: close a block device
* bdev_reply: process the result of a block driver request
* bdev_up: a block driver has been mapped in
* gen_opcl: generic call to a character driver to perform an open/close
* gen_io: generic call to a character driver to initiate I/O
* no_dev: open/close processing for devices that don't exist
* no_dev_io: i/o processing for devices that don't exist
* tty_opcl: perform tty-specific processing for open/close
* ctty_opcl: perform controlling-tty-specific processing for open/close
* ctty_io: perform controlling-tty-specific processing for I/O
* pm_setsid: perform VFS's side of setsid system call
* do_ioctl: perform the IOCTL system call
*/
@ -41,49 +33,11 @@
#include "vmnt.h"
#include "param.h"
static int cdev_opcl(int op, dev_t dev, int flags);
static int block_io(endpoint_t driver_e, message *mess_ptr);
static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op,
void *buf, unsigned long size);
/*===========================================================================*
* cdev_open *
*===========================================================================*/
int cdev_open(dev_t dev, int flags)
{
/* Open a character device. */
devmajor_t major_dev;
int r;
/* Determine the major device number so as to call the device class specific
* open/close routine. (This is the only routine that must check the
* device number for being in range. All others can trust this check.)
*/
major_dev = major(dev);
if (major_dev < 0 || major_dev >= NR_DEVICES) return(ENXIO);
if (dmap[major_dev].dmap_driver == NONE) return(ENXIO);
r = (*dmap[major_dev].dmap_opcl)(CDEV_OPEN, dev, fp->fp_endpoint, flags);
return(r);
}
/*===========================================================================*
* cdev_close *
*===========================================================================*/
int cdev_close(dev_t dev)
{
/* Close a character device. */
devmajor_t major_dev;
int r;
/* See if driver is roughly valid. */
major_dev = major(dev);
if (major_dev < 0 || major_dev >= NR_DEVICES) return(ENXIO);
if (dmap[major_dev].dmap_driver == NONE) return(ENXIO);
r = (*dmap[major_dev].dmap_opcl)(CDEV_CLOSE, dev, fp->fp_endpoint, 0);
return(r);
}
/*===========================================================================*
* bdev_open *
*===========================================================================*/
@ -158,6 +112,7 @@ static int bdev_ioctl(dev_t dev, endpoint_t proc_e, unsigned long req,
message dev_mess;
devmajor_t major_dev;
devminor_t minor_dev;
int r;
major_dev = major(dev);
minor_dev = minor(dev);
@ -183,17 +138,15 @@ static int bdev_ioctl(dev_t dev, endpoint_t proc_e, unsigned long req,
dev_mess.BDEV_ID = 0;
/* Call the task. */
block_io(dp->dmap_driver, &dev_mess);
r = block_io(dp->dmap_driver, &dev_mess);
/* Clean up. */
if (GRANT_VALID(gid)) cpf_revoke(gid);
if (dp->dmap_driver == NONE) {
printf("VFS: block driver gone!?\n");
return(EIO);
}
/* Return the result. */
if (r != OK)
return(r);
return(dev_mess.BDEV_STATUS);
}
@ -246,6 +199,48 @@ static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op,
return gid;
}
/*===========================================================================*
* cdev_get *
*===========================================================================*/
static struct dmap *cdev_get(dev_t dev, devminor_t *minor_dev)
{
/* Obtain the dmap structure for the given device, if a valid driver exists for
* the major device. Perform redirection for CTTY_MAJOR.
*/
devmajor_t major_dev;
struct dmap *dp;
int slot;
/* First cover one special case: /dev/tty, the magic device that translates
* to the controlling tty.
*/
if (major(dev) == CTTY_MAJOR) {
/* No controlling terminal? Fail the request. */
if (fp->fp_tty == 0) return(NULL);
/* Substitute the controlling terminal device. */
dev = fp->fp_tty;
}
/* Determine task dmap. */
major_dev = major(dev);
if (major_dev < 0 || major_dev >= NR_DEVICES) return(NULL);
dp = &dmap[major_dev];
/* See if driver is roughly valid. */
if (dp->dmap_driver == NONE) return(NULL);
if (isokendpt(dp->dmap_driver, &slot) != OK) {
printf("VFS: cdev_get: old driver for major %x (%d)\n", major_dev,
dp->dmap_driver);
return(NULL);
}
/* Also return the (possibly redirected) minor number. */
*minor_dev = minor(dev);
return dp;
}
/*===========================================================================*
* cdev_io *
@ -261,28 +256,17 @@ int cdev_io(
)
{
/* Initiate a read, write, or ioctl to a character device. */
devminor_t minor_dev;
struct dmap *dp;
message dev_mess;
cp_grant_id_t gid;
devmajor_t major_dev;
devminor_t minor_dev;
int r, slot;
int r;
assert(op == CDEV_READ || op == CDEV_WRITE || op == CDEV_IOCTL);
/* Determine task dmap. */
major_dev = major(dev);
minor_dev = minor(dev);
dp = &dmap[major_dev];
/* See if driver is roughly valid. */
if (dp->dmap_driver == NONE) return(ENXIO);
if(isokendpt(dp->dmap_driver, &slot) != OK) {
printf("VFS: dev_io: old driver for major %x (%d)\n", major_dev,
dp->dmap_driver);
return(ENXIO);
}
/* Determine task map. */
if ((dp = cdev_get(dev, &minor_dev)) == NULL)
return(EIO);
/* Create a grant for the buffer provided by the user process. */
gid = make_grant(dp->dmap_driver, proc_e, op, buf, bytes);
@ -306,13 +290,8 @@ int cdev_io(
dev_mess.CDEV_FLAGS |= CDEV_NONBLOCK;
/* Send the request to the driver. */
r = (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
if (r != OK) {
cpf_revoke(gid);
return r;
}
if ((r = asynsend3(dp->dmap_driver, &dev_mess, AMF_NOREPLY)) != OK)
panic("VFS: asynsend in cdev_io failed: %d", r);
/* Suspend the calling process until a reply arrives. */
wait_for(dp->dmap_driver);
@ -324,9 +303,9 @@ int cdev_io(
/*===========================================================================*
* clone_cdev *
* cdev_clone *
*===========================================================================*/
static int cdev_clone(dev_t dev, endpoint_t proc_e, devminor_t new_minor)
static int cdev_clone(dev_t dev, devminor_t new_minor)
{
/* A new minor device number has been returned. Request PFS to create a
* temporary device file to hold it.
@ -335,8 +314,6 @@ static int cdev_clone(dev_t dev, endpoint_t proc_e, devminor_t new_minor)
struct node_details res;
int r;
assert(proc_e == fp->fp_endpoint);
/* Device number of the new device. */
dev = makedev(major(dev), new_minor);
@ -344,14 +321,14 @@ static int cdev_clone(dev_t dev, endpoint_t proc_e, devminor_t new_minor)
r = req_newnode(PFS_PROC_NR, fp->fp_effuid, fp->fp_effgid,
ALL_MODES | I_CHAR_SPECIAL, dev, &res);
if (r != OK) {
(void) gen_opcl(CDEV_CLOSE, dev, proc_e, 0);
(void) cdev_opcl(CDEV_CLOSE, dev, 0);
return r;
}
/* Drop old node and use the new values */
if ((vp = get_free_vnode()) == NULL) {
req_putnode(PFS_PROC_NR, res.inode_nr, 1); /* is this right? */
(void) gen_opcl(CDEV_CLOSE, dev, proc_e, 0);
(void) cdev_opcl(CDEV_CLOSE, dev, 0);
return(err_code);
}
lock_vnode(vp, VNODE_OPCL);
@ -376,49 +353,63 @@ static int cdev_clone(dev_t dev, endpoint_t proc_e, devminor_t new_minor)
/*===========================================================================*
* gen_opcl *
* cdev_opcl *
*===========================================================================*/
int gen_opcl(
static int cdev_opcl(
int op, /* operation, CDEV_OPEN or CDEV_CLOSE */
dev_t dev, /* device to open or close */
endpoint_t proc_e, /* process to open/close for */
int flags /* mode bits and flags */
)
{
/* Called from the dmap struct on opens & closes of special files.*/
devmajor_t major_dev;
/* Open or close a character device. */
devminor_t minor_dev, new_minor;
struct dmap *dp;
struct fproc *rfp;
message dev_mess;
int r, r2;
/* Determine task dmap. */
major_dev = major(dev);
minor_dev = minor(dev);
assert(major_dev >= 0 && major_dev < NR_DEVICES);
dp = &dmap[major_dev];
assert(dp->dmap_driver != NONE);
assert(op == CDEV_OPEN || op == CDEV_CLOSE);
assert(!IS_BDEV_RQ(op));
/* Determine task dmap. */
if ((dp = cdev_get(dev, &minor_dev)) == NULL)
return(ENXIO);
/* CTTY exception: do not actually send the open/close request for /dev/tty
* to the driver. This avoids the case that the actual device will remain
* open forever if the process calls setsid() after opening /dev/tty.
*/
if (major(dev) == CTTY_MAJOR) return(OK);
/* Add O_NOCTTY to the access flags if this process is not a session leader,
* or if it already has a controlling tty, or if it is someone else's
* controlling tty. For performance reasons, only search the full process
* table if this driver has set controlling ttys before.
*/
if (!(fp->fp_flags & FP_SESLDR) || fp->fp_tty != 0) {
flags |= O_NOCTTY;
} else if (!(flags & O_NOCTTY) && dp->dmap_seen_tty) {
for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++)
if (rfp->fp_pid != PID_FREE && rfp->fp_tty == dev)
flags |= O_NOCTTY;
}
/* Prepare the request message. */
memset(&dev_mess, 0, sizeof(dev_mess));
dev_mess.m_type = op;
dev_mess.CDEV_MINOR = minor_dev;
dev_mess.CDEV_ID = proc_e;
dev_mess.CDEV_ID = who_e;
if (op == CDEV_OPEN) {
dev_mess.CDEV_USER = proc_e;
dev_mess.CDEV_USER = who_e;
dev_mess.CDEV_ACCESS = 0;
if (flags & R_BIT) dev_mess.CDEV_ACCESS |= CDEV_R_BIT;
if (flags & W_BIT) dev_mess.CDEV_ACCESS |= CDEV_W_BIT;
if (flags & O_NOCTTY) dev_mess.CDEV_ACCESS |= CDEV_NOCTTY;
}
/* Call the task. */
r = (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
if (r != OK) return(r);
/* Send the request to the driver. */
if ((r = asynsend3(dp->dmap_driver, &dev_mess, AMF_NOREPLY)) != OK)
panic("VFS: asynsend in cdev_opcl failed: %d", r);
/* Block the thread waiting for a reply. */
fp->fp_task = dp->dmap_driver;
@ -430,106 +421,55 @@ int gen_opcl(
self->w_task = NONE;
self->w_drv_sendrec = NULL;
/* Process the reply. */
r = dev_mess.CDEV_STATUS;
/* Some devices need special processing upon open. Such a device is "cloned",
* i.e. on a succesful open it is replaced by a new device with a new unique
* minor device number. This new device number identifies a new object (such
* as a new network connection) that has been allocated within a task.
*/
if (op == CDEV_OPEN && r >= 0) {
/* Some devices need special processing upon open. Such a device is
* "cloned", i.e. on a succesful open it is replaced by a new device
* with a new unique minor device number. This new device number
* identifies a new object (such as a new network connection) that has
* been allocated within a driver.
*/
if (r & CDEV_CLONED) {
new_minor = r & ~(CDEV_CLONED | CDEV_CTTY);
r &= CDEV_CTTY;
if ((r2 = cdev_clone(dev, proc_e, new_minor)) < 0)
r = r2;
} else
r &= CDEV_CTTY;
/* Upon success, we now return either OK or CDEV_CTTY. */
if ((r2 = cdev_clone(dev, new_minor)) < 0)
return(r2);
}
/* Did this call make the tty the controlling tty? */
if (r & CDEV_CTTY) {
fp->fp_tty = dev;
dp->dmap_seen_tty = TRUE;
}
r = OK;
}
/* Return the result from the driver. */
return(r);
}
/*===========================================================================*
* tty_opcl *
* cdev_open *
*===========================================================================*/
int tty_opcl(
int op, /* operation, CDEV_OPEN or CDEV_CLOSE */
dev_t dev, /* device to open or close */
endpoint_t proc_e, /* process to open/close for */
int flags /* mode bits and flags */
)
int cdev_open(dev_t dev, int flags)
{
/* This procedure is called from the dmap struct on tty open/close. */
int r;
register struct fproc *rfp;
/* Open a character device. */
assert(!IS_BDEV_RQ(op));
/* Add O_NOCTTY to the flags if this process is not a session leader, or
* if it already has a controlling tty, or if it is someone elses
* controlling tty.
*/
if (!(fp->fp_flags & FP_SESLDR) || fp->fp_tty != 0) {
flags |= O_NOCTTY;
} else {
for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
if(rfp->fp_pid == PID_FREE) continue;
if (rfp->fp_tty == dev) flags |= O_NOCTTY;
}
}
r = gen_opcl(op, dev, proc_e, flags);
/* Did this call make the tty the controlling tty? */
if (r >= 0 && (r & CDEV_CTTY)) {
fp->fp_tty = dev;
r = OK;
}
return(r);
return cdev_opcl(CDEV_OPEN, dev, flags);
}
/*===========================================================================*
* ctty_opcl *
* cdev_close *
*===========================================================================*/
int ctty_opcl(
int op, /* operation, CDEV_OPEN or CDEV_CLOSE */
dev_t UNUSED(dev), /* device to open or close */
endpoint_t UNUSED(proc_e), /* process to open/close for */
int UNUSED(flags) /* mode bits and flags */
)
int cdev_close(dev_t dev)
{
/* This procedure is called from the dmap struct on opening or closing
* /dev/tty, the magic device that translates to the controlling tty.
*/
/* Close a character device. */
if (IS_BDEV_RQ(op))
panic("ctty_opcl() called for block device request?");
return(fp->fp_tty == 0 ? ENXIO : OK);
}
/*===========================================================================*
* pm_setsid *
*===========================================================================*/
void pm_setsid(endpoint_t proc_e)
{
/* Perform the VFS side of the SETSID call, i.e. get rid of the controlling
* terminal of a process, and make the process a session leader.
*/
register struct fproc *rfp;
int slot;
/* Make the process a session leader with no controlling tty. */
okendpt(proc_e, &slot);
rfp = &fproc[slot];
rfp->fp_flags |= FP_SESLDR;
rfp->fp_tty = 0;
return cdev_opcl(CDEV_CLOSE, dev, 0);
}
@ -583,25 +523,27 @@ int do_ioctl(message *UNUSED(m_out))
int cdev_select(dev_t dev, int ops)
{
/* Initiate a select call on a device. Return OK iff the request was sent. */
devmajor_t major_dev;
devminor_t minor_dev;
message dev_mess;
struct dmap *dp;
int r;
major_dev = major(dev);
minor_dev = minor(dev);
dp = &dmap[major_dev];
if (dp->dmap_driver == NONE) return ENXIO;
/* Determine task dmap. */
if ((dp = cdev_get(dev, &minor_dev)) == NULL)
return(EIO);
/* Prepare the request message. */
memset(&dev_mess, 0, sizeof(dev_mess));
dev_mess.m_type = CDEV_SELECT;
dev_mess.CDEV_MINOR = minor_dev;
dev_mess.CDEV_OPS = ops;
/* Call the task. */
return (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
/* Send the request to the driver. */
if ((r = asynsend3(dp->dmap_driver, &dev_mess, AMF_NOREPLY)) != OK)
panic("VFS: asynsend in cdev_select failed: %d", r);
return(OK);
}
@ -611,24 +553,25 @@ int cdev_select(dev_t dev, int ops)
int cdev_cancel(dev_t dev)
{
/* Cancel an I/O request, blocking until it has been cancelled. */
devmajor_t major_dev;
devminor_t minor_dev;
message dev_mess;
struct dmap *dp;
int r;
major_dev = major(dev);
minor_dev = minor(dev);
dp = &dmap[major_dev];
/* Determine task dmap. */
if ((dp = cdev_get(dev, &minor_dev)) == NULL)
return(EIO);
/* Prepare the request message. */
memset(&dev_mess, 0, sizeof(dev_mess));
dev_mess.m_type = CDEV_CANCEL;
dev_mess.CDEV_MINOR = minor_dev;
dev_mess.CDEV_ID = fp->fp_endpoint;
r = (*dp->dmap_io)(fp->fp_task, &dev_mess);
if (r != OK) return r; /* ctty_io returned an error? should be impossible */
/* Send the request to the driver. */
if ((r = asynsend3(dp->dmap_driver, &dev_mess, AMF_NOREPLY)) != OK)
panic("VFS: asynsend in cdev_cancel failed: %d", r);
/* Suspend this thread until we have received the response. */
fp->fp_task = dp->dmap_driver;
@ -668,30 +611,29 @@ static int block_io(endpoint_t driver_e, message *mess_ptr)
do {
r = drv_sendrec(driver_e, mess_ptr);
if (r == OK) {
status = mess_ptr->BDEV_STATUS;
if (status == ERESTART) {
r = EDEADEPT;
*mess_ptr = mess_retry;
retry_count++;
}
if (r != OK)
return r;
status = mess_ptr->BDEV_STATUS;
if (status == ERESTART) {
r = EDEADEPT;
*mess_ptr = mess_retry;
retry_count++;
}
} while (status == ERESTART && retry_count < 5);
/* If we failed to restart the request, return EIO */
if (status == ERESTART && retry_count >= 5) {
r = OK;
mess_ptr->m_type = EIO;
}
if (status == ERESTART && retry_count >= 5)
return EIO;
if (r != OK) {
if (r == EDEADSRCDST || r == EDEADEPT) {
printf("VFS: dead driver %d\n", driver_e);
dmap_unmap_by_endpt(driver_e);
return(r);
return(EIO);
} else if (r == ELOCKED) {
printf("VFS: ELOCKED talking to %d\n", driver_e);
return(r);
return(EIO);
}
panic("block_io: can't send/receive: %d", r);
}
@ -700,87 +642,6 @@ static int block_io(endpoint_t driver_e, message *mess_ptr)
}
/*===========================================================================*
* gen_io *
*===========================================================================*/
int gen_io(endpoint_t drv_e, message *mess_ptr)
{
/* Initiate I/O to a character driver. Do not wait for the reply. */
int r;
assert(!IS_BDEV_RQ(mess_ptr->m_type));
r = asynsend3(drv_e, mess_ptr, AMF_NOREPLY);
if (r != OK) panic("VFS: asynsend in gen_io failed: %d", r);
return(OK);
}
/*===========================================================================*
* ctty_io *
*===========================================================================*/
int ctty_io(
endpoint_t UNUSED(task_nr), /* not used - for compatibility with dmap_t */
message *mess_ptr /* pointer to message for task */
)
{
/* This routine is only called for one device, namely /dev/tty. Its job
* is to change the message to use the controlling terminal, instead of the
* major/minor pair for /dev/tty itself.
*/
struct dmap *dp;
int slot;
if (fp->fp_tty == 0) {
/* No controlling tty present anymore, return an I/O error. */
return(EIO);
} else {
/* Substitute the controlling terminal device. */
dp = &dmap[major(fp->fp_tty)];
mess_ptr->CDEV_MINOR = minor(fp->fp_tty);
if (dp->dmap_driver == NONE) {
printf("FS: ctty_io: no driver for dev\n");
return(EIO);
}
if (isokendpt(dp->dmap_driver, &slot) != OK) {
printf("VFS: ctty_io: old driver %d\n", dp->dmap_driver);
return(EIO);
}
return (*dp->dmap_io)(dp->dmap_driver, mess_ptr);
}
}
/*===========================================================================*
* no_dev *
*===========================================================================*/
int no_dev(
int UNUSED(op), /* operation, CDEV_OPEN or CDEV_CLOSE */
dev_t UNUSED(dev), /* device to open or close */
endpoint_t UNUSED(proc), /* process to open/close for */
int UNUSED(flags) /* mode bits and flags */
)
{
/* Called when opening a nonexistent device. */
return(ENODEV);
}
/*===========================================================================*
* no_dev_io *
*===========================================================================*/
int no_dev_io(endpoint_t UNUSED(proc), message *UNUSED(m))
{
/* Called when doing i/o on a nonexistent device. */
printf("VFS: I/O on unmapped device number\n");
return(EIO);
}
/*===========================================================================*
* bdev_up *
*===========================================================================*/

View file

@ -36,7 +36,7 @@ void lock_dmap(struct dmap *dp)
org_self = worker_suspend();
if ((r = mutex_lock(dp->dmap_lock_ref)) != 0)
if ((r = mutex_lock(&dp->dmap_lock)) != 0)
panic("unable to get a lock on dmap: %d\n", r);
worker_resume(org_self);
@ -52,10 +52,57 @@ void unlock_dmap(struct dmap *dp)
assert(dp != NULL);
if ((r = mutex_unlock(dp->dmap_lock_ref)) != 0)
if ((r = mutex_unlock(&dp->dmap_lock)) != 0)
panic("unable to unlock dmap lock: %d\n", r);
}
/*===========================================================================*
* map_driver *
*===========================================================================*/
static int map_driver(label, major, proc_nr_e)
const char label[LABEL_MAX]; /* name of the driver */
int major; /* major number of the device */
endpoint_t proc_nr_e; /* process number of the driver */
{
/* Add a new device driver mapping in the dmap table. If the proc_nr is set to
* NONE, we're supposed to unmap it.
*/
size_t len;
struct dmap *dp;
/* Get pointer to device entry in the dmap table. */
if (major < 0 || major >= NR_DEVICES) return(ENODEV);
dp = &dmap[major];
/* Check if we're supposed to unmap it. */
if (proc_nr_e == NONE) {
/* Even when a driver is now unmapped and is shortly to be mapped in
* due to recovery, invalidate associated filps if they're character
* special files. More sophisticated recovery mechanisms which would
* reduce the need to invalidate files are possible, but would require
* cooperation of the driver and more recovery framework between RS,
* VFS, and DS.
*/
invalidate_filp_by_char_major(major);
dp->dmap_driver = NONE;
return(OK);
}
if (label != NULL) {
len = strlen(label);
if (len+1 > sizeof(dp->dmap_label)) {
printf("VFS: map_driver: label too long: %d\n", len);
return(EINVAL);
}
strlcpy(dp->dmap_label, label, sizeof(dp->dmap_label));
}
/* Store driver I/O routines based on type of device */
dp->dmap_driver = proc_nr_e;
return(OK);
}
/*===========================================================================*
* do_mapdriver *
*===========================================================================*/
@ -66,7 +113,7 @@ int do_mapdriver(message *UNUSED(m_out))
* etc), and its label. This label is registered with DS, and allows us to
* retrieve the driver's endpoint.
*/
int r, flags, major, style, slot;
int r, major, slot;
endpoint_t endpoint;
vir_bytes label_vir;
size_t label_len;
@ -79,8 +126,6 @@ int do_mapdriver(message *UNUSED(m_out))
label_vir = (vir_bytes) job_m_in.md_label;
label_len = (size_t) job_m_in.md_label_len;
major = job_m_in.md_major;
flags = job_m_in.md_flags;
style = job_m_in.md_style;
/* Get the label */
if (label_len+1 > sizeof(label)) { /* Can we store this label? */
@ -110,88 +155,7 @@ int do_mapdriver(message *UNUSED(m_out))
rfp->fp_flags |= FP_SRV_PROC;
/* Try to update device mapping. */
return map_driver(label, major, endpoint, style, flags);
}
/*===========================================================================*
* map_driver *
*===========================================================================*/
int map_driver(label, major, proc_nr_e, style, flags)
const char label[LABEL_MAX]; /* 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 flags; /* device flags */
{
/* Add a new device driver mapping in the dmap table. If the proc_nr is set to
* NONE, we're supposed to unmap it.
*/
int slot, s;
size_t len;
struct dmap *dp;
/* Get pointer to device entry in the dmap table. */
if (major < 0 || major >= NR_DEVICES) return(ENODEV);
dp = &dmap[major];
/* Check if we're supposed to unmap it. */
if (proc_nr_e == NONE) {
/* Even when a driver is now unmapped and is shortly to be mapped in
* due to recovery, invalidate associated filps if they're character
* special files. More sophisticated recovery mechanisms which would
* reduce the need to invalidate files are possible, but would require
* cooperation of the driver and more recovery framework between RS,
* VFS, and DS.
*/
invalidate_filp_by_char_major(major);
dp->dmap_opcl = no_dev;
dp->dmap_io = no_dev_io;
dp->dmap_driver = NONE;
dp->dmap_flags = flags;
dp->dmap_lock_ref = &dp->dmap_lock;
return(OK);
}
/* Check process number of new driver if it was alive before mapping */
s = isokendpt(proc_nr_e, &slot);
if (s != OK) {
/* This is not a problem only when we force this driver mapping */
if (! (flags & DRV_FORCED))
return(EINVAL);
}
if (label != NULL) {
len = strlen(label);
if (len+1 > sizeof(dp->dmap_label))
panic("VFS: map_driver: label too long: %d", len);
strlcpy(dp->dmap_label, label, LABEL_MAX);
}
/* Store driver I/O routines based on type of device */
switch (style) {
case STYLE_DEV:
dp->dmap_opcl = gen_opcl;
dp->dmap_io = gen_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;
break;
default:
return(EINVAL);
}
dp->dmap_driver = proc_nr_e;
dp->dmap_flags = flags;
dp->dmap_style = style;
return(OK);
return map_driver(label, major, endpoint);
}
/*===========================================================================*
@ -205,7 +169,7 @@ void dmap_unmap_by_endpt(endpoint_t proc_e)
for (major = 0; major < NR_DEVICES; major++) {
if (dmap_driver_match(proc_e, major)) {
/* Found driver; overwrite it with a NULL entry */
if ((r = map_driver(NULL, major, NONE, 0, 0)) != OK) {
if ((r = map_driver(NULL, major, NONE)) != OK) {
printf("VFS: unmapping driver %d for major %d failed:"
" %d\n", proc_e, major, r);
}
@ -220,7 +184,6 @@ int map_service(struct rprocpub *rpub)
{
/* Map a new service by storing its device driver properties. */
int r, slot;
struct dmap *fdp, *sdp;
struct fproc *rfp;
if (IS_RPUB_BOOT_USR(rpub)) return(OK);
@ -238,62 +201,32 @@ int map_service(struct rprocpub *rpub)
if (rpub->dev_nr == NO_DEV) return(OK);
/* Map driver. */
r = map_driver(rpub->label, rpub->dev_nr, rpub->endpoint, rpub->dev_style,
rpub->dev_flags);
r = map_driver(rpub->label, rpub->dev_nr, rpub->endpoint);
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);
/* To ensure that future dmap lock attempts always lock the same driver
* regardless of major number, refer the second dmap lock reference
* to the first dmap entry.
*/
fdp = get_dmap_by_major(rpub->dev_nr);
sdp = get_dmap_by_major(rpub->dev_nr+1);
assert(fdp != NULL);
assert(sdp != NULL);
assert(fdp != sdp);
sdp->dmap_lock_ref = &fdp->dmap_lock;
}
return(OK);
}
/*===========================================================================*
* init_dmap *
*===========================================================================*/
void init_dmap()
void init_dmap(void)
{
/* Initialize the table with empty device <-> driver mappings. */
/* Initialize the device mapping table. */
int i;
memset(dmap, 0, sizeof(dmap));
for (i = 0; i < NR_DEVICES; i++) {
dmap[i].dmap_opcl = no_dev;
dmap[i].dmap_io = no_dev_io;
dmap[i].dmap_driver = NONE;
dmap[i].dmap_style = STYLE_NDEV;
dmap[i].dmap_servicing = INVALID_THREAD;
}
}
/*===========================================================================*
* init_dmap_locks *
*===========================================================================*/
void init_dmap_locks()
{
int i;
for (i = 0; i < NR_DEVICES; i++) {
if (mutex_init(&dmap[i].dmap_lock, NULL) != 0)
panic("unable to initialize dmap lock");
dmap[i].dmap_lock_ref = &dmap[i].dmap_lock;
}
/* CTTY_MAJOR is a special case, which is handled by VFS itself. */
if (map_driver("vfs", CTTY_MAJOR, CTTY_ENDPT) != OK)
panic("map_driver(CTTY_MAJOR) failed");
}
/*===========================================================================*

View file

@ -14,18 +14,14 @@
*/
extern struct dmap {
int(*dmap_opcl) (int, dev_t, endpoint_t, int);
int(*dmap_io) (endpoint_t, message *);
endpoint_t dmap_driver;
char dmap_label[LABEL_MAX];
int dmap_flags;
int dmap_style;
int dmap_sel_busy;
struct filp *dmap_sel_filp;
thread_t dmap_servicing;
mutex_t dmap_lock;
mutex_t *dmap_lock_ref;
int dmap_recovering;
int dmap_seen_tty;
} dmap[];
#endif

View file

@ -325,10 +325,21 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info)
mess.m_type = OK; /* tell PM that we succeeded */
s = send(PM_PROC_NR, &mess); /* send synchronization message */
/* All process table entries have been set. Continue with initialization. */
init_dmap(); /* Initialize device table. */
system_hz = sys_hz();
/* Subscribe to block and character driver events. */
s = ds_subscribe("drv\\.[bc]..\\..*", DSF_INITIAL | DSF_OVERWRITE);
if (s != OK) panic("VFS: can't subscribe to driver events (%d)", s);
/* Initialize worker threads */
worker_init();
/* Initialize global locks */
if (mthread_mutex_init(&bsf_lock, NULL) != 0)
panic("VFS: couldn't initialize block special file lock");
init_dmap(); /* Initialize device table. */
/* Map all the services in the boot image. */
if ((s = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0,
(vir_bytes) rprocpub, sizeof(rprocpub))) != OK){
@ -342,17 +353,6 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info)
}
}
/* Subscribe to block and character driver events. */
s = ds_subscribe("drv\\.[bc]..\\..*", DSF_INITIAL | DSF_OVERWRITE);
if (s != OK) panic("VFS: can't subscribe to driver events (%d)", s);
/* Initialize worker threads */
worker_init();
/* Initialize global locks */
if (mthread_mutex_init(&bsf_lock, NULL) != 0)
panic("VFS: couldn't initialize block special file lock");
/* Initialize locks and initial values for all processes. */
for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
if (mutex_init(&rfp->fp_lock, NULL) != 0)
@ -372,7 +372,6 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info)
rfp->fp_wd = NULL;
}
init_dmap_locks(); /* init dmap locks */
init_vnodes(); /* init vnodes */
init_vmnts(); /* init vmnt structures */
init_select(); /* init select() structures */

View file

@ -6,6 +6,7 @@
* do_fcntl: perform the FCNTL system call
* do_sync: perform the SYNC system call
* do_fsync: perform the FSYNC system call
* pm_setsid: perform VFS's side of setsid system call
* pm_reboot: sync disks and prepare for shutdown
* pm_fork: adjust the tables after PM has performed a FORK system call
* do_exec: handle files with FD_CLOEXEC on after PM has done an EXEC
@ -745,6 +746,24 @@ int ruid;
tfp->fp_realuid = ruid;
}
/*===========================================================================*
* pm_setsid *
*===========================================================================*/
void pm_setsid(endpoint_t proc_e)
{
/* Perform the VFS side of the SETSID call, i.e. get rid of the controlling
* terminal of a process, and make the process a session leader.
*/
struct fproc *rfp;
int slot;
/* Make the process a session leader with no controlling tty. */
okendpt(proc_e, &slot);
rfp = &fproc[slot];
rfp->fp_flags |= FP_SESLDR;
rfp->fp_tty = 0;
}
/*===========================================================================*
* do_svrctl *
*===========================================================================*/

View file

@ -49,8 +49,6 @@
#define md_label m2_p1
#define md_label_len m2_l1
#define md_major m2_i1
#define md_style m2_i2
#define md_flags m2_i3
/* The following names are synonyms for the variables in the output message. */
#define reply_type m_type

View file

@ -39,32 +39,18 @@ int bdev_open(dev_t dev, int access);
int bdev_close(dev_t dev);
void bdev_reply(void);
void bdev_up(int major);
int gen_opcl(int op, dev_t dev, endpoint_t task_nr, int flags);
int gen_io(endpoint_t drv_e, message *mess_ptr);
int no_dev(int op, dev_t dev, endpoint_t proc, int flags);
int no_dev_io(endpoint_t, message *);
int tty_opcl(int op, dev_t dev, endpoint_t proc, int flags);
int ctty_opcl(int op, dev_t dev, endpoint_t proc, int flags);
int clone_opcl(int op, dev_t dev, endpoint_t proc, int flags);
int ctty_io(endpoint_t task_nr, message *mess_ptr);
int do_ioctl(message *m_out);
void pm_setsid(endpoint_t proc_e);
/* dmap.c */
void lock_dmap(struct dmap *dp);
void unlock_dmap(struct dmap *dp);
int do_mapdriver(message *m_out);
void init_dmap(void);
void init_dmap_locks(void);
int dmap_driver_match(endpoint_t proc, int major);
void dmap_endpt_up(endpoint_t proc_nr, int is_blk);
void dmap_unmap_by_endpt(endpoint_t proc_nr);
struct dmap *get_dmap(endpoint_t proc_e);
struct dmap *get_dmap_by_major(int major);
int map_service(struct rprocpub *rpub);
void dmap_unmap_by_endpt(endpoint_t proc_nr);
int map_driver(const char *label, int major, endpoint_t proc_nr, int
dev_style, int flags);
int map_service(struct rprocpub *rpub);
/* elf_core_dump.c */
@ -124,6 +110,7 @@ void pm_fork(endpoint_t pproc, endpoint_t cproc, pid_t cpid);
void pm_setgid(endpoint_t proc_e, int egid, int rgid);
void pm_setuid(endpoint_t proc_e, int euid, int ruid);
void pm_setgroups(endpoint_t proc_e, int ngroups, gid_t *addr);
void pm_setsid(endpoint_t proc_e);
int do_sync(message *m_out);
int do_fsync(message *m_out);
void pm_reboot(void);
@ -296,7 +283,7 @@ long conv4(int norm, long x);
int copy_name(size_t len, char *dest);
int fetch_name(vir_bytes path, size_t len, char *dest);
int no_sys(message *);
int isokendpt_f(char *f, int l, endpoint_t e, int *p, int ft);
int isokendpt_f(const char *f, int l, endpoint_t e, int *p, int ft);
int in_group(struct fproc *rfp, gid_t grp);
#define okendpt(e, p) isokendpt_f(__FILE__, __LINE__, (e), (p), 1)

View file

@ -106,7 +106,7 @@ int no_sys(message *UNUSED(m_out))
/*===========================================================================*
* isokendpt_f *
*===========================================================================*/
int isokendpt_f(char *file, int line, endpoint_t endpoint, int *proc,
int isokendpt_f(const char *file, int line, endpoint_t endpoint, int *proc,
int fatal)
{
int failed = 0;