xref: /plan9-contrib/sys/src/games/music/jukefs/server.c (revision 6ca6a3e703ee2ec4aed99c2177f71d7f127da6d9)
1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include <bio.h>
5 #include <fcall.h>
6 #include "object.h"
7 #include "parse.h"
8 #include "print.h"
9 #include "catset.h"
10 #include "../debug.h"
11 
12 // #include <pool.h>
13 
14 char		*user, *mapname, *svrname;
15 int		p[2];
16 int		mfd[2];
17 int		debug = 0; //DBGSERVER|DBGSTATE|DBGPICKLE|DBGPLAY;
18 Biobuf		*f;
19 char		*file;
20 
21 Object *root;
22 
23 Object **	otab;		// object table
24 int		notab;	// no of entries used
25 int		sotab;	// no of entries mallocated (invariant sotab >= notab)
26 int		hotab;	// no of holes in otab;
27 
28 char usage[] = "Usage: %s [-f] [-l] [mapfile]\n";
29 
30 char *startdir;
31 
32 Object **catobjects;	/* for quickly finding category objects */
33 int ncat = 0;
34 
35 void
post(char * name,char * envname,int srvfd)36 post(char *name, char *envname, int srvfd)
37 {
38 	int fd;
39 	char buf[32];
40 
41 	fd = create(name, OWRITE, 0666);
42 	if(fd < 0)
43 		return;
44 	sprint(buf, "%d",srvfd);
45 	if(write(fd, buf, strlen(buf)) != strlen(buf))
46 		sysfatal("srv write: %r");
47 	close(fd);
48 	putenv(envname, name);
49 }
50 
51 int
robusthandler(void *,char * s)52 robusthandler(void*, char *s)
53 {
54 	if (debug) fprint(2, "inthandler: %s\n", s);
55 	return (s && (strstr(s, "interrupted") || strstr(s, "hangup")));
56 }
57 
58 long
robustread(int fd,void * buf,long sz)59 robustread(int fd, void *buf, long sz)
60 {
61 	long r;
62 	char err[32];
63 
64 	do {
65 		r = read(fd , buf, sz);
66 		if (r < 0)
67 			rerrstr(err, sizeof(err));
68 	} while (r < 0 && robusthandler(nil, err));
69 	return r;
70 }
71 
72 void
delobject(Object * o)73 delobject(Object *o)
74 {
75 	/* Free an object and all its descendants */
76 	Object *oo;
77 	int i;
78 
79 	for (i = 0; i < o->nchildren; i++){
80 		oo = o->children[i];
81 		if (oo->parent == o)
82 			delobject(oo);
83 	}
84 	freeobject(o, "r");
85 }
86 
87 void
threadmain(int argc,char * argv[])88 threadmain(int argc, char *argv[]) {
89 	char *q;
90 	char *srvname;
91 	char *mntpt;
92 	int list;
93 
94 	mntpt = "/mnt";
95 	user = strdup(getuser());
96 	srvname = nil;
97 	list = 0;
98 
99 	// mainmem->flags |= POOL_NOREUSE;
100 
101 	ARGBEGIN{
102 	case 'l':
103 		list = 1;
104 		break;
105 	case 'm':
106 		mntpt = ARGF();
107 		break;
108 	case 'd':
109 		debug = strtoul(ARGF(), nil, 0);
110 		break;
111 	case 's':
112 		srvname = ARGF();
113 		break;
114 	case 'f':
115 		fflag = 1;
116 		break;
117 	default:
118 		fprint(2, usage, argv0);
119 		exits("usage");
120 	}ARGEND
121 
122 	switch (argc) {
123 	default:
124 		fprint(2, usage, argv0);
125 		exits("usage");
126 	case 0:
127 		mapname = DEFAULTMAP;
128 		break;
129 	case 1:
130 		mapname = argv[0];
131 		break;
132 	}
133 
134 	quotefmtinstall();
135 
136 	if((f = Bopen(mapname, OREAD)) == nil)
137 		sysfatal("%s: %r", mapname);
138 	free(file);
139 	file = strdup(mapname);
140 	free(startdir);
141 	startdir = strdup(mapname);
142 	if ((q = strrchr(startdir, '/')))
143 		*q = '\0';
144 	else
145 		startdir[0] = '\0';
146 	inittokenlist();
147 	getobject(Root, nil);
148 	Bterm(f);
149 	f = nil;
150 	root->parent = root;
151 
152 	if(list){
153 		listfiles(root);
154 		threadexits(nil);
155 	}
156 
157 	if(pipe(p) < 0)
158 		sysfatal("pipe failed: %r");
159 	mfd[0] = p[0];
160 	mfd[1] = p[0];
161 
162 	threadnotify(robusthandler, 1);
163 	user = strdup(getuser());
164 
165 	if(debug)
166 		fmtinstall('F', fcallfmt);
167 
168 	procrfork(io, nil, STACKSIZE, RFFDG);	//RFNOTEG?
169 
170 	close(p[0]);	/* don't deadlock if child fails */
171 
172 	if(srvname){
173 		srvname = smprint("/srv/jukefs.%s", srvname);
174 		remove(srvname);
175 		post(srvname, "jukefs", p[1]);
176 	}
177 	if(mount(p[1], -1, mntpt, MBEFORE, "") < 0)
178 		sysfatal("mount failed: %r");
179 	threadexits(nil);
180 }
181 
182 void
reread(void)183 reread(void)
184 {
185 	int i;
186 	extern int catnr;
187 	char *q;
188 
189 	assert(f == nil);
190 	if((f = Bopen(mapname, OREAD)) == nil)
191 		fprint(2, "reread: %s: %r\n", mapname);
192 	freetree(root);
193 	root = nil;
194 	for(i = 0; i< ntoken; i++){
195 		free(tokenlist[i].name);
196 		catsetfree(&tokenlist[i].categories);
197 	}
198 	catnr = 0;
199 	free(tokenlist);
200 	free(catobjects);
201 	catobjects = nil;
202 	ncat = 0;
203 	tokenlist = nil;
204 	ntoken = Ntoken;
205 	inittokenlist();
206 	free(file);
207 	file = strdup(mapname);
208 	free(startdir);
209 	startdir = strdup(mapname);
210 	if ((q = strrchr(startdir, '/')))
211 		*q = '\0';
212 	else
213 		startdir[0] = '\0';
214 	getobject(Root, nil);
215 	root->parent = root;
216 	Bterm(f);
217 	f = nil;
218 }
219