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.
1/1 # Mass storage / IDE
;
};
+
+driver mfs
+{
+ system
+ EXIT # 2
+ VIRCOPY # 15
+ TIMES # 25
+ SAFECOPYFROM # 31
+ SAFECOPYTO # 32
+ SETGRANT # 34
+ ;
+ uid 0;
+};
#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
# 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 */
#define _PATH_TMP "/tmp"
#define _PATH_BSHELL "/bin/sh"
+#define _PATH_SERVICE "/bin/service"
+#define _PATH_DRIVERS_CONF "/etc/drivers.conf"
#endif
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
int rsp_nr_class;
struct { u32_t class; u32_t mask; } rsp_class[RSP_NR_CLASS];
};
+
_times.c \
_truncate.c \
_umask.c \
- _umount.c \
_uname.c \
_unlink.c \
_utime.c \
#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;
}
+++ /dev/null
-#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));
-}
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");
}
#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))
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) {
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) {
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)
sp->s_dev = NO_DEV;
-printf("MFS(%d) DEV %d unmounted\n", SELF_E, fs_dev);
return OK;
}
/* 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) {
*===========================================================================*/
PUBLIC int fs_create()
{
+ phys_bytes len;
int r, b;
struct inode *ldirp;
struct inode *rip;
/* 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) {
{
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;
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;
*===========================================================================*/
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 */
}
/* 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),
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) );
/*===========================================================================*
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;
/* 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 */
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__);
/*===========================================================================*
* 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
/* 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;
_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)
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);
+ }
+}
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
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;
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;
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++) {
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 *
*===========================================================================*/
*/
#include <stdarg.h>
+#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
"down",
"refresh",
"restart",
- "rescue",
+ "-unused",
"shutdown",
"upcopy", /* fill for RS_UP_COPY */
"catch for illegal 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 */
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. */
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");
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);
}
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 */
}
int call_nr;
} system_tab[]=
{
+ { "EXIT", SYS_EXIT },
{ "PRIVCTL", SYS_PRIVCTL },
{ "TRACE", SYS_TRACE },
{ "KILL", SYS_KILL },
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
*/
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.
*/
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
/* 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;
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;
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) );
/*===========================================================================*
PUBLIC int do_mount()
{
endpoint_t fs_e;
- int r;
/* Only the super-user may do MOUNT. */
if (!super_user) return(EPERM);
}
/* 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);
}
/* 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;
}
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);
}
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;
-}
-
-
/* 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;
}
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 */
}
/* No FS ?? */
- if (!old_driver_e) {
+ if (old_driver_e == NONE) {
panic(__FILE__, "VFSdead_driver: couldn't find FS\n",
old_driver_e);
}
*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;
}
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]);
}
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;