]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/bus-unit-util.c
tree-wide: use TAKE_PTR() and TAKE_FD() macros
[thirdparty/systemd.git] / src / shared / bus-unit-util.c
index b9224bb23cf11d0d7bb87458dab3506d06bfe48e..a9c17d29e2a0a25813539f179f661107a674b254 100644 (file)
@@ -24,6 +24,7 @@
 #include "bus-util.h"
 #include "cap-list.h"
 #include "cgroup-util.h"
+#include "condition.h"
 #include "cpu-set-util.h"
 #include "env-util.h"
 #include "errno-list.h"
@@ -72,61 +73,69 @@ int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
                         &u->job_path);
 }
 
-#define DEFINE_BUS_APPEND_PARSE_PTR(bus_type, cast_type, type, parse_func)                           \
-        static int bus_append_##parse_func(sd_bus_message *m, const char *field, const char *eq) {   \
-                type val;                                                                            \
-                int r;                                                                               \
-                                                                                                     \
-                r = parse_func(eq, &val);                                                            \
-                if (r < 0)                                                                           \
-                        return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq);           \
-                                                                                                     \
-                r = sd_bus_message_append(m, "(sv)", field, bus_type, (cast_type) val);              \
-                if (r < 0)                                                                           \
-                        return bus_log_create_error(r);                                              \
-                                                                                                     \
-                return 1;                                                                            \
+#define DEFINE_BUS_APPEND_PARSE_PTR(bus_type, cast_type, type, parse_func) \
+        static int bus_append_##parse_func(                             \
+                        sd_bus_message *m,                              \
+                        const char *field,                              \
+                        const char *eq) {                               \
+                type val;                                               \
+                int r;                                                  \
+                                                                        \
+                r = parse_func(eq, &val);                               \
+                if (r < 0)                                              \
+                        return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq); \
+                                                                        \
+                r = sd_bus_message_append(m, "(sv)", field,             \
+                                          bus_type, (cast_type) val);   \
+                if (r < 0)                                              \
+                        return bus_log_create_error(r);                 \
+                                                                        \
+                return 1;                                               \
         }
 
-#define DEFINE_BUS_APPEND_PARSE(bus_type, parse_func)                                                \
-        static int bus_append_##parse_func(sd_bus_message *m, const char *field, const char *eq) {   \
-                int r;                                                                               \
-                                                                                                     \
-                r = parse_func(eq);                                                                  \
-                if (r < 0) {                                                                         \
-                        log_error("Failed to parse %s: %s", field, eq);                              \
-                        return -EINVAL;                                                              \
-                }                                                                                    \
-                                                                                                     \
-                r = sd_bus_message_append(m, "(sv)", field, bus_type, (int32_t) r);                  \
-                if (r < 0)                                                                           \
-                        return bus_log_create_error(r);                                              \
-                                                                                                     \
-                return 1;                                                                            \
+#define DEFINE_BUS_APPEND_PARSE(bus_type, parse_func)                   \
+        static int bus_append_##parse_func(                             \
+                        sd_bus_message *m,                              \
+                        const char *field,                              \
+                        const char *eq) {                               \
+                int r;                                                  \
+                                                                        \
+                r = parse_func(eq);                                     \
+                if (r < 0) {                                            \
+                        log_error("Failed to parse %s: %s", field, eq); \
+                        return -EINVAL;                                 \
+                }                                                       \
+                                                                        \
+                r = sd_bus_message_append(m, "(sv)", field,             \
+                                          bus_type, (int32_t) r);       \
+                if (r < 0)                                              \
+                        return bus_log_create_error(r);                 \
+                                                                        \
+                return 1;                                               \
         }
 
-DEFINE_BUS_APPEND_PARSE("b", parse_boolean)
-DEFINE_BUS_APPEND_PARSE("i", ioprio_class_from_string)
-DEFINE_BUS_APPEND_PARSE("i", ip_tos_from_string)
-DEFINE_BUS_APPEND_PARSE("i", log_facility_unshifted_from_string)
-DEFINE_BUS_APPEND_PARSE("i", log_level_from_string)
-DEFINE_BUS_APPEND_PARSE("i", parse_errno)
-DEFINE_BUS_APPEND_PARSE("i", sched_policy_from_string)
-DEFINE_BUS_APPEND_PARSE("i", secure_bits_from_string)
-DEFINE_BUS_APPEND_PARSE("i", signal_from_string_try_harder)
-DEFINE_BUS_APPEND_PARSE("i", socket_protocol_from_name)
-DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, ioprio_parse_priority)
-DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, parse_nice)
-DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, safe_atoi)
-DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, nsec_t, parse_nsec)
-DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_blkio_weight_parse)
-DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_cpu_shares_parse)
-DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_weight_parse)
-DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, unsigned long, mount_propagation_flags_from_string)
-DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, usec_t, parse_sec)
-DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, mode_t, parse_mode)
-DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, unsigned, safe_atou)
-DEFINE_BUS_APPEND_PARSE_PTR("x", int64_t, int64_t, safe_atoi64)
+DEFINE_BUS_APPEND_PARSE("b", parse_boolean);
+DEFINE_BUS_APPEND_PARSE("i", ioprio_class_from_string);
+DEFINE_BUS_APPEND_PARSE("i", ip_tos_from_string);
+DEFINE_BUS_APPEND_PARSE("i", log_facility_unshifted_from_string);
+DEFINE_BUS_APPEND_PARSE("i", log_level_from_string);
+DEFINE_BUS_APPEND_PARSE("i", parse_errno);
+DEFINE_BUS_APPEND_PARSE("i", sched_policy_from_string);
+DEFINE_BUS_APPEND_PARSE("i", secure_bits_from_string);
+DEFINE_BUS_APPEND_PARSE("i", signal_from_string_try_harder);
+DEFINE_BUS_APPEND_PARSE("i", socket_protocol_from_name);
+DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, ioprio_parse_priority);
+DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, parse_nice);
+DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, safe_atoi);
+DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, nsec_t, parse_nsec);
+DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_blkio_weight_parse);
+DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_cpu_shares_parse);
+DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_weight_parse);
+DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, unsigned long, mount_propagation_flags_from_string);
+DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, safe_atou64);
+DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, mode_t, parse_mode);
+DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, unsigned, safe_atou);
+DEFINE_BUS_APPEND_PARSE_PTR("x", int64_t, int64_t, safe_atoi64);
 
 static inline int bus_append_string(sd_bus_message *m, const char *field, const char *eq) {
         int r;
@@ -241,12 +250,12 @@ static int bus_append_parse_sec_rename(sd_bus_message *m, const char *field, con
         return 1;
 }
 
-static int bus_append_parse_iec_size(sd_bus_message *m, const char *field, const char *eq) {
+static int bus_append_parse_size(sd_bus_message *m, const char *field, const char *eq, uint64_t base) {
         uint64_t v;
         int r;
 
-        r = parse_size(eq, 1024, &v);
-        if (r < 0 || (uint64_t) (size_t) v != v)
+        r = parse_size(eq, base, &v);
+        if (r < 0)
                 return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq);
 
         r = sd_bus_message_append(m, "(sv)", field, "t", v);
@@ -423,7 +432,6 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
         }
 
         if (STR_IN_SET(field, "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "TasksMax")) {
-                uint64_t val;
 
                 if (isempty(eq) || streq(eq, "infinity")) {
                         r = sd_bus_message_append(m, "(sv)", field, "t", CGROUP_LIMIT_MAX);
@@ -449,18 +457,9 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
                 }
 
                 if (streq(field, "TasksMax"))
-                        r = safe_atou64(eq, &val);
-                else
-                        r = parse_size(eq, 1024, &val);
-
-                if (r < 0)
-                        return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq);
+                        return bus_append_safe_atou64(m, field, eq);
 
-                r = sd_bus_message_append(m, "(sv)", field, "t", val);
-                if (r < 0)
-                        return bus_log_create_error(r);
-
-                return 1;
+                return bus_append_parse_size(m, field, eq, 1024);
         }
 
         if (streq(field, "CPUQuota")) {
@@ -488,23 +487,15 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
                 if (isempty(eq))
                         r = sd_bus_message_append(m, "(sv)", field, "a(ss)", 0);
                 else {
-                        const char *path, *rwm, *e;
+                        const char *path = eq, *rwm = NULL, *e;
 
                         e = strchr(eq, ' ');
                         if (e) {
                                 path = strndupa(eq, e - eq);
                                 rwm = e+1;
-                        } else {
-                                path = eq;
-                                rwm = "";
-                        }
-
-                        if (!is_deviceallow_pattern(path)) {
-                                log_error("%s is not a device file in /dev.", path);
-                                return -EINVAL;
                         }
 
-                        r = sd_bus_message_append(m, "(sv)", field, "a(ss)", 1, path, rwm);
+                        r = sd_bus_message_append(m, "(sv)", field, "a(ss)", 1, path, strempty(rwm));
                 }
 
                 if (r < 0)
@@ -522,18 +513,13 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
                         uint64_t bytes;
 
                         e = strchr(eq, ' ');
-                        if (e) {
-                                path = strndupa(eq, e - eq);
-                                bandwidth = e+1;
-                        } else {
+                        if (!e) {
                                 log_error("Failed to parse %s value %s.", field, eq);
                                 return -EINVAL;
                         }
 
-                        if (!path_startswith(path, "/dev")) {
-                                log_error("%s is not a device file in /dev.", path);
-                                return -EINVAL;
-                        }
+                        path = strndupa(eq, e - eq);
+                        bandwidth = e+1;
 
                         if (streq(bandwidth, "infinity")) {
                                 bytes = CGROUP_LIMIT_MAX;
@@ -561,18 +547,13 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
                         uint64_t u;
 
                         e = strchr(eq, ' ');
-                        if (e) {
-                                path = strndupa(eq, e - eq);
-                                weight = e+1;
-                        } else {
+                        if (!e) {
                                 log_error("Failed to parse %s value %s.", field, eq);
                                 return -EINVAL;
                         }
 
-                        if (!path_startswith(path, "/dev")) {
-                                log_error("%s is not a device file in /dev.", path);
-                                return -EINVAL;
-                        }
+                        path = strndupa(eq, e - eq);
+                        weight = e+1;
 
                         r = safe_atou64(weight, &u);
                         if (r < 0)
@@ -698,6 +679,23 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
         return 0;
 }
 
+static int bus_append_automount_property(sd_bus_message *m, const char *field, const char *eq) {
+
+        if (streq(field, "Where"))
+
+                return bus_append_string(m, field, eq);
+
+        if (streq(field, "DirectoryMode"))
+
+                return bus_append_parse_mode(m, field, eq);
+
+        if (streq(field, "TimeoutIdleSec"))
+
+                return bus_append_parse_sec_rename(m, field, eq);
+
+        return 0;
+}
+
 static int bus_append_execute_property(sd_bus_message *m, const char *field, const char *eq) {
         int r, rl;
 
@@ -1134,6 +1132,62 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
                 return 1;
         }
 
+        if (streq(field, "TemporaryFileSystem")) {
+                const char *p = eq;
+
+                r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_open_container(m, 'v', "a(ss)");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_open_container(m, 'a', "(ss)");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                for (;;) {
+                        _cleanup_free_ char *word = NULL, *path = NULL;
+                        const char *w;
+
+                        r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse argument: %m");
+                        if (r == 0)
+                                break;
+
+                        w = word;
+                        r = extract_first_word(&w, &path, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse argument: %m");
+                        if (r == 0)
+                                return log_error("Failed to parse argument: %m");
+
+                        r = sd_bus_message_append(m, "(ss)", path, w);
+                        if (r < 0)
+                                return bus_log_create_error(r);
+                }
+
+                r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                return 1;
+        }
+
         return 0;
 }
 
@@ -1154,14 +1208,30 @@ static int bus_append_kill_property(sd_bus_message *m, const char *field, const
         return 0;
 }
 
-static int bus_append_path_property(sd_bus_message *m, const char *field, const char *eq) {
+static int bus_append_mount_property(sd_bus_message *m, const char *field, const char *eq) {
 
-        if (STR_IN_SET(field,
-                       "PathExists", "PathExistsGlob", "PathChanged",
-                       "PathModified", "DirectoryNotEmpty"))
+        if (STR_IN_SET(field, "What", "Where", "Options", "Type"))
 
                 return bus_append_string(m, field, eq);
 
+        if (streq(field, "TimeoutSec"))
+
+                return bus_append_parse_sec_rename(m, field, eq);
+
+        if (streq(field, "DirectoryMode"))
+
+                return bus_append_parse_mode(m, field, eq);
+
+        if (STR_IN_SET(field, "SloppyOptions", "LazyUnmount", "ForceUnmount"))
+
+                return bus_append_parse_boolean(m, field, eq);
+
+        return 0;
+}
+
+static int bus_append_path_property(sd_bus_message *m, const char *field, const char *eq) {
+        int r;
+
         if (streq(field, "MakeDirectory"))
 
                 return bus_append_parse_boolean(m, field, eq);
@@ -1170,23 +1240,49 @@ static int bus_append_path_property(sd_bus_message *m, const char *field, const
 
                 return bus_append_parse_mode(m, field, eq);
 
+        if (STR_IN_SET(field,
+                       "PathExists", "PathExistsGlob", "PathChanged",
+                       "PathModified", "DirectoryNotEmpty")) {
+
+                if (isempty(eq))
+                        r = sd_bus_message_append(m, "(sv)", "Paths", "a(ss)", 0);
+                else
+                        r = sd_bus_message_append(m, "(sv)", "Paths", "a(ss)", 1, field, eq);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                return 1;
+        }
+
         return 0;
 }
 
 static int bus_append_service_property(sd_bus_message *m, const char *field, const char *eq) {
+        int r;
 
-        if (STR_IN_SET(field, "Type", "Restart", "NotifyAccess"))
+        if (STR_IN_SET(field,
+                       "PIDFile", "Type", "Restart", "BusName", "NotifyAccess",
+                       "USBFunctionDescriptors", "USBFunctionStrings"))
 
                 return bus_append_string(m, field, eq);
 
-        if (streq(field, "RemainAfterExit"))
+        if (STR_IN_SET(field, "PermissionsStartOnly", "RootDirectoryStartOnly", "RemainAfterExit", "GuessMainPID"))
 
                 return bus_append_parse_boolean(m, field, eq);
 
-        if (streq(field, "RuntimeMaxSec"))
+        if (STR_IN_SET(field, "RestartSec", "TimeoutStartSec", "TimeoutStopSec", "RuntimeMaxSec", "WatchdogSec"))
 
                 return bus_append_parse_sec_rename(m, field, eq);
 
+        if (streq(field, "TimeoutSec")) {
+
+                r = bus_append_parse_sec_rename(m, "TimeoutStartSec", eq);
+                if (r < 0)
+                        return r;
+
+                return bus_append_parse_sec_rename(m, "TimeoutStopSec", eq);
+        }
+
         if (streq(field, "FileDescriptorStoreMax"))
 
                 return bus_append_safe_atou(m, field, eq);
@@ -1197,6 +1293,82 @@ static int bus_append_service_property(sd_bus_message *m, const char *field, con
 
                 return bus_append_exec_command(m, field, eq);
 
+        if (STR_IN_SET(field, "RestartPreventExitStatus", "RestartForceExitStatus", "SuccessExitStatus")) {
+                _cleanup_free_ int *status = NULL, *signal = NULL;
+                size_t sz_status = 0, sz_signal = 0;
+                const char *p;
+
+                for (p = eq;;) {
+                        _cleanup_free_ char *word = NULL;
+                        int val;
+
+                        r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
+                        if (r == 0)
+                                break;
+                        if (r == -ENOMEM)
+                                return log_oom();
+                        if (r < 0)
+                                return log_error_errno(r, "Invalid syntax in %s: %s", field, eq);
+
+                        r = safe_atoi(word, &val);
+                        if (r < 0) {
+                                val = signal_from_string_try_harder(word);
+                                if (val < 0)
+                                        return log_error_errno(r, "Invalid status or signal %s in %s: %m", word, field);
+
+                                signal = reallocarray(signal, sz_signal + 1, sizeof(int));
+                                if (!signal)
+                                        return log_oom();
+
+                                signal[sz_signal++] = val;
+                        } else {
+                                status = reallocarray(status, sz_status + 1, sizeof(int));
+                                if (!status)
+                                        return log_oom();
+
+                                status[sz_status++] = val;
+                        }
+                }
+
+                r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_open_container(m, 'v', "(aiai)");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_open_container(m, 'r', "aiai");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append_array(m, 'i', status, sz_status);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append_array(m, 'i', signal, sz_signal);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_close_container(m);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                return 1;
+        }
+
         return 0;
 }
 
@@ -1235,7 +1407,7 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
 
         if (STR_IN_SET(field, "ReceiveBuffer", "SendBuffer", "PipeSize"))
 
-                return bus_append_parse_iec_size(m, field, eq);
+                return bus_append_parse_size(m, field, eq, 1024);
 
         if (STR_IN_SET(field, "ExecStartPre", "ExecStartPost", "ExecReload", "ExecStopPost"))
 
@@ -1260,7 +1432,10 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
                        "ListenStream", "ListenDatagram", "ListenSequentialPacket", "ListenNetlink",
                        "ListenSpecial", "ListenMessageQueue", "ListenFIFO", "ListenUSBFunction")) {
 
-                r = sd_bus_message_append(m, "(sv)", "Listen", "a(ss)", 1, field + strlen("Listen"), eq);
+                if (isempty(eq))
+                        r = sd_bus_message_append(m, "(sv)", "Listen", "a(ss)", 0);
+                else
+                        r = sd_bus_message_append(m, "(sv)", "Listen", "a(ss)", 1, field + STRLEN("Listen"), eq);
                 if (r < 0)
                         return bus_log_create_error(r);
 
@@ -1270,43 +1445,106 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
         return 0;
 }
 static int bus_append_timer_property(sd_bus_message *m, const char *field, const char *eq) {
-
-        if (streq(field, "OnCalendar"))
-
-                return bus_append_string(m, field, eq);
+        int r;
 
         if (STR_IN_SET(field, "WakeSystem", "RemainAfterElapse", "Persistent"))
 
                 return bus_append_parse_boolean(m, field, eq);
 
+        if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec"))
+
+                return bus_append_parse_sec_rename(m, field, eq);
+
         if (STR_IN_SET(field,
                        "OnActiveSec", "OnBootSec", "OnStartupSec",
-                       "OnUnitActiveSec","OnUnitInactiveSec"))
+                       "OnUnitActiveSec","OnUnitInactiveSec")) {
 
-                return bus_append_parse_sec(m, field, eq);
+                if (isempty(eq))
+                        r = sd_bus_message_append(m, "(sv)", "TimersMonotonic", "a(st)", 0);
+                else {
+                        usec_t t;
+                        r = parse_sec(eq, &t);
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq);
 
-        if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec"))
+                        r = sd_bus_message_append(m, "(sv)", "TimersMonotonic", "a(st)", 1, field, t);
+                }
+                if (r < 0)
+                        return bus_log_create_error(r);
 
-                return bus_append_parse_sec_rename(m, field, eq);
+                return 1;
+        }
+
+        if (streq(field, "OnCalendar")) {
+
+                if (isempty(eq))
+                        r = sd_bus_message_append(m, "(sv)", "TimersCalendar", "a(ss)", 0);
+                else
+                        r = sd_bus_message_append(m, "(sv)", "TimersCalendar", "a(ss)", 1, field, eq);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                return 1;
+        }
 
         return 0;
 }
 
 static int bus_append_unit_property(sd_bus_message *m, const char *field, const char *eq) {
-        UnitDependency dep;
+        ConditionType t = _CONDITION_TYPE_INVALID;
+        bool is_condition = false;
         int r;
 
-        if (STR_IN_SET(field, "Description", "CollectMode", "FailureAction", "SuccessAction"))
+        if (STR_IN_SET(field,
+                       "Description", "SourcePath", "OnFailureJobMode",
+                       "JobTimeoutAction", "JobTimeoutRebootArgument",
+                       "StartLimitAction", "FailureAction", "SuccessAction",
+                       "RebootArgument", "CollectMode"))
 
                 return bus_append_string(m, field, eq);
 
-        if (streq(field, "DefaultDependencies"))
+        if (STR_IN_SET(field,
+                       "StopWhenUnneeded", "RefuseManualStart", "RefuseManualStop",
+                       "AllowIsolate", "IgnoreOnIsolate", "DefaultDependencies"))
 
                 return bus_append_parse_boolean(m, field, eq);
 
-        if ((dep = unit_dependency_from_string(field)) >= 0) {
+        if (STR_IN_SET(field, "JobTimeoutSec", "JobRunningTimeoutSec", "StartLimitIntervalSec"))
+
+                return bus_append_parse_sec_rename(m, field, eq);
+
+        if (streq(field, "StartLimitBurst"))
+
+                return bus_append_safe_atou(m, field, eq);
+
+        if (unit_dependency_from_string(field) >= 0 ||
+            STR_IN_SET(field, "Documentation", "RequiresMountsFor"))
+
+                return bus_append_strv(m, field, eq, EXTRACT_QUOTES);
+
+        t = condition_type_from_string(field);
+        if (t >= 0)
+                is_condition = true;
+        else
+                t = assert_type_from_string(field);
+        if (t >= 0) {
+                if (isempty(eq))
+                        r = sd_bus_message_append(m, "(sv)", is_condition ? "Conditions" : "Asserts", "a(sbbs)", 0);
+                else {
+                        const char *p = eq;
+                        int trigger, negate;
+
+                        trigger = *p == '|';
+                        if (trigger)
+                                p++;
 
-                r = sd_bus_message_append(m, "(sv)", field, "as", 1, eq);
+                        negate = *p == '!';
+                        if (negate)
+                                p++;
+
+                        r = sd_bus_message_append(m, "(sv)", is_condition ? "Conditions" : "Asserts", "a(sbbs)", 1,
+                                                  field, trigger, negate, p);
+                }
                 if (r < 0)
                         return bus_log_create_error(r);
 
@@ -1388,6 +1626,10 @@ int bus_append_unit_property_assignment(sd_bus_message *m, UnitType t, const cha
                 break;
 
         case UNIT_SCOPE:
+
+                if (streq(field, "TimeoutStopSec"))
+                        return bus_append_parse_sec_rename(m, field, eq);
+
                 r = bus_append_cgroup_property(m, field, eq);
                 if (r != 0)
                         return r;
@@ -1398,7 +1640,29 @@ int bus_append_unit_property_assignment(sd_bus_message *m, UnitType t, const cha
                 break;
 
         case UNIT_MOUNT:
+                r = bus_append_cgroup_property(m, field, eq);
+                if (r != 0)
+                        return r;
+
+                r = bus_append_execute_property(m, field, eq);
+                if (r != 0)
+                        return r;
+
+                r = bus_append_kill_property(m, field, eq);
+                if (r != 0)
+                        return r;
+
+                r = bus_append_mount_property(m, field, eq);
+                if (r != 0)
+                        return r;
+
+                break;
+
         case UNIT_AUTOMOUNT:
+                r = bus_append_automount_property(m, field, eq);
+                if (r != 0)
+                        return r;
+
                 break;
 
         case UNIT_TARGET:
@@ -1519,36 +1783,29 @@ int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret) {
         /* When we are a bus client we match by sender. Direct
          * connections OTOH have no initialized sender field, and
          * hence we ignore the sender then */
-        r = sd_bus_add_match(
+        r = sd_bus_match_signal_async(
                         bus,
                         &d->slot_job_removed,
-                        bus->bus_client ?
-                        "type='signal',"
-                        "sender='org.freedesktop.systemd1',"
-                        "interface='org.freedesktop.systemd1.Manager',"
-                        "member='JobRemoved',"
-                        "path='/org/freedesktop/systemd1'" :
-                        "type='signal',"
-                        "interface='org.freedesktop.systemd1.Manager',"
-                        "member='JobRemoved',"
-                        "path='/org/freedesktop/systemd1'",
-                        match_job_removed, d);
+                        bus->bus_client ? "org.freedesktop.systemd1" : NULL,
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "JobRemoved",
+                        match_job_removed, NULL, d);
         if (r < 0)
                 return r;
 
-        r = sd_bus_add_match(
+        r = sd_bus_match_signal_async(
                         bus,
                         &d->slot_disconnected,
-                        "type='signal',"
-                        "sender='org.freedesktop.DBus.Local',"
-                        "interface='org.freedesktop.DBus.Local',"
-                        "member='Disconnected'",
-                        match_disconnected, d);
+                        "org.freedesktop.DBus.Local",
+                        NULL,
+                        "org.freedesktop.DBus.Local",
+                        "Disconnected",
+                        match_disconnected, NULL, d);
         if (r < 0)
                 return r;
 
-        *ret = d;
-        d = NULL;
+        *ret = TAKE_PTR(d);
 
         return 0;
 }
@@ -2164,7 +2421,7 @@ int unit_show_processes(
         if (r < 0)
                 return r;
 
-        cgroups = hashmap_new(&string_hash_ops);
+        cgroups = hashmap_new(&path_hash_ops);
         if (!cgroups)
                 return -ENOMEM;