>From faf68949bba456988ec4aaa2715c8d9cd664f513 Mon Sep 17 00:00:00 2001 From: Nathan Kinder Date: Wed, 4 Nov 2009 14:39:44 -0800 Subject: [PATCH] Allow plugin execution order to be defined This patch adds support for assigning a precedence to each plugin. This precedence value is used to determine what order the plugins should be called in within a given plugin type. The precedence value is an integer between 1 and 99. The value is set in the nsslapd-pluginPrecedence attribute in a plugin config entry in "cn=config". If a plugin does not have a precedence value set, the plugin is treated as if it has a precedence of 50. For more details, see the feature design document at: http://directory.fedoraproject.org/wiki/Plugin_Ordering I also removed an incorrect log message in the linked attrs plugin that I noticed while debugging this patch. --- ldap/servers/plugins/linkedattrs/linked_attrs.c | 4 - ldap/servers/slapd/main.c | 1 + ldap/servers/slapd/plugin.c | 92 ++++++++++++++++++++++- ldap/servers/slapd/proto-slap.h | 1 + ldap/servers/slapd/slap.h | 15 +++- 5 files changed, 103 insertions(+), 10 deletions(-) diff --git a/ldap/servers/plugins/linkedattrs/linked_attrs.c b/ldap/servers/plugins/linkedattrs/linked_attrs.c index a04fbb0..edaf5db 100644 --- a/ldap/servers/plugins/linkedattrs/linked_attrs.c +++ b/ldap/servers/plugins/linkedattrs/linked_attrs.c @@ -1582,10 +1582,6 @@ linked_attrs_mod_post_op(Slapi_PBlock *pb) /* First check if the config is being modified. */ if (linked_attrs_dn_is_config(dn)) { linked_attrs_load_config(); - } else { - slapi_log_error(SLAPI_LOG_PLUGIN, LINK_PLUGIN_SUBSYSTEM, - "linked_attrs_mod_post_op: Error " - "retrieving dn\n"); } /* get the mod set */ diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c index 1d820f3..3cad84b 100644 --- a/ldap/servers/slapd/main.c +++ b/ldap/servers/slapd/main.c @@ -1134,6 +1134,7 @@ main( int argc, char **argv) */ task_cleanup(); + plugin_print_lists(); plugin_startall(argc, argv, 1 /* Start Backends */, 1 /* Start Globals */); if (housekeeping_start((time_t)0, NULL) == NULL) { return_value = 1; diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c index 75ec4f9..1664cc1 100644 --- a/ldap/servers/slapd/plugin.c +++ b/ldap/servers/slapd/plugin.c @@ -105,11 +105,43 @@ static void add_plugin_to_list(struct slapdplugin **list, struct slapdplugin *plugin) { struct slapdplugin **tmp; + struct slapdplugin *last = NULL; + int plugin_added = 0; + + /* Insert the plugin into list based off of precedence. */ for ( tmp = list; *tmp; tmp = &(*tmp)->plg_next ) { - ; /* NULL */ + if (plugin->plg_precedence < (*tmp)->plg_precedence) + { + if (last) + { + /* Insert item between last and tmp. */ + plugin->plg_next = *tmp; + last->plg_next = plugin; + } else { + /* Add as the first list item. */ + plugin->plg_next = *tmp; + *list = plugin; + } + + plugin_added = 1; + + /* We've added the plug-in to the + * list, so bail from the loop. */ + break; + } + + /* Save a pointer to this plugin so we can + * refer to it on the next loop iteration. */ + last = *tmp; + } + + /* If we didn't add the plug-in to the list yet, + * it needs to be added to the end of the list. */ + if (!plugin_added) + { + *tmp = plugin; } - *tmp = plugin; } struct slapdplugin * @@ -2024,6 +2056,37 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid *group, plugin->plg_name = value; /* plugin owns value's memory now, don't free */ } + if (!(value = slapi_entry_attr_get_charptr(plugin_entry, ATTR_PLUGIN_PRECEDENCE))) + { + /* A precedence isn't set, so just use the default. */ + plugin->plg_precedence = PLUGIN_DEFAULT_PRECEDENCE; + } + else + { + /* A precedence was set, so let's make sure it's valid. */ + int precedence = 0; + char *endptr = NULL; + + /* Convert the value. */ + precedence = strtol(value, &endptr, 10); + + /* Make sure the precedence is within our valid + * range and that we had no conversion errors. */ + if ((*value == '\0') || (*endptr != '\0') || + (precedence < PLUGIN_MIN_PRECEDENCE) || (precedence > PLUGIN_MAX_PRECEDENCE)) + { + LDAPDebug(LDAP_DEBUG_ANY, "Error: value for attribute %s must be " + "an integer between %d and %d\n", ATTR_PLUGIN_PRECEDENCE, + PLUGIN_MIN_PRECEDENCE, PLUGIN_MAX_PRECEDENCE); + status = -1; + goto PLUGIN_CLEANUP; + } + else + { + plugin->plg_precedence = precedence; + } + } + if (!(value = slapi_entry_attr_get_charptr(plugin_entry, ATTR_PLUGIN_INITFN))) { @@ -2797,6 +2860,31 @@ void plugin_print_versions(void) } /* + * Prints a list of plugins in execution order for each + * plug-in type. This will only be printed at the + * SLAPI_LOG_PLUGIN log level. + */ +void plugin_print_lists(void) +{ + int i; + struct slapdplugin *list = NULL; + struct slapdplugin *tmp = NULL; + + for (i = 0; i < PLUGIN_LIST_GLOBAL_MAX; i++) { + if (list = get_plugin_list(i)) + { + slapi_log_error(SLAPI_LOG_PLUGIN, NULL, + "---- Plugin List (type %d) ----\n", i); + for ( tmp = list; tmp; tmp = tmp->plg_next ) + { + slapi_log_error(SLAPI_LOG_PLUGIN, NULL, " %s (precedence: %d)\n", + tmp->plg_name, tmp->plg_precedence); + } + } + } +} + +/* * check the spedified plugin entry and its nssladp-pluginEnabled value * Return Value: 1 if the plugin is on. * : 0 otherwise. diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index b220bf0..feca39a 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -772,6 +772,7 @@ int plugin_add_descriptive_attributes( Slapi_Entry *e, void plugin_call_entryfetch_plugins(char **entrystr, uint *size); void plugin_call_entrystore_plugins(char **entrystr, uint *size); void plugin_print_versions(void); +void plugin_print_lists(void); /* * plugin_mr.c diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h index 76c8df2..35fc1f5 100644 --- a/ldap/servers/slapd/slap.h +++ b/ldap/servers/slapd/slap.h @@ -691,6 +691,12 @@ struct matchingRuleList { #define ATTR_PLUGIN_INVOKE_FOR_REPLOP "nsslapd-invokeForReplOp" #define ATTR_PLUGIN_LOAD_NOW "nsslapd-pluginLoadNow" #define ATTR_PLUGIN_LOAD_GLOBAL "nsslapd-pluginLoadGlobal" +#define ATTR_PLUGIN_PRECEDENCE "nsslapd-pluginPrecedence" + +/* plugin precedence defines */ +#define PLUGIN_DEFAULT_PRECEDENCE 50 +#define PLUGIN_MIN_PRECEDENCE 1 +#define PLUGIN_MAX_PRECEDENCE 99 /* plugin action states */ enum @@ -738,16 +744,17 @@ struct pluginconfig{ struct slapdplugin { void *plg_private; /* data private to plugin */ char *plg_version; /* version of this plugin */ - int plg_argc; /* argc from config file */ + int plg_argc; /* argc from config file */ char **plg_argv; /* args from config file */ char *plg_libpath; /* library path for dll/so */ - char *plg_initfunc; /* init symbol */ + char *plg_initfunc; /* init symbol */ IFP plg_close; /* close function */ Slapi_PluginDesc plg_desc; /* vendor's info */ - char *plg_name; /* used for plugin rdn in cn=config */ + char *plg_name; /* used for plugin rdn in cn=config */ struct slapdplugin *plg_next; /* for plugin lists */ int plg_type; /* discriminates union */ - char *plg_dn; /* config dn for this plugin */ + char *plg_dn; /* config dn for this plugin */ + int plg_precedence; /* for plugin execution ordering */ struct slapdplugin *plg_group; /* pointer to the group to which this plugin belongs */ struct pluginconfig plg_conf; /* plugin configuration parameters */ IFP plg_cleanup; /* cleanup function */ -- 1.6.2.5