clinuxkernel-moduleprintkdmesg

Linux Kernel module: printk message not where I expect to be in the buffer log


This question relates to a lab/homework assignment. We are asked to learn how to load and remove a kernel module, and then modify the C code in a kernel module that has been provided. We must define a struct that contains some elements to be inserted into a linked list. Then we must print some messages, using data from the linked list, via printk().

Here is my code:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/types.h>


/*Defines a struct containing the elements that are to be
inserted in the linked list*/
struct birthday{
    int day;
    int month;
    int year;
    struct list_head list;
};

/*Declares a list_head object */
static LIST_HEAD(birthday_list);

/* This function is called when the module is loaded. */
int simple_init(void) { 
    /* Create and initialize instances of struct birthday*/
    struct birthday *person, *ptr;
    int count;

    printk(KERN_INFO "Loading Module\n");

    /* This loop populates the linked list with 5 nodes,
     * each with different birthday data*/
    for (count = 0; count < 5  ; count++){
        person = kmalloc(sizeof(*person), GFP_KERNEL);
        person -> day = count + 2;
        person -> month = 11 - (count + 2);
        person -> year = 1985 + ((count + 1) * 3);
        INIT_LIST_HEAD(&person -> list);
        list_add_tail(&person -> list, &birthday_list);
    }

    /*Traverse the list*/
    list_for_each_entry(ptr, &birthday_list, list) {
        printk(KERN_INFO "Birthday: Month %d Day %d Year %d\n", ptr -> month, ptr -> day, ptr -> year);
    }
    return 0;
}

/* This function is called when the module is removed. */
void simple_exit(void) {
    struct birthday *ptr, *next;

    printk(KERN_INFO "Removing Module\n");  

    list_for_each_entry_safe(ptr, next, &birthday_list, list){
        printk(KERN_INFO "Removing %d %d %d", ptr->month,     ptr->day, ptr->year);
        list_del(&ptr -> list);
        kfree(ptr);
    }
}

/* Macros for registering module entry and exit points. */
module_init( simple_init );
module_exit( simple_exit );


MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple Module");
MODULE_AUTHOR("SGG");

I can compile the code without errors, and it seems to load and remove just fine. My problem, is with the printed statements. When I load the module, and check the log buffer with dmesg I can see all 5 messages (one for each node in the linked list). When I remove the module and check the log buffer I only see 4 messages. The messsage associated with the 5th node in the linked list does not print at this time. If I then load the module again, and then check the log buffer, the very first message is the one that should have been in the log when I removed the module.

I have only had this problem when I have 5 nodes. If I change my loop to create 10 nodes, all messages printed as I expected. The same is true with 6 nodes or 4 nodes. But every time I create 5 nodes I come up against this problem.

Here is my output: Screenshot of my output from command line

All of the editing and operations for this assignment have been done within Oracle VM VirtualBox, running in Windows 10. The Linux kernel and the kernel module that I am modifying are provided as part of the course materials and textbook.

Any help is greatly appreciated!


Solution

  • This is because you missed '\n' at end of your printk.