/src/trafficserver/include/proxy/http/remap/PluginFactory.h
Line | Count | Source |
1 | | /** @file |
2 | | |
3 | | Functionality allowing to load all plugins from a single config reload (header). |
4 | | |
5 | | @section license License |
6 | | |
7 | | Licensed to the Apache Software Foundation (ASF) under one |
8 | | or more contributor license agreements. See the NOTICE file |
9 | | distributed with this work for additional information |
10 | | regarding copyright ownership. The ASF licenses this file |
11 | | to you under the Apache License, Version 2.0 (the |
12 | | "License"); you may not use this file except in compliance |
13 | | with the License. You may obtain a copy of the License at |
14 | | |
15 | | http://www.apache.org/licenses/LICENSE-2.0 |
16 | | |
17 | | Unless required by applicable law or agreed to in writing, software |
18 | | distributed under the License is distributed on an "AS IS" BASIS, |
19 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
20 | | See the License for the specific language governing permissions and |
21 | | limitations under the License. |
22 | | */ |
23 | | |
24 | | #pragma once |
25 | | |
26 | | #include <vector> |
27 | | |
28 | | #include "swoc/IntrusiveDList.h" |
29 | | |
30 | | #include "tscore/Ptr.h" |
31 | | #include "proxy/http/remap/PluginDso.h" |
32 | | #include "proxy/http/remap/RemapPluginInfo.h" |
33 | | |
34 | | #include "tscore/ink_uuid.h" |
35 | | #include "ts/apidefs.h" |
36 | | |
37 | | /** |
38 | | * @brief Bundles plugin info + plugin instance data to be used always together. |
39 | | */ |
40 | | class RemapPluginInst |
41 | | { |
42 | | public: |
43 | | RemapPluginInst() = delete; |
44 | | RemapPluginInst(RemapPluginInst &) = delete; |
45 | | RemapPluginInst(RemapPluginInfo &plugin); |
46 | | ~RemapPluginInst(); |
47 | | |
48 | | /* Used by the PluginFactory */ |
49 | | static RemapPluginInst *init(RemapPluginInfo *plugin, int argc, char **argv, std::string &error); |
50 | | void done(); |
51 | | |
52 | | /* Used by the traffic server core while processing requests */ |
53 | | TSRemapStatus doRemap(TSHttpTxn rh, TSRemapRequestInfo *rri); |
54 | | void osResponse(TSHttpTxn rh, int os_response_type); |
55 | | |
56 | | /* List used by the plugin factory */ |
57 | | using self_type = RemapPluginInst; ///< Self reference type. |
58 | | self_type *_next = nullptr; |
59 | | self_type *_prev = nullptr; |
60 | | using Linkage = swoc::IntrusiveLinkage<self_type>; |
61 | | |
62 | | /* Plugin instance = the plugin info + the data returned by the init callback */ |
63 | | RemapPluginInfo &_plugin; |
64 | | void *_instance = nullptr; |
65 | | }; |
66 | | |
67 | | /** |
68 | | * @brief loads plugins, instantiates and keep track of plugin instances created by this factory. |
69 | | * |
70 | | * - Handles looking through search directories to determine final plugin canonical file name to be used (called here effective |
71 | | * path). |
72 | | * - Makes sure we load each DSO only once per effective path. |
73 | | * - Keeps track of all loaded remap plugins and their instances. |
74 | | * - Maitains the notion of plugin runtime paths and makes sure every factory instance uses different runtime paths for its plugins. |
75 | | * - Makes sure plugin DSOs are loaded for the lifetime of the PluginFactory. |
76 | | * |
77 | | * Each plugin factory instance corresponds to a config reload, each new config file set is meant to use a new factory instance. |
78 | | * A notion of runtime directory is maintained to make sure the DSO library files are not erased or modified while the library are |
79 | | * loaded in memory and make sure if the library file is overridden with a new DSO file that the new overriding plugin's |
80 | | * functionality will be loaded with the next factory, it also handles some problems noticed on different OSes in handling |
81 | | * filesystem links and different dl library implementations. |
82 | | * |
83 | | * @note This is meant to unify the way global and remap plugins are (re)loaded (global plugin support is not implemented yet). |
84 | | * @note In the case of a mixed plugin, getRemapPlugin/dynamicReloadEnabled can be internally overwritten if the plugin opt out to |
85 | | * take part in the dynamic reload process. |
86 | | */ |
87 | | class PluginFactory |
88 | | { |
89 | | using PluginInstList = swoc::IntrusiveDList<RemapPluginInst::Linkage>; |
90 | | |
91 | | public: |
92 | | PluginFactory(); |
93 | | virtual ~PluginFactory(); |
94 | | |
95 | | PluginFactory &setRuntimeDir(const fs::path &runtimeDir); |
96 | | PluginFactory &setCompilerPath(const fs::path &compilerPath); |
97 | | PluginFactory &addSearchDir(const fs::path &searchDir); |
98 | | |
99 | | RemapPluginInst *getRemapPlugin(const fs::path &configPath, int argc, char **argv, std::string &error, bool dynamicReloadEnabled); |
100 | | |
101 | | virtual const char *getUuid(); |
102 | | |
103 | | void deactivate(); |
104 | | void indicatePreReload(); |
105 | | void indicatePostReload(bool reloadSuccessful); |
106 | | void collectUsedPlugins(std::unordered_map<PluginDso *, int> &pluginUsed); |
107 | | |
108 | | static void cleanup(); // For startup, clean out all temporary directory we may have left from before |
109 | | |
110 | | protected: |
111 | | PluginDso *findByEffectivePath(const fs::path &path, bool dynamicReloadEnabled); |
112 | | fs::path getEffectivePath(const fs::path &configPath); |
113 | | |
114 | | std::vector<fs::path> _searchDirs; /** @brief ordered list of search paths where we look for plugins */ |
115 | | fs::path _runtimeDir; /** @brief the path where we would create a temporary copies of the plugins to load */ |
116 | | fs::path _compilerPath; /** @brief the compilation script to use for cripts and other non-DSO plugins */ |
117 | | |
118 | | PluginInstList _instList; |
119 | | |
120 | | ATSUuid *_uuid = nullptr; |
121 | | std::error_code _ec; |
122 | | |
123 | | static constexpr const char *const _tag = "plugin_factory"; /** @brief log tag used by this class */ |
124 | | static const DbgCtl &_dbg_ctl(); |
125 | | }; |
126 | | |
127 | | inline const DbgCtl & |
128 | | PluginFactory::_dbg_ctl() |
129 | 0 | { |
130 | 0 | static DbgCtl dc{_tag}; |
131 | |
|
132 | 0 | return dc; |
133 | 0 | } |