Skip to content

endless poll loop in http_write when POLLHUP is returned  #827

@vliaskov

Description

@vliaskov

Describe the bug

Customer observes that cupsd occasionally gets stuck in a poll() loop. strace shows:

poll([{fd=30, events=POLLOUT}], 1, 10000) = 1 ([{fd=30, revents=POLLOUT|POLLHUP}])
poll([{fd=30, events=POLLOUT}], 1, 10000) = 1 ([{fd=30, revents=POLLOUT|POLLHUP}])
poll([{fd=30, events=POLLOUT}], 1, 10000) = 1 ([{fd=30, revents=POLLOUT|POLLHUP}])

If POLLHUP is received (i.e. the connection's other end was closed?), should we continue polling? Should POLLHUP be checked in the revents to break the loop? I haven't yet found an obvious upstream fix for this, so I am opening the bug.

Backtrace of the cupsd process:

(gdb) bt
#0  0x00007f828cb92963 in ?? () at ../sysdeps/wordsize-64/../../io/fts.c:1062 from /lib64/libc.so.6
#1  0x00007f828cf2d903 in poll (__timeout=<optimized out>, __nfds=1, __fds=0x7ffeabd1c3d8) at /usr/include/bits/poll2.h:46
#2  http_write (http=http@entry=0x557afca93d00, buffer=buffer@entry=0x7ffeabd1c420 "20b\r\n", length=5) at http.c:4690
#3  0x00007f828cf2daa4 in http_write_chunk (http=0x557afca93d00, 
    buffer=0x557afca964f8 "/printers/bamp0027ls\">bamp0027ls</A></TD><TD>bamp0027ls</TD><TD>BAM</TD><TD>LaserSoft printer</TD><TD>bampadm - retry-current-job</TD><TD>Idle</TD></TR>\n\n<TR><TD><A HREF=\"/printers/bamp0028\">bamp0028<"..., length=523) at http.c:4820
#4  0x00007f828cf2de35 in httpFlushWrite (http=0x557afca93d00) at http.c:704
#5  0x0000557aea021a79 in cupsdWriteClient (con=0x557afcd38560) at client.c:2727
#6  0x0000557aea04adfb in cupsdDoSelect (timeout=timeout@entry=1) at select.c:489
#7  0x0000557aea019b5e in main (argc=<optimized out>, argv=<optimized out>) at main.c:831

To Reproduce

Unfortunately, I am still not clear on how to reproduce this. Probably clients need to be closed while cupsd is sending data to them. I will update if I have an exact reproducer from the customer.

If there are ideas on how to stress test this let me know. Is there an existing testcase that would stress this scenario?

Expected behavior
Cups should not keep polling indefinitely if the other side has hung up.

System Information:

  • OS and its version: SLE15-SP4, x86_64
  • CUPS version 2.2.7 (2.2.7-150000.3.46.1)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions