From 79e4c7b2fad6db15863efb4e979525b1bd4862ea Mon Sep 17 00:00:00 2001 From: Krishnan Parthasarathi Date: Fri, 5 Jun 2015 10:33:11 +0530 Subject: stack: use list_head for managing frames PROBLEM -------- statedump requests that traverse call frames of all call stacks in execution may race with a STACK_RESET on a stack. This could crash the corresponding glusterfs process. For e.g, recently we observed this in a regression test case tests/basic/afr/sparse-self-heal.t. FIX --- gf_proc_dump_pending_frames takes a (TRY_LOCK) call_pool->lock before iterating through call frames of all call stacks in progress. With this fix, STACK_RESET removes its call frames under the same lock. Additional info ---------------- This fix makes call_stack_t to use struct list_head in place of custom doubly-linked list implementation. This makes call_frame_t manipulation easier to maintain in the context of STACK_WIND et al. BUG: 1229658 Change-Id: I7e43bccd3994cd9184ab982dba3dbc10618f0d94 Signed-off-by: Krishnan Parthasarathi Reviewed-on: http://review.gluster.org/11095 Reviewed-by: Niels de Vos Tested-by: Gluster Build System Reviewed-by: Pranith Kumar Karampuri Tested-by: NetBSD Build System --- xlators/features/protect/src/prot_client.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'xlators/features') diff --git a/xlators/features/protect/src/prot_client.c b/xlators/features/protect/src/prot_client.c index dde3abdadc8..79636410b94 100644 --- a/xlators/features/protect/src/prot_client.c +++ b/xlators/features/protect/src/prot_client.c @@ -35,10 +35,9 @@ pcli_print_trace (char *name, call_frame_t *frame) int i; gf_log (name, GF_LOG_INFO, "Translator stack:"); - while (frame) { + list_for_each_entry (frame, &frame->root->myframes, frames) { gf_log (name, GF_LOG_INFO, "%s (%s)", frame->wind_from, frame->this->name); - frame = frame->next; } size = backtrace (frames, NUM_FRAMES); @@ -77,7 +76,7 @@ pcli_rename (call_frame_t *frame, xlator_t *this, loc_t *oldloc, if (value != PROT_ACT_NONE) { gf_log (this->name, GF_LOG_WARNING, "got rename for protected %s", oldloc->path); - pcli_print_trace (this->name, frame->next); + pcli_print_trace (this->name, frame); if (value == PROT_ACT_REJECT) { STACK_UNWIND_STRICT (rename, frame, -1, EPERM, NULL, NULL, NULL, NULL, NULL, @@ -161,7 +160,7 @@ pcli_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int xflag, if (value != PROT_ACT_NONE) { gf_log (this->name, GF_LOG_WARNING, "got unlink for protected %s", loc->path); - pcli_print_trace(this->name,frame->next); + pcli_print_trace(this->name, frame); if (value == PROT_ACT_REJECT) { STACK_UNWIND_STRICT (unlink, frame, -1, EPERM, NULL, NULL, NULL); -- cgit