mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-11 05:17:44 +03:00
event: when handling SIGCHLD of a child process only reap after dispatching event source
That way the even source callback is run with the zombie process still around so that it can access /proc/$PID/ and similar, and so that it can be sure that the PID has not been reused yet.
This commit is contained in:
parent
e599ba01f5
commit
08cd155254
9
TODO
9
TODO
@ -45,9 +45,11 @@ Features:
|
|||||||
- add field to transient units that indicate whether systemd or somebody else saves/restores its settings, for integration with libvirt
|
- add field to transient units that indicate whether systemd or somebody else saves/restores its settings, for integration with libvirt
|
||||||
- ensure scope units may be started only a single time
|
- ensure scope units may be started only a single time
|
||||||
|
|
||||||
* switch to SipHash for hashmaps/sets?
|
* code cleanup
|
||||||
|
- get rid of readdir_r/dirent_storage stuff, it's unnecessary on Linux
|
||||||
|
- we probably should replace the left-over uses of strv_append() and replace them by strv_push() or strv_extend()
|
||||||
|
|
||||||
* general: get rid of readdir_r/dirent_storage stuff, it's unnecessary on Linux
|
* switch to SipHash for hashmaps/sets?
|
||||||
|
|
||||||
* when we detect low battery and no AC on boot, show pretty splash and refuse boot
|
* when we detect low battery and no AC on boot, show pretty splash and refuse boot
|
||||||
|
|
||||||
@ -71,8 +73,6 @@ Features:
|
|||||||
|
|
||||||
* Add a new Distribute=$NUMBER key to socket units that makes use of SO_REUSEPORT to distribute network traffic on $NUMBER instances
|
* Add a new Distribute=$NUMBER key to socket units that makes use of SO_REUSEPORT to distribute network traffic on $NUMBER instances
|
||||||
|
|
||||||
* we probably should replace the left-over uses of strv_append() and replace them by strv_push() or strv_extend()
|
|
||||||
|
|
||||||
* move config_parse_path_strv() out of conf-parser.c
|
* move config_parse_path_strv() out of conf-parser.c
|
||||||
|
|
||||||
* After coming back from hibernation reset hibernation swap partition using the /dev/snapshot ioctl APIs
|
* After coming back from hibernation reset hibernation swap partition using the /dev/snapshot ioctl APIs
|
||||||
@ -137,7 +137,6 @@ Features:
|
|||||||
but do not return anything up to the event loop caller. Instead
|
but do not return anything up to the event loop caller. Instead
|
||||||
add parameter to sd_event_request_quit() to take retval. This way
|
add parameter to sd_event_request_quit() to take retval. This way
|
||||||
errors rippling upwards are the option, not the default
|
errors rippling upwards are the option, not the default
|
||||||
- child pid handling: first invoke waitid(WNOHANG) and call event handler, only afterwards reap the process
|
|
||||||
- native support for watchdog stuff
|
- native support for watchdog stuff
|
||||||
|
|
||||||
* in the final killing spree, detect processes from the root directory, and
|
* in the final killing spree, detect processes from the root directory, and
|
||||||
|
@ -1555,6 +1555,10 @@ static int process_child(sd_event *e) {
|
|||||||
don't care about. Since this is O(n) this means that if you
|
don't care about. Since this is O(n) this means that if you
|
||||||
have a lot of processes you probably want to handle SIGCHLD
|
have a lot of processes you probably want to handle SIGCHLD
|
||||||
yourself.
|
yourself.
|
||||||
|
|
||||||
|
We do not reap the children here (by using WNOWAIT), this
|
||||||
|
is only done after the event source is dispatched so that
|
||||||
|
the callback still sees the process as a zombie.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
HASHMAP_FOREACH(s, e->child_sources, i) {
|
HASHMAP_FOREACH(s, e->child_sources, i) {
|
||||||
@ -1567,11 +1571,27 @@ static int process_child(sd_event *e) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
zero(s->child.siginfo);
|
zero(s->child.siginfo);
|
||||||
r = waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|s->child.options);
|
r = waitid(P_PID, s->child.pid, &s->child.siginfo,
|
||||||
|
WNOHANG | (s->child.options & WEXITED ? WNOWAIT : 0) | s->child.options);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (s->child.siginfo.si_pid != 0) {
|
if (s->child.siginfo.si_pid != 0) {
|
||||||
|
bool zombie =
|
||||||
|
s->child.siginfo.si_code == CLD_EXITED ||
|
||||||
|
s->child.siginfo.si_code == CLD_KILLED ||
|
||||||
|
s->child.siginfo.si_code == CLD_DUMPED;
|
||||||
|
|
||||||
|
if (!zombie && (s->child.options & WEXITED)) {
|
||||||
|
/* If the child isn't dead then let's
|
||||||
|
* immediately remove the state change
|
||||||
|
* from the queue, since there's no
|
||||||
|
* benefit in leaving it queued */
|
||||||
|
|
||||||
|
assert(s->child.options & (WSTOPPED|WCONTINUED));
|
||||||
|
waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|(s->child.options & (WSTOPPED|WCONTINUED)));
|
||||||
|
}
|
||||||
|
|
||||||
r = source_set_pending(s, true);
|
r = source_set_pending(s, true);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -1625,7 +1645,6 @@ static int process_signal(sd_event *e, uint32_t events) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1667,9 +1686,21 @@ static int source_dispatch(sd_event_source *s) {
|
|||||||
r = s->signal.callback(s, &s->signal.siginfo, s->userdata);
|
r = s->signal.callback(s, &s->signal.siginfo, s->userdata);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SOURCE_CHILD:
|
case SOURCE_CHILD: {
|
||||||
|
bool zombie;
|
||||||
|
|
||||||
|
zombie = s->child.siginfo.si_code == CLD_EXITED ||
|
||||||
|
s->child.siginfo.si_code == CLD_KILLED ||
|
||||||
|
s->child.siginfo.si_code == CLD_DUMPED;
|
||||||
|
|
||||||
r = s->child.callback(s, &s->child.siginfo, s->userdata);
|
r = s->child.callback(s, &s->child.siginfo, s->userdata);
|
||||||
|
|
||||||
|
/* Now, reap the PID for good. */
|
||||||
|
if (zombie)
|
||||||
|
waitid(P_PID, s->child.pid, &s->child.siginfo, WNOHANG|WEXITED);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case SOURCE_DEFER:
|
case SOURCE_DEFER:
|
||||||
r = s->defer.callback(s, s->userdata);
|
r = s->defer.callback(s, s->userdata);
|
||||||
|
Loading…
Reference in New Issue
Block a user