/** * Add a plugin that can be loaded, meets all * constraints. * * @note that this does not mean that the backend * validates after it is added. It only means that * the situation is not getting worse. * * @throw PluginCheckException or its subclasses if it was not possible * to load the plugin * * For validation @see validated(). */ void Backend::addPlugin (PluginSpec const & plugin) { KeySet fullPluginConfig = plugin.getConfig (); fullPluginConfig.append (plugin.getConfig ()); // add previous configs tryPlugin (plugin); errorplugins.addPlugin (*plugins.back ()); getplugins.addPlugin (*plugins.back ()); setplugins.addPlugin (*plugins.back ()); KeySet toAdd = plugins.back ()->getNeededConfig (); config.append (toAdd); }
PluginDatabase::func_t ModulesPluginDatabase::getSymbol (PluginSpec const & spec, std::string const & which) const { try { PluginPtr plugin = impl->modules.load (spec.getName (), spec.getConfig ()); return plugin->getSymbol (which); } catch (...) { return NULL; } }
std::string ModulesPluginDatabase::lookupInfo (PluginSpec const & spec, std::string const & which) const { PluginPtr plugin; try { plugin = impl->modules.load (spec.getName (), spec.getConfig ()); } catch (...) { throw; } return plugin->lookupInfo (which); }
PluginDatabase::Status ModulesPluginDatabase::status (PluginSpec const & spec) const { PluginPtr plugin; try { KeySet conf = spec.getConfig (); conf.append (Key ("system/module", KEY_VALUE, "this plugin was loaded for the status", KEY_END)); plugin = impl->modules.load (spec.getName (), conf); return real; } catch (...) { if (hasProvides (*this, spec.getName ())) { return provides; } else { return missing; } } }
/** * @brief Add a plugin. * * @pre Needs to be a unique new name (use refname if you want to add the same module multiple times) * * Will automatically resolve virtual plugins to actual plugins. * * Also calls the checkconf function if provided by the plugin. The checkconf function has the * following signature: int checkconf (Key * errorKey, KeySet * config) and allows a plugin to * verify its configuration at mount time. * * @see resolveNeeds() * @param plugin */ void BackendBuilder::addPlugin (PluginSpec const & plugin) { typedef int (*checkConfPtr) (ckdb::Key *, ckdb::KeySet *); for (auto & p : toAdd) { if (p.getFullName () == plugin.getFullName ()) { throw PluginAlreadyInserted (plugin.getFullName ()); } } PluginSpec newPlugin = plugin; // if the plugin is actually a provider use it (otherwise we will get our name back): PluginSpec provides = pluginDatabase->lookupProvides (plugin.getName ()); if (provides.getName () != newPlugin.getName ()) { // keep our config and refname newPlugin.setName (provides.getName ()); newPlugin.appendConfig (provides.getConfig ()); } // call plugin's checkconf function (if provided) // this enables a plugin to verify its configuration at mount time checkConfPtr checkConfFunction = reinterpret_cast<checkConfPtr> (pluginDatabase->getSymbol (newPlugin, "checkconf")); if (checkConfFunction) { ckdb::Key * errorKey = ckdb::keyNew (0); // merge plugin config and backend config together ckdb::KeySet * pluginConfig = newPlugin.getConfig ().dup (); ckdb::ksAppend (pluginConfig, backendConf.getKeySet ()); // call the plugin's checkconf function int checkResult = checkConfFunction (errorKey, pluginConfig); if (checkResult == -1) { ckdb::ksDel (pluginConfig); throw PluginConfigInvalid (errorKey); } else if (checkResult == 1) { // separate plugin config from the backend config ckdb::Key * backendParent = ckdb::keyNew ("system/", KEY_END); ckdb::KeySet * newBackendConfig = ckdb::ksCut (pluginConfig, backendParent); // take over the new configuration KeySet modifiedPluginConfig = KeySet (pluginConfig); KeySet modifiedBackendConfig = KeySet (newBackendConfig); newPlugin.setConfig (modifiedPluginConfig); setBackendConfig (modifiedBackendConfig); ckdb::keyDel (backendParent); } else { ckdb::ksDel (pluginConfig); } ckdb::keyDel (errorKey); } toAdd.push_back (newPlugin); sort (); }