File: | xlators/mgmt/glusterd/src/glusterd-volgen.c |
Location: | line 3429, column 25 |
Description: | Access to field 'name' results in a dereference of a null pointer (loaded from variable 'this') |
1 | /* | |||||
2 | Copyright (c) 2010-2012 Red Hat, Inc. <http://www.redhat.com> | |||||
3 | This file is part of GlusterFS. | |||||
4 | ||||||
5 | This file is licensed to you under your choice of the GNU Lesser | |||||
6 | General Public License, version 3 or any later version (LGPLv3 or | |||||
7 | later), or the GNU General Public License, version 2 (GPLv2), in all | |||||
8 | cases as published by the Free Software Foundation. | |||||
9 | */ | |||||
10 | ||||||
11 | #ifndef _CONFIG_H | |||||
12 | #define _CONFIG_H | |||||
13 | #include "config.h" | |||||
14 | #endif | |||||
15 | ||||||
16 | #include <fnmatch.h> | |||||
17 | #include <sys/wait.h> | |||||
18 | ||||||
19 | #if (HAVE_LIB_XML1) | |||||
20 | #include <libxml/encoding.h> | |||||
21 | #include <libxml/xmlwriter.h> | |||||
22 | #endif | |||||
23 | ||||||
24 | #include "xlator.h" | |||||
25 | #include "glusterd.h" | |||||
26 | #include "defaults.h" | |||||
27 | #include "logging.h" | |||||
28 | #include "dict.h" | |||||
29 | #include "graph-utils.h" | |||||
30 | #include "trie.h" | |||||
31 | #include "glusterd-mem-types.h" | |||||
32 | #include "cli1-xdr.h" | |||||
33 | #include "glusterd-volgen.h" | |||||
34 | #include "glusterd-op-sm.h" | |||||
35 | #include "glusterd-utils.h" | |||||
36 | #include "run.h" | |||||
37 | ||||||
38 | extern struct volopt_map_entry glusterd_volopt_map[]; | |||||
39 | ||||||
40 | /********************************************* | |||||
41 | * | |||||
42 | * xlator generation / graph manipulation API | |||||
43 | * | |||||
44 | *********************************************/ | |||||
45 | ||||||
46 | ||||||
47 | struct volgen_graph { | |||||
48 | char **errstr; | |||||
49 | glusterfs_graph_t graph; | |||||
50 | }; | |||||
51 | typedef struct volgen_graph volgen_graph_t; | |||||
52 | ||||||
53 | static void | |||||
54 | set_graph_errstr (volgen_graph_t *graph, const char *str) | |||||
55 | { | |||||
56 | if (!graph->errstr) | |||||
57 | return; | |||||
58 | ||||||
59 | *graph->errstr = gf_strdup (str); | |||||
60 | } | |||||
61 | ||||||
62 | static xlator_t * | |||||
63 | xlator_instantiate_va (const char *type, const char *format, va_list arg) | |||||
64 | { | |||||
65 | xlator_t *xl = NULL((void*)0); | |||||
66 | char *volname = NULL((void*)0); | |||||
67 | int ret = 0; | |||||
68 | ||||||
69 | ret = gf_vasprintf (&volname, format, arg); | |||||
70 | if (ret < 0) { | |||||
71 | volname = NULL((void*)0); | |||||
72 | ||||||
73 | goto error; | |||||
74 | } | |||||
75 | ||||||
76 | xl = GF_CALLOC (1, sizeof (*xl), gf_common_mt_xlator_t)__gf_calloc (1, sizeof (*xl), gf_common_mt_xlator_t); | |||||
77 | if (!xl) | |||||
78 | goto error; | |||||
79 | ret = xlator_set_type_virtual (xl, type); | |||||
80 | if (ret) | |||||
81 | goto error; | |||||
82 | xl->options = get_new_dict(); | |||||
83 | if (!xl->options) | |||||
84 | goto error; | |||||
85 | xl->name = volname; | |||||
86 | INIT_LIST_HEAD (&xl->volume_options)do { (&xl->volume_options)->next = (&xl->volume_options )->prev = &xl->volume_options; } while (0); | |||||
87 | ||||||
88 | xl->ctx = THIS(*__glusterfs_this_location())->ctx; | |||||
89 | ||||||
90 | return xl; | |||||
91 | ||||||
92 | error: | |||||
93 | gf_log ("", GF_LOG_ERROR, "creating xlator of type %s failed",do { do { if (0) printf ("creating xlator of type %s failed", type); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 94, GF_LOG_ERROR, "creating xlator of type %s failed", type ); } while (0) | |||||
94 | type)do { do { if (0) printf ("creating xlator of type %s failed", type); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 94, GF_LOG_ERROR, "creating xlator of type %s failed", type ); } while (0); | |||||
95 | GF_FREE (volname)__gf_free (volname); | |||||
96 | if (xl) | |||||
97 | xlator_destroy (xl); | |||||
98 | ||||||
99 | return NULL((void*)0); | |||||
100 | } | |||||
101 | ||||||
102 | #ifdef __not_used_as_of_now_ | |||||
103 | static xlator_t * | |||||
104 | xlator_instantiate (const char *type, const char *format, ...) | |||||
105 | { | |||||
106 | va_list arg; | |||||
107 | xlator_t *xl; | |||||
108 | ||||||
109 | va_start (arg, format)__builtin_va_start(arg, format); | |||||
110 | xl = xlator_instantiate_va (type, format, arg); | |||||
111 | va_end (arg)__builtin_va_end(arg); | |||||
112 | ||||||
113 | return xl; | |||||
114 | } | |||||
115 | #endif | |||||
116 | ||||||
117 | static int | |||||
118 | volgen_xlator_link (xlator_t *pxl, xlator_t *cxl) | |||||
119 | { | |||||
120 | int ret = 0; | |||||
121 | ||||||
122 | ret = glusterfs_xlator_link (pxl, cxl); | |||||
123 | if (ret == -1) { | |||||
124 | gf_log ("", GF_LOG_ERROR,do { do { if (0) printf ("Out of memory, cannot link xlators %s <- %s" , pxl->name, cxl->name); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 126, GF_LOG_ERROR, "Out of memory, cannot link xlators %s <- %s" , pxl->name, cxl->name); } while (0) | |||||
125 | "Out of memory, cannot link xlators %s <- %s",do { do { if (0) printf ("Out of memory, cannot link xlators %s <- %s" , pxl->name, cxl->name); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 126, GF_LOG_ERROR, "Out of memory, cannot link xlators %s <- %s" , pxl->name, cxl->name); } while (0) | |||||
126 | pxl->name, cxl->name)do { do { if (0) printf ("Out of memory, cannot link xlators %s <- %s" , pxl->name, cxl->name); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 126, GF_LOG_ERROR, "Out of memory, cannot link xlators %s <- %s" , pxl->name, cxl->name); } while (0); | |||||
127 | } | |||||
128 | ||||||
129 | return ret; | |||||
130 | } | |||||
131 | ||||||
132 | static int | |||||
133 | volgen_graph_link (volgen_graph_t *graph, xlator_t *xl) | |||||
134 | { | |||||
135 | int ret = 0; | |||||
136 | ||||||
137 | /* no need to care about graph->top here */ | |||||
138 | if (graph->graph.first) | |||||
139 | ret = volgen_xlator_link (xl, graph->graph.first); | |||||
140 | if (ret == -1) { | |||||
141 | gf_log ("", GF_LOG_ERROR, "failed to add graph entry %s",do { do { if (0) printf ("failed to add graph entry %s", xl-> name); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 142, GF_LOG_ERROR, "failed to add graph entry %s", xl->name ); } while (0) | |||||
142 | xl->name)do { do { if (0) printf ("failed to add graph entry %s", xl-> name); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 142, GF_LOG_ERROR, "failed to add graph entry %s", xl->name ); } while (0); | |||||
143 | ||||||
144 | return -1; | |||||
145 | } | |||||
146 | ||||||
147 | return 0; | |||||
148 | } | |||||
149 | ||||||
150 | static xlator_t * | |||||
151 | volgen_graph_add_as (volgen_graph_t *graph, const char *type, | |||||
152 | const char *format, ...) | |||||
153 | { | |||||
154 | va_list arg; | |||||
155 | xlator_t *xl = NULL((void*)0); | |||||
156 | ||||||
157 | va_start (arg, format)__builtin_va_start(arg, format); | |||||
158 | xl = xlator_instantiate_va (type, format, arg); | |||||
159 | va_end (arg)__builtin_va_end(arg); | |||||
160 | ||||||
161 | if (!xl) | |||||
162 | return NULL((void*)0); | |||||
163 | ||||||
164 | if (volgen_graph_link (graph, xl)) { | |||||
165 | xlator_destroy (xl); | |||||
166 | ||||||
167 | return NULL((void*)0); | |||||
168 | } else | |||||
169 | glusterfs_graph_set_first (&graph->graph, xl); | |||||
170 | ||||||
171 | return xl; | |||||
172 | } | |||||
173 | ||||||
174 | static xlator_t * | |||||
175 | volgen_graph_add_nolink (volgen_graph_t *graph, const char *type, | |||||
176 | const char *format, ...) | |||||
177 | { | |||||
178 | va_list arg; | |||||
179 | xlator_t *xl = NULL((void*)0); | |||||
180 | ||||||
181 | va_start (arg, format)__builtin_va_start(arg, format); | |||||
182 | xl = xlator_instantiate_va (type, format, arg); | |||||
183 | va_end (arg)__builtin_va_end(arg); | |||||
184 | ||||||
185 | if (!xl) | |||||
186 | return NULL((void*)0); | |||||
187 | ||||||
188 | glusterfs_graph_set_first (&graph->graph, xl); | |||||
189 | ||||||
190 | return xl; | |||||
191 | } | |||||
192 | ||||||
193 | static xlator_t * | |||||
194 | volgen_graph_add (volgen_graph_t *graph, char *type, char *volname) | |||||
195 | { | |||||
196 | char *shorttype = NULL((void*)0); | |||||
197 | ||||||
198 | shorttype = strrchr (type, '/'); | |||||
199 | GF_ASSERT (shorttype)do { if (!(shorttype)) { do { do { if (0) printf ("Assertion failed: " "shorttype"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 199, GF_LOG_ERROR, "Assertion failed: " "shorttype" ); } while (0); } } while (0); | |||||
200 | shorttype++; | |||||
201 | GF_ASSERT (*shorttype)do { if (!(*shorttype)) { do { do { if (0) printf ("Assertion failed: " "*shorttype"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 201, GF_LOG_ERROR, "Assertion failed: " "*shorttype" ); } while (0); } } while (0); | |||||
202 | ||||||
203 | return volgen_graph_add_as (graph, type, "%s-%s", volname, shorttype); | |||||
204 | } | |||||
205 | ||||||
206 | /* XXX Seems there is no such generic routine? | |||||
207 | * Maybe should put to xlator.c ?? | |||||
208 | */ | |||||
209 | static int | |||||
210 | xlator_set_option (xlator_t *xl, char *key, char *value) | |||||
211 | { | |||||
212 | char *dval = NULL((void*)0); | |||||
213 | ||||||
214 | dval = gf_strdup (value); | |||||
215 | if (!dval) { | |||||
216 | gf_log ("", GF_LOG_ERROR,do { do { if (0) printf ("failed to set xlator opt: %s[%s] = %s" , xl->name, key, value); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 218, GF_LOG_ERROR, "failed to set xlator opt: %s[%s] = %s" , xl->name, key, value); } while (0) | |||||
217 | "failed to set xlator opt: %s[%s] = %s",do { do { if (0) printf ("failed to set xlator opt: %s[%s] = %s" , xl->name, key, value); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 218, GF_LOG_ERROR, "failed to set xlator opt: %s[%s] = %s" , xl->name, key, value); } while (0) | |||||
218 | xl->name, key, value)do { do { if (0) printf ("failed to set xlator opt: %s[%s] = %s" , xl->name, key, value); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 218, GF_LOG_ERROR, "failed to set xlator opt: %s[%s] = %s" , xl->name, key, value); } while (0); | |||||
219 | ||||||
220 | return -1; | |||||
221 | } | |||||
222 | ||||||
223 | return dict_set_dynstr (xl->options, key, dval); | |||||
224 | } | |||||
225 | ||||||
226 | static int | |||||
227 | xlator_get_option (xlator_t *xl, char *key, char **value) | |||||
228 | { | |||||
229 | GF_ASSERT (xl)do { if (!(xl)) { do { do { if (0) printf ("Assertion failed: " "xl"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 229, GF_LOG_ERROR, "Assertion failed: " "xl") ; } while (0); } } while (0); | |||||
230 | return dict_get_str (xl->options, key, value); | |||||
231 | } | |||||
232 | ||||||
233 | static inline xlator_t * | |||||
234 | first_of (volgen_graph_t *graph) | |||||
235 | { | |||||
236 | return (xlator_t *)graph->graph.first; | |||||
237 | } | |||||
238 | ||||||
239 | ||||||
240 | ||||||
241 | ||||||
242 | /************************** | |||||
243 | * | |||||
244 | * Trie glue | |||||
245 | * | |||||
246 | *************************/ | |||||
247 | ||||||
248 | ||||||
249 | static int | |||||
250 | volopt_selector (int lvl, char **patt, void *param, | |||||
251 | int (*optcbk)(char *word, void *param)) | |||||
252 | { | |||||
253 | struct volopt_map_entry *vme = NULL((void*)0); | |||||
254 | char *w = NULL((void*)0); | |||||
255 | int i = 0; | |||||
256 | int len = 0; | |||||
257 | int ret = 0; | |||||
258 | char *dot = NULL((void*)0); | |||||
259 | ||||||
260 | for (vme = glusterd_volopt_map; vme->key; vme++) { | |||||
261 | w = vme->key; | |||||
262 | ||||||
263 | for (i = 0; i < lvl; i++) { | |||||
264 | if (patt[i]) { | |||||
265 | w = strtail (w, patt[i]); | |||||
266 | GF_ASSERT (!w || *w)do { if (!(!w || *w)) { do { do { if (0) printf ("Assertion failed: " "!w || *w"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 266, GF_LOG_ERROR, "Assertion failed: " "!w || *w" ); } while (0); } } while (0); | |||||
267 | if (!w || *w != '.') | |||||
268 | goto next; | |||||
269 | } else { | |||||
270 | w = strchr (w, '.'); | |||||
271 | GF_ASSERT (w)do { if (!(w)) { do { do { if (0) printf ("Assertion failed: " "w"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 271, GF_LOG_ERROR, "Assertion failed: " "w"); } while (0); } } while (0); | |||||
272 | } | |||||
273 | w++; | |||||
274 | } | |||||
275 | ||||||
276 | dot = strchr (w, '.'); | |||||
277 | if (dot) { | |||||
278 | len = dot - w; | |||||
279 | w = gf_strdup (w); | |||||
280 | if (!w) | |||||
281 | return -1; | |||||
282 | w[len] = '\0'; | |||||
283 | } | |||||
284 | ret = optcbk (w, param); | |||||
285 | if (dot) | |||||
286 | GF_FREE (w)__gf_free (w); | |||||
287 | if (ret) | |||||
288 | return -1; | |||||
289 | next: | |||||
290 | continue; | |||||
291 | } | |||||
292 | ||||||
293 | return 0; | |||||
294 | } | |||||
295 | ||||||
296 | static int | |||||
297 | volopt_trie_cbk (char *word, void *param) | |||||
298 | { | |||||
299 | return trie_add ((trie_t *)param, word); | |||||
300 | } | |||||
301 | ||||||
302 | static int | |||||
303 | process_nodevec (struct trienodevec *nodevec, char **hint) | |||||
304 | { | |||||
305 | int ret = 0; | |||||
306 | char *hint1 = NULL((void*)0); | |||||
307 | char *hint2 = NULL((void*)0); | |||||
308 | char *hintinfx = ""; | |||||
309 | trienode_t **nodes = nodevec->nodes; | |||||
310 | ||||||
311 | if (!nodes[0]) { | |||||
312 | *hint = NULL((void*)0); | |||||
313 | return 0; | |||||
314 | } | |||||
315 | ||||||
316 | #if 0 | |||||
317 | /* Limit as in git */ | |||||
318 | if (trienode_get_dist (nodes[0]) >= 6) { | |||||
319 | *hint = NULL((void*)0); | |||||
320 | return 0; | |||||
321 | } | |||||
322 | #endif | |||||
323 | ||||||
324 | if (trienode_get_word (nodes[0], &hint1)) | |||||
325 | return -1; | |||||
326 | ||||||
327 | if (nodevec->cnt < 2 || !nodes[1]) { | |||||
328 | *hint = hint1; | |||||
329 | return 0; | |||||
330 | } | |||||
331 | ||||||
332 | if (trienode_get_word (nodes[1], &hint2)) | |||||
333 | return -1; | |||||
334 | ||||||
335 | if (*hint) | |||||
336 | hintinfx = *hint; | |||||
337 | ret = gf_asprintf (hint, "%s or %s%s", hint1, hintinfx, hint2); | |||||
338 | if (ret > 0) | |||||
339 | ret = 0; | |||||
340 | return ret; | |||||
341 | } | |||||
342 | ||||||
343 | static int | |||||
344 | volopt_trie_section (int lvl, char **patt, char *word, char **hint, int hints) | |||||
345 | { | |||||
346 | trienode_t *nodes[] = { NULL((void*)0), NULL((void*)0) }; | |||||
347 | struct trienodevec nodevec = { nodes, 2}; | |||||
348 | trie_t *trie = NULL((void*)0); | |||||
349 | int ret = 0; | |||||
350 | ||||||
351 | trie = trie_new (); | |||||
352 | if (!trie) | |||||
353 | return -1; | |||||
354 | ||||||
355 | if (volopt_selector (lvl, patt, trie, &volopt_trie_cbk)) { | |||||
356 | trie_destroy (trie); | |||||
357 | ||||||
358 | return -1; | |||||
359 | } | |||||
360 | ||||||
361 | GF_ASSERT (hints <= 2)do { if (!(hints <= 2)) { do { do { if (0) printf ("Assertion failed: " "hints <= 2"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 361, GF_LOG_ERROR, "Assertion failed: " "hints <= 2" ); } while (0); } } while (0); | |||||
362 | nodevec.cnt = hints; | |||||
363 | ret = trie_measure_vec (trie, word, &nodevec); | |||||
364 | if (ret || !nodevec.nodes[0]) | |||||
365 | trie_destroy (trie); | |||||
366 | ||||||
367 | ret = process_nodevec (&nodevec, hint); | |||||
368 | trie_destroy (trie); | |||||
369 | ||||||
370 | return ret; | |||||
371 | } | |||||
372 | ||||||
373 | static int | |||||
374 | volopt_trie (char *key, char **hint) | |||||
375 | { | |||||
376 | char *patt[] = { NULL((void*)0) }; | |||||
377 | char *fullhint = NULL((void*)0); | |||||
378 | char *dot = NULL((void*)0); | |||||
379 | char *dom = NULL((void*)0); | |||||
380 | int len = 0; | |||||
381 | int ret = 0; | |||||
382 | ||||||
383 | *hint = NULL((void*)0); | |||||
384 | ||||||
385 | dot = strchr (key, '.'); | |||||
386 | if (!dot) | |||||
387 | return volopt_trie_section (1, patt, key, hint, 2); | |||||
388 | ||||||
389 | len = dot - key; | |||||
390 | dom = gf_strdup (key); | |||||
391 | if (!dom) | |||||
392 | return -1; | |||||
393 | dom[len] = '\0'; | |||||
394 | ||||||
395 | ret = volopt_trie_section (0, NULL((void*)0), dom, patt, 1); | |||||
396 | GF_FREE (dom)__gf_free (dom); | |||||
397 | if (ret) { | |||||
398 | patt[0] = NULL((void*)0); | |||||
399 | goto out; | |||||
400 | } | |||||
401 | if (!patt[0]) | |||||
402 | goto out; | |||||
403 | ||||||
404 | *hint = "..."; | |||||
405 | ret = volopt_trie_section (1, patt, dot + 1, hint, 2); | |||||
406 | if (ret) | |||||
407 | goto out; | |||||
408 | if (*hint) { | |||||
409 | ret = gf_asprintf (&fullhint, "%s.%s", patt[0], *hint); | |||||
410 | GF_FREE (*hint)__gf_free (*hint); | |||||
411 | if (ret >= 0) { | |||||
412 | ret = 0; | |||||
413 | *hint = fullhint; | |||||
414 | } | |||||
415 | } | |||||
416 | ||||||
417 | out: | |||||
418 | GF_FREE (patt[0])__gf_free (patt[0]); | |||||
419 | if (ret) | |||||
420 | *hint = NULL((void*)0); | |||||
421 | ||||||
422 | return ret; | |||||
423 | } | |||||
424 | ||||||
425 | ||||||
426 | ||||||
427 | ||||||
428 | /************************** | |||||
429 | * | |||||
430 | * Volume generation engine | |||||
431 | * | |||||
432 | **************************/ | |||||
433 | ||||||
434 | ||||||
435 | typedef int (*volgen_opthandler_t) (volgen_graph_t *graph, | |||||
436 | struct volopt_map_entry *vme, | |||||
437 | void *param); | |||||
438 | ||||||
439 | struct opthandler_data { | |||||
440 | volgen_graph_t *graph; | |||||
441 | volgen_opthandler_t handler; | |||||
442 | struct volopt_map_entry *vme; | |||||
443 | gf_boolean_t found; | |||||
444 | gf_boolean_t data_t_fake; | |||||
445 | int rv; | |||||
446 | char *volname; | |||||
447 | void *param; | |||||
448 | }; | |||||
449 | ||||||
450 | static int | |||||
451 | process_option (char *key, data_t *value, void *param) | |||||
452 | { | |||||
453 | struct opthandler_data *odt = param; | |||||
454 | struct volopt_map_entry vme = {0,}; | |||||
455 | ||||||
456 | if (odt->rv) | |||||
457 | return 0; | |||||
458 | odt->found = _gf_true; | |||||
459 | ||||||
460 | vme.key = key; | |||||
461 | vme.voltype = odt->vme->voltype; | |||||
462 | vme.option = odt->vme->option; | |||||
463 | if (!vme.option) { | |||||
464 | vme.option = strrchr (key, '.'); | |||||
465 | if (vme.option) | |||||
466 | vme.option++; | |||||
467 | else | |||||
468 | vme.option = key; | |||||
469 | } | |||||
470 | if (odt->data_t_fake) | |||||
471 | vme.value = (char *)value; | |||||
472 | else | |||||
473 | vme.value = value->data; | |||||
474 | ||||||
475 | odt->rv = odt->handler (odt->graph, &vme, odt->param); | |||||
476 | return 0; | |||||
477 | } | |||||
478 | ||||||
479 | static int | |||||
480 | volgen_graph_set_options_generic (volgen_graph_t *graph, dict_t *dict, | |||||
481 | void *param, volgen_opthandler_t handler) | |||||
482 | { | |||||
483 | struct volopt_map_entry *vme = NULL((void*)0); | |||||
484 | struct opthandler_data odt = {0,}; | |||||
485 | data_t *data = NULL((void*)0); | |||||
486 | ||||||
487 | odt.graph = graph; | |||||
488 | odt.handler = handler; | |||||
489 | odt.param = param; | |||||
490 | (void)data; | |||||
491 | ||||||
492 | for (vme = glusterd_volopt_map; vme->key; vme++) { | |||||
493 | odt.vme = vme; | |||||
494 | odt.found = _gf_false; | |||||
495 | odt.data_t_fake = _gf_false; | |||||
496 | ||||||
497 | data = dict_get (dict, vme->key); | |||||
498 | ||||||
499 | if (data) | |||||
500 | process_option (vme->key, data, &odt); | |||||
501 | if (odt.rv) | |||||
502 | return odt.rv; | |||||
503 | ||||||
504 | if (odt.found) | |||||
505 | continue; | |||||
506 | ||||||
507 | /* check for default value */ | |||||
508 | ||||||
509 | if (vme->value) { | |||||
510 | /* stupid hack to be able to reuse dict iterator | |||||
511 | * in this context | |||||
512 | */ | |||||
513 | odt.data_t_fake = _gf_true; | |||||
514 | process_option (vme->key, (data_t *)vme->value, &odt); | |||||
515 | if (odt.rv) | |||||
516 | return odt.rv; | |||||
517 | } | |||||
518 | } | |||||
519 | ||||||
520 | return 0; | |||||
521 | } | |||||
522 | ||||||
523 | static int | |||||
524 | no_filter_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme, | |||||
525 | void *param) | |||||
526 | { | |||||
527 | xlator_t *trav; | |||||
528 | int ret = 0; | |||||
529 | ||||||
530 | for (trav = first_of (graph); trav; trav = trav->next) { | |||||
531 | if (strcmp (trav->type, vme->voltype) != 0) | |||||
532 | continue; | |||||
533 | ||||||
534 | ret = xlator_set_option (trav, vme->option, vme->value); | |||||
535 | if (ret) | |||||
536 | break; | |||||
537 | } | |||||
538 | return ret; | |||||
539 | } | |||||
540 | ||||||
541 | static int | |||||
542 | basic_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme, | |||||
543 | void *param) | |||||
544 | { | |||||
545 | int ret = 0; | |||||
546 | ||||||
547 | if (vme->option[0] == '!') | |||||
548 | goto out; | |||||
549 | ||||||
550 | ret = no_filter_option_handler (graph, vme, param); | |||||
551 | out: | |||||
552 | return ret; | |||||
553 | } | |||||
554 | ||||||
555 | static int | |||||
556 | volgen_graph_set_options (volgen_graph_t *graph, dict_t *dict) | |||||
557 | { | |||||
558 | return volgen_graph_set_options_generic (graph, dict, NULL((void*)0), | |||||
559 | &basic_option_handler); | |||||
560 | } | |||||
561 | ||||||
562 | static int | |||||
563 | optget_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme, | |||||
564 | void *param) | |||||
565 | { | |||||
566 | struct volopt_map_entry *vme2 = param; | |||||
567 | ||||||
568 | if (strcmp (vme->key, vme2->key) == 0) | |||||
569 | vme2->value = vme->value; | |||||
570 | ||||||
571 | return 0; | |||||
572 | } | |||||
573 | ||||||
574 | static glusterd_server_xlator_t | |||||
575 | get_server_xlator (char *xlator) | |||||
576 | { | |||||
577 | glusterd_server_xlator_t subvol = GF_XLATOR_NONE; | |||||
578 | ||||||
579 | if (strcmp (xlator, "posix") == 0) | |||||
580 | subvol = GF_XLATOR_POSIX; | |||||
581 | if (strcmp (xlator, "acl") == 0) | |||||
582 | subvol = GF_XLATOR_ACL; | |||||
583 | if (strcmp (xlator, "locks") == 0) | |||||
584 | subvol = GF_XLATOR_LOCKS; | |||||
585 | if (strcmp (xlator, "io-threads") == 0) | |||||
586 | subvol = GF_XLATOR_IOT; | |||||
587 | if (strcmp (xlator, "index") == 0) | |||||
588 | subvol = GF_XLATOR_INDEX; | |||||
589 | if (strcmp (xlator, "marker") == 0) | |||||
590 | subvol = GF_XLATOR_MARKER; | |||||
591 | if (strcmp (xlator, "io-stats") == 0) | |||||
592 | subvol = GF_XLATOR_IO_STATS; | |||||
593 | ||||||
594 | return subvol; | |||||
595 | } | |||||
596 | ||||||
597 | static glusterd_client_xlator_t | |||||
598 | get_client_xlator (char *xlator) | |||||
599 | { | |||||
600 | glusterd_client_xlator_t subvol = GF_CLNT_XLATOR_NONE; | |||||
601 | ||||||
602 | if (strcmp (xlator, "client") == 0) | |||||
603 | subvol = GF_CLNT_XLATOR_FUSE; | |||||
604 | ||||||
605 | return subvol; | |||||
606 | } | |||||
607 | ||||||
608 | static int | |||||
609 | debugxl_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme, | |||||
610 | void *param) | |||||
611 | { | |||||
612 | char *volname = NULL((void*)0); | |||||
613 | gf_boolean_t enabled = _gf_false; | |||||
614 | ||||||
615 | volname = param; | |||||
616 | ||||||
617 | if (strcmp (vme->option, "!debug") != 0) | |||||
618 | return 0; | |||||
619 | ||||||
620 | if (!strcmp (vme->key , "debug.trace") || | |||||
621 | !strcmp (vme->key, "debug.error-gen")) { | |||||
622 | if (get_server_xlator (vme->value) == GF_XLATOR_NONE && | |||||
623 | get_client_xlator (vme->value) == GF_CLNT_XLATOR_NONE) | |||||
624 | return 0; | |||||
625 | else | |||||
626 | goto add_graph; | |||||
627 | } | |||||
628 | ||||||
629 | if (gf_string2boolean (vme->value, &enabled) == -1) | |||||
630 | return -1; | |||||
631 | if (!enabled) | |||||
632 | return 0; | |||||
633 | ||||||
634 | add_graph: | |||||
635 | if (volgen_graph_add (graph, vme->voltype, volname)) | |||||
636 | return 0; | |||||
637 | else | |||||
638 | return -1; | |||||
639 | } | |||||
640 | ||||||
641 | int | |||||
642 | check_and_add_debug_xl (volgen_graph_t *graph, dict_t *set_dict, char *volname, | |||||
643 | char *xlname) | |||||
644 | { | |||||
645 | int ret = 0; | |||||
646 | char *value_str = NULL((void*)0); | |||||
647 | ||||||
648 | ret = dict_get_str (set_dict, "debug.trace", &value_str); | |||||
649 | if (!ret) { | |||||
650 | if (strcmp (xlname, value_str) == 0) { | |||||
651 | ret = volgen_graph_set_options_generic (graph, set_dict, volname, | |||||
652 | &debugxl_option_handler); | |||||
653 | if (ret) | |||||
654 | goto out; | |||||
655 | } | |||||
656 | } | |||||
657 | ||||||
658 | ret = dict_get_str (set_dict, "debug.error-gen", &value_str); | |||||
659 | if (!ret) { | |||||
660 | if (strcmp (xlname, value_str) == 0) { | |||||
661 | ret = volgen_graph_set_options_generic (graph, set_dict, volname, | |||||
662 | &debugxl_option_handler); | |||||
663 | if (ret) | |||||
664 | goto out; | |||||
665 | } | |||||
666 | } | |||||
667 | ||||||
668 | ret = 0; | |||||
669 | ||||||
670 | out: | |||||
671 | return ret; | |||||
672 | } | |||||
673 | ||||||
674 | /* This getter considers defaults also. */ | |||||
675 | static int | |||||
676 | volgen_dict_get (dict_t *dict, char *key, char **value) | |||||
677 | { | |||||
678 | struct volopt_map_entry vme = {0,}; | |||||
679 | int ret = 0; | |||||
680 | ||||||
681 | vme.key = key; | |||||
682 | ||||||
683 | ret = volgen_graph_set_options_generic (NULL((void*)0), dict, &vme, | |||||
684 | &optget_option_handler); | |||||
685 | if (ret) { | |||||
686 | gf_log ("", GF_LOG_ERROR, "Out of memory")do { do { if (0) printf ("Out of memory"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 686, GF_LOG_ERROR, "Out of memory" ); } while (0); | |||||
687 | ||||||
688 | return -1; | |||||
689 | } | |||||
690 | ||||||
691 | *value = vme.value; | |||||
692 | ||||||
693 | return 0; | |||||
694 | } | |||||
695 | ||||||
696 | static int | |||||
697 | option_complete (char *key, char **completion) | |||||
698 | { | |||||
699 | struct volopt_map_entry *vme = NULL((void*)0); | |||||
700 | ||||||
701 | *completion = NULL((void*)0); | |||||
702 | for (vme = glusterd_volopt_map; vme->key; vme++) { | |||||
703 | if (strcmp (strchr (vme->key, '.') + 1, key) != 0) | |||||
704 | continue; | |||||
705 | ||||||
706 | if (*completion && strcmp (*completion, vme->key) != 0) { | |||||
707 | /* cancel on non-unique match */ | |||||
708 | *completion = NULL((void*)0); | |||||
709 | ||||||
710 | return 0; | |||||
711 | } else | |||||
712 | *completion = vme->key; | |||||
713 | } | |||||
714 | ||||||
715 | if (*completion) { | |||||
716 | /* For sake of unified API we want | |||||
717 | * have the completion to be a to-be-freed | |||||
718 | * string. | |||||
719 | */ | |||||
720 | *completion = gf_strdup (*completion); | |||||
721 | return -!*completion; | |||||
722 | } | |||||
723 | ||||||
724 | return 0; | |||||
725 | } | |||||
726 | ||||||
727 | int | |||||
728 | glusterd_volinfo_get (glusterd_volinfo_t *volinfo, char *key, char **value) | |||||
729 | { | |||||
730 | return volgen_dict_get (volinfo->dict, key, value); | |||||
731 | } | |||||
732 | ||||||
733 | int | |||||
734 | glusterd_volinfo_get_boolean (glusterd_volinfo_t *volinfo, char *key) | |||||
735 | { | |||||
736 | char *val = NULL((void*)0); | |||||
737 | gf_boolean_t boo = _gf_false; | |||||
738 | int ret = 0; | |||||
739 | ||||||
740 | ret = glusterd_volinfo_get (volinfo, key, &val); | |||||
741 | if (ret) | |||||
742 | return -1; | |||||
743 | ||||||
744 | if (val) | |||||
745 | ret = gf_string2boolean (val, &boo); | |||||
746 | if (ret) { | |||||
747 | gf_log ("", GF_LOG_ERROR, "value for %s option is not valid", key)do { do { if (0) printf ("value for %s option is not valid", key ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 747, GF_LOG_ERROR, "value for %s option is not valid", key) ; } while (0); | |||||
748 | ||||||
749 | return -1; | |||||
750 | } | |||||
751 | ||||||
752 | return boo; | |||||
753 | } | |||||
754 | ||||||
755 | gf_boolean_t | |||||
756 | glusterd_check_voloption_flags (char *key, int32_t flags) | |||||
757 | { | |||||
758 | char *completion = NULL((void*)0); | |||||
759 | struct volopt_map_entry *vmep = NULL((void*)0); | |||||
760 | int ret = 0; | |||||
761 | ||||||
762 | COMPLETE_OPTION(key, completion, ret)do { if (!strchr (key, '.')) { ret = option_complete (key, & completion); if (ret) { do { do { if (0) printf ("Out of memory" ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 762, GF_LOG_ERROR, "Out of memory"); } while (0); return _gf_false ; } if (!completion) { do { do { if (0) printf ("option %s does not" "exist", key); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 762, GF_LOG_ERROR, "option %s does not" "exist" , key); } while (0); return _gf_false; } } if (completion) __gf_free (completion); } while (0);; | |||||
763 | for (vmep = glusterd_volopt_map; vmep->key; vmep++) { | |||||
764 | if (strcmp (vmep->key, key) == 0) { | |||||
765 | if (vmep->flags & flags) | |||||
766 | return _gf_true; | |||||
767 | else | |||||
768 | return _gf_false; | |||||
769 | } | |||||
770 | } | |||||
771 | ||||||
772 | return _gf_false; | |||||
773 | } | |||||
774 | ||||||
775 | gf_boolean_t | |||||
776 | glusterd_check_globaloption (char *key) | |||||
777 | { | |||||
778 | char *completion = NULL((void*)0); | |||||
779 | struct volopt_map_entry *vmep = NULL((void*)0); | |||||
780 | int ret = 0; | |||||
781 | ||||||
782 | COMPLETE_OPTION(key, completion, ret)do { if (!strchr (key, '.')) { ret = option_complete (key, & completion); if (ret) { do { do { if (0) printf ("Out of memory" ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 782, GF_LOG_ERROR, "Out of memory"); } while (0); return _gf_false ; } if (!completion) { do { do { if (0) printf ("option %s does not" "exist", key); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 782, GF_LOG_ERROR, "option %s does not" "exist" , key); } while (0); return _gf_false; } } if (completion) __gf_free (completion); } while (0);; | |||||
783 | for (vmep = glusterd_volopt_map; vmep->key; vmep++) { | |||||
784 | if (strcmp (vmep->key, key) == 0) { | |||||
785 | if ((vmep->type == GLOBAL_DOC) || | |||||
786 | (vmep->type == GLOBAL_NO_DOC)) | |||||
787 | return _gf_true; | |||||
788 | else | |||||
789 | return _gf_false; | |||||
790 | } | |||||
791 | } | |||||
792 | ||||||
793 | return _gf_false; | |||||
794 | } | |||||
795 | ||||||
796 | gf_boolean_t | |||||
797 | glusterd_check_localoption (char *key) | |||||
798 | { | |||||
799 | char *completion = NULL((void*)0); | |||||
800 | struct volopt_map_entry *vmep = NULL((void*)0); | |||||
801 | int ret = 0; | |||||
802 | ||||||
803 | COMPLETE_OPTION(key, completion, ret)do { if (!strchr (key, '.')) { ret = option_complete (key, & completion); if (ret) { do { do { if (0) printf ("Out of memory" ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 803, GF_LOG_ERROR, "Out of memory"); } while (0); return _gf_false ; } if (!completion) { do { do { if (0) printf ("option %s does not" "exist", key); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 803, GF_LOG_ERROR, "option %s does not" "exist" , key); } while (0); return _gf_false; } } if (completion) __gf_free (completion); } while (0);; | |||||
804 | for (vmep = glusterd_volopt_map; vmep->key; vmep++) { | |||||
805 | if (strcmp (vmep->key, key) == 0) { | |||||
806 | if ((vmep->type == DOC) || | |||||
807 | (vmep->type == NO_DOC)) | |||||
808 | return _gf_true; | |||||
809 | else | |||||
810 | return _gf_false; | |||||
811 | } | |||||
812 | } | |||||
813 | ||||||
814 | return _gf_false; | |||||
815 | } | |||||
816 | ||||||
817 | int | |||||
818 | glusterd_check_voloption (char *key) | |||||
819 | { | |||||
820 | char *completion = NULL((void*)0); | |||||
821 | struct volopt_map_entry *vmep = NULL((void*)0); | |||||
822 | int ret = 0; | |||||
823 | ||||||
824 | COMPLETE_OPTION(key, completion, ret)do { if (!strchr (key, '.')) { ret = option_complete (key, & completion); if (ret) { do { do { if (0) printf ("Out of memory" ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 824, GF_LOG_ERROR, "Out of memory"); } while (0); return _gf_false ; } if (!completion) { do { do { if (0) printf ("option %s does not" "exist", key); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 824, GF_LOG_ERROR, "option %s does not" "exist" , key); } while (0); return _gf_false; } } if (completion) __gf_free (completion); } while (0);; | |||||
825 | for (vmep = glusterd_volopt_map; vmep->key; vmep++) { | |||||
826 | if (strcmp (vmep->key, key) == 0) { | |||||
827 | if ((vmep->type == DOC) || | |||||
828 | (vmep->type == DOC)) | |||||
829 | return _gf_true; | |||||
830 | else | |||||
831 | return _gf_false; | |||||
832 | } | |||||
833 | } | |||||
834 | ||||||
835 | return _gf_false; | |||||
836 | ||||||
837 | } | |||||
838 | ||||||
839 | int | |||||
840 | glusterd_check_option_exists (char *key, char **completion) | |||||
841 | { | |||||
842 | struct volopt_map_entry vme = {0,}; | |||||
843 | struct volopt_map_entry *vmep = NULL((void*)0); | |||||
844 | int ret = 0; | |||||
845 | xlator_t *this = THIS(*__glusterfs_this_location()); | |||||
846 | ||||||
847 | (void)vme; | |||||
848 | (void)vmep; | |||||
849 | ||||||
850 | if (!strchr (key, '.')) { | |||||
851 | if (completion) { | |||||
852 | ret = option_complete (key, completion); | |||||
853 | if (ret) { | |||||
854 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("Out of memory"); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__, 855, GF_LOG_ERROR , "Out of memory"); } while (0) | |||||
855 | "Out of memory")do { do { if (0) printf ("Out of memory"); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__, 855, GF_LOG_ERROR , "Out of memory"); } while (0); | |||||
856 | return -1; | |||||
857 | } | |||||
858 | ||||||
859 | ret = !!*completion; | |||||
860 | if (ret) | |||||
861 | return ret; | |||||
862 | else | |||||
863 | goto trie; | |||||
864 | } else | |||||
865 | return 0; | |||||
866 | } | |||||
867 | ||||||
868 | for (vmep = glusterd_volopt_map; vmep->key; vmep++) { | |||||
869 | if (strcmp (vmep->key, key) == 0) { | |||||
870 | ret = 1; | |||||
871 | break; | |||||
872 | } | |||||
873 | } | |||||
874 | ||||||
875 | if (ret || !completion) | |||||
876 | return ret; | |||||
877 | ||||||
878 | trie: | |||||
879 | ret = volopt_trie (key, completion); | |||||
880 | if (ret) { | |||||
881 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("Some error occurred during keyword hinting" ); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__ , 882, GF_LOG_ERROR, "Some error occurred during keyword hinting" ); } while (0) | |||||
882 | "Some error occurred during keyword hinting")do { do { if (0) printf ("Some error occurred during keyword hinting" ); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__ , 882, GF_LOG_ERROR, "Some error occurred during keyword hinting" ); } while (0); | |||||
883 | } | |||||
884 | ||||||
885 | return ret; | |||||
886 | } | |||||
887 | ||||||
888 | char* | |||||
889 | glusterd_get_trans_type_rb (gf_transport_type ttype) | |||||
890 | { | |||||
891 | char *trans_type = NULL((void*)0); | |||||
892 | ||||||
893 | switch (ttype) { | |||||
894 | case GF_TRANSPORT_RDMA: | |||||
895 | gf_asprintf (&trans_type, "rdma"); | |||||
896 | break; | |||||
897 | case GF_TRANSPORT_TCP: | |||||
898 | case GF_TRANSPORT_BOTH_TCP_RDMA: | |||||
899 | gf_asprintf (&trans_type, "tcp"); | |||||
900 | break; | |||||
901 | default: | |||||
902 | gf_log (THIS->name, GF_LOG_ERROR, "Unknown "do { do { if (0) printf ("Unknown " "transport type"); } while (0); _gf_log ((*__glusterfs_this_location())->name, "glusterd-volgen.c" , __FUNCTION__, 903, GF_LOG_ERROR, "Unknown " "transport type" ); } while (0) | |||||
903 | "transport type")do { do { if (0) printf ("Unknown " "transport type"); } while (0); _gf_log ((*__glusterfs_this_location())->name, "glusterd-volgen.c" , __FUNCTION__, 903, GF_LOG_ERROR, "Unknown " "transport type" ); } while (0); | |||||
904 | } | |||||
905 | ||||||
906 | return trans_type; | |||||
907 | } | |||||
908 | ||||||
909 | static int | |||||
910 | _xl_link_children (xlator_t *parent, xlator_t *children, size_t child_count) | |||||
911 | { | |||||
912 | xlator_t *trav = NULL((void*)0); | |||||
913 | size_t seek = 0; | |||||
914 | int ret = -1; | |||||
915 | ||||||
916 | if (child_count == 0) | |||||
917 | goto out; | |||||
918 | seek = child_count; | |||||
919 | for (trav = children; --seek; trav = trav->next); | |||||
920 | for (; child_count--; trav = trav->prev) { | |||||
921 | ret = volgen_xlator_link (parent, trav); | |||||
922 | if (ret) | |||||
923 | goto out; | |||||
924 | } | |||||
925 | ret = 0; | |||||
926 | out: | |||||
927 | return ret; | |||||
928 | } | |||||
929 | ||||||
930 | static int | |||||
931 | volgen_graph_merge_sub (volgen_graph_t *dgraph, volgen_graph_t *sgraph, | |||||
932 | size_t child_count) | |||||
933 | { | |||||
934 | xlator_t *trav = NULL((void*)0); | |||||
935 | int ret = 0; | |||||
936 | ||||||
937 | GF_ASSERT (dgraph->graph.first)do { if (!(dgraph->graph.first)) { do { do { if (0) printf ("Assertion failed: " "dgraph->graph.first"); } while (0) ; _gf_log_callingfn ("", "glusterd-volgen.c", __FUNCTION__, 937 , GF_LOG_ERROR, "Assertion failed: " "dgraph->graph.first" ); } while (0); } } while (0); | |||||
938 | ||||||
939 | ret = _xl_link_children (first_of (dgraph), first_of (sgraph), | |||||
940 | child_count); | |||||
941 | if (ret) | |||||
942 | goto out; | |||||
943 | ||||||
944 | for (trav = first_of (dgraph); trav->next; trav = trav->next); | |||||
945 | ||||||
946 | trav->next = first_of (sgraph); | |||||
947 | trav->next->prev = trav; | |||||
948 | dgraph->graph.xl_count += sgraph->graph.xl_count; | |||||
949 | ||||||
950 | out: | |||||
951 | return ret; | |||||
952 | } | |||||
953 | ||||||
954 | static void | |||||
955 | volgen_apply_filters (char *orig_volfile) | |||||
956 | { | |||||
957 | DIR *filterdir = NULL((void*)0); | |||||
958 | struct dirent entry = {0,}; | |||||
959 | struct dirent *next = NULL((void*)0); | |||||
960 | char *filterpath = NULL((void*)0); | |||||
961 | struct stat statbuf = {0,}; | |||||
962 | ||||||
963 | filterdir = opendir(FILTERDIR"/usr/local/lib/glusterfs/3git/filter"); | |||||
964 | if (!filterdir) { | |||||
965 | return; | |||||
966 | } | |||||
967 | ||||||
968 | while ((readdir_r(filterdir,&entry,&next) == 0) && next) { | |||||
969 | if (!strncmp(entry.d_name,".",sizeof(entry.d_name))) { | |||||
970 | continue; | |||||
971 | } | |||||
972 | if (!strncmp(entry.d_name,"..",sizeof(entry.d_name))) { | |||||
973 | continue; | |||||
974 | } | |||||
975 | /* | |||||
976 | * d_type isn't guaranteed to be present/valid on all systems, | |||||
977 | * so do an explicit stat instead. | |||||
978 | */ | |||||
979 | if (gf_asprintf(&filterpath,"%s/%.*s",FILTERDIR"/usr/local/lib/glusterfs/3git/filter", | |||||
980 | sizeof(entry.d_name), entry.d_name) == (-1)) { | |||||
981 | continue; | |||||
982 | } | |||||
983 | /* Deliberately use stat instead of lstat to allow symlinks. */ | |||||
984 | if (stat(filterpath,&statbuf) == (-1)) { | |||||
985 | goto free_fp; | |||||
986 | } | |||||
987 | if (!S_ISREG(statbuf.st_mode)((((statbuf.st_mode)) & 0170000) == (0100000))) { | |||||
988 | goto free_fp; | |||||
989 | } | |||||
990 | /* | |||||
991 | * We could check the mode in statbuf directly, or just skip | |||||
992 | * this entirely and check for EPERM after exec fails, but this | |||||
993 | * is cleaner. | |||||
994 | */ | |||||
995 | if (access(filterpath,X_OK1) != 0) { | |||||
996 | goto free_fp; | |||||
997 | } | |||||
998 | if (runcmd(filterpath,orig_volfile,NULL((void*)0))) { | |||||
999 | gf_log("",GF_LOG_ERROR,"failed to run filter %.*s",do { do { if (0) printf ("failed to run filter %.*s", (int)sizeof (entry.d_name), entry.d_name); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 1000, GF_LOG_ERROR,"failed to run filter %.*s" , (int)sizeof(entry.d_name), entry.d_name); } while (0) | |||||
1000 | (int)sizeof(entry.d_name), entry.d_name)do { do { if (0) printf ("failed to run filter %.*s", (int)sizeof (entry.d_name), entry.d_name); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 1000, GF_LOG_ERROR,"failed to run filter %.*s" , (int)sizeof(entry.d_name), entry.d_name); } while (0); | |||||
1001 | } | |||||
1002 | free_fp: | |||||
1003 | GF_FREE(filterpath)__gf_free (filterpath); | |||||
1004 | } | |||||
1005 | } | |||||
1006 | ||||||
1007 | static int | |||||
1008 | volgen_write_volfile (volgen_graph_t *graph, char *filename) | |||||
1009 | { | |||||
1010 | char *ftmp = NULL((void*)0); | |||||
1011 | FILE *f = NULL((void*)0); | |||||
1012 | int fd = 0; | |||||
1013 | xlator_t *this = NULL((void*)0); | |||||
1014 | ||||||
1015 | this = THIS(*__glusterfs_this_location()); | |||||
1016 | ||||||
1017 | if (gf_asprintf (&ftmp, "%s.tmp", filename) == -1) { | |||||
1018 | ftmp = NULL((void*)0); | |||||
1019 | ||||||
1020 | goto error; | |||||
1021 | } | |||||
1022 | ||||||
1023 | fd = creat (ftmp, S_IRUSR0400 | S_IWUSR0200); | |||||
1024 | if (fd < 0) { | |||||
1025 | gf_log (this->name, GF_LOG_ERROR, "%s",do { do { if (0) printf ("%s", strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "glusterd-volgen.c" , __FUNCTION__, 1026, GF_LOG_ERROR, "%s", strerror ((*__errno_location ()))); } while (0) | |||||
1026 | strerror (errno))do { do { if (0) printf ("%s", strerror ((*__errno_location ( )))); } while (0); _gf_log (this->name, "glusterd-volgen.c" , __FUNCTION__, 1026, GF_LOG_ERROR, "%s", strerror ((*__errno_location ()))); } while (0); | |||||
1027 | goto error; | |||||
1028 | } | |||||
1029 | ||||||
1030 | close (fd); | |||||
1031 | ||||||
1032 | f = fopen (ftmp, "w"); | |||||
1033 | if (!f) | |||||
1034 | goto error; | |||||
1035 | ||||||
1036 | if (glusterfs_graph_print_file (f, &graph->graph) == -1) | |||||
1037 | goto error; | |||||
1038 | ||||||
1039 | if (fclose (f) != 0) { | |||||
1040 | gf_log (THIS->name, GF_LOG_ERROR, "fclose on the file %s "do { do { if (0) printf ("fclose on the file %s " "failed (%s)" , ftmp, strerror ((*__errno_location ()))); } while (0); _gf_log ((*__glusterfs_this_location())->name, "glusterd-volgen.c" , __FUNCTION__, 1041, GF_LOG_ERROR, "fclose on the file %s " "failed (%s)" , ftmp, strerror ((*__errno_location ()))); } while (0) | |||||
1041 | "failed (%s)", ftmp, strerror (errno))do { do { if (0) printf ("fclose on the file %s " "failed (%s)" , ftmp, strerror ((*__errno_location ()))); } while (0); _gf_log ((*__glusterfs_this_location())->name, "glusterd-volgen.c" , __FUNCTION__, 1041, GF_LOG_ERROR, "fclose on the file %s " "failed (%s)" , ftmp, strerror ((*__errno_location ()))); } while (0); | |||||
1042 | /* | |||||
1043 | * Even though fclose has failed here, we have to set f to NULL. | |||||
1044 | * Otherwise when the code path goes to error, there again we | |||||
1045 | * try to close it which might cause undefined behavior such as | |||||
1046 | * process crash. | |||||
1047 | */ | |||||
1048 | f = NULL((void*)0); | |||||
1049 | goto error; | |||||
1050 | } | |||||
1051 | ||||||
1052 | f = NULL((void*)0); | |||||
1053 | ||||||
1054 | if (rename (ftmp, filename) == -1) | |||||
1055 | goto error; | |||||
1056 | ||||||
1057 | GF_FREE (ftmp)__gf_free (ftmp); | |||||
1058 | ||||||
1059 | volgen_apply_filters(filename); | |||||
1060 | ||||||
1061 | return 0; | |||||
1062 | ||||||
1063 | error: | |||||
1064 | ||||||
1065 | GF_FREE (ftmp)__gf_free (ftmp); | |||||
1066 | if (f) | |||||
1067 | fclose (f); | |||||
1068 | ||||||
1069 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("failed to create volfile %s", filename ); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__ , 1070, GF_LOG_ERROR, "failed to create volfile %s", filename ); } while (0) | |||||
1070 | "failed to create volfile %s", filename)do { do { if (0) printf ("failed to create volfile %s", filename ); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__ , 1070, GF_LOG_ERROR, "failed to create volfile %s", filename ); } while (0); | |||||
1071 | ||||||
1072 | return -1; | |||||
1073 | } | |||||
1074 | ||||||
1075 | static void | |||||
1076 | volgen_graph_free (volgen_graph_t *graph) | |||||
1077 | { | |||||
1078 | xlator_t *trav = NULL((void*)0); | |||||
1079 | xlator_t *trav_old = NULL((void*)0); | |||||
1080 | ||||||
1081 | for (trav = first_of (graph) ;; trav = trav->next) { | |||||
1082 | if (trav_old) | |||||
1083 | xlator_destroy (trav_old); | |||||
1084 | ||||||
1085 | trav_old = trav; | |||||
1086 | ||||||
1087 | if (!trav) | |||||
1088 | break; | |||||
1089 | } | |||||
1090 | } | |||||
1091 | ||||||
1092 | static int | |||||
1093 | build_graph_generic (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, | |||||
1094 | dict_t *mod_dict, void *param, | |||||
1095 | int (*builder) (volgen_graph_t *graph, | |||||
1096 | glusterd_volinfo_t *volinfo, | |||||
1097 | dict_t *set_dict, void *param)) | |||||
1098 | { | |||||
1099 | dict_t *set_dict = NULL((void*)0); | |||||
1100 | int ret = 0; | |||||
1101 | ||||||
1102 | if (mod_dict) { | |||||
1103 | set_dict = dict_copy (volinfo->dict, NULL((void*)0)); | |||||
1104 | if (!set_dict) | |||||
1105 | return -1; | |||||
1106 | dict_copy (mod_dict, set_dict); | |||||
1107 | /* XXX dict_copy swallows errors */ | |||||
1108 | } else { | |||||
1109 | set_dict = volinfo->dict; | |||||
1110 | } | |||||
1111 | ||||||
1112 | ret = builder (graph, volinfo, set_dict, param); | |||||
1113 | if (!ret) | |||||
1114 | ret = volgen_graph_set_options (graph, set_dict); | |||||
1115 | ||||||
1116 | if (mod_dict) | |||||
1117 | dict_destroy (set_dict); | |||||
1118 | ||||||
1119 | return ret; | |||||
1120 | } | |||||
1121 | ||||||
1122 | static gf_transport_type | |||||
1123 | transport_str_to_type (char *tt) | |||||
1124 | { | |||||
1125 | gf_transport_type type = GF_TRANSPORT_TCP; | |||||
1126 | ||||||
1127 | if (!strcmp ("tcp", tt)) | |||||
1128 | type = GF_TRANSPORT_TCP; | |||||
1129 | else if (!strcmp ("rdma", tt)) | |||||
1130 | type = GF_TRANSPORT_RDMA; | |||||
1131 | else if (!strcmp ("tcp,rdma", tt)) | |||||
1132 | type = GF_TRANSPORT_BOTH_TCP_RDMA; | |||||
1133 | return type; | |||||
1134 | } | |||||
1135 | ||||||
1136 | static void | |||||
1137 | transport_type_to_str (gf_transport_type type, char *tt) | |||||
1138 | { | |||||
1139 | switch (type) { | |||||
1140 | case GF_TRANSPORT_RDMA: | |||||
1141 | strcpy (tt, "rdma"); | |||||
1142 | break; | |||||
1143 | case GF_TRANSPORT_TCP: | |||||
1144 | strcpy (tt, "tcp"); | |||||
1145 | break; | |||||
1146 | case GF_TRANSPORT_BOTH_TCP_RDMA: | |||||
1147 | strcpy (tt, "tcp,rdma"); | |||||
1148 | break; | |||||
1149 | } | |||||
1150 | } | |||||
1151 | ||||||
1152 | static void | |||||
1153 | get_vol_transport_type (glusterd_volinfo_t *volinfo, char *tt) | |||||
1154 | { | |||||
1155 | transport_type_to_str (volinfo->transport_type, tt); | |||||
1156 | } | |||||
1157 | ||||||
1158 | static void | |||||
1159 | get_vol_nfs_transport_type (glusterd_volinfo_t *volinfo, char *tt) | |||||
1160 | { | |||||
1161 | if (volinfo->nfs_transport_type == GF_TRANSPORT_BOTH_TCP_RDMA) { | |||||
1162 | gf_log ("", GF_LOG_ERROR, "%s:nfs transport cannot be both"do { do { if (0) printf ("%s:nfs transport cannot be both" " tcp and rdma" , volinfo->volname); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 1163, GF_LOG_ERROR, "%s:nfs transport cannot be both" " tcp and rdma", volinfo->volname); } while (0) | |||||
1163 | " tcp and rdma", volinfo->volname)do { do { if (0) printf ("%s:nfs transport cannot be both" " tcp and rdma" , volinfo->volname); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 1163, GF_LOG_ERROR, "%s:nfs transport cannot be both" " tcp and rdma", volinfo->volname); } while (0); | |||||
1164 | GF_ASSERT (0)do { if (!(0)) { do { do { if (0) printf ("Assertion failed: " "0"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 1164, GF_LOG_ERROR, "Assertion failed: " "0") ; } while (0); } } while (0); | |||||
1165 | } | |||||
1166 | transport_type_to_str (volinfo->nfs_transport_type, tt); | |||||
1167 | } | |||||
1168 | ||||||
1169 | /* gets the volinfo, dict, a character array for filling in | |||||
1170 | * the transport type and a boolean option which says whether | |||||
1171 | * the transport type is required for nfs or not. If its not | |||||
1172 | * for nfs, then it is considered as the client transport | |||||
1173 | * and client transport type is filled in the character array | |||||
1174 | */ | |||||
1175 | static void | |||||
1176 | get_transport_type (glusterd_volinfo_t *volinfo, dict_t *set_dict, | |||||
1177 | char *transt, gf_boolean_t is_nfs) | |||||
1178 | { | |||||
1179 | int ret = -1; | |||||
1180 | char *tt = NULL((void*)0); | |||||
1181 | char *key = NULL((void*)0); | |||||
1182 | typedef void (*transport_type) (glusterd_volinfo_t *volinfo, char *tt); | |||||
1183 | transport_type get_transport; | |||||
1184 | ||||||
1185 | if (is_nfs == _gf_false) { | |||||
1186 | key = "client-transport-type"; | |||||
1187 | get_transport = get_vol_transport_type; | |||||
1188 | } else { | |||||
1189 | key = "nfs.transport-type"; | |||||
1190 | get_transport = get_vol_nfs_transport_type; | |||||
1191 | } | |||||
1192 | ||||||
1193 | ret = dict_get_str (set_dict, key, &tt); | |||||
1194 | if (ret) | |||||
1195 | get_transport (volinfo, transt); | |||||
1196 | if (!ret) | |||||
1197 | strcpy (transt, tt); | |||||
1198 | } | |||||
1199 | ||||||
1200 | static int | |||||
1201 | server_auth_option_handler (volgen_graph_t *graph, | |||||
1202 | struct volopt_map_entry *vme, void *param) | |||||
1203 | { | |||||
1204 | xlator_t *xl = NULL((void*)0); | |||||
1205 | xlator_list_t *trav = NULL((void*)0); | |||||
1206 | char *aa = NULL((void*)0); | |||||
1207 | int ret = 0; | |||||
1208 | char *key = NULL((void*)0); | |||||
1209 | ||||||
1210 | if (strcmp (vme->option, "!server-auth") != 0) | |||||
1211 | return 0; | |||||
1212 | ||||||
1213 | xl = first_of (graph); | |||||
1214 | ||||||
1215 | /* from 'auth.allow' -> 'allow', and 'auth.reject' -> 'reject' */ | |||||
1216 | key = strchr (vme->key, '.') + 1; | |||||
1217 | ||||||
1218 | for (trav = xl->children; trav; trav = trav->next) { | |||||
1219 | ret = gf_asprintf (&aa, "auth.addr.%s.%s", trav->xlator->name, | |||||
1220 | key); | |||||
1221 | if (ret != -1) { | |||||
1222 | ret = xlator_set_option (xl, aa, vme->value); | |||||
1223 | GF_FREE (aa)__gf_free (aa); | |||||
1224 | } | |||||
1225 | if (ret) | |||||
1226 | return -1; | |||||
1227 | } | |||||
1228 | ||||||
1229 | return 0; | |||||
1230 | } | |||||
1231 | ||||||
1232 | static int | |||||
1233 | loglevel_option_handler (volgen_graph_t *graph, | |||||
1234 | struct volopt_map_entry *vme, void *param) | |||||
1235 | { | |||||
1236 | char *role = param; | |||||
1237 | struct volopt_map_entry vme2 = {0,}; | |||||
1238 | ||||||
1239 | if ( (strcmp (vme->option, "!client-log-level") != 0 && | |||||
1240 | strcmp (vme->option, "!brick-log-level") != 0) | |||||
1241 | || !strstr (vme->key, role)) | |||||
1242 | return 0; | |||||
1243 | ||||||
1244 | memcpy (&vme2, vme, sizeof (vme2)); | |||||
1245 | vme2.option = "log-level"; | |||||
1246 | ||||||
1247 | return basic_option_handler (graph, &vme2, NULL((void*)0)); | |||||
1248 | } | |||||
1249 | ||||||
1250 | static int | |||||
1251 | server_check_marker_off (volgen_graph_t *graph, struct volopt_map_entry *vme, | |||||
1252 | glusterd_volinfo_t *volinfo) | |||||
1253 | { | |||||
1254 | gf_boolean_t bool = _gf_false; | |||||
1255 | int ret = 0; | |||||
1256 | ||||||
1257 | GF_ASSERT (volinfo)do { if (!(volinfo)) { do { do { if (0) printf ("Assertion failed: " "volinfo"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 1257, GF_LOG_ERROR, "Assertion failed: " "volinfo" ); } while (0); } } while (0); | |||||
1258 | GF_ASSERT (vme)do { if (!(vme)) { do { do { if (0) printf ("Assertion failed: " "vme"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 1258, GF_LOG_ERROR, "Assertion failed: " "vme" ); } while (0); } } while (0); | |||||
1259 | ||||||
1260 | if (strcmp (vme->option, "!xtime") != 0) | |||||
1261 | return 0; | |||||
1262 | ||||||
1263 | ret = gf_string2boolean (vme->value, &bool); | |||||
1264 | if (ret || bool) | |||||
1265 | goto out; | |||||
1266 | ||||||
1267 | ret = glusterd_volinfo_get_boolean (volinfo, VKEY_MARKER_XTIME"geo-replication"".indexing"); | |||||
1268 | if (ret < 0) { | |||||
1269 | gf_log ("", GF_LOG_WARNING, "failed to get the marker status")do { do { if (0) printf ("failed to get the marker status"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 1269 , GF_LOG_WARNING, "failed to get the marker status"); } while (0); | |||||
1270 | ret = -1; | |||||
1271 | goto out; | |||||
1272 | } | |||||
1273 | ||||||
1274 | if (ret) { | |||||
1275 | bool = _gf_false; | |||||
1276 | ret = glusterd_check_gsync_running (volinfo, &bool); | |||||
1277 | ||||||
1278 | if (bool) { | |||||
1279 | gf_log ("", GF_LOG_WARNING, GEOREP" sessions active"do { do { if (0) printf ("geo-replication"" sessions active" "for the volume %s, cannot disable marker " ,volinfo->volname); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 1281, GF_LOG_WARNING, "geo-replication"" sessions active" "for the volume %s, cannot disable marker " ,volinfo->volname ); } while (0) | |||||
1280 | "for the volume %s, cannot disable marker "do { do { if (0) printf ("geo-replication"" sessions active" "for the volume %s, cannot disable marker " ,volinfo->volname); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 1281, GF_LOG_WARNING, "geo-replication"" sessions active" "for the volume %s, cannot disable marker " ,volinfo->volname ); } while (0) | |||||
1281 | ,volinfo->volname)do { do { if (0) printf ("geo-replication"" sessions active" "for the volume %s, cannot disable marker " ,volinfo->volname); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 1281, GF_LOG_WARNING, "geo-replication"" sessions active" "for the volume %s, cannot disable marker " ,volinfo->volname ); } while (0); | |||||
1282 | set_graph_errstr (graph, | |||||
1283 | VKEY_MARKER_XTIME"geo-replication"".indexing"" cannot be disabled " | |||||
1284 | "while "GEOREP"geo-replication"" sessions exist"); | |||||
1285 | ret = -1; | |||||
1286 | goto out; | |||||
1287 | } | |||||
1288 | ||||||
1289 | if (ret) { | |||||
1290 | gf_log ("", GF_LOG_WARNING, "Unable to get the status"do { do { if (0) printf ("Unable to get the status" " of active gsync session" ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 1291, GF_LOG_WARNING, "Unable to get the status" " of active gsync session" ); } while (0) | |||||
1291 | " of active gsync session")do { do { if (0) printf ("Unable to get the status" " of active gsync session" ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 1291, GF_LOG_WARNING, "Unable to get the status" " of active gsync session" ); } while (0); | |||||
1292 | goto out; | |||||
1293 | } | |||||
1294 | } | |||||
1295 | ||||||
1296 | ret = 0; | |||||
1297 | out: | |||||
1298 | gf_log ("", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 1298, GF_LOG_DEBUG, "Returning %d" , ret); } while (0); | |||||
1299 | return ret; | |||||
1300 | ||||||
1301 | } | |||||
1302 | ||||||
1303 | static int | |||||
1304 | sys_loglevel_option_handler (volgen_graph_t *graph, | |||||
1305 | struct volopt_map_entry *vme, | |||||
1306 | void *param) | |||||
1307 | { | |||||
1308 | char *role = NULL((void*)0); | |||||
1309 | struct volopt_map_entry vme2 = {0,}; | |||||
1310 | ||||||
1311 | role = (char *) param; | |||||
1312 | ||||||
1313 | if (strcmp (vme->option, "!sys-log-level") != 0 || | |||||
1314 | !strstr (vme->key, role)) | |||||
1315 | return 0; | |||||
1316 | ||||||
1317 | memcpy (&vme2, vme, sizeof (vme2)); | |||||
1318 | vme2.option = "sys-log-level"; | |||||
1319 | ||||||
1320 | return basic_option_handler (graph, &vme2, NULL((void*)0)); | |||||
1321 | } | |||||
1322 | ||||||
1323 | static int | |||||
1324 | volgen_graph_set_xl_options (volgen_graph_t *graph, dict_t *dict) | |||||
1325 | { | |||||
1326 | int32_t ret = -1; | |||||
1327 | char *xlator = NULL((void*)0); | |||||
1328 | char xlator_match[1024] = {0,}; /* for posix* -> *posix* */ | |||||
1329 | char *loglevel = NULL((void*)0); | |||||
1330 | xlator_t *trav = NULL((void*)0); | |||||
1331 | ||||||
1332 | ret = dict_get_str (dict, "xlator", &xlator); | |||||
1333 | if (ret) | |||||
1334 | goto out; | |||||
1335 | ||||||
1336 | ret = dict_get_str (dict, "loglevel", &loglevel); | |||||
1337 | if (ret) | |||||
1338 | goto out; | |||||
1339 | ||||||
1340 | snprintf (xlator_match, 1024, "*%s", xlator); | |||||
1341 | ||||||
1342 | for (trav = first_of (graph); trav; trav = trav->next) { | |||||
1343 | if (fnmatch(xlator_match, trav->type, FNM_NOESCAPE(1 << 1)) == 0) { | |||||
1344 | gf_log ("glusterd", GF_LOG_DEBUG, "Setting log level for xlator: %s",do { do { if (0) printf ("Setting log level for xlator: %s", trav ->type); } while (0); _gf_log ("glusterd", "glusterd-volgen.c" , __FUNCTION__, 1345, GF_LOG_DEBUG, "Setting log level for xlator: %s" , trav->type); } while (0) | |||||
1345 | trav->type)do { do { if (0) printf ("Setting log level for xlator: %s", trav ->type); } while (0); _gf_log ("glusterd", "glusterd-volgen.c" , __FUNCTION__, 1345, GF_LOG_DEBUG, "Setting log level for xlator: %s" , trav->type); } while (0); | |||||
1346 | ret = xlator_set_option (trav, "log-level", loglevel); | |||||
1347 | if (ret) | |||||
1348 | break; | |||||
1349 | } | |||||
1350 | } | |||||
1351 | ||||||
1352 | out: | |||||
1353 | return ret; | |||||
1354 | } | |||||
1355 | ||||||
1356 | static int | |||||
1357 | server_spec_option_handler (volgen_graph_t *graph, | |||||
1358 | struct volopt_map_entry *vme, void *param) | |||||
1359 | { | |||||
1360 | int ret = 0; | |||||
1361 | glusterd_volinfo_t *volinfo = NULL((void*)0); | |||||
1362 | ||||||
1363 | volinfo = param; | |||||
1364 | ||||||
1365 | ret = server_auth_option_handler (graph, vme, NULL((void*)0)); | |||||
1366 | if (!ret) | |||||
1367 | ret = server_check_marker_off (graph, vme, volinfo); | |||||
1368 | ||||||
1369 | if (!ret) | |||||
1370 | ret = loglevel_option_handler (graph, vme, "brick"); | |||||
1371 | ||||||
1372 | if (!ret) | |||||
1373 | ret = sys_loglevel_option_handler (graph, vme, "brick"); | |||||
1374 | ||||||
1375 | return ret; | |||||
1376 | } | |||||
1377 | ||||||
1378 | static int | |||||
1379 | server_spec_extended_option_handler (volgen_graph_t *graph, | |||||
1380 | struct volopt_map_entry *vme, void *param) | |||||
1381 | { | |||||
1382 | int ret = 0; | |||||
1383 | dict_t *dict = NULL((void*)0); | |||||
1384 | ||||||
1385 | GF_ASSERT (param)do { if (!(param)) { do { do { if (0) printf ("Assertion failed: " "param"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 1385, GF_LOG_ERROR, "Assertion failed: " "param" ); } while (0); } } while (0); | |||||
1386 | dict = (dict_t *)param; | |||||
1387 | ||||||
1388 | ret = server_auth_option_handler (graph, vme, NULL((void*)0)); | |||||
1389 | if (!ret) | |||||
1390 | ret = volgen_graph_set_xl_options (graph, dict); | |||||
1391 | ||||||
1392 | return ret; | |||||
1393 | } | |||||
1394 | ||||||
1395 | static void get_vol_tstamp_file (char *filename, glusterd_volinfo_t *volinfo); | |||||
1396 | ||||||
1397 | static int | |||||
1398 | server_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, | |||||
1399 | dict_t *set_dict, void *param) | |||||
1400 | { | |||||
1401 | char *volname = NULL((void*)0); | |||||
1402 | char *path = NULL((void*)0); | |||||
1403 | int pump = 0; | |||||
1404 | xlator_t *xl = NULL((void*)0); | |||||
1405 | xlator_t *txl = NULL((void*)0); | |||||
1406 | xlator_t *rbxl = NULL((void*)0); | |||||
1407 | char transt[16] = {0,}; | |||||
1408 | char *ptranst = NULL((void*)0); | |||||
1409 | char volume_id[64] = {0,}; | |||||
1410 | char tstamp_file[PATH_MAX4096] = {0,}; | |||||
1411 | int ret = 0; | |||||
1412 | char *xlator = NULL((void*)0); | |||||
1413 | char *loglevel = NULL((void*)0); | |||||
1414 | char *username = NULL((void*)0); | |||||
1415 | char *password = NULL((void*)0); | |||||
1416 | char index_basepath[PATH_MAX4096] = {0}; | |||||
1417 | char key[1024] = {0}; | |||||
1418 | char *vgname = NULL((void*)0); | |||||
1419 | char *vg = NULL((void*)0); | |||||
1420 | glusterd_brickinfo_t *brickinfo = NULL((void*)0); | |||||
1421 | ||||||
1422 | brickinfo = param; | |||||
1423 | path = brickinfo->path; | |||||
1424 | volname = volinfo->volname; | |||||
1425 | get_vol_transport_type (volinfo, transt); | |||||
1426 | ||||||
1427 | ret = dict_get_str (set_dict, "xlator", &xlator); | |||||
1428 | ||||||
1429 | /* got a cli log level request */ | |||||
1430 | if (!ret) { | |||||
1431 | ret = dict_get_str (set_dict, "loglevel", &loglevel); | |||||
1432 | if (ret) { | |||||
1433 | gf_log ("glusterd", GF_LOG_ERROR, "could not get both"do { do { if (0) printf ("could not get both" " translator name and loglevel for log level request" ); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1434, GF_LOG_ERROR, "could not get both" " translator name and loglevel for log level request" ); } while (0) | |||||
1434 | " translator name and loglevel for log level request")do { do { if (0) printf ("could not get both" " translator name and loglevel for log level request" ); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1434, GF_LOG_ERROR, "could not get both" " translator name and loglevel for log level request" ); } while (0); | |||||
1435 | goto out; | |||||
1436 | } | |||||
1437 | } | |||||
1438 | ||||||
1439 | if (volinfo->backend == GD_VOL_BK_BD) { | |||||
1440 | xl = volgen_graph_add (graph, "storage/bd_map", volname); | |||||
1441 | if (!xl) | |||||
1442 | return -1; | |||||
1443 | ||||||
1444 | ret = xlator_set_option (xl, "device", "vg"); | |||||
1445 | if (ret) | |||||
1446 | return -1; | |||||
1447 | ||||||
1448 | vg = gf_strdup (path); | |||||
1449 | vgname = strrchr (vg, '/'); | |||||
1450 | if (strchr(vg, '/') != vgname) { | |||||
1451 | gf_log ("glusterd", GF_LOG_ERROR,do { do { if (0) printf ("invalid vg specified %s", path); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__, 1452, GF_LOG_ERROR, "invalid vg specified %s", path); } while (0) | |||||
1452 | "invalid vg specified %s", path)do { do { if (0) printf ("invalid vg specified %s", path); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__, 1452, GF_LOG_ERROR, "invalid vg specified %s", path); } while (0); | |||||
1453 | GF_FREE (vg)__gf_free (vg); | |||||
1454 | goto out; | |||||
1455 | } | |||||
1456 | vgname++; | |||||
1457 | ret = xlator_set_option (xl, "export", vgname); | |||||
1458 | GF_FREE (vg)__gf_free (vg); | |||||
1459 | if (ret) | |||||
1460 | return -1; | |||||
1461 | } else { | |||||
1462 | xl = volgen_graph_add (graph, "storage/posix", volname); | |||||
1463 | if (!xl) | |||||
1464 | return -1; | |||||
1465 | ||||||
1466 | ret = xlator_set_option (xl, "directory", path); | |||||
1467 | if (ret) | |||||
1468 | return -1; | |||||
1469 | ||||||
1470 | ret = xlator_set_option (xl, "volume-id", | |||||
1471 | uuid_utoa (volinfo->volume_id)); | |||||
1472 | if (ret) | |||||
1473 | return -1; | |||||
1474 | ||||||
1475 | ret = check_and_add_debug_xl (graph, set_dict, volname, | |||||
1476 | "posix"); | |||||
1477 | if (ret) | |||||
1478 | return -1; | |||||
1479 | } | |||||
1480 | xl = volgen_graph_add (graph, "features/access-control", volname); | |||||
1481 | if (!xl) | |||||
1482 | return -1; | |||||
1483 | ||||||
1484 | ret = check_and_add_debug_xl (graph, set_dict, volname, "acl"); | |||||
1485 | if (ret) | |||||
1486 | return -1; | |||||
1487 | ||||||
1488 | xl = volgen_graph_add (graph, "features/locks", volname); | |||||
1489 | if (!xl) | |||||
1490 | return -1; | |||||
1491 | ||||||
1492 | ret = check_and_add_debug_xl (graph, set_dict, volname, "locks"); | |||||
1493 | if (ret) | |||||
1494 | return -1; | |||||
1495 | ||||||
1496 | xl = volgen_graph_add (graph, "performance/io-threads", volname); | |||||
1497 | if (!xl) | |||||
1498 | return -1; | |||||
1499 | ||||||
1500 | ret = check_and_add_debug_xl (graph, set_dict, volname, "io-threads"); | |||||
1501 | if (ret) | |||||
1502 | return -1; | |||||
1503 | ||||||
1504 | ret = dict_get_int32 (volinfo->dict, "enable-pump", &pump); | |||||
1505 | if (ret == -ENOENT2) | |||||
1506 | ret = pump = 0; | |||||
1507 | if (ret) | |||||
1508 | return -1; | |||||
1509 | ||||||
1510 | username = glusterd_auth_get_username (volinfo); | |||||
1511 | password = glusterd_auth_get_password (volinfo); | |||||
1512 | ||||||
1513 | if (pump) { | |||||
1514 | txl = first_of (graph); | |||||
1515 | ||||||
1516 | rbxl = volgen_graph_add_nolink (graph, "protocol/client", | |||||
1517 | "%s-replace-brick", volname); | |||||
1518 | if (!rbxl) | |||||
1519 | return -1; | |||||
1520 | ||||||
1521 | ptranst = glusterd_get_trans_type_rb (volinfo->transport_type); | |||||
1522 | if (NULL((void*)0) == ptranst) | |||||
1523 | return -1; | |||||
1524 | ||||||
1525 | if (username) { | |||||
1526 | ret = xlator_set_option (rbxl, "username", username); | |||||
1527 | if (ret) | |||||
1528 | return -1; | |||||
1529 | } | |||||
1530 | ||||||
1531 | if (password) { | |||||
1532 | ret = xlator_set_option (rbxl, "password", password); | |||||
1533 | if (ret) | |||||
1534 | return -1; | |||||
1535 | } | |||||
1536 | ||||||
1537 | ret = xlator_set_option (rbxl, "transport-type", ptranst); | |||||
1538 | GF_FREE (ptranst)__gf_free (ptranst); | |||||
1539 | if (ret) | |||||
1540 | return -1; | |||||
1541 | ||||||
1542 | xl = volgen_graph_add_nolink (graph, "cluster/pump", "%s-pump", | |||||
1543 | volname); | |||||
1544 | if (!xl) | |||||
1545 | return -1; | |||||
1546 | ret = volgen_xlator_link (xl, txl); | |||||
1547 | if (ret) | |||||
1548 | return -1; | |||||
1549 | ret = volgen_xlator_link (xl, rbxl); | |||||
1550 | if (ret) | |||||
1551 | return -1; | |||||
1552 | } | |||||
1553 | ||||||
1554 | xl = volgen_graph_add (graph, "features/index", volname); | |||||
1555 | if (!xl) | |||||
1556 | return -1; | |||||
1557 | ||||||
1558 | snprintf (index_basepath, sizeof (index_basepath), "%s/%s", | |||||
1559 | path, ".glusterfs/indices"); | |||||
1560 | ret = xlator_set_option (xl, "index-base", index_basepath); | |||||
1561 | if (ret) | |||||
1562 | return -1; | |||||
1563 | ||||||
1564 | ret = check_and_add_debug_xl (graph, set_dict, volname, | |||||
1565 | "index"); | |||||
1566 | if (ret) | |||||
1567 | return -1; | |||||
1568 | ||||||
1569 | xl = volgen_graph_add (graph, "features/marker", volname); | |||||
1570 | if (!xl) | |||||
1571 | return -1; | |||||
1572 | ||||||
1573 | uuid_unparse (volinfo->volume_id, volume_id); | |||||
1574 | ret = xlator_set_option (xl, "volume-uuid", volume_id); | |||||
1575 | if (ret) | |||||
1576 | return -1; | |||||
1577 | get_vol_tstamp_file (tstamp_file, volinfo); | |||||
1578 | ret = xlator_set_option (xl, "timestamp-file", tstamp_file); | |||||
1579 | if (ret) | |||||
1580 | return -1; | |||||
1581 | ||||||
1582 | ret = check_and_add_debug_xl (graph, set_dict, volname, "marker"); | |||||
1583 | if (ret) | |||||
1584 | return -1; | |||||
1585 | ||||||
1586 | if (dict_get_str_boolean (set_dict, "features.read-only", 0) && | |||||
1587 | dict_get_str_boolean (set_dict, "features.worm",0)) { | |||||
1588 | gf_log (THIS->name, GF_LOG_ERROR,do { do { if (0) printf ("read-only and worm cannot be set together" ); } while (0); _gf_log ((*__glusterfs_this_location())->name , "glusterd-volgen.c", __FUNCTION__, 1589, GF_LOG_ERROR, "read-only and worm cannot be set together" ); } while (0) | |||||
1589 | "read-only and worm cannot be set together")do { do { if (0) printf ("read-only and worm cannot be set together" ); } while (0); _gf_log ((*__glusterfs_this_location())->name , "glusterd-volgen.c", __FUNCTION__, 1589, GF_LOG_ERROR, "read-only and worm cannot be set together" ); } while (0); | |||||
1590 | ret = -1; | |||||
1591 | goto out; | |||||
1592 | } | |||||
1593 | ||||||
1594 | /* Check for read-only volume option, and add it to the graph */ | |||||
1595 | if (dict_get_str_boolean (set_dict, "features.read-only", 0)) { | |||||
1596 | xl = volgen_graph_add (graph, "features/read-only", volname); | |||||
1597 | if (!xl) { | |||||
1598 | ret = -1; | |||||
1599 | goto out; | |||||
1600 | } | |||||
1601 | } | |||||
1602 | ||||||
1603 | /* Check for worm volume option, and add it to the graph */ | |||||
1604 | if (dict_get_str_boolean (set_dict, "features.worm", 0)) { | |||||
1605 | xl = volgen_graph_add (graph, "features/worm", volname); | |||||
1606 | if (!xl) { | |||||
1607 | ret = -1; | |||||
1608 | goto out; | |||||
1609 | } | |||||
1610 | } | |||||
1611 | ||||||
1612 | xl = volgen_graph_add_as (graph, "debug/io-stats", path); | |||||
1613 | if (!xl) | |||||
1614 | return -1; | |||||
1615 | ||||||
1616 | xl = volgen_graph_add (graph, "protocol/server", volname); | |||||
1617 | if (!xl) | |||||
1618 | return -1; | |||||
1619 | ret = xlator_set_option (xl, "transport-type", transt); | |||||
1620 | if (ret) | |||||
1621 | return -1; | |||||
1622 | ||||||
1623 | /*In the case of running multiple glusterds on a single machine, | |||||
1624 | * we should ensure that bricks don't listen on all IPs on that | |||||
1625 | * machine and break the IP based separation being brought about.*/ | |||||
1626 | if (dict_get (THIS(*__glusterfs_this_location())->options, "transport.socket.bind-address")) { | |||||
1627 | ret = xlator_set_option (xl, "transport.socket.bind-address", | |||||
1628 | brickinfo->hostname); | |||||
1629 | if (ret) | |||||
1630 | return -1; | |||||
1631 | } | |||||
1632 | ||||||
1633 | if (username) { | |||||
1634 | memset (key, 0, sizeof (key)); | |||||
1635 | snprintf (key, sizeof (key), "auth.login.%s.allow", path); | |||||
1636 | ||||||
1637 | ret = xlator_set_option (xl, key, username); | |||||
1638 | if (ret) | |||||
1639 | return -1; | |||||
1640 | } | |||||
1641 | ||||||
1642 | if (password) { | |||||
1643 | memset (key, 0, sizeof (key)); | |||||
1644 | snprintf (key, sizeof (key), "auth.login.%s.password", | |||||
1645 | username); | |||||
1646 | ||||||
1647 | ret = xlator_set_option (xl, key, password); | |||||
1648 | if (ret) | |||||
1649 | return -1; | |||||
1650 | } | |||||
1651 | ||||||
1652 | ret = volgen_graph_set_options_generic (graph, set_dict, | |||||
1653 | (xlator && loglevel) ? (void *)set_dict : volinfo, | |||||
1654 | (xlator && loglevel) ? &server_spec_extended_option_handler : | |||||
1655 | &server_spec_option_handler); | |||||
1656 | ||||||
1657 | out: | |||||
1658 | return ret; | |||||
1659 | } | |||||
1660 | ||||||
1661 | ||||||
1662 | /* builds a graph for server role , with option overrides in mod_dict */ | |||||
1663 | static int | |||||
1664 | build_server_graph (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, | |||||
1665 | dict_t *mod_dict, glusterd_brickinfo_t *brickinfo) | |||||
1666 | { | |||||
1667 | return build_graph_generic (graph, volinfo, mod_dict, brickinfo, | |||||
1668 | &server_graph_builder); | |||||
1669 | } | |||||
1670 | ||||||
1671 | static int | |||||
1672 | perfxl_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme, | |||||
1673 | void *param) | |||||
1674 | { | |||||
1675 | char *volname = NULL((void*)0); | |||||
1676 | gf_boolean_t enabled = _gf_false; | |||||
1677 | ||||||
1678 | volname = param; | |||||
1679 | ||||||
1680 | if (strcmp (vme->option, "!perf") != 0) | |||||
1681 | return 0; | |||||
1682 | ||||||
1683 | if (gf_string2boolean (vme->value, &enabled) == -1) | |||||
1684 | return -1; | |||||
1685 | if (!enabled) | |||||
1686 | return 0; | |||||
1687 | ||||||
1688 | if (volgen_graph_add (graph, vme->voltype, volname)) | |||||
1689 | return 0; | |||||
1690 | else | |||||
1691 | return -1; | |||||
1692 | } | |||||
1693 | ||||||
1694 | static int | |||||
1695 | nfsperfxl_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme, | |||||
1696 | void *param) | |||||
1697 | { | |||||
1698 | char *volname = NULL((void*)0); | |||||
1699 | gf_boolean_t enabled = _gf_false; | |||||
1700 | ||||||
1701 | volname = param; | |||||
1702 | ||||||
1703 | if (strcmp (vme->option, "!nfsperf") != 0) | |||||
1704 | return 0; | |||||
1705 | ||||||
1706 | if (gf_string2boolean (vme->value, &enabled) == -1) | |||||
1707 | return -1; | |||||
1708 | if (!enabled) | |||||
1709 | return 0; | |||||
1710 | ||||||
1711 | if (volgen_graph_add (graph, vme->voltype, volname)) | |||||
1712 | return 0; | |||||
1713 | else | |||||
1714 | return -1; | |||||
1715 | } | |||||
1716 | ||||||
1717 | #if (HAVE_LIB_XML1) | |||||
1718 | static int | |||||
1719 | end_sethelp_xml_doc (xmlTextWriterPtr writer) | |||||
1720 | { | |||||
1721 | int ret = -1; | |||||
1722 | ||||||
1723 | ret = xmlTextWriterEndElement(writer); | |||||
1724 | if (ret < 0) { | |||||
1725 | gf_log ("glusterd", GF_LOG_ERROR, "Could not end an "do { do { if (0) printf ("Could not end an " "xmlElemetnt"); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1726, GF_LOG_ERROR, "Could not end an " "xmlElemetnt"); } while (0) | |||||
1726 | "xmlElemetnt")do { do { if (0) printf ("Could not end an " "xmlElemetnt"); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1726, GF_LOG_ERROR, "Could not end an " "xmlElemetnt"); } while (0); | |||||
1727 | ret = -1; | |||||
1728 | goto out; | |||||
1729 | } | |||||
1730 | ret = xmlTextWriterEndDocument (writer); | |||||
1731 | if (ret < 0) { | |||||
1732 | gf_log ("glusterd", GF_LOG_ERROR, "Could not end an "do { do { if (0) printf ("Could not end an " "xmlDocument"); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1733, GF_LOG_ERROR, "Could not end an " "xmlDocument"); } while (0) | |||||
1733 | "xmlDocument")do { do { if (0) printf ("Could not end an " "xmlDocument"); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1733, GF_LOG_ERROR, "Could not end an " "xmlDocument"); } while (0); | |||||
1734 | ret = -1; | |||||
1735 | goto out; | |||||
1736 | } | |||||
1737 | ret = 0; | |||||
1738 | out: | |||||
1739 | gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__, 1739, GF_LOG_DEBUG , "Returning %d", ret); } while (0); | |||||
1740 | return ret; | |||||
1741 | ||||||
1742 | } | |||||
1743 | ||||||
1744 | static int | |||||
1745 | init_sethelp_xml_doc (xmlTextWriterPtr *writer, xmlBufferPtr *buf) | |||||
1746 | { | |||||
1747 | int ret; | |||||
1748 | ||||||
1749 | *buf = xmlBufferCreateSize (8192); | |||||
1750 | if (buf == NULL((void*)0)) { | |||||
1751 | gf_log ("glusterd", GF_LOG_ERROR, "Error creating the xml "do { do { if (0) printf ("Error creating the xml " "buffer"); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1752, GF_LOG_ERROR, "Error creating the xml " "buffer"); } while (0) | |||||
1752 | "buffer")do { do { if (0) printf ("Error creating the xml " "buffer"); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1752, GF_LOG_ERROR, "Error creating the xml " "buffer"); } while (0); | |||||
1753 | ret = -1; | |||||
1754 | goto out; | |||||
1755 | } | |||||
1756 | ||||||
1757 | xmlBufferSetAllocationScheme (*buf,XML_BUFFER_ALLOC_DOUBLEIT); | |||||
1758 | ||||||
1759 | *writer = xmlNewTextWriterMemory(*buf, 0); | |||||
1760 | if (writer == NULL((void*)0)) { | |||||
1761 | gf_log ("glusterd", GF_LOG_ERROR, " Error creating the xml "do { do { if (0) printf (" Error creating the xml " "writer") ; } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1762, GF_LOG_ERROR, " Error creating the xml " "writer"); } while (0) | |||||
1762 | "writer")do { do { if (0) printf (" Error creating the xml " "writer") ; } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1762, GF_LOG_ERROR, " Error creating the xml " "writer"); } while (0); | |||||
1763 | ret = -1; | |||||
1764 | goto out; | |||||
1765 | } | |||||
1766 | ||||||
1767 | ret = xmlTextWriterStartDocument(*writer, "1.0", "UTF-8", "yes"); | |||||
1768 | if (ret < 0) { | |||||
1769 | gf_log ("glusterd", GF_LOG_ERROR, "Error While starting the "do { do { if (0) printf ("Error While starting the " "xmlDoc" ); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1770, GF_LOG_ERROR, "Error While starting the " "xmlDoc"); } while (0) | |||||
1770 | "xmlDoc")do { do { if (0) printf ("Error While starting the " "xmlDoc" ); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1770, GF_LOG_ERROR, "Error While starting the " "xmlDoc"); } while (0); | |||||
1771 | goto out; | |||||
1772 | } | |||||
1773 | ||||||
1774 | ret = xmlTextWriterStartElement(*writer, (xmlChar *)"options"); | |||||
1775 | if (ret < 0) { | |||||
1776 | gf_log ("glusterd", GF_LOG_ERROR, "Could not create an "do { do { if (0) printf ("Could not create an " "xmlElemetnt" ); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1777, GF_LOG_ERROR, "Could not create an " "xmlElemetnt"); } while (0) | |||||
1777 | "xmlElemetnt")do { do { if (0) printf ("Could not create an " "xmlElemetnt" ); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1777, GF_LOG_ERROR, "Could not create an " "xmlElemetnt"); } while (0); | |||||
1778 | ret = -1; | |||||
1779 | goto out; | |||||
1780 | } | |||||
1781 | ||||||
1782 | ||||||
1783 | ret = 0; | |||||
1784 | ||||||
1785 | out: | |||||
1786 | gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__, 1786, GF_LOG_DEBUG , "Returning %d", ret); } while (0); | |||||
1787 | return ret; | |||||
1788 | ||||||
1789 | } | |||||
1790 | ||||||
1791 | static int | |||||
1792 | xml_add_volset_element (xmlTextWriterPtr writer, const char *name, | |||||
1793 | const char *def_val, const char *dscrpt) | |||||
1794 | { | |||||
1795 | ||||||
1796 | int ret = -1; | |||||
1797 | ||||||
1798 | GF_ASSERT (name)do { if (!(name)) { do { do { if (0) printf ("Assertion failed: " "name"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 1798, GF_LOG_ERROR, "Assertion failed: " "name" ); } while (0); } } while (0); | |||||
1799 | ||||||
1800 | ret = xmlTextWriterStartElement(writer, (xmlChar *) "option"); | |||||
1801 | if (ret < 0) { | |||||
1802 | gf_log ("glusterd", GF_LOG_ERROR, "Could not create an "do { do { if (0) printf ("Could not create an " "xmlElemetnt" ); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1803, GF_LOG_ERROR, "Could not create an " "xmlElemetnt"); } while (0) | |||||
1803 | "xmlElemetnt")do { do { if (0) printf ("Could not create an " "xmlElemetnt" ); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1803, GF_LOG_ERROR, "Could not create an " "xmlElemetnt"); } while (0); | |||||
1804 | ret = -1; | |||||
1805 | goto out; | |||||
1806 | } | |||||
1807 | ||||||
1808 | ret = xmlTextWriterWriteFormatElement(writer, (xmlChar*)"defaultValue", | |||||
1809 | "%s", def_val); | |||||
1810 | if (ret < 0) { | |||||
1811 | gf_log ("glusterd", GF_LOG_ERROR, "Could not create an "do { do { if (0) printf ("Could not create an " "xmlElemetnt" ); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1812, GF_LOG_ERROR, "Could not create an " "xmlElemetnt"); } while (0) | |||||
1812 | "xmlElemetnt")do { do { if (0) printf ("Could not create an " "xmlElemetnt" ); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1812, GF_LOG_ERROR, "Could not create an " "xmlElemetnt"); } while (0); | |||||
1813 | ret = -1; | |||||
1814 | goto out; | |||||
1815 | } | |||||
1816 | ||||||
1817 | ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *)"description", | |||||
1818 | "%s", dscrpt ); | |||||
1819 | if (ret < 0) { | |||||
1820 | gf_log ("glusterd", GF_LOG_ERROR, "Could not create an "do { do { if (0) printf ("Could not create an " "xmlElemetnt" ); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1821, GF_LOG_ERROR, "Could not create an " "xmlElemetnt"); } while (0) | |||||
1821 | "xmlElemetnt")do { do { if (0) printf ("Could not create an " "xmlElemetnt" ); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1821, GF_LOG_ERROR, "Could not create an " "xmlElemetnt"); } while (0); | |||||
1822 | ret = -1; | |||||
1823 | goto out; | |||||
1824 | } | |||||
1825 | ||||||
1826 | ret = xmlTextWriterWriteFormatElement(writer, (xmlChar *) "name", "%s", | |||||
1827 | name); | |||||
1828 | if (ret < 0) { | |||||
1829 | gf_log ("glusterd", GF_LOG_ERROR, "Could not create an "do { do { if (0) printf ("Could not create an " "xmlElemetnt" ); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1830, GF_LOG_ERROR, "Could not create an " "xmlElemetnt"); } while (0) | |||||
1830 | "xmlElemetnt")do { do { if (0) printf ("Could not create an " "xmlElemetnt" ); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1830, GF_LOG_ERROR, "Could not create an " "xmlElemetnt"); } while (0); | |||||
1831 | ret = -1; | |||||
1832 | goto out; | |||||
1833 | } | |||||
1834 | ||||||
1835 | ret = xmlTextWriterEndElement(writer); | |||||
1836 | if (ret < 0) { | |||||
1837 | gf_log ("glusterd", GF_LOG_ERROR, "Could not end an "do { do { if (0) printf ("Could not end an " "xmlElemetnt"); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1838, GF_LOG_ERROR, "Could not end an " "xmlElemetnt"); } while (0) | |||||
1838 | "xmlElemetnt")do { do { if (0) printf ("Could not end an " "xmlElemetnt"); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__ , 1838, GF_LOG_ERROR, "Could not end an " "xmlElemetnt"); } while (0); | |||||
1839 | ret = -1; | |||||
1840 | goto out; | |||||
1841 | } | |||||
1842 | ||||||
1843 | ret = 0; | |||||
1844 | out: | |||||
1845 | gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__, 1845, GF_LOG_DEBUG , "Returning %d", ret); } while (0); | |||||
1846 | return ret; | |||||
1847 | ||||||
1848 | } | |||||
1849 | ||||||
1850 | #endif | |||||
1851 | ||||||
1852 | static int | |||||
1853 | get_key_from_volopt ( struct volopt_map_entry *vme, char **key) | |||||
1854 | { | |||||
1855 | int ret = 0; | |||||
1856 | ||||||
1857 | GF_ASSERT (vme)do { if (!(vme)) { do { do { if (0) printf ("Assertion failed: " "vme"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 1857, GF_LOG_ERROR, "Assertion failed: " "vme" ); } while (0); } } while (0); | |||||
1858 | GF_ASSERT (key)do { if (!(key)) { do { do { if (0) printf ("Assertion failed: " "key"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 1858, GF_LOG_ERROR, "Assertion failed: " "key" ); } while (0); } } while (0); | |||||
1859 | ||||||
1860 | ||||||
1861 | if (!strcmp (vme->key, AUTH_ALLOW_MAP_KEY"auth.allow")) | |||||
1862 | *key = gf_strdup (AUTH_ALLOW_OPT_KEY"auth.addr.*.allow"); | |||||
1863 | else if (!strcmp (vme->key, AUTH_REJECT_MAP_KEY"auth.reject")) | |||||
1864 | *key = gf_strdup (AUTH_REJECT_OPT_KEY"auth.addr.*.reject"); | |||||
1865 | else if (!strcmp (vme->key, NFS_DISABLE_MAP_KEY"nfs.disable")) | |||||
1866 | *key = gf_strdup (NFS_DISABLE_OPT_KEY"nfs.*.disable"); | |||||
1867 | else { | |||||
1868 | if (vme->option) { | |||||
1869 | if (vme->option[0] == '!') { | |||||
1870 | *key = vme->option + 1; | |||||
1871 | if (!*key[0]) | |||||
1872 | ret = -1; | |||||
1873 | } else { | |||||
1874 | *key = vme->option; | |||||
1875 | } | |||||
1876 | } else { | |||||
1877 | *key = strchr (vme->key, '.'); | |||||
1878 | if (*key) { | |||||
1879 | (*key) ++; | |||||
1880 | if (!*key[0]) | |||||
1881 | ret = -1; | |||||
1882 | } else { | |||||
1883 | ret = -1; | |||||
1884 | } | |||||
1885 | } | |||||
1886 | } | |||||
1887 | if (ret) | |||||
1888 | gf_log ("glusterd", GF_LOG_ERROR, "Wrong entry found in "do { do { if (0) printf ("Wrong entry found in " "glusterd_volopt_map entry %s" , vme->key); } while (0); _gf_log ("glusterd", "glusterd-volgen.c" , __FUNCTION__, 1889, GF_LOG_ERROR, "Wrong entry found in " "glusterd_volopt_map entry %s" , vme->key); } while (0) | |||||
1889 | "glusterd_volopt_map entry %s", vme->key)do { do { if (0) printf ("Wrong entry found in " "glusterd_volopt_map entry %s" , vme->key); } while (0); _gf_log ("glusterd", "glusterd-volgen.c" , __FUNCTION__, 1889, GF_LOG_ERROR, "Wrong entry found in " "glusterd_volopt_map entry %s" , vme->key); } while (0); | |||||
1890 | else | |||||
1891 | gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__, 1891, GF_LOG_DEBUG , "Returning %d", ret); } while (0); | |||||
1892 | ||||||
1893 | return ret; | |||||
1894 | } | |||||
1895 | ||||||
1896 | int | |||||
1897 | glusterd_get_volopt_content (dict_t * ctx, gf_boolean_t xml_out) | |||||
1898 | { | |||||
1899 | ||||||
1900 | char *xlator_type = NULL((void*)0); | |||||
1901 | void *dl_handle = NULL((void*)0); | |||||
1902 | volume_opt_list_t vol_opt_handle = {{0},}; | |||||
1903 | char *key = NULL((void*)0); | |||||
1904 | struct volopt_map_entry *vme = NULL((void*)0); | |||||
1905 | int ret = -1; | |||||
1906 | char *def_val = NULL((void*)0); | |||||
1907 | char *descr = NULL((void*)0); | |||||
1908 | char output_string[25600] = {0, }; | |||||
1909 | char *output = NULL((void*)0); | |||||
1910 | char tmp_str[2048] = {0, }; | |||||
1911 | #if (HAVE_LIB_XML1) | |||||
1912 | xmlTextWriterPtr writer = NULL((void*)0); | |||||
1913 | xmlBufferPtr buf = NULL((void*)0); | |||||
1914 | ||||||
1915 | if (xml_out) { | |||||
1916 | ret = init_sethelp_xml_doc (&writer, &buf); | |||||
1917 | if (ret) /*logging done in init_xml_lib*/ | |||||
1918 | goto out; | |||||
1919 | } | |||||
1920 | #endif | |||||
1921 | ||||||
1922 | INIT_LIST_HEAD (&vol_opt_handle.list)do { (&vol_opt_handle.list)->next = (&vol_opt_handle .list)->prev = &vol_opt_handle.list; } while (0); | |||||
1923 | ||||||
1924 | for (vme = &glusterd_volopt_map[0]; vme->key; vme++) { | |||||
1925 | ||||||
1926 | if ( ( vme->type == NO_DOC) || (vme->type == GLOBAL_NO_DOC) ) | |||||
1927 | continue; | |||||
1928 | ||||||
1929 | if (get_key_from_volopt (vme, &key)) | |||||
1930 | goto out; /*Some error while getin key*/ | |||||
1931 | ||||||
1932 | if (vme->description) { | |||||
1933 | descr = vme->description; | |||||
1934 | def_val = vme->value; | |||||
1935 | } else { | |||||
1936 | if (!xlator_type || strcmp (vme->voltype, xlator_type)){ | |||||
1937 | ret = xlator_volopt_dynload (vme->voltype, | |||||
1938 | &dl_handle, | |||||
1939 | &vol_opt_handle); | |||||
1940 | if (ret) { | |||||
1941 | dl_handle = NULL((void*)0); | |||||
1942 | continue; | |||||
1943 | } | |||||
1944 | } | |||||
1945 | ret = xlator_option_info_list (&vol_opt_handle, key, | |||||
1946 | &def_val, &descr); | |||||
1947 | if (ret) /*Swallow Error i.e if option not found*/ | |||||
1948 | continue; | |||||
1949 | } | |||||
1950 | ||||||
1951 | if (xml_out) { | |||||
1952 | #if (HAVE_LIB_XML1) | |||||
1953 | if (xml_add_volset_element (writer,vme->key, | |||||
1954 | def_val, descr)) | |||||
1955 | goto out; | |||||
1956 | #else | |||||
1957 | gf_log ("glusterd", GF_LOG_ERROR, "Libxml not present")do { do { if (0) printf ("Libxml not present"); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__, 1957, GF_LOG_ERROR , "Libxml not present"); } while (0); | |||||
1958 | #endif | |||||
1959 | } else { | |||||
1960 | snprintf (tmp_str, sizeof (tmp_str), "Option: %s\nDefault " | |||||
1961 | "Value: %s\nDescription: %s\n\n", | |||||
1962 | vme->key, def_val, descr); | |||||
1963 | strcat (output_string, tmp_str); | |||||
1964 | } | |||||
1965 | ||||||
1966 | if (!strcmp (key, AUTH_ALLOW_OPT_KEY"auth.addr.*.allow") || | |||||
1967 | !strcmp (key, AUTH_REJECT_OPT_KEY"auth.addr.*.reject") || | |||||
1968 | !strcmp (key, NFS_DISABLE_OPT_KEY"nfs.*.disable")) | |||||
1969 | GF_FREE (key)__gf_free (key); | |||||
1970 | } | |||||
1971 | ||||||
1972 | #if (HAVE_LIB_XML1) | |||||
1973 | if ((xml_out) && | |||||
1974 | (ret = end_sethelp_xml_doc (writer))) | |||||
1975 | goto out; | |||||
1976 | #else | |||||
1977 | if (xml_out) | |||||
1978 | gf_log ("glusterd", GF_LOG_ERROR, "Libxml not present")do { do { if (0) printf ("Libxml not present"); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__, 1978, GF_LOG_ERROR , "Libxml not present"); } while (0); | |||||
1979 | #endif | |||||
1980 | ||||||
1981 | if (!xml_out) | |||||
1982 | output = gf_strdup (output_string); | |||||
1983 | else | |||||
1984 | #if (HAVE_LIB_XML1) | |||||
1985 | output = gf_strdup ((char *)buf->content); | |||||
1986 | #else | |||||
1987 | gf_log ("glusterd", GF_LOG_ERROR, "Libxml not present")do { do { if (0) printf ("Libxml not present"); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__, 1987, GF_LOG_ERROR , "Libxml not present"); } while (0); | |||||
1988 | #endif | |||||
1989 | ||||||
1990 | if (NULL((void*)0) == output) { | |||||
1991 | ret = -1; | |||||
1992 | goto out; | |||||
1993 | } | |||||
1994 | ||||||
1995 | ret = dict_set_dynstr (ctx, "help-str", output); | |||||
1996 | out: | |||||
1997 | gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__, 1997, GF_LOG_DEBUG , "Returning %d", ret); } while (0); | |||||
1998 | return ret; | |||||
1999 | ||||||
2000 | } | |||||
2001 | ||||||
2002 | static int | |||||
2003 | volgen_graph_build_clients (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, | |||||
2004 | dict_t *set_dict, void *param) | |||||
2005 | { | |||||
2006 | int i = 0; | |||||
2007 | int ret = -1; | |||||
2008 | uint32_t client_type = GF_CLIENT_OTHER; | |||||
2009 | char transt[16] = {0,}; | |||||
2010 | char *volname = NULL((void*)0); | |||||
2011 | char *str = NULL((void*)0); | |||||
2012 | glusterd_brickinfo_t *brick = NULL((void*)0); | |||||
2013 | xlator_t *xl = NULL((void*)0); | |||||
2014 | char *ssl_str = NULL((void*)0); | |||||
2015 | gf_boolean_t ssl_bool; | |||||
2016 | ||||||
2017 | volname = volinfo->volname; | |||||
2018 | ||||||
2019 | if (volinfo->brick_count == 0) { | |||||
2020 | gf_log ("", GF_LOG_ERROR,do { do { if (0) printf ("volume inconsistency: brick count is 0" ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 2021, GF_LOG_ERROR, "volume inconsistency: brick count is 0" ); } while (0) | |||||
2021 | "volume inconsistency: brick count is 0")do { do { if (0) printf ("volume inconsistency: brick count is 0" ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 2021, GF_LOG_ERROR, "volume inconsistency: brick count is 0" ); } while (0); | |||||
2022 | goto out; | |||||
2023 | } | |||||
2024 | ||||||
2025 | if ((volinfo->dist_leaf_count < volinfo->brick_count) && | |||||
2026 | ((volinfo->brick_count % volinfo->dist_leaf_count) != 0)) { | |||||
2027 | gf_log ("", GF_LOG_ERROR,do { do { if (0) printf ("volume inconsistency: " "total number of bricks (%d) is not divisible with " "number of bricks per cluster (%d) in a multi-cluster " "setup" , volinfo->brick_count, volinfo->dist_leaf_count); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 2032, GF_LOG_ERROR , "volume inconsistency: " "total number of bricks (%d) is not divisible with " "number of bricks per cluster (%d) in a multi-cluster " "setup" , volinfo->brick_count, volinfo->dist_leaf_count); } while (0) | |||||
2028 | "volume inconsistency: "do { do { if (0) printf ("volume inconsistency: " "total number of bricks (%d) is not divisible with " "number of bricks per cluster (%d) in a multi-cluster " "setup" , volinfo->brick_count, volinfo->dist_leaf_count); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 2032, GF_LOG_ERROR , "volume inconsistency: " "total number of bricks (%d) is not divisible with " "number of bricks per cluster (%d) in a multi-cluster " "setup" , volinfo->brick_count, volinfo->dist_leaf_count); } while (0) | |||||
2029 | "total number of bricks (%d) is not divisible with "do { do { if (0) printf ("volume inconsistency: " "total number of bricks (%d) is not divisible with " "number of bricks per cluster (%d) in a multi-cluster " "setup" , volinfo->brick_count, volinfo->dist_leaf_count); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 2032, GF_LOG_ERROR , "volume inconsistency: " "total number of bricks (%d) is not divisible with " "number of bricks per cluster (%d) in a multi-cluster " "setup" , volinfo->brick_count, volinfo->dist_leaf_count); } while (0) | |||||
2030 | "number of bricks per cluster (%d) in a multi-cluster "do { do { if (0) printf ("volume inconsistency: " "total number of bricks (%d) is not divisible with " "number of bricks per cluster (%d) in a multi-cluster " "setup" , volinfo->brick_count, volinfo->dist_leaf_count); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 2032, GF_LOG_ERROR , "volume inconsistency: " "total number of bricks (%d) is not divisible with " "number of bricks per cluster (%d) in a multi-cluster " "setup" , volinfo->brick_count, volinfo->dist_leaf_count); } while (0) | |||||
2031 | "setup",do { do { if (0) printf ("volume inconsistency: " "total number of bricks (%d) is not divisible with " "number of bricks per cluster (%d) in a multi-cluster " "setup" , volinfo->brick_count, volinfo->dist_leaf_count); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 2032, GF_LOG_ERROR , "volume inconsistency: " "total number of bricks (%d) is not divisible with " "number of bricks per cluster (%d) in a multi-cluster " "setup" , volinfo->brick_count, volinfo->dist_leaf_count); } while (0) | |||||
2032 | volinfo->brick_count, volinfo->dist_leaf_count)do { do { if (0) printf ("volume inconsistency: " "total number of bricks (%d) is not divisible with " "number of bricks per cluster (%d) in a multi-cluster " "setup" , volinfo->brick_count, volinfo->dist_leaf_count); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 2032, GF_LOG_ERROR , "volume inconsistency: " "total number of bricks (%d) is not divisible with " "number of bricks per cluster (%d) in a multi-cluster " "setup" , volinfo->brick_count, volinfo->dist_leaf_count); } while (0); | |||||
2033 | goto out; | |||||
2034 | } | |||||
2035 | ||||||
2036 | get_transport_type (volinfo, set_dict, transt, _gf_false); | |||||
2037 | ||||||
2038 | if (!strcmp (transt, "tcp,rdma")) | |||||
2039 | strcpy (transt, "tcp"); | |||||
2040 | ||||||
2041 | i = 0; | |||||
2042 | ret = -1; | |||||
2043 | list_for_each_entry (brick, &volinfo->bricks, brick_list)for (brick = ((typeof(*brick) *)((char *)((&volinfo->bricks )->next)-(unsigned long)(&((typeof(*brick) *)0)->brick_list ))); &brick->brick_list != (&volinfo->bricks); brick = ((typeof(*brick) *)((char *)(brick->brick_list.next)-(unsigned long)(&((typeof(*brick) *)0)->brick_list)))) { | |||||
2044 | ret = -1; | |||||
2045 | xl = volgen_graph_add_nolink (graph, "protocol/client", | |||||
2046 | "%s-client-%d", volname, i); | |||||
2047 | if (!xl) | |||||
2048 | goto out; | |||||
2049 | ret = xlator_set_option (xl, "remote-host", brick->hostname); | |||||
2050 | if (ret) | |||||
2051 | goto out; | |||||
2052 | ret = xlator_set_option (xl, "remote-subvolume", brick->path); | |||||
2053 | if (ret) | |||||
2054 | goto out; | |||||
2055 | ret = xlator_set_option (xl, "transport-type", transt); | |||||
2056 | if (ret) | |||||
2057 | goto out; | |||||
2058 | ||||||
2059 | ret = dict_get_uint32 (set_dict, "trusted-client", | |||||
2060 | &client_type); | |||||
2061 | ||||||
2062 | if (!ret && client_type == GF_CLIENT_TRUSTED) { | |||||
2063 | str = NULL((void*)0); | |||||
2064 | str = glusterd_auth_get_username (volinfo); | |||||
2065 | if (str) { | |||||
2066 | ret = xlator_set_option (xl, "username", | |||||
2067 | str); | |||||
2068 | if (ret) | |||||
2069 | goto out; | |||||
2070 | } | |||||
2071 | ||||||
2072 | str = glusterd_auth_get_password (volinfo); | |||||
2073 | if (str) { | |||||
2074 | ret = xlator_set_option (xl, "password", | |||||
2075 | str); | |||||
2076 | if (ret) | |||||
2077 | goto out; | |||||
2078 | } | |||||
2079 | } | |||||
2080 | ||||||
2081 | if (dict_get_str(set_dict,"client.ssl",&ssl_str) == 0) { | |||||
2082 | if (gf_string2boolean(ssl_str,&ssl_bool) == 0) { | |||||
2083 | if (ssl_bool) { | |||||
2084 | ret = xlator_set_option(xl, | |||||
2085 | "transport.socket.ssl-enabled", | |||||
2086 | "true"); | |||||
2087 | if (ret) { | |||||
2088 | goto out; | |||||
2089 | } | |||||
2090 | } | |||||
2091 | } | |||||
2092 | } | |||||
2093 | ||||||
2094 | i++; | |||||
2095 | } | |||||
2096 | ||||||
2097 | if (i != volinfo->brick_count) { | |||||
2098 | gf_log ("", GF_LOG_ERROR,do { do { if (0) printf ("volume inconsistency: actual number of bricks (%d) " "differs from brick count (%d)", i, volinfo->brick_count) ; } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 2101, GF_LOG_ERROR, "volume inconsistency: actual number of bricks (%d) " "differs from brick count (%d)", i, volinfo->brick_count) ; } while (0) | |||||
2099 | "volume inconsistency: actual number of bricks (%d) "do { do { if (0) printf ("volume inconsistency: actual number of bricks (%d) " "differs from brick count (%d)", i, volinfo->brick_count) ; } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 2101, GF_LOG_ERROR, "volume inconsistency: actual number of bricks (%d) " "differs from brick count (%d)", i, volinfo->brick_count) ; } while (0) | |||||
2100 | "differs from brick count (%d)", i,do { do { if (0) printf ("volume inconsistency: actual number of bricks (%d) " "differs from brick count (%d)", i, volinfo->brick_count) ; } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 2101, GF_LOG_ERROR, "volume inconsistency: actual number of bricks (%d) " "differs from brick count (%d)", i, volinfo->brick_count) ; } while (0) | |||||
2101 | volinfo->brick_count)do { do { if (0) printf ("volume inconsistency: actual number of bricks (%d) " "differs from brick count (%d)", i, volinfo->brick_count) ; } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 2101, GF_LOG_ERROR, "volume inconsistency: actual number of bricks (%d) " "differs from brick count (%d)", i, volinfo->brick_count) ; } while (0); | |||||
2102 | ||||||
2103 | ret = -1; | |||||
2104 | goto out; | |||||
2105 | } | |||||
2106 | ret = 0; | |||||
2107 | out: | |||||
2108 | return ret; | |||||
2109 | } | |||||
2110 | ||||||
2111 | static int | |||||
2112 | volgen_graph_build_clusters (volgen_graph_t *graph, | |||||
2113 | glusterd_volinfo_t *volinfo, char *xl_type, | |||||
2114 | char *xl_namefmt, size_t child_count, | |||||
2115 | size_t sub_count) | |||||
2116 | { | |||||
2117 | int i = 0; | |||||
2118 | int j = 0; | |||||
2119 | xlator_t *txl = NULL((void*)0); | |||||
2120 | xlator_t *xl = NULL((void*)0); | |||||
2121 | xlator_t *trav = NULL((void*)0); | |||||
2122 | char *volname = NULL((void*)0); | |||||
2123 | int ret = -1; | |||||
2124 | ||||||
2125 | if (child_count == 0) | |||||
2126 | goto out; | |||||
2127 | volname = volinfo->volname; | |||||
2128 | txl = first_of (graph); | |||||
2129 | for (trav = txl; --child_count; trav = trav->next); | |||||
2130 | for (;; trav = trav->prev) { | |||||
2131 | if ((i % sub_count) == 0) { | |||||
2132 | xl = volgen_graph_add_nolink (graph, xl_type, | |||||
2133 | xl_namefmt, volname, j); | |||||
2134 | if (!xl) { | |||||
2135 | ret = -1; | |||||
2136 | goto out; | |||||
2137 | } | |||||
2138 | j++; | |||||
2139 | } | |||||
2140 | ||||||
2141 | ret = volgen_xlator_link (xl, trav); | |||||
2142 | if (ret) | |||||
2143 | goto out; | |||||
2144 | ||||||
2145 | if (trav == txl) | |||||
2146 | break; | |||||
2147 | ||||||
2148 | i++; | |||||
2149 | } | |||||
2150 | ||||||
2151 | ret = j; | |||||
2152 | out: | |||||
2153 | return ret; | |||||
2154 | } | |||||
2155 | ||||||
2156 | gf_boolean_t | |||||
2157 | _xl_is_client_decommissioned (xlator_t *xl, glusterd_volinfo_t *volinfo) | |||||
2158 | { | |||||
2159 | int ret = 0; | |||||
2160 | gf_boolean_t decommissioned = _gf_false; | |||||
2161 | char *hostname = NULL((void*)0); | |||||
2162 | char *path = NULL((void*)0); | |||||
2163 | ||||||
2164 | GF_ASSERT (!strcmp (xl->type, "protocol/client"))do { if (!(!strcmp (xl->type, "protocol/client"))) { do { do { if (0) printf ("Assertion failed: " "!strcmp (xl->type, \"protocol/client\")" ); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c", __FUNCTION__ , 2164, GF_LOG_ERROR, "Assertion failed: " "!strcmp (xl->type, \"protocol/client\")" ); } while (0); } } while (0); | |||||
2165 | ret = xlator_get_option (xl, "remote-host", &hostname); | |||||
2166 | if (ret) { | |||||
2167 | GF_ASSERT (0)do { if (!(0)) { do { do { if (0) printf ("Assertion failed: " "0"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 2167, GF_LOG_ERROR, "Assertion failed: " "0") ; } while (0); } } while (0); | |||||
2168 | gf_log ("glusterd", GF_LOG_ERROR, "Failed to get remote-host "do { do { if (0) printf ("Failed to get remote-host " "from client %s" , xl->name); } while (0); _gf_log ("glusterd", "glusterd-volgen.c" , __FUNCTION__, 2169, GF_LOG_ERROR, "Failed to get remote-host " "from client %s", xl->name); } while (0) | |||||
2169 | "from client %s", xl->name)do { do { if (0) printf ("Failed to get remote-host " "from client %s" , xl->name); } while (0); _gf_log ("glusterd", "glusterd-volgen.c" , __FUNCTION__, 2169, GF_LOG_ERROR, "Failed to get remote-host " "from client %s", xl->name); } while (0); | |||||
2170 | goto out; | |||||
2171 | } | |||||
2172 | ret = xlator_get_option (xl, "remote-subvolume", &path); | |||||
2173 | if (ret) { | |||||
2174 | GF_ASSERT (0)do { if (!(0)) { do { do { if (0) printf ("Assertion failed: " "0"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 2174, GF_LOG_ERROR, "Assertion failed: " "0") ; } while (0); } } while (0); | |||||
2175 | gf_log ("glusterd", GF_LOG_ERROR, "Failed to get remote-host "do { do { if (0) printf ("Failed to get remote-host " "from client %s" , xl->name); } while (0); _gf_log ("glusterd", "glusterd-volgen.c" , __FUNCTION__, 2176, GF_LOG_ERROR, "Failed to get remote-host " "from client %s", xl->name); } while (0) | |||||
2176 | "from client %s", xl->name)do { do { if (0) printf ("Failed to get remote-host " "from client %s" , xl->name); } while (0); _gf_log ("glusterd", "glusterd-volgen.c" , __FUNCTION__, 2176, GF_LOG_ERROR, "Failed to get remote-host " "from client %s", xl->name); } while (0); | |||||
2177 | goto out; | |||||
2178 | } | |||||
2179 | ||||||
2180 | decommissioned = glusterd_is_brick_decommissioned (volinfo, hostname, | |||||
2181 | path); | |||||
2182 | out: | |||||
2183 | return decommissioned; | |||||
2184 | } | |||||
2185 | ||||||
2186 | gf_boolean_t | |||||
2187 | _xl_has_decommissioned_clients (xlator_t *xl, glusterd_volinfo_t *volinfo) | |||||
2188 | { | |||||
2189 | xlator_list_t *xl_child = NULL((void*)0); | |||||
2190 | gf_boolean_t decommissioned = _gf_false; | |||||
2191 | xlator_t *cxl = NULL((void*)0); | |||||
2192 | ||||||
2193 | if (!xl) | |||||
2194 | goto out; | |||||
2195 | ||||||
2196 | if (!strcmp (xl->type, "protocol/client")) { | |||||
2197 | decommissioned = _xl_is_client_decommissioned (xl, volinfo); | |||||
2198 | goto out; | |||||
2199 | } | |||||
2200 | ||||||
2201 | xl_child = xl->children; | |||||
2202 | while (xl_child) { | |||||
2203 | cxl = xl_child->xlator; | |||||
2204 | /* this can go into 2 depths if the volume type | |||||
2205 | is stripe-replicate */ | |||||
2206 | decommissioned = _xl_has_decommissioned_clients (cxl, volinfo); | |||||
2207 | if (decommissioned) | |||||
2208 | break; | |||||
2209 | ||||||
2210 | xl_child = xl_child->next; | |||||
2211 | } | |||||
2212 | out: | |||||
2213 | return decommissioned; | |||||
2214 | } | |||||
2215 | ||||||
2216 | static int | |||||
2217 | _graph_get_decommissioned_children (xlator_t *dht, glusterd_volinfo_t *volinfo, | |||||
2218 | char **children) | |||||
2219 | { | |||||
2220 | int ret = -1; | |||||
2221 | xlator_list_t *xl_child = NULL((void*)0); | |||||
2222 | xlator_t *cxl = NULL((void*)0); | |||||
2223 | gf_boolean_t comma = _gf_false; | |||||
2224 | ||||||
2225 | *children = NULL((void*)0); | |||||
2226 | xl_child = dht->children; | |||||
2227 | while (xl_child) { | |||||
2228 | cxl = xl_child->xlator; | |||||
2229 | if (_xl_has_decommissioned_clients (cxl, volinfo)) { | |||||
2230 | if (!*children) { | |||||
2231 | *children = GF_CALLOC (16 * GF_UNIT_KB, 1,__gf_calloc (16 * 1024ULL, 1, gf_common_mt_char) | |||||
2232 | gf_common_mt_char)__gf_calloc (16 * 1024ULL, 1, gf_common_mt_char); | |||||
2233 | if (!*children) | |||||
2234 | goto out; | |||||
2235 | } | |||||
2236 | ||||||
2237 | if (comma) | |||||
2238 | strcat (*children, ","); | |||||
2239 | strcat (*children, cxl->name); | |||||
2240 | comma = _gf_true; | |||||
2241 | } | |||||
2242 | ||||||
2243 | xl_child = xl_child->next; | |||||
2244 | } | |||||
2245 | ret = 0; | |||||
2246 | out: | |||||
2247 | return ret; | |||||
2248 | } | |||||
2249 | ||||||
2250 | static int | |||||
2251 | volgen_graph_build_dht_cluster (volgen_graph_t *graph, | |||||
2252 | glusterd_volinfo_t *volinfo, size_t child_count) | |||||
2253 | { | |||||
2254 | int32_t clusters = 0; | |||||
2255 | int ret = -1; | |||||
2256 | char *decommissioned_children = NULL((void*)0); | |||||
2257 | xlator_t *dht = NULL((void*)0); | |||||
2258 | char *optstr = NULL((void*)0); | |||||
2259 | gf_boolean_t use_nufa = _gf_false; | |||||
2260 | ||||||
2261 | if (dict_get_str(volinfo->dict,"cluster.nufa",&optstr) == 0) { | |||||
2262 | /* Keep static analyzers quiet by "using" the value. */ | |||||
2263 | ret = gf_string2boolean(optstr,&use_nufa); | |||||
2264 | } | |||||
2265 | ||||||
2266 | clusters = volgen_graph_build_clusters (graph, volinfo, | |||||
2267 | use_nufa | |||||
2268 | ? "cluster/nufa" | |||||
2269 | : "cluster/distribute", | |||||
2270 | "%s-dht", | |||||
2271 | child_count, child_count); | |||||
2272 | if (clusters < 0) | |||||
2273 | goto out; | |||||
2274 | dht = first_of (graph); | |||||
2275 | ret = _graph_get_decommissioned_children (dht, volinfo, | |||||
2276 | &decommissioned_children); | |||||
2277 | if (ret) | |||||
2278 | goto out; | |||||
2279 | if (decommissioned_children) { | |||||
2280 | ret = xlator_set_option (dht, "decommissioned-bricks", | |||||
2281 | decommissioned_children); | |||||
2282 | if (ret) | |||||
2283 | goto out; | |||||
2284 | } | |||||
2285 | ret = 0; | |||||
2286 | out: | |||||
2287 | GF_FREE (decommissioned_children)__gf_free (decommissioned_children); | |||||
2288 | return ret; | |||||
2289 | } | |||||
2290 | ||||||
2291 | static int | |||||
2292 | volume_volgen_graph_build_clusters (volgen_graph_t *graph, | |||||
2293 | glusterd_volinfo_t *volinfo) | |||||
2294 | { | |||||
2295 | char *replicate_args[] = {"cluster/replicate", | |||||
2296 | "%s-replicate-%d"}; | |||||
2297 | char *stripe_args[] = {"cluster/stripe", | |||||
2298 | "%s-stripe-%d"}; | |||||
2299 | int rclusters = 0; | |||||
2300 | int clusters = 0; | |||||
2301 | int dist_count = 0; | |||||
2302 | int ret = -1; | |||||
2303 | ||||||
2304 | if (!volinfo->dist_leaf_count) | |||||
2305 | goto out; | |||||
2306 | ||||||
2307 | if (volinfo->dist_leaf_count == 1) | |||||
2308 | goto build_distribute; | |||||
2309 | ||||||
2310 | /* All other cases, it will have one or the other cluster type */ | |||||
2311 | switch (volinfo->type) { | |||||
2312 | case GF_CLUSTER_TYPE_REPLICATE: | |||||
2313 | clusters = volgen_graph_build_clusters (graph, volinfo, | |||||
2314 | replicate_args[0], | |||||
2315 | replicate_args[1], | |||||
2316 | volinfo->brick_count, | |||||
2317 | volinfo->replica_count); | |||||
2318 | if (clusters < 0) | |||||
2319 | goto out; | |||||
2320 | break; | |||||
2321 | case GF_CLUSTER_TYPE_STRIPE: | |||||
2322 | clusters = volgen_graph_build_clusters (graph, volinfo, | |||||
2323 | stripe_args[0], | |||||
2324 | stripe_args[1], | |||||
2325 | volinfo->brick_count, | |||||
2326 | volinfo->stripe_count); | |||||
2327 | if (clusters < 0) | |||||
2328 | goto out; | |||||
2329 | break; | |||||
2330 | case GF_CLUSTER_TYPE_STRIPE_REPLICATE: | |||||
2331 | /* Replicate after the clients, then stripe */ | |||||
2332 | if (volinfo->replica_count == 0) | |||||
2333 | goto out; | |||||
2334 | clusters = volgen_graph_build_clusters (graph, volinfo, | |||||
2335 | replicate_args[0], | |||||
2336 | replicate_args[1], | |||||
2337 | volinfo->brick_count, | |||||
2338 | volinfo->replica_count); | |||||
2339 | if (clusters < 0) | |||||
2340 | goto out; | |||||
2341 | ||||||
2342 | rclusters = volinfo->brick_count / volinfo->replica_count; | |||||
2343 | GF_ASSERT (rclusters == clusters)do { if (!(rclusters == clusters)) { do { do { if (0) printf ( "Assertion failed: " "rclusters == clusters"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c", __FUNCTION__, 2343, GF_LOG_ERROR, "Assertion failed: " "rclusters == clusters"); } while (0); } } while (0); | |||||
2344 | clusters = volgen_graph_build_clusters (graph, volinfo, | |||||
2345 | stripe_args[0], | |||||
2346 | stripe_args[1], | |||||
2347 | rclusters, | |||||
2348 | volinfo->stripe_count); | |||||
2349 | if (clusters < 0) | |||||
2350 | goto out; | |||||
2351 | break; | |||||
2352 | default: | |||||
2353 | gf_log ("", GF_LOG_ERROR, "volume inconsistency: "do { do { if (0) printf ("volume inconsistency: " "unrecognized clustering type" ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 2354, GF_LOG_ERROR, "volume inconsistency: " "unrecognized clustering type" ); } while (0) | |||||
2354 | "unrecognized clustering type")do { do { if (0) printf ("volume inconsistency: " "unrecognized clustering type" ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 2354, GF_LOG_ERROR, "volume inconsistency: " "unrecognized clustering type" ); } while (0); | |||||
2355 | goto out; | |||||
2356 | } | |||||
2357 | ||||||
2358 | build_distribute: | |||||
2359 | dist_count = volinfo->brick_count / volinfo->dist_leaf_count; | |||||
2360 | if (!dist_count) { | |||||
2361 | ret = -1; | |||||
2362 | goto out; | |||||
2363 | } | |||||
2364 | ||||||
2365 | ret = volgen_graph_build_dht_cluster (graph, volinfo, | |||||
2366 | dist_count); | |||||
2367 | if (ret) | |||||
2368 | goto out; | |||||
2369 | ||||||
2370 | ret = 0; | |||||
2371 | out: | |||||
2372 | return ret; | |||||
2373 | } | |||||
2374 | ||||||
2375 | static int | |||||
2376 | client_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, | |||||
2377 | dict_t *set_dict, void *param) | |||||
2378 | { | |||||
2379 | int ret = 0; | |||||
2380 | xlator_t *xl = NULL((void*)0); | |||||
2381 | char *volname = NULL((void*)0); | |||||
2382 | data_t *tmp_data = NULL((void*)0); | |||||
2383 | ||||||
2384 | volname = volinfo->volname; | |||||
2385 | ret = volgen_graph_build_clients (graph, volinfo, set_dict, param); | |||||
2386 | if (ret) | |||||
2387 | goto out; | |||||
2388 | ||||||
2389 | ret = volume_volgen_graph_build_clusters (graph, volinfo); | |||||
2390 | if (ret) | |||||
2391 | goto out; | |||||
2392 | ||||||
2393 | ret = glusterd_volinfo_get_boolean (volinfo, VKEY_FEATURES_QUOTA"features.quota"); | |||||
2394 | if (ret == -1) | |||||
2395 | goto out; | |||||
2396 | if (ret) { | |||||
2397 | xl = volgen_graph_add (graph, "features/quota", volname); | |||||
2398 | ||||||
2399 | if (!xl) { | |||||
2400 | ret = -1; | |||||
2401 | goto out; | |||||
2402 | } | |||||
2403 | } | |||||
2404 | ||||||
2405 | /* Logic to make sure NFS doesn't have performance translators by | |||||
2406 | default for a volume */ | |||||
2407 | tmp_data = dict_get (set_dict, "nfs-volume-file"); | |||||
2408 | if (!tmp_data) | |||||
2409 | ret = volgen_graph_set_options_generic (graph, set_dict, volname, | |||||
2410 | &perfxl_option_handler); | |||||
2411 | else | |||||
2412 | ret = volgen_graph_set_options_generic (graph, set_dict, volname, | |||||
2413 | &nfsperfxl_option_handler); | |||||
2414 | ||||||
2415 | if (ret) | |||||
2416 | goto out; | |||||
2417 | ||||||
2418 | /* add debug translators depending on the options */ | |||||
2419 | ret = check_and_add_debug_xl (graph, set_dict, volname, | |||||
2420 | "client"); | |||||
2421 | if (ret) | |||||
2422 | return -1; | |||||
2423 | ||||||
2424 | ret = -1; | |||||
2425 | xl = volgen_graph_add_as (graph, "debug/io-stats", volname); | |||||
2426 | if (!xl) | |||||
2427 | goto out; | |||||
2428 | ||||||
2429 | ret = volgen_graph_set_options_generic (graph, set_dict, "client", | |||||
2430 | &loglevel_option_handler); | |||||
2431 | ||||||
2432 | if (ret) | |||||
2433 | gf_log (THIS->name, GF_LOG_WARNING, "changing client log level"do { do { if (0) printf ("changing client log level" " failed" ); } while (0); _gf_log ((*__glusterfs_this_location())->name , "glusterd-volgen.c", __FUNCTION__, 2434, GF_LOG_WARNING, "changing client log level" " failed"); } while (0) | |||||
2434 | " failed")do { do { if (0) printf ("changing client log level" " failed" ); } while (0); _gf_log ((*__glusterfs_this_location())->name , "glusterd-volgen.c", __FUNCTION__, 2434, GF_LOG_WARNING, "changing client log level" " failed"); } while (0); | |||||
2435 | ||||||
2436 | ret = volgen_graph_set_options_generic (graph, set_dict, "client", | |||||
2437 | &sys_loglevel_option_handler); | |||||
2438 | if (ret) | |||||
2439 | gf_log (THIS->name, GF_LOG_WARNING, "changing client syslog "do { do { if (0) printf ("changing client syslog " "level failed" ); } while (0); _gf_log ((*__glusterfs_this_location())->name , "glusterd-volgen.c", __FUNCTION__, 2440, GF_LOG_WARNING, "changing client syslog " "level failed"); } while (0) | |||||
2440 | "level failed")do { do { if (0) printf ("changing client syslog " "level failed" ); } while (0); _gf_log ((*__glusterfs_this_location())->name , "glusterd-volgen.c", __FUNCTION__, 2440, GF_LOG_WARNING, "changing client syslog " "level failed"); } while (0); | |||||
2441 | out: | |||||
2442 | return ret; | |||||
2443 | } | |||||
2444 | ||||||
2445 | ||||||
2446 | /* builds a graph for client role , with option overrides in mod_dict */ | |||||
2447 | static int | |||||
2448 | build_client_graph (volgen_graph_t *graph, glusterd_volinfo_t *volinfo, | |||||
2449 | dict_t *mod_dict) | |||||
2450 | { | |||||
2451 | return build_graph_generic (graph, volinfo, mod_dict, NULL((void*)0), | |||||
2452 | &client_graph_builder); | |||||
2453 | } | |||||
2454 | ||||||
2455 | char *gd_shd_options[] = { | |||||
2456 | "!self-heal-daemon", | |||||
2457 | "!heal-timeout", | |||||
2458 | NULL((void*)0) | |||||
2459 | }; | |||||
2460 | ||||||
2461 | char* | |||||
2462 | gd_get_matching_option (char **options, char *option) | |||||
2463 | { | |||||
2464 | while (*options && strcmp (*options, option)) | |||||
2465 | options++; | |||||
2466 | return *options; | |||||
2467 | } | |||||
2468 | ||||||
2469 | static int | |||||
2470 | shd_option_handler (volgen_graph_t *graph, struct volopt_map_entry *vme, | |||||
2471 | void *param) | |||||
2472 | { | |||||
2473 | int ret = 0; | |||||
2474 | struct volopt_map_entry new_vme = {0}; | |||||
2475 | char *shd_option = NULL((void*)0); | |||||
2476 | ||||||
2477 | shd_option = gd_get_matching_option (gd_shd_options, vme->option); | |||||
2478 | if ((vme->option[0] == '!') && !shd_option) | |||||
2479 | goto out; | |||||
2480 | new_vme = *vme; | |||||
2481 | if (shd_option) { | |||||
2482 | new_vme.option = shd_option + 1;//option with out '!' | |||||
2483 | } | |||||
2484 | ||||||
2485 | ret = no_filter_option_handler (graph, &new_vme, param); | |||||
2486 | out: | |||||
2487 | return ret; | |||||
2488 | } | |||||
2489 | ||||||
2490 | static int | |||||
2491 | nfs_option_handler (volgen_graph_t *graph, | |||||
2492 | struct volopt_map_entry *vme, void *param) | |||||
2493 | { | |||||
2494 | xlator_t *xl = NULL((void*)0); | |||||
2495 | char *aa = NULL((void*)0); | |||||
2496 | int ret = 0; | |||||
2497 | glusterd_volinfo_t *volinfo = NULL((void*)0); | |||||
2498 | ||||||
2499 | volinfo = param; | |||||
2500 | ||||||
2501 | xl = first_of (graph); | |||||
2502 | ||||||
2503 | /* if (vme->type == GLOBAL_DOC || vme->type == GLOBAL_NO_DOC) { | |||||
2504 | ||||||
2505 | ret = xlator_set_option (xl, vme->key, vme->value); | |||||
2506 | }*/ | |||||
2507 | if (!volinfo || (volinfo->volname[0] == '\0')) | |||||
2508 | return 0; | |||||
2509 | ||||||
2510 | if (! strcmp (vme->option, "!rpc-auth.addr.*.allow")) { | |||||
2511 | ret = gf_asprintf (&aa, "rpc-auth.addr.%s.allow", | |||||
2512 | volinfo->volname); | |||||
2513 | ||||||
2514 | if (ret != -1) { | |||||
2515 | ret = xlator_set_option (xl, aa, vme->value); | |||||
2516 | GF_FREE (aa)__gf_free (aa); | |||||
2517 | } | |||||
2518 | ||||||
2519 | if (ret) | |||||
2520 | return -1; | |||||
2521 | } | |||||
2522 | ||||||
2523 | if (! strcmp (vme->option, "!rpc-auth.addr.*.reject")) { | |||||
2524 | ret = gf_asprintf (&aa, "rpc-auth.addr.%s.reject", | |||||
2525 | volinfo->volname); | |||||
2526 | ||||||
2527 | if (ret != -1) { | |||||
2528 | ret = xlator_set_option (xl, aa, vme->value); | |||||
2529 | GF_FREE (aa)__gf_free (aa); | |||||
2530 | } | |||||
2531 | ||||||
2532 | if (ret) | |||||
2533 | return -1; | |||||
2534 | } | |||||
2535 | ||||||
2536 | if (! strcmp (vme->option, "!rpc-auth.auth-unix.*")) { | |||||
2537 | ret = gf_asprintf (&aa, "rpc-auth.auth-unix.%s", | |||||
2538 | volinfo->volname); | |||||
2539 | ||||||
2540 | if (ret != -1) { | |||||
2541 | ret = xlator_set_option (xl, aa, vme->value); | |||||
2542 | GF_FREE (aa)__gf_free (aa); | |||||
2543 | } | |||||
2544 | ||||||
2545 | if (ret) | |||||
2546 | return -1; | |||||
2547 | } | |||||
2548 | if (! strcmp (vme->option, "!rpc-auth.auth-null.*")) { | |||||
2549 | ret = gf_asprintf (&aa, "rpc-auth.auth-null.%s", | |||||
2550 | volinfo->volname); | |||||
2551 | ||||||
2552 | if (ret != -1) { | |||||
2553 | ret = xlator_set_option (xl, aa, vme->value); | |||||
2554 | GF_FREE (aa)__gf_free (aa); | |||||
2555 | } | |||||
2556 | ||||||
2557 | if (ret) | |||||
2558 | return -1; | |||||
2559 | } | |||||
2560 | ||||||
2561 | if (! strcmp (vme->option, "!nfs3.*.trusted-sync")) { | |||||
2562 | ret = gf_asprintf (&aa, "nfs3.%s.trusted-sync", | |||||
2563 | volinfo->volname); | |||||
2564 | ||||||
2565 | if (ret != -1) { | |||||
2566 | ret = xlator_set_option (xl, aa, vme->value); | |||||
2567 | GF_FREE (aa)__gf_free (aa); | |||||
2568 | } | |||||
2569 | ||||||
2570 | if (ret) | |||||
2571 | return -1; | |||||
2572 | } | |||||
2573 | ||||||
2574 | if (! strcmp (vme->option, "!nfs3.*.trusted-write")) { | |||||
2575 | ret = gf_asprintf (&aa, "nfs3.%s.trusted-write", | |||||
2576 | volinfo->volname); | |||||
2577 | ||||||
2578 | if (ret != -1) { | |||||
2579 | ret = xlator_set_option (xl, aa, vme->value); | |||||
2580 | GF_FREE (aa)__gf_free (aa); | |||||
2581 | } | |||||
2582 | ||||||
2583 | if (ret) | |||||
2584 | return -1; | |||||
2585 | } | |||||
2586 | ||||||
2587 | if (! strcmp (vme->option, "!nfs3.*.volume-access")) { | |||||
2588 | ret = gf_asprintf (&aa, "nfs3.%s.volume-access", | |||||
2589 | volinfo->volname); | |||||
2590 | ||||||
2591 | if (ret != -1) { | |||||
2592 | ret = xlator_set_option (xl, aa, vme->value); | |||||
2593 | GF_FREE (aa)__gf_free (aa); | |||||
2594 | } | |||||
2595 | ||||||
2596 | if (ret) | |||||
2597 | return -1; | |||||
2598 | } | |||||
2599 | ||||||
2600 | if (! strcmp (vme->option, "!nfs3.*.export-dir")) { | |||||
2601 | ret = gf_asprintf (&aa, "nfs3.%s.export-dir", | |||||
2602 | volinfo->volname); | |||||
2603 | ||||||
2604 | if (ret != -1) { | |||||
2605 | ret = gf_canonicalize_path (vme->value); | |||||
2606 | if (ret) | |||||
2607 | return -1; | |||||
2608 | ||||||
2609 | ret = xlator_set_option (xl, aa, vme->value); | |||||
2610 | GF_FREE (aa)__gf_free (aa); | |||||
2611 | } | |||||
2612 | ||||||
2613 | if (ret) | |||||
2614 | return -1; | |||||
2615 | } | |||||
2616 | ||||||
2617 | ||||||
2618 | ||||||
2619 | if (! strcmp (vme->option, "!rpc-auth.ports.*.insecure")) { | |||||
2620 | ret = gf_asprintf (&aa, "rpc-auth.ports.%s.insecure", | |||||
2621 | volinfo->volname); | |||||
2622 | ||||||
2623 | if (ret != -1) { | |||||
2624 | ret = xlator_set_option (xl, aa, vme->value); | |||||
2625 | GF_FREE (aa)__gf_free (aa); | |||||
2626 | } | |||||
2627 | ||||||
2628 | if (ret) | |||||
2629 | return -1; | |||||
2630 | } | |||||
2631 | ||||||
2632 | ||||||
2633 | if (! strcmp (vme->option, "!nfs-disable")) { | |||||
2634 | ret = gf_asprintf (&aa, "nfs.%s.disable", | |||||
2635 | volinfo->volname); | |||||
2636 | ||||||
2637 | if (ret != -1) { | |||||
2638 | ret = xlator_set_option (xl, aa, vme->value); | |||||
2639 | GF_FREE (aa)__gf_free (aa); | |||||
2640 | } | |||||
2641 | ||||||
2642 | if (ret) | |||||
2643 | return -1; | |||||
2644 | } | |||||
2645 | ||||||
2646 | if ( (strcmp (vme->voltype, "nfs/server") == 0) && | |||||
2647 | (vme->option && vme->option[0]!='!') ) { | |||||
2648 | ret = xlator_set_option (xl, vme->option, vme->value); | |||||
2649 | if (ret) | |||||
2650 | return -1; | |||||
2651 | } | |||||
2652 | ||||||
2653 | ||||||
2654 | /*key = strchr (vme->key, '.') + 1; | |||||
2655 | ||||||
2656 | for (trav = xl->children; trav; trav = trav->next) { | |||||
2657 | ret = gf_asprintf (&aa, "auth.addr.%s.%s", trav->xlator->name, | |||||
2658 | key); | |||||
2659 | if (ret != -1) { | |||||
2660 | ret = xlator_set_option (xl, aa, vme->value); | |||||
2661 | GF_FREE (aa); | |||||
2662 | } | |||||
2663 | if (ret) | |||||
2664 | return -1; | |||||
2665 | }*/ | |||||
2666 | ||||||
2667 | return 0; | |||||
2668 | } | |||||
2669 | ||||||
2670 | static int | |||||
2671 | volgen_graph_set_iam_shd (volgen_graph_t *graph) | |||||
2672 | { | |||||
2673 | xlator_t *trav; | |||||
2674 | int ret = 0; | |||||
2675 | ||||||
2676 | for (trav = first_of (graph); trav; trav = trav->next) { | |||||
2677 | if (strcmp (trav->type, "cluster/replicate") != 0) | |||||
2678 | continue; | |||||
2679 | ||||||
2680 | ret = xlator_set_option (trav, "iam-self-heal-daemon", "yes"); | |||||
2681 | if (ret) | |||||
2682 | break; | |||||
2683 | } | |||||
2684 | return ret; | |||||
2685 | } | |||||
2686 | ||||||
2687 | static int | |||||
2688 | build_shd_graph (volgen_graph_t *graph, dict_t *mod_dict) | |||||
2689 | { | |||||
2690 | volgen_graph_t cgraph = {0}; | |||||
2691 | glusterd_volinfo_t *voliter = NULL((void*)0); | |||||
2692 | xlator_t *this = NULL((void*)0); | |||||
2693 | glusterd_conf_t *priv = NULL((void*)0); | |||||
2694 | dict_t *set_dict = NULL((void*)0); | |||||
2695 | int ret = 0; | |||||
2696 | gf_boolean_t valid_config = _gf_false; | |||||
2697 | xlator_t *iostxl = NULL((void*)0); | |||||
2698 | int rclusters = 0; | |||||
2699 | int replica_count = 0; | |||||
2700 | gf_boolean_t graph_check = _gf_false; | |||||
2701 | ||||||
2702 | this = THIS(*__glusterfs_this_location()); | |||||
2703 | priv = this->private; | |||||
2704 | ||||||
2705 | set_dict = dict_new (); | |||||
2706 | if (!set_dict) { | |||||
2707 | ret = -ENOMEM12; | |||||
2708 | goto out; | |||||
2709 | } | |||||
2710 | ||||||
2711 | graph_check = dict_get_str_boolean (mod_dict, "graph-check", 0); | |||||
2712 | iostxl = volgen_graph_add_as (graph, "debug/io-stats", "glustershd"); | |||||
2713 | if (!iostxl) { | |||||
2714 | ret = -1; | |||||
2715 | goto out; | |||||
2716 | } | |||||
2717 | ||||||
2718 | list_for_each_entry (voliter, &priv->volumes, vol_list)for (voliter = ((typeof(*voliter) *)((char *)((&priv-> volumes)->next)-(unsigned long)(&((typeof(*voliter) *) 0)->vol_list))); &voliter->vol_list != (&priv-> volumes); voliter = ((typeof(*voliter) *)((char *)(voliter-> vol_list.next)-(unsigned long)(&((typeof(*voliter) *)0)-> vol_list)))) { | |||||
2719 | if (!graph_check && | |||||
2720 | (voliter->status != GLUSTERD_STATUS_STARTED)) | |||||
2721 | continue; | |||||
2722 | ||||||
2723 | if (!glusterd_is_volume_replicate (voliter)) | |||||
2724 | continue; | |||||
2725 | ||||||
2726 | replica_count = voliter->replica_count; | |||||
2727 | ||||||
2728 | valid_config = _gf_true; | |||||
2729 | ||||||
2730 | ret = dict_set_str (set_dict, "cluster.self-heal-daemon", "on"); | |||||
2731 | if (ret) | |||||
2732 | goto out; | |||||
2733 | ||||||
2734 | ret = dict_set_uint32 (set_dict, "trusted-client", | |||||
2735 | GF_CLIENT_TRUSTED); | |||||
2736 | if (ret) | |||||
2737 | goto out; | |||||
2738 | ||||||
2739 | dict_copy (voliter->dict, set_dict); | |||||
2740 | if (mod_dict) | |||||
2741 | dict_copy (mod_dict, set_dict); | |||||
2742 | ||||||
2743 | memset (&cgraph, 0, sizeof (cgraph)); | |||||
2744 | ret = volgen_graph_build_clients (&cgraph, voliter, set_dict, | |||||
2745 | NULL((void*)0)); | |||||
2746 | if (ret) | |||||
2747 | goto out; | |||||
2748 | ||||||
2749 | rclusters = volgen_graph_build_clusters (&cgraph, voliter, | |||||
2750 | "cluster/replicate", | |||||
2751 | "%s-replicate-%d", | |||||
2752 | voliter->brick_count, | |||||
2753 | replica_count); | |||||
2754 | if (rclusters < 0) { | |||||
2755 | ret = -1; | |||||
2756 | goto out; | |||||
2757 | } | |||||
2758 | ||||||
2759 | ret = volgen_graph_set_options_generic (&cgraph, set_dict, voliter, | |||||
2760 | shd_option_handler); | |||||
2761 | if (ret) | |||||
2762 | goto out; | |||||
2763 | ||||||
2764 | ret = volgen_graph_set_iam_shd (&cgraph); | |||||
2765 | if (ret) | |||||
2766 | goto out; | |||||
2767 | ||||||
2768 | ret = volgen_graph_merge_sub (graph, &cgraph, rclusters); | |||||
2769 | if (ret) | |||||
2770 | goto out; | |||||
2771 | ||||||
2772 | ret = volgen_graph_set_options_generic (graph, set_dict, | |||||
2773 | "client", | |||||
2774 | &loglevel_option_handler); | |||||
2775 | ||||||
2776 | if (ret) | |||||
2777 | gf_log (THIS->name, GF_LOG_WARNING, "changing loglevel "do { do { if (0) printf ("changing loglevel " "of self-heal daemon failed" ); } while (0); _gf_log ((*__glusterfs_this_location())->name , "glusterd-volgen.c", __FUNCTION__, 2778, GF_LOG_WARNING, "changing loglevel " "of self-heal daemon failed"); } while (0) | |||||
2778 | "of self-heal daemon failed")do { do { if (0) printf ("changing loglevel " "of self-heal daemon failed" ); } while (0); _gf_log ((*__glusterfs_this_location())->name , "glusterd-volgen.c", __FUNCTION__, 2778, GF_LOG_WARNING, "changing loglevel " "of self-heal daemon failed"); } while (0); | |||||
2779 | ||||||
2780 | ret = volgen_graph_set_options_generic (graph, set_dict, | |||||
2781 | "client", | |||||
2782 | &sys_loglevel_option_handler); | |||||
2783 | if (ret) | |||||
2784 | gf_log (THIS->name, GF_LOG_WARNING, "changing syslog "do { do { if (0) printf ("changing syslog " "level of self-heal daemon failed" ); } while (0); _gf_log ((*__glusterfs_this_location())->name , "glusterd-volgen.c", __FUNCTION__, 2785, GF_LOG_WARNING, "changing syslog " "level of self-heal daemon failed"); } while (0) | |||||
2785 | "level of self-heal daemon failed")do { do { if (0) printf ("changing syslog " "level of self-heal daemon failed" ); } while (0); _gf_log ((*__glusterfs_this_location())->name , "glusterd-volgen.c", __FUNCTION__, 2785, GF_LOG_WARNING, "changing syslog " "level of self-heal daemon failed"); } while (0); | |||||
2786 | ||||||
2787 | ret = dict_reset (set_dict); | |||||
2788 | if (ret) | |||||
2789 | goto out; | |||||
2790 | } | |||||
2791 | out: | |||||
2792 | if (set_dict) | |||||
2793 | dict_unref (set_dict); | |||||
2794 | if (!valid_config) | |||||
2795 | ret = -EINVAL22; | |||||
2796 | return ret; | |||||
2797 | } | |||||
2798 | ||||||
2799 | /* builds a graph for nfs server role, with option overrides in mod_dict */ | |||||
2800 | static int | |||||
2801 | build_nfs_graph (volgen_graph_t *graph, dict_t *mod_dict) | |||||
2802 | { | |||||
2803 | volgen_graph_t cgraph = {0,}; | |||||
2804 | glusterd_volinfo_t *voliter = NULL((void*)0); | |||||
2805 | xlator_t *this = NULL((void*)0); | |||||
2806 | glusterd_conf_t *priv = NULL((void*)0); | |||||
2807 | dict_t *set_dict = NULL((void*)0); | |||||
2808 | xlator_t *nfsxl = NULL((void*)0); | |||||
2809 | char *skey = NULL((void*)0); | |||||
2810 | int ret = 0; | |||||
2811 | char nfs_xprt[16] = {0,}; | |||||
2812 | char *volname = NULL((void*)0); | |||||
2813 | data_t *data = NULL((void*)0); | |||||
2814 | ||||||
2815 | this = THIS(*__glusterfs_this_location()); | |||||
2816 | GF_ASSERT (this)do { if (!(this)) { do { do { if (0) printf ("Assertion failed: " "this"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 2816, GF_LOG_ERROR, "Assertion failed: " "this" ); } while (0); } } while (0); | |||||
2817 | priv = this->private; | |||||
2818 | GF_ASSERT (priv)do { if (!(priv)) { do { do { if (0) printf ("Assertion failed: " "priv"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 2818, GF_LOG_ERROR, "Assertion failed: " "priv" ); } while (0); } } while (0); | |||||
2819 | ||||||
2820 | set_dict = dict_new (); | |||||
2821 | if (!set_dict) { | |||||
2822 | gf_log ("", GF_LOG_ERROR, "Out of memory")do { do { if (0) printf ("Out of memory"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 2822, GF_LOG_ERROR, "Out of memory" ); } while (0); | |||||
2823 | return -1; | |||||
2824 | } | |||||
2825 | ||||||
2826 | nfsxl = volgen_graph_add_as (graph, "nfs/server", "nfs-server"); | |||||
2827 | if (!nfsxl) { | |||||
2828 | ret = -1; | |||||
2829 | goto out; | |||||
2830 | } | |||||
2831 | ret = xlator_set_option (nfsxl, "nfs.dynamic-volumes", "on"); | |||||
2832 | if (ret) | |||||
2833 | goto out; | |||||
2834 | ||||||
2835 | ret = xlator_set_option (nfsxl, "nfs.nlm", "on"); | |||||
2836 | if (ret) | |||||
2837 | goto out; | |||||
2838 | ||||||
2839 | list_for_each_entry (voliter, &priv->volumes, vol_list)for (voliter = ((typeof(*voliter) *)((char *)((&priv-> volumes)->next)-(unsigned long)(&((typeof(*voliter) *) 0)->vol_list))); &voliter->vol_list != (&priv-> volumes); voliter = ((typeof(*voliter) *)((char *)(voliter-> vol_list.next)-(unsigned long)(&((typeof(*voliter) *)0)-> vol_list)))) { | |||||
2840 | if (voliter->status != GLUSTERD_STATUS_STARTED) | |||||
2841 | continue; | |||||
2842 | ||||||
2843 | if (dict_get_str_boolean (voliter->dict, "nfs.disable", 0)) | |||||
2844 | continue; | |||||
2845 | ||||||
2846 | ret = gf_asprintf (&skey, "rpc-auth.addr.%s.allow", | |||||
2847 | voliter->volname); | |||||
2848 | if (ret == -1) { | |||||
2849 | gf_log ("", GF_LOG_ERROR, "Out of memory")do { do { if (0) printf ("Out of memory"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 2849, GF_LOG_ERROR, "Out of memory" ); } while (0); | |||||
2850 | goto out; | |||||
2851 | } | |||||
2852 | ret = xlator_set_option (nfsxl, skey, "*"); | |||||
2853 | GF_FREE (skey)__gf_free (skey); | |||||
2854 | if (ret) | |||||
2855 | goto out; | |||||
2856 | ||||||
2857 | ret = gf_asprintf (&skey, "nfs3.%s.volume-id", | |||||
2858 | voliter->volname); | |||||
2859 | if (ret == -1) { | |||||
2860 | gf_log ("", GF_LOG_ERROR, "Out of memory")do { do { if (0) printf ("Out of memory"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 2860, GF_LOG_ERROR, "Out of memory" ); } while (0); | |||||
2861 | goto out; | |||||
2862 | } | |||||
2863 | ret = xlator_set_option (nfsxl, skey, uuid_utoa (voliter->volume_id)); | |||||
2864 | GF_FREE (skey)__gf_free (skey); | |||||
2865 | if (ret) | |||||
2866 | goto out; | |||||
2867 | ||||||
2868 | /* If both RDMA and TCP are the transport_type, use RDMA | |||||
2869 | for NFS client protocols */ | |||||
2870 | memset (&cgraph, 0, sizeof (cgraph)); | |||||
2871 | if (mod_dict) | |||||
2872 | get_transport_type (voliter, mod_dict, nfs_xprt, _gf_true); | |||||
2873 | else | |||||
2874 | get_transport_type (voliter, voliter->dict, nfs_xprt, _gf_true); | |||||
2875 | ||||||
2876 | ret = dict_set_str (set_dict, "performance.stat-prefetch", "off"); | |||||
2877 | if (ret) | |||||
2878 | goto out; | |||||
2879 | ||||||
2880 | ret = dict_set_str (set_dict, "performance.client-io-threads", | |||||
2881 | "off"); | |||||
2882 | if (ret) | |||||
2883 | goto out; | |||||
2884 | ||||||
2885 | ret = dict_set_str (set_dict, "client-transport-type", | |||||
2886 | nfs_xprt); | |||||
2887 | if (ret) | |||||
2888 | goto out; | |||||
2889 | ||||||
2890 | ret = dict_set_uint32 (set_dict, "trusted-client", | |||||
2891 | GF_CLIENT_TRUSTED); | |||||
2892 | if (ret) | |||||
2893 | goto out; | |||||
2894 | ||||||
2895 | ret = dict_set_str (set_dict, "nfs-volume-file", "yes"); | |||||
2896 | if (ret) | |||||
2897 | goto out; | |||||
2898 | ||||||
2899 | if (mod_dict && (data = dict_get (mod_dict, "volume-name"))) { | |||||
2900 | volname = data->data; | |||||
2901 | if (strcmp (volname, voliter->volname) == 0) | |||||
2902 | dict_copy (mod_dict, set_dict); | |||||
2903 | } | |||||
2904 | ||||||
2905 | ret = build_client_graph (&cgraph, voliter, set_dict); | |||||
2906 | if (ret) | |||||
2907 | goto out; | |||||
2908 | ||||||
2909 | if (mod_dict) { | |||||
2910 | dict_copy (mod_dict, set_dict); | |||||
2911 | ret = volgen_graph_set_options_generic (&cgraph, set_dict, voliter, | |||||
2912 | basic_option_handler); | |||||
2913 | } else { | |||||
2914 | ret = volgen_graph_set_options_generic (&cgraph, voliter->dict, voliter, | |||||
2915 | basic_option_handler); | |||||
2916 | } | |||||
2917 | ||||||
2918 | if (ret) | |||||
2919 | goto out; | |||||
2920 | ||||||
2921 | ret = volgen_graph_merge_sub (graph, &cgraph, 1); | |||||
2922 | if (ret) | |||||
2923 | goto out; | |||||
2924 | ret = dict_reset (set_dict); | |||||
2925 | if (ret) | |||||
2926 | goto out; | |||||
2927 | } | |||||
2928 | ||||||
2929 | list_for_each_entry (voliter, &priv->volumes, vol_list)for (voliter = ((typeof(*voliter) *)((char *)((&priv-> volumes)->next)-(unsigned long)(&((typeof(*voliter) *) 0)->vol_list))); &voliter->vol_list != (&priv-> volumes); voliter = ((typeof(*voliter) *)((char *)(voliter-> vol_list.next)-(unsigned long)(&((typeof(*voliter) *)0)-> vol_list)))) { | |||||
2930 | ||||||
2931 | if (mod_dict) { | |||||
2932 | ret = volgen_graph_set_options_generic (graph, mod_dict, voliter, | |||||
2933 | nfs_option_handler); | |||||
2934 | } else { | |||||
2935 | ret = volgen_graph_set_options_generic (graph, voliter->dict, voliter, | |||||
2936 | nfs_option_handler); | |||||
2937 | } | |||||
2938 | ||||||
2939 | if (ret) | |||||
2940 | gf_log ("glusterd", GF_LOG_WARNING, "Could not set "do { do { if (0) printf ("Could not set " "vol-options for the volume %s" , voliter->volname); } while (0); _gf_log ("glusterd", "glusterd-volgen.c" , __FUNCTION__, 2941, GF_LOG_WARNING, "Could not set " "vol-options for the volume %s" , voliter->volname); } while (0) | |||||
2941 | "vol-options for the volume %s", voliter->volname)do { do { if (0) printf ("Could not set " "vol-options for the volume %s" , voliter->volname); } while (0); _gf_log ("glusterd", "glusterd-volgen.c" , __FUNCTION__, 2941, GF_LOG_WARNING, "Could not set " "vol-options for the volume %s" , voliter->volname); } while (0); | |||||
2942 | } | |||||
2943 | ||||||
2944 | out: | |||||
2945 | gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__, 2945, GF_LOG_DEBUG , "Returning %d", ret); } while (0); | |||||
2946 | dict_destroy (set_dict); | |||||
2947 | ||||||
2948 | return ret; | |||||
2949 | } | |||||
2950 | ||||||
2951 | ||||||
2952 | ||||||
2953 | ||||||
2954 | /**************************** | |||||
2955 | * | |||||
2956 | * Volume generation interface | |||||
2957 | * | |||||
2958 | ****************************/ | |||||
2959 | ||||||
2960 | ||||||
2961 | static void | |||||
2962 | get_brick_filepath (char *filename, glusterd_volinfo_t *volinfo, | |||||
2963 | glusterd_brickinfo_t *brickinfo) | |||||
2964 | { | |||||
2965 | char path[PATH_MAX4096] = {0,}; | |||||
2966 | char brick[PATH_MAX4096] = {0,}; | |||||
2967 | glusterd_conf_t *priv = NULL((void*)0); | |||||
2968 | ||||||
2969 | priv = THIS(*__glusterfs_this_location())->private; | |||||
2970 | ||||||
2971 | GLUSTERD_REMOVE_SLASH_FROM_PATH (brickinfo->path, brick)do { int i = 0; for (i = 1; i < strlen (brickinfo->path ); i++) { brick[i-1] = brickinfo->path[i]; if (brick[i-1] == '/') brick[i-1] = '-'; } } while (0); | |||||
2972 | GLUSTERD_GET_VOLUME_DIR (path, volinfo, priv)snprintf (path, 4096, "%s/vols/%s", priv->workdir, volinfo ->volname);; | |||||
2973 | ||||||
2974 | snprintf (filename, PATH_MAX4096, "%s/%s.%s.%s.vol", | |||||
2975 | path, volinfo->volname, | |||||
2976 | brickinfo->hostname, | |||||
2977 | brick); | |||||
2978 | } | |||||
2979 | ||||||
2980 | gf_boolean_t | |||||
2981 | glusterd_is_valid_volfpath (char *volname, char *brick) | |||||
2982 | { | |||||
2983 | char volfpath[PATH_MAX4096] = {0,}; | |||||
2984 | glusterd_brickinfo_t *brickinfo = NULL((void*)0); | |||||
2985 | glusterd_volinfo_t *volinfo = NULL((void*)0); | |||||
2986 | int32_t ret = 0; | |||||
2987 | xlator_t *this = NULL((void*)0); | |||||
2988 | ||||||
2989 | this = THIS(*__glusterfs_this_location()); | |||||
2990 | GF_ASSERT (this)do { if (!(this)) { do { do { if (0) printf ("Assertion failed: " "this"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 2990, GF_LOG_ERROR, "Assertion failed: " "this" ); } while (0); } } while (0); | |||||
2991 | ||||||
2992 | ret = glusterd_brickinfo_new_from_brick (brick, &brickinfo); | |||||
2993 | if (ret) { | |||||
2994 | gf_log (this->name, GF_LOG_WARNING, "Failed to create brickinfo"do { do { if (0) printf ("Failed to create brickinfo" " for brick %s" , brick); } while (0); _gf_log (this->name, "glusterd-volgen.c" , __FUNCTION__, 2995, GF_LOG_WARNING, "Failed to create brickinfo" " for brick %s", brick); } while (0) | |||||
2995 | " for brick %s", brick )do { do { if (0) printf ("Failed to create brickinfo" " for brick %s" , brick); } while (0); _gf_log (this->name, "glusterd-volgen.c" , __FUNCTION__, 2995, GF_LOG_WARNING, "Failed to create brickinfo" " for brick %s", brick); } while (0); | |||||
2996 | ret = 0; | |||||
2997 | goto out; | |||||
2998 | } | |||||
2999 | ret = glusterd_volinfo_new (&volinfo); | |||||
3000 | if (ret) { | |||||
3001 | gf_log (this->name, GF_LOG_WARNING, "Failed to create volinfo")do { do { if (0) printf ("Failed to create volinfo"); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__ , 3001, GF_LOG_WARNING, "Failed to create volinfo"); } while ( 0); | |||||
3002 | ret = 0; | |||||
3003 | goto out; | |||||
3004 | } | |||||
3005 | strncpy (volinfo->volname, volname, sizeof (volinfo->volname)); | |||||
3006 | get_brick_filepath (volfpath, volinfo, brickinfo); | |||||
3007 | ||||||
3008 | ret = (strlen (volfpath) < _POSIX_PATH_MAX256); | |||||
3009 | ||||||
3010 | out: | |||||
3011 | if (brickinfo) | |||||
3012 | glusterd_brickinfo_delete (brickinfo); | |||||
3013 | if (volinfo) | |||||
3014 | glusterd_volinfo_delete (volinfo); | |||||
3015 | return ret; | |||||
3016 | } | |||||
3017 | ||||||
3018 | static int | |||||
3019 | glusterd_generate_brick_volfile (glusterd_volinfo_t *volinfo, | |||||
3020 | glusterd_brickinfo_t *brickinfo) | |||||
3021 | { | |||||
3022 | volgen_graph_t graph = {0,}; | |||||
3023 | char filename[PATH_MAX4096] = {0,}; | |||||
3024 | int ret = -1; | |||||
3025 | ||||||
3026 | GF_ASSERT (volinfo)do { if (!(volinfo)) { do { do { if (0) printf ("Assertion failed: " "volinfo"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 3026, GF_LOG_ERROR, "Assertion failed: " "volinfo" ); } while (0); } } while (0); | |||||
3027 | GF_ASSERT (brickinfo)do { if (!(brickinfo)) { do { do { if (0) printf ("Assertion failed: " "brickinfo"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 3027, GF_LOG_ERROR, "Assertion failed: " "brickinfo" ); } while (0); } } while (0); | |||||
3028 | ||||||
3029 | get_brick_filepath (filename, volinfo, brickinfo); | |||||
3030 | ||||||
3031 | ret = build_server_graph (&graph, volinfo, NULL((void*)0), brickinfo); | |||||
3032 | if (!ret) | |||||
3033 | ret = volgen_write_volfile (&graph, filename); | |||||
3034 | ||||||
3035 | volgen_graph_free (&graph); | |||||
3036 | ||||||
3037 | return ret; | |||||
3038 | } | |||||
3039 | ||||||
3040 | ||||||
3041 | ||||||
3042 | static void | |||||
3043 | get_vol_tstamp_file (char *filename, glusterd_volinfo_t *volinfo) | |||||
3044 | { | |||||
3045 | glusterd_conf_t *priv = NULL((void*)0); | |||||
3046 | ||||||
3047 | priv = THIS(*__glusterfs_this_location())->private; | |||||
3048 | ||||||
3049 | GLUSTERD_GET_VOLUME_DIR (filename, volinfo, priv)snprintf (filename, 4096, "%s/vols/%s", priv->workdir, volinfo ->volname);; | |||||
3050 | strncat (filename, "/marker.tstamp", | |||||
3051 | PATH_MAX4096 - strlen(filename) - 1); | |||||
3052 | } | |||||
3053 | ||||||
3054 | int | |||||
3055 | generate_brick_volfiles (glusterd_volinfo_t *volinfo) | |||||
3056 | { | |||||
3057 | glusterd_brickinfo_t *brickinfo = NULL((void*)0); | |||||
3058 | char tstamp_file[PATH_MAX4096] = {0,}; | |||||
3059 | int ret = -1; | |||||
3060 | ||||||
3061 | ret = glusterd_volinfo_get_boolean (volinfo, VKEY_MARKER_XTIME"geo-replication"".indexing"); | |||||
3062 | if (ret == -1) | |||||
3063 | return -1; | |||||
3064 | ||||||
3065 | get_vol_tstamp_file (tstamp_file, volinfo); | |||||
3066 | ||||||
3067 | if (ret) { | |||||
3068 | ret = open (tstamp_file, O_WRONLY01|O_CREAT0100|O_EXCL0200, 0600); | |||||
3069 | if (ret == -1 && errno(*__errno_location ()) == EEXIST17) { | |||||
3070 | gf_log ("", GF_LOG_DEBUG, "timestamp file exist")do { do { if (0) printf ("timestamp file exist"); } while (0) ; _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3070, GF_LOG_DEBUG , "timestamp file exist"); } while (0); | |||||
3071 | ret = -2; | |||||
3072 | } | |||||
3073 | if (ret == -1) { | |||||
3074 | gf_log ("", GF_LOG_ERROR, "failed to create %s (%s)",do { do { if (0) printf ("failed to create %s (%s)", tstamp_file , strerror ((*__errno_location ()))); } while (0); _gf_log ("" , "glusterd-volgen.c", __FUNCTION__, 3075, GF_LOG_ERROR, "failed to create %s (%s)" , tstamp_file, strerror ((*__errno_location ()))); } while (0 ) | |||||
3075 | tstamp_file, strerror (errno))do { do { if (0) printf ("failed to create %s (%s)", tstamp_file , strerror ((*__errno_location ()))); } while (0); _gf_log ("" , "glusterd-volgen.c", __FUNCTION__, 3075, GF_LOG_ERROR, "failed to create %s (%s)" , tstamp_file, strerror ((*__errno_location ()))); } while (0 ); | |||||
3076 | return -1; | |||||
3077 | } | |||||
3078 | if (ret >= 0) | |||||
3079 | close (ret); | |||||
3080 | } else { | |||||
3081 | ret = unlink (tstamp_file); | |||||
3082 | if (ret == -1 && errno(*__errno_location ()) == ENOENT2) | |||||
3083 | ret = 0; | |||||
3084 | if (ret == -1) { | |||||
3085 | gf_log ("", GF_LOG_ERROR, "failed to unlink %s (%s)",do { do { if (0) printf ("failed to unlink %s (%s)", tstamp_file , strerror ((*__errno_location ()))); } while (0); _gf_log ("" , "glusterd-volgen.c", __FUNCTION__, 3086, GF_LOG_ERROR, "failed to unlink %s (%s)" , tstamp_file, strerror ((*__errno_location ()))); } while (0 ) | |||||
3086 | tstamp_file, strerror (errno))do { do { if (0) printf ("failed to unlink %s (%s)", tstamp_file , strerror ((*__errno_location ()))); } while (0); _gf_log ("" , "glusterd-volgen.c", __FUNCTION__, 3086, GF_LOG_ERROR, "failed to unlink %s (%s)" , tstamp_file, strerror ((*__errno_location ()))); } while (0 ); | |||||
3087 | return -1; | |||||
3088 | } | |||||
3089 | } | |||||
3090 | ||||||
3091 | list_for_each_entry (brickinfo, &volinfo->bricks, brick_list)for (brickinfo = ((typeof(*brickinfo) *)((char *)((&volinfo ->bricks)->next)-(unsigned long)(&((typeof(*brickinfo ) *)0)->brick_list))); &brickinfo->brick_list != (& volinfo->bricks); brickinfo = ((typeof(*brickinfo) *)((char *)(brickinfo->brick_list.next)-(unsigned long)(&((typeof (*brickinfo) *)0)->brick_list)))) { | |||||
3092 | gf_log ("", GF_LOG_DEBUG,do { do { if (0) printf ("Found a brick - %s:%s", brickinfo-> hostname, brickinfo->path); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 3094, GF_LOG_DEBUG, "Found a brick - %s:%s", brickinfo ->hostname, brickinfo->path); } while (0) | |||||
3093 | "Found a brick - %s:%s", brickinfo->hostname,do { do { if (0) printf ("Found a brick - %s:%s", brickinfo-> hostname, brickinfo->path); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 3094, GF_LOG_DEBUG, "Found a brick - %s:%s", brickinfo ->hostname, brickinfo->path); } while (0) | |||||
3094 | brickinfo->path)do { do { if (0) printf ("Found a brick - %s:%s", brickinfo-> hostname, brickinfo->path); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 3094, GF_LOG_DEBUG, "Found a brick - %s:%s", brickinfo ->hostname, brickinfo->path); } while (0); | |||||
3095 | ||||||
3096 | ret = glusterd_generate_brick_volfile (volinfo, brickinfo); | |||||
3097 | if (ret) | |||||
3098 | goto out; | |||||
3099 | ||||||
3100 | } | |||||
3101 | ||||||
3102 | ret = 0; | |||||
3103 | ||||||
3104 | out: | |||||
3105 | gf_log ("", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3105, GF_LOG_DEBUG, "Returning %d" , ret); } while (0); | |||||
3106 | return ret; | |||||
3107 | } | |||||
3108 | ||||||
3109 | static int | |||||
3110 | generate_single_transport_client_volfile (glusterd_volinfo_t *volinfo, | |||||
3111 | char *filepath, dict_t *dict) | |||||
3112 | { | |||||
3113 | volgen_graph_t graph = {0,}; | |||||
3114 | int ret = -1; | |||||
3115 | ||||||
3116 | ret = build_client_graph (&graph, volinfo, dict); | |||||
3117 | if (!ret) | |||||
3118 | ret = volgen_write_volfile (&graph, filepath); | |||||
3119 | ||||||
3120 | volgen_graph_free (&graph); | |||||
3121 | ||||||
3122 | return ret; | |||||
3123 | } | |||||
3124 | ||||||
3125 | static void | |||||
3126 | enumerate_transport_reqs (gf_transport_type type, char **types) | |||||
3127 | { | |||||
3128 | switch (type) { | |||||
3129 | case GF_TRANSPORT_TCP: | |||||
3130 | types[0] = "tcp"; | |||||
3131 | break; | |||||
3132 | case GF_TRANSPORT_RDMA: | |||||
3133 | types[0] = "rdma"; | |||||
3134 | break; | |||||
3135 | case GF_TRANSPORT_BOTH_TCP_RDMA: | |||||
3136 | types[0] = "tcp"; | |||||
3137 | types[1] = "rdma"; | |||||
3138 | break; | |||||
3139 | } | |||||
3140 | } | |||||
3141 | ||||||
3142 | static int | |||||
3143 | generate_client_volfiles (glusterd_volinfo_t *volinfo, | |||||
3144 | glusterd_client_type_t client_type) | |||||
3145 | { | |||||
3146 | char filepath[PATH_MAX4096] = {0,}; | |||||
3147 | int ret = -1; | |||||
3148 | char *types[] = {NULL((void*)0), NULL((void*)0), NULL((void*)0)}; | |||||
3149 | int i = 0; | |||||
3150 | dict_t *dict = NULL((void*)0); | |||||
3151 | gf_transport_type type = GF_TRANSPORT_TCP; | |||||
3152 | ||||||
3153 | enumerate_transport_reqs (volinfo->transport_type, types); | |||||
3154 | dict = dict_new (); | |||||
3155 | if (!dict) | |||||
3156 | goto out; | |||||
3157 | for (i = 0; types[i]; i++) { | |||||
3158 | memset (filepath, 0, sizeof (filepath)); | |||||
3159 | ret = dict_set_str (dict, "client-transport-type", types[i]); | |||||
3160 | if (ret) | |||||
3161 | goto out; | |||||
3162 | type = transport_str_to_type (types[i]); | |||||
3163 | ||||||
3164 | ret = dict_set_uint32 (dict, "trusted-client", client_type); | |||||
3165 | if (ret) | |||||
3166 | goto out; | |||||
3167 | ||||||
3168 | if (client_type == GF_CLIENT_TRUSTED) { | |||||
3169 | glusterd_get_trusted_client_filepath (filepath, | |||||
3170 | volinfo, | |||||
3171 | type); | |||||
3172 | } else { | |||||
3173 | glusterd_get_client_filepath (filepath, | |||||
3174 | volinfo, | |||||
3175 | type); | |||||
3176 | } | |||||
3177 | ||||||
3178 | ret = generate_single_transport_client_volfile (volinfo, | |||||
3179 | filepath, | |||||
3180 | dict); | |||||
3181 | if (ret) | |||||
3182 | goto out; | |||||
3183 | } | |||||
3184 | out: | |||||
3185 | if (dict) | |||||
3186 | dict_unref (dict); | |||||
3187 | return ret; | |||||
3188 | } | |||||
3189 | ||||||
3190 | int | |||||
3191 | glusterd_create_rb_volfiles (glusterd_volinfo_t *volinfo, | |||||
3192 | glusterd_brickinfo_t *brickinfo) | |||||
3193 | { | |||||
3194 | int ret = -1; | |||||
3195 | ||||||
3196 | ret = glusterd_generate_brick_volfile (volinfo, brickinfo); | |||||
3197 | if (!ret) | |||||
3198 | ret = generate_client_volfiles (volinfo, GF_CLIENT_TRUSTED); | |||||
3199 | if (!ret) | |||||
3200 | ret = glusterd_fetchspec_notify (THIS(*__glusterfs_this_location())); | |||||
3201 | ||||||
3202 | return ret; | |||||
3203 | } | |||||
3204 | ||||||
3205 | int | |||||
3206 | glusterd_create_volfiles_and_notify_services (glusterd_volinfo_t *volinfo) | |||||
3207 | { | |||||
3208 | int ret = -1; | |||||
3209 | xlator_t *this = NULL((void*)0); | |||||
3210 | ||||||
3211 | this = THIS(*__glusterfs_this_location()); | |||||
3212 | ||||||
3213 | ret = generate_brick_volfiles (volinfo); | |||||
3214 | if (ret) { | |||||
3215 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("Could not generate volfiles for bricks" ); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__ , 3216, GF_LOG_ERROR, "Could not generate volfiles for bricks" ); } while (0) | |||||
3216 | "Could not generate volfiles for bricks")do { do { if (0) printf ("Could not generate volfiles for bricks" ); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__ , 3216, GF_LOG_ERROR, "Could not generate volfiles for bricks" ); } while (0); | |||||
3217 | goto out; | |||||
3218 | } | |||||
3219 | ||||||
3220 | ret = generate_client_volfiles (volinfo, GF_CLIENT_TRUSTED); | |||||
3221 | if (ret) { | |||||
3222 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("Could not generate trusted client volfiles" ); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__ , 3223, GF_LOG_ERROR, "Could not generate trusted client volfiles" ); } while (0) | |||||
3223 | "Could not generate trusted client volfiles")do { do { if (0) printf ("Could not generate trusted client volfiles" ); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__ , 3223, GF_LOG_ERROR, "Could not generate trusted client volfiles" ); } while (0); | |||||
3224 | goto out; | |||||
3225 | } | |||||
3226 | ||||||
3227 | ret = generate_client_volfiles (volinfo, GF_CLIENT_OTHER); | |||||
3228 | if (ret) { | |||||
3229 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("Could not generate client volfiles" ); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__ , 3230, GF_LOG_ERROR, "Could not generate client volfiles"); } while (0) | |||||
3230 | "Could not generate client volfiles")do { do { if (0) printf ("Could not generate client volfiles" ); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__ , 3230, GF_LOG_ERROR, "Could not generate client volfiles"); } while (0); | |||||
3231 | goto out; | |||||
3232 | } | |||||
3233 | ||||||
3234 | ret = glusterd_fetchspec_notify (this); | |||||
3235 | ||||||
3236 | out: | |||||
3237 | return ret; | |||||
3238 | } | |||||
3239 | ||||||
3240 | int | |||||
3241 | glusterd_create_global_volfile (int (*builder) (volgen_graph_t *graph, | |||||
3242 | dict_t *set_dict), | |||||
3243 | char *filepath, dict_t *mod_dict) | |||||
3244 | { | |||||
3245 | volgen_graph_t graph = {0,}; | |||||
3246 | int ret = -1; | |||||
3247 | ||||||
3248 | ret = builder (&graph, mod_dict); | |||||
3249 | if (!ret) | |||||
3250 | ret = volgen_write_volfile (&graph, filepath); | |||||
3251 | ||||||
3252 | volgen_graph_free (&graph); | |||||
3253 | ||||||
3254 | return ret; | |||||
3255 | } | |||||
3256 | ||||||
3257 | int | |||||
3258 | glusterd_create_nfs_volfile () | |||||
3259 | { | |||||
3260 | char filepath[PATH_MAX4096] = {0,}; | |||||
3261 | glusterd_conf_t *conf = THIS(*__glusterfs_this_location())->private; | |||||
3262 | ||||||
3263 | glusterd_get_nodesvc_volfile ("nfs", conf->workdir, | |||||
3264 | filepath, sizeof (filepath)); | |||||
3265 | return glusterd_create_global_volfile (build_nfs_graph, | |||||
3266 | filepath, NULL((void*)0)); | |||||
3267 | } | |||||
3268 | ||||||
3269 | int | |||||
3270 | glusterd_create_shd_volfile () | |||||
3271 | { | |||||
3272 | char filepath[PATH_MAX4096] = {0,}; | |||||
3273 | int ret = -1; | |||||
3274 | glusterd_conf_t *conf = THIS(*__glusterfs_this_location())->private; | |||||
3275 | dict_t *mod_dict = NULL((void*)0); | |||||
3276 | ||||||
3277 | mod_dict = dict_new (); | |||||
3278 | if (!mod_dict) | |||||
3279 | goto out; | |||||
3280 | ||||||
3281 | ret = dict_set_uint32 (mod_dict, "cluster.background-self-heal-count", 0); | |||||
3282 | if (ret) | |||||
3283 | goto out; | |||||
3284 | ||||||
3285 | ret = dict_set_str (mod_dict, "cluster.data-self-heal", "on"); | |||||
3286 | if (ret) | |||||
3287 | goto out; | |||||
3288 | ||||||
3289 | ret = dict_set_str (mod_dict, "cluster.metadata-self-heal", "on"); | |||||
3290 | if (ret) | |||||
3291 | goto out; | |||||
3292 | ||||||
3293 | ret = dict_set_str (mod_dict, "cluster.entry-self-heal", "on"); | |||||
3294 | if (ret) | |||||
3295 | goto out; | |||||
3296 | ||||||
3297 | glusterd_get_nodesvc_volfile ("glustershd", conf->workdir, | |||||
3298 | filepath, sizeof (filepath)); | |||||
3299 | ret = glusterd_create_global_volfile (build_shd_graph, filepath, | |||||
3300 | mod_dict); | |||||
3301 | out: | |||||
3302 | if (mod_dict) | |||||
3303 | dict_unref (mod_dict); | |||||
3304 | return ret; | |||||
3305 | } | |||||
3306 | ||||||
3307 | int | |||||
3308 | glusterd_check_nfs_volfile_identical (gf_boolean_t *identical) | |||||
3309 | { | |||||
3310 | char nfsvol[PATH_MAX4096] = {0,}; | |||||
3311 | char tmpnfsvol[PATH_MAX4096] = {0,}; | |||||
3312 | glusterd_conf_t *conf = NULL((void*)0); | |||||
3313 | xlator_t *this = NULL((void*)0); | |||||
3314 | int ret = -1; | |||||
3315 | int need_unlink = 0; | |||||
3316 | int tmp_fd = -1; | |||||
3317 | ||||||
3318 | this = THIS(*__glusterfs_this_location()); | |||||
3319 | ||||||
3320 | GF_ASSERT (this)do { if (!(this)) { do { do { if (0) printf ("Assertion failed: " "this"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 3320, GF_LOG_ERROR, "Assertion failed: " "this" ); } while (0); } } while (0); | |||||
3321 | GF_ASSERT (identical)do { if (!(identical)) { do { do { if (0) printf ("Assertion failed: " "identical"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 3321, GF_LOG_ERROR, "Assertion failed: " "identical" ); } while (0); } } while (0); | |||||
3322 | ||||||
3323 | conf = this->private; | |||||
3324 | ||||||
3325 | glusterd_get_nodesvc_volfile ("nfs", conf->workdir, | |||||
3326 | nfsvol, sizeof (nfsvol)); | |||||
3327 | ||||||
3328 | snprintf (tmpnfsvol, sizeof (tmpnfsvol), "/tmp/gnfs-XXXXXX"); | |||||
3329 | ||||||
3330 | tmp_fd = mkstemp (tmpnfsvol); | |||||
3331 | if (tmp_fd < 0) { | |||||
3332 | gf_log ("", GF_LOG_WARNING, "Unable to create temp file %s: "do { do { if (0) printf ("Unable to create temp file %s: " "(%s)" , tmpnfsvol, strerror ((*__errno_location ()))); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3333, GF_LOG_WARNING , "Unable to create temp file %s: " "(%s)", tmpnfsvol, strerror ((*__errno_location ()))); } while (0) | |||||
3333 | "(%s)", tmpnfsvol, strerror (errno))do { do { if (0) printf ("Unable to create temp file %s: " "(%s)" , tmpnfsvol, strerror ((*__errno_location ()))); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3333, GF_LOG_WARNING , "Unable to create temp file %s: " "(%s)", tmpnfsvol, strerror ((*__errno_location ()))); } while (0); | |||||
3334 | goto out; | |||||
3335 | } | |||||
3336 | ||||||
3337 | need_unlink = 1; | |||||
3338 | ||||||
3339 | ret = glusterd_create_global_volfile (build_nfs_graph, | |||||
3340 | tmpnfsvol, NULL((void*)0)); | |||||
3341 | if (ret) | |||||
3342 | goto out; | |||||
3343 | ||||||
3344 | ret = glusterd_check_files_identical (nfsvol, tmpnfsvol, | |||||
3345 | identical); | |||||
3346 | if (ret) | |||||
3347 | goto out; | |||||
3348 | ||||||
3349 | out: | |||||
3350 | if (need_unlink) | |||||
3351 | unlink (tmpnfsvol); | |||||
3352 | ||||||
3353 | if (tmp_fd >= 0) | |||||
3354 | close (tmp_fd); | |||||
3355 | ||||||
3356 | return ret; | |||||
3357 | } | |||||
3358 | ||||||
3359 | int | |||||
3360 | glusterd_delete_volfile (glusterd_volinfo_t *volinfo, | |||||
3361 | glusterd_brickinfo_t *brickinfo) | |||||
3362 | { | |||||
3363 | int ret = 0; | |||||
3364 | char filename[PATH_MAX4096] = {0,}; | |||||
3365 | ||||||
3366 | GF_ASSERT (volinfo)do { if (!(volinfo)) { do { do { if (0) printf ("Assertion failed: " "volinfo"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 3366, GF_LOG_ERROR, "Assertion failed: " "volinfo" ); } while (0); } } while (0); | |||||
3367 | GF_ASSERT (brickinfo)do { if (!(brickinfo)) { do { do { if (0) printf ("Assertion failed: " "brickinfo"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 3367, GF_LOG_ERROR, "Assertion failed: " "brickinfo" ); } while (0); } } while (0); | |||||
3368 | ||||||
3369 | get_brick_filepath (filename, volinfo, brickinfo); | |||||
3370 | ret = unlink (filename); | |||||
3371 | if (ret) | |||||
3372 | gf_log ("glusterd", GF_LOG_ERROR, "failed to delete file: %s, "do { do { if (0) printf ("failed to delete file: %s, " "reason: %s" , filename, strerror ((*__errno_location ()))); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__, 3373, GF_LOG_ERROR , "failed to delete file: %s, " "reason: %s", filename, strerror ((*__errno_location ()))); } while (0) | |||||
3373 | "reason: %s", filename, strerror (errno))do { do { if (0) printf ("failed to delete file: %s, " "reason: %s" , filename, strerror ((*__errno_location ()))); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__, 3373, GF_LOG_ERROR , "failed to delete file: %s, " "reason: %s", filename, strerror ((*__errno_location ()))); } while (0); | |||||
3374 | return ret; | |||||
3375 | } | |||||
3376 | ||||||
3377 | int | |||||
3378 | validate_shdopts (glusterd_volinfo_t *volinfo, | |||||
3379 | dict_t *val_dict, | |||||
3380 | char **op_errstr) | |||||
3381 | { | |||||
3382 | volgen_graph_t graph = {0,}; | |||||
3383 | int ret = -1; | |||||
3384 | ||||||
3385 | graph.errstr = op_errstr; | |||||
3386 | ||||||
3387 | if (!glusterd_is_volume_replicate (volinfo)) { | |||||
3388 | ret = 0; | |||||
3389 | goto out; | |||||
3390 | } | |||||
3391 | ret = dict_set_str (val_dict, "graph-check", "on"); | |||||
3392 | if (ret) | |||||
3393 | goto out; | |||||
3394 | ret = build_shd_graph (&graph, val_dict); | |||||
3395 | if (!ret) | |||||
3396 | ret = graph_reconf_validateopt (&graph.graph, op_errstr); | |||||
3397 | ||||||
3398 | volgen_graph_free (&graph); | |||||
3399 | ||||||
3400 | gf_log ("glusterd", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("glusterd", "glusterd-volgen.c", __FUNCTION__, 3400, GF_LOG_DEBUG , "Returning %d", ret); } while (0); | |||||
3401 | out: | |||||
3402 | dict_del (val_dict, "graph-check"); | |||||
3403 | return ret; | |||||
3404 | } | |||||
3405 | ||||||
3406 | int | |||||
3407 | validate_nfsopts (glusterd_volinfo_t *volinfo, | |||||
3408 | dict_t *val_dict, | |||||
3409 | char **op_errstr) | |||||
3410 | { | |||||
3411 | volgen_graph_t graph = {0,}; | |||||
3412 | int ret = -1; | |||||
3413 | char transport_type[16] = {0,}; | |||||
3414 | char *tt = NULL((void*)0); | |||||
3415 | char err_str[4096] = {0,}; | |||||
3416 | xlator_t *this = THIS(*__glusterfs_this_location()); | |||||
3417 | ||||||
3418 | GF_ASSERT (this)do { if (!(this)) { do { do { if (0) printf ("Assertion failed: " "this"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 3418, GF_LOG_ERROR, "Assertion failed: " "this" ); } while (0); } } while (0); | |||||
3419 | ||||||
3420 | graph.errstr = op_errstr; | |||||
3421 | ||||||
3422 | get_vol_transport_type (volinfo, transport_type); | |||||
3423 | ret = dict_get_str (val_dict, "nfs.transport-type", &tt); | |||||
3424 | if (!ret) { | |||||
3425 | if (volinfo->transport_type != GF_TRANSPORT_BOTH_TCP_RDMA) { | |||||
3426 | snprintf (err_str, sizeof (err_str), "Changing nfs " | |||||
3427 | "transport type is allowed only for volumes " | |||||
3428 | "of transport type tcp,rdma"); | |||||
3429 | gf_log (this->name, GF_LOG_ERROR, "%s", err_str)do { do { if (0) printf ("%s", err_str); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__, 3429, GF_LOG_ERROR , "%s", err_str); } while (0); | |||||
| ||||||
3430 | *op_errstr = gf_strdup (err_str); | |||||
3431 | ret = -1; | |||||
3432 | goto out; | |||||
3433 | } | |||||
3434 | if (strcmp (tt,"tcp") && strcmp (tt,"rdma")) { | |||||
3435 | snprintf (err_str, sizeof (err_str), "wrong transport " | |||||
3436 | "type %s", tt); | |||||
3437 | *op_errstr = gf_strdup (err_str); | |||||
3438 | ret = -1; | |||||
3439 | goto out; | |||||
3440 | } | |||||
3441 | } | |||||
3442 | ||||||
3443 | ret = dict_set_str (val_dict, "volume-name", volinfo->volname); | |||||
3444 | if (ret) { | |||||
3445 | gf_log (this->name, GF_LOG_ERROR, "Failed to set volume name")do { do { if (0) printf ("Failed to set volume name"); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__ , 3445, GF_LOG_ERROR, "Failed to set volume name"); } while ( 0); | |||||
3446 | goto out; | |||||
3447 | } | |||||
3448 | ||||||
3449 | ret = build_nfs_graph (&graph, val_dict); | |||||
3450 | if (!ret) | |||||
3451 | ret = graph_reconf_validateopt (&graph.graph, op_errstr); | |||||
3452 | ||||||
3453 | volgen_graph_free (&graph); | |||||
3454 | ||||||
3455 | out: | |||||
3456 | if (dict_get (val_dict, "volume-name")) | |||||
3457 | dict_del (val_dict, "volume-name"); | |||||
3458 | gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log (this->name, "glusterd-volgen.c", __FUNCTION__, 3458, GF_LOG_DEBUG , "Returning %d", ret); } while (0); | |||||
3459 | return ret; | |||||
3460 | } | |||||
3461 | ||||||
3462 | ||||||
3463 | int | |||||
3464 | validate_clientopts (glusterd_volinfo_t *volinfo, | |||||
3465 | dict_t *val_dict, | |||||
3466 | char **op_errstr) | |||||
3467 | { | |||||
3468 | volgen_graph_t graph = {0,}; | |||||
3469 | int ret = -1; | |||||
3470 | ||||||
3471 | GF_ASSERT (volinfo)do { if (!(volinfo)) { do { do { if (0) printf ("Assertion failed: " "volinfo"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 3471, GF_LOG_ERROR, "Assertion failed: " "volinfo" ); } while (0); } } while (0); | |||||
3472 | ||||||
3473 | graph.errstr = op_errstr; | |||||
3474 | ||||||
3475 | ret = build_client_graph (&graph, volinfo, val_dict); | |||||
3476 | if (!ret) | |||||
3477 | ret = graph_reconf_validateopt (&graph.graph, op_errstr); | |||||
3478 | ||||||
3479 | volgen_graph_free (&graph); | |||||
3480 | ||||||
3481 | gf_log ("", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3481, GF_LOG_DEBUG, "Returning %d" , ret); } while (0); | |||||
3482 | return ret; | |||||
3483 | } | |||||
3484 | ||||||
3485 | int | |||||
3486 | validate_brickopts (glusterd_volinfo_t *volinfo, | |||||
3487 | glusterd_brickinfo_t *brickinfo, | |||||
3488 | dict_t *val_dict, | |||||
3489 | char **op_errstr) | |||||
3490 | { | |||||
3491 | volgen_graph_t graph = {0,}; | |||||
3492 | int ret = -1; | |||||
3493 | ||||||
3494 | GF_ASSERT (volinfo)do { if (!(volinfo)) { do { do { if (0) printf ("Assertion failed: " "volinfo"); } while (0); _gf_log_callingfn ("", "glusterd-volgen.c" , __FUNCTION__, 3494, GF_LOG_ERROR, "Assertion failed: " "volinfo" ); } while (0); } } while (0); | |||||
3495 | ||||||
3496 | graph.errstr = op_errstr; | |||||
3497 | ||||||
3498 | ret = build_server_graph (&graph, volinfo, val_dict, brickinfo); | |||||
3499 | if (!ret) | |||||
3500 | ret = graph_reconf_validateopt (&graph.graph, op_errstr); | |||||
3501 | ||||||
3502 | volgen_graph_free (&graph); | |||||
3503 | ||||||
3504 | gf_log ("", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3504, GF_LOG_DEBUG, "Returning %d" , ret); } while (0); | |||||
3505 | return ret; | |||||
3506 | } | |||||
3507 | ||||||
3508 | int | |||||
3509 | glusterd_validate_brickreconf (glusterd_volinfo_t *volinfo, | |||||
3510 | dict_t *val_dict, | |||||
3511 | char **op_errstr) | |||||
3512 | { | |||||
3513 | glusterd_brickinfo_t *brickinfo = NULL((void*)0); | |||||
3514 | int ret = -1; | |||||
3515 | ||||||
3516 | list_for_each_entry (brickinfo, &volinfo->bricks, brick_list)for (brickinfo = ((typeof(*brickinfo) *)((char *)((&volinfo ->bricks)->next)-(unsigned long)(&((typeof(*brickinfo ) *)0)->brick_list))); &brickinfo->brick_list != (& volinfo->bricks); brickinfo = ((typeof(*brickinfo) *)((char *)(brickinfo->brick_list.next)-(unsigned long)(&((typeof (*brickinfo) *)0)->brick_list)))) { | |||||
3517 | gf_log ("", GF_LOG_DEBUG,do { do { if (0) printf ("Validating %s", brickinfo->hostname ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 3518, GF_LOG_DEBUG, "Validating %s", brickinfo->hostname ); } while (0) | |||||
3518 | "Validating %s", brickinfo->hostname)do { do { if (0) printf ("Validating %s", brickinfo->hostname ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 3518, GF_LOG_DEBUG, "Validating %s", brickinfo->hostname ); } while (0); | |||||
3519 | ||||||
3520 | ret = validate_brickopts (volinfo, brickinfo, val_dict, | |||||
3521 | op_errstr); | |||||
3522 | if (ret) | |||||
3523 | goto out; | |||||
3524 | } | |||||
3525 | ||||||
3526 | ret = 0; | |||||
3527 | ||||||
3528 | out: | |||||
3529 | return ret; | |||||
3530 | } | |||||
3531 | ||||||
3532 | static int | |||||
3533 | _check_globalopt (dict_t *this, char *key, data_t *value, void *ret_val) | |||||
3534 | { | |||||
3535 | int *ret = NULL((void*)0); | |||||
3536 | ||||||
3537 | ret = ret_val; | |||||
3538 | if (*ret) | |||||
3539 | return 0; | |||||
3540 | if (!glusterd_check_globaloption (key)) | |||||
3541 | *ret = 1; | |||||
3542 | ||||||
3543 | return 0; | |||||
3544 | } | |||||
3545 | ||||||
3546 | int | |||||
3547 | glusterd_validate_globalopts (glusterd_volinfo_t *volinfo, | |||||
3548 | dict_t *val_dict, char **op_errstr) | |||||
3549 | { | |||||
3550 | int ret = 0; | |||||
3551 | ||||||
3552 | dict_foreach (val_dict, _check_globalopt, &ret); | |||||
3553 | if (ret) { | |||||
3554 | *op_errstr = gf_strdup ( "option specified is not a global option"); | |||||
3555 | return -1; | |||||
3556 | } | |||||
3557 | ret = glusterd_validate_brickreconf (volinfo, val_dict, op_errstr); | |||||
3558 | ||||||
3559 | if (ret) { | |||||
3560 | gf_log ("", GF_LOG_DEBUG,do { do { if (0) printf ("Could not Validate bricks"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3561, GF_LOG_DEBUG , "Could not Validate bricks"); } while (0) | |||||
3561 | "Could not Validate bricks")do { do { if (0) printf ("Could not Validate bricks"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3561, GF_LOG_DEBUG , "Could not Validate bricks"); } while (0); | |||||
3562 | goto out; | |||||
3563 | } | |||||
3564 | ||||||
3565 | ret = validate_clientopts (volinfo, val_dict, op_errstr); | |||||
3566 | if (ret) { | |||||
3567 | gf_log ("", GF_LOG_DEBUG,do { do { if (0) printf ("Could not Validate client"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3568, GF_LOG_DEBUG , "Could not Validate client"); } while (0) | |||||
3568 | "Could not Validate client")do { do { if (0) printf ("Could not Validate client"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3568, GF_LOG_DEBUG , "Could not Validate client"); } while (0); | |||||
3569 | goto out; | |||||
3570 | } | |||||
3571 | ||||||
3572 | ret = validate_nfsopts (volinfo, val_dict, op_errstr); | |||||
3573 | if (ret) { | |||||
3574 | gf_log ("", GF_LOG_DEBUG, "Could not Validate nfs")do { do { if (0) printf ("Could not Validate nfs"); } while ( 0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3574, GF_LOG_DEBUG , "Could not Validate nfs"); } while (0); | |||||
3575 | goto out; | |||||
3576 | } | |||||
3577 | ||||||
3578 | ret = validate_shdopts (volinfo, val_dict, op_errstr); | |||||
3579 | if (ret) { | |||||
3580 | gf_log ("", GF_LOG_DEBUG, "Could not Validate self-heald")do { do { if (0) printf ("Could not Validate self-heald"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3580, GF_LOG_DEBUG , "Could not Validate self-heald"); } while (0); | |||||
3581 | goto out; | |||||
3582 | } | |||||
3583 | ||||||
3584 | out: | |||||
3585 | gf_log ("", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3585, GF_LOG_DEBUG, "Returning %d" , ret); } while (0); | |||||
3586 | return ret; | |||||
3587 | } | |||||
3588 | ||||||
3589 | static int | |||||
3590 | _check_localopt (dict_t *this, char *key, data_t *value, void *ret_val) | |||||
3591 | { | |||||
3592 | int *ret = NULL((void*)0); | |||||
3593 | ||||||
3594 | ret = ret_val; | |||||
3595 | if (*ret) | |||||
3596 | return 0; | |||||
3597 | if (!glusterd_check_localoption (key)) | |||||
3598 | *ret = 1; | |||||
3599 | ||||||
3600 | return 0; | |||||
3601 | } | |||||
3602 | ||||||
3603 | int | |||||
3604 | glusterd_validate_reconfopts (glusterd_volinfo_t *volinfo, dict_t *val_dict, | |||||
3605 | char **op_errstr) | |||||
3606 | { | |||||
3607 | int ret = 0; | |||||
3608 | ||||||
3609 | dict_foreach (val_dict, _check_localopt, &ret); | |||||
3610 | if (ret) { | |||||
| ||||||
3611 | *op_errstr = gf_strdup ( "option specified is not a local option"); | |||||
3612 | return -1; | |||||
3613 | } | |||||
3614 | ret = glusterd_validate_brickreconf (volinfo, val_dict, op_errstr); | |||||
3615 | ||||||
3616 | if (ret) { | |||||
3617 | gf_log ("", GF_LOG_DEBUG,do { do { if (0) printf ("Could not Validate bricks"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3618, GF_LOG_DEBUG , "Could not Validate bricks"); } while (0) | |||||
3618 | "Could not Validate bricks")do { do { if (0) printf ("Could not Validate bricks"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3618, GF_LOG_DEBUG , "Could not Validate bricks"); } while (0); | |||||
3619 | goto out; | |||||
3620 | } | |||||
3621 | ||||||
3622 | ret = validate_clientopts (volinfo, val_dict, op_errstr); | |||||
3623 | if (ret) { | |||||
3624 | gf_log ("", GF_LOG_DEBUG,do { do { if (0) printf ("Could not Validate client"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3625, GF_LOG_DEBUG , "Could not Validate client"); } while (0) | |||||
3625 | "Could not Validate client")do { do { if (0) printf ("Could not Validate client"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3625, GF_LOG_DEBUG , "Could not Validate client"); } while (0); | |||||
3626 | goto out; | |||||
3627 | } | |||||
3628 | ||||||
3629 | ret = validate_nfsopts (volinfo, val_dict, op_errstr); | |||||
3630 | if (ret) { | |||||
3631 | gf_log ("", GF_LOG_DEBUG, "Could not Validate nfs")do { do { if (0) printf ("Could not Validate nfs"); } while ( 0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3631, GF_LOG_DEBUG , "Could not Validate nfs"); } while (0); | |||||
3632 | goto out; | |||||
3633 | } | |||||
3634 | ||||||
3635 | ||||||
3636 | ret = validate_shdopts (volinfo, val_dict, op_errstr); | |||||
3637 | if (ret) { | |||||
3638 | gf_log ("", GF_LOG_DEBUG, "Could not Validate self-heald")do { do { if (0) printf ("Could not Validate self-heald"); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3638, GF_LOG_DEBUG , "Could not Validate self-heald"); } while (0); | |||||
3639 | goto out; | |||||
3640 | } | |||||
3641 | ||||||
3642 | ||||||
3643 | out: | |||||
3644 | gf_log ("", GF_LOG_DEBUG, "Returning %d", ret)do { do { if (0) printf ("Returning %d", ret); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__, 3644, GF_LOG_DEBUG, "Returning %d" , ret); } while (0); | |||||
3645 | return ret; | |||||
3646 | } | |||||
3647 | ||||||
3648 | uint32_t | |||||
3649 | glusterd_get_op_version_for_key (char *key) | |||||
3650 | { | |||||
3651 | char *completion = NULL((void*)0); | |||||
3652 | struct volopt_map_entry *vmep = NULL((void*)0); | |||||
3653 | int ret = 0; | |||||
3654 | ||||||
3655 | COMPLETE_OPTION(key, completion, ret)do { if (!strchr (key, '.')) { ret = option_complete (key, & completion); if (ret) { do { do { if (0) printf ("Out of memory" ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 3655, GF_LOG_ERROR, "Out of memory"); } while (0); return _gf_false ; } if (!completion) { do { do { if (0) printf ("option %s does not" "exist", key); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 3655, GF_LOG_ERROR, "option %s does not" "exist" , key); } while (0); return _gf_false; } } if (completion) __gf_free (completion); } while (0);; | |||||
3656 | for (vmep = glusterd_volopt_map; vmep->key; vmep++) { | |||||
3657 | if (strcmp (vmep->key, key) == 0) { | |||||
3658 | return vmep->op_version; | |||||
3659 | } | |||||
3660 | } | |||||
3661 | ||||||
3662 | return 0; | |||||
3663 | } | |||||
3664 | ||||||
3665 | gf_boolean_t | |||||
3666 | gd_is_client_option (char *key) | |||||
3667 | { | |||||
3668 | char *completion = NULL((void*)0); | |||||
3669 | struct volopt_map_entry *vmep = NULL((void*)0); | |||||
3670 | int ret = 0; | |||||
3671 | ||||||
3672 | COMPLETE_OPTION(key, completion, ret)do { if (!strchr (key, '.')) { ret = option_complete (key, & completion); if (ret) { do { do { if (0) printf ("Out of memory" ); } while (0); _gf_log ("", "glusterd-volgen.c", __FUNCTION__ , 3672, GF_LOG_ERROR, "Out of memory"); } while (0); return _gf_false ; } if (!completion) { do { do { if (0) printf ("option %s does not" "exist", key); } while (0); _gf_log ("", "glusterd-volgen.c" , __FUNCTION__, 3672, GF_LOG_ERROR, "option %s does not" "exist" , key); } while (0); return _gf_false; } } if (completion) __gf_free (completion); } while (0);; | |||||
3673 | for (vmep = glusterd_volopt_map; vmep->key; vmep++) { | |||||
3674 | if (strcmp (vmep->key, key) == 0) { | |||||
3675 | return vmep->client_option; | |||||
3676 | } | |||||
3677 | } | |||||
3678 | ||||||
3679 | return _gf_false; | |||||
3680 | } |