2016-10-03 11 views
8

Piszę moduł jądra, aby monitorować kilka systemów, które chcą zwrócić argumenty funkcji do użytkownika-land (przez gniazdo netlink), jeśli wywołanie zakończyło się pomyślnie.Linux Kernel - Jak dopasować jprobe do kretprobe?

jprobe.kp.symbol_name = "rename"; 
jprobe.entry = rename_handler; 

kretprobe.kp.symbol_name = "rename"; 
kretprobe.handler = rename_ret_handler; 

static rename_obj_t _g_cur_rename = NULL; 

static void _rename_handler(const char *oldpath, const char *newpath) 
{ 
    _g_cur_rename = create_rename(oldpath, newpath); 
    jprobe_return(); 
} 

static void _rename_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) 
{ 
    /* Send only if successful */ 
    if (regs_return_value(regs) == 0) { 
     add_send_queue(_g_cur_rename); 
    } 
    return 0; 
} 

Martwię się, że kolejna zmiana nazwy syscall może wywłaszczyć [1] obecną jedna po jprobe i wyślę błędne kody powrotne i argumentów.

jprobe: rename(a, b) 
    jprobe rename(c, d) 
    kretprobe 
kretprobe 

Edit: Ten artykuł [2] stanowi, że przerwania są wyłączone podczas obsługi kprobe. Ale czy to oznacza, że ​​przerwania są wyłączone w całym łańcuchu (jprobe -> kprobe -> kretprobe) lub tylko dla tego pojedynczego kprobe?

  1. https://unix.stackexchange.com/questions/186355/few-questions-about-system-calls-and-kernel-modules-kernel-services-in-parallel
  2. https://lwn.net/Articles/132196/

Odpowiedz

1

Przerwania są wyłączone dla każdego jprobe rozmowy: nie dla całej sekwencji.

Ile połączeń oczekujesz w czasie, w którym aplikacja będzie je przetwarzać? Istnieją różne podejścia w zależności od tego, jak szybko oczekujesz wywołań. Najprostsza metoda, jeśli spodziewasz się tylko kilkuset połączeń, zanim je przetworzysz, a przeznaczasz pamięć statyczną na cel, to wdrożenie tablica statyczna z obiektów rename_obj_t w pamięci, a następnie użyj atomic_add z jądra asm, aby wskazać następny wpis (zmień rozmiar twojej tablicy).

W ten sposób za każdym razem zwracasz unikalne odniesienie statyczne, o ile licznik nie zawija się przed przetworzeniem zwróconych wartości. atomic_add ma zagwarantowane prawidłowe bariery pamięci, więc nie musisz martwić się o takie rzeczy, jak spójność pamięci podręcznej.

Powiązane problemy