From e07122436c5ad5135f9d62d8f07b26fbe82df6b1 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 20 Jun 2012 11:34:46 +0200 Subject: Make sure that all features of critical plugins are loaded --- src/libstrongswan/plugins/plugin_loader.c | 69 ++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index aabeb1f86..d4c92468a 100644 --- a/src/libstrongswan/plugins/plugin_loader.c +++ b/src/libstrongswan/plugins/plugin_loader.c @@ -68,6 +68,11 @@ struct plugin_entry_t { */ plugin_t *plugin; + /** + * TRUE, if the plugin is marked as critical + */ + bool critical; + /** * dlopen handle, if in separate lib */ @@ -113,7 +118,8 @@ static bool plugin_feature_equals(plugin_feature_t *a, plugin_feature_t *b) * FAILED, if the plugin could not be constructed */ static status_t create_plugin(private_plugin_loader_t *this, void *handle, - char *name, bool integrity, plugin_entry_t **entry) + char *name, bool integrity, bool critical, + plugin_entry_t **entry) { char create[128]; plugin_t *plugin; @@ -149,6 +155,7 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle, } INIT(*entry, .plugin = plugin, + .critical = critical, .loaded = linked_list_create(), .failed = linked_list_create(), ); @@ -159,12 +166,13 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle, /** * load a single plugin */ -static bool load_plugin(private_plugin_loader_t *this, char *name, char *file) +static bool load_plugin(private_plugin_loader_t *this, char *name, char *file, + bool critical) { plugin_entry_t *entry; void *handle; - switch (create_plugin(this, RTLD_DEFAULT, name, FALSE, &entry)) + switch (create_plugin(this, RTLD_DEFAULT, name, FALSE, critical, &entry)) { case SUCCESS: this->plugins->insert_last(this->plugins, entry); @@ -190,7 +198,7 @@ static bool load_plugin(private_plugin_loader_t *this, char *name, char *file) DBG1(DBG_LIB, "plugin '%s' failed to load: %s", name, dlerror()); return FALSE; } - if (create_plugin(this, handle, name, TRUE, &entry) != SUCCESS) + if (create_plugin(this, handle, name, TRUE, critical, &entry) != SUCCESS) { dlclose(handle); return FALSE; @@ -473,6 +481,55 @@ static int unload_features(private_plugin_loader_t *this, plugin_entry_t *entry) return unloaded; } +/** + * Check that we have all features loaded for critical plugins + */ +static bool missing_critical_features(private_plugin_loader_t *this) +{ + enumerator_t *enumerator; + plugin_entry_t *entry; + bool critical_failed = FALSE; + + enumerator = this->plugins->create_enumerator(this->plugins); + while (enumerator->enumerate(enumerator, &entry)) + { + if (!entry->plugin->get_features) + { /* feature interface not supported */ + continue; + } + if (entry->critical) + { + plugin_feature_t *feature; + char *name, *provide; + int count, i, failed = 0; + + name = entry->plugin->get_name(entry->plugin); + count = entry->plugin->get_features(entry->plugin, &feature); + for (i = 0; i < count; i++, feature++) + { + if (feature->kind == FEATURE_PROVIDE && + !feature_loaded(this, entry, feature)) + { + provide = plugin_feature_get_string(feature); + DBG2(DBG_LIB, " failed to load %s in critical plugin '%s'", + provide, name); + free(provide); + failed++; + } + } + if (failed) + { + DBG1(DBG_LIB, "failed to load %d feature%s in critical plugin " + "'%s'", failed, failed > 1 ? "s" : "", name); + critical_failed = TRUE; + } + } + } + enumerator->destroy(enumerator); + + return critical_failed; +} + /** * Remove plugins that we were not able to load any features from. */ @@ -533,7 +590,7 @@ METHOD(plugin_loader_t, load_plugins, bool, { return FALSE; } - if (!load_plugin(this, token, file) && critical) + if (!load_plugin(this, token, file, critical) && critical) { critical_failed = TRUE; DBG1(DBG_LIB, "loading critical plugin '%s' failed", token); @@ -556,6 +613,8 @@ METHOD(plugin_loader_t, load_plugins, bool, } /* report missing dependencies */ load_features(this, FALSE, TRUE); + /* check for unloaded features provided by critical plugins */ + critical_failed = missing_critical_features(this); /* unload plugins that we were not able to load any features for */ purge_plugins(this); } -- cgit v1.2.3