Open Source im professionellen Einsatz
Linux-Magazin 06/2014
1269

Dateizugriffe

Mit diesem Wissen ausgestattet kann der Anwender beispielsweise den Zugriff auf bestimmte Dateien überwachten. Möchte er etwa wissen, welche Tasks auf die Dateien »/etc/passwd« oder »/etc/shadow« zugreifen, verwendet er das Ktap-Skript aus Listing 1. Damit das Skript die zugreifenden Tasks identifizieren kann, setzt es einen Tracepoint auf den Beginn des Systemcalls »open()« .

Listing 1

fileaccess.kp überwacht Dateien

01 #!/usr/local/bin/ktap -q
02
03 var path = {}
04
05 printf("%5s %6s %-12s %3s %3s %s\n",
06     "UID", "PID", "COMM", "FD", "ERR", "PATH");
07
08 trace syscalls:sys_enter_open {
09     path[tid] = user_string(arg1)
10 }
11
12 trace syscalls:sys_exit_open {
13     var fd
14     var errno
15
16     if (arg1 < 0) {
17         fd = 0
18         errno = -arg1
19     } else {
20         fd = arg1
21         errno = 0
22     }
23     #if (execname=="w") {
24     #   path[tid] = 0
25     #    return
26     #}
27     if (path[tid]=="/etc/passwd") {
28         printf("%5d %6d %-12s %3d %3d %s\n",
29             uid, pid, execname, fd,
30             errno, path[tid])
31     }
32     if (path[tid]=="/etc/shadow") {
33         printf("%5d %6d %-12s %3d %3d %s\n",
34             uid, pid, execname, fd,
35             errno, path[tid])
36     }
37     path[tid] = 0
38 }

Sobald der Kernel diesen aufruft, speichert das Skript den Namen der geöffneten Datei. Eigentlich könnte an dieser Stelle direkt eine Ausgabe erfolgen, falls es sich um die Datei »/etc/passwd« oder »/etc/shadow« handelt. Möchte der Anwender zugleich mitprotokollieren, ob das Programm erfolgreich Zugriff erhält, wertet er zusätzlich den Returnwert des Systemcalls aus. Daher setzt er einen zweiten Tracepoint auf das Ende des Systemcalls »sys_exit_open()« . Dann erfolgt die Ausgabe.

Den Namen der zu öffnenden Datei in einem Feld (Assoziativ-Array) abspeichern ist notwendig, da mehrere Tasks zugleich den Systemcall »open()« verwenden könnten. Das Feld, indiziert mit der Thread-ID, rettet die Namen auch im Fall paralleler Zugriffe. Auf den Anfang und auf das Ende von Funktionen triggern zu können ermöglicht es, die Verarbeitungsdauer einer Funktion auszumessen. Das mit Ktap ausgelieferte Beispielprogramm »function_time.kp« zeigt, wie das geht. Es ermittelt die minimale, durchschnittliche und maximale Reaktionszeit des Systemcalls »read()« (Kernelfunktion »vfs_read()« ). Dazu setzt das Skript zwei Tracepoints, den ersten zu Beginn der Funktion »vfs_read()« . Bei dessen Auslösung speichert es per »gettimeofday_us()« die aktuelle Zeit in einer Tabelle ab.

Am Ende der Funktion nimmt das Programm wiederum die Zeit. Mittels Subtraktion der Zeitstempel lässt sich dann die Zeitdauer ermitteln. Das Ktap-Skript überprüft noch, ob es damit einen neuen Maximal- oder Minimalwert gibt, danach aktualisiert es zur Berechnung der Durchschnittszeit die bisherige Gesamtzeit und die Anzahl der Aufrufe. Wird das Skript abgebrochen, gibt »trace_end« die erfassten Zeiten aus (Listing 2).

Listing 2

Differenzzeitmessung mit function_time.kp

01 #!/usr/bin/env ktap
02
03 var self = {}
04 var count_max = 0
05 var count_min = 0
06 var count_num = 0
07 var total_time = 0
08
09 printf("measure time(us) of function vfs_read\n");
10
11 trace probe:vfs_read {
12     if (execname == "ktap") {
13         return
14     }
15
16     self[tid] = gettimeofday_us()
17 }
18
19 trace probe:vfs_read%return {
20     if (execname == "ktap") {
21         return
22     }
23
24     if (self[tid] == nil) {
25         return
26     }
27
28     var durtion = gettimeofday_us() - self[tid]
29     if (durtion > count_max) {
30         count_max = durtion
31     }
32     var min = count_min
33     if (min == 0 || durtion < min) {
34         count_min = durtion
35     }
36
37     count_num = count_num + 1
38     total_time = total_time + durtion
39
40     self[tid] = nil
41 }
42
43 trace_end {
44     var avg
45     if (count_num == 0) {
46         avg = 0
47     } else {
48         avg = total_time/count_num
49     }
50
51     printf("avg\tmax\tmin\n");
52     printf("-------------------\n")
53     printf("%d\t%d\t%d\n", avg, count_max, count_min)
54 }

Außerdem können Treiberentwickler mit Ktap ihren selbst geschriebenen Code überwachen. Listing 3 zeigt ein Programm, das die Funktion »driver_read()« eines Gerätetreibers überwacht, wie ihn etwa die Kern-Technik-Folge 69 [3] beschrieben hat. Dabei kommt die Filterfunktion zum Einsatz, die den Instruction Pointer (»ip« , Befehlszähler der CPU) auf die Adresse der Funktion »driver_read()« überwacht. Ein einfaches Skript, das Ftrace verwendet, gibt bei jedem Zugriff eine Meldung aus und beim Abbrechen die Gesamtzahl der Zugriffe.

Listing 3

driverread.kp überwacht driver_read

01 var count=0;
02
03 trace ftrace:function /ip==driver_read*/ {
04     print("driverread ")
05     count+=1;
06 }
07
08 trace_end {
09     print("driverread hist:")
10     print(count)
11 }

Besonders gut verdeutlicht das von Tadaki Sakai bereitgestellte Skript »tetris.kp« die Leistungsfähigkeit von Ktap. Damit spielen Anwender das altbekannte Tetris – jedoch im Kernel (Abbildung 4). Dabei läuft im Linux-Kern nicht nur der Spielalgorithmus, sondern sogar die komplette Eingabe. Ein Blick in den für x86-Prozessoren geschriebenen Programmcode offenbart, wie das Skript eine Kernelprobe auf die Funktion »kbd_event()« [4] setzt und dort aus den CPU-Registern den Keycode ausliest.

Abbildung 4: Tetris im Linux-Kernel: Ktap und seine eingebaute Skriptsprache machen's möglich.

Zusätzlich aktiviert das Skript alle 200 Millisekunden eine Timerfunktion, die den Keycode auswertet und damit den Spielstein bewegt oder rotiert sowie die Ausgabe auf der Konsole initiiert. Der Code zum Ktap-Tetris findet sich im Ktap-Archiv unter »sample/games/tetris.kp« .

Work in Progress

Eigentlich müsste unter den Ktap-Appetithappen jetzt ein Abschnitt über das Foreign Function Interface (FFI) folgen. Es ermöglicht, direkt aus Ktap heraus auf Kernel-interne Datenstrukturen zuzugreifen und sogar Kernelfunktionen selbst aufzurufen [5]. Funktionen lassen sich also nicht nur überwachen, sondern auch im Programm verwenden. Die Beispielskripte zeigen das Aufrufen der Funktion »printk()« , über die Ktap Daten im Kernel-Log ablegt oder den Zugriff auf die zentrale Datenstruktur »skb« des Netzwerk-Subsystems. Das Skript »ffi_kmalloc.kp« ruft 1000-mal die Funktionen »kmalloc()« und »kfree()« auf, um die dafür benötigte Zeit zu messen.

Allerdings ist in der aktuellen Version 0.4 der Code für das FFI kaputt, da sich Jovi Zhangwei ganz auf die Integration der zentralen Komponenten seines Trace-Subsystems in den Standardkernel konzentriert. Das prinzipielle Placet hat er zwar, aber für die konkrete Aufnahme fordern die Core-Entwickler noch schlankeren Bytecode. Ktap ist also "Work in progress" und arbeitet zudem nicht in allen Punkten fehlerfrei. Laufen Ktap-Programme über einen längeren Zeitraum, kommt es schon mal zu Abbrüchen. In machen Fällen muss man zur Behebung in »include/ktap_types.h« Konstanten anpassen.

Und schließlich die Dokumentation: Das beiliegende Tutorial [6] ist verglichen mit den Möglichkeiten von Ktap als bescheiden zu bezeichnen. Um diese auszuschöpfen, ist aber viel Know-how aus dem Bereich Kerneltracing notwendig. Einen ersten Einstieg mit Schwerpunkt auf dem Werkzeug Dtrace liefert [7]. Wer bereits Erfahrungen mit Dtrace oder Systemtap besitzt, wird schnell die Parallelen erfassen. Neulinge sollten sich vor allem die Beispielprogramme ansehen, die dem Ktap-Quellcode unterhalb des Verzeichnisses »samples/« beiliegen. Es gibt noch viel zu tun für den Entwickler Jovi Zhangwei, vielleicht finden sich ja noch ein paar Mitstreiter. (mhu)

Infos

  1. Ktap: http://www.ktap.org
  2. Quade, Kunst: "Kern-Technik – Folge 73": Linux-Magazin 04/14, S. 92
  3. Quade, Kunst: "Kern-Technik – Folge 69": Linux-Magazin 08/13, S. 86
  4. »kbd_event« : http://lxr.free-electrons.com/source/drivers/tty/vt/keyboard.c#L1364
  5. Qingping, Eason, "Ktap FFI Proposal": https://www.cs.cmu.edu/~412/lectures/L09_KTAP_Proposal.pdf
  6. Ktap-Tutorial: http://www.ktap.org/doc/tutorial.html
  7. Brendan Gregg, "Linux Performance Analysis and Tools": http://www.brendangregg.com/Slides/SCaLE_Linux_Performance2013.pdf
  8. Listings zum Artikel: http://www.linux-magazin.de/static/listings/magazin/2014/06/kern-technik/

Der Autor

Eva-Katharina Kunst, Journalistin, und Jürgen Quade, Professor an der Hochschule Niederrhein, sind seit den Anfängen von Linux Fans von Open Source. Mit "Embedded Linux lernen mit dem Raspberry Pi" erscheint Quades drittes Linux-Buch.

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 5 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Kern-Technik

    Das Tracing-Werkzeug Ktap hilft Admins und Kernelentwicklern bei Tuning und Fehlersuche. Diese Kern-Technik zeigt die ersten Schritte mit dem Interpreter im Kernel.

comments powered by Disqus

Stellenmarkt

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.