diff options
author | Mike Yuan <me@yhndnzj.com> | 2023-01-13 16:52:29 +0800 |
---|---|---|
committer | Mike Yuan <me@yhndnzj.com> | 2023-01-16 19:46:52 +0800 |
commit | 372997694446f26ffdedc95a14278cd5b3d2b73d (patch) | |
tree | 769def8a2edd08531aa7c8aa78b94732b27dc4cf | |
parent | 8e481bd29258274b4d92737d4b11636eabfffcb5 (diff) | |
download | systemd-372997694446f26ffdedc95a14278cd5b3d2b73d.tar.gz |
systemctl: list-dependencies: support --type= and --state=
Closes #25975
-rw-r--r-- | man/systemctl.xml | 14 | ||||
-rw-r--r-- | src/systemctl/systemctl-list-dependencies.c | 29 | ||||
-rw-r--r-- | src/systemctl/systemctl-util.c | 29 | ||||
-rw-r--r-- | src/systemctl/systemctl-util.h | 3 | ||||
-rwxr-xr-x | test/units/testsuite-26.sh | 3 |
5 files changed, 69 insertions, 9 deletions
diff --git a/man/systemctl.xml b/man/systemctl.xml index bd64e430c3..04b2e9813d 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -354,6 +354,10 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err dependencies. If no units are specified, <filename>default.target</filename> is implied.</para> + <para>The units that are shown are additionally filtered by <option>--type=</option> and + <option>--state=</option> if those options are specified. Note that we won't be able to + use a tree structure in this case, so <option>--plain</option> is implied.</para> + <para>By default, only target units are recursively expanded. When <option>--all</option> is passed, all other units are recursively expanded as well.</para> @@ -1657,8 +1661,8 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err <listitem> <para>The argument is a comma-separated list of unit types such as <option>service</option> and <option>socket</option>. When units are listed with <command>list-units</command>, - <command>show</command>, or <command>status</command>, only units of the specified types will be - shown. By default, units of all types are shown.</para> + <command>list-dependencies</command>, <command>show</command>, or <command>status</command>, + only units of the specified types will be shown. By default, units of all types are shown.</para> <para>As a special case, if one of the arguments is <option>help</option>, a list of allowed values will be printed and the program will exit.</para> @@ -1670,9 +1674,9 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err <listitem> <para>The argument is a comma-separated list of unit LOAD, SUB, or ACTIVE states. When listing - units with <command>list-units</command>, <command>show</command>, or <command>status</command>, - show only those in the specified states. Use <option>--state=failed</option> or - <option>--failed</option> to show only failed units.</para> + units with <command>list-units</command>, <command>list-dependencies</command>, <command>show</command> + or <command>status</command>, show only those in the specified states. Use <option>--state=failed</option> + or <option>--failed</option> to show only failed units.</para> <para>As a special case, if one of the arguments is <option>help</option>, a list of allowed values will be printed and the program will exit.</para> diff --git a/src/systemctl/systemctl-list-dependencies.c b/src/systemctl/systemctl-list-dependencies.c index 91b8ac6bff..6878954268 100644 --- a/src/systemctl/systemctl-list-dependencies.c +++ b/src/systemctl/systemctl-list-dependencies.c @@ -80,6 +80,9 @@ static int list_dependencies_one( typesafe_qsort(deps, strv_length(deps), list_dependencies_compare); STRV_FOREACH(c, deps) { + _cleanup_free_ char *load_state = NULL, *sub_state = NULL; + UnitActiveState active_state; + if (strv_contains(*units, *c)) { if (!arg_plain) { printf(" "); @@ -90,14 +93,31 @@ static int list_dependencies_one( continue; } + if (arg_types && !strv_contains(arg_types, unit_type_suffix(*c))) + continue; + + r = get_state_one_unit(bus, *c, &active_state); + if (r < 0) + return r; + + if (arg_states) { + r = unit_load_state(bus, *c, &load_state); + if (r < 0) + return r; + + r = get_sub_state_one_unit(bus, *c, &sub_state); + if (r < 0) + return r; + + if (!strv_overlap(arg_states, STRV_MAKE(unit_active_state_to_string(active_state), load_state, sub_state))) + continue; + } + if (arg_plain) printf(" "); else { - UnitActiveState active_state = _UNIT_ACTIVE_STATE_INVALID; const char *on; - (void) get_state_one_unit(bus, *c, &active_state); - switch (active_state) { case UNIT_ACTIVE: case UNIT_RELOADING: @@ -141,6 +161,9 @@ int verb_list_dependencies(int argc, char *argv[], void *userdata) { sd_bus *bus; int r; + /* We won't be able to preserve the tree structure if --type= or --state= is used */ + arg_plain = arg_plain || arg_types || arg_states; + r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) return r; diff --git a/src/systemctl/systemctl-util.c b/src/systemctl/systemctl-util.c index b333850bec..bcad65f8dc 100644 --- a/src/systemctl/systemctl-util.c +++ b/src/systemctl/systemctl-util.c @@ -122,6 +122,7 @@ int get_state_one_unit(sd_bus *bus, const char *unit, UnitActiveState *ret_activ UnitActiveState state; int r; + assert(bus); assert(unit); assert(ret_active_state); @@ -148,6 +149,34 @@ int get_state_one_unit(sd_bus *bus, const char *unit, UnitActiveState *ret_activ return 0; } +int get_sub_state_one_unit(sd_bus *bus, const char *unit, char **ret_sub_state) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_free_ char *sub_state = NULL, *dbus_path = NULL; + int r; + + assert(bus); + assert(unit); + assert(ret_sub_state); + + dbus_path = unit_dbus_path_from_name(unit); + if (!dbus_path) + return log_oom(); + + r = sd_bus_get_property_string( + bus, + "org.freedesktop.systemd1", + dbus_path, + "org.freedesktop.systemd1.Unit", + "SubState", + &error, + &sub_state); + if (r < 0) + return log_error_errno(r, "Failed to retrieve unit sub state: %s", bus_error_message(&error, r)); + + *ret_sub_state = TAKE_PTR(sub_state); + return 0; +} + int get_unit_list( sd_bus *bus, const char *machine, diff --git a/src/systemctl/systemctl-util.h b/src/systemctl/systemctl-util.h index 6445bb4887..317bab75b7 100644 --- a/src/systemctl/systemctl-util.h +++ b/src/systemctl/systemctl-util.h @@ -21,7 +21,8 @@ void polkit_agent_open_maybe(void); int translate_bus_error_to_exit_status(int r, const sd_bus_error *error); -int get_state_one_unit(sd_bus *bus, const char *name, UnitActiveState *ret_active_state); +int get_state_one_unit(sd_bus *bus, const char *unit, UnitActiveState *ret_active_state); +int get_sub_state_one_unit(sd_bus *bus, const char *unit, char **ret_sub_state); int get_unit_list(sd_bus *bus, const char *machine, char **patterns, UnitInfo **unit_infos, int c, sd_bus_message **ret_reply); int expand_unit_names(sd_bus *bus, char **names, const char* suffix, char ***ret, bool *ret_expanded); diff --git a/test/units/testsuite-26.sh b/test/units/testsuite-26.sh index a89d089e12..dc2c7f5004 100755 --- a/test/units/testsuite-26.sh +++ b/test/units/testsuite-26.sh @@ -99,6 +99,9 @@ systemctl list-jobs --after systemctl list-jobs --before systemctl list-jobs --after --before systemctl list-jobs "*" +systemctl list-dependencies sysinit.target --type=socket,mount +systemctl list-dependencies multi-user.target --state=active +systemctl list-dependencies sysinit.target --state=mounted --all # is-* verbs # Should return 4 for a missing unit file |