mirror of
https://github.com/systemd/systemd.git
synced 2024-11-01 00:51:24 +03:00
core: make IOSchedulingClass= and IOSchedulingPriority= settable for transient units
This patch is a bit more complex thant I hoped. In particular the single IOScheduling= property exposed on the bus is split up into IOSchedulingClass= and IOSchedulingPriority= (though compat is retained). Otherwise the asymmetry between setting props and getting them is a bit too nasty. Fixes #5613
This commit is contained in:
parent
f52b982cc9
commit
7f452159b8
@ -905,6 +905,23 @@ int pid_compare_func(const void *a, const void *b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ioprio_parse_priority(const char *s, int *ret) {
|
||||
int i, r;
|
||||
|
||||
assert(s);
|
||||
assert(ret);
|
||||
|
||||
r = safe_atoi(s, &i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!ioprio_priority_is_valid(i))
|
||||
return -EINVAL;
|
||||
|
||||
*ret = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *const ioprio_class_table[] = {
|
||||
[IOPRIO_CLASS_NONE] = "none",
|
||||
[IOPRIO_CLASS_RT] = "realtime",
|
||||
|
@ -25,10 +25,11 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "format-util.h"
|
||||
#include "ioprio.h"
|
||||
#include "macro.h"
|
||||
|
||||
#define procfs_file_alloca(pid, field) \
|
||||
@ -108,3 +109,13 @@ int pid_compare_func(const void *a, const void *b);
|
||||
static inline bool nice_is_valid(int n) {
|
||||
return n >= PRIO_MIN && n < PRIO_MAX;
|
||||
}
|
||||
|
||||
static inline bool ioprio_class_is_valid(int i) {
|
||||
return IN_SET(i, IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE);
|
||||
}
|
||||
|
||||
static inline bool ioprio_priority_is_valid(int i) {
|
||||
return i >= 0 && i < IOPRIO_BE_NR;
|
||||
}
|
||||
|
||||
int ioprio_parse_priority(const char *s, int *ret);
|
||||
|
@ -160,21 +160,51 @@ static int property_get_ioprio(
|
||||
|
||||
|
||||
ExecContext *c = userdata;
|
||||
int32_t n;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
assert(c);
|
||||
|
||||
if (c->ioprio_set)
|
||||
n = c->ioprio;
|
||||
else {
|
||||
n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
|
||||
if (n < 0)
|
||||
n = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
|
||||
}
|
||||
return sd_bus_message_append(reply, "i", exec_context_get_effective_ioprio(c));
|
||||
}
|
||||
|
||||
return sd_bus_message_append(reply, "i", n);
|
||||
static int property_get_ioprio_class(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
|
||||
ExecContext *c = userdata;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
assert(c);
|
||||
|
||||
return sd_bus_message_append(reply, "i", IOPRIO_PRIO_CLASS(exec_context_get_effective_ioprio(c)));
|
||||
}
|
||||
|
||||
|
||||
static int property_get_ioprio_priority(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
|
||||
ExecContext *c = userdata;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
assert(c);
|
||||
|
||||
return sd_bus_message_append(reply, "i", IOPRIO_PRIO_DATA(exec_context_get_effective_ioprio(c)));
|
||||
}
|
||||
|
||||
static int property_get_cpu_sched_policy(
|
||||
@ -762,7 +792,8 @@ const sd_bus_vtable bus_exec_vtable[] = {
|
||||
SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
@ -784,7 +815,6 @@ const sd_bus_vtable bus_exec_vtable[] = {
|
||||
SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("AmbientCapabilities", "t", property_get_ambient_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
@ -794,9 +824,6 @@ const sd_bus_vtable bus_exec_vtable[] = {
|
||||
SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(ExecContext, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("ReadWritePaths", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("ReadOnlyPaths", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("InaccessiblePaths", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
@ -831,6 +858,14 @@ const sd_bus_vtable bus_exec_vtable[] = {
|
||||
SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool, offsetof(ExecContext, mount_apivfs), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
|
||||
/* Obsolete/redundant properties: */
|
||||
SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
@ -1050,6 +1085,50 @@ int bus_exec_context_set_transient_property(
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "IOSchedulingClass")) {
|
||||
int32_t q;
|
||||
|
||||
r = sd_bus_message_read(message, "i", &q);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!ioprio_class_is_valid(q))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling class: %i", q);
|
||||
|
||||
if (mode != UNIT_CHECK) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
|
||||
r = ioprio_class_to_string_alloc(q, &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c->ioprio = IOPRIO_PRIO_VALUE(q, IOPRIO_PRIO_DATA(c->ioprio));
|
||||
c->ioprio_set = true;
|
||||
|
||||
unit_write_drop_in_private_format(u, mode, name, "IOSchedulingClass=%s", s);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "IOSchedulingPriority")) {
|
||||
int32_t p;
|
||||
|
||||
r = sd_bus_message_read(message, "i", &p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!ioprio_priority_is_valid(p))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling priority: %i", p);
|
||||
|
||||
if (mode != UNIT_CHECK) {
|
||||
c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), p);
|
||||
c->ioprio_set = true;
|
||||
|
||||
unit_write_drop_in_private_format(u, mode, name, "IOSchedulingPriority=%i", p);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "TTYPath", "RootDirectory", "RootImage")) {
|
||||
const char *s;
|
||||
|
||||
|
@ -3701,6 +3701,21 @@ bool exec_context_maintains_privileges(ExecContext *c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int exec_context_get_effective_ioprio(ExecContext *c) {
|
||||
int p;
|
||||
|
||||
assert(c);
|
||||
|
||||
if (c->ioprio_set)
|
||||
return c->ioprio;
|
||||
|
||||
p = ioprio_get(IOPRIO_WHO_PROCESS, 0);
|
||||
if (p < 0)
|
||||
return IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 4);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void exec_status_start(ExecStatus *s, pid_t pid) {
|
||||
assert(s);
|
||||
|
||||
|
@ -307,6 +307,8 @@ const char* exec_context_fdname(const ExecContext *c, int fd_index);
|
||||
bool exec_context_may_touch_console(ExecContext *c);
|
||||
bool exec_context_maintains_privileges(ExecContext *c);
|
||||
|
||||
int exec_context_get_effective_ioprio(ExecContext *c);
|
||||
|
||||
void exec_status_start(ExecStatus *s, pid_t pid);
|
||||
void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status);
|
||||
void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix);
|
||||
|
@ -940,8 +940,8 @@ int config_parse_exec_io_priority(const char *unit,
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = safe_atoi(rvalue, &i);
|
||||
if (r < 0 || i < 0 || i >= IOPRIO_BE_NR) {
|
||||
r = ioprio_parse_priority(rvalue, &i);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse IO priority, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
@ -389,6 +389,24 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
|
||||
|
||||
r = sd_bus_message_append(m, "v", "i", (int32_t) n);
|
||||
|
||||
} else if (streq(field, "IOSchedulingClass")) {
|
||||
int c;
|
||||
|
||||
c = ioprio_class_from_string(eq);
|
||||
if (c < 0)
|
||||
return log_error_errno(r, "Failed to parse IO scheduling class: %s", eq);
|
||||
|
||||
r = sd_bus_message_append(m, "v", "i", (int32_t) c);
|
||||
|
||||
} else if (streq(field, "IOSchedulingPriority")) {
|
||||
int q;
|
||||
|
||||
r = ioprio_parse_priority(eq, &q);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse IO scheduling priority: %s", eq);
|
||||
|
||||
r = sd_bus_message_append(m, "v", "i", (int32_t) q);
|
||||
|
||||
} else if (STR_IN_SET(field, "Environment", "PassEnvironment")) {
|
||||
const char *p;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user