Tema 1 - Kprobe based tracer

  • Termen de predare: 29 Martie 2020, ora 23:00

Scopul temei

  • dobândirea de cunoștinţe legate de instrumentarea funcțiilor din nucleul Linux (mecanismul kretprobes)
  • obținerea de cunoștințe legate de interacțiunea cu sistemul de fişiere /proc din nucleul Linux.
  • obținerea de deprinderi de lucru cu structurile de date specifice nucleului Linux (hash table, list).

Enunț

Realizați un inspector de operații de kernel.

Prin acest inspector ne propunem să interceptăm:

  • apelurile kmalloc și kfree
  • apelul schedule
  • apelurile up și down_interruptible
  • apelurile mutex_lock și mutex_unlock

Inspectorul va reține, la nivel de proces, numărul de apeluri pentru fiecare dintre funcțiile de mai sus. În plus, pentru apelurile kmalloc şi kfree se afișează cantitatea totală de memorie alocată și eliberată.

Inspectorul va fi implementat ca un modul de kernel cu numele tracer.ko.

Detalii de implementare

Interceptarea se va face întregistrând câte o probă (kretprobe) pentru fiecare din funcţiile de mai sus. Inspectorul va reține o listă/tabelă de dispersie cu procesele monitorizate și va contabiliza informațiile de mai sus pentru aceste procese.

Pentru controlul listei/tabelei de dispersie cu procesele monitorizate, se va folosi un char device denumit /dev/tracer, cu majorul 10 și minorul 42. Acesta va expune o interfață ioctl cu două argumente:

  • primul argument reprezintă cererea către subsistemul de monitorizare:
    • TRACER_ADD_PROCESS
    • TRACER_REMOVE_PROCESS
  • al doilea argument reprezintă PID-ul procesului pentru care se va executa cererea de monitorizare.

Pentru a putea crea un char device cu majorul 10 va trebui să folosiţi interfaţa miscdevice din kernel. Definiţiile macro-urilor aferente se găsesc în header-ul tracer.h

Întrucât funcţia kmalloc este inline pentru instrumentarea cantităţii de memorie allocate se va inspecta funcţia __kmalloc, astfel:

  • se va folosi o probă de tip kretprobe, care va reţine cantitatea de memorie alocată şi adresa zonei de memorie alocată.
  • se vor folosi câmpurile .entry_handler şi .handler din structura kretprobe pentru a retine informatii despre cantitatea de memorie alocata si adresa de unde incepe memoria alocata.
static struct kretprobe kmalloc_probe = {
       .entry_handler = kmalloc_probe_entry_handler, /* entry handler */                                                                                                                                                               
       .handler = kmalloc_probe_handler, /* return probe handler */
       .maxactive = 32,
};

Întrucât funcţia kfree primeşte doar adresa zonei de memorie ce urmează a fi eliberată, pentru a determina cantitatea totală de memorie eliberată va trebui pe baza adresei zonei să determinăm dimensiunea ei. Acest lucru este posibil întrucât există o asociere adresa - dimensiune făcută la inspectarea funcţiei __kmalloc.

Pentru restul functiilor de instrumentat este suficient sa folositi o proba de tipulul kretprobe

static struct kretprobe up_probe = {
       .entry_handler = up_probe_handler,
       .maxactive = 32,
};

Kernel-ul din mașina virtuală are opțiunea CONFIG_DEBUG_LOCK_ALLOC activată unde simbolul mutex_lock este un macro care se expandează la mutex_lock_nested. Astfel, pentru a obține informații despre funcția mutex_lock va trebui să instrumentați funcția mutex_lock_nested.

Procesele care au fost adăugate în listă/tabela de dispersie și care își încheie execuția vor fi eliminate din listă/tabela de dispersie. De asemenea un proces va fi eliminat din lista/tabela de dispesie în urma operaţiei TRACER_REMOVE_PROCESS.

Informațiile reținute de inspector vor fi afișate prin intermediul sistemului de fișiere procfs, în fişierul /proc/tracer. Pentru fiecare proces monitorizat se creează o intrare în fişierul /proc/tracer având ca şi prim câmp PID-ul procesului. Intrarea va fi de tipul read-only, și o operație de citire pe aceasta va afișa rezultatele reținute. Un exemplu de afișare a conținutului intrării este:

$cat /proc/tracer
PID   kmalloc kfree kmalloc_mem kfree_mem  sched   up     down  lock   unlock
42    12      12    2048        2048        124    2      2     9      9
1099  0       0     0           0           1984   0      0     0      0
1244  0       0     0           0           1221   100   1023   1023   1002
1337  123     99    125952      101376      193821 992   81921  7421   6392

Testare

Pentru simplificarea procesului de corectare a temelor, dar și pentru a reduce greșelile temelor trimise, corectarea temelor se va face automat cu ajutorul testelor publice care se găsesc în noua infrastructură. Pentru testarea locală, folosiți următoarele comenzi:

$ git clone https://github.com/linux-kernel-labs/linux.git
$ cd linux/tools/labs
$ LABS=assignments/1-tracer make skels 
# dezvoltarea temei se va efectua în directorul skels/assignments/1-tracer/
$ make build
$ make copy
$ make boot

Sfaturi

Pentru a vă mări șansele de a obține nota maximă, citiți și respectați coding style-ul kernelului Linux descris din documentul Coding Style.

De asemenea, folosiți următoarele tool-uri de analiza statică pentru a verifica codul:

checkpatch.pl

  •  scripts/checkpatch.pl --no-tree --strict -f /path/to/your/src-file.c 

sparse

  •  sudo apt-get install sparse 
  •  make C=2 /path/to/your/src-file.c 

cppcheck

  •  sudo apt-get install cppcheck 
  •  cppcheck /path/to/your/src-file.c 

Depunctări

Depunctările generale pentru teme se găsesc pe pagina de Indicații generale. În plus, se vor avea în vedere următoarele elemente:

  • -2: omiterea eliminării corespunzătoare a resurselor (kretprobes, intrări în /proc)
  • -2: probleme de sincronizare la date folosite de mai multe instanțe de execuție (spre exemplu, lista/tabela de dispersie cu procese)

În cazuri excepționale (tema trece testele prin nerespectarea cerințelor) și în cazul în care tema nu trece toate testele se poate scădea mai mult decât este menționat mai sus.

Submitere

Arhiva temei va fi submisă pe vmchecker, în conformitate cu precizările din pagina de reguli.

Din interfața vmchecker alegeți opțiunea Kprobe Based Tracer, aferentă acestei teme.

Resurse

Resursele temei se găsesc și în repo-ul linux, noua infrastructură. Repo-ul so2-assignments conține un script Bash care vă ajută să vă creați un repository privat pe instanța de GitLab a facultății. Urmăriți indicațiile din README și de pe pagina de Wiki dedicată pentru git.

Întrebări

Pentru întrebări legate de temă puteți consulta arhivele listei de discuții sau puteți trimite un e-mail (trebuie să fiți înregistrați). Vă rugăm să urmăriți și să respectați indicațiile de utilizare a listei.

so2/teme/tema1.txt · Last modified: 2020/03/17 17:42 by lucian.teodorescu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0