vendredi 10 janvier 2014

Linux: /proc/[pid]/io syscr - syscw


Dans le système de fichiers  /proc, Linux fournit un fichier /proc/[pid]/io pour chaque processus.  Ce fichier contient les informations suivantes:
$ cat /proc/$$/io
rchar: 3753772
wchar: 44053
syscr: 36162
syscw: 276
read_bytes: 3014656
write_bytes: 4096
cancelled_write_bytes: 4096



  • Les champs rchar et wchar fournissent le nombre d'octets lus par le processus au moment où l'on consulte ce fichier io.
  • Les champs syscr et syswr donnent le nombre d'appels systèmes read et write effectués par le processus, les appels readv, pread et writev, pwrite sont inclus dans ce décompte.
  • Les champs read_bytes et write_bytes indiquent le nombre d'octets transférés depuis le disque à l’initiative de ce processus
  • Le champ cancelled_write_bytes tente de compter les octets qui auraient du être écrits sur disque mais qui n'ont jamais atteints le disque... parce que ce processus à, par exemple, détruit ou tronquer le fichier.
La description de ce fichier se trouve dans la page manuel proc(5)

Après observation, lorsqu'un processus se termine, ses compteurs syscr et syscw sont cumulés avec ceux de son père lorsque celui-ci fait waitpid du fils. Rien d'étrange? Cela ressemble à ce qui est fait, connu et enseigné sur les temps cpu utilisateur et système des fils. Si le père est déjà terminé, c'est init, qui récupèrera ces informations

Certes. On peut aussi ajouter d'autres champs qui sont reportés d'un fils mort vers un processus père: le nombre de fautes de page  majeures, le nombre de fautes de page mineures...

Il y a une différence dans le traitement de ces informations: 
  • Les temps CPU des fils morts sont cumulés dans des champs dédiés du descripteur du processus père, distinct des champs utilisés pour comptabiliser le temps CPU du processus père lui-même
  • Les compteurs d'appel système read et write sont directement cumulés avec ceux du père! D'ailleurs le descripteur de processus ne prévoit pas de compteurs spécifiques pour les valeurs des fils décédés.
Pourquoi? A ce jour, je n'en ai pas la moindre idée. 

Comment le vérifie-t-on ?  De la manière suivante :


  1. On commence par prendre l'état du fichier io du shell courant
  2. On exécute une commande dd simple effectuant un read et un write
  3. On reprend l'état du fichier io du shell courant
  4. La différence entre 1 et 3 nous donne un delta de référence de read/write pour le shell
  5. On exécute une commande dd effectuant 11 read et 11 write
  6. On reprend l'état du fichier io du shell courant
  7. On calcule la différence entre 3 et 6
  8. On compare les résultats entre 4 et 7... Différence : +10 syscr et +10 syscw!
 Voilà le shell script utilisé (io.sh) :
set -x
cat /proc/$$/io
dd if=/dev/zero of=/dev/null bs=1 count=1
cat /proc/$$/io
dd if=/dev/zero of=/dev/null bs=1 count=11
cat /proc/$$/io


Et voilà le résultat simplifié!
cat /proc/4173/io
syscr: 5
syscw: 1
dd if=/dev/zero of=/dev/null bs=1 count=1
1 byte (1 B) copied, 2.851e-05 s, 35.1 kB/s
cat /proc/4173/io
syscr: 26           # Donc le nombre de read est de 26 - 5 : 21
syscw: 8            # Donc le nombre de write est de 8 - 1 :  7
dd if=/dev/zero of=/dev/null bs=1 count=11 # On fait 10 read et 10 write de plus
11 bytes (11 B) copied, 3.5497e-05 s, 310 kB/s
cat /proc/4173/io
syscr: 57 # Nombre de read : 57 - 26 -> 31 (au lieu de 21, soit +10)
syscw: 25 # Nombre de write: 25 - 8  -> 17 (au lieu de 7, soit +10)

D'où quelques questions:
  • Quel usage était initialement prévu pour ces métriques?
  • Comment peut-on se servir de cette métrique, puisqu'elle n'indique pas ce que l'on attend?
Moralité:
  • Les documentations associées aux métriques sont à prendre avec précaution
  • Il est préférable de vérifier les choses de visu.
LeFA

Aucun commentaire:

Enregistrer un commentaire