今天做的一个测试,当做笔记记录一下。
测试环境:
我在/home目录下面建立一个proc文件夹,然后把proc文件系统挂载到上面,结果如下:
然后执行sleep 200 < ./proc,模拟./proc被使用情况。
以下是测试模块的代码和注释:
#include <linux/gfp.h>
#include <linux/syscalls.h>
#include <linux/rcupdate.h>
#include <linux/sched.h>
#include <linux/signal.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Linmiaohe");
MODULE_DESCRIPTION("try to umount ./proc while it is in use");
typedef typeof(sys_umount) *my_sys_umount;
//static char *mnt = "./proc";
//module_param(mnt,charp,0);
static int sys_umount_open(struct inode *inode, struct file *file)
{
return 0;
}
/*测试例子通过传递需要卸载的目录来执行卸载操作*/
static ssize_t sys_umount_write(struct file *file,const char __user *out,size_t size,loff_t *off)
{
int ret = 0;
my_sys_umount um;
struct task_struct *p;
rcu_read_lock();
/*遍历运行队列链表*/
for_each_process(p) {
/*查找名字为sleep的进程,这里的sleep进程是拿来测试用的,为的是使目录处于使用状态*/
if(strcmp(p->comm,"sleep") == 0)
force_sig(SIGKILL,p);
/*找到则发送信号杀死该进程*/
}
rcu_read_unlock();
/*0xc0222f60是sys_umount在符号表中的位置,具体可以参考上一篇文章*/
um = (my_sys_umount)0xc0222f60;
/*卸载文件系统*/
ret = um((char *)out,0);
/*打印返回值ret*/
printk(KERN_INFO "************************ret = %d,um = %p,out = %p************************\n",ret,um,out);
return size;
}
static struct file_operations sys_umount_fops = {
.owner = THIS_MODULE,
.open = sys_umount_open,
.read = NULL,
.write = sys_umount_write,
.llseek = NULL
};
static struct miscdevice reverse_misc_device = {
.minor = MISC_DYNAMIC_MINOR,
.name = "umount",/*会产生/dev/umount*/
.fops = &sys_umount_fops,
};
static int __init sys_umount_init(void)
{
misc_register(&reverse_misc_device);
printk(KERN_INFO "*********************sys_umount_init***********************\n");
return 0;
}
static void __exit sys_umount_exit(void)
{
misc_deregister(&reverse_misc_device);
printk(KERN_INFO "*********************sys_umount_exit***********************\n");
}
module_init(sys_umount_init);
module_exit(sys_umount_exit);
用来测试的用户程序为(往/dev/umount中写入需要卸载的文件系统目录即可):
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#define DEVICE "/dev/umount"
int main(int argc,char **argv)
{
int fd = 0;
if(argv[1] == NULL){
printf("Usage:./umount_test string. \n");
return 0;
}
fd = open(DEVICE,O_RDWR);
if(fd == -1){
printf("Open the %s failed \n",DEVICE);
return 0;
}
write(fd,argv[1],strlen(argv[1]));
close(fd);
return 0;
}
测试结果(文件系统被成功卸载):