Commit 10a94420 authored by Lennart Poettering's avatar Lennart Poettering
Browse files

systemctl: show sub state along active state

parent c2748801
......@@ -93,6 +93,12 @@ static UnitActiveState automount_active_state(Unit *u) {
return state_translation_table[AUTOMOUNT(u)->state];
}
static const char *automount_sub_state_to_string(Unit *u) {
assert(u);
return state_string_table[AUTOMOUNT(u)->state];
}
const UnitVTable automount_vtable = {
.suffix = ".mount",
......@@ -104,5 +110,6 @@ const UnitVTable automount_vtable = {
.dump = automount_dump,
.active_state = automount_active_state
.active_state = automount_active_state,
.sub_state_to_string = automount_sub_state_to_string
};
......@@ -42,7 +42,7 @@
" </method>" \
" <method name=\"ClearJobs\"/>" \
" <method name=\"ListUnits\">" \
" <arg name=\"units\" type=\"a(ssssouso)\" direction=\"out\"/>" \
" <arg name=\"units\" type=\"a(sssssouso)\" direction=\"out\"/>" \
" </method>" \
" <method name=\"ListJobs\">" \
" <arg name=\"jobs\" type=\"a(usssoo)\" direction=\"out\"/>" \
......@@ -234,12 +234,12 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection
dbus_message_iter_init_append(reply, &iter);
if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ssssouso)", &sub))
if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(sssssouso)", &sub))
goto oom;
HASHMAP_FOREACH_KEY(u, k, m->units, i) {
char *u_path, *j_path;
const char *id, *description, *load_state, *active_state, *job_type;
const char *id, *description, *load_state, *active_state, *sub_state, *job_type;
DBusMessageIter sub2;
uint32_t job_id;
......@@ -253,6 +253,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection
description = unit_description(u);
load_state = unit_load_state_to_string(u->meta.load_state);
active_state = unit_active_state_to_string(unit_active_state(u));
sub_state = unit_sub_state_to_string(u);
if (!(u_path = unit_dbus_path(u)))
goto oom;
......@@ -276,6 +277,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &description) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &load_state) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &active_state) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &sub_state) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_OBJECT_PATH, &u_path) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &job_id) ||
!dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &job_type) ||
......
......@@ -49,6 +49,7 @@ static const char introspection[] =
" <property name=\"Description\" type=\"s\" access=\"read\"/>"
" <property name=\"LoadState\" type=\"s\" access=\"read\"/>"
" <property name=\"ActiveState\" type=\"s\" access=\"read\"/>"
" <property name=\"SubState\" type=\"s\" access=\"read\"/>"
" <property name=\"FragmentPath\" type=\"s\" access=\"read\"/>"
" <property name=\"ActiveEnterTimestamp\" type=\"t\" access=\"read\"/>"
" <property name=\"ActiveExitTimestamp\" type=\"t\" access=\"read\"/>"
......@@ -113,6 +114,23 @@ static int bus_unit_append_active_state(Manager *m, DBusMessageIter *i, const ch
return 0;
}
static int bus_unit_append_sub_state(Manager *m, DBusMessageIter *i, const char *property, void *data) {
Unit *u = data;
const char *state;
assert(m);
assert(i);
assert(property);
assert(u);
state = unit_sub_state_to_string(u);
if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
return -ENOMEM;
return 0;
}
static int bus_unit_append_can_reload(Manager *m, DBusMessageIter *i, const char *property, void *data) {
Unit *u = data;
dbus_bool_t b;
......@@ -202,6 +220,7 @@ static DBusHandlerResult bus_unit_message_dispatch(Unit *u, DBusMessage *message
{ "org.freedesktop.systemd1.Unit", "Description", bus_unit_append_description, "s", u },
{ "org.freedesktop.systemd1.Unit", "LoadState", bus_unit_append_load_state, "s", &u->meta.load_state },
{ "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", "ActiveEnterTimestamp", bus_property_append_uint64, "t", &u->meta.active_enter_timestamp },
{ "org.freedesktop.systemd1.Unit", "ActiveExitTimestamp", bus_property_append_uint64, "t", &u->meta.active_exit_timestamp },
......
......@@ -99,6 +99,12 @@ static UnitActiveState device_active_state(Unit *u) {
return state_translation_table[DEVICE(u)->state];
}
static const char *device_sub_state_to_string(Unit *u) {
assert(u);
return state_string_table[DEVICE(u)->state];
}
static int device_add_escaped_name(Unit *u, const char *dn, bool make_id) {
char *e;
int r;
......@@ -478,6 +484,7 @@ const UnitVTable device_vtable = {
.dump = device_dump,
.active_state = device_active_state,
.sub_state_to_string = device_sub_state_to_string,
.enumerate = device_enumerate,
.shutdown = device_shutdown
......
......@@ -720,6 +720,12 @@ static UnitActiveState mount_active_state(Unit *u) {
return state_translation_table[MOUNT(u)->state];
}
static const char *mount_sub_state_to_string(Unit *u) {
assert(u);
return state_string_table[MOUNT(u)->state];
}
static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
Mount *m = MOUNT(u);
bool success;
......@@ -1286,6 +1292,7 @@ const UnitVTable mount_vtable = {
.reload = mount_reload,
.active_state = mount_active_state,
.sub_state_to_string = mount_sub_state_to_string,
.sigchld_event = mount_sigchld_event,
.timer_event = mount_timer_event,
......
......@@ -1638,6 +1638,12 @@ static UnitActiveState service_active_state(Unit *u) {
return state_translation_table[SERVICE(u)->state];
}
static const char *service_sub_state_to_string(Unit *u) {
assert(u);
return service_state_to_string(SERVICE(u)->state);
}
static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
Service *s = SERVICE(u);
bool success;
......@@ -2065,6 +2071,7 @@ const UnitVTable service_vtable = {
.can_reload = service_can_reload,
.active_state = service_active_state,
.sub_state_to_string = service_sub_state_to_string,
.sigchld_event = service_sigchld_event,
.timer_event = service_timer_event,
......
......@@ -711,6 +711,12 @@ static UnitActiveState socket_active_state(Unit *u) {
return state_translation_table[SOCKET(u)->state];
}
static const char *socket_sub_state_to_string(Unit *u) {
assert(u);
return state_string_table[SOCKET(u)->state];
}
static void socket_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
Socket *s = SOCKET(u);
......@@ -894,6 +900,7 @@ const UnitVTable socket_vtable = {
.stop = socket_stop,
.active_state = socket_active_state,
.sub_state_to_string = socket_sub_state_to_string,
.fd_event = socket_fd_event,
.sigchld_event = socket_sigchld_event,
......
......@@ -104,7 +104,7 @@ int main (string[] args) {
uint n = 0;
Posix.qsort(list, list.length, sizeof(Manager.UnitInfo), unit_info_compare);
stdout.printf("%-45s %-6s %-12s %-17s\n", "UNIT", "LOAD", "ACTIVE", "JOB");
stdout.printf("%-45s %-6s %-12s %-12s %-17s\n", "UNIT", "LOAD", "ACTIVE", "SUB", "JOB");
foreach (var i in list) {
......@@ -114,7 +114,7 @@ int main (string[] args) {
if (!all && i.active_state == "inactive")
continue;
stdout.printf("%-45s %-6s %-12s", i.id, i.load_state, i.active_state);
stdout.printf("%-45s %-6s %-12s %-12s", i.id, i.load_state, i.active_state, i.sub_state);
if (i.job_id != 0)
stdout.printf(" → %-15s", i.job_type);
......
......@@ -27,6 +27,7 @@ public interface Manager : DBus.Object {
string description;
string load_state;
string active_state;
string sub_state;
ObjectPath unit_path;
uint32 job_id;
string job_type;
......
......@@ -96,6 +96,12 @@ static UnitActiveState target_active_state(Unit *u) {
return state_translation_table[TARGET(u)->state];
}
static const char *target_sub_state_to_string(Unit *u) {
assert(u);
return state_string_table[TARGET(u)->state];
}
int target_get_runlevel(Target *t) {
static const struct {
......@@ -136,5 +142,6 @@ const UnitVTable target_vtable = {
.start = target_start,
.stop = target_stop,
.active_state = target_active_state
.active_state = target_active_state,
.sub_state_to_string = target_sub_state_to_string
};
......@@ -334,6 +334,12 @@ UnitActiveState unit_active_state(Unit *u) {
return UNIT_VTABLE(u)->active_state(u);
}
const char* unit_sub_state_to_string(Unit *u) {
assert(u);
return UNIT_VTABLE(u)->sub_state_to_string(u);
}
static void complete_move(Set **s, Set **other) {
assert(s);
assert(other);
......
......@@ -236,6 +236,12 @@ struct UnitVTable {
* a simpler one that the engine can understand */
UnitActiveState (*active_state)(Unit *u);
/* Returns the substate specific to this unit type as
* string. This is purely information so that we can give the
* user a more finegrained explanation in which actual state a
* unit is in. */
const char* (*sub_state_to_string)(Unit *u);
void (*fd_event)(Unit *u, int fd, uint32_t events, Watch *w);
void (*sigchld_event)(Unit *u, pid_t pid, int code, int status);
void (*timer_event)(Unit *u, uint64_t n_elapsed, Watch *w);
......@@ -320,6 +326,8 @@ bool unit_has_name(Unit *u, const char *name);
UnitActiveState unit_active_state(Unit *u);
const char* unit_sub_state_to_string(Unit *u);
void unit_dump(Unit *u, FILE *f, const char *prefix);
bool unit_can_reload(Unit *u);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment