Автоматическая настройка приоритетов процессов в Linux - PullRequest
7 голосов
/ 26 сентября 2010

Я пытаюсь написать программу, которая автоматически устанавливает приоритеты процесса на основе файла конфигурации (в основном пары путь - приоритет).

Я думал, что лучшим решением будет модуль ядра, который заменяет системный вызов execve (). Жаль, что таблица системных вызовов не экспортируется в версиях ядра> 2.6.0, поэтому невозможно заменить системные вызовы без действительно ужасных хаков.

Я не хочу сделать следующее:

-Заменить двоичные файлы скриптами оболочки, которые запускают и обновляют двоичные файлы. -Патч / перекомпилировать мое ядро ​​Ubuntu -Деет отвратительные хаки, такие как чтение исполняемой памяти ядра и угадывание местоположения таблицы системных вызовов -Обработка запущенных процессов

Я действительно хочу быть:

-Возможно контролировать приоритет любого процесса на основе его исполняемого пути и файла конфигурации. Правила распространяются на любого пользователя.

У кого-нибудь из вас есть идеи, как выполнить это задание?

Ответы [ 7 ]

4 голосов
/ 22 сентября 2015

Если вы выбрали решение для опроса, большинство функций, которые вы хотите реализовать, уже существуют в Automatic Nice Daemon . Вы можете настроить хорошие уровни для процессов на основе имени процесса, пользователя и группы. Можно даже динамически настраивать приоритеты процесса в зависимости от того, сколько процессорного времени оно использовало до сих пор.

3 голосов
/ 26 сентября 2010

Иногда опрос является необходимостью, и даже больше оптимально в конце концов - хотите верьте, хотите нет. Это зависит от множества переменных.

Если затраты на опрос достаточно малы, они намного превышают сложность, стоимость и РИСК разработки собственных хуков ядра стиля, чтобы получать уведомления об изменениях, которые вам необходимы. Тем не менее, когда перехватчики или события уведомления доступны или могут быть легко введены, их, безусловно, следует использовать, если ситуация вызывает.

Это классическое мышление программиста «совершенство». Как инженеры, мы стремимся к совершенству. Это реальный мир, хотя иногда приходится идти на компромиссы. По иронии судьбы, в некоторых случаях более совершенное решение может быть менее эффективным.

Я разрабатываю аналогичный инструмент «Автоматизация оптимизации процессов и приоритетов процессов» для Windows под названием «Process Lasso» (не реклама, его бесплатно). У меня был похожий выбор, чтобы сделать гибридное решение. Ловушки режима ядра доступны для определенных связанных с процессом событий в Windows (создание и уничтожение), но они не только не отображаются в пользовательском режиме, но и не помогают при мониторинге других метрик процесса. Я не думаю, что какая-либо ОС будет изначально информировать вас о любых изменениях в любой метрике процесса. Накладные расходы для этого множества различных хуков могут быть намного больше, чем простой опрос.

Наконец, учитывая ВЫСОКУЮ частоту изменений процесса, может быть лучше обрабатывать все изменения одновременно (опрос с интервалом) по сравнению с событиями / перехватами уведомлений, которые, возможно, придется обрабатывать много раз в секунду.

Вы правы, чтобы держаться подальше от сценариев. Зачем? Потому что они медленные (э). Конечно, планировщик linux неплохо справляется с обработкой потоков, связанных с процессором, понижая их приоритет и вознаграждая (обновляя) приоритет потоков, связанных с вводом / выводом, поэтому даже при высоких нагрузках скрипт должен быть Я думаю, отзывчивый.

1 голос
/ 17 июля 2014

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

$KERNEL_SOURCE/fs/binfmt_elf.c
$KERNEL_SOURCE/fs/binfmt_misc.c
$KERNEL_SOURCE/fs/binfmt_script.c

Они могут дать вам первое представление, с чего начать.

Вы можете просто изменить загрузчик ELF, чтобы проверить наличие дополнительного раздела в ELF.файлы и при обнаружении использовать его содержимое для изменения приоритетов планирования.Тогда вам даже не нужно будет управлять отдельными файлами конфигурации, а просто добавить новый раздел к каждому исполняемому файлу ELF, которым вы хотите управлять таким образом, и все готово.Смотрите objcopy / objdump инструментов binutils, чтобы узнать, как добавить новые разделы в файлы ELF.

1 голос
/ 26 сентября 2010

Есть еще одна точка атаки, которую вы можете рассмотреть: замените системный динамический компоновщик на модифицированный, который применяет вашу логику. (См. Эту статью , где приведены некоторые хорошие примеры того, что возможно из-за пренебрежения искусством взлома линкеров).

Где этот подход будет иметь проблемы с чисто статически связанными двоичными файлами. Я сомневаюсь, что в современной системе есть многое, что на самом деле не связывает что-то динамически (такие вещи, как busybox-static являются очевидными исключениями, хотя вы можете рассматривать возможность получить минимальную оболочку вне ваших элементов управления как особенность, когда все идет ужасно неправильно), так что это может не иметь большого значения. С другой стороны, если политики приоритетов предназначены для наведения порядка в перегруженной общей многопользовательской системе, вы можете увидеть, как умные пользователи готовят статически связанные версии приложений, чтобы избежать навязанных компоновщиком приоритетов.

1 голос
/ 26 сентября 2010

Конечно, просто переберите / proc / nnn / exe, чтобы получить путь к запущенному образу. Используйте только те, у которых есть косые черты, остальные - проки ядра.

Проверьте, не обработали ли вы его ранее, в противном случае найдите новый приоритет в файле конфигурации и используйте renice (8), чтобы настроить его приоритет.

0 голосов
/ 22 ноября 2016

Если рассматриваемые процессы запускаются путем выполнения исполняемого файла с известным путем, вы можете использовать механизм inotify для отслеживания событий в этом файле. Его выполнение вызовет события I_OPEN и I_ACCESS.

К сожалению, это не скажет вам, какой процесс вызвал событие, но затем вы можете проверить, какие /proc/*/exe являются символической ссылкой на исполняемый файл и renice идентификатор процесса в вопросе.

например. Вот грубая реализация в Perl, использующая Linux :: Inotify2 (которая в Ubuntu предоставляется пакетом liblinux-inotify2-perl):

perl -MLinux::Inotify2 -e '
  use warnings;
  use strict;
  my $x = shift(@ARGV);
  my $w = new Linux::Inotify2;
  $w->watch($x, IN_ACCESS, sub
  {
    for (glob("/proc/*/exe"))
    {
      if (-r $_ && readlink($_) eq $x && m#^/proc/(\d+)/#)
      {
        system(@ARGV, $1)
      }
    }
  });
  1 while $w->poll
' /bin/ls renice

Конечно, вы можете сохранить код Perl в файл, скажем, onexecuting, добавить первую строку #!/usr/bin/env perl, сделать файл исполняемым, поместить его в $PATH и затем использовать onexecuting /bin/ls renice.

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

0 голосов
/ 12 июня 2016

Есть ли у кого-нибудь из вас идеи о том, как выполнить эту задачу?

В качестве идеи рассмотрите возможность использования apparmor в жалобе.-Режим.Это будет записывать определенные сообщения в системный журнал, который вы можете прослушать.

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