| /** @file |
| |
| Functionality allowing to load all plugins from a single config reload (header). |
| |
| @section license License |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include <vector> |
| |
| #include "tscore/Ptr.h" |
| #include "PluginDso.h" |
| #include "RemapPluginInfo.h" |
| |
| #include "tscore/Ptr.h" |
| #include "tscpp/util/IntrusiveDList.h" |
| |
| #include "tscore/ink_uuid.h" |
| #include "ts/apidefs.h" |
| |
| /** |
| * @brief Bundles plugin info + plugin instance data to be used always together. |
| */ |
| class RemapPluginInst |
| { |
| public: |
| RemapPluginInst() = delete; |
| RemapPluginInst(RemapPluginInst &) = delete; |
| RemapPluginInst(RemapPluginInfo &plugin); |
| ~RemapPluginInst(); |
| |
| /* Used by the PluginFactory */ |
| static RemapPluginInst *init(RemapPluginInfo *plugin, int argc, char **argv, std::string &error); |
| void done(); |
| |
| /* Used by the traffic server core while processing requests */ |
| TSRemapStatus doRemap(TSHttpTxn rh, TSRemapRequestInfo *rri); |
| void osResponse(TSHttpTxn rh, int os_response_type); |
| |
| /* List used by the plugin factory */ |
| using self_type = RemapPluginInst; ///< Self reference type. |
| self_type *_next = nullptr; |
| self_type *_prev = nullptr; |
| using Linkage = ts::IntrusiveLinkage<self_type>; |
| |
| /* Plugin instance = the plugin info + the data returned by the init callback */ |
| RemapPluginInfo &_plugin; |
| void *_instance = nullptr; |
| }; |
| |
| /** |
| * @brief loads plugins, instantiates and keep track of plugin instances created by this factory. |
| * |
| * - Handles looking through search directories to determine final plugin canonical file name to be used (called here effective |
| * path). |
| * - Makes sure we load each DSO only once per effective path. |
| * - Keeps track of all loaded remap plugins and their instances. |
| * - Maitains the notion of plugin runtime paths and makes sure every factory instance uses different runtime paths for its plugins. |
| * - Makes sure plugin DSOs are loaded for the lifetime of the PluginFactory. |
| * |
| * Each plugin factory instance corresponds to a config reload, each new config file set is meant to use a new factory instance. |
| * A notion of runtime directory is maintained to make sure the DSO library files are not erased or modified while the library are |
| * loaded in memory and make sure if the library file is overriden with a new DSO file that the new overriding plugin's |
| * functionality will be loaded with the next factory, it also handles some problems noticed on different OSes in handling |
| * filesystem links and different dl library implementations. |
| * |
| * @note This is meant to unify the way global and remap plugins are (re)loaded (global plugin support is not implemented yet). |
| */ |
| class PluginFactory |
| { |
| using PluginInstList = ts::IntrusiveDList<RemapPluginInst::Linkage>; |
| PluginDso::PluginList &_list = PluginDso::_list; |
| |
| public: |
| PluginFactory(); |
| virtual ~PluginFactory(); |
| |
| PluginFactory &setRuntimeDir(const fs::path &runtimeDir); |
| PluginFactory &addSearchDir(const fs::path &searchDir); |
| |
| RemapPluginInst *getRemapPlugin(const fs::path &configPath, int argc, char **argv, std::string &error); |
| |
| virtual const char *getUuid(); |
| void clean(std::string &error); |
| |
| void deactivate(); |
| void indicatePreReload(); |
| void indicatePostReload(bool reloadSuccessful); |
| |
| protected: |
| PluginDso *findByEffectivePath(const fs::path &path); |
| fs::path getEffectivePath(const fs::path &configPath); |
| |
| std::vector<fs::path> _searchDirs; /** @brief ordered list of search paths where we look for plugins */ |
| fs::path _runtimeDir; /** @brief the path where we would create a temporary copies of the plugins to load */ |
| |
| PluginInstList _instList; |
| |
| ATSUuid *_uuid = nullptr; |
| std::error_code _ec; |
| bool _preventiveCleaning = true; |
| |
| static constexpr const char *const _tag = "plugin_factory"; /** @brief log tag used by this class */ |
| }; |