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