In 389-ds-base 1.3.3 there is now support to add/delete/restart/configure/etc the plugins without restarting the 389 server.
In order to implement the new dynamic design there are a few changes/conditions that need to be met:
[1] Plugins should now have a close function (SLAPI_PLUGIN_CLOSE_FN)
[2] slap_config_register_callbacks, need to be unregistered in the close function via slapi_config_unregister_callback().
The callback registration also needs to pass in the Slapi_PBlock as the function argument when registering callbacks. Note - callbacks should be registered in the start or init function of a plugin(that have access to the pblock) A new flag must also be used when registering a callback from a plugin: DSE_FLAG_PLUGIN Example:
slapi_config_register_callback(SLAPI_OPERATION_MODIFY, DSE_FLAG_PREOP | DSE_FLAG_PLUGIN , config_dn, LDAP_SCOPE_BASE, MEMBEROF_CONFIG_FILTER, memberof_validate_config, pb);
- Note the new flag, and the pblock being passed in. So functions like: ipa_winsync_config(...), will need to be modified so the Slapi_PBlock is passed in from the start function(ipa_winsync_plugin_start(Slapi_PBlock *pb)).
[3] Slapi tasks should now be created using: slapi_plugin_new_task(), instead of slapi_new_task().
The new task and callback register changes are part of a new internal operation reference counter, that will prevent a plugin from being closed/stopped while operations/tasks are using the plugin.
The work being done on 389 can be found at: https://fedorahosted.org/389/ticket/47451
Please let me know if there are any questions about this new behavior/design.
Forgot a few things, any registered object extensions:
int slapi_register_object_extension( const char* pluginname, const char* objectname, slapi_extension_constructor_fnptr constructor, slapi_extension_destructor_fnptr destructor, int *objecttype, int *extensionhandle)
must also be unregistered in the CLOSE function using:
int slapi_unregister_object_extension( const char* pluginname, const char* objectname, int *objecttype, int *extensionhandle)
Example from content synchronization plugin:
int sync_register_operation_extension(void) { return slapi_register_object_extension(SYNC_PLUGIN_SUBSYSTEM, SLAPI_EXT_OPERATION, sync_operation_extension_ctor, sync_operation_extension_dtor, &sync_extension_type, &sync_extension_handle); } int sync_unregister_operation_entension(void) { int rc = slapi_unregister_object_extension(SYNC_PLUGIN_SUBSYSTEM, SLAPI_EXT_OPERATION, &sync_extension_type, &sync_extension_handle); return rc; }
Also, when registering a task handler, replace slapi_task_register_handler() with:
int slapi_plugin_task_register_handler(const char *name, dseCallbackFn func, Slapi_PBlock *plugin_pb)
The only change is passing in the PBlock.
Metadata Update from @mreynolds: - Issue assigned to someone - Issue set to the milestone: Future Releases