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

@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 に答える
0

コードの非常に早い段階で、一度だけcopy_to_user()発生ioctl()します。その時点では関数がまだ実行されていないため、おそらくその時点でカーネル バッファーmsgBufferは空です。後で実行して設定failureDetection()しても問題ありません。これは、ユーザー空間プログラムが を再度呼び出すことはないため、 の新しい内容が表示されないためです。failureDetection()msgBufferioctl()msgBuffer

また、呼び出しにバグがあります- (これは定数です) のcopy_to_user()代わりに、おそらく を使用する必要があります。sizeof(args)4sizeof msgBuffer

于 2012-05-29T06:49:34.237 に答える