#include "cgroup-show.h"
#include "cpu-set-util.h"
#include "errno-util.h"
+#include "exec-directory-util.h"
#include "exec-util.h"
#include "exit-status.h"
+#include "extract-word.h"
#include "format-util.h"
#include "hexdecoct.h"
#include "hostname-setup.h"
#include "pager.h"
#include "parse-util.h"
#include "path-util.h"
+#include "percent-util.h"
#include "pretty-print.h"
#include "process-util.h"
#include "set.h"
LIST_FIELDS(struct UnitCondition, conditions);
} UnitCondition;
+typedef struct QuotaInfo {
+ bool quota_enforce;
+ bool quota_accounting;
+ uint64_t quota_usage;
+ uint64_t quota_limit;
+} QuotaInfo;
+
static UnitCondition* unit_condition_free(UnitCondition *c) {
if (!c)
return NULL;
uint64_t default_memory_low;
uint64_t default_startup_memory_low;
+ /* Exec Quotas */
+ QuotaInfo exec_directories_quota[_EXEC_DIRECTORY_TYPE_MAX];
+
LIST_HEAD(ExecStatusInfo, exec_status_info_list);
} UnitStatusInfo;
*enable_on = *enable_off = "";
}
+static void print_exec_directory_quota(UnitStatusInfo *i, ExecDirectoryType dt) {
+ assert(i);
+
+ if (!IN_SET(dt, EXEC_DIRECTORY_STATE, EXEC_DIRECTORY_CACHE, EXEC_DIRECTORY_LOGS))
+ return;
+
+ if (i->exec_directories_quota[dt].quota_accounting) {
+ printf(" %s: %s", exec_directory_type_to_string(dt), FORMAT_BYTES(i->exec_directories_quota[dt].quota_usage));
+
+ if (i->exec_directories_quota[dt].quota_enforce)
+ printf(" (max: %s)", FORMAT_BYTES(i->exec_directories_quota[dt].quota_limit));
+
+ printf("\n");
+ }
+}
+
static void print_status_info(
sd_bus *bus,
UnitStatusInfo *i,
if (i->cpu_usage_nsec != UINT64_MAX)
printf(" CPU: %s\n", FORMAT_TIMESPAN(i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
+ for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++)
+ print_exec_directory_quota(i, dt);
+
if (i->control_group) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
static const char prefix[] = " ";
return 0;
}
+static int map_quota(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
+ int r;
+ QuotaInfo *qi = ASSERT_PTR(userdata);
+ uint64_t quota_usage, quota_limit;
+
+ r = sd_bus_message_read(m, "(tt)", "a_usage, "a_limit);
+ if (r < 0)
+ return r;
+
+ *qi = (QuotaInfo) {
+ .quota_enforce = quota_limit != UINT64_MAX,
+ .quota_accounting = quota_usage != UINT64_MAX,
+ .quota_usage = quota_usage,
+ .quota_limit = quota_limit
+ };
+
+ return 0;
+}
+
static int print_property(const char *name, const char *expected_value, sd_bus_message *m, BusPrintPropertyFlags flags) {
char bus_type;
const char *contents;
fputc('\n', stdout);
}
return 1;
+ } else if (STR_IN_SET(name, "StateDirectoryQuota", "CacheDirectoryQuota", "LogsDirectoryQuota")) {
+ uint64_t quota_absolute;
+ uint32_t quota_scale;
+ const char *quota_enforce;
+
+ r = sd_bus_message_read(m, "(tus)", "a_absolute, "a_scale, "a_enforce);
+ if (r < 0)
+ return r;
+
+ r = parse_boolean(quota_enforce);
+ if (r < 0)
+ return r;
+
+ if (!r)
+ bus_print_property_value(name, expected_value, flags, "[not set]");
+ else if (quota_absolute != UINT64_MAX)
+ bus_print_property_valuef(name, expected_value, flags, "%" PRIu64, quota_absolute);
+ else
+ bus_print_property_valuef(name, expected_value, flags, "%d%%", UINT32_SCALE_TO_PERCENT(quota_scale));
+
+ return 1;
}
break;
{ "IPEgressBytes", "t", NULL, offsetof(UnitStatusInfo, ip_egress_bytes) },
{ "IOReadBytes", "t", NULL, offsetof(UnitStatusInfo, io_read_bytes) },
{ "IOWriteBytes", "t", NULL, offsetof(UnitStatusInfo, io_write_bytes) },
+ { "StateDirectoryQuotaUsage", "(tt)", map_quota, offsetof(UnitStatusInfo, exec_directories_quota[EXEC_DIRECTORY_STATE]) },
+ { "CacheDirectoryQuotaUsage", "(tt)", map_quota, offsetof(UnitStatusInfo, exec_directories_quota[EXEC_DIRECTORY_CACHE]) },
+ { "LogsDirectoryQuotaUsage", "(tt)", map_quota, offsetof(UnitStatusInfo, exec_directories_quota[EXEC_DIRECTORY_LOGS]) },
{ "ExecCondition", "a(sasbttttuii)", map_exec, 0 },
{ "ExecConditionEx", "a(sasasttttuii)", map_exec, 0 },
{ "ExecStartPre", "a(sasbttttuii)", map_exec, 0 },