core: Unit Runtime in io.systemd.Unit.List method
This commit is contained in:
+117
-1
@@ -2,6 +2,10 @@
|
||||
|
||||
#include "sd-json.h"
|
||||
|
||||
#include "bitfield.h"
|
||||
#include "condition.h"
|
||||
#include "execute.h"
|
||||
#include "install.h"
|
||||
#include "json-util.h"
|
||||
#include "manager.h"
|
||||
#include "set.h"
|
||||
@@ -183,6 +187,115 @@ static int unit_context_build_json(sd_json_variant **ret, const char *name, void
|
||||
// Socket context
|
||||
}
|
||||
|
||||
static int can_clean_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
ExecCleanMask mask;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
r = unit_can_clean(u, &mask);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to check if unit can be cleaned: %m");
|
||||
|
||||
for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) {
|
||||
if (!BIT_SET(mask, t))
|
||||
continue;
|
||||
|
||||
r = sd_json_variant_append_arrayb(&v, SD_JSON_BUILD_STRING(exec_resource_type_to_string(t)));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(mask, EXEC_CLEAN_FDSTORE)) {
|
||||
r = sd_json_variant_append_arrayb(&v, SD_JSON_BUILD_STRING("fdstore"));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int markers_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
unsigned *markers = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
BIT_FOREACH(m, *markers) {
|
||||
r = sd_json_variant_append_arrayb(&v, SD_JSON_BUILD_STRING(unit_marker_to_string(m)));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int activation_details_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
const ActivationDetails *activation_details = userdata;
|
||||
_cleanup_strv_free_ char **pairs = NULL;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
/* activation_details_append_pair() gracefully takes activation_details==NULL */
|
||||
r = activation_details_append_pair(activation_details, &pairs);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get activation details: %m");
|
||||
|
||||
STRV_FOREACH_PAIR(key, value, pairs) {
|
||||
r = sd_json_variant_append_arraybo(&v,
|
||||
SD_JSON_BUILD_PAIR_STRING("type", *key),
|
||||
SD_JSON_BUILD_PAIR_STRING("name", *value));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unit_runtime_build_json(sd_json_variant **ret, const char *name, void *userdata) {
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
Unit *f = unit_following(u);
|
||||
|
||||
return sd_json_buildo(
|
||||
ASSERT_PTR(ret),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("Following", f ? f->id : NULL),
|
||||
SD_JSON_BUILD_PAIR_STRING("LoadState", unit_load_state_to_string(u->load_state)),
|
||||
SD_JSON_BUILD_PAIR_STRING("ActiveState", unit_active_state_to_string(unit_active_state(u))),
|
||||
SD_JSON_BUILD_PAIR_STRING("FreezerState", freezer_state_to_string(u->freezer_state)),
|
||||
SD_JSON_BUILD_PAIR_STRING("SubState", unit_sub_state_to_string(u)),
|
||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("UnitFileState", unit_file_state_to_string(unit_get_unit_file_state(u))),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("StateChangeTimestamp", &u->state_change_timestamp),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("ActiveEnterTimestamp", &u->active_enter_timestamp),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("ActiveExitTimestamp", &u->active_exit_timestamp),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("InactiveEnterTimestamp", &u->inactive_enter_timestamp),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("InactiveExitTimestamp", &u->inactive_exit_timestamp),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("CanStart", unit_can_start_refuse_manual(u)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("CanStop", unit_can_stop_refuse_manual(u)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("CanReload", unit_can_reload(u)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("CanIsolate", unit_can_isolate_refuse_manual(u)),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("CanClean", can_clean_build_json, u),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("CanFreeze", unit_can_freeze(u)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("CanLiveMount", unit_can_live_mount(u, /* error= */ NULL) >= 0),
|
||||
JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("JobId", u->job ? u->job->id : 0),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("NeedDaemonReload", unit_need_daemon_reload(u)),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("ConditionResult", u->condition_result),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("AssertResult", u->assert_result),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("ConditionTimestamp", &u->condition_timestamp),
|
||||
JSON_BUILD_PAIR_DUAL_TIMESTAMP_NON_NULL("AssertTimestamp", &u->assert_timestamp),
|
||||
SD_JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(u->invocation_id), "InvocationID", SD_JSON_BUILD_UUID(u->invocation_id)),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("Markers", markers_build_json, &u->markers),
|
||||
JSON_BUILD_PAIR_CALLBACK_NON_NULL("ActivationDetails", activation_details_build_json, u->activation_details),
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("DebugInvocation", u->debug_invocation));
|
||||
}
|
||||
|
||||
static int list_unit_one(sd_varlink *link, Unit *unit, bool more) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
int r;
|
||||
@@ -190,7 +303,10 @@ static int list_unit_one(sd_varlink *link, Unit *unit, bool more) {
|
||||
assert(link);
|
||||
assert(unit);
|
||||
|
||||
r = sd_json_buildo(&v, SD_JSON_BUILD_PAIR_CALLBACK("context", unit_context_build_json, unit));
|
||||
r = sd_json_buildo(
|
||||
&v,
|
||||
SD_JSON_BUILD_PAIR_CALLBACK("context", unit_context_build_json, unit),
|
||||
SD_JSON_BUILD_PAIR_CALLBACK("runtime", unit_runtime_build_json, unit));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -154,13 +154,81 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("Whether this unit is perpetual"),
|
||||
SD_VARLINK_DEFINE_FIELD(Perpetual, SD_VARLINK_BOOL, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
ActivationDetails,
|
||||
SD_VARLINK_FIELD_COMMENT("Trigger unit type"),
|
||||
SD_VARLINK_DEFINE_FIELD(type, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Trigger unit name"),
|
||||
SD_VARLINK_DEFINE_FIELD(name, SD_VARLINK_STRING, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
UnitRuntime,
|
||||
SD_VARLINK_FIELD_COMMENT("If not empty, the field contains the name of another unit that this unit follows in state"),
|
||||
SD_VARLINK_DEFINE_FIELD(Following, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the configuration file of this unit has been loaded"),
|
||||
SD_VARLINK_DEFINE_FIELD(LoadState, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the unit is currently active or not"),
|
||||
SD_VARLINK_DEFINE_FIELD(ActiveState, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the unit is currently frozen or not"),
|
||||
SD_VARLINK_DEFINE_FIELD(FreezerState, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflect more fine-grained state that is unit-type-specific"),
|
||||
SD_VARLINK_DEFINE_FIELD(SubState, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects the install state of the unit file"),
|
||||
SD_VARLINK_DEFINE_FIELD(UnitFileState, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Timestamp when the firmware first began execution"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(StateChangeTimestamp, Timestamp, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Timestamp when the unit entered active state"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(ActiveEnterTimestamp, Timestamp, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Timestamp when the unit exited active state"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(ActiveExitTimestamp, Timestamp, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Timestamp when the unit entered inactive state"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(InactiveEnterTimestamp, Timestamp, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Timestamp when the unit exited inactive state"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(InactiveExitTimestamp, Timestamp, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the unit can be started or not"),
|
||||
SD_VARLINK_DEFINE_FIELD(CanStart, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the unit can be stopped or not"),
|
||||
SD_VARLINK_DEFINE_FIELD(CanStop, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the unit can be reloaded or not"),
|
||||
SD_VARLINK_DEFINE_FIELD(CanReload, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the unit may be started in isolation mode"),
|
||||
SD_VARLINK_DEFINE_FIELD(CanIsolate, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Returns which unit resources can be cleaned up"),
|
||||
SD_VARLINK_DEFINE_FIELD(CanClean, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Whether the unit supports the freeze operation"),
|
||||
SD_VARLINK_DEFINE_FIELD(CanFreeze, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Whether the unit supports live mounting"),
|
||||
SD_VARLINK_DEFINE_FIELD(CanLiveMount, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("The job ID of the job currently scheduled or being executed for this unit, if there is any."),
|
||||
SD_VARLINK_DEFINE_FIELD(JobId, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Whether the configuration file this unit is loaded from (i.e. FragmentPath or SourcePath) has changed since the configuration was read and hence whether a configuration reload is recommended"),
|
||||
SD_VARLINK_DEFINE_FIELD(NeedDaemonReload, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Condition result of the last time the configured conditions of this unit were checked"),
|
||||
SD_VARLINK_DEFINE_FIELD(ConditionResult, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Assert result of the last time the configured asserts of this unit were checked"),
|
||||
SD_VARLINK_DEFINE_FIELD(AssertResult, SD_VARLINK_BOOL, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("The last time the configured conditions of the unit have been checked"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(ConditionTimestamp, Timestamp, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The last time the configured asserts of the unit have been checked"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(AssertTimestamp, Timestamp, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Current invocation ID"),
|
||||
SD_VARLINK_DEFINE_FIELD(InvocationID, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether the unit has been marked for reload, restart, etc."),
|
||||
SD_VARLINK_DEFINE_FIELD(Markers, SD_VARLINK_STRING, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Provides details about why a unit was activated"),
|
||||
SD_VARLINK_DEFINE_FIELD_BY_TYPE(ActivationDetails, ActivationDetails, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("When true, logs about this unit will be at debug level regardless of other log level settings"),
|
||||
SD_VARLINK_DEFINE_FIELD(DebugInvocation, SD_VARLINK_BOOL, 0));
|
||||
|
||||
static SD_VARLINK_DEFINE_ERROR(NoSuchUnit);
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD_FULL(
|
||||
List,
|
||||
SD_VARLINK_SUPPORTS_MORE,
|
||||
SD_VARLINK_FIELD_COMMENT("Configuration of the unit"),
|
||||
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(context, UnitContext, 0));
|
||||
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(context, UnitContext, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Runtime information of the unit"),
|
||||
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(runtime, UnitRuntime, 0));
|
||||
|
||||
SD_VARLINK_DEFINE_INTERFACE(
|
||||
io_systemd_Unit,
|
||||
@@ -172,5 +240,11 @@ SD_VARLINK_DEFINE_INTERFACE(
|
||||
&vl_type_Condition,
|
||||
SD_VARLINK_SYMBOL_COMMENT("An object to represent a unit's context"),
|
||||
&vl_type_UnitContext,
|
||||
SD_VARLINK_SYMBOL_COMMENT("An object to represent a unit's runtime information"),
|
||||
&vl_type_UnitRuntime,
|
||||
SD_VARLINK_SYMBOL_COMMENT("A timestamp object consisting of both CLOCK_REALTIME and CLOCK_MONOTONIC timestamps"),
|
||||
&vl_type_Timestamp,
|
||||
SD_VARLINK_SYMBOL_COMMENT("An object to represent a unit's activation details"),
|
||||
&vl_type_ActivationDetails,
|
||||
SD_VARLINK_SYMBOL_COMMENT("No matching unit found"),
|
||||
&vl_error_NoSuchUnit);
|
||||
|
||||
Reference in New Issue
Block a user