]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/bus-unit-util.c
core: add RootImage= setting for using a specific image file as root directory for...
[thirdparty/systemd.git] / src / shared / bus-unit-util.c
index 388b39134255789eec7a0fd31b4235d08d544917..20c1085697ae6c6b01607700fdd8906a9156b8ad 100644 (file)
@@ -27,6 +27,7 @@
 #include "hashmap.h"
 #include "list.h"
 #include "locale-util.h"
+#include "mount-util.h"
 #include "nsflags.h"
 #include "parse-util.h"
 #include "path-util.h"
@@ -207,7 +208,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                               "PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers", "NoNewPrivileges",
                               "SyslogLevelPrefix", "Delegate", "RemainAfterElapse", "MemoryDenyWriteExecute",
                               "RestrictRealtime", "DynamicUser", "RemoveIPC", "ProtectKernelTunables",
-                              "ProtectKernelModules", "ProtectControlGroups")) {
+                              "ProtectKernelModules", "ProtectControlGroups", "MountAPIVFS")) {
 
                 r = parse_boolean(eq);
                 if (r < 0)
@@ -265,7 +266,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                               "StandardInput", "StandardOutput", "StandardError",
                               "Description", "Slice", "Type", "WorkingDirectory",
                               "RootDirectory", "SyslogIdentifier", "ProtectSystem",
-                              "ProtectHome", "SELinuxContext"))
+                              "ProtectHome", "SELinuxContext", "Restart", "RootImage"))
                 r = sd_bus_message_append(m, "v", "s", eq);
 
         else if (streq(field, "SyslogLevel")) {
@@ -483,7 +484,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
 
                 for (p = eq;;) {
                         _cleanup_free_ char *word = NULL;
-                        int offset;
+                        size_t offset;
 
                         r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
                         if (r < 0) {
@@ -499,6 +500,8 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                         }
 
                         offset = word[0] == '-';
+                        offset += word[offset] == '+';
+
                         if (!path_is_absolute(word + offset)) {
                                 log_error("Failed to parse %s value %s", field, eq);
                                 return -EINVAL;
@@ -575,7 +578,85 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 r = sd_bus_message_append(m, "v", "t", flags);
         } else if ((dep = unit_dependency_from_string(field)) >= 0)
                 r = sd_bus_message_append(m, "v", "as", 1, eq);
-        else {
+        else if (streq(field, "MountFlags")) {
+                unsigned long f;
+
+                r = mount_propagation_flags_from_string(eq, &f);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse mount propagation flags: %s", eq);
+
+                r = sd_bus_message_append(m, "v", "t", f);
+        } else if (STR_IN_SET(field, "BindPaths", "BindReadOnlyPaths")) {
+                const char *p = eq;
+
+                r = sd_bus_message_open_container(m, 'v', "a(ssbt)");
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_open_container(m, 'a', "(ssbt)");
+                if (r < 0)
+                        return r;
+
+                for (;;) {
+                        _cleanup_free_ char *source = NULL, *destination = NULL;
+                        char *s = NULL, *d = NULL;
+                        bool ignore_enoent = false;
+                        uint64_t flags = MS_REC;
+
+                        r = extract_first_word(&p, &source, ":" WHITESPACE, EXTRACT_QUOTES|EXTRACT_DONT_COALESCE_SEPARATORS);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse argument: %m");
+                        if (r == 0)
+                                break;
+
+                        s = source;
+                        if (s[0] == '-') {
+                                ignore_enoent = true;
+                                s++;
+                        }
+
+                        if (p && p[-1] == ':') {
+                                r = extract_first_word(&p, &destination, ":" WHITESPACE, EXTRACT_QUOTES|EXTRACT_DONT_COALESCE_SEPARATORS);
+                                if (r < 0)
+                                        return log_error_errno(r, "Failed to parse argument: %m");
+                                if (r == 0) {
+                                        log_error("Missing argument after ':': %s", eq);
+                                        return -EINVAL;
+                                }
+
+                                d = destination;
+
+                                if (p && p[-1] == ':') {
+                                        _cleanup_free_ char *options = NULL;
+
+                                        r = extract_first_word(&p, &options, NULL, EXTRACT_QUOTES);
+                                        if (r < 0)
+                                                return log_error_errno(r, "Failed to parse argument: %m");
+
+                                        if (isempty(options) || streq(options, "rbind"))
+                                                flags = MS_REC;
+                                        else if (streq(options, "norbind"))
+                                                flags = 0;
+                                        else {
+                                                log_error("Unknown options: %s", eq);
+                                                return -EINVAL;
+                                        }
+                                }
+                        } else
+                                d = s;
+
+
+                        r = sd_bus_message_append(m, "(ssbt)", s, d, ignore_enoent, flags);
+                        if (r < 0)
+                                return r;
+                }
+
+                r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_close_container(m);
+        } else {
                 log_error("Unknown assignment %s.", assignment);
                 return -EINVAL;
         }
@@ -764,6 +845,7 @@ static const struct {
         const char *result, *explanation;
 } explanations [] = {
         { "resources",   "of unavailable resources or another system error" },
+        { "protocol",    "the service did not take the steps required by its unit configuration" },
         { "timeout",     "a timeout was exceeded" },
         { "exit-code",   "the control process exited with error code" },
         { "signal",      "a fatal signal was delivered to the control process" },