1

I wrote a linux module to creat a proc file and write and read the data from it. But I am unable to remove the module, its showing an error unable to remove saying "device or resource busy. here is my code.

#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/fs.h> /*this is the file structure, file open read close */
#include<linux/cdev.h> /* this is for character device, makes cdev avilable*/
#include<linux/semaphore.h> /* this is for the semaphore*/
#include<linux/uaccess.h> /*this is for copy_user vice vers*/
#include<linux/proc_fs.h>

#define MAX_LEN 1024
int read_info(char *page, char **start, off_t off,  int count, int *eof, void *data);
int write_info(struct file *filp, const char __user *buffer, unsigned long length, void *data);

static struct proc_dir_entry *proc_entry;
static char *info;
static int write_index;
static int read_index;

int write_info(struct file *filp, const char __user *buffer, unsigned long length, void *data) {
    int capacity = (MAX_LEN - write_index) +1;
    if(length > capacity) {
        printk(KERN_INFO "NO sapce to write into peoc file \n");
        return -1;
    }
    if(copy_from_user(&info[write_index], buffer, length)) 
        return -2;
    write_index += length;
    printk(KERN_INFO " megharaj proc writing succesful, %d write \n", length);
    return length;
}

int read_info(char *page, char **start, off_t off, int count, int *eof, void *data) {
    int len;
    len = sprintf(page, "%s\n", &info[read_index]);
    read_index += len;
    printk(KERN_INFO " megharaj proc reading succesful, %d read \n", len);
    return len;
}


int init_module(void) 
{
    int ret = 0;
    info = (char *)vmalloc(MAX_LEN);
    memset(info, 0 , MAX_LEN);
/*truct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
                                         struct proc_dir_entry *parent);*/
    proc_entry = create_proc_entry("megharaj_proc", 0666, NULL);
    if(proc_entry == NULL) {
        ret = -1;
        vfree(info);
        printk(KERN_INFO " megharaj proc not created \n");
    }
    else {
        write_index = 0;
        read_index = 0;
        proc_entry->read_proc = read_info;
        proc_entry->write_proc = write_info;
        printk(KERN_INFO " megharaj proc created \n");
    }
    return ret;
}

void clean_module(void) 
{
    vfree(info);
    remove_proc_entry("megharaj_proc", NULL);

}

also attaching the makefile,

obj-m   := proc.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD       := $(shell pwd)

all:
    $(MAKE) -C $(KERNELDIR) M=$(PWD)

clean:
    rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

echo and cat on proc file are working. Once work is done i am not able to remove the module by using sudo rmmod proc

output from lsmod shows

proc                   12518  0 [permanent]

Now another question, what is this permanent ? Is this the problem. ?

Megharaj
  • 1,589
  • 2
  • 20
  • 32
  • possible duplicate of [Why is this kernel module marked at permanent on 2.6.39](http://stackoverflow.com/questions/7482469/why-is-this-kernel-module-marked-at-permanent-on-2-6-39) – gby Sep 15 '13 at 10:45
  • @gby No its not a possible duplicate. I am not able to remove my proc module(main question). Because my other modules are working fine. I am doing some mistake in the module dont know what, trying to figure out. – Megharaj Sep 15 '13 at 11:00
  • you are right. it does not seems to be the same issue. My bad. – gby Sep 15 '13 at 12:40
  • shouldn't you close the open files before exiting? – Dru Sep 17 '13 at 03:31
  • @dru no. Should remove proc entry. – Megharaj Sep 17 '13 at 17:41

1 Answers1

4

Either name the module cleanup function cleanup_module (and not clean_module) or specifically declare it as a cleanup function (much better) like so:

module_init(init_module);
module_exit(clean_module);
gby
  • 14,900
  • 40
  • 57
  • I just cant imaging I made such a silly error. Sorry. Need to be more patient while writing codes. – Megharaj Sep 15 '13 at 14:16
  • I think since there was no exit, that made the module permanent. But one thing I dont understand is that why it called init module function. This gave rise to big question. – Megharaj Sep 15 '13 at 14:17
  • 2
    @Megharaj: IIRC, the module loader looks for a function named `init_module` in the kernel module. `module_init(func)` creates an alias with name `init_module` for `func` among other things. In your case, the loader probably found your function which happened to have the appropriate name and called it. – Eugene Sep 16 '13 at 14:47