Насколько на практике нестабильны kprobe, связанные с сетью?

Я очень новичок в мире разработки BPF, и мне нужно использовать kprobes в моей программе BPF, чтобы я мог правильно обнаруживать и собирать PID для процессов, пытающихся отправить пакеты по сети. Я хочу развернуть эту программу BPF с моим приложением пользовательского пространства, и мое приложение пользовательского пространства работает в различных версиях и дистрибутивах Linux, хотя все они относительно недавние.

Я знаю, что механизм kprobe официально нестабилен, но насколько вероятно, что моя программа сломается на практике? Я подключаю такие функции, как tcp_connect и ip4_datagram_connect. Я бы подумал, что эти функции не будут сильно меняться между версиями ядра, поэтому более или менее полагаться на них должно быть безопасно? Или я что-то недопонимаю?

Могу ли я отправить приложение, которое использует эти конкретные (tcp/udp) kprobes, не слишком беспокоясь о совместимости или стабильности?


person horseyguy    schedule 20.05.2020    source источник


Ответы (2)


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

На практике я обнаружил, что, например, функции bcc trace с kprobes достаточно стабильны. Только несколько инструментов bcc требовали изменений для обработки новых версий ядра, которые вышли с момента их создания. Это также связано с тем, что авторы инструмента старались использовать более «центральные» функции, которые с меньшей вероятностью изменятся.

На первый взгляд, я бы назвал две упомянутые вами функции, tcp_connect и ip4_datagram_connect, такими "центральными" функциями. Во-первых, они оба экспортируются в таблицу символов.

person pchaigno    schedule 20.05.2020
comment
Блестящий ответ, спасибо, дружище, возможно, однажды мы встретимся в день короля ;) Ты потрясающий! - person horseyguy; 21.05.2020

Дополнение к ответу pchaigno: bcc также отлично подходит для переносимости, поскольку программы BPF компилируются во время выполнения bcc, непосредственно перед загрузкой в ​​​​ядро (поэтому вы обязательно используете определения функций для текущего работающего ядра).

Для работы без bcc, но с такими же гарантиями переносимости программ трассировки, я бы рекомендовал взглянуть на механизм CO-RE (Compile-Once, Run-Everywhere), подробно описанный в этот пост в блоге. CO-RE требует, в частности, чтобы ядро ​​было собрано с отладочной информацией BTF. Эта информация используется при загрузке программы, чтобы убедиться, что она правильно взаимодействует с ядром.

CO-RE не полностью устраняет риск того, что изменения ядра нарушат работу kprobe BPF, но может обойти некоторые изменения в определениях функций или структур.

person Qeole    schedule 20.05.2020