Skip to content

socketserver.Unix*Server may attempt to set SO_REUSEPORT on Unix sockets, causing EOPNOTSUPP, e.g. in test_asyncio #128916

Closed
@mgorny

Description

@mgorny

Bug report

Bug description:

When socketserver.Unix*Server.server_bind() is called with allow_reuse_port attribute set to True, it attempts to call self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) on a Unix socket, and it fails with: OSError: [Errno 95] Operation not supported. In particular, this happens in test_asyncio tests.

This seems to be a recent change on my system (probably in Linux kernel), as the relevant tests used to pass when I tested CPython 3.14.0a3, and now the same version failed. Now I'm at 6.12.9, back then it was 6.12.5 (but I don't think there's a point in actually verifying that).

Output from `test_asyncio.test_sock_lowlevel`
$ ./python -E  -m test -v test_asyncio.test_sock_lowlevel
== CPython 3.14.0a4+ (heads/main:3193cb5ef87, Jan 16 2025, 13:54:51) [GCC 14.2.1 20241221]
== Linux-6.12.9-gentoo-dist-x86_64-AMD_Ryzen_5_3600_6-Core_Processor-with-glibc2.40 little-endian
== Python build: release
== cwd: /home/mgorny/git/cpython/build/test_python_worker_532605æ
== CPU count: 12
== encodings: locale=UTF-8 FS=utf-8
== resources: all test resources are disabled, use -u option to unskip tests

Using random seed: 3831794787
0:00:00 load avg: 0.54 Run 1 test sequentially in a single process
0:00:00 load avg: 0.54 [1/1] test_asyncio.test_sock_lowlevel
test_cancel_sock_accept (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests.test_cancel_sock_accept) ... ok
test_create_connection_sock (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests.test_create_connection_sock) ... ok
test_huge_content (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests.test_huge_content) ... ok
test_huge_content_recvinto (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests.test_huge_content_recvinto) ... ok
test_recvfrom (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests.test_recvfrom) ... ok
test_recvfrom_into (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests.test_recvfrom_into) ... ok
test_sendto_blocking (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests.test_sendto_blocking) ... ok
test_sock_accept (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests.test_sock_accept) ... ok
test_sock_client_connect_racing (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests.test_sock_client_connect_racing) ... ok
test_sock_client_fail (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests.test_sock_client_fail) ... ok
test_sock_client_ops (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests.test_sock_client_ops) ... ok
test_sock_client_racing (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests.test_sock_client_racing) ... ok
test_unix_sock_client_ops (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests.test_unix_sock_client_ops) ... ERROR
test_cancel_sock_accept (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests.test_cancel_sock_accept) ... ok
test_create_connection_sock (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests.test_create_connection_sock) ... ok
test_huge_content (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests.test_huge_content) ... ok
test_huge_content_recvinto (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests.test_huge_content_recvinto) ... ok
test_recvfrom (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests.test_recvfrom) ... ok
test_recvfrom_into (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests.test_recvfrom_into) ... ok
test_sendto_blocking (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests.test_sendto_blocking) ... ok
test_sock_accept (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests.test_sock_accept) ... ok
test_sock_client_connect_racing (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests.test_sock_client_connect_racing) ... ok
test_sock_client_fail (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests.test_sock_client_fail) ... ok
test_sock_client_ops (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests.test_sock_client_ops) ... ok
test_sock_client_racing (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests.test_sock_client_racing) ... ok
test_unix_sock_client_ops (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests.test_unix_sock_client_ops) ... ERROR
test_cancel_sock_accept (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_cancel_sock_accept) ... ok
test_create_connection_sock (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_create_connection_sock) ... ok
test_huge_content (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_huge_content) ... ok
test_huge_content_recvinto (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_huge_content_recvinto) ... ok
test_recvfrom (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_recvfrom) ... ok
test_recvfrom_into (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_recvfrom_into) ... ok
test_sendto_blocking (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_sendto_blocking) ... ok
test_sock_accept (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_sock_accept) ... ok
test_sock_client_connect_racing (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_sock_client_connect_racing) ... ok
test_sock_client_fail (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_sock_client_fail) ... ok
test_sock_client_ops (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_sock_client_ops) ... ok
test_sock_client_racing (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_sock_client_racing) ... ok
test_unix_sock_client_ops (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_unix_sock_client_ops) ... ERROR

======================================================================
ERROR: test_unix_sock_client_ops (test.test_asyncio.test_sock_lowlevel.EPollEventLoopTests.test_unix_sock_client_ops)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/test_sock_lowlevel.py", line 462, in test_unix_sock_client_ops
    with test_utils.run_test_unix_server() as httpd:
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/mgorny/git/cpython/Lib/contextlib.py", line 141, in __enter__
    return next(self.gen)
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/utils.py", line 261, in run_test_unix_server
    yield from _run_test_server(address=path, use_ssl=use_ssl,
                                server_cls=SilentUnixWSGIServer,
                                server_ssl_cls=UnixSSLWSGIServer)
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/utils.py", line 188, in _run_test_server
    httpd = server_class(address, SilentWSGIRequestHandler)
  File "/home/mgorny/git/cpython/Lib/socketserver.py", line 457, in __init__
    self.server_bind()
    ~~~~~~~~~~~~~~~~^^
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/utils.py", line 217, in server_bind
    UnixHTTPServer.server_bind(self)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/utils.py", line 207, in server_bind
    socketserver.UnixStreamServer.server_bind(self)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/home/mgorny/git/cpython/Lib/socketserver.py", line 472, in server_bind
    self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
    ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 95] Operation not supported

======================================================================
ERROR: test_unix_sock_client_ops (test.test_asyncio.test_sock_lowlevel.PollEventLoopTests.test_unix_sock_client_ops)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/test_sock_lowlevel.py", line 462, in test_unix_sock_client_ops
    with test_utils.run_test_unix_server() as httpd:
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/mgorny/git/cpython/Lib/contextlib.py", line 141, in __enter__
    return next(self.gen)
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/utils.py", line 261, in run_test_unix_server
    yield from _run_test_server(address=path, use_ssl=use_ssl,
                                server_cls=SilentUnixWSGIServer,
                                server_ssl_cls=UnixSSLWSGIServer)
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/utils.py", line 188, in _run_test_server
    httpd = server_class(address, SilentWSGIRequestHandler)
  File "/home/mgorny/git/cpython/Lib/socketserver.py", line 457, in __init__
    self.server_bind()
    ~~~~~~~~~~~~~~~~^^
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/utils.py", line 217, in server_bind
    UnixHTTPServer.server_bind(self)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/utils.py", line 207, in server_bind
    socketserver.UnixStreamServer.server_bind(self)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/home/mgorny/git/cpython/Lib/socketserver.py", line 472, in server_bind
    self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
    ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 95] Operation not supported

======================================================================
ERROR: test_unix_sock_client_ops (test.test_asyncio.test_sock_lowlevel.SelectEventLoopTests.test_unix_sock_client_ops)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/test_sock_lowlevel.py", line 462, in test_unix_sock_client_ops
    with test_utils.run_test_unix_server() as httpd:
         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/mgorny/git/cpython/Lib/contextlib.py", line 141, in __enter__
    return next(self.gen)
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/utils.py", line 261, in run_test_unix_server
    yield from _run_test_server(address=path, use_ssl=use_ssl,
                                server_cls=SilentUnixWSGIServer,
                                server_ssl_cls=UnixSSLWSGIServer)
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/utils.py", line 188, in _run_test_server
    httpd = server_class(address, SilentWSGIRequestHandler)
  File "/home/mgorny/git/cpython/Lib/socketserver.py", line 457, in __init__
    self.server_bind()
    ~~~~~~~~~~~~~~~~^^
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/utils.py", line 217, in server_bind
    UnixHTTPServer.server_bind(self)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/home/mgorny/git/cpython/Lib/test/test_asyncio/utils.py", line 207, in server_bind
    socketserver.UnixStreamServer.server_bind(self)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/home/mgorny/git/cpython/Lib/socketserver.py", line 472, in server_bind
    self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
    ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 95] Operation not supported

----------------------------------------------------------------------
Ran 39 tests in 1.296s

FAILED (errors=3)
test test_asyncio.test_sock_lowlevel failed
test_asyncio.test_sock_lowlevel failed (3 errors)

== Tests result: FAILURE ==

1 test failed:
    test_asyncio.test_sock_lowlevel

Total duration: 1.4 sec
Total tests: run=39
Total test files: run=1/1 failed=1
Result: FAILURE

Bisect points to 192d17c:

commit 192d17c3fd9945104bc0303cf248bb0d074d260e
Author:     Idan Kapustian <[email protected]>
AuthorDate: 2024-06-16 14:15:03 +0200
Commit:     GitHub <[email protected]>
CommitDate: 2024-06-16 14:15:03 +0200

    gh-120485: Add an override of `allow_reuse_port` on classes subclassing `socketserver.TCPServer` (GH-120488)
    
    Co-authored-by: Vinay Sajip <[email protected]>

CPython versions tested on:

3.14, CPython main branch

Operating systems tested on:

Linux

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions