错误:";“设备或资源忙”;在删除proc模块时出错

错误:";“设备或资源忙”;在删除proc模块时出错,c,linux,linux-kernel,linux-device-driver,C,Linux,Linux Kernel,Linux Device Driver,我编写了一个linux模块来创建一个proc文件,并从中写入和读取数据。但是我无法删除该模块,它显示了一个无法删除的错误,上面写着“设备或资源正忙。这是我的代码。” #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

我编写了一个linux模块来创建一个proc文件,并从中写入和读取数据。但是我无法删除该模块,它显示了一个无法删除的错误,上面写着“设备或资源正忙。这是我的代码。”

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

}
echo和cat on proc文件正在工作。工作完成后,我无法使用sudo rmmod proc删除模块

lsmod的输出显示

proc                   12518  0 [permanent]

现在还有一个问题,这是永久性的吗?这就是问题所在。

将模块清理函数命名为cleanup\u module(而不是clean\u module),或者专门将其声明为清理函数(更好),如下所示:


将模块清理函数命名为cleanup_module(而不是clean_module),或者将其明确声明为清理函数(更好),如下所示:


@gby可能重复不可能重复。我无法删除我的程序模块(主要问题)。因为我的其他模块工作正常。我在模块中犯了一些错误,不知道是什么,试图找出原因。你是对的。这似乎不是同一个问题。我的问题。你不应该在退出之前关闭打开的文件吗?@dru no。应该删除进程条目。@gby no的可能重复不可能重复。我无法删除我的程序模块(主要问题)。因为我的其他模块工作正常。我在模块中犯了一些错误,不知道是什么,试图找出原因。你是对的。这似乎不是同一个问题。我的问题。你不应该在退出之前关闭打开的文件吗?@dru否。应该删除进程条目。我只是无法想象我犯了这样一个愚蠢的错误。抱歉。在退出之前需要更多耐心编写代码。我认为因为没有出口,所以模块是永久的。但有一件事我不明白,为什么它调用init module函数。这引起了一个大问题。@Megharaj:IIRC,模块加载器在内核模块中查找名为
init_module
的函数。
module_init(func)
func
等创建了一个名为
init_module
的别名。在你的情况下,加载程序可能找到了你的函数,该函数恰巧有合适的名称并调用了它。我只是无法想象我犯了这样一个愚蠢的错误。对不起,在编写代码时需要更加耐心。我想,既然没有出口,那么使模块永久化。但有一件事我不明白,为什么它调用init module函数。这引起了一个大问题。@Megharaj:IIRC,模块加载器在内核模块中查找名为
init\u module
的函数。
module\u init(func)
func
等创建名为
init_module
的别名。在您的情况下,加载程序可能找到了您的函数,该函数恰好具有适当的名称并调用了它。
proc                   12518  0 [permanent]
module_init(init_module);
module_exit(clean_module);