chiark / gitweb /
implement recursive_stop/stop_when_unneeded unit flags
[elogind.git] / load-fragment.c
index 94bdf171af56782cfae35bedade867142807942a..ac96d0f746836e8b25daca5457d4a1f4233834d5 100644 (file)
@@ -12,6 +12,7 @@
 #include "conf-parser.h"
 #include "load-fragment.h"
 #include "log.h"
+#include "ioprio.h"
 
 static int config_parse_deps(
                 const char *filename,
@@ -625,6 +626,90 @@ int config_parse_level(
         return 0;
 }
 
+int config_parse_io_class(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        static const char * const table[] = {
+                [IOPRIO_CLASS_NONE] = NULL,
+                [IOPRIO_CLASS_RT] = "realtime",
+                [IOPRIO_CLASS_BE] = "best-effort",
+                [IOPRIO_CLASS_IDLE] = "idle",
+        };
+
+        ExecContext *c = data;
+        int i;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        for (i = 0; i < (int) ELEMENTSOF(table); i++) {
+                if (!table[i])
+                        continue;
+
+                if (streq(rvalue, table[i])) {
+                        c->ioprio = IOPRIO_PRIO_VALUE(i, IOPRIO_PRIO_DATA(c->ioprio));
+                        break;
+                }
+        }
+
+        if (i >= (int) ELEMENTSOF(table)) {
+
+                /* Second try, let's see if this is a number. */
+                if (safe_atoi(rvalue, &i) >= 0 &&
+                    i >= 0 &&
+                    i < (int) ELEMENTSOF(table) &&
+                    table[i])
+                        c->ioprio = IOPRIO_PRIO_VALUE(i, IOPRIO_PRIO_DATA(c->ioprio));
+                else {
+                        log_error("[%s:%u] Failed to parse io priority: %s", filename, line, rvalue);
+                        return -EBADMSG;
+                }
+        }
+
+        c->ioprio_set = true;
+
+        return 0;
+}
+
+int config_parse_io_priority(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        ExecContext *c = data;
+        int i;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (safe_atoi(rvalue, &i) >= 0 &&
+            i >= 0 &&
+            i < IOPRIO_BE_NR)
+                c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), i);
+        else {
+                log_error("[%s:%u] Failed to parse io priority: %s", filename, line, rvalue);
+                return -EBADMSG;
+        }
+
+        c->ioprio_set = true;
+
+        return 0;
+}
+
 #define FOLLOW_MAX 8
 
 static int open_follow(char **filename, FILE **_f, Set *names, char **_id) {
@@ -709,12 +794,15 @@ static int load_from_path(Unit *u, const char *path) {
         };
 
 #define EXEC_CONTEXT_CONFIG_ITEMS(context, section) \
-                { "Directory",              config_parse_path,            &(context).directory,                            section   }, \
+                { "WorkingDirectory",       config_parse_path,            &(context).working_directory,                    section   }, \
+                { "RootDirectory",          config_parse_path,            &(context).root_directory,                       section   }, \
                 { "User",                   config_parse_string,          &(context).user,                                 section   }, \
                 { "Group",                  config_parse_string,          &(context).group,                                section   }, \
                 { "SupplementaryGroups",    config_parse_strv,            &(context).supplementary_groups,                 section   }, \
                 { "Nice",                   config_parse_nice,            &(context),                                      section   }, \
                 { "OOMAdjust",              config_parse_oom_adjust,      &(context),                                      section   }, \
+                { "IOPriority",             config_parse_io_priority,     &(context),                                      section   }, \
+                { "IOSchedulingClass",      config_parse_io_class,        &(context),                                      section   }, \
                 { "UMask",                  config_parse_umask,           &(context).umask,                                section   }, \
                 { "Environment",            config_parse_strv,            &(context).environment,                          section   }, \
                 { "Output",                 config_parse_output,          &(context).output,                               section   }, \
@@ -733,6 +821,8 @@ static int load_from_path(Unit *u, const char *path) {
                 { "Conflicts",              config_parse_deps,            UINT_TO_PTR(UNIT_CONFLICTS),                     "Meta"    },
                 { "Before",                 config_parse_deps,            UINT_TO_PTR(UNIT_BEFORE),                        "Meta"    },
                 { "After",                  config_parse_deps,            UINT_TO_PTR(UNIT_AFTER),                         "Meta"    },
+                { "RecursiveStop",          config_parse_bool,            &u->meta.recursive_stop,                         "Meta"    },
+                { "StopWhenUnneeded",       config_parse_bool,            &u->meta.stop_when_unneeded,                     "Meta"    },
 
                 { "PIDFile",                config_parse_path,            &u->service.pid_file,                            "Service" },
                 { "ExecStartPre",           config_parse_exec,            u->service.exec_command+SERVICE_EXEC_START_PRE,  "Service" },
@@ -807,10 +897,11 @@ static int load_from_path(Unit *u, const char *path) {
                         goto finish;
 
 
+                if (id == k)
+                        unit_choose_id(u, id);
                 free(k);
         }
 
-        unit_choose_id(u, id);
 
         free(u->meta.load_path);
         u->meta.load_path = filename;
@@ -860,10 +951,10 @@ int unit_load_fragment(Unit *u) {
                 /* If syslog or kernel logging is requested, make sure
                  * our own logging daemon is run first. */
 
-                if ((k = unit_add_dependency(u, UNIT_AFTER, u->meta.manager->special_units[SPECIAL_LOGGER_SOCKET])) < 0)
+                if ((k = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_LOGGER_SOCKET)) < 0)
                         return k;
 
-                if ((k = unit_add_dependency(u, UNIT_REQUIRES, u->meta.manager->special_units[SPECIAL_LOGGER_SOCKET])) < 0)
+                if ((k = unit_add_dependency_by_name(u, UNIT_REQUIRES, SPECIAL_LOGGER_SOCKET)) < 0)
                         return k;
         }