Browse Source

Rename DUMMY service type to PLACEHOLDER, add loading flag

To open the door to the use of placeholder services for things other
than detecting cyclic dependencies, add a separate flag to indicate a
service is loading. At the same time, rename DUMMY service type to
PLACEHOLDER which is more descriptive.
Davin McCall 10 months ago
parent
commit
caa84dcca3
3 changed files with 28 additions and 18 deletions
  1. 9 9
      src/includes/service-constants.h
  2. 16 6
      src/includes/service.h
  3. 3 3
      src/load-service.cc

+ 9 - 9
src/includes/service-constants.h

@@ -13,15 +13,15 @@ enum class service_state_t {
 
 /* Service types */
 enum class service_type_t {
-    DUMMY,      // Dummy service, used to detect cyclice dependencies
-    PROCESS,    // Service runs as a process, and can be stopped by
-                // sending the process a signal (usually SIGTERM)
-    BGPROCESS,  // Service runs as a process which "daemonizes" to run in the
-                // "background".
-    SCRIPTED,   // Service requires an external command to start,
-                // and a second command to stop
-    INTERNAL,   // Internal service, runs no external process
-    TRIGGERED   // Externally triggered service
+    PLACEHOLDER,  // Placeholder service, used for various reasons
+    PROCESS,      // Service runs as a process, and can be stopped by
+                  // sending the process a signal (usually SIGTERM)
+    BGPROCESS,    // Service runs as a process which "daemonizes" to run in the
+                  // "background".
+    SCRIPTED,     // Service requires an external command to start,
+                  // and a second command to stop
+    INTERNAL,     // Internal service, runs no external process
+    TRIGGERED     // Externally triggered service
 };
 
 /* Service events */

+ 16 - 6
src/includes/service.h

@@ -280,6 +280,8 @@ class service_record
     bool in_auto_restart : 1;
     bool in_user_restart : 1;
 
+    bool is_loading : 1;        // used to detect cyclic dependencies when loading a service
+
     int required_by = 0;        // number of dependents wanting this service to be started
 
     // list of dependencies
@@ -303,7 +305,7 @@ class service_record
     int term_signal = SIGTERM;  // signal to use for process termination
     
     string socket_path; // path to the socket for socket-activation service
-    int socket_perms;   // socket permissions ("mode")
+    int socket_perms = 0;   // socket permissions ("mode")
     uid_t socket_uid = -1;  // socket user id or -1
     gid_t socket_gid = -1;  // socket group id or -1
 
@@ -444,6 +446,9 @@ class service_record
 
     public:
 
+    class loading_tag_cls { };
+    static const loading_tag_cls LOADING_TAG;
+
     service_record(service_set *set, const string &name)
         : service_name(name), service_state(service_state_t::STOPPED),
             desired_state(service_state_t::STOPPED), auto_restart(false), smooth_recovery(false),
@@ -452,11 +457,16 @@ class service_record
             waiting_for_execstat(false), start_explicit(false), prop_require(false), prop_release(false),
             prop_failure(false), prop_start(false), prop_stop(false), prop_pin_dpt(false),
             start_failed(false), start_skipped(false), in_auto_restart(false), in_user_restart(false),
-            force_stop(false)
+			is_loading(false), force_stop(false)
     {
         services = set;
-        record_type = service_type_t::DUMMY;
-        socket_perms = 0;
+        record_type = service_type_t::PLACEHOLDER;
+    }
+
+    // Construct a service record and mark it as a placeholder for a loading service
+    service_record(service_set *set, const string &name, loading_tag_cls tag)
+    	: service_record(set, name) {
+    	is_loading = true;
     }
 
     service_record(service_set *set, const string &name, service_type_t record_type_p,
@@ -597,9 +607,9 @@ class service_record
     }
 
     // Is this a dummy service (used only when loading a new service)?
-    bool is_dummy() noexcept
+    bool check_is_loading() noexcept
     {
-        return record_type == service_type_t::DUMMY;
+        return is_loading;
     }
     
     bool did_start_fail() noexcept

+ 3 - 3
src/load-service.cc

@@ -284,7 +284,7 @@ service_record * dirload_service_set::load_reload_service(const char *name, serv
         // First try and find an existing record...
         service_record * rval = find_service(string(name));
         if (rval != nullptr) {
-            if (rval == avoid_circular || rval->is_dummy()) {
+            if (rval == avoid_circular || rval->check_is_loading()) {
                 throw service_cyclic_dependency(name);
             }
             return rval;
@@ -337,9 +337,9 @@ service_record * dirload_service_set::load_reload_service(const char *name, serv
 
     try {
         if (reload_svc == nullptr) {
-            // Add a dummy service record now to prevent infinite recursion in case of cyclic dependency.
+            // Add a placeholder record now to prevent infinite recursion in case of cyclic dependency.
             // We replace this with the real service later (or remove it if we find a configuration error).
-            dummy = new service_record(this, string(name));
+            dummy = new service_record(this, string(name), service_record::LOADING_TAG);
             add_service(dummy);
         }