local.c 4.9 KB

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