Проблема программы контроллера устройства BPF cgroup с картой - PullRequest
0 голосов
/ 09 марта 2020

Я хочу передать данные между пользователем / стороной ядра с помощью BPF_PROG_TYPE_CGROUP_DEVICE

Я определил карту как:

struct bpf_map_def SEC("maps") my_map = {
    .type = BPF_MAP_TYPE_ARRAY,
    .key_size = sizeof(int),
    .value_size = sizeof(int),
    .max_entries = 100,
};

Когда я выполняю следующее в программе BPF:

int ret = bpf_map_update_elem(&my_map, &key, &value, BPF_ANY);
void *out = bpf_map_lookup_elem(&my_map, &key);

if (!out)
{
    // Never gets in here
}

Мой код никогда не входит в оператор if.

Сторона пользователя

На стороне пользователя я получаю правильно загруженную ссылку на карту с вспомогательными функциями, которые предоставляют мне глобальные массивы как struct bpf_map_data map_data[MAX_MAPS];.

Я могу получить имя карты с помощью:

printf("Name: %s \n", map_data[0].name); это означает, что я могу правильно проанализировать ELF-файл для атрибута SE C ("maps"), и когда я попробуйте следующее:

bpf_map_update_elem(map_data[0].fd, &key, &value, BPF_ANY); bpf_map_lookup_elem(map_data[0].fd, &key, &value);

Данные карты обновлены, и они отображаются в пространстве пользователя.

Проблема в том, что я не вижу карту, определенную в программе BPF, внутри себя. Я пробовал с другим типом программы, и она ведет себя как ожидалось.

Я что-то упускаю с этим типом BPF_PROG_TYPE_CGROUP_DEVICE и обмен данными с картами?

Ответы [ 2 ]

1 голос
/ 09 марта 2020

Это не связано с BPF_PROG_TYPE_CGROUP_DEVICE, но с вашим использованием BPF_MAP_TYPE_ARRAY. Значения карт BPF массива типов всегда инициализируются (в ноль), поэтому out никогда не может быть null. Вы можете проверить значение, указанное out; по умолчанию оно будет равно нулю.

Вам все еще нужно проверить, что возвращаемое значение не равно нулю, потому что верификатор BPF не знает, что он никогда не будет. Так что, если вы не проверите, он будет жаловаться.

0 голосов
/ 09 марта 2020

Моя карта не была правильно связана с объектом int map_fd[MAX_MAPS];. Я поищу причину, но получение карты с этим вызовом:

int map_fd = bpf_object__find_map_fd_by_name(obj, "my_map");

решило мои проблемы.

...