Forum Linux.debian/ubuntu [Debian] : Améliorer ioctl.h pour communication non-standard

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
1
15
avr.
2019

Bonjour à tous,

J'ai compilé/recompilé les drivers (.ko) du projet dont je vous indique l'adresse.

https://linux-gpib.sourceforge.io/

Tout est bien configuré mais en allant executer un strace, j'ai identifié cette erreur.

09:48:32.520979 ioctl(3, TCGETS, 0x7fff5ac30bd0) = -1 ENOTTY (Inappropriate ioctl for device) <0.000015>
ENOTTY
(C ++ 11)
Opération de contrôle d'E / S inappropriée
(constante de macro)

A priori, il faut améliorer ioctl.h pour des communications non-standard.

On m'a conseillé ce lien. Est-ce que vous avez déjà fait ceci ?

http://www.dnx-rtos.org/doxygen/group__sys-ioctl-h.html

Quel fichier regarder sur le lien ci-dessous pour exemple !

https://packages.debian.org/search?searchon=contents&keywords=ioctl&mode=filename&suite=stable&arch=i386

Merci par avance.

  • # descripteur fermé?

    Posté par  . Évalué à 2.

    Sans trop chercher (j'ai regardé le 1er lien très vite fait cependant), je dirais que ce message d'erreur:

    Opération de contrôle d'E / S inappropriée

    est le même que celui que j'ai quand j'essaie de faire un printf (en bourne) dans un script dont stdout à probablement été fermé.

    En extrapolant un peu, (constante de macro) aurait tendance à me faire penser que ton appel passe par une macro, pas par une véritable fonction.
    Du coup, je te suggérerais de trouver l'appel qui fait ça dans le code, qui est probablement un "fprint( stdout, "foobar");" et de le remplacer par un truc du genre write( fd, "foobar", strlen( "foobar" );, en prenant soin d'être sûr que fd est ouvert en écriture.

    D'autres pourront peut-être en dire plus que moi, en prenant le temps de lire tes 3 liens en fond en comble, mais un peu plus d'info contextuelles ne serait pas de trop: on ne sait même pas ce que tu essaies vraiment de faire ni d'où tu sors réellement tes sources :/

    • [^] # Re: descripteur fermé?

      Posté par  (site web personnel) . Évalué à 2.

      je dirais que ce message d'erreur:
      Opération de contrôle d'E / S inappropriée
      est le même que celui que j'ai quand j'essaie de faire un printf (en bourne) dans un script
      dont stdout à probablement été fermé.

      Ah bon, on ne se prend pas juste un SIGPIPE dans les dents dans ce cas là ?

      • [^] # Re: descripteur fermé?

        Posté par  . Évalué à 2.

        Ah bon, on ne se prend pas juste un SIGPIPE dans les dents dans ce cas là ?

        Probablement que le processus appelant se mange en effet ce signal, ce qui peut le sortir d'un appel à poll ou read entres autres, et les appels système que je connais renvoient dans ce genre de cas un -1, avec la variable errno mise à jour en conséquence.
        Un appel à strerror( errno ) permets probablement ensuite de traduire un errno numérique et totalement illisible ou un numéro de signal du même acabit en une chaîne de caractères plus lisible par l'homme mais moins par la machine?

        Après tout, un signal, ça s'attrape (enfin, certains), et je serais très déçu qu'un shell ne fasse pas le maximum dans ce sens là… et de fil en aiguille, via mes notions et mon expérience (uniquement gnulibc, pour ce coup, et juste debian stable), j'ai déduis sans vérifier que le message d'erreur que j'ai eu via des appels à des scripts check de runit qui affichaient ce type de message d'erreur étaient lié à ça: après tout, sv check foobar n'a aucune raison de laisser "foobar" écrire, on lui demande juste si oui ou non le service tourne, un simple "return EXIT_FAILURE" (en C) devrait faire l'affaire.

        Après, je me plante peut-être aussi complètement, ça ne serait ni la première, ni la dernière fois.

  • # regardez plutôt du coté du driver, ou des sources de l'appli

    Posté par  . Évalué à 2. Dernière modification le 15 avril 2019 à 14:40.

    Bonjour,
    Les ioctl sont des commandes standards envoyées depuis un logiciel vers un driver, mais avec un contenu qui peut être fortement variable. Le format en lui même de la fonction ioctl ne doit pas avoir d'impact sur ce genre de message d'erreur.
    Par contre, la fonctionnalité intégrée dans le driver appelé via cet ioctl (TCGETS) renvoie cette erreur car c'est une fonction qu'il considère non applicable sur le matériel cible.
    La solution serait donc plutôt, soit de modifier le code source de l'appli si celle-ci s'appuie sur du matériel standard/courant/éprouvé (rayer la mention inutile), soit de modifier le driver du-dit matériel si il n'est pas très courant.

    voir par exemple cette page de man tty_ioctl qui indique

    ERRORS
    […]
    ENOTTY Inappropriate fd.

    et pour exemple, une fonction hung_up_tty_ioctl qui peut renvoyer cette erreur, appelé par la fonction tty_ioctl

    • [^] # Re: regardez plutôt du coté du driver, ou des sources de l'appli

      Posté par  . Évalué à 1.

      Tu parles d'ioctl.h, je suppose que tu as du écrire un bout de code pour le tester ; dans ce cas, es-tu sûr que tu ouvres le bon device ? Peut-être que l'ioctl ne se fait pas sur le bon fd ou qu'elle ne soit tout simplement pas supportée par le driver.

      Le driver (le .ko) que tu charges gère-t-il bien le périphérique comme le décrit sa documentation ? Je pense que tu devrais voir quelques lignes dans les logs kernels (cf. dmesg) qui dit que ton driver est chargé, et s'il est assez gentil, t'affichera les devices qu'il a pu trouver et gérer …

    • [^] # Re: regardez plutôt du coté du driver, ou des sources de l'appli

      Posté par  (site web personnel) . Évalué à 2.

      Les ioctl sont des commandes standards envoyées depuis un logiciel vers un driver,
      mais avec un contenu qui peut être fortement variable.
      Le format en lui même de la fonction ioctl ne doit pas avoir d'impact sur ce genre de message d'erreur.

      Tout à fait, un rapide coup d’œil et cela me semble être le cas ici, c'est l'erreur par défaut qui lancée lorsqu'un appel ioctl demandé n'est pas reconnu.
      - l'opération unlocked_ioctl appelle ibioctl de sys/osfuncs.c, la liste de commandes comprises se trouvent dans le grand switch case . -

      … reste à creuser pour savoir qui provoque cette erreur.

  • # Aucun pb à priori…

    Posté par  (site web personnel) . Évalué à 3.

    ioctl() sert en effet à passer des commandes spécifiques aux pilotes de périphériques.

    Parmi ces commandes, un ensemble sert à faire les requêtes sur les terminaux (virtuels ou réels, comme les ports série) :
    http://man7.org/linux/man-pages/man4/tty_ioctl.4.html

    ioctl(TCGETS) est appelé par la fonction tcgetattr() de la libc.

    Quelle est la commande lancée depuis strace ?
    Une partie de celle-ci (ou alors une redirection depuis le shell?) tente d'ouvrir le device publié par le pilote, en supposant qu'il s'agit d'un tty, et donc en faisant des appels dessus.

    Vu que ce n'est pas un terminal, le pilote ne reconnaît pas la requête et retourne juste un code d'erreur pour le signifier au processus appelant, et ajoute un log depuis le kernel.

    Ce n'est absolument pas un problème, c'est même tout à fait normal.

    Ce qui l'est moins c'est que la commande pense que c'est un tty si ça ne l'est pas.

    Sauf si c'est une commande qui s'attend à être utilisée avec un tty justement.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.