+done:
+ slap_sync_cookie_free( &syncCookie, 0 );
+ slap_sync_cookie_free( &syncCookie_req, 0 );
+
+ if ( res ) ldap_msgfree( res );
+
+ if ( rc && si->si_ld ) {
+ ldap_unbind( si->si_ld );
+ si->si_ld = NULL;
+ }
+
+ return rc;
+}
+
+void *
+do_syncrepl(
+ void *ctx,
+ void *arg )
+{
+ struct re_s* rtask = arg;
+ syncinfo_t *si = ( syncinfo_t * ) rtask->arg;
+ Connection conn = {0};
+ Operation op = {0};
+ int rc = LDAP_SUCCESS;
+ int first = 0;
+ int dostop = 0;
+ ber_socket_t s;
+
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, DETAIL1, "do_syncrepl\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE, "=>do_syncrepl\n", 0, 0, 0 );
+#endif
+
+ if ( si == NULL )
+ return NULL;
+
+ switch( abs( si->si_type )) {
+ case LDAP_SYNC_REFRESH_ONLY:
+ case LDAP_SYNC_REFRESH_AND_PERSIST:
+ break;
+ default:
+ return NULL;
+ }
+
+ if ( slapd_abrupt_shutdown && si->si_ld ) {
+ ldap_get_option( si->si_ld, LDAP_OPT_DESC, &s );
+ connection_client_stop( s );
+ ldap_unbind( si->si_ld );
+ si->si_ld = NULL;
+ return NULL;
+ }
+
+ conn.c_connid = -1;
+ conn.c_send_ldap_result = slap_send_ldap_result;
+ conn.c_send_search_entry = slap_send_search_entry;
+ conn.c_send_search_reference = slap_send_search_reference;
+ conn.c_listener = (Listener *)&dummy_list;
+ conn.c_peer_name = slap_empty_bv;
+
+ /* set memory context */
+#define SLAB_SIZE 1048576
+ op.o_tmpmemctx = sl_mem_create( SLAB_SIZE, ctx );
+ op.o_tmpmfuncs = &sl_mfuncs;
+
+ op.o_dn = si->si_updatedn;
+ op.o_ndn = si->si_updatedn;
+ op.o_time = slap_get_time();
+ op.o_threadctx = ctx;
+ op.o_managedsait = 1;
+ op.o_bd = si->si_be;
+ op.o_conn = &conn;
+ op.o_connid = op.o_conn->c_connid;
+
+ op.o_sync_state.ctxcsn = NULL;
+ op.o_sync_state.sid = -1;
+ op.o_sync_state.octet_str = NULL;
+ op.o_sync_slog_size = -1;
+ LDAP_STAILQ_FIRST( &op.o_sync_slog_list ) = NULL;
+ op.o_sync_slog_list.stqh_last = &LDAP_STAILQ_FIRST(&op.o_sync_slog_list);
+
+ /* Establish session, do search */
+ if ( !si->si_ld ) {
+ first = 1;
+ rc = do_syncrep1( &op, si );
+ }
+
+ /* Process results */
+ if ( rc == LDAP_SUCCESS ) {
+ ldap_get_option( si->si_ld, LDAP_OPT_DESC, &s );
+
+ rc = do_syncrep2( &op, si );
+
+ if ( abs(si->si_type) == LDAP_SYNC_REFRESH_AND_PERSIST ) {
+ /* If we succeeded, enable the connection for further listening.
+ * If we failed, tear down the connection and reschedule.
+ */
+ if ( rc == LDAP_SUCCESS ) {
+ if ( first ) {
+ rc = connection_client_setup( s, (Listener *)&dummy_list, do_syncrepl,
+ arg );
+ } else {
+ connection_client_enable( s );
+ }
+ } else if ( !first ) {
+ dostop = 1;
+ }
+ } else {
+ if ( rc == -2 ) rc = 0;
+ }
+ }
+
+ /* At this point, we have 4 cases:
+ * 1) for any hard failure, give up and remove this task
+ * 2) for ServerDown, reschedule this task to run
+ * 3) for Refresh and Success, reschedule to run
+ * 4) for Persist and Success, reschedule to defer
+ */
+ ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex );
+ if ( ldap_pvt_runqueue_isrunning( &syncrepl_rq, rtask )) {
+ ldap_pvt_runqueue_stoptask( &syncrepl_rq, rtask );
+ }