drepl_reps_update(s, "repsTo", op->source_dsa->partition->dn,
&op->source_dsa->repsFrom1->source_dsa_obj_guid,
werr);
+ /* Decrement the number of call that are using this source */
+ op->source_dsa->used--;
+ SMB_ASSERT(op->source_dsa->used >= 0);
+ DEBUG(10, ("Source DSA to %s partition %s is still used in %d calls\n",
+ op->source_dsa->repsFrom1->other_info->dns_name,
+ ldb_dn_get_linearized(op->source_dsa->partition->dn),
+ op->source_dsa->used));
talloc_free(op);
s->ops.n_current = NULL;
op->replica_flags = replica_flags;
op->schedule_time = time(NULL);
+ s->used++;
DLIST_ADD_END(service->ops.notifies, op, struct dreplsrv_notify_operation *);
talloc_steal(service, op);
return WERR_OK;
op->callback = callback;
op->cb_data = cb_data;
op->schedule_time = time(NULL);
+ source->used++;
DLIST_ADD_END(s->ops.pending, op, struct dreplsrv_out_operation *);
if (op->callback) {
op->callback(s, werr, op->extended_ret, op->cb_data);
}
+ op->source_dsa->used--;
+ SMB_ASSERT(op->source_dsa->used >= 0);
talloc_free(op);
s->ops.current = NULL;
dreplsrv_run_pending_ops(s);
drepl_reps_update(s, "repsFrom", op->source_dsa->partition->dn,
&op->source_dsa->repsFrom1->source_dsa_obj_guid, werr);
}
+ op->source_dsa->used--;
+ SMB_ASSERT(op->source_dsa->used >= 0);
+
/* unblock queue processing */
s->ops.current = NULL;
/*
struct dreplsrv_partition *p,
struct dreplsrv_partition_source_dsa **listp,
struct dreplsrv_partition_source_dsa *check_list,
+ struct dreplsrv_partition_source_dsa **oldlist,
const struct ldb_val *val)
{
WERROR status;
}
/* re-use an existing source if found */
- for (s2=*listp; s2; s2=s2->next) {
+ for (s2=*oldlist; s2; s2=s2->next) {
if (GUID_compare(&s2->repsFrom1->source_dsa_obj_guid,
&source->repsFrom1->source_dsa_obj_guid) == 0) {
talloc_free(s2->repsFrom1->other_info);
*s2->repsFrom1 = *source->repsFrom1;
talloc_steal(s2, s2->repsFrom1->other_info);
talloc_free(source);
- return WERR_OK;
+ source = s2;
+ DLIST_REMOVE(*oldlist, s2);
+ break;
}
}
NULL
};
struct ldb_dn *dn;
+ struct dreplsrv_partition_source_dsa *src, *oldsources, *oldnotifies;
DEBUG(4, ("dreplsrv_refresh_partition(%s)\n",
ldb_dn_get_linearized(p->dn)));
status = WERR_OK;
+ oldsources = p->sources;
+ p->sources = NULL;
if (r != NULL && (orf_el = ldb_msg_find_element(r->msgs[0], "repsFrom"))) {
for (i=0; i < orf_el->num_values; i++) {
status = dreplsrv_partition_add_source_dsa(s, p, &p->sources,
- NULL, &orf_el->values[i]);
+ NULL, &oldsources,
+ &orf_el->values[i]);
W_ERROR_NOT_OK_GOTO_DONE(status);
}
+ } else {
+ if (r != NULL && p->sources) {
+ DEBUG(0, ("repsFrom do not exists or is empty\n"));
+ }
}
+ oldnotifies = p->notifies;
+ p->notifies = NULL;
if (r != NULL && (orf_el = ldb_msg_find_element(r->msgs[0], "repsTo"))) {
for (i=0; i < orf_el->num_values; i++) {
status = dreplsrv_partition_add_source_dsa(s, p, &p->notifies,
- p->sources, &orf_el->values[i]);
+ p->sources,
+ &oldnotifies,
+ &orf_el->values[i]);
W_ERROR_NOT_OK_GOTO_DONE(status);
}
}
+ if (oldsources) {
+ src = oldsources;
+ while(src) {
+ struct dreplsrv_partition_source_dsa *tmp = src->next;
+
+ /*
+ * Keep sources that are still in use or we can
+ * face some strange behavior
+ */
+
+ if (src->used > 0) {
+ DLIST_ADD(p->sources, src);
+ } else {
+ talloc_free(src);
+ }
+ src = tmp;
+ }
+ }
+
+
+ if (oldnotifies) {
+ src = oldnotifies;
+ while(src) {
+ struct dreplsrv_partition_source_dsa *tmp = src->next;
+
+ /*
+ * Keep sources that are still in use or we can
+ * face some strange behavior
+ */
+
+ if (src->used > 0) {
+ DLIST_ADD(p->sources, src);
+ } else {
+ talloc_free(src);
+ }
+ src = tmp;
+ }
+ }
+
done:
talloc_free(mem_ctx);
return status;