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 299782 Details for
Bug 439907
Need to improve and expose SLAPI task API
[?]
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
diffs.txt (text/plain), 83.12 KB, created by
Nathan Kinder
on 2008-03-31 22:41:56 UTC
(
hide
)
Description:
CVS Diffs
Filename:
MIME Type:
Creator:
Nathan Kinder
Created:
2008-03-31 22:41:56 UTC
Size:
83.12 KB
patch
obsolete
>Index: ldap/servers/plugins/memberof/memberof.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/memberof/memberof.c,v >retrieving revision 1.4 >diff -u -5 -t -r1.4 memberof.c >--- ldap/servers/plugins/memberof/memberof.c 28 Mar 2008 21:45:52 -0000 1.4 >+++ ldap/servers/plugins/memberof/memberof.c 31 Mar 2008 22:22:08 -0000 >@@ -47,14 +47,14 @@ > * existing entries that have inconsistent state (for example, > * if the memberof attribute was incorrectly edited directly) > * > * To start the memberof task add an entry like: > * >- * dn: cn=memberof task 2, cn=memberof task, cn=tasks, cn=config >+ * dn: cn=mytask, cn=memberof task, cn=tasks, cn=config > * objectClass: top > * objectClass: extensibleObject >- * cn: sample task >+ * cn: mytask > * basedn: dc=example, dc=com > * filter: (uid=test4) > * > * where "basedn" is required and refers to the top most node to perform the > * task on, and where "filter" is an optional attribute that provides a filter >@@ -73,11 +73,10 @@ > #include "nspr.h" > > #define MEMBEROF_GROUP_ATTR "member" > #define MEMBEROF_ATTR "memberof" > #define MEMBEROF_GROUP_ATTR_IS_DN 1 >-#define MEMBEROF_GROUP_ATTR_TYPE "uid" > #define MEMBEROF_GROUP_FILTER "(" MEMBEROF_GROUP_ATTR "=*)" > > #define MEMBEROF_PLUGIN_SUBSYSTEM "memberof-plugin" /* used for logging */ > static Slapi_PluginDesc pdesc = { "memberof", PLUGIN_MAGIC_VENDOR_STR, > PRODUCTTEXT, "memberof plugin" }; >@@ -90,54 +89,10 @@ > { > char *dn; > void *next; > } memberofstringll; > >- >- >-/****** secrets *********/ >- >-/*from FDS slap.h >- * until we get a proper api for access >- */ >-#define TASK_RUNNING_AS_TASK 0x0 >- >-/*from FDS slapi-private.h >- * until we get a proper api for access >- */ >- >- >-#define SLAPI_DSE_CALLBACK_OK (1) >-#define SLAPI_DSE_CALLBACK_ERROR (-1) >-#define SLAPI_DSE_CALLBACK_DO_NOT_APPLY (0) >- >-/****************************************************************************** >- * Online tasks interface (to support import, export, etc) >- * After some cleanup, we could consider making these public. >- */ >-struct _slapi_task { >- struct _slapi_task *next; >- char *task_dn; >- int task_exitcode; /* for the end user */ >- int task_state; /* (see above) */ >- int task_progress; /* number between 0 and task_work */ >- int task_work; /* "units" of work to be done */ >- int task_flags; /* (see above) */ >- >- /* it is the task's responsibility to allocate this memory & free it: */ >- char *task_status; /* transient status info */ >- char *task_log; /* appended warnings, etc */ >- >- void *task_private; /* for use by backends */ >- TaskCallbackFn cancel; /* task has been cancelled by user */ >- TaskCallbackFn destructor; /* task entry is being destroyed */ >- int task_refcount; >-}; >- >-/****** secrets ********/ >- >- > /*** function prototypes ***/ > > /* exported functions */ > int memberof_postop_init(Slapi_PBlock *pb ); > >@@ -167,11 +122,11 @@ > char *op_this, Slapi_Attr *attr, memberofstringll *stack); > static int memberof_add_attr_list(Slapi_PBlock *pb, char *groupdn, Slapi_Attr *attr); > static int memberof_del_attr_list(Slapi_PBlock *pb, char *groupdn, Slapi_Attr *attr); > static int memberof_moddn_attr_list(Slapi_PBlock *pb, char *pre_dn, char *post_dn, > Slapi_Attr *attr); >-static int memberofd_replace_list(Slapi_PBlock *pb, char *group_dn); >+static int memberof_replace_list(Slapi_PBlock *pb, char *group_dn); > static void memberof_set_plugin_id(void * plugin_id); > static void *memberof_get_plugin_id(); > static int memberof_compare(const void *a, const void *b); > static void memberof_load_array(Slapi_Value **array, Slapi_Attr *attr); > static Slapi_Filter *memberof_string2filter(char *strfilter); >@@ -193,13 +148,14 @@ > static int memberof_add_groups_search_callback(Slapi_Entry *e, void *callback_data); > static int memberof_add_membership(Slapi_PBlock *pb, char *op_this, char *op_to); > static int memberof_task_add(Slapi_PBlock *pb, Slapi_Entry *e, > Slapi_Entry *eAfter, int *returncode, char *returntext, > void *arg); >+static void memberof_task_destructor(Slapi_Task *task); > static const char *fetch_attr(Slapi_Entry *e, const char *attrname, > const char *default_val); >-static void memberof_memberof_fixup_task_thread(void *arg); >+static void memberof_fixup_task_thread(void *arg); > static int memberof_fix_memberof(char *dn, char *filter_str); > static int memberof_fix_memberof_callback(Slapi_Entry *e, void *callback_data); > > > /*** implementation ***/ >@@ -509,10 +465,12 @@ > { > Slapi_Attr *attr = 0; > > memberof_lock(); > >+ /* get a list of member attributes present in the group >+ * entry that is being renamed. */ > if(0 == slapi_entry_attr_find(post_e, MEMBEROF_GROUP_ATTR, &attr)) > { > memberof_moddn_attr_list(pb, pre_dn, post_dn, attr); > } > >@@ -654,11 +612,11 @@ > > case LDAP_MOD_DELETE: > { > /* If there are no values in the smod, we should > * just do a replace instead. The user is just >- * trying to delete all members from this this >+ * trying to delete all members from this group > * entry, which the replace code deals with. */ > if (slapi_mod_get_num_values(smod) == 0) > { > memberof_replace_list(pb, dn); > } >@@ -671,11 +629,11 @@ > } > > case LDAP_MOD_REPLACE: > { > /* replace current values */ >- memberofd_replace_list(pb, dn); >+ memberof_replace_list(pb, dn); > break; > } > > default: > { >@@ -875,10 +833,18 @@ > } > else if(LDAP_MOD_ADD == mod_op) > { > op_str = "ADD"; > } >+ else if(LDAP_MOD_REPLACE == mod_op) >+ { >+ op_str = "REPLACE"; >+ } >+ else >+ { >+ op_str = "UNKNOWN"; >+ } > > slapi_log_error( SLAPI_LOG_PLUGIN, MEMBEROF_PLUGIN_SUBSYSTEM, > "memberof_modop_one_r: %s %s in %s\n" > ,op_str, op_this, op_to); > >@@ -1345,11 +1311,11 @@ > > slapi_sdn_free(&sdn); > return rc; > } > >-/* memberof_memberof_search_callback() >+/* memberof_test_membership() > * for each attribute in the memberof attribute > * determine if the entry is still a member > * > * test each for direct membership > * move groups entry is memberof to member group >@@ -1515,11 +1481,11 @@ > * memberof_replace_list() > * > * Perform replace the group DN list in the memberof attribute of the list of targets > * > */ >-int memberofd_replace_list(Slapi_PBlock *pb, char *group_dn) >+int memberof_replace_list(Slapi_PBlock *pb, char *group_dn) > { > struct slapi_entry *pre_e = NULL; > struct slapi_entry *post_e = NULL; > Slapi_Attr *pre_attr = 0; > Slapi_Attr *post_attr = 0; >@@ -1874,55 +1840,38 @@ > void memberof_unlock() > { > slapi_unlock_mutex(memberof_operation_lock); > } > >-/* >- * >- */ >- > typedef struct _task_data > { > char *dn; > char *filter_str; >- Slapi_Task *task; > } task_data; > >-void memberof_memberof_fixup_task_thread(void *arg) >+void memberof_fixup_task_thread(void *arg) > { >- task_data *td = (task_data *)arg; >- Slapi_Task *task = td->task; >+ Slapi_Task *task = (Slapi_Task *)arg; >+ task_data *td = NULL; > int rc = 0; > >- task->task_work = 1; >- task->task_progress = 0; >- task->task_state = SLAPI_TASK_RUNNING; >- >- slapi_task_status_changed(task); >+ /* Fetch our task data from the task */ >+ td = (task_data *)slapi_task_get_data(task); > >+ slapi_task_begin(task, 1); > slapi_task_log_notice(task, "Memberof task starts (arg: %s) ...\n", > td->filter_str); > > /* do real work */ > rc = memberof_fix_memberof(td->dn, td->filter_str); > > slapi_task_log_notice(task, "Memberof task finished."); > slapi_task_log_status(task, "Memberof task finished."); >+ slapi_task_inc_progress(task); > >- task->task_progress = 1; >- task->task_exitcode = rc; >- task->task_state = SLAPI_TASK_FINISHED; >- slapi_task_status_changed(task); >- >- slapi_ch_free_string(&td->dn); >- slapi_ch_free_string(&td->filter_str); >- >- { >- /* make the compiler happy */ >- void *ptd = td; >- slapi_ch_free(&ptd); >- } >+ /* this will queue the destruction of the task */ >+ slapi_task_finish(task, rc); > } > > /* 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. >@@ -1964,60 +1913,63 @@ > *returncode = LDAP_OBJECT_CLASS_VIOLATION; > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } > >- /* allocate new task now */ >- task = slapi_new_task(slapi_entry_get_ndn(e)); >- task->task_state = SLAPI_TASK_SETUP; >- task->task_work = 1; >- task->task_progress = 0; >- >- /* create a pblock to pass the necessary info to the task thread */ >+ /* setup our task data */ > mytaskdata = (task_data*)slapi_ch_malloc(sizeof(task_data)); > if (mytaskdata == NULL) > { > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } > mytaskdata->dn = slapi_ch_strdup(dn); > mytaskdata->filter_str = slapi_ch_strdup(filter); >- mytaskdata->task = task; >+ >+ /* allocate new task now */ >+ task = slapi_new_task(slapi_entry_get_ndn(e)); >+ >+ /* register our destructor for cleaning up our private data */ >+ slapi_task_set_destructor_fn(task, memberof_task_destructor); >+ >+ /* Stash a pointer to our data in the task */ >+ slapi_task_set_data(task, mytaskdata); > > /* start the sample task as a separate thread */ >- thread = PR_CreateThread(PR_USER_THREAD, memberof_memberof_fixup_task_thread, >- (void *)mytaskdata, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, >+ thread = PR_CreateThread(PR_USER_THREAD, memberof_fixup_task_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, MEMBEROF_PLUGIN_SUBSYSTEM, > "unable to create task thread!\n"); > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; >- >- slapi_ch_free_string(&mytaskdata->dn); >- slapi_ch_free_string(&mytaskdata->filter_str); >- >- { >- void *ptask = mytaskdata; >- slapi_ch_free(&ptask); >- goto out; >- } >+ slapi_task_finish(task, *returncode); >+ } else { >+ rv = SLAPI_DSE_CALLBACK_OK; > } > >- /* thread successful -- don't free the pb, let the thread do that. */ >- return SLAPI_DSE_CALLBACK_OK; >- > out: >- if (task) >- { >- slapi_destroy_task(task); >- } > return rv; > } > >+void >+memberof_task_destructor(Slapi_Task *task) >+{ >+ if (task) { >+ task_data *mydata = (task_data *)slapi_task_get_data(task); >+ if (mydata) { >+ slapi_ch_free_string(&mydata->dn); >+ slapi_ch_free_string(&mydata->filter_str); >+ /* Need to cast to avoid a compiler warning */ >+ slapi_ch_free((void **)&mydata); >+ } >+ } >+} >+ > int memberof_fix_memberof(char *dn, char *filter_str) > { > int rc = 0; > Slapi_PBlock *search_pb = slapi_pblock_new(); > >Index: ldap/servers/slapd/main.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/main.c,v >retrieving revision 1.22 >diff -u -5 -t -r1.22 main.c >--- ldap/servers/slapd/main.c 18 Oct 2007 00:08:34 -0000 1.22 >+++ ldap/servers/slapd/main.c 31 Mar 2008 22:22:08 -0000 >@@ -2116,11 +2116,11 @@ > pb.pb_ldif_encrypt = importexport_encrypt; > pb.pb_instance_name = cmd_line_instance_name; > pb.pb_ldif_files = ldif_file; > pb.pb_ldif_include = db2ldif_include; > pb.pb_ldif_exclude = db2ldif_exclude; >- pb.pb_task_flags = TASK_RUNNING_FROM_COMMANDLINE; >+ pb.pb_task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE; > #ifndef _WIN32 > main_setuid(slapdFrontendConfig->localuser); > #endif > if ( plugin->plg_ldif2db != NULL ) { > return_value = (*plugin->plg_ldif2db)( &pb ); >@@ -2243,11 +2243,11 @@ > pb.pb_ldif_exclude = db2ldif_exclude; > pb.pb_ldif_dump_replica = db2ldif_dump_replica; > pb.pb_ldif_dump_uniqueid = db2ldif_dump_uniqueid; > pb.pb_ldif_encrypt = importexport_encrypt; > pb.pb_instance_name = *instp; >- pb.pb_task_flags = TASK_RUNNING_FROM_COMMANDLINE; >+ pb.pb_task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE; > if (is_slapd_running()) > pb.pb_server_running = 1; > else > pb.pb_server_running = 0; > >@@ -2429,11 +2429,11 @@ > memset( &pb, '\0', sizeof(pb) ); > pb.pb_backend = NULL; > pb.pb_plugin = plugin; > pb.pb_db2index_attrs = db2index_attrs; > pb.pb_instance_name = cmd_line_instance_name; >- pb.pb_task_flags = TASK_RUNNING_FROM_COMMANDLINE; >+ pb.pb_task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE; > #ifndef _WIN32 > main_setuid(slapdFrontendConfig->localuser); > #endif > return_value = (*plugin->plg_db2index)( &pb ); > >@@ -2487,11 +2487,11 @@ > memset( &pb, '\0', sizeof(pb) ); > pb.pb_backend = NULL; > pb.pb_plugin = backend_plugin; > pb.pb_instance_name = cmd_line_instance_name; > pb.pb_seq_val = archive_name; >- pb.pb_task_flags = TASK_RUNNING_FROM_COMMANDLINE; >+ pb.pb_task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE; > #ifndef _WIN32 > main_setuid(slapdFrontendConfig->localuser); > #endif > return_value = (backend_plugin->plg_db2archive)( &pb ); > return return_value; >@@ -2537,11 +2537,11 @@ > memset( &pb, '\0', sizeof(pb) ); > pb.pb_backend = NULL; > pb.pb_plugin = backend_plugin; > pb.pb_instance_name = cmd_line_instance_name; > pb.pb_seq_val = archive_name; >- pb.pb_task_flags = TASK_RUNNING_FROM_COMMANDLINE; >+ pb.pb_task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE; > #ifndef _WIN32 > main_setuid(slapdFrontendConfig->localuser); > #endif > return_value = (backend_plugin->plg_archive2db)( &pb ); > return return_value; >@@ -2599,11 +2599,11 @@ > memset( &pb, '\0', sizeof(pb) ); > pb.pb_backend = NULL; > pb.pb_plugin = backend_plugin; > pb.pb_seq_val = archive_name; > pb.pb_seq_type = upgradedb_force; >- pb.pb_task_flags = TASK_RUNNING_FROM_COMMANDLINE; >+ pb.pb_task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE; > /* borrowing import code, so need to set up the import variables */ > pb.pb_ldif_generate_uniqueid = ldif2db_generate_uniqueid; > pb.pb_ldif_namespaceid = ldif2db_namespaceid; > pb.pb_ldif2db_noattrindexes = 0; > pb.pb_removedupvals = 0; >@@ -2654,11 +2654,11 @@ > memset( &pb, '\0', sizeof(pb) ); > pb.pb_backend = NULL; > pb.pb_seq_type = dbverify_verbose; > pb.pb_plugin = backend_plugin; > pb.pb_instance_name = (char *)cmd_line_instance_names; >- pb.pb_task_flags = TASK_RUNNING_FROM_COMMANDLINE; >+ pb.pb_task_flags = SLAPI_TASK_RUNNING_FROM_COMMANDLINE; > > if ( backend_plugin->plg_dbverify != NULL ) { > return_value = (*backend_plugin->plg_dbverify)( &pb ); > } else { > LDAPDebug( LDAP_DEBUG_ANY, >Index: ldap/servers/slapd/slap.h >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slap.h,v >retrieving revision 1.30 >diff -u -5 -t -r1.30 slap.h >--- ldap/servers/slapd/slap.h 18 Oct 2007 01:22:29 -0000 1.30 >+++ ldap/servers/slapd/slap.h 31 Mar 2008 22:22:08 -0000 >@@ -1281,10 +1281,31 @@ > #define SLAPD_POLL_FLAGS (POLLIN) > #else > #define SLAPD_POLL_FLAGS (PR_POLL_READ) > #endif > >+/****************************************************************************** >+ * * Online tasks interface (to support import, export, etc) >+ * * After some cleanup, we could consider making these public. >+ * */ >+struct slapi_task { >+ struct slapi_task *next; >+ char *task_dn; >+ int task_exitcode; /* for the end user */ >+ int task_state; /* current state of task */ >+ int task_progress; /* number between 0 and task_work */ >+ int task_work; /* "units" of work to be done */ >+ int task_flags; /* (see above) */ >+ char *task_status; /* transient status info */ >+ char *task_log; /* appended warnings, etc */ >+ void *task_private; /* allow opaque data to be stashed in the task */ >+ TaskCallbackFn cancel; /* task has been cancelled by user */ >+ TaskCallbackFn destructor; /* task entry is being destroyed */ >+ int task_refcount; >+} slapi_task; >+/* End of interface to support online tasks **********************************/ >+ > typedef struct slapi_pblock { > /* common */ > Slapi_Backend *pb_backend; > Connection *pb_conn; > Operation *pb_op; >@@ -2014,14 +2035,10 @@ > > #define LDIF_CSNPREFIX_MAXLENGTH 6 /* sizeof(xxcsn-) */ > > #include "intrinsics.h" > >-/* task flag (pb_task_flags)*/ >-#define TASK_RUNNING_AS_TASK 0x0 >-#define TASK_RUNNING_FROM_COMMANDLINE 0x1 >- > /* printkey: import & export */ > #define EXPORT_PRINTKEY 0x1 > #define EXPORT_NOWRAP 0x2 > #define EXPORT_APPENDMODE 0x4 > #define EXPORT_MINIMAL_ENCODING 0x8 >Index: ldap/servers/slapd/slapi-plugin.h >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slapi-plugin.h,v >retrieving revision 1.19 >diff -u -5 -t -r1.19 slapi-plugin.h >--- ldap/servers/slapd/slapi-plugin.h 5 Oct 2007 23:31:07 -0000 1.19 >+++ ldap/servers/slapd/slapi-plugin.h 31 Mar 2008 22:22:08 -0000 >@@ -147,13 +147,14 @@ > typedef struct slapi_dn Slapi_DN; > typedef struct slapi_rdn Slapi_RDN; > typedef struct slapi_mod Slapi_Mod; > typedef struct slapi_mods Slapi_Mods; > typedef struct slapi_componentid Slapi_ComponentId; >+ > /* Online tasks interface (to support import, export, etc) */ >-typedef struct _slapi_task Slapi_Task; >-typedef int (*TaskCallbackFn)(Slapi_Task *task); >+typedef struct slapi_task Slapi_Task; >+typedef void (*TaskCallbackFn)(Slapi_Task *task); > > /* > * The default thread stacksize for nspr21 is 64k (except on IRIX! It's 32k!). > * For OSF, we require a larger stacksize as actual storage allocation is > * higher i.e pointers are allocated 8 bytes but lower 4 bytes are used. >@@ -1204,10 +1205,26 @@ > /* DSE */ > /* Front end configuration */ > typedef int (*dseCallbackFn)(Slapi_PBlock *, Slapi_Entry *, Slapi_Entry *, > int *, char*, void *); > >+/* >+ * Note: DSE callback functions MUST return one of these three values: >+ * >+ * SLAPI_DSE_CALLBACK_OK -- no errors occurred; apply changes. >+ * SLAPI_DSE_CALLBACK_ERROR -- an error occurred; don't apply changes. >+ * SLAPI_DSE_CALLBACK_DO_NOT_APPLY -- no error, but do not apply changes. >+ * >+ * SLAPI_DSE_CALLBACK_DO_NOT_APPLY should only be returned by modify >+ * callbacks (i.e., those registered with operation==SLAPI_OPERATION_MODIFY). >+ * A return value of SLAPI_DSE_CALLBACK_DO_NOT_APPLY is treated the same as >+ * SLAPI_DSE_CALLBACK_ERROR for all other operations. >+ */ >+#define SLAPI_DSE_CALLBACK_OK (1) >+#define SLAPI_DSE_CALLBACK_ERROR (-1) >+#define SLAPI_DSE_CALLBACK_DO_NOT_APPLY (0) >+ > /****************************************************************************** > * Online tasks interface (to support import, export, etc) > * After some cleanup, we could consider making these public. > */ > >@@ -1215,14 +1232,30 @@ > #define SLAPI_TASK_SETUP 0 > #define SLAPI_TASK_RUNNING 1 > #define SLAPI_TASK_FINISHED 2 > #define SLAPI_TASK_CANCELLED 3 > >+/* task flag (pb_task_flags)*/ >+#define SLAPI_TASK_RUNNING_AS_TASK 0x0 >+#define SLAPI_TASK_RUNNING_FROM_COMMANDLINE 0x1 >+ > /* task flags (set by the task-control code) */ > #define SLAPI_TASK_DESTROYING 0x01 /* queued event for destruction */ > > int slapi_task_register_handler(const char *name, dseCallbackFn func); >+void slapi_task_begin(Slapi_Task *task, int total_work); >+void slapi_task_inc_progress(Slapi_Task *task); >+void slapi_task_finish(Slapi_Task *task, int rc); >+void slapi_task_cancel(Slapi_Task *task, int rc); >+int slapi_task_get_state(Slapi_Task *task); >+void slapi_task_set_data(Slapi_Task *task, void *data); >+void * slapi_task_get_data(Slapi_Task *task); >+void slapi_task_inc_refcount(Slapi_Task *task); >+void slapi_task_dec_refcount(Slapi_Task *task); >+int slapi_task_get_refcount(Slapi_Task *task); >+void slapi_task_set_destructor_fn(Slapi_Task *task, TaskCallbackFn func); >+void slapi_task_set_cancel_fn(Slapi_Task *task, TaskCallbackFn func); > void slapi_task_status_changed(Slapi_Task *task); > void slapi_task_log_status(Slapi_Task *task, char *format, ...) > #ifdef __GNUC__ > __attribute__ ((format (printf, 2, 3))); > #else >Index: ldap/servers/slapd/slapi-private.h >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/slapi-private.h,v >retrieving revision 1.20 >diff -u -5 -t -r1.20 slapi-private.h >--- ldap/servers/slapd/slapi-private.h 18 Oct 2007 22:40:18 -0000 1.20 >+++ ldap/servers/slapd/slapi-private.h 31 Mar 2008 22:22:08 -0000 >@@ -1058,26 +1058,10 @@ > /***************************************************************************** > * JCMREPL - Added for the replication plugin. > */ > > /* >- * Note: DSE callback functions MUST return one of these three values: >- * >- * SLAPI_DSE_CALLBACK_OK -- no errors occurred; apply changes. >- * SLAPI_DSE_CALLBACK_ERROR -- an error occurred; don't apply changes. >- * SLAPI_DSE_CALLBACK_DO_NOT_APPLY -- no error, but do not apply changes. >- * >- * SLAPI_DSE_CALLBACK_DO_NOT_APPLY should only be returned by modify >- * callbacks (i.e., those registered with operation==SLAPI_OPERATION_MODIFY). >- * A return value of SLAPI_DSE_CALLBACK_DO_NOT_APPLY is treated the same as >- * SLAPI_DSE_CALLBACK_ERROR for all other operations. >- */ >-#define SLAPI_DSE_CALLBACK_OK (1) >-#define SLAPI_DSE_CALLBACK_ERROR (-1) >-#define SLAPI_DSE_CALLBACK_DO_NOT_APPLY (0) >- >-/* > * Flags for slapi_config_register_callback() and > * slapi_config_remove_callback() > */ > #define DSE_FLAG_PREOP 0x0001 > #define DSE_FLAG_POSTOP 0x0002 >@@ -1196,34 +1180,10 @@ > configuration entries will be found */ > #define PLUGIN_BASE_DN "cn=plugins,cn=config" > > /***** End of items added for the replication plugin. ***********************/ > >-/****************************************************************************** >- * Online tasks interface (to support import, export, etc) >- * After some cleanup, we could consider making these public. >- */ >-struct _slapi_task { >- struct _slapi_task *next; >- char *task_dn; >- int task_exitcode; /* for the end user */ >- int task_state; /* (see above) */ >- int task_progress; /* number between 0 and task_work */ >- int task_work; /* "units" of work to be done */ >- int task_flags; /* (see above) */ >- >- /* it is the task's responsibility to allocate this memory & free it: */ >- char *task_status; /* transient status info */ >- char *task_log; /* appended warnings, etc */ >- >- void *task_private; /* for use by backends */ >- TaskCallbackFn cancel; /* task has been cancelled by user */ >- TaskCallbackFn destructor; /* task entry is being destroyed */ >- int task_refcount; >-}; >-/* End of interface to support online tasks **********************************/ >- > void DS_Sleep(PRIntervalTime ticks); > > /* macro to specify the behavior of upgradedb */ > #define SLAPI_UPGRADEDB_FORCE 0x1 /* reindex all (no check w/ idl switch) */ > #define SLAPI_UPGRADEDB_SKIPINIT 0x2 /* call upgradedb as part of other op */ >Index: ldap/servers/slapd/task.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/task.c,v >retrieving revision 1.14 >diff -u -5 -t -r1.14 task.c >--- ldap/servers/slapd/task.c 18 Oct 2007 00:08:34 -0000 1.14 >+++ ldap/servers/slapd/task.c 31 Mar 2008 22:22:08 -0000 >@@ -45,18 +45,23 @@ > */ > > #include "slap.h" > > >+/*********************************** >+ * Static Global Variables >+ ***********************************/ > /* don't panic, this is only used when creating new tasks or removing old > * ones... > */ > static Slapi_Task *global_task_list = NULL; > static PRLock *global_task_lock = NULL; > static int shutting_down = 0; > >- >+/*********************************** >+ * Private Defines >+ ***********************************/ > #define TASK_BASE_DN "cn=tasks, cn=config" > #define TASK_IMPORT_DN "cn=import, cn=tasks, cn=config" > #define TASK_EXPORT_DN "cn=export, cn=tasks, cn=config" > #define TASK_BACKUP_DN "cn=backup, cn=tasks, cn=config" > #define TASK_RESTORE_DN "cn=restore, cn=tasks, cn=config" >@@ -69,17 +74,402 @@ > #define TASK_PROGRESS_NAME "nsTaskCurrentItem" > #define TASK_WORK_NAME "nsTaskTotalItems" > > #define DEFAULT_TTL "120" /* seconds */ > >+#define LOG_BUFFER 256 >+/* if the cumul. log gets larger than this, it's truncated: */ >+#define MAX_SCROLLBACK_BUFFER 8192 >+ >+#define NEXTMOD(_type, _val) do { \ >+ modlist[cur].mod_op = LDAP_MOD_REPLACE; \ >+ modlist[cur].mod_type = (_type); \ >+ modlist[cur].mod_values = (char **)slapi_ch_malloc(2*sizeof(char *)); \ >+ modlist[cur].mod_values[0] = (_val); \ >+ modlist[cur].mod_values[1] = NULL; \ >+ mod[cur] = &modlist[cur]; \ >+ cur++; \ >+} while (0) > >+ >+/*********************************** >+ * Static Function Prototypes >+ ***********************************/ >+static Slapi_Task *new_task(const char *dn); >+static void destroy_task(time_t when, void *arg); > static int task_modify(Slapi_PBlock *pb, Slapi_Entry *e, > Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg); > static int task_deny(Slapi_PBlock *pb, Slapi_Entry *e, > Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg); >-static int task_generic_destructor(Slapi_Task *task); >+static void task_generic_destructor(Slapi_Task *task); >+static const char *fetch_attr(Slapi_Entry *e, const char *attrname, >+ const char *default_val); >+static Slapi_Entry *get_internal_entry(Slapi_PBlock *pb, char *dn); >+static void modify_internal_entry(char *dn, LDAPMod **mods); >+ >+/*********************************** >+ * Public Functions >+ ***********************************/ >+/* >+ * slapi_new_task: create a new task, fill in DN, and setup modify callback >+ * argument: >+ * dn: task dn >+ * result: >+ * Success: Slapi_Task object >+ * Failure: NULL >+ */ >+Slapi_Task * >+slapi_new_task(const char *dn) >+{ >+ return new_task(dn); >+} >+ >+/* slapi_destroy_task: destroy a task >+ * argument: >+ * task: task to destroy >+ * result: >+ * none >+ */ >+void >+slapi_destroy_task(void *arg) >+{ >+ if (arg) { >+ destroy_task(1, arg); >+ } >+} >+ >+/* >+ * Sets the initial task state and updated status >+ */ >+void slapi_task_begin(Slapi_Task *task, int total_work) >+{ >+ if (task) { >+ task->task_work = total_work; >+ task->task_progress = 0; >+ task->task_state = SLAPI_TASK_RUNNING; >+ slapi_task_status_changed(task); >+ } >+} >+ >+/* >+ * Increments task progress and updates status >+ */ >+void slapi_task_inc_progress(Slapi_Task *task) >+{ >+ if (task) { >+ task->task_progress++; >+ slapi_task_status_changed(task); >+ } >+} >+ >+/* >+ * Sets completed task state and updates status >+ */ >+void slapi_task_finish(Slapi_Task *task, int rc) >+{ >+ if (task) { >+ task->task_exitcode = rc; >+ task->task_state = SLAPI_TASK_FINISHED; >+ slapi_task_status_changed(task); >+ } >+} >+ >+/* >+ * Cancels a task >+ */ >+void slapi_task_cancel(Slapi_Task *task, int rc) >+{ >+ if (task) { >+ task->task_exitcode = rc; >+ task->task_state = SLAPI_TASK_CANCELLED; >+ slapi_task_status_changed(task); >+ } >+} >+ >+/* >+ * Get the current state of a task >+ */ >+int slapi_task_get_state(Slapi_Task *task) >+{ >+ if (task) { >+ return task->task_state; >+ } >+} > >+/* this changes the 'nsTaskStatus' value, which is transient (anything logged >+ * here wipes out any previous status) >+ */ >+void slapi_task_log_status(Slapi_Task *task, char *format, ...) >+{ >+ va_list ap; >+ >+ if (! task->task_status) >+ task->task_status = (char *)slapi_ch_malloc(10 * LOG_BUFFER); >+ if (! task->task_status) >+ return; /* out of memory? */ >+ >+ va_start(ap, format); >+ PR_vsnprintf(task->task_status, (10 * LOG_BUFFER), format, ap); >+ va_end(ap); >+ slapi_task_status_changed(task); >+} >+ >+/* this adds a line to the 'nsTaskLog' value, which is cumulative (anything >+ * logged here is added to the end) >+ */ >+void slapi_task_log_notice(Slapi_Task *task, char *format, ...) >+{ >+ va_list ap; >+ char buffer[LOG_BUFFER]; >+ size_t len; >+ >+ va_start(ap, format); >+ PR_vsnprintf(buffer, LOG_BUFFER, format, ap); >+ va_end(ap); >+ >+ len = 2 + strlen(buffer) + (task->task_log ? strlen(task->task_log) : 0); >+ if ((len > MAX_SCROLLBACK_BUFFER) && task->task_log) { >+ size_t i; >+ char *newbuf; >+ >+ /* start from middle of buffer, and find next linefeed */ >+ i = strlen(task->task_log)/2; >+ while (task->task_log[i] && (task->task_log[i] != '\n')) >+ i++; >+ if (task->task_log[i]) >+ i++; >+ len = strlen(task->task_log) - i + 2 + strlen(buffer); >+ newbuf = (char *)slapi_ch_malloc(len); >+ if (! newbuf) >+ return; /* out of memory? */ >+ strcpy(newbuf, task->task_log + i); >+ slapi_ch_free((void **)&task->task_log); >+ task->task_log = newbuf; >+ } else { >+ if (! task->task_log) { >+ task->task_log = (char *)slapi_ch_malloc(len); >+ task->task_log[0] = 0; >+ } else { >+ task->task_log = (char *)slapi_ch_realloc(task->task_log, len); >+ } >+ if (! task->task_log) >+ return; /* out of memory? */ >+ } >+ >+ if (task->task_log[0]) >+ strcat(task->task_log, "\n"); >+ strcat(task->task_log, buffer); >+ >+ slapi_task_status_changed(task); >+} >+ >+/* update attributes in the entry under "cn=tasks" to match the current >+ * status of the task. */ >+void slapi_task_status_changed(Slapi_Task *task) >+{ >+ LDAPMod modlist[20]; >+ LDAPMod *mod[20]; >+ int cur = 0, i; >+ char s1[20], s2[20], s3[20]; >+ >+ if (shutting_down) { >+ /* don't care about task status updates anymore */ >+ return; >+ } >+ >+ NEXTMOD(TASK_LOG_NAME, task->task_log); >+ NEXTMOD(TASK_STATUS_NAME, task->task_status); >+ sprintf(s1, "%d", task->task_exitcode); >+ sprintf(s2, "%d", task->task_progress); >+ sprintf(s3, "%d", task->task_work); >+ NEXTMOD(TASK_PROGRESS_NAME, s2); >+ NEXTMOD(TASK_WORK_NAME, s3); >+ /* only add the exit code when the job is done */ >+ if ((task->task_state == SLAPI_TASK_FINISHED) || >+ (task->task_state == SLAPI_TASK_CANCELLED)) { >+ NEXTMOD(TASK_EXITCODE_NAME, s1); >+ /* make sure the console can tell the task has ended */ >+ if (task->task_progress != task->task_work) { >+ task->task_progress = task->task_work; >+ } >+ } >+ >+ mod[cur] = NULL; >+ modify_internal_entry(task->task_dn, mod); >+ >+ for (i = 0; i < cur; i++) >+ slapi_ch_free((void **)&modlist[i].mod_values); >+ >+ if (((task->task_state == SLAPI_TASK_FINISHED) || >+ (task->task_state == SLAPI_TASK_CANCELLED)) && >+ !(task->task_flags & SLAPI_TASK_DESTROYING)) { >+ Slapi_PBlock *pb = slapi_pblock_new(); >+ Slapi_Entry *e; >+ int ttl; >+ time_t expire; >+ >+ e = get_internal_entry(pb, task->task_dn); >+ if (e == NULL) >+ return; >+ ttl = atoi(fetch_attr(e, "ttl", DEFAULT_TTL)); >+ if (ttl > 3600) >+ ttl = 3600; /* be reasonable. */ >+ expire = time(NULL) + ttl; >+ task->task_flags |= SLAPI_TASK_DESTROYING; >+ /* queue an event to destroy the state info */ >+ slapi_eq_once(destroy_task, (void *)task, expire); >+ >+ slapi_free_search_results_internal(pb); >+ slapi_pblock_destroy(pb); >+ } >+} >+ >+/* >+ * Stash some opaque task specific data in the task for later use. >+ */ >+void slapi_task_set_data(Slapi_Task *task, void *data) >+{ >+ if (task) { >+ task->task_private = data; >+ } >+} >+ >+/* >+ * Retrieve some opaque task specific data from the task. >+ */ >+void * slapi_task_get_data(Slapi_Task *task) >+{ >+ if (task) { >+ return task->task_private; >+ } >+} >+ >+/* >+ * Increment the task reference count >+ */ >+void slapi_task_inc_refcount(Slapi_Task *task) >+{ >+ if (task) { >+ task->task_refcount++; >+ } >+} >+ >+/* >+ * Decrement the task reference count >+ */ >+void slapi_task_dec_refcount(Slapi_Task *task) >+{ >+ if (task) { >+ task->task_refcount--; >+ } >+} >+ >+/* >+ * Returns the task reference count >+ */ >+int slapi_task_get_refcount(Slapi_Task *task) >+{ >+ if (task) { >+ return task->task_refcount; >+ } >+} >+ >+/* name is, for example, "import" */ >+int slapi_task_register_handler(const char *name, dseCallbackFn func) >+{ >+ char *dn = NULL; >+ Slapi_PBlock *pb = NULL; >+ Slapi_Operation *op; >+ LDAPMod *mods[3]; >+ LDAPMod mod[3]; >+ const char *objectclass[3]; >+ const char *cnvals[2]; >+ int ret = -1; >+ int x; >+ >+ dn = slapi_ch_smprintf("cn=%s, %s", name, TASK_BASE_DN); >+ if (dn == NULL) { >+ goto out; >+ } >+ >+ pb = slapi_pblock_new(); >+ if (pb == NULL) { >+ goto out; >+ } >+ >+ /* this is painful :( */ >+ mods[0] = &mod[0]; >+ mod[0].mod_op = LDAP_MOD_ADD; >+ mod[0].mod_type = "objectClass"; >+ mod[0].mod_values = (char **)objectclass; >+ objectclass[0] = "top"; >+ objectclass[1] = "extensibleObject"; >+ objectclass[2] = NULL; >+ mods[1] = &mod[1]; >+ mod[1].mod_op = LDAP_MOD_ADD; >+ mod[1].mod_type = "cn"; >+ mod[1].mod_values = (char **)cnvals; >+ cnvals[0] = name; >+ cnvals[1] = NULL; >+ mods[2] = NULL; >+ slapi_add_internal_set_pb(pb, dn, mods, NULL, >+ plugin_get_default_component_id(), 0); >+ x = 1; >+ slapi_pblock_set(pb, SLAPI_DSE_DONT_WRITE_WHEN_ADDING, &x); >+ /* Make sure these adds don't appear in the audit and change logs */ >+ slapi_pblock_get(pb, SLAPI_OPERATION, &op); >+ operation_set_flag(op, OP_FLAG_ACTION_NOLOG); >+ >+ slapi_add_internal_pb(pb); >+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &x); >+ if ((x != LDAP_SUCCESS) && (x != LDAP_ALREADY_EXISTS)) { >+ LDAPDebug(LDAP_DEBUG_ANY, >+ "Can't create task node '%s' (error %d)\n", >+ name, x, 0); >+ ret = x; >+ goto out; >+ } >+ >+ /* register add callback */ >+ slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, >+ dn, LDAP_SCOPE_SUBTREE, "(objectclass=*)", func, NULL); >+ /* deny modify/delete of the root task entry */ >+ slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, >+ dn, LDAP_SCOPE_BASE, "(objectclass=*)", task_deny, NULL); >+ slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP, >+ dn, LDAP_SCOPE_BASE, "(objectclass=*)", task_deny, NULL); >+ >+ ret = 0; >+ >+out: >+ if (dn) { >+ slapi_ch_free((void **)&dn); >+ } >+ if (pb) { >+ slapi_pblock_destroy(pb); >+ } >+ return ret; >+} >+ >+void slapi_task_set_destructor_fn(Slapi_Task *task, TaskCallbackFn func) >+{ >+ if (task) { >+ task->destructor = func; >+ } >+} >+ >+void slapi_task_set_cancel_fn(Slapi_Task *task, TaskCallbackFn func) >+{ >+ if (task) { >+ task->cancel = func; >+ } >+} >+ >+ >+/*********************************** >+ * Static Helper Functions >+ ***********************************/ > /* create a new task, fill in DN, and setup modify callback */ > static Slapi_Task * > new_task(const char *dn) > { > Slapi_Task *task = (Slapi_Task *)slapi_ch_calloc(1, sizeof(Slapi_Task)); >@@ -90,20 +480,24 @@ > task->next = global_task_list; > global_task_list = task; > PR_Unlock(global_task_lock); > > task->task_dn = slapi_ch_strdup(dn); >- task->destructor = task_generic_destructor; >+ task->task_state = SLAPI_TASK_SETUP; >+ task->task_flags = SLAPI_TASK_RUNNING_AS_TASK; >+ task->destructor = NULL; >+ task->cancel = NULL; >+ task->task_private = NULL; > slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, dn, > LDAP_SCOPE_BASE, "(objectclass=*)", task_modify, (void *)task); > slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP, dn, > LDAP_SCOPE_BASE, "(objectclass=*)", task_deny, NULL); > /* don't add entries under this one */ > #if 0 > /* don't know why, but this doesn't work. it makes the current add >- * operation fail. :( >- */ >+ * * operation fail. :( >+ * */ > slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, dn, > LDAP_SCOPE_SUBTREE, "(objectclass=*)", task_deny, NULL); > #endif > > return task; >@@ -115,12 +509,17 @@ > { > Slapi_Task *task = (Slapi_Task *)arg; > Slapi_Task *t1; > Slapi_PBlock *pb = slapi_pblock_new(); > >- if (task->destructor != NULL) >+ /* Call the custom destructor callback if one was provided, >+ * then perform the internal task destruction. */ >+ if (task->destructor != NULL) { > (*task->destructor)(task); >+ } >+ >+ task_generic_destructor(task); > > /* if when == 0, we're already locked (called during shutdown) */ > if (when != 0) { > PR_Lock(global_task_lock); > } >@@ -139,49 +538,20 @@ > } > > slapi_config_remove_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, > task->task_dn, LDAP_SCOPE_BASE, "(objectclass=*)", task_modify); > slapi_config_remove_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP, >- task->task_dn, LDAP_SCOPE_BASE, "(objectclass=*)", task_deny); >- slapi_delete_internal_set_pb(pb, task->task_dn, NULL, NULL, >- (void *)plugin_get_default_component_id(), 0); >- >- slapi_delete_internal_pb(pb); >- slapi_pblock_destroy(pb); >- >- slapi_ch_free((void **)&task->task_dn); >- slapi_ch_free((void **)&task); >-} >- >-/* >- * slapi_new_task: create a new task, fill in DN, and setup modify callback >- * argument: >- * dn: task dn >- * result: >- * Success: Slapi_Task object >- * Failure: NULL >- */ >-Slapi_Task * >-slapi_new_task(const char *dn) >-{ >- return new_task(dn); >-} >- >-/* slapi_destroy_task: destroy a task >- * argument: >- * task: task to destroy >- * result: >- * none >- */ >-void >-slapi_destroy_task(void *arg) >-{ >- destroy_task(1, arg); >-} >+ task->task_dn, LDAP_SCOPE_BASE, "(objectclass=*)", task_deny); >+ slapi_delete_internal_set_pb(pb, task->task_dn, NULL, NULL, >+ (void *)plugin_get_default_component_id(), 0); > >-/********** some useful helper functions **********/ >+ slapi_delete_internal_pb(pb); >+ slapi_pblock_destroy(pb); > >+ slapi_ch_free((void **)&task->task_dn); >+ slapi_ch_free((void **)&task); >+} > > /* 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. > */ >@@ -266,94 +636,19 @@ > pblock_done(&pb); > > } while (ret != LDAP_SUCCESS); > } > >- >-/********** helper functions for dealing with task logging **********/ >- >-#define LOG_BUFFER 256 >-/* if the cumul. log gets larger than this, it's truncated: */ >-#define MAX_SCROLLBACK_BUFFER 8192 >- >-/* this changes the 'nsTaskStatus' value, which is transient (anything logged >- * here wipes out any previous status) >- */ >-void slapi_task_log_status(Slapi_Task *task, char *format, ...) >-{ >- va_list ap; >- >- if (! task->task_status) >- task->task_status = (char *)slapi_ch_malloc(10 * LOG_BUFFER); >- if (! task->task_status) >- return; /* out of memory? */ >- >- va_start(ap, format); >- PR_vsnprintf(task->task_status, (10 * LOG_BUFFER), format, ap); >- va_end(ap); >- slapi_task_status_changed(task); >-} >- >-/* this adds a line to the 'nsTaskLog' value, which is cumulative (anything >- * logged here is added to the end) >- */ >-void slapi_task_log_notice(Slapi_Task *task, char *format, ...) >-{ >- va_list ap; >- char buffer[LOG_BUFFER]; >- size_t len; >- >- va_start(ap, format); >- PR_vsnprintf(buffer, LOG_BUFFER, format, ap); >- va_end(ap); >- >- len = 2 + strlen(buffer) + (task->task_log ? strlen(task->task_log) : 0); >- if ((len > MAX_SCROLLBACK_BUFFER) && task->task_log) { >- size_t i; >- char *newbuf; >- >- /* start from middle of buffer, and find next linefeed */ >- i = strlen(task->task_log)/2; >- while (task->task_log[i] && (task->task_log[i] != '\n')) >- i++; >- if (task->task_log[i]) >- i++; >- len = strlen(task->task_log) - i + 2 + strlen(buffer); >- newbuf = (char *)slapi_ch_malloc(len); >- if (! newbuf) >- return; /* out of memory? */ >- strcpy(newbuf, task->task_log + i); >- slapi_ch_free((void **)&task->task_log); >- task->task_log = newbuf; >- } else { >- if (! task->task_log) { >- task->task_log = (char *)slapi_ch_malloc(len); >- task->task_log[0] = 0; >- } else { >- task->task_log = (char *)slapi_ch_realloc(task->task_log, len); >- } >- if (! task->task_log) >- return; /* out of memory? */ >- } >- >- if (task->task_log[0]) >- strcat(task->task_log, "\n"); >- strcat(task->task_log, buffer); >- >- slapi_task_status_changed(task); >-} >- >-static int task_generic_destructor(Slapi_Task *task) >+static void task_generic_destructor(Slapi_Task *task) > { > if (task->task_log) { > slapi_ch_free((void **)&task->task_log); > } > if (task->task_status) { > slapi_ch_free((void **)&task->task_status); > } > task->task_log = task->task_status = NULL; >- return 0; > } > > > /********** actual task callbacks **********/ > >@@ -551,17 +846,16 @@ > uniqueid_kind = SLAPI_UNIQUEID_GENERATE_TIME_BASED; > } > } > > /* allocate new task now */ >- task = new_task(slapi_entry_get_ndn(e)); >+ task = slapi_new_task(slapi_entry_get_ndn(e)); > if (task == NULL) { > LDAPDebug(LDAP_DEBUG_ANY, "unable to allocate new task!\n", 0, 0, 0); > rv = LDAP_OPERATIONS_ERROR; > goto out; > } >- task->task_state = SLAPI_TASK_SETUP; > > memset(&mypb, 0, sizeof(mypb)); > mypb.pb_backend = be; > mypb.pb_plugin = be->be_database; > mypb.pb_removedupvals = atoi(fetch_attr(e, "nsImportChunkSize", "0")); >@@ -573,11 +867,11 @@ > mypb.pb_instance_name = (char *)instance_name; > mypb.pb_ldif_files = ldif_file; > mypb.pb_ldif_include = include; > mypb.pb_ldif_exclude = exclude; > mypb.pb_task = task; >- mypb.pb_task_flags = TASK_RUNNING_AS_TASK; >+ mypb.pb_task_flags = SLAPI_TASK_RUNNING_AS_TASK; > if (NULL != encrypt_on_import && 0 == strcasecmp(encrypt_on_import, "true") ) { > mypb.pb_ldif_encrypt = 1; > } > > rv = (*mypb.pb_plugin->plg_ldif2db)(&mypb); >@@ -616,14 +910,11 @@ > Slapi_Task *task = pb->pb_task; > > g_incr_active_threadcnt(); > for (count = 0, inp = instance_names; *inp; inp++, count++) > ; >- task->task_work = count; >- task->task_progress = 0; >- task->task_state = SLAPI_TASK_RUNNING; >- slapi_task_status_changed(task); >+ slapi_task_begin(task, count); > > for (inp = instance_names; *inp; inp++) { > int release_me = 0; > /* lookup the backend */ > be = slapi_be_select_by_instance_name((const char *)*inp); >@@ -691,12 +982,11 @@ > } > > if (rv != 0) > break; > >- task->task_progress++; >- slapi_task_status_changed(task); >+ slapi_task_inc_progress(task); > } > > /* free the memory now */ > charray_free(instance_names); > slapi_ch_free((void **)&ldif_file); >@@ -710,13 +1000,11 @@ > } else { > slapi_task_log_notice(task, "Export failed."); > LDAPDebug(LDAP_DEBUG_ANY, "Export failed.\n", 0, 0, 0); > } > >- task->task_exitcode = rv; >- task->task_state = SLAPI_TASK_FINISHED; >- slapi_task_status_changed(task); >+ slapi_task_finish(task, rv); > g_decr_active_threadcnt(); > } > > static int task_export_add(Slapi_PBlock *pb, Slapi_Entry *e, > Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg) >@@ -886,20 +1174,17 @@ > goto out; > } > } > > /* allocate new task now */ >- task = new_task(slapi_entry_get_ndn(e)); >+ task = slapi_new_task(slapi_entry_get_ndn(e)); > if (task == NULL) { > LDAPDebug(LDAP_DEBUG_ANY, "unable to allocate new task!\n", 0, 0, 0); > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } >- task->task_state = SLAPI_TASK_SETUP; >- task->task_work = instance_cnt; >- task->task_progress = 0; > > mypb = slapi_pblock_new(); > if (mypb == NULL) { > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; >@@ -912,11 +1197,11 @@ > mypb->pb_ldif_dump_uniqueid = dump_uniqueid_flag; > mypb->pb_ldif_file = ldif_file; > /* horrible hack */ > mypb->pb_instance_name = (char *)instance_names; > mypb->pb_task = task; >- mypb->pb_task_flags = TASK_RUNNING_AS_TASK; >+ mypb->pb_task_flags = SLAPI_TASK_RUNNING_AS_TASK; > if (NULL != decrypt_on_export && 0 == strcasecmp(decrypt_on_export, "true") ) { > mypb->pb_ldif_encrypt = 1; > } > > /* start the export as a separate thread */ >@@ -955,14 +1240,11 @@ > Slapi_PBlock *pb = (Slapi_PBlock *)arg; > Slapi_Task *task = pb->pb_task; > int rv; > > g_incr_active_threadcnt(); >- task->task_work = 1; >- task->task_progress = 0; >- task->task_state = SLAPI_TASK_RUNNING; >- slapi_task_status_changed(task); >+ slapi_task_begin(task, 1); > > slapi_task_log_notice(task, "Beginning backup of '%s'", > pb->pb_plugin->plg_name); > LDAPDebug(LDAP_DEBUG_ANY, "Beginning backup of '%s'\n", > pb->pb_plugin->plg_name, 0, 0); >@@ -976,15 +1258,11 @@ > slapi_task_log_notice(task, "Backup finished."); > slapi_task_log_status(task, "Backup finished."); > LDAPDebug(LDAP_DEBUG_ANY, "Backup finished.\n", 0, 0, 0); > } > >- task->task_progress = 1; >- task->task_exitcode = rv; >- task->task_state = SLAPI_TASK_FINISHED; >- slapi_task_status_changed(task); >- >+ slapi_task_finish(task, rv); > slapi_ch_free((void **)&pb->pb_seq_val); > slapi_pblock_destroy(pb); > g_decr_active_threadcnt(); > } > >@@ -1046,31 +1324,28 @@ > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } > > /* allocate new task now */ >- task = new_task(slapi_entry_get_ndn(e)); >+ task = slapi_new_task(slapi_entry_get_ndn(e)); > if (task == NULL) { > LDAPDebug(LDAP_DEBUG_ANY, "unable to allocate new task!\n", 0, 0, 0); > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } >- task->task_state = SLAPI_TASK_SETUP; >- task->task_work = 1; >- task->task_progress = 0; > > mypb = slapi_pblock_new(); > if (mypb == NULL) { > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } > mypb->pb_seq_val = slapi_ch_strdup(archive_dir); > mypb->pb_plugin = be->be_database; > mypb->pb_task = task; >- mypb->pb_task_flags = TASK_RUNNING_AS_TASK; >+ mypb->pb_task_flags = SLAPI_TASK_RUNNING_AS_TASK; > > /* start the backup as a separate thread */ > thread = PR_CreateThread(PR_USER_THREAD, task_backup_thread, > (void *)mypb, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, > PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); >@@ -1100,14 +1375,11 @@ > Slapi_PBlock *pb = (Slapi_PBlock *)arg; > Slapi_Task *task = pb->pb_task; > int rv; > > g_incr_active_threadcnt(); >- task->task_work = 1; >- task->task_progress = 0; >- task->task_state = SLAPI_TASK_RUNNING; >- slapi_task_status_changed(task); >+ slapi_task_begin(task, 1); > > slapi_task_log_notice(task, "Beginning restore to '%s'", > pb->pb_plugin->plg_name); > LDAPDebug(LDAP_DEBUG_ANY, "Beginning restore to '%s'\n", > pb->pb_plugin->plg_name, 0, 0); >@@ -1121,15 +1393,11 @@ > slapi_task_log_notice(task, "Restore finished."); > slapi_task_log_status(task, "Restore finished."); > LDAPDebug(LDAP_DEBUG_ANY, "Restore finished.\n", 0, 0, 0); > } > >- task->task_progress = 1; >- task->task_exitcode = rv; >- task->task_state = SLAPI_TASK_FINISHED; >- slapi_task_status_changed(task); >- >+ slapi_task_finish(task, rv); > slapi_ch_free((void **)&pb->pb_seq_val); > slapi_pblock_destroy(pb); > g_decr_active_threadcnt(); > } > >@@ -1197,20 +1465,17 @@ > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } > > /* allocate new task now */ >- task = new_task(slapi_entry_get_ndn(e)); >+ task = slapi_new_task(slapi_entry_get_ndn(e)); > if (task == NULL) { > LDAPDebug(LDAP_DEBUG_ANY, "unable to allocate new task!\n", 0, 0, 0); > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } >- task->task_state = SLAPI_TASK_SETUP; >- task->task_work = 1; >- task->task_progress = 0; > > mypb = slapi_pblock_new(); > if (mypb == NULL) { > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; >@@ -1219,11 +1484,11 @@ > mypb->pb_seq_val = slapi_ch_strdup(archive_dir); > mypb->pb_plugin = be->be_database; > if (NULL != instance_name) > mypb->pb_instance_name = slapi_ch_strdup(instance_name); > mypb->pb_task = task; >- mypb->pb_task_flags = TASK_RUNNING_AS_TASK; >+ mypb->pb_task_flags = SLAPI_TASK_RUNNING_AS_TASK; > > /* start the restore as a separate thread */ > thread = PR_CreateThread(PR_USER_THREAD, task_restore_thread, > (void *)mypb, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, > PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); >@@ -1253,27 +1518,20 @@ > Slapi_PBlock *pb = (Slapi_PBlock *)arg; > Slapi_Task *task = pb->pb_task; > int rv; > > g_incr_active_threadcnt(); >- task->task_work = 1; >- task->task_progress = 0; >- task->task_state = SLAPI_TASK_RUNNING; >- slapi_task_status_changed(task); >+ slapi_task_begin(task, 1); > > rv = (*pb->pb_plugin->plg_db2index)(pb); > if (rv != 0) { > slapi_task_log_notice(task, "Index failed (error %d)", rv); > slapi_task_log_status(task, "Index failed (error %d)", rv); > LDAPDebug(LDAP_DEBUG_ANY, "Index failed (error %d)\n", rv, 0, 0); > } > >- task->task_progress = task->task_work; >- task->task_exitcode = rv; >- task->task_state = SLAPI_TASK_FINISHED; >- slapi_task_status_changed(task); >- >+ slapi_task_finish(task, rv); > charray_free(pb->pb_db2index_attrs); > slapi_ch_free((void **)&pb->pb_instance_name); > slapi_pblock_destroy(pb); > g_decr_active_threadcnt(); > } >@@ -1351,20 +1609,17 @@ > rv = SLAPI_DSE_CALLBACK_OK; > goto out; > } > > /* allocate new task now */ >- task = new_task(slapi_entry_get_ndn(e)); >+ task = slapi_new_task(slapi_entry_get_ndn(e)); > if (task == NULL) { > LDAPDebug(LDAP_DEBUG_ANY, "unable to allocate new task!\n", 0, 0, 0); > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } >- task->task_state = SLAPI_TASK_SETUP; >- task->task_work = 1; >- task->task_progress = 0; > > mypb = slapi_pblock_new(); > if (mypb == NULL) { > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; >@@ -1373,11 +1628,11 @@ > mypb->pb_backend = be; > mypb->pb_plugin = be->be_database; > mypb->pb_instance_name = slapi_ch_strdup(instance_name); > mypb->pb_db2index_attrs = indexlist; > mypb->pb_task = task; >- mypb->pb_task_flags = TASK_RUNNING_AS_TASK; >+ mypb->pb_task_flags = SLAPI_TASK_RUNNING_AS_TASK; > > /* start the db2index as a separate thread */ > thread = PR_CreateThread(PR_USER_THREAD, task_index_thread, > (void *)mypb, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, > PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); >@@ -1458,29 +1713,29 @@ > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } > > /* allocate new task now */ >- task = new_task(slapi_entry_get_ndn(e)); >+ task = slapi_new_task(slapi_entry_get_ndn(e)); > if (task == NULL) { > LDAPDebug(LDAP_DEBUG_ANY, "unable to allocate new task!\n", 0, 0, 0); > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } >- task->task_state = SLAPI_TASK_SETUP; >+ /* NGK - This could use some cleanup to use the SLAPI task API, such as slapi_task_begin() */ > task->task_work = 1; > task->task_progress = 0; > > memset(&mypb, 0, sizeof(mypb)); > mypb.pb_backend = be; > mypb.pb_plugin = be->be_database; > if (force && 0 == strcasecmp(force, "true")) > mypb.pb_seq_type = SLAPI_UPGRADEDB_FORCE; /* force; reindex all regardless the dbversion */ > mypb.pb_seq_val = slapi_ch_strdup(archive_dir); > mypb.pb_task = task; >- mypb.pb_task_flags = TASK_RUNNING_AS_TASK; >+ mypb.pb_task_flags = SLAPI_TASK_RUNNING_AS_TASK; > > rv = (mypb.pb_plugin->plg_upgradedb)(&mypb); > if (rv == 0) { > slapi_entry_attr_set_charptr(e, TASK_LOG_NAME, ""); > slapi_entry_attr_set_charptr(e, TASK_STATUS_NAME, ""); >@@ -1500,80 +1755,10 @@ > > *returncode = LDAP_SUCCESS; > return SLAPI_DSE_CALLBACK_OK; > } > >-/* update attributes in the entry under "cn=tasks" to match the current >- * status of the task. >- */ >-#define NEXTMOD(_type, _val) do { \ >- modlist[cur].mod_op = LDAP_MOD_REPLACE; \ >- modlist[cur].mod_type = (_type); \ >- modlist[cur].mod_values = (char **)slapi_ch_malloc(2*sizeof(char *)); \ >- modlist[cur].mod_values[0] = (_val); \ >- modlist[cur].mod_values[1] = NULL; \ >- mod[cur] = &modlist[cur]; \ >- cur++; \ >-} while (0) >-void slapi_task_status_changed(Slapi_Task *task) >-{ >- LDAPMod modlist[20]; >- LDAPMod *mod[20]; >- int cur = 0, i; >- char s1[20], s2[20], s3[20]; >- >- if (shutting_down) { >- /* don't care about task status updates anymore */ >- return; >- } >- >- NEXTMOD(TASK_LOG_NAME, task->task_log); >- NEXTMOD(TASK_STATUS_NAME, task->task_status); >- sprintf(s1, "%d", task->task_exitcode); >- sprintf(s2, "%d", task->task_progress); >- sprintf(s3, "%d", task->task_work); >- NEXTMOD(TASK_PROGRESS_NAME, s2); >- NEXTMOD(TASK_WORK_NAME, s3); >- /* only add the exit code when the job is done */ >- if ((task->task_state == SLAPI_TASK_FINISHED) || >- (task->task_state == SLAPI_TASK_CANCELLED)) { >- NEXTMOD(TASK_EXITCODE_NAME, s1); >- /* make sure the console can tell the task has ended */ >- if (task->task_progress != task->task_work) { >- task->task_progress = task->task_work; >- } >- } >- >- mod[cur] = NULL; >- modify_internal_entry(task->task_dn, mod); >- >- for (i = 0; i < cur; i++) >- slapi_ch_free((void **)&modlist[i].mod_values); >- >- if ((task->task_state == SLAPI_TASK_FINISHED) && >- !(task->task_flags & SLAPI_TASK_DESTROYING)) { >- Slapi_PBlock *pb = slapi_pblock_new(); >- Slapi_Entry *e; >- int ttl; >- time_t expire; >- >- e = get_internal_entry(pb, task->task_dn); >- if (e == NULL) >- return; >- ttl = atoi(fetch_attr(e, "ttl", DEFAULT_TTL)); >- if (ttl > 3600) >- ttl = 3600; /* be reasonable. */ >- expire = time(NULL) + ttl; >- task->task_flags |= SLAPI_TASK_DESTROYING; >- /* queue an event to destroy the state info */ >- slapi_eq_once(destroy_task, (void *)task, expire); >- >- slapi_free_search_results_internal(pb); >- slapi_pblock_destroy(pb); >- } >-} >- > /* cleanup old tasks that may still be in the DSE from a previous session > * (this can happen if the server crashes [no matter how unlikely we like > * to think that is].) > */ > void task_cleanup(void) >@@ -1634,88 +1819,10 @@ > slapi_sdn_free(&rootDN); > slapi_free_search_results_internal(pb); > slapi_pblock_destroy(pb); > } > >-/* name is, for exmaple, "import" */ >-int slapi_task_register_handler(const char *name, dseCallbackFn func) >-{ >- char *dn = NULL; >- Slapi_PBlock *pb = NULL; >- Slapi_Operation *op; >- LDAPMod *mods[3]; >- LDAPMod mod[3]; >- const char *objectclass[3]; >- const char *cnvals[2]; >- int ret = -1; >- int x; >- >- dn = slapi_ch_smprintf("cn=%s, %s", name, TASK_BASE_DN); >- if (dn == NULL) { >- goto out; >- } >- >- pb = slapi_pblock_new(); >- if (pb == NULL) { >- goto out; >- } >- >- /* this is painful :( */ >- mods[0] = &mod[0]; >- mod[0].mod_op = LDAP_MOD_ADD; >- mod[0].mod_type = "objectClass"; >- mod[0].mod_values = (char **)objectclass; >- objectclass[0] = "top"; >- objectclass[1] = "extensibleObject"; >- objectclass[2] = NULL; >- mods[1] = &mod[1]; >- mod[1].mod_op = LDAP_MOD_ADD; >- mod[1].mod_type = "cn"; >- mod[1].mod_values = (char **)cnvals; >- cnvals[0] = name; >- cnvals[1] = NULL; >- mods[2] = NULL; >- slapi_add_internal_set_pb(pb, dn, mods, NULL, >- plugin_get_default_component_id(), 0); >- x = 1; >- slapi_pblock_set(pb, SLAPI_DSE_DONT_WRITE_WHEN_ADDING, &x); >- /* Make sure these adds don't appear in the audit and change logs */ >- slapi_pblock_get(pb, SLAPI_OPERATION, &op); >- operation_set_flag(op, OP_FLAG_ACTION_NOLOG); >- >- slapi_add_internal_pb(pb); >- slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &x); >- if ((x != LDAP_SUCCESS) && (x != LDAP_ALREADY_EXISTS)) { >- LDAPDebug(LDAP_DEBUG_ANY, >- "Can't create task node '%s' (error %d)\n", >- name, x, 0); >- ret = x; >- goto out; >- } >- >- /* register add callback */ >- slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, >- dn, LDAP_SCOPE_SUBTREE, "(objectclass=*)", func, NULL); >- /* deny modify/delete of the root task entry */ >- slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP, >- dn, LDAP_SCOPE_BASE, "(objectclass=*)", task_deny, NULL); >- slapi_config_register_callback(SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP, >- dn, LDAP_SCOPE_BASE, "(objectclass=*)", task_deny, NULL); >- >- ret = 0; >- >-out: >- if (dn) { >- slapi_ch_free((void **)&dn); >- } >- if (pb) { >- slapi_pblock_destroy(pb); >- } >- return ret; >-} >- >- > void task_init(void) > { > global_task_lock = PR_NewLock(); > if (global_task_lock == NULL) { > LDAPDebug(LDAP_DEBUG_ANY, "unable to create global tasks lock! " >Index: ldap/servers/slapd/back-ldbm/archive.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/archive.c,v >retrieving revision 1.15 >diff -u -5 -t -r1.15 archive.c >--- ldap/servers/slapd/back-ldbm/archive.c 4 Dec 2007 17:52:56 -0000 1.15 >+++ ldap/servers/slapd/back-ldbm/archive.c 31 Mar 2008 22:22:08 -0000 >@@ -59,11 +59,11 @@ > slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li ); > slapi_pblock_get( pb, SLAPI_SEQ_VAL, &rawdirectory ); > slapi_pblock_get( pb, SLAPI_BACKEND_INSTANCE_NAME, &backendname); > slapi_pblock_get( pb, SLAPI_BACKEND_TASK, &task ); > slapi_pblock_get( pb, SLAPI_TASK_FLAGS, &task_flags ); >- li->li_flags = run_from_cmdline = (task_flags & TASK_RUNNING_FROM_COMMANDLINE); >+ li->li_flags = run_from_cmdline = (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE); > > if ( !rawdirectory || !*rawdirectory ) { > LDAPDebug( LDAP_DEBUG_ANY, "archive2db: no archive name\n", > 0, 0, 0 ); > return( -1 ); >@@ -271,11 +271,11 @@ > struct stat sbuf; > > slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li ); > slapi_pblock_get( pb, SLAPI_SEQ_VAL, &rawdirectory ); > slapi_pblock_get( pb, SLAPI_TASK_FLAGS, &task_flags ); >- li->li_flags = run_from_cmdline = (task_flags & TASK_RUNNING_FROM_COMMANDLINE); >+ li->li_flags = run_from_cmdline = (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE); > > slapi_pblock_get( pb, SLAPI_BACKEND_TASK, &task ); > > if ( !rawdirectory || !*rawdirectory ) { > LDAPDebug( LDAP_DEBUG_ANY, "db2archive: no archive name\n", >Index: ldap/servers/slapd/back-ldbm/back-ldbm.h >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/back-ldbm.h,v >retrieving revision 1.12 >diff -u -5 -t -r1.12 back-ldbm.h >--- ldap/servers/slapd/back-ldbm/back-ldbm.h 19 Oct 2007 02:09:24 -0000 1.12 >+++ ldap/servers/slapd/back-ldbm/back-ldbm.h 31 Mar 2008 22:22:08 -0000 >@@ -511,14 +511,14 @@ > int li_flags; > int li_fat_lock; /* 608146 -- make this configurable, first */ > int li_legacy_errcode; /* 615428 -- in case legacy err code is expected */ > }; > >-/* li_flags could store these bits defined in ../slap.h >+/* li_flags could store these bits defined in ../slapi-plugin.h > * task flag (pb_task_flags) * >- * #define TASK_RUNNING_AS_TASK 0x0 >- * #define TASK_RUNNING_FROM_COMMANDLINE 0x1 >+ * SLAPI_TASK_RUNNING_AS_TASK >+ * SLAPI_TASK_RUNNING_FROM_COMMANDLINE > */ > /* allow conf w/o CONFIG_FLAG_ALLOW_RUNNING_CHANGE to be updated */ > #define LI_FORCE_MOD_CONFIG 0x10 > > /* Structure used to hold stuff for the lifetime of an LDAP transaction */ >Index: ldap/servers/slapd/back-ldbm/dblayer.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/dblayer.c,v >retrieving revision 1.26 >diff -u -5 -t -r1.26 dblayer.c >--- ldap/servers/slapd/back-ldbm/dblayer.c 4 Dec 2007 00:50:19 -0000 1.26 >+++ ldap/servers/slapd/back-ldbm/dblayer.c 31 Mar 2008 22:22:09 -0000 >@@ -1952,11 +1952,11 @@ > "No other process is allowed to access the database\n", > 0, 0, 0); > oflags |= DB_PRIVATE; > } > PR_Lock(li->li_config_mutex); >- if ((li->li_flags & TASK_RUNNING_FROM_COMMANDLINE) && >+ if ((li->li_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE) && > (li->li_import_cache_autosize)) /* Autosizing importCache > * Need to re-eval every time > * to guarantee the memory is > * really available > * (just for command line I/F) >@@ -5676,11 +5676,11 @@ > /* now start the database code up, to prevent recovery next time the > * server starts; > * dse_conf_verify may need to have db started, as well. */ > /* If no logfiles were stored, then fatal recovery isn't required */ > >- if (li->li_flags & TASK_RUNNING_FROM_COMMANDLINE) >+ if (li->li_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE) > { > /* command line mode; no need to run db threads */ > dbmode |= DBLAYER_NO_DBTHREADS_MODE; > } > else /* on-line mode */ >@@ -5705,11 +5705,11 @@ > if (0 != tmp_rval) > LDAPDebug(LDAP_DEBUG_ANY, > "Warning: Unable to verify the index configuration\n", 0, 0, 0); > } > >- if (li->li_flags & TASK_RUNNING_FROM_COMMANDLINE) { >+ if (li->li_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE) { > /* command line: close the database down again */ > tmp_rval = dblayer_close(li, dbmode); > if (0 != tmp_rval) { > LDAPDebug(LDAP_DEBUG_ANY, > "dblayer_restore: Failed to close database\n", 0, 0, 0); >Index: ldap/servers/slapd/back-ldbm/import.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/import.c,v >retrieving revision 1.10 >diff -u -5 -t -r1.10 import.c >--- ldap/servers/slapd/back-ldbm/import.c 18 Oct 2007 00:08:34 -0000 1.10 >+++ ldap/servers/slapd/back-ldbm/import.c 31 Mar 2008 22:22:09 -0000 >@@ -195,59 +195,46 @@ > /* also save it in the logs for posterity */ > LDAPDebug(LDAP_DEBUG_ANY, "import %s: %s\n", job->inst->inst_name, > buffer, 0); > } > >-static int import_task_destroy(Slapi_Task *task) >+static void import_task_destroy(Slapi_Task *task) > { >- ImportJob *job = (ImportJob *)task->task_private; >- >- if (task->task_log) { >- slapi_ch_free((void **)&task->task_log); >- } >- >- if (task->task_status) { >- slapi_ch_free((void **)&task->task_status); >- } >- >+ ImportJob *job = (ImportJob *)slapi_task_get_data(task); > > if (job && job->task_status) { > slapi_ch_free((void **)&job->task_status); > job->task_status = NULL; > } > FREE(job); >- task->task_private = NULL; >- return 0; >+ slapi_task_set_data(task, NULL); > } > >-static int import_task_abort(Slapi_Task *task) >+static void import_task_abort(Slapi_Task *task) > { > ImportJob *job; > > /* don't log anything from here, because we're still holding the > * DSE lock for modify... > */ > >- if (task->task_state == SLAPI_TASK_FINISHED) { >+ if (slapi_task_get_state(task) == SLAPI_TASK_FINISHED) { > /* too late */ >- return 0; > } > > /* > * Race condition. > * If the import thread happens to finish right now we're in trouble > * because it will free the job. > */ > >- job = (ImportJob *)task->task_private; >+ job = (ImportJob *)slapi_task_get_data(task); > > import_abort_all(job, 0); >- while (task->task_state != SLAPI_TASK_FINISHED) >+ while (slapi_task_get_state(task) != SLAPI_TASK_FINISHED) > DS_Sleep(PR_MillisecondsToInterval(100)); > >- >- return 0; > } > > > /********** helper functions for importing **********/ > >@@ -1040,17 +1027,12 @@ > ret = dbversion_write(inst->inst_li, inst_dirp, NULL); > if (inst_dirp != inst_dir) > slapi_ch_free_string(&inst_dirp); > } > >- if (job->task != NULL && 0 == job->task->task_refcount) { >- /* exit code */ >- job->task->task_exitcode = ret; >- job->task->task_state = SLAPI_TASK_FINISHED; >- job->task->task_progress = job->task->task_work; >- job->task->task_private = NULL; >- slapi_task_status_changed(job->task); >+ if ((job->task != NULL) && (0 == slapi_task_get_refcount(job->task))) { >+ slapi_task_finish(job->task, ret); > } > > if (job->flags & FLAG_ONLINE) { > /* make sure the indexes are online as well */ > /* richm 20070919 - if index entries are added online, they >@@ -1091,11 +1073,11 @@ > int status = 0; > int verbose = 1; > ImportWorkerInfo *producer = NULL; > > if (job->task) >- job->task->task_refcount++; >+ slapi_task_inc_refcount(job->task); > > PR_ASSERT(inst != NULL); > time(&beginning); > > /* Decide which indexes are needed */ >@@ -1362,17 +1344,15 @@ > } > > if (0 != ret) { > import_log_notice(job, "Import failed."); > if (job->task != NULL) { >- job->task->task_state = SLAPI_TASK_FINISHED; >- job->task->task_exitcode = ret; >- slapi_task_status_changed(job->task); >+ slapi_task_finish(job->task, ret); > } > } else { > if (job->task) >- job->task->task_refcount--; >+ slapi_task_dec_refcount(job->task); > > import_all_done(job, ret); > } > > /* This instance isn't busy anymore */ >@@ -1469,19 +1449,21 @@ > while (name_array && name_array[total_files] != NULL) > total_files++; > /* add 1 to account for post-import cleanup (which can take a > * significant amount of time) > */ >+ /* NGK - This should eventually be cleaned up to use the public >+ * task API. */ > if (0 == total_files) /* reindexing */ > job->task->task_work = 2; > else > job->task->task_work = total_files + 1; > job->task->task_progress = 0; > job->task->task_state = SLAPI_TASK_RUNNING; >- job->task->task_private = job; >- job->task->destructor = import_task_destroy; >- job->task->cancel = import_task_abort; >+ slapi_task_set_data(job->task, job); >+ slapi_task_set_destructor_fn(job->task, import_task_destroy); >+ slapi_task_set_cancel_fn(job->task, import_task_abort); > job->flags |= FLAG_ONLINE; > > /* create thread for import_main, so we can return */ > thread = PR_CreateThread(PR_USER_THREAD, import_main, (void *)job, > PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, >Index: ldap/servers/slapd/back-ldbm/ldif2ldbm.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/back-ldbm/ldif2ldbm.c,v >retrieving revision 1.15 >diff -u -5 -t -r1.15 ldif2ldbm.c >--- ldap/servers/slapd/back-ldbm/ldif2ldbm.c 13 Oct 2007 01:49:32 -0000 1.15 >+++ ldap/servers/slapd/back-ldbm/ldif2ldbm.c 31 Mar 2008 22:22:09 -0000 >@@ -566,11 +566,11 @@ > > /* BEGIN complex dependencies of various initializations. */ > /* hopefully this will go away once import is not run standalone... */ > > slapi_pblock_get(pb, SLAPI_TASK_FLAGS, &task_flags); >- if (task_flags & TASK_RUNNING_FROM_COMMANDLINE) { >+ if (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE) { > /* initialize UniqueID generator - must be done once backends are started > and event queue is initialized but before plugins are started */ > Slapi_DN *sdn = slapi_sdn_new_dn_byval ("cn=uniqueid generator,cn=config"); > int rc = uniqueIDGenInit (NULL, sdn, 0 /* use single thread mode */); > slapi_sdn_free (&sdn); >@@ -579,11 +579,11 @@ > "Fatal Error---Failed to initialize uniqueid generator; error = %d. " > "Exiting now.\n", rc, 0, 0 ); > return -1; > } > >- li->li_flags |= TASK_RUNNING_FROM_COMMANDLINE; >+ li->li_flags |= SLAPI_TASK_RUNNING_FROM_COMMANDLINE; > ldbm_config_load_dse_info(li); > autosize_import_cache(li); > } > > /* Find the instance that the ldif2db will be done on. */ >@@ -602,11 +602,11 @@ > return -1; > } > > /***** prepare & init libdb and dblayer *****/ > >- if (! (task_flags & TASK_RUNNING_FROM_COMMANDLINE)) { >+ if (! (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE)) { > /* shutdown this instance of the db */ > LDAPDebug(LDAP_DEBUG_ANY, "Bringing %s offline...\n", > instance_name, 0, 0); > slapi_mtn_be_disable(inst->inst_be); > >@@ -776,15 +776,15 @@ > > slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li ); > slapi_pblock_get( pb, SLAPI_TASK_FLAGS, &task_flags ); > slapi_pblock_get( pb, SLAPI_DB2LDIF_DECRYPT, &decrypt ); > slapi_pblock_get( pb, SLAPI_DB2LDIF_SERVER_RUNNING, &server_running ); >- run_from_cmdline = (task_flags & TASK_RUNNING_FROM_COMMANDLINE); >+ run_from_cmdline = (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE); > > dump_replica = pb->pb_ldif_dump_replica; > if (run_from_cmdline) { >- li->li_flags |= TASK_RUNNING_FROM_COMMANDLINE; >+ li->li_flags |= SLAPI_TASK_RUNNING_FROM_COMMANDLINE; > if (!dump_replica) { > we_start_the_backends = 1; > } > } > >@@ -1296,16 +1296,16 @@ > } > > slapi_pblock_get(pb, SLAPI_BACKEND_INSTANCE_NAME, &instance_name); > slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &li); > slapi_pblock_get(pb, SLAPI_TASK_FLAGS, &task_flags); >- run_from_cmdline = (task_flags & TASK_RUNNING_FROM_COMMANDLINE); >+ run_from_cmdline = (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE); > slapi_pblock_get(pb, SLAPI_BACKEND_TASK, &task); > > if (run_from_cmdline) { > /* No ldbm backend exists until we process the config info. */ >- li->li_flags |= TASK_RUNNING_FROM_COMMANDLINE; >+ li->li_flags |= SLAPI_TASK_RUNNING_FROM_COMMANDLINE; > ldbm_config_load_dse_info(li); > txn.back_txn_txn = NULL; /* no transaction */ > } > > inst = ldbm_instance_find_by_name(li, instance_name); >@@ -1762,10 +1762,12 @@ > percent = (idindex*100 / (idl->b_nids ? idl->b_nids : 1)); > } else { > percent = (ep->ep_id*100 / (lastid ? lastid : 1)); > } > if (task) { >+ /* NGK - This should eventually be cleaned up to use the >+ * public task API */ > task->task_progress = (idl ? idindex : ep->ep_id); > task->task_work = (idl ? idl->b_nids : lastid); > slapi_task_status_changed(task); > slapi_task_log_status(task, "%s: Indexed %d entries (%d%%).", > inst->inst_name, count, percent); >@@ -1968,11 +1970,11 @@ > slapi_log_error(SLAPI_LOG_TRACE, "upgrade DB", "Reindexing all...\n"); > slapi_pblock_get(pb, SLAPI_TASK_FLAGS, &task_flags); > slapi_pblock_get(pb, SLAPI_BACKEND_TASK, &task); > slapi_pblock_get(pb, SLAPI_DB2LDIF_SERVER_RUNNING, &server_running); > >- run_from_cmdline = (task_flags & TASK_RUNNING_FROM_COMMANDLINE); >+ run_from_cmdline = (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE); > slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &li); > if (run_from_cmdline) > { > if (!(up_flags & SLAPI_UPGRADEDB_SKIPINIT)) > { >@@ -2433,11 +2435,11 @@ > backend *be = NULL; > int task_flags = 0; > int run_from_cmdline = 0; > > slapi_pblock_get(pb, SLAPI_TASK_FLAGS, &task_flags); >- run_from_cmdline = (task_flags & TASK_RUNNING_FROM_COMMANDLINE); >+ run_from_cmdline = (task_flags & SLAPI_TASK_RUNNING_FROM_COMMANDLINE); > > be = inst->inst_be; > slapi_log_error(SLAPI_LOG_FATAL, "upgrade DB", > "%s: Start upgradedb.\n", inst->inst_name); > >Index: ldap/servers/slapd/test-plugins/sampletask.c >=================================================================== >RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/test-plugins/sampletask.c,v >retrieving revision 1.2 >diff -u -5 -t -r1.2 sampletask.c >--- ldap/servers/slapd/test-plugins/sampletask.c 13 Aug 2007 15:35:35 -0000 1.2 >+++ ldap/servers/slapd/test-plugins/sampletask.c 31 Mar 2008 22:22:09 -0000 >@@ -45,41 +45,41 @@ > * dn: cn=sampletask,cn=plugins,cn=config > * objectClass: top > * objectClass: nsSlapdPlugin > * objectClass: extensibleObject > * cn: sampletask >- * nsslapd-pluginPath: <prefix>/usr/lib/<PACKAGE_NAME>/plugins/libsampletask-plugin.so >+ * nsslapd-pluginPath: libsampletask-plugin > * nsslapd-pluginInitfunc: sampletask_init > * nsslapd-pluginType: object > * nsslapd-pluginEnabled: on > * nsslapd-pluginId: sampletask > * nsslapd-pluginVersion: <plugin_version> > * nsslapd-pluginVendor: <vendor name> > * nsslapd-pluginDescription: Sample task plugin > * > * 4. create a config task entry in dse.ldif > * Task entry: >- * dn: cn=sample task, cn=tasks, cn=config >+ * dn: cn=sampletask, cn=tasks, cn=config > * objectClass: top > * objectClass: extensibleObject >- * cn: sample task >+ * cn: sampletask > * > * 5. to invoke the sample task, run the command line: > * $ ./ldapmodify -h <host> -p <port> -D "cn=Directory Manager" -w <pw> -a >- * dn: cn=sample task 0, cn=sample task, cn=tasks, cn=config >+ * dn: cn=sampletask 0, cn=sample task, cn=tasks, cn=config > * objectClass: top > * objectClass: extensibleObject > * cn: sample task 0 >- * arg0: sample task arg0 >+ * myarg: sample task myarg > * > * Result is in the errors log >- * [...] - Sample task starts (arg: sample task arg0) ... >+ * [...] - Sample task starts (arg: sample task myarg) ... > * [...] - Sample task finished. > */ > >-#include "slap.h" >-#include "slapi-private.h" >+#include "slapi-plugin.h" >+#include "nspr.h" > > static int task_sampletask_add(Slapi_PBlock *pb, Slapi_Entry *e, > Slapi_Entry *eAfter, int *returncode, char *returntext, > void *arg); > static int task_sampletask_start(Slapi_PBlock *pb); >@@ -116,37 +116,36 @@ > * Not necessary be a thread, but it'd not disturb the server's other jobs. > */ > static void > task_sampletask_thread(void *arg) > { >- Slapi_PBlock *pb = (Slapi_PBlock *)arg; >- Slapi_Task *task = pb->pb_task; >- int rv; >- >- task->task_work = 1; >- task->task_progress = 0; >- task->task_state = SLAPI_TASK_RUNNING; >- slapi_task_status_changed(task); >- >- slapi_task_log_notice(task, "Sample task starts (arg: %s) ...\n", >- pb->pb_seq_val); >- LDAPDebug(LDAP_DEBUG_ANY, "Sample task starts (arg: %s) ...\n", >- pb->pb_seq_val, 0, 0); >- /* do real work */ >- rv = 0; >+ Slapi_Task *task = (Slapi_Task *)arg; >+ char *myarg = NULL; >+ int i, rv = 0; >+ int total_work = 3; >+ >+ /* fetch our argument from the task */ >+ myarg = (char *)slapi_task_get_data(task); >+ >+ /* update task state to show it's running */ >+ slapi_task_begin(task, total_work); >+ slapi_task_log_notice(task, "Sample task starts (arg: %s) ...\n", myarg); >+ slapi_log_error(SLAPI_LOG_FATAL, "sampletask", "Sample task starts (arg: %s) ...\n", myarg); >+ >+ /* real work would be done here */ >+ for (i = 0; i < total_work; i++) { >+ PR_Sleep(10000); >+ slapi_task_inc_progress(task); >+ } > >+ /* update task state to say we're finished */ > slapi_task_log_notice(task, "Sample task finished."); > slapi_task_log_status(task, "Sample task finished."); >- LDAPDebug(LDAP_DEBUG_ANY, "Sample task finished.\n", 0, 0, 0); >- >- task->task_progress = 1; >- task->task_exitcode = rv; >- task->task_state = SLAPI_TASK_FINISHED; >- slapi_task_status_changed(task); >+ slapi_log_error(SLAPI_LOG_FATAL, "sampletask", "Sample task finished.\n"); > >- slapi_ch_free((void **)&pb->pb_seq_val); >- slapi_pblock_destroy(pb); >+ /* 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. >@@ -161,10 +160,21 @@ > return default_val; > slapi_attr_first_value(attr, &val); > return slapi_value_get_string(val); > } > >+static void >+task_sampletask_destructor(Slapi_Task *task) >+{ >+ if (task) { >+ char *myarg = (char *)slapi_task_get_data(task); >+ if (myarg) { >+ slapi_ch_free_string(&myarg); >+ } >+ } >+} >+ > /* > * 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. > */ >@@ -176,67 +186,54 @@ > PRThread *thread = NULL; > const char *cn; > int rv = SLAPI_DSE_CALLBACK_OK; > Slapi_PBlock *mypb = NULL; > Slapi_Task *task = NULL; >- const char *arg0; >+ const char *myarg; > > *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) */ >- if ((arg0 = fetch_attr(e, "arg0", NULL)) == NULL) { >+ if ((myarg = fetch_attr(e, "myarg", NULL)) == NULL) { > *returncode = LDAP_OBJECT_CLASS_VIOLATION; > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } > > /* allocate new task now */ > task = slapi_new_task(slapi_entry_get_ndn(e)); > if (task == NULL) { >- LDAPDebug(LDAP_DEBUG_ANY, "unable to allocate new task!\n", 0, 0, 0); >- *returncode = LDAP_OPERATIONS_ERROR; >- rv = SLAPI_DSE_CALLBACK_ERROR; >- goto out; >- } >- task->task_state = SLAPI_TASK_SETUP; >- task->task_work = 1; >- task->task_progress = 0; >- >- /* create a pblock to pass the necessary info to the task thread */ >- mypb = slapi_pblock_new(); >- if (mypb == NULL) { >+ slapi_log_error(SLAPI_LOG_FATAL, "sampletask", "unable to allocate new task!\n"); > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; > goto out; > } >- mypb->pb_seq_val = slapi_ch_strdup(arg0); >- mypb->pb_task = task; >- mypb->pb_task_flags = TASK_RUNNING_AS_TASK; >+ >+ /* set a destructor that will clean up myarg for us when the task is complete */ >+ slapi_task_set_destructor_fn(task, task_sampletask_destructor); >+ >+ /* Stash our argument in the task for use by the task thread */ >+ slapi_task_set_data(task, slapi_ch_strdup(myarg)); > > /* start the sample task as a separate thread */ > thread = PR_CreateThread(PR_USER_THREAD, task_sampletask_thread, >- (void *)mypb, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, >+ (void *)task, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, > PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); > if (thread == NULL) { >- LDAPDebug(LDAP_DEBUG_ANY, >- "unable to create sample task thread!\n", 0, 0, 0); >+ slapi_log_error(SLAPI_LOG_FATAL, "sampletask", >+ "unable to create sample task thread!\n"); > *returncode = LDAP_OPERATIONS_ERROR; > rv = SLAPI_DSE_CALLBACK_ERROR; >- slapi_ch_free((void **)&mypb->pb_seq_val); >- slapi_pblock_destroy(mypb); >- goto out; >+ slapi_task_finish(task, *returncode); >+ } else { >+ /* thread successful */ >+ rv = SLAPI_DSE_CALLBACK_OK; > } > >- /* thread successful -- don't free the pb, let the thread do that. */ >- return SLAPI_DSE_CALLBACK_OK; >- > out: >- if (task) { >- slapi_destroy_task(task); >- } > 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 439907
: 299782 |
300281