Demati'Nal,
À la lecture de signal(7)
, on se rend compte que deux signaux sont réservés pour les signaux utilisateurs SIGUSR1
et SIGUSR2
. Deux, c'est peu. Je vous propose donc cette technique qu'on baptisera le signal knocking par analogie au Port_knocking
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
int signalvalue = 0;
void sigusr1handler(int signum);
void sigusr2handler(int signum);
void sigusr1handler(int signum) {
++signalvalue;
}
void sigusr2handler(int signum) {
switch(signalvalue) {
case 0: puts("action 0"); break;
case 1: puts("action 1"); break;
case 2: puts("action 2"); break;
case 3: puts("action 3"); break;
}
}
int main() {
signal(SIGUSR1, sigusr1handler);
signal(SIGUSR2, sigusr2handler);
while(1) sleep(10);
return 0;
}
Et voilà, on peut faire les traitements qu'on veut suivant la séquence de SIGUSR
qu'on envoie :-)
# Séquence
Posté par raspbeguy (site web personnel, Mastodon) . Évalué à 1. Dernière modification le 10 mai 2023 à 17:24.
Donc si je comprends bien, une séquence sera composée d'un nombre caractéristique de SIGUSR1, et terminée par un SIGUSR2, c'est bien ça ?
Pas bête.
On pourrait aussi imaginer un dictionnaire de séquences non préfixé (aucun mot du dictionnaire n'étant le préfixe de l'autre) pour pouvoir réduire un peu en moyenne la taille des séquences en alternant SIGUSR1 et SIGUSR2.
Un gentil du net
[^] # Re: Séquence
Posté par gUI (Mastodon) . Évalué à 9.
Du coup faudrait juste remettre à zéro le compteur de séquence dans
sigusr2handler()
pour pouvoir enchaîner des actions différentes.En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.
[^] # Re: Séquence
Posté par Philippe F (site web personnel) . Évalué à 9.
Ou sinon, on pourrait imaginer une séquence unique de début de trame, une séquence unique de fin de trame, et au milieu de ces deux séquences, sigusr1 signifierai un bit à 0 et siguser2 un bit à 1.
Bien sur, il faudrait faire des traitements sur les signaux du milieu pour éviter que les séquences de début et fin ne se retrouvent dans les données.
En fait, on peut refaire toute la théorie de traitement du signal.
[^] # Re: Séquence
Posté par Lucky Seven . Évalué à 4. Dernière modification le 11 mai 2023 à 19:09.
On pourrait représenter SIGUSR1 par un point et SIGUSR2 par un trait, ainsi on pourrait avoir ce genre de tableau :
[^] # Re: Séquence
Posté par gUI (Mastodon) . Évalué à 5.
De ce que j'ai compris, non ça ne marcherait pas. Il te faut un moyen de séparer les caractères. En morse c'est fait par le temps (pause entre les caractères et les mots). Or dans le cas des SIGUSR il n'y a aucune garantie de temps, ni même d'ordre.
En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.
[^] # Re: Séquence
Posté par Lucky Seven . Évalué à 1.
Si un caractère est égale à un signal géré par ton programme, ça ferait déjà une 40 aine de possibilités d'après le tableau. De la à écrire des phrases avec des signaux…
[^] # Re: Séquence
Posté par Psychofox (Mastodon) . Évalué à 3.
euh…si tu en arrives à ce genre de besoin, utilise un socket ou d-bus.
# Ça marche pas.
Posté par ml . Évalué à 7.
La bonne méthode :
1. Avoir un thread à demeure qui se met en lecture sur une FIFO.
2. Ou déclencher la lecture de la FIFO à réception du signal (évite de créer un thread dédié).
[^] # Re: Ça marche pas.
Posté par ml . Évalué à 4. Dernière modification le 10 mai 2023 à 18:09.
PS : bien faire attention à la cinématique, on se retrouve dans le cas d’une communication multi-thread. read/write est atomique en-dessous de PIPE_BUF, pas atomique au-dessus (attention aux blagues si plusieurs process veulent écrire dans la même FIFO), les appels sont bloquants (sauf précision contraire), bien gérer leurs codes retour.
Ça peut vite être assez tricky.
[^] # Re: Ça marche pas.
Posté par serge_sans_paille (site web personnel) . Évalué à 2.
Si le premier SIGUSR1 est géré avant réception du deuxième SIGUSR1, c'est ok, non ? EN tout cas c'est le comportement que j'observe…
[^] # Re: Ça marche pas.
Posté par Thomas Douillard . Évalué à 2.
Si il n’y a pas de "ack" il suffit que le processus soit bloqué un moment par un sigstop ou autre pour que la mécanique s’enraye par contre non ?
[^] # Re: Ça marche pas.
Posté par ml . Évalué à 4. Dernière modification le 10 mai 2023 à 18:50.
Il est possible que :
Linux (dans la version que tu utilises, avec les paramètres de compilation que tu as passé au noyau, etc.) ait une queue en interne (je ne sais pas comment il gère les signaux).
Dans le cas simple où tu as juste deux programmes en charge CPU, ça passe crème : le noyau va recevoir le signal de l’émetteur, basculer sur le code du récepteur (par optimisation par exemple : le noyau sait que le récepteur a du code à exécuter donc il va préférer basculer sur lui), il va exécuter entièrement le handler, avant de rebasculer sur l’émetteur, et ainsi de suite. Ça peut très bien se passer. Dans un cas de test simple. Mais sur une machine qui a un peu de load ou autre, multi-processeur, etc., rien ne te garantit que le noyau va exécuter alternativement les codes de l’un et de l’autre.
Si tu veux coder propre, il faut pas juste se contenter du “chez moi ça marche” mais prendre en compte les cas de comportement indéterminés. Cela implique de lire la doc à fond. En pur C/posix c’est incontournable. Dans le cas contraire tu t’exposes au risque que ça te pète à la gueule (au pire moment dira Murphy). Ça peut marcher pendant 10 ans, puis un beau jour casser parce que la mécanique interne du noyau et/ou de la lib a changé.
Sinon si t’as un peu de temps et de la motivation, tu peux essayer un émetteur qui envoie 10, 100 voir 1000 signaux dans la boucle la plus rapide possible, un récepteur qui a un handler artificiellement long (absolument via un
sleep
ouusleep
ça obligera le noyau à reprendre la main). Vois si ton handler récupère tous les signaux.[^] # Re: Ça marche pas.
Posté par barmic 🦦 . Évalué à 3.
Il me semble qu'il ne faut pas trop s'embêter, il s'agit d'un petit hack pour jouer. Il existe un tas d'ipc qui seront plus à même de faire des choses plus sophistiqué que ces 2 signaux utilisateurs.
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
# KillN
Posté par Amiralgaby . Évalué à 3.
Amiralgaby#1847
# Utilisation
Posté par ted (site web personnel) . Évalué à 2.
J'ai eu à faire quelques exercices avec les signaux, et je me demande si c'est encore beaucoup utilisé aujourd'hui "dans la vrai vie". Ça m'a l'air vachement limité, d'ailleurs le fait que ce journal parle d'un hack pour contourner une limite du truc me conforte un peu dans cet avis.
Un LUG en Lorraine : https://enunclic-cappel.fr
[^] # Re: Utilisation
Posté par Renault (site web personnel) . Évalué à 9.
Les signaux sont toujours utilisés et utiles dans la vraie vie.
Mais leur usage est de fait limité à cause des limitations de cette techno.
Car les signaux sont un moyen simple d’interagir avec un programme qui tourne, c'est standard, c'est facilement utilisable via la ligne de commande, un script shell ou un programme quelconque.
Mais ce n'est pas bidirectionnel, il y a peu de garanties en cas d'envoi multiples ou parallèles et peu extensibles. Donc pour s'en servir comme moyen de communication complexe je trouve que c'est bof.
Mais en usage réel que j'ai rencontré récemment il y a :
Bref, c'est utile mais ça soit être réservé à des usages où la concurrence des signaux et l'empilement des requêtes n'est pas critique. C'est donc bien pour éventuellement un contexte de débogue ou effectuer une action dynamique précise, mais guère plus.
[^] # Re: Utilisation
Posté par gUI (Mastodon) . Évalué à 7.
Recharger le fichier de config par exemple.
En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.
[^] # Re: Utilisation
Posté par Benoît Sibaud (site web personnel) . Évalué à 8.
[^] # Re: Utilisation
Posté par SChauveau . Évalué à 6.
Afficher les stats lors de la copie d'une ISO avec
dd
: Sending a USR1 signal to a running 'dd' process makes it print I/O statistics to standard error and then resume copying.[^] # Re: Utilisation
Posté par cg . Évalué à 3.
Une version moderne, ce serait les messages sur dbus.
[^] # Re: Utilisation
Posté par Amiralgaby . Évalué à 4. Dernière modification le 10 mai 2023 à 23:09.
Perso j'ai un petit projet en tête et le seul moyen que je trouve pour demander à un service (daemon) de lancer son traitement à un instant T pour du debuggage (parce que sinon il le lance à un intervalle régulier) est de le faire avec un signal.
Vive leur existence.
Amiralgaby#1847
[^] # Re: Utilisation
Posté par Krunch (site web personnel) . Évalué à 3. Dernière modification le 10 mai 2023 à 23:31.
Les signaux ne répondent pas au problème de lancer un traitement à un instant T puisqu'il n'y a pas de garantie du moment où ils sont livrés. Pour du débogage tu as plusieurs systèmes de breakpoints et tracepoints fait exprès pour ça mais ça varie généralement selon le système utilisé.
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
[^] # Re: Utilisation
Posté par Yth (Mastodon) . Évalué à 4.
Tout dépend de ton besoin de « à un instant T ».
Si c'est pour en crontab demander à un processus de faire un traitement, ça peut arriver n'importe quand selon la cron configurée, le programme ne sait pas à l'avance, donc c'est un instant T quelconque.
Par contre ya pas forcément besoin d'une réponse immédiate et synchrone, juste que ça soit fait.
C'est exactement ce qu'il se passe avec les logrotate d'ailleurs, où on peut envoyer un signal au processus pour lui demander de rouvrir son fichier de log.
Ça arrive à un instant T quelconque, mais t'as pas besoin d'être synchrone, faut juste que ça soit fait.
[^] # Re: Utilisation
Posté par Krunch (site web personnel) . Évalué à 2.
Heureusement que c'était précisé dans le message auquel j'ai répondu alors. Dommage que ça n'ai rien à voir avec un cron ou logrotate.
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
[^] # Re: Utilisation
Posté par Yth (Mastodon) . Évalué à 4.
Mais son besoin n'est pas plus urgent.
Tel que je le comprend c'est manuel : « Tiens processus, file-moi tes stats », et après t'attends le fichier.
Si au premier « ls » il n'est pas là, tu recommences, et le signal a normalement eu le temps de passer…
En tout cas son « à l'instant T » je l'ai compris comme « à un instant non défini à l'avance, mais qui peut arriver n'importe quand. » plutôt qu'à un appel synchrone genre « je veux ces données tout de suite ».
Dans le second cas, en effet, le signal n'est pas adapté, puisque c'est asynchrone comme fonctionnement.
[^] # Re: Utilisation
Posté par Amiralgaby . Évalué à 1.
Si je lance un signal à un service, il devrait quand même arriver assez vite pour lancer le traitement quasi dans la demi-seconde qui suit, non ?
Amiralgaby#1847
[^] # Re: Utilisation
Posté par Krunch (site web personnel) . Évalué à 2.
« dans la demi-seconde qui suit » c'est pas très « instant T » dans un contexte informatique. Quand on me parle de débogage je pense à une série d'instructions qui prennent chacune de l'ordre de la nanoseconde pour s'exécuter.
Le délai va dépendre de plein de trucs mais il y a pas mal de situations où ça peut prendre plus d'une demi seconde. Ça dépend de ton cas d'utilisation précis. Sur un système puissant qui fait rien d'autre, probablement que ça va arriver à temps.
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
[^] # Re: Utilisation
Posté par Amiralgaby . Évalué à 1.
Je m'étais mal exprimé.
Mon intérêt c'est de ne pas attendre que le service lance son traitement.
Je lance le signal
Il le reçoit
Il fait le traitement
Et moi j'ai des logs qui seront disponibles du fait de ce traitement
Amiralgaby#1847
[^] # Re: Utilisation
Posté par pulkomandy (site web personnel, Mastodon) . Évalué à 3.
Quand j'ai besoin de gérer des signaux sous Linux, je le fait plutôt à l'aide d'tn signalfd qui permet de récupérer les évènements via un descripteur de fichiers et de les faire rentrer dans ma boucle d'évènements avec tous les autres trucs que mon code doit traiter. Ça rend pour moi les choses beaucoup plus simples, mais le traitement un petit peu moins immédiat.
Mais si le code est architecturé comme il faut, ça se comptera au pire en centaines de millisecondes.
[^] # Re: Utilisation
Posté par barmic 🦦 . Évalué à 3.
Ça sert à ce pour quoi c'est faire. Lancer un signal à un programme. Pour l'arrêter c'est beaucoup utiliser, pour demander des rechargements de configuration aussi. A savoir quand un processus fils est mort.
C'est la solution la plus simple et la plus légère de toutes les IPC, mais tu en a pleins d'autres :
et un paquet d'autres plus ou moins spécifique (genre pour l'un des plus sophistiqué sous linux : dbus).
À noter, je crois que personne ne l'a cité, mais tu n'a aucune garantie que ton signal arrive sur le processus que tu attends, il me semble. Il peut être mort et son pid être réutilisé entre le moment où tu as lu le pid et le moment où tu envoi le signal.
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
[^] # Re: Utilisation
Posté par E3Ms6vyX . Évalué à 1.
Sur les calculateurs massivement parallèle gérés avec SLURM, on peut utiliser les signaux pour arrêter un programme proprement à la fin du temps alloué.
https://services.criann.fr/services/hpc/cluster-myria/guide/signals-sent-by-slurm/
# Réponse sérieuse
Posté par pulkomandy (site web personnel, Mastodon) . Évalué à 6.
Il y a aussi les signaux entre SIGRTMIN et SIGRTMAX qui sont disponibles. Ça en fait une trentaine de plus sous Linux.
[^] # Re: Réponse sérieuse
Posté par Krunch (site web personnel) . Évalué à 7. Dernière modification le 11 mai 2023 à 14:57.
Ça vient en fait de POSIX.1b qui définit les signaux temps réels. Ça défini aussi une union (int, void*) qui peut être passée entre l'envoyeur et le receveur et du coup on a besoin que d'un seul numéro de signal. L'ordre de réception pour un même numéro de signal est garanti. Mais du coup il faut utiliser l'API adéquat (sigqueue).
Par contre, si on utilise directement plusieurs numéros de signal entre SIGRTMIN et SIGRTMAX, l'ordre garanti c'est que le numéro de signal le plus bas est reçu en premier. Ce qui va rajouter encore plus de confusion si on ne prend pas ça en compte. Si j'ai bien compris…
https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_02
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
[^] # Re: Réponse sérieuse
Posté par Krunch (site web personnel) . Évalué à 2. Dernière modification le 11 mai 2023 à 23:18.
L'avantage aussi c'est que dans le shell on peut dire kill -q 42 SIGRTMIN plutôt que l'horrible killN mentionné ci-dessus.
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
[^] # Re: Réponse sérieuse
Posté par Amiralgaby . Évalué à 1.
Mon killN :'(
Mdr, j'avoue c'est horrible et de toute façon, selon les post par-ci par-là ça devrait être proscrit.
Amiralgaby#1847
# oui mais non
Posté par Krunch (site web personnel) . Évalué à 9.
Plusieurs commentaires ont tenté d'expliquer pourquoi cette approche est problématique. Une exploration plus détaillée des problème de concurrence peut être trouvée dans « Is Parallel Programming Hard, And, If So, What Can You Do About It? » de Paul E. McKenney (aka « perfbook ») : https://cdn.kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.html
TL;DR : c'est compliqué et réinventer la roue est un excellent moyen de se retrouver avec un système cassé de manière subtile et difficile à déboguer et corriger. Un peu comme en cryptographie.
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
# Une autre approche
Posté par devnewton 🍺 (site web personnel) . Évalué à 10. Dernière modification le 11 mai 2023 à 11:04.
Lorsque le programme reçoit un SIGUSR1, il fait une requête grpc+mtls+oauth2 à une API web hébergé sur un kubernetes dans le cloud qui lui renvoie le signal métier au format json.
L'API web stocke l'association host+pid => signal métier json dans une base Cassandra.
Pour envoyer un signal, il faut donc d'abord utiliser l'API web via une IHM qui délègue l'authentification à un Keycloak configuré en double facteur (password + biométrie).
Pour aller plus loin, il faudrait… Heu c'était quoi déjà le problème à résoudre?
Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.
[^] # Re: Une autre approche
Posté par Krunch (site web personnel) . Évalué à 10.
Ça manque de blockchain et de machine learning comme même.
pertinent adj. Approprié : qui se rapporte exactement à ce dont il est question.
# Sigurður
Posté par AlexTérieur . Évalué à 3.
C'est le plus sûr !!
-->[]
# prochaine étape
Posté par Benoît Sibaud (site web personnel) . Évalué à 8.
Le inotify knocking, créer/supprimer les bons fichiers dans le bon ordre ?
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.