#include <stdlib.h>
#include <dirent.h>
#include <string.h>
-#include <unistd.h>
#include <sys/mount.h>
+#include <unistd.h>
#include <fcntl.h>
#include <minix/config.h>
#include <minix/const.h>
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;
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;
*ap = NULL;
argc = (ap - argv);
- if (ro && swap) usage();
+ if (mountflags & MS_RDONLY && swap) usage();
if (swap) {
if (argc != 2) usage();
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]);
/* 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");
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);
#include <string.h>
#include <sys/mount.h>
+void usage(void) {
+ fprintf(stderr, "Usage: newroot [-i] <block-special>\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 <block-special>\n");
- exit(1);
+ 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];
}
- dev= argv[1];
- r= mount(dev, "/", 0 /* !ro */, NULL, NULL);
- if (r != 0)
- {
- fprintf(stderr, "newroot: mount failed: %s\n", strerror(errno));
+
+ r = mount(dev, "/", mountflags, NULL, NULL);
+ if (r != 0) {
+ fprintf(stderr, "newroot: mount failed: %s\n",strerror(errno));
exit(1);
}
+
return 0;
}
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
loadramdisk "$ramimagename"
fi
echo "Root device name is $rootdevname"
-/bin/newroot "$rootdevname"
+/bin/newroot $bin_img"$rootdevname"
exec /bin/sh /etc/rc "$@"
# 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`"
echo "Setting /usr on cd is $usr"
fi
+
# Mount the /usr partition unless this is a single floppy Minix.
if [ ! -d /usr/bin ]
then
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."
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.
* 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
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;
}
strcpy(path, FSPATH);
strcat(path, type);
+
if(stat(path, &statbuf) != 0) {
errno = EINVAL;
return -1;
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;
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) );
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 */
rp->r_nice= 0;
rp->r_exec= NULL;
+
if (do_copy)
{
s= read_exec(rp);
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;
}
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)
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);
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");
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;
{
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);
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)
{
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 */
}
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 */
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) {