2012-04-09 15 views
11

Estoy desarrollando un módulo kernel que usa unlocked_ioctl. Lo probé con la versión 2.6.24-23-generic del kernel y funciona perfectamente. Ahora lo probé con la versión de kernel 3.3.1-1-ARCH y sucede algo raro: la función ioctl no se ejecuta cuando el valor de solicitud (cmd) es 2. Devuelve 0, pero la función no se ejecuta. Con el fin de comprobar que no se ejecuta hice lo siguiente:ioctl no se llama si cmd = 2

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

printk("Called with cmd = %d\n", cmd); 

me escribió un programa de prueba que llama ioctl para este dispositivo de 0 a 4096, y puedo ver en dmesg el mensaje "Llamada con CMD = n "para todos esos valores, excepto de" 2 ", el único que no se muestra.

¿Alguna pista sobre lo que estoy haciendo mal?

gracias de antemano,

+0

Parte del código en la cadena está interceptando == cmd 2 y su manejo? – zvrba

Respuesta

9

echar un vistazo en this:

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 

Como se puede ver, hay algunos de los interruptores-casos antes vfs_ioctl o file_ioctl llamada.

+0

No veo la relevancia, ninguno de estos casos se aplica – Hasturkun

+1

Me corresponde corregir, el valor de 'FIGETBSZ' es de hecho 2, +1 – Hasturkun

3

Según lo indicado por @Ilya, Usted está golpeando un caso genérico (FIGETBSZ en este caso).

En general, usted quiere componer sus comandos ioctl usando el _IO family of macros, con un tipo único, para evitar colisiones.

Sugiero leer ioctl-number.txt de la documentación del núcleo para obtener más información, incluida una lista de la mayoría de los tipos utilizados

+0

Aquí hay un ejemplo' ioctl' mínimo usando '_IOx': https: // stackoverflow .com/a/44613896/895245 –