* hook emergency.target into local-fs.target in some way as OnFailure with isolate
-* convince Karel to give us our own mount option prefix
-
Features:
-* show failure error string in "systemctl status"
+* introduce "x-systemd-automount" as alternative to the "comment=systemd.automount" mount option
-* send SIGCONT before SIGTERM
+* show failure error string in "systemctl status"
* make sure timeouts are applied to Type=oneshot services.
return r < 0 ? -errno : 0;
}
-int cg_kill(const char *controller, const char *path, int sig, bool ignore_self, Set *s) {
+int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s) {
bool done = false;
int r, ret = 0;
pid_t my_pid;
if (kill(pid, sig) < 0) {
if (ret >= 0 && errno != ESRCH)
ret = -errno;
- } else if (ret == 0)
+ } else if (ret == 0) {
+
+ if (sigcont)
+ kill(pid, SIGCONT);
+
ret = 1;
+ }
done = false;
return ret;
}
-int cg_kill_recursive(const char *controller, const char *path, int sig, bool ignore_self, bool rem, Set *s) {
+int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool rem, Set *s) {
int r, ret = 0;
DIR *d = NULL;
char *fn;
if (!(s = allocated_set = set_new(trivial_hash_func, trivial_compare_func)))
return -ENOMEM;
- ret = cg_kill(controller, path, sig, ignore_self, s);
+ ret = cg_kill(controller, path, sig, sigcont, ignore_self, s);
if ((r = cg_enumerate_subgroups(controller, path, &d)) < 0) {
if (ret >= 0 && r != -ENOENT)
goto finish;
}
- r = cg_kill_recursive(controller, p, sig, ignore_self, rem, s);
+ r = cg_kill_recursive(controller, p, sig, sigcont, ignore_self, rem, s);
free(p);
if (r != 0 && ret >= 0)
else
sig = 0;
- if ((r = cg_kill_recursive(controller, path, sig, true, rem, NULL)) <= 0)
+ if ((r = cg_kill_recursive(controller, path, sig, true, true, rem, NULL)) <= 0)
return r;
usleep(200 * USEC_PER_MSEC);
int cg_enumerate_subgroups(const char *controller, const char *path, DIR **_d);
int cg_read_subgroup(DIR *d, char **fn);
-int cg_kill(const char *controller, const char *path, int sig, bool ignore_self, Set *s);
-int cg_kill_recursive(const char *controller, const char *path, int sig, bool ignore_self, bool remove, Set *s);
+int cg_kill(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, Set *s);
+int cg_kill_recursive(const char *controller, const char *path, int sig, bool sigcont, bool ignore_self, bool remove, Set *s);
int cg_kill_recursive_and_wait(const char *controller, const char *path, bool remove);
int cg_migrate(const char *controller, const char *from, const char *to, bool ignore_self);
return 0;
}
-int cgroup_bonding_kill(CGroupBonding *b, int sig, Set *s) {
+int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s) {
assert(b);
assert(sig >= 0);
if (!b->realized || !b->ours)
return 0;
- return cg_kill_recursive(b->controller, b->path, sig, true, false, s);
+ return cg_kill_recursive(b->controller, b->path, sig, sigcont, true, false, s);
}
-int cgroup_bonding_kill_list(CGroupBonding *first, int sig, Set *s) {
+int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s) {
CGroupBonding *b;
Set *allocated_set = NULL;
int ret = -EAGAIN, r;
return -ENOMEM;
LIST_FOREACH(by_unit, b, first) {
- if ((r = cgroup_bonding_kill(b, sig, s)) < 0) {
+ if ((r = cgroup_bonding_kill(b, sig, sigcont, s)) < 0) {
if (r == -EAGAIN || r == -ESRCH)
continue;
int cgroup_bonding_install(CGroupBonding *b, pid_t pid);
int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid);
-int cgroup_bonding_kill(CGroupBonding *b, int sig, Set *s);
-int cgroup_bonding_kill_list(CGroupBonding *first, int sig, Set *s);
+int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s);
+int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s);
void cgroup_bonding_trim(CGroupBonding *first, bool delete_root);
void cgroup_bonding_trim_list(CGroupBonding *first, bool delete_root);
closelog();
- if (pam_pid > 1)
+ if (pam_pid > 1) {
kill(pam_pid, SIGTERM);
+ kill(pam_pid, SIGCONT);
+ }
return EXIT_PAM;
}
state == MOUNT_REMOUNTING_SIGTERM) ? m->exec_context.kill_signal : SIGKILL;
if (m->control_pid > 0) {
- if (kill(m->exec_context.kill_mode == KILL_PROCESS_GROUP ?
- -m->control_pid :
- m->control_pid, sig) < 0 && errno != ESRCH)
+ if (kill_and_sigcont(m->exec_context.kill_mode == KILL_PROCESS_GROUP ?
+ -m->control_pid :
+ m->control_pid, sig) < 0 && errno != ESRCH)
log_warning("Failed to kill control process %li: %m", (long) m->control_pid);
else
if ((r = set_put(pid_set, LONG_TO_PTR(m->control_pid))) < 0)
goto fail;
- if ((r = cgroup_bonding_kill_list(m->meta.cgroup_bondings, sig, pid_set)) < 0) {
+ if ((r = cgroup_bonding_kill_list(m->meta.cgroup_bondings, sig, true, pid_set)) < 0) {
if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
log_warning("Failed to kill control group: %s", strerror(-r));
} else if (r > 0)
goto finish;
}
- if ((q = cgroup_bonding_kill_list(m->meta.cgroup_bondings, signo, pid_set)) < 0)
+ if ((q = cgroup_bonding_kill_list(m->meta.cgroup_bondings, signo, false, pid_set)) < 0)
if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
r = q;
}
int sig = (state == SERVICE_STOP_SIGTERM || state == SERVICE_FINAL_SIGTERM) ? s->exec_context.kill_signal : SIGKILL;
if (s->main_pid > 0) {
- if (kill(s->exec_context.kill_mode == KILL_PROCESS_GROUP ?
- -s->main_pid :
- s->main_pid, sig) < 0 && errno != ESRCH)
+ if (kill_and_sigcont(s->exec_context.kill_mode == KILL_PROCESS_GROUP ?
+ -s->main_pid :
+ s->main_pid, sig) < 0 && errno != ESRCH)
log_warning("Failed to kill main process %li: %m", (long) s->main_pid);
else
}
if (s->control_pid > 0) {
- if (kill(s->exec_context.kill_mode == KILL_PROCESS_GROUP ?
- -s->control_pid :
- s->control_pid, sig) < 0 && errno != ESRCH)
+ if (kill_and_sigcont(s->exec_context.kill_mode == KILL_PROCESS_GROUP ?
+ -s->control_pid :
+ s->control_pid, sig) < 0 && errno != ESRCH)
log_warning("Failed to kill control process %li: %m", (long) s->control_pid);
else
if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0)
goto fail;
- if ((r = cgroup_bonding_kill_list(s->meta.cgroup_bondings, sig, pid_set)) < 0) {
+ if ((r = cgroup_bonding_kill_list(s->meta.cgroup_bondings, sig, true, pid_set)) < 0) {
if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
log_warning("Failed to kill control group: %s", strerror(-r));
} else if (r > 0)
goto finish;
}
- if ((q = cgroup_bonding_kill_list(s->meta.cgroup_bondings, signo, pid_set)) < 0)
+ if ((q = cgroup_bonding_kill_list(s->meta.cgroup_bondings, signo, false, pid_set)) < 0)
if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
r = q;
}
int sig = (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_FINAL_SIGTERM) ? s->exec_context.kill_signal : SIGKILL;
if (s->control_pid > 0) {
- if (kill(s->exec_context.kill_mode == KILL_PROCESS_GROUP ?
- -s->control_pid :
- s->control_pid, sig) < 0 && errno != ESRCH)
+ if (kill_and_sigcont(s->exec_context.kill_mode == KILL_PROCESS_GROUP ?
+ -s->control_pid :
+ s->control_pid, sig) < 0 && errno != ESRCH)
log_warning("Failed to kill control process %li: %m", (long) s->control_pid);
else
if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0)
goto fail;
- if ((r = cgroup_bonding_kill_list(s->meta.cgroup_bondings, sig, pid_set)) < 0) {
+ if ((r = cgroup_bonding_kill_list(s->meta.cgroup_bondings, sig, true, pid_set)) < 0) {
if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
log_warning("Failed to kill control group: %s", strerror(-r));
} else if (r > 0)
goto finish;
}
- if ((q = cgroup_bonding_kill_list(s->meta.cgroup_bondings, signo, pid_set)) < 0)
+ if ((q = cgroup_bonding_kill_list(s->meta.cgroup_bondings, signo, false, pid_set)) < 0)
if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
r = q;
}
state == SWAP_DEACTIVATING_SIGTERM) ? s->exec_context.kill_signal : SIGKILL;
if (s->control_pid > 0) {
- if (kill(s->exec_context.kill_mode == KILL_PROCESS_GROUP ?
- -s->control_pid :
- s->control_pid, sig) < 0 && errno != ESRCH)
+ if (kill_and_sigcont(s->exec_context.kill_mode == KILL_PROCESS_GROUP ?
+ -s->control_pid :
+ s->control_pid, sig) < 0 && errno != ESRCH)
log_warning("Failed to kill control process %li: %m", (long) s->control_pid);
else
if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0)
goto fail;
- if ((r = cgroup_bonding_kill_list(s->meta.cgroup_bondings, sig, pid_set)) < 0) {
+ if ((r = cgroup_bonding_kill_list(s->meta.cgroup_bondings, sig, true, pid_set)) < 0) {
if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
log_warning("Failed to kill control group: %s", strerror(-r));
} else if (r > 0)
goto finish;
}
- if ((q = cgroup_bonding_kill_list(s->meta.cgroup_bondings, signo, pid_set)) < 0)
+ if ((q = cgroup_bonding_kill_list(s->meta.cgroup_bondings, signo, false, pid_set)) < 0)
if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
r = q;
}
/* Inform pager that we are done */
fclose(stdout);
+ kill(pager_pid, SIGCONT);
wait_for_terminate(pager_pid, &dummy);
pager_pid = 0;
}
/* Inform agent that we are done */
kill(agent_pid, SIGTERM);
+ kill(agent_pid, SIGCONT);
wait_for_terminate(agent_pid, &dummy);
agent_pid = 0;
}
assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", false) > 0);
assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", false) == 0);
- assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0, false, false, NULL) == 0);
- assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0, false, false, NULL) > 0);
+ assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0, false, false, false, NULL) == 0);
+ assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0, false, false, false, NULL) > 0);
assert_se(cg_migrate_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", "/test-a", false, false) > 0);
assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", false) == 0);
assert_se(cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", false) > 0);
- assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0, false, false, NULL) > 0);
- assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0, false, false, NULL) == 0);
+ assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-a", 0, false, false, false, NULL) > 0);
+ assert_se(cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, "/test-b", 0, false, false, false, NULL) == 0);
cg_trim(SYSTEMD_CGROUP_CONTROLLER, "/", false);
hashmap_free_free(pids);
}
+int kill_and_sigcont(pid_t pid, int sig) {
+ int r;
+
+ r = kill(pid, sig) < 0 ? -errno : 0;
+
+ if (r >= 0)
+ kill(pid, SIGCONT);
+
+ return r;
+}
+
static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_NONE] = "none",
[IOPRIO_CLASS_RT] = "realtime",
void execute_directory(const char *directory, DIR *_d, char *argv[]);
+int kill_and_sigcont(pid_t pid, int sig);
+
#define NULSTR_FOREACH(i, l) \
for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)