decouple file system server start/termination from mount/umount

This commit is contained in:
Dirk Vogt 2010-11-23 19:34:56 +00:00
parent 41ae712b50
commit 9ed280d1ec
21 changed files with 121 additions and 132 deletions

View file

@ -45,6 +45,7 @@ char *argv[];
type = argv[i];
break;
case 'i': mountflags |= MS_REUSE; break;
case 'e': mountflags |= MS_EXISTING; break;
case 'n': write_mtab = 0; break;
case 'o': if (++i == argc) usage();
args = argv[i];
@ -149,6 +150,6 @@ void list()
void usage()
{
std_err("Usage: mount [-r] [-t type] [-o options] special name\n");
std_err("Usage: mount [-r] [-e] [-t type] [-o options] special name\n");
exit(1);
}

View file

@ -7,6 +7,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <getopt.h>
#include <errno.h>
#include <limits.h>
#include <minix/minlib.h>
@ -28,10 +29,30 @@ int argc;
char *argv[];
{
int found;
int flags = 0UL;
int i;
char c;
char *name;
if (argc != 2) usage();
found = find_mtab_entry(argv[1]);
if (umount(argv[1]) < 0) {
while ((c = getopt (argc, argv, "e")) != -1)
{
switch (c) {
case 'e': flags |= MS_EXISTING; break;
default: break;
}
}
if (argc - optind != 1) {
usage();
}
name = argv[optind];
found = find_mtab_entry(name);
if (umount2(name, flags) < 0) {
if (errno == EINVAL)
std_err("umount: Device not mounted\n");
else if (errno == ENOTBLK)
@ -44,7 +65,7 @@ char *argv[];
printf("%s unmounted from %s\n", device, mountpoint);
update_mtab();
}
else printf("%s unmounted (mtab not updated)\n", argv[1]);
else printf("%s unmounted (mtab not updated)\n", name);
return(0);
}
@ -105,6 +126,6 @@ void update_mtab()
void usage()
{
std_err("Usage: umount name\n");
std_err("Usage: umount [-e] name\n");
exit(1);
}

View file

@ -8,6 +8,7 @@
#define MS_RDONLY 0x001 /* Mount device read only */
#define MS_REUSE 0x002 /* Tell RS to try reusing binary from memory */
#define MS_LABEL16 0x004 /* Mount message points to 16-byte label */
#define MS_EXISTING 0x008 /* Tell mount to use already running server */
/* Function Prototypes. */
@ -18,5 +19,6 @@
_PROTOTYPE( int mount, (char *_spec, char *_name, int _mountflags,
char *type, char *args) );
_PROTOTYPE( int umount, (const char *_name) );
_PROTOTYPE( int umount2, (const char *_name, int flags) );
#endif /* _MOUNT_H */

View file

@ -35,7 +35,8 @@ int mountflags;
char path[60];
char cmd[200];
char *p;
int reuse;
int reuse = 0;
int use_existing = 0;
/* Default values. */
if (type == NULL) type = FSDEFAULT;
@ -47,6 +48,11 @@ int mountflags;
reuse = 1;
mountflags &= ~MS_REUSE; /* Temporary: turn off to not confuse VFS */
}
if(mountflags & MS_EXISTING) {
use_existing = 1;
mountflags &= ~MS_EXISTING; /* Temporary: turn off to not confuse VFS */
}
/* Make a label for the file system process. This label must be unique and
* may currently not exceed 16 characters including terminating null. For
@ -55,17 +61,27 @@ int mountflags;
* hopefully enough). For requests with no associated block device, we use
* the device number and inode of the mount point, in hexadecimal form.
*/
if (special) {
p = strrchr(special, '/');
p = p ? p + 1 : special;
if (strchr(p, '\'')) {
errno = EINVAL;
return -1;
if (!use_existing) {
if (special) {
p = strrchr(special, '/');
p = p ? p + 1 : special;
if (strchr(p, '\'')) {
errno = EINVAL;
return -1;
}
sprintf(label, "fs_%.12s", p);
} else {
if (stat(name, &statbuf) < 0) return -1;
sprintf(label, "fs_%04x%x", statbuf.st_dev, statbuf.st_ino);
}
sprintf(label, "fs_%.12s", p);
} else {
if (stat(name, &statbuf) < 0) return -1;
sprintf(label, "fs_%04x%lx", statbuf.st_dev, statbuf.st_ino);
/* label to long? */
if (strlen(type) < 16) {
sprintf(label, "%s", type);
} else {
errno = ENOMEM;
return -1;
}
}
/* Tell VFS that we are passing in a 16-byte label. */
@ -89,20 +105,22 @@ int mountflags;
errno = EINVAL;
return -1;
}
/* start the fs-server if not using existing one */
if (!use_existing) {
if(strlen(_PATH_SERVICE)+strlen(path)+strlen(label)+
strlen(args)+50 >= sizeof(cmd)) {
errno = E2BIG;
return -1;
}
if(strlen(_PATH_SERVICE)+strlen(path)+strlen(label)+
strlen(args)+50 >= sizeof(cmd)) {
errno = E2BIG;
return -1;
}
sprintf(cmd, _PATH_SERVICE " %sup %s -label '%s' -args '%s%s'",
reuse ? "-r ": "", path, label, args[0] ? "-o " : "", args);
sprintf(cmd, _PATH_SERVICE " %sup %s -label '%s' -args '%s%s'",
reuse ? "-r ": "", path, label, args[0] ? "-o " : "", args);
if((r = system(cmd)) != 0) {
fprintf(stderr, "mount: couldn't run %s\n", cmd);
errno = r;
return -1;
if((r = system(cmd)) != 0) {
fprintf(stderr, "mount: couldn't run %s\n", cmd);
errno = r;
return -1;
}
}
/* Now perform mount(). */
@ -126,18 +144,29 @@ int mountflags;
PUBLIC int umount(name)
_CONST char *name;
{
return umount2(name, 0);
}
PUBLIC int umount2(name, flags)
_CONST char *name;
int flags;
{
message m;
int r;
_loadname(name, &m);
r = _syscall(VFS_PROC_NR, UMOUNT, &m);
if(r == OK) {
/* VFS returns the label of the unmounted file system in the reply.
* As of writing, the size of the m3_ca1 field is 16 bytes.
*/
rs_down(m.m3_ca1);
/* don't shut down the driver when exist flag is set */
if (!(flags & MS_EXISTING)) {
if (r == OK) {
/* VFS returns the label of the unmounted file system in the reply.
* As of writing, the size of the m3_ca1 field is 16 bytes.
*/
rs_down(m.m3_ca1);
}
}
return r;

View file

@ -17,17 +17,10 @@ PRIVATE int init_server(int UNUSED(type), sef_init_info_t *UNUSED(info))
{
/* Initialize internal state, and register with VFS.
*/
int r;
/* Initialize the virtual tree. */
init_inodes(inodes, root_stat, root_entries);
/* Tell VFS that we are here. */
fs_m_out.m_type = FS_READY;
if ((r = send(VFS_PROC_NR, &fs_m_out)) != OK)
panic(__FILE__, "error sending login to VFS", r);
/* Do not yet allow any requests except REQ_READSUPER. */
fs_mounted = FALSE;

View file

@ -8,6 +8,7 @@ mount, umount \- mount or umount a file system
int mount(char *\fIspecial\fP, char *\fIname\fP, int \fImountflags\fP, char *\fItype\fP, char *\fIargs\fP)
int umount(char *\fIname\fP)
int umount2(char *\fIname\fP, int \fIflags)
.fi
.ft P
.SH DESCRIPTION
@ -38,6 +39,11 @@ Mount file system read-only, rather than read-write.
.TP
.B MS_REUSE
Reuse the file system server image if possible.
.TP
.B MS_EXISTING
Do not start the file system server, but use existing one. The label of
the running file server is specified in
.I Type.
.PP
.I Type
is the type of the file system (e.g. "mfs"), used to pick a file system server.
@ -55,7 +61,18 @@ same mount point then unmounting at the mount point removes the last mounted
device, unmounting a device removes precisely that device. The unmount will
only succeed if none of the files on the device are in use.
.PP
Both calls may only be executed by the super-user.
.B Umount2()
Same as Umount(), but takes an additional
.I flags
parameter.
.I Flags
may be a bitwise combination of the following flags:
.TP 2
.B MS_EXISTING
Umount the file system but do not terminate the the file system server.
.PP
.TO
These calls may only be executed by the super-user.
.SH "SEE ALSO"
.BR mount (1),
.BR umount (1).

View file

@ -117,7 +117,7 @@ PRIVATE void sef_local_startup()
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the Minix file server. */
int i, r;
int i;
/* Defaults */
opt.use_orlov = TRUE;
@ -149,12 +149,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
buf_pool(DEFAULT_NR_BUFS);
fs_block_size = _MIN_BLOCK_SIZE;
fs_m_in.m_type = FS_READY;
if ((r = send(VFS_PROC_NR, &fs_m_in)) != OK) {
panic("Error sending login to VFS: %d", r);
}
return(OK);
}

View file

@ -85,7 +85,7 @@ PRIVATE void sef_local_startup()
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the iso9660fs server. */
int i, r;
int i;
/* Init driver mapping */
for (i = 0; i < NR_DEVICES; ++i)
@ -95,12 +95,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
/* hash_init(); */ /* Init the table with the ids */
setenv("TZ","",1); /* Used to calculate the time */
fs_m_in.m_type = FS_READY;
if ((r = send(VFS_PROC_NR, &fs_m_in)) != OK) {
panic("Error sending login to VFS: %d", r);
}
return(OK);
}

View file

@ -97,7 +97,7 @@ PRIVATE void sef_local_startup()
PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
{
/* Initialize the Minix file server. */
int i, r;
int i;
may_use_vmcache = 1;
@ -117,12 +117,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
buf_pool(DEFAULT_NR_BUFS);
fs_block_size = _MIN_BLOCK_SIZE;
fs_m_in.m_type = FS_READY;
if ((r = send(VFS_PROC_NR, &fs_m_in)) != OK) {
panic("Error sending login to VFS: %d", r);
}
return(OK);
}

View file

@ -10,7 +10,7 @@ LDADD+= -lsys
MAN=
BINDIR?= /usr/sbin
INSTALLFLAGS+= -S 1225k
INSTALLFLAGS+= -S 8125k
CPPFLAGS+= -I${MINIXSRCDIR}

View file

@ -68,9 +68,9 @@ vir_bytes *pc;
* complete stack image, including pointers, args, environ, etc. The stack
* is copied to a buffer inside VFS, and then to the new core image.
*/
int r, r1, sep_id, round, proc_s, hdrlen, load_text, allow_setuid;
vir_bytes text_bytes, data_bytes, bss_bytes;
phys_bytes tot_bytes; /* total space for program, including gap */
int r, r1, sep_id=0, round, proc_s, hdrlen=0, load_text, allow_setuid;
vir_bytes text_bytes=0, data_bytes=0, bss_bytes=0;
phys_bytes tot_bytes=0; /* total space for program, including gap */
vir_bytes stack_top, vsp;
off_t off;
uid_t new_uid;

View file

@ -268,7 +268,6 @@ PUBLIC int cancel_fd(ep, fd)
endpoint_t ep;
int fd;
{
int j;
int proc;
if (isokendpt(ep, &proc) != OK) {

View file

@ -31,6 +31,7 @@
#include <limits.h>
#include <errno.h>
#include <unistd.h>
#include <minix/syslib.h>
#include <minix/sysutil.h>

View file

@ -3,6 +3,7 @@
#include "file.h"
#include "fproc.h"
_PROTOTYPE( int gcov_flush, (cp_grant_id_t grantid, size_t size ));
/*===========================================================================*
* do_gcov_flush *
@ -15,7 +16,6 @@ PUBLIC int do_gcov_flush()
* makes the target copy its buffer to the caller (incl vfs
* itself).
*/
int i;
struct fproc *rfp;
ssize_t size;
cp_grant_id_t grantid;

View file

@ -13,8 +13,6 @@ EXTERN int reviving; /* number of pipe processes to be revived */
EXTERN dev_t root_dev; /* device number of the root device */
EXTERN int ROOT_FS_E; /* kernel endpoint of the root FS proc */
EXTERN int last_login_fs_e; /* endpoint of the FS proc that logged in
before the corresponding mount request */
EXTERN u32_t system_hz; /* system clock frequency. */
/* The parameters of the call are kept here. */

View file

@ -30,7 +30,7 @@ PUBLIC int do_link()
{
/* Perform the link(name1, name2) system call. */
int r = OK;
struct vnode *vp, *vp_d;
struct vnode *vp = NULL, *vp_d = NULL;
/* See if 'name1' (file to be linked to) exists. */
if(fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
@ -124,7 +124,7 @@ PUBLIC int do_rename()
{
/* Perform the rename(name1, name2) system call. */
int r = OK, r1;
struct vnode *old_dirp, *new_dirp, *vp;
struct vnode *old_dirp, *new_dirp = NULL, *vp;
char old_name[PATH_MAX+1];
/* See if 'name1' (existing file) exists. Get dir and file inodes. */

View file

@ -224,7 +224,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info)
struct rprocpub rprocpub[NR_BOOT_PROCS];
/* Clear endpoint field */
last_login_fs_e = NONE;
mount_m_in.m1_p3 = (char *) NONE;
/* Initialize the process table with help of the process manager messages.
@ -448,22 +447,6 @@ PRIVATE void init_root()
root_dev = DEV_IMGRD;
ROOT_FS_E = MFS_PROC_NR;
/* Wait FS login message */
if (last_login_fs_e != ROOT_FS_E) {
/* Wait FS login message */
if (sef_receive(ROOT_FS_E, &m) != OK) {
printf("VFS: Error receiving login request from FS_e %d\n",
ROOT_FS_E);
panic("Error receiving login request from root filesystem: %d", ROOT_FS_E);
}
if (m.m_type != FS_READY) {
printf("VFS: Invalid login request from FS_e %d\n",
ROOT_FS_E);
panic("Error receiving login request from root filesystem: %d", ROOT_FS_E);
}
}
last_login_fs_e = NONE;
/* Initialize vmnt table */
for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp)
vmp->m_dev = NO_DEV;

View file

@ -62,7 +62,6 @@ FORWARD _PROTOTYPE( int write_seg, (struct inode *rip, off_t off, int proc_e,
*===========================================================================*/
PUBLIC int do_getsysinfo()
{
struct fproc *proc_addr;
vir_bytes src_addr, dst_addr;
size_t len;
int s;

View file

@ -48,31 +48,8 @@ FORWARD _PROTOTYPE( dev_t find_free_nonedev, (void) );
*===========================================================================*/
PUBLIC int do_fslogin()
{
int r;
/* Login before mount request */
if (mount_fs_e != who_e) {
last_login_fs_e = who_e;
r = SUSPEND;
}
/* Login after a suspended mount */
else {
/* Copy back original mount request message */
m_in = mount_m_in;
/* Set up last login FS */
last_login_fs_e = who_e;
/* Set up endpoint and call nr */
who_e = m_in.m_source;
who_p = _ENDPOINT_P(who_e);
call_nr = m_in.m_type;
fp = &fproc[who_p]; /* pointer to proc table struct */
super_user = (fp->fp_effuid == SU_UID ? TRUE : FALSE); /* su? */
r = mount_fs(mount_fs_e);
}
return(r);
/* deprecated */
return(SUSPEND);
}
@ -136,19 +113,6 @@ PRIVATE int mount_fs(endpoint_t fs_e)
/* Only the super-user may do MOUNT. */
if (!super_user) return(EPERM);
/* If FS not yet logged in, save message and suspend mount */
if (last_login_fs_e != fs_e) {
mount_m_in = m_in;
mount_fs_e = fs_e;
/* mount_label is already saved */
return(SUSPEND);
}
/* Mount request got after FS login or FS login arrived after a suspended
* mount.
*/
last_login_fs_e = NONE;
/* Clear endpoint field */
mount_fs_e = NONE;

View file

@ -46,7 +46,7 @@ struct fproc *rfp;
int r;
struct vnode *new_vp, *vp;
struct vmnt *vmp;
struct node_details res;
struct node_details res = {0,0,0,0,0,0,0};
assert(dirp);

View file

@ -387,7 +387,7 @@ PUBLIC int req_lookup(
{
int r;
size_t len;
cp_grant_id_t grant_id, grant_id2;
cp_grant_id_t grant_id=0, grant_id2=0;
message m;
vfs_ucred_t credentials;
@ -1061,8 +1061,8 @@ PRIVATE int fs_sendrec_f(char *file, int line, endpoint_t fs_e, message *reqm)
* It also handles driver recovery mechanism and reissuing the
* request which failed due to a dead driver.
*/
int r, old_driver_e;
message origm, m;
int r;
message origm;
if(fs_e <= 0 || fs_e == NONE)
panic("talking to bogus endpoint: %d", fs_e);