mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
Add quota support for DBus
This commit is contained in:
@@ -31,7 +31,9 @@
|
||||
#include "namespace.h"
|
||||
#include "nsflags.h"
|
||||
#include "ordered-set.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "percent-util.h"
|
||||
#include "pcre2-util.h"
|
||||
#include "process-util.h"
|
||||
#include "rlimit-util.h"
|
||||
@@ -1000,6 +1002,22 @@ static int property_get_exec_dir_symlink(
|
||||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
static int property_get_exec_quota(sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
QuotaLimit *q = ASSERT_PTR(userdata);
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
return sd_bus_message_append(reply, "(tus)", q->quota_absolute, q->quota_scale, yes_no(q->quota_enforce));
|
||||
}
|
||||
|
||||
static int property_get_image_policy(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
@@ -1266,12 +1284,18 @@ const sd_bus_vtable bus_exec_vtable[] = {
|
||||
SD_BUS_PROPERTY("RuntimeDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("StateDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("StateDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("StateDirectoryAccounting", "b", bus_property_get_bool, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].exec_quota.quota_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("StateDirectoryQuota", "(tus)", property_get_exec_quota, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].exec_quota), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("StateDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CacheDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CacheDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CacheDirectoryAccounting", "b", bus_property_get_bool, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].exec_quota.quota_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CacheDirectoryQuota", "(tus)", property_get_exec_quota, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].exec_quota), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CacheDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("LogsDirectorySymlink", "a(sst)", property_get_exec_dir_symlink, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("LogsDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("LogsDirectoryAccounting", "b", bus_property_get_bool, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].exec_quota.quota_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("LogsDirectoryQuota", "(tus)", property_get_exec_quota, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].exec_quota), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("LogsDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("ConfigurationDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("ConfigurationDirectory", "as", property_get_exec_dir, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
@@ -1309,6 +1333,60 @@ const sd_bus_vtable bus_exec_vtable[] = {
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
static int property_get_quota_usage(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Unit *u = ASSERT_PTR(userdata);
|
||||
ExecContext *c = ASSERT_PTR(unit_get_exec_context(u));
|
||||
uint64_t current_usage_bytes = UINT64_MAX, limit_bytes = UINT64_MAX;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
|
||||
ExecDirectoryType dt;
|
||||
if (streq(property, "StateDirectoryQuotaUsage"))
|
||||
dt = EXEC_DIRECTORY_STATE;
|
||||
else if (streq(property, "CacheDirectoryQuotaUsage"))
|
||||
dt = EXEC_DIRECTORY_CACHE;
|
||||
else if (streq(property, "LogsDirectoryQuotaUsage"))
|
||||
dt = EXEC_DIRECTORY_LOGS;
|
||||
else
|
||||
assert_not_reached();
|
||||
|
||||
const QuotaLimit *q;
|
||||
q = &c->directories[dt].exec_quota;
|
||||
|
||||
if (q->quota_enforce || q->quota_accounting) {
|
||||
r = unit_get_exec_quota_stats(u, c, dt, ¤t_usage_bytes, &limit_bytes);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!q->quota_enforce)
|
||||
limit_bytes = UINT64_MAX;
|
||||
if (!q->quota_accounting)
|
||||
current_usage_bytes = UINT64_MAX;
|
||||
|
||||
return sd_bus_message_append(reply, "(tt)", current_usage_bytes, limit_bytes);
|
||||
}
|
||||
|
||||
const sd_bus_vtable bus_unit_exec_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
|
||||
SD_BUS_PROPERTY("StateDirectoryQuotaUsage", "(tt)", property_get_quota_usage, 0, 0),
|
||||
SD_BUS_PROPERTY("CacheDirectoryQuotaUsage", "(tt)", property_get_quota_usage, 0, 0),
|
||||
SD_BUS_PROPERTY("LogsDirectoryQuotaUsage", "(tt)", property_get_quota_usage, 0, 0),
|
||||
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
|
||||
int r;
|
||||
|
||||
@@ -2210,6 +2288,15 @@ int bus_exec_context_set_transient_property(
|
||||
if (streq(name, "RuntimeDirectoryMode"))
|
||||
return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_RUNTIME].mode, message, flags, error);
|
||||
|
||||
if (streq(name, "StateDirectoryAccounting"))
|
||||
return bus_set_transient_bool(u, name, &c->directories[EXEC_DIRECTORY_STATE].exec_quota.quota_accounting, message, flags, error);
|
||||
|
||||
if (streq(name, "CacheDirectoryAccounting"))
|
||||
return bus_set_transient_bool(u, name, &c->directories[EXEC_DIRECTORY_CACHE].exec_quota.quota_accounting, message, flags, error);
|
||||
|
||||
if (streq(name, "LogsDirectoryAccounting"))
|
||||
return bus_set_transient_bool(u, name, &c->directories[EXEC_DIRECTORY_LOGS].exec_quota.quota_accounting, message, flags, error);
|
||||
|
||||
if (streq(name, "StateDirectoryMode"))
|
||||
return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_STATE].mode, message, flags, error);
|
||||
|
||||
@@ -3603,6 +3690,47 @@ int bus_exec_context_set_transient_property(
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "StateDirectoryQuota", "CacheDirectoryQuota", "LogsDirectoryQuota")) {
|
||||
uint64_t quota_absolute = UINT64_MAX;
|
||||
uint32_t quota_scale = UINT32_MAX;
|
||||
const char *enforce_flag;
|
||||
int quota_enforce;
|
||||
|
||||
r = sd_bus_message_read(message, "(tus)", "a_absolute, "a_scale, &enforce_flag);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
quota_enforce = parse_boolean(enforce_flag);
|
||||
if (quota_enforce < 0)
|
||||
return quota_enforce;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
ExecDirectoryType dt;
|
||||
if (streq(name, "StateDirectoryQuota"))
|
||||
dt = EXEC_DIRECTORY_STATE;
|
||||
else if (streq(name, "CacheDirectoryQuota"))
|
||||
dt = EXEC_DIRECTORY_CACHE;
|
||||
else if (streq(name, "LogsDirectoryQuota"))
|
||||
dt = EXEC_DIRECTORY_LOGS;
|
||||
else
|
||||
assert_not_reached();
|
||||
|
||||
if (quota_enforce) {
|
||||
c->directories[dt].exec_quota.quota_absolute = quota_absolute;
|
||||
c->directories[dt].exec_quota.quota_scale = quota_scale;
|
||||
|
||||
if (quota_absolute != UINT64_MAX)
|
||||
unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, quota_absolute);
|
||||
else
|
||||
unit_write_settingf(u, flags, name, "%s=%d%%", name, UINT32_SCALE_TO_PERCENT(quota_scale));
|
||||
} else
|
||||
unit_write_settingf(u, flags, name, "%s=", name);
|
||||
|
||||
c->directories[dt].exec_quota.quota_enforce = quota_enforce;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "AppArmorProfile", "SmackProcessLabel")) {
|
||||
int ignore;
|
||||
const char *s;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
SD_BUS_PROPERTY(name, "a(sasasttttuii)", bus_property_get_exec_ex_command_list, offset, flags)
|
||||
|
||||
extern const sd_bus_vtable bus_exec_vtable[];
|
||||
extern const sd_bus_vtable bus_unit_exec_vtable[];
|
||||
|
||||
int bus_property_get_exec_output(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error);
|
||||
int bus_property_get_exec_command(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error);
|
||||
|
||||
@@ -338,9 +338,8 @@ static int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *in
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
static int bus_unit_exec_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
ExecContext *c;
|
||||
Unit *u;
|
||||
int r;
|
||||
|
||||
@@ -356,6 +355,27 @@ static int bus_exec_context_find(sd_bus *bus, const char *path, const char *inte
|
||||
if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
|
||||
return 0;
|
||||
|
||||
if (!UNIT_HAS_EXEC_CONTEXT(u))
|
||||
return 0;
|
||||
|
||||
*found = u;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
|
||||
ExecContext *c;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(path);
|
||||
assert(interface);
|
||||
assert(found);
|
||||
|
||||
Unit *u;
|
||||
r = bus_unit_exec_context_find(bus, path, interface, userdata, (void**) &u, error);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
c = unit_get_exec_context(u);
|
||||
if (!c)
|
||||
return 0;
|
||||
@@ -443,6 +463,7 @@ static const BusObjectImplementation bus_mount_object = {
|
||||
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
|
||||
{ bus_cgroup_vtable, bus_cgroup_context_find },
|
||||
{ bus_exec_vtable, bus_exec_context_find },
|
||||
{ bus_unit_exec_vtable, bus_unit_exec_context_find },
|
||||
{ bus_kill_vtable, bus_kill_context_find }),
|
||||
};
|
||||
|
||||
@@ -471,6 +492,7 @@ static const BusObjectImplementation bus_service_object = {
|
||||
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
|
||||
{ bus_cgroup_vtable, bus_cgroup_context_find },
|
||||
{ bus_exec_vtable, bus_exec_context_find },
|
||||
{ bus_unit_exec_vtable, bus_unit_exec_context_find },
|
||||
{ bus_kill_vtable, bus_kill_context_find }),
|
||||
};
|
||||
|
||||
@@ -491,6 +513,7 @@ static const BusObjectImplementation bus_socket_object = {
|
||||
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
|
||||
{ bus_cgroup_vtable, bus_cgroup_context_find },
|
||||
{ bus_exec_vtable, bus_exec_context_find },
|
||||
{ bus_unit_exec_vtable, bus_unit_exec_context_find },
|
||||
{ bus_kill_vtable, bus_kill_context_find }),
|
||||
};
|
||||
|
||||
@@ -502,6 +525,7 @@ static const BusObjectImplementation bus_swap_object = {
|
||||
{ bus_unit_cgroup_vtable, bus_unit_cgroup_find },
|
||||
{ bus_cgroup_vtable, bus_cgroup_context_find },
|
||||
{ bus_exec_vtable, bus_exec_context_find },
|
||||
{ bus_unit_exec_vtable, bus_unit_exec_context_find },
|
||||
{ bus_kill_vtable, bus_kill_context_find }),
|
||||
};
|
||||
|
||||
@@ -1160,6 +1184,7 @@ void dump_bus_properties(FILE *f) {
|
||||
vtable_dump_bus_properties(f, bus_cgroup_vtable);
|
||||
vtable_dump_bus_properties(f, bus_device_vtable);
|
||||
vtable_dump_bus_properties(f, bus_exec_vtable);
|
||||
vtable_dump_bus_properties(f, bus_unit_exec_vtable);
|
||||
vtable_dump_bus_properties(f, bus_job_vtable);
|
||||
vtable_dump_bus_properties(f, bus_kill_vtable);
|
||||
vtable_dump_bus_properties(f, bus_manager_vtable);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "cgroup-setup.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "chase.h"
|
||||
#include "chattr-util.h"
|
||||
#include "condition.h"
|
||||
#include "dbus-unit.h"
|
||||
#include "dropin.h"
|
||||
@@ -45,6 +46,7 @@
|
||||
#include "mountpoint-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "quota-util.h"
|
||||
#include "rm-rf.h"
|
||||
#include "serialize.h"
|
||||
#include "set.h"
|
||||
@@ -6722,6 +6724,52 @@ static uint64_t unit_get_cpu_weight(Unit *u) {
|
||||
return cc ? cgroup_context_cpu_weight(cc, manager_state(u->manager)) : CGROUP_WEIGHT_DEFAULT;
|
||||
}
|
||||
|
||||
int unit_get_exec_quota_stats(Unit *u, ExecContext *c, ExecDirectoryType dt, uint64_t *ret_usage, uint64_t *ret_limit) {
|
||||
int r;
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
_cleanup_free_ char *p = NULL, *pp = NULL;
|
||||
|
||||
assert(u);
|
||||
assert(c);
|
||||
|
||||
if (c->directories[dt].n_items == 0) {
|
||||
*ret_usage = UINT64_MAX;
|
||||
*ret_limit = UINT64_MAX;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ExecDirectoryItem *i = &c->directories[dt].items[0];
|
||||
p = path_join(u->manager->prefix[dt], i->path);
|
||||
if (!p)
|
||||
return log_oom_debug();
|
||||
|
||||
if (exec_directory_is_private(c, dt)) {
|
||||
pp = path_join(u->manager->prefix[dt], "private", i->path);
|
||||
if (!pp)
|
||||
return log_oom_debug();
|
||||
}
|
||||
|
||||
const char *target_dir = pp ?: p;
|
||||
fd = open(target_dir, O_PATH | O_CLOEXEC | O_DIRECTORY);
|
||||
if (fd < 0)
|
||||
return log_unit_debug_errno(u, errno, "Failed to get exec quota stats: %m");
|
||||
|
||||
uint32_t proj_id;
|
||||
r = read_fs_xattr_fd(fd, /* ret_xflags = */ NULL, &proj_id);
|
||||
if (r < 0)
|
||||
return log_unit_debug_errno(u, r, "Failed to get project ID for exec quota stats: %m");
|
||||
|
||||
struct dqblk req;
|
||||
r = quota_query_proj_id(fd, proj_id, &req);
|
||||
if (r <= 0)
|
||||
return log_unit_debug_errno(u, r, "Failed to query project ID for exec quota stats: %m");
|
||||
|
||||
*ret_usage = req.dqb_curspace;
|
||||
*ret_limit = req.dqb_bhardlimit * QIF_DQBLKSIZE;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int unit_compare_priority(Unit *a, Unit *b) {
|
||||
int ret;
|
||||
|
||||
|
||||
@@ -938,6 +938,8 @@ int unit_add_default_target_dependency(Unit *u, Unit *target);
|
||||
void unit_start_on_termination_deps(Unit *u, UnitDependencyAtom atom);
|
||||
void unit_trigger_notify(Unit *u);
|
||||
|
||||
int unit_get_exec_quota_stats(Unit *u, ExecContext *c, ExecDirectoryType dt, uint64_t *ret_usage, uint64_t *ret_limit);
|
||||
|
||||
UnitFileState unit_get_unit_file_state(Unit *u);
|
||||
PresetAction unit_get_unit_file_preset(Unit *u);
|
||||
|
||||
|
||||
@@ -2059,6 +2059,31 @@ static int bus_append_directory(sd_bus_message *m, const char *field, const char
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bus_append_quota_directory(sd_bus_message *m, const char *field, const char *eq) {
|
||||
uint64_t quota_absolute = UINT64_MAX;
|
||||
uint32_t quota_scale = UINT32_MAX;
|
||||
int quota_enforce = false;
|
||||
int r;
|
||||
|
||||
if (!isempty(eq) && !streq(eq, "off")) {
|
||||
r = parse_permyriad(eq);
|
||||
if (r < 0) {
|
||||
r = parse_size(eq, 1024, "a_absolute);
|
||||
if (r < 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse argument: %s=%s", field, eq);
|
||||
} else
|
||||
quota_scale = UINT32_SCALE_FROM_PERMYRIAD(r);
|
||||
|
||||
quota_enforce = true;
|
||||
}
|
||||
|
||||
r = sd_bus_message_append(m, "(sv)", field, "(tus)", quota_absolute, quota_scale, yes_no(quota_enforce));
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bus_append_protect_hostname(sd_bus_message *m, const char *field, const char *eq) {
|
||||
int r;
|
||||
|
||||
@@ -2514,6 +2539,12 @@ static const BusProperty execute_properties[] = {
|
||||
{ "ProtectControlGroupsEx", bus_append_boolean_or_ex_string }, /* compat */
|
||||
{ "PrivateUsers", bus_append_boolean_or_ex_string },
|
||||
{ "PrivateUsersEx", bus_append_boolean_or_ex_string }, /* compat */
|
||||
{ "StateDirectoryQuota", bus_append_quota_directory },
|
||||
{ "CacheDirectoryQuota", bus_append_quota_directory },
|
||||
{ "LogsDirectoryQuota", bus_append_quota_directory },
|
||||
{ "StateDirectoryAccounting", bus_append_parse_boolean },
|
||||
{ "CacheDirectoryAccounting", bus_append_parse_boolean },
|
||||
{ "LogsDirectoryAccounting", bus_append_parse_boolean },
|
||||
|
||||
{ NULL, bus_try_append_resource_limit, dump_resource_limits },
|
||||
{}
|
||||
|
||||
@@ -784,6 +784,8 @@ CPUSchedulingPriority=
|
||||
CPUSchedulingResetOnFork=
|
||||
CacheDirectory=
|
||||
CacheDirectoryMode=
|
||||
CacheDirectoryAccounting=
|
||||
CacheDirectoryQuota=
|
||||
Capability=
|
||||
Compress=
|
||||
ConfigurationDirectory=
|
||||
@@ -861,6 +863,8 @@ LogRateLimitBurst=
|
||||
LogFilterPatterns=
|
||||
LogsDirectory=
|
||||
LogsDirectoryMode=
|
||||
LogsDirectoryAccounting=
|
||||
LogsDirectoryQuota=
|
||||
MACVLAN=
|
||||
MachineID=
|
||||
MaxFileSec=
|
||||
@@ -943,6 +947,8 @@ StandardInputText=
|
||||
StandardOutput=
|
||||
StateDirectory=
|
||||
StateDirectoryMode=
|
||||
StateDirectoryAccounting=
|
||||
StateDirectoryQuota=
|
||||
Storage=
|
||||
SuspendKeyIgnoreInhibited=
|
||||
SyncIntervalSec=
|
||||
|
||||
Reference in New Issue
Block a user