File: | xlators/cluster/afr/src/afr-self-heald.c |
Location: | line 550, column 25 |
Description: | Value stored to 'ret' is never read |
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 | |
22 | typedef enum { |
23 | STOP_CRAWL_ON_SINGLE_SUBVOL = 1 |
24 | } afr_crawl_flags_t; |
25 | |
26 | typedef enum { |
27 | HEAL = 1, |
28 | INFO |
29 | } shd_crawl_op; |
30 | |
31 | typedef struct shd_dump { |
32 | dict_t *dict; |
33 | xlator_t *this; |
34 | int child; |
35 | } shd_dump_t; |
36 | |
37 | typedef struct shd_event_ { |
38 | int child; |
39 | char *path; |
40 | } shd_event_t; |
41 | |
42 | typedef struct shd_pos_ { |
43 | int child; |
44 | xlator_t *this; |
45 | afr_child_pos_t pos; |
46 | } shd_pos_t; |
47 | |
48 | typedef int |
49 | (*afr_crawl_done_cbk_t) (int ret, call_frame_t *sync_frame, void *crawl_data); |
50 | |
51 | void |
52 | afr_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 | |
57 | static 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). */ |
61 | int |
62 | afr_find_child_position (xlator_t *this, int child, afr_child_pos_t *pos); |
63 | |
64 | /* For deferring through a new synctask. */ |
65 | int |
66 | afr_syncop_find_child_position (void *data); |
67 | |
68 | static 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 | |
86 | void |
87 | shd_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); |
95 | out: |
96 | return; |
97 | } |
98 | |
99 | int |
100 | afr_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 | |
113 | static 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 | |
130 | int |
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 | |
171 | inc_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; |
179 | out: |
180 | return ret; |
181 | } |
182 | |
183 | int |
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; |
209 | out: |
210 | if (!ret) |
211 | *fpath = path; |
212 | if (xattr) |
213 | dict_unref (xattr); |
214 | return ret; |
215 | } |
216 | |
217 | int |
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); |
231 | out: |
232 | return ret; |
233 | } |
234 | |
235 | int |
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 | |
247 | void |
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); |
267 | out: |
268 | return; |
269 | } |
270 | |
271 | int |
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 | |
299 | out: |
300 | if (ret && path) |
301 | GF_FREE (path)__gf_free (path); |
302 | return ret; |
303 | } |
304 | |
305 | void |
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; |
379 | out: |
380 | if (ret && path) |
381 | GF_FREE (path)__gf_free (path); |
382 | return; |
383 | } |
384 | |
385 | int |
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; |
400 | out: |
401 | return ret; |
402 | } |
403 | |
404 | int |
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 | |
426 | static int |
427 | afr_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 | |
434 | void |
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 | |
442 | gf_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; |
474 | out: |
475 | if (reason) |
476 | *reason = msg; |
477 | return proceed; |
478 | } |
479 | |
480 | int |
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); |
Value stored to 'ret' is never read | |
551 | } |
552 | } |
553 | out: |
554 | return op_ret; |
555 | } |
556 | |
557 | int |
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 | |
564 | int |
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 | |
570 | int |
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 | |
588 | int |
589 | afr_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 | } |
635 | out: |
636 | dict_del (output, this->name); |
637 | return ret; |
638 | } |
639 | |
640 | void |
641 | afr_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 | } |
681 | unlock: |
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 | |
694 | static int |
695 | afr_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)); |
710 | out: |
711 | GF_FREE (data)__gf_free (data); |
712 | return 0; |
713 | } |
714 | |
715 | void |
716 | afr_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; |
736 | out: |
737 | return; |
738 | } |
739 | |
740 | static int |
741 | get_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; |
763 | out: |
764 | return ret; |
765 | } |
766 | |
767 | int |
768 | afr_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; |
792 | out: |
793 | return ret; |
794 | } |
795 | |
796 | int |
797 | afr_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; |
848 | out: |
849 | if (xattr) |
850 | dict_unref (xattr); |
851 | loc_wipe (&rootloc); |
852 | return ret; |
853 | } |
854 | |
855 | int |
856 | afr_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; |
881 | out: |
882 | if (!ret) |
883 | *dirfd = fd; |
884 | return ret; |
885 | } |
886 | |
887 | xlator_t* |
888 | afr_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 | |
900 | int |
901 | afr_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 | } |
917 | out: |
918 | return ret; |
919 | } |
920 | |
921 | static 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; |
976 | out: |
977 | loc_wipe (&entry_loc); |
978 | return ret; |
979 | } |
980 | |
981 | static 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, |
1023 | crawl_data); |
1024 | gf_dirent_free (&entries); |
1025 | free_entries = _gf_false; |
1026 | } |
1027 | ret = 0; |
1028 | out: |
1029 | if (free_entries) |
1030 | gf_dirent_free (&entries); |
1031 | return ret; |
1032 | } |
1033 | |
1034 | static char* |
1035 | position_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 | |
1048 | int |
1049 | afr_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); |
1085 | out: |
1086 | if (ret) |
1087 | *pos = AFR_POS_UNKNOWN; |
1088 | loc_wipe (&loc); |
1089 | return ret; |
1090 | } |
1091 | |
1092 | int |
1093 | afr_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 | |
1103 | static int |
1104 | afr_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); |
1141 | out: |
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 | |
1150 | static int |
1151 | afr_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); |
1198 | out: |
1199 | return ret; |
1200 | } |
1201 | |
1202 | void |
1203 | afr_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); |
1244 | out: |
1245 | return; |
1246 | } |
1247 | |
1248 | void |
1249 | afr_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 | |
1260 | int |
1261 | afr_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 |