printk


printk stanowi odpowiednik funkcji printf przeznaczony do pracy z kodem źródłowym jądra linuksa. Stworzono ją ze względu na brak dostępu do standardowej biblioteki wejścia/wyjścia (stdio) w wielu miejscach jądra. Jest podobna do printf pod względem sposobu formatowania komunikatów. Nie obsługuje jednak liczb zmiennoprzecinkowych.

Przykład:

printk(KERN_WARNING "Wszystko w porzadku!\n");

printk pozwala klasyfikować komunikaty, nadając im różne priorytety (loglevels). Priorytety te określa się zwykle używając odpowiedniego makra zdefiniowanego w pliku linux/kernel.h. Makro rozwija sie do stringa, który jest dołączany do komunikatu podczas kompilacji.

Dostępne priorytety:

#define KERN_EMERG     "<0>"
#define KERN_ALERT     "<1>"
#define KERN_CRIT      "<2>"
#define KERN_ERR       "<3>"
#define KERN_WARNING   "<4>"
#define KERN_NOTICE    "<5>"
#define KERN_INFO      "<6>"
#define KERN_DEBUG     "<7>"

Mniejsza wartość -> wyższy priorytet.

Zachowanie printk zależne jest od czterech zmiennych:

Wartość tych zmiennych można odczytać w pliku /proc/sys/kernel/printk. Pozwala on również na ich modyfikację, np. przy wykorzystaniu polecenia echo:

$ echo "3 3 1 7" > /proc/sys/kernel/printk

Innym sposobem na zmianę ich wartości jest użycie wywołania systemowgo syslog lub sysctl.

Można także uruchomić klogd z opcją -c, aby ustalić wartość zmiennej console_loglevel np.

$ klogd -c 5

Jeśli w systemie działa klogd i standardowo skonfigurowany syslogd to część komunikatów (zależnie od priorytetu) jest dodawana, do któregoś z plików w katalogu /var/log np. syslog.

Można je zawsze odczytać w pliku /proc/kmsg (o ile zamontowany jest /proc).


printk wpisuje komunikaty do bufora cyklicznego o długości LOG_BUF_LEN bajtów zdefinowanej w pliku kernel/printk.c (zwykle rzędu kilkudziesięciu kilobajtów). Następnie budzi czekające na nie procesy: śpiące w wywołaniu systemowym syslog lub czytające z pliku /proc/kmsg.

W przypadku zapełnienia bufora, printk nadpisuje najstarsze dane. Dzięki temu system może działać bez procesu logującego komunikaty jądra i jednocześnie minimalizowane jest zużycie pamięci.


Aby zapobiec przeciążeniu systemu przez zalew komunikatów można użyć funkcji printk_ratelimit. Kontroluje ona liczbę nadchodzących komunikatów i zwraca 0 w sytuacji, gdy jest ich zbyt wiele.

Umieszcza się ją przed printk:

if (printk_ratelimit())
  printk(KERN_DEBUG "W porzadku! Limit nie zostal przekroczony!\n");

Jej zachowanie kontroluje się poprzez następujące pliki:

We wczesnej fazie inicjalizacji systemu printk nie działa. Stosuje się wtedy early_printk.



Bibliografia

http://rainbow.mimuw.edu.pl/SO/Linux-doc/LinuxDeviceDrivers/ch04.pdf
http://web.cs.wpi.edu/~cs3013/a06/procinfo.pdf
http://www.kernelthread.com/publications/faq/335.html
prezentacje dotyczące odpluskwiania z ubiegłego roku