diff --git a/commands/simple/mount.c b/commands/simple/mount.c index 911407bf3..f89d06875 100755 --- a/commands/simple/mount.c +++ b/commands/simple/mount.c @@ -6,8 +6,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -31,12 +31,12 @@ int main(argc, argv) int argc; char *argv[]; { - int i, ro, swap, n, v; + int i, swap, n, v, mountflags; char **ap, *vs, *opt, *err, *type, *args; char special[PATH_MAX+1], mounted_on[PATH_MAX+1], version[10], rw_flag[10]; if (argc == 1) list(); /* just list /etc/mtab */ - ro = 0; + mountflags = 0; swap = 0; type = NULL; args = NULL; @@ -45,11 +45,12 @@ char *argv[]; if (argv[i][0] == '-') { opt = argv[i]+1; while (*opt != 0) switch (*opt++) { - case 'r': ro = 1; break; - case 's': swap = 1; break; + case 'r': mountflags |= MS_RDONLY; break; + case 's': swap = 1; break; case 't': if (++i == argc) usage(); type = argv[i]; break; + case 'i': mountflags |= MS_REUSE; break; case 'o': if (++i == argc) usage(); args = argv[i]; break; @@ -62,7 +63,7 @@ char *argv[]; *ap = NULL; argc = (ap - argv); - if (ro && swap) usage(); + if (mountflags & MS_RDONLY && swap) usage(); if (swap) { if (argc != 2) usage(); @@ -71,7 +72,7 @@ char *argv[]; tell(" is swapspace\n"); } else { if (argc != 3) usage(); - if (mount(argv[1], argv[2], ro, type, args) < 0) { + if (mount(argv[1], argv[2], mountflags, type, args) < 0) { err = strerror(errno); std_err("mount: Can't mount "); std_err(argv[1]); @@ -85,7 +86,7 @@ char *argv[]; /* The mount has completed successfully. Tell the user. */ tell(argv[1]); tell(" is read-"); - tell(ro ? "only" : "write"); + tell(mountflags & MS_RDONLY ? "only" : "write"); tell(" mounted on "); tell(argv[2]); tell("\n"); @@ -127,7 +128,8 @@ char *argv[]; vs = "-"; } } - n = put_mtab_entry(argv[1], swap ? "swap" : argv[2], vs, (ro ? "ro" : "rw") ); + n = put_mtab_entry(argv[1], swap ? "swap" : argv[2], vs, + (mountflags & MS_RDONLY ? "ro" : "rw") ); if (n < 0) { std_err("mount: /etc/mtab has grown too large\n"); exit(1); diff --git a/commands/simple/newroot.c b/commands/simple/newroot.c index 0fa1fd77e..e6ea8cc27 100644 --- a/commands/simple/newroot.c +++ b/commands/simple/newroot.c @@ -10,22 +10,36 @@ Replace the current root with a new one #include #include +void usage(void) { + fprintf(stderr, "Usage: newroot [-i] \n"); + fprintf(stderr, "-i: copy mfs binary from boot image to memory\n"); + exit(1); +} + int main(int argc, char *argv[]) { int r; char *dev; + int mountflags; - if (argc != 2) - { - fprintf(stderr, "Usage: newroot \n"); - exit(1); - } - dev= argv[1]; - r= mount(dev, "/", 0 /* !ro */, NULL, NULL); - if (r != 0) - { - fprintf(stderr, "newroot: mount failed: %s\n", strerror(errno)); + r = 0; + mountflags = 0; /* !read-only */ + + if (argc != 2 && argc != 3) usage(); + if(argc == 2) { + dev = argv[1]; + } else if(argc == 3) { + /* -i flag was supposedly entered. Verify.*/ + if(strcmp(argv[1], "-i") != 0) usage(); + mountflags |= MS_REUSE; + dev = argv[2]; + } + + r = mount(dev, "/", mountflags, NULL, NULL); + if (r != 0) { + fprintf(stderr, "newroot: mount failed: %s\n",strerror(errno)); exit(1); } + return 0; } diff --git a/drivers/memory/ramdisk/rc b/drivers/memory/ramdisk/rc index 6446da30f..4a28f9a10 100644 --- a/drivers/memory/ramdisk/rc +++ b/drivers/memory/ramdisk/rc @@ -20,6 +20,11 @@ rootdev=`sysenv rootdev` || echo 'No rootdev?' rootdevname=`/bin/dev2name "$rootdev"` || { echo 'No device name for root device'; exit 1; } +if [ "`sysenv bin_img`" = 1 ] +then + bin_img="-i " +fi + if sysenv cdproberoot >/dev/null then echo @@ -40,5 +45,5 @@ then loadramdisk "$ramimagename" fi echo "Root device name is $rootdevname" -/bin/newroot "$rootdevname" +/bin/newroot $bin_img"$rootdevname" exec /bin/sh /etc/rc "$@" diff --git a/etc/rc b/etc/rc index e73217e19..4e9b0286e 100755 --- a/etc/rc +++ b/etc/rc @@ -73,6 +73,12 @@ start) # Any swapspace on a device? test "$swap" : '/dev/' && mount -s $swap + # Use MFS binary only from kernel image? + if [ "`sysenv bin_img`" = 1 ] + then + bin_img="-i " + fi + # Are we booting from CD? bootcd="`/bin/sysenv bootcd`" @@ -89,6 +95,7 @@ start) echo "Setting /usr on cd is $usr" fi + # Mount the /usr partition unless this is a single floppy Minix. if [ ! -d /usr/bin ] then @@ -101,7 +108,8 @@ start) echo "usr=/dev/$usr" >/tmp/usr' . /tmp/usr fi - mount $usr_roflag $usr /usr || { + + mount $bin_img $usr_roflag $usr /usr || { echo "\ Please try to mount something else as /usr, then hit CTRL-D to continue startup. Mount $usr /usr failed -- Single user." @@ -129,11 +137,11 @@ Mount $usr /usr failed -- Single user." then echo "fsck /home - $home" intr fsck -r $home fi - mount $usr /usr + mount $bin_img $usr /usr fi if [ ! -z "$home" ] - then mount $home /home || echo "WARNING: couldn't mount $home on /home" + then mount $bin_img $home /home || echo "WARNING: couldn't mount $home on /home" fi # This file is necessary for above 'shutdown -C' check. diff --git a/include/minix/rs.h b/include/minix/rs.h index 29012b4f3..543f9a8cf 100644 --- a/include/minix/rs.h +++ b/include/minix/rs.h @@ -41,6 +41,7 @@ struct rs_start * to restart the driver without accessing FS */ #define RF_IPC_VALID 0x02 /* rss_ipc and rss_ipclen are valid */ +#define RF_REUSE 0x04 /* Try to reuse previously copied binary */ #define RSP_LABEL_SIZE 16 #define RSP_NR_DEVICE 16 diff --git a/lib/other/_mount.c b/lib/other/_mount.c index 16975923c..8b093157c 100755 --- a/lib/other/_mount.c +++ b/lib/other/_mount.c @@ -66,6 +66,12 @@ int mountflags; if (args == NULL) args = ""; reuse = 0; + /* Check mount flags */ + if(mountflags & MS_REUSE) { + reuse = 1; + mountflags &= ~MS_REUSE; /* Temporary: turn off to not confuse VFS */ + } + /* Make FS process label for RS from special name. */ if(!(label=makelabel(special))) { return -1; @@ -78,6 +84,7 @@ int mountflags; } strcpy(path, FSPATH); strcat(path, type); + if(stat(path, &statbuf) != 0) { errno = EINVAL; return -1; @@ -95,19 +102,17 @@ int mountflags; return -1; } - if(mountflags & MS_REUSE) { - reuse = 1; - mountflags &= ~MS_REUSE; /* Temporary: turn off to not confuse VFS */ - } - sprintf(cmd, _PATH_SERVICE " up %s -label '%s' -config " _PATH_DRIVERS_CONF + + sprintf(cmd, _PATH_SERVICE " %sup %s -label '%s' -config " _PATH_DRIVERS_CONF " -args '%s%s' -printep yes", - path, label, args[0] ? "-o " : "", args); + reuse ? "-r ": "", path, label, args[0] ? "-o " : "", args); 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; diff --git a/servers/rs/manager.c b/servers/rs/manager.c index 351b6c603..49b4f17f4 100644 --- a/servers/rs/manager.c +++ b/servers/rs/manager.c @@ -29,6 +29,8 @@ FORWARD _PROTOTYPE( int start_service, (struct rproc *rp, int flags, FORWARD _PROTOTYPE( int stop_service, (struct rproc *rp,int how) ); FORWARD _PROTOTYPE( int fork_nb, (void) ); FORWARD _PROTOTYPE( int read_exec, (struct rproc *rp) ); +FORWARD _PROTOTYPE( int copy_exec, (struct rproc *rp_src, + struct rproc *rp_dst) ); FORWARD _PROTOTYPE( void run_script, (struct rproc *rp) ); FORWARD _PROTOTYPE( char *get_next_label, (char *ptr, char *label, char *caller_label) ); @@ -66,8 +68,6 @@ int flags; /* extra flags, if any */ int r; endpoint_t ep; /* new endpoint no. */ -printf("RS: in do_up\n"); - /* See if there is a free entry in the table with system processes. */ for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) { rp = &rproc[slot_nr]; /* get pointer to slot */ @@ -122,6 +122,7 @@ printf("RS: in do_up\n"); rp->r_nice= 0; rp->r_exec= NULL; + if (do_copy) { s= read_exec(rp); @@ -283,9 +284,32 @@ message *m_ptr; /* request message pointer */ rp->r_ipc_list[0]= '\0'; rp->r_exec= NULL; - if (rs_start.rss_flags & RF_COPY) - { - s= read_exec(rp); + if (rs_start.rss_flags & RF_COPY) { + int exst_cpy; + struct rproc *rp2; + exst_cpy = 0; + + if(rs_start.rss_flags & RF_REUSE) { + char *cmd = rp->r_cmd; + int i; + + for(i = 0; i < NR_SYS_PROCS; i++) { + rp2 = &rproc[i]; + if(strcmp(rp->r_cmd, rp2->r_cmd) == 0 && + rp2->r_exec != NULL) { + /* We have found the same binary that's + * already been copied */ + exst_cpy = 1; + break; + } + } + } + + if(!exst_cpy) + s = read_exec(rp); + else + s = copy_exec(rp, rp2); + if (s != OK) return s; } @@ -405,9 +429,9 @@ PUBLIC int do_down(message *m_ptr) if (rp->r_flags & RS_IN_USE && strcmp(rp->r_label, label) == 0) { if(rs_verbose) printf("RS: stopping '%s' (%d)\n", label, rp->r_pid); - stop_service(rp,RS_EXITING); - if (rp->r_pid == -1) - { + stop_service(rp,RS_EXITING); + if (rp->r_pid == -1) + { /* Process is already gone */ rp->r_flags = 0; /* release slot */ if (rp->r_exec) @@ -418,12 +442,12 @@ PUBLIC int do_down(message *m_ptr) proc = _ENDPOINT_P(rp->r_proc_nr_e); rproc_ptr[proc] = NULL; return(OK); - } + } - /* Late reply - send a reply when process dies. */ - rp->r_flags |= RS_LATEREPLY; - rp->r_caller = m_ptr->m_source; - return EDONTREPLY; + /* Late reply - send a reply when process dies. */ + rp->r_flags |= RS_LATEREPLY; + rp->r_caller = m_ptr->m_source; + return EDONTREPLY; } } if(rs_verbose) printf("RS: do_down: '%s' not found\n", label); @@ -762,8 +786,7 @@ endpoint_t *endpoint; message m; use_copy= (rp->r_exec != NULL); - - + /* Now fork and branch for parent and child process (and check for error). */ if (use_copy) { if(rs_verbose) printf("RS: fork_nb..\n"); @@ -940,6 +963,23 @@ PRIVATE pid_t fork_nb() return(_syscall(PM_PROC_NR, FORK_NB, &m)); } +PRIVATE int copy_exec(rp_dst, rp_src) +struct rproc *rp_dst, *rp_src; +{ + /* Copy binary from rp_src to rp_dst. */ + rp_dst->r_exec_len = rp_src->r_exec_len; + rp_dst->r_exec = malloc(rp_dst->r_exec_len); + if(rp_dst->r_exec == NULL) + return ENOMEM; + + memcpy(rp_dst->r_exec, rp_src->r_exec, rp_dst->r_exec_len); + if(rp_dst->r_exec_len != 0 && rp_dst->r_exec != NULL) + return OK; + + rp_dst->r_exec = NULL; + return EIO; +} + PRIVATE int read_exec(rp) struct rproc *rp; { @@ -947,9 +987,10 @@ struct rproc *rp; char *e_name; struct stat sb; + e_name= rp->r_argv[0]; r= stat(e_name, &sb); - if (r != 0) + if (r != 0) return -errno; fd= open(e_name, O_RDONLY); diff --git a/servers/rs/service.c b/servers/rs/service.c index 2351b4f77..3e0251d41 100644 --- a/servers/rs/service.c +++ b/servers/rs/service.c @@ -133,10 +133,11 @@ PRIVATE int parse_arguments(int argc, char **argv) char *hz; int req_nr; int c, i; - int c_flag; + int c_flag, r_flag; - c_flag= 0; - while (c= getopt(argc, argv, "ci?"), c != -1) + c_flag = 0; + r_flag = 0; + while (c= getopt(argc, argv, "rci?"), c != -1) { switch(c) { @@ -144,7 +145,11 @@ PRIVATE int parse_arguments(int argc, char **argv) print_usage(argv[ARG_NAME], "wrong number of arguments"); exit(EINVAL); case 'c': - c_flag= 1; + c_flag = 1; + break; + case 'r': + c_flag = 1; /* -r implies -c */ + r_flag = 1; break; case 'i': /* Legacy - remove later */ @@ -184,13 +189,15 @@ PRIVATE int parse_arguments(int argc, char **argv) } if (req_nr == RS_UP) { - - req_nr= RS_START; + req_nr= RS_START; rs_start.rss_flags= RF_IPC_VALID; if (c_flag) rs_start.rss_flags |= RF_COPY; + if(r_flag) + rs_start.rss_flags |= RF_REUSE; + if (do_run) { /* Set default recovery script for RUN */ @@ -198,8 +205,10 @@ PRIVATE int parse_arguments(int argc, char **argv) req_nr = RS_START; } +#if 0 if (req_nr == RS_UP && c_flag) req_nr= RS_UP_COPY; +#endif /* Verify argument count. */ if (argc - 1 < optind+ARG_PATH) {