local.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <../boot/boot.h>
  4. static char diskname[64];
  5. static char *disk;
  6. static char **args;
  7. void
  8. configlocal(Method *mp)
  9. {
  10. char *p;
  11. int n;
  12. if(*sys == '/' || *sys == '#'){
  13. /*
  14. * if the user specifies the disk in the boot cmd or
  15. * 'root is from' prompt, use it
  16. */
  17. disk = sys;
  18. } else if(strncmp(argv0, "dksc(0,", 7) == 0){
  19. /*
  20. * on many mips arg0 of the boot command specifies the
  21. * scsi logical unit number
  22. */
  23. p = strchr(argv0, ',');
  24. n = strtoul(p+1, 0, 10);
  25. sprint(diskname, "#w%d/sd%dfs", n, n);
  26. disk = diskname;
  27. } else if(mp->arg){
  28. /*
  29. * a default is supplied when the kernel is made
  30. */
  31. disk = mp->arg;
  32. } else if(*bootdisk){
  33. /*
  34. * an environment variable from a pc's plan9.ini or
  35. * from the mips nvram or generated by the kernel
  36. * is the last resort.
  37. */
  38. disk = bootdisk;
  39. }
  40. /* if we've decided on one, pass it on to all programs */
  41. if(disk)
  42. setenv("bootdisk", disk);
  43. USED(mp);
  44. }
  45. int
  46. connectlocalkfs(void)
  47. {
  48. int i, pid, fd, p[2];
  49. char partition[64];
  50. char *dev;
  51. char **arg, **argp;
  52. Dir *d;
  53. if(stat("/boot/kfs", statbuf, sizeof statbuf) < 0)
  54. return -1;
  55. dev = disk ? disk : bootdisk;
  56. snprint(partition, sizeof partition, "%sfs", dev);
  57. fd = open(partition, OREAD);
  58. if(fd < 0){
  59. strcpy(partition, dev);
  60. fd = open(partition, OREAD);
  61. if(fd < 0)
  62. return -1;
  63. }
  64. /*
  65. * can't do this check -- might be some other server posing as kfs.
  66. *
  67. memset(buf, 0, sizeof buf);
  68. pread(fd, buf, 512, 0);
  69. close(fd);
  70. if(memcmp(buf+256, "kfs wren device\n", 16) != 0){
  71. if(strstr(partition, "/fs"))
  72. print("no kfs file system found on %s\n", partition);
  73. return -1;
  74. }
  75. *
  76. */
  77. d = dirfstat(fd);
  78. close(fd);
  79. if(d == nil)
  80. return -1;
  81. if(d->mode&DMDIR){
  82. free(d);
  83. return -1;
  84. }
  85. free(d);
  86. print("kfs...");
  87. if(pipe(p)<0)
  88. fatal("pipe");
  89. switch(pid = fork()){
  90. case -1:
  91. fatal("fork");
  92. case 0:
  93. arg = malloc((bargc+5)*sizeof(char*));
  94. argp = arg;
  95. *argp++ = "kfs";
  96. *argp++ = "-f";
  97. *argp++ = partition;
  98. *argp++ = "-s";
  99. for(i=1; i<bargc; i++)
  100. *argp++ = bargv[i];
  101. *argp = 0;
  102. dup(p[0], 0);
  103. dup(p[1], 1);
  104. close(p[0]);
  105. close(p[1]);
  106. exec("/boot/kfs", arg);
  107. fatal("can't exec kfs");
  108. default:
  109. break;
  110. }
  111. for(;;){
  112. if((i = waitpid()) == -1)
  113. fatal("waitpid for kfs failed");
  114. if(i == pid)
  115. break;
  116. }
  117. close(p[1]);
  118. return p[0];
  119. }
  120. static void
  121. run(char *file, ...)
  122. {
  123. char buf[64];
  124. Waitmsg *w;
  125. int pid;
  126. switch(pid = fork()){
  127. case -1:
  128. fatal("fork");
  129. case 0:
  130. exec(file, &file);
  131. snprint(buf, sizeof buf, "can't exec %s", file);
  132. fatal(buf);
  133. default:
  134. while((w = wait()) != nil)
  135. if(w->pid == pid)
  136. break;
  137. if(w == nil){
  138. snprint(buf, sizeof buf, "wait returned nil running %s", file);
  139. fatal(buf);
  140. }
  141. }
  142. }
  143. static int
  144. print1(int fd, char *s)
  145. {
  146. return write(fd, s, strlen(s));
  147. }
  148. void
  149. configloopback(void)
  150. {
  151. int fd;
  152. if((fd = open("/net/ipifc/clone", ORDWR)) < 0){
  153. bind("#I", "/net", MAFTER);
  154. if((fd = open("/net/ipifc/clone", ORDWR)) < 0)
  155. fatal("open /net/ipifc/clone for loopback");
  156. }
  157. if(print1(fd, "bind loopback /dev/null") < 0
  158. || print1(fd, "add 127.0.0.1 255.255.255.255") < 0)
  159. fatal("write /net/ipifc/clone for loopback");
  160. }
  161. int
  162. connectlocalfossil(void)
  163. {
  164. int fd;
  165. char *venti, *f[32], *p;
  166. int nf;
  167. char partition[128], buf[512];
  168. char *dev;
  169. if(stat("/boot/fossil", statbuf, sizeof statbuf) < 0)
  170. return -1;
  171. bind("#k", "/dev", MAFTER);
  172. /* look for fossil partition */
  173. dev = disk ? disk : bootdisk;
  174. snprint(partition, sizeof partition, "%sfossil", dev);
  175. fd = open(partition, OREAD);
  176. if(fd < 0){
  177. strcpy(partition, dev);
  178. fd = open(partition, OREAD);
  179. if(fd < 0)
  180. return -1;
  181. }
  182. memset(buf, 0, sizeof buf);
  183. pread(fd, buf, 512, 127*1024);
  184. close(fd);
  185. if(memcmp(buf, "fossil config\n", 14) != 0){
  186. if(strstr(partition, "/fossil"))
  187. print("no fossil config found on %s\n", partition);
  188. return -1;
  189. }
  190. settime(1, -1, nil);
  191. /* make venti available */
  192. if((venti = getenv("venti")) && (nf = tokenize(venti, f, nelem(f)))){
  193. if((fd = open(f[0], OREAD)) >= 0){
  194. print("venti...");
  195. memset(buf, 0, sizeof buf);
  196. pread(fd, buf, 512, 248*1024);
  197. close(fd);
  198. if(memcmp(buf, "venti config\n", 13) != 0){
  199. print("no venti config found on %s\n", f[0]);
  200. return -1;
  201. }
  202. if(stat("/boot/venti", statbuf, sizeof statbuf) < 0){
  203. print("/boot/venti does not exist\n");
  204. return -1;
  205. }
  206. switch(nf){
  207. case 1:
  208. f[1] = "tcp!127.1!17034";
  209. case 2:
  210. f[2] = "tcp!127.1!8000";
  211. }
  212. configloopback();
  213. run("/boot/venti", "-c", f[0], "-a", f[1], "-h", f[2], 0);
  214. /*
  215. * If the announce address is tcp!*!foo, then set
  216. * $venti to tcp!127.1!foo instead, which is actually dialable.
  217. */
  218. if((p = strstr(f[1], "!*!")) != 0){
  219. *p = 0;
  220. snprint(buf, sizeof buf, "%s!127.1!%s", f[1], p+3);
  221. f[1] = buf;
  222. }
  223. setenv("venti", f[1]);
  224. }else{
  225. /* set up the network so we can talk to the venti server */
  226. /* this is such a crock. */
  227. configip(nf, f, 0);
  228. setenv("venti", f[0]);
  229. }
  230. }
  231. /* start fossil */
  232. print("fossil(%s)...", partition);
  233. run("/boot/fossil", "-f", partition, "-c", "srv -A fboot", "-c", "srv -p fscons", 0);
  234. fd = open("#s/fboot", ORDWR);
  235. if(fd < 0){
  236. print("open #s/fboot: %r\n");
  237. return -1;
  238. }
  239. remove("#s/fboot"); /* we'll repost as #s/boot */
  240. return fd;
  241. }
  242. int
  243. connectlocal(void)
  244. {
  245. int fd;
  246. if(bind("#c", "/dev", MREPL) < 0)
  247. fatal("bind #c");
  248. if(bind("#p", "/proc", MREPL) < 0)
  249. fatal("bind #p");
  250. bind("#S", "/dev", MAFTER);
  251. if((fd = connectlocalfossil()) < 0)
  252. if((fd = connectlocalkfs()) < 0)
  253. return -1;
  254. return fd;
  255. }