mirror of
https://github.com/systemd/systemd.git
synced 2025-03-31 14:50:15 +03:00
core: fix support for transient resource limit properties
Make sure we can properly process resource limit properties. Specifically, allow transient configuration of both the soft and hard limit, the same way from the unit files. Previously, only the the hard rlimits could be configured but they'd implicitly spill into the soft hard rlimits. This also updates the client-side code to be able to parse hard/soft resource limit specifications. Since we need to serialize two properties in bus_append_unit_property_assignment() now, the marshalling of the container around it is now moved into the function itself. This has the benefit of shortening the calling code. As a side effect this now beefs up the rlimit parser of "systemctl set-property" to understand time and disk sizes where that's appropriate.
This commit is contained in:
parent
fb8a9fc9b5
commit
cab2aca3e7
@ -835,7 +835,8 @@ int bus_exec_context_set_transient_property(
|
||||
UnitSetPropertiesMode mode,
|
||||
sd_bus_error *error) {
|
||||
|
||||
int r;
|
||||
const char *soft = NULL;
|
||||
int r, ri;
|
||||
|
||||
assert(u);
|
||||
assert(c);
|
||||
@ -1492,7 +1493,23 @@ int bus_exec_context_set_transient_property(
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (rlimit_from_string(name) >= 0) {
|
||||
}
|
||||
|
||||
ri = rlimit_from_string(name);
|
||||
if (ri < 0) {
|
||||
soft = endswith(name, "Soft");
|
||||
if (soft) {
|
||||
const char *n;
|
||||
|
||||
n = strndupa(name, soft - name);
|
||||
ri = rlimit_from_string(n);
|
||||
if (ri >= 0)
|
||||
name = n;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (ri >= 0) {
|
||||
uint64_t rl;
|
||||
rlim_t x;
|
||||
|
||||
@ -1510,22 +1527,36 @@ int bus_exec_context_set_transient_property(
|
||||
}
|
||||
|
||||
if (mode != UNIT_CHECK) {
|
||||
int z;
|
||||
_cleanup_free_ char *f = NULL;
|
||||
struct rlimit nl;
|
||||
|
||||
z = rlimit_from_string(name);
|
||||
if (c->rlimit[ri]) {
|
||||
nl = *c->rlimit[ri];
|
||||
|
||||
if (!c->rlimit[z]) {
|
||||
c->rlimit[z] = new(struct rlimit, 1);
|
||||
if (!c->rlimit[z])
|
||||
if (soft)
|
||||
nl.rlim_cur = x;
|
||||
else
|
||||
nl.rlim_max = x;
|
||||
} else
|
||||
/* When the resource limit is not initialized yet, then assign the value to both fields */
|
||||
nl = (struct rlimit) {
|
||||
.rlim_cur = x,
|
||||
.rlim_max = x,
|
||||
};
|
||||
|
||||
r = rlimit_format(&nl, &f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (c->rlimit[ri])
|
||||
*c->rlimit[ri] = nl;
|
||||
else {
|
||||
c->rlimit[ri] = newdup(struct rlimit, &nl, 1);
|
||||
if (!c->rlimit[ri])
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
c->rlimit[z]->rlim_cur = c->rlimit[z]->rlim_max = x;
|
||||
|
||||
if (x == RLIM_INFINITY)
|
||||
unit_write_drop_in_private_format(u, mode, name, "%s=infinity\n", name);
|
||||
else
|
||||
unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64 "\n", name, rl);
|
||||
unit_write_drop_in_private_format(u, mode, name, "%s=%s\n", name, f);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -166,17 +166,9 @@ int register_machine(
|
||||
}
|
||||
|
||||
STRV_FOREACH(i, properties) {
|
||||
r = sd_bus_message_open_container(m, 'r', "sv");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = bus_append_unit_property_assignment(m, *i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_close_container(m);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
}
|
||||
|
||||
r = sd_bus_message_close_container(m);
|
||||
|
@ -422,17 +422,9 @@ static int transient_unit_set_properties(sd_bus_message *m, char **properties) {
|
||||
return r;
|
||||
|
||||
STRV_FOREACH(i, properties) {
|
||||
r = sd_bus_message_open_container(m, 'r', "sv");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = bus_append_unit_property_assignment(m, *i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_close_container(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1398,7 +1398,7 @@ int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
|
||||
|
||||
int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) {
|
||||
const char *eq, *field;
|
||||
int r;
|
||||
int r, rl;
|
||||
|
||||
assert(m);
|
||||
assert(assignment);
|
||||
@ -1409,6 +1409,10 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
field = strndupa(assignment, eq - assignment);
|
||||
eq ++;
|
||||
|
||||
@ -1430,20 +1434,14 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
return 0;
|
||||
goto finish;
|
||||
|
||||
} else if (streq(field, "EnvironmentFile")) {
|
||||
|
||||
r = sd_bus_message_append(m, "sv", "EnvironmentFiles", "a(sb)", 1,
|
||||
eq[0] == '-' ? eq + 1 : eq,
|
||||
eq[0] == '-');
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
return 0;
|
||||
goto finish;
|
||||
|
||||
} else if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec")) {
|
||||
char *n;
|
||||
@ -1461,17 +1459,38 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
|
||||
/* Change suffix Sec → USec */
|
||||
strcpy(mempcpy(n, field, l - 3), "USec");
|
||||
r = sd_bus_message_append(m, "sv", n, "t", t);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
return 0;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
if (STR_IN_SET(field,
|
||||
rl = rlimit_from_string(field);
|
||||
if (rl >= 0) {
|
||||
const char *sn;
|
||||
struct rlimit l;
|
||||
|
||||
r = rlimit_parse(rl, eq, &l);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse resource limit: %s", eq);
|
||||
|
||||
r = sd_bus_message_append(m, "v", "t", l.rlim_max);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_close_container(m);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
sn = strjoina(field, "Soft");
|
||||
r = sd_bus_message_append(m, "sv", sn, "t", l.rlim_cur);
|
||||
|
||||
} else if (STR_IN_SET(field,
|
||||
"CPUAccounting", "MemoryAccounting", "BlockIOAccounting", "TasksAccounting",
|
||||
"SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies",
|
||||
"IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit",
|
||||
@ -1652,21 +1671,6 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
|
||||
r = sd_bus_message_append(m, "v", "a(st)", path, u);
|
||||
}
|
||||
|
||||
} else if (rlimit_from_string(field) >= 0) {
|
||||
uint64_t rl;
|
||||
|
||||
if (streq(eq, "infinity"))
|
||||
rl = (uint64_t) -1;
|
||||
else {
|
||||
r = safe_atou64(eq, &rl);
|
||||
if (r < 0) {
|
||||
log_error("Invalid resource limit: %s", eq);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_bus_message_append(m, "v", "t", rl);
|
||||
|
||||
} else if (streq(field, "Nice")) {
|
||||
int32_t i;
|
||||
|
||||
@ -1849,6 +1853,11 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
finish:
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_close_container(m);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
|
@ -4873,17 +4873,9 @@ static int set_property(int argc, char *argv[], void *userdata) {
|
||||
return bus_log_create_error(r);
|
||||
|
||||
STRV_FOREACH(i, strv_skip(argv, 2)) {
|
||||
r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = bus_append_unit_property_assignment(m, *i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_close_container(m);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
}
|
||||
|
||||
r = sd_bus_message_close_container(m);
|
||||
|
Loading…
x
Reference in New Issue
Block a user