1 #include <lunaix/fs/twifs.h>
2 #include <lunaix/fs/twimap.h>
3 #include <lunaix/syscall.h>
4 #include <lunaix/syscall_utils.h>
5 #include <lunaix/syslog.h>
6 #include <lunaix/device.h>
7 #include <lunaix/owloysius.h>
8 #include <lunaix/ds/flipbuf.h>
12 #include <klibc/strfmt.h>
14 #include "kp_records.h"
16 #define MAX_BUFSZ_HLF 256
17 #define MAX_KPENT_NUM 1024
19 static char tmp_buf[MAX_BUFSZ_HLF * 2];
20 static DEFINE_FLIPBUF(fmtbuf, MAX_BUFSZ_HLF, tmp_buf);
22 static struct kp_records kprecs = {
23 .kp_ents = { .ents = { .next = &kprecs.kp_ents.ents,
24 .prev = &kprecs.kp_ents.ents } },
25 .max_recs = MAX_KPENT_NUM,
26 .kp_ent_wp = &kprecs.kp_ents.ents
28 export_symbol(debug, kprintf, kprecs);
31 shift_level(const char* str, int* level)
33 if (str[0] == KMSG_LVLSTART) {
34 *level = KMSG_LOGLEVEL(str[1]);
44 __put_console(const struct kp_entry* ent)
50 if (unlikely(!sysconsole)) {
55 ms = ent->time % 1000;
56 buf = flipbuf_flip(&fmtbuf);
57 sz = ksnprintf(buf, MAX_BUFSZ_HLF,
58 "[%04d.%03d] %s", s, ms, ent->content);
60 sysconsole->ops.write(sysconsole, buf, 0, sz);
64 kprintf_put(int level, const char* buf, size_t sz)
66 __put_console(kprec_put(&kprecs, level, buf, sz));
70 kprintf_ml(const char* component, int level, const char* fmt, va_list args)
75 buf = flipbuf_top(&fmtbuf);
76 ksnprintf(buf, MAX_BUFSZ_HLF, "%s: %s\n", component, fmt);
78 sz = ksnprintfv(flipbuf_flip(&fmtbuf), buf, MAX_BUFSZ_HLF, args);
80 kprintf_put(level, flipbuf_top(&fmtbuf), sz);
84 kprintf_m(const char* component, const char* fmt, va_list args)
87 fmt = shift_level(fmt, &level);
89 kprintf_ml(component, level, fmt, args);
93 kprintf_v(const char* component, const char* fmt, ...)
97 kprintf_m(component, fmt, args);
102 __twimap_kprintf_read(struct twimap* map)
104 struct kp_records* __kprecs = twimap_data(map, struct kp_records*);
107 XXX we can foreach all records in a single twimap read call,
108 as records is monotonic increasing by design.
110 struct kp_entry *pos, *n;
111 llist_for_each(pos, n, __kprecs->kp_ent_wp, ents)
113 time_t s = pos->time / 1000;
114 time_t ms = pos->time % 1000;
115 twimap_printf(map, "[%05d.%03d] %s", s, ms, pos->content);
120 kprintf_mapping_init()
122 twimap_entry_simple(NULL, "kmsg", &kprecs, __twimap_kprintf_read);
124 EXPORT_TWIFS_PLUGIN(kprintf, kprintf_mapping_init);
128 kprintf_dump_logs() {
129 if (unlikely(!sysconsole)) {
133 struct kp_entry *pos, *n;
134 llist_for_each(pos, n, kprecs.kp_ent_wp, ents)
140 __DEFINE_LXSYSCALL3(void, syslog, int, level,
141 const char*, buf, unsigned int, size)
143 kprintf_put(level, buf, size);