From 47678bde5c2f8e674289d2b0893865ab3fa43940 Mon Sep 17 00:00:00 2001 From: Atin Mukherjee Date: Sun, 1 Apr 2018 10:10:41 +0530 Subject: [PATCH 207/212] glusterd: fix txn_opinfo memory leak For transactions where there's no volname involved (eg : gluster v status), the originator node initiates with staging phase and what that means in op-sm there's no unlock event triggered which resulted into a txn_opinfo dictionary leak. Credits : cynthia.zhou@nokia-sbell.com > upstream patch : https://review.gluster.org/#/c/19801/ >Change-Id: I92fffbc2e8e1b010f489060f461be78aa2b86615 >Fixes: bz#1550339 >Signed-off-by: Atin Mukherjee Change-Id: I92fffbc2e8e1b010f489060f461be78aa2b86615 BUG: 1529451 Signed-off-by: Atin Mukherjee Reviewed-on: https://code.engineering.redhat.com/gerrit/134448 Tested-by: RHGS Build Bot --- xlators/mgmt/glusterd/src/glusterd-handler.c | 1 + xlators/mgmt/glusterd/src/glusterd-op-sm.c | 32 ++++++++++++++++++++-------- xlators/mgmt/glusterd/src/glusterd-op-sm.h | 1 + 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/xlators/mgmt/glusterd/src/glusterd-handler.c b/xlators/mgmt/glusterd/src/glusterd-handler.c index ddab159..dbf80a1 100644 --- a/xlators/mgmt/glusterd/src/glusterd-handler.c +++ b/xlators/mgmt/glusterd/src/glusterd-handler.c @@ -1073,6 +1073,7 @@ __glusterd_handle_stage_op (rpcsvc_request_t *req) glusterd_txn_opinfo_init (&txn_op_info, &state, &op_req.op, req_ctx->dict, req); + txn_op_info.skip_locking = _gf_true; ret = glusterd_set_txn_opinfo (txn_id, &txn_op_info); if (ret) { gf_msg (this->name, GF_LOG_ERROR, 0, diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c index a02a0b3..72d349b 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c @@ -5919,14 +5919,15 @@ glusterd_op_init_commit_rsp_dict (glusterd_op_t op) static int glusterd_op_ac_commit_op (glusterd_op_sm_event_t *event, void *ctx) { - int ret = 0; - glusterd_req_ctx_t *req_ctx = NULL; - int32_t status = 0; - char *op_errstr = NULL; - dict_t *dict = NULL; - dict_t *rsp_dict = NULL; - xlator_t *this = NULL; - uuid_t *txn_id = NULL; + int ret = 0; + glusterd_req_ctx_t *req_ctx = NULL; + int32_t status = 0; + char *op_errstr = NULL; + dict_t *dict = NULL; + dict_t *rsp_dict = NULL; + xlator_t *this = NULL; + uuid_t *txn_id = NULL; + glusterd_op_info_t txn_op_info = {{0},}; this = THIS; GF_ASSERT (this); @@ -5965,6 +5966,15 @@ glusterd_op_ac_commit_op (glusterd_op_sm_event_t *event, void *ctx) ret = -1; goto out; } + ret = glusterd_get_txn_opinfo (&event->txn_id, &txn_op_info); + if (ret) { + gf_msg_callingfn (this->name, GF_LOG_ERROR, 0, + GD_MSG_TRANS_OPINFO_GET_FAIL, + "Unable to get transaction opinfo " + "for transaction ID : %s", + uuid_utoa (event->txn_id)); + goto out; + } ret = dict_set_bin (rsp_dict, "transaction_id", txn_id, sizeof(*txn_id)); @@ -5985,7 +5995,11 @@ out: if (rsp_dict) dict_unref (rsp_dict); - + /* for no volname transactions, the txn_opinfo needs to be cleaned up + * as there's no unlock event triggered + */ + if (txn_op_info.skip_locking) + ret = glusterd_clear_txn_opinfo (txn_id); gf_msg_debug (this->name, 0, "Returning with %d", ret); return ret; diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.h b/xlators/mgmt/glusterd/src/glusterd-op-sm.h index 24b1944..f2aee9c 100644 --- a/xlators/mgmt/glusterd/src/glusterd-op-sm.h +++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.h @@ -101,6 +101,7 @@ struct glusterd_op_info_ { char *op_errstr; struct cds_list_head pending_bricks; uint32_t txn_generation; + gf_boolean_t skip_locking; }; typedef struct glusterd_op_info_ glusterd_op_info_t; -- 1.8.3.1