MOD_{INC, DEC}_USE_COUNT

ええと、簡単なキャラクタデバイスをつくるを教材に色々試してるんですが、ここに記述されているソレが無い。どうも obsolete らしい。
どんなキーワードで探したのかも忘れたのですが、以下の文書に hit

file_operations 構造体の owner という属性がカギらしい。当たり前ですが 2.4 系よりは面倒見るのが楽 (自分で INC だの DEC だのせんで良い) らしい。確認してみるか。

かくにん君

ええと昨晩作ったナニは file_operations 構造体の実体 (fifo_fops) が以下の定義

struct file_operations fifo_fops = {
        .owner = NULL,
        .read = NULL,
        .write = NULL,
        .ioctl = NULL,
        .open = yamanetoshi_open,
        .release = yamanetoshi_release,
};

owner 属性に THIS_MODULE というマクロを代入しとけば良いらしい。あとは

  • 試験なプログラムで open したまま無限ループ
  • rmmod してみる

これで rmmod できなんだら OK という事ッスか。実装して試験したナニが以下

# mknod /dev/fifo100130 c 130 100
# ls /dev/fifo100130
/dev/fifo100130
# insmod yamanetoshi.ko
# rmmod yamanetoshi
ERROR: Module yamanetoshi is in use
# 

ちなみに insmod した後に裏で無限ループなソレを起動しております。
以下にソースを。

Makefile

obj-m   := yamanetoshi.o

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

default:
#       $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
        $(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
        @rm -rf *~ *.o *.ko Module.symvers *.mod.c

yamanetoshi.c

fifo_fops の owner 属性に THIS_MODULE を代入したのみ

#include <linux/module.h>   // required by all modules
#include <linux/kernel.h>   // required by printk()
#include <linux/init.h>
#include <linux/fs.h>

MODULE_LICENSE("GPL");

#define DRIVERNAME "yamanetoshi"
int fifo_major = 130;

static int yamanetoshi_open(struct inode *inode, struct file *file)
{
	printk("yamanetoshi_open\n");
	printk(" file->f_version     : %lu\n", file->f_version);
	printk(" MINOR(inode->i_rdev): %d\n", MINOR(inode->i_rdev));
	return 0;
}

static int yamanetoshi_release(struct inode *inode, struct file *file)
{
	printk("yamanetoshi_close\n");
	printk(" file->f_version     : %lu\n", file->f_version);
	return 0;
}

struct file_operations fifo_fops = {
	.owner = THIS_MODULE,
	.read = NULL,
	.write = NULL,
	.ioctl = NULL,
	.open = yamanetoshi_open,
	.release = yamanetoshi_release,
};

// Start/Init function
static int yamanetoshi_init(void) {
	int ret;

	printk("initialize the fifo device\n");
	ret = register_chrdev(fifo_major, DRIVERNAME, &fifo_fops);

	if(ret < 0)
		return ret;

	if(fifo_major == 0)
		fifo_major = ret;

    return 0;
}

// End/Cleanup function
static void yamanetoshi_exit(void) {
	printk("cleanup the fifo device\n");
	unregister_chrdev(fifo_major, DRIVERNAME);
}

module_init(yamanetoshi_init);
module_exit(yamanetoshi_exit);

test_yamanetoshi.c

無限ループ中に rmmod させるためのナニ

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	FILE *fptr = NULL;
	if(NULL == (fptr = fopen("/dev/fifo100130", "r"))) {
		fprintf(stderr, "open error /dev/fifo100130");
		exit(1);
	}

	while(1);

	fclose(fptr);
	fptr = NULL;

	return 0;
}