- 论坛徽章:
- 1
|
本帖最后由 shihyu 于 2016-03-16 21:50 编辑
我代码作用是想从 用户空间 appln process 透过 ioctl 传 用户空间 process 的 pid 到 内核 , 内核再透过 send_sig 函数不断发 SIGUSR2 给用户空间的 appln prcoess , 当我不想kernel 再发 SIGUSR2 signal 我再透过 ioctl 让 kernel 停止发 SIGUSR2- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/device.h>
- #include <linux/kernel.h>
- #include <linux/oom.h>
- #include <linux/sched.h>
- #include <linux/delay.h>
- #include <linux/kthread.h>
- #include "header.h"
- MODULE_LICENSE("Dual BSD/GPL");
- static int major_no;
- static int vrmonitor_pid;
- static int cccc = 100;
- static int send_sig_flag = 1;
- static struct task_struct* brook_tsk;
- static int vrmonitor_sig_handler(void* arg);
- static int vrmonitor_sig_handler(void* arg)
- {
- struct task_struct* p;
- struct pid* pp;
- printk(KERN_EMERG "cccc addr=%p ,cccc=%d\n", &cccc, cccc++);
- pp = find_vpid(vrmonitor_pid);
- p = pid_task(pp, PIDTYPE_PID);
- while (send_sig_flag) {
- msleep(1000);
- send_sig(SIGUSR2, p, 0);
- printk(KERN_EMERG "vrmonitor_sig_handler current pid=%d send to PID=%d \n", current->pid, vrmonitor_pid);
- }
- send_sig_flag = 1;
- return 0;
- }
- static int device_open(struct inode* inode, struct file* file)
- {
- printk(KERN_EMERG "pid=%d, Node Opened\n", current->pid);
- return 0;
- }
- int device_ioctl(struct file* filp,
- unsigned int cmd,
- unsigned long args)
- {
- int ret;
- switch (cmd) {
- case IOCTL_CMD:
- printk(KERN_EMERG "IOCTL_CMD");
- break;
- case IOCTL_SEND_PID:
- printk(KERN_EMERG "appln PID=%u , current kernel pid=%d\n", (unsigned int)args, current->pid);
- vrmonitor_pid = (unsigned int)args;
- brook_tsk = kthread_create(vrmonitor_sig_handler, NULL, "brook");
- if (IS_ERR(brook_tsk)) {
- ret = PTR_ERR(brook_tsk);
- brook_tsk = NULL;
- goto out;
- }
- wake_up_process(brook_tsk);
- break;
- case IOCTL_STOP_SIG:
- send_sig_flag = 0;
- printk(KERN_EMERG "IOCTL_STOP_SIG send_sig_flag=%d\n", send_sig_flag);
- break;
- default:
- printk(KERN_EMERG "Illegal ioctl command word\n");
- break;
- }
- return 0;
- out:
- return ret;
- }
- static int device_release(struct inode* inode, struct file* file)
- {
- printk(KERN_EMERG "Module Released \n");
- return 0;
- }
- static struct class* my_class;
- static struct file_operations fops = {
- .open = device_open,
- .release = device_release,
- .unlocked_ioctl = device_ioctl
- };
- static int hello_init(void)
- {
- major_no = register_chrdev(0, DEVICE_NAME, &fops);
- printk(KERN_EMERG "Module Major No : %d\n", major_no);
- my_class = class_create(THIS_MODULE, DEVICE_NAME);
- device_create(my_class, NULL, MKDEV(major_no, 0), NULL, DEVICE_NAME);
- printk(KERN_EMERG "Module loaded in kernel\n");
- return 0;
- }
- static void hello_exit(void)
- {
- printk(KERN_EMERG "Device is Released or closed \n");
- device_destroy(my_class, MKDEV(major_no, 0));
- class_unregister(my_class);
- class_destroy(my_class);
- unregister_chrdev(major_no, DEVICE_NAME);
- }
- module_init(hello_init);
- module_exit(hello_exit);
复制代码- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/ioctl.h>
- #include <signal.h>
- #include "header.h"
- static int fd;
- void stop_sig(int sig)
- {
- unsigned int sig_flag = 0;
- ioctl(fd, IOCTL_STOP_SIG, sig_flag);
- printf("stop_sig=%d, pid=%d\n", sig, getpid());
- (void) signal(SIGINT, SIG_DFL);
- #if 0
- kill(getpid(), SIGINT);
- #endif
- }
- void signal_handler(int signum)
- {
- printf("signal_handler %d, pid=%d\n", signum, getpid());
- if (signum == SIGUSR2) {
- printf("SIGUSR2\n");
- } else if (signum == SIGUSR1) {
- printf("SIGUSR1\n");
- }
- }
- int main()
- {
- pid_t pid = getpid();
- printf("PID=%u\n", pid);
- signal(SIGUSR2, signal_handler);
- signal(SIGINT, stop_sig);
- fd = open(DEVICE_PATH, O_RDWR);
- if (fd == -1) {
- printf("open fail\n");
- exit(-1);
- }
- ioctl(fd, IOCTL_SEND_PID, pid);
- printf("Ioctl executed\n");
- while(1) {}
- close(fd);
- return 0;
- }
复制代码 运行步骤
sudo insmod sample.ko
sudo ./appln
下面是打印出来的log
// user space log
PID=6897
Ioctl executed
signal_handler 12, pid=6897
SIGUSR2
signal_handler 12, pid=6897
SIGUSR2
^Cstop_sig=2, pid=6897 // ctrl + c 发往 kernel 让kernel停止发送 SIGUSR2
// kernel log
[ 681.335568] vrmonitor_sig_handler current pid=6898 send to PID=6897
[ 682.339540] vrmonitor_sig_handler current pid=6898 send to PID=6897
[ 682.871588] IOCTL_STOP_SIG send_sig_flag=0 // kernel 收到准备停止
[ 682.871646] Module Released
[ 683.343531] vrmonitor_sig_handler current pid=6898 send to PID=6897
我再一般pc上运行正常 ,
可是再 vmware ubuntu kernel 只发两次 SIGUSR2 , 就打印出 Module Released
下面 log , user space 的 appln prcoess 就莫名其妙结束 , 我还没按 ctrl+c
只是启动 sudo ./appln 这样
[ 681.335568] vrmonitor_sig_handler current pid=6898 send to PID=6897
[ 682.339540] vrmonitor_sig_handler current pid=6898 send to PID=6897
[ 682.871646] Module Released
|
|