mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 16:57:49 +03:00
11e1432ff8
Summary: Update the EdenFS monitor to restart itself when it receives SIGHUP. This allows upgrading the monitor daemon to a new version of the software without disrupting the current running EdenFS daemon. Reviewed By: wez Differential Revision: D19588698 fbshipit-source-id: f0303788cee0cc9bf4ce3b7342f10a595c3874b1
143 lines
3.4 KiB
C++
143 lines
3.4 KiB
C++
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This software may be used and distributed according to the terms of the
|
|
* GNU General Public License version 2.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <sys/types.h>
|
|
#include <array>
|
|
#include <chrono>
|
|
#include <cstddef>
|
|
#include <memory>
|
|
|
|
#include <folly/File.h>
|
|
#include <folly/Portability.h>
|
|
#include <folly/Subprocess.h>
|
|
#include <folly/io/async/AsyncTimeout.h>
|
|
#include <folly/io/async/EventHandler.h>
|
|
|
|
#include "eden/fs/utils/PathFuncs.h"
|
|
|
|
namespace folly {
|
|
class EventBase;
|
|
template <typename T>
|
|
class Future;
|
|
struct Unit;
|
|
} // namespace folly
|
|
|
|
namespace facebook {
|
|
namespace eden {
|
|
|
|
class EdenMonitor;
|
|
class LogFile;
|
|
|
|
/**
|
|
* EdenInstance represents a single instance of the edenfs process.
|
|
*
|
|
* It exists to manage the process and inform the EdenMonitor when the edenfs
|
|
* process exits.
|
|
*/
|
|
class EdenInstance {
|
|
public:
|
|
explicit EdenInstance(EdenMonitor* monitor);
|
|
virtual ~EdenInstance();
|
|
|
|
FOLLY_NODISCARD virtual folly::Future<folly::Unit> start() = 0;
|
|
virtual pid_t getPid() const = 0;
|
|
virtual void checkLiveness() = 0;
|
|
|
|
protected:
|
|
EdenInstance(EdenInstance const&) = delete;
|
|
EdenInstance& operator=(EdenInstance const&) = delete;
|
|
|
|
/*
|
|
* We store a raw pointer to the EdenMonitor.
|
|
* The EdenMonitor owns us, and will destroy us before it is destroyed.
|
|
*/
|
|
EdenMonitor* const monitor_;
|
|
};
|
|
|
|
/**
|
|
* ExistingEdenInstance tracks an edenfs process that was not started by this
|
|
* process.
|
|
*/
|
|
class ExistingEdenInstance : public EdenInstance, private folly::AsyncTimeout {
|
|
public:
|
|
ExistingEdenInstance(EdenMonitor* monitor, pid_t pid);
|
|
|
|
FOLLY_NODISCARD folly::Future<folly::Unit> start() override;
|
|
|
|
pid_t getPid() const override {
|
|
return pid_;
|
|
}
|
|
|
|
void checkLiveness() override;
|
|
|
|
private:
|
|
void timeoutExpired() noexcept override;
|
|
bool isAlive();
|
|
|
|
pid_t pid_{0};
|
|
std::chrono::milliseconds pollInterval_{60000};
|
|
};
|
|
|
|
/**
|
|
* SpawnedEdenInstance tracks an edenfs process that was spawned directly by
|
|
* this process.
|
|
*
|
|
* It reads stdout and stderr output from EdenFS and writes them to a log file,
|
|
* performing log rotation as necessary.
|
|
*/
|
|
class SpawnedEdenInstance : public EdenInstance,
|
|
private folly::EventHandler,
|
|
private folly::AsyncTimeout {
|
|
public:
|
|
SpawnedEdenInstance(EdenMonitor* monitor, std::shared_ptr<LogFile> log);
|
|
~SpawnedEdenInstance() override;
|
|
|
|
FOLLY_NODISCARD folly::Future<folly::Unit> start() override;
|
|
|
|
void takeover(pid_t pid, int logFD);
|
|
|
|
pid_t getPid() const override {
|
|
return pid_;
|
|
}
|
|
|
|
int getLogPipeFD() const {
|
|
return logPipe_.fd();
|
|
}
|
|
|
|
void checkLiveness() override;
|
|
|
|
private:
|
|
static constexpr size_t kLogBufferSize = 64 * 1024;
|
|
|
|
class StartupStatusChecker;
|
|
|
|
void handlerReady(uint16_t events) noexcept override;
|
|
void timeoutExpired() noexcept override;
|
|
|
|
void beginProcessingLogPipe();
|
|
void forwardLogOutput();
|
|
void closeLogPipe();
|
|
void checkLivenessImpl();
|
|
|
|
std::string edenfsExe_;
|
|
folly::Subprocess cmd_;
|
|
pid_t pid_{0};
|
|
folly::File logPipe_;
|
|
std::shared_ptr<LogFile> log_;
|
|
std::unique_ptr<StartupStatusChecker> startupChecker_;
|
|
|
|
// EdenInstance objects are always allocated on the heap, so we just
|
|
// keep the log buffer in an inline array, rather than in a separately
|
|
// allocated buffer.
|
|
std::array<std::byte, kLogBufferSize> logBuffer_{};
|
|
};
|
|
|
|
} // namespace eden
|
|
} // namespace facebook
|