Lorsqu'un processus est en mode utilisateur, il peut être interrompu à tout moment (passage en mode noyau). Lorsque le noyau retourne en mode utilisateur, il vérifie s'il y a des signaux en attente (y compris ceux qui sont utilisés pour tuer le processus, tels que SIGTERM
et SIGKILL
). Cela signifie qu'un processus ne peut être tué qu'au retour en mode utilisateur.
La raison pour laquelle un processus ne peut pas être tué en mode noyau est qu'il pourrait potentiellement corrompre les structures du noyau utilisées par tous les autres processus de la même machine (de la même manière, tuer un thread peut potentiellement corrompre les structures de données utilisées par d'autres threads dans le même processus) .
Lorsque le noyau a besoin de faire quelque chose qui pourrait prendre beaucoup de temps (attendre sur un tube écrit par un autre processus ou attendre que le matériel fasse quelque chose, par exemple), il dort en se marquant comme endormi et en appelant le planificateur pour passer à un autre processus (s'il n'y a pas de processus non dormant, il passe à un processus "factice" qui indique au processeur de ralentir un peu et se place dans une boucle - la boucle inactive).
Si un signal est envoyé à un processus en veille, il doit être réveillé avant de retourner dans l'espace utilisateur et de traiter ainsi le signal en attente. Ici, nous avons la différence entre les deux principaux types de sommeil:
TASK_INTERRUPTIBLE
, le sommeil interruptible. Si une tâche est marquée de cet indicateur, elle est en veille, mais peut être réveillée par des signaux. Cela signifie que le code qui a marqué la tâche comme étant en veille attend un signal possible et, après son réveil, le vérifiera et reviendra de l'appel système. Une fois le signal traité, l'appel système peut potentiellement être redémarré automatiquement (et je n'entrerai pas dans les détails sur la façon dont cela fonctionne).
TASK_UNINTERRUPTIBLE
, le sommeil ininterrompu. Si une tâche est marquée avec cet indicateur, elle ne s'attend pas à être réveillée par autre chose que ce qu'elle attend, soit parce qu'elle ne peut pas être redémarrée facilement, soit parce que les programmes s'attendent à ce que l'appel système soit atomique. Cela peut également être utilisé pour les dortoirs connus pour être très courts.
TASK_KILLABLE
(mentionné dans l'article LWN lié à la réponse de ddaa) est une nouvelle variante.
Cela répond à votre première question. Quant à votre deuxième question: vous ne pouvez pas éviter les sommeil ininterrompus, c'est une chose normale (cela arrive, par exemple, chaque fois qu'un processus lit / écrit depuis / sur le disque); cependant, ils ne devraient durer qu'une fraction de seconde. S'ils durent beaucoup plus longtemps, cela signifie généralement un problème matériel (ou un problème de pilote de périphérique, qui ressemble au noyau), où le pilote de périphérique attend que le matériel fasse quelque chose qui ne se produira jamais. Cela peut également signifier que vous utilisez NFS et que le serveur NFS est en panne (il attend que le serveur se rétablisse; vous pouvez également utiliser l'option «intr» pour éviter le problème).
Enfin, la raison pour laquelle vous ne pouvez pas récupérer est la même raison pour laquelle le noyau attend le retour en mode utilisateur pour délivrer un signal ou tuer le processus: cela corromprait potentiellement les structures de données du noyau (le code en attente d'un sommeil interruptible peut recevoir une erreur qui le signale pour revenir à l'espace utilisateur, où le processus peut être tué; le code en attente d'un sommeil ininterrompu n'attend aucune erreur).
TASK_UNINTERUPTIBLE
état chaque fois que le système n'est pas dans un état inactif, collectant ainsi de force des données, attendant de transmettre une fois que le super utilisateur quitte? Ce serait une mine d'or pour les pirates informatiques pour récupérer des informations, revenir à l'état de zombie et transmettre des informations via le réseau au repos. Certains peuvent soutenir que c'est une façon de créer unBlackdoor
pour les pouvoirs en place, d'entrer et de sortir de n'importe quel système comme souhaité. Je crois fermement que cette faille peut être scellée pour de bon, en éliminant le `TASK_UNINTERUPTIB