Мне всегда нравилась FreeBSD. Нравилась лаконичностью, простым и понятным расположением и назначением файлов, элементов, структур и какой-то «тёплой», «домашней» консервативностью. Но с выходом 10-ки я замечаю, что она всё больше от меня отдаляется и я всё больше не понимаю что и зачем в ней меняется. И дело даже не в том, что не развиваются те вещи которыми была всегда сильна FreeBSD и которые нужно развивать, как морально и архитектурно устаревший сетевой стек. Дело в мелочах.

image
— Видишь суслика?
— Нет.
— И я не вижу. А он есть!

© ДМБ (2000г. реж. Роман Качанов)

Те кому доводилось тюнить FreeBSD (начиная с 4-ки) без труда вспомнят параметр ядра kern.ipc.somaxconn. С его увеличения обычно начиналось «улучшение» работы с TCP. Он же и сейчас описан в RU-хэндбуке:

12.13.1.2. kern.ipc.somaxconn
Переменная sysctl kern.ipc.somaxconn ограничивает размер очереди для приема новых TCP соединений. Значение по умолчанию 128 слишком мало для надежной обработки новых соединений для нагруженного web сервера. Для такого сервера рекомендуется увеличить это значение до 1024 или выше. Даемон сервиса может сам ограничивать очередь приема новых соединений (например, sendmail(8), или Apache), но обычно в файле настройки даемона есть директива для настройки длины очереди. Более длинная очередь также помогает избежать атак Denial of Service (DoS).

То есть параметр есть?
Здесь и далее
$ uname -or
FreeBSD 10.3-STABLE

Допустим мы не помним в какой секции точно находится somaxconn. Найдём его grep'нув вывод sysctl:
$ sysctl -A | grep somaxconn
$

Нет такого параметра?
Вспоминаем, что он в секции kern.ipc.
$ sysctl kern.ipc.
$ sysctl kern.ipc.
kern.ipc.maxsockbuf: 2097152
kern.ipc.sockbuf_waste_factor: 8
kern.ipc.max_linkhdr: 16
kern.ipc.max_protohdr: 60
kern.ipc.max_hdr: 76
kern.ipc.max_datalen: 92
kern.ipc.sendfile.readahead: 1
kern.ipc.maxsockets: 2095270
kern.ipc.numopensockets: 77
kern.ipc.soacceptqueue: 128
kern.ipc.shm_allow_removed: 0
kern.ipc.shm_use_phys: 0
kern.ipc.shmall: 131072
kern.ipc.shmseg: 128
kern.ipc.shmmni: 192
kern.ipc.shmmin: 1
kern.ipc.shmmax: 536870912
kern.ipc.semaem: 16384
kern.ipc.semvmx: 32767
kern.ipc.semusz: 632
kern.ipc.semume: 50
kern.ipc.semopm: 100
kern.ipc.semmsl: 340
kern.ipc.semmnu: 150
kern.ipc.semmns: 340
kern.ipc.semmni: 50
kern.ipc.msgseg: 2048
kern.ipc.msgssz: 8
kern.ipc.msgtql: 40
kern.ipc.msgmnb: 2048
kern.ipc.msgmni: 40
kern.ipc.msgmax: 16384
kern.ipc.piperesizeallowed: 1
kern.ipc.piperesizefail: 0
kern.ipc.pipeallocfail: 0
kern.ipc.pipefragretry: 0
kern.ipc.pipekva: 49152
kern.ipc.maxpipekva: 1072775168
kern.ipc.nmbufs: 26114730
kern.ipc.nmbjumbo16: 1360140
kern.ipc.nmbjumbo9: 1813521
kern.ipc.nmbjumbop: 2040212
kern.ipc.nmbclusters: 4080424
kern.ipc.maxmbufmem: 33426839552
$


И визуально его также не обнаруживаем… Но если задать полный путь
$ sysctl kern.ipc.somaxconn
kern.ipc.somaxconn: 128

то суслик находится.
Не обнаружив в man'е sysctl такой особенности вывода параметров и несколько недоумевая смотрим в исходники, где в sys/kern/uipc_socket.c и наблюдаем:

/*
 * Limit on the number of connections in the listen queue waiting
 * for accept(2).
 * NB: The orginal sysctl somaxconn is still available but hidden
 * to prevent confusion about the actual purpose of this number.
 */
static int somaxconn = SOMAXCONN;

static int
sysctl_somaxconn(SYSCTL_HANDLER_ARGS)
{
        int error;
        int val;

        val = somaxconn;
        error = sysctl_handle_int(oidp, &val, 0, req);
        if (error || !req->newptr )
                return (error);

        if (val < 1 || val > USHRT_MAX)
                return (EINVAL);

        somaxconn = val;
        return (0);
}
SYSCTL_PROC(_kern_ipc, OID_AUTO, soacceptqueue, CTLTYPE_UINT | CTLFLAG_RW,
    0, sizeof(int), sysctl_somaxconn, "I",
    "Maximum listen socket pending connection accept queue size");
SYSCTL_PROC(_kern_ipc, KIPC_SOMAXCONN, somaxconn,
    CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_SKIP,
    0, sizeof(int), sysctl_somaxconn, "I",
    "Maximum listen socket pending connection accept queue size (compat)");


То есть somaxconn больше не в почёте и заменён на soacceptqueue? Так как этот файл имеет непосредственное отношение к системному вызову listen смотрим его man, где и обнаруживаем:
$ man listen | col | tail -n 11
HISTORY
     The listen() system call appeared in 4.2BSD.  The ability to configure
     the maximum backlog at run-time, and to use a negative backlog to request
     the maximum allowable value, was introduced in FreeBSD 2.2.  The
     kern.ipc.somaxconn sysctl(3) has been replaced with
     kern.ipc.soacceptqueue in FreeBSD 10.0 to prevent confusion about its
     actual functionality.  The original sysctl(3) kern.ipc.somaxconn is still
     available but hidden from a sysctl(3) -a output so that existing applica-
     tions and scripts continue to work.

What!? Оказывается это сделано с заботой обо мне? Чтобы «предотвратить путаницу»?
А то, что у кого-то в древнем скрипте, который кочует десяток лет может быть парсинг параметров sysctl kern.ipc. или sysctl -A | grep somaxconn никого не волновало? Ну не нравится вам описание функционала данного параметра добавьте параллельно синоним, но убирать-то его из выдачи sysctl зачем?
Мне даже страшно представить, что может произойти с десятками других параметров ядра, которые не отражают точного смысла…
Поделиться с друзьями
-->

Комментарии (20)


  1. levkin
    19.06.2016 11:57

    И сколько в конце-концов будет синонимов? :) сами же плеваться будете. всем не угодишь. старые скрипты для старых ОС, новые для новых


    1. chaturanga
      19.06.2016 12:01
      +1

      С каждым обновлением системы переписываете скрипты с нуля?


      1. ValdikSS
        19.06.2016 12:21
        +3

        Никто в здравом уме в скрипте не будет пасить вывод sysctl -a | grep, а сделает вызов sysctl kern.ipc.somaxconn. Не вижу причины жаловаться.


        1. chaturanga
          19.06.2016 12:31
          +1

          Парсить может и не будет, а вот найти секцию для того чтобы сделать sysctl kern.ipc.somaxconn очень даже захочет сделав sysctl -a | grep
          Клонирование параметра абсолютно бессмысленное, а с последующим его выводом из выдачи sysctl просто абсурдное.


        1. simpleadmin
          19.06.2016 22:54
          +1

          Не вижу причины жаловаться.

          Я уж давно не жалуюсь. Но может Вам и нравится, что путь развития FreeBSD — выдумывание новых имён для различных параметров, а мне бы хотелось, чтобы, например, обработка трафика приблизилась к своему теоретическому максимуму.
          Жаль, у нас разные видения развития ОС.
          Как вариант, давайте всю секцию p1003_1b переименуем в posix_1b_extensions, а то она вообще глаз режет.


      1. levkin
        19.06.2016 14:37

        все когда-то меняется. как по-вашему сохранять совместимость в данном случае? кроме алиасов


      1. fidewu
        19.06.2016 22:56

        С каждым?
        Сколько прошло лет между FreeBSD 4 и 10???


        1. simpleadmin
          19.06.2016 22:57

          Так а чем больше тем хуже.
          Если мыло 15 лет называли мылом, а теперь стали называть шилом, то лучше не станет.


          1. fidewu
            20.06.2016 06:14

            Дык зачем обновлять то?
            Это ж Фряха.
            9-ка вполне стабильна.


    1. simpleadmin
      19.06.2016 12:05

      Так он и сделан синонимом, только скрытым из вывода.
      Зачем это сделано вообще? От этого, что ускорилась обработка listen?


  1. Ivan_83
    19.06.2016 15:15

    Странные жалобы.

    Нужно же читать UPDATING, там обычно такое пишут.
    Да и sysctl вроде ругается, я уже давно заменил в sysctl.conf и забыл, потому что такой проблемы нет.

    Точно также можно жаловаться что раньше все диски были /dev/daX а теперь вдруг стали /dev/adaX, но для тех кто на бронепоезде целую мажорную версию по дефолту делали симлинки daX->adaX.

    Конкретно про soacceptqueue — в любом уважающем себя сервисе должна в конфиге быть крутилка для этого. Если её нет, значит сервис не рассчитан на большие нагрузки.


    1. simpleadmin
      19.06.2016 23:05
      +1

      я уже давно заменил в sysctl.conf

      На сколько PPS теперь больше «держите» чем при somaxconn? :)


      1. Ivan_83
        20.06.2016 00:18

        На много.
        В 10х появилось возможность слать из памяти в сеть без копирования используя sendfile().
        Тесты у Андриана Чада в блоге есть.
        Я у себя в msd/msd_lite впилил как только проапгрейдился.

        «Зачем это сделано вообще? От этого, что ускорилась обработка listen?» —
        Порядку ради.
        Те кто этим пользовался заметили оное ещё при апгрейде с 9х на 10х в начале 2014 года: http://mailing.freebsd.questions.narkive.com/INtfUMet/kern-ipc-somaxconn-missing

        Вот патч вместе с автором и пояснением: https://lists.freebsd.org/pipermail/svn-src-head/2012-October/041326.html
        Если не устраивает: пиши свой патч и используй как приватный.
        У меня amdtemp приватным патчем уже года 3.

        «Я уж давно не жалуюсь. Но может Вам и нравится, что путь развития FreeBSD — выдумывание новых имён для различных параметров, а мне бы хотелось, чтобы, например, обработка трафика приблизилась к своему теоретическому максимуму.» — не вижу проблем, спонсируй или сам пили, чего ныть то в коментах?
        Если эта фраза про роутинг, то причём тут somaxconn?
        И собственно почему оно сейчас вдруг всплыло, а не 2 года назад?
        Скоро 11 выйдет уже, там тоже будет много изменений.

        Вон нетфликсу надо, они пилят. Уже весь sendfile() перепилили так что мама не горюй, за 3-5 лет. (льют по 40 гигов с таза в сеть, и ещё проц не в полку забит)
        Джуну надо — они впилили свою фс для флеша.
        Мне надо было считывать температуру на процах amd я взял и переписал этот драйвер/модуль.
        Захотелось мне uTP почикать — написал нетграф ноду.
        Не работал мопед от хуавея E3272 — пропатчил ядро, чтобы узнавало…

        Вот недавно захотелось чтобы congestion control стал работать так же как в линухе, но сразу так не осилил, есть ощущение что где то там закопана большая бага в части контроля скорости, которая ломает=ухудшает работу всех сс алгоритмов.

        «А изменение параметра к которому все привыкли за десять лет было настолько важно в рамках развития ОС, что его два года даже не могут изменить в русском хендбуке.» — Возьми да измени, или спонсируй.
        Заодно ещё поменяй в: de_DE, el_GR, fr_FR, hu_HU, it_IT, ja_JP, mn_MN, nl_NL, pl_PL, zh_CN.
        Собственно только в en_US его и поменяли.

        2 chaturanga:
        Прямо в доках/релизнотесах не увидел упоминания о переименовании.
        Насколько помню у меня после апгрейда до 10.х sysctl при старте стал на него ругаться и я быстро нашёл что его переименовали.
        Но меня это переименование вообще никак не трогало, ибо почти у всего софта оно тюнится через конфиги, очень мало кто использует дефолт системы и не имеет своих настроек.


        1. simpleadmin
          20.06.2016 09:42
          +2

          Так я так и не увидел чем именно помогло конкретно изменение имени параметра? :)

          Возьми да измени, или спонсируй.

          Спонсировать то что мне не нравится. В чём логика?
          Я уж лучше в пользу netmap'а.

          Собственно только в en_US его и поменяли.

          Да его толком нигде не поменяли. В этом ещё больший идиотизм. В итоге в какой-нибудь 12-ке somaxconn выкинут из параметров вообще, но оставлят его в манах:
          $  man tuning | col | grep "sysctl limits" -A 7
               The kern.ipc.somaxconn sysctl limits the size of the listen queue for
               accepting new TCP connections.  The default value of 128 is typically too
               low for robust handling of new connections in a heavily loaded web server
               environment.  For such environments, we recommend increasing this value
               to 1024 or higher.  The service daemon may itself limit the listen queue
               size (e.g., sendmail(8), apache) but will often have a directive in its
               configuration file to adjust the queue size up.  Larger listen queues
               also do a better job of fending off denial of service attacks.
          

          README-шках
          # cat ./tools/tools/netrate/tcpp/README | grep somaxconn
          kern.ipc.somaxconn=49152
          

          Комментариях в коде, да и в самом коде
          grep -rnA 4 "We retrieve kern.ipc.somaxconn" ./tools/regression/sockets/listen_backlog/listen_backlog.c
          58: * We retrieve kern.ipc.somaxconn before running the tests in order to use a
          59- * run-time set value of SOMAXCONN, rather than compile-time set.  We assume
          60- * that no other process will be simultaneously frobbing it, and these tests
          61- * may fail if that assumption is not held.
          62- */
          

          Зачем?


    1. chaturanga
      19.06.2016 23:08

      Нужно же читать UPDATING, там обычно такое пишут.

      Читаю, не видел.
      Буду благодарен если ткнёте пальцем.


  1. yermulnik
    19.06.2016 22:56
    -1

    По прочтению статьи у меня сложилось впечатление, что у автора статьи был/есть скрипт, который grep'ом парсит вывод sysctl и не умеет обрабатывать exception'ы.


    1. simpleadmin
      19.06.2016 23:03

      Нет, не было.
      А если бы и был что это меняет?


      1. yermulnik
        19.06.2016 23:11
        -1

        То, что автор негодует по поводу давно уже анонсированного изменения имени параметра и наличия поддержки его старого именования: лично я не понял суть статьи — имя параметра изменили, привели его к более осмысленному виду, объявили об этом, какие-то время поддерживали обратную совместимость и… и всё плохо. Так что ли?


        1. simpleadmin
          19.06.2016 23:34

          Ну, видимо, все кроме меня считают, что других проблем у Фри нет…
          А изменение параметра к которому все привыкли за десять лет было настолько важно в рамках развития ОС, что его два года даже не могут изменить в русском хендбуке.


  1. ef_end_y
    19.06.2016 23:53
    -2

    О, класс, теперь я благодаря данной статье знаю, что заблуждался насчет kern.ipc.somaxconn. Спасибо, что заменили на новый параметр, теперь его значение интуитивно понятно