взаимодействие python с картами BPF
Мне интересно, можно ли легко инициализировать карты BPF из пользовательского пространства Python. Для моего проекта у меня будет страшно выглядящий массив NxN 2d с плавающей запятой для каждого процесса. Для простоты предположим, что N постоянно во всех процессах (скажем, 5). Чтобы добиться поддержки этих данных ядром, я мог бы сделать что-то вроде:
b = BPF(text = """
typedef struct
{
float transMat[5][5];
} trans_struct;
BPF_HASH(trans_mapping, char[16], trans_struct);
.....
""")
Мне интересно, есть ли простой способ инициализировать эту карту из python. Что-то типа:
for ele in someDictionary:
#asume someDitionary has mapping (comm -> 5x5 float matrix)
b["trans_mapping"].insert(ele, someDictionary[ele])
Я полагаю, что суть моей путаницы заключается в следующем: 1) все методы карты доступны пользователю, 2) как мы обеспечиваем согласованность типов при переходе от объектов python к структурам c
1 ответ
Решение на основе комментария pchaigno. Ключевые моменты, на которые следует обратить внимание, - это использование c_types для обеспечения согласованности типов во всех средах и извлечение таблицы путем индексации программного объекта BPF. Из-за нашей способности получать карты путем индексации функция get_table() теперь считается устаревшей. Этот формат обеспечивает структуру загрузки данных в карту из интерфейса Python, но не полностью соответствует специфике моего вопроса.
from time import sleep, strftime
from bcc import BPF
from bcc.utils import printb
from bcc.syscall import syscall_name, syscalls
from ctypes import *
b = BPF(text = """
BPF_HASH(start, u32, u64);
TRACEPOINT_PROBE(raw_syscalls, sys_exit)
{
u32 syscall_id = args->id;
u32 key = 1;
u64 *val;
u32 uid = bpf_get_current_uid_gid();
if (uid == 0)
{
val = start.lookup(&key); //find value associated with key 1
if (val)
bpf_trace_printk("Hello world, I have value %d!\\n", *val);
}
return 0;
}
""")
thisStart = b["start"]
thisStart[c_int(1)] = c_int(9) #insert key-value part 1->9
while 1:
try:
(task, pid, cpu, flags, ts, msg) = b.trace_fields()
except KeyboardInterrupt:
print("Detaching")
exit()
print("%-18.9f %-16s %-6d %s" % (ts, task, pid, msg))