diff --git a/docs/UPDATING b/docs/UPDATING index 0aaebd5be..19920b5ee 100644 --- a/docs/UPDATING +++ b/docs/UPDATING @@ -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. diff --git a/etc/drivers.conf b/etc/drivers.conf index 978d462db..176b0c07f 100644 --- a/etc/drivers.conf +++ b/etc/drivers.conf @@ -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; +}; diff --git a/include/minix/com.h b/include/minix/com.h index b206bd22c..819248e7b 100755 --- a/include/minix/com.h +++ b/include/minix/com.h @@ -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 */ diff --git a/include/minix/paths.h b/include/minix/paths.h index c35b7daeb..8ec598948 100644 --- a/include/minix/paths.h +++ b/include/minix/paths.h @@ -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 diff --git a/include/minix/rs.h b/include/minix/rs.h index 371d871a5..a2c19da00 100644 --- a/include/minix/rs.h +++ b/include/minix/rs.h @@ -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]; }; + diff --git a/lib/posix/Makefile.in b/lib/posix/Makefile.in index b3eec7cc5..21c313f12 100644 --- a/lib/posix/Makefile.in +++ b/lib/posix/Makefile.in @@ -92,7 +92,6 @@ libc_FILES=" \ _times.c \ _truncate.c \ _umask.c \ - _umount.c \ _uname.c \ _unlink.c \ _utime.c \ diff --git a/lib/posix/_mount.c b/lib/posix/_mount.c index e7dc63134..5d38b471e 100755 --- a/lib/posix/_mount.c +++ b/lib/posix/_mount.c @@ -1,49 +1,123 @@ #include #define mount _mount +#define umount _umount #include #include +#include #include #include #include - +#include +#include #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; } diff --git a/lib/posix/_umount.c b/lib/posix/_umount.c deleted file mode 100755 index 71e712544..000000000 --- a/lib/posix/_umount.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#define umount _umount -#include - -PUBLIC int umount(name) -_CONST char *name; -{ - message m; - - _loadname(name, &m); - return(_syscall(FS, UMOUNT, &m)); -} diff --git a/servers/is/dmp_rs.c b/servers/is/dmp_rs.c index beec021fa..3602beadb 100644 --- a/servers/is/dmp_rs.c +++ b/servers/is/dmp_rs.c @@ -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; ir_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"); } diff --git a/servers/mfs/const.h b/servers/mfs/const.h index 2fed5b48f..9f5027523 100644 --- a/servers/mfs/const.h +++ b/servers/mfs/const.h @@ -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)) diff --git a/servers/mfs/link.c b/servers/mfs/link.c index 141d94ba1..0e76712b5 100644 --- a/servers/mfs/link.c +++ b/servers/mfs/link.c @@ -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) diff --git a/servers/mfs/mount.c b/servers/mfs/mount.c index c75fdc9a6..b777dfa1d 100644 --- a/servers/mfs/mount.c +++ b/servers/mfs/mount.c @@ -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; } diff --git a/servers/mfs/open.c b/servers/mfs/open.c index a45d94c34..b2889e21d 100644 --- a/servers/mfs/open.c +++ b/servers/mfs/open.c @@ -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), diff --git a/servers/mfs/path.c b/servers/mfs/path.c index 04e4e6104..e5459c3cf 100644 --- a/servers/mfs/path.c +++ b/servers/mfs/path.c @@ -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; diff --git a/servers/mfs/proto.h b/servers/mfs/proto.h index e83f36d39..8b3bbca80 100644 --- a/servers/mfs/proto.h +++ b/servers/mfs/proto.h @@ -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) diff --git a/servers/mfs/utility.c b/servers/mfs/utility.c index 387d877ab..328844d69 100644 --- a/servers/mfs/utility.c +++ b/servers/mfs/utility.c @@ -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); + } +} diff --git a/servers/rs/Makefile b/servers/rs/Makefile index b5c8ca7d4..407dd79ec 100644 --- a/servers/rs/Makefile +++ b/servers/rs/Makefile @@ -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 diff --git a/servers/rs/main.c b/servers/rs/main.c index dec432bdc..4e805098d 100644 --- a/servers/rs/main.c +++ b/servers/rs/main.c @@ -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; diff --git a/servers/rs/manager.c b/servers/rs/manager.c index aafef4ee3..1c26d2877 100644 --- a/servers/rs/manager.c +++ b/servers/rs/manager.c @@ -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 * *===========================================================================*/ diff --git a/servers/rs/service.c b/servers/rs/service.c index 8ed7a8f55..b2d1f48a4 100644 --- a/servers/rs/service.c +++ b/servers/rs/service.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -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; diff --git a/servers/vfs/mount.c b/servers/vfs/mount.c index f337e3bef..6eb207027 100644 --- a/servers/vfs/mount.c +++ b/servers/vfs/mount.c @@ -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; -} - - diff --git a/servers/vfs/request.c b/servers/vfs/request.c index 4e2d739f3..4f620911d 100644 --- a/servers/vfs/request.c +++ b/servers/vfs/request.c @@ -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; } diff --git a/servers/vfs/utility.c b/servers/vfs/utility.c index bbfb4a015..b5410c3c5 100644 --- a/servers/vfs/utility.c +++ b/servers/vfs/utility.c @@ -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;