#4199 [RFE] IPA plugins need to handle the new dynamic restart functionality in DS
Opened by mreynolds. Modified

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)

  • This is used to reset/free global resources: locks, config settings, etc. The idea is to prevent memory leaks, crashes, unexpected behavior(creating a lock twice, etc). I know some IPA plugins are using global structures, etc, so these should be freed/reset in the close function.

[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

Metadata