Skip to content

Commit 5f568cd

Browse files
committed
Defer deletion of reloadable remap plugins
1 parent 93b0e22 commit 5f568cd

File tree

8 files changed

+39
-32
lines changed

8 files changed

+39
-32
lines changed

cmake/layout.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ set(CMAKE_INSTALL_LOCALSTATEDIR
4343
CACHE STRING "localstatedir"
4444
)
4545
set(CMAKE_INSTALL_RUNSTATEDIR
46-
"${CMAKE_INSTALL_LOCALSTATEDIR}/trafficserver"
46+
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LOCALSTATEDIR}/trafficserver"
4747
CACHE STRING "runstatedir"
4848
)
4949
set(CMAKE_INSTALL_DATAROOTDIR

include/proxy/http/remap/PluginDso.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,8 @@ class PluginDso : public PluginThreadContext
170170
static constexpr const char *const _tag = "plugin_dso"; /** @brief log tag used by this class */
171171
static const DbgCtl &_dbg_ctl();
172172
swoc::file::file_time_type _mtime{fs::file_time_type::min()}; /* @brief modification time of the DSO's file, used for checking */
173-
bool _preventiveCleaning = true;
174-
175-
static Ptr<LoadedPlugins>
176-
_plugins; /** @brief a global list of plugins, usually maintained by a plugin factory or plugin instance itself */
177-
std::atomic<int> _instanceCount{
178-
0}; /** @brief used for properly calling "done" and "indicate config reload" methods by the factory */
173+
static Ptr<LoadedPlugins> _plugins; /** @brief a global list of plugins */
174+
std::atomic<int> _instanceCount{0}; /** @brief used for properly calling "done" and "indicate config reload" */
179175
};
180176

181177
inline const DbgCtl &

include/proxy/http/remap/PluginFactory.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,13 @@ class PluginFactory
9999
RemapPluginInst *getRemapPlugin(const fs::path &configPath, int argc, char **argv, std::string &error, bool dynamicReloadEnabled);
100100

101101
virtual const char *getUuid();
102-
void clean(std::string &error);
103102

104103
void deactivate();
105104
void indicatePreReload();
106105
void indicatePostReload(bool reloadSuccessful);
107106

107+
static void cleanup(); // For startup, clean out all temporary directory we may have left from before
108+
108109
protected:
109110
PluginDso *findByEffectivePath(const fs::path &path, bool dynamicReloadEnabled);
110111
fs::path getEffectivePath(const fs::path &configPath);
@@ -117,7 +118,6 @@ class PluginFactory
117118

118119
ATSUuid *_uuid = nullptr;
119120
std::error_code _ec;
120-
bool _preventiveCleaning = true;
121121

122122
static constexpr const char *const _tag = "plugin_factory"; /** @brief log tag used by this class */
123123
static const DbgCtl &_dbg_ctl();

src/proxy/http/remap/PluginDso.cc

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ PluginDso::PluginDso(const fs::path &configPath, const fs::path &effectivePath,
6868
PluginDso::~PluginDso()
6969
{
7070
std::string error;
71+
7172
(void)unload(error);
7273
}
7374

@@ -136,11 +137,6 @@ PluginDso::load(std::string &error, const fs::path &compilerPath)
136137
PluginError("plugin '%s' failed to load: %s", _configPath.c_str(), error.c_str());
137138
}
138139
}
139-
140-
/* Remove the runtime DSO copy even if we succeed loading to avoid leftovers after crashes */
141-
if (_preventiveCleaning) {
142-
clean(error);
143-
}
144140
}
145141
PluginDbg(_dbg_ctl(), "plugin '%s' finished loading DSO", _configPath.c_str());
146142

src/proxy/http/remap/PluginFactory.cc

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "../../../iocore/eventsystem/P_EventSystem.h"
3737

3838
#include <algorithm> /* std::swap */
39+
#include <filesystem>
3940

4041
RemapPluginInst::RemapPluginInst(RemapPluginInfo &plugin) : _plugin(plugin)
4142
{
@@ -102,7 +103,14 @@ PluginFactory::~PluginFactory()
102103
_instList.apply([](RemapPluginInst *pluginInst) -> void { delete pluginInst; });
103104
_instList.clear();
104105

105-
fs::remove_all(_runtimeDir, _ec);
106+
{
107+
uint32_t elevate_access = 0;
108+
109+
REC_ReadConfigInteger(elevate_access, "proxy.config.plugin.load_elevated");
110+
ElevateAccess access(elevate_access ? ElevateAccess::FILE_PRIVILEGE : 0);
111+
112+
fs::remove_all(_runtimeDir, _ec);
113+
}
106114

107115
PluginDbg(_dbg_ctl(), "destroyed plugin factory %s", getUuid());
108116
delete _uuid;
@@ -226,9 +234,6 @@ PluginFactory::getRemapPlugin(const fs::path &configPath, int argc, char **argv,
226234
delete plugin;
227235
}
228236

229-
if (dynamicReloadEnabled && _preventiveCleaning) {
230-
clean(error);
231-
}
232237
} else {
233238
/* Plugin DSO load failed. */
234239
PluginDbg(_dbg_ctl(), "plugin '%s' DSO load failed", configPath.c_str());
@@ -276,6 +281,26 @@ PluginFactory::getEffectivePath(const fs::path &configPath)
276281
return path;
277282
}
278283

284+
void
285+
PluginFactory::cleanup()
286+
{
287+
std::error_code ec;
288+
auto path = RecConfigReadRuntimeDir();
289+
290+
if (path.starts_with("/") && std::filesystem::is_directory(path)) {
291+
for (const auto &entry : std::filesystem::directory_iterator(path, ec)) {
292+
if (entry.is_directory()) {
293+
std::string dir_name = entry.path().string();
294+
int dash_count = std::count(dir_name.begin(), dir_name.end(), '-'); // All UUIDs have 4 dashes
295+
296+
if (dash_count == 4) {
297+
std::filesystem::remove_all(dir_name, ec);
298+
}
299+
}
300+
}
301+
}
302+
}
303+
279304
/**
280305
* @brief Find a plugin by path from our linked plugin list by using plugin effective (canonical) path
281306
*
@@ -326,9 +351,3 @@ PluginFactory::indicatePostReload(bool reloadSuccessful)
326351

327352
PluginDso::loadedPlugins()->indicatePostReload(reloadSuccessful, pluginUsed, getUuid());
328353
}
329-
330-
void
331-
PluginFactory::clean(std::string & /* error ATS_UNUSED */)
332-
{
333-
fs::remove_all(_runtimeDir, _ec);
334-
}

src/proxy/http/remap/unit-tests/test_PluginDso.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ class PluginDsoUnitTest : public PluginDso
6666
PluginDsoUnitTest(const fs::path &configPath, const fs::path &effectivePath, const fs::path &runtimePath)
6767
: PluginDso(configPath, effectivePath, runtimePath)
6868
{
69-
/* don't remove runtime DSO copy preventively so we can check if it was created properly */
70-
_preventiveCleaning = false;
7169
}
7270

7371
virtual void

src/proxy/http/remap/unit-tests/test_PluginFactory.cc

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,7 @@ static fs::path tempComponent = fs::path("c71e2bab-90dc-4770-9535-c9304c3de38e")
6868
class PluginFactoryUnitTest : public PluginFactory
6969
{
7070
public:
71-
PluginFactoryUnitTest(const fs::path &tempComponent)
72-
{
73-
_tempComponent = tempComponent;
74-
_preventiveCleaning = false;
75-
}
71+
PluginFactoryUnitTest(const fs::path &tempComponent) { _tempComponent = tempComponent; }
7672

7773
protected:
7874
const char *

src/traffic_server/traffic_server.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1767,7 +1767,6 @@ configure_io_uring()
17671767
//
17681768
// Main
17691769
//
1770-
17711770
int
17721771
main(int /* argc ATS_UNUSED */, const char **argv)
17731772
{
@@ -1907,6 +1906,9 @@ main(int /* argc ATS_UNUSED */, const char **argv)
19071906
signal_register_crash_handler(crash_logger_invoke);
19081907
}
19091908

1909+
// Clean out any remnant temporary plugin (UUID named) directories.
1910+
PluginFactory::cleanup();
1911+
19101912
#if TS_USE_POSIX_CAP
19111913
// Change the user of the process.
19121914
// Do this before we start threads so we control the user id of the

0 commit comments

Comments
 (0)