Bug 277764 - daemon(8): high CPU usage after stopping and continuing child process
Summary: daemon(8): high CPU usage after stopping and continuing child process
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: Konstantin Belousov
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-03-17 19:21 UTC by 5mxnbm6q5
Modified: 2024-04-05 15:23 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description 5mxnbm6q5 2024-03-17 19:21:30 UTC
Using daemon utility to execute a program (child) and then sending a stop signal (ex. SIGSTOP) to the child process and afterwards sending the continue signal (SIGCONT) can make the daemon process get stuck at 100% CPU usage.

Full setup:
create a script test.sh containing the following:
```
#!/bin/sh

while true; do echo hello; sleep 1; done
```
execute daemon utility: `daemon -f -p test.pid ./test.sh`
send stop signal: `pkill -STOP -F test.pid`
send continue signal: `pkill -CONT -F test.pid`
wait until test.sh executes `echo hello`
daemon process rises to 100% usage (single core)


As far as i can tell stopping and continuing the child process sends a SIGCHLD signal and the daemon utility assumes that the child is closing. It then keeps calling waitpid (which returns immediately, returning 0) inside an infinite loop in the daemon_is_child_dead function and this causes the high CPU usage. Also before entering daemon_is_child_dead function, the daemon process is waiting / listening for child output in the listen_child function. That's why the above script contains an echo so the daemon will exit that function and go on to process the SIGCHLD event.

Maybe the fix could be to include WCONTINUED option and setting status output parameter (currently set to NULL) when calling waitpid inside daemon_is_child_dead and then checking if WIFCONTINUED(status) equals True and in that case returning false?
Comment 1 Konstantin Belousov freebsd_committer freebsd_triage 2024-03-18 08:49:28 UTC
https://reviews.freebsd.org/D44401
Comment 2 commit-hook freebsd_committer freebsd_triage 2024-03-20 01:07:52 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=8eaa6be80d6aef6a118fa854a860bfdaeb7ed753

commit 8eaa6be80d6aef6a118fa854a860bfdaeb7ed753
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-03-18 08:44:39 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-03-20 01:07:00 +0000

    daemon(8): handle case of waitpid() returning without exited child

    Not checking for either WIFEXITED(status) or zero result results in
    never finishing the loop.

    PR:     277764
    Reviewed by:    kevans (previous version)
    Discussed with: Daniel Tameling
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D44401

 usr.sbin/daemon/daemon.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
Comment 3 commit-hook freebsd_committer freebsd_triage 2024-03-27 08:27:51 UTC
A commit in branch stable/14 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=daefc4bda7c5a9728ec62eddcfd9af492531a7f8

commit daefc4bda7c5a9728ec62eddcfd9af492531a7f8
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-03-18 08:44:39 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-03-27 08:27:23 +0000

    daemon(8): handle case of waitpid() returning without exited child

    PR:     277764

    (cherry picked from commit 8eaa6be80d6aef6a118fa854a860bfdaeb7ed753)

 usr.sbin/daemon/daemon.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
Comment 4 commit-hook freebsd_committer freebsd_triage 2024-03-27 08:28:55 UTC
A commit in branch stable/13 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=1d2a587ef9f8310da6a9203bd1fff43d61ca66f7

commit 1d2a587ef9f8310da6a9203bd1fff43d61ca66f7
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-03-18 08:44:39 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-03-27 08:27:52 +0000

    daemon(8): handle case of waitpid() returning without exited child

    PR:     277764

    (cherry picked from commit 8eaa6be80d6aef6a118fa854a860bfdaeb7ed753)

 usr.sbin/daemon/daemon.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
Comment 5 Mark Linimon freebsd_committer freebsd_triage 2024-04-05 09:55:58 UTC
^Triage: assign to committer who also MFCed.