| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- /** BEGIN COPYRIGHT BLOCK
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- *
- * License: GPL (version 3 or any later version).
- * See LICENSE for details.
- * END COPYRIGHT BLOCK **/
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
- /* repl_connext.c - replication extension to the Connection object
- */
- #include "repl.h"
- #include "repl5.h"
- /* ***** Supplier side ***** */
- /* NOT NEEDED YET */
- /* ***** Consumer side ***** */
- /* consumer connection extension constructor */
- void* consumer_connection_extension_constructor (void *object, void *parent)
- {
- consumer_connection_extension *ext = (consumer_connection_extension*) slapi_ch_malloc (sizeof (consumer_connection_extension));
- if (ext == NULL)
- {
- slapi_log_error(SLAPI_LOG_PLUGIN, LOG_DEBUG, repl_plugin_name, "unable to create replication consumer connection extension - out of memory\n" );
- }
- else
- {
- ext->is_legacy_replication_dn= 0;
- ext->repl_protocol_version = REPL_PROTOCOL_UNKNOWN;
- ext->replica_acquired = NULL;
- ext->isreplicationsession= 0;
- ext->supplier_ruv = NULL;
- ext->connection = NULL;
- ext->in_use_opid = -1;
- ext->lock = PR_NewLock();
- if (NULL == ext->lock)
- {
- slapi_log_error(SLAPI_LOG_PLUGIN, LOG_DEBUG, repl_plugin_name, "unable to create replication consumer connection extension lock - out of memory\n" );
- /* no need to go through the full destructor, but still need to free up this memory */
- slapi_ch_free((void **)&ext);
- ext = NULL;
- }
- }
- return ext;
- }
- /* consumer connection extension destructor */
- void consumer_connection_extension_destructor (void *ext, void *object, void *parent)
- {
- PRUint64 connid = 0;
- if (ext)
- {
- /* Check to see if this replication session has acquired
- * a replica. If so, release it here.
- */
- consumer_connection_extension *connext = (consumer_connection_extension *)ext;
- if (NULL != connext->replica_acquired)
- {
- Replica *r = object_get_data ((Object*)connext->replica_acquired);
- /* If a total update was in progress, abort it */
- if (REPL_PROTOCOL_50_TOTALUPDATE == connext->repl_protocol_version)
- {
- Slapi_PBlock *pb = slapi_pblock_new();
- const Slapi_DN *repl_root_sdn = replica_get_root(r);
- PR_ASSERT(NULL != repl_root_sdn);
- if (NULL != repl_root_sdn)
- {
- slapi_pblock_set(pb, SLAPI_CONNECTION, connext->connection);
- slapi_pblock_set(pb, SLAPI_TARGET_SDN, (void*)repl_root_sdn);
- slapi_pblock_get(pb, SLAPI_CONN_ID, &connid);
- slapi_log_error(SLAPI_LOG_REPL, LOG_DEBUG, repl_plugin_name,
- "Aborting total update in progress for replicated "
- "area %s connid=%" NSPRIu64 "\n", slapi_sdn_get_dn(repl_root_sdn),
- connid);
- slapi_stop_bulk_import(pb);
- }
- else
- {
- slapi_log_error(SLAPI_LOG_FATAL, LOG_ERR, repl_plugin_name,
- "consumer_connection_extension_destructor: can't determine root "
- "of replicated area.\n");
- }
- slapi_pblock_destroy(pb);
- /* allow reaping again */
- replica_set_tombstone_reap_stop(r, PR_FALSE);
- }
- replica_relinquish_exclusive_access(r, connid, -1);
- object_release ((Object*)connext->replica_acquired);
- connext->replica_acquired = NULL;
- }
- if (connext->supplier_ruv)
- {
- ruv_destroy ((RUV **)&connext->supplier_ruv);
- }
-
- if (connext->lock)
- {
- PR_DestroyLock(connext->lock);
- connext->lock = NULL;
- }
-
- connext->in_use_opid = -1;
-
- connext->connection = NULL;
- slapi_ch_free((void **)&ext);
- }
- }
- /* Obtain exclusive access to this connection extension.
- * Returns the consumer_connection_extension* if successful, else NULL.
- *
- * This is similar to obtaining exclusive access to the replica, but not identical.
- * For the connection extension, you only want to hold on to exclusive access as
- * long as it is being actively used to process an operation. Mainly that means
- * while processing either a 'start' or an 'end' extended operation. This makes
- * certain that if another 'start' or 'end' operation is received on the connection,
- * the ops will not trample on each other's state. As soon as you are done with
- * that single operation, it is time to relinquish the connection extension.
- * That differs from acquiring exclusive access to the replica, which is held over
- * after the 'start' operation and relinquished during the 'end' operation.
- */
- consumer_connection_extension*
- consumer_connection_extension_acquire_exclusive_access(void* conn, PRUint64 connid, int opid)
- {
- consumer_connection_extension* ret = NULL;
-
- /* step 1, grab the connext */
- consumer_connection_extension* connext = (consumer_connection_extension*)
- repl_con_get_ext(REPL_CON_EXT_CONN, conn);
-
- if (NULL != connext)
- {
- /* step 2, acquire its lock */
- PR_Lock(connext->lock);
- /* step 3, see if it is not in use, or in use by us */
- if (0 > connext->in_use_opid)
- {
- /* step 4, take it! */
- connext->in_use_opid = opid;
- ret = connext;
- slapi_log_error(SLAPI_LOG_REPL, LOG_DEBUG, repl_plugin_name,
- "conn=%" NSPRIu64 " op=%d Acquired consumer connection extension\n",
- connid, opid);
- }
- else if (opid == connext->in_use_opid)
- {
- ret = connext;
- slapi_log_error(SLAPI_LOG_REPL, LOG_DEBUG, repl_plugin_name,
- "conn=%" NSPRIu64 " op=%d Reacquired consumer connection extension\n",
- connid, opid);
- }
- else
- {
- slapi_log_error(SLAPI_LOG_REPL, LOG_DEBUG, repl_plugin_name,
- "conn=%" NSPRIu64 " op=%d Could not acquire consumer connection extension; it is in use by op=%d\n",
- connid, opid, connext->in_use_opid);
- }
- /* step 5, drop the lock */
- PR_Unlock(connext->lock);
- }
- else
- {
- slapi_log_error(SLAPI_LOG_REPL, LOG_DEBUG, repl_plugin_name,
- "conn=%" NSPRIu64 " op=%d Could not acquire consumer extension, it is NULL!\n",
- connid, opid);
- }
-
- return ret;
- }
- /* Relinquish exclusive access to this connection extension.
- * Returns 0 if exclusive access could NOT be relinquished, and non-zero if it was.
- * Specifically:
- * 1 if the extension was in use and was relinquished.
- * 2 if the extension was not in use to begin with.
- *
- * The extension will only be relinquished if it was first acquired by this op,
- * or if 'force' is TRUE. Do not use 'force' without a legitimate reason, such
- * as when destroying the parent connection.
- *
- * cf. consumer_connection_extension_acquire_exclusive_access() for details on how,
- * when, and why you would want to acquire and relinquish exclusive access.
- */
- int
- consumer_connection_extension_relinquish_exclusive_access(void* conn, PRUint64 connid, int opid, PRBool force)
- {
- int ret = 0;
-
- /* step 1, grab the connext */
- consumer_connection_extension* connext = (consumer_connection_extension*)
- repl_con_get_ext(REPL_CON_EXT_CONN, conn);
-
- if (NULL != connext)
- {
- /* step 2, acquire its lock */
- PR_Lock(connext->lock);
- /* step 3, see if it is in use */
- if (0 > connext->in_use_opid)
- {
- slapi_log_error(SLAPI_LOG_REPL, LOG_DEBUG, repl_plugin_name,
- "conn=%" NSPRIu64 " op=%d Consumer connection extension is not in use\n",
- connid, opid);
- ret = 2;
- }
- else if (opid == connext->in_use_opid)
- {
- /* step 4, relinquish it (normal) */
- slapi_log_error(SLAPI_LOG_REPL, LOG_DEBUG, repl_plugin_name,
- "conn=%" NSPRIu64 " op=%d Relinquishing consumer connection extension\n",
- connid, opid);
- connext->in_use_opid = -1;
- ret = 1;
- }
- else if (force)
- {
- /* step 4, relinquish it (forced) */
- slapi_log_error(SLAPI_LOG_REPL, LOG_DEBUG, repl_plugin_name,
- "conn=%" NSPRIu64 " op=%d Forced to relinquish consumer connection extension held by op=%d\n",
- connid, opid, connext->in_use_opid);
- connext->in_use_opid = -1;
- ret = 1;
- }
- else
- {
- slapi_log_error(SLAPI_LOG_REPL, LOG_DEBUG, repl_plugin_name,
- "conn=%" NSPRIu64 " op=%d Not relinquishing consumer connection extension, it is held by op=%d!\n",
- connid, opid, connext->in_use_opid);
- }
-
- /* step 5, drop the lock */
- PR_Unlock(connext->lock);
- }
- else
- {
- slapi_log_error(SLAPI_LOG_REPL, LOG_DEBUG, repl_plugin_name,
- "conn=%" NSPRIu64 " op=%d Could not relinquish consumer extension, it is NULL!\n",
- connid, opid);
- }
-
- return ret;
- }
|