Re: [PATCH] Only call qb_ipcc_disconnect when the instance is fully dereferenced.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Tell us how you really feel... ;)

On 04/02/2012 09:54 PM, Fabio M. Di Nitto wrote:
> Laaaaaaadiesssss and gentlement... WE HAVE A WINNER!!!
> 
> 
> On 04/03/2012 01:57 AM, Angus Salkeld wrote:
>> 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);
> 
> _______________________________________________
> discuss mailing list
> discuss@xxxxxxxxxxxx
> http://lists.corosync.org/mailman/listinfo/discuss


-- 
Digimer
Papers and Projects: https://alteeve.com
_______________________________________________
discuss mailing list
discuss@xxxxxxxxxxxx
http://lists.corosync.org/mailman/listinfo/discuss


[Index of Archives]     [Linux Clusters]     [Corosync Project]     [Linux USB Devel]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Linux Kernel]     [Linux SCSI]     [X.Org]

  Powered by Linux