ioctl n’est pas appelé si cmd = 2

Je développe un module de kernel qui utilise unlocked_ioctl. Je l’ai testé avec la version 2.6.24-23-generic du kernel et cela fonctionne parfaitement. Maintenant, je l’ai essayé avec la version 3.3.1-1-ARCH du kernel et quelque chose de bizarre se produit: la fonction ioctl n’est pas exécutée lorsque la valeur de la demande (cmd) est égale à 2. Elle renvoie 0 mais la fonction n’est pas exécutée. Afin de vérifier qu’il n’est pas exécuté, j’ai procédé comme suit:

static long midriver_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { printk("Called with cmd = %d\n", cmd); 

J’ai écrit un programme de test qui appelle ioctl pour cet appareil de 0 à 4096 et je peux voir dans dmesg le message “Appelé avec cmd = n” pour toutes ces valeurs, à l’exception de “2”, le seul qui ne soit pas affiché.

Des indices sur ce que je fais mal?

Merci d’avance,

Jetez un coup d’oeil sur ceci :

  546 int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, 547 unsigned long arg) 548 { 549 int error = 0; 550 int __user *argp = (int __user *)arg; 551 struct inode *inode = filp->f_path.dentry->d_inode; 552 553 switch (cmd) { 554 case FIOCLEX: 555 set_close_on_exec(fd, 1); 556 break; 557 558 case FIONCLEX: 559 set_close_on_exec(fd, 0); 560 break; 561 562 case FIONBIO: 563 error = ioctl_fionbio(filp, argp); 564 break; 565 566 case FIOASYNC: 567 error = ioctl_fioasync(fd, filp, argp); 568 break; 569 570 case FIOQSIZE: 571 if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) || 572 S_ISLNK(inode->i_mode)) { 573 loff_t res = inode_get_bytes(inode); 574 error = copy_to_user(argp, &res, sizeof(res)) ? 575 -EFAULT : 0; 576 } else 577 error = -ENOTTY; 578 break; 579 580 case FIFREEZE: 581 error = ioctl_fsfreeze(filp); 582 break; 583 584 case FITHAW: 585 error = ioctl_fsthaw(filp); 586 break; 587 588 case FS_IOC_FIEMAP: 589 return ioctl_fiemap(filp, arg); 590 591 case FIGETBSZ: 592 return put_user(inode->i_sb->s_blocksize, argp); 593 594 default: 595 if (S_ISREG(inode->i_mode)) 596 error = file_ioctl(filp, cmd, arg); 597 else 598 error = vfs_ioctl(filp, cmd, arg); 599 break; 600 } 601 return error; 602 

Comme vous pouvez le constater, il existe certains cas de commutation avant l’appel vfs_ioctl ou file_ioctl .

Comme l’a souligné @Ilya, vous frappez un cas générique ( FIGETBSZ dans ce cas).

En général, vous souhaitez composer vos commandes ioctl à l’aide de la famille de macros _IO , avec un type unique, pour éviter les collisions.

Je suggère de lire ioctl-number.txt dans la documentation du kernel pour plus d’informations, y compris une liste des types les plus utilisés