Параметр ядра Linux "net.ipv4.tcp_workaround_signed_windows"

Если Вы хотите свалить повреждение количества каждого типа файла рекурсивно под некоторым dir с GNU find, Вы могли сделать:

find /some/dir/. ! -name . -printf '%y\n' | sort | uniq -c | sed '
  s/f/regular files/;t
  s/d/directories/;t
  s/l/symbolic links/;t
  s/s/Unix domain sockets/;t
  s/b/block devices/;t
  s/c/character devices/;t
  s/p/FIFOs/;t
  s/D/Doors/;t
  s/n/network special files/;t
  s/.$/others (&)/'

На /usr/bin в моей системе, которая дает:

   3727 regular files
    710 symbolic links

На /dev:

     83 block devices
    203 character devices
     31 directories
    426 symbolic links
      1 FIFOs
      1 Unix domain sockets

Для символьных ссылок, если Вы считали бы их как тип файла, они указывают на, а не symbolic links, можно изменить его на:

find /some/dir/. ! -name . -printf '%Y\n' | sort | uniq -c | sed '
  s/f/regular files/;t
  s/d/directories/;t
  s/N/broken symbolic links/;t
  s/s/Unix domain sockets/;t
  s/b/block devices/;t
  s/c/character devices/;t
  s/p/FIFOs/;t
  s/D/Doors/;t
  s/n/network special files/;t
  s/.$/others (&)/'

Который теперь дает для моего /usr/bin:

      1 directories
   4434 regular files
      2 broken symbolic links

(поврежденная символьная ссылка является символьной ссылкой на файл для который find не может определить тип или потому что файл не существует или находится в каталоге, к которому у Вас нет доступа или существует цикл в разрешении пути файла. В моем случае, те 2, где символьные ссылки на файлы, которых теперь не стало).

Ни один из тех не рассчитывает . и ... Если Вы хотели их включенный (почему был бы Вы?), нет никакого другого пути с find чем предполагают, что они там для каждого каталога и систематически считают их:

find /some/dir/. -printf '%y\n' \( -name . -printf 'd\n' -o \
  -type d -printf 'd\nd\n' \)  | sort | uniq -c | sed '
  s/f/regular files/;t
  s/d/directories/;t
  s/l/symbolic links/;t
  s/s/Unix domain sockets/;t
  s/b/block devices/;t
  s/c/character devices/;t
  s/p/FIFOs/;t
  s/D/Doors/;t
  s/n/network special files/;t
  s/.$/others (&)/'

Который затем дает на моем /usr/bin:

      2 directories
   3727 regular files
    710 symbolic links

Если у Вас нет доступа к GNU find, можно переписать первый как:

find /some/dir/. ! -name . \( \
  -type f -exec printf '%.0sregular files\n' {} + -o \
  -type d -exec printf '%.0sdirectories\n' {} + -o \
  -type l -exec printf '%.0ssymbolic links\n' {} + -o \
  -type s -exec printf '%.0sUnix domain sockets\n' {} + -o \
  -type b -exec printf '%.0sblock devices\n' {} + -o \
  -type c -exec printf '%.0scharacter devices\n' {} + -o \
  -type p -exec printf '%.0sFIFOs\n' {} + -o \
  -exec printf '%.0sothers\n' {} + \) | sort | uniq -c

Теперь, строго говоря, мы не считали файлы, но записи каталога. Каталог как /usr/bin обычно имеет несколько записей, которые указывают на тот же файл. Например, здесь, я имею:

$ ls -lid /usr/bin/{nvi,nview,nex}
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nex
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nvi
672252 -rwxr-xr-x 3 root root 434616 May 25 07:40 /usr/bin/nview

Это - 3 записи каталога (иначе имена файлов иначе жесткие ссылки) в тот же файл (тот с inode 672252. Считать файлы вместо записей каталога и с GNU find и GNU uniq (игнорирование . и .. файлы, которые так или иначе являются жесткими ссылками на другие каталоги):

find /some/dir/. ! -name . -printf '%y\t%D:%i\n' |
  sort -u |
  cut -f1 |
  uniq -c |
  sed '
    s/f/regular files/;t
    s/d/directories/;t
    s/l/symbolic links/;t
    s/s/Unix domain sockets/;t
    s/b/block devices/;t
    s/c/character devices/;t
    s/p/FIFOs/;t
    s/d/Doors/;t
    s/n/network special files/;t
    s/.$/others (&)/'

На моем /usr/bin, это дает:

   3711 regular files
    710 symbolic links
3
10.06.2015, 21:54
2 ответа

Окно Масштабирование - это опция, которая может быть установлена ​​в TCP, что позволяет расширенному размеру (больше первоначально разрешенного) буфера приема. Мне не очевидно, как эта опция поможет. Я думаю, что, возможно, если в реализации произошла ошибка, которая установлена ​​так или иначе, может избежать ошибки, но на самом деле TCP должна работать в любом случае (в одном случае, возможно, это может быть просто допущена чаще, чем он должен).

1
27.01.2020, 21:22

В TCP размер окна представляет собой 16-битное беззнаковое поле, указывающее, сколько еще байтов данных у получателя в настоящее время есть память для приема.

Оказывается, 16 битов было недостаточно, поскольку это позволило бы в любой момент времени передавать только 64 КБ данных. Вот почему была введена опция масштабирования окна. При масштабировании окна размер поля по-прежнему составляет всего 16 бит, но ему не нужно считать отдельные байты, вместо этого оно может подсчитывать 2, 4, 8, ... или 16384 байта за раз.

Точные детали того, как работает масштабирование окна, не имеют особого отношения к вашему вопросу. Поскольку приведенное вами объяснение указывает, что параметр tcp_workaround_signed_windows применяется только тогда, когда масштабирование окна не используется.

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

Ошибка

В ссылке упоминается некорректный приемник, обрабатывающий поле размера окна как значение со знаком. Это означает, что для всех значений до 32 КБ он работает правильно, но любое значение 32 КБ или более будет неправильно интерпретировано как отрицательное число.

В результате, если вы сообщаете партнеру с этой ошибкой, что у вас в настоящее время есть память для получения на 48 КБ дополнительных данных, одноранговый узел неверно интерпретирует это как -16 КБ и перестанет отправлять больше данных, поскольку следующие 1,4 КБ он хочет отправить явно не влезет.(Или он может сделать что-то еще более глупое, чем это, когда увидит отрицательное значение в поле, которое всегда должно было быть положительным.)

Если вы столкнетесь с этой ошибкой, вы увидите, что при обмене данными с конкретными запущенными компьютерами какое-то очень старое программное обеспечение, передача данных остановится без всякой причины.

Это можно обойти, никогда не отправляя размер окна больше 32 КБ, чего я и ожидал от этого описания.

Что делает этот параметр?

Уменьшение используемого размера окна с 64 КБ до 32 КБ позволит избежать задержек соединения при обмене данными с реализацией TCP, страдающей от этой ошибки.

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

И поэтому такой обходной путь не включен постоянно.

Почему можно обойти проблему только тогда, когда масштабирование окна не используется?

Нет прямой связи между ошибкой и масштабированием окна. Итак, я предполагаю, что единственная причина, по которой рассматривается масштабирование окна, заключается в том, что это наиболее известная эвристика для обнаружения конкретной реализации с ошибками.

И действительно кажется вероятным, что такая ошибка будет исправлена ​​до того, как кто-нибудь начнет реализовывать масштабирование окна. В конце концов, если вам нужны окна большего размера, было бы глупо не исправлять ошибку, ограничивающую размер окна половиной того, что было бы.

2
27.01.2020, 21:22

Теги

Похожие вопросы