mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
Add quota support for systemctl
This commit is contained in:
@@ -15,8 +15,10 @@
|
||||
#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"
|
||||
@@ -33,6 +35,7 @@
|
||||
#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"
|
||||
@@ -161,6 +164,13 @@ typedef struct UnitCondition {
|
||||
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;
|
||||
@@ -299,6 +309,9 @@ typedef struct UnitStatusInfo {
|
||||
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;
|
||||
|
||||
@@ -338,6 +351,22 @@ static void format_enable_state(const char *enable_state, const char **enable_on
|
||||
*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,
|
||||
@@ -877,6 +906,9 @@ static void print_status_info(
|
||||
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[] = " ";
|
||||
@@ -1122,6 +1154,25 @@ static int map_exec(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_e
|
||||
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;
|
||||
@@ -1338,6 +1389,27 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
|
||||
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;
|
||||
@@ -2201,6 +2273,9 @@ static int show_one(
|
||||
{ "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 },
|
||||
|
||||
Reference in New Issue
Block a user