Vraag Hoe voeg ik een bericht toe dat wordt gelezen met dmesg?


Ik probeer enkele aangepaste berichten te schrijven in mijn dmesg-uitvoer. Ik probeerde:

logger "Hello"

maar dit werkt niet. Het wordt zonder fouten afgesloten, maar er verschijnt geen "Hallo" in de uitvoer van:

dmesg

Ik gebruik een Fedora 9, en het lijkt erop dat er geen syslogd / klogd-daemon draait. Alle kernelberichten worden echter met succes in de dmesg-buffer geschreven.

Enig idee?


41
2018-05-10 18:24


oorsprong




antwoorden:


dmesg geeft weer wat zich in de kernelbuffer bevindt, terwijl logger is voor syslogd. Ik denk dat als je dingen in de kernelbuffer wilt afdrukken, je een stuurprogramma moet maken dat de printk() kernelfunctie. Als je het gewoon wilt hebben /var/log/messages, dan met een "normale" opstelling denk ik aan wat je hebt gedaan logger is al goed.

Het meest eenvoudige voorbeeld van een bestuurder met printk() zou zijn:

hello.c:

#include <linux/module.h>
#include <linux/kernel.h>

int init_module(void)
{
    printk(KERN_INFO "Hello world\n");
    return 0;
}

void cleanup_module(void)
{
    printk(KERN_INFO "Goodbye world\n");

}

Makefile:

obj-m += hello.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

Dan:

$ make
$ sudo insmod hello.ko
$ dmesg | tail -n1
 [7089996.746366] Hello world

http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN121 voor meer...


34
2018-05-10 18:30



Ik heb een fout gemaakt, omdat je spaties hebt geplaatst vóór de make -C ... in de Makefile in plaats van een Tab, dus het kopiëren van de bovenstaande inhoud van de Makefile werkt niet - meer hier. Ik kan dit in een bewerking niet toevoegen ... Bedankt trouwens, geweldig antwoord. - Wilf


Je kunt als root naar schrijven /dev/kmsg om naar de berichtenbuffer van de kernel af te drukken:

 fixnum:~# echo Some message > /dev/kmsg
 fixnum:~# dmesg | tail -n1
 [28078118.692242] Some message

Ik heb dit op mijn server en een ingebouwd Linux-apparaat getest en het werkt op beide, dus ik ga er gewoon van uit dat het vrijwel overal werkt.


101
2018-02-23 14:47



Interessant dat dit in Ubuntu werkt als root maar niet met sudo. Je moet eigenlijk root worden. - dotancohen
Eigenlijk is dat omdat de invoeromleiding wordt afgehandeld door je shell, die niet wordt uitgevoerd met verhoogde rechten. Probeer te rennen echo Some message | sudo tee /dev/kmesg als niet-root. - wvdschel
Dat werkt. Bedankt, interessant. Trouwens, het is kmsg niet kmesg maar ik verwar ook met dmesg welke heeft de e! - dotancohen
Veel eenvoudiger dan het compileren van kernelmodule - e271p314


Gebaseerd op Kyle's module hierboven:


#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>

static int pk_write(struct file *file, const char *buffer, unsigned long count, void *data)
{
        char string[256];
        count = count < 255 ? count : 255;

        if(copy_from_user(string, buffer, count))
                return -EFAULT;

        string[count] = '\0';        
        printk(string);
        return count;
}


static int __init printk_init(void)
{
        struct proc_dir_entry *pk_file;

        pk_file = create_proc_entry("printk", 0222, NULL);
        if(pk_file == NULL)
                return -ENOMEM;

        pk_file->write_proc = pk_write;
        pk_file->owner = THIS_MODULE;

        return 0;
}

static void __exit printk_cleanup(void)
{
        remove_proc_entry("printk", NULL);
}

module_init(printk_init);
module_exit(printk_cleanup);
MODULE_LICENSE("GPL");

Om een ​​printk vanuit gebruikersruimte te doen:

echo "Hello" > /proc/printk

13
2018-05-11 09:34



Dit werkt alleen voor Linux-kernel <3,10. Zie mijn antwoord voor een nieuwer alternatief. - kevinf


@ Calandoa's antwoord werkt niet langer voor Kernel +3.10. Gecombineerd zijn code en de voorbeeldcode die ik vond hier. Toen verbeterde de code kwaliteit ...

Code opgeslagen in printk_user.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>

static ssize_t write_proc(struct file *filep, const char *buffer, size_t count, loff_t *offsetp)
{
    char string[256];
    count = count < 255 ? count : 255;

    if(copy_from_user(string, buffer, count) != 0) {
        return -EFAULT;
    }

    string[count] = '\0';
    printk(string);
    return count;
}

static const struct file_operations proc_fops = {
    .owner = THIS_MODULE,
    .write = write_proc,
};

static int proc_init(void) {
    struct proc_dir_entry *proc_file;
    proc_file = proc_create("printk_user", 0, NULL, &proc_fops);

    if(proc_file == NULL) {
        return -ENOMEM;
    }

    return 0;
}

static void proc_cleanup(void) {
    remove_proc_entry("printk_user", NULL);
}

MODULE_LICENSE("GPL"); 
module_init(proc_init);
module_exit(proc_cleanup);

Maak gebruik van deze Makefile

TARGET = printk_user
obj-m := $(TARGET).o

KERNEL_VERSION=$(shell uname -r)
KDIR = /lib/modules/$(KERNEL_VERSION)/build
PWD = $(shell pwd)

printk:
    $(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
    $(MAKE) -C $(KDIR) M=$(PWD) clean

5
2017-11-25 20:59





Gebaseerd op het antwoord van Kyle, hier is een korte handleiding die laat zien hoe je dat precies doet.


3
2018-05-10 18:35