Bläddra i källkod

Bug 531642 - EntryUSN: RFE: a configuration option to make entryusn "global"

https://bugzilla.redhat.com/show_bug.cgi?id=531642
Resolves: 531642
Fix description:
1. Introduced a config parameter nsslapd-entryusn-global: on|off to
   enable | disable the global mode.  By default, off.
   In the global mode, search on root dse returns "lastusn: <num>"
   without the backend subtype (e.g., "lastusn;userroot: <num>")
2. Added slapi_get_next_suffix_ext to mapping_tree.c, which visits
   children as well as siblings in the mapping tree.
   (Note: slapi_get_next_suffix does just siblings.)
3. import (ldif2db) adds "entryusn: 0" to every entry unless the
   entry already contains the entryusn attribute.
4. ldbm_back_delete, ldbm_back_modify, ldbm_back_modrdn: set
   ldap_result_code to pblock so that bepost plugin could see if
   the operation was successful or not.
See also http://directory.fedoraproject.org/wiki/Entry_USN#Global_mode
Noriko Hosoi 15 år sedan
förälder
incheckning
a0282b832d

+ 45 - 18
ldap/servers/plugins/usn/usn.c

@@ -565,31 +565,58 @@ usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter,
     int attr_len = 64; /* length of lastusn;<backend_name> */
     char *attr = (char *)slapi_ch_malloc(attr_len);
     char *attr_subp = NULL;
+    int isglobal = config_get_entryusn_global();
 
     slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
                     "--> usn_rootdse_search\n");
 
     usn_berval.bv_val = counter_buf;
-    PR_snprintf(attr, USN_LAST_USN_ATTR_CORE_LEN+1, "%s;", USN_LAST_USN);
-    attr_subp = attr + USN_LAST_USN_ATTR_CORE_LEN;
-    for (be = slapi_get_first_backend(&cookie); be;
-         be = slapi_get_next_backend(cookie)) {
-        if (NULL == be->be_usn_counter) { /* no counter == not a db backend */
-            continue;
+    if (isglobal) {
+        /* nsslapd-entryusn-global: on*/
+        /* root dse shows ...
+         * lastusn: <num> */
+        PR_snprintf(attr, USN_LAST_USN_ATTR_CORE_LEN + 1, "%s", USN_LAST_USN);
+        for (be = slapi_get_first_backend(&cookie); be;
+             be = slapi_get_next_backend(cookie)) {
+            if (be->be_usn_counter) {
+                break;
+            }
+        }
+        if (be->be_usn_counter) {
+            /* get a next USN counter from be_usn_counter; 
+             * then minus 1 from it */
+            PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRI64 "d",
+                                slapi_counter_get_value(be->be_usn_counter)-1);
+            usn_berval.bv_len = strlen(usn_berval.bv_val);
+            slapi_entry_attr_replace(e, attr, vals);
         }
-        /* get a next USN counter from be_usn_counter; then minus 1 from it */
-        PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRI64 "d", 
-                                 slapi_counter_get_value(be->be_usn_counter)-1);
-        usn_berval.bv_len = strlen(usn_berval.bv_val);
-
-        if (USN_LAST_USN_ATTR_CORE_LEN + strlen(be->be_name) + 1 > attr_len) {
-            attr_len *= 2;
-            attr = (char *)slapi_ch_realloc(attr, attr_len);
-            attr_subp = attr + USN_LAST_USN_ATTR_CORE_LEN;
+    } else {
+        /* nsslapd-entryusn-global: off (default) */
+        /* root dse shows ...
+         * lastusn;<backend>: <num> */
+        PR_snprintf(attr, USN_LAST_USN_ATTR_CORE_LEN + 2, "%s;", USN_LAST_USN);
+        attr_subp = attr + USN_LAST_USN_ATTR_CORE_LEN + 1;
+        for (be = slapi_get_first_backend(&cookie); be;
+             be = slapi_get_next_backend(cookie)) {
+            if (NULL == be->be_usn_counter) {
+                /* no counter == not a db backend */
+                continue;
+            }
+            /* get a next USN counter from be_usn_counter; 
+             * then minus 1 from it */
+            PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRI64 "d",
+                                slapi_counter_get_value(be->be_usn_counter)-1);
+            usn_berval.bv_len = strlen(usn_berval.bv_val);
+    
+            if (USN_LAST_USN_ATTR_CORE_LEN+strlen(be->be_name)+2 > attr_len) {
+                attr_len *= 2;
+                attr = (char *)slapi_ch_realloc(attr, attr_len);
+                attr_subp = attr + USN_LAST_USN_ATTR_CORE_LEN;
+            }
+            PR_snprintf(attr_subp, attr_len - USN_LAST_USN_ATTR_CORE_LEN,
+                                    "%s", be->be_name);
+            slapi_entry_attr_replace(e, attr, vals);
         }
-        PR_snprintf(attr_subp, attr_len - USN_LAST_USN_ATTR_CORE_LEN,
-                                "%s", be->be_name);
-        slapi_entry_attr_replace(e, attr, vals);
     }
 
     slapi_ch_free_string(&cookie);

+ 1 - 1
ldap/servers/plugins/usn/usn.h

@@ -44,7 +44,7 @@
 #define USN_CSNGEN_ID              65535
 
 #define USN_LAST_USN               "lastusn"
-#define USN_LAST_USN_ATTR_CORE_LEN 8 /* lastusn; */
+#define USN_LAST_USN_ATTR_CORE_LEN 7 /* lastusn */
 
 #define USN_COUNTER_BUF_LEN        64 /* enough size for 64 bit integers */
 

+ 4 - 0
ldap/servers/slapd/back-ldbm/back-ldbm.h

@@ -635,6 +635,7 @@ struct ldbminfo {
     int li_flags;
     int li_fat_lock;         /* 608146 -- make this configurable, first */
     int li_legacy_errcode;   /* 615428 -- in case legacy err code is expected */
+    Slapi_Counter *li_global_usn_counter; /* global USN counter */
 };
 
 /* li_flags could store these bits defined in ../slapi-plugin.h
@@ -840,4 +841,7 @@ typedef struct _back_search_result_set
  */ 
 #define LDBM_ERROR_FOUND_DUPDN 9999
 
+/* Initial entryusn value */
+#define INITIALUSN (PRUint64)(-1)
+
 #endif /* _back_ldbm_h_ */

+ 4 - 0
ldap/servers/slapd/back-ldbm/dblayer.c

@@ -657,6 +657,10 @@ int dblayer_terminate(struct ldbminfo *li)
     slapi_ch_free((void**)&priv);
     li->li_dblayer_private = NULL;
 
+    if (config_get_entryusn_global()) {
+        slapi_counter_destroy(&li->li_global_usn_counter);
+    }
+
     return 0;
 }
 

+ 23 - 4
ldap/servers/slapd/back-ldbm/import-threads.c

@@ -666,11 +666,30 @@ import_producer(void *param)
             pw_encodevals( (Slapi_Value **)va ); /* jcm - cast away const */
         }
 
-         if (job->flags & FLAG_ABORT) { 
-             backentry_free(&ep);
-             goto error;
-         }
+        if (job->flags & FLAG_ABORT) { 
+            backentry_free(&ep);
+            goto error;
+        }
 
+        /* 
+         * Check if entryusn plugin is enabled.  
+         * If yes, add "entryusn: 0" to the entry 
+         * if it does not have the attr type .
+         */
+        if (plugin_enabled("USN", (void *)plugin_get_default_component_id())) {
+            if (slapi_entry_attr_find(ep->ep_entry, SLAPI_ATTR_ENTRYUSN,
+                                                      &attr)) { /* not found */
+                /* add entryusn: 0 to the entry */
+                Slapi_Value *usn_value = NULL;
+                struct berval usn_berval = {0};
+                usn_berval.bv_val = slapi_ch_smprintf("0");
+                usn_berval.bv_len = strlen(usn_berval.bv_val);
+                usn_value = slapi_value_new_berval(&usn_berval);
+                slapi_entry_add_value(ep->ep_entry,
+                                      SLAPI_ATTR_ENTRYUSN, usn_value);
+                slapi_value_free(&usn_value);
+            }
+        }
 
         /* Now we have this new entry, all decoded
          * Next thing we need to do is:

+ 2 - 0
ldap/servers/slapd/back-ldbm/ldbm_delete.c

@@ -892,6 +892,8 @@ common_return:
 		backentry_free( &tombstone );
 	}
 	
+	/* result code could be used in the bepost plugin functions. */
+	slapi_pblock_get(pb, SLAPI_RESULT_CODE, &ldap_result_code);
 	/*
 	 * The bepostop is called even if the operation fails,
 	 * but not if the operation is purging tombstones.

+ 15 - 3
ldap/servers/slapd/back-ldbm/ldbm_instance_config.c

@@ -855,9 +855,21 @@ static int ldbm_instance_generate(struct ldbminfo *li, char *instance_name,
     rc = ldbm_instance_create_default_indexes(new_be);
 
     /* if USN plugin is enabled, set slapi_counter */
-    if (plugin_enabled("USN", li->li_identity)) {
-        /* slapi_counter_new sets the initial value to 0 */
-        new_be->be_usn_counter = slapi_counter_new();
+    if (plugin_enabled("USN", li->li_identity) && ldbm_back_isinitialized()) {
+        /* 
+         * ldbm_back is already initialized. 
+         * I.e., a new instance is being added.
+         * If not initialized, ldbm_usn_init is called later and
+         * be usn counter is initialized there.
+         */
+        if (config_get_entryusn_global()) {
+            /* global usn counter is already created. 
+             * set it to be_usn_counter. */
+            new_be->be_usn_counter = li->li_global_usn_counter;
+        } else {
+            new_be->be_usn_counter = slapi_counter_new();
+            slapi_counter_set_value(new_be->be_usn_counter, INITIALUSN);
+        }
     }
 
     if (ret_be != NULL) {

+ 7 - 4
ldap/servers/slapd/back-ldbm/ldbm_modify.c

@@ -332,7 +332,6 @@ ldbm_back_modify( Slapi_PBlock *pb )
 		}
 		if ( !change_entry || ldap_result_code != 0 ) {
 			/* change_entry == 0 is not an error, but we need to free lock etc */
-			slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code);
 			goto error_return;
 		}
 	}
@@ -550,7 +549,11 @@ common_return:
 	{
 		CACHE_RETURN( &inst->inst_cache, &ec );
 	}
-	/* JCMREPL - The bepostop is called even if the operation fails. */
+
+	/* result code could be used in the bepost plugin functions. */
+	slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code);
+
+	/* The bepostop is called even if the operation fails. */
 	if (!disk_full)
 		plugin_call_plugins (pb, SLAPI_PLUGIN_BE_POST_MODIFY_FN);
 
@@ -560,10 +563,10 @@ common_return:
 	}
 	if(ldap_result_code!=-1)
 	{
-    	slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL );
+		slapi_send_ldap_result( pb, ldap_result_code, NULL, ldap_result_message, 0, NULL );
 	}
 	
-    slapi_ch_free( (void**)&errbuf);
+	slapi_ch_free_string(&errbuf);
 	return rc;
 }
 

+ 3 - 0
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c

@@ -995,6 +995,9 @@ common_return:
     }
 
     moddn_unlock_and_return_entries(be,&e,&existingentry);
+
+    /* result code could be used in the bepost plugin functions. */
+    slapi_pblock_get(pb, SLAPI_RESULT_CODE, &ldap_result_code);
     /*
      * The bepostop is called even if the operation fails.
      */

+ 55 - 15
ldap/servers/slapd/back-ldbm/ldbm_usn.c

@@ -67,6 +67,9 @@ ldbm_usn_init(struct ldbminfo  *li)
     int rc = 0;
     Slapi_Backend *be = NULL;
     PRUint64 last_usn = 0;
+    PRUint64 global_last_usn = INITIALUSN;
+    int isglobal = config_get_entryusn_global();
+    int isfirst = 1;
 
     /* if USN is not enabled, return immediately */
     if (!plugin_enabled("USN", li->li_identity)) {
@@ -75,15 +78,34 @@ ldbm_usn_init(struct ldbminfo  *li)
 
     /* Search each namingContext in turn */
     for ( sdn = slapi_get_first_suffix( &node, 0 ); sdn != NULL;
-          sdn = slapi_get_next_suffix( &node, 0 )) {
+          sdn = slapi_get_next_suffix_ext( &node, 0 )) {
         be = slapi_mapping_tree_find_backend_for_sdn(sdn);
-        slapi_log_error(SLAPI_LOG_TRACE, "ldbm_usn_init",
-                        "backend: %s\n", be->be_name);
+        slapi_log_error(SLAPI_LOG_BACKLDBM, "ldbm_usn_init",
+                    "backend: %s \n", be->be_name, isglobal?"(global mode)":"");
         rc = usn_get_last_usn(be, &last_usn);
         if (0 == rc) { /* only when the last usn is available */
-            be->be_usn_counter = slapi_counter_new();
-            slapi_counter_set_value(be->be_usn_counter, last_usn);
-            slapi_counter_increment(be->be_usn_counter); /* stores next usn */
+            if (isglobal) {
+                if (isfirst) {
+                    li->li_global_usn_counter = slapi_counter_new();
+                    isfirst = 0;
+                }
+                /* share one counter */
+                be->be_usn_counter = li->li_global_usn_counter;
+                /* Initialize global_last_usn;
+                 * Set the largest last_usn among backends */
+                if ((global_last_usn == INITIALUSN) ||
+                   ((last_usn != INITIALUSN) && (global_last_usn < last_usn))) {
+                    global_last_usn = last_usn;
+                }
+                slapi_counter_set_value(be->be_usn_counter, global_last_usn);
+                /* stores next usn */
+                slapi_counter_increment(be->be_usn_counter);
+            } else {
+                be->be_usn_counter = slapi_counter_new();
+                slapi_counter_set_value(be->be_usn_counter, last_usn);
+                /* stores next usn */
+                slapi_counter_increment(be->be_usn_counter);
+            }
         }
     }
 bail:
@@ -110,7 +132,7 @@ usn_get_last_usn(Slapi_Backend *be, PRUint64 *last_usn)
     memset(&key, 0, sizeof(key));
     memset(&value, 0, sizeof(key));
 
-    *last_usn = -1; /* to start from 0 */
+    *last_usn = INITIALUSN; /* to start from 0 */
 
     /* Open the entryusn index */
     ainfo_get(be, SLAPI_ATTR_ENTRYUSN, &ai);
@@ -179,14 +201,32 @@ int
 ldbm_set_last_usn(Slapi_Backend *be)
 {
     PRUint64 last_usn = 0;
-    int rc = usn_get_last_usn(be, &last_usn);
-
-    if (0 == rc) { /* only when the last usn is available */
-        /* destroy old counter, if any */
-        slapi_counter_destroy(&(be->be_usn_counter));
-        be->be_usn_counter = slapi_counter_new();
-        slapi_counter_set_value(be->be_usn_counter, last_usn);
-        slapi_counter_increment(be->be_usn_counter); /* stores next usn */
+    PRUint64 current_usn = 0;
+    int isglobal = config_get_entryusn_global();
+    int rc = -1;
+
+    if (NULL == be) {
+        slapi_log_error(SLAPI_LOG_FATAL, "ldbm_set_last_usn",
+                        "Empty backend\n");
+        return rc;
+    }
+
+    if (isglobal) {
+       struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private;
+       /* destroy old counter, if any */
+       slapi_counter_destroy(&(li->li_global_usn_counter));
+       ldbm_usn_init(li);
+    } else {
+        slapi_log_error(SLAPI_LOG_BACKLDBM, "ldbm_set_last_usn",
+                        "backend: %s\n", be->be_name);
+        rc = usn_get_last_usn(be, &last_usn);
+        if (0 == rc) { /* only when the last usn is available */
+            /* destroy old counter, if any */
+            slapi_counter_destroy(&(be->be_usn_counter));
+            be->be_usn_counter = slapi_counter_new();
+            slapi_counter_set_value(be->be_usn_counter, last_usn);
+            slapi_counter_increment(be->be_usn_counter); /* stores next usn */
+        }
     }
 
     return rc;

+ 1 - 0
ldap/servers/slapd/back-ldbm/proto-back-ldbm.h

@@ -479,6 +479,7 @@ int ldbm_back_entry_release( Slapi_PBlock *pb, void *backend_info_ptr );
 void ldbm_back_search_results_release( void **search_results );
 int ldbm_back_init( Slapi_PBlock *pb ); 
 void ldbm_back_prev_search_results( Slapi_PBlock *pb );
+int ldbm_back_isinitialized();
 
 /*
  * monitor.c

+ 8 - 1
ldap/servers/slapd/back-ldbm/start.c

@@ -46,6 +46,14 @@
 
 #include "back-ldbm.h"
 
+static int initialized = 0;
+
+int
+ldbm_back_isinitialized()
+{
+    return initialized;
+}
+
 /*
  * Start the LDBM plugin, and all its instances.
  */
@@ -53,7 +61,6 @@ int
 ldbm_back_start( Slapi_PBlock *pb )
 {
   struct ldbminfo  *li;
-  static int initialized = 0;
   char *home_dir;
   int action;
   int retval; 

+ 3 - 1
ldap/servers/slapd/backend.c

@@ -129,7 +129,9 @@ be_done(Slapi_Backend *be)
     slapi_ch_free((void **)&be->be_backendconfig);
     /* JCM char **be_include; ??? */
     slapi_ch_free((void **)&be->be_name);
-    slapi_counter_destroy(&be->be_usn_counter);
+    if (!config_get_entryusn_global()) {
+        slapi_counter_destroy(&be->be_usn_counter);
+    }
     PR_DestroyLock(be->be_state_lock);
     if (be->be_lock != NULL)
     {

+ 31 - 1
ldap/servers/slapd/libglobs.c

@@ -624,7 +624,11 @@ static struct config_get_and_set {
 	{CONFIG_FORCE_SASL_EXTERNAL_ATTRIBUTE, config_set_force_sasl_external,
 		NULL, 0,
 		(void**)&global_slapdFrontendConfig.force_sasl_external, CONFIG_ON_OFF,
-		(ConfigGetFunc)config_get_force_sasl_external}
+		(ConfigGetFunc)config_get_force_sasl_external},
+	{CONFIG_ENTRYUSN_GLOBAL, config_set_entryusn_global,
+		NULL, 0,
+		(void**)&global_slapdFrontendConfig.entryusn_global, CONFIG_ON_OFF,
+		(ConfigGetFunc)config_get_entryusn_global}
 #ifdef MEMPOOL_EXPERIMENTAL
 	,{CONFIG_MEMPOOL_SWITCH_ATTRIBUTE, config_set_mempool_switch,
 		NULL, 0,
@@ -1002,6 +1006,8 @@ FrontendConfig_init () {
   cfg->auditlog_exptime = 1;
   cfg->auditlog_exptimeunit = slapi_ch_strdup("month");
 
+  cfg->entryusn_global = LDAP_OFF; 
+
 #ifdef MEMPOOL_EXPERIMENTAL
   cfg->mempool_switch = LDAP_ON;
   cfg->mempool_maxfreelist = 1024;
@@ -5526,6 +5532,30 @@ config_set_force_sasl_external( const char *attrname, char *value,
 	return retVal;
 }
 
+int
+config_get_entryusn_global(void)
+{
+    int retVal;
+    slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+    CFG_LOCK_READ(slapdFrontendConfig);
+    retVal = slapdFrontendConfig->entryusn_global;
+    CFG_UNLOCK_READ(slapdFrontendConfig);
+
+    return retVal;
+}
+
+int
+config_set_entryusn_global( const char *attrname, char *value,
+                            char *errorbuf, int apply )
+{
+    int retVal = LDAP_SUCCESS;
+    slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+    retVal = config_set_onoff(attrname, value,
+                              &(slapdFrontendConfig->entryusn_global),
+                              errorbuf, apply);
+    return retVal;
+}
 
 /*
  * This function is intended to be used from the dse code modify callback.  It

+ 42 - 3
ldap/servers/slapd/mapping_tree.c

@@ -3005,6 +3005,9 @@ Slapi_DN *
 slapi_get_first_suffix(void ** node, int show_private)
 {
     mapping_tree_node * first_node = mapping_tree_root->mtn_children;
+    if (NULL == node) {
+        return NULL;
+    }
     *node = (void * ) first_node ;
     while (first_node && (first_node->mtn_private && (show_private == 0)))
             first_node = first_node->mtn_brother;
@@ -3014,11 +3017,15 @@ slapi_get_first_suffix(void ** node, int show_private)
 Slapi_DN * 
 slapi_get_next_suffix(void ** node, int show_private)
 {
-    mapping_tree_node * next_node = *node;
+    mapping_tree_node * next_node = NULL;
 
-    if (next_node == NULL)
+    if (NULL == node) {
         return NULL;
-        
+    }
+    next_node = *node;
+    if (next_node == NULL) {
+        return NULL;
+    }
     next_node = next_node->mtn_brother;
     while (next_node && (next_node->mtn_private && (show_private == 0)))
             next_node = next_node->mtn_brother;
@@ -3026,6 +3033,38 @@ slapi_get_next_suffix(void ** node, int show_private)
     return (next_node ? next_node->mtn_subtree : NULL);
 }
 
+/* get mapping tree node recursively */
+Slapi_DN * 
+slapi_get_next_suffix_ext(void ** node, int show_private)
+{
+    mapping_tree_node * next_node = NULL;
+
+    if (NULL == node) {
+        return NULL;
+    }
+    next_node = *node;
+    if (next_node == NULL) {
+        return NULL;
+    }
+    if (next_node->mtn_children) {
+        next_node = next_node->mtn_children;
+    } else if (next_node->mtn_brother) {
+        next_node = next_node->mtn_brother;
+    } else {
+        next_node = next_node->mtn_parent;
+        if (next_node) {
+            next_node = next_node->mtn_brother;
+        }
+    }
+    while (next_node && (next_node->mtn_private && (show_private == 0)))
+            next_node = next_node->mtn_brother;
+    if (next_node) {
+        *node = next_node;
+        return next_node->mtn_subtree;
+    }
+    return (next_node ? next_node->mtn_subtree : NULL);
+}
+
 /* check if a suffix is a root of the DIT
  * return 1 if yes, 0 if no
  */

+ 3 - 0
ldap/servers/slapd/proto-slap.h

@@ -371,6 +371,8 @@ int config_set_minssf(const char *attrname, char *value, char *errorbuf, int app
 int config_set_accesslogbuffering(const char *attrname, char *value, char *errorbuf, int apply);
 int config_set_csnlogging(const char *attrname, char *value, char *errorbuf, int apply);
 int config_set_force_sasl_external(const char *attrname, char *value, char *errorbuf, int apply );
+int config_set_entryusn_global( const char *attrname, char *value, char *errorbuf, int apply );
+
 
 #if !defined(_WIN32) && !defined(AIX)
 int config_set_maxdescriptors( const char *attrname, char *value, char *errorbuf, int apply );
@@ -509,6 +511,7 @@ long config_get_system_page_size();
 int config_get_system_page_bits();
 #endif
 int config_get_force_sasl_external();
+int config_get_entryusn_global(void);
 
 int is_abspath(const char *);
 char* rel2abspath( char * );

+ 2 - 0
ldap/servers/slapd/slap.h

@@ -1891,6 +1891,7 @@ typedef struct _slapdEntryPoints {
 #define CONFIG_HASH_FILTERS_ATTRIBUTE "nsslapd-hash-filters"
 #define CONFIG_OUTBOUND_LDAP_IO_TIMEOUT_ATTRIBUTE "nsslapd-outbound-ldap-io-timeout"
 #define CONFIG_FORCE_SASL_EXTERNAL_ATTRIBUTE "nsslapd-force-sasl-external"
+#define CONFIG_ENTRYUSN_GLOBAL	"nsslapd-entryusn-global"
 
 #ifdef MEMPOOL_EXPERIMENTAL
 #define CONFIG_MEMPOOL_SWITCH_ATTRIBUTE "nsslapd-mempool"
@@ -2107,6 +2108,7 @@ typedef struct _slapdFrontendConfig {
   int system_page_bits;			/* bit count to shift the system page size */
 #endif /* MEMPOOL_EXPERIMENTAL */
   int force_sasl_external;      /* force SIMPLE bind to be SASL/EXTERNAL if client cert credentials were supplied */
+  int entryusn_global;          /* Entry USN: Use global counter */
 } slapdFrontendConfig_t;
 
 /* possible values for slapdFrontendConfig_t.schemareplace */

+ 1 - 0
ldap/servers/slapd/slapi-plugin.h

@@ -5104,6 +5104,7 @@ void * slapi_be_get_instance_info(Slapi_Backend * be);
 void  slapi_be_set_instance_info(Slapi_Backend * be, void * data);
 Slapi_DN * slapi_get_first_suffix(void ** node, int show_private);
 Slapi_DN * slapi_get_next_suffix(void ** node, int show_private);
+Slapi_DN * slapi_get_next_suffix_ext(void ** node, int show_private);
 int slapi_is_root_suffix(Slapi_DN * dn);
 const Slapi_DN *slapi_get_suffix_by_dn(const Slapi_DN *dn);
 const char * slapi_be_gettype(Slapi_Backend *be);