1 /* ctxcsn.c -- Context CSN Management Routines */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/ctxcsn.c,v 1.40.2.6 2008/02/12 00:44:15 quanah Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2003-2008 The OpenLDAP Foundation.
6 * Portions Copyright 2003 IBM Corporation.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
22 #include <ac/string.h>
23 #include <ac/socket.h>
27 #include "lutil_ldap.h"
29 const struct berval slap_ldapsync_bv
= BER_BVC("ldapsync");
30 const struct berval slap_ldapsync_cn_bv
= BER_BVC("cn=ldapsync");
39 struct slap_csn_entry
*csne
, *committed_csne
= NULL
;
45 ldap_pvt_thread_mutex_lock( op
->o_bd
->be_pcl_mutexp
);
47 LDAP_TAILQ_FOREACH( csne
, op
->o_bd
->be_pending_csn_list
, ce_csn_link
) {
48 if ( csne
->ce_opid
== op
->o_opid
&& csne
->ce_connid
== op
->o_connid
) {
49 csne
->ce_state
= SLAP_CSN_COMMIT
;
54 LDAP_TAILQ_FOREACH( csne
, op
->o_bd
->be_pending_csn_list
, ce_csn_link
) {
55 if ( csne
->ce_state
== SLAP_CSN_COMMIT
) committed_csne
= csne
;
56 if ( csne
->ce_state
== SLAP_CSN_PENDING
) break;
59 if ( committed_csne
&& maxcsn
) *maxcsn
= committed_csne
->ce_csn
;
60 ldap_pvt_thread_mutex_unlock( op
->o_bd
->be_pcl_mutexp
);
64 slap_rewind_commit_csn( Operation
*op
)
66 struct slap_csn_entry
*csne
;
68 ldap_pvt_thread_mutex_lock( op
->o_bd
->be_pcl_mutexp
);
70 LDAP_TAILQ_FOREACH( csne
, op
->o_bd
->be_pending_csn_list
, ce_csn_link
) {
71 if ( csne
->ce_opid
== op
->o_opid
&& csne
->ce_connid
== op
->o_connid
) {
72 csne
->ce_state
= SLAP_CSN_PENDING
;
77 ldap_pvt_thread_mutex_unlock( op
->o_bd
->be_pcl_mutexp
);
81 slap_graduate_commit_csn( Operation
*op
)
83 struct slap_csn_entry
*csne
;
85 if ( op
== NULL
) return;
86 if ( op
->o_bd
== NULL
) return;
89 /* it is NULL when we get here from the frontendDB;
90 * alternate fix: initialize frontendDB like all other backends */
91 assert( op
->o_bd
->be_pcl_mutexp
!= NULL
);
94 if ( op
->o_bd
->be_pcl_mutexp
== NULL
) return;
96 ldap_pvt_thread_mutex_lock( op
->o_bd
->be_pcl_mutexp
);
98 LDAP_TAILQ_FOREACH( csne
, op
->o_bd
->be_pending_csn_list
, ce_csn_link
) {
99 if ( csne
->ce_opid
== op
->o_opid
&& csne
->ce_connid
== op
->o_connid
) {
100 LDAP_TAILQ_REMOVE( op
->o_bd
->be_pending_csn_list
,
102 Debug( LDAP_DEBUG_SYNC
, "slap_graduate_commit_csn: removing %p %s\n",
103 csne
->ce_csn
.bv_val
, csne
->ce_csn
.bv_val
, 0 );
104 if ( op
->o_csn
.bv_val
== csne
->ce_csn
.bv_val
) {
105 BER_BVZERO( &op
->o_csn
);
107 ch_free( csne
->ce_csn
.bv_val
);
113 ldap_pvt_thread_mutex_unlock( op
->o_bd
->be_pcl_mutexp
);
118 static struct berval ocbva
[] = {
121 BER_BVC("syncProviderSubentry"),
126 slap_create_context_csn_entry(
128 struct berval
*context_csn
)
136 attr_merge( e
, slap_schema
.si_ad_objectClass
,
138 attr_merge_one( e
, slap_schema
.si_ad_structuralObjectClass
,
140 attr_merge_one( e
, slap_schema
.si_ad_cn
,
141 (struct berval
*)&slap_ldapsync_bv
, NULL
);
144 attr_merge_one( e
, slap_schema
.si_ad_contextCSN
,
148 BER_BVSTR( &bv
, "{}" );
149 attr_merge_one( e
, slap_schema
.si_ad_subtreeSpecification
, &bv
, NULL
);
151 build_new_dn( &e
->e_name
, &be
->be_nsuffix
[0],
152 (struct berval
*)&slap_ldapsync_cn_bv
, NULL
);
153 ber_dupbv( &e
->e_nname
, &e
->e_name
);
163 struct slap_csn_entry
*pending
;
165 pending
= (struct slap_csn_entry
*) ch_calloc( 1,
166 sizeof( struct slap_csn_entry
));
168 Debug( LDAP_DEBUG_SYNC
, "slap_queue_csn: queing %p %s\n", csn
->bv_val
, csn
->bv_val
, 0 );
170 ldap_pvt_thread_mutex_lock( op
->o_bd
->be_pcl_mutexp
);
172 ber_dupbv( &pending
->ce_csn
, csn
);
173 ber_bvreplace_x( &op
->o_csn
, &pending
->ce_csn
, op
->o_tmpmemctx
);
174 pending
->ce_connid
= op
->o_connid
;
175 pending
->ce_opid
= op
->o_opid
;
176 pending
->ce_state
= SLAP_CSN_PENDING
;
177 LDAP_TAILQ_INSERT_TAIL( op
->o_bd
->be_pending_csn_list
,
178 pending
, ce_csn_link
);
179 ldap_pvt_thread_mutex_unlock( op
->o_bd
->be_pcl_mutexp
);
188 if ( csn
== NULL
) return LDAP_OTHER
;
190 /* gmtime doesn't always need a mutex, but lutil_csnstr does */
191 ldap_pvt_thread_mutex_lock( &gmtime_mutex
);
192 csn
->bv_len
= lutil_csnstr( csn
->bv_val
, csn
->bv_len
, slap_serverID
, 0 );
193 ldap_pvt_thread_mutex_unlock( &gmtime_mutex
);
196 slap_queue_csn( op
, csn
);