কীভাবে বার্তা যুক্ত করবেন যা ডেমেসগের সাথে পঠিত হবে?


44

আমি আমার ডেমেজ আউটপুটে কিছু কাস্টম বার্তা লেখার চেষ্টা করছি। আমি চেষ্টা করেছিলাম:

logger "Hello"

কিন্তু এই কাজ করে না. এটি ত্রুটি ছাড়াই প্রস্থান করে তবে এর কোনও আউটপুট "হ্যালো" উপস্থিত হয় না:

dmesg

আমি ফেডোরা 9 ব্যবহার করছি এবং মনে হচ্ছে কোনও সিসলগড / ক্লগড ডিমন চলছে না। তবে, আমার সমস্ত কর্নেল বার্তা সফলভাবে dmesg বাফারে লেখা আছে are

কোন ধারণা?

উত্তর:


37

dmesgকার্নেল বাফারে যা রয়েছে তা প্রদর্শন করে, যেখানে loggerরয়েছে syslogd। আমি মনে করি আপনি কার্নেল বাফারে জিনিসগুলি মুদ্রণ করতে চাইলে আপনার একটি ড্রাইভার তৈরি করতে হবে যা printk()কার্নেল ফাংশন ব্যবহার করবে । যদি আপনি এটি কেবল চান /var/log/messages, তবে একটি "সাধারণ" সেটআপ দিয়ে আমি মনে করি আপনি যা করেছেন loggerতা ইতিমধ্যে ঠিক আছে।

ড্রাইভার সহ সবচেয়ে মৌলিক উদাহরণটি হ'ল printk():

, 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

তারপর:

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

http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN121 আরও জন্য ...


আমি একটি ত্রুটি পেয়েছি, যেহেতু আপনি make -C ...কোনও ট্যাবের পরিবর্তে মেকফিলের আগে ফাঁকা স্থান রেখেছেন , তাই মেকফিলের উপরের বিষয়গুলি অনুলিপি করা কার্যকর হয় না - আরও এখানে । আমি কোনও সম্পাদনায় এটি যুক্ত করতে অক্ষম বলে মনে করি ... ধন্যবাদ, দুর্দান্ত উত্তর answer
উইলফ

107

আপনি, মূল হিসাবে, /dev/kmsgকার্নেল বার্তা বাফার প্রিন্ট করতে লিখতে পারেন :

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

আমি এটি আমার সার্ভারে এবং এমবেডেড লিনাক্স ডিভাইসে পরীক্ষা করেছি এবং এটি উভয় ক্ষেত্রেই কাজ করে, তাই আমি কেবল ধরে নিচ্ছি যে এটি সর্বত্র বেশ কার্যকরভাবে কাজ করে।


1
আকর্ষণীয় যে উবুন্টুতে, এটি মূল হিসাবে কাজ করে তবে সুডোর সাথে নয়। একটি আসলে মূল হতে হবে।
dotancohen

15
প্রকৃতপক্ষে, কারণ ইনপুট পুনঃনির্দেশটি আপনার শেল দ্বারা পরিচালিত হয়, যা উন্নত অধিকারের সাথে চলছে না। রুটহীন echo Some message | sudo tee /dev/kmesgহিসাবে চালানোর চেষ্টা করুন ।
wvdschel

3
ওই কাজগুলো. ধন্যবাদ, আকর্ষণীয়। যাইহোক, এটি kmsgনয় kmesgতবে আমিও বিভ্রান্ত করছি যার সাথে dmesgই আছে!
dotancohen

4
কার্নেল মডিউল সংকলনের চেয়ে অনেক বেশি সহজ
e271p314

13

উপরে কাইলের মডিউলটির ভিত্তিতে:


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

ব্যবহারকারীর স্থান থেকে একটি মুদ্রণ করতে:

echo "Hello" > /proc/printk

1
এটি কেবল লিনাক্স কার্নেলের জন্য <3.10 ব্যবহার করে। আরও নতুন বিকল্পের জন্য আমার উত্তর দেখুন।
কেভিনফ

5

@ ক্যালান্ডোয়া উত্তর আর কার্নেল +3.10 এর জন্য কাজ করে না। তার কোড মিলিত এবং উদাহরণের কোড আমি দেখেছি এখানে । তারপরে কোডের মান উন্নত ...

কোডটি 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);

এই মেকফিলটি ব্যবহার করুন

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


2

অনুভূত যে আমি এগিয়ে যাব এবং এমন কিছুর একটি পূর্ণ প্রস্ফুটিত উদাহরণ অন্তর্ভুক্ত করব যা লোকেদের কেবল সংকলন করতে পারে এবং তাদের জন্য দৌড়াতে পারে যা @ বুভিনজে'র উত্তরের ভিত্তিতে সি এর সাথে দক্ষ নয়

#include <stdio.h>
#include <string.h>
#include <fcntl.h> // open function
#include <unistd.h> // close function
#include "sys/syscall.h"


int main(); // Let's not worry about this for now

void dmesg( const char *tag, const char *msg, const int len )
{
    const int TAG_LEN=3;
    char buffer[128]={0};
    memcpy( &buffer[0], tag, TAG_LEN );
    memcpy( &buffer[TAG_LEN], msg, len );
    int fd_kmsg = open( "/dev/kmsg", O_WRONLY );
    write( fd_kmsg, &buffer, TAG_LEN+len );
    close( fd_kmsg );
}
void dmesgWarn(  const char *msg, const int len ){ dmesg( "<4>", msg, len ); }
void dmesgInfo(  const char *msg, const int len ){ dmesg( "<6>", msg, len ); }
void dmesgDebug( const char *msg, const int len ){ dmesg( "<7>", msg, len ); }


int main(int argc, char **argv)
{
    int getmysize = strlen(argv[1]);
    printf("%d\n", getmysize);

    printf("To be written: %s\nSize of argument: %d\n", argv[1], getmysize);
    // dmesgWarn dmesgInfo or dmesgDebug
    dmesgDebug(argv[1], getmysize);
};

উপরের অংশগুলি কে.এম.এস.সি. ও জিসিসি কেএমএস.সি.-কে কেএমএসজি হিসাবে সংরক্ষণ করুন; sudo ./kmsg "স্ট্রিং আপনি / dev / kmsg" এ যুক্ত করতে চান


0

আমি ক্রস কমপ্লাইড কার্নেলের মধ্যে অন্য কারও দ্বারা লিখিত ডিমনটিতে কিছু দ্রুত ডিবাগিং বার্তা চেয়েছিলাম। আমি ব্যবহার করার চেষ্টা করার সময় একটি সংকলন ত্রুটির মধ্যে দৌড়েছি printk, যেমন <linux/module.h>অন্তর্ভুক্ত করা যায়নি। তারপরে অতিরিক্ত মাত্রায় লড়াই করুন (এটি সঠিক উপায়ে করতে) আমি প্রতারণা করেছি এবং নীচের অলস ব্যবহার করেছি, তবে কার্যকর 5 মিনিটের মতো কাজ:

void dmesg( const char *tag, const char *msg, const int len )
{
    const int TAG_LEN=3;
    char buffer[128]={0};
    memcpy( &buffer[0], tag, TAG_LEN );
    memcpy( &buffer[TAG_LEN], msg, len );
    int fd_kmsg = open( "/dev/kmsg", O_WRONLY );
    write( fd_kmsg, &buffer, TAG_LEN+len );
    close( fd_kmsg );
}
void dmesgWarn(  const char *msg, const int len ){ dmesg( "<4>", msg, len ); }
void dmesgInfo(  const char *msg, const int len ){ dmesg( "<6>", msg, len ); }
void dmesgDebug( const char *msg, const int len ){ dmesg( "<7>", msg, len ); }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.