123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- #include <u.h>
- #include <libc.h>
- #include <../boot/boot.h>
- static char diskname[64];
- static char *disk;
- static char **args;
- void
- configlocal(Method *mp)
- {
- char *p, *inibootdisk;
- int n;
- inibootdisk = getenv("bootdisk");
- if(*sys == '/' || *sys == '#'){
- /*
- * if the user specifies the disk in the boot cmd or
- * 'root is from' prompt, use it
- */
- disk = sys;
- } else if(strncmp(argv0, "dksc(0,", 7) == 0){
- /*
- * on many mips arg0 of the boot command specifies the
- * scsi logical unit number
- */
- p = strchr(argv0, ',');
- n = strtoul(p+1, 0, 10);
- sprint(diskname, "#w%d/sd%dfs", n, n);
- disk = diskname;
- } else if(mp->arg){
- /*
- * a default is optionally supplied when the kernel is made
- */
- disk = mp->arg;
- } else if(inibootdisk != nil && *inibootdisk)
- /* plan9.ini overrides default from config file */
- disk = inibootdisk;
- else if(bootdisk != nil && *bootdisk){
- /*
- * an environment variable from a pc's plan9.ini or
- * from the mips nvram or generated by the kernel
- * is the last resort.
- */
- disk = bootdisk;
- }
- /* if we've decided on one, pass it on to all programs */
- if(disk) {
- bootdisk = disk;
- setenv("bootdisk", bootdisk);
- }
- }
- int
- connectlocalkfs(void)
- {
- int i, pid, fd, p[2];
- char partition[64];
- char *dev;
- char **arg, **argp;
- Dir *d;
- if(stat("/boot/kfs", statbuf, sizeof statbuf) < 0)
- return -1;
- dev = disk ? disk : bootdisk;
- snprint(partition, sizeof partition, "%sfs", dev);
- fd = open(partition, OREAD);
- if(fd < 0){
- strcpy(partition, dev);
- fd = open(partition, OREAD);
- if(fd < 0)
- return -1;
- }
- /*
- * can't do this check -- might be some other server posing as kfs.
- *
- memset(buf, 0, sizeof buf);
- pread(fd, buf, 512, 0);
- close(fd);
- if(memcmp(buf+256, "kfs wren device\n", 16) != 0){
- if(strstr(partition, "/fs"))
- print("no kfs file system found on %s\n", partition);
- return -1;
- }
- *
- */
- d = dirfstat(fd);
- close(fd);
- if(d == nil)
- return -1;
- if(d->mode&DMDIR){
- free(d);
- return -1;
- }
- free(d);
- print("kfs...");
- if(pipe(p)<0)
- fatal("pipe");
- switch(pid = fork()){
- case -1:
- fatal("fork");
- case 0:
- arg = malloc((bargc+5)*sizeof(char*));
- argp = arg;
- *argp++ = "kfs";
- *argp++ = "-f";
- *argp++ = partition;
- *argp++ = "-s";
- for(i=1; i<bargc; i++)
- *argp++ = bargv[i];
- *argp = 0;
- dup(p[0], 0);
- dup(p[1], 1);
- close(p[0]);
- close(p[1]);
- exec("/boot/kfs", arg);
- fatal("can't exec kfs");
- default:
- break;
- }
- for(;;){
- if((i = waitpid()) == -1)
- fatal("waitpid for kfs failed");
- if(i == pid)
- break;
- }
- close(p[1]);
- return p[0];
- }
- void
- runv(char **argv)
- {
- int i, pid;
- switch(pid = fork()){
- case -1:
- fatal("fork");
- case 0:
- exec(argv[0], argv);
- fatal(smprint("can't exec %s: %r", argv[0]));
- default:
- while ((i = waitpid()) != pid && i != -1)
- ;
- if(i == -1)
- fatal(smprint("wait failed running %s", argv[0]));
- }
- }
- void
- run(char *file, ...)
- {
- runv(&file);
- }
- static int
- print1(int fd, char *s)
- {
- return write(fd, s, strlen(s));
- }
- void
- configloopback(void)
- {
- int fd;
- if((fd = open("/net/ipifc/clone", ORDWR)) < 0){
- bind("#I", "/net", MAFTER);
- if((fd = open("/net/ipifc/clone", ORDWR)) < 0)
- fatal("open /net/ipifc/clone for loopback");
- }
- if(print1(fd, "bind loopback /dev/null") < 0
- || print1(fd, "add 127.0.0.1 255.255.255.255") < 0)
- fatal("write /net/ipifc/clone for loopback");
- }
- int
- connectlocalfossil(void)
- {
- int fd;
- char *venti, *f[32], *p;
- int nf;
- char partition[128], buf[512];
- char *dev;
- if(stat("/boot/fossil", statbuf, sizeof statbuf) < 0)
- return -1;
- /* look for fossil partition */
- dev = disk ? disk : bootdisk;
- snprint(partition, sizeof partition, "%sfossil", dev);
- fd = open(partition, OREAD);
- if(fd < 0){
- strcpy(partition, dev);
- fd = open(partition, OREAD);
- if(fd < 0)
- return -1;
- }
- memset(buf, 0, sizeof buf);
- pread(fd, buf, 512, 127*1024);
- close(fd);
- if(memcmp(buf, "fossil config\n", 14) != 0){
- if(strstr(partition, "/fossil"))
- print("no fossil config found on %s\n", partition);
- return -1;
- }
- settime(1, -1, nil);
- /* make venti available. give it 20% of free memory. */
- if((venti = getenv("venti")) && (nf = tokenize(venti, f, nelem(f)))){
- if((fd = open(f[0], OREAD)) >= 0){
- print("venti...");
- memset(buf, 0, sizeof buf);
- pread(fd, buf, 512, 248*1024);
- close(fd);
- if(memcmp(buf, "venti config\n", 13) != 0){
- print("no venti config found on %s\n", f[0]);
- return -1;
- }
- if(stat("/boot/venti", statbuf, sizeof statbuf) < 0){
- print("/boot/venti does not exist\n");
- return -1;
- }
- switch(nf){
- case 1:
- f[1] = "tcp!127.1!17034";
- case 2:
- f[2] = "tcp!127.1!8000";
- }
- configloopback();
- run("/boot/venti", "-m", "20", "-c", f[0],
- "-a", f[1], "-h", f[2], nil);
- /*
- * If the announce address is tcp!*!foo, then set
- * $venti to tcp!127.1!foo instead, which is actually dialable.
- */
- if((p = strstr(f[1], "!*!")) != 0){
- *p = 0;
- snprint(buf, sizeof buf, "%s!127.1!%s", f[1], p+3);
- f[1] = buf;
- }
- setenv("venti", f[1]);
- }else{
- /* set up the network so we can talk to the venti server */
- /* this is such a crock. */
- configip(nf, f, 0);
- setenv("venti", f[0]);
- }
- }
- /* start fossil. give it 20% of free memory. */
- print("fossil(%s)...", partition);
- run("/boot/fossil", "-m", "20", "-f", partition,
- "-c", "srv -A fboot", "-c", "srv -p fscons", nil);
- fd = open("#s/fboot", ORDWR);
- if(fd < 0){
- warning("open #s/fboot");
- return -1;
- }
- remove("#s/fboot"); /* we'll repost fd as #s/boot after fversion(fd) */
- return fd;
- }
- int
- connectlocal(void)
- {
- int fd;
- if(bind("#c", "/dev", MREPL) < 0)
- fatal("bind #c");
- if(bind("#p", "/proc", MREPL) < 0)
- fatal("bind #p");
- bind("#S", "/dev", MAFTER);
- bind("#k", "/dev", MAFTER);
- bind("#u", "/dev", MAFTER);
- bind("#æ", "/dev", MAFTER);
- mountusbparts(); /* make partfs partitions visible again */
- if((fd = connectlocalfossil()) < 0)
- fd = connectlocalkfs();
- return fd;
- }
|