Hi,

I have an issue with acpid.

What happens is that acpid start consume 100% cpu of the core it uses.
quad core so it shows 25% in top.

  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
 1552     1 root     R     7908   0%   5  25% /sbin/acpid -l /var/log/acpid
 2507     1 ncopa    S     876m  11%   4   0% /usr/lib/firefox-8.0.1/firefox
 2416     1 ncopa    S     316m   4%   0   0% xfdesktop
...

It also does not repond to any signals except SIGKILL.

When attaching with strace:
poll([{fd=3, events=POLLIN}, {fd=4, events=POLLIN}, {fd=5,
events=POLLIN}, {fd=6, events=POLLIN}, {fd=7, events=POLLIN}, {fd=8,
events=POLLIN}], 6, -1) = 1 ([{fd=5, revents=POLLIN|POLLERR|POLLHUP}])
read(5, 0x7fffed179ee0, 24)             = -1 ENODEV (No such device)
poll([{fd=3, events=POLLIN}, {fd=4, events=POLLIN}, {fd=5,
events=POLLIN}, {fd=6, events=POLLIN}, {fd=7, events=POLLIN}, {fd=8,
events=POLLIN}], 6, -1) = 1 ([{fd=5, revents=POLLIN|POLLERR|POLLHUP}])

I can reproduce it by starting acpid and then power off one of the screens.

Looking a bit at the code, it appears that it never checks for POLLERR
or POLLHUP and thus enters an endless loop.

Doh... it just hit me.

What happens is, I have an USB keyboard and USB mouse attached to the
screen. When I power off the screen the keyboard and mouse input
devices disappear and the file handle in acpid becomes invalid. Since
nothing checks for POLLERR|POLLHUP it ends up in an endless loop since
POLLIN was not set.

I wonder what the proper way to handle this is. Probably do some
netlink stuff to detect new devices for acpid?

Quick workaround would be to just close fd on POLLHUP or POLLERR:

diff --git a/util-linux/acpid.c b/util-linux/acpid.c
index 6e7321b..3d723c0 100644
--- a/util-linux/acpid.c
+++ b/util-linux/acpid.c
@@ -292,6 +292,11 @@ int acpid_main(int argc UNUSED_PARAM, char **argv)
                for (i = 0; i < nfd; i++) {
                        const char *event = NULL;

+                       if (pfd[i].revents & (POLLERR | POLLHUP)) {
+                               close(pfd[i].fd);
+                               pfd[i].fd = -1;
+                       }
+
                        memset(&ev, 0, sizeof(ev));

                        if (!(pfd[i].revents & POLLIN))


-- 
Natanael Copa
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to