local.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <../boot/boot.h>
  12. static char diskname[64];
  13. static char *disk;
  14. void
  15. shell(char *c, char *d)
  16. {
  17. char *argv[] = {"rc", "-m", "/boot/rcmain", 0, 0, 0};
  18. print("Shell: Run %s %s\n", c, d);
  19. argv[3] = c;
  20. argv[4] = d;
  21. switch(fork()){
  22. case -1:
  23. print("configrc: fork failed: %r\n");
  24. case 0:
  25. exec("/boot/rc", argv);
  26. fatal("can't exec rc");
  27. default:
  28. break;
  29. }
  30. while(waitpid() != -1)
  31. ;
  32. }
  33. void
  34. configlocal(Method *mp)
  35. {
  36. char *p;
  37. int n;
  38. if(*sys == '/' || *sys == '#'){
  39. /*
  40. * if the user specifies the disk in the boot cmd or
  41. * 'root is from' prompt, use it
  42. */
  43. disk = sys;
  44. } else if(strncmp(argv0, "dksc(0,", 7) == 0){
  45. /*
  46. * on many mips arg0 of the boot command specifies the
  47. * scsi logical unit number
  48. */
  49. p = strchr(argv0, ',');
  50. n = strtoul(p + 1, 0, 10);
  51. sprint(diskname, "#w%d/sd%dfs", n, n);
  52. disk = diskname;
  53. } else if(mp->arg){
  54. /*
  55. * a default is supplied when the kernel is made
  56. */
  57. disk = mp->arg;
  58. } else if(*bootdisk){
  59. /*
  60. * an environment variable from a pc's plan9.ini or
  61. * from the mips nvram or generated by the kernel
  62. * is the last resort.
  63. */
  64. disk = bootdisk;
  65. } else {
  66. disk = "#s/sdE0/";
  67. }
  68. /* if we've decided on one, pass it on to all programs */
  69. if(disk){
  70. setenv("bootdisk", disk);
  71. setenv("nvram", smprint("%s/nvram", disk));
  72. setenv("venti", smprint("%s/arenas", disk));
  73. }
  74. shell("-c", smprint("/boot/fdisk -p '%s/data' > '%s/ctl'", disk, disk));
  75. shell("-c", smprint("/boot/prep -p '%s/plan9' > '%s/ctl'", disk, disk));
  76. //shell("-i", nil);
  77. USED(mp);
  78. }
  79. static int
  80. print1(int fd, char *s)
  81. {
  82. return write(fd, s, strlen(s));
  83. }
  84. void
  85. configloopback(void)
  86. {
  87. int fd;
  88. if((fd = open("/net/ipifc/clone", ORDWR)) < 0){
  89. bind("#I", "/net", MAFTER);
  90. if((fd = open("/net/ipifc/clone", ORDWR)) < 0)
  91. fatal("open /net/ipifc/clone for loopback");
  92. }
  93. if(print1(fd, "bind loopback /dev/null") < 0 || print1(fd, "add 127.0.0.1 255.255.255.255") < 0)
  94. fatal("write /net/ipifc/clone for loopback");
  95. close(fd);
  96. }
  97. int
  98. connectlocalfossil(void)
  99. {
  100. int fd;
  101. char *venti, *f[32], *p;
  102. int nf;
  103. char partition[128], buf[512];
  104. char *dev;
  105. if(stat("/boot/fossil", statbuf, sizeof statbuf) < 0)
  106. return -1;
  107. /* look for fossil partition */
  108. dev = disk ? disk : bootdisk;
  109. snprint(partition, sizeof partition, "%sfossil", dev);
  110. fd = open(partition, OREAD);
  111. if(fd < 0){
  112. strcpy(partition, dev);
  113. fd = open(partition, OREAD);
  114. if(fd < 0)
  115. return -1;
  116. }
  117. memset(buf, 0, sizeof buf);
  118. pread(fd, buf, 512, 127 * 1024);
  119. close(fd);
  120. if(memcmp(buf, "fossil config\n", 14) != 0){
  121. if(strstr(partition, "/fossil"))
  122. print("no fossil config found on %s\n", partition);
  123. return -1;
  124. }
  125. settime(1, -1, nil);
  126. /* make venti available */
  127. if((venti = getenv("venti")) && (nf = tokenize(venti, f, nelem(f)))){
  128. print("VENTI on %s\n", f[0]);
  129. if((fd = open(f[0], OREAD)) >= 0){
  130. print("venti...");
  131. memset(buf, 0, sizeof buf);
  132. pread(fd, buf, 512, 248 * 1024);
  133. close(fd);
  134. if(memcmp(buf, "venti config\n", 13) != 0){
  135. print("no venti config found on %s\n", f[0]);
  136. return -1;
  137. }
  138. if(stat("/boot/venti", statbuf, sizeof statbuf) < 0){
  139. print("/boot/venti does not exist\n");
  140. return -1;
  141. }
  142. switch(nf){
  143. case 1:
  144. f[1] = "tcp!127.1!17034";
  145. case 2:
  146. f[2] = "tcp!127.1!8000";
  147. }
  148. configloopback();
  149. shell("-c", smprint("/boot/venti -c '%s' -a %s -h %s", f[0], f[1], f[2]));
  150. /*
  151. * If the announce address is tcp!*!foo, then set
  152. * $venti to tcp!127.1!foo instead, which is actually dialable.
  153. */
  154. if((p = strstr(f[1], "!*!")) != 0){
  155. *p = 0;
  156. snprint(buf, sizeof buf, "%s!127.1!%s", f[1], p + 3);
  157. f[1] = buf;
  158. }
  159. setenv("venti", f[1]);
  160. } else {
  161. print("NO VENTI?\n");
  162. /* set up the network so we can talk to the venti server */
  163. /* this is such a crock. */
  164. configip(nf, f, 0);
  165. setenv("venti", f[0]);
  166. }
  167. }
  168. /* start fossil */
  169. print("fossil(%s)...", partition);
  170. shell("-c", smprint("/boot/fossil -f '%s' -c 'srv -A fboot' -c 'srv -p fscons'", partition));
  171. fd = open("#s/fboot", ORDWR);
  172. if(fd < 0){
  173. print("open #s/fboot: %r\n");
  174. return -1;
  175. }
  176. remove("#s/fboot"); /* we'll repost as #s/boot */
  177. return fd;
  178. }
  179. int
  180. connectlocal(void)
  181. {
  182. int fd;
  183. if(bind("#c", "/dev", MREPL) < 0)
  184. fatal("bind #c");
  185. if(bind("#p", "/proc", MREPL) < 0)
  186. fatal("bind #p");
  187. bind("#S", "/dev", MAFTER);
  188. bind("#k", "/dev", MAFTER);
  189. bind("#æ", "/dev", MAFTER);
  190. if((fd = connectlocalfossil()) < 0){
  191. shell("-i", nil);
  192. return -1;
  193. }
  194. return fd;
  195. }