54 votes

Comment ajouter un message qui sera lu par dmesg ?

J'essaie d'écrire des messages personnalisés dans ma sortie dmesg. J'ai essayé :

logger "Hello"

mais cela ne fonctionne pas. Il sort sans erreur, mais aucun "Hello" n'apparaît dans la sortie de :

dmesg

J'utilise une Fedora 9, et il semble qu'il n'y ait pas de démon syslogd/klogd en cours d'exécution. Cependant, tous les messages du noyau sont écrits avec succès dans le tampon dmesg.

Une idée ?

138voto

Raghu Points 1

Vous pouvez, en tant que root, écrire à /dev/kmsg pour l'imprimer dans le tampon de messages du noyau :

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

J'ai testé cela sur mon serveur et sur un appareil Linux embarqué, et cela fonctionne sur les deux, je vais donc supposer que cela fonctionne à peu près partout.

46voto

Kyle Brandt Points 81077

dmesg affiche ce qui se trouve dans la mémoire tampon du noyau, tandis que logger est pour syslogd . Je pense que si vous voulez imprimer des choses dans le tampon du noyau, vous devrez créer un pilote qui utilise la fonction printk() fonction du noyau. Si vous voulez seulement l'avoir en /var/log/messages Dans le cas d'une configuration "normale", je pense que ce que vous avez fait avec logger est déjà très bien.

L'exemple le plus simple d'un conducteur avec printk() serait :

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

Ensuite :

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

http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN121 pour plus...

14voto

calandoa Points 1205

Basé sur le module de Kyle ci-dessus :

#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");

Pour effectuer un printk à partir de l'espace utilisateur :

echo "Hello" > /proc/printk

6voto

Kevin Points 193

La réponse de @Calandoa ne fonctionne plus pour le noyau +3.10. En combinant son code, et le code d'exemple que j'ai trouvé aquí . Puis amélioration de la qualité du code...

Code sauvegardé dans 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);

Make en utilisant ce 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

3voto

TCampbell Points 2004

Basé sur la réponse de Kyle, aquí est un tutoriel rapide qui montre comment procéder.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X