summaryrefslogtreecommitdiff
path: root/src/core/unit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/unit.c')
-rw-r--r--src/core/unit.c53
1 files changed, 46 insertions, 7 deletions
diff --git a/src/core/unit.c b/src/core/unit.c
index 3bfc2460bc..3a6313e4a2 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -452,6 +452,7 @@ static void unit_free_requires_mounts_for(Unit *u) {
static void unit_done(Unit *u) {
ExecContext *ec;
CGroupContext *cc;
+ int r;
assert(u);
@@ -468,6 +469,10 @@ static void unit_done(Unit *u) {
cc = unit_get_cgroup_context(u);
if (cc)
cgroup_context_done(cc);
+
+ r = unit_remove_from_netclass_cgroup(u);
+ if (r < 0)
+ log_warning_errno(r, "Unable to remove unit from netclass group: %m");
}
void unit_free(Unit *u) {
@@ -1241,6 +1246,14 @@ int unit_load(Unit *u) {
}
unit_update_cgroup_members_masks(u);
+
+ /* If we are reloading, we need to wait for the deserializer
+ * to restore the net_cls ids that have been set previously */
+ if (u->manager->n_reloading <= 0) {
+ r = unit_add_to_netclass_cgroup(u);
+ if (r < 0)
+ return r;
+ }
}
assert((u->load_state != UNIT_MERGED) == !u->merged_into);
@@ -2591,6 +2604,9 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
unit_serialize_item(u, f, "cgroup", u->cgroup_path);
unit_serialize_item(u, f, "cgroup-realized", yes_no(u->cgroup_realized));
+ if (u->cgroup_netclass_id)
+ unit_serialize_item_format(u, f, "netclass-id", "%" PRIu32, u->cgroup_netclass_id);
+
if (serialize_jobs) {
if (u->job) {
fprintf(f, "job\n");
@@ -2778,6 +2794,17 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
u->cgroup_realized = b;
continue;
+ } else if (streq(l, "netclass-id")) {
+ r = safe_atou32(v, &u->cgroup_netclass_id);
+ if (r < 0)
+ log_unit_debug(u, "Failed to parse netclass ID %s, ignoring.", v);
+ else {
+ r = unit_add_to_netclass_cgroup(u);
+ if (r < 0)
+ log_unit_debug_errno(u, r, "Failed to add unit to netclass cgroup, ignoring: %m");
+ }
+
+ continue;
}
if (unit_can_serialize(u)) {
@@ -3037,32 +3064,39 @@ int unit_kill_common(
sd_bus_error *error) {
int r = 0;
+ bool killed = false;
- if (who == KILL_MAIN) {
+ if (IN_SET(who, KILL_MAIN, KILL_MAIN_FAIL)) {
if (main_pid < 0)
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type));
else if (main_pid == 0)
return sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
}
- if (who == KILL_CONTROL) {
+ if (IN_SET(who, KILL_CONTROL, KILL_CONTROL_FAIL)) {
if (control_pid < 0)
return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type));
else if (control_pid == 0)
return sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
}
- if (who == KILL_CONTROL || who == KILL_ALL)
- if (control_pid > 0)
+ if (IN_SET(who, KILL_CONTROL, KILL_CONTROL_FAIL, KILL_ALL, KILL_ALL_FAIL))
+ if (control_pid > 0) {
if (kill(control_pid, signo) < 0)
r = -errno;
+ else
+ killed = true;
+ }
- if (who == KILL_MAIN || who == KILL_ALL)
- if (main_pid > 0)
+ if (IN_SET(who, KILL_MAIN, KILL_MAIN_FAIL, KILL_ALL, KILL_ALL_FAIL))
+ if (main_pid > 0) {
if (kill(main_pid, signo) < 0)
r = -errno;
+ else
+ killed = true;
+ }
- if (who == KILL_ALL && u->cgroup_path) {
+ if (IN_SET(who, KILL_ALL, KILL_ALL_FAIL) && u->cgroup_path) {
_cleanup_set_free_ Set *pid_set = NULL;
int q;
@@ -3074,8 +3108,13 @@ int unit_kill_common(
q = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, signo, false, false, false, pid_set);
if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
r = q;
+ else
+ killed = true;
}
+ if (r == 0 && !killed && IN_SET(who, KILL_ALL_FAIL, KILL_CONTROL_FAIL, KILL_ALL_FAIL))
+ return -ESRCH;
+
return r;
}