19ef1f84bSDavid du Colombier #include <u.h>
29ef1f84bSDavid du Colombier #include <libc.h>
39ef1f84bSDavid du Colombier #include <../boot/boot.h>
49ef1f84bSDavid du Colombier
59ef1f84bSDavid du Colombier static char diskname[64];
69ef1f84bSDavid du Colombier static char *disk;
79ef1f84bSDavid du Colombier static char **args;
89ef1f84bSDavid du Colombier
99ef1f84bSDavid du Colombier void
configlocal(Method * mp)109ef1f84bSDavid du Colombier configlocal(Method *mp)
119ef1f84bSDavid du Colombier {
12*532111f7SDavid du Colombier char *p, *inibootdisk;
139ef1f84bSDavid du Colombier int n;
149ef1f84bSDavid du Colombier
15*532111f7SDavid du Colombier inibootdisk = getenv("bootdisk");
169ef1f84bSDavid du Colombier if(*sys == '/' || *sys == '#'){
179ef1f84bSDavid du Colombier /*
189ef1f84bSDavid du Colombier * if the user specifies the disk in the boot cmd or
199ef1f84bSDavid du Colombier * 'root is from' prompt, use it
209ef1f84bSDavid du Colombier */
219ef1f84bSDavid du Colombier disk = sys;
229ef1f84bSDavid du Colombier } else if(strncmp(argv0, "dksc(0,", 7) == 0){
239ef1f84bSDavid du Colombier /*
249ef1f84bSDavid du Colombier * on many mips arg0 of the boot command specifies the
259ef1f84bSDavid du Colombier * scsi logical unit number
269ef1f84bSDavid du Colombier */
279ef1f84bSDavid du Colombier p = strchr(argv0, ',');
289ef1f84bSDavid du Colombier n = strtoul(p+1, 0, 10);
299ef1f84bSDavid du Colombier sprint(diskname, "#w%d/sd%dfs", n, n);
309ef1f84bSDavid du Colombier disk = diskname;
319ef1f84bSDavid du Colombier } else if(mp->arg){
329ef1f84bSDavid du Colombier /*
33*532111f7SDavid du Colombier * a default is optionally supplied when the kernel is made
349ef1f84bSDavid du Colombier */
359ef1f84bSDavid du Colombier disk = mp->arg;
36*532111f7SDavid du Colombier } else if(inibootdisk != nil && *inibootdisk)
37*532111f7SDavid du Colombier /* plan9.ini overrides default from config file */
38*532111f7SDavid du Colombier disk = inibootdisk;
39*532111f7SDavid du Colombier else if(bootdisk != nil && *bootdisk){
409ef1f84bSDavid du Colombier /*
419ef1f84bSDavid du Colombier * an environment variable from a pc's plan9.ini or
429ef1f84bSDavid du Colombier * from the mips nvram or generated by the kernel
439ef1f84bSDavid du Colombier * is the last resort.
449ef1f84bSDavid du Colombier */
459ef1f84bSDavid du Colombier disk = bootdisk;
469ef1f84bSDavid du Colombier }
479ef1f84bSDavid du Colombier
489ef1f84bSDavid du Colombier /* if we've decided on one, pass it on to all programs */
49*532111f7SDavid du Colombier if(disk) {
50*532111f7SDavid du Colombier bootdisk = disk;
51*532111f7SDavid du Colombier setenv("bootdisk", bootdisk);
52*532111f7SDavid du Colombier }
539ef1f84bSDavid du Colombier }
549ef1f84bSDavid du Colombier
559ef1f84bSDavid du Colombier int
connectlocalkfs(void)569ef1f84bSDavid du Colombier connectlocalkfs(void)
579ef1f84bSDavid du Colombier {
589ef1f84bSDavid du Colombier int i, pid, fd, p[2];
599ef1f84bSDavid du Colombier char partition[64];
609ef1f84bSDavid du Colombier char *dev;
619ef1f84bSDavid du Colombier char **arg, **argp;
629ef1f84bSDavid du Colombier Dir *d;
639ef1f84bSDavid du Colombier
649ef1f84bSDavid du Colombier if(stat("/boot/kfs", statbuf, sizeof statbuf) < 0)
659ef1f84bSDavid du Colombier return -1;
669ef1f84bSDavid du Colombier
679ef1f84bSDavid du Colombier dev = disk ? disk : bootdisk;
689ef1f84bSDavid du Colombier snprint(partition, sizeof partition, "%sfs", dev);
699ef1f84bSDavid du Colombier fd = open(partition, OREAD);
709ef1f84bSDavid du Colombier if(fd < 0){
719ef1f84bSDavid du Colombier strcpy(partition, dev);
729ef1f84bSDavid du Colombier fd = open(partition, OREAD);
739ef1f84bSDavid du Colombier if(fd < 0)
749ef1f84bSDavid du Colombier return -1;
759ef1f84bSDavid du Colombier }
769ef1f84bSDavid du Colombier /*
779ef1f84bSDavid du Colombier * can't do this check -- might be some other server posing as kfs.
789ef1f84bSDavid du Colombier *
799ef1f84bSDavid du Colombier memset(buf, 0, sizeof buf);
809ef1f84bSDavid du Colombier pread(fd, buf, 512, 0);
819ef1f84bSDavid du Colombier close(fd);
829ef1f84bSDavid du Colombier if(memcmp(buf+256, "kfs wren device\n", 16) != 0){
839ef1f84bSDavid du Colombier if(strstr(partition, "/fs"))
849ef1f84bSDavid du Colombier print("no kfs file system found on %s\n", partition);
859ef1f84bSDavid du Colombier return -1;
869ef1f84bSDavid du Colombier }
879ef1f84bSDavid du Colombier *
889ef1f84bSDavid du Colombier */
899ef1f84bSDavid du Colombier d = dirfstat(fd);
909ef1f84bSDavid du Colombier close(fd);
919ef1f84bSDavid du Colombier if(d == nil)
929ef1f84bSDavid du Colombier return -1;
939ef1f84bSDavid du Colombier if(d->mode&DMDIR){
949ef1f84bSDavid du Colombier free(d);
959ef1f84bSDavid du Colombier return -1;
969ef1f84bSDavid du Colombier }
979ef1f84bSDavid du Colombier free(d);
989ef1f84bSDavid du Colombier
999ef1f84bSDavid du Colombier print("kfs...");
1009ef1f84bSDavid du Colombier if(pipe(p)<0)
1019ef1f84bSDavid du Colombier fatal("pipe");
1029ef1f84bSDavid du Colombier switch(pid = fork()){
1039ef1f84bSDavid du Colombier case -1:
1049ef1f84bSDavid du Colombier fatal("fork");
1059ef1f84bSDavid du Colombier case 0:
1069ef1f84bSDavid du Colombier arg = malloc((bargc+5)*sizeof(char*));
1079ef1f84bSDavid du Colombier argp = arg;
1089ef1f84bSDavid du Colombier *argp++ = "kfs";
1099ef1f84bSDavid du Colombier *argp++ = "-f";
1109ef1f84bSDavid du Colombier *argp++ = partition;
1119ef1f84bSDavid du Colombier *argp++ = "-s";
1129ef1f84bSDavid du Colombier for(i=1; i<bargc; i++)
1139ef1f84bSDavid du Colombier *argp++ = bargv[i];
1149ef1f84bSDavid du Colombier *argp = 0;
1159ef1f84bSDavid du Colombier
1169ef1f84bSDavid du Colombier dup(p[0], 0);
1179ef1f84bSDavid du Colombier dup(p[1], 1);
1189ef1f84bSDavid du Colombier close(p[0]);
1199ef1f84bSDavid du Colombier close(p[1]);
1209ef1f84bSDavid du Colombier exec("/boot/kfs", arg);
1219ef1f84bSDavid du Colombier fatal("can't exec kfs");
1229ef1f84bSDavid du Colombier default:
1239ef1f84bSDavid du Colombier break;
1249ef1f84bSDavid du Colombier }
1259ef1f84bSDavid du Colombier for(;;){
1269ef1f84bSDavid du Colombier if((i = waitpid()) == -1)
1279ef1f84bSDavid du Colombier fatal("waitpid for kfs failed");
1289ef1f84bSDavid du Colombier if(i == pid)
1299ef1f84bSDavid du Colombier break;
1309ef1f84bSDavid du Colombier }
1319ef1f84bSDavid du Colombier
1329ef1f84bSDavid du Colombier close(p[1]);
1339ef1f84bSDavid du Colombier return p[0];
1349ef1f84bSDavid du Colombier }
1359ef1f84bSDavid du Colombier
1369ef1f84bSDavid du Colombier void
runv(char ** argv)137*532111f7SDavid du Colombier runv(char **argv)
1389ef1f84bSDavid du Colombier {
1399ef1f84bSDavid du Colombier int i, pid;
1409ef1f84bSDavid du Colombier
1419ef1f84bSDavid du Colombier switch(pid = fork()){
1429ef1f84bSDavid du Colombier case -1:
1439ef1f84bSDavid du Colombier fatal("fork");
1449ef1f84bSDavid du Colombier case 0:
145*532111f7SDavid du Colombier exec(argv[0], argv);
146*532111f7SDavid du Colombier fatal(smprint("can't exec %s: %r", argv[0]));
1479ef1f84bSDavid du Colombier default:
1489ef1f84bSDavid du Colombier while ((i = waitpid()) != pid && i != -1)
1499ef1f84bSDavid du Colombier ;
1509ef1f84bSDavid du Colombier if(i == -1)
151*532111f7SDavid du Colombier fatal(smprint("wait failed running %s", argv[0]));
1529ef1f84bSDavid du Colombier }
1539ef1f84bSDavid du Colombier }
1549ef1f84bSDavid du Colombier
155*532111f7SDavid du Colombier void
run(char * file,...)156*532111f7SDavid du Colombier run(char *file, ...)
157*532111f7SDavid du Colombier {
158*532111f7SDavid du Colombier runv(&file);
159*532111f7SDavid du Colombier }
160*532111f7SDavid du Colombier
1619ef1f84bSDavid du Colombier static int
print1(int fd,char * s)1629ef1f84bSDavid du Colombier print1(int fd, char *s)
1639ef1f84bSDavid du Colombier {
1649ef1f84bSDavid du Colombier return write(fd, s, strlen(s));
1659ef1f84bSDavid du Colombier }
1669ef1f84bSDavid du Colombier
1679ef1f84bSDavid du Colombier void
configloopback(void)1689ef1f84bSDavid du Colombier configloopback(void)
1699ef1f84bSDavid du Colombier {
1709ef1f84bSDavid du Colombier int fd;
1719ef1f84bSDavid du Colombier
1729ef1f84bSDavid du Colombier if((fd = open("/net/ipifc/clone", ORDWR)) < 0){
1739ef1f84bSDavid du Colombier bind("#I", "/net", MAFTER);
1749ef1f84bSDavid du Colombier if((fd = open("/net/ipifc/clone", ORDWR)) < 0)
1759ef1f84bSDavid du Colombier fatal("open /net/ipifc/clone for loopback");
1769ef1f84bSDavid du Colombier }
1779ef1f84bSDavid du Colombier if(print1(fd, "bind loopback /dev/null") < 0
1789ef1f84bSDavid du Colombier || print1(fd, "add 127.0.0.1 255.255.255.255") < 0)
1799ef1f84bSDavid du Colombier fatal("write /net/ipifc/clone for loopback");
1809ef1f84bSDavid du Colombier }
1819ef1f84bSDavid du Colombier
1829ef1f84bSDavid du Colombier int
connectlocalfossil(void)1839ef1f84bSDavid du Colombier connectlocalfossil(void)
1849ef1f84bSDavid du Colombier {
1859ef1f84bSDavid du Colombier int fd;
1869ef1f84bSDavid du Colombier char *venti, *f[32], *p;
1879ef1f84bSDavid du Colombier int nf;
1889ef1f84bSDavid du Colombier char partition[128], buf[512];
1899ef1f84bSDavid du Colombier char *dev;
1909ef1f84bSDavid du Colombier
1919ef1f84bSDavid du Colombier if(stat("/boot/fossil", statbuf, sizeof statbuf) < 0)
1929ef1f84bSDavid du Colombier return -1;
1939ef1f84bSDavid du Colombier
1949ef1f84bSDavid du Colombier /* look for fossil partition */
1959ef1f84bSDavid du Colombier dev = disk ? disk : bootdisk;
1969ef1f84bSDavid du Colombier snprint(partition, sizeof partition, "%sfossil", dev);
1979ef1f84bSDavid du Colombier fd = open(partition, OREAD);
1989ef1f84bSDavid du Colombier if(fd < 0){
1999ef1f84bSDavid du Colombier strcpy(partition, dev);
2009ef1f84bSDavid du Colombier fd = open(partition, OREAD);
2019ef1f84bSDavid du Colombier if(fd < 0)
2029ef1f84bSDavid du Colombier return -1;
2039ef1f84bSDavid du Colombier }
2049ef1f84bSDavid du Colombier memset(buf, 0, sizeof buf);
2059ef1f84bSDavid du Colombier pread(fd, buf, 512, 127*1024);
2069ef1f84bSDavid du Colombier close(fd);
2079ef1f84bSDavid du Colombier if(memcmp(buf, "fossil config\n", 14) != 0){
2089ef1f84bSDavid du Colombier if(strstr(partition, "/fossil"))
2099ef1f84bSDavid du Colombier print("no fossil config found on %s\n", partition);
2109ef1f84bSDavid du Colombier return -1;
2119ef1f84bSDavid du Colombier }
2129ef1f84bSDavid du Colombier
2139ef1f84bSDavid du Colombier settime(1, -1, nil);
2149ef1f84bSDavid du Colombier
215*532111f7SDavid du Colombier /* make venti available. give it 20% of free memory. */
2169ef1f84bSDavid du Colombier if((venti = getenv("venti")) && (nf = tokenize(venti, f, nelem(f)))){
2179ef1f84bSDavid du Colombier if((fd = open(f[0], OREAD)) >= 0){
2189ef1f84bSDavid du Colombier print("venti...");
2199ef1f84bSDavid du Colombier memset(buf, 0, sizeof buf);
2209ef1f84bSDavid du Colombier pread(fd, buf, 512, 248*1024);
2219ef1f84bSDavid du Colombier close(fd);
2229ef1f84bSDavid du Colombier if(memcmp(buf, "venti config\n", 13) != 0){
2239ef1f84bSDavid du Colombier print("no venti config found on %s\n", f[0]);
2249ef1f84bSDavid du Colombier return -1;
2259ef1f84bSDavid du Colombier }
2269ef1f84bSDavid du Colombier if(stat("/boot/venti", statbuf, sizeof statbuf) < 0){
2279ef1f84bSDavid du Colombier print("/boot/venti does not exist\n");
2289ef1f84bSDavid du Colombier return -1;
2299ef1f84bSDavid du Colombier }
2309ef1f84bSDavid du Colombier switch(nf){
2319ef1f84bSDavid du Colombier case 1:
2329ef1f84bSDavid du Colombier f[1] = "tcp!127.1!17034";
2339ef1f84bSDavid du Colombier case 2:
2349ef1f84bSDavid du Colombier f[2] = "tcp!127.1!8000";
2359ef1f84bSDavid du Colombier }
2369ef1f84bSDavid du Colombier configloopback();
237*532111f7SDavid du Colombier run("/boot/venti", "-m", "20", "-c", f[0],
238*532111f7SDavid du Colombier "-a", f[1], "-h", f[2], nil);
2399ef1f84bSDavid du Colombier /*
2409ef1f84bSDavid du Colombier * If the announce address is tcp!*!foo, then set
2419ef1f84bSDavid du Colombier * $venti to tcp!127.1!foo instead, which is actually dialable.
2429ef1f84bSDavid du Colombier */
2439ef1f84bSDavid du Colombier if((p = strstr(f[1], "!*!")) != 0){
2449ef1f84bSDavid du Colombier *p = 0;
2459ef1f84bSDavid du Colombier snprint(buf, sizeof buf, "%s!127.1!%s", f[1], p+3);
2469ef1f84bSDavid du Colombier f[1] = buf;
2479ef1f84bSDavid du Colombier }
2489ef1f84bSDavid du Colombier setenv("venti", f[1]);
2499ef1f84bSDavid du Colombier }else{
2509ef1f84bSDavid du Colombier /* set up the network so we can talk to the venti server */
2519ef1f84bSDavid du Colombier /* this is such a crock. */
2529ef1f84bSDavid du Colombier configip(nf, f, 0);
2539ef1f84bSDavid du Colombier setenv("venti", f[0]);
2549ef1f84bSDavid du Colombier }
2559ef1f84bSDavid du Colombier }
2569ef1f84bSDavid du Colombier
257*532111f7SDavid du Colombier /* start fossil. give it 20% of free memory. */
2589ef1f84bSDavid du Colombier print("fossil(%s)...", partition);
259*532111f7SDavid du Colombier run("/boot/fossil", "-m", "20", "-f", partition,
260*532111f7SDavid du Colombier "-c", "srv -A fboot", "-c", "srv -p fscons", nil);
2619ef1f84bSDavid du Colombier fd = open("#s/fboot", ORDWR);
2629ef1f84bSDavid du Colombier if(fd < 0){
263*532111f7SDavid du Colombier warning("open #s/fboot");
2649ef1f84bSDavid du Colombier return -1;
2659ef1f84bSDavid du Colombier }
266*532111f7SDavid du Colombier remove("#s/fboot"); /* we'll repost fd as #s/boot after fversion(fd) */
2679ef1f84bSDavid du Colombier return fd;
2689ef1f84bSDavid du Colombier }
2699ef1f84bSDavid du Colombier
2709ef1f84bSDavid du Colombier int
connectlocal(void)2719ef1f84bSDavid du Colombier connectlocal(void)
2729ef1f84bSDavid du Colombier {
2739ef1f84bSDavid du Colombier int fd;
2749ef1f84bSDavid du Colombier
2759ef1f84bSDavid du Colombier if(bind("#c", "/dev", MREPL) < 0)
2769ef1f84bSDavid du Colombier fatal("bind #c");
2779ef1f84bSDavid du Colombier if(bind("#p", "/proc", MREPL) < 0)
2789ef1f84bSDavid du Colombier fatal("bind #p");
2799ef1f84bSDavid du Colombier bind("#S", "/dev", MAFTER);
2809ef1f84bSDavid du Colombier bind("#k", "/dev", MAFTER);
281*532111f7SDavid du Colombier bind("#u", "/dev", MAFTER);
2829ef1f84bSDavid du Colombier bind("#æ", "/dev", MAFTER);
283*532111f7SDavid du Colombier mountusbparts(); /* make partfs partitions visible again */
2849ef1f84bSDavid du Colombier
2859ef1f84bSDavid du Colombier if((fd = connectlocalfossil()) < 0)
286*532111f7SDavid du Colombier fd = connectlocalkfs();
2879ef1f84bSDavid du Colombier return fd;
2889ef1f84bSDavid du Colombier }
289