FlatImage
A configurable Linux containerization system
Loading...
Searching...
No Matches
janitor.cpp
Go to the documentation of this file.
1
9
10
11#include <chrono>
12#include <cstdlib>
13#include <thread>
14#include <filesystem>
15#include <csignal>
16
17#include "../std/expected.hpp"
18#include "../lib/log.hpp"
19#include "../lib/fuse.hpp"
20#include "../macro.hpp"
21
22// https://stackoverflow.com/questions/24931456/how-does-sig-atomic-t-actually-work
23// https://en.cppreference.com/w/cpp/utility/program/sig_atomic_t.html
24// https://man7.org/linux/man-pages/man7/signal-safety.7.html
25// https://www.cs.wm.edu/~smherwig/courses/csci415-common/signals/sig_atomic/index.html
26volatile std::sig_atomic_t G_PARENT_OK = 0;
27
36void cleanup([[maybe_unused]] int sig)
37{
38 G_PARENT_OK = 1;
39}
40
41
49[[nodiscard]] Value<void> boot(int argc, char** argv)
50{
51 // Register signal handlers
52 signal(SIGTERM, cleanup);
53 // Ignore SIGPIPE - when parent dies and pipe readers close, we can still cleanup
54 signal(SIGPIPE, SIG_IGN);
55 // Check argc
56 return_if(argc < 3, Error("E::Incorrect usage: fim_janitor <parent_pid> <log_path>"));
57 // Get pid to wait for
58 pid_t pid_parent = Try(std::stoi(argv[1]));
59 // Get log path from parent
60 std::string path_log_file = argv[2];
61 // Create a novel session for the child process
62 pid_t pid_session = setsid();
63 return_if(pid_session < 0, Error("E::Failed to create a novel session for janitor"));
64 // Enable logger to write INFO messages to stdout (for pipe capture)
65 ns_log::set_level(ns_log::Level::DEBUG);
67 // Configure logger sink to write directly to file (fallback if pipe readers die)
68 ns_log::set_sink_file(path_log_file);
69 logger("I::Session id is '{}'", pid_session);
70 // Wait for parent process to exit
71 while (not G_PARENT_OK and kill(pid_parent, 0) == 0)
72 {
73 std::this_thread::sleep_for(std::chrono::milliseconds{100});
74 }
75 // Check if should skip clean
76 if(G_PARENT_OK)
77 {
78 logger("I::Parent process with pid '{}' finished", pid_parent);
79 return {};
80 }
81 // Log that parent exited abnormally
82 logger("E::Parent process with pid '{}' failed to send skip signal", pid_parent);
83 // Cleanup of mountpoints
84 for (auto&& path_dir_mountpoint : std::vector<std::filesystem::path>(argv+2, argv+argc))
85 {
86 logger("I::Un-mount '{}'", path_dir_mountpoint);
87 ns_fuse::unmount(path_dir_mountpoint).discard("E::Could not un-mount '{}'", path_dir_mountpoint);
88 }
89 return {};
90}
91
99int main(int argc, char** argv)
100{
101 auto __expected_fn = [](auto&&){ return 1; };
102 Pop(boot(argc, argv), "C::Failure to start janitor");
103 return EXIT_SUCCESS;
104} // main
105
106/* vim: set expandtab fdm=marker ts=2 sw=2 tw=100 et :*/
Enhanced error handling framework built on std::expected.
constexpr auto __expected_fn
Lambda helper for Pop macro error returns.
Definition expected.hpp:147
A library for operations on fuse filesystems.
Value< void > boot(int argc, char **argv)
Boots the main janitor program.
Definition janitor.cpp:49
void cleanup(int sig)
Signal handler for parent process exit detection.
Definition janitor.cpp:36
A library for file logging.
#define logger(fmt,...)
Compile-time log level dispatch macro with automatic location capture.
Definition log.hpp:682
Simplified macros for common control flow patterns with optional logging.
Value< int > unmount(fs::path const &path_dir_mount)
Un-mounts the given fuse mount point.
Definition fuse.hpp:90
void set_as_fork()
Marks the logger as being in a forked child process.
Definition log.hpp:390
void set_level(Level level)
Sets the logging verbosity (CRITICAL,ERROR,INFO,DEBUG)
Definition log.hpp:339
void set_sink_file(fs::path const &path_file_sink)
Sets the sink file of the logger.
Definition log.hpp:359
int main()
Entry point for the portal daemon.
Enhanced expected type with integrated logging capabilities.
Definition expected.hpp:44