summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2010-09-15 16:15:12 +1000
committerAndrew Tridgell <tridge@samba.org>2010-09-16 07:24:00 +1000
commit54b53704747f45757642c9d4a17645ac777dc9ea (patch)
tree80271f7d3c4ea3e81b0b4ab6224c7c75759dbe21
parent7f1db0d8df6c5b68c9eb9a2d578ce79a43ce0719 (diff)
downloadsamba-54b53704747f45757642c9d4a17645ac777dc9ea.tar.gz
samba-54b53704747f45757642c9d4a17645ac777dc9ea.tar.bz2
samba-54b53704747f45757642c9d4a17645ac777dc9ea.zip
s4-repl: cleanup getncchanges extended op calls
Multiple calls are allowed to run in parallel as long as they don't conflict. This also cleans up the variable names in the extended op calls. Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>
-rw-r--r--source4/dsdb/repl/drepl_fsmo.c13
-rw-r--r--source4/dsdb/repl/drepl_ridalloc.c91
-rw-r--r--source4/dsdb/repl/drepl_service.h6
3 files changed, 70 insertions, 40 deletions
diff --git a/source4/dsdb/repl/drepl_fsmo.c b/source4/dsdb/repl/drepl_fsmo.c
index a389c39bf2..63b831669a 100644
--- a/source4/dsdb/repl/drepl_fsmo.c
+++ b/source4/dsdb/repl/drepl_fsmo.c
@@ -43,9 +43,7 @@ static void drepl_role_callback(struct dreplsrv_service *service,
} else {
DEBUG(0,(__location__ ": Successful role transfer\n"));
}
- talloc_free(service->ncchanges_extended.role_owner_source_dsa);
- service->ncchanges_extended.role_owner_source_dsa = NULL;
- service->ncchanges_extended.in_progress = false;
+ service->role_transfer_in_progress = false;
}
static bool fsmo_master_cmp(struct ldb_dn *ntds_dn, struct ldb_dn *role_owner_dn)
@@ -67,13 +65,14 @@ WERROR dreplsrv_fsmo_role_check(struct dreplsrv_service *service,
TALLOC_CTX *tmp_ctx = talloc_new(service);
struct ldb_context *ldb = service->samdb;
int ret;
- uint64_t alloc_pool = 0;
+ uint64_t fsmo_info = 0;
enum drsuapi_DsExtendedOperation extended_op = DRSUAPI_EXOP_NONE;
WERROR werr;
- if (service->ncchanges_extended.in_progress) {
+ if (service->role_transfer_in_progress) {
talloc_free(tmp_ctx);
- return WERR_OK;
+ /* should we allow these in parallel? */
+ return WERR_DS_DRA_REPL_PENDING;
}
ntds_dn = samdb_ntds_settings_dn(ldb);
@@ -158,7 +157,7 @@ WERROR dreplsrv_fsmo_role_check(struct dreplsrv_service *service,
fsmo_role_dn,
role_owner_dn,
extended_op,
- alloc_pool,
+ fsmo_info,
drepl_role_callback);
if (W_ERROR_IS_OK(werr)) {
dreplsrv_run_pending_ops(service);
diff --git a/source4/dsdb/repl/drepl_ridalloc.c b/source4/dsdb/repl/drepl_ridalloc.c
index 44843166f7..cc41db1360 100644
--- a/source4/dsdb/repl/drepl_ridalloc.c
+++ b/source4/dsdb/repl/drepl_ridalloc.c
@@ -33,11 +33,14 @@
/*
create the role owner source dsa structure
- */
+ nc_dn: the DN of the subtree being replicated
+ source_dsa_dn: the DN of the server that we are replicating from
+ */
WERROR drepl_create_role_owner_source_dsa(struct dreplsrv_service *service,
- struct ldb_dn *fsmo_role_dn,
- struct ldb_dn *role_owner_dn)
+ struct ldb_dn *nc_dn,
+ struct ldb_dn *source_dsa_dn,
+ struct dreplsrv_partition_source_dsa **_sdsa)
{
struct dreplsrv_partition_source_dsa *sdsa;
struct ldb_context *ldb = service->samdb;
@@ -53,29 +56,29 @@ WERROR drepl_create_role_owner_source_dsa(struct dreplsrv_service *service,
return WERR_NOMEM;
}
- sdsa->partition->dn = ldb_dn_copy(sdsa->partition, fsmo_role_dn);
+ sdsa->partition->dn = ldb_dn_copy(sdsa->partition, nc_dn);
if (!sdsa->partition->dn) {
talloc_free(sdsa);
return WERR_NOMEM;
}
- sdsa->partition->nc.dn = ldb_dn_alloc_linearized(sdsa->partition, fsmo_role_dn);
+ sdsa->partition->nc.dn = ldb_dn_alloc_linearized(sdsa->partition, nc_dn);
if (!sdsa->partition->nc.dn) {
talloc_free(sdsa);
return WERR_NOMEM;
}
- ret = dsdb_find_guid_by_dn(ldb, fsmo_role_dn, &sdsa->partition->nc.guid);
+ ret = dsdb_find_guid_by_dn(ldb, nc_dn, &sdsa->partition->nc.guid);
if (ret != LDB_SUCCESS) {
DEBUG(0,(__location__ ": Failed to find GUID for %s\n",
- ldb_dn_get_linearized(fsmo_role_dn)));
+ ldb_dn_get_linearized(nc_dn)));
talloc_free(sdsa);
return WERR_DS_DRA_INTERNAL_ERROR;
}
sdsa->repsFrom1 = &sdsa->_repsFromBlob.ctr.ctr1;
- ret = dsdb_find_guid_by_dn(ldb, role_owner_dn, &sdsa->repsFrom1->source_dsa_obj_guid);
+ ret = dsdb_find_guid_by_dn(ldb, source_dsa_dn, &sdsa->repsFrom1->source_dsa_obj_guid);
if (ret != LDB_SUCCESS) {
DEBUG(0,(__location__ ": Failed to find objectGUID for %s\n",
- ldb_dn_get_linearized(role_owner_dn)));
+ ldb_dn_get_linearized(source_dsa_dn)));
talloc_free(sdsa);
return WERR_DS_DRA_INTERNAL_ERROR;
}
@@ -99,15 +102,35 @@ WERROR drepl_create_role_owner_source_dsa(struct dreplsrv_service *service,
werr = dreplsrv_out_connection_attach(service, sdsa->repsFrom1, &sdsa->conn);
if (!W_ERROR_IS_OK(werr)) {
DEBUG(0,(__location__ ": Failed to attach connection to %s\n",
- ldb_dn_get_linearized(fsmo_role_dn)));
+ ldb_dn_get_linearized(nc_dn)));
talloc_free(sdsa);
return werr;
}
- service->ncchanges_extended.role_owner_source_dsa = sdsa;
+ *_sdsa = sdsa;
return WERR_OK;
}
+struct extended_op_data {
+ dreplsrv_fsmo_callback_t callback;
+ void *callback_data;
+ struct dreplsrv_partition_source_dsa *sdsa;
+};
+
+/*
+ called when an extended op finishes
+ */
+static void extended_op_callback(struct dreplsrv_service *service,
+ WERROR err,
+ enum drsuapi_DsExtendedError exop_error,
+ void *cb_data)
+{
+ struct extended_op_data *data = talloc_get_type_abort(cb_data, struct extended_op_data);
+ talloc_free(data->sdsa);
+ data->callback(service, err, exop_error, data->callback_data);
+ talloc_free(data);
+}
+
/*
schedule a getncchanges request to the role owner for an extended operation
*/
@@ -115,20 +138,31 @@ WERROR drepl_request_extended_op(struct dreplsrv_service *service,
struct ldb_dn *fsmo_role_dn,
struct ldb_dn *role_owner_dn,
enum drsuapi_DsExtendedOperation extended_op,
- uint64_t alloc_pool,
- dreplsrv_fsmo_callback_t callback)
+ uint64_t fsmo_info,
+ dreplsrv_fsmo_callback_t callback,
+ void *callback_data)
{
WERROR werr;
- if (service->ncchanges_extended.role_owner_source_dsa == NULL) {
- /* we need to establish a connection to the role owner */
- werr = drepl_create_role_owner_source_dsa(service, fsmo_role_dn, role_owner_dn);
- W_ERROR_NOT_OK_RETURN(werr);
- }
+ struct extended_op_data *data;
+ struct dreplsrv_partition_source_dsa *sdsa;
+
+ werr = drepl_create_role_owner_source_dsa(service, role_owner_dn, fsmo_role_dn, &sdsa);
+ W_ERROR_NOT_OK_RETURN(werr);
+
+ data = talloc(service, struct extended_op_data);
+ W_ERROR_HAVE_NO_MEMORY(data);
- service->ncchanges_extended.in_progress = true;
- werr = dreplsrv_schedule_partition_pull_source(service, service->ncchanges_extended.role_owner_source_dsa,
- extended_op, alloc_pool,
- callback, NULL);
+ data->callback = callback;
+ data->callback_data = callback_data;
+ data->sdsa = sdsa;
+
+ werr = dreplsrv_schedule_partition_pull_source(service, sdsa,
+ extended_op, fsmo_info,
+ extended_op_callback, data);
+ if (!W_ERROR_IS_OK(werr)) {
+ talloc_free(sdsa);
+ talloc_free(data);
+ }
return werr;
}
@@ -147,11 +181,7 @@ static void drepl_new_rid_pool_callback(struct dreplsrv_service *service,
DEBUG(3,(__location__ ": RID Manager completed RID allocation OK\n"));
}
- /* don't keep the connection open to the RID Manager */
- talloc_free(service->ncchanges_extended.role_owner_source_dsa);
- service->ncchanges_extended.role_owner_source_dsa = NULL;
-
- service->ncchanges_extended.in_progress = false;
+ service->rid_alloc_in_progress = false;
}
/*
@@ -167,7 +197,10 @@ static WERROR drepl_request_new_rid_pool(struct dreplsrv_service *service,
fsmo_role_dn,
DRSUAPI_EXOP_FSMO_RID_ALLOC,
alloc_pool,
- drepl_new_rid_pool_callback);
+ drepl_new_rid_pool_callback, NULL);
+ if (W_ERROR_IS_OK(werr)) {
+ service->rid_alloc_in_progress = true;
+ }
return werr;
}
@@ -271,7 +304,7 @@ WERROR dreplsrv_ridalloc_check_rid_pool(struct dreplsrv_service *service)
int ret;
uint64_t alloc_pool;
- if (service->ncchanges_extended.in_progress) {
+ if (service->rid_alloc_in_progress) {
talloc_free(tmp_ctx);
return WERR_OK;
}
diff --git a/source4/dsdb/repl/drepl_service.h b/source4/dsdb/repl/drepl_service.h
index dba9a37bae..fac555c2e3 100644
--- a/source4/dsdb/repl/drepl_service.h
+++ b/source4/dsdb/repl/drepl_service.h
@@ -216,10 +216,8 @@ struct dreplsrv_service {
struct dreplsrv_notify_operation *n_current;
} ops;
- struct {
- bool in_progress;
- struct dreplsrv_partition_source_dsa *role_owner_source_dsa;
- } ncchanges_extended;
+ bool rid_alloc_in_progress;
+ bool role_transfer_in_progress;
bool syncall_workaround;
};