diff options
| author | Dan Engelbrecht <[email protected]> | 2024-04-18 12:44:26 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2024-04-18 12:44:26 +0200 |
| commit | 6d634ab59c05adf1ba028d95b16031a7f8e8db2a (patch) | |
| tree | 87e8215fed65506f98f6838b2af08c4ffd5819f0 /src/zen/cmds/up_cmd.cpp | |
| parent | zen startup hardening (#49) (diff) | |
| download | archived-zen-6d634ab59c05adf1ba028d95b16031a7f8e8db2a.tar.xz archived-zen-6d634ab59c05adf1ba028d95b16031a7f8e8db2a.zip | |
improved lock file handling (#50)
- Feature: `zen down`
- --`data-dir` to specify a data directory to deduce which zen instance to bring down
- Feature: `zen attach`
- --`data-dir` to specify a data directory to deduce which zen instance to attach to222
- Feature: `zen status`
- --`port` filter running zen instances based on port
- --`data-dir` filter running zen instances based on information in the data directory
- Improvement: Trying to load a compact binary object from an empty file no longer causes access violation
Diffstat (limited to 'src/zen/cmds/up_cmd.cpp')
| -rw-r--r-- | src/zen/cmds/up_cmd.cpp | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/src/zen/cmds/up_cmd.cpp b/src/zen/cmds/up_cmd.cpp index 61a901fd6..3095211b6 100644 --- a/src/zen/cmds/up_cmd.cpp +++ b/src/zen/cmds/up_cmd.cpp @@ -2,7 +2,9 @@ #include "up_cmd.h" +#include <zencore/compactbinary.h> #include <zencore/filesystem.h> +#include <zencore/fmtutils.h> #include <zencore/logging.h> #include <zencore/process.h> #include <zencore/timer.h> @@ -48,10 +50,9 @@ UpCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) }; std::vector<EntryInfo> RunningEntries; State.Snapshot([&RunningEntries, DesiredPort = this->m_Port](const zen::ZenServerState::ZenServerEntry& Entry) { - uint32_t Pid = Entry.Pid.load(); - if (IsProcessRunning(Pid) && (DesiredPort == 0 || Entry.DesiredListenPort.load() == DesiredPort)) + if (DesiredPort == 0 || Entry.DesiredListenPort.load() == DesiredPort) { - RunningEntries.push_back(EntryInfo{.Pid = Pid, + RunningEntries.push_back(EntryInfo{.Pid = Entry.Pid.load(), .DesiredPort = Entry.DesiredListenPort.load(), .EffectivePort = Entry.EffectiveListenPort.load()}); } @@ -86,6 +87,7 @@ UpCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) if (!Server.WaitUntilReady(Timeout)) { ZEN_ERROR("zen server launch failed (timed out)"); + return 1; } else { @@ -101,6 +103,7 @@ AttachCommand::AttachCommand() { m_Options.add_option("", "p", "port", "Host port", cxxopts::value(m_Port)->default_value("8558"), "<hostport>"); m_Options.add_option("lifetime", "", "owner-pid", "Specify owning process id", cxxopts::value(m_OwnerPid), "<identifier>"); + m_Options.add_option("", "", "data-dir", "Path to data directory to inspect for running server", cxxopts::value(m_DataDir), "<file>"); } AttachCommand::~AttachCommand() = default; @@ -119,6 +122,24 @@ AttachCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) Instance.Initialize(); Instance.Sweep(); ZenServerState::ZenServerEntry* Entry = Instance.Lookup(m_Port); + + if (!m_DataDir.empty()) + { + if (!std::filesystem::is_regular_file(m_DataDir / ".lock")) + { + ZEN_CONSOLE("lock file does not exist in directory '{}'", m_DataDir); + return 1; + } + LockFileInfo Info = ReadLockFilePayload(LoadCompactBinaryObject(IoBufferBuilder::MakeFromFile(m_DataDir / ".lock"))); + std::string Reason; + if (!ValidateLockFileInfo(Info, Reason)) + { + ZEN_CONSOLE("lock file in directory '{}' is not valid. Reason: '{}'", m_DataDir, Reason); + return 1; + } + Entry = Instance.LookupByEffectivePort(Info.EffectiveListenPort); + } + if (!Entry) { ZEN_WARN("no zen server instance to add sponsor process to"); @@ -142,6 +163,7 @@ DownCommand::DownCommand() m_Options.add_option("", "p", "port", "Host port", cxxopts::value(m_Port)->default_value("0"), "<hostport>"); m_Options.add_option("", "f", "force", "Force terminate if graceful shutdown fails", cxxopts::value(m_ForceTerminate), "<force>"); m_Options.add_option("", "b", "base-dir", "Parent folder of server executable", cxxopts::value(m_ProgramBaseDir), "<directory>"); + m_Options.add_option("", "", "data-dir", "Path to data directory to inspect for running server", cxxopts::value(m_DataDir), "<file>"); } DownCommand::~DownCommand() = default; @@ -167,6 +189,23 @@ DownCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) m_ProgramBaseDir = ExePath.parent_path(); } + if (!m_DataDir.empty()) + { + if (!std::filesystem::is_regular_file(m_DataDir / ".lock")) + { + ZEN_CONSOLE("lock file does not exist in directory '{}'", m_DataDir); + return 1; + } + LockFileInfo Info = ReadLockFilePayload(LoadCompactBinaryObject(IoBufferBuilder::MakeFromFile(m_DataDir / ".lock"))); + std::string Reason; + if (!ValidateLockFileInfo(Info, Reason)) + { + ZEN_CONSOLE("lock file in directory '{}' is not valid. Reason: '{}'", m_DataDir, Reason); + return 1; + } + Entry = Instance.LookupByEffectivePort(Info.EffectiveListenPort); + } + if (Entry) { int EntryPort = (int)Entry->DesiredListenPort.load(); |