Added a hack to start binaries from the boot image only. In particular, setting
bin_img=1 in the boot monitor will make sure that during the boot procedure the mfs binary that is part of the boot image is the only binary that is used to mount partitions. This is useful when for some reason the mfs binary on disk malfunctions, rendering Minix unable to boot. By setting bin_img=1, the binary on disk is ignored and the binary in the boot image is used instead. - 'service' now accepts an additional flag -r. -r implies -c. -r instructs RS to first look in memory if the binary has already been copied to memory and execute that version, instead of loading the binary from disk. For example, the first time a MFS is being started it is copied (-c) to memory and executed from there. The second time MFS is being started this way, RS will look in memory for a previously copied MFS binary and reuse it if it exists. - The mount and newroot commands now accept an additional flag -i, which instructs them to set the MS_REUSE flag in the mount flags. - The mount system call now supports the MS_REUSE flag and invokes 'service' with the -r flag when MS_REUSE is set. - /etc/rc and the rc script that's included in the boot image check for the existence of the bin_img flag in the boot monitor, and invoke mount and newroot with the -i flag accordingly.
This commit is contained in:
parent
47a2bfeddd
commit
b47483433c
8 changed files with 136 additions and 51 deletions
|
@ -6,8 +6,8 @@
|
|||
#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>
|
||||
|
@ -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 '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);
|
||||
|
|
|
@ -10,22 +10,36 @@ Replace the current root with a new one
|
|||
#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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 "$@"
|
||||
|
|
14
etc/rc
14
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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -763,7 +787,6 @@ endpoint_t *endpoint;
|
|||
|
||||
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,6 +987,7 @@ struct rproc *rp;
|
|||
char *e_name;
|
||||
struct stat sb;
|
||||
|
||||
|
||||
e_name= rp->r_argv[0];
|
||||
r= stat(e_name, &sb);
|
||||
if (r != 0)
|
||||
|
|
|
@ -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;
|
||||
|
||||
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) {
|
||||
|
|
Loading…
Reference in a new issue