| < | 1. Wstęp | 3. klogd i syslogd | 4. strace i ltrace | 5. gdb i UML | 6. kdb i kgdb | > |
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:
console_loglevel - komunikaty o priorytecie mniejszym od wartości tej zmiennej przekazywane są do bieżącej konsolidefault_message_loglevel - taki priorytet jest nadawany komunikatom, którym go jawnie nie przypisaliśmyminimum_console_loglevel - najmniejsza dopuszczalna wartość console_logleveldefault_console_loglevel - domyślna wartość dla console_loglevel, początkowo określona przez makro #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */ z pliku kernel/printk.c
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:
/proc/sys/kernel/printk_ratelimit - minimalny średni odstęp między komunikatami/proc/sys/kernel/printk_ratelimit_burst - najdłuższa dopuszczalna seria komunikatów
We wczesnej fazie inicjalizacji systemu printk nie działa. Stosuje się wtedy early_printk.
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
| < | 1. Wstęp | 3. klogd i syslogd | 4. strace i ltrace | 5. gdb i UML | 6. kdb i kgdb | > |