Brutus Processus

Niveau : Star Star Star Empty Empty
Résumé : ps ; top ; htop ; atop ;

Suite à un arti­cle sur les pro­ces­sus, j’ai trouvé une excel­lente série d’arti­cle vous per­met­tant de décou­vrir le fonc­tion­ne­ment interne du noyau sur les pro­ces­sus et la mémoire :

Main­te­nant, essayons de résu­mer la ges­tion des pro­ces­sus d’un point de vue uti­li­sa­teur et déve­lop­peur.

Nais­sance, vie et mort d’un pro­ces­sus

Un pro­ces­sus est créé lors­que l’appel sys­tème fork est appelé et seu­le­ment dans ce cas. Les autres métho­des pos­si­bles se basent tou­tes sur fork (et clone, mais il ne faut pas le dire). Fork ne fait qu’une chose (et il le fait bien), il dupli­que un pro­ces­sus exis­tant, entiè­re­ment, à l’iden­ti­que, y com­pris ses droits.

Ensuite, durant sa vie un pro­ces­sus peut être modi­fié de nom­breu­ses façons :

  • Chan­ge­ment d’uti­li­sa­teur
  • Chan­ge­ment de code
  • Chan­ge­ment de père
  • Chan­ge­ment de prio­rité
  • etc.

Enfin un pro­ces­sus meurt dans 2 cas :

  • Il se ter­mine tout seul comme un grand (appel sys­tème exit)
  • Il reçoit un signal qui lui est fatal

Infor­ma­tions sur un pro­ces­sus

Infor­ma­tions géné­ra­les

Pour récu­pé­rer des infor­ma­tions sur un pro­ces­sus vous dis­po­sez de plu­sieurs com­man­des. Ces com­man­des ou tou­tes pour source /proc/<pid> qui est un réper­toire vir­tuel peu­plé direc­te­ment par le noyau.

Les com­man­des les plus cou­ran­tes sont :

  • ps : liste des pro­ces­sus et de leurs carac­té­ris­ti­ques
  • htop : liste dyna­mi­que des pro­ces­sus et de ce qu’ils con­som­ment
  • pgrep : récu­pé­ra­tion d’une liste de pro­ces­sus par expres­sion régu­lière
  • pidof : récu­pé­ra­tion du pid d’un pro­ces­sus recher­ché
  • fuser : infor­ma­tions sur les file des­crip­tor d’un pro­ces­sus
  • lsof : idem
  • pmap : affi­cher le map­ping mémoire d’un pro­ces­sus
Don­nées sur l’acti­vité

Un pro­ces­sus a une acti­vité somme toute limi­tée, c’est pour­quoi il est par­fai­te­ment fai­sa­ble de tout tra­cer. Le plus évi­dent est de tra­cer les appels sys­tème, mais cela ne révèle que ses inte­rac­tions avec le reste du monde. Il est aussi pos­si­ble de tra­cer les appels de fonc­tions voire cha­cune des ins­truc­tions.

  • strace : liste les appels sys­tème du pro­ces­sus
  • ltrace : liste les appels de fonc­tion de biblio­thè­ques dyna­mi­ques (.so) du pro­ces­sus
  • pstack : affi­che la pile d’appel du pro­ces­sus
  • gdb : avec gdb on peut tout savoir et même modi­fier l’action d’un pro­ces­sus. gdb uti­lise l’appel sys­tème ptrace pour cela.

Agir sur un pro­ces­sus

Les actions sur un pro­ces­sus peu­vent être effec­tuées par plu­sieurs enti­tés :

  • Le pro­ces­sus lui -même
  • Le pro­ces­sus père du pro­ces­sus
  • Un autre pro­ces­sus ayant les droits pour effec­tuer une action (c’est-à-dire même pro­prié­taire ou root … en l’absence de patch sur le noyau)

Les actions qu’on peut effec­tuer sur un pro­ces­sus sont tou­tes liées à un appel sys­tème. En géné­ral il existe une com­mande shell four­nis­sant une fonc­tion­na­lité équi­va­lente.

Envoi d’un signal

Les signaux per­met­tent de com­mu­ni­quer de façon basi­que avec un pro­ces­sus. Il peu­vent être envoyé par un autre pro­ces­sus ou par le noyau. man 1 kill vous indi­que la liste des signaux et l’action par défaut asso­ciée pour les pro­ces­sus qui ne les sur­char­gent pas.

Pour envoyer un signal à un pro­ces­sus il existe plu­sieurs com­man­des (qui uti­li­sent tou­tes l’appel sys­tème kill) :

  • kill : envoyer un signal à un pro­ces­sus con­nais­sant son pid
  • killall : envoie un signal à tous les pro­ces­sus por­tant un cer­tain nom
  • pkill : envoie un signal aux pro­ces­sus mat­chant une expres­sion régu­lière
  • ctrl-z : envoie le signal STOP au pro­ces­sus en avant plan du shell en cours
  • fg, bg : envoie le signal CONT à un pro­ces­sus stoppé du shell en cours
Répar­tir les tâches

Les pro­ces­sus peu­vent être plus ou moins con­som­ma­teurs de res­source pro­ces­seur. La par­tie du noyau nom­mée ordon­nan­ceur (sche­du­ler) s’occupe d’allouer ces res­sour­ces aux dif­fé­rents pro­ces­sus.

Pour influen­cer l’acti­vité de l’ordon­nan­ceur, il existe plu­sieurs métho­des. Tout d’abord cha­que pro­ces­sus dis­pose d’une prio­rité, le niveau de nice. Pour alté­rer son pro­pre niveau, il y a l’appel sys­tème nice qui a donné la com­mande nice. Pour alté­rer celui d’un autre pro­ces­sus il y a l’appel sys­tème set­prio­rity qui a donné la com­mande renice.

L’ordon­nan­ceur a la charge de répar­tir l’acti­vité de plu­sieurs pro­ces­sus, de plus en plus sou­vent entre plu­sieurs pro­ces­seurs. Il est pos­si­ble d’influen­cer la répar­ti­tion des pro­ces­sus entre pro­ces­seurs avec la com­mande task­set (uti­li­sant l’appel sys­tème sched_setaf­fi­nity). Cette com­mande per­met de limi­ter un pro­ces­sus à un ou plu­sieurs pro­ces­seurs don­nés.

Il existe aussi avec CFS, un moyen de con­trô­ler fine­ment le temps alloué à cha­que pro­ces­sus à tra­vers /sys/ker­nel/uids ou à tra­vers les cgroups (voir Docu­men­ta­tion/sche­du­ler/sched-design-CFS.txt).

De plus il existe dans le noyau un deuxième ordon­nan­ceur qui, cette fois, orga­nise les tâches d’accès au dis­que. Si c’est le CFQ qui a été choisi (car il est modi­fia­ble), il est pos­si­ble de l’influen­cer. Le grand inté­rêt de ceci est de limi­ter les pro­ces­sus qui pour­raient pha­go­cy­ter les autres en fai­sant énor­mé­ment d’accès dis­que (pen­sez aux backups). L’appel sys­tème ioprio_set est implé­menté dans la com­mande ionice pour gérer cette fonc­tion­na­lité. Lisez Docu­men­ta­tion/block/ioprio.txt pour plus de détails.

Ges­tion des droits

Il n’est pas pos­si­ble de chan­ger les droits d’un pro­ces­sus de l’exté­rieur. Seul lui-même en est capa­ble. Mais le méca­nisme stan­dard d’héri­tage lors du fork et de chan­ge­ment de droits lors de l’exec per­met de faire tout ce qu’on veut.

Il n’existe qu’un seul cas où les droits peu­vent être aug­men­tés (en sup­po­sant l’absence de patch de sécu­rité spé­ci­fi­que) : lan­cer la com­mande exec sur un fichier dis­po­sant du bit suid (et éven­tuel­le­ment de capa­bi­li­ties).

Ensuite pour réduire ses droits, le pro­ces­sus peut uti­li­ser :

  • L’appel sys­tème chroot qui a donné la com­mande chroot
  • L’appel sys­tème setXXuid qui est uti­lisé dans pam (com­mande login par exem­ple)
  • Les capa­bi­li­ties à tra­vers l’appel sys­tème set­cap qui per­met de limi­ter la liste des appels sys­tè­mes dis­po­ni­bles pour un pro­ces­sus (ceci est une option du noyau)
Deve­nir indé­pen­dant

Un pro­ces­sus reçoit des signaux mor­tels lors­que son tty est coupé. C’est pour­quoi un pro­ces­sus peut vou­loir obte­nir son indé­pen­dance.

Il appelle alors l’appel sys­tème set­sid qui le déta­che de son ter­mi­nal. De plus il crée un nou­veau groupe de pro­ces­sus pour lui et ses fils, ce qui en pra­ti­que le déta­che de son père (lequel ne pourra donc plus le tuer lorsqu’il mourra).

La com­mande set­sid fait la même chose en ligne de com­mande.

Limi­ta­tions

Il est pos­si­ble d’impo­ser des limi­ta­tions à un pro­ces­sus ainsi qu’à ses fils, il existe un appel sys­tème pour cela nom­mée setr­li­mit. Bash pro­pose une implé­men­ta­tion en ligne de com­mande pour cet appel nom­mée uli­mit.

Les limi­ta­tions incluent des limi­ta­tions en nom­bre de fichiers ouverts, en con­som­ma­tion CPU, en occu­pa­tion mémoire … vous trou­ve­rez les détails dans le manuel de bash à la com­mande uli­mit.

IPC et mémoire par­ta­gée

Une ancienne méthode cha­ma­ni­que uti­li­sée pour com­mu­ni­quer entre pro­ces­sus est cons­ti­tuée des IPC (inter pro­cess com­mu­ni­ca­tion). Les ipc per­met­tent à des pro­ces­sus de :

  • s’envoyer des mes­sa­ges (appels sys­tème msgXXX)
  • poser des séma­pho­res, une tech­ni­que de lock pour l’accès à des don­nées (appels sys­tè­mes semXXX)
  • par­ta­ger de la mémoire (appels sys­tème shmXXX)

Ces 3 caté­go­ries de métho­des génè­rent des don­nées qui sont indé­pen­dan­tes des pro­ces­sus de par le fait qu’elle sont des­ti­nées à d’autres pro­ces­sus. C’est pour­quoi lorsqu’un pro­ces­sus uti­li­sant des ipc plante, il laisse des tra­ces dans le sys­tème. Ces tra­ces con­som­ment de la mémoire inu­ti­le­ment et par­fois blo­quent d’autres pro­ces­sus.

C’est pour­quoi les com­man­des ipcs et ipcrm per­met­tent de mani­pu­ler ces don­nées de façon exté­rieu­res. Pen­sez à lire le manuel, c’est très court et vous pour­rez en pro­fi­ter pour moni­to­rer les don­nées en ques­tion.

Com­mu­ni­ca­tion avec le pro­ces­sus

Enfin, un pro­ces­sus est isolé et com­mu­ni­que avec le reste du monde de très peu de façons dif­fé­ren­tes :

  • avec des file des­crip­tor (réseau, fichier, pipe, tty, device …)
  • à tra­vers la mémoire par­ta­gée et les IPC
  • avec des signaux
  • par la ligne de com­mande (en lec­ture seule)
  • et avec quel­ques appels sys­tème ayant une action sur le sys­tème lui-même
Vus : 242
Publié par Peck : 100