Как сделать как "netstat -p", но быстрее? - PullRequest
3 голосов
/ 30 октября 2010

Кажется, что "netstat -p" и "lsof -n -i -P" читают ссылки на все процессы fd, например stat /proc/*/fd/*.

Как сделать это эффективнее?

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

Также приветствуются способы, предлагающие вещи iptables или патчи ядра.

1 Ответ

4 голосов
/ 30 октября 2010

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

  1. Кэширование файловых дескрипторов в /proc и информации в /proc/net. Это делается программами, упомянутыми в связанном ответе, но жизнеспособно, только если ваш процесс длится более нескольких секунд.
  2. Вы можете попробовать getpeername(), но это зависит от того, знаете ли вы о возможных конечных точках и процессах, на которые они отображаются. Ваши вопросы предполагают, что вы подключаете сокеты локально, вы можете попробовать использовать Unix сокеты , которые позволяют вам получать учетные данные однорангового узла при обмене сообщениями, передавая SO_PASSCRED в setsockopt() , Посмотрите на эти примеры (они довольно неприятные, но лучшее, что я смог найти).
  3. Взгляните на fs/proc/base.c в ядре Linux. В этом суть информации, полученной в результате ссылки на чтение файлового дескриптора в /proc/PID/fd/FD. Значительная часть накладных расходов заключается в передаче запросов вверх и вниз по уровню VFS, многочисленных блокировках, которые происходят во всех структурах данных ядра, которые предоставляют предоставленную информацию, и в stringyfying и destringyfying в ядре и на вашем конце соответственно. Вы можете адаптировать часть кода в этом файле, чтобы генерировать эту информацию без многих промежуточных уровней, в частности, минимизировать блокировку один раз на процесс или просто один раз на сканирование всего набора данных, который вам нужен.

Моя личная рекомендация состоит в том, чтобы пока просто перебирать его, в идеале проходить процессы в /proc в обратном числовом порядке, поскольку более свежие и интересные процессы будут иметь более высокие PID и возвращаться, как только вы найдете результаты, которые вы после. Делать это один раз для каждого входящего соединения стоит относительно дешево, это действительно зависит от того, насколько критична производительность вашего приложения. Вы определенно найдете целесообразным обойти вызов netstat и непосредственно проанализировать новое соединение с /proc/net/PROTO, а затем найти сокет в /proc/PID/fd. Если весь ваш трафик является локальным, просто переключитесь на сокеты Unix и получите учетные данные напрямую. Написание нового модуля syscall или proc, который выдает огромные объемы данных относительно файловых дескрипторов, которые я бы сохранил в последний раз.

...