Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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