aboutsummaryrefslogtreecommitdiff
path: root/src/zen/cmds/up_cmd.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-04-18 12:44:26 +0200
committerGitHub Enterprise <[email protected]>2024-04-18 12:44:26 +0200
commit6d634ab59c05adf1ba028d95b16031a7f8e8db2a (patch)
tree87e8215fed65506f98f6838b2af08c4ffd5819f0 /src/zen/cmds/up_cmd.cpp
parentzen startup hardening (#49) (diff)
downloadarchived-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.cpp45
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();