Sometimes calling xyz_finilize() within a dispatch would cause a crash because the qb_ipcc_disconnect actually disconnects immediatly and frees it't memory. whereas the corosync structure is reference counted. So this makes use of the reference counting to only call qb_ipcc_disconnect when it is fully dereferenced. Signed-off-by: Angus Salkeld <asalkeld@xxxxxxxxxx> --- lib/cfg.c | 20 +++++++++++++++++--- lib/cmap.c | 25 +++++++++++++++++++++++-- lib/cpg.c | 20 +++++++++++++++++--- lib/quorum.c | 22 +++++++++++++++++----- lib/votequorum.c | 21 +++++++++++++++++---- 5 files changed, 91 insertions(+), 17 deletions(-) diff --git a/lib/cfg.c b/lib/cfg.c index 34b8ea4..248df4d 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -72,7 +72,9 @@ struct cfg_inst { /* * All instances in one database */ -DECLARE_HDB_DATABASE (cfg_hdb,NULL); +static void cfg_inst_free (void *inst); + +DECLARE_HDB_DATABASE (cfg_hdb, cfg_inst_free); /* * Implementation @@ -96,6 +98,7 @@ corosync_cfg_initialize ( goto error_destroy; } + cfg_inst->finalize = 0; cfg_inst->c = qb_ipcc_connect ("cfg", IPC_REQUEST_SIZE); if (cfg_inst->c == NULL) { error = qb_to_cs_error(-errno); @@ -218,6 +221,13 @@ corosync_cfg_dispatch ( goto error_nounlock; break; } + if (cfg_inst->finalize) { + /* + * If the finalize has been called then get out of the dispatch. + */ + error = CS_ERR_BAD_HANDLE; + goto error_put; + } /* * Determine if more messages should be processed @@ -233,6 +243,12 @@ error_nounlock: return (error); } +static void cfg_inst_free (void *inst) +{ + struct cfg_inst *cfg_inst = (struct cfg_inst *)inst; + qb_ipcc_disconnect(cfg_inst->c); +} + cs_error_t corosync_cfg_finalize ( corosync_cfg_handle_t cfg_handle) @@ -255,8 +271,6 @@ corosync_cfg_finalize ( cfg_inst->finalize = 1; - qb_ipcc_disconnect (cfg_inst->c); - (void)hdb_handle_destroy (&cfg_hdb, cfg_handle); (void)hdb_handle_put (&cfg_hdb, cfg_handle); diff --git a/lib/cmap.c b/lib/cmap.c index 1a58541..bfe7d6e 100644 --- a/lib/cmap.c +++ b/lib/cmap.c @@ -54,6 +54,7 @@ #include <stdio.h> struct cmap_inst { + int finalize; qb_ipcc_connection_t *c; const void *context; }; @@ -65,7 +66,9 @@ struct cmap_track_inst { cmap_track_handle_t track_handle; }; -DECLARE_HDB_DATABASE(cmap_handle_t_db,NULL); +static void cmap_inst_free (void *inst); + +DECLARE_HDB_DATABASE(cmap_handle_t_db, cmap_inst_free); DECLARE_HDB_DATABASE(cmap_track_handle_t_db,NULL); /* @@ -99,6 +102,7 @@ cs_error_t cmap_initialize (cmap_handle_t *handle) } error = CS_OK; + cmap_inst->finalize = 0; cmap_inst->c = qb_ipcc_connect("cmap", IPC_REQUEST_SIZE); if (cmap_inst->c == NULL) { error = qb_to_cs_error(-errno); @@ -117,6 +121,12 @@ error_no_destroy: return (error); } +static void cmap_inst_free (void *inst) +{ + struct cmap_inst *cmap_inst = (struct cmap_inst *)inst; + qb_ipcc_disconnect(cmap_inst->c); +} + cs_error_t cmap_finalize(cmap_handle_t handle) { struct cmap_inst *cmap_inst; @@ -129,7 +139,11 @@ cs_error_t cmap_finalize(cmap_handle_t handle) return (error); } - qb_ipcc_disconnect(cmap_inst->c); + if (cmap_inst->finalize) { + (void)hdb_handle_put (&cmap_handle_t_db, handle); + return (CS_ERR_BAD_HANDLE); + } + cmap_inst->finalize = 1; /* * Destroy all track instances for given connection @@ -270,6 +284,13 @@ cs_error_t cmap_dispatch ( goto error_put; break; } + if (cmap_inst->finalize) { + /* + * If the finalize has been called then get out of the dispatch. + */ + error = CS_ERR_BAD_HANDLE; + goto error_put; + } /* * Determine if more messages should be processed diff --git a/lib/cpg.c b/lib/cpg.c index 700303f..0c9fa1a 100644 --- a/lib/cpg.c +++ b/lib/cpg.c @@ -73,8 +73,9 @@ struct cpg_inst { }; struct list_head iteration_list_head; }; +static void cpg_inst_free (void *inst); -DECLARE_HDB_DATABASE(cpg_handle_t_db,NULL); +DECLARE_HDB_DATABASE(cpg_handle_t_db, cpg_inst_free); struct cpg_iteration_instance_t { cpg_iteration_handle_t cpg_iteration_handle; @@ -108,6 +109,12 @@ static void cpg_iteration_instance_finalize (struct cpg_iteration_instance_t *cp hdb_handle_destroy (&cpg_iteration_handle_t_db, cpg_iteration_instance->cpg_iteration_handle); } +static void cpg_inst_free (void *inst) +{ + struct cpg_inst *cpg_inst = (struct cpg_inst *)inst; + qb_ipcc_disconnect(cpg_inst->c); +} + static void cpg_inst_finalize (struct cpg_inst *cpg_inst, hdb_handle_t handle) { struct list_head *iter, *iter_next; @@ -248,8 +255,6 @@ cs_error_t cpg_finalize ( &res_lib_cpg_finalize, sizeof (struct res_lib_cpg_finalize)); - qb_ipcc_disconnect(cpg_inst->c); - cpg_inst_finalize (cpg_inst, handle); hdb_handle_put (&cpg_handle_t_db, handle); @@ -475,6 +480,15 @@ cs_error_t cpg_dispatch ( break; /* case CPG_MODEL_V1 */ } /* - switch (cpg_inst_copy.model_data.model) */ + if (cpg_inst_copy.finalize || cpg_inst->finalize) { + /* + * If the finalize has been called then get out of the dispatch. + */ + cpg_inst->finalize = 1; + error = CS_ERR_BAD_HANDLE; + goto error_put; + } + /* * Determine if more messages should be processed */ diff --git a/lib/quorum.c b/lib/quorum.c index 1ee2f06..eb53b7f 100644 --- a/lib/quorum.c +++ b/lib/quorum.c @@ -61,7 +61,9 @@ struct quorum_inst { quorum_callbacks_t callbacks; }; -DECLARE_HDB_DATABASE(quorum_handle_t_db,NULL); +static void quorum_inst_free (void *inst); + +DECLARE_HDB_DATABASE(quorum_handle_t_db, quorum_inst_free); cs_error_t quorum_initialize ( quorum_handle_t *handle, @@ -85,6 +87,7 @@ cs_error_t quorum_initialize ( } error = CS_OK; + quorum_inst->finalize = 0; quorum_inst->c = qb_ipcc_connect ("quorum", IPC_REQUEST_SIZE); if (quorum_inst->c == NULL) { error = qb_to_cs_error(-errno); @@ -129,6 +132,12 @@ error_no_destroy: return (error); } +static void quorum_inst_free (void *inst) +{ + struct quorum_inst *quorum_inst = (struct quorum_inst *)inst; + qb_ipcc_disconnect(quorum_inst->c); +} + cs_error_t quorum_finalize ( quorum_handle_t handle) { @@ -150,8 +159,6 @@ cs_error_t quorum_finalize ( quorum_inst->finalize = 1; - qb_ipcc_disconnect (quorum_inst->c); - (void)hdb_handle_destroy (&quorum_handle_t_db, handle); (void)hdb_handle_put (&quorum_handle_t_db, handle); @@ -433,6 +440,13 @@ cs_error_t quorum_dispatch ( goto error_put; break; } + if (quorum_inst->finalize) { + /* + * If the finalize has been called then get out of the dispatch. + */ + error = CS_ERR_BAD_HANDLE; + goto error_put; + } /* * Determine if more messages should be processed @@ -442,8 +456,6 @@ cs_error_t quorum_dispatch ( } } while (cont); - goto error_put; - error_put: (void)hdb_handle_put (&quorum_handle_t_db, handle); return (error); diff --git a/lib/votequorum.c b/lib/votequorum.c index 6240f99..e2b578f 100644 --- a/lib/votequorum.c +++ b/lib/votequorum.c @@ -64,7 +64,9 @@ struct votequorum_inst { votequorum_callbacks_t callbacks; }; -DECLARE_HDB_DATABASE(votequorum_handle_t_db,NULL); +static void votequorum_inst_free (void *inst); + +DECLARE_HDB_DATABASE(votequorum_handle_t_db, votequorum_inst_free); cs_error_t votequorum_initialize ( votequorum_handle_t *handle, @@ -83,6 +85,7 @@ cs_error_t votequorum_initialize ( goto error_destroy; } + votequorum_inst->finalize = 0; votequorum_inst->c = qb_ipcc_connect ("votequorum", IPC_REQUEST_SIZE); if (votequorum_inst->c == NULL) { error = qb_to_cs_error(-errno); @@ -106,6 +109,12 @@ error_no_destroy: return (error); } +static void votequorum_inst_free (void *inst) +{ + struct votequorum_inst *vq_inst = (struct votequorum_inst *)inst; + qb_ipcc_disconnect(vq_inst->c); +} + cs_error_t votequorum_finalize ( votequorum_handle_t handle) { @@ -127,8 +136,6 @@ cs_error_t votequorum_finalize ( votequorum_inst->finalize = 1; - qb_ipcc_disconnect (votequorum_inst->c); - hdb_handle_destroy (&votequorum_handle_t_db, handle); hdb_handle_put (&votequorum_handle_t_db, handle); @@ -521,6 +528,13 @@ cs_error_t votequorum_dispatch ( goto error_put; break; } + if (votequorum_inst->finalize) { + /* + * If the finalize has been called then get out of the dispatch. + */ + error = CS_ERR_BAD_HANDLE; + goto error_put; + } /* * Determine if more messages should be processed @@ -530,7 +544,6 @@ cs_error_t votequorum_dispatch ( } } while (cont); - goto error_put; error_put: hdb_handle_put (&votequorum_handle_t_db, handle); -- 1.7.9.3 _______________________________________________ discuss mailing list discuss@xxxxxxxxxxxx http://lists.corosync.org/mailman/listinfo/discuss