Bug 40213 - Сервер впадает в бесконечный цикл
Summary: Сервер впадает в бесконечный цикл
Status: CLOSED FIXED
Alias: None
Product: Sisyphus
Classification: Development
Component: unfs3 (show other bugs)
Version: unstable
Hardware: x86_64 Linux
: P5 major
Assignee: Michael Shigorin
QA Contact: qa-sisyphus
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-06-13 17:24 MSK by Alexey Gladkov
Modified: 2023-06-14 15:56 MSK (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alexey Gladkov 2021-06-13 17:24:02 MSK
unfs3 не работает. Если указать порты, то под strace видно, что он цыклится.

strace -f unfsd -d -p -t -n 6000 -m 6001 -e /to/exports
...
select(1024, [3 4], NULL, NULL, {tv_sec=1, tv_usec=0}) = 2 (in [3 4], left {tv_sec=0, tv_usec=999998})
accept(3, 0x7fffe52cf160, [128])        = -1 EINVAL (Недопустимый аргумент)
accept(4, 0x7fffe52cf160, [128])        = -1 EINVAL (Недопустимый аргумент)
select(1024, [3 4], NULL, NULL, {tv_sec=1, tv_usec=0}) = 2 (in [3 4], left {tv_sec=0, tv_usec=999998})
accept(3, 0x7fffe52cf160, [128])        = -1 EINVAL (Недопустимый аргумент)
accept(4, 0x7fffe52cf160, [128])        = -1 EINVAL (Недопустимый аргумент)

Эти строки будут повторяться постоянно. Сервер при этом не будет слушать запросы.
select делает unfs3 сервер, accept библиотека libtirpc.

Я проверил апстрим, но там ситуация та же. Даже если собрать его с поддержкой poll, то циклится он будет на poll. Всё дело в какой-то несовместимости между unfs3 и libtirpc, поддержки которой нет в апстриме. Там есть лишь PR по добавлению libtirpc. С этим PR тоже не работает т.к. он добавляет только возможность собраться с этой библиотекой.

https://github.com/legionus/unfs3 -- тут я собрал несколько фиксов для unfs3. Они, впрочем, не решают описанную проблему.
Comment 1 Alexey Sheplyakov 2023-06-13 18:20:35 MSK
#0  0x00007ffff7ebc4f3 in __libc_accept (fd=4, addr=addr@entry=..., len=len@entry=0x7fffffffdc0c) at ../sysdeps/unix/sysv/linux/accept.c:26
#1  0x00007ffff7facb93 in rendezvous_request (xprt=0x555555a3ad20, msg=<optimized out>) at svc_vc.c:340
#2  0x00007ffff7fa98a0 in svc_getreq_common (fd=fd@entry=4) at svc.c:700
#3  0x00007ffff7fa9a1c in svc_getreqset (readfds=<optimized out>) at svc.c:669
#4  0x000055555555a225 in unfs3_svc_run () at daemon.c:822
#5  0x000055555555a735 in main (argc=2, argv=0x7fffffffe5d8) at daemon.c:968


337             r = (struct cf_rendezvous *)xprt->xp_p1;
338     again:
339             len = sizeof addr;
340             sock = accept(xprt->xp_fd, (struct sockaddr *)(void *)&addr, &len);
341             if (sock < 0) {
342                     if (errno == EINTR)
343                             goto again;
344                     return (FALSE);
345             }


Крутится он здесь. Что делает этот rendezvous_request -- в душе не ведаю. Почему каждый раз accept завершается с EINTR -- тоже загадка.
Comment 2 Alexey Sheplyakov 2023-06-13 23:04:15 MSK
(Ответ для Alexey Gladkov на комментарий #0)
> unfs3 не работает. Если указать порты, то под strace видно, что он цыклится.
> 
> strace -f unfsd -d -p -t -n 6000 -m 6001 -e /to/exports
> ...
> select(1024, [3 4], NULL, NULL, {tv_sec=1, tv_usec=0}) = 2 (in [3 4], left
> {tv_sec=0, tv_usec=999998})
> accept(3, 0x7fffe52cf160, [128])        = -1 EINVAL (Недопустимый аргумент)
> accept(4, 0x7fffe52cf160, [128])        = -1 EINVAL (Недопустимый аргумент)
> select(1024, [3 4], NULL, NULL, {tv_sec=1, tv_usec=0}) = 2 (in [3 4], left
> {tv_sec=0, tv_usec=999998})
> accept(3, 0x7fffe52cf160, [128])        = -1 EINVAL (Недопустимый аргумент)
> accept(4, 0x7fffe52cf160, [128])        = -1 EINVAL (Недопустимый аргумент)
> 
> Эти строки будут повторяться постоянно. Сервер при этом не будет слушать
> запросы.
> select делает unfs3 сервер, accept библиотека libtirpc.

А listen не делает никто.

https://github.com/asheplyakov/unfs3/blob/master/daemon.c#L782-L794

libtirpc (по крайней мере, версия 1.3.3) может либо сама создать и подготовить сокет, либо взять уже подготовленный вручную. Но в последнем случае нужно самостоятельно сделать listen, а create_tcp_transport из unfs3 этого не делает.


diff --git a/unfs3/daemon.c b/unfs3/daemon.c
index d14af45..964d1ab 100644
--- a/unfs3/daemon.c
+++ b/unfs3/daemon.c
@@ -779,6 +779,11 @@ static SVCXPRT *create_tcp_transport(unsigned int port)
            fprintf(stderr, "Couldn't bind to tcp port %d\n", port);
            exit(1);
        }
+        if (listen(sock, SOMAXCONN)) {
+            perror("listen");
+           fprintf(stderr, "Couldn't listen tcp port %d\n", port);
+           exit(1);
+        }
     }
 
     transp = svctcp_create(sock, 0, 0);

Вот так надо сделать, чтоб заработало.


> Я проверил апстрим, но там ситуация та же.

Я им уже патч засылал на эту тему (https://github.com/asheplyakov/unfs3/commit/a9d97fa8305fa766c72d19d7123ed1659bd9f02a), правда, я не упоминал отдельно то, что с ним unfs3 таки работает.
Comment 3 Alexey Sheplyakov 2023-06-13 23:12:24 MSK
Патчерам, которые "Fixed ftbfs" - пламенный привет, лучи света и добра, и всё такое.
Comment 4 Alexey Sheplyakov 2023-06-13 23:18:18 MSK
В 0.10.0 исправлено:

commit a7bd4ba0c228cca1dbc78b8bf4699107a3542eaa
Author: Martin Škoudlil <skoudmar@fel.cvut.cz>
Date:   Thu May 12 17:01:22 2022 +0200

    svc_dg_create and svc_vc_create requires bound socket
    
    When started with '-u' the socket passed to these functions is not bound.
    This will prevent any connection.
Comment 5 Repository Robot 2023-06-14 15:56:21 MSK
unfs3-0.10.0-alt1 -> sisyphus:

 Wed Jun 14 2023 Alexey Sheplyakov <asheplyakov@altlinux> 0.10.0-alt1
 - 0.10.0
 - Ensure TCP socket is always listened (closes: #40213)