all your root belongs to boot/boot - vx32 - Local 9vx git repository for patches.
       
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
 (DIR) commit 06c96392a91db65e4286fbf5b6c65a694a8c6300
 (DIR) parent 66c63641d116dca26d9fcfa7f7ad7de827bd8fd0
 (HTM) Author: Jesus Galan Lopez (yiyus) <yiyu.jgl@gmail.com>
       Date:   Fri, 25 Jun 2010 00:21:49 +0200
       
       all your root belongs to boot/boot
       
       Diffstat:
         doc/9vx.1                           |      40 +++++++++++++++++++------------
         src/9vx/a/bootboot.ed               |      58 ++++++++++++++++++++++++++++++
         src/9vx/bootcode.9                  |       0 
         src/9vx/conf.c                      |      35 ++++++++++++++-----------------
         src/9vx/conf.h                      |       6 ++++--
         src/9vx/devfs-posix.c               |      50 ++++++++-----------------------
         src/9vx/main.c                      |     107 ++++++++++++-------------------
       
       7 files changed, 155 insertions(+), 141 deletions(-)
       ---
 (DIR) diff --git a/doc/9vx.1 b/doc/9vx.1
       @@ -15,6 +15,9 @@
        t[
        .I -u user
        ]
       +t[
       +.I bootargs
       +]
        .PP
        .B 9vx-tap
        t[
       @@ -29,6 +32,9 @@
        t[
        .I -u user
        ]
       +t[
       +.I bootargs
       +]
        .SH DESCRIPTION
        Plan 9 VX (or
        .I 9vx
       @@ -45,18 +51,22 @@ Options can be passed to
        .I 9vx
        as command line arguments or in configuration files specified with the
        .I -p
       -option (see below). If no
       -.I root
       -argument is present, the current directory is used.
       -Alternatively, a file system can be specified in a 9vx.ini file.
       +option (see below). The host file server will be visible from inside as
       +.I #Z.
       +One or more
       +.I bootargs
       +arguments will be passed to boot/boot as explained in boot(8), with the addition that
       +tthe local method also supports local directories. The
       +.I -r
       +option sets
       +.I nobootprompt=local!#Z/localroot
       +tto boot from a local directory containing a Plan 9 tree.
        If an
        .I user
        is not specified, the current user in the host operating system will be used.
        Other options are:
        .nr xx \w'\fL-m\f2name\ \ '
        .TP \n(xxu
       -.BI -b
       -Run /boot/boot instead of bootscript
        .TP
        .BI -f
        Do not fork at init
       @@ -65,7 +75,9 @@ Do not fork at init
        Do not start the gui
        .TP
        .BI -i
       -Run rc instead of init
       +Run rc instead of init (sets
       +.I init=#Z/386/bin/rc
       +)
        .TP
        .BI -t
        Use tty for input/output
       @@ -101,25 +113,23 @@ A
        .I 9vx.ini
        file contains a list of
        .I parameter=value
       -pairs in a similar fasion to plan9.ini(8). Available options are
       -.I bootboot,
       +pairs in a similar fasion to plan9.ini(8). Additional options are
        .I nofork,
        .I nogui,
        .I initrc,
        .I usetty,
        .I memsize,
       -.I netdev,
       -.I macaddr
       -(that can also be part of a netdev line),
       -.I localroot
       +.I netdev
        and
       -.I user.
       -Other options will be passed to the boot process as environment variables.
       +.I macaddr
       +(that can also be part of a netdev line).
        .SH BUGS
        The menu system of plan9.ini(8) is not supported in
        .I 9vx.ini
        files.
        .P
       +kfs file systems are not supported by the included boot/boot
       +.P
        .I 9vx
        is not so stable as native Plan9 systems.
        .SH "SEE ALSO"
 (DIR) diff --git a/src/9vx/a/bootboot.ed b/src/9vx/a/bootboot.ed
       @@ -0,0 +1,58 @@
       +diff -e plan9/sys/src/9/boot/aux.c 9vx/sys/src/9/boot/aux.c
       +73,74c
       +        exits(buf);
       +.
       +diff -e plan9/sys/src/9/boot/boot.c 9vx/sys/src/9/boot/boot.c
       +154a
       +Init:
       +.
       +94a
       +        if(localroot){
       +                srvcreate("boot", fd);
       +                goto Init;
       +        }
       +.
       +6a
       +char *localroot;
       +.
       +diff -e plan9/sys/src/9/boot/boot.h 9vx/sys/src/9/boot/boot.h
       +16a
       +extern char*        localroot;
       +.
       +diff -e plan9/sys/src/9/boot/local.c 9vx/sys/src/9/boot/local.c
       +278d
       +276a
       +        if((fd = connectlocalroot()) < 0)
       +.
       +264a
       +connectlocalroot(void)
       +{
       +        int fd;
       +        char buf[1024];
       +
       +        if(stat(buf, statbuf, sizeof statbuf) < 0)
       +                return -1;
       +        localroot = disk;
       +
       +        /* create working fd for /srv/boot */
       +        fd = open("#~/mntloop", ORDWR);
       +        if(fd < 0){
       +                print("open #~/mntloop: %r\n");
       +                return -1;
       +        }
       +        write(fd, disk, strlen(disk));
       +        return fd;
       +}
       +
       +int
       +.
       +171c
       +                        return;
       +.
       +diff -e plan9/sys/src/9/pc/pcf 9vx/sys/src/9/pc/pcf
       +119a
       +        tcp
       +.
       +117,118c
       +boot boot #Z/usr/local/9vx
       +.
 (DIR) diff --git a/src/9vx/bootcode.9 b/src/9vx/bootcode.9
       Binary files differ.
 (DIR) diff --git a/src/9vx/conf.c b/src/9vx/conf.c
       @@ -12,8 +12,6 @@
        #include        "etherif.h"
        #include         "vether.h"
        
       -extern char*        localroot;
       -
        /*
         *  read configuration file
         */
       @@ -120,9 +118,7 @@ iniopt(char *name, char *value)
        
                if(*name == '*')
                        name++;
       -        if(strcmp(name, "bootboot") == 0)
       -                bootboot = 1;
       -        else if(strcmp(name, "initrc") == 0)
       +        if(strcmp(name, "initrc") == 0)
                        initrc = 1;
                else if(strcmp(name, "nofork") == 0)
                        nofork = 1;
       @@ -155,8 +151,6 @@ iniopt(char *name, char *value)
                }
                else if(strcmp(name, "macaddr") == 0)
                        setmac(value);
       -        else if(strcmp(name, "localroot") == 0 && !localroot)
       -                localroot = value;
                else if(strcmp(name, "user") == 0 && !username)
                        username = value;
        }
       @@ -172,23 +166,26 @@ inienv(char *name, char *value)
         * Debugging: tell user what options we guessed.
        */
        void
       -printconfig(char *argv0, char **inifile, int n){
       +printconfig(char *argv0){
                int i;
        
       -        print("%s ", argv0);
       -        for(i=0; i<n; i++)
       -                print("-p %s ", inifile[i]);
       -        if(bootboot | nofork | nogui | initrc | usetty)
       -                print("-%s%s%s%s%s ", bootboot ? "b" : "", nofork ? "f " : "",
       -                        nogui ? "g" : "", initrc ? "i " : "", usetty ? "t " : "");
       +        print(argv0);
       +        if(inifile)
       +                print(" -p %s", inifile);
       +        if(nofork | nogui | initrc | usetty)
       +                print(" -%s%s%s%s", nofork ? "f " : "", nogui ? "g" : "",
       +                        initrc ? "i " : "", usetty ? "t " : "");
                if(memsize != 0)
       -                print("-m %d ", memsize);
       +                print(" -m %d", memsize);
                for(i=0; i<nve; i++){
       -                print("-n %s", ve[i].tap ? "tap ": "");
       +                print(" -n %s", ve[i].tap ? "tap ": "");
                        if(ve[i].dev != nil)
       -                        print("%s ", ve[i].dev);
       +                        print(" %s", ve[i].dev);
                        if(ve[i].mac != nil)
       -                        print("-a %s ", ve[i].mac);
       +                        print(" -a %s", ve[i].mac);
                }
       -        print("-r %s -u %s\n", localroot, username);
       +        print(" -u %s", username);
       +        for(i = 0; i < bootargc; i++)
       +                print(" %s", bootargv[i]);
       +        print("\n");
        } 
       \ No newline at end of file
 (DIR) diff --git a/src/9vx/conf.h b/src/9vx/conf.h
       @@ -4,16 +4,18 @@
        
        char        inibuf[BOOTARGSLEN];
        char        *iniline[MAXCONF];
       -int        bootboot;        /* run /boot/boot instead of bootscript */
        int        initrc;        /* run rc instead of init */
        int        nofork;        /* do not fork at init */
        int        nogui;        /* do not start the gui */
        int        usetty;        /* use tty for input/output */
        int        memsize;        /* memory size */
       +int        bootargc;
       +char**        bootargv;
       +char*        inifile;
        char*        username;
        
        int        readini(char *fn);
        void        inifields(void (*fp)(char*, char*));
        void        iniopt(char*, char*);
        void        inienv(char*, char*);
       -void        printconfig(char*, char**, int);
       +void        printconfig(char*);
 (DIR) diff --git a/src/9vx/devfs-posix.c b/src/9vx/devfs-posix.c
       @@ -34,8 +34,6 @@ enum
        };
        
        extern Path *addelem(Path*, char*, Chan*);
       -char        *localroot;
       -
        static char *uidtoname(int);
        static char *gidtoname(int);
        static int nametouid(char*);
       @@ -48,12 +46,11 @@ struct UnixFd
        {
                int        fd;
                int        issocket;
       -        int        plan9;        // rooted at localroot?
                DIR*        dir;
                vlong        diroffset;
                QLock        dirlock;
                struct dirent *nextde;
       -        Path        *path;        // relative to localroot
       +        Path        *path;
        };
        
        void
       @@ -106,34 +103,20 @@ fsattach(char *spec)
                struct stat st;
                Chan *c;
                UnixFd *ufd;
       -        int plan9, dev;
       +        int dev;
                
                dev = 1;
       -        plan9 = 0;
                if(spec && spec[0]){
       -                if(strcmp(spec, "plan9") == 0) {
       -                        plan9 = 1;
       -                        dev = 2;
       -                } else{
       -                        snprint(up->genbuf, sizeof up->genbuf, "no file system #%C%s", FsChar, spec);
       -                        error(up->genbuf);
       -                }
       +                snprint(up->genbuf, sizeof up->genbuf, "no file system #%C%s", FsChar, spec);
       +                error(up->genbuf);
                }
        
       -        if(plan9){
       -                if(localroot == nil)
       -                        error("no #Zplan9 root without -r");
       -                if(stat(localroot, &st) < 0)
       -                        oserror();
       -        }else{
       -                if(stat("/", &st) < 0)
       -                        oserror();
       -        }
       +        if(stat("/", &st) < 0)
       +                oserror();
        
       -        c = devattach(FsChar, spec);
       +        c = devattach(FsChar, 0);
                ufd = mallocz(sizeof(UnixFd), 1);
                ufd->path = newpath("/");
       -        ufd->plan9 = plan9;
                ufd->fd = -1;
        
                c->aux = ufd;
       @@ -182,20 +165,11 @@ fspath(Chan *c, char *suffix)
                
                ufd = c->aux;
                s = ufd->path->s;
       -        if(ufd->plan9){
       -                len = strlen(localroot)+strlen(s)+1;
       -                if(suffix)
       -                        len += 1+strlen(suffix);
       -                t = smalloc(len);
       -                strcpy(t, localroot);
       -                strcat(t, s);
       -        }else{
       -                len = strlen(s)+1;
       -                if(suffix)
       -                        len += 1+strlen(suffix);
       -                t = smalloc(len);
       -                strcpy(t, s);
       -        }
       +        len = strlen(s)+1;
       +        if(suffix)
       +                len += 1+strlen(suffix);
       +        t = smalloc(len);
       +        strcpy(t, s);
                if(suffix){
                        if(s[strlen(s)-1] != '/')
                                strcat(t, "/");
 (DIR) diff --git a/src/9vx/main.c b/src/9vx/main.c
       @@ -49,11 +49,11 @@ int        doabort = 1;        // for now
        int        abortonfault;
        char*        argv0;
        char*        conffile = "9vx";
       +char*        localroot;
        Conf        conf;
        
        static Mach mach0;
        
       -extern char*        localroot;
        extern int        tracemmu;
        extern int tracekdev;
        extern int nuspace;
       @@ -63,12 +63,13 @@ static void        bootinit(void);
        static void        siginit(void);
        
        static char*        getuser(void);
       +static char*        nobootprompt(char*);
        
        void
        usage(void)
        {
                // TODO(yy): add debug and other options by ron
       -        fprint(2, "usage: 9vx [-p file.ini] [-bfgit] [-m memsize] [-n [tap] netdev] [-a macaddr] [-r root] [-u user]\n");
       +        fprint(2, "usage: 9vx [-p file.ini] [-fgit] [-m memsize] [-n [tap] netdev] [-a macaddr] [-r root] [-u user] [bootargs]\n");
                exit(1);
        }
        
       @@ -84,8 +85,6 @@ main(int argc, char **argv)
                int i, n;
                char *vedev;
                char *inifile[32];
       -        char cwd[1024];
       -        char buf[1024];
                
                /* Minimal set up to make print work. */
                setmach(&mach0);
       @@ -93,7 +92,6 @@ main(int argc, char **argv)
                quotefmtinstall();
        
                memset(iniline, 0, MAXCONF);
       -        localroot = nil;
                memsize = 0;
                n = 0;
                nogui = 0;
       @@ -134,9 +132,6 @@ main(int argc, char **argv)
                case 'a':
                        setmac(EARGF(usage()));
                        break;
       -        case 'b':
       -                bootboot = 1;
       -                break;
                case 'f':
                        nofork = 1;
                        break;
       @@ -176,30 +171,24 @@ main(int argc, char **argv)
                default:
                        usage();
                }ARGEND
       -        
       -        if(argc != 0)
       -                usage();
        
                /*
                 * Loop in reverse direction to overwrite older options
                 */
       -        for(i=n-1; i>=0; i--)
       +        for(i = n-1; i >= 0; i--)
                        if(readini(inifile[i]) != 0)
                                panic("error reading config file %s", inifile[i]);
        
       -        inifields(&iniopt);
       -
       -        if(!bootboot){
       -                if(localroot == nil){
       -                        if(getcwd(cwd, sizeof cwd) == nil)
       -                                panic("getcwd: %r");
       -                        localroot = cwd;
       -                }
       -                snprint(buf, sizeof buf, "%s/386/bin/rc", localroot);
       -                if(access(buf, 0) < 0)
       -                        panic("%s does not exist", buf);
       -        }
       +        bootargc = argc;
       +        bootargv = argv;
       +        /*
       +         * bootargs have preference over -r
       +         */
       +        if(bootargc > 0)
       +                localroot = nil;
        
       +        inifields(&iniopt);
       +        
                if(username == nil && (username = getuser()) == nil)
                        username = "tor";
                eve = strdup(username);
       @@ -230,7 +219,7 @@ main(int argc, char **argv)
                 */
                siginit();
        
       -        printconfig(argv0, inifile, n);
       +        printconfig(argv0);
        
                if(nve == 0)
                        ipdevtab = pipdevtab;
       @@ -266,6 +255,18 @@ main(int argc, char **argv)
                return 0;  // Not reached
        }
        
       +char*
       +nobootprompt(char *root) {
       +        char cwd[1024];
       +
       +        if(root[0] != '/'){
       +                if(getcwd(cwd, sizeof cwd) == nil)
       +                        panic("getcwd: %r");
       +                root = cleanname(smprint("%s/%s", cwd, root));
       +        }
       +        return smprint("local!#Z%s", root);
       +}
       +
        static char*
        getuser(void)
        {
       @@ -298,22 +299,6 @@ confinit(void)
                conf.ialloc = 1<<20;
        }
        
       -/*
       - * Simple boot script.  Init0 takes care of setting up the
       - * environment variables and name space bindings that
       - * are needed to run rc and /386/init. 
       - * Can't use #!/386/init -t directly, because init will treat
       - * the extra argument /boot/boot as a command to run,
       - * which will cause a loop.
       - */
       -static char *bootscript =
       -        "#!/386/bin/rc\n"
       -        "exec /386/init -t\n";
       -
       -static char *rcscript =
       -        "#!/386/bin/rc\n"
       -        "/386/bin/rc -i\n";
       -
        static void
        bootinit(void)
        {
       @@ -322,7 +307,14 @@ bootinit(void)
                 * to ask for keys, so we have to embed a factotum binary,
                 * even if we don't execute it to provide a file system.
                 * Also, maybe /boot/boot needs it.
       +         *
       +         * factotum, fossil and venti are the normal Plan9 binary.
       +         * bootcode.9 is the file bootpcf.out obtained applyng
       +         * the patch in a/bootboot.ed and compiling with:
       +         *        mk 'CONF=pcf' bootpcf.out
                 */
       +        extern uchar bootcode[];
       +        extern long bootlen;
                extern uchar factotumcode[];
                extern long factotumlen;
                extern uchar fossilcode[];
       @@ -330,14 +322,7 @@ bootinit(void)
                extern uchar venticode[];
                extern long ventilen;
        
       -        if(bootboot){
       -                extern uchar bootcode[];
       -                extern long bootlen;
       -                addbootfile("boot", bootcode, bootlen);
       -        }else if(initrc)
       -                addbootfile("boot", (uchar*)rcscript, strlen(rcscript));
       -        else
       -                addbootfile("boot", (uchar*)bootscript, strlen(bootscript));
       +        addbootfile("boot", bootcode, bootlen);
                addbootfile("factotum", factotumcode, factotumlen);
                addbootfile("fossil", fossilcode, fossillen);
                addbootfile("venti", venticode, ventilen);
       @@ -434,7 +419,8 @@ bootargs(void *base)
        
                ac = 0;
                av[ac++] = pusharg("9vx");
       -        /* TODO: could use command line argc, argv here if it was useful */
       +        for(i = 0; i < bootargc && ac < 32; i++)
       +                av[ac++] = pusharg(bootargv[i]);
        
                /* 4 byte word align stack */
                sp = (uchar*)((uintptr)sp & ~3);
       @@ -480,8 +466,6 @@ static void
        init0(void)
        {
                char buf[2*KNAMELEN];
       -        Chan *c, *srvc;
       -        char *root;
        
                up->nerrlab = 0;
                if(waserror())
       @@ -512,21 +496,10 @@ init0(void)
                ksetenv("user", username, 0);
                ksetenv("sysname", "vx32", 0);
                inifields(&inienv);
       -
       -        /* if we're not running /boot/boot, mount / and create /srv/boot */
       -        if(!bootboot){
       -                kbind("#Zplan9/", "/", MAFTER);
       -                kbind("#p", "/proc", MREPL);
       -
       -                /* create working /srv/boot for backward compatibility */
       -                c = namec("#~/mntloop", Aopen, ORDWR, 0);
       -                root = "#Zplan9/";
       -                devtab[c->type]->write(c, root, strlen(root), 0);
       -                srvc = namec("#s/boot", Acreate, OWRITE, 0666);
       -                ksrvadd(srvc, c);
       -                cclose(srvc);
       -                cclose(c);
       -        }
       +        if(initrc != 0)
       +                inienv("init", "/386/bin/rc -i");
       +        if(localroot)
       +                inienv("nobootprompt", nobootprompt(localroot));
        
                poperror();