vfs/mount/rs/service changes:

. changed umount() and mount() to call 'service', so that it can include
   a custom label, so that umount() works again (RS slot gets freed now).
   merged umount() and mount() into one file to encode keep this label
   knowledge in one file.
 . removed obsolete RS_PID field and RS_RESCUE rescue command
 . added label to RS_START struct
 . vfs no longer does kill of fs process on unmount (which was failing
   due to RS_PID request not working)
 . don't assume that if error wasn't one of three errors, that no error
   occured in vfs/request.c
mfs changes:
 . added checks to copy statements to truncate copies at buffer sizes
   (left in debug code for now)
 . added checks for null-terminatedness, if less than NAME_MAX was copied
 . added checks for copy function success
is changes: 
 . dump rs label
drivers.conf changes:
 . added acl for mfs so that mfs can be started with 'service start',
   so that a custom label can be provided
This commit is contained in:
Ben Gras 2007-01-22 15:25:41 +00:00
parent d954a122f7
commit 2194bc0310
23 changed files with 300 additions and 222 deletions

View file

@ -31,3 +31,6 @@
in /etc/make.conf, included by some Makefiles and sourced by
some shell scripts. To install it, type 'make install' in
src/etc, or simply copy the file over.
20070118:
drivers.conf has been updated to include an ACL for mfs. it has
to be installed before rebooting after an update of the mount command.

View file

@ -142,3 +142,16 @@ driver at_wini
1/1 # Mass storage / IDE
;
};
driver mfs
{
system
EXIT # 2
VIRCOPY # 15
TIMES # 25
SAFECOPYFROM # 31
SAFECOPYTO # 32
SETGRANT # 34
;
uid 0;
};

View file

@ -555,7 +555,6 @@
#define RS_DOWN (RS_RQ_BASE + 1) /* stop system service */
#define RS_REFRESH (RS_RQ_BASE + 2) /* refresh system service */
#define RS_RESTART (RS_RQ_BASE + 3) /* restart system service */
#define RS_RESCUE (RS_RQ_BASE + 4) /* set rescue directory */
#define RS_SHUTDOWN (RS_RQ_BASE + 5) /* alert about shutdown */
#define RS_UP_COPY (RS_RQ_BASE + 6) /* start system service and
* keep the binary in memory
@ -567,7 +566,6 @@
# define RS_CMD_ADDR m1_p1 /* command string */
# define RS_CMD_LEN m1_i1 /* length of command */
# define RS_PID m1_i1 /* pid of system service */
# define RS_PERIOD m1_i2 /* heartbeat period */
# define RS_DEV_MAJOR m1_i3 /* major device number */

View file

@ -17,5 +17,7 @@
#define _PATH_TMP "/tmp"
#define _PATH_BSHELL "/bin/sh"
#define _PATH_SERVICE "/bin/service"
#define _PATH_DRIVERS_CONF "/etc/drivers.conf"
#endif

View file

@ -31,6 +31,8 @@ struct rs_start
int rss_nr_pci_class;
struct { u32_t class; u32_t mask; } rss_pci_class[RSS_NR_PCI_CLASS];
u32_t rss_system[RSS_NR_SYSTEM];
char *rss_label;
size_t rss_labellen;
};
#define RF_COPY 0x01 /* Copy the brinary into RS to make it possible
@ -51,3 +53,4 @@ struct rs_pci
int rsp_nr_class;
struct { u32_t class; u32_t mask; } rsp_class[RSP_NR_CLASS];
};

View file

@ -92,7 +92,6 @@ libc_FILES=" \
_times.c \
_truncate.c \
_umask.c \
_umount.c \
_uname.c \
_unlink.c \
_utime.c \

View file

@ -1,49 +1,123 @@
#include <lib.h>
#define mount _mount
#define umount _umount
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <minix/syslib.h>
#include <minix/rs.h>
#include <minix/paths.h>
#define OK 0
#define MFSNAME "mfs"
#define MFSPATH "/sbin/"
PRIVATE int rs_down(char *label)
{
char cmd[200];
message m;
if(strlen(_PATH_SERVICE)+strlen(label)+50 >= sizeof(cmd))
return -1;
sprintf(cmd, _PATH_SERVICE " down %s", label);
return system(cmd);
}
PRIVATE char *makelabel(_CONST char *special)
{
static char label[40];
_CONST char *dev;
/* Make label name. */
dev = strrchr(special, '/');
if(dev) dev++;
else dev = special;
if(strlen(dev)+strlen(MFSNAME)+3 >= sizeof(label))
return NULL;
sprintf(label, MFSNAME "_%s", dev);
return label;
}
PUBLIC int mount(special, name, rwflag)
char *name, *special;
int rwflag;
{
int r;
struct stat stat_buf;
message m;
m.RS_CMD_ADDR = "/sbin/mfs";
if (stat(m.RS_CMD_ADDR, &stat_buf) == -1) {
/* /sbin/mfs does not exist, try /bin/mfs as well */
m.RS_CMD_ADDR = "/bin/mfs";
if (stat(m.RS_CMD_ADDR, &stat_buf) == -1) {
/* /bin/mfs does not exist either, give up */
return -1;
}
}
if (m.RS_CMD_ADDR) {
m.RS_CMD_LEN = strlen(m.RS_CMD_ADDR);
m.RS_DEV_MAJOR = 0;
m.RS_PERIOD = 0;
r= _taskcall(RS_PROC_NR, RS_UP, &m);
if (r != OK) {
errno= -r;
return -1;
}
/* copy endpointnumber */
m.m1_p3 = (char*)(unsigned long)m.RS_ENDPOINT;
struct rs_start rs_start;
char *label;
char cmd[200];
FILE *pipe;
int ep;
/* Make MFS process label for RS from special name. */
if(!(label=makelabel(special))) {
errno = E2BIG;
return -1;
}
if(strlen(_PATH_SERVICE)+strlen(MFSPATH)+strlen(MFSNAME)+
strlen(label)+50 >= sizeof(cmd)) {
errno = E2BIG;
return -1;
}
sprintf(cmd, _PATH_SERVICE " up " MFSPATH MFSNAME
" -label \"%s\" -config " _PATH_DRIVERS_CONF " -printep yes",
label);
if(!(pipe = popen(cmd, "r"))) {
fprintf(stderr, "mount: couldn't run %s\n", cmd);
return -1;
}
if(fscanf(pipe, "%d", &ep) != 1 || ep <= 0) {
fprintf(stderr, "mount: couldn't parse endpoint from %s\n", cmd);
errno = EINVAL;
pclose(pipe);
return -1;
}
pclose(pipe);
/* Now perform mount(). */
m.m1_i1 = strlen(special) + 1;
m.m1_i2 = strlen(name) + 1;
m.m1_i3 = rwflag;
m.m1_p1 = special;
m.m1_p2 = name;
return(_syscall(FS, MOUNT, &m));
m.m1_p3 = (char*) ep;
r = _syscall(FS, MOUNT, &m);
if(r != OK) {
/* If mount() failed, tell RS to shutdown MFS process.
* No error check - won't do anything with this error anyway.
*/
rs_down(label);
}
return r;
}
PUBLIC int umount(name)
_CONST char *name;
{
message m;
char *label;
int r;
/* Make MFS process label for RS from special name. */
if(!(label=makelabel(name))) {
errno = E2BIG;
return -1;
}
_loadname(name, &m);
r = _syscall(FS, UMOUNT, &m);
if(r == OK) {
rs_down(label);
}
return r;
}

View file

@ -1,12 +0,0 @@
#include <lib.h>
#define umount _umount
#include <unistd.h>
PUBLIC int umount(name)
_CONST char *name;
{
message m;
_loadname(name, &m);
return(_syscall(FS, UMOUNT, &m));
}

View file

@ -28,20 +28,20 @@ PUBLIC void rproc_dmp()
getsysinfo(RS_PROC_NR, SI_PROC_TAB, rproc);
printf("Reincarnation Server (RS) system process table dump\n");
printf("-----proc---pid-flag--dev- -T---checked----alive-starts-backoff-command (argc)-\n");
printf("-----proc---pid-flag--dev- -T---checked----alive-starts-backoff-label command-\n");
for (i=prev_i; i<NR_SYS_PROCS; i++) {
rp = &rproc[i];
if (! rp->r_flags & RS_IN_USE) continue;
if (++n > 22) break;
printf("%9d %5d %s %3d/%2d %3u %8u %8u %4dx %3d %s (%d)",
rp->r_proc_nr_e, rp->r_pid,
printf("%9d %s %3d/%2d %3u %8u %8u %4dx %3d %s %s",
rp->r_proc_nr_e,
s_flags_str(rp->r_flags),
rp->r_dev_nr, rp->r_dev_style,
rp->r_period,
rp->r_check_tm, rp->r_alive_tm,
rp->r_restarts, rp->r_backoff,
rp->r_cmd,
rp->r_argc
rp->r_label,
rp->r_cmd
);
printf("\n");
}

View file

@ -108,3 +108,4 @@
#define V2_INODES_PER_BLOCK(b) ((b)/V2_INODE_SIZE)/* # V2 dsk inodes/blk */
#define MFS_MIN(a,b) mfs_min_f(__FILE__,__LINE__,(a), (b))
#define MFS_NUL(str,l,m) mfs_nul_f(__FILE__,__LINE__,(str), (l), (m))

View file

@ -38,14 +38,17 @@ PUBLIC int fs_link()
register int r;
char string[NAME_MAX];
struct inode *new_ip;
phys_bytes len;
caller_uid = fs_m_in.REQ_UID;
caller_gid = fs_m_in.REQ_GID;
len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string));
/* Copy the link name's last component */
r = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH,
SELF, (vir_bytes) string,
(phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string)));
SELF, (vir_bytes) string, (phys_bytes) len);
if (r != OK) return r;
MFS_NUL(string, len, sizeof(string));
/* Temporarily open the file. */
if ( (rip = get_inode(fs_dev, fs_m_in.REQ_LINKED_FILE)) == NIL_INODE) {
@ -117,16 +120,17 @@ PUBLIC int fs_unlink()
struct inode *rldirp;
int r;
char string[NAME_MAX];
phys_bytes len;
caller_uid = fs_m_in.REQ_UID;
caller_gid = fs_m_in.REQ_GID;
/* Copy the last component */
len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string));
r = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH,
SELF, (vir_bytes) string,
(phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string)));
SELF, (vir_bytes) string, (phys_bytes) len);
if (r != OK) return r;
MFS_NUL(string, len, sizeof(string));
/* Temporarily open the dir. */
if ( (rldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NIL_INODE) {
@ -297,22 +301,25 @@ PUBLIC int fs_rename()
int same_pdir; /* TRUE iff parent dirs are the same */
char old_name[NAME_MAX], new_name[NAME_MAX];
ino_t numb;
phys_bytes len;
int r1;
caller_uid = fs_m_in.REQ_UID;
caller_gid = fs_m_in.REQ_GID;
/* Copy the last component of the old name */
len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(old_name));
r = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH,
SELF, (vir_bytes) old_name,
(phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(old_name)));
SELF, (vir_bytes) old_name, (phys_bytes) len);
if (r != OK) return r;
MFS_NUL(old_name, len, sizeof(old_name));
/* Copy the last component of the new name */
len = MFS_MIN(fs_m_in.REQ_SLENGTH, sizeof(new_name));
r = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_USER_ADDR,
SELF, (vir_bytes) new_name,
(phys_bytes) fs_m_in.REQ_SLENGTH);
SELF, (vir_bytes) new_name, (phys_bytes) len);
if (r != OK) return r;
MFS_NUL(new_name, len, sizeof(new_name));
/* Get old dir inode */
if ( (old_dirp = get_inode(fs_dev, fs_m_in.REQ_OLD_DIR)) == NIL_INODE)

View file

@ -185,7 +185,6 @@ PUBLIC int fs_unmount()
sp->s_dev = NO_DEV;
printf("MFS(%d) DEV %d unmounted\n", SELF_E, fs_dev);
return OK;
}

View file

@ -48,13 +48,13 @@ PUBLIC int fs_open()
/* If O_CREATE is set, try to make the file. */
if (oflags & O_CREAT) {
phys_bytes len;
/* Copy the last component */
len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(lastc));
err_code = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH,
SELF, (vir_bytes) lastc,
(phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN,
sizeof(lastc)));
SELF, (vir_bytes) lastc, (phys_bytes) len);
if (err_code != OK) return err_code;
MFS_NUL(lastc, len, sizeof(lastc));
/* Get last directory inode */
if ((ldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NIL_INODE) {
@ -150,6 +150,7 @@ printf("MFS(%d) get_inode by open() failed\n", SELF_E);
*===========================================================================*/
PUBLIC int fs_create()
{
phys_bytes len;
int r, b;
struct inode *ldirp;
struct inode *rip;
@ -165,10 +166,11 @@ PUBLIC int fs_create()
/* Try to make the file. */
/* Copy the last component */
len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(lastc));
err_code = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH,
SELF, (vir_bytes) lastc, (phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(lastc)));
SELF, (vir_bytes) lastc, (phys_bytes) len);
if (err_code != OK) return err_code;
MFS_NUL(lastc, len, sizeof(lastc));
/* Get last directory inode */
if ((ldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NIL_INODE) {
@ -212,13 +214,14 @@ PUBLIC int fs_mknod()
{
struct inode *ip, *ldirp;
char lastc[NAME_MAX];
phys_bytes len;
/* Copy the last component and set up caller's user and group id */
len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(lastc));
err_code = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH, SELF,
(vir_bytes) lastc,
(phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(lastc)));
(vir_bytes) lastc, (phys_bytes) len);
if (err_code != OK) return err_code;
MFS_NUL(lastc, len, sizeof(lastc));
caller_uid = fs_m_in.REQ_UID;
caller_gid = fs_m_in.REQ_GID;
@ -247,13 +250,14 @@ PUBLIC int fs_mkdir()
ino_t dot, dotdot; /* inode numbers for . and .. */
struct inode *rip, *ldirp;
char lastc[NAME_MAX]; /* last component */
phys_bytes len;
/* Copy the last component and set up caller's user and group id */
len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(lastc));
err_code = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH, SELF,
(vir_bytes) lastc, (phys_bytes)
MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(lastc)));
(vir_bytes) lastc, (phys_bytes) len);
if (err_code != OK) return err_code;
MFS_NUL(lastc, len, sizeof(lastc));
caller_uid = fs_m_in.REQ_UID;
caller_gid = fs_m_in.REQ_GID;
@ -309,6 +313,7 @@ printf("MFS(%d) get_inode for parent dir by mkdir() failed\n", SELF_E);
*===========================================================================*/
PUBLIC int fs_slink()
{
phys_bytes len;
struct inode *sip; /* inode containing symbolic link */
struct inode *ldirp; /* directory containing link */
register int r; /* error code */
@ -324,11 +329,11 @@ PUBLIC int fs_slink()
}
/* Copy the link name's last component */
len = MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string));
r = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH,
SELF, (vir_bytes) string,
(phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string)));
SELF, (vir_bytes) string, (phys_bytes) len);
if (r != OK) return r;
MFS_NUL(string, len, sizeof(string));
/* Create the inode for the symlink. */
sip = new_node(ldirp, string, (mode_t) (I_SYMBOLIC_LINK | RWX_MODES),

View file

@ -26,7 +26,7 @@ PUBLIC char dot2[3] = ".."; /* permissions for . and .. */
FORWARD _PROTOTYPE( char *get_name, (char *old_name, char string [NAME_MAX]) );
FORWARD _PROTOTYPE( int ltraverse, (struct inode *rip, char *path,
char *suffix) );
char *suffix, int pathlen) );
/*===========================================================================*
@ -37,15 +37,26 @@ PUBLIC int lookup()
char string[PATH_MAX];
struct inode *rip;
int s_error, flags;
int len;
string[0] = '\0';
/* Check length. */
len = fs_m_in.REQ_PATH_LEN;
if(len > sizeof(string)) return E2BIG; /* too big for buffer */
if(len < 1) return EINVAL; /* too small for \0 */
/* Copy the pathname and set up caller's user and group id */
err_code = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH, SELF,
(vir_bytes) user_path,
(phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string)));
(vir_bytes) user_path, (phys_bytes) len);
if (err_code != OK) {
printf("mfs:%s:%d: sys_datacopy failed: %d\n", __FILE__, __LINE__, err_code);
return err_code;
}
if (err_code != OK) return err_code;
/* Verify this is a null-terminated path. */
if(user_path[len-1] != '\0')
return EINVAL;
caller_uid = fs_m_in.REQ_UID;
caller_gid = fs_m_in.REQ_GID;
@ -60,9 +71,12 @@ PUBLIC int lookup()
/* Copy back the last name if it is required */
if (err_code != OK || (flags & PATH_PENULTIMATE)) {
s_error = sys_datacopy(SELF_E, (vir_bytes) string, FS_PROC_NR,
(vir_bytes) fs_m_in.REQ_USER_ADDR, (phys_bytes)
MFS_MIN(strlen(string)+1, NAME_MAX));
if (s_error != OK) return s_error;
(vir_bytes) fs_m_in.REQ_USER_ADDR, (phys_bytes) NAME_MAX);
if (s_error != OK) {
printf("mfs:%s:%d: sys_datacopy failed: %d\n",
__FILE__, __LINE__, s_error);
return s_error;
}
}
/* Error or mount point encountered */
@ -234,7 +248,8 @@ printf("%s, %d\n", __FILE__, __LINE__);
if (*new_name != '\0') new_name--;
/* Extract path name from the symlink file */
if (ltraverse(rip, user_path, new_name) != OK) {
if (ltraverse(rip, user_path, new_name,
sizeof(user_path)) != OK) {
put_inode(dir_ip);
err_code = ENOENT;
printf("%s, %d\n", __FILE__, __LINE__);
@ -290,10 +305,11 @@ printf("%s, %d\n", __FILE__, __LINE__);
/*===========================================================================*
* ltraverse *
*===========================================================================*/
PRIVATE int ltraverse(rip, path, suffix)
PRIVATE int ltraverse(rip, path, suffix, pathlen)
register struct inode *rip; /* symbolic link */
char *path; /* path containing link */
char *suffix; /* suffix following link within path */
int pathlen;
{
/* Traverse a symbolic link. Copy the link text from the inode and insert
* the text into the path. Return error code or report success. Base
@ -318,18 +334,25 @@ char *suffix; /* suffix following link within path */
/* Insert symbolic text into path name. */
tl = strlen(suffix);
if (sl > 0 && sl + tl <= PATH_MAX-1) {
if(sl+tl >= pathlen)
panic(__FILE__,"path too small for symlink", sl+tl);
memmove(path+sl, suffix, tl);
memmove(path, sp, sl);
path[sl+tl] = 0;
/* Copy back to VFS layer THIS SHOULD BE IN parse_path */
/* Copy back to VFS layer THIS SHOULD BE IN parse_path.
* sys_datacopy() error, if any, gets returned as r later.
*/
r = sys_datacopy(SELF_E, (vir_bytes) path, FS_PROC_NR,
(vir_bytes) vfs_slink_storage, (phys_bytes) sl+tl+1);
/*
dup_inode(bip = path[0] == '/' ? chroot_dir : ldip);
*/
}
if(r != OK) {
printf("mfs:%s:%d: sys_datacopy failed: %d\n",
__FILE__, __LINE__, r);
}
} else panic(__FILE__,"didn't copy symlink", sl+tl);
}
else {
r = ENOENT;

View file

@ -182,6 +182,8 @@ _PROTOTYPE( int fetch_name, (char *path, int len, int flag) );
_PROTOTYPE( int no_sys, (void) );
_PROTOTYPE( int isokendpt_f, (char *f, int l, int e, int *p, int ft));
_PROTOTYPE( void panic, (char *who, char *mess, int num) );
_PROTOTYPE( void mfs_nul_f, (char *file, int line, char *str, int len, int maxlen));
_PROTOTYPE( int mfs_min_f, (char *file, int line, int len1, int len2) );
#define okendpt(e, p) isokendpt_f(__FILE__, __LINE__, (e), (p), 1)
#define isokendpt(e, p) isokendpt_f(__FILE__, __LINE__, (e), (p), 0)

View file

@ -92,8 +92,26 @@ PUBLIC time_t clock_time()
int mfs_min_f(char *file, int line, int v1, int v2)
{
if(v1 < 0 || v2 < 0) {
printf("mfs:%s:%d: strange string lengths: %d, %d\n",
file, line, v1, v2);
panic(file, "strange string lengths", NO_NUM);
}
if(v2 >= v1) return v1;
printf("mfs:%s:%d: truncated %d to %d\n",
file, line, v1, v2);
return v2;
}
void mfs_nul_f(char *file, int line, char *str, int len, int maxlen)
{
if(len < 1) {
printf("mfs:%s:%d: %d-length string?!\n", file, line, len);
panic(file, "strange string length", NO_NUM);
}
if(len < maxlen && str[len-1] != '\0') {
printf("mfs:%s:%d: string (length %d, maxlen %d) "
"not null-terminated\n",
file, line, len, maxlen);
}
}

View file

@ -16,8 +16,7 @@ CC = exec cc
CPPFLAGS = -I../../kernel/arch/$(ARCH)/include
CFLAGS = -I$i $(CPROFILE) $(CPPFLAGS)
LDFLAGS = -i
UTIL_LIBS = -lsysutil -lsys
LIBS = -lsysutil -lsys
LIBS = -lsys -lsysutil
UTIL_OBJ = service.o
OBJ = exec.o main.o manager.o

View file

@ -86,7 +86,6 @@ PUBLIC int main(void)
case RS_START: result = do_start(&m); break;
case RS_DOWN: result = do_down(&m); break;
case RS_REFRESH: result = do_refresh(&m); break;
case RS_RESCUE: result = do_rescue(&m); break;
case RS_RESTART: result = do_restart(&m); break;
case RS_SHUTDOWN: result = do_shutdown(&m); break;
case GETSYSINFO: result = do_getsysinfo(&m); break;

View file

@ -106,7 +106,7 @@ int flags; /* extra flags, if any */
len= MAX_LABEL_LEN-1; /* truncate name */
memcpy(rp->r_label, label, len);
rp->r_label[len]= '\0';
printf("using label '%s'\n", rp->r_label);
printf("RS: do_up: using label '%s'\n", rp->r_label);
rp->r_uid= 0;
rp->r_nice= 0;
@ -197,18 +197,31 @@ message *m_ptr; /* request message pointer */
rp->r_argv[arg_count] = NULL; /* end with NULL pointer */
rp->r_argc = arg_count;
/* Default label for the driver */
label= strrchr(rp->r_argv[0], '/');
if (label)
label++;
else
label= rp->r_argv[0];
len= strlen(label);
if (len > MAX_LABEL_LEN-1)
len= MAX_LABEL_LEN-1; /* truncate name */
memcpy(rp->r_label, label, len);
rp->r_label[len]= '\0';
printf("using label '%s'\n", rp->r_label);
if(rs_start.rss_label) {
int len;
/* RS_START caller has supplied a custom label for this driver. */
len = MIN(sizeof(rp->r_label)-1, rs_start.rss_labellen);
s=sys_datacopy(m_ptr->m_source, (vir_bytes) rs_start.rss_label,
SELF, (vir_bytes) rp->r_label, len);
if(s != OK)
return s;
rp->r_label[len] = '\0';
printf("RS: do_start: using label (custom) '%s'\n", rp->r_label);
} else {
/* Default label for the driver. */
label= strrchr(rp->r_argv[0], '/');
if (label)
label++;
else
label= rp->r_argv[0];
len= strlen(label);
if (len > MAX_LABEL_LEN-1)
len= MAX_LABEL_LEN-1; /* truncate name */
memcpy(rp->r_label, label, len);
rp->r_label[len]= '\0';
printf("RS: do_start: using label (from binary %s) '%s'\n",
rp->r_argv[0], rp->r_label);
}
/* Check for duplicates */
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
@ -455,31 +468,6 @@ PUBLIC int do_refresh(message *m_ptr)
return(ESRCH);
}
/*===========================================================================*
* do_rescue *
*===========================================================================*/
PUBLIC int do_rescue(message *m_ptr)
{
char rescue_dir[MAX_RESCUE_DIR_LEN];
int s;
/* Copy rescue directory from user. */
if (m_ptr->RS_CMD_LEN > MAX_RESCUE_DIR_LEN) return(E2BIG);
if (OK!=(s=sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->RS_CMD_ADDR,
SELF, (vir_bytes) rescue_dir, m_ptr->RS_CMD_LEN))) return(s);
rescue_dir[m_ptr->RS_CMD_LEN] = '\0'; /* ensure it is terminated */
if (rescue_dir[0] != '/') return(EINVAL); /* insist on absolute path */
/* Change RS' directory to the rescue directory. Provided that the needed
* binaries are in the rescue dir, this makes recovery possible even if the
* (root) file system is no longer available, because no directory lookups
* are required. Thus if an absolute path fails, we can try to strip the
* path an see if the command is in the rescue dir.
*/
if (chdir(rescue_dir) != 0) return(errno);
return(OK);
}
/*===========================================================================*
* do_shutdown *
*===========================================================================*/

View file

@ -6,6 +6,7 @@
*/
#include <stdarg.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -30,7 +31,7 @@ PRIVATE char *known_requests[] = {
"down",
"refresh",
"restart",
"rescue",
"-unused",
"shutdown",
"upcopy", /* fill for RS_UP_COPY */
"catch for illegal requests"
@ -63,9 +64,11 @@ PRIVATE char *known_requests[] = {
#define ARG_SCRIPT "-script" /* name of the script to restart a
* driver
*/
#define ARG_LABELNAME "-label" /* custom label name */
#define ARG_CONFIG "-config" /* name of the file with the resource
* configuration
*/
#define ARG_PRINTEP "-printep" /* print endpoint number after start */
#define DRIVER_LOGIN "driver" /* Passwd file entry for drivers */
@ -83,7 +86,9 @@ PRIVATE char *req_args;
PRIVATE int req_major;
PRIVATE long req_period;
PRIVATE char *req_script;
PRIVATE char *req_label;
PRIVATE char *req_config;
PRIVATE int req_printep;
PRIVATE int class_recurs; /* Nesting level of class statements */
/* Buffer to build "/command arg1 arg2 ..." string to pass to RS server. */
@ -199,6 +204,7 @@ PRIVATE int parse_arguments(int argc, char **argv)
print_usage(argv[ARG_NAME], "binary should be absolute path");
exit(EINVAL);
}
if (stat(req_path, &stat_buf) == -1) {
perror(req_path);
fprintf(stderr, "couldn't get stat binary\n");
@ -242,10 +248,17 @@ PRIVATE int parse_arguments(int argc, char **argv)
req_script = argv[i+1];
req_nr = RS_START;
}
else if (strcmp(argv[i], ARG_LABELNAME)==0) {
req_label = argv[i+1];
req_nr = RS_START;
}
else if (strcmp(argv[i], ARG_CONFIG)==0) {
req_config = argv[i+1];
req_nr = RS_START;
}
else if (strcmp(argv[i], ARG_PRINTEP)==0) {
req_printep = 1;
}
else {
print_usage(argv[ARG_NAME], "unknown optional argument given");
exit(EINVAL);
@ -261,27 +274,6 @@ PRIVATE int parse_arguments(int argc, char **argv)
}
req_label= argv[optind+ARG_LABEL];
}
else if (req_nr == RS_RESCUE) {
/* Verify argument count. */
if (argc - 1 < optind+ARG_PATH) {
print_usage(argv[ARG_NAME], "action requires rescue directory");
exit(EINVAL);
}
req_path = argv[optind+ARG_PATH];
if (req_path[0] != '/') {
print_usage(argv[ARG_NAME], "rescue dir should be absolute path");
exit(EINVAL);
}
if (stat(argv[optind+ARG_PATH], &stat_buf) == -1) {
print_usage(argv[ARG_NAME], "couldn't get status of directory");
exit(errno);
}
if ( ! (stat_buf.st_mode & S_IFDIR)) {
print_usage(argv[ARG_NAME], "file is not a directory");
exit(EINVAL);
}
}
else if (req_nr == RS_SHUTDOWN) {
/* no extra arguments required */
}
@ -658,6 +650,7 @@ struct
int call_nr;
} system_tab[]=
{
{ "EXIT", SYS_EXIT },
{ "PRIVCTL", SYS_PRIVCTL },
{ "TRACE", SYS_TRACE },
{ "KILL", SYS_KILL },
@ -871,7 +864,7 @@ PUBLIC int main(int argc, char **argv)
int result;
int request;
int i, s;
char *label;
char *label, *progname = NULL;
struct passwd *pw;
/* Verify and parse the command line arguments. All arguments are checked
@ -881,6 +874,13 @@ PUBLIC int main(int argc, char **argv)
*/
request = parse_arguments(argc, argv);
if(req_path) {
/* Obtain binary name. */
progname = strrchr(req_path, '/');
assert(progname); /* an absolute path was required */
progname++; /* skip last slash */
}
/* Arguments seem fine. Try to perform the request. Only valid requests
* should end up here. The default is used for not yet supported requests.
*/
@ -912,6 +912,13 @@ PUBLIC int main(int argc, char **argv)
rs_start.rss_major= req_major;
rs_start.rss_period= req_period;
rs_start.rss_script= req_script;
if(req_label) {
rs_start.rss_label = req_label;
rs_start.rss_labellen = strlen(req_label);
} else {
rs_start.rss_label = progname;
rs_start.rss_labellen = strlen(progname);
}
if (req_script)
rs_start.rss_scriptlen= strlen(req_script);
else
@ -925,14 +932,18 @@ PUBLIC int main(int argc, char **argv)
/* The name of the driver */
(label= strrchr(req_path, '/')) ? label++ : (label= req_path);
if (req_config)
do_config(label, req_config);
if (req_config) {
assert(progname);
do_config(progname, req_config);
}
m.RS_CMD_ADDR = (char *) &rs_start;
/* Build request message and send the request. */
if (OK != (s=_taskcall(RS_PROC_NR, request, &m)))
failure(-s);
else if(req_printep)
printf("%d\n", m.RS_ENDPOINT);
result = m.m_type;
break;
@ -941,13 +952,6 @@ PUBLIC int main(int argc, char **argv)
case RS_RESTART:
m.RS_CMD_ADDR = req_label;
m.RS_CMD_LEN = strlen(req_label);
printf("RS_CMD_LEN = %d\n", m.RS_CMD_LEN);
if (OK != (s=_taskcall(RS_PROC_NR, request, &m)))
failure(-s);
break;
case RS_RESCUE:
m.RS_CMD_ADDR = req_path;
m.RS_CMD_LEN = strlen(req_path);
if (OK != (s=_taskcall(RS_PROC_NR, request, &m)))
failure(-s);
break;

View file

@ -32,7 +32,6 @@
PRIVATE int allow_newroot = 1;
FORWARD _PROTOTYPE( dev_t name_to_dev, (void) );
FORWARD _PROTOTYPE( int fs_exit, (endpoint_t fs_e) );
FORWARD _PROTOTYPE( int mount_fs, (endpoint_t fs_e) );
/*===========================================================================*
@ -71,7 +70,6 @@ PUBLIC int do_fslogin()
PUBLIC int do_mount()
{
endpoint_t fs_e;
int r;
/* Only the super-user may do MOUNT. */
if (!super_user) return(EPERM);
@ -86,17 +84,7 @@ PUBLIC int do_mount()
}
/* Do the actual job */
r = mount_fs(fs_e);
/* If not OK and not suspended, bring down FS proc.. */
if (r != OK && r != SUSPEND) {
/* Ask RS to bring down FS */
if (-1 == fs_exit(fs_e)) {
printf("VFSmount: WARNING: couldn't stop FS endp: %d\n", fs_e);
}
}
return r;
return mount_fs(fs_e);
}
@ -482,7 +470,7 @@ Dev_t dev;
/* Find vmnt */
for (vmp_i = &vmnt[0]; vmp_i < &vmnt[NR_MNTS]; ++vmp_i) {
if (vmp->m_dev == dev) {
if (vmp_i->m_dev == dev) {
if(vmp) panic(__FILE__, "device mounted more than once", dev);
vmp = vmp_i;
}
@ -560,12 +548,6 @@ Dev_t dev;
vmp->m_fs_e = NONE;
vmp->m_driver_e = NONE;
/* Ask RS to bring down FS */
if (-1 == fs_exit(fs_e)) {
printf("VFSunmount: WARNING: couldn't stop FS endp: %d\n", fs_e);
}
printf("VFSunmount: DEV: %d unmounted\n", dev);
return(OK);
}
@ -596,35 +578,3 @@ PRIVATE dev_t name_to_dev()
return res.dev;
}
/*===========================================================================*
* fs_exit *
*===========================================================================*/
PRIVATE int fs_exit(fs_e)
endpoint_t fs_e;
{
/* Build a message for stoping a FS server and ask RS to do it */
message m;
pid_t fs_pid;
int r;
/* Don't need to stop the one in the bootimage */
if (fs_e == MFS_PROC_NR) return OK;
/* Get pid for this endpoint */
if (-1 == (fs_pid = getnpid(fs_e))) {
printf("VFS: couldn't find pid for fs_e: %d\n", fs_e);
return -1;
}
/* Ask RS to stop process */
m.RS_PID = fs_pid;
if (OK != (r = _taskcall(RS_PROC_NR, RS_DOWN, &m))) {
printf("VFSfs_exit: couldn't bring FS down pid: %d\n", fs_pid);
return -1;
}
return OK;
}

View file

@ -792,7 +792,7 @@ endpoint_t driver_e;
/* Issue request */
if ((r = sendrec(fs_e, &m)) != OK) {
printf("VFSreq_newdriver: error sending message to %d\n", fs_e);
printf("VFSreq_newdriver: error sending message to %d: %d\n", fs_e, r);
return r;
}
@ -971,17 +971,19 @@ PRIVATE int fs_sendrec(endpoint_t fs_e, message *reqm)
for (;;) {
/* Do the actual send, receive */
if (OK != sendrec(fs_e, reqm)) {
printf("VFS: error sending message. FS_e: %d req_nr: %d\n",
fs_e, reqm->m_type);
if (OK != (r=sendrec(fs_e, reqm))) {
printf("VFS: error sending message. FS_e: %d req_nr: %d err: %d\n",
fs_e, reqm->m_type, r);
}
/* Get response type */
r = reqm->m_type;
if(r == OK) {
/* Sendrec was okay */
break;
}
/* Dead driver */
if (r == EDEADSRCDST || r == EDSTDIED || r == ESRCDIED) {
old_driver_e = 0;
old_driver_e = NONE;
/* Find old driver enpoint */
for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) {
if (vmp->m_fs_e == reqm->m_source) { /* found FS */
@ -992,7 +994,7 @@ PRIVATE int fs_sendrec(endpoint_t fs_e, message *reqm)
}
/* No FS ?? */
if (!old_driver_e) {
if (old_driver_e == NONE) {
panic(__FILE__, "VFSdead_driver: couldn't find FS\n",
old_driver_e);
}
@ -1033,12 +1035,13 @@ PRIVATE int fs_sendrec(endpoint_t fs_e, message *reqm)
*reqm = origm;
continue;
}
/* Sendrec was okay */
break;
printf("fs_sendrec: unhandled error %d sending to %d\n", r, fs_e);
panic(__FILE__, "fs_sendrec: unhandled error", NO_NUM);
}
/* Return message type */
return r;
return reqm->m_type;
}

View file

@ -64,7 +64,7 @@ int flag; /* M3 means path may be in message */
if(user_fullpath[len-1] != '\0') {
int i;
printf("fetch_name: name not null-terminated: ");
printf("vfs: fetch_name: name not null-terminated: ");
for(i = 0; i < len; i++) {
printf("%c", user_fullpath[i]);
}
@ -115,11 +115,11 @@ PUBLIC int isokendpt_f(char *file, int line, int endpoint, int *proc, int fatal)
int failed = 0;
*proc = _ENDPOINT_P(endpoint);
if(*proc < 0 || *proc >= NR_PROCS) {
printf("FS:%s:%d: proc (%d) from endpoint (%d) out of range\n",
printf("vfs:%s:%d: proc (%d) from endpoint (%d) out of range\n",
file, line, *proc, endpoint);
failed = 1;
} else if(fproc[*proc].fp_endpoint != endpoint) {
printf("FS:%s:%d: proc (%d) from endpoint (%d) doesn't match "
printf("vfs:%s:%d: proc (%d) from endpoint (%d) doesn't match "
"known endpoint (%d)\n",
file, line, *proc, endpoint, fproc[*proc].fp_endpoint);
failed = 1;