Сар: что означает Тоцк

Я ищу объяснение столбца totsck для вывода "sar -n SOCK"

09:44:06 PM    totsck    tcpsck    udpsck    rawsck   ip-frag    tcp-tw
09:44:09 PM       580        18         5         0         0         1
09:44:10 PM       580        18         5         0         0         0
09:44:11 PM       580        18         5         0         0         0
Average:          580        18         5         0         0         1

Это явно не сумма сокетов tcp/udp/raw. Единственное другое объяснение, которое я нашел, это то, что это розетки плюс

 sysctl fs.file-nr 

но на моей тестовой коробке это

fs.file-nr = 5632   0   803168

Точное объяснение высоко ценится.

Спасибо

Редактировать 2: Так что, очевидно, totsck эквивалентно

cat /proc/net/sockstat

что приводит к вопросу, что там считается. Я нашел это, но в конце он только рекомендует спросить парней, которые написали этот конкретный кусок кода ядра.

Изменить (для учета сокетов домена):

[root@fedora16 fs]# netstat --protocol unix| wc -l
413
[root@fedora16 fs]# sar -n SOCK 1 1
Linux 3.3.1-5.fc16.x86_64 (fedora16)    06/21/2012  _x86_64_    (4 CPU)

10:03:25 PM    totsck    tcpsck    udpsck    rawsck   ip-frag    tcp-tw
10:03:26 PM       598         6         5         0         0         3
Average:          598         6         5         0         0         3

2 ответа

Решение

Есть также доменные сокеты UNIX (STREAM и DGRAM), которые учитываются в общем количестве сокетов, используемых системой, как кажется. На доменные сокеты UNIX процессы ссылаются как на inode в файловой системе. Есть много вещей, которые до сих пор используют доменные сокеты UNIX для различных целей, поэтому sar поднимает это. Проверьте, что вывод netstat -a чтобы увидеть, сколько сокетов домена UNIX открыто в вашей системе.

fs.file-nr это максимальное количество файловых дескрипторов, и хотя оно не имеет ничего общего с тем, что вы видите на sar выход.

Изменить: пожалуйста, учтите, что sar в основном читает /proc/net/sockstat и делает среднее по этому количеству или сообщает исторические значения. Кажется, что /proc/net/sockstat получает данные из двух мест (источник ядра для 2.6.27) и местоположения net/socket.c линия: 2324 и net/ipv4/proc.c строка 54 и далее, и общее количество поступает из первых мест, а остальные из второго. Проходя через net Структура также показывает, какие сокеты подсчитываются / учитываются и печатаются в файловой системе proc.

 79  * @SOCK_STREAM: stream (connection) socket
 80  * @SOCK_DGRAM: datagram (conn.less) socket>  
 81  * @SOCK_RAW: raw socket
 82  * @SOCK_RDM: reliably-delivered message>
 83  * @SOCK_SEQPACKET: sequential packet socket
 84  * @SOCK_DCCP: Datagram Congestion Control Protocol socket

Хорошо, у меня тоже была эта проблема, и я пришел к выводу, что все ядра имеют этот очевидный недостаток/ошибку. Я тестировал это на ядрах 3.10, 4.2, 5.1 и 6.2, и код версий до 2.6 и 4.16 не изменился.

Так что похоже у нас дырявые розетки!

Рассмотрим следующие команды:

      ss -Han |wc -l ;\
awk 'NR==1 { print $NF }' /proc/net/sockstat

Вывод каждой команды должен быть примерно одинаковым (по крайней мере, 1 сокет создается первой командой). Но для многих моих серверов вывод каждой команды сильно различается.

получает информацию от, как мы видим во второй команде. Эта информация предоставляется кодом драйвера сокета ядра, как описано ниже.

возможно и то и другоеине предоставляют исчерпывающий список сокетов. Это будет ошибка или отсутствие документации с их стороны.

Возможно, ошибка в коде . Однако я не смог его найти. Этот код обрабатывает выделение и освобождение всех сокетов в системе. Когда он создает новый, он увеличивает счетчик. Когда он уничтожает один, он уменьшает счетчик. Довольно просто, не должно быть места для ошибки.

Однако в коде есть некоторая скрытая сложность в отношении многопроцессорных систем. Я обнаружил, что мои однопроцессорные виртуальные машины в целом имели меньшие расхождения, чем другие мои системы. Но этим системам выделяется только 1 ЦП, поскольку они являются тестовыми системами и не используются интенсивно. Разница в моих однопроцессорных системах составляет <10%. Но для многопроцессорных виртуальных машин существует широкий разброс: от < 1% до 10 раз!

Код для каждого процессора вв отчете выглядит так:

              for_each_possible_cpu(cpu)
            counter += per_cpu(sockets_in_use, cpu);

Инкрементеры и декрементеры выглядят так:

      percpu_add(sockets_in_use,1);
...
percpu_sub(sockets_in_use,1);

Этот код принципиально не менялся с 2005 по 2017 год, в версии 4.16 с net-namespaces. Но я все еще наблюдаю несоответствие в версиях до 6.2, так что, возможно, под ним тот же код.

Эти макросы для каждого процессора скрывают множество деталей. Я не все это понимаю, но, возможно, пойму, после того как изучу эту страницу . В конечном счете, он должен действовать как массив, индексированный по номеру процессора. Я полагаю, что эта конструкция необходима для того, чтобы ядро, работающее на каждом процессоре, могло обновлять свой собственный счетчик, чтобы избежать дорогостоящей спин-блокировки и, возможно, очистки кэша. Макросы гарантируют, что эти операции добавления/подстановки являются атомарными. Каждый счетчик представляет собой. Никакая проверка границ не выполняется. Целочисленные математические вычисления будут работать корректно даже при переполнении/недополнении нескольких процессоров. И это очень известный код, используемый повсюду.

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

Другие вопросы по тегам