0

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!

Patch85
  • 3
  • 2
  • Welcome to SO - your post is fine, could you please add your console output as a code snippet instead of a screenshot? Otherwise, search engines won't be able to crawl it. – Michael Lihs Oct 07 '18 at 17:39

1 Answers1

2

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

  • Thank you, that did the trick. I am still unclear as to why it only happened when I had 5 nodes, when it worked fine when I used 4, 6, and 10. Is it at all related to having an odd number of nodes in my linked list? Or an odd number of statements? – Patch85 Oct 07 '18 at 20:21
  • This is not anyhow related to numbers. Kernel log is line-oriented. There is rather complex logic to separate messages coming from different contexts and avoid mixing characters from different messages together. When you don't "close" your message with newline character, that logic may work not how you expect. – Nikita Yushchenko Oct 07 '18 at 20:40