Почему я не могу перехватить write в seq?

Вопрос или проблема

На основе Limit file IO speed я создал https://git.data.coop/tange/tangetools/src/branch/master/iothrottle

Это работает для некоторых программ:

iothrottle -i 10M cat foo > bar # Да, здесь можно просто использовать pv
iothrottle -o 1M ffmpeg -i foo.mp3 foo.wav
iothrottle -o 1M cp -a foodir /other/fs/foodir

Это не работает:

iothrottle -o 1M cp -a foodir /same/fs/foodir

потому что на одной файловой системе cp использует один вызов copy_file_range на файл.

Меня устраивает это ограничение.

Это также не работает для seq. Когда я запускаю strace seq 100000, я получаю:

write(1, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14"..., 8192) = 8192
write(1, "\n1861\n1862\n1863\n1864\n1865\n1866\n1"..., 4096) = 4096
write(1, "2680\n2681\n2682\n2683\n2684\n2685\n26"..., 4096) = 4096
write(1, "499\n3500\n3501\n3502\n3503\n3504\n350"..., 4096) = 4096
write(1, "18\n4319\n4320\n4321\n4322\n4323\n4324"..., 4096) = 4096
write(1, "7\n5138\n5139\n5140\n5141\n5142\n5143\n"..., 4096) = 4096
write(1, "\n5957\n5958\n5959\n5960\n5961\n5962\n5"..., 4096) = 4096
write(1, "6776\n6777\n6778\n6779\n6780\n6781\n67"..., 4096) = 4096
write(1, "595\n7596\n7597\n7598\n7599\n7600\n760"..., 4096) = 4096
write(1, "14\n8415\n8416\n8417\n8418\n8419\n8420"..., 4096) = 4096
write(1, "3\n9234\n9235\n9236\n9237\n9238\n9239\n"..., 3838) = 3838

Таким образом, кажется, что он вызывает write (а не какой-то mmap или другую магию), и, следовательно, должен работать.

Но когда я запускаю: IOTHROTTLE_DEBUG=1 iothrottle -o 1M seq 10000 >/dev/null, я получаю:

init called: default read_limit=0, write_limit=0
IOTHROTTLE_READ=0
IOTHROTTLE_WRITE=1048576
Final read_limit=0, write_limit=1048576
allowed: 608 written: 0
allowed: 617 written: 0

Это говорит мне, что iothrottle перехватывает только 2 вызова write.

Что я упускаю?

Ответ или решение

Понимание того, почему не удается перехватить вызов write в команде seq, предполагает глубокий анализ работы системы и метода перехвата системных вызовов. Ваше желание использовать iothrottle для ограничения скорости ввода-вывода данных с помощью команды seq подразумевает необходимость в корректном отслеживании всех вызовов write. Ниже подробно рассмотрим возможные причины, почему это может не работать так, как ожидается.

Проблемы перехвата системных вызовов

  1. Библиотеки и обертки: Возможно, iothrottle не охватывает все возможные способы вызова функций write, что может быть связано с библиотеками, используемыми в программе seq. Например, некоторые системные вызовы могут выполняться не напрямую, а через стандартные функции ввода-вывода, такие как fwrite, которые могут не захватываться вашим инструментом, если они реализованы через buffered I/O.

  2. Оптимизации ядра: Проверьте, нет ли оптимизаций, связанных с выводом на консоль или перенаправлением в /dev/null. Некоторые программы могут работать по-разному в зависимости от конечного местоположения вывода, что особенно актуально для высоко оптимизированных системных утилит, таких как seq.

  3. Проблемы с библиотеками: Если iothrottle зависит от замены стандартных библиотек динамического связывания (LD_PRELOAD), это также может быть причиной. Некоторые системные утилиты могут игнорировать эти параметры из-за безопасности или по другим причинам.

Анализ вывода и логирования

  1. Ограниченное количество вызовов write: Вы заметили, что только 2 вызова write отображаются в логах iothrottle, хотя strace демонстрирует больше. Это может указывать на проблему с обработкой вызовов в iothrottle. Убедитесь, что все необходимые вызовы действительно перехватываются.

  2. Проблемы совместимости: Возможно, имеются проблемы с версией iothrottle или его совместимостью с текущим окружением и используемой версией ядра или утилит.

Рекомендации по решению

  • Дополнительные проверки и тесты: Используйте другие утилиты мониторинга, такие как lsof или dstat, для проверки, отслеживаются ли все вызовы корректно.
  • Кодовая база и тестирование: Проанализируйте исходный код iothrottle, чтобы выявить, какие сценарии он может пропускать. Проведите тестирование с разными конфигурациями окружения.
  • Обновления и патчи: Убедитесь, что используете последнюю версию iothrottle и, если возможно, внесите необходимые изменения для расширения функциональности.

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

Оцените материал
Добавить комментарий

Капча загружается...