Skip to content

Commit

Permalink
tree-wide: increase granularity of percent specifications all over th…
Browse files Browse the repository at this point in the history
…e place to permille

We so far had various placed we'd parse percentages with
parse_percent(). Let's make them use parse_permille() instead, which is
downward compatible (as it also parses percent values), and increases
the granularity a bit. Given that on the wire we usually normalize
relative specifications to something like UINT32_MAX anyway changing
from base-100 to base-1000 calculations can be done easily without
breaking compat.

This commit doesn't document this change in the man pages. While
allowing more precise specifcations permille is not as commonly
understood as perent I guess, hence let's keep this out of the docs for
now.

(cherry picked from commit f806dfd)

Resolves: #2178179
  • Loading branch information
poettering authored and systemd-rhel-bot committed Jun 14, 2023
1 parent cb99c3e commit 30343fc
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 21 deletions.
12 changes: 6 additions & 6 deletions src/core/load-fragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -2991,13 +2991,13 @@ int config_parse_cpu_quota(
return 0;
}

r = parse_percent_unbounded(rvalue);
r = parse_permille_unbounded(rvalue);
if (r <= 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid CPU quota '%s', ignoring.", rvalue);
return 0;
}

c->cpu_quota_per_sec_usec = ((usec_t) r * USEC_PER_SEC) / 100U;
c->cpu_quota_per_sec_usec = ((usec_t) r * USEC_PER_SEC) / 1000U;
return 0;
}

Expand Down Expand Up @@ -3057,15 +3057,15 @@ int config_parse_memory_limit(

if (!isempty(rvalue) && !streq(rvalue, "infinity")) {

r = parse_percent(rvalue);
r = parse_permille(rvalue);
if (r < 0) {
r = parse_size(rvalue, 1024, &bytes);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid memory limit '%s', ignoring: %m", rvalue);
return 0;
}
} else
bytes = physical_memory_scale(r, 100U);
bytes = physical_memory_scale(r, 1000U);

if (bytes >= UINT64_MAX ||
(bytes <= 0 && !STR_IN_SET(lvalue, "MemorySwapMax", "MemoryLow", "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin"))) {
Expand Down Expand Up @@ -3132,15 +3132,15 @@ int config_parse_tasks_max(
return 0;
}

r = parse_percent(rvalue);
r = parse_permille(rvalue);
if (r < 0) {
r = safe_atou64(rvalue, &v);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid maximum tasks value '%s', ignoring: %m", rvalue);
return 0;
}
} else
v = system_tasks_max_scale(r, 100U);
v = system_tasks_max_scale(r, 1000U);

if (v <= 0 || v >= UINT64_MAX) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Maximum tasks value '%s' out of range, ignoring.", rvalue);
Expand Down
6 changes: 3 additions & 3 deletions src/login/logind-user.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,9 +794,9 @@ int config_parse_tmpfs_size(
assert(data);

/* First, try to parse as percentage */
r = parse_percent(rvalue);
if (r > 0 && r < 100)
*sz = physical_memory_scale(r, 100U);
r = parse_permille(rvalue);
if (r > 0 && r < 1000)
*sz = physical_memory_scale(r, 1000U);
else {
uint64_t k;

Expand Down
4 changes: 2 additions & 2 deletions src/login/pam_systemd.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,9 @@ static int append_session_memory_max(pam_handle_t *handle, sd_bus_message *m, co
return r;
}
} else {
r = parse_percent(limit);
r = parse_permille(limit);
if (r >= 0) {
r = sd_bus_message_append(m, "(sv)", "MemoryMaxScale", "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U));
r = sd_bus_message_append(m, "(sv)", "MemoryMaxScale", "u", (uint32_t) (((uint64_t) r * UINT32_MAX) / 1000U));
if (r < 0) {
pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror(-r));
return r;
Expand Down
22 changes: 12 additions & 10 deletions src/shared/bus-unit-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -440,16 +440,16 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
return 1;
}

r = parse_percent(eq);
r = parse_permille(eq);
if (r >= 0) {
char *n;

/* When this is a percentage we'll convert this into a relative value in the range
* 0…UINT32_MAX and pass it in the MemoryLowScale property (and related
* ones). This way the physical memory size can be determined server-side */
/* When this is a percentage we'll convert this into a relative value in the range 0…UINT32_MAX
* and pass it in the MemoryLowScale property (and related ones). This way the physical memory
* size can be determined server-side. */

n = strjoina(field, "Scale");
r = sd_bus_message_append(m, "(sv)", n, "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U));
r = sd_bus_message_append(m, "(sv)", n, "u", (uint32_t) (((uint64_t) r * UINT32_MAX) / 1000U));
if (r < 0)
return bus_log_create_error(r);

Expand All @@ -467,13 +467,15 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
if (isempty(eq))
r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", USEC_INFINITY);
else {
r = parse_percent_unbounded(eq);
if (r <= 0) {
log_error_errno(r, "CPU quota '%s' invalid.", eq);
return -EINVAL;
r = parse_permille_unbounded(eq);
if (r == 0) {
log_error("CPU quota too small.");
return -ERANGE;
}
if (r < 0)
return log_error_errno(r, "CPU quota '%s' invalid.", eq);

r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", (usec_t) r * USEC_PER_SEC / 100U);
r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", (((uint64_t) r * USEC_PER_SEC) / 1000U));
}

if (r < 0)
Expand Down

0 comments on commit 30343fc

Please sign in to comment.