3

当条件失败时,我正在尝试从内核空间到用户空间获取一些消息!

这是我的内核代码:

#define MESSAGTOUSER 1

int ret_val;
struct siginfo sinfo;
pid_t id;
struct task_struct *task;

unsigned char msgBuffer[20];
unsigned char buf1[20]= "HI";

static int major_no;
static struct class *safe_class;

static long device_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static int device_open(struct inode *inode, struct file *file);
static int device_write(struct file *file, const char *gdata, size_t len, loff_t *off);
static int device_read(struct file *file, char *buf, size_t len, loff_t *off);
static int device_release(struct inode *inode, struct file *file);


int failureDetection (char* faultMsg) {
    strcpy (msgBuffer, faultMsg);
    printk(KERN_ALERT"\nMessage from HBM %s\n", msgBuffer);
    printk(KERN_ALERT".......... RETURN VALUE ...... : %d", ret_val);

    int Reg_Dev(void);
    memset (&sinfo, 0, sizeof(struct siginfo));
    sinfo.si_signo = SIGUSR1;
    sinfo.si_code  = SI_USER;

    if (id == 0) {
        printk("\ncan't find User PID: %d\n", id);
    }else {
    //task = pid_task(find_vpid(pid), PIDTYPE_PID);
    task = find_task_by_vpid(id);
    send_sig_info(SIGUSR1, &sinfo, task);
    }
    return 0;
}

static int device_open(struct inode *inode, struct file *file){
    /*sucess*/
    return 0;
}

void strPrint(void) {
    printk("value of msgBuffer: %s", msgBuffer);
}

static int device_write(struct file *file, const char *gdata, size_t len, loff_t *off){
    get_user (id,(int *)gdata);
    if(id <0)
        printk(KERN_ALERT"Cann't find PID from userspace its : %i", id);
    else
        printk(KERN_ALERT"Successfully received the PID of userspace %i", id);
    return len;
}

static int
device_read(struct file *file, char *buf, size_t len, loff_t *off){
    /*success*/
    return 0;
}

static int device_release(struct inode *inode, struct file *file){
    /*success*/
    return 0;
}


static long device_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {


    switch (cmd) {
        case MESSAGTOUSER:
            ret_val = copy_to_user((char *)arg, msgBuffer, sizeof(arg));
            printk("Msg of Kernel %s", msgBuffer);
            break;
        default:
            break;
    }
    return 0;

}



static struct file_operations fops = {
    .open = device_open,
    .write = device_write,
    .read = device_read,
    .release = device_release,
    .unlocked_ioctl = device_ioctl
};


int Reg_Dev(void) {

    major_no = register_chrdev(0, "safe_dev", &fops);
    safe_class = class_create(THIS_MODULE, "safe_dev");
    device_create(safe_class,NULL, MKDEV(major_no, 0), "safe_dev");
    printk("\n Device Registered and Created \n");
    return 0;
}

void UnReg_dev (void) {
    printk("\nUser PID : %d\n", id);
    unregister_chrdev(major_no, "safe_dev");
    device_destroy(safe_class, MKDEV(major_no,0));
    class_unregister(safe_class);
    class_destroy(safe_class);
    printk("\n Device Un-Registered and Destroyed \n");
}

extern int Reg_Dev(void);

对于他的用户空间,我有这个代码:

#define PORT 9930
#define G_IP "192.168.10.71"
#define BUFLEN 512

#define MESSAGTOUSER 0

unsigned char *str[20];
char b1[BUFLEN], b2[BUFLEN];
struct sockaddr_in me,client;
int s, i, n=sizeof(me);
int fd;



void error_handler(char *s) {
  perror(s);
  exit(1);
}



void signal_handler (int signum) {

  if(signum == SIGUSR1)
  {
    printf("\n%s\n",str);

    if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))  == -1)
       error_handler("\nERROR: in Socket\n");

    memset((char *) &me, 0, sizeof(me));
    me.sin_family = AF_INET;
    me.sin_port = PORT;

    if (inet_aton(G_IP, &me.sin_addr)==0) 
    {
       fprintf(stderr, "inet_aton() failed\n");
       exit(1);
    }
    printf("Message from Kernel : %s", &str);
    //strcpy (str, newStr);


    int cntr =0;    sprintf(b2, "\nFailure Message: %s\n",str);
    printf("\nsending Fault to PMN Group : Tick - %d\n", cntr++);


    if(sendto(s, str, sizeof(str),0,(struct sockaddr *) &me,n)==-1)
        error_handler("\nERROR: in sendto()\n");
    close (s);
//    counter ++;
 //   sendAndReceiveOverUDP();
    return;
  }
}

int main() {
   pid_t u_id;
   u_id = getpid();
   int i = 1;

   fd = open("/dev/safe_dev",O_RDWR);
   write(fd, &u_id, 4);
   ioctl (fd, MESSAGTOUSER, &str);
   printf("\n PID sent to device successfully: %d \n", u_id);
   close(fd);

   signal(SIGUSR1, signal_handler);
   printf("\nMy PID is: %d\n",u_id);
   //printf("Subnet 1 working fine.. Tick - %d", tv.tv_sec);

   while (1)
   sleep(1);
   return 0;
}

现在我期望在用户空间收到什么:

Message from Kernel: A<->B
Sending Fault o PMN Group : tick - 0

Message from Kernel: B<->B
Sending Fault o PMN Group : tick - 1
....
...

但输出是什么:

Message from Kernel:
Sending Fault o PMN Group : tick - 0

Message from Kernel:
Sending Fault o PMN Group : tick - 1
....
...

似乎 copy_to_user 不工作,而在简单的程序中只是将字符串从内核复制到用户工作正常,但是当我在这种情况下使用它时它不工作,它的编译没有任何警告,

  • 其他一些细节:
  • failureDetection() 得到一个字符串,如 A<->B 在其余程序的输出中提到的..
  • 来自 failureDetection 的相同消息正在内核级别打印,但不在用户级别传输。
  • 我也尝试在其中创建一个自己的字符串并尝试转移它,但它也不起作用!假设msgBuffer = HI,那么我应该收到 HI 到用户空间。但它没有发生!任何人都可以请让我纠正这段代码有什么问题吗?我怎样才能获得用户空间的更新!!???

信德..

4

2 回答 2

0

copy_to_user()唯一发生在响应的,ioctl()它只发生一次,很早就在你的代码中。大概在那个时候内核缓冲区msgBuffer是空的,因为那个failureDetection()函数还没有运行。failureDetection()如果稍后运行然后设置并不重要msgBuffer,因为您的用户空间程序永远不会再次调用,ioctl()所以它看不到msgBuffer.

您的copy_to_user()通话中也有一个错误-sizeof(args)4可能应该使用sizeof msgBuffer.

于 2012-05-29T06:49:34.237 回答
0

@caf:非常感谢你..

void signal_handler (int signum) {

if(signum == SIGUSR1)
{
    fd = open ("/dev/safe_dev",O_RDWR);
    ioctl (fd, MESSAGTOUSER, &str);
    close (fd);

    if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))  == -1)
        error_handler("\nERROR: in Socket\n");

    memset((char *) &me, 0, sizeof(me));
    me.sin_family = AF_INET;
    me.sin_port = PORT;

    if (inet_aton(G_IP, &me.sin_addr)==0) 
    {
        fprintf(stderr, "inet_aton() failed\n");
        exit(1);
    }

    printf("Failure Detected on Eth Cards as : %s are non reachable.", str);

    printf("\nsending Fault to PMN Group : Tick - %d\n", cntr++);
    sprintf(b2, "\nFailure Message: %s\n",str);



    if(sendto(s, str, sizeof(str),0,(struct sockaddr *) &me,n)==-1)
        error_handler("\nERROR: in sendto()\n");
    close (s);
    return;
    }
}

我只是犯了一个愚蠢的错误..呵呵..我没有在文件打开和关闭块之间添加它..你的建议解决了我的问题......

非常感谢你的回复..

拉希..

于 2012-05-30T08:18:01.267 回答