From: Davin McCall Date: Fri, 1 Jan 2016 02:16:00 +0000 (+0000) Subject: Add "run-on-console" service option, to specify that a service X-Git-Tag: v0.01~75 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=41b55b06ee54123e6c5a4fbc997ec0766d9c441c;p=oweals%2Fdinit.git Add "run-on-console" service option, to specify that a service runs on the console. Only one service can be running on the console at a time, so there is a queue to obtain the console. Not 100% complete yet. Part of the functionality seems to have crept in with previous commit though? git gremlins... --- diff --git a/load_service.cc b/load_service.cc index 8957f0e..a7f1fef 100644 --- a/load_service.cc +++ b/load_service.cc @@ -322,6 +322,10 @@ ServiceRecord * ServiceSet::loadServiceRecord(const char * name) string sigtermsetting = read_setting_value(i, end); onstart_flags.no_sigterm = (sigtermsetting == "yes" || sigtermsetting == "true"); } + else if (setting == "runs-on-console") { + string runconsolesetting = read_setting_value(i, end); + onstart_flags.runs_on_console = (runconsolesetting == "yes" || runconsolesetting == "true"); + } else { throw ServiceDescriptionExc(name, "Unknown setting: " + setting); } diff --git a/service.h b/service.h index ae05e26..ea83149 100644 --- a/service.h +++ b/service.h @@ -41,8 +41,10 @@ struct OnstartFlags { // Not actually "onstart" commands: bool no_sigterm : 1; // do not send SIGTERM + bool runs_on_console : 1; // run "in the foreground" - OnstartFlags() noexcept : release_console(false), rw_ready(false), no_sigterm(false) + OnstartFlags() noexcept : release_console(false), rw_ready(false), + no_sigterm(false), runs_on_console(false) { } }; @@ -186,6 +188,9 @@ class ServiceRecord ServiceSet *service_set; // the set this service belongs to + // Next service (after this one) in the queue for the console: + ServiceRecord *next_for_console; + // Process services: bool force_stop; // true if the service must actually stop. This is the // case if for example the process dies; the service, @@ -222,7 +227,7 @@ class ServiceRecord // For process services, start the process, return true on success bool start_ps_process() noexcept; - bool start_ps_process(const std::vector &args) noexcept; + bool start_ps_process(const std::vector &args, bool on_console) noexcept; // Callback from libev when a child process dies static void process_child_callback(struct ev_loop *loop, struct ev_child *w, @@ -231,7 +236,7 @@ class ServiceRecord // A dependency has reached STARTED state void dependencyStarted() noexcept; - void allDepsStarted() noexcept; + void allDepsStarted(bool haveConsole = false) noexcept; // Check whether dependencies have started, and optionally ask them to start bool startCheckDependencies(bool do_start) noexcept; @@ -247,13 +252,21 @@ class ServiceRecord void forceStop() noexcept; // force-stop this service and all dependents - void notifyListeners(ServiceEvent event) + void notifyListeners(ServiceEvent event) noexcept { for (auto l : listeners) { l->serviceEvent(this, event); } } + // Queue to run on the console. 'acquiredConsole()' will be called when the console is available. + void queueForConsole() noexcept; + + // Console is available. + void acquiredConsole() noexcept; + + // Release console (console must be currently held by this service) + void releaseConsole() noexcept; public: @@ -374,6 +387,8 @@ class ServiceSet ShutdownType shutdown_type = ShutdownType::CONTINUE; // Shutdown type, if stopping + ServiceRecord * console_queue_tail = nullptr; // last record in console queue + // Private methods // Load a service description, and dependencies, if there is no existing @@ -421,6 +436,14 @@ class ServiceSet // transition to the 'stopped' state. void stopService(const std::string &name) noexcept; + // Set the console queue tail (returns previous tail) + ServiceRecord * consoleQueueTail(ServiceRecord * newTail) noexcept + { + auto prev_tail = console_queue_tail; + console_queue_tail = newTail; + return prev_tail; + } + // Notification from service that it is active (state != STOPPED) // Only to be called on the transition from inactive to active. void service_active(ServiceRecord *) noexcept;