andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From 6946341b5d2a9a65ebcadcf31410f5578fefd552 Mon Sep 17 00:00:00 2001
dc8c34
From: Mark Reynolds <mreynolds@redhat.com>
dc8c34
Date: Fri, 9 Jan 2015 13:53:20 -0500
dc8c34
Subject: [PATCH 298/305] Ticket 47973 - During schema reload sometimes the
dc8c34
 search  returns no results
dc8c34
dc8c34
Bug Description:  During a schema reload operation the search of an existing
dc8c34
                  entry may randomly report no results.  This is because during
dc8c34
                  the schema reload all existing attribute syntaxes are removed,
dc8c34
                  and there is a small window where ldap operations can be performed
dc8c34
                  before the new schema is loaded.  During this window, attribute
dc8c34
                  values are normalized to NULL which causes operation to unexpectedly
dc8c34
                  fail.
dc8c34
dc8c34
Fix Description:  Instead of wiping out the existing attribute syntax hastables
dc8c34
                  in the middle of the task, instead load the new schema into
dc8c34
                  temporary hash tables.  Once the reload is complete, then take
dc8c34
                  the asi write lock, remove the old hash tables, and swap in the
dc8c34
                  new ones.
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/47973
dc8c34
dc8c34
valgrind: PASSED
dc8c34
dc8c34
Reviewed by: nhosoi(Thanks!)
dc8c34
dc8c34
(cherry picked from commit 3fafcbe0a2ada038f02efdfdce77c1768f0e1819)
dc8c34
dc8c34
Conflicts:
dc8c34
	ldap/servers/slapd/attrsyntax.c
dc8c34
	ldap/servers/slapd/proto-slap.h
dc8c34
dc8c34
(cherry picked from commit 457252f5c97aa8b72d94376e328e63c5d47a825b)
dc8c34
---
dc8c34
 ldap/servers/plugins/schema_reload/schema_reload.c |   7 -
dc8c34
 ldap/servers/slapd/attr.c                          |   8 +-
dc8c34
 ldap/servers/slapd/attrsyntax.c                    | 230 +++++++++++++++------
dc8c34
 ldap/servers/slapd/opshared.c                      |   2 +-
dc8c34
 ldap/servers/slapd/proto-slap.h                    |  12 +-
dc8c34
 ldap/servers/slapd/schema.c                        | 116 ++++++-----
dc8c34
 6 files changed, 243 insertions(+), 132 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/plugins/schema_reload/schema_reload.c b/ldap/servers/plugins/schema_reload/schema_reload.c
dc8c34
index efc0de2..4e5c7f0 100644
dc8c34
--- a/ldap/servers/plugins/schema_reload/schema_reload.c
dc8c34
+++ b/ldap/servers/plugins/schema_reload/schema_reload.c
dc8c34
@@ -170,13 +170,6 @@ schemareload_thread(void *arg)
dc8c34
             slapi_task_log_notice(task, "Schema reload task finished.");
dc8c34
             slapi_task_log_status(task, "Schema reload task finished.");
dc8c34
             slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Schema reload task finished.\n");
dc8c34
-
dc8c34
-            slapi_log_error(SLAPI_LOG_FATAL, "schemareload",
dc8c34
-                            "Register internal schema.\n");
dc8c34
-            rv = slapi_reload_internal_attr_syntax();
dc8c34
-            slapi_log_error(SLAPI_LOG_FATAL, "schemareload",
dc8c34
-                            "Register internal schema finished.\n");
dc8c34
-
dc8c34
         } else {
dc8c34
             slapi_task_log_notice(task, "Schema reload task failed.");
dc8c34
             slapi_task_log_status(task, "Schema reload task failed.");
dc8c34
diff --git a/ldap/servers/slapd/attr.c b/ldap/servers/slapd/attr.c
dc8c34
index 983e286..a4d8a96 100644
dc8c34
--- a/ldap/servers/slapd/attr.c
dc8c34
+++ b/ldap/servers/slapd/attr.c
dc8c34
@@ -175,8 +175,8 @@ slapi_attr_types_equivalent(const char *t1, const char *t2)
dc8c34
 		return 0;
dc8c34
 	}
dc8c34
 
dc8c34
-	asi1 = attr_syntax_get_by_name(t1);
dc8c34
-	asi2 = attr_syntax_get_by_name(t2);
dc8c34
+	asi1 = attr_syntax_get_by_name(t1, 0);
dc8c34
+	asi2 = attr_syntax_get_by_name(t2, 0);
dc8c34
 	if (NULL != asi1) {
dc8c34
 		if (NULL != asi2) {
dc8c34
 			/* Both found - compare normalized names */
dc8c34
@@ -277,7 +277,7 @@ slapi_attr_init_locking_optional(Slapi_Attr *a, const char *type, PRBool use_loc
dc8c34
 			{
dc8c34
 				basetype = tmp;	/* basetype was malloc'd */
dc8c34
 			}
dc8c34
-			asi = attr_syntax_get_by_name_locking_optional(basetype, use_lock);
dc8c34
+			asi = attr_syntax_get_by_name_locking_optional(basetype, use_lock, 0);
dc8c34
 		}
dc8c34
 		if(NULL == asi)
dc8c34
 		{
dc8c34
@@ -288,7 +288,7 @@ slapi_attr_init_locking_optional(Slapi_Attr *a, const char *type, PRBool use_loc
dc8c34
 			 * attribute type that has that syntax.
dc8c34
 			 */
dc8c34
 			asi = attr_syntax_get_by_name_locking_optional(
dc8c34
-					ATTR_WITH_OCTETSTRING_SYNTAX, use_lock);
dc8c34
+					ATTR_WITH_OCTETSTRING_SYNTAX, use_lock, 0);
dc8c34
 		}
dc8c34
 		else
dc8c34
 		{
dc8c34
diff --git a/ldap/servers/slapd/attrsyntax.c b/ldap/servers/slapd/attrsyntax.c
dc8c34
index 75114e0..d92728a 100644
dc8c34
--- a/ldap/servers/slapd/attrsyntax.c
dc8c34
+++ b/ldap/servers/slapd/attrsyntax.c
dc8c34
@@ -73,14 +73,19 @@ static Slapi_RWLock *name2asi_lock = NULL;
dc8c34
 #define AS_UNLOCK_READ(l)	slapi_rwlock_unlock(l)
dc8c34
 #define AS_UNLOCK_WRITE(l)	slapi_rwlock_unlock(l)
dc8c34
 
dc8c34
+/*
dc8c34
+ * For the schema reload task, we need to use separate temporary hashtables & linked lists
dc8c34
+ */
dc8c34
+static PLHashTable *oid2asi_tmp = NULL;
dc8c34
+static PLHashTable *name2asi_tmp = NULL;
dc8c34
 
dc8c34
 static struct asyntaxinfo *default_asi = NULL;
dc8c34
 
dc8c34
 static void *attr_syntax_get_plugin_by_name_with_default( const char *type );
dc8c34
 static void attr_syntax_delete_no_lock( struct asyntaxinfo *asip,
dc8c34
-		PRBool remove_from_oid_table );
dc8c34
+		PRBool remove_from_oid_table, PRUint32 schema_flags );
dc8c34
 static struct asyntaxinfo *attr_syntax_get_by_oid_locking_optional( const
dc8c34
-		char *oid, PRBool use_lock);
dc8c34
+		char *oid, PRBool use_lock, PRUint32 schema_flags);
dc8c34
 
dc8c34
 #ifdef ATTR_LDAP_DEBUG
dc8c34
 static void attr_syntax_print();
dc8c34
@@ -198,8 +203,6 @@ attr_syntax_check_oids()
dc8c34
 void
dc8c34
 attr_syntax_free( struct asyntaxinfo *a )
dc8c34
 {
dc8c34
-	PR_ASSERT( a->asi_refcnt == 0 );
dc8c34
-
dc8c34
 	cool_charray_free( a->asi_aliases );
dc8c34
 	slapi_ch_free( (void**)&a->asi_name );
dc8c34
 	slapi_ch_free( (void **)&a->asi_desc );
dc8c34
@@ -228,9 +231,9 @@ attr_syntax_new()
dc8c34
  * be returned by calling to attr_syntax_return().
dc8c34
  */
dc8c34
 struct asyntaxinfo *
dc8c34
-attr_syntax_get_by_oid(const char *oid)
dc8c34
+attr_syntax_get_by_oid(const char *oid, PRUint32 schema_flags)
dc8c34
 {
dc8c34
-	return attr_syntax_get_by_oid_locking_optional( oid, PR_TRUE);
dc8c34
+	return attr_syntax_get_by_oid_locking_optional( oid, PR_TRUE, schema_flags);
dc8c34
 }
dc8c34
 
dc8c34
 
dc8c34
@@ -243,15 +246,30 @@ attr_syntax_get_by_oid(const char *oid)
dc8c34
  * same use_lock parameter.
dc8c34
  */
dc8c34
 static struct asyntaxinfo *
dc8c34
-attr_syntax_get_by_oid_locking_optional( const char *oid, PRBool use_lock )
dc8c34
+attr_syntax_get_by_oid_locking_optional( const char *oid, PRBool use_lock, PRUint32 schema_flags )
dc8c34
 {
dc8c34
 	struct asyntaxinfo *asi = 0;
dc8c34
-	if (oid2asi)
dc8c34
+	PLHashTable *ht = oid2asi;
dc8c34
+	int using_tmp_ht = 0;
dc8c34
+
dc8c34
+	if (schema_flags & DSE_SCHEMA_LOCKED){
dc8c34
+		ht = oid2asi_tmp;
dc8c34
+		using_tmp_ht = 1;
dc8c34
+		use_lock = 0;
dc8c34
+	}
dc8c34
+	if (ht)
dc8c34
 	{
dc8c34
 		if ( use_lock ) {
dc8c34
 			AS_LOCK_READ(oid2asi_lock);
dc8c34
 		}
dc8c34
-		asi = (struct asyntaxinfo *)PL_HashTableLookup_const(oid2asi, oid);
dc8c34
+		if (!using_tmp_ht){
dc8c34
+			/*
dc8c34
+			 * The oid2asi pointer could have been rewritten by the schema_reload task
dc8c34
+			 * while waiting on the lock, so grab it again.
dc8c34
+			 */
dc8c34
+			ht = oid2asi;
dc8c34
+		}
dc8c34
+		asi = (struct asyntaxinfo *)PL_HashTableLookup_const(ht, oid);
dc8c34
 		if (asi)
dc8c34
 		{
dc8c34
 			PR_AtomicIncrement( &asi->asi_refcnt );
dc8c34
@@ -272,18 +290,22 @@ attr_syntax_get_by_oid_locking_optional( const char *oid, PRBool use_lock )
dc8c34
  * to worry about resource contention.
dc8c34
  */
dc8c34
 static void
dc8c34
-attr_syntax_add_by_oid(const char *oid, struct asyntaxinfo *a, int lock)
dc8c34
+attr_syntax_add_by_oid(const char *oid, struct asyntaxinfo *a, PRUint32 schema_flags, int lock)
dc8c34
 {
dc8c34
 	if (0 != attr_syntax_init()) return;
dc8c34
 
dc8c34
-	if (lock) {
dc8c34
-		AS_LOCK_WRITE(oid2asi_lock);
dc8c34
-	}
dc8c34
+	if(schema_flags & DSE_SCHEMA_LOCKED){
dc8c34
+		PL_HashTableAdd(oid2asi_tmp, oid, a);
dc8c34
+	} else {
dc8c34
+		if (lock) {
dc8c34
+			AS_LOCK_WRITE(oid2asi_lock);
dc8c34
+		}
dc8c34
 
dc8c34
-	PL_HashTableAdd(oid2asi, oid, a);
dc8c34
+		PL_HashTableAdd(oid2asi, oid, a);
dc8c34
 
dc8c34
-	if (lock) {
dc8c34
-		AS_UNLOCK_WRITE(oid2asi_lock);
dc8c34
+		if (lock) {
dc8c34
+			AS_UNLOCK_WRITE(oid2asi_lock);
dc8c34
+		}
dc8c34
 	}
dc8c34
 }
dc8c34
 
dc8c34
@@ -296,18 +318,19 @@ attr_syntax_add_by_oid(const char *oid, struct asyntaxinfo *a, int lock)
dc8c34
  * be returned by calling to attr_syntax_return().
dc8c34
  */
dc8c34
 struct asyntaxinfo *
dc8c34
-attr_syntax_get_by_name(const char *name)
dc8c34
+attr_syntax_get_by_name(const char *name, PRUint32 schema_flags)
dc8c34
 {
dc8c34
-	return attr_syntax_get_by_name_locking_optional(name, PR_TRUE);
dc8c34
+	return attr_syntax_get_by_name_locking_optional(name, PR_TRUE, schema_flags);
dc8c34
 }
dc8c34
 
dc8c34
 struct asyntaxinfo *
dc8c34
 attr_syntax_get_by_name_with_default(const char *name)
dc8c34
 {
dc8c34
 	struct asyntaxinfo *asi = NULL;
dc8c34
-	asi = attr_syntax_get_by_name_locking_optional(name, PR_TRUE);
dc8c34
+
dc8c34
+	asi = attr_syntax_get_by_name_locking_optional(name, PR_TRUE, 0);
dc8c34
 	if (asi == NULL)
dc8c34
-		asi = attr_syntax_get_by_name(ATTR_WITH_OCTETSTRING_SYNTAX);
dc8c34
+		asi = attr_syntax_get_by_name(ATTR_WITH_OCTETSTRING_SYNTAX, 0);
dc8c34
 	if ( asi == NULL ) 
dc8c34
 		asi = default_asi;
dc8c34
 	return asi;
dc8c34
@@ -322,15 +345,30 @@ attr_syntax_get_by_name_with_default(const char *name)
dc8c34
  * same use_lock parameter.
dc8c34
  */
dc8c34
 struct asyntaxinfo *
dc8c34
-attr_syntax_get_by_name_locking_optional(const char *name, PRBool use_lock)
dc8c34
+attr_syntax_get_by_name_locking_optional(const char *name, PRBool use_lock, PRUint32 schema_flags)
dc8c34
 {
dc8c34
 	struct asyntaxinfo *asi = 0;
dc8c34
-	if (name2asi)
dc8c34
+	PLHashTable *ht = name2asi;
dc8c34
+	int using_tmp_ht = 0;
dc8c34
+
dc8c34
+	if (schema_flags & DSE_SCHEMA_LOCKED){
dc8c34
+		ht = name2asi_tmp;
dc8c34
+		using_tmp_ht = 1;
dc8c34
+		use_lock = 0;
dc8c34
+	}
dc8c34
+	if (ht)
dc8c34
 	{
dc8c34
 		if ( use_lock ) {
dc8c34
 			AS_LOCK_READ(name2asi_lock);
dc8c34
 		}
dc8c34
-		asi = (struct asyntaxinfo *)PL_HashTableLookup_const(name2asi, name);
dc8c34
+		if(!using_tmp_ht){
dc8c34
+			/*
dc8c34
+			 * The name2asi pointer could have been rewritten by the schema_reload task
dc8c34
+			 * while waiting on the lock, so grab it again.
dc8c34
+			 */
dc8c34
+			ht = name2asi;
dc8c34
+		}
dc8c34
+		asi = (struct asyntaxinfo *)PL_HashTableLookup_const(ht, name);
dc8c34
 		if ( NULL != asi ) {
dc8c34
 			PR_AtomicIncrement( &asi->asi_refcnt );
dc8c34
 		}
dc8c34
@@ -339,7 +377,7 @@ attr_syntax_get_by_name_locking_optional(const char *name, PRBool use_lock)
dc8c34
 		}
dc8c34
 	}
dc8c34
 	if (!asi) /* given name may be an OID */
dc8c34
-		asi = attr_syntax_get_by_oid_locking_optional(name, use_lock);
dc8c34
+		asi = attr_syntax_get_by_oid_locking_optional(name, use_lock, schema_flags);
dc8c34
 
dc8c34
 	return asi;
dc8c34
 }
dc8c34
@@ -402,26 +440,37 @@ attr_syntax_return_locking_optional(struct asyntaxinfo *asi, PRBool use_lock)
dc8c34
  * to worry about resource contention.
dc8c34
  */
dc8c34
 static void
dc8c34
-attr_syntax_add_by_name(struct asyntaxinfo *a, int lock)
dc8c34
+attr_syntax_add_by_name(struct asyntaxinfo *a, PRUint32 schema_flags, int lock)
dc8c34
 {
dc8c34
 	if (0 != attr_syntax_init()) return;
dc8c34
 
dc8c34
-	if (lock) {
dc8c34
-		AS_LOCK_WRITE(name2asi_lock);
dc8c34
-	}
dc8c34
+	if (schema_flags & DSE_SCHEMA_LOCKED ){
dc8c34
+		PL_HashTableAdd(name2asi_tmp, a->asi_name, a);
dc8c34
+		if ( a->asi_aliases != NULL ) {
dc8c34
+			int i;
dc8c34
+
dc8c34
+			for ( i = 0; a->asi_aliases[i] != NULL; ++i ) {
dc8c34
+				PL_HashTableAdd(name2asi_tmp, a->asi_aliases[i], a);
dc8c34
+			}
dc8c34
+		}
dc8c34
+	} else {
dc8c34
+		if (lock) {
dc8c34
+			AS_LOCK_WRITE(name2asi_lock);
dc8c34
+		}
dc8c34
 
dc8c34
-	PL_HashTableAdd(name2asi, a->asi_name, a);
dc8c34
-	if ( a->asi_aliases != NULL ) {
dc8c34
-		int		i;
dc8c34
+		PL_HashTableAdd(name2asi, a->asi_name, a);
dc8c34
+		if ( a->asi_aliases != NULL ) {
dc8c34
+			int i;
dc8c34
 
dc8c34
-		for ( i = 0; a->asi_aliases[i] != NULL; ++i ) {
dc8c34
-			PL_HashTableAdd(name2asi, a->asi_aliases[i], a);
dc8c34
+			for ( i = 0; a->asi_aliases[i] != NULL; ++i ) {
dc8c34
+				PL_HashTableAdd(name2asi, a->asi_aliases[i], a);
dc8c34
+			}
dc8c34
+		}
dc8c34
+		if (lock) {
dc8c34
+			AS_UNLOCK_WRITE(name2asi_lock);
dc8c34
 		}
dc8c34
 	}
dc8c34
 
dc8c34
-	if (lock) {
dc8c34
-		AS_UNLOCK_WRITE(name2asi_lock);
dc8c34
-	}
dc8c34
 }
dc8c34
 
dc8c34
 
dc8c34
@@ -430,7 +479,7 @@ attr_syntax_add_by_name(struct asyntaxinfo *a, int lock)
dc8c34
  * and oids.
dc8c34
  */
dc8c34
 void
dc8c34
-attr_syntax_delete( struct asyntaxinfo *asi )
dc8c34
+attr_syntax_delete( struct asyntaxinfo *asi, PRUint32 schema_flags )
dc8c34
 {
dc8c34
 	PR_ASSERT( asi );
dc8c34
 
dc8c34
@@ -438,7 +487,7 @@ attr_syntax_delete( struct asyntaxinfo *asi )
dc8c34
 		AS_LOCK_WRITE(oid2asi_lock);
dc8c34
 		AS_LOCK_WRITE(name2asi_lock);
dc8c34
 
dc8c34
-		attr_syntax_delete_no_lock( asi, PR_TRUE );
dc8c34
+		attr_syntax_delete_no_lock( asi, PR_TRUE, schema_flags );
dc8c34
 
dc8c34
 		AS_UNLOCK_WRITE(name2asi_lock);
dc8c34
 		AS_UNLOCK_WRITE(oid2asi_lock);
dc8c34
@@ -452,19 +501,34 @@ attr_syntax_delete( struct asyntaxinfo *asi )
dc8c34
  */
dc8c34
 static void
dc8c34
 attr_syntax_delete_no_lock( struct asyntaxinfo *asi,
dc8c34
-		PRBool remove_from_oidtable )
dc8c34
+		PRBool remove_from_oidtable, PRUint32 schema_flags )
dc8c34
 {
dc8c34
-	int		i;
dc8c34
+	PLHashTable *ht = NULL;
dc8c34
+	int using_tmp_ht = 0;
dc8c34
+	int i;
dc8c34
 
dc8c34
+	if (schema_flags & DSE_SCHEMA_LOCKED){
dc8c34
+		using_tmp_ht = 1;
dc8c34
+	}
dc8c34
 	if (oid2asi && remove_from_oidtable ) {
dc8c34
-		PL_HashTableRemove(oid2asi, asi->asi_oid);
dc8c34
+		if (using_tmp_ht){
dc8c34
+			ht = oid2asi_tmp;
dc8c34
+		} else {
dc8c34
+			ht = oid2asi;
dc8c34
+		}
dc8c34
+		PL_HashTableRemove(ht, asi->asi_oid);
dc8c34
 	}
dc8c34
 
dc8c34
 	if(name2asi) {
dc8c34
-		PL_HashTableRemove(name2asi, asi->asi_name);
dc8c34
+		if (using_tmp_ht){
dc8c34
+			ht = name2asi_tmp;
dc8c34
+		} else {
dc8c34
+			ht = name2asi;
dc8c34
+		}
dc8c34
+		PL_HashTableRemove(ht, asi->asi_name);
dc8c34
 		if ( asi->asi_aliases != NULL ) {
dc8c34
 			for ( i = 0; asi->asi_aliases[i] != NULL; ++i ) {
dc8c34
-				PL_HashTableRemove(name2asi, asi->asi_aliases[i]);
dc8c34
+				PL_HashTableRemove(ht, asi->asi_aliases[i]);
dc8c34
 			}
dc8c34
 		}
dc8c34
 		if ( asi->asi_refcnt > 0 ) {
dc8c34
@@ -496,7 +560,7 @@ slapi_attr_syntax_normalize( const char *s )
dc8c34
 	struct asyntaxinfo *asi = NULL;
dc8c34
 	char *r = NULL;
dc8c34
 
dc8c34
-	if((asi=attr_syntax_get_by_name(s)) != NULL ) {
dc8c34
+	if((asi=attr_syntax_get_by_name(s, 0)) != NULL ) {
dc8c34
 		r = slapi_ch_strdup(asi->asi_name);
dc8c34
 		attr_syntax_return( asi );
dc8c34
 	}
dc8c34
@@ -507,7 +571,6 @@ slapi_attr_syntax_normalize( const char *s )
dc8c34
 	return r;
dc8c34
 }
dc8c34
 
dc8c34
-
dc8c34
 /*
dc8c34
  * attr_syntax_exists: return 1 if attr_name exists, 0 otherwise
dc8c34
  *
dc8c34
@@ -517,7 +580,8 @@ attr_syntax_exists(const char *attr_name)
dc8c34
 {
dc8c34
 	struct asyntaxinfo	*asi;
dc8c34
 
dc8c34
-	asi = attr_syntax_get_by_name(attr_name);
dc8c34
+
dc8c34
+	asi = attr_syntax_get_by_name(attr_name, 0);
dc8c34
 	attr_syntax_return( asi );
dc8c34
 
dc8c34
 	if ( asi != NULL )
dc8c34
@@ -686,13 +750,13 @@ attr_syntax_get_plugin_by_name_with_default( const char *type )
dc8c34
 	/*
dc8c34
 	 * first we look for this attribute type explictly
dc8c34
 	 */
dc8c34
-	if ( (asi = attr_syntax_get_by_name(type)) == NULL ) {
dc8c34
+	if ( (asi = attr_syntax_get_by_name(type, 0)) == NULL ) {
dc8c34
 		/*
dc8c34
 		 * no syntax for this type... return Octet String
dc8c34
 		 * syntax.  we accomplish this by looking up a well known
dc8c34
 		 * attribute type that has that syntax.
dc8c34
 		 */
dc8c34
-		asi = attr_syntax_get_by_name(ATTR_WITH_OCTETSTRING_SYNTAX);
dc8c34
+		asi = attr_syntax_get_by_name(ATTR_WITH_OCTETSTRING_SYNTAX, 0);
dc8c34
 		if (asi == NULL) 
dc8c34
 			asi = default_asi;
dc8c34
 	}
dc8c34
@@ -729,14 +793,13 @@ attr_syntax_dup( struct asyntaxinfo *a )
dc8c34
 	return( newas );
dc8c34
 }
dc8c34
 
dc8c34
-
dc8c34
 /*
dc8c34
  * Add a new attribute type to the schema.
dc8c34
  *
dc8c34
  * Returns an LDAP error code (LDAP_SUCCESS if all goes well).
dc8c34
  */
dc8c34
 int 
dc8c34
-attr_syntax_add( struct asyntaxinfo *asip )
dc8c34
+attr_syntax_add( struct asyntaxinfo *asip, PRUint32 schema_flags )
dc8c34
 {
dc8c34
 	int i, rc = LDAP_SUCCESS;
dc8c34
 	int nolock = asip->asi_flags & SLAPI_ATTR_FLAG_NOLOCKING;
dc8c34
@@ -748,7 +811,7 @@ attr_syntax_add( struct asyntaxinfo *asip )
dc8c34
 
dc8c34
 	/* make sure the oid is unique */
dc8c34
 	if ( NULL != ( oldas_from_oid = attr_syntax_get_by_oid_locking_optional(
dc8c34
-					asip->asi_oid, !nolock))) {
dc8c34
+					asip->asi_oid, !nolock, schema_flags))) {
dc8c34
 		if ( 0 == (asip->asi_flags & SLAPI_ATTR_FLAG_OVERRIDE)) {
dc8c34
 			/* failure - OID is in use; no override flag */
dc8c34
 			rc = LDAP_TYPE_OR_VALUE_EXISTS;
dc8c34
@@ -760,7 +823,7 @@ attr_syntax_add( struct asyntaxinfo *asip )
dc8c34
      * the primary name and OID point to the same schema definition.
dc8c34
 	 */
dc8c34
 	if ( NULL != ( oldas_from_name = attr_syntax_get_by_name_locking_optional(
dc8c34
-					asip->asi_name, !nolock))) {
dc8c34
+					asip->asi_name, !nolock, schema_flags))) {
dc8c34
 		if ( 0 == (asip->asi_flags & SLAPI_ATTR_FLAG_OVERRIDE)
dc8c34
 					|| ( oldas_from_oid != oldas_from_name )) {
dc8c34
 			/* failure; no override flag OR OID and name don't match */
dc8c34
@@ -768,7 +831,7 @@ attr_syntax_add( struct asyntaxinfo *asip )
dc8c34
 			goto cleanup_and_return;
dc8c34
 		}
dc8c34
 		/* Flag for deletion.  We are going to override this attr */
dc8c34
-		attr_syntax_delete(oldas_from_name);
dc8c34
+		attr_syntax_delete(oldas_from_name, schema_flags);
dc8c34
 	} else if ( NULL != oldas_from_oid ) {
dc8c34
 		/* failure - OID is in use but name does not exist */
dc8c34
 		rc = LDAP_TYPE_OR_VALUE_EXISTS;
dc8c34
@@ -782,11 +845,11 @@ attr_syntax_add( struct asyntaxinfo *asip )
dc8c34
 
dc8c34
 			if ( NULL != ( tmpasi =
dc8c34
 							attr_syntax_get_by_name_locking_optional(
dc8c34
-							asip->asi_aliases[i], !nolock))) {
dc8c34
+							asip->asi_aliases[i], !nolock, schema_flags))) {
dc8c34
 				if (asip->asi_flags & SLAPI_ATTR_FLAG_OVERRIDE) {
dc8c34
 					/* Flag for tmpasi for deletion.  It will be free'd
dc8c34
 					 * when attr_syntax_return is called. */
dc8c34
-					attr_syntax_delete(tmpasi);
dc8c34
+					attr_syntax_delete(tmpasi, schema_flags);
dc8c34
 				} else {
dc8c34
 					/* failure - one of the aliases is already in use */
dc8c34
 					rc = LDAP_TYPE_OR_VALUE_EXISTS;
dc8c34
@@ -805,8 +868,8 @@ attr_syntax_add( struct asyntaxinfo *asip )
dc8c34
 	/* ditto for the override one */
dc8c34
 	asip->asi_flags &= ~SLAPI_ATTR_FLAG_OVERRIDE;
dc8c34
 	
dc8c34
-	attr_syntax_add_by_oid( asip->asi_oid, asip, !nolock);
dc8c34
-	attr_syntax_add_by_name( asip, !nolock);
dc8c34
+	attr_syntax_add_by_oid( asip->asi_oid, asip, schema_flags, !nolock);
dc8c34
+	attr_syntax_add_by_name( asip, schema_flags, !nolock);
dc8c34
 
dc8c34
 cleanup_and_return:
dc8c34
 	attr_syntax_return_locking_optional( oldas_from_oid, !nolock );
dc8c34
@@ -979,7 +1042,7 @@ slapi_attr_type2plugin( const char *type, void **pi )
dc8c34
 int
dc8c34
 slapi_attr_get_oid( const Slapi_Attr *a, char **oid )
dc8c34
 {
dc8c34
-	struct asyntaxinfo *asi = attr_syntax_get_by_name(a->a_type);
dc8c34
+	struct asyntaxinfo *asi = attr_syntax_get_by_name(a->a_type, 0);
dc8c34
 	if (asi) {
dc8c34
 		*oid = asi->asi_oid;
dc8c34
 		attr_syntax_return(asi);
dc8c34
@@ -995,7 +1058,7 @@ slapi_attr_get_oid( const Slapi_Attr *a, char **oid )
dc8c34
 int
dc8c34
 slapi_attr_get_oid_copy( const Slapi_Attr *a, char **oidp )
dc8c34
 {
dc8c34
-	struct asyntaxinfo *asi = attr_syntax_get_by_name(a->a_type);
dc8c34
+	struct asyntaxinfo *asi = attr_syntax_get_by_name(a->a_type, 0);
dc8c34
 	if (asi) {
dc8c34
 		*oidp = slapi_ch_strdup( asi->asi_oid );
dc8c34
 		attr_syntax_return(asi);
dc8c34
@@ -1191,7 +1254,7 @@ attr_syntax_delete_if_not_flagged(struct asyntaxinfo *asip, void *arg)
dc8c34
 	PR_ASSERT( fi != NULL );
dc8c34
 
dc8c34
 	if ( 0 == ( asip->asi_flags & fi->asef_flag )) {
dc8c34
-		attr_syntax_delete_no_lock( asip, PR_FALSE );
dc8c34
+		attr_syntax_delete_no_lock( asip, PR_FALSE, 0 );
dc8c34
 		return ATTR_SYNTAX_ENUM_REMOVE;
dc8c34
 	} else {
dc8c34
 		return ATTR_SYNTAX_ENUM_NEXT;
dc8c34
@@ -1207,7 +1270,7 @@ attr_syntax_force_to_delete(struct asyntaxinfo *asip, void *arg)
dc8c34
 	fi = (struct attr_syntax_enum_flaginfo *)arg;
dc8c34
 	PR_ASSERT( fi != NULL );
dc8c34
 
dc8c34
-	attr_syntax_delete_no_lock( asip, PR_FALSE );
dc8c34
+	attr_syntax_delete_no_lock( asip, PR_FALSE, 0 );
dc8c34
 	return ATTR_SYNTAX_ENUM_REMOVE;
dc8c34
 }
dc8c34
 
dc8c34
@@ -1272,6 +1335,7 @@ attr_syntax_delete_all_for_schemareload(unsigned long flag)
dc8c34
 
dc8c34
 #define ATTR_DEFAULT_SYNTAX_OID	"1.1"
dc8c34
 #define ATTR_DEFAULT_SYNTAX	"defaultdirstringsyntax"
dc8c34
+
dc8c34
 static int
dc8c34
 attr_syntax_init(void)
dc8c34
 {
dc8c34
@@ -1290,6 +1354,14 @@ attr_syntax_init(void)
dc8c34
 		}
dc8c34
 	}
dc8c34
 
dc8c34
+	if (!oid2asi_tmp)
dc8c34
+	{
dc8c34
+		/* temporary hash table for schema reload */
dc8c34
+		oid2asi_tmp = PL_NewHashTable(2047, hashNocaseString,
dc8c34
+		                              hashNocaseCompare,
dc8c34
+		                              PL_CompareValues, 0, 0);
dc8c34
+	}
dc8c34
+
dc8c34
 	if (!name2asi)
dc8c34
 	{
dc8c34
 		name2asi = PL_NewHashTable(2047, hashNocaseString,
dc8c34
@@ -1310,6 +1382,14 @@ attr_syntax_init(void)
dc8c34
 	                                DIRSTRING_SYNTAX_OID, 
dc8c34
 	                                SLAPI_ATTR_FLAG_NOUSERMOD );
dc8c34
 	}
dc8c34
+	if (!name2asi_tmp)
dc8c34
+	{
dc8c34
+		/* temporary hash table for schema reload */
dc8c34
+		name2asi_tmp = PL_NewHashTable(2047, hashNocaseString,
dc8c34
+		                               hashNocaseCompare,
dc8c34
+		                               PL_CompareValues, 0, 0);
dc8c34
+	}
dc8c34
+
dc8c34
 	return 0;
dc8c34
 }
dc8c34
 
dc8c34
@@ -1379,7 +1459,7 @@ slapi_add_internal_attr_syntax( const char *name, const char *oid,
dc8c34
 			 &asip );
dc8c34
 
dc8c34
 	if ( rc == LDAP_SUCCESS ) {
dc8c34
-		rc = attr_syntax_add( asip );
dc8c34
+		rc = attr_syntax_add( asip, 0 );
dc8c34
 		if ( rc == LDAP_SUCCESS ) {
dc8c34
 			if (attr_syntax_internal_asi_add_ht(asip)) {
dc8c34
 				slapi_log_error(SLAPI_LOG_FATAL,
dc8c34
@@ -1387,6 +1467,8 @@ slapi_add_internal_attr_syntax( const char *name, const char *oid,
dc8c34
 				                "Failed to stash internal asyntaxinfo: %s.\n",
dc8c34
 				                asip->asi_name);
dc8c34
 			}
dc8c34
+		} else {
dc8c34
+			attr_syntax_free(asip);
dc8c34
 		}
dc8c34
 	}
dc8c34
 
dc8c34
@@ -1406,7 +1488,7 @@ attr_syntax_internal_asi_add(struct asyntaxinfo *asip, void *arg)
dc8c34
 	/* Copy is needed since when reloading the schema,
dc8c34
 	 * existing syntax info is cleaned up. */
dc8c34
 	asip_copy = attr_syntax_dup(asip);
dc8c34
-	rc = attr_syntax_add(asip_copy);
dc8c34
+	rc = attr_syntax_add(asip_copy, 0);
dc8c34
 	if (LDAP_SUCCESS != rc) {
dc8c34
 		attr_syntax_free(asip_copy);
dc8c34
 	}
dc8c34
@@ -1426,3 +1508,25 @@ slapi_reload_internal_attr_syntax()
dc8c34
 	attr_syntax_enumerate_attrs_ext(internalasi, attr_syntax_internal_asi_add, NULL);
dc8c34
 	return rc;
dc8c34
 }
dc8c34
+
dc8c34
+/*
dc8c34
+ * schema reload - now that we have loaded the schema into temporary
dc8c34
+ * hash tables, swap out the old for the new.
dc8c34
+ */
dc8c34
+void
dc8c34
+attr_syntax_swap_ht()
dc8c34
+{
dc8c34
+	/* Remove the old hash tables */
dc8c34
+	PL_HashTableDestroy(name2asi);
dc8c34
+	PL_HashTableDestroy(oid2asi);
dc8c34
+
dc8c34
+	/*
dc8c34
+	 * Swap the hash table/linked list pointers, and set the
dc8c34
+	 * temporary pointers to NULL
dc8c34
+	 */
dc8c34
+	name2asi = name2asi_tmp;
dc8c34
+	name2asi_tmp = NULL;
dc8c34
+	oid2asi = oid2asi_tmp;
dc8c34
+	oid2asi_tmp = NULL;
dc8c34
+}
dc8c34
+
dc8c34
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
dc8c34
index 7a0b544..a7367a7 100644
dc8c34
--- a/ldap/servers/slapd/opshared.c
dc8c34
+++ b/ldap/servers/slapd/opshared.c
dc8c34
@@ -91,7 +91,7 @@ int op_shared_is_allowed_attr (const char *attr_name, int replicated_op)
dc8c34
         struct asyntaxinfo    *asi;
dc8c34
         int                    no_user_mod = 0;
dc8c34
 
dc8c34
-        asi = attr_syntax_get_by_name( attr_name );
dc8c34
+        asi = attr_syntax_get_by_name( attr_name, 0 );
dc8c34
         if ( NULL != asi &&
dc8c34
                 0 != ( asi->asi_flags & SLAPI_ATTR_FLAG_NOUSERMOD ))
dc8c34
         {
dc8c34
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
dc8c34
index 0891608..da9c925 100644
dc8c34
--- a/ldap/servers/slapd/proto-slap.h
dc8c34
+++ b/ldap/servers/slapd/proto-slap.h
dc8c34
@@ -117,7 +117,7 @@ void attr_syntax_write_lock(void);
dc8c34
 void attr_syntax_unlock_read(void);
dc8c34
 void attr_syntax_unlock_write(void);
dc8c34
 int attr_syntax_exists (const char *attr_name);
dc8c34
-void attr_syntax_delete ( struct asyntaxinfo *asip );
dc8c34
+void attr_syntax_delete ( struct asyntaxinfo *asip, PRUint32 schema_flags );
dc8c34
 #define SLAPI_SYNTAXLENGTH_NONE		(-1)	/* for syntaxlength parameter */
dc8c34
 int attr_syntax_create( const char *attr_oid, char *const*attr_names,
dc8c34
 		int num_names, const char *attr_desc, const char *attr_superior,
dc8c34
@@ -126,15 +126,17 @@ int attr_syntax_create( const char *attr_oid, char *const*attr_names,
dc8c34
 		const char *attr_syntax, int syntaxlength, unsigned long flags,
dc8c34
 		struct asyntaxinfo **asip );
dc8c34
 void attr_syntax_free( struct asyntaxinfo *a );
dc8c34
-int attr_syntax_add( struct asyntaxinfo *asip );
dc8c34
+int attr_syntax_add( struct asyntaxinfo *asip, PRUint32 schema_flags );
dc8c34
 char *attr_syntax_normalize_no_lookup( const char *s );
dc8c34
 void attr_syntax_enumerate_attrs(AttrEnumFunc aef, void *arg, PRBool writelock);
dc8c34
 void attr_syntax_all_clear_flag( unsigned long flag );
dc8c34
 void attr_syntax_delete_all_not_flagged( unsigned long flag );
dc8c34
-struct asyntaxinfo *attr_syntax_get_by_oid ( const char *oid );
dc8c34
-struct asyntaxinfo *attr_syntax_get_by_name ( const char *name );
dc8c34
-struct asyntaxinfo *attr_syntax_get_by_name_locking_optional ( const char *name, PRBool use_lock );
dc8c34
+struct asyntaxinfo *attr_syntax_get_by_oid ( const char *oid, PRUint32 schema_flags );
dc8c34
+struct asyntaxinfo *attr_syntax_get_by_name ( const char *name, PRUint32 schema_flags );
dc8c34
 struct asyntaxinfo *attr_syntax_get_by_name_with_default ( const char *name );
dc8c34
+struct asyntaxinfo *attr_syntax_get_by_name_locking_optional ( const char *name, PRBool use_lock, PRUint32 schema_flags );
dc8c34
+struct asyntaxinfo *attr_syntax_get_global_at();
dc8c34
+void attr_syntax_swap_ht(void);
dc8c34
 /*
dc8c34
  * Call attr_syntax_return() when you are done using a value returned
dc8c34
  * by attr_syntax_get_by_oid() or attr_syntax_get_by_name().
dc8c34
diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c
dc8c34
index 18ae152..798d905 100644
dc8c34
--- a/ldap/servers/slapd/schema.c
dc8c34
+++ b/ldap/servers/slapd/schema.c
dc8c34
@@ -154,6 +154,8 @@ static int schema_strcmp( const char *s1, const char *s2 );
dc8c34
 static int schema_strcmp_array( char **sa1, char **sa2,
dc8c34
 		const char *ignorestr );
dc8c34
 static PRBool schema_type_is_interesting( const char *type );
dc8c34
+static void reload_schemafile_lock(void);
dc8c34
+static void reload_schemafile_unlock(void);
dc8c34
 static void schema_create_errormsg( char *errorbuf, size_t errorbufsize,
dc8c34
 		const char *prefix, const char *name, const char *fmt, ... )
dc8c34
 #ifdef __GNUC__ 
dc8c34
@@ -2125,7 +2127,7 @@ schema_delete_attributes ( Slapi_Entry *entryBefore, LDAPMod *mod,
dc8c34
 	
dc8c34
 	sscanf (attr_ldif, "%s name %s syntax %s",
dc8c34
 			psbAttrOid->buffer, psbAttrName->buffer, psbAttrSyntax->buffer);
dc8c34
-	if ((a = attr_syntax_get_by_name ( psbAttrName->buffer)) != NULL ) {
dc8c34
+	if ((a = attr_syntax_get_by_name ( psbAttrName->buffer, 0 )) != NULL ) {
dc8c34
 	  /* only modify attrs which were user defined */
dc8c34
 	  if (a->asi_flags & SLAPI_ATTR_FLAG_STD_ATTR) {
dc8c34
 		schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_at,
dc8c34
@@ -2177,7 +2179,7 @@ schema_delete_attributes ( Slapi_Entry *entryBefore, LDAPMod *mod,
dc8c34
 	  }
dc8c34
 
dc8c34
 	  /* Delete it. */
dc8c34
-	  attr_syntax_delete( a );
dc8c34
+	  attr_syntax_delete( a, 0 );
dc8c34
 	  attr_syntax_return( a );
dc8c34
 	}
dc8c34
 	else {
dc8c34
@@ -2300,7 +2302,7 @@ add_oc_internal(struct objclass *pnew_oc, char *errorbuf, size_t errorbufsize,
dc8c34
 	}
dc8c34
 
dc8c34
 	/* check to see if the oid is already in use by an attribute */
dc8c34
-	if (!rc && (pasyntaxinfo = attr_syntax_get_by_oid(pnew_oc->oc_oid))) {
dc8c34
+	if (!rc && (pasyntaxinfo = attr_syntax_get_by_oid(pnew_oc->oc_oid, flags))) {
dc8c34
 		schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_oc,
dc8c34
 				pnew_oc->oc_name,
dc8c34
 				"The OID \"%s\" is also used by the attribute type \"%s\"",
dc8c34
@@ -2419,7 +2421,7 @@ schema_replace_attributes ( Slapi_PBlock *pb, LDAPMod *mod, char *errorbuf,
dc8c34
 		 * handle the various cases.
dc8c34
 		 */
dc8c34
 		if ( NULL == ( oldasip =
dc8c34
-					attr_syntax_get_by_oid( newasip->asi_oid ))) {
dc8c34
+					attr_syntax_get_by_oid( newasip->asi_oid, 0 ))) {
dc8c34
 			/* new attribute type */
dc8c34
 			LDAPDebug( LDAP_DEBUG_TRACE, "schema_replace_attributes:"
dc8c34
 					" new type %s (OID %s)\n",
dc8c34
@@ -2437,14 +2439,14 @@ schema_replace_attributes ( Slapi_PBlock *pb, LDAPMod *mod, char *errorbuf,
dc8c34
 						" replacing type %s (OID %s)\n",
dc8c34
 						newasip->asi_name, newasip->asi_oid, 0 );
dc8c34
 				/* flag for deletion */
dc8c34
-				attr_syntax_delete( oldasip );
dc8c34
+				attr_syntax_delete( oldasip, 0 );
dc8c34
 			}
dc8c34
 
dc8c34
 			attr_syntax_return( oldasip );
dc8c34
 		}
dc8c34
 
dc8c34
 		if ( NULL != newasip ) {	/* add new or replacement definition */
dc8c34
-			rc = attr_syntax_add( newasip );
dc8c34
+			rc = attr_syntax_add( newasip, 0 );
dc8c34
 			if ( LDAP_SUCCESS != rc ) {
dc8c34
 				schema_create_errormsg( errorbuf, errorbufsize,
dc8c34
 						schema_errprefix_at, newasip->asi_name,
dc8c34
@@ -3355,7 +3357,7 @@ read_at_ldif(const char *input, struct asyntaxinfo **asipp, char *errorbuf,
dc8c34
     if (!status && (NULL != pSuperior)) {
dc8c34
         struct asyntaxinfo *asi_parent;
dc8c34
         
dc8c34
-        asi_parent = attr_syntax_get_by_name(pSuperior);
dc8c34
+        asi_parent = attr_syntax_get_by_name(pSuperior, schema_flags);
dc8c34
         /* if we find no match then server won't start or add the attribute type */
dc8c34
         if (asi_parent == NULL) {
dc8c34
             LDAPDebug (LDAP_DEBUG_PARSE,
dc8c34
@@ -3467,7 +3469,7 @@ read_at_ldif(const char *input, struct asyntaxinfo **asipp, char *errorbuf,
dc8c34
         struct asyntaxinfo    *tmpasi;
dc8c34
 
dc8c34
         if (!(flags & SLAPI_ATTR_FLAG_OVERRIDE) &&
dc8c34
-            ( NULL != ( tmpasi = attr_syntax_get_by_oid(pOid)))) {
dc8c34
+            ( NULL != ( tmpasi = attr_syntax_get_by_oid(pOid, schema_flags)))) {
dc8c34
             schema_create_errormsg( errorbuf, errorbufsize,
dc8c34
                 schema_errprefix_at, first_attr_name,
dc8c34
                 "Could not be added because the OID \"%s\" is already in use",
dc8c34
@@ -3490,7 +3492,7 @@ read_at_ldif(const char *input, struct asyntaxinfo **asipp, char *errorbuf,
dc8c34
         if ( NULL != asipp ) {
dc8c34
             *asipp = tmpasip;    /* just return it */
dc8c34
         } else {                /* add the new attribute to the global store */
dc8c34
-            status = attr_syntax_add( tmpasip );
dc8c34
+            status = attr_syntax_add( tmpasip, schema_flags );
dc8c34
             if ( LDAP_SUCCESS != status ) {
dc8c34
                 if ( 0 != (flags & SLAPI_ATTR_FLAG_OVERRIDE) &&
dc8c34
                             LDAP_TYPE_OR_VALUE_EXISTS == status ) {
dc8c34
@@ -4307,6 +4309,59 @@ get_tagged_oid( const char *tag, const char **inputp,
dc8c34
 	return( oid );
dc8c34
 }
dc8c34
 
dc8c34
+/* 
dc8c34
+ * Reload the schema files
dc8c34
+ *
dc8c34
+ * This is only called from the schema_reload task.  The flag DSE_SCHEMA_LOCKED
dc8c34
+ * is also only set been called from this function.  To not interrupt clients
dc8c34
+ * we will  rebuild the schema in separate hash tables, and then swap the
dc8c34
+ * hash tables once the schema is completely reloaded.  We use the DSE_SCHEMA_LOCKED
dc8c34
+ * flag to tell the attribute syntax functions to use the temporary hashtables.
dc8c34
+ */
dc8c34
+int
dc8c34
+slapi_reload_schema_files(char *schemadir)
dc8c34
+{
dc8c34
+	int rc = LDAP_SUCCESS;
dc8c34
+	struct dse *my_pschemadse = NULL;
dc8c34
+	/* get be to lock */
dc8c34
+	Slapi_Backend *be = slapi_be_select_by_instance_name( DSE_SCHEMA );
dc8c34
+
dc8c34
+	if (NULL == be)
dc8c34
+	{
dc8c34
+		slapi_log_error( SLAPI_LOG_FATAL, "schema_reload",
dc8c34
+				"schema file reload failed\n" );
dc8c34
+		return LDAP_LOCAL_ERROR;
dc8c34
+	}
dc8c34
+	slapi_be_Wlock(be);	/* be lock must be outer of schemafile lock */
dc8c34
+	reload_schemafile_lock();
dc8c34
+	oc_delete_all_nolock();
dc8c34
+	rc = init_schema_dse_ext(schemadir, be, &my_pschemadse,
dc8c34
+	                         DSE_SCHEMA_NO_CHECK | DSE_SCHEMA_LOCKED);
dc8c34
+	if (rc) {
dc8c34
+		/*
dc8c34
+		 * The schema has been reloaded into the temporary hash tables.
dc8c34
+		 * Take the write lock, wipe out the existing hash tables, and
dc8c34
+		 * swap in the new ones.
dc8c34
+		 */
dc8c34
+		attr_syntax_write_lock();
dc8c34
+		attr_syntax_delete_all_for_schemareload(SLAPI_ATTR_FLAG_KEEP);
dc8c34
+		attr_syntax_swap_ht();
dc8c34
+		attr_syntax_unlock_write();
dc8c34
+		slapi_reload_internal_attr_syntax();
dc8c34
+
dc8c34
+		dse_destroy(pschemadse);
dc8c34
+		pschemadse = my_pschemadse;
dc8c34
+		reload_schemafile_unlock();
dc8c34
+		slapi_be_Unlock(be);
dc8c34
+		return LDAP_SUCCESS;
dc8c34
+	} else {
dc8c34
+		reload_schemafile_unlock();
dc8c34
+		slapi_be_Unlock(be);
dc8c34
+		slapi_log_error( SLAPI_LOG_FATAL, "schema_reload",
dc8c34
+				"schema file reload failed\n" );
dc8c34
+		return LDAP_LOCAL_ERROR;
dc8c34
+	}
dc8c34
+}
dc8c34
 
dc8c34
 /*
dc8c34
  * sprintf to `outp' the contents of `tag' followed by `oid' followed by a
dc8c34
@@ -4818,49 +4873,6 @@ slapi_validate_schema_files(char *schemadir)
dc8c34
 }
dc8c34
 
dc8c34
 /* 
dc8c34
- * API to reload the schema files.
dc8c34
- * Rule: this function is called when slapi_validate_schema_files is passed.
dc8c34
- *       Schema checking is skipped in this function.
dc8c34
- */
dc8c34
-int
dc8c34
-slapi_reload_schema_files(char *schemadir)
dc8c34
-{
dc8c34
-	int rc = LDAP_SUCCESS;
dc8c34
-	struct dse *my_pschemadse = NULL;
dc8c34
-	/* get be to lock */
dc8c34
-	Slapi_Backend *be = slapi_be_select_by_instance_name( DSE_SCHEMA );
dc8c34
-
dc8c34
-	if (NULL == be)
dc8c34
-	{
dc8c34
-		slapi_log_error( SLAPI_LOG_FATAL, "schema_reload",
dc8c34
-				"schema file reload failed\n" );
dc8c34
-		return LDAP_LOCAL_ERROR;
dc8c34
-	}
dc8c34
-	slapi_be_Wlock(be);	/* be lock must be outer of schemafile lock */
dc8c34
-	reload_schemafile_lock();
dc8c34
-	/* Exclude attr_syntax not to grab from the hash table while cleaning up  */
dc8c34
-	attr_syntax_write_lock();
dc8c34
-	attr_syntax_delete_all_for_schemareload(SLAPI_ATTR_FLAG_KEEP);
dc8c34
-	oc_delete_all_nolock();
dc8c34
-	attr_syntax_unlock_write();
dc8c34
-	rc = init_schema_dse_ext(schemadir, be, &my_pschemadse,
dc8c34
-	                         DSE_SCHEMA_NO_CHECK | DSE_SCHEMA_LOCKED);
dc8c34
-	if (rc) {
dc8c34
-		dse_destroy(pschemadse);
dc8c34
-		pschemadse = my_pschemadse;
dc8c34
-		reload_schemafile_unlock();
dc8c34
-		slapi_be_Unlock(be);
dc8c34
-		return LDAP_SUCCESS;
dc8c34
-	} else {
dc8c34
-		reload_schemafile_unlock();
dc8c34
-		slapi_be_Unlock(be);
dc8c34
-		slapi_log_error( SLAPI_LOG_FATAL, "schema_reload",
dc8c34
-				"schema file reload failed\n" );
dc8c34
-		return LDAP_LOCAL_ERROR;
dc8c34
-	}
dc8c34
-}
dc8c34
-
dc8c34
-/* 
dc8c34
  * slapi_schema_list_objectclass_attributes:
dc8c34
  *         Return the list of attributes belonging to the objectclass
dc8c34
  *
dc8c34
-- 
dc8c34
1.9.3
dc8c34