"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "chironfs-1.1.1/src/chiron-conf.c" of archive chironfs-1.1.1.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /* Copyright 2005-2008, Luis Furquim
2 *
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 */
18
19
20 #define _GNU_SOURCE /* for access to canonicalize_file_name() inside stdlib.h
21 and the constant O_NOFOLLOW inside fcntl.h */
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdarg.h>
27 #include <errno.h>
28
29 #include <unistd.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>
32 #include <sys/statvfs.h>
33 #include <fcntl.h>
34 #include <dlfcn.h>
35
36 #include <libgen.h>
37 //
38 // The lines below are from a patch contributed by Antti Kantee
39 // to make ChironFS run on NetBSD
40 // Yen-Ming Lee has sent another patch, porting ChironFS to
41 // FreeBSD very similar to it
42 //
43 #ifdef __linux__
44 #include <linux/limits.h>
45 #else
46 #include <limits.h>
47 #endif
48 //
49 // End of BSD patch
50 //
51 #include <string.h>
52 #include <stdint.h>
53 #include <sys/resource.h>
54
55 //
56 // The line below is from a patch contributed by Yen-Ming Lee
57 // to make ChironFS run on FreeBSD
58 // But it works in Linux and NetBSD as well
59 //
60 #include <sys/sysctl.h>
61 //
62 // End of Yen-Ming Lee patch
63 //
64
65 #include "chiron-types.h"
66 #include "chirondbg.h"
67 #include "chironfs.h"
68 #include "chironfn.h"
69
70
71 void print_paths()
72 {
73 int i, j;
74 dbg(("\n(%s):",mount_point));
75 for(i=0;i<max_replica;++i) {
76 dbg(("\n (%s)",paths[i].path));
77 }
78 dbg(("\nHIGH\n"));
79 for(i=0;i<max_replica_high;++i) {
80 dbg(("\n("));
81 for(j=0;j<max_replica_high;++j) {
82 dbg(("%d ",round_robin_high[i][j]));
83 }
84 dbg((")"));
85 }
86 dbg(("\nLOW\n"));
87 for(i=0;i<max_replica_low;++i) {
88 dbg(("\n("));
89 for(j=0;j<max_replica_low;++j) {
90 dbg(("%d ",round_robin_low[i][j]));
91 }
92 dbg((")"));
93 }
94 dbg(("\n"));
95 }
96
97 void free_paths()
98 {
99 int i;
100 if (mount_point!=NULL) {
101 free(mount_point);
102 }
103 if (paths[0].path!=NULL) {
104 if (strcmp(paths[0].path,".")) {
105 free(paths[0].path);
106 paths[0].path = NULL;
107 }
108 }
109 for(i=1;i<max_replica;++i) {
110 if (paths[i].path!=NULL) {
111 free(paths[i].path);
112 paths[i].path = NULL;
113 }
114 }
115 free(paths);
116 if (logfd!=NULL) {
117 fclose(logfd);
118 logfd = NULL;
119 }
120 }
121
122 void free_tab_fd()
123 {
124 // int i;
125 // while (i<max_replica) {
126 // free(tab_fd.fd[i++]);
127 // }
128 free(tab_fd.fd);
129 }
130
131 void free_round_robin(int **rr, int max_rep)
132 {
133 int i;
134 if (rr!=NULL) {
135 for(i=0;i<max_rep;++i) {
136 if (rr[i]!=NULL) {
137 free(rr[i]);
138 rr[i] = NULL;
139 }
140 }
141 free(rr);
142 }
143 }
144
145
146 void opt_parse(char *fo, char**logname, char**argvbuf)
147 {
148 int opt, start, dest;
149 size_t i, len;
150
151 start = opt = i = 0;
152 len = strlen(fo);
153 do {
154 if ((!fo[i]) || (fo[i]==',')) {
155 if (!strncmp(fo+start,"log",3)) {
156 fo[i] = 0;
157 (*logname) = chiron_realpath(fo+start+4);
158 if ((*logname)==NULL) {
159 print_err(errno,fo+start+4);
160 exit(errno);
161 }
162 dbg(("\nlog=%s", fo+start));
163 if (start) {
164 dest = start-1;
165 } else {
166 dest = start;
167 }
168 sprintf(fo+dest,"%s",fo+start+4+strlen(*logname));
169 len -= i - start + 1;
170 i = start - 1;
171 } else if (!strncmp(fo+start,"fsname",6)) {
172 fo[i] = 0;
173 (*argvbuf) = strdup(fo+start);
174 if ((*argvbuf)==NULL) {
175 print_err(CHIRONFS_ERR_LOW_MEMORY,"fsname allocation");
176 exit(CHIRONFS_ERR_LOW_MEMORY);
177 }
178 dbg(("\nfsname=%s", fo+start));
179 if (start) {
180 dest = start-1;
181 } else {
182 dest = start;
183 }
184 sprintf(fo+dest,"%s",fo+start+strlen(*argvbuf));
185 len -= i - start + 1;
186 i = start - 1;
187 } else if (!strncmp(fo+start,"quiet",5)) {
188 fo[i] = 0;
189 quiet_mode = 1;
190 sprintf(fo+start,"%s",fo+6);
191 i = start - 1;
192 } else {
193 start = i + 1;
194 }
195 }
196 i++;
197 dbg(("\n%s",fo));
198 } while (i<=len);
199 }
200
201 int **mk_round_robin(int *tmp_list,int dim)
202 {
203 int **round_robin, j, i;
204
205 round_robin = calloc(dim,sizeof(int *));
206 if (round_robin!=NULL) {
207 for(i=0;i<dim;++i) {
208 round_robin[i] = calloc(dim,sizeof(int));
209 if (round_robin[i]==NULL) {
210 while (i) {
211 free(round_robin[--i]);
212 }
213 free(round_robin);
214 return(NULL);
215 }
216 for(j=0;j<dim;++j) {
217 if ((j+i)<dim) {
218 round_robin[i][j] = tmp_list[j+i];
219 } else {
220 round_robin[i][j] = tmp_list[j+i-dim];
221 }
222 }
223 }
224 }
225 return(round_robin);
226 }
227
228
229 #ifndef __linux__
230
231 /*
232 * This function was originally written by Antti Kantee
233 * Changed by Luis Otavio de Colla Furquim to test the return
234 * result from malloc and, in case of failure, return NULL
235 * without calling realpath.
236 * Yen-Ming Lee has sent another patch, porting ChironFS to
237 * FreeBSD also solving this problem
238 */
239 char *do_realpath(const char *path, char *resolvedpath)
240 {
241
242 if (resolvedpath == NULL) {
243 if (!(resolvedpath = malloc(PATH_MAX))) {
244 return(NULL);
245 }
246 }
247 return realpath(path, resolvedpath);
248 }
249
250 #endif
251
252
253
254 int do_mount(char *filesystems, char *mountpoint)
255 {
256 int i, start, res, errno, rep_on_mount=0, err;
257 int *tmp_high, *tmp_low;
258 unsigned long tmpfd;
259 struct rlimit rlp;
260 int oldval;
261 size_t oldlenp = sizeof(oldval);
262 int sysctl_names[] = {
263 #ifdef __linux__
264 CTL_FS, FS_MAXFILE
265 #else
266 CTL_KERN, KERN_MAXFILES
267 #endif
268 };
269
270
271
272
273 for(max_replica=1,i=0;filesystems[i];++i) {
274 if (filesystems[i]=='=') {
275 ++max_replica;
276 filesystems[i] = 0;
277 }
278 }
279
280 if (mountpoint[0]==':') {
281 max_replica++;
282 }
283
284 res = sysctl (sysctl_names, 2, &oldval, &oldlenp, NULL, 0);
285 if (res) {
286 print_err(errno,"reading system parameter 'max open files'");
287 FD_BUF_SIZE = 4096;
288 } else {
289 FD_BUF_SIZE = (long long unsigned int) oldval;
290 }
291
292 tmpfd = (FD_BUF_SIZE >>= 1);
293
294 if (getrlimit(CHIRON_LIMIT,&rlp)) {
295 print_err(errno,"reading nofile resource limit");
296 exit(errno);
297 }
298 dbg(("\n1cur:%d\tmax:%d",rlp.rlim_cur,rlp.rlim_max));
299 rlp.rlim_max = tmpfd;
300 dbg(("\n2cur:%d\tmax:%d",rlp.rlim_cur,rlp.rlim_max));
301 if (rlp.rlim_cur<rlp.rlim_max) {
302 rlp.rlim_cur = rlp.rlim_max;
303 dbg(("\n3cur:%d\tmax:%d",rlp.rlim_cur,rlp.rlim_max));
304 if (setrlimit(RLIMIT_NOFILE,&rlp)) {
305 dbg(("\n4cur:%d\tmax:%d",rlp.rlim_cur,rlp.rlim_max));
306 if (getrlimit(RLIMIT_NOFILE,&rlp)) {
307 print_err(errno,"reading nofile resource limit, second attempt");
308 exit(errno);
309 }
310 }
311 }
312 dbg(("\n5cur:%d\tmax:%d",rlp.rlim_cur,rlp.rlim_max));
313
314 dbg(("\n1tmpfd:%d",tmpfd));
315 tmpfd = (rlp.rlim_cur<tmpfd)
316 ? rlp.rlim_cur
317 : tmpfd;
318 dbg(("\n2tmpfd:%d",tmpfd));
319
320 tmpfd = (tmpfd - 6) / max_replica;
321
322 dbg(("\n3tmpfd:%d",tmpfd));
323 while (tmpfd) {
324 qt_hash_bits++;
325 hash_mask = hash_mask<<1 | 1;
326 tmpfd >>= 1;
327 }
328 hash_mask >>= 1;
329 FD_BUF_SIZE = hash_mask;
330 dbg(("\nhash_mask:%x",hash_mask));
331
332 tab_fd.fd = calloc(FD_BUF_SIZE,sizeof(int *));
333 if (tab_fd.fd==NULL) {
334 print_err(CHIRONFS_ERR_LOW_MEMORY,"file descriptor hash table allocation");
335 exit(CHIRONFS_ERR_LOW_MEMORY);
336 }
337
338 for(i=0;((unsigned)i)<FD_BUF_SIZE;++i) {
339 tab_fd.fd[i] = NULL;
340 }
341
342 paths = calloc(max_replica,sizeof(path_t));
343 if (paths==NULL) {
344 free_paths();
345 free_tab_fd();
346 print_err(errno,"replica info allocation");
347 exit(errno);
348 }
349 for(i=0;i<max_replica;++i) {
350 paths[i].path = NULL;
351 paths[i].disabled = (time_t)0;
352 paths[i].priority = 0;
353 }
354
355 tmp_high = calloc(max_replica,sizeof(int));
356 if (tmp_high==NULL) {
357 free_paths();
358 free_tab_fd();
359 print_err(errno,"high priority round robin table allocation");
360 exit(errno);
361 }
362
363 tmp_low = calloc(max_replica,sizeof(int));
364 if (tmp_low==NULL) {
365 free_paths();
366 free(tmp_high);
367 free_tab_fd();
368 print_err(errno,"low priority round robin table allocation");
369 exit(errno);
370 }
371
372 if (mountpoint[0]==':') {
373 mount_point = do_realpath(mountpoint+1,NULL);
374 rep_on_mount = i = 1;
375 tmp_high[max_replica_high++] = 0;
376 } else {
377 mount_point = do_realpath(mountpoint,NULL);
378 i = 0;
379 }
380 if (mount_point==NULL) {
381 err = errno;
382 free_tab_fd();
383 print_err(err,mountpoint);
384 exit(err);
385 }
386
387 start = 0;
388 for(;i<max_replica;++i) {
389 if (filesystems[start]==':') {
390 start++;
391 paths[i].priority = 1;
392 tmp_low[max_replica_low++] = i;
393 } else {
394 tmp_high[max_replica_high++] = i;
395 }
396
397 paths[i].path = do_realpath(filesystems+start, NULL);
398 if (paths[i].path==NULL) {
399 free_paths();
400 free_tab_fd();
401 free(tmp_high);
402 free(tmp_low);
403 print_err(errno,filesystems+start);
404 exit(errno);
405 }
406 // just to store it and avoid future recalculations
407 paths[i].pathlen = strlen(paths[i].path);
408 start += strlen(filesystems+start) + 1;
409 if (paths[i].priority) {
410 call_log("replica priority low",paths[i].path,0);
411 dbg(("\nreplica low: %s",paths[i].path));
412 } else {
413 call_log("replica priority high",paths[i].path,0);
414 dbg(("\nreplica high: %s",paths[i].path));
415 }
416 }
417
418 if (rep_on_mount) {
419 paths[0].path = currdir;
420 chdir(mount_point);
421 }
422
423 if (logname!=NULL) {
424 attach_log();
425 }
426
427 round_robin_high = mk_round_robin(tmp_high,max_replica_high);
428 if (round_robin_high==NULL) {
429 free_paths();
430 free_tab_fd();
431 free(tmp_high);
432 free(tmp_low);
433 print_err(CHIRONFS_ERR_LOW_MEMORY,"high priority round robin state table allocation");
434 exit(CHIRONFS_ERR_LOW_MEMORY);
435 }
436 free(tmp_high);
437
438 round_robin_low = mk_round_robin(tmp_low,max_replica_low);
439 if (round_robin_low==NULL) {
440 free_paths();
441 free(tmp_low);
442 free_round_robin(round_robin_high,max_replica_high);
443 free_tab_fd();
444 print_err(CHIRONFS_ERR_LOW_MEMORY,"low priority round robin state table allocation");
445 exit(CHIRONFS_ERR_LOW_MEMORY);
446 }
447 free(tmp_low);
448
449 print_paths();
450
451 return(0);
452 }
453
454