Skip to content

Instantly share code, notes, and snippets.

@perillo
Last active August 29, 2015 14:11
Show Gist options
  • Save perillo/3c2a0c8e2f596dff3a3f to your computer and use it in GitHub Desktop.
Save perillo/3c2a0c8e2f596dff3a3f to your computer and use it in GitHub Desktop.
/*
* Create an input/output character device that will put in an
* uninterruptible sleep state the user process that opens it.
*
* Copyright 2014 Manlio Perillo. All rights reserved.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/fs.h>
#include <linux/delay.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Manlio Perillo");
MODULE_DESCRIPTION("A character device for uninterruptible sleep");
#define DEVICE_NAME "chardev"
#define DEVICE_FILE_NAME "unkill"
#define MAJOR_NUM 1975
// Default timeout in milliseconds.
// Can be overridden during build or installation.
#ifndef TIMEOUT
#define TIMEOUT 60 * 1000
#endif
static int timeout = TIMEOUT;
/*
* Make timeout parameter visible in
* /sys/module/unkill/parameters/timeout
*/
module_param(timeout, int, 0444);
MODULE_PARM_DESC(timeout, "Timeout in milliseconds");
static int device_open(struct inode *inode, struct file *file)
{
printk(KERN_INFO "unkill: device_open will sleep for %d ms\n", timeout);
/*
* Equivalent to:
* set_current_state(TASK_UNINTERRUPTIBLE);
* schedule_timeout();
*/
msleep(timeout);
return -EBUSY;
}
struct file_operations Fops = {
.open = device_open,
};
int init_module()
{
int ret_val;
ret_val = register_chrdev(MAJOR_NUM, DEVICE_NAME, &Fops);
if (ret_val < 0) {
printk(KERN_ALERT "register_chrdev() failed: %d\n", ret_val);
return ret_val;
}
// Note that the device name is not important
printk(KERN_INFO "unkill: mknod %s c %d 0\n", DEVICE_FILE_NAME, MAJOR_NUM);
return 0;
}
void cleanup_module()
{
(void) unregister_chrdev(MAJOR_NUM, DEVICE_NAME);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment