From 067883b778f3b1ee82a2c8fcf69648960b864aa3 Mon Sep 17 00:00:00 2001 From: Ravin Perera <33562092+ravinsp@users.noreply.github.com> Date: Tue, 9 Feb 2021 15:23:03 +0530 Subject: [PATCH] Support external hpfs process. (#239) --- src/conf.cpp | 23 ++++++++++++++++++++++- src/conf.hpp | 11 ++++++++--- src/hpfs/hpfs_mount.cpp | 19 +++++++++++++++---- src/hpfs/hpfs_mount.hpp | 5 +++-- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/conf.cpp b/src/conf.cpp index fe1b2faa..ce55a8ee 100644 --- a/src/conf.cpp +++ b/src/conf.cpp @@ -172,7 +172,7 @@ namespace conf const std::string tls_command = "openssl req -newkey rsa:2048 -new -nodes -x509 -days 365 -keyout " + ctx.config_dir + "/tlskey.pem" + " -out " + ctx.config_dir + "/tlscert.pem " + "-subj \"/C=HP/ST=HP/L=HP/O=HP/CN=" + cfg.node.public_key_hex + ".hotpocket.contract\" > /dev/null 2>&1"; - + // We don't mind if this command fails, because when running the contract we'll check and inform the user that // tls key files are missing, so they can create them manually. system(tls_command.c_str()); @@ -422,6 +422,20 @@ namespace conf } } + // hpfs + { + try + { + const jsoncons::ojson &hpfs = d["hpfs"]; + cfg.hpfs.external = hpfs["external"].as(); + } + catch (const std::exception &e) + { + std::cerr << "Required hpfs config field " << extract_missing_field(e.what()) << " missing at " << ctx.config_file << std::endl; + return -1; + } + } + // log { try @@ -518,6 +532,13 @@ namespace conf d.insert_or_assign("user", user_config); } + // hpfs configs + { + jsoncons::ojson hpfs_config; + hpfs_config.insert_or_assign("external", cfg.hpfs.external); + d.insert_or_assign("hpfs", hpfs_config); + } + // Log configs. { jsoncons::ojson log_config; diff --git a/src/conf.hpp b/src/conf.hpp index d92340e6..8c4cbebf 100644 --- a/src/conf.hpp +++ b/src/conf.hpp @@ -87,8 +87,8 @@ namespace conf struct contract_config { std::string id; // Contract guid. - bool execute; // Whether or not to execute the contract on the node. - bool log_output; // Whether to log stdout/err of the contract process. + bool execute = false; // Whether or not to execute the contract on the node. + bool log_output = false; // Whether to log stdout/err of the contract process. std::string version; // Contract version string. std::set unl; // Unique node list (list of binary public keys) std::string bin_path; // Full path to the contract binary @@ -138,6 +138,11 @@ namespace conf peer_discovery_config peer_discovery; // Peer discovery configs. }; + struct hpfs_config + { + bool external = false; // Whether to refrain from manageing built-in hpfs process or not. + }; + // Holds contextual information about the currently loaded contract. struct contract_ctx { @@ -169,12 +174,12 @@ namespace conf // Holds all the config values. struct hp_config { - // Config elements which are loaded from the config file. std::string hp_version; // Version of Hot Pocket that generated the config. node_config node; contract_config contract; mesh_config mesh; user_config user; + hpfs_config hpfs; log_config log; }; diff --git a/src/hpfs/hpfs_mount.cpp b/src/hpfs/hpfs_mount.cpp index 3e37595d..385b4b79 100644 --- a/src/hpfs/hpfs_mount.cpp +++ b/src/hpfs/hpfs_mount.cpp @@ -35,7 +35,7 @@ namespace hpfs if (prepare_fs() == -1) { - util::kill_process(hpfs_pid, true); + stop_hpfs_process(); return -1; } @@ -50,9 +50,7 @@ namespace hpfs { if (init_success) { - LOG_DEBUG << "Stopping hpfs process... pid:" << hpfs_pid; - if (hpfs_pid > 0 && util::kill_process(hpfs_pid, true) == 0) - LOG_INFO << "Stopped hpfs process."; + stop_hpfs_process(); } } @@ -70,6 +68,9 @@ namespace hpfs */ int hpfs_mount::start_hpfs_process() { + if (conf::cfg.hpfs.external) + return 0; + const pid_t pid = fork(); if (pid > 0) { @@ -148,6 +149,16 @@ namespace hpfs return 0; } + void hpfs_mount::stop_hpfs_process() + { + LOG_DEBUG << "Stopping hpfs process... pid:" << hpfs_pid; + if (!conf::cfg.hpfs.external && hpfs_pid > 0 && util::kill_process(hpfs_pid, true) == 0) + { + hpfs_pid = 0; + LOG_INFO << "Stopped hpfs process."; + } + } + /** * Starts a virtual fs ReadWrite session with hash map enabled. * If RW session already started, this will simply acquire a consumer reference. diff --git a/src/hpfs/hpfs_mount.hpp b/src/hpfs/hpfs_mount.hpp index a37e1b9c..e5ad642d 100644 --- a/src/hpfs/hpfs_mount.hpp +++ b/src/hpfs/hpfs_mount.hpp @@ -39,7 +39,7 @@ namespace hpfs private: pid_t hpfs_pid = 0; std::string fs_dir; - bool is_full_history; + bool is_full_history = false; bool init_success = false; // Keeps the hashes of hpfs parents against its vpath. std::unordered_map parent_hashes; @@ -48,6 +48,8 @@ namespace hpfs // We use this as a reference counting mechanism to cleanup RW session when no one requires it. uint32_t rw_consumers = 0; std::mutex rw_mutex; + int start_hpfs_process(); + void stop_hpfs_process(); protected: std::string mount_dir; @@ -59,7 +61,6 @@ namespace hpfs int init(const uint32_t mount_id, std::string_view fs_dir, std::string_view mount_dir, std::string_view rw_dir, const bool is_full_history); void deinit(); - int start_hpfs_process(); int acquire_rw_session(); int release_rw_session(); int start_ro_session(const std::string &name, const bool hmap_enabled);