]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: Properly handle POLLERR from poll() 6906/head
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 12 Aug 2020 13:49:20 +0000 (09:49 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 12 Aug 2020 13:49:20 +0000 (09:49 -0400)
There are situations where POLLERR will be returned.  But
since we were not handling it.  Thread processing effectively
is turned into an infinite loop, which is bad.

Modify the code so that if we receive a POLLERR we turn it
into a read event to be handled as an error from the handler
function.

This was discovered in pim:

Thread statistics for pimd:
Showing poll FD's for main
--------------------------
Count: 14/1024
     0 fd:     9 events: 1 revents: 0 mroute_read
     1 fd:    12 events: 1 revents: 0 vty_accept
     2 fd:    13 events: 1 revents: 0 vtysh_accept
     3 fd:    11 events: 1 revents: 0 zclient_read
     4 fd:    15 events: 1 revents: 0 mroute_read
     5 fd:    16 events: 1 revents: 0 mroute_read
     6 fd:    17 events: 1 revents: 0 pim_sock_read
     7 fd:    19 events: 1 revents: 0 pim_sock_read
     8 fd:    21 events: 1 revents: 0 pim_igmp_read
     9 fd:    22 events: 1 revents: 0 pim_sock_read
    10 fd:    23 events: 1 revents: 0 pim_sock_read
    11 fd:    20 events: 1 revents: 0 vtysh_read
    12 fd:    18 events: 1 revents: 0 pim_sock_read
    13 fd:    24 events: 0 revents: 0

strace was showing this line over and over and over:

poll([{fd=9, events=POLLIN}, {fd=12, events=POLLIN}, {fd=13, events=POLLIN}, {fd=11, events=POLLIN}, {fd=15, events=POLLIN}, {fd=16, events=POLLIN}, {fd=17, events=POLLIN}, {fd=19, events=POLLIN}, {fd=21, events=POLLIN}, {fd=22, events=POLLIN}, {fd=23, events=POLLIN}, {fd=20, events=POLLIN}, {fd=18, events=POLLIN}, {fd=6, events=POLLIN}], 14, 20) = 1 ([{fd=21, revents=POLLERR}])

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
lib/thread.c

index 48183cc9ad05d2dc812f0b1109dcbea290ba88e6..19e482728385766df863f8a22e029fecb285e930 100644 (file)
@@ -1314,8 +1314,12 @@ static void thread_process_io(struct thread_master *m, unsigned int num)
                 * copy, so there's no need to update it. Similarily,
                 * barring deletion, the fd should still be a valid index
                 * into the master's pfds.
+                *
+                * We are including POLLERR here to do a READ event
+                * this is because the read should fail and the
+                * read function should handle it appropriately
                 */
-               if (pfds[i].revents & (POLLIN | POLLHUP)) {
+               if (pfds[i].revents & (POLLIN | POLLHUP | POLLERR)) {
                        thread_process_io_helper(m, m->read[pfds[i].fd], POLLIN,
                                                 pfds[i].revents, i);
                }