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:
parent
d954a122f7
commit
2194bc0310
23 changed files with 300 additions and 222 deletions
|
@ -31,3 +31,6 @@
|
||||||
in /etc/make.conf, included by some Makefiles and sourced by
|
in /etc/make.conf, included by some Makefiles and sourced by
|
||||||
some shell scripts. To install it, type 'make install' in
|
some shell scripts. To install it, type 'make install' in
|
||||||
src/etc, or simply copy the file over.
|
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.
|
||||||
|
|
|
@ -142,3 +142,16 @@ driver at_wini
|
||||||
1/1 # Mass storage / IDE
|
1/1 # Mass storage / IDE
|
||||||
;
|
;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
driver mfs
|
||||||
|
{
|
||||||
|
system
|
||||||
|
EXIT # 2
|
||||||
|
VIRCOPY # 15
|
||||||
|
TIMES # 25
|
||||||
|
SAFECOPYFROM # 31
|
||||||
|
SAFECOPYTO # 32
|
||||||
|
SETGRANT # 34
|
||||||
|
;
|
||||||
|
uid 0;
|
||||||
|
};
|
||||||
|
|
|
@ -555,7 +555,6 @@
|
||||||
#define RS_DOWN (RS_RQ_BASE + 1) /* stop system service */
|
#define RS_DOWN (RS_RQ_BASE + 1) /* stop system service */
|
||||||
#define RS_REFRESH (RS_RQ_BASE + 2) /* refresh system service */
|
#define RS_REFRESH (RS_RQ_BASE + 2) /* refresh system service */
|
||||||
#define RS_RESTART (RS_RQ_BASE + 3) /* restart 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_SHUTDOWN (RS_RQ_BASE + 5) /* alert about shutdown */
|
||||||
#define RS_UP_COPY (RS_RQ_BASE + 6) /* start system service and
|
#define RS_UP_COPY (RS_RQ_BASE + 6) /* start system service and
|
||||||
* keep the binary in memory
|
* keep the binary in memory
|
||||||
|
@ -567,7 +566,6 @@
|
||||||
|
|
||||||
# define RS_CMD_ADDR m1_p1 /* command string */
|
# define RS_CMD_ADDR m1_p1 /* command string */
|
||||||
# define RS_CMD_LEN m1_i1 /* length of command */
|
# 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_PERIOD m1_i2 /* heartbeat period */
|
||||||
# define RS_DEV_MAJOR m1_i3 /* major device number */
|
# define RS_DEV_MAJOR m1_i3 /* major device number */
|
||||||
|
|
||||||
|
|
|
@ -17,5 +17,7 @@
|
||||||
#define _PATH_TMP "/tmp"
|
#define _PATH_TMP "/tmp"
|
||||||
|
|
||||||
#define _PATH_BSHELL "/bin/sh"
|
#define _PATH_BSHELL "/bin/sh"
|
||||||
|
#define _PATH_SERVICE "/bin/service"
|
||||||
|
#define _PATH_DRIVERS_CONF "/etc/drivers.conf"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,6 +31,8 @@ struct rs_start
|
||||||
int rss_nr_pci_class;
|
int rss_nr_pci_class;
|
||||||
struct { u32_t class; u32_t mask; } rss_pci_class[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];
|
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
|
#define RF_COPY 0x01 /* Copy the brinary into RS to make it possible
|
||||||
|
@ -51,3 +53,4 @@ struct rs_pci
|
||||||
int rsp_nr_class;
|
int rsp_nr_class;
|
||||||
struct { u32_t class; u32_t mask; } rsp_class[RSP_NR_CLASS];
|
struct { u32_t class; u32_t mask; } rsp_class[RSP_NR_CLASS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,6 @@ libc_FILES=" \
|
||||||
_times.c \
|
_times.c \
|
||||||
_truncate.c \
|
_truncate.c \
|
||||||
_umask.c \
|
_umask.c \
|
||||||
_umount.c \
|
|
||||||
_uname.c \
|
_uname.c \
|
||||||
_unlink.c \
|
_unlink.c \
|
||||||
_utime.c \
|
_utime.c \
|
||||||
|
|
|
@ -1,49 +1,123 @@
|
||||||
|
|
||||||
#include <lib.h>
|
#include <lib.h>
|
||||||
#define mount _mount
|
#define mount _mount
|
||||||
|
#define umount _umount
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <minix/syslib.h>
|
#include <minix/syslib.h>
|
||||||
|
#include <minix/rs.h>
|
||||||
|
#include <minix/paths.h>
|
||||||
#define OK 0
|
#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)
|
PUBLIC int mount(special, name, rwflag)
|
||||||
char *name, *special;
|
char *name, *special;
|
||||||
int rwflag;
|
int rwflag;
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
struct stat stat_buf;
|
|
||||||
message m;
|
message m;
|
||||||
|
struct rs_start rs_start;
|
||||||
m.RS_CMD_ADDR = "/sbin/mfs";
|
char *label;
|
||||||
if (stat(m.RS_CMD_ADDR, &stat_buf) == -1) {
|
char cmd[200];
|
||||||
/* /sbin/mfs does not exist, try /bin/mfs as well */
|
FILE *pipe;
|
||||||
m.RS_CMD_ADDR = "/bin/mfs";
|
int ep;
|
||||||
if (stat(m.RS_CMD_ADDR, &stat_buf) == -1) {
|
|
||||||
/* /bin/mfs does not exist either, give up */
|
/* Make MFS process label for RS from special name. */
|
||||||
return -1;
|
if(!(label=makelabel(special))) {
|
||||||
}
|
errno = E2BIG;
|
||||||
}
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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_i1 = strlen(special) + 1;
|
||||||
m.m1_i2 = strlen(name) + 1;
|
m.m1_i2 = strlen(name) + 1;
|
||||||
m.m1_i3 = rwflag;
|
m.m1_i3 = rwflag;
|
||||||
m.m1_p1 = special;
|
m.m1_p1 = special;
|
||||||
m.m1_p2 = name;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
|
|
@ -28,20 +28,20 @@ PUBLIC void rproc_dmp()
|
||||||
getsysinfo(RS_PROC_NR, SI_PROC_TAB, rproc);
|
getsysinfo(RS_PROC_NR, SI_PROC_TAB, rproc);
|
||||||
|
|
||||||
printf("Reincarnation Server (RS) system process table dump\n");
|
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++) {
|
for (i=prev_i; i<NR_SYS_PROCS; i++) {
|
||||||
rp = &rproc[i];
|
rp = &rproc[i];
|
||||||
if (! rp->r_flags & RS_IN_USE) continue;
|
if (! rp->r_flags & RS_IN_USE) continue;
|
||||||
if (++n > 22) break;
|
if (++n > 22) break;
|
||||||
printf("%9d %5d %s %3d/%2d %3u %8u %8u %4dx %3d %s (%d)",
|
printf("%9d %s %3d/%2d %3u %8u %8u %4dx %3d %s %s",
|
||||||
rp->r_proc_nr_e, rp->r_pid,
|
rp->r_proc_nr_e,
|
||||||
s_flags_str(rp->r_flags),
|
s_flags_str(rp->r_flags),
|
||||||
rp->r_dev_nr, rp->r_dev_style,
|
rp->r_dev_nr, rp->r_dev_style,
|
||||||
rp->r_period,
|
rp->r_period,
|
||||||
rp->r_check_tm, rp->r_alive_tm,
|
rp->r_check_tm, rp->r_alive_tm,
|
||||||
rp->r_restarts, rp->r_backoff,
|
rp->r_restarts, rp->r_backoff,
|
||||||
rp->r_cmd,
|
rp->r_label,
|
||||||
rp->r_argc
|
rp->r_cmd
|
||||||
);
|
);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,3 +108,4 @@
|
||||||
#define V2_INODES_PER_BLOCK(b) ((b)/V2_INODE_SIZE)/* # V2 dsk inodes/blk */
|
#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_MIN(a,b) mfs_min_f(__FILE__,__LINE__,(a), (b))
|
||||||
|
#define MFS_NUL(str,l,m) mfs_nul_f(__FILE__,__LINE__,(str), (l), (m))
|
||||||
|
|
|
@ -38,14 +38,17 @@ PUBLIC int fs_link()
|
||||||
register int r;
|
register int r;
|
||||||
char string[NAME_MAX];
|
char string[NAME_MAX];
|
||||||
struct inode *new_ip;
|
struct inode *new_ip;
|
||||||
|
phys_bytes len;
|
||||||
|
|
||||||
caller_uid = fs_m_in.REQ_UID;
|
caller_uid = fs_m_in.REQ_UID;
|
||||||
caller_gid = fs_m_in.REQ_GID;
|
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 */
|
/* Copy the link name's last component */
|
||||||
r = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH,
|
r = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH,
|
||||||
SELF, (vir_bytes) string,
|
SELF, (vir_bytes) string, (phys_bytes) len);
|
||||||
(phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string)));
|
if (r != OK) return r;
|
||||||
|
MFS_NUL(string, len, sizeof(string));
|
||||||
|
|
||||||
/* Temporarily open the file. */
|
/* Temporarily open the file. */
|
||||||
if ( (rip = get_inode(fs_dev, fs_m_in.REQ_LINKED_FILE)) == NIL_INODE) {
|
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;
|
struct inode *rldirp;
|
||||||
int r;
|
int r;
|
||||||
char string[NAME_MAX];
|
char string[NAME_MAX];
|
||||||
|
phys_bytes len;
|
||||||
|
|
||||||
caller_uid = fs_m_in.REQ_UID;
|
caller_uid = fs_m_in.REQ_UID;
|
||||||
caller_gid = fs_m_in.REQ_GID;
|
caller_gid = fs_m_in.REQ_GID;
|
||||||
|
|
||||||
/* Copy the last component */
|
/* 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,
|
r = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH,
|
||||||
SELF, (vir_bytes) string,
|
SELF, (vir_bytes) string, (phys_bytes) len);
|
||||||
(phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string)));
|
|
||||||
|
|
||||||
if (r != OK) return r;
|
if (r != OK) return r;
|
||||||
|
MFS_NUL(string, len, sizeof(string));
|
||||||
|
|
||||||
/* Temporarily open the dir. */
|
/* Temporarily open the dir. */
|
||||||
if ( (rldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NIL_INODE) {
|
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 */
|
int same_pdir; /* TRUE iff parent dirs are the same */
|
||||||
char old_name[NAME_MAX], new_name[NAME_MAX];
|
char old_name[NAME_MAX], new_name[NAME_MAX];
|
||||||
ino_t numb;
|
ino_t numb;
|
||||||
|
phys_bytes len;
|
||||||
int r1;
|
int r1;
|
||||||
|
|
||||||
caller_uid = fs_m_in.REQ_UID;
|
caller_uid = fs_m_in.REQ_UID;
|
||||||
caller_gid = fs_m_in.REQ_GID;
|
caller_gid = fs_m_in.REQ_GID;
|
||||||
|
|
||||||
/* Copy the last component of the old name */
|
/* 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,
|
r = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH,
|
||||||
SELF, (vir_bytes) old_name,
|
SELF, (vir_bytes) old_name, (phys_bytes) len);
|
||||||
(phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(old_name)));
|
|
||||||
if (r != OK) return r;
|
if (r != OK) return r;
|
||||||
|
MFS_NUL(old_name, len, sizeof(old_name));
|
||||||
|
|
||||||
/* Copy the last component of the new 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,
|
r = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_USER_ADDR,
|
||||||
SELF, (vir_bytes) new_name,
|
SELF, (vir_bytes) new_name, (phys_bytes) len);
|
||||||
(phys_bytes) fs_m_in.REQ_SLENGTH);
|
|
||||||
if (r != OK) return r;
|
if (r != OK) return r;
|
||||||
|
MFS_NUL(new_name, len, sizeof(new_name));
|
||||||
|
|
||||||
/* Get old dir inode */
|
/* Get old dir inode */
|
||||||
if ( (old_dirp = get_inode(fs_dev, fs_m_in.REQ_OLD_DIR)) == NIL_INODE)
|
if ( (old_dirp = get_inode(fs_dev, fs_m_in.REQ_OLD_DIR)) == NIL_INODE)
|
||||||
|
|
|
@ -185,7 +185,6 @@ PUBLIC int fs_unmount()
|
||||||
sp->s_dev = NO_DEV;
|
sp->s_dev = NO_DEV;
|
||||||
|
|
||||||
|
|
||||||
printf("MFS(%d) DEV %d unmounted\n", SELF_E, fs_dev);
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,13 +48,13 @@ PUBLIC int fs_open()
|
||||||
|
|
||||||
/* If O_CREATE is set, try to make the file. */
|
/* If O_CREATE is set, try to make the file. */
|
||||||
if (oflags & O_CREAT) {
|
if (oflags & O_CREAT) {
|
||||||
|
phys_bytes len;
|
||||||
/* Copy the last component */
|
/* 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,
|
err_code = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH,
|
||||||
SELF, (vir_bytes) lastc,
|
SELF, (vir_bytes) lastc, (phys_bytes) len);
|
||||||
(phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN,
|
|
||||||
sizeof(lastc)));
|
|
||||||
|
|
||||||
if (err_code != OK) return err_code;
|
if (err_code != OK) return err_code;
|
||||||
|
MFS_NUL(lastc, len, sizeof(lastc));
|
||||||
|
|
||||||
/* Get last directory inode */
|
/* Get last directory inode */
|
||||||
if ((ldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NIL_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()
|
PUBLIC int fs_create()
|
||||||
{
|
{
|
||||||
|
phys_bytes len;
|
||||||
int r, b;
|
int r, b;
|
||||||
struct inode *ldirp;
|
struct inode *ldirp;
|
||||||
struct inode *rip;
|
struct inode *rip;
|
||||||
|
@ -165,10 +166,11 @@ PUBLIC int fs_create()
|
||||||
/* Try to make the file. */
|
/* Try to make the file. */
|
||||||
|
|
||||||
/* Copy the last component */
|
/* 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,
|
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;
|
if (err_code != OK) return err_code;
|
||||||
|
MFS_NUL(lastc, len, sizeof(lastc));
|
||||||
|
|
||||||
/* Get last directory inode */
|
/* Get last directory inode */
|
||||||
if ((ldirp = get_inode(fs_dev, fs_m_in.REQ_INODE_NR)) == NIL_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;
|
struct inode *ip, *ldirp;
|
||||||
char lastc[NAME_MAX];
|
char lastc[NAME_MAX];
|
||||||
|
phys_bytes len;
|
||||||
|
|
||||||
/* Copy the last component and set up caller's user and group id */
|
/* 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,
|
err_code = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH, SELF,
|
||||||
(vir_bytes) lastc,
|
(vir_bytes) lastc, (phys_bytes) len);
|
||||||
(phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(lastc)));
|
|
||||||
|
|
||||||
if (err_code != OK) return err_code;
|
if (err_code != OK) return err_code;
|
||||||
|
MFS_NUL(lastc, len, sizeof(lastc));
|
||||||
|
|
||||||
caller_uid = fs_m_in.REQ_UID;
|
caller_uid = fs_m_in.REQ_UID;
|
||||||
caller_gid = fs_m_in.REQ_GID;
|
caller_gid = fs_m_in.REQ_GID;
|
||||||
|
@ -247,13 +250,14 @@ PUBLIC int fs_mkdir()
|
||||||
ino_t dot, dotdot; /* inode numbers for . and .. */
|
ino_t dot, dotdot; /* inode numbers for . and .. */
|
||||||
struct inode *rip, *ldirp;
|
struct inode *rip, *ldirp;
|
||||||
char lastc[NAME_MAX]; /* last component */
|
char lastc[NAME_MAX]; /* last component */
|
||||||
|
phys_bytes len;
|
||||||
|
|
||||||
/* Copy the last component and set up caller's user and group id */
|
/* 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,
|
err_code = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH, SELF,
|
||||||
(vir_bytes) lastc, (phys_bytes)
|
(vir_bytes) lastc, (phys_bytes) len);
|
||||||
MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(lastc)));
|
|
||||||
|
|
||||||
if (err_code != OK) return err_code;
|
if (err_code != OK) return err_code;
|
||||||
|
MFS_NUL(lastc, len, sizeof(lastc));
|
||||||
|
|
||||||
caller_uid = fs_m_in.REQ_UID;
|
caller_uid = fs_m_in.REQ_UID;
|
||||||
caller_gid = fs_m_in.REQ_GID;
|
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()
|
PUBLIC int fs_slink()
|
||||||
{
|
{
|
||||||
|
phys_bytes len;
|
||||||
struct inode *sip; /* inode containing symbolic link */
|
struct inode *sip; /* inode containing symbolic link */
|
||||||
struct inode *ldirp; /* directory containing link */
|
struct inode *ldirp; /* directory containing link */
|
||||||
register int r; /* error code */
|
register int r; /* error code */
|
||||||
|
@ -324,11 +329,11 @@ PUBLIC int fs_slink()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the link name's last component */
|
/* 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,
|
r = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH,
|
||||||
SELF, (vir_bytes) string,
|
SELF, (vir_bytes) string, (phys_bytes) len);
|
||||||
(phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string)));
|
|
||||||
|
|
||||||
if (r != OK) return r;
|
if (r != OK) return r;
|
||||||
|
MFS_NUL(string, len, sizeof(string));
|
||||||
|
|
||||||
/* Create the inode for the symlink. */
|
/* Create the inode for the symlink. */
|
||||||
sip = new_node(ldirp, string, (mode_t) (I_SYMBOLIC_LINK | RWX_MODES),
|
sip = new_node(ldirp, string, (mode_t) (I_SYMBOLIC_LINK | RWX_MODES),
|
||||||
|
|
|
@ -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( char *get_name, (char *old_name, char string [NAME_MAX]) );
|
||||||
FORWARD _PROTOTYPE( int ltraverse, (struct inode *rip, char *path,
|
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];
|
char string[PATH_MAX];
|
||||||
struct inode *rip;
|
struct inode *rip;
|
||||||
int s_error, flags;
|
int s_error, flags;
|
||||||
|
int len;
|
||||||
|
|
||||||
string[0] = '\0';
|
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 */
|
/* 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,
|
err_code = sys_datacopy(FS_PROC_NR, (vir_bytes) fs_m_in.REQ_PATH, SELF,
|
||||||
(vir_bytes) user_path,
|
(vir_bytes) user_path, (phys_bytes) len);
|
||||||
(phys_bytes) MFS_MIN(fs_m_in.REQ_PATH_LEN, sizeof(string)));
|
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_uid = fs_m_in.REQ_UID;
|
||||||
caller_gid = fs_m_in.REQ_GID;
|
caller_gid = fs_m_in.REQ_GID;
|
||||||
|
@ -60,9 +71,12 @@ PUBLIC int lookup()
|
||||||
/* Copy back the last name if it is required */
|
/* Copy back the last name if it is required */
|
||||||
if (err_code != OK || (flags & PATH_PENULTIMATE)) {
|
if (err_code != OK || (flags & PATH_PENULTIMATE)) {
|
||||||
s_error = sys_datacopy(SELF_E, (vir_bytes) string, FS_PROC_NR,
|
s_error = sys_datacopy(SELF_E, (vir_bytes) string, FS_PROC_NR,
|
||||||
(vir_bytes) fs_m_in.REQ_USER_ADDR, (phys_bytes)
|
(vir_bytes) fs_m_in.REQ_USER_ADDR, (phys_bytes) NAME_MAX);
|
||||||
MFS_MIN(strlen(string)+1, NAME_MAX));
|
if (s_error != OK) {
|
||||||
if (s_error != OK) return s_error;
|
printf("mfs:%s:%d: sys_datacopy failed: %d\n",
|
||||||
|
__FILE__, __LINE__, s_error);
|
||||||
|
return s_error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Error or mount point encountered */
|
/* Error or mount point encountered */
|
||||||
|
@ -234,7 +248,8 @@ printf("%s, %d\n", __FILE__, __LINE__);
|
||||||
if (*new_name != '\0') new_name--;
|
if (*new_name != '\0') new_name--;
|
||||||
|
|
||||||
/* Extract path name from the symlink file */
|
/* 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);
|
put_inode(dir_ip);
|
||||||
err_code = ENOENT;
|
err_code = ENOENT;
|
||||||
printf("%s, %d\n", __FILE__, __LINE__);
|
printf("%s, %d\n", __FILE__, __LINE__);
|
||||||
|
@ -290,10 +305,11 @@ printf("%s, %d\n", __FILE__, __LINE__);
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* ltraverse *
|
* ltraverse *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE int ltraverse(rip, path, suffix)
|
PRIVATE int ltraverse(rip, path, suffix, pathlen)
|
||||||
register struct inode *rip; /* symbolic link */
|
register struct inode *rip; /* symbolic link */
|
||||||
char *path; /* path containing link */
|
char *path; /* path containing link */
|
||||||
char *suffix; /* suffix following link within path */
|
char *suffix; /* suffix following link within path */
|
||||||
|
int pathlen;
|
||||||
{
|
{
|
||||||
/* Traverse a symbolic link. Copy the link text from the inode and insert
|
/* 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
|
* 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. */
|
/* Insert symbolic text into path name. */
|
||||||
tl = strlen(suffix);
|
tl = strlen(suffix);
|
||||||
if (sl > 0 && sl + tl <= PATH_MAX-1) {
|
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+sl, suffix, tl);
|
||||||
memmove(path, sp, sl);
|
memmove(path, sp, sl);
|
||||||
path[sl+tl] = 0;
|
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,
|
r = sys_datacopy(SELF_E, (vir_bytes) path, FS_PROC_NR,
|
||||||
(vir_bytes) vfs_slink_storage, (phys_bytes) sl+tl+1);
|
(vir_bytes) vfs_slink_storage, (phys_bytes) sl+tl+1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
dup_inode(bip = path[0] == '/' ? chroot_dir : ldip);
|
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 {
|
else {
|
||||||
r = ENOENT;
|
r = ENOENT;
|
||||||
|
|
|
@ -182,6 +182,8 @@ _PROTOTYPE( int fetch_name, (char *path, int len, int flag) );
|
||||||
_PROTOTYPE( int no_sys, (void) );
|
_PROTOTYPE( int no_sys, (void) );
|
||||||
_PROTOTYPE( int isokendpt_f, (char *f, int l, int e, int *p, int ft));
|
_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 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 okendpt(e, p) isokendpt_f(__FILE__, __LINE__, (e), (p), 1)
|
||||||
#define isokendpt(e, p) isokendpt_f(__FILE__, __LINE__, (e), (p), 0)
|
#define isokendpt(e, p) isokendpt_f(__FILE__, __LINE__, (e), (p), 0)
|
||||||
|
|
|
@ -92,8 +92,26 @@ PUBLIC time_t clock_time()
|
||||||
|
|
||||||
int mfs_min_f(char *file, int line, int v1, int v2)
|
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;
|
if(v2 >= v1) return v1;
|
||||||
printf("mfs:%s:%d: truncated %d to %d\n",
|
printf("mfs:%s:%d: truncated %d to %d\n",
|
||||||
file, line, v1, v2);
|
file, line, v1, v2);
|
||||||
return 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,8 +16,7 @@ CC = exec cc
|
||||||
CPPFLAGS = -I../../kernel/arch/$(ARCH)/include
|
CPPFLAGS = -I../../kernel/arch/$(ARCH)/include
|
||||||
CFLAGS = -I$i $(CPROFILE) $(CPPFLAGS)
|
CFLAGS = -I$i $(CPROFILE) $(CPPFLAGS)
|
||||||
LDFLAGS = -i
|
LDFLAGS = -i
|
||||||
UTIL_LIBS = -lsysutil -lsys
|
LIBS = -lsys -lsysutil
|
||||||
LIBS = -lsysutil -lsys
|
|
||||||
|
|
||||||
UTIL_OBJ = service.o
|
UTIL_OBJ = service.o
|
||||||
OBJ = exec.o main.o manager.o
|
OBJ = exec.o main.o manager.o
|
||||||
|
|
|
@ -86,7 +86,6 @@ PUBLIC int main(void)
|
||||||
case RS_START: result = do_start(&m); break;
|
case RS_START: result = do_start(&m); break;
|
||||||
case RS_DOWN: result = do_down(&m); break;
|
case RS_DOWN: result = do_down(&m); break;
|
||||||
case RS_REFRESH: result = do_refresh(&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_RESTART: result = do_restart(&m); break;
|
||||||
case RS_SHUTDOWN: result = do_shutdown(&m); break;
|
case RS_SHUTDOWN: result = do_shutdown(&m); break;
|
||||||
case GETSYSINFO: result = do_getsysinfo(&m); break;
|
case GETSYSINFO: result = do_getsysinfo(&m); break;
|
||||||
|
|
|
@ -106,7 +106,7 @@ int flags; /* extra flags, if any */
|
||||||
len= MAX_LABEL_LEN-1; /* truncate name */
|
len= MAX_LABEL_LEN-1; /* truncate name */
|
||||||
memcpy(rp->r_label, label, len);
|
memcpy(rp->r_label, label, len);
|
||||||
rp->r_label[len]= '\0';
|
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_uid= 0;
|
||||||
rp->r_nice= 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_argv[arg_count] = NULL; /* end with NULL pointer */
|
||||||
rp->r_argc = arg_count;
|
rp->r_argc = arg_count;
|
||||||
|
|
||||||
/* Default label for the driver */
|
if(rs_start.rss_label) {
|
||||||
label= strrchr(rp->r_argv[0], '/');
|
int len;
|
||||||
if (label)
|
/* RS_START caller has supplied a custom label for this driver. */
|
||||||
label++;
|
len = MIN(sizeof(rp->r_label)-1, rs_start.rss_labellen);
|
||||||
else
|
s=sys_datacopy(m_ptr->m_source, (vir_bytes) rs_start.rss_label,
|
||||||
label= rp->r_argv[0];
|
SELF, (vir_bytes) rp->r_label, len);
|
||||||
len= strlen(label);
|
if(s != OK)
|
||||||
if (len > MAX_LABEL_LEN-1)
|
return s;
|
||||||
len= MAX_LABEL_LEN-1; /* truncate name */
|
rp->r_label[len] = '\0';
|
||||||
memcpy(rp->r_label, label, len);
|
printf("RS: do_start: using label (custom) '%s'\n", rp->r_label);
|
||||||
rp->r_label[len]= '\0';
|
} else {
|
||||||
printf("using label '%s'\n", rp->r_label);
|
/* 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 */
|
/* Check for duplicates */
|
||||||
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
|
for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
|
||||||
|
@ -455,31 +468,6 @@ PUBLIC int do_refresh(message *m_ptr)
|
||||||
return(ESRCH);
|
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 *
|
* do_shutdown *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -30,7 +31,7 @@ PRIVATE char *known_requests[] = {
|
||||||
"down",
|
"down",
|
||||||
"refresh",
|
"refresh",
|
||||||
"restart",
|
"restart",
|
||||||
"rescue",
|
"-unused",
|
||||||
"shutdown",
|
"shutdown",
|
||||||
"upcopy", /* fill for RS_UP_COPY */
|
"upcopy", /* fill for RS_UP_COPY */
|
||||||
"catch for illegal requests"
|
"catch for illegal requests"
|
||||||
|
@ -63,9 +64,11 @@ PRIVATE char *known_requests[] = {
|
||||||
#define ARG_SCRIPT "-script" /* name of the script to restart a
|
#define ARG_SCRIPT "-script" /* name of the script to restart a
|
||||||
* driver
|
* driver
|
||||||
*/
|
*/
|
||||||
|
#define ARG_LABELNAME "-label" /* custom label name */
|
||||||
#define ARG_CONFIG "-config" /* name of the file with the resource
|
#define ARG_CONFIG "-config" /* name of the file with the resource
|
||||||
* configuration
|
* configuration
|
||||||
*/
|
*/
|
||||||
|
#define ARG_PRINTEP "-printep" /* print endpoint number after start */
|
||||||
|
|
||||||
#define DRIVER_LOGIN "driver" /* Passwd file entry for drivers */
|
#define DRIVER_LOGIN "driver" /* Passwd file entry for drivers */
|
||||||
|
|
||||||
|
@ -83,7 +86,9 @@ PRIVATE char *req_args;
|
||||||
PRIVATE int req_major;
|
PRIVATE int req_major;
|
||||||
PRIVATE long req_period;
|
PRIVATE long req_period;
|
||||||
PRIVATE char *req_script;
|
PRIVATE char *req_script;
|
||||||
|
PRIVATE char *req_label;
|
||||||
PRIVATE char *req_config;
|
PRIVATE char *req_config;
|
||||||
|
PRIVATE int req_printep;
|
||||||
PRIVATE int class_recurs; /* Nesting level of class statements */
|
PRIVATE int class_recurs; /* Nesting level of class statements */
|
||||||
|
|
||||||
/* Buffer to build "/command arg1 arg2 ..." string to pass to RS server. */
|
/* 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");
|
print_usage(argv[ARG_NAME], "binary should be absolute path");
|
||||||
exit(EINVAL);
|
exit(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat(req_path, &stat_buf) == -1) {
|
if (stat(req_path, &stat_buf) == -1) {
|
||||||
perror(req_path);
|
perror(req_path);
|
||||||
fprintf(stderr, "couldn't get stat binary\n");
|
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_script = argv[i+1];
|
||||||
req_nr = RS_START;
|
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) {
|
else if (strcmp(argv[i], ARG_CONFIG)==0) {
|
||||||
req_config = argv[i+1];
|
req_config = argv[i+1];
|
||||||
req_nr = RS_START;
|
req_nr = RS_START;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(argv[i], ARG_PRINTEP)==0) {
|
||||||
|
req_printep = 1;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
print_usage(argv[ARG_NAME], "unknown optional argument given");
|
print_usage(argv[ARG_NAME], "unknown optional argument given");
|
||||||
exit(EINVAL);
|
exit(EINVAL);
|
||||||
|
@ -261,27 +274,6 @@ PRIVATE int parse_arguments(int argc, char **argv)
|
||||||
}
|
}
|
||||||
req_label= argv[optind+ARG_LABEL];
|
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) {
|
else if (req_nr == RS_SHUTDOWN) {
|
||||||
/* no extra arguments required */
|
/* no extra arguments required */
|
||||||
}
|
}
|
||||||
|
@ -658,6 +650,7 @@ struct
|
||||||
int call_nr;
|
int call_nr;
|
||||||
} system_tab[]=
|
} system_tab[]=
|
||||||
{
|
{
|
||||||
|
{ "EXIT", SYS_EXIT },
|
||||||
{ "PRIVCTL", SYS_PRIVCTL },
|
{ "PRIVCTL", SYS_PRIVCTL },
|
||||||
{ "TRACE", SYS_TRACE },
|
{ "TRACE", SYS_TRACE },
|
||||||
{ "KILL", SYS_KILL },
|
{ "KILL", SYS_KILL },
|
||||||
|
@ -871,7 +864,7 @@ PUBLIC int main(int argc, char **argv)
|
||||||
int result;
|
int result;
|
||||||
int request;
|
int request;
|
||||||
int i, s;
|
int i, s;
|
||||||
char *label;
|
char *label, *progname = NULL;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
|
||||||
/* Verify and parse the command line arguments. All arguments are checked
|
/* 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);
|
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
|
/* Arguments seem fine. Try to perform the request. Only valid requests
|
||||||
* should end up here. The default is used for not yet supported 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_major= req_major;
|
||||||
rs_start.rss_period= req_period;
|
rs_start.rss_period= req_period;
|
||||||
rs_start.rss_script= req_script;
|
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)
|
if (req_script)
|
||||||
rs_start.rss_scriptlen= strlen(req_script);
|
rs_start.rss_scriptlen= strlen(req_script);
|
||||||
else
|
else
|
||||||
|
@ -925,14 +932,18 @@ PUBLIC int main(int argc, char **argv)
|
||||||
/* The name of the driver */
|
/* The name of the driver */
|
||||||
(label= strrchr(req_path, '/')) ? label++ : (label= req_path);
|
(label= strrchr(req_path, '/')) ? label++ : (label= req_path);
|
||||||
|
|
||||||
if (req_config)
|
if (req_config) {
|
||||||
do_config(label, req_config);
|
assert(progname);
|
||||||
|
do_config(progname, req_config);
|
||||||
|
}
|
||||||
|
|
||||||
m.RS_CMD_ADDR = (char *) &rs_start;
|
m.RS_CMD_ADDR = (char *) &rs_start;
|
||||||
|
|
||||||
/* Build request message and send the request. */
|
/* Build request message and send the request. */
|
||||||
if (OK != (s=_taskcall(RS_PROC_NR, request, &m)))
|
if (OK != (s=_taskcall(RS_PROC_NR, request, &m)))
|
||||||
failure(-s);
|
failure(-s);
|
||||||
|
else if(req_printep)
|
||||||
|
printf("%d\n", m.RS_ENDPOINT);
|
||||||
result = m.m_type;
|
result = m.m_type;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -941,13 +952,6 @@ PUBLIC int main(int argc, char **argv)
|
||||||
case RS_RESTART:
|
case RS_RESTART:
|
||||||
m.RS_CMD_ADDR = req_label;
|
m.RS_CMD_ADDR = req_label;
|
||||||
m.RS_CMD_LEN = strlen(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)))
|
if (OK != (s=_taskcall(RS_PROC_NR, request, &m)))
|
||||||
failure(-s);
|
failure(-s);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
PRIVATE int allow_newroot = 1;
|
PRIVATE int allow_newroot = 1;
|
||||||
|
|
||||||
FORWARD _PROTOTYPE( dev_t name_to_dev, (void) );
|
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) );
|
FORWARD _PROTOTYPE( int mount_fs, (endpoint_t fs_e) );
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
@ -71,7 +70,6 @@ PUBLIC int do_fslogin()
|
||||||
PUBLIC int do_mount()
|
PUBLIC int do_mount()
|
||||||
{
|
{
|
||||||
endpoint_t fs_e;
|
endpoint_t fs_e;
|
||||||
int r;
|
|
||||||
|
|
||||||
/* Only the super-user may do MOUNT. */
|
/* Only the super-user may do MOUNT. */
|
||||||
if (!super_user) return(EPERM);
|
if (!super_user) return(EPERM);
|
||||||
|
@ -86,17 +84,7 @@ PUBLIC int do_mount()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do the actual job */
|
/* Do the actual job */
|
||||||
r = mount_fs(fs_e);
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -482,7 +470,7 @@ Dev_t dev;
|
||||||
|
|
||||||
/* Find vmnt */
|
/* Find vmnt */
|
||||||
for (vmp_i = &vmnt[0]; vmp_i < &vmnt[NR_MNTS]; ++vmp_i) {
|
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);
|
if(vmp) panic(__FILE__, "device mounted more than once", dev);
|
||||||
vmp = vmp_i;
|
vmp = vmp_i;
|
||||||
}
|
}
|
||||||
|
@ -560,12 +548,6 @@ Dev_t dev;
|
||||||
vmp->m_fs_e = NONE;
|
vmp->m_fs_e = NONE;
|
||||||
vmp->m_driver_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(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,35 +578,3 @@ PRIVATE dev_t name_to_dev()
|
||||||
return res.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -792,7 +792,7 @@ endpoint_t driver_e;
|
||||||
|
|
||||||
/* Issue request */
|
/* Issue request */
|
||||||
if ((r = sendrec(fs_e, &m)) != OK) {
|
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;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -971,17 +971,19 @@ PRIVATE int fs_sendrec(endpoint_t fs_e, message *reqm)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Do the actual send, receive */
|
/* Do the actual send, receive */
|
||||||
if (OK != sendrec(fs_e, reqm)) {
|
if (OK != (r=sendrec(fs_e, reqm))) {
|
||||||
printf("VFS: error sending message. FS_e: %d req_nr: %d\n",
|
printf("VFS: error sending message. FS_e: %d req_nr: %d err: %d\n",
|
||||||
fs_e, reqm->m_type);
|
fs_e, reqm->m_type, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get response type */
|
if(r == OK) {
|
||||||
r = reqm->m_type;
|
/* Sendrec was okay */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Dead driver */
|
/* Dead driver */
|
||||||
if (r == EDEADSRCDST || r == EDSTDIED || r == ESRCDIED) {
|
if (r == EDEADSRCDST || r == EDSTDIED || r == ESRCDIED) {
|
||||||
old_driver_e = 0;
|
old_driver_e = NONE;
|
||||||
/* Find old driver enpoint */
|
/* Find old driver enpoint */
|
||||||
for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) {
|
for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) {
|
||||||
if (vmp->m_fs_e == reqm->m_source) { /* found FS */
|
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 ?? */
|
/* No FS ?? */
|
||||||
if (!old_driver_e) {
|
if (old_driver_e == NONE) {
|
||||||
panic(__FILE__, "VFSdead_driver: couldn't find FS\n",
|
panic(__FILE__, "VFSdead_driver: couldn't find FS\n",
|
||||||
old_driver_e);
|
old_driver_e);
|
||||||
}
|
}
|
||||||
|
@ -1033,12 +1035,13 @@ PRIVATE int fs_sendrec(endpoint_t fs_e, message *reqm)
|
||||||
*reqm = origm;
|
*reqm = origm;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sendrec was okay */
|
printf("fs_sendrec: unhandled error %d sending to %d\n", r, fs_e);
|
||||||
break;
|
panic(__FILE__, "fs_sendrec: unhandled error", NO_NUM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return message type */
|
/* Return message type */
|
||||||
return r;
|
return reqm->m_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ int flag; /* M3 means path may be in message */
|
||||||
|
|
||||||
if(user_fullpath[len-1] != '\0') {
|
if(user_fullpath[len-1] != '\0') {
|
||||||
int i;
|
int i;
|
||||||
printf("fetch_name: name not null-terminated: ");
|
printf("vfs: fetch_name: name not null-terminated: ");
|
||||||
for(i = 0; i < len; i++) {
|
for(i = 0; i < len; i++) {
|
||||||
printf("%c", user_fullpath[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;
|
int failed = 0;
|
||||||
*proc = _ENDPOINT_P(endpoint);
|
*proc = _ENDPOINT_P(endpoint);
|
||||||
if(*proc < 0 || *proc >= NR_PROCS) {
|
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);
|
file, line, *proc, endpoint);
|
||||||
failed = 1;
|
failed = 1;
|
||||||
} else if(fproc[*proc].fp_endpoint != endpoint) {
|
} 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",
|
"known endpoint (%d)\n",
|
||||||
file, line, *proc, endpoint, fproc[*proc].fp_endpoint);
|
file, line, *proc, endpoint, fproc[*proc].fp_endpoint);
|
||||||
failed = 1;
|
failed = 1;
|
||||||
|
|
Loading…
Reference in a new issue