Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 307257 Details for
Bug 436837
Dynamically reload schema via task interface
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
cvs diffs
schemareload.diffs (text/plain), 71.79 KB, created by
Noriko Hosoi
on 2008-05-30 23:49:44 UTC
(
hide
)
Description:
cvs diffs
Filename:
MIME Type:
Creator:
Noriko Hosoi
Created:
2008-05-30 23:49:44 UTC
Size:
71.79 KB
patch
obsolete
>Index: ldap/servers/slapd/attrsyntax.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/attrsyntax.c,v >retrieving revision 1.6 >diff -t -w -U4 -r1.6 attrsyntax.c >--- ldap/servers/slapd/attrsyntax.c 4 Oct 2007 16:27:47 -0000 1.6 >+++ ldap/servers/slapd/attrsyntax.c 30 May 2008 23:36:40 -0000 >@@ -451,8 +451,9 @@ > > > if((asi=attr_syntax_get_by_name_locking_optional(s, PR_TRUE, PR_FALSE)) != NULL ) { > r = slapi_ch_strdup(asi->asi_name); >+ attr_syntax_return( asi ); > } > if ( NULL == asi ) { > r = attr_syntax_normalize_no_lookup( s ); > } >@@ -500,8 +501,9 @@ > ATTR_WITH_DIRSTRING_SYNTAX, PR_TRUE, PR_FALSE); > } > if ( NULL != asi ) { > plugin = asi->asi_plugin; >+ attr_syntax_return( asi ); > } > return( plugin ); > } > >@@ -889,8 +891,21 @@ > return ATTR_SYNTAX_ENUM_NEXT; > } > } > >+static int >+attr_syntax_force_to_delete(struct asyntaxinfo *asip, void *arg) >+{ >+ struct attr_syntax_enum_flaginfo *fi; >+ >+ PR_ASSERT( asip != NULL ); >+ fi = (struct attr_syntax_enum_flaginfo *)arg; >+ PR_ASSERT( fi != NULL ); >+ >+ attr_syntax_delete_no_lock( asip, PR_FALSE ); >+ return ATTR_SYNTAX_ENUM_REMOVE; >+} >+ > > /* > * Clear 'flag' within all attribute definitions. > */ >@@ -920,8 +935,21 @@ > attr_syntax_enumerate_attrs( attr_syntax_delete_if_not_flagged, > (void *)&fi, PR_TRUE ); > } > >+/* >+ * Delete all attribute definitions >+ */ >+void >+attr_syntax_delete_all() >+{ >+ struct attr_syntax_enum_flaginfo fi; >+ >+ memset( &fi, 0, sizeof(fi)); >+ attr_syntax_enumerate_attrs( attr_syntax_force_to_delete, >+ (void *)&fi, PR_TRUE ); >+} >+ > static int > attr_syntax_init(void) > { > if (!oid2asi) >Index: ldap/servers/slapd/backend.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/backend.c,v >retrieving revision 1.6 >diff -t -w -U4 -r1.6 backend.c >--- ldap/servers/slapd/backend.c 10 Nov 2006 23:45:40 -0000 1.6 >+++ ldap/servers/slapd/backend.c 30 May 2008 23:36:40 -0000 >@@ -114,8 +114,13 @@ > slapi_ch_free((void **)&be->be_backendconfig); > /* JCM char **be_include; ??? */ > slapi_ch_free((void **)&be->be_name); > PR_DestroyLock(be->be_state_lock); >+ if (be->be_lock != NULL) >+ { >+ PR_DestroyRWLock(be->be_lock); >+ be->be_lock = NULL; >+ } > } > > void > slapi_be_delete_onexit (Slapi_Backend *be) >@@ -160,8 +165,14 @@ > } > return r; > } > >+int >+be_isdeleted( const Slapi_Backend *be ) >+{ >+ return BE_STATE_DELETED == be->be_state; >+} >+ > void > be_addsuffix(Slapi_Backend *be,const Slapi_DN *suffix) > { > if (be->be_state != BE_STATE_DELETED) >Index: ldap/servers/slapd/backend_manager.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/backend_manager.c,v >retrieving revision 1.9 >diff -t -w -U4 -r1.9 backend_manager.c >--- ldap/servers/slapd/backend_manager.c 9 Apr 2007 23:02:41 -0000 1.9 >+++ ldap/servers/slapd/backend_manager.c 30 May 2008 23:36:40 -0000 >@@ -148,8 +148,17 @@ > /* All the other function pointers default to NULL */ > return be; > } > >+/* >+ * Rule: before coming to this point, slapi_be_Wlock(be) must be acquired. >+ */ >+void >+be_replace_dse_internal(Slapi_Backend *be, struct dse *pdse) >+{ >+ be->be_database->plg_private= (void*)pdse; >+} >+ > Slapi_Backend* > slapi_get_first_backend (char **cookie) > { > int i; >@@ -340,10 +349,9 @@ > slapi_pblock_set( &pb, SLAPI_PLUGIN, backends[i]->be_database ); > slapi_pblock_set( &pb, SLAPI_BACKEND, backends[i] ); > > (*backends[i]->be_cleanup)( &pb ); >- be_done(backends[i]); >- slapi_ch_free((void **)&backends[i]); >+ slapi_be_free(&backends[i]); > } > } > slapi_ch_free((void**)&backends); > } >Index: ldap/servers/slapd/dse.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/dse.c,v >retrieving revision 1.8 >diff -t -w -U4 -r1.8 dse.c >--- ldap/servers/slapd/dse.c 18 Oct 2007 00:08:34 -0000 1.8 >+++ ldap/servers/slapd/dse.c 30 May 2008 23:36:40 -0000 >@@ -209,18 +209,18 @@ > { > Slapi_Entry *e= NULL; > struct dse_node *n; > >- if (use_lock == DSE_USE_LOCK) >+ if (use_lock == DSE_USE_LOCK && pdse->dse_rwlock) > PR_RWLock_Rlock(pdse->dse_rwlock); > > n = dse_find_node( pdse, dn ); > if(n!=NULL) > { > e = slapi_entry_dup(n->entry); > } > >- if (use_lock == DSE_USE_LOCK) >+ if (use_lock == DSE_USE_LOCK && pdse->dse_rwlock) > PR_RWLock_Unlock(pdse->dse_rwlock); > > return e; > } >@@ -443,31 +443,44 @@ > /* > * Get rid of a dse structure. > */ > int >-dse_deletedse(Slapi_PBlock *pb) >-{ >- struct dse *pdse = NULL; >- >- slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &pdse); >- >- if (pdse) >+dse_destroy(struct dse *pdse) > { > int nentries = 0; >+ if (pdse->dse_rwlock) > PR_RWLock_Wlock(pdse->dse_rwlock); > slapi_ch_free((void **)&(pdse->dse_filename)); > slapi_ch_free((void **)&(pdse->dse_tmpfile)); > slapi_ch_free((void **)&(pdse->dse_fileback)); > slapi_ch_free((void **)&(pdse->dse_filestartOK)); > dse_callback_deletelist(&pdse->dse_callback); >+ charray_free(pdse->dse_filelist); > nentries = avl_free(pdse->dse_tree, dse_internal_delete_entry); >+ if (pdse->dse_rwlock) { > PR_RWLock_Unlock(pdse->dse_rwlock); > PR_DestroyRWLock(pdse->dse_rwlock); >+ } > slapi_ch_free((void **)&pdse); > LDAPDebug( SLAPI_DSE_TRACELEVEL, "Removed [%d] entries from the dse tree.\n", > nentries,0,0 ); > } > >+/* >+ * Get rid of a dse structure. >+ */ >+int >+dse_deletedse(Slapi_PBlock *pb) >+{ >+ struct dse *pdse = NULL; >+ >+ slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &pdse); >+ >+ if (pdse) >+ { >+ dse_destroy(pdse); >+ } >+ > /* data is freed, so make sure no one tries to use it */ > slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, NULL); > > return 0; >@@ -642,8 +655,11 @@ > int rc= 0; /* Fail */ > PRInt32 nr = 0; > PRFileInfo prfinfo; > PRFileDesc *prfd = 0; >+ int schema_flags = 0; >+ >+ slapi_pblock_get(pb, SLAPI_TASK_FLAGS, &schema_flags); > > if ( (NULL != pdse) && (NULL != filename) ) > { > if ( (rc = PR_GetFileInfo( filename, &prfinfo )) != PR_SUCCESS ) >@@ -704,8 +720,10 @@ > { > int dont_check_dups = 0; > int str2entry_flags = SLAPI_STR2ENTRY_EXPAND_OBJECTCLASSES | > SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF ; >+ if (schema_flags & DSE_SCHEMA_LOCKED) >+ str2entry_flags |= SLAPI_STR2ENTRY_NO_SCHEMA_LOCK; > > PR_ASSERT(pb); > slapi_pblock_get(pb, SLAPI_DSE_DONT_CHECK_DUPS, &dont_check_dups); > if ( !dont_check_dups ) { >@@ -891,8 +909,9 @@ > dse_check_for_readonly_error(Slapi_PBlock *pb, struct dse* pdse) > { > int rc = 0; /* default: no error */ > >+ if (pdse->dse_rwlock) > PR_RWLock_Rlock(pdse->dse_rwlock); > > if ( !pdse->dse_is_updateable ) { > if ( !pdse->dse_readonly_error_reported ) { >@@ -907,8 +926,9 @@ > } > rc = 1; /* return an error to the client */ > } > >+ if (pdse->dse_rwlock) > PR_RWLock_Unlock(pdse->dse_rwlock); > > if ( rc != 0 ) { > slapi_send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL, >@@ -1055,8 +1075,9 @@ > slapi_pblock_get(pb, SLAPI_DSE_DONT_WRITE_WHEN_ADDING, &dont_write_file); > slapi_pblock_get(pb, SLAPI_DSE_MERGE_WHEN_ADDING, &merge); > > /* keep write lock during both tree update and file write operations */ >+ if (pdse->dse_rwlock) > PR_RWLock_Wlock(pdse->dse_rwlock); > if (merge) > { > rc= avl_insert( &(pdse->dse_tree), n, entry_dn_cmp, dupentry_merge ); >@@ -1078,8 +1099,9 @@ > } > } else { /* duplicate entry ignored */ > dse_node_delete(&n); /* This also deletes the contained entry */ > } >+ if (pdse->dse_rwlock) > PR_RWLock_Unlock(pdse->dse_rwlock); > > if (rc == -1) > { >@@ -1253,9 +1275,9 @@ > int rc= -1; > if ( NULL != e ) > { > struct dse_node *n= dse_node_new(e); >- if (use_lock) >+ if (use_lock && pdse->dse_rwlock) > PR_RWLock_Wlock(pdse->dse_rwlock); > rc = avl_insert( &(pdse->dse_tree), n, entry_dn_cmp, dupentry_replace ); > if (write_file) > dse_write_file_nolock(pdse); >@@ -1264,9 +1286,9 @@ > if (DSE_ENTRY_WAS_REPLACED == rc) { > dse_node_delete(&n); > rc = 0; /* for return to caller */ > } >- if (use_lock) >+ if (use_lock && pdse->dse_rwlock) > PR_RWLock_Unlock(pdse->dse_rwlock); > } > return rc; > } >@@ -1365,8 +1387,9 @@ > > slapi_pblock_get(pb, SLAPI_DSE_DONT_WRITE_WHEN_ADDING, &dont_write_file); > > /* keep write lock for both tree deleting and file writing */ >+ if (pdse->dse_rwlock) > PR_RWLock_Wlock(pdse->dse_rwlock); > if ((deleted_node = (struct dse_node *)avl_delete(&pdse->dse_tree, > n, entry_dn_cmp))) > dse_node_delete(&deleted_node); >@@ -1378,8 +1401,9 @@ > dse_updateNumSubOfParent(pdse, slapi_entry_get_sdn_const(e), > SLAPI_OPERATION_DELETE); > dse_write_file_nolock(pdse); > } >+ if (pdse->dse_rwlock) > PR_RWLock_Unlock(pdse->dse_rwlock); > > return 1; > } >@@ -1554,10 +1578,12 @@ > * entries that change, we skip looking through the DSE entries. > */ > if ( pb->pb_op == NULL > || !operation_is_flag_set( pb->pb_op, OP_FLAG_PS_CHANGESONLY )) { >+ if (pdse->dse_rwlock) > PR_RWLock_Rlock(pdse->dse_rwlock); > dse_apply_nolock(pdse,dse_search_filter_entry,(caddr_t)&stuff); >+ if (pdse->dse_rwlock) > PR_RWLock_Unlock(pdse->dse_rwlock); > } > > if (stuff.ss) /* something was found which matched our criteria */ >Index: ldap/servers/slapd/entry.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/entry.c,v >retrieving revision 1.14 >diff -t -w -U4 -r1.14 entry.c >--- ldap/servers/slapd/entry.c 18 Oct 2007 00:08:34 -0000 1.14 >+++ ldap/servers/slapd/entry.c 30 May 2008 23:36:40 -0000 >@@ -1066,10 +1066,17 @@ > return e; /* e == NULL */ > > if ( flags & SLAPI_STR2ENTRY_EXPAND_OBJECTCLASSES ) > { >+ if ( flags & SLAPI_STR2ENTRY_NO_SCHEMA_LOCK ) >+ { >+ schema_expand_objectclasses_nolock( e ); >+ } >+ else >+ { > slapi_schema_expand_objectclasses( e ); > } >+ } > > if ( flags & SLAPI_STR2ENTRY_TOMBSTONE_CHECK ) > { > /* >Index: ldap/servers/slapd/mapping_tree.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/mapping_tree.c,v >retrieving revision 1.12 >diff -t -w -U4 -r1.12 mapping_tree.c >--- ldap/servers/slapd/mapping_tree.c 18 Oct 2007 00:08:34 -0000 1.12 >+++ ldap/servers/slapd/mapping_tree.c 30 May 2008 23:36:40 -0000 >@@ -1604,9 +1604,9 @@ > node= add_internal_mapping_tree_node("cn=config", be, mapping_tree_root); > mapping_tree_node_add_child(mapping_tree_root, node); > node= add_internal_mapping_tree_node("cn=monitor", be, mapping_tree_root); > mapping_tree_node_add_child(mapping_tree_root, node); >- be= slapi_be_select_by_instance_name( "schema-internal" ); >+ be= slapi_be_select_by_instance_name( DSE_SCHEMA ); > node= add_internal_mapping_tree_node("cn=schema", be, mapping_tree_root); > mapping_tree_node_add_child(mapping_tree_root, node); > > /* >@@ -2002,9 +2002,9 @@ > (op_type != SLAPI_OPERATION_SEARCH)) ) { > > mtn_unlock(); > *be = slapi_be_select_by_instance_name(DSE_BACKEND); >- if(*be != NULL) >+ if(*be != NULL && !be_isdeleted(*be)) > { > ret = LDAP_SUCCESS; > slapi_be_Rlock(*be); /* also done inside mtn_get_be() below */ > } else { >@@ -2025,9 +2025,9 @@ > /* if a backend was returned, make sure that all non-search operations > * fail if the backend is read-only, > * or if the whole server is readonly AND backend is public (!private) > */ >- if ((ret == LDAP_SUCCESS) && *be && >+ if ((ret == LDAP_SUCCESS) && *be && !be_isdeleted(*be) && > ((*be)->be_readonly || > (slapi_config_get_readonly() && !slapi_be_private(*be)))) { > unsigned long op_type = operation_get_type(op); > >@@ -2100,9 +2100,9 @@ > if( sdn_is_nulldn(target_sdn) && ( op_type == SLAPI_OPERATION_SEARCH) > && (scope == LDAP_SCOPE_BASE) ) { > mtn_unlock(); > be = slapi_be_select_by_instance_name(DSE_BACKEND); >- if(be != NULL) >+ if(be != NULL && !be_isdeleted(be)) > { > be_list[0]=be; > be_list[1] = NULL; > ret_code = LDAP_SUCCESS; >@@ -2127,9 +2127,9 @@ > || ((node_list == mapping_tree_root) && node->mtn_private > && (scope != LDAP_SCOPE_BASE)) ) > && (!be || strncmp(be->be_name, "default", 8))) > { >- if (be) >+ if (be && !be_isdeleted(be)) > { > /* wrong backend or referall, ignore it */ > slapi_log_error(SLAPI_LOG_ARGS, NULL, > "mapping tree release backend : %s\n", >@@ -2138,9 +2138,9 @@ > } > } > else > { >- if (be) >+ if (be && !be_isdeleted(be)) > { > be_list[be_index++]=be; > } > >@@ -2284,9 +2284,9 @@ > slapi_entry_free(new_referral); > > if (ret != LDAP_SUCCESS) > { >- if (*be) >+ if (be && !be_isdeleted(be)) > { > slapi_be_Unlock(*be); > *be = NULL; > } >@@ -2520,9 +2520,9 @@ > } > } > > if (result == LDAP_SUCCESS) { >- if (*be) { >+ if (*be && !be_isdeleted(*be)) { > slapi_log_error(SLAPI_LOG_ARGS, NULL, > "mapping tree selected backend : %s\n", > slapi_be_get_name(*be)); > slapi_be_Rlock(*be); >@@ -2789,9 +2789,9 @@ > /* Check if the dn targets an internal reserved backends */ > int > slapi_on_internal_backends(const Slapi_DN *sdn) > { >- char *backend_names[] = {"frontend-internal", "schema-internal"}; >+ char *backend_names[] = {DSE_BACKEND, DSE_SCHEMA}; > int internal = 1; > int numOfInternalBackends = 2; > int count; > >Index: ldap/servers/slapd/pblock.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/pblock.c,v >retrieving revision 1.12 >diff -t -w -U4 -r1.12 pblock.c >--- ldap/servers/slapd/pblock.c 18 Oct 2007 20:49:01 -0000 1.12 >+++ ldap/servers/slapd/pblock.c 30 May 2008 23:36:40 -0000 >@@ -561,8 +561,11 @@ > break; > case SLAPI_PLUGIN_DB_WIRE_IMPORT_FN: > (*(IFP *)value) = pblock->pb_plugin->plg_wire_import; > break; >+ case SLAPI_PLUGIN_DB_ADD_SCHEMA_FN: >+ (*(IFP *)value) = pblock->pb_plugin->plg_add_schema; >+ break; > case SLAPI_PLUGIN_DB_SEQ_FN: > if ( pblock->pb_plugin->plg_type != SLAPI_PLUGIN_DATABASE ) { > return( -1 ); > } >@@ -1838,8 +1841,11 @@ > break; > case SLAPI_PLUGIN_DB_WIRE_IMPORT_FN: > pblock->pb_plugin->plg_wire_import = (IFP) value; > break; >+ case SLAPI_PLUGIN_DB_ADD_SCHEMA_FN: >+ pblock->pb_plugin->plg_add_schema = (IFP) value; >+ break; > case SLAPI_PLUGIN_DB_SEQ_FN: > if ( pblock->pb_plugin->plg_type != SLAPI_PLUGIN_DATABASE ) { > return( -1 ); > } >Index: ldap/servers/slapd/proto-slap.h >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/proto-slap.h,v >retrieving revision 1.32 >diff -t -w -U4 -r1.32 proto-slap.h >--- ldap/servers/slapd/proto-slap.h 3 Apr 2008 21:07:55 -0000 1.32 >+++ ldap/servers/slapd/proto-slap.h 30 May 2008 23:36:40 -0000 >@@ -116,8 +116,9 @@ > * by attr_syntax_get_by_oid() or attr_syntax_get_by_name(). > */ > void attr_syntax_return( struct asyntaxinfo *asi ); > void attr_syntax_return_locking_optional( struct asyntaxinfo *asi, PRBool use_lock ); >+void attr_syntax_delete_all(void); > > /* > * value.c > */ >@@ -191,8 +192,9 @@ > /* > * backend_manager.c > */ > Slapi_Backend *be_new_internal(struct dse *pdse, const char *type, const char *name); >+void be_replace_dse_internal(Slapi_Backend *be, struct dse *pdse); > int fedse_create_startOK(char *filename, char *startokfilename, const char *configdir); > void be_cleanupall(); > void be_flushall(); > int be_remove( Slapi_Backend *be ); >@@ -549,12 +551,14 @@ > #define DSE_OPERATION_READ 0x100 > #define DSE_OPERATION_WRITE 0x200 > > #define DSE_BACKEND "frontend-internal" >+#define DSE_SCHEMA "schema-internal" > > struct dse *dse_new( char *filename, char *tmpfilename, char *backfilename, char *startokfilename, const char *configdir); > struct dse *dse_new_with_filelist(char *filename, char *tmpfilename, char *backfilename, char *startokfilename, const char *configdir, char **filelist); > int dse_deletedse(Slapi_PBlock *pb); >+int dse_destroy(struct dse *pdse); > int dse_read_file(struct dse *pdse, Slapi_PBlock *pb); > int dse_bind( Slapi_PBlock *pb ); > int dse_unbind( Slapi_PBlock *pb ); > int dse_search(Slapi_PBlock *pb); >@@ -852,13 +856,21 @@ > /* Note: callers of g_set_global_schema_csn() must hold a write lock. */ > /* csn is consumed. */ > void g_set_global_schema_csn(CSN *csn); > void slapi_schema_expand_objectclasses( Slapi_Entry *e ); >+/* lock to protect both objectclass and schema_dse */ >+void slapi_load_schemafile_lock( void ); >+void slapi_load_schemafile_unlock( void ); >+/* API to validate the schema files */ >+int slapi_validate_schema_files(char *schemadir); >+/* API to reload the schema files */ >+int slapi_reload_schema_files(char *schemadir); > > /* > * schemaparse.c > */ > void normalize_oc( void ); >+void normalize_oc_nolock( void ); > /* Note: callers of oc_update_inheritance_nolock() must hold a write lock */ > void oc_update_inheritance_nolock( struct objclass *oc ); > > /* >Index: ldap/servers/slapd/schema.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/schema.c,v >retrieving revision 1.11 >diff -t -w -U4 -r1.11 schema.c >--- ldap/servers/slapd/schema.c 25 Sep 2007 19:43:50 -0000 1.11 >+++ ldap/servers/slapd/schema.c 30 May 2008 23:36:40 -0000 >@@ -110,9 +110,9 @@ > char *errorbuf, size_t errorbufsize ); > static int schema_replace_objectclasses ( Slapi_PBlock *pb, LDAPMod *mod, > char *errorbuf, size_t errorbufsize ); > static int read_oc_ldif ( const char *input, struct objclass **oc, >- char *errorbuf, size_t errorbufsize, int nolock, int is_user_defined, >+ char *errorbuf, size_t errorbufsize, PRUint32 flags, int is_user_defined, > int schema_ds4x_compat ); > static int schema_check_name(char *name, PRBool isAttribute, char *errorbuf, > size_t errorbufsize ); > static int schema_check_oid(const char *name, const char *oid, >@@ -121,10 +121,10 @@ > static int isExtensibleObjectclass(const char *objectclass); > static int strip_oc_options ( struct objclass *poc ); > static char *stripOption (char *attr); > static int read_at_ldif(const char *input, struct asyntaxinfo **asipp, >- char *errorbuf, size_t errorbufsize, int nolock, int is_user_defined, >- int schema_ds4x_compat, int is_remote); >+ char *errorbuf, size_t errorbufsize, PRUint32 flags, >+ int is_user_defined, int schema_ds4x_compat, int is_remote); > static char **parse_qdlist(const char *s, int *n, int strip_options); > static void free_qdlist(char **vals, int n); > static char **parse_qdescrs(const char *s, int *n); > static char **parse_qdstrings(const char *s, int *n); >@@ -455,8 +455,9 @@ > int is_extensible_object = 0; > int i, oc_count = 0; > int unknown_class = 0; > char errtext[ BUFSIZ ]; >+ PRUint32 schema_flags; > > /* smart referrals are not allowed in Directory Lite */ > if ( config_is_slapd_lite() ) { > if ( has_smart_referral(e) ) { >@@ -467,10 +468,12 @@ > /* > * say the schema checked out ok if we're not checking schema at > * all, or if this is a replication update. > */ >- if (pb != NULL) >+ if (pb != NULL) { > slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &is_replicated_operation); >+ slapi_pblock_get(pb, SLAPI_TASK_FLAGS, &schema_flags); >+ } > if ( schemacheck == 0 || is_replicated_operation ) { > return( 0 ); > } > >@@ -503,8 +506,9 @@ > > /* > * Need the read lock to create the oc array and while we use it. > */ >+ if (!(schema_flags & DSE_SCHEMA_LOCKED)) > oc_lock_read(); > > oc_count = 0; > for (i= slapi_attr_first_value(aoc,&v); i != -1; >@@ -622,8 +626,9 @@ > } > > out: > /* Done with the oc array so can release the lock */ >+ if (!(schema_flags & DSE_SCHEMA_LOCKED)) > oc_unlock(); > slapi_ch_free((void**)&oclist); > > return( ret ); >@@ -921,8 +926,21 @@ > > return rc; > } > >+static void >+oc_delete_all_nolock( void ) >+{ >+ struct objclass *oc, *pnext; >+ >+ oc = g_get_global_oc_nolock(); >+ for (pnext = oc->oc_next; oc; >+ oc = pnext, pnext = oc?oc->oc_next:NULL) { >+ oc_free( &oc ); >+ } >+ g_set_global_oc_nolock ( NULL ); >+} >+ > > /* > * Compare two objectclass definitions for equality. Return PR_TRUE if > * they are equivalent and PR_FALSE if not. >@@ -2196,9 +2214,9 @@ > /* struct sizedbuffer *psbAttrSyntax= sizedbuffer_construct(BUFSIZ); */ > int status = 0; > > for (i = 0; LDAP_SUCCESS == status && mod->mod_bvalues[i]; i++) { >- int nolock = 0; /* lock global resources during normal operation */ >+ PRUint32 nolock = 0; /* lock global resources during normal operation */ > attr_ldif = (char *) mod->mod_bvalues[i]->bv_val; > > status = read_at_ldif(attr_ldif, NULL, errorbuf, errorbufsize, > nolock, 1 /* user defined */, schema_ds4x_compat, 1); >@@ -2220,14 +2238,15 @@ > * Returns an LDAP error code (LDAP_SUCCESS if all goes well) > */ > static int > add_oc_internal(struct objclass *pnew_oc, char *errorbuf, size_t errorbufsize, >- int schema_ds4x_compat ) >+ int schema_ds4x_compat, PRUint32 flags ) > { > struct objclass *oldoc_by_name, *oldoc_by_oid, *psup_oc = NULL; > int redefined_oc = 0, rc=0; > asyntaxinfo *pasyntaxinfo = 0; > >+ if (!(flags & DSE_SCHEMA_LOCKED)) > oc_lock_write(); > > oldoc_by_name = oc_find_nolock (pnew_oc->oc_name); > oldoc_by_oid = oc_find_nolock (pnew_oc->oc_oid); >@@ -2295,15 +2314,16 @@ > attr_syntax_return( pasyntaxinfo ); > } > > /* check to see if the objectclass name is valid */ >- if (!rc && schema_check_name ( pnew_oc->oc_name, PR_FALSE, >- errorbuf, errorbufsize ) == 0 ) { >+ if (!rc && !(flags & DSE_SCHEMA_NO_CHECK) && >+ schema_check_name ( pnew_oc->oc_name, PR_FALSE, errorbuf, errorbufsize ) >+ == 0 ) { > rc = schema_ds4x_compat ? LDAP_OPERATIONS_ERROR : LDAP_INVALID_SYNTAX; > } > > /* check to see if the oid is valid */ >- if (!rc) >+ if (!rc && !(flags & DSE_SCHEMA_NO_CHECK)) > { > struct sizedbuffer *psbOcOid, *psbOcName; > > psbOcName = sizedbuffer_construct(strlen(pnew_oc->oc_name) + 1); >@@ -2319,9 +2339,10 @@ > sizedbuffer_destroy(psbOcOid); > } > > /* check to see if the oc's attributes are valid */ >- if (!rc && schema_check_oc_attrs ( pnew_oc, errorbuf, errorbufsize, >+ if (!rc && !(flags & DSE_SCHEMA_NO_CHECK) && >+ schema_check_oc_attrs ( pnew_oc, errorbuf, errorbufsize, > 0 /* don't strip options */ ) == 0 ) { > rc = schema_ds4x_compat ? LDAP_OPERATIONS_ERROR : LDAP_INVALID_SYNTAX; > } > /* insert new objectclass exactly where the old one one in the linked list*/ >@@ -2337,8 +2358,9 @@ > if (!rc && redefined_oc ) { > oc_update_inheritance_nolock( pnew_oc ); > } > >+ if (!(flags & DSE_SCHEMA_LOCKED)) > oc_unlock(); > return rc; > } > >@@ -2469,9 +2491,9 @@ > return rc; > } > > if ( LDAP_SUCCESS != (rc = add_oc_internal(pnew_oc, errorbuf, >- errorbufsize, schema_ds4x_compat))) { >+ errorbufsize, schema_ds4x_compat, 0/* no restriction */))) { > oc_free( &pnew_oc ); > return rc; > } > >@@ -2540,9 +2562,9 @@ > for ( i = 0; mod->mod_bvalues[i] != NULL; ++i ) { > struct objclass *addocp = NULL; > > if ( LDAP_SUCCESS != ( rc = read_oc_ldif( mod->mod_bvalues[i]->bv_val, >- &newocp, errorbuf, errorbufsize, 1 /* no locking */, >+ &newocp, errorbuf, errorbufsize, DSE_SCHEMA_NO_GLOCK, > 1 /* user defined */, 0 /* no DS 4.x compat issues */ ))) { > rc = LDAP_INVALID_SYNTAX; > goto clean_up_and_return; > } >@@ -2694,9 +2716,14 @@ > * input : value of objectclasses attribute to read > * oc : pointer write the objectclass to > * errorbuf : buffer to write any errors to > * is_user_defined : if non-zero, force objectclass to be user defined >- * nolock : if non-zero, assume oc_lock_*() has been called. >+ * schema_flags : Any or none of the following bits could be set >+ * DSE_SCHEMA_NO_CHECK -- schema won't be checked >+ * DSE_SCHEMA_NO_GLOCK -- don't lock global resources >+ * DSE_SCHEMA_LOCKED -- already locked with >+ * slapi_load_schemafile_lock; >+ * no further lock needed > * schema_ds4x_compat: if non-zero, act like Netscape DS 4.x > * > * Returns: an LDAP error code > * >@@ -2707,10 +2734,11 @@ > * be written to errorbuf > */ > static int > read_oc_ldif ( const char *input, struct objclass **oc, char *errorbuf, >- size_t errorbufsize, int nolock, int is_user_defined, >- int schema_ds4x_compat ) { >+ size_t errorbufsize, PRUint32 schema_flags, int is_user_defined, >+ int schema_ds4x_compat ) >+{ > int i, j, num_origins; > const char *pstart, *nextinput; > struct objclass *pnew_oc, *psup_oc; > char **RequiredAttrsArray, **AllowedAttrsArray; >@@ -2847,9 +2875,9 @@ > /* look for the optional OBSOLETE marker */ > flags |= get_flag_keyword( schema_obsolete_with_spaces, > OC_FLAG_OBSOLETE, &nextinput, keyword_strstr_fn ); > >- if (!nolock) { >+ if (!(schema_flags & DSE_SCHEMA_NO_GLOCK)) { > oc_lock_read(); /* needed because we access the superior oc */ > } > > if ( schema_ds4x_compat ) nextinput = input; >@@ -3004,9 +3032,9 @@ > OrigRequiredAttrsArray = charray_dup ( RequiredAttrsArray ); > OrigAllowedAttrsArray = charray_dup ( AllowedAttrsArray ); > } > >- if (!nolock) { >+ if (!(schema_flags & DSE_SCHEMA_NO_GLOCK)) { > oc_unlock(); /* we are done accessing superior oc (psup_oc) */ > } > > /* finally -- create new objclass structure */ >@@ -3107,19 +3135,24 @@ > /* > * if asipp is NULL, the attribute type is added to the global set of schema. > * if asipp is not NULL, the AT is not added but *asipp is set. > * >- * if nolock is true, locking of global resources is turned off; this saves >- * time during initialization since the server operates in single threaded >- * mode at that time. >+ * schema_flags: Any or none of the following bits could be set >+ * DSE_SCHEMA_NO_CHECK -- schema won't be checked >+ * DSE_SCHEMA_NO_GLOCK -- locking of global resources is turned off; >+ * this saves time during initialization since >+ * the server operates in single threaded mode >+ * at that time or in slapi_load_schemafile_lock. >+ * DSE_SCHEMA_LOCKED -- already locked with slapi_load_schemafile_lock; >+ * no further lock needed > * > * if is_user_defined is true, force attribute type to be user defined. > * > * returns an LDAP error code (LDAP_SUCCESS if all goes well) > */ > static int > read_at_ldif(const char *input, struct asyntaxinfo **asipp, char *errorbuf, >- size_t errorbufsize, int nolock, int is_user_defined, >+ size_t errorbufsize, PRUint32 schema_flags, int is_user_defined, > int schema_ds4x_compat, int is_remote) > { > char *pStart, *pEnd; > char *pOid, *pSyntax, *pSuperior, *pMREquality, *pMROrdering, *pMRSubstring; >@@ -3190,9 +3223,9 @@ > keyword_strstr_fn = PL_strstr; > invalid_syntax_error = LDAP_INVALID_SYNTAX; > } > >- if (nolock) >+ if (schema_flags & DSE_SCHEMA_NO_GLOCK) > flags |= SLAPI_ATTR_FLAG_NOLOCKING; > > psbAttrName->buffer[0] = '\0'; > psbAttrDesc->buffer[0] = '\0'; >@@ -3379,8 +3412,9 @@ > schema_errprefix_at, first_attr_name, > "Missing parent attribute syntax OID"); > status = invalid_syntax_error; > } >+ attr_syntax_return( asi_parent ); > } > } > /* > if we are remote (via modify_schema_dse) then check sup dependencies. Locally >@@ -3417,8 +3451,9 @@ > > if (!status) { > struct objclass *poc; > /* check to make sure that the OID isn't being used by an objectclass */ >+ if (!(schema_flags & DSE_SCHEMA_LOCKED)) > oc_lock_read(); > poc = oc_find_oid_nolock( pOid ); > if ( poc != NULL) { > schema_create_errormsg( errorbuf, errorbufsize, >@@ -3426,8 +3461,9 @@ > "The OID \"%s\" is also used by the object class \"%s\"", > pOid, poc->oc_name); > status = LDAP_TYPE_OR_VALUE_EXISTS; > } >+ if (!(schema_flags & DSE_SCHEMA_LOCKED)) > oc_unlock(); > } > > if (!status && !element_is_user_defined( attr_origins )) { >@@ -3440,9 +3476,9 @@ > flags |= SLAPI_ATTR_FLAG_STD_ATTR; > } > } > >- if (!status) { >+ if (!(schema_flags & DSE_SCHEMA_NO_CHECK) && !status) { > int ii; > /* check to see if the attribute name is valid */ > for (ii = 0; !status && (ii < num_names); ++ii) { > if ( schema_check_name(attr_names[ii], PR_TRUE, errorbuf, >@@ -3458,9 +3494,9 @@ > } > } > } > >- if (!status) { >+ if (!(schema_flags & DSE_SCHEMA_NO_CHECK) && !status) { > if ( schema_check_oid ( first_attr_name, pOid, PR_TRUE, errorbuf, > errorbufsize ) == 0 ) { > status = invalid_syntax_error; > } >@@ -3919,11 +3955,13 @@ > load_schema_dse(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *ignored, > int *returncode, char *returntext, void *arg) > { > Slapi_Attr *attr = 0; >- int nolock = 1; /* don't lock global resources during initialization */ > int primary_file = 0; /* this is the primary (writeable) schema file */ > int schema_ds4x_compat = config_get_ds4_compatible_schema(); >+ PRUint32 flags = *(PRUint32 *)arg; >+ flags |= DSE_SCHEMA_NO_GLOCK; /* don't lock global resources >+ during initialization */ > > *returncode = 0; > > /* >@@ -3944,14 +3982,27 @@ > { > const char *s = slapi_value_get_string(v); > if (!s) > continue; >+ if (flags & DSE_SCHEMA_NO_LOAD) >+ { >+ struct asyntaxinfo *tmpasip = NULL; >+ if ((*returncode = read_at_ldif(s, &tmpasip, returntext, >+ SLAPI_DSE_RETURNTEXT_SIZE, flags, >+ primary_file /* force user defined? */, >+ schema_ds4x_compat, 0)) != 0) >+ break; >+ attr_syntax_free( tmpasip ); /* trash it */ >+ } >+ else >+ { > if ((*returncode = read_at_ldif(s, NULL, returntext, >- SLAPI_DSE_RETURNTEXT_SIZE, nolock, >+ SLAPI_DSE_RETURNTEXT_SIZE, flags, > primary_file /* force user defined? */, > schema_ds4x_compat, 0)) != 0) > break; > } >+ } > slapi_entry_attr_delete(e, "attributetypes"); > } > > if (*returncode) >@@ -3970,24 +4021,35 @@ > const char *s = slapi_value_get_string(v); > if (!s) > continue; > if ( LDAP_SUCCESS != (*returncode = read_oc_ldif(s, &oc, returntext, >- SLAPI_DSE_RETURNTEXT_SIZE, nolock, >+ SLAPI_DSE_RETURNTEXT_SIZE, flags, > primary_file /* force user defined? */, > schema_ds4x_compat))) { > break; > } >- if ( LDAP_SUCCESS != (*returncode = add_oc_internal(oc, returntext, >- SLAPI_DSE_RETURNTEXT_SIZE, schema_ds4x_compat))) { >+ if (flags & DSE_SCHEMA_NO_LOAD) >+ { >+ /* we don't load the objectclase; free it */ >+ oc_free( &oc ); >+ } >+ else >+ { >+ if ( LDAP_SUCCESS != >+ (*returncode = add_oc_internal(oc, returntext, >+ SLAPI_DSE_RETURNTEXT_SIZE, schema_ds4x_compat, >+ flags))) { > oc_free( &oc ); > break; > } > } >+ } > slapi_entry_attr_delete(e, "objectclasses"); > } > > /* Set the schema CSN */ >- if (!slapi_entry_attr_find(e, "nsschemacsn", &attr) && attr) >+ if (!(flags & DSE_SCHEMA_NO_LOAD) && >+ !slapi_entry_attr_find(e, "nsschemacsn", &attr) && attr) > { > Slapi_Value *v = NULL; > slapi_attr_first_value(attr, &v); > if (NULL != v) { >@@ -4009,32 +4071,53 @@ > * file doesn't exist, we try to create it and put a minimal > * schema entry into it. > * > * Returns 1 for OK, 0 for Fail. >+ * >+ * schema_flags: >+ * DSE_SCHEMA_NO_LOAD -- schema won't get loaded >+ * DSE_SCHEMA_NO_CHECK -- schema won't be checked >+ * DSE_SCHEMA_NO_BACKEND -- don't add as backend >+ * DSE_SCHEMA_LOCKED -- already locked; no further lock needed >+ > */ >-int >-init_schema_dse(const char *configdir) >+static int >+init_schema_dse_ext(char *schemadir, Slapi_Backend *be, >+ struct dse **local_pschemadse, PRUint32 schema_flags) > { > int rc= 1; /* OK */ >- char *schemadir = 0; > char *userschemafile = 0; > char *userschematmpfile = 0; > char **filelist = 0; >+ char *myschemadir = NULL; > Slapi_DN schema; > >+ if (NULL == local_pschemadse) >+ { >+ return 0; /* cannot proceed; return failure */ >+ } >+ > slapi_sdn_init_dn_byref(&schema,"cn=schema"); > >- schemadir = config_get_schemadir(); >- if (NULL == schemadir) { >- /* schemadir info is not configured, let's use the default place */ >- schemadir = slapi_ch_smprintf("%s/%s", configdir, SCHEMA_SUBDIR_NAME); >+ /* get schemadir if not given */ >+ if (NULL == schemadir) >+ { >+ myschemadir = config_get_schemadir(); >+ if (NULL == myschemadir) >+ { >+ return 0; /* cannot proceed; return failure */ >+ } >+ } >+ else >+ { >+ myschemadir = schemadir; > } > >- filelist = get_priority_filelist(schemadir, ".*ldif$"); >+ filelist = get_priority_filelist(myschemadir, ".*ldif$"); > if (!filelist || !*filelist) > { > slapi_log_error(SLAPI_LOG_FATAL, "schema", >- "No schema files were found in the directory %s\n", schemadir); >+ "No schema files were found in the directory %s\n", myschemadir); > free_filelist(filelist); > rc = 0; > } > else >@@ -4045,20 +4128,25 @@ > userschemafile = filelist[ii-1]; > userschematmpfile = slapi_ch_smprintf("%s.tmp", userschemafile); > } > >- if(rc && (pschemadse==NULL)) >+ if(rc) > { >- pschemadse= dse_new_with_filelist(userschemafile,userschematmpfile, NULL, NULL, >- schemadir,filelist); >- PR_ASSERT(pschemadse); >- if ((rc= (pschemadse!=NULL)) != 0) >- dse_register_callback(pschemadse,DSE_OPERATION_READ,DSE_FLAG_PREOP,&schema, >+ *local_pschemadse = dse_new_with_filelist(userschemafile, >+ userschematmpfile, NULL, NULL, myschemadir, filelist); >+ } >+ PR_ASSERT(*local_pschemadse); >+ if ((rc = (*local_pschemadse != NULL)) != 0) >+ { >+ /* pass schema_flags as arguments */ >+ dse_register_callback(*local_pschemadse, >+ DSE_OPERATION_READ, DSE_FLAG_PREOP, &schema, > LDAP_SCOPE_BASE,NULL, >- load_schema_dse,NULL); >- slapi_ch_free((void**)&userschematmpfile); >+ load_schema_dse, (void *)&schema_flags); > } >- slapi_ch_free((void**)&schemadir); >+ slapi_ch_free_string(&userschematmpfile); >+ if (NULL == schemadir) >+ slapi_ch_free_string(&myschemadir); /* allocated in this function */ > > if(rc) > { > char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE] = {0}; >@@ -4072,56 +4160,102 @@ > /* duplicate entries are allowed */ > slapi_pblock_set(&pb, SLAPI_DSE_MERGE_WHEN_ADDING, (void*)&merge); > /* use the non duplicate checking str2entry */ > slapi_pblock_set(&pb, SLAPI_DSE_DONT_CHECK_DUPS, (void*)&dont_dup_check); >+ /* borrow the task flag space */ >+ slapi_pblock_set(&pb, SLAPI_TASK_FLAGS, (void*)&schema_flags); > > /* add the objectclass attribute so we can do some basic schema > checking during initialization; this will be overridden when > its "real" definition is read from the schema conf files */ >+ if (schema_flags & DSE_SCHEMA_NO_LOAD) >+ { >+ struct asyntaxinfo *tmpasip = NULL; >+ rc = read_at_ldif("attributeTypes: ( 2.5.4.0 NAME 'objectClass' " >+ "DESC 'Standard schema for LDAP' SYNTAX " >+ "1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2252' )", >+ &tmpasip, errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, >+ DSE_SCHEMA_NO_GLOCK|schema_flags, 0, 0, 0); >+ attr_syntax_free( tmpasip ); /* trash it */ >+ } >+ else >+ { > rc = read_at_ldif("attributeTypes: ( 2.5.4.0 NAME 'objectClass' " > "DESC 'Standard schema for LDAP' SYNTAX " > "1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'RFC 2252' )", >- NULL, errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, 1, 0, 0, 0); >+ NULL, errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, >+ DSE_SCHEMA_NO_GLOCK|schema_flags, 0, 0, 0); >+ } > if (rc) > { > slapi_log_error(SLAPI_LOG_FATAL, "schema", "Could not add" > " attribute type \"objectClass\" to the schema: %s\n", > errorbuf); > } > >- rc = dse_read_file(pschemadse, &pb); >+ rc = dse_read_file(*local_pschemadse, &pb); > } > >- if (rc) >+ if (rc && !(schema_flags & DSE_SCHEMA_NO_BACKEND)) > { > /* make sure the schema is normalized */ >+ if (schema_flags & DSE_SCHEMA_LOCKED) >+ normalize_oc_nolock(); >+ else > normalize_oc(); > > /* register callbacks */ >- dse_register_callback(pschemadse,SLAPI_OPERATION_SEARCH,DSE_FLAG_PREOP,&schema, >- LDAP_SCOPE_BASE,NULL,read_schema_dse,NULL); >- dse_register_callback(pschemadse,SLAPI_OPERATION_MODIFY,DSE_FLAG_PREOP,&schema, >- LDAP_SCOPE_BASE,NULL,modify_schema_dse,NULL); >- dse_register_callback(pschemadse,SLAPI_OPERATION_DELETE,DSE_FLAG_PREOP,&schema, >- LDAP_SCOPE_BASE,NULL,dont_allow_that,NULL); >- dse_register_callback(pschemadse,DSE_OPERATION_WRITE,DSE_FLAG_PREOP,&schema, >- LDAP_SCOPE_BASE,NULL,refresh_user_defined_schema, >- NULL); >+ dse_register_callback(*local_pschemadse, SLAPI_OPERATION_SEARCH, >+ DSE_FLAG_PREOP,&schema, LDAP_SCOPE_BASE, >+ NULL, read_schema_dse, NULL); >+ dse_register_callback(*local_pschemadse, SLAPI_OPERATION_MODIFY, >+ DSE_FLAG_PREOP,&schema, LDAP_SCOPE_BASE, >+ NULL, modify_schema_dse, NULL); >+ dse_register_callback(*local_pschemadse, SLAPI_OPERATION_DELETE, >+ DSE_FLAG_PREOP, &schema, LDAP_SCOPE_BASE, >+ NULL,dont_allow_that,NULL); >+ dse_register_callback(*local_pschemadse, DSE_OPERATION_WRITE, >+ DSE_FLAG_PREOP, &schema, LDAP_SCOPE_BASE, >+ NULL, refresh_user_defined_schema, NULL); > > if (rc) { >- Slapi_Backend *be; >- >+ if (NULL == be) { /* be is not given. select it */ >+ be = slapi_be_select_by_instance_name( DSE_SCHEMA ); >+ } >+ if (NULL == be) { /* first time */ > /* add as a backend */ >- be= be_new_internal(pschemadse,"DSE", "schema-internal"); /* JCM - should be a #define */ >+ be = be_new_internal(*local_pschemadse, "DSE", DSE_SCHEMA); > be_addsuffix(be,&schema); >+ } else { /* schema file reload */ >+ struct slapdplugin *backend_plugin = NULL; >+ be_replace_dse_internal(be, *local_pschemadse); >+ >+ /* ldbm has some internal attributes to be added */ >+ backend_plugin = plugin_get_by_name("ldbm database"); >+ if (backend_plugin) { >+ (backend_plugin->plg_add_schema)( NULL ); >+ } >+ } > } > } > > slapi_sdn_done(&schema); > return rc; > } > >- >+int >+init_schema_dse(const char *configdir) >+{ >+ char *schemadir = config_get_schemadir(); >+ int rc = 0; >+ if (NULL == schemadir) >+ { >+ schemadir = slapi_ch_smprintf("%s/%s", configdir, SCHEMA_SUBDIR_NAME); >+ } >+ rc = init_schema_dse_ext(schemadir, NULL, &pschemadse, 0); >+ slapi_ch_free_string(&schemadir); >+ return rc; >+} > > /* > * Look for `keyword' within `*inputp' and return the flag_value if found > * (zero if returned if not found). >@@ -4712,4 +4846,116 @@ > sa->a_present_values.va = va; > > oc_unlock(); > } >+ >+void >+schema_expand_objectclasses_nolock( Slapi_Entry *e ) >+{ >+ Slapi_Attr *sa; >+ Slapi_Value **va; >+ const char *dn = slapi_entry_get_dn_const( e ); >+ int i; >+ >+ if ( 0 != slapi_entry_attr_find( e, SLAPI_ATTR_OBJECTCLASS, &sa )) { >+ return; /* no OC values -- nothing to do */ >+ } >+ >+ va = attr_get_present_values( sa ); >+ >+ if ( va == NULL || va[0] == NULL ) { >+ return; /* no OC values -- nothing to do */ >+ } >+ >+ /* >+ * This loop relies on the fact that bv_expand_one_oc() >+ * always adds to the end >+ */ >+ for ( i = 0; va[i] != NULL; ++i ) { >+ if ( NULL != slapi_value_get_string(va[i]) ) { >+ va_expand_one_oc( dn, &va, slapi_value_get_string(va[i]) ); >+ } >+ } >+ >+ /* top must always be present */ >+ va_expand_one_oc( dn, &va, "top" ); >+ >+ /* >+ * Reset the present values in the set because we may have realloc'd it. >+ * Note that this is the counterpart to the attr_get_present_values() >+ * call we made above... nothing new has been allocated, but sa holds >+ * a pointer to the original (pre realloc) va. >+ */ >+ sa->a_present_values.va = va; >+} >+ >+/* lock to protect both objectclass and schema_dse */ >+static void >+slapi_load_schemafile_lock() >+{ >+ oc_lock_write(); >+ schema_dse_lock_write(); >+} >+ >+static void >+slapi_load_schemafile_unlock() >+{ >+ schema_dse_unlock(); >+ oc_unlock(); >+} >+ >+/* API to validate the schema files */ >+int >+slapi_validate_schema_files(char *schemadir) >+{ >+ struct dse *my_pschemadse = NULL; >+ int rc = init_schema_dse_ext(schemadir, NULL, &my_pschemadse, >+ DSE_SCHEMA_NO_LOAD | DSE_SCHEMA_NO_BACKEND); >+ dse_destroy(my_pschemadse); >+ if (rc) >+ return LDAP_SUCCESS; >+ else { >+ slapi_log_error( SLAPI_LOG_FATAL, "schema_reload", >+ "schema file validation failed\n" ); >+ return LDAP_OBJECT_CLASS_VIOLATION; >+ } >+} >+ >+/* >+ * API to reload the schema files. >+ * Rule: this function is called when slapi_validate_schema_files is passed. >+ * Schema checking is skipped in this function. >+ */ >+int >+slapi_reload_schema_files(char *schemadir) >+{ >+ int rc = LDAP_SUCCESS; >+ struct dse *my_pschemadse = NULL; >+ /* get be to lock */ >+ Slapi_Backend *be = slapi_be_select_by_instance_name( DSE_SCHEMA ); >+ >+ if (NULL == be) >+ { >+ slapi_log_error( SLAPI_LOG_FATAL, "schema_reload", >+ "schema file reload failed\n" ); >+ return LDAP_LOCAL_ERROR; >+ } >+ slapi_be_Wlock(be); /* be lock must be outer of schemafile lock */ >+ slapi_load_schemafile_lock(); >+ attr_syntax_delete_all(); >+ oc_delete_all_nolock(); >+ rc = init_schema_dse_ext(schemadir, be, &my_pschemadse, >+ DSE_SCHEMA_NO_CHECK | DSE_SCHEMA_LOCKED); >+ if (rc) { >+ dse_destroy(pschemadse); >+ pschemadse = my_pschemadse; >+ slapi_load_schemafile_unlock(); >+ slapi_be_Unlock(be); >+ return LDAP_SUCCESS; >+ } else { >+ slapi_load_schemafile_unlock(); >+ slapi_be_Unlock(be); >+ slapi_log_error( SLAPI_LOG_FATAL, "schema_reload", >+ "schema file reload failed\n" ); >+ return LDAP_LOCAL_ERROR; >+ } >+} >Index: ldap/servers/slapd/schemaparse.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/schemaparse.c,v >retrieving revision 1.5 >diff -t -w -U4 -r1.5 schemaparse.c >--- ldap/servers/slapd/schemaparse.c 10 Nov 2006 23:45:40 -0000 1.5 >+++ ldap/servers/slapd/schemaparse.c 30 May 2008 23:36:40 -0000 >@@ -253,8 +253,26 @@ > > oc_unlock(); > } > >+void >+normalize_oc_nolock( void ) >+{ >+ struct objclass *oc; >+ >+ for ( oc = g_get_global_oc_nolock(); oc != NULL; oc = oc->oc_next ) { >+ LDAPDebug (LDAP_DEBUG_PARSE, >+ "normalize_oc: normalizing '%s'\n", oc->oc_name, 0, 0); >+ /* required attributes */ >+ normalize_list( oc->oc_required ); >+ normalize_list( oc->oc_orig_required ); >+ >+ /* optional attributes */ >+ normalize_list( oc->oc_allowed ); >+ normalize_list( oc->oc_orig_allowed ); >+ } >+} >+ > /* > * oc_update_inheritance_nolock: > * If an objectclass is redefined, we need to make sure that any objectclasses > * which inherit from the redefined objectclass have their required and allowed >Index: ldap/servers/slapd/slap.h >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slap.h,v >retrieving revision 1.32 >diff -t -w -U4 -r1.32 slap.h >--- ldap/servers/slapd/slap.h 16 May 2008 16:46:49 -0000 1.32 >+++ ldap/servers/slapd/slap.h 30 May 2008 23:36:40 -0000 >@@ -775,8 +775,9 @@ > IFP plg_un_db_register_dn_callback; /* Register a function to call when a operation is applied to a given DN */ > IFP plg_un_db_register_oc_callback; /* Register a function to call when a operation is applied to a given ObjectClass */ > IFP plg_un_db_init_instance; /* initializes new db instance */ > IFP plg_un_db_wire_import; /* fast replica update */ >+ IFP plg_un_db_add_schema; /* add schema */ > IFP plg_un_db_verify; /* verify db files */ > } plg_un_db; > #define plg_bind plg_un.plg_un_db.plg_un_db_bind > #define plg_unbind plg_un.plg_un_db.plg_un_db_unbind >@@ -807,8 +808,9 @@ > #define plg_dbtest plg_un.plg_un_db.plg_un_db_dbtest > #define plg_rmdb plg_un.plg_un_db.plg_un_db_rmdb > #define plg_init_instance plg_un.plg_un_db.plg_un_db_init_instance > #define plg_wire_import plg_un.plg_un_db.plg_un_db_wire_import >+#define plg_add_schema plg_un.plg_un_db.plg_un_db_add_schema > > /* extended operation plugin structure */ > struct plg_un_protocol_extension { > char **plg_un_pe_exoids; /* exop oids */ >Index: ldap/servers/slapd/slapi-plugin.h >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slapi-plugin.h,v >retrieving revision 1.21 >diff -t -w -U4 -r1.21 slapi-plugin.h >--- ldap/servers/slapd/slapi-plugin.h 30 May 2008 15:39:00 -0000 1.21 >+++ ldap/servers/slapd/slapi-plugin.h 30 May 2008 23:36:40 -0000 >@@ -216,8 +216,9 @@ > Well formed LDIF has no duplicate attribute values, already > has the RDN as an attribute of the entry, and has all values for a > given attribute type listed contiguously. */ > #define SLAPI_STR2ENTRY_NOT_WELL_FORMED_LDIF 128 >+#define SLAPI_STR2ENTRY_NO_SCHEMA_LOCK 256 > > char *slapi_entry2str_with_options( Slapi_Entry *e, int *len, int options ); > /* Options for slapi_entry2str_with_options() */ > #define SLAPI_DUMP_STATEINFO 1 /* replication state */ >Index: ldap/servers/slapd/slapi-private.h >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slapi-private.h,v >retrieving revision 1.21 >diff -t -w -U4 -r1.21 slapi-private.h >--- ldap/servers/slapd/slapi-private.h 3 Apr 2008 16:52:46 -0000 1.21 >+++ ldap/servers/slapd/slapi-private.h 30 May 2008 23:36:40 -0000 >@@ -647,8 +647,10 @@ > }IndexConfig; > > void be_set_sizelimit(Slapi_Backend * be, int sizelimit); > void be_set_timelimit(Slapi_Backend * be, int timelimit); >+int be_isdeleted( const Slapi_Backend *be ); >+ > > /* used by mapping tree to delay sending of result code when several > * backend are parsed > */ >@@ -856,8 +858,9 @@ > #define SLAPI_PLUGIN_DB_INIT_INSTANCE_FN 231 > #define SLAPI_PLUGIN_DB_WIRE_IMPORT_FN 234 > #define SLAPI_PLUGIN_DB_UPGRADEDB_FN 235 > #define SLAPI_PLUGIN_DB_DBVERIFY_FN 236 >+#define SLAPI_PLUGIN_DB_ADD_SCHEMA_FN 237 > /* database plugin-specific parameters */ > #define SLAPI_PLUGIN_DB_NO_ACL 250 > #define SLAPI_PLUGIN_DB_RMDB_FN 280 > >@@ -1072,8 +1075,18 @@ > > int slapi_config_register_callback(int operation, int flags, const char *base, int scope, const char *filter, dseCallbackFn fn, void *fn_arg); > int slapi_config_remove_callback(int operation, int flags, const char *base, int scope, const char *filter, dseCallbackFn fn); > int config_is_slapd_lite( void ); >+void schema_expand_objectclasses_nolock( Slapi_Entry *e ); >+ >+#define DSE_SCHEMA_NO_LOAD 0x0001 /* schema won't get loaded */ >+#define DSE_SCHEMA_NO_CHECK 0x0002 /* schema won't be checked */ >+#define DSE_SCHEMA_NO_BACKEND 0x0004 /* don't add as backend */ >+ >+#define DSE_SCHEMA_NO_GLOCK 0x0010 /* don't lock global resources */ >+#define DSE_SCHEMA_LOCKED 0x0020 /* already locked with >+ * slapi_load_schemafile_lock; >+ * no further lock needed */ > > #define SLAPI_RTN_BIT_FETCH_EXISTING_DN_ENTRY 0 > #define SLAPI_RTN_BIT_FETCH_PARENT_ENTRY 1 > #define SLAPI_RTN_BIT_FETCH_NEWPARENT_ENTRY 2 >Index: ldap/servers/slapd/back-ldbm/init.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/init.c,v >retrieving revision 1.9 >diff -t -w -U4 -r1.9 init.c >--- ldap/servers/slapd/back-ldbm/init.c 7 Sep 2007 19:08:45 -0000 1.9 >+++ ldap/servers/slapd/back-ldbm/init.c 30 May 2008 23:36:40 -0000 >@@ -63,8 +63,31 @@ > module_ldap_debug = level_ptr; > } > #endif > >+/* pb: not used */ >+int >+ldbm_back_add_schema( Slapi_PBlock *pb ) >+{ >+ int rc = add_ldbm_internal_attr_syntax( "entrydn", >+ LDBM_ENTRYDN_OID, DN_SYNTAX_OID, DNMATCH_NAME, >+ SLAPI_ATTR_FLAG_SINGLE ); >+ >+ rc |= add_ldbm_internal_attr_syntax( "dncomp", >+ LDBM_DNCOMP_OID, DN_SYNTAX_OID, DNMATCH_NAME, >+ 0 ); >+ >+ rc |= add_ldbm_internal_attr_syntax( "parentid", >+ LDBM_PARENTID_OID, DIRSTRING_SYNTAX_OID, CASEIGNOREMATCH_NAME, >+ SLAPI_ATTR_FLAG_SINGLE ); >+ >+ rc |= add_ldbm_internal_attr_syntax( "entryid", >+ LDBM_ENTRYID_OID, DIRSTRING_SYNTAX_OID, CASEIGNOREMATCH_NAME, >+ SLAPI_ATTR_FLAG_SINGLE ); >+ >+ return rc; >+} >+ > int > ldbm_back_init( Slapi_PBlock *pb ) > { > struct ldbminfo *li; >@@ -113,23 +136,9 @@ > return (-1); > } > > /* add some private attributes */ >- rc = add_ldbm_internal_attr_syntax( "entrydn", >- LDBM_ENTRYDN_OID, DN_SYNTAX_OID, DNMATCH_NAME, >- SLAPI_ATTR_FLAG_SINGLE ); >- >- rc = add_ldbm_internal_attr_syntax( "dncomp", >- LDBM_DNCOMP_OID, DN_SYNTAX_OID, DNMATCH_NAME, >- 0 ); >- >- rc = add_ldbm_internal_attr_syntax( "parentid", >- LDBM_PARENTID_OID, DIRSTRING_SYNTAX_OID, CASEIGNOREMATCH_NAME, >- SLAPI_ATTR_FLAG_SINGLE ); >- >- rc = add_ldbm_internal_attr_syntax( "entryid", >- LDBM_ENTRYID_OID, DIRSTRING_SYNTAX_OID, CASEIGNOREMATCH_NAME, >- SLAPI_ATTR_FLAG_SINGLE ); >+ rc = ldbm_back_add_schema( pb ); > > /* set plugin private pointer and initialize locks, etc. */ > rc = slapi_pblock_set( pb, SLAPI_PLUGIN_PRIVATE, (void *) li ); > >@@ -225,8 +234,10 @@ > (void *) ldbm_back_init ); /* register itself so that the secon instance > can be initialized */ > rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_WIRE_IMPORT_FN, > (void *) ldbm_back_wire_import); >+ rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DB_ADD_SCHEMA_FN, >+ (void *) ldbm_back_add_schema ); > > if ( rc != 0 ) { > LDAPDebug( LDAP_DEBUG_ANY, "ldbm_back_init failed\n", 0, 0, 0 ); > return( -1 ); >Index: ldap/ldif/template-dse.ldif.in >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/ldif/template-dse.ldif.in,v >retrieving revision 1.5 >diff -t -w -U4 -r1.5 template-dse.ldif.in >--- ldap/ldif/template-dse.ldif.in 18 Oct 2007 01:22:29 -0000 1.5 >+++ ldap/ldif/template-dse.ldif.in 30 May 2008 23:36:40 -0000 >@@ -199,8 +199,18 @@ > nsslapd-plugininitfunc: ces_init > nsslapd-plugintype: syntax > nsslapd-pluginenabled: on > >+dn: cn=Schema Reload,cn=plugins,cn=config >+objectclass: top >+objectclass: nsSlapdPlugin >+objectclass: extensibleObject >+cn: Schema Reload >+nsslapd-pluginpath: libschemareload-plugin >+nsslapd-plugininitfunc: schemareload_init >+nsslapd-plugintype: object >+nsslapd-pluginenabled: on >+ > dn: cn=Space Insensitive String Syntax,cn=plugins,cn=config > objectclass: top > objectclass: nsSlapdPlugin > objectclass: extensibleObject >Index: Makefile.am >=================================================================== >RCS file: /cvs/dirsec/ldapserver/Makefile.am,v >retrieving revision 1.67 >diff -t -w -U4 -r1.67 Makefile.am >--- Makefile.am 30 May 2008 15:38:59 -0000 1.67 >+++ Makefile.am 30 May 2008 23:36:40 -0000 >@@ -116,10 +116,11 @@ > libback-ldbm.la libchainingdb-plugin.la libcos-plugin.la libdes-plugin.la \ > libdistrib-plugin.la libhttp-client-plugin.la libcollation-plugin.la \ > libmemberof-plugin.la libpassthru-plugin.la libpresence-plugin.la \ > libpwdstorage-plugin.la libreferint-plugin.la libreplication-plugin.la \ >- libretrocl-plugin.la libroles-plugin.la libstatechange-plugin.la libsyntax-plugin.la \ >- libviews-plugin.la $(LIBPAM_PASSTHRU_PLUGIN) $(LIBDNA_PLUGIN) $(LIBBITWISE_PLUGIN) >+ libretrocl-plugin.la libroles-plugin.la libstatechange-plugin.la \ >+ libsyntax-plugin.la libviews-plugin.la libschemareload-plugin.la \ >+ $(LIBPAM_PASSTHRU_PLUGIN) $(LIBDNA_PLUGIN) $(LIBBITWISE_PLUGIN) > > nodist_property_DATA = ns-slapd.properties > > noinst_PROGRAMS = makstrdb >@@ -828,8 +829,16 @@ > libviews_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) > libviews_plugin_la_LDFLAGS = -avoid-version > > #------------------------ >+# libschemareload-plugin >+#------------------------ >+libschemareload_plugin_la_SOURCES = ldap/servers/plugins/schema_reload/schema_reload.c >+ >+libschemareload_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) >+libschemareload_plugin_la_LDFLAGS = -avoid-version >+ >+#------------------------ > # libdna-plugin > #------------------------ > libdna_plugin_la_SOURCES = ldap/servers/plugins/dna/dna.c > >=============================================================================== >new file: ldap/servers/plugin/schema_reload/schema_reload.c >=============================================================================== >/** BEGIN COPYRIGHT BLOCK > * This Program is free software; you can redistribute it and/or modify it under > * the terms of the GNU General Public License as published by the Free Software > * Foundation; version 2 of the License. > * > * This Program is distributed in the hope that it will be useful, but WITHOUT > * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS > * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. > * > * You should have received a copy of the GNU General Public License along with > * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple > * Place, Suite 330, Boston, MA 02111-1307 USA. > * > * In addition, as a special exception, Red Hat, Inc. gives You the additional > * right to link the code of this Program with code not covered under the GNU > * General Public License ("Non-GPL Code") and to distribute linked combinations > * including the two, subject to the limitations in this paragraph. Non-GPL Code > * permitted under this exception must only link to the code of this Program > * through those well defined interfaces identified in the file named EXCEPTION > * found in the source code files (the "Approved Interfaces"). The files of > * Non-GPL Code may instantiate templates or use macros or inline functions from > * the Approved Interfaces without causing the resulting work to be covered by > * the GNU General Public License. Only Red Hat, Inc. may make changes or > * additions to the list of Approved Interfaces. You must obey the GNU General > * Public License in all respects for all of the Program code and other code used > * in conjunction with the Program except the Non-GPL Code covered by this > * exception. If you modify this file, you may extend this exception to your > * version of the file, but you are not obligated to do so. If you do not wish to > * provide this exception without modification, you must delete this exception > * statement from your version and license this file solely under the GPL without > * exception. > * > * Copyright (C) 2008 Red Hat, Inc. > * All rights reserved. > * END COPYRIGHT BLOCK **/ > >#ifdef HAVE_CONFIG_H ># include <config.h> >#endif > >/* > * Dynamic schema file reload plugin > * > * plugin entry in dse.ldif > * dn: cn=Schema Reload,cn=plugins,cn=config > * objectClass: top > * objectClass: nsSlapdPlugin > * objectClass: extensibleObject > * cn: Schema Reload > * nsslapd-pluginPath: libschemareload-plugin > * nsslapd-pluginInitfunc: schemareload_init > * nsslapd-pluginType: object > * nsslapd-pluginEnabled: on > * nsslapd-pluginId: schemareload > * nsslapd-pluginVersion: <plugin_version> > * nsslapd-pluginVendor: <vendor name> > * nsslapd-pluginDescription: task plugin to reload schema files > * > * config task entry in dse.ldif (registered in task_schemareload_start) > * dn: cn=schema reload task, cn=tasks, cn=config > * objectClass: top > * objectClass: extensibleObject > * cn: schema reload task > * > * To invoke the sample task, run the command line: > * $ ldapmodify -h <host> -p <port> -D "cn=Directory Manager" -w <pw> -a > * dn: cn=schema reload task 0, cn=schema reload task, cn=tasks, cn=config > * objectClass: top > * objectClass: extensibleObject > * cn: schema reload task 0 > * [ schemadir: path to reload files from ] > */ > >#include "slapi-plugin.h" >#include "nspr.h" >#include "dirver.h" /* PRODUCTTEXT */ >#include <dirlite_strings.h> /* PLUGIN_MAGIC_VENDOR_STR */ > >static PRLock *schemareload_lock = NULL; > >static Slapi_PluginDesc pdesc = { "schemareload", > PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, > "task plugin to reload schema files" }; > >static int task_schemareload_add(Slapi_PBlock *pb, Slapi_Entry *e, > Slapi_Entry *eAfter, int *returncode, char *returntext, > void *arg); >static int task_schemareload_start(Slapi_PBlock *pb); > >/* > * Init function > * Specified in the plugin entry as "nsslapd-pluginInitfunc: schemareload_init" > */ >int >schemareload_init( Slapi_PBlock *pb ) >{ > int rc = 0; > schemareload_lock = PR_NewLock(); > if (NULL == schemareload_lock) { > slapi_log_error(SLAPI_LOG_FATAL, "schemareload", > "Failed to create global schema reload lock."); > return rc; > } > rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, > (void *) SLAPI_PLUGIN_VERSION_03 ); > rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, > (void *)&pdesc ); > rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_START_FN, > (void *) task_schemareload_start ); > > return rc; >} > >/* > * Task start function > * Register the function task_schemareload_add, which invokes the task on demand. > */ >static int >task_schemareload_start(Slapi_PBlock *pb) >{ > int rc = slapi_task_register_handler("schema reload task", task_schemareload_add); > return rc; >} > >/* preop */ >static int >task_schema_validation(void *arg) >{ > Slapi_Task *task = (Slapi_Task *)arg; > char *schemadir = NULL; > int rval = LDAP_SUCCESS; > > /* fetch our argument from the task */ > schemadir = (char *)slapi_task_get_data(task); > > rval = slapi_validate_schema_files(schemadir); > > return rval; >} > >/* postop */ >static int >task_reload_schema_files(void *arg) >{ > Slapi_Task *task = (Slapi_Task *)arg; > char *schemadir = NULL; > int rval = LDAP_SUCCESS; > > /* fetch our argument from the task */ > schemadir = (char *)slapi_task_get_data(task); > > rval = slapi_reload_schema_files(schemadir); > > return rval; >} > >/* > * Task thread > * Not necessary be a thread, but it'd not disturb the server's other jobs. > */ >static void >task_schemareload_thread(void *arg) >{ > Slapi_Task *task = (Slapi_Task *)arg; > int i, rv = 0; > int total_work = 2; > /* fetch our argument from the task */ > char *schemadir = (char *)slapi_task_get_data(task); > > /* update task state to show it's running */ > slapi_task_begin(task, total_work); > PR_Lock(schemareload_lock); /* make schema reload serialized */ > slapi_task_log_notice(task, "Schema reload task starts (schema dir: %s) ...\n", schemadir?schemadir:"default"); > slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Schema reload task starts (schema dir: %s) ...\n", schemadir?schemadir:"default"); > > rv = task_schema_validation(arg); > slapi_task_inc_progress(task); > > if (LDAP_SUCCESS == rv) { > slapi_task_log_notice(task, "Schema validation passed."); > slapi_task_log_status(task, "Schema validation passed."); > slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Schema validation passed.\n"); > > rv = task_reload_schema_files(arg); > slapi_task_inc_progress(task); > > /* update task state to say we're finished */ > if (LDAP_SUCCESS == rv) { > slapi_task_log_notice(task, "Schema reload task finished."); > slapi_task_log_status(task, "Schema reload task finished."); > slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Schema reload task finished.\n"); > } else { > slapi_task_log_notice(task, "Schema reload task failed."); > slapi_task_log_status(task, "Schema reload task failed."); > slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Schema reload task failed.\n"); > } > PR_Unlock(schemareload_lock); > } else { > slapi_task_log_notice(task, "Schema validation failed."); > slapi_task_log_status(task, "Schema validation failed."); > slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "Schema validation failed.\n"); > PR_Unlock(schemareload_lock); > } > > /* this will queue the destruction of the task */ > slapi_task_finish(task, rv); >} > >/* extract a single value from the entry (as a string) -- if it's not in the > * entry, the default will be returned (which can be NULL). > * you do not need to free anything returned by this. > */ >static const char *fetch_attr(Slapi_Entry *e, const char *attrname, > const char *default_val) >{ > Slapi_Attr *attr; > Slapi_Value *val = NULL; > > if (slapi_entry_attr_find(e, attrname, &attr) != 0) > return default_val; > slapi_attr_first_value(attr, &val); > return slapi_value_get_string(val); >} > >static void >task_schemareload_destructor(Slapi_Task *task) >{ > if (task) { > char *schemadir = (char *)slapi_task_get_data(task); > slapi_ch_free_string(&schemadir); > } >} > >/* > * Invoked when the task instance is added by the client (step 5 of the comment) > * Get the necessary attributes from the task entry, and spawns a thread to do > * the task. > */ >static int >task_schemareload_add(Slapi_PBlock *pb, Slapi_Entry *e, > Slapi_Entry *eAfter, int *returncode, char *returntext, > void *arg) >{ > PRThread *thread = NULL; > const char *cn; > int rv = SLAPI_DSE_CALLBACK_OK; > Slapi_PBlock *mypb = NULL; > Slapi_Task *task = NULL; > char *schemadir = NULL; > > *returncode = LDAP_SUCCESS; > if ((cn = fetch_attr(e, "cn", NULL)) == NULL) { > *returncode = LDAP_OBJECT_CLASS_VIOLATION; > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } > > /* get arg(s) */ > schemadir = fetch_attr(e, "schemadir", NULL); > > /* allocate new task now */ > task = slapi_new_task(slapi_entry_get_ndn(e)); > if (task == NULL) { > slapi_log_error(SLAPI_LOG_FATAL, "schemareload", "unable to allocate new task!\n"); > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } > > /* set a destructor that will clean up schemadir for us when the task is complete */ > slapi_task_set_destructor_fn(task, task_schemareload_destructor); > > /* Stash our argument in the task for use by the task thread */ > slapi_task_set_data(task, slapi_ch_strdup(schemadir)); > > /* start the schema reload task as a separate thread */ > thread = PR_CreateThread(PR_USER_THREAD, task_schemareload_thread, > (void *)task, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, > PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); > if (thread == NULL) { > slapi_log_error(SLAPI_LOG_FATAL, "schemareload", > "unable to create schema reload task thread!\n"); > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; > slapi_task_finish(task, *returncode); > } else { > /* thread successful */ > rv = SLAPI_DSE_CALLBACK_OK; > } > >out: > return rv; >} >===============================================================================
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 436837
: 307257 |
308278
|
308379
|
308400
|
308403
|
308554
|
308555
|
308847
|
308848
|
311975