< | 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_loglevel
default_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 | > |