chiark / gitweb /
bus-proxyd: explicitly address messages to unique and well-known name
[elogind.git] / src / systemctl / systemctl.c
index af3cc9791120af30275111a9916da3c91b9f51bd..78b7c963e80493825c71cc58a4f0f06fffcf4763 100644 (file)
@@ -67,6 +67,7 @@
 #include "logs-show.h"
 #include "socket-util.h"
 #include "fileio.h"
+#include "copy.h"
 #include "env-util.h"
 #include "bus-util.h"
 #include "bus-message.h"
@@ -301,21 +302,37 @@ static int compare_unit_info(const void *a, const void *b) {
 }
 
 static bool output_show_unit(const UnitInfo *u, char **patterns) {
-        const char *dot;
-
         if (!strv_isempty(patterns)) {
                 char **pattern;
 
                 STRV_FOREACH(pattern, patterns)
                         if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
-                                return true;
+                                goto next;
                 return false;
         }
 
-        return (!arg_types || ((dot = strrchr(u->id, '.')) &&
-                               strv_find(arg_types, dot+1))) &&
-                (arg_all || !(streq(u->active_state, "inactive")
-                              || u->following[0]) || u->job_id > 0);
+next:
+        if (arg_types) {
+                const char *dot;
+
+                dot = strrchr(u->id, '.');
+                if (!dot)
+                        return false;
+
+                if (!strv_find(arg_types, dot+1))
+                        return false;
+        }
+
+        if (arg_all)
+                return true;
+
+        if (u->job_id > 0)
+                return true;
+
+        if (streq(u->active_state, "inactive") || u->following[0])
+                return false;
+
+        return true;
 }
 
 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
@@ -1231,18 +1248,33 @@ static int compare_unit_file_list(const void *a, const void *b) {
 }
 
 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
-        const char *dot;
-
         if (!strv_isempty(patterns)) {
                 char **pattern;
 
                 STRV_FOREACH(pattern, patterns)
                         if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
-                                return true;
+                                goto next;
                 return false;
         }
 
-        return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
+next:
+        if (!strv_isempty(arg_types)) {
+                const char *dot;
+
+                dot = strrchr(u->path, '.');
+                if (!dot)
+                        return false;
+
+                if (!strv_find(arg_types, dot+1))
+                        return false;
+        }
+
+        if (!strv_isempty(arg_states)) {
+                if (!strv_find(arg_states, unit_file_state_to_string(u->state)))
+                        return false;
+        }
+
+        return true;
 }
 
 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
@@ -1965,18 +1997,28 @@ static int set_default(sd_bus *bus, char **args) {
 
                 r = 0;
         } else {
-                _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+                _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
 
-                r = sd_bus_call_method(
+                r = sd_bus_message_new_method_call(
                                 bus,
+                                &m,
                                 "org.freedesktop.systemd1",
                                 "/org/freedesktop/systemd1",
                                 "org.freedesktop.systemd1.Manager",
-                                "SetDefaultTarget",
-                                &error,
-                                &reply,
-                                "sb", unit, true);
+                                "SetDefaultTarget");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append(m, "sb", unit, 1);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_call(bus, m, 0, &error, &reply);
                 if (r < 0) {
                         log_error("Failed to set default target: %s", bus_error_message(&error, -r));
                         return r;
@@ -2143,6 +2185,7 @@ static int list_jobs(sd_bus *bus, char **args) {
 static int cancel_job(sd_bus *bus, char **args) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         char **name;
+        int r = 0;
 
         assert(args);
 
@@ -2150,31 +2193,43 @@ static int cancel_job(sd_bus *bus, char **args) {
                 return daemon_reload(bus, args);
 
         STRV_FOREACH(name, args+1) {
+                _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
                 uint32_t id;
-                int r;
+                int q;
 
-                r = safe_atou32(*name, &id);
-                if (r < 0) {
-                        log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
-                        return r;
+                q = safe_atou32(*name, &id);
+                if (q < 0) {
+                        log_error("Failed to parse job id \"%s\": %s", *name, strerror(-q));
+                        return q;
                 }
 
-                r = sd_bus_call_method(
+                q = sd_bus_message_new_method_call(
                                 bus,
+                                &m,
                                 "org.freedesktop.systemd1",
                                 "/org/freedesktop/systemd1",
                                 "org.freedesktop.systemd1.Manager",
-                                "CancelJob",
-                                &error,
-                                NULL,
-                                "u", id);
-                if (r < 0) {
-                        log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, r));
-                        return r;
+                                "CancelJob");
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+                if (q < 0)
+                        return bus_log_create_error(1);
+
+                q = sd_bus_message_append(m, "u", id);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_call(bus, m, 0, &error, NULL);
+                if (q < 0) {
+                        log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
+                        if (r == 0)
+                                r = q;
                 }
         }
 
-        return 0;
+        return r;
 }
 
 static int need_daemon_reload(sd_bus *bus, const char *unit) {
@@ -2567,7 +2622,7 @@ static int start_unit_one(
                 sd_bus_error *error,
                 Set *s) {
 
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
         const char *path;
         int r;
 
@@ -2577,15 +2632,26 @@ static int start_unit_one(
         assert(error);
 
         log_debug("Calling manager for %s on %s, %s", method, name, mode);
-        r = sd_bus_call_method(
+
+        r = sd_bus_message_new_method_call(
                         bus,
+                        &m,
                         "org.freedesktop.systemd1",
                         "/org/freedesktop/systemd1",
                         "org.freedesktop.systemd1.Manager",
-                        method,
-                        error,
-                        &reply,
-                        "ss", name, mode);
+                        method);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_append(m, "ss", name, mode);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_call(bus, m, 0, error, &reply);
         if (r < 0) {
                 const char *verb;
 
@@ -2827,7 +2893,7 @@ static int reboot_with_logind(sd_bus *bus, enum action a) {
                         method,
                         &error,
                         NULL,
-                        "b", true);
+                        "b", arg_ask_password);
         if (r < 0)
                 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
 
@@ -3050,18 +3116,29 @@ static int kill_unit(sd_bus *bus, char **args) {
                 log_error("Failed to expand names: %s", strerror(-r));
 
         STRV_FOREACH(name, names) {
-                q = sd_bus_call_method(
+                _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+
+                q = sd_bus_message_new_method_call(
                                 bus,
+                                &m,
                                 "org.freedesktop.systemd1",
                                 "/org/freedesktop/systemd1",
                                 "org.freedesktop.systemd1.Manager",
-                                "KillUnit",
-                                &error,
-                                NULL,
-                                "ssi", *names, arg_kill_who, arg_signal);
+                                "KillUnit");
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_call(bus, m, 0, &error, NULL);
                 if (q < 0) {
-                        log_error("Failed to kill unit %s: %s",
-                                  *names, bus_error_message(&error, r));
+                        log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
                         if (r == 0)
                                 r = q;
                 }
@@ -3195,7 +3272,14 @@ typedef struct UnitStatusInfo {
         bool failed_condition_trigger;
         bool failed_condition_negate;
         const char *failed_condition;
-        const char *failed_condition_param;
+        const char *failed_condition_parameter;
+
+        usec_t assert_timestamp;
+        bool assert_result;
+        bool failed_assert_trigger;
+        bool failed_assert_negate;
+        const char *failed_assert;
+        const char *failed_assert_parameter;
 
         /* Socket */
         unsigned n_accepted;
@@ -3339,7 +3423,8 @@ static void print_status_info(
                 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
                 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
 
-                printf("           start condition failed at %s%s%s\n",
+                printf("Condition: start %scondition failed%s at %s%s%s\n",
+                       ansi_highlight_yellow(), ansi_highlight_off(),
                        s2, s1 ? "; " : "", s1 ? s1 : "");
                 if (i->failed_condition_trigger)
                         printf("           none of the trigger conditions were met\n");
@@ -3347,7 +3432,23 @@ static void print_status_info(
                         printf("           %s=%s%s was not met\n",
                                i->failed_condition,
                                i->failed_condition_negate ? "!" : "",
-                               i->failed_condition_param);
+                               i->failed_condition_parameter);
+        }
+
+        if (!i->assert_result && i->assert_timestamp > 0) {
+                s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
+                s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
+
+                printf("   Assert: start %sassertion failed%s at %s%s%s\n",
+                       ansi_highlight_red(), ansi_highlight_off(),
+                       s2, s1 ? "; " : "", s1 ? s1 : "");
+                if (i->failed_assert_trigger)
+                        printf("           none of the trigger assertions were met\n");
+                else if (i->failed_assert)
+                        printf("           %s=%s%s was not met\n",
+                               i->failed_assert,
+                               i->failed_assert_negate ? "!" : "",
+                               i->failed_assert_parameter);
         }
 
         if (i->sysfs_path)
@@ -3598,6 +3699,8 @@ static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *
                         i->need_daemon_reload = b;
                 else if (streq(name, "ConditionResult"))
                         i->condition_result = b;
+                else if (streq(name, "AssertResult"))
+                        i->assert_result = b;
 
                 break;
         }
@@ -3667,6 +3770,8 @@ static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *
                         i->active_exit_timestamp = (usec_t) u;
                 else if (streq(name, "ConditionTimestamp"))
                         i->condition_timestamp = (usec_t) u;
+                else if (streq(name, "AssertTimestamp"))
+                        i->assert_timestamp = (usec_t) u;
 
                 break;
         }
@@ -3759,7 +3864,32 @@ static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *
                                         i->failed_condition = cond;
                                         i->failed_condition_trigger = trigger;
                                         i->failed_condition_negate = negate;
-                                        i->failed_condition_param = param;
+                                        i->failed_condition_parameter = param;
+                                }
+                        }
+                        if (r < 0)
+                                return bus_log_parse_error(r);
+
+                        r = sd_bus_message_exit_container(m);
+                        if (r < 0)
+                                return bus_log_parse_error(r);
+
+                } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
+                        const char *cond, *param;
+                        int trigger, negate;
+                        int32_t state;
+
+                        r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
+                        if (r < 0)
+                                return bus_log_parse_error(r);
+
+                        while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, &param, &state)) > 0) {
+                                log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
+                                if (state < 0 && (!trigger || !i->failed_assert)) {
+                                        i->failed_assert = cond;
+                                        i->failed_assert_trigger = trigger;
+                                        i->failed_assert_negate = negate;
+                                        i->failed_assert_parameter = param;
                                 }
                         }
                         if (r < 0)
@@ -4518,7 +4648,7 @@ static int cat(sd_bus *bus, char **args) {
                                ansi_highlight_off());
                         fflush(stdout);
 
-                        r = sendfile_full(STDOUT_FILENO, fragment_path);
+                        r = copy_file_fd(fragment_path, STDOUT_FILENO);
                         if (r < 0) {
                                 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
                                 continue;
@@ -4533,7 +4663,7 @@ static int cat(sd_bus *bus, char **args) {
                                ansi_highlight_off());
                         fflush(stdout);
 
-                        r = sendfile_full(STDOUT_FILENO, *path);
+                        r = copy_file_fd(*path, STDOUT_FILENO);
                         if (r < 0) {
                                 log_warning("Failed to cat %s: %s", *path, strerror(-r));
                                 continue;
@@ -4561,6 +4691,10 @@ static int set_property(sd_bus *bus, char **args) {
         if (r < 0)
                 return bus_log_create_error(r);
 
+        r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+        if (r < 0)
+                return bus_log_create_error(r);
+
         n = unit_name_mangle(args[1], MANGLE_NOGLOB);
         if (!n)
                 return log_oom();
@@ -4602,7 +4736,7 @@ static int set_property(sd_bus *bus, char **args) {
 
 static int snapshot(sd_bus *bus, char **args) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
         _cleanup_free_ char *n = NULL, *id = NULL;
         const char *path;
         int r;
@@ -4614,15 +4748,25 @@ static int snapshot(sd_bus *bus, char **args) {
         if (!n)
                 return log_oom();
 
-        r = sd_bus_call_method(
+        r = sd_bus_message_new_method_call(
                         bus,
+                        &m,
                         "org.freedesktop.systemd1",
                         "/org/freedesktop/systemd1",
                         "org.freedesktop.systemd1.Manager",
-                        "CreateSnapshot",
-                        &error,
-                        &reply,
-                        "sb", n, false);
+                        "CreateSnapshot");
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_append(m, "sb", n, false);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_call(bus, m, 0, &error, &reply);
         if (r < 0) {
                 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
                 return r;
@@ -4655,7 +4799,7 @@ static int delete_snapshot(sd_bus *bus, char **args) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_strv_free_ char **names = NULL;
         char **name;
-        int r, q;
+        int r;
 
         assert(args);
 
@@ -4664,18 +4808,30 @@ static int delete_snapshot(sd_bus *bus, char **args) {
                 log_error("Failed to expand names: %s", strerror(-r));
 
         STRV_FOREACH(name, names) {
-                q = sd_bus_call_method(
+                _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+                int q;
+
+                q = sd_bus_message_new_method_call(
                                 bus,
+                                &m,
                                 "org.freedesktop.systemd1",
                                 "/org/freedesktop/systemd1",
                                 "org.freedesktop.systemd1.Manager",
-                                "RemoveSnapshot",
-                                &error,
-                                NULL,
-                                "s", *name);
+                                "RemoveSnapshot");
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_append(m, "s", *name);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_call(bus, m, 0, &error, NULL);
                 if (q < 0) {
-                        log_error("Failed to remove snapshot %s: %s",
-                                  *name, bus_error_message(&error, r));
+                        log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
                         if (r == 0)
                                 r = q;
                 }
@@ -4686,6 +4842,7 @@ static int delete_snapshot(sd_bus *bus, char **args) {
 
 static int daemon_reload(sd_bus *bus, char **args) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
         const char *method;
         int r;
 
@@ -4709,16 +4866,21 @@ static int daemon_reload(sd_bus *bus, char **args) {
                                     /* "daemon-reload" */ "Reload";
         }
 
-        r = sd_bus_call_method(
+        r = sd_bus_message_new_method_call(
                         bus,
+                        &m,
                         "org.freedesktop.systemd1",
                         "/org/freedesktop/systemd1",
                         "org.freedesktop.systemd1.Manager",
-                        method,
-                        &error,
-                        NULL,
-                        NULL);
+                        method);
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+        if (r < 0)
+                return bus_log_create_error(r);
 
+        r = sd_bus_call(bus, m, 0, &error, NULL);
         if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
                 /* There's always a fallback possible for
                  * legacy actions. */
@@ -4747,18 +4909,29 @@ static int reset_failed(sd_bus *bus, char **args) {
                 log_error("Failed to expand names: %s", strerror(-r));
 
         STRV_FOREACH(name, names) {
-                q = sd_bus_call_method(
+                _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+
+                q = sd_bus_message_new_method_call(
                                 bus,
+                                &m,
                                 "org.freedesktop.systemd1",
                                 "/org/freedesktop/systemd1",
                                 "org.freedesktop.systemd1.Manager",
-                                "ResetFailedUnit",
-                                &error,
-                                NULL,
-                                "s", *name);
+                                "ResetFailedUnit");
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_message_append(m, "s", *name);
+                if (q < 0)
+                        return bus_log_create_error(q);
+
+                q = sd_bus_call(bus, m, 0, &error, NULL);
                 if (q < 0) {
-                        log_error("Failed to reset failed state of unit %s: %s",
-                                  *name, bus_error_message(&error, r));
+                        log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
                         if (r == 0)
                                 r = q;
                 }
@@ -4889,6 +5062,10 @@ static int set_environment(sd_bus *bus, char **args) {
         if (r < 0)
                 return bus_log_create_error(r);
 
+        r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+        if (r < 0)
+                return bus_log_create_error(r);
+
         r = sd_bus_message_append_strv(m, args + 1);
         if (r < 0)
                 return bus_log_create_error(r);
@@ -4920,6 +5097,10 @@ static int import_environment(sd_bus *bus, char **args) {
         if (r < 0)
                 return bus_log_create_error(r);
 
+        r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+        if (r < 0)
+                return bus_log_create_error(r);
+
         if (strv_isempty(args + 1))
                 r = sd_bus_message_append_strv(m, environ);
         else {
@@ -5231,6 +5412,10 @@ static int enable_unit(sd_bus *bus, char **args) {
                 if (r < 0)
                         return bus_log_create_error(r);
 
+                r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
                 r = sd_bus_message_append_strv(m, names);
                 if (r < 0)
                         return bus_log_create_error(r);
@@ -5346,23 +5531,15 @@ static int add_dependency(sd_bus *bus, char **args) {
                 if (r < 0)
                         return bus_log_create_error(r);
 
-                r = sd_bus_message_append_strv(m, names);
+                r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
                 if (r < 0)
                         return bus_log_create_error(r);
 
-                r = sd_bus_message_append(m, "s", target);
-                if (r < 0)
-                        return bus_log_create_error(r);
-
-                r = sd_bus_message_append(m, "s", unit_dependency_to_string(dep));
-                if (r < 0)
-                        return bus_log_create_error(r);
-
-                r = sd_bus_message_append(m, "b", arg_runtime);
+                r = sd_bus_message_append_strv(m, names);
                 if (r < 0)
                         return bus_log_create_error(r);
 
-                r = sd_bus_message_append(m, "b", arg_force);
+                r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
                 if (r < 0)
                         return bus_log_create_error(r);
 
@@ -5404,21 +5581,33 @@ static int preset_all(sd_bus *bus, char **args) {
                 r = 0;
 
         } else {
-                _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+                _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
 
-                r = sd_bus_call_method(
+                r = sd_bus_message_new_method_call(
                                 bus,
+                                &m,
                                 "org.freedesktop.systemd1",
                                 "/org/freedesktop/systemd1",
                                 "org.freedesktop.systemd1.Manager",
-                                "PresetAllUnitFiles",
-                                &error,
-                                &reply,
+                                "PresetAllUnitFiles");
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_message_append(
+                                m,
                                 "sbb",
                                 unit_file_preset_mode_to_string(arg_preset_mode),
                                 arg_runtime,
                                 arg_force);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                r = sd_bus_call(bus, m, 0, &error, &reply);
                 if (r < 0) {
                         log_error("Failed to execute operation: %s", bus_error_message(&error, r));
                         return r;
@@ -5471,7 +5660,8 @@ static int unit_is_enabled(sd_bus *bus, char **args) {
 
                         if (state == UNIT_FILE_ENABLED ||
                             state == UNIT_FILE_ENABLED_RUNTIME ||
-                            state == UNIT_FILE_STATIC)
+                            state == UNIT_FILE_STATIC ||
+                            state == UNIT_FILE_INDIRECT)
                                 enabled = true;
 
                         if (!arg_quiet)
@@ -5501,9 +5691,7 @@ static int unit_is_enabled(sd_bus *bus, char **args) {
                         if (r < 0)
                                 return bus_log_parse_error(r);
 
-                        if (streq(s, "enabled") ||
-                            streq(s, "enabled-runtime") ||
-                            streq(s, "static"))
+                        if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
                                 enabled = true;
 
                         if (!arg_quiet)
@@ -6813,8 +7001,13 @@ done:
 
 static int halt_now(enum action a) {
 
-/* Make sure C-A-D is handled by the kernel from this
-         * point on... */
+        /* The kernel will automaticall flush ATA disks and suchlike
+         * on reboot(), but the file systems need to be synce'd
+         * explicitly in advance. */
+        sync();
+
+        /* Make sure C-A-D is handled by the kernel from this point
+         * on... */
         reboot(RB_ENABLE_CAD);
 
         switch (a) {