试图在Linux上密切关注

R..*_*R.. 10 c linux unit-testing signals

我需要在close可能被信号处理程序(有或没有SA_RESTART)中断的情况下调查/测试Linux上某些代码的行为.什么是最方便的设置,使close系统调用睡眠在一个可测量的时间窗口,在此期间,我可以尝试用信号命中过程?一些想法:

  • 故意缓慢/无响应的NFS安装
  • 自定义FUSE驱动程序

但是,由于这些设置有点痛苦,我想知道是否有更多现成的我可以使用它可以提供所需的行为.

Nem*_*emo 8

如果没有其他人有更好的主意......

您可以实现自己的角色设备驱动程序.从Linux设备驱动程序(第3版)中的第3章中的模板开始,并将其调整为除了在close()上暂停一段时间之外什么都不做.(您可以使用msleepmsleep_interruptible来自第7章进行阻止.)

实际上,如果没有其他人建议其他东西,我可以通过调整我现有的一些代码来快速推动这一点.你多久需要它?

[编辑]

好的,试试这个......

Makefile文件:

ifneq ($(KERNELRELEASE),)
        obj-m := closer.o

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

default: modules

%:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) "$@"

.PHONY: default
endif
Run Code Online (Sandbox Code Playgroud)

closer.c:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/fs.h>

MODULE_DESCRIPTION("Block-on-close driver");
MODULE_AUTHOR("Nemo <nemo@self-evident.org>");
MODULE_LICENSE("GPL");
#define VERSION "20110705"
MODULE_VERSION(VERSION);

#define MY_NAME "closer"

int my_open(struct inode *, struct file *);
int my_release(struct inode *, struct file *);
ssize_t my_read(struct file *, char __user *, size_t, loff_t *);
ssize_t my_write(struct file *, const char __user *, size_t, loff_t *);

static struct file_operations my_fops = {
    .owner = THIS_MODULE,
    .open = my_open,
    .read = my_read,
    .write = my_write,
    .release = my_release,
};

static struct miscdevice my_dev;

int __init
my_init(void)
{
    int err = 0;

    printk(KERN_INFO "%s: loading version %s\n", MY_NAME, VERSION);

    my_dev.minor = MISC_DYNAMIC_MINOR;
    my_dev.name = MY_NAME;
    my_dev.fops = &my_fops;
    err = misc_register(&my_dev);

    if (err)
        printk(KERN_ERR "%s: misc_register failed, error %d\n", MY_NAME, err);

    return err;
}

int
my_open(struct inode *inode, struct file *filp)
{
    return 0;
}

ssize_t
my_read(struct file *file, char __user *p, size_t n, loff_t *off) {
    return 0;
}

ssize_t
my_write(struct file *file, const char __user *p, size_t n, loff_t *off) {
    return n;
}

int
my_release(struct inode *inode, struct file *filp)
{
    int err = 0;
    /* 10 second sleep, interruptible. */
    if (msleep_interruptible(10 * 1000) > 0)
        err = -EINTR;

    return err;
}

void __exit
my_exit(void)
{
    misc_deregister(&my_dev);
    printk(KERN_INFO "%s: unloaded\n", MY_NAME);
}

module_init(my_init);
module_exit(my_exit);
Run Code Online (Sandbox Code Playgroud)

使用"insmod closer.o"加载模块.如果您有一个相当现代/完整的Linux环境,udev将自动唤醒并生成/ dev/close.如果没有,您可以自己创建设备节点:

mknod /dev/closer c `tr : ' ' </sys/class/misc/closer/dev`
Run Code Online (Sandbox Code Playgroud)

(即/ sys/class/misc/closer/dev表示要使用的major:minor.)

读写工作类似/ dev/null; 即任何读取的EOF,任何写入的成功.

我已经确认"cat </ dev/closer"会阻塞close()10秒钟.我还没有创建一个测试来捕获SIGINT(或者其他)并验证它实际上是否会产生EINTR.

针对2.6.32内核构建.让我知道它对你有用.