core: support unit specifiers in IODeviceWeight= and friends
This commit is contained in:
parent
063c4b1a92
commit
c9f620bfec
2
TODO
2
TODO
|
@ -329,8 +329,6 @@ Features:
|
||||||
* rework fopen_temporary() to make use of open_tmpfile_linkable() (problem: the
|
* rework fopen_temporary() to make use of open_tmpfile_linkable() (problem: the
|
||||||
kernel doesn't support linkat() that replaces existing files, currently)
|
kernel doesn't support linkat() that replaces existing files, currently)
|
||||||
|
|
||||||
* check if DeviceAllow= should split first, resolve specifiers later
|
|
||||||
|
|
||||||
* transient units: don't bother with actually setting unit properties, we
|
* transient units: don't bother with actually setting unit properties, we
|
||||||
reload the unit file anyway
|
reload the unit file anyway
|
||||||
|
|
||||||
|
|
|
@ -3421,11 +3421,10 @@ int config_parse_device_allow(
|
||||||
void *data,
|
void *data,
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
|
|
||||||
_cleanup_free_ char *path = NULL, *t = NULL;
|
_cleanup_free_ char *path = NULL, *resolved = NULL;
|
||||||
CGroupContext *c = data;
|
CGroupContext *c = data;
|
||||||
CGroupDeviceAllow *a;
|
CGroupDeviceAllow *a;
|
||||||
const char *m = NULL;
|
const char *p = rvalue;
|
||||||
size_t n;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (isempty(rvalue)) {
|
if (isempty(rvalue)) {
|
||||||
|
@ -3435,32 +3434,35 @@ int config_parse_device_allow(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = unit_full_printf(userdata, rvalue, &t);
|
r = extract_first_word(&p, &path, NULL, EXTRACT_QUOTES);
|
||||||
|
if (r == -ENOMEM)
|
||||||
|
return log_oom();
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed to resolve specifiers in %s, ignoring: %m",
|
"Invalid syntax, ignoring: %s", rvalue);
|
||||||
rvalue);
|
return 0;
|
||||||
|
}
|
||||||
|
if (r == 0) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
|
"Failed to extract device path and rights from '%s', ignoring.", rvalue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = strcspn(t, WHITESPACE);
|
r = unit_full_printf(userdata, path, &resolved);
|
||||||
|
if (r < 0) {
|
||||||
path = strndup(t, n);
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
if (!path)
|
"Failed to resolve unit specifiers in '%s', ignoring: %m", path);
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
if (!is_deviceallow_pattern(path) &&
|
|
||||||
!path_startswith(path, "/run/systemd/inaccessible/")) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m = t + n + strspn(t + n, WHITESPACE);
|
if (!is_deviceallow_pattern(resolved) &&
|
||||||
if (isempty(m))
|
!path_startswith(resolved, "/run/systemd/inaccessible/")) {
|
||||||
m = "rwm";
|
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!in_charset(m, "rwm")) {
|
if (!isempty(p) && !in_charset(p, "rwm")) {
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device rights '%s'. Ignoring.", m);
|
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device rights '%s', ignoring.", p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3468,10 +3470,10 @@ int config_parse_device_allow(
|
||||||
if (!a)
|
if (!a)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
a->path = TAKE_PTR(path);
|
a->path = TAKE_PTR(resolved);
|
||||||
a->r = !!strchr(m, 'r');
|
a->r = isempty(p) || !!strchr(p, 'r');
|
||||||
a->w = !!strchr(m, 'w');
|
a->w = isempty(p) || !!strchr(p, 'w');
|
||||||
a->m = !!strchr(m, 'm');
|
a->m = isempty(p) || !!strchr(p, 'm');
|
||||||
|
|
||||||
LIST_PREPEND(device_allow, c->device_allow, a);
|
LIST_PREPEND(device_allow, c->device_allow, a);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -3517,12 +3519,11 @@ int config_parse_io_device_weight(
|
||||||
void *data,
|
void *data,
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
|
|
||||||
_cleanup_free_ char *path = NULL;
|
_cleanup_free_ char *path = NULL, *resolved = NULL;
|
||||||
CGroupIODeviceWeight *w;
|
CGroupIODeviceWeight *w;
|
||||||
CGroupContext *c = data;
|
CGroupContext *c = data;
|
||||||
const char *weight;
|
const char *p = rvalue;
|
||||||
uint64_t u;
|
uint64_t u;
|
||||||
size_t n;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(filename);
|
assert(filename);
|
||||||
|
@ -3536,28 +3537,36 @@ int config_parse_io_device_weight(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = strcspn(rvalue, WHITESPACE);
|
r = extract_first_word(&p, &path, NULL, EXTRACT_QUOTES);
|
||||||
weight = rvalue + n;
|
if (r == -ENOMEM)
|
||||||
weight += strspn(weight, WHITESPACE);
|
|
||||||
|
|
||||||
if (isempty(weight)) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Expected block device and device weight. Ignoring.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
path = strndup(rvalue, n);
|
|
||||||
if (!path)
|
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
if (r < 0) {
|
||||||
if (!path_startswith(path, "/dev") &&
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
!path_startswith(path, "/run/systemd/inaccessible/")) {
|
"Invalid syntax, ignoring: %s", rvalue);
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path);
|
return 0;
|
||||||
|
}
|
||||||
|
if (r == 0 || isempty(p)) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
|
"Failed to extract device path and weight from '%s', ignoring.", rvalue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = cg_weight_parse(weight, &u);
|
r = unit_full_printf(userdata, path, &resolved);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r, "IO weight '%s' invalid. Ignoring.", weight);
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
|
"Failed to resolve unit specifiers in '%s', ignoring: %m", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path_startswith(resolved, "/dev") &&
|
||||||
|
!path_startswith(resolved, "/run/systemd/inaccessible/")) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = cg_weight_parse(p, &u);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r, "IO weight '%s' invalid, ignoring: %m", p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3567,8 +3576,7 @@ int config_parse_io_device_weight(
|
||||||
if (!w)
|
if (!w)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
w->path = TAKE_PTR(path);
|
w->path = TAKE_PTR(resolved);
|
||||||
|
|
||||||
w->weight = u;
|
w->weight = u;
|
||||||
|
|
||||||
LIST_PREPEND(device_weights, c->io_device_weights, w);
|
LIST_PREPEND(device_weights, c->io_device_weights, w);
|
||||||
|
@ -3587,13 +3595,12 @@ int config_parse_io_limit(
|
||||||
void *data,
|
void *data,
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
|
|
||||||
_cleanup_free_ char *path = NULL;
|
_cleanup_free_ char *path = NULL, *resolved = NULL;
|
||||||
CGroupIODeviceLimit *l = NULL, *t;
|
CGroupIODeviceLimit *l = NULL, *t;
|
||||||
CGroupContext *c = data;
|
CGroupContext *c = data;
|
||||||
CGroupIOLimitType type;
|
CGroupIOLimitType type;
|
||||||
const char *limit;
|
const char *p = rvalue;
|
||||||
uint64_t num;
|
uint64_t num;
|
||||||
size_t n;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(filename);
|
assert(filename);
|
||||||
|
@ -3609,37 +3616,45 @@ int config_parse_io_limit(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = strcspn(rvalue, WHITESPACE);
|
r = extract_first_word(&p, &path, NULL, EXTRACT_QUOTES);
|
||||||
limit = rvalue + n;
|
if (r == -ENOMEM)
|
||||||
limit += strspn(limit, WHITESPACE);
|
|
||||||
|
|
||||||
if (!*limit) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Expected space separated pair of device node and bandwidth. Ignoring.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
path = strndup(rvalue, n);
|
|
||||||
if (!path)
|
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
if (r < 0) {
|
||||||
if (!path_startswith(path, "/dev") &&
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
!path_startswith(path, "/run/systemd/inaccessible/")) {
|
"Invalid syntax, ignoring: %s", rvalue);
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path);
|
return 0;
|
||||||
|
}
|
||||||
|
if (r == 0 || isempty(p)) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
|
"Failed to extract device node and bandwidth from '%s', ignoring.", rvalue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (streq("infinity", limit)) {
|
r = unit_full_printf(userdata, path, &resolved);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
|
"Failed to resolve unit specifiers in '%s', ignoring: %m", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path_startswith(resolved, "/dev") &&
|
||||||
|
!path_startswith(resolved, "/run/systemd/inaccessible/")) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (streq("infinity", p)) {
|
||||||
num = CGROUP_LIMIT_MAX;
|
num = CGROUP_LIMIT_MAX;
|
||||||
} else {
|
} else {
|
||||||
r = parse_size(limit, 1000, &num);
|
r = parse_size(p, 1000, &num);
|
||||||
if (r < 0 || num <= 0) {
|
if (r < 0 || num <= 0) {
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r, "IO Limit '%s' invalid. Ignoring.", rvalue);
|
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid IO limit '%s', ignoring.", p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LIST_FOREACH(device_limits, t, c->io_device_limits) {
|
LIST_FOREACH(device_limits, t, c->io_device_limits) {
|
||||||
if (path_equal(path, t->path)) {
|
if (path_equal(resolved, t->path)) {
|
||||||
l = t;
|
l = t;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3652,7 +3667,7 @@ int config_parse_io_limit(
|
||||||
if (!l)
|
if (!l)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
l->path = TAKE_PTR(path);
|
l->path = TAKE_PTR(resolved);
|
||||||
for (ttype = 0; ttype < _CGROUP_IO_LIMIT_TYPE_MAX; ttype++)
|
for (ttype = 0; ttype < _CGROUP_IO_LIMIT_TYPE_MAX; ttype++)
|
||||||
l->limits[ttype] = cgroup_io_limit_defaults[ttype];
|
l->limits[ttype] = cgroup_io_limit_defaults[ttype];
|
||||||
|
|
||||||
|
@ -3704,12 +3719,11 @@ int config_parse_blockio_device_weight(
|
||||||
void *data,
|
void *data,
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
|
|
||||||
_cleanup_free_ char *path = NULL;
|
_cleanup_free_ char *path = NULL, *resolved = NULL;
|
||||||
CGroupBlockIODeviceWeight *w;
|
CGroupBlockIODeviceWeight *w;
|
||||||
CGroupContext *c = data;
|
CGroupContext *c = data;
|
||||||
const char *weight;
|
const char *p = rvalue;
|
||||||
uint64_t u;
|
uint64_t u;
|
||||||
size_t n;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(filename);
|
assert(filename);
|
||||||
|
@ -3723,28 +3737,36 @@ int config_parse_blockio_device_weight(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = strcspn(rvalue, WHITESPACE);
|
r = extract_first_word(&p, &path, NULL, EXTRACT_QUOTES);
|
||||||
weight = rvalue + n;
|
if (r == -ENOMEM)
|
||||||
weight += strspn(weight, WHITESPACE);
|
|
||||||
|
|
||||||
if (isempty(weight)) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Expected block device and device weight. Ignoring.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
path = strndup(rvalue, n);
|
|
||||||
if (!path)
|
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
if (r < 0) {
|
||||||
if (!path_startswith(path, "/dev") &&
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
!path_startswith(path, "/run/systemd/inaccessible/")) {
|
"Invalid syntax, ignoring: %s", rvalue);
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path);
|
return 0;
|
||||||
|
}
|
||||||
|
if (r == 0 || isempty(p)) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
|
"Failed to extract device node and weight from '%s', ignoring.", rvalue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = cg_blkio_weight_parse(weight, &u);
|
r = unit_full_printf(userdata, path, &resolved);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r, "Block IO weight '%s' invalid. Ignoring.", weight);
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
|
"Failed to resolve unit specifiers in '%s', ignoring: %m", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path_startswith(resolved, "/dev") &&
|
||||||
|
!path_startswith(resolved, "/run/systemd/inaccessible/")) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", resolved);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = cg_blkio_weight_parse(p, &u);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid block IO weight '%s', ignoring: %m", p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3754,8 +3776,7 @@ int config_parse_blockio_device_weight(
|
||||||
if (!w)
|
if (!w)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
w->path = TAKE_PTR(path);
|
w->path = TAKE_PTR(resolved);
|
||||||
|
|
||||||
w->weight = u;
|
w->weight = u;
|
||||||
|
|
||||||
LIST_PREPEND(device_weights, c->blockio_device_weights, w);
|
LIST_PREPEND(device_weights, c->blockio_device_weights, w);
|
||||||
|
@ -3774,13 +3795,12 @@ int config_parse_blockio_bandwidth(
|
||||||
void *data,
|
void *data,
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
|
|
||||||
_cleanup_free_ char *path = NULL;
|
_cleanup_free_ char *path = NULL, *resolved = NULL;
|
||||||
CGroupBlockIODeviceBandwidth *b = NULL, *t;
|
CGroupBlockIODeviceBandwidth *b = NULL, *t;
|
||||||
CGroupContext *c = data;
|
CGroupContext *c = data;
|
||||||
const char *bandwidth;
|
const char *p = rvalue;
|
||||||
uint64_t bytes;
|
uint64_t bytes;
|
||||||
bool read;
|
bool read;
|
||||||
size_t n;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(filename);
|
assert(filename);
|
||||||
|
@ -3797,33 +3817,41 @@ int config_parse_blockio_bandwidth(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = strcspn(rvalue, WHITESPACE);
|
r = extract_first_word(&p, &path, NULL, EXTRACT_QUOTES);
|
||||||
bandwidth = rvalue + n;
|
if (r == -ENOMEM)
|
||||||
bandwidth += strspn(bandwidth, WHITESPACE);
|
|
||||||
|
|
||||||
if (!*bandwidth) {
|
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Expected space separated pair of device node and bandwidth. Ignoring.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
path = strndup(rvalue, n);
|
|
||||||
if (!path)
|
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
if (r < 0) {
|
||||||
if (!path_startswith(path, "/dev") &&
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
!path_startswith(path, "/run/systemd/inaccessible/")) {
|
"Invalid syntax, ignoring: %s", rvalue);
|
||||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s'. Ignoring.", path);
|
return 0;
|
||||||
|
}
|
||||||
|
if (r == 0 || isempty(p)) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
|
"Failed to extract device node and bandwidth from '%s', ignoring.", rvalue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = parse_size(bandwidth, 1000, &bytes);
|
r = unit_full_printf(userdata, path, &resolved);
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
|
"Failed to resolve unit specifiers in '%s', ignoring: %m", path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path_startswith(resolved, "/dev") &&
|
||||||
|
!path_startswith(resolved, "/run/systemd/inaccessible/")) {
|
||||||
|
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = parse_size(p, 1000, &bytes);
|
||||||
if (r < 0 || bytes <= 0) {
|
if (r < 0 || bytes <= 0) {
|
||||||
log_syntax(unit, LOG_ERR, filename, line, r, "Block IO Bandwidth '%s' invalid. Ignoring.", rvalue);
|
log_syntax(unit, LOG_ERR, filename, line, r, "Invalid Block IO Bandwidth '%s', ignoring.", p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LIST_FOREACH(device_bandwidths, t, c->blockio_device_bandwidths) {
|
LIST_FOREACH(device_bandwidths, t, c->blockio_device_bandwidths) {
|
||||||
if (path_equal(path, t->path)) {
|
if (path_equal(resolved, t->path)) {
|
||||||
b = t;
|
b = t;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3834,7 +3862,7 @@ int config_parse_blockio_bandwidth(
|
||||||
if (!b)
|
if (!b)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
b->path = TAKE_PTR(path);
|
b->path = TAKE_PTR(resolved);
|
||||||
b->rbps = CGROUP_LIMIT_MAX;
|
b->rbps = CGROUP_LIMIT_MAX;
|
||||||
b->wbps = CGROUP_LIMIT_MAX;
|
b->wbps = CGROUP_LIMIT_MAX;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue