Файлы System/bin Android 12. Справочник.


  Все     Команда     Скрипт     Служба     Приложение  

bpfloader
Загрузка виртуальной машины BPF

Тип файла: команда

   

Комментарии
bpfloader.rc

zygote-start официально запускает netd (см. //system/core/rootdir/init.rc)

Однако на некоторых аппаратных средствах он также запускается с post-fs-data, что чуть раньше.
Однако в этом нет никакой пользы, поскольку на устройствах 4.9+ P+ netd просто
блокируется до тех пор, пока bpfloader не завершит работу и не установит свойство bpf.progs_loaded.

Важно, чтобы мы запускали bpfloader после:
- /sys/fs/bpf уже смонтирован,
- инициализируется апекс (в т.ч. откат), чтобы в дальнейшем мы могли загружать bpf-программы,
поставляемые в составе основных модулей апекса)
- logd готов для логирования

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

на load_bpf_programs

Включите eBPF JIT, но обратите внимание, что в 64-разрядных ядрах он, вероятно,
уже принудительно включен параметром конфигурации ядра BPF_JIT_ALWAYS_ON.
написать /proc/sys/net/core/bpf_jit_enable 1

Включить JIT-экспорт kallsyms только для привилегированных пользователей
написать /proc/sys/net/core/bpf_jit_kallsyms 1
exec_start bpfloader
служба bpfloader /system/bin/bpfloader
возможности CHOWN SYS_ADMIN NET_ADMIN

Установите RLIMIT_MEMLOCK на 1 ГБ для bpfloader.

На самом деле потребовалось бы только 8 МБ, если бы bpfloader работал как собственный uid.

Однако, хотя rlimit относится к потоку, учет распространяется на всю систему.
Так, например, если графический стек уже выделил 10 МБ данных memlock еще до того,
как bpfloader получит шанс запуститься, он потерпит неудачу, если его rlimit memlock
составляет всего 8 МБ, поскольку для него не останется ничего.

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

У нас были проблемы, из-за которых устройства иногда (редко) загружались в аварийном цикле,
потому что bpfloader иногда терял гонку времени загрузки против выделения памяти,
заблокированного во время загрузки графического стека.

Таким образом, memlock bpfloader должен быть на 8 МБ выше, чем потребление заблокированной
памяти корневым uid где-либо еще в системе...
Но мы не знаем, что это такое для всех возможных устройств...

В идеале мы бы просто предоставили bpfloader возможность IPC_LOCK, и он просто проигнорировал
бы свой memlock rlimit...
Но оказывается, что эта возможность даже не проверяется системным вызовом ядра bpf.

Таким образом, мы просто используем 1 ГБ как разумное приближение к бесконечности.

rlimit memlock 1073741824 1073741824 ваншот
reboot_on_failure reboot,bpfloader-failed мы на самом деле не обновляемся,
но хотим иметь возможность загружать программы bpf, поставляемые в обновляемых апексах


Berkeley Packet Filters (BPF)

Современная технология BPF — это улучшенная и дополненная версия старой технологии с тем же названием, называемой нынче, во избежание путаницы, classic BPF. На основе классического BPF были созданы всем известная утилита tcpdump, механизм seccomp, а также менее известные модуль xt_bpf для iptables и классификатор cls_bpf. В современном Linux классические программы BPF автоматически транслируются в новую форму, однако, с пользовательской точки зрения, API остался на месте и новые применения классического BPF находятся до сих пор.

https://habr.com/ru/articles/514736/

В своей основе BPF — это виртуальная машина-песочница, позволяющая запускать «произвольный» код в пространстве ядра без ущерба для безопасности. Программы BPF создаются в пространстве пользователя, загружаются в ядро и подсоединяются к какому-нибудь источнику событий. Событием может быть, например, доставка пакета на сетевой интерфейс, запуск какой-нибудь функции ядра, и т.п. В случае пакета программе BPF будут доступны данные и метаданные пакета (на чтение и, может, на запись, в зависимости от типа программы), в случае запуска функции ядра — аргументы функции, включая указатели на память ядра, и т.п.

https://source.android.com/docs/core/architecture/kernel/bpf

Расширенный пакетный фильтр Беркли (eBPF) — это виртуальная машина в ядре, которая
запускает пользовательские программы eBPF для расширения функциональных возможностей ядра.
Эти программы можно подключить к зондам или событиям в ядре и использовать
для сбора полезной статистики ядра, мониторинга и отладки.

Программа загружается в ядро с помощью системного вызова bpf(2) и предоставляется
пользователем в виде двоичного двоичного объекта машинных инструкций eBPF.
Система сборки Android поддерживает компиляцию программ C в eBPF с использованием
простого синтаксиса файла сборки, описанного в этом документе.

Дополнительную информацию о внутреннем устройстве и архитектуре eBPF можно найти
на странице eBPF Брендана Грегга .

Android включает в себя загрузчик eBPF и библиотеку, которая загружает программы eBPF во время загрузки.

Android-загрузчик BPF

Во время загрузки Android /system/etc/bpf/загружаются все программы eBPF,
расположенные по адресу. Эти программы представляют собой двоичные объекты,
созданные системой сборки Android из программ C и сопровождаемые файлами Android.bp
в дереве исходного кода Android.

Система сборки сохраняет сгенерированные объекты по адресу /system/etc/bpf,
и эти объекты становятся частью образа системы.