Bug Summary

File:xlators/cluster/afr/src/afr-self-heald.c
Location:line 1022, column 17
Description:Value stored to 'ret' is never read

Annotated Source Code

1/*
2 Copyright (c) 2008-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#include "afr.h"
16#include "syncop.h"
17#include "afr-self-heald.h"
18#include "afr-self-heal-common.h"
19#include "protocol-common.h"
20#include "event-history.h"
21
22typedef enum {
23 STOP_CRAWL_ON_SINGLE_SUBVOL = 1
24} afr_crawl_flags_t;
25
26typedef enum {
27 HEAL = 1,
28 INFO
29} shd_crawl_op;
30
31typedef struct shd_dump {
32 dict_t *dict;
33 xlator_t *this;
34 int child;
35} shd_dump_t;
36
37typedef struct shd_event_ {
38 int child;
39 char *path;
40} shd_event_t;
41
42typedef struct shd_pos_ {
43 int child;
44 xlator_t *this;
45 afr_child_pos_t pos;
46} shd_pos_t;
47
48typedef int
49(*afr_crawl_done_cbk_t) (int ret, call_frame_t *sync_frame, void *crawl_data);
50
51void
52afr_start_crawl (xlator_t *this, int idx, afr_crawl_type_t crawl,
53 process_entry_cbk_t process_entry, void *op_data,
54 gf_boolean_t exclusive, int crawl_flags,
55 afr_crawl_done_cbk_t crawl_done);
56
57static int
58_crawl_directory (fd_t *fd, loc_t *loc, afr_crawl_data_t *crawl_data);
59
60/* For calling straight through (e.g. already in a synctask). */
61int
62afr_find_child_position (xlator_t *this, int child, afr_child_pos_t *pos);
63
64/* For deferring through a new synctask. */
65int
66afr_syncop_find_child_position (void *data);
67
68static int
69_loc_assign_gfid_path (loc_t *loc)
70{
71 int ret = -1;
72 char gfid_path[64] = {0};
73
74 if (loc->inode && !uuid_is_null (loc->inode->gfid)) {
75 ret = inode_path (loc->inode, NULL((void*)0), (char**)&loc->path);
76 } else if (!uuid_is_null (loc->gfid)) {
77 snprintf (gfid_path, sizeof (gfid_path), "<gfid:%s>",
78 uuid_utoa (loc->gfid));
79 loc->path = gf_strdup (gfid_path);
80 if (loc->path)
81 ret = 0;
82 }
83 return ret;
84}
85
86void
87shd_cleanup_event (void *event)
88{
89 shd_event_t *shd_event = event;
90
91 if (!shd_event)
92 goto out;
93 GF_FREE (shd_event->path)__gf_free (shd_event->path);
94 GF_FREE (shd_event)__gf_free (shd_event);
95out:
96 return;
97}
98
99int
100afr_get_local_child (afr_self_heald_t *shd, unsigned int child_count)
101{
102 int i = 0;
103 int ret = -1;
104 for (i = 0; i < child_count; i++) {
105 if (shd->pos[i] == AFR_POS_LOCAL) {
106 ret = i;
107 break;
108 }
109 }
110 return ret;
111}
112
113static int
114_build_index_loc (xlator_t *this, loc_t *loc, char *name, loc_t *parent)
115{
116 int ret = 0;
117
118 uuid_copy (loc->pargfid, parent->inode->gfid);
119 loc->path = "";
120 loc->name = name;
121 loc->parent = inode_ref (parent->inode);
122 if (!loc->parent) {
123 loc->path = NULL((void*)0);
124 loc_wipe (loc);
125 ret = -1;
126 }
127 return ret;
128}
129
130int
131_add_path_to_dict (xlator_t *this, dict_t *output, int child, char *path,
132 struct timeval *tv, gf_boolean_t dyn)
133{
134 //subkey not used for now
135 int ret = -1;
136 uint64_t count = 0;
137 char key[256] = {0};
138 int xl_id = 0;
139
140 ret = dict_get_int32 (output, this->name, &xl_id);
141 if (ret) {
142 gf_log (this->name, GF_LOG_ERROR, "xl does not have id")do { do { if (0) printf ("xl does not have id"); } while (0);
_gf_log (this->name, "afr-self-heald.c", __FUNCTION__, 142
, GF_LOG_ERROR, "xl does not have id"); } while (0)
;
143 goto out;
144 }
145
146 snprintf (key, sizeof (key), "%d-%d-count", xl_id, child);
147 ret = dict_get_uint64 (output, key, &count);
148
149 snprintf (key, sizeof (key), "%d-%d-%"PRIu64"ll" "u", xl_id, child, count);
150 if (dyn)
151 ret = dict_set_dynstr (output, key, path);
152 else
153 ret = dict_set_str (output, key, path);
154 if (ret) {
155 gf_log (this->name, GF_LOG_ERROR, "%s: Could not add to output",do { do { if (0) printf ("%s: Could not add to output", path)
; } while (0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 156, GF_LOG_ERROR, "%s: Could not add to output", path); } while
(0)
156 path)do { do { if (0) printf ("%s: Could not add to output", path)
; } while (0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 156, GF_LOG_ERROR, "%s: Could not add to output", path); } while
(0)
;
157 goto out;
158 }
159
160 if (!tv)
161 goto inc_count;
162 snprintf (key, sizeof (key), "%d-%d-%"PRIu64"ll" "u""-time", xl_id,
163 child, count);
164 ret = dict_set_uint32 (output, key, tv->tv_sec);
165 if (ret) {
166 gf_log (this->name, GF_LOG_ERROR, "%s: Could not set time",do { do { if (0) printf ("%s: Could not set time", path); } while
(0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 167, GF_LOG_ERROR, "%s: Could not set time", path); } while
(0)
167 path)do { do { if (0) printf ("%s: Could not set time", path); } while
(0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 167, GF_LOG_ERROR, "%s: Could not set time", path); } while
(0)
;
168 goto out;
169 }
170
171inc_count:
172 snprintf (key, sizeof (key), "%d-%d-count", xl_id, child);
173 ret = dict_set_uint64 (output, key, count + 1);
174 if (ret) {
175 gf_log (this->name, GF_LOG_ERROR, "Could not increment count")do { do { if (0) printf ("Could not increment count"); } while
(0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 175, GF_LOG_ERROR, "Could not increment count"); } while (0
)
;
176 goto out;
177 }
178 ret = 0;
179out:
180 return ret;
181}
182
183int
184_get_path_from_gfid_loc (xlator_t *this, xlator_t *readdir_xl, loc_t *child,
185 char **fpath, gf_boolean_t *missing)
186{
187 dict_t *xattr = NULL((void*)0);
188 char *path = NULL((void*)0);
189 int ret = -1;
190
191 ret = syncop_getxattr (readdir_xl, child, &xattr, GFID_TO_PATH_KEY"glusterfs.gfid2path");
192 if (ret < 0) {
193 if ((errno(*__errno_location ()) == ENOENT2) && missing)
194 *missing = _gf_true;
195 goto out;
196 }
197 ret = dict_get_str (xattr, GFID_TO_PATH_KEY"glusterfs.gfid2path", &path);
198 if (ret) {
199 gf_log (this->name, GF_LOG_ERROR, "Failed to get path for "do { do { if (0) printf ("Failed to get path for " "gfid %s",
uuid_utoa (child->gfid)); } while (0); _gf_log (this->
name, "afr-self-heald.c", __FUNCTION__, 200, GF_LOG_ERROR, "Failed to get path for "
"gfid %s", uuid_utoa (child->gfid)); } while (0)
200 "gfid %s", uuid_utoa (child->gfid))do { do { if (0) printf ("Failed to get path for " "gfid %s",
uuid_utoa (child->gfid)); } while (0); _gf_log (this->
name, "afr-self-heald.c", __FUNCTION__, 200, GF_LOG_ERROR, "Failed to get path for "
"gfid %s", uuid_utoa (child->gfid)); } while (0)
;
201 goto out;
202 }
203 path = gf_strdup (path);
204 if (!path) {
205 ret = -1;
206 goto out;
207 }
208 ret = 0;
209out:
210 if (!ret)
211 *fpath = path;
212 if (xattr)
213 dict_unref (xattr);
214 return ret;
215}
216
217int
218_add_event_to_dict (circular_buffer_t *cb, void *data)
219{
220 int ret = 0;
221 shd_dump_t *dump_data = NULL((void*)0);
222 shd_event_t *shd_event = NULL((void*)0);
223
224 dump_data = data;
225 shd_event = cb->data;
226 if (shd_event->child != dump_data->child)
227 goto out;
228 ret = _add_path_to_dict (dump_data->this, dump_data->dict,
229 dump_data->child, shd_event->path, &cb->tv,
230 _gf_false);
231out:
232 return ret;
233}
234
235int
236_add_eh_to_dict (xlator_t *this, eh_t *eh, dict_t *dict, int child)
237{
238 shd_dump_t dump_data = {0};
239
240 dump_data.this = this;
241 dump_data.dict = dict;
242 dump_data.child = child;
243 eh_dump (eh, &dump_data, _add_event_to_dict);
244 return 0;
245}
246
247void
248_remove_stale_index (xlator_t *this, xlator_t *readdir_xl,
249 loc_t *parent, char *fname)
250{
251 int ret = 0;
252 loc_t index_loc = {0};
253
254 ret = _build_index_loc (this, &index_loc, fname, parent);
255 if (ret)
256 goto out;
257 gf_log (this->name, GF_LOG_DEBUG, "Removing stale index "do { do { if (0) printf ("Removing stale index " "for %s on %s"
, index_loc.name, readdir_xl->name); } while (0); _gf_log (
this->name, "afr-self-heald.c", __FUNCTION__, 258, GF_LOG_DEBUG
, "Removing stale index " "for %s on %s", index_loc.name, readdir_xl
->name); } while (0)
258 "for %s on %s", index_loc.name, readdir_xl->name)do { do { if (0) printf ("Removing stale index " "for %s on %s"
, index_loc.name, readdir_xl->name); } while (0); _gf_log (
this->name, "afr-self-heald.c", __FUNCTION__, 258, GF_LOG_DEBUG
, "Removing stale index " "for %s on %s", index_loc.name, readdir_xl
->name); } while (0)
;
259 ret = syncop_unlink (readdir_xl, &index_loc);
260 if(ret && (errno(*__errno_location ()) != ENOENT2)) {
261 gf_log(this->name, GF_LOG_ERROR, "%s: Failed to remove index "do { do { if (0) printf ("%s: Failed to remove index " "on %s - %s"
,index_loc.name, readdir_xl->name, strerror ((*__errno_location
()))); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 263, GF_LOG_ERROR, "%s: Failed to remove index "
"on %s - %s",index_loc.name, readdir_xl->name, strerror (
(*__errno_location ()))); } while (0)
262 "on %s - %s",index_loc.name, readdir_xl->name,do { do { if (0) printf ("%s: Failed to remove index " "on %s - %s"
,index_loc.name, readdir_xl->name, strerror ((*__errno_location
()))); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 263, GF_LOG_ERROR, "%s: Failed to remove index "
"on %s - %s",index_loc.name, readdir_xl->name, strerror (
(*__errno_location ()))); } while (0)
263 strerror (errno))do { do { if (0) printf ("%s: Failed to remove index " "on %s - %s"
,index_loc.name, readdir_xl->name, strerror ((*__errno_location
()))); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 263, GF_LOG_ERROR, "%s: Failed to remove index "
"on %s - %s",index_loc.name, readdir_xl->name, strerror (
(*__errno_location ()))); } while (0)
;
264 }
265 index_loc.path = NULL((void*)0);
266 loc_wipe (&index_loc);
267out:
268 return;
269}
270
271int
272_add_summary_to_dict (xlator_t *this, afr_crawl_data_t *crawl_data,
273 gf_dirent_t *entry,
274 loc_t *childloc, loc_t *parentloc, struct iatt *iattr)
275{
276 dict_t *output = NULL((void*)0);
277 xlator_t *readdir_xl = NULL((void*)0);
278 int ret = -1;
279 char *path = NULL((void*)0);
280 gf_boolean_t missing = _gf_false;
281 char gfid_str[64] = {0};
282
283 if (uuid_is_null (childloc->gfid))
284 goto out;
285
286 output = crawl_data->op_data;
287 readdir_xl = crawl_data->readdir_xl;
288
289 ret = _get_path_from_gfid_loc (this, readdir_xl, childloc, &path,
290 &missing);
291 if (ret == 0) {
292 ret = _add_path_to_dict (this, output, crawl_data->child, path,
293 NULL((void*)0), _gf_true);
294 } else if (missing) {
295 _remove_stale_index (this, readdir_xl, parentloc,
296 uuid_utoa_r (childloc->gfid, gfid_str));
297 }
298
299out:
300 if (ret && path)
301 GF_FREE (path)__gf_free (path);
302 return ret;
303}
304
305void
306_crawl_post_sh_action (xlator_t *this, loc_t *parent, loc_t *child,
307 int32_t op_ret, int32_t op_errno, dict_t *xattr_rsp,
308 afr_crawl_data_t *crawl_data)
309{
310 int ret = 0;
311 afr_private_t *priv = NULL((void*)0);
312 afr_self_heald_t *shd = NULL((void*)0);
313 eh_t *eh = NULL((void*)0);
314 char *path = NULL((void*)0);
315 char gfid_str[64] = {0};
316 shd_event_t *event = NULL((void*)0);
317 int32_t sh_failed = 0;
318 gf_boolean_t split_brain = 0;
319 int32_t actual_sh_done = 0;
320 priv = this->private;
321 shd = &priv->shd;
322 if (crawl_data->crawl == INDEX) {
323 if ((op_ret < 0) && (op_errno == ENOENT2)) {
324 _remove_stale_index (this, crawl_data->readdir_xl,
325 parent, uuid_utoa_r (child->gfid,
326 gfid_str));
327 goto out;
328 }
329 ret = _get_path_from_gfid_loc (this, crawl_data->readdir_xl,
330 child, &path, NULL((void*)0));
331 if (ret)
332 goto out;
333 } else {
334 path = gf_strdup (child->path);
335 if (!path) {
336 ret = -1;
337 goto out;
338 }
339 }
340
341 if (xattr_rsp) {
342 ret = dict_get_int32 (xattr_rsp, "sh-failed", &sh_failed);
343 ret = dict_get_int32 (xattr_rsp, "actual-sh-done", &actual_sh_done);
344 }
345
346 split_brain = afr_is_split_brain (this, child->inode);
347
348 if ((op_ret < 0 && op_errno == EIO5) || split_brain) {
349 eh = shd->split_brain;
350 } else if ((op_ret < 0) || sh_failed) {
351 eh = shd->heal_failed;
352 } else if (actual_sh_done == 1) {
353 eh = shd->healed;
354 }
355
356 ret = -1;
357
358 if (eh != NULL((void*)0)) {
359 event = GF_CALLOC (1, sizeof (*event), gf_afr_mt_shd_event_t)__gf_calloc (1, sizeof (*event), gf_afr_mt_shd_event_t);
360 if (!event)
361 goto out;
362 event->child = crawl_data->child;
363 event->path = path;
364
365 ret = eh_save_history (eh, event);
366 if (ret < 0) {
367 gf_log (this->name, GF_LOG_ERROR, "%s:Failed to save "do { do { if (0) printf ("%s:Failed to save " "to event history, (%d, %s)"
, path, op_ret, strerror (op_errno)); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 369, GF_LOG_ERROR
, "%s:Failed to save " "to event history, (%d, %s)", path, op_ret
, strerror (op_errno)); } while (0)
368 "to event history, (%d, %s)", path, op_ret,do { do { if (0) printf ("%s:Failed to save " "to event history, (%d, %s)"
, path, op_ret, strerror (op_errno)); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 369, GF_LOG_ERROR
, "%s:Failed to save " "to event history, (%d, %s)", path, op_ret
, strerror (op_errno)); } while (0)
369 strerror (op_errno))do { do { if (0) printf ("%s:Failed to save " "to event history, (%d, %s)"
, path, op_ret, strerror (op_errno)); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 369, GF_LOG_ERROR
, "%s:Failed to save " "to event history, (%d, %s)", path, op_ret
, strerror (op_errno)); } while (0)
;
370
371 goto out;
372 }
373 } else {
374 gf_log (this->name, GF_LOG_DEBUG, "%s:Self heal already done ",do { do { if (0) printf ("%s:Self heal already done ", path);
} while (0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 375, GF_LOG_DEBUG, "%s:Self heal already done ", path); } while
(0)
375 path)do { do { if (0) printf ("%s:Self heal already done ", path);
} while (0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 375, GF_LOG_DEBUG, "%s:Self heal already done ", path); } while
(0)
;
376
377 }
378 ret = 0;
379out:
380 if (ret && path)
381 GF_FREE (path)__gf_free (path);
382 return;
383}
384
385int
386_link_inode_update_loc (xlator_t *this, loc_t *loc, struct iatt *iattr)
387{
388 inode_t *link_inode = NULL((void*)0);
389 int ret = -1;
390
391 link_inode = inode_link (loc->inode, NULL((void*)0), NULL((void*)0), iattr);
392 if (link_inode == NULL((void*)0)) {
393 gf_log (this->name, GF_LOG_ERROR, "inode link failed "do { do { if (0) printf ("inode link failed " "on the inode (%s)"
, uuid_utoa (iattr->ia_gfid)); } while (0); _gf_log (this->
name, "afr-self-heald.c", __FUNCTION__, 394, GF_LOG_ERROR, "inode link failed "
"on the inode (%s)", uuid_utoa (iattr->ia_gfid)); } while
(0)
394 "on the inode (%s)", uuid_utoa (iattr->ia_gfid))do { do { if (0) printf ("inode link failed " "on the inode (%s)"
, uuid_utoa (iattr->ia_gfid)); } while (0); _gf_log (this->
name, "afr-self-heald.c", __FUNCTION__, 394, GF_LOG_ERROR, "inode link failed "
"on the inode (%s)", uuid_utoa (iattr->ia_gfid)); } while
(0)
;
395 goto out;
396 }
397 inode_unref (loc->inode);
398 loc->inode = link_inode;
399 ret = 0;
400out:
401 return ret;
402}
403
404int
405_self_heal_entry (xlator_t *this, afr_crawl_data_t *crawl_data, gf_dirent_t *entry,
406 loc_t *child, loc_t *parent, struct iatt *iattr)
407{
408 struct iatt parentbuf = {0};
409 int ret = 0;
410 dict_t *xattr_rsp = NULL((void*)0);
411
412 gf_log (this->name, GF_LOG_DEBUG, "lookup %s", child->path)do { do { if (0) printf ("lookup %s", child->path); } while
(0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 412, GF_LOG_DEBUG, "lookup %s", child->path); } while (0
)
;
413
414 ret = syncop_lookup (this, child, NULL((void*)0),
415 iattr, &xattr_rsp, &parentbuf);
416 _crawl_post_sh_action (this, parent, child, ret, errno(*__errno_location ()), xattr_rsp,
417 crawl_data);
418 if (xattr_rsp)
419 dict_unref (xattr_rsp);
420 if (ret == 0)
421 ret = _link_inode_update_loc (this, child, iattr);
422
423 return ret;
424}
425
426static int
427afr_crawl_done (int ret, call_frame_t *sync_frame, void *data)
428{
429 GF_FREE (data)__gf_free (data);
430 STACK_DESTROY (sync_frame->root);
431 return 0;
432}
433
434void
435_do_self_heal_on_subvol (xlator_t *this, int child, afr_crawl_type_t crawl)
436{
437 afr_start_crawl (this, child, crawl, _self_heal_entry,
438 NULL((void*)0), _gf_true, STOP_CRAWL_ON_SINGLE_SUBVOL,
439 afr_crawl_done);
440}
441
442gf_boolean_t
443_crawl_proceed (xlator_t *this, int child, int crawl_flags, char **reason)
444{
445 afr_private_t *priv = NULL((void*)0);
446 afr_self_heald_t *shd = NULL((void*)0);
447 gf_boolean_t proceed = _gf_false;
448 char *msg = NULL((void*)0);
449
450 priv = this->private;
451 shd = &priv->shd;
452 if (!shd->enabled) {
453 msg = "Self-heal daemon is not enabled";
454 gf_log (this->name, GF_LOG_DEBUG, "%s", msg)do { do { if (0) printf ("%s", msg); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 454, GF_LOG_DEBUG
, "%s", msg); } while (0)
;
455 goto out;
456 }
457 if (!priv->child_up[child]) {
458 gf_log (this->name, GF_LOG_DEBUG, "Stopping crawl for %s , "do { do { if (0) printf ("Stopping crawl for %s , " "subvol went down"
, priv->children[child]->name); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 459, GF_LOG_DEBUG
, "Stopping crawl for %s , " "subvol went down", priv->children
[child]->name); } while (0)
459 "subvol went down", priv->children[child]->name)do { do { if (0) printf ("Stopping crawl for %s , " "subvol went down"
, priv->children[child]->name); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 459, GF_LOG_DEBUG
, "Stopping crawl for %s , " "subvol went down", priv->children
[child]->name); } while (0)
;
460 msg = "Brick is Not connected";
461 goto out;
462 }
463
464 if (crawl_flags & STOP_CRAWL_ON_SINGLE_SUBVOL) {
465 if (afr_up_children_count (priv->child_up,
466 priv->child_count) < 2) {
467 gf_log (this->name, GF_LOG_DEBUG, "Stopping crawl as "do { do { if (0) printf ("Stopping crawl as " "< 2 children are up"
); } while (0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 468, GF_LOG_DEBUG, "Stopping crawl as " "< 2 children are up"
); } while (0)
468 "< 2 children are up")do { do { if (0) printf ("Stopping crawl as " "< 2 children are up"
); } while (0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 468, GF_LOG_DEBUG, "Stopping crawl as " "< 2 children are up"
); } while (0)
;
469 msg = "< 2 bricks in replica are running";
470 goto out;
471 }
472 }
473 proceed = _gf_true;
474out:
475 if (reason)
476 *reason = msg;
477 return proceed;
478}
479
480int
481_do_crawl_op_on_local_subvols (xlator_t *this, afr_crawl_type_t crawl,
482 shd_crawl_op op, dict_t *output)
483{
484 afr_private_t *priv = NULL((void*)0);
485 char *status = NULL((void*)0);
486 char *subkey = NULL((void*)0);
487 char key[256] = {0};
488 shd_pos_t pos_data = {0};
489 int op_ret = -1;
490 int xl_id = -1;
491 int i = 0;
492 int ret = 0;
493 int crawl_flags = 0;
494
495 priv = this->private;
496 if (op == HEAL)
497 crawl_flags |= STOP_CRAWL_ON_SINGLE_SUBVOL;
498
499 if (output) {
500 ret = dict_get_int32 (output, this->name, &xl_id);
501 if (ret) {
502 gf_log (this->name, GF_LOG_ERROR, "Invalid input, "do { do { if (0) printf ("Invalid input, " "translator-id is not available"
); } while (0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 503, GF_LOG_ERROR, "Invalid input, " "translator-id is not available"
); } while (0)
503 "translator-id is not available")do { do { if (0) printf ("Invalid input, " "translator-id is not available"
); } while (0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 503, GF_LOG_ERROR, "Invalid input, " "translator-id is not available"
); } while (0)
;
504 goto out;
505 }
506 }
507 pos_data.this = this;
508 subkey = "status";
509 for (i = 0; i < priv->child_count; i++) {
510 if (_crawl_proceed (this, i, crawl_flags, &status)) {
511 pos_data.child = i;
512 /*
513 * We're already in a synctask in this case, so we
514 * don't need to defer through a second (and in fact
515 * that can cause deadlock). Just call straight
516 * through instead.
517 */
518 ret = afr_find_child_position(pos_data.this,
519 pos_data.child,
520 &pos_data.pos);
521 if (ret) {
522 status = "Not able to find brick location";
523 } else if (pos_data.pos == AFR_POS_REMOTE) {
524 status = "brick is remote";
525 } else {
526 op_ret = 0;
527 if (op == HEAL) {
528 status = "Started self-heal";
529 _do_self_heal_on_subvol (this, i,
530 crawl);
531 } else if (output) {
532 status = "";
533 afr_start_crawl (this, i, INDEX,
534 _add_summary_to_dict,
535 output, _gf_false, 0,
536 NULL((void*)0));
537 }
538 }
539 if (output) {
540 snprintf (key, sizeof (key), "%d-%d-%s", xl_id,
541 i, subkey);
542 ret = dict_set_str (output, key, status);
543 }
544 if (!op_ret && (crawl == FULL))
545 break;
546 }
547 if (output) {
548 snprintf (key, sizeof (key), "%d-%d-%s", xl_id, i,
549 subkey);
550 ret = dict_set_str (output, key, status);
551 }
552 }
553out:
554 return op_ret;
555}
556
557int
558_do_self_heal_on_local_subvols (xlator_t *this, afr_crawl_type_t crawl,
559 dict_t *output)
560{
561 return _do_crawl_op_on_local_subvols (this, crawl, HEAL, output);
562}
563
564int
565_get_index_summary_on_local_subvols (xlator_t *this, dict_t *output)
566{
567 return _do_crawl_op_on_local_subvols (this, INDEX, INFO, output);
568}
569
570int
571_add_all_subvols_eh_to_dict (xlator_t *this, eh_t *eh, dict_t *dict)
572{
573 afr_private_t *priv = NULL((void*)0);
574 afr_self_heald_t *shd = NULL((void*)0);
575 int i = 0;
576
577 priv = this->private;
578 shd = &priv->shd;
579
580 for (i = 0; i < priv->child_count; i++) {
581 if (shd->pos[i] != AFR_POS_LOCAL)
582 continue;
583 _add_eh_to_dict (this, eh, dict, i);
584 }
585 return 0;
586}
587
588int
589afr_xl_op (xlator_t *this, dict_t *input, dict_t *output)
590{
591 gf_xl_afr_op_t op = GF_AFR_OP_INVALID;
592 int ret = 0;
593 afr_private_t *priv = NULL((void*)0);
594 afr_self_heald_t *shd = NULL((void*)0);
595 int xl_id = 0;
596
597 priv = this->private;
598 shd = &priv->shd;
599
600 ret = dict_get_int32 (input, "xl-op", (int32_t*)&op);
601 if (ret)
602 goto out;
603 ret = dict_get_int32 (input, this->name, &xl_id);
604 if (ret)
605 goto out;
606 ret = dict_set_int32 (output, this->name, xl_id);
607 if (ret)
608 goto out;
609 switch (op) {
610 case GF_AFR_OP_HEAL_INDEX:
611 ret = _do_self_heal_on_local_subvols (this, INDEX, output);
612 break;
613 case GF_AFR_OP_HEAL_FULL:
614 ret = _do_self_heal_on_local_subvols (this, FULL, output);
615 break;
616 case GF_AFR_OP_INDEX_SUMMARY:
617 (void)_get_index_summary_on_local_subvols (this, output);
618 ret = 0;
619 break;
620 case GF_AFR_OP_HEALED_FILES:
621 ret = _add_all_subvols_eh_to_dict (this, shd->healed, output);
622 break;
623 case GF_AFR_OP_HEAL_FAILED_FILES:
624 ret = _add_all_subvols_eh_to_dict (this, shd->heal_failed,
625 output);
626 break;
627 case GF_AFR_OP_SPLIT_BRAIN_FILES:
628 ret = _add_all_subvols_eh_to_dict (this, shd->split_brain,
629 output);
630 break;
631 default:
632 gf_log (this->name, GF_LOG_ERROR, "Unknown set op %d", op)do { do { if (0) printf ("Unknown set op %d", op); } while (0
); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__, 632
, GF_LOG_ERROR, "Unknown set op %d", op); } while (0)
;
633 break;
634 }
635out:
636 dict_del (output, this->name);
637 return ret;
638}
639
640void
641afr_poll_self_heal (void *data)
642{
643 afr_private_t *priv = NULL((void*)0);
644 afr_self_heald_t *shd = NULL((void*)0);
645 struct timeval timeout = {0};
646 xlator_t *this = NULL((void*)0);
647 long child = (long)data;
648 gf_timer_t *old_timer = NULL((void*)0);
649 gf_timer_t *new_timer = NULL((void*)0);
650 shd_pos_t pos_data = {0};
651 int ret = 0;
652
653 this = THIS(*__glusterfs_this_location());
654 priv = this->private;
655 shd = &priv->shd;
656
657 if (shd->pos[child] == AFR_POS_UNKNOWN) {
658 pos_data.this = this;
659 pos_data.child = child;
660 ret = synctask_new (this->ctx->env,
661 afr_syncop_find_child_position,
662 NULL((void*)0), NULL((void*)0), &pos_data);
663 if (!ret)
664 shd->pos[child] = pos_data.pos;
665 }
666 if (shd->enabled && (shd->pos[child] == AFR_POS_LOCAL))
667 _do_self_heal_on_subvol (this, child, INDEX);
668 timeout.tv_sec = shd->timeout;
669 timeout.tv_usec = 0;
670 //notify and previous timer should be synchronized.
671 LOCK (&priv->lock)pthread_spin_lock (&priv->lock);
672 {
673 old_timer = shd->timer[child];
674 if (shd->pos[child] == AFR_POS_REMOTE)
675 goto unlock;
676 shd->timer[child] = gf_timer_call_after (this->ctx, timeout,
677 afr_poll_self_heal,
678 data);
679 new_timer = shd->timer[child];
680 }
681unlock:
682 UNLOCK (&priv->lock)pthread_spin_unlock (&priv->lock);
683
684 if (old_timer)
685 gf_timer_call_cancel (this->ctx, old_timer);
686 if (!new_timer && (shd->pos[child] != AFR_POS_REMOTE)) {
687 gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("Could not create self-heal polling timer for %s"
, priv->children[child]->name); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 689, GF_LOG_WARNING
, "Could not create self-heal polling timer for %s", priv->
children[child]->name); } while (0)
688 "Could not create self-heal polling timer for %s",do { do { if (0) printf ("Could not create self-heal polling timer for %s"
, priv->children[child]->name); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 689, GF_LOG_WARNING
, "Could not create self-heal polling timer for %s", priv->
children[child]->name); } while (0)
689 priv->children[child]->name)do { do { if (0) printf ("Could not create self-heal polling timer for %s"
, priv->children[child]->name); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 689, GF_LOG_WARNING
, "Could not create self-heal polling timer for %s", priv->
children[child]->name); } while (0)
;
690 }
691 return;
692}
693
694static int
695afr_handle_child_up (int ret, call_frame_t *sync_frame, void *data)
696{
697 afr_self_heald_t *shd = NULL((void*)0);
698 shd_pos_t *pos_data = data;
699 afr_private_t *priv = NULL((void*)0);
700
701 if (ret)
702 goto out;
703
704 priv = pos_data->this->private;
705 shd = &priv->shd;
706 shd->pos[pos_data->child] = pos_data->pos;
707 if (pos_data->pos != AFR_POS_REMOTE)
708 afr_poll_self_heal ((void*)(long)pos_data->child);
709 _do_self_heal_on_local_subvols (THIS(*__glusterfs_this_location()), INDEX, NULL((void*)0));
710out:
711 GF_FREE (data)__gf_free (data);
712 return 0;
713}
714
715void
716afr_proactive_self_heal (void *data)
717{
718 xlator_t *this = NULL((void*)0);
719 long child = (long)data;
720 shd_pos_t *pos_data = NULL((void*)0);
721 int ret = 0;
722
723 this = THIS(*__glusterfs_this_location());
724
725 //Position of brick could have changed and it could be local now.
726 //Compute the position again
727 pos_data = GF_CALLOC (1, sizeof (*pos_data), gf_afr_mt_pos_data_t)__gf_calloc (1, sizeof (*pos_data), gf_afr_mt_pos_data_t);
728 if (!pos_data)
729 goto out;
730 pos_data->this = this;
731 pos_data->child = child;
732 ret = synctask_new (this->ctx->env, afr_syncop_find_child_position,
733 afr_handle_child_up, NULL((void*)0), pos_data);
734 if (ret)
735 goto out;
736out:
737 return;
738}
739
740static int
741get_pathinfo_host (char *pathinfo, char *hostname, size_t size)
742{
743 char *start = NULL((void*)0);
744 char *end = NULL((void*)0);
745 int ret = -1;
746 int i = 0;
747
748 if (!pathinfo)
749 goto out;
750
751 start = strchr (pathinfo, ':');
752 if (!start)
753 goto out;
754 end = strrchr (pathinfo, ':');
755 if (start == end)
756 goto out;
757
758 memset (hostname, 0, size);
759 i = 0;
760 while (++start != end)
761 hostname[i++] = *start;
762 ret = 0;
763out:
764 return ret;
765}
766
767int
768afr_local_pathinfo (char *pathinfo, gf_boolean_t *local)
769{
770 int ret = 0;
771 char pathinfohost[1024] = {0};
772 char localhost[1024] = {0};
773 xlator_t *this = THIS(*__glusterfs_this_location());
774
775 *local = _gf_false;
776 ret = get_pathinfo_host (pathinfo, pathinfohost, sizeof (pathinfohost));
777 if (ret) {
778 gf_log (this->name, GF_LOG_ERROR, "Invalid pathinfo: %s",do { do { if (0) printf ("Invalid pathinfo: %s", pathinfo); }
while (0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 779, GF_LOG_ERROR, "Invalid pathinfo: %s", pathinfo); } while
(0)
779 pathinfo)do { do { if (0) printf ("Invalid pathinfo: %s", pathinfo); }
while (0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 779, GF_LOG_ERROR, "Invalid pathinfo: %s", pathinfo); } while
(0)
;
780 goto out;
781 }
782
783 ret = gethostname (localhost, sizeof (localhost));
784 if (ret) {
785 gf_log (this->name, GF_LOG_ERROR, "gethostname() failed, "do { do { if (0) printf ("gethostname() failed, " "reason: %s"
, strerror ((*__errno_location ()))); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 786, GF_LOG_ERROR
, "gethostname() failed, " "reason: %s", strerror ((*__errno_location
()))); } while (0)
786 "reason: %s", strerror (errno))do { do { if (0) printf ("gethostname() failed, " "reason: %s"
, strerror ((*__errno_location ()))); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 786, GF_LOG_ERROR
, "gethostname() failed, " "reason: %s", strerror ((*__errno_location
()))); } while (0)
;
787 goto out;
788 }
789
790 if (!strcmp (localhost, pathinfohost))
791 *local = _gf_true;
792out:
793 return ret;
794}
795
796int
797afr_crawl_build_start_loc (xlator_t *this, afr_crawl_data_t *crawl_data,
798 loc_t *dirloc)
799{
800 afr_private_t *priv = NULL((void*)0);
801 dict_t *xattr = NULL((void*)0);
802 void *index_gfid = NULL((void*)0);
803 loc_t rootloc = {0};
804 struct iatt iattr = {0};
805 struct iatt parent = {0};
806 int ret = 0;
807 xlator_t *readdir_xl = crawl_data->readdir_xl;
808
809 priv = this->private;
810 if (crawl_data->crawl == FULL) {
811 afr_build_root_loc (this, dirloc);
812 } else {
813 afr_build_root_loc (this, &rootloc);
814 ret = syncop_getxattr (readdir_xl, &rootloc, &xattr,
815 GF_XATTROP_INDEX_GFID"glusterfs.xattrop_index_gfid");
816 if (ret < 0)
817 goto out;
818 ret = dict_get_ptr (xattr, GF_XATTROP_INDEX_GFID"glusterfs.xattrop_index_gfid", &index_gfid);
819 if (ret < 0) {
820 gf_log (this->name, GF_LOG_ERROR, "failed to get index "do { do { if (0) printf ("failed to get index " "dir gfid on %s"
, readdir_xl->name); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 821, GF_LOG_ERROR, "failed to get index " "dir gfid on %s"
, readdir_xl->name); } while (0)
821 "dir gfid on %s", readdir_xl->name)do { do { if (0) printf ("failed to get index " "dir gfid on %s"
, readdir_xl->name); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 821, GF_LOG_ERROR, "failed to get index " "dir gfid on %s"
, readdir_xl->name); } while (0)
;
822 goto out;
823 }
824 if (!index_gfid) {
825 gf_log (this->name, GF_LOG_ERROR, "index gfid empty "do { do { if (0) printf ("index gfid empty " "on %s", readdir_xl
->name); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 826, GF_LOG_ERROR, "index gfid empty " "on %s"
, readdir_xl->name); } while (0)
826 "on %s", readdir_xl->name)do { do { if (0) printf ("index gfid empty " "on %s", readdir_xl
->name); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 826, GF_LOG_ERROR, "index gfid empty " "on %s"
, readdir_xl->name); } while (0)
;
827 ret = -1;
828 goto out;
829 }
830 uuid_copy (dirloc->gfid, index_gfid);
831 dirloc->path = "";
832 dirloc->inode = inode_new (priv->root_inode->table);
833 ret = syncop_lookup (readdir_xl, dirloc, NULL((void*)0),
834 &iattr, NULL((void*)0), &parent);
835 if (ret < 0) {
836 if (errno(*__errno_location ()) != ENOENT2) {
837 gf_log (this->name, GF_LOG_ERROR, "lookup "do { do { if (0) printf ("lookup " "failed on index dir on %s - (%s)"
, readdir_xl->name, strerror ((*__errno_location ()))); } while
(0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 839, GF_LOG_ERROR, "lookup " "failed on index dir on %s - (%s)"
, readdir_xl->name, strerror ((*__errno_location ()))); } while
(0)
838 "failed on index dir on %s - (%s)",do { do { if (0) printf ("lookup " "failed on index dir on %s - (%s)"
, readdir_xl->name, strerror ((*__errno_location ()))); } while
(0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 839, GF_LOG_ERROR, "lookup " "failed on index dir on %s - (%s)"
, readdir_xl->name, strerror ((*__errno_location ()))); } while
(0)
839 readdir_xl->name, strerror (errno))do { do { if (0) printf ("lookup " "failed on index dir on %s - (%s)"
, readdir_xl->name, strerror ((*__errno_location ()))); } while
(0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 839, GF_LOG_ERROR, "lookup " "failed on index dir on %s - (%s)"
, readdir_xl->name, strerror ((*__errno_location ()))); } while
(0)
;
840 }
841 goto out;
842 }
843 ret = _link_inode_update_loc (this, dirloc, &iattr);
844 if (ret)
845 goto out;
846 }
847 ret = 0;
848out:
849 if (xattr)
850 dict_unref (xattr);
851 loc_wipe (&rootloc);
852 return ret;
853}
854
855int
856afr_crawl_opendir (xlator_t *this, afr_crawl_data_t *crawl_data, fd_t **dirfd,
857 loc_t *dirloc)
858{
859 fd_t *fd = NULL((void*)0);
860 int ret = 0;
861
862 if (crawl_data->crawl == FULL) {
863 fd = fd_create (dirloc->inode, crawl_data->pid);
864 if (!fd) {
865 gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("Failed to create fd for %s", dirloc
->path); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 866, GF_LOG_ERROR, "Failed to create fd for %s"
, dirloc->path); } while (0)
866 "Failed to create fd for %s", dirloc->path)do { do { if (0) printf ("Failed to create fd for %s", dirloc
->path); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 866, GF_LOG_ERROR, "Failed to create fd for %s"
, dirloc->path); } while (0)
;
867 ret = -1;
868 goto out;
869 }
870
871 ret = syncop_opendir (crawl_data->readdir_xl, dirloc, fd);
872 if (ret < 0) {
873 gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("opendir failed on %s", dirloc->path
); } while (0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 874, GF_LOG_ERROR, "opendir failed on %s", dirloc->path)
; } while (0)
874 "opendir failed on %s", dirloc->path)do { do { if (0) printf ("opendir failed on %s", dirloc->path
); } while (0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 874, GF_LOG_ERROR, "opendir failed on %s", dirloc->path)
; } while (0)
;
875 goto out;
876 }
877 } else {
878 fd = fd_anonymous (dirloc->inode);
879 }
880 ret = 0;
881out:
882 if (!ret)
883 *dirfd = fd;
884 return ret;
885}
886
887xlator_t*
888afr_crawl_readdir_xl_get (xlator_t *this, afr_crawl_data_t *crawl_data)
889{
890 afr_private_t *priv = this->private;
891
892 if (crawl_data->crawl == FULL) {
893 return this;
894 } else {
895 return priv->children[crawl_data->child];
896 }
897 return NULL((void*)0);
898}
899
900int
901afr_crawl_build_child_loc (xlator_t *this, loc_t *child, loc_t *parent,
902 gf_dirent_t *entry, afr_crawl_data_t *crawl_data)
903{
904 int ret = -1;
905 afr_private_t *priv = NULL((void*)0);
906
907 priv = this->private;
908 if (crawl_data->crawl == FULL) {
909 ret = afr_build_child_loc (this, child, parent, entry->d_name);
910 } else {
911 child->inode = inode_new (priv->root_inode->table);
912 if (!child->inode)
913 goto out;
914 uuid_parse (entry->d_name, child->gfid);
915 ret = _loc_assign_gfid_path (child);
916 }
917out:
918 return ret;
919}
920
921static int
922_process_entries (xlator_t *this, loc_t *parentloc, gf_dirent_t *entries,
923 off_t *offset, afr_crawl_data_t *crawl_data)
924{
925 gf_dirent_t *entry = NULL((void*)0);
926 gf_dirent_t *tmp = NULL((void*)0);
927 int ret = 0;
928 loc_t entry_loc = {0};
929 fd_t *fd = NULL((void*)0);
930 struct iatt iattr = {0};
931
932 list_for_each_entry_safe (entry, tmp, &entries->list, list)for (entry = ((typeof(*entry) *)((char *)((&entries->list
)->next)-(unsigned long)(&((typeof(*entry) *)0)->list
))), tmp = ((typeof(*entry) *)((char *)(entry->list.next)-
(unsigned long)(&((typeof(*entry) *)0)->list))); &
entry->list != (&entries->list); entry = tmp, tmp =
((typeof(*tmp) *)((char *)(tmp->list.next)-(unsigned long
)(&((typeof(*tmp) *)0)->list))))
{
933 if (!_crawl_proceed (this, crawl_data->child,
934 crawl_data->crawl_flags, NULL((void*)0))) {
935 ret = -1;
936 goto out;
937 }
938 *offset = entry->d_off;
939 if (IS_ENTRY_CWD (entry->d_name)(!strcmp (entry->d_name, ".")) ||
940 IS_ENTRY_PARENT (entry->d_name)(!strcmp (entry->d_name, "..")))
941 continue;
942 if ((crawl_data->crawl == FULL) &&
943 uuid_is_null (entry->d_stat.ia_gfid)) {
944 gf_log (this->name, GF_LOG_WARNING, "%s/%s: No "do { do { if (0) printf ("%s/%s: No " "gfid present skipping"
, parentloc->path, entry->d_name); } while (0); _gf_log
(this->name, "afr-self-heald.c", __FUNCTION__, 946, GF_LOG_WARNING
, "%s/%s: No " "gfid present skipping", parentloc->path, entry
->d_name); } while (0)
945 "gfid present skipping",do { do { if (0) printf ("%s/%s: No " "gfid present skipping"
, parentloc->path, entry->d_name); } while (0); _gf_log
(this->name, "afr-self-heald.c", __FUNCTION__, 946, GF_LOG_WARNING
, "%s/%s: No " "gfid present skipping", parentloc->path, entry
->d_name); } while (0)
946 parentloc->path, entry->d_name)do { do { if (0) printf ("%s/%s: No " "gfid present skipping"
, parentloc->path, entry->d_name); } while (0); _gf_log
(this->name, "afr-self-heald.c", __FUNCTION__, 946, GF_LOG_WARNING
, "%s/%s: No " "gfid present skipping", parentloc->path, entry
->d_name); } while (0)
;
947 continue;
948 }
949
950 loc_wipe (&entry_loc);
951 ret = afr_crawl_build_child_loc (this, &entry_loc, parentloc,
952 entry, crawl_data);
953 if (ret)
954 goto out;
955
956 ret = crawl_data->process_entry (this, crawl_data, entry,
957 &entry_loc, parentloc, &iattr);
958
959 if (ret)
960 continue;
961
962 if (crawl_data->crawl == INDEX)
963 continue;
964
965 if (!IA_ISDIR (iattr.ia_type)(iattr.ia_type == IA_IFDIR))
966 continue;
967 fd = NULL((void*)0);
968 ret = afr_crawl_opendir (this, crawl_data, &fd, &entry_loc);
969 if (ret)
970 continue;
971 ret = _crawl_directory (fd, &entry_loc, crawl_data);
972 if (fd)
973 fd_unref (fd);
974 }
975 ret = 0;
976out:
977 loc_wipe (&entry_loc);
978 return ret;
979}
980
981static int
982_crawl_directory (fd_t *fd, loc_t *loc, afr_crawl_data_t *crawl_data)
983{
984 xlator_t *this = NULL((void*)0);
985 off_t offset = 0;
986 gf_dirent_t entries;
987 int ret = 0;
988 gf_boolean_t free_entries = _gf_false;
989 xlator_t *readdir_xl = crawl_data->readdir_xl;
990
991 INIT_LIST_HEAD (&entries.list)do { (&entries.list)->next = (&entries.list)->prev
= &entries.list; } while (0)
;
992 this = THIS(*__glusterfs_this_location());
993
994 GF_ASSERT (loc->inode)do { if (!(loc->inode)) { do { do { if (0) printf ("Assertion failed: "
"loc->inode"); } while (0); _gf_log_callingfn ("", "afr-self-heald.c"
, __FUNCTION__, 994, GF_LOG_ERROR, "Assertion failed: " "loc->inode"
); } while (0); } } while (0)
;
995
996 if (crawl_data->crawl == FULL)
997 gf_log (this->name, GF_LOG_DEBUG, "crawling %s", loc->path)do { do { if (0) printf ("crawling %s", loc->path); } while
(0); _gf_log (this->name, "afr-self-heald.c", __FUNCTION__
, 997, GF_LOG_DEBUG, "crawling %s", loc->path); } while (0
)
;
998 else
999 gf_log (this->name, GF_LOG_DEBUG, "crawling INDEX %s",do { do { if (0) printf ("crawling INDEX %s", uuid_utoa (loc->
gfid)); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 1000, GF_LOG_DEBUG, "crawling INDEX %s", uuid_utoa
(loc->gfid)); } while (0)
1000 uuid_utoa (loc->gfid))do { do { if (0) printf ("crawling INDEX %s", uuid_utoa (loc->
gfid)); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 1000, GF_LOG_DEBUG, "crawling INDEX %s", uuid_utoa
(loc->gfid)); } while (0)
;
1001
1002 while (1) {
1003 if (crawl_data->crawl == FULL)
1004 ret = syncop_readdirp (readdir_xl, fd, 131072, offset,
1005 NULL((void*)0), &entries);
1006 else
1007 ret = syncop_readdir (readdir_xl, fd, 131072, offset,
1008 &entries);
1009 if (ret <= 0)
1010 break;
1011 ret = 0;
1012 free_entries = _gf_true;
1013
1014 if (!_crawl_proceed (this, crawl_data->child,
1015 crawl_data->crawl_flags, NULL((void*)0))) {
1016 ret = -1;
1017 goto out;
1018 }
1019 if (list_empty (&entries.list))
1020 goto out;
1021
1022 ret = _process_entries (this, loc, &entries, &offset,
Value stored to 'ret' is never read
1023 crawl_data);
1024 gf_dirent_free (&entries);
1025 free_entries = _gf_false;
1026 }
1027 ret = 0;
1028out:
1029 if (free_entries)
1030 gf_dirent_free (&entries);
1031 return ret;
1032}
1033
1034static char*
1035position_str_get (afr_child_pos_t pos)
1036{
1037 switch (pos) {
1038 case AFR_POS_UNKNOWN:
1039 return "unknown";
1040 case AFR_POS_LOCAL:
1041 return "local";
1042 case AFR_POS_REMOTE:
1043 return "remote";
1044 }
1045 return NULL((void*)0);
1046}
1047
1048int
1049afr_find_child_position (xlator_t *this, int child, afr_child_pos_t *pos)
1050{
1051 afr_private_t *priv = NULL((void*)0);
1052 afr_self_heald_t *shd = NULL((void*)0);
1053 dict_t *xattr_rsp = NULL((void*)0);
1054 loc_t loc = {0};
1055 int ret = 0;
1056 char *node_uuid = NULL((void*)0);
1057
1058 priv = this->private;
1059 shd = &priv->shd;
1060
1061 afr_build_root_loc (this, &loc);
1062
1063 ret = syncop_getxattr (priv->children[child], &loc, &xattr_rsp,
1064 GF_XATTR_NODE_UUID_KEY"trusted.glusterfs.node-uuid");
1065 if (ret < 0) {
1066 gf_log (this->name, GF_LOG_ERROR, "getxattr failed on %s - "do { do { if (0) printf ("getxattr failed on %s - " "(%s)", priv
->children[child]->name, strerror ((*__errno_location (
)))); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 1067, GF_LOG_ERROR, "getxattr failed on %s - "
"(%s)", priv->children[child]->name, strerror ((*__errno_location
()))); } while (0)
1067 "(%s)", priv->children[child]->name, strerror (errno))do { do { if (0) printf ("getxattr failed on %s - " "(%s)", priv
->children[child]->name, strerror ((*__errno_location (
)))); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 1067, GF_LOG_ERROR, "getxattr failed on %s - "
"(%s)", priv->children[child]->name, strerror ((*__errno_location
()))); } while (0)
;
1068 goto out;
1069 }
1070
1071 ret = dict_get_str (xattr_rsp, GF_XATTR_NODE_UUID_KEY"trusted.glusterfs.node-uuid", &node_uuid);
1072 if (ret) {
1073 gf_log (this->name, GF_LOG_ERROR, "node-uuid key not found on "do { do { if (0) printf ("node-uuid key not found on " "child %s"
, priv->children[child]->name); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 1074, GF_LOG_ERROR
, "node-uuid key not found on " "child %s", priv->children
[child]->name); } while (0)
1074 "child %s", priv->children[child]->name)do { do { if (0) printf ("node-uuid key not found on " "child %s"
, priv->children[child]->name); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 1074, GF_LOG_ERROR
, "node-uuid key not found on " "child %s", priv->children
[child]->name); } while (0)
;
1075 goto out;
1076 }
1077
1078 if (!strcmp (node_uuid, shd->node_uuid))
1079 *pos = AFR_POS_LOCAL;
1080 else
1081 *pos = AFR_POS_REMOTE;
1082
1083 gf_log (this->name, GF_LOG_DEBUG, "child %s is %s",do { do { if (0) printf ("child %s is %s", priv->children[
child]->name, position_str_get (*pos)); } while (0); _gf_log
(this->name, "afr-self-heald.c", __FUNCTION__, 1084, GF_LOG_DEBUG
, "child %s is %s", priv->children[child]->name, position_str_get
(*pos)); } while (0)
1084 priv->children[child]->name, position_str_get (*pos))do { do { if (0) printf ("child %s is %s", priv->children[
child]->name, position_str_get (*pos)); } while (0); _gf_log
(this->name, "afr-self-heald.c", __FUNCTION__, 1084, GF_LOG_DEBUG
, "child %s is %s", priv->children[child]->name, position_str_get
(*pos)); } while (0)
;
1085out:
1086 if (ret)
1087 *pos = AFR_POS_UNKNOWN;
1088 loc_wipe (&loc);
1089 return ret;
1090}
1091
1092int
1093afr_syncop_find_child_position (void *data)
1094{
1095 shd_pos_t *pos_data = data;
1096 int ret = 0;
1097
1098 ret = afr_find_child_position (pos_data->this, pos_data->child,
1099 &pos_data->pos);
1100 return ret;
1101}
1102
1103static int
1104afr_dir_crawl (void *data)
1105{
1106 xlator_t *this = NULL((void*)0);
1107 int ret = -1;
1108 xlator_t *readdir_xl = NULL((void*)0);
1109 fd_t *fd = NULL((void*)0);
1110 loc_t dirloc = {0};
1111 afr_crawl_data_t *crawl_data = data;
1112
1113 this = THIS(*__glusterfs_this_location());
1114
1115 if (!_crawl_proceed (this, crawl_data->child, crawl_data->crawl_flags,
1116 NULL((void*)0)))
1117 goto out;
1118
1119 readdir_xl = afr_crawl_readdir_xl_get (this, crawl_data);
1120 if (!readdir_xl)
1121 goto out;
1122 crawl_data->readdir_xl = readdir_xl;
1123
1124 ret = afr_crawl_build_start_loc (this, crawl_data, &dirloc);
1125 if (ret)
1126 goto out;
1127
1128 ret = afr_crawl_opendir (this, crawl_data, &fd, &dirloc);
1129 if (ret)
1130 goto out;
1131
1132 ret = _crawl_directory (fd, &dirloc, crawl_data);
1133 if (ret)
1134 gf_log (this->name, GF_LOG_ERROR, "Crawl failed on %s",do { do { if (0) printf ("Crawl failed on %s", readdir_xl->
name); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 1135, GF_LOG_ERROR, "Crawl failed on %s", readdir_xl
->name); } while (0)
1135 readdir_xl->name)do { do { if (0) printf ("Crawl failed on %s", readdir_xl->
name); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 1135, GF_LOG_ERROR, "Crawl failed on %s", readdir_xl
->name); } while (0)
;
1136 else
1137 gf_log (this->name, GF_LOG_DEBUG, "Crawl completed "do { do { if (0) printf ("Crawl completed " "on %s", readdir_xl
->name); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 1138, GF_LOG_DEBUG, "Crawl completed " "on %s"
, readdir_xl->name); } while (0)
1138 "on %s", readdir_xl->name)do { do { if (0) printf ("Crawl completed " "on %s", readdir_xl
->name); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 1138, GF_LOG_DEBUG, "Crawl completed " "on %s"
, readdir_xl->name); } while (0)
;
1139 if (crawl_data->crawl == INDEX)
1140 dirloc.path = NULL((void*)0);
1141out:
1142 if (fd)
1143 fd_unref (fd);
1144 if (crawl_data->crawl == INDEX)
1145 dirloc.path = NULL((void*)0);
1146 loc_wipe (&dirloc);
1147 return ret;
1148}
1149
1150static int
1151afr_dir_exclusive_crawl (void *data)
1152{
1153 afr_private_t *priv = NULL((void*)0);
1154 afr_self_heald_t *shd = NULL((void*)0);
1155 gf_boolean_t crawl = _gf_false;
1156 int ret = 0;
1157 int child = -1;
1158 xlator_t *this = NULL((void*)0);
1159 afr_crawl_data_t *crawl_data = data;
1160
1161 this = THIS(*__glusterfs_this_location());
1162 priv = this->private;
1163 shd = &priv->shd;
1164 child = crawl_data->child;
1165
1166 LOCK (&priv->lock)pthread_spin_lock (&priv->lock);
1167 {
1168 if (shd->inprogress[child]) {
1169 if (shd->pending[child] != FULL)
1170 shd->pending[child] = crawl_data->crawl;
1171 } else {
1172 shd->inprogress[child] = _gf_true;
1173 crawl = _gf_true;
1174 }
1175 }
1176 UNLOCK (&priv->lock)pthread_spin_unlock (&priv->lock);
1177
1178 if (!crawl) {
1179 gf_log (this->name, GF_LOG_INFO, "Another crawl is in progress "do { do { if (0) printf ("Another crawl is in progress " "for %s"
, priv->children[child]->name); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 1180, GF_LOG_INFO
, "Another crawl is in progress " "for %s", priv->children
[child]->name); } while (0)
1180 "for %s", priv->children[child]->name)do { do { if (0) printf ("Another crawl is in progress " "for %s"
, priv->children[child]->name); } while (0); _gf_log (this
->name, "afr-self-heald.c", __FUNCTION__, 1180, GF_LOG_INFO
, "Another crawl is in progress " "for %s", priv->children
[child]->name); } while (0)
;
1181 goto out;
1182 }
1183
1184 do {
1185 afr_dir_crawl (data);
1186 LOCK (&priv->lock)pthread_spin_lock (&priv->lock);
1187 {
1188 if (shd->pending[child] != NONE) {
1189 crawl_data->crawl = shd->pending[child];
1190 shd->pending[child] = NONE;
1191 } else {
1192 shd->inprogress[child] = _gf_false;
1193 crawl = _gf_false;
1194 }
1195 }
1196 UNLOCK (&priv->lock)pthread_spin_unlock (&priv->lock);
1197 } while (crawl);
1198out:
1199 return ret;
1200}
1201
1202void
1203afr_start_crawl (xlator_t *this, int idx, afr_crawl_type_t crawl,
1204 process_entry_cbk_t process_entry, void *op_data,
1205 gf_boolean_t exclusive, int crawl_flags,
1206 afr_crawl_done_cbk_t crawl_done)
1207{
1208 afr_private_t *priv = NULL((void*)0);
1209 call_frame_t *frame = NULL((void*)0);
1210 afr_crawl_data_t *crawl_data = NULL((void*)0);
1211 int ret = 0;
1212 int (*crawler) (void*) = NULL((void*)0);
1213
1214 priv = this->private;
1215
1216 frame = create_frame (this, this->ctx->pool);
1217 if (!frame)
1218 goto out;
1219
1220 afr_set_lk_owner (frame, this, frame->root);
1221 afr_set_low_priority (frame);
1222 crawl_data = GF_CALLOC (1, sizeof (*crawl_data),__gf_calloc (1, sizeof (*crawl_data), gf_afr_mt_crawl_data_t)
1223 gf_afr_mt_crawl_data_t)__gf_calloc (1, sizeof (*crawl_data), gf_afr_mt_crawl_data_t);
1224 if (!crawl_data)
1225 goto out;
1226 crawl_data->process_entry = process_entry;
1227 crawl_data->child = idx;
1228 crawl_data->pid = frame->root->pid;
1229 crawl_data->crawl = crawl;
1230 crawl_data->op_data = op_data;
1231 crawl_data->crawl_flags = crawl_flags;
1232 gf_log (this->name, GF_LOG_DEBUG, "starting crawl %d for %s",do { do { if (0) printf ("starting crawl %d for %s", crawl_data
->crawl, priv->children[idx]->name); } while (0); _gf_log
(this->name, "afr-self-heald.c", __FUNCTION__, 1233, GF_LOG_DEBUG
, "starting crawl %d for %s", crawl_data->crawl, priv->
children[idx]->name); } while (0)
1233 crawl_data->crawl, priv->children[idx]->name)do { do { if (0) printf ("starting crawl %d for %s", crawl_data
->crawl, priv->children[idx]->name); } while (0); _gf_log
(this->name, "afr-self-heald.c", __FUNCTION__, 1233, GF_LOG_DEBUG
, "starting crawl %d for %s", crawl_data->crawl, priv->
children[idx]->name); } while (0)
;
1234
1235 if (exclusive)
1236 crawler = afr_dir_exclusive_crawl;
1237 else
1238 crawler = afr_dir_crawl;
1239 ret = synctask_new (this->ctx->env, crawler,
1240 crawl_done, frame, crawl_data);
1241 if (ret)
1242 gf_log (this->name, GF_LOG_ERROR, "Could not create the "do { do { if (0) printf ("Could not create the " "task for %d ret %d"
, idx, ret); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 1243, GF_LOG_ERROR, "Could not create the " "task for %d ret %d"
, idx, ret); } while (0)
1243 "task for %d ret %d", idx, ret)do { do { if (0) printf ("Could not create the " "task for %d ret %d"
, idx, ret); } while (0); _gf_log (this->name, "afr-self-heald.c"
, __FUNCTION__, 1243, GF_LOG_ERROR, "Could not create the " "task for %d ret %d"
, idx, ret); } while (0)
;
1244out:
1245 return;
1246}
1247
1248void
1249afr_build_root_loc (xlator_t *this, loc_t *loc)
1250{
1251 afr_private_t *priv = NULL((void*)0);
1252
1253 priv = this->private;
1254 loc->path = gf_strdup ("/");
1255 loc->name = "";
1256 loc->inode = inode_ref (priv->root_inode);
1257 uuid_copy (loc->gfid, loc->inode->gfid);
1258}
1259
1260int
1261afr_set_root_gfid (dict_t *dict)
1262{
1263 uuid_t gfid;
1264 int ret = 0;
1265
1266 memset (gfid, 0, 16);
1267 gfid[15] = 1;
1268
1269 ret = afr_set_dict_gfid (dict, gfid);
1270
1271 return ret;
1272}
1273