ctxcsn.c 4.9 KB
Newer Older
Kurt Zeilenga's avatar
Kurt Zeilenga committed
1
/* ctxcsn.c -- Context CSN Management Routines */
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
2
/* $OpenLDAP$ */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
3
4
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 *
Kurt Zeilenga's avatar
Kurt Zeilenga committed
5
 * Copyright 2003-2008 The OpenLDAP Foundation.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
6
7
 * Portions Copyright 2003 IBM Corporation.
 * All rights reserved.
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
8
 *
Kurt Zeilenga's avatar
Kurt Zeilenga committed
9
10
11
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
12
 *
Kurt Zeilenga's avatar
Kurt Zeilenga committed
13
14
15
 * A copy of this license is available in the file LICENSE in the
 * top-level directory of the distribution or, alternatively, at
 * <http://www.OpenLDAP.org/license.html>.
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
16
17
18
19
20
21
22
23
24
25
26
27
28
 */

#include "portable.h"

#include <stdio.h>

#include <ac/string.h>
#include <ac/socket.h>

#include "lutil.h"
#include "slap.h"
#include "lutil_ldap.h"

Howard Chu's avatar
Howard Chu committed
29
30
const struct berval slap_ldapsync_bv = BER_BVC("ldapsync");
const struct berval slap_ldapsync_cn_bv = BER_BVC("cn=ldapsync");
31
int slap_serverID;
Howard Chu's avatar
Howard Chu committed
32
33

void
34
35
slap_get_commit_csn(
	Operation *op,
36
	struct berval *maxcsn
37
)
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
38
{
39
	struct slap_csn_entry *csne, *committed_csne = NULL;
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
40

41
42
43
	if ( maxcsn ) {
		BER_BVZERO( maxcsn );
	}
Howard Chu's avatar
Howard Chu committed
44

45
	ldap_pvt_thread_mutex_lock( op->o_bd->be_pcl_mutexp );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
46

Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
47
	LDAP_TAILQ_FOREACH( csne, op->o_bd->be_pending_csn_list, ce_csn_link ) {
Kurt Zeilenga's avatar
cleanup    
Kurt Zeilenga committed
48
49
		if ( csne->ce_opid == op->o_opid && csne->ce_connid == op->o_connid ) {
			csne->ce_state = SLAP_CSN_COMMIT;
50
51
			break;
		}
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
52
53
	}

Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
54
	LDAP_TAILQ_FOREACH( csne, op->o_bd->be_pending_csn_list, ce_csn_link ) {
Kurt Zeilenga's avatar
cleanup    
Kurt Zeilenga committed
55
56
		if ( csne->ce_state == SLAP_CSN_COMMIT ) committed_csne = csne;
		if ( csne->ce_state == SLAP_CSN_PENDING ) break;
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
57
	}
58

59
	if ( committed_csne && maxcsn ) *maxcsn = committed_csne->ce_csn;
60
	ldap_pvt_thread_mutex_unlock( op->o_bd->be_pcl_mutexp );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
61
62
63
}

void
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
64
slap_rewind_commit_csn( Operation *op )
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
65
{
66
	struct slap_csn_entry *csne;
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
67

68
	ldap_pvt_thread_mutex_lock( op->o_bd->be_pcl_mutexp );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
69

Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
70
	LDAP_TAILQ_FOREACH( csne, op->o_bd->be_pending_csn_list, ce_csn_link ) {
Kurt Zeilenga's avatar
cleanup    
Kurt Zeilenga committed
71
72
		if ( csne->ce_opid == op->o_opid && csne->ce_connid == op->o_connid ) {
			csne->ce_state = SLAP_CSN_PENDING;
73
74
			break;
		}
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
75
76
	}

77
	ldap_pvt_thread_mutex_unlock( op->o_bd->be_pcl_mutexp );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
78
79
80
}

void
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
81
slap_graduate_commit_csn( Operation *op )
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
82
{
83
	struct slap_csn_entry *csne;
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
84

Kurt Zeilenga's avatar
cleanup    
Kurt Zeilenga committed
85
86
	if ( op == NULL ) return;
	if ( op->o_bd == NULL ) return;
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
87

88
89
90
#if 0
	/* it is NULL when we get here from the frontendDB;
	 * alternate fix: initialize frontendDB like all other backends */
91
	assert( op->o_bd->be_pcl_mutexp != NULL );
92
93
94
#endif
	
	if ( op->o_bd->be_pcl_mutexp == NULL ) return;
95

96
	ldap_pvt_thread_mutex_lock( op->o_bd->be_pcl_mutexp );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
97

Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
98
	LDAP_TAILQ_FOREACH( csne, op->o_bd->be_pending_csn_list, ce_csn_link ) {
Kurt Zeilenga's avatar
cleanup    
Kurt Zeilenga committed
99
		if ( csne->ce_opid == op->o_opid && csne->ce_connid == op->o_connid ) {
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
100
			LDAP_TAILQ_REMOVE( op->o_bd->be_pending_csn_list,
Kurt Zeilenga's avatar
cleanup    
Kurt Zeilenga committed
101
				csne, ce_csn_link );
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
102
103
			Debug( LDAP_DEBUG_SYNC, "slap_graduate_commit_csn: removing %p %s\n",
				csne->ce_csn.bv_val, csne->ce_csn.bv_val, 0 );
Howard Chu's avatar
Howard Chu committed
104
105
106
			if ( op->o_csn.bv_val == csne->ce_csn.bv_val ) {
				BER_BVZERO( &op->o_csn );
			}
107
			ch_free( csne->ce_csn.bv_val );
108
109
110
			ch_free( csne );
			break;
		}
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
111
112
	}

113
	ldap_pvt_thread_mutex_unlock( op->o_bd->be_pcl_mutexp );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
114
115
116
117

	return;
}

118
119
120
121
static struct berval ocbva[] = {
	BER_BVC("top"),
	BER_BVC("subentry"),
	BER_BVC("syncProviderSubentry"),
Pierangelo Masarati's avatar
Pierangelo Masarati committed
122
	BER_BVNULL
123
124
};

Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
125
Entry *
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
126
slap_create_context_csn_entry(
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
127
	Backend *be,
Kurt Zeilenga's avatar
cleanup    
Kurt Zeilenga committed
128
	struct berval *context_csn )
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
129
130
131
{
	Entry* e;

132
	struct berval bv;
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
133

134
	e = entry_alloc();
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
135

Kurt Zeilenga's avatar
Kurt Zeilenga committed
136
137
138
139
140
141
	attr_merge( e, slap_schema.si_ad_objectClass,
		ocbva, NULL );
	attr_merge_one( e, slap_schema.si_ad_structuralObjectClass,
		&ocbva[1], NULL );
	attr_merge_one( e, slap_schema.si_ad_cn,
		(struct berval *)&slap_ldapsync_bv, NULL );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
142

143
144
145
	if ( context_csn ) {
		attr_merge_one( e, slap_schema.si_ad_contextCSN,
			context_csn, NULL );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
146
147
	}

Pierangelo Masarati's avatar
Pierangelo Masarati committed
148
	BER_BVSTR( &bv, "{}" );
149
150
	attr_merge_one( e, slap_schema.si_ad_subtreeSpecification, &bv, NULL );

Kurt Zeilenga's avatar
Kurt Zeilenga committed
151
152
	build_new_dn( &e->e_name, &be->be_nsuffix[0],
		(struct berval *)&slap_ldapsync_cn_bv, NULL );
Howard Chu's avatar
Howard Chu committed
153
	ber_dupbv( &e->e_nname, &e->e_name );
154

Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
155
156
157
	return e;
}

158
159
160
161
162
163
164
165
166
void
slap_queue_csn(
	Operation *op,
	struct berval *csn )
{
	struct slap_csn_entry *pending;

	pending = (struct slap_csn_entry *) ch_calloc( 1,
			sizeof( struct slap_csn_entry ));
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
167
168
169

	Debug( LDAP_DEBUG_SYNC, "slap_queue_csn: queing %p %s\n", csn->bv_val, csn->bv_val, 0 );

170
171
	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
175
176
177
178
179
180
181
	pending->ce_connid = op->o_connid;
	pending->ce_opid = op->o_opid;
	pending->ce_state = SLAP_CSN_PENDING;
	LDAP_TAILQ_INSERT_TAIL( op->o_bd->be_pending_csn_list,
		pending, ce_csn_link );
	ldap_pvt_thread_mutex_unlock( op->o_bd->be_pcl_mutexp );
}

Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
182
183
184
185
int
slap_get_csn(
	Operation *op,
	struct berval *csn,
Kurt Zeilenga's avatar
cleanup    
Kurt Zeilenga committed
186
	int manage_ctxcsn )
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
187
{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
188
	if ( csn == NULL ) return LDAP_OTHER;
189

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 );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
194

195
196
	if ( manage_ctxcsn )
		slap_queue_csn( op, csn );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
197
198
199

	return LDAP_SUCCESS;
}