From 90bbc9469ec29b6094dadf27aa88743d44ab56e7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 9 Mar 2011 23:58:17 +0100 Subject: [PATCH] condition: take a timestamp and store last result of conditions --- TODO | 2 -- src/dbus-unit.h | 14 +++++++++----- src/systemctl.c | 17 +++++++++++++++++ src/unit.c | 11 ++++++++++- src/unit.h | 7 +++++++ 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index a8b8797802..935978216a 100644 --- a/TODO +++ b/TODO @@ -26,8 +26,6 @@ Features: * consider services with no [Install] section and stored in /lib enabled by "systemctl is-enabled" -* store time when conditions where checked to inform admins about whether a unit was considered at all - * consider services with any kind of link in /etc/systemd/system enabled * show failure error string in "systemctl status" diff --git a/src/dbus-unit.h b/src/dbus-unit.h index 4e46fc4825..efb61797f4 100644 --- a/src/dbus-unit.h +++ b/src/dbus-unit.h @@ -102,6 +102,8 @@ " \n" \ " \n" \ " \n" \ + " \n" \ + " \n" \ " \n" #define BUS_UNIT_INTERFACES_LIST \ @@ -132,10 +134,10 @@ { "org.freedesktop.systemd1.Unit", "ActiveState", bus_unit_append_active_state, "s", u }, \ { "org.freedesktop.systemd1.Unit", "SubState", bus_unit_append_sub_state, "s", u }, \ { "org.freedesktop.systemd1.Unit", "FragmentPath", bus_property_append_string, "s", u->meta.fragment_path }, \ - { "org.freedesktop.systemd1.Unit", "InactiveExitTimestamp",bus_property_append_uint64, "t", &u->meta.inactive_exit_timestamp.realtime }, \ - { "org.freedesktop.systemd1.Unit", "ActiveEnterTimestamp", bus_property_append_uint64, "t", &u->meta.active_enter_timestamp.realtime }, \ - { "org.freedesktop.systemd1.Unit", "ActiveExitTimestamp", bus_property_append_uint64, "t", &u->meta.active_exit_timestamp.realtime }, \ - { "org.freedesktop.systemd1.Unit", "InactiveEnterTimestamp",bus_property_append_uint64, "t", &u->meta.inactive_enter_timestamp.realtime }, \ + { "org.freedesktop.systemd1.Unit", "InactiveExitTimestamp",bus_property_append_usec, "t", &u->meta.inactive_exit_timestamp.realtime }, \ + { "org.freedesktop.systemd1.Unit", "ActiveEnterTimestamp", bus_property_append_usec, "t", &u->meta.active_enter_timestamp.realtime }, \ + { "org.freedesktop.systemd1.Unit", "ActiveExitTimestamp", bus_property_append_usec, "t", &u->meta.active_exit_timestamp.realtime }, \ + { "org.freedesktop.systemd1.Unit", "InactiveEnterTimestamp",bus_property_append_usec, "t", &u->meta.inactive_enter_timestamp.realtime }, \ { "org.freedesktop.systemd1.Unit", "CanStart", bus_unit_append_can_start, "b", u }, \ { "org.freedesktop.systemd1.Unit", "CanStop", bus_unit_append_can_stop, "b", u }, \ { "org.freedesktop.systemd1.Unit", "CanReload", bus_unit_append_can_reload, "b", u }, \ @@ -149,7 +151,9 @@ { "org.freedesktop.systemd1.Unit", "DefaultControlGroup", bus_unit_append_default_cgroup, "s", u }, \ { "org.freedesktop.systemd1.Unit", "ControlGroup", bus_unit_append_cgroups, "as", u }, \ { "org.freedesktop.systemd1.Unit", "NeedDaemonReload", bus_unit_append_need_daemon_reload, "b", u }, \ - { "org.freedesktop.systemd1.Unit", "JobTimeoutUSec", bus_property_append_usec, "t", &u->meta.job_timeout } + { "org.freedesktop.systemd1.Unit", "JobTimeoutUSec", bus_property_append_usec, "t", &u->meta.job_timeout }, \ + { "org.freedesktop.systemd1.Unit", "ConditionTimestamp", bus_property_append_usec, "t", &u->meta.condition_timestamp.realtime }, \ + { "org.freedesktop.systemd1.Unit", "ConditionResult", bus_property_append_bool, "b", &u->meta.condition_result } int bus_unit_append_names(Manager *m, DBusMessageIter *i, const char *property, void *data); int bus_unit_append_following(Manager *m, DBusMessageIter *i, const char *property, void *data); diff --git a/src/systemctl.c b/src/systemctl.c index 63e74d904a..5b205fec56 100644 --- a/src/systemctl.c +++ b/src/systemctl.c @@ -1831,6 +1831,9 @@ typedef struct UnitStatusInfo { int exit_code, exit_status; + usec_t condition_timestamp; + bool condition_result; + /* Socket */ unsigned n_accepted; unsigned n_connections; @@ -1922,6 +1925,16 @@ static void print_status_info(UnitStatusInfo *i) { else printf("\n"); + if (!i->condition_result && i->condition_timestamp > 0) { + s1 = format_timestamp_pretty(since1, sizeof(since1), i->condition_timestamp); + s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp); + + if (s1) + printf("\t start condition failed at %s; %s\n", s2, s1); + else if (s2) + printf("\t start condition failed at %s\n", s2); + } + if (i->sysfs_path) printf("\t Device: %s\n", i->sysfs_path); if (i->where) @@ -2117,6 +2130,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn i->accept = b; else if (streq(name, "NeedDaemonReload")) i->need_daemon_reload = b; + else if (streq(name, "ConditionResult")) + i->condition_result = b; break; } @@ -2174,6 +2189,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn i->inactive_exit_timestamp = (usec_t) u; else if (streq(name, "ActiveExitTimestamp")) i->active_exit_timestamp = (usec_t) u; + else if (streq(name, "ConditionTimestamp")) + i->condition_timestamp = (usec_t) u; break; } diff --git a/src/unit.c b/src/unit.c index 450b190c0e..117af4df44 100644 --- a/src/unit.c +++ b/src/unit.c @@ -825,6 +825,15 @@ fail: return r; } +bool unit_condition_test(Unit *u) { + assert(u); + + dual_timestamp_get(&u->meta.condition_timestamp); + u->meta.condition_result = condition_test_list(u->meta.conditions); + + return u->meta.condition_result; +} + /* Errors: * -EBADR: This unit type does not support starting. * -EALREADY: Unit is already started. @@ -849,7 +858,7 @@ int unit_start(Unit *u) { return -EALREADY; /* If the conditions failed, don't do anything at all */ - if (!condition_test_list(u->meta.conditions)) { + if (!unit_condition_test(u)) { log_debug("Starting of %s requested but condition failed. Ignoring.", u->meta.id); return -EALREADY; } diff --git a/src/unit.h b/src/unit.h index 5f55a89da8..9b7eb5e854 100644 --- a/src/unit.h +++ b/src/unit.h @@ -160,6 +160,8 @@ struct Meta { /* Conditions to check */ LIST_HEAD(Condition, conditions); + dual_timestamp condition_timestamp; + dual_timestamp inactive_exit_timestamp; dual_timestamp active_enter_timestamp; dual_timestamp active_exit_timestamp; @@ -208,6 +210,9 @@ struct Meta { /* Allow isolation requests */ bool allow_isolate; + /* Did the last condition check suceed? */ + bool condition_result; + bool in_load_queue:1; bool in_dbus_queue:1; bool in_cleanup_queue:1; @@ -513,6 +518,8 @@ bool unit_name_is_valid(const char *n, bool template_ok); void unit_trigger_on_failure(Unit *u); +bool unit_condition_test(Unit *u); + const char *unit_load_state_to_string(UnitLoadState i); UnitLoadState unit_load_state_from_string(const char *s);