Programmation avancée sous Linux


précédentsommairesuivant

7. Le Système de Fichiers /proc

Essayez d'invoquer la commande mount sans argument -- elle liste les systèmes de fichiers actuellement montés sur votre système GNU/Linux. Vous apercevrez une ligne de ce type:

 
Sélectionnez

proc on /proc type proc (rw)

Il s'agit du système de fichiers spécial /proc. Notez que le premier champ, proc, indique qu'il n'est associé à aucun périphérique matériel, comme un lecteur de disque. Au lieu de cela, /proc est une fenêtre sur le noyau Linux en cours d'exécution. Les fichiers de /proc ne correspondent pas à des fichiers réels sur un disque physique. Il s'agit plutôt d'objets magiques qui se comportent comme des fichiers mais donnent accès à des paramètres, des structures de données et des statistiques du noyau. Le « contenu » de ces fichiers n'est pas composé de blocs de données, comme celui des fichiers ordinaires. Au lieu de cela, il est généré à la volée par le noyau Linux lorsque vous lisez le fichier. Vous pouvez également changer la configuration du noyau en cours d'exécution en écrivant dans certains fichiers du système de fichiers /proc.

Étudions un exemple:

 
Sélectionnez

% ls -l /proc/version
-r--r--r--    1 root  root 0 Jan 17 18:09 /proc/version

Notez que la taille du fichier est zéro; comme le contenu du fichier est généré par le noyau, le concept de taille de fichier n'a pas de sens. De plus, si vous essayez cette commande, vous remarquerez que la date de modification est la date courante.

Qu'y a-t-il dans ce fichier? Le contenu de /proc/version est une chaîne décrivant le numéro de version du noyau Linux. Il correspond aux informations qui seraient renvoyées par l'appel système uname, décrit dans le Chapitre 8, « Appels Système Linux », Section 8.15, « uname », ainsi que des informations supplémentaires comme la version du compilateur utilisé pour construire le noyau. Vous pouvez lire /proc/version comme n'importe quel autre fichier. Par exemple, au moyen de cat:

 
Sélectionnez

% cat /proc/version
Linux version 2.2.14-5.0 (root@porky.devel.redhat.com) (gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)) #1 Tue Mar 7 21:07:39 EST 2000

Les différentes entrées du système de fichiers /proc sont décrites dans la page de manuel de /proc (Section 5). Pour la consulter, utilisez la commande suivante:

 
Sélectionnez

% man 5 proc

Dans ce chapitre, nous décrirons certaines fonctionnalités du système de fichiers /proc qui sont les plus susceptibles de servir à des programmeurs et nous donnerons des exemples d'utilisation. Quelques unes de ces fonctionnalités sont également utiles pour le débogage.

Si vous êtes intéressé par le fonctionnement exact de /proc, consultez le code source du noyau Linux situé dans /usr/src/linux/fs/proc.

7-1. Obtenir des Informations à partir de /proc

La plupart des fichiers de /proc donnent des informations formatées pour pouvoir être lues par des humains, cependant leur présentation reste suffisamment simple pour qu'elles puissent être analysées automatiquement. Par exemple, /proc/cpuinfo contient des informations sur le processeur (ou les processeurs dans le cas d'une machine multiprocesseur). Son contenu est un tableau de valeurs, une par ligne, avec une description de la valeur et deux points avant chacune d'entre elles.

Par exemple, son contenu peut ressembler à cela:

 
Sélectionnez

% cat /proc/cpuinfo
processor       :0
vendor_id       : GenuineIntel
cpu family      :6
model           :5
model name      : Pentium II (Deschutes)
stepping        :2
cpu MHz         : 400.913520
cache size      : 512 KB
fdiv_bug        : no
hlt_bug         : no
sep_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     :2
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep
mtrr pge mca cmov pat pse36 mmx fxsr
bogomips        : 399.77

Nous décrirons à quoi correspondent certains de ces champs dans la Section 7.3.1, « Informations sur le Processeur ».

Une méthode simple pour extraire une valeur de cette liste est de lire le fichier dans un tampon et de l'analyser en mémoire au moyen de sscanf. Le Listing clockspeed montre une façon de faire. Le programme déclare une fonction, get_cpu_clock_speed, qui charge /proc/cpuinfo en mémoire et en extrait la vitesse d'horloge du premier processeur.

Exemple d'utilisation de /proc/cpuinfo clock-speed.c
Sélectionnez

#include <stdio.h>
#include <string.h>

/* Renvoie la vitesse d'horloge du processeur en MHZ, d'après /proc/cpuinfo.
   Sur un système multiprocesseur, renvoie la vitesse du premier.
   Renvoie zéro en cas d'erreur. */

float get_cpu_clock_speed ()
{
  FILE* fp;
  char buffer[1024];
  size_t bytes_read;
  char* match;
  float clock_speed;

  /* Charge le contenu de /proc/cpuinfo dans le tampon. */
  fp = fopen ("/proc/cpuinfo", "r");
  bytes_read = fread (buffer, 1, sizeof (buffer), fp);
  fclose (fp);
  /* Traite le cas  la lecture échoue ou le buffer est trop petit. */
  if (bytes_read == 0 || bytes_read == sizeof (buffer))
    return 0;
  /* Place un caractère nul à la fin de la chaîne. */
  buffer[bytes_read] = "\0";
  /* Recherche la ligne commençant par "cpu MHz". */
  match = strstr (buffer, "cpu MHz");
  if (match == NULL)
    return 0;
  /* Analyse la ligne pour extraire la vitesse d'horloge. */
  sscanf (match, "cpu MHz : %f", &amp;clock_speed);
  return clock_speed;
}

int main ()
{
  printf ("CPU clock speed: %4.0f MHz\n", get_cpu_clock_speed ());
  return 0;
}

Soyez conscient du fait que les noms, la signification et les formats de sortie des entrées du système de fichiers /proc peuvent changer au fil des révisions du noyau Linux. Si vous les utilisez au sein d'un programme, assurez-vous que le comportement du programme reste cohérent si une entrée est absente ou formatée d'une façon inconnue.

7-2. Répertoires de Processus

Le système de fichiers /proc contient un répertoire par processus s'exécutant sur le système. Le nom de chacun de ces répertoires est l'identifiant du processus auquel il correspond(Sur certains systèmes UNIX, les identifiants de processus sont alignés au moyen de zéros. Ce n'est pas le cas sous GNU/Linux.). Ces répertoires apparaissent et disparaissent dynamiquement lors du démarrage et de l'arrêt d'un processus. Chaque dossier contient plusieurs entrées donnant accès aux informations sur le processus en cours d'exécution. C'est de ces répertoires de processus que le système de fichiers /proc tire son nom.

Chaque répertoire de processus contient ces fichiers:

  • cmdline contient la liste d'argument du processus. L'entrée cmdline est décrite dans la Section 7.2.2, « Liste d'Arguments d'un Processus ».
  • cwd est un lien symbolique pointant vers le répertoire de travail courant du processus (qui peut être défini par exemple, via un appel à chdir).
  • environ contient l'environnement du processus. Le fichier environ est décrit dans la Section 7.2.3, « Environnement de Processus ».
  • exe est un lien symbolique pointant vers l'image binaire exécutée par le processus. L'entrée exe est décrite dans la Section 7.2.5, « Descripteurs de Fichiers d'un Processus ».
  • maps contient des informations sur les fichiers mis en correspondance avec l'espace mémoire du processus. Consultez le Chapitre IPC, Section mmap, « Mémoire Mappée » pour plus de détails sur le fonctionnement des fichiers mis en correspondance avec la mémoire. Pour chaque fichier mis en correspondance, maps affiche l'intervalle d'adresses de l'espace mémoire du processus avec lequel le fichier est mis en correspondance, les permissions applicables à ces adresses, le nom du fichier ainsi que d'autres informations. Le tableau maps affiche pour chaque processus le fichier binaire en cours d'exécution, les bibliothèques partagées actuellement chargées et les autres fichiers que le processus a mis en correspondance avec sa mémoire.
  • root est un lien symbolique vers le répertoire racine du processus. Généralement, il s'agit d'un lien vers /, le répertoire racine du système. Le répertoire racine d'un processus peut être changé par le biais de l'appel chroot ou de la commande chroot(L'appel et la commande chroot sortent du cadre de ce livre. Consultez la page de manuel de chroot dans la section 1 pour des informations sur la commande (man 1 chroot) ou la page de manuel de chroot dans la section 2 (man 2 chroot) pour plus d'informations sur l'appel.).
  • stat contient des statistiques et des informations sur le statut du processus. Ce sont les mêmes données que celles présentées dans le fichier status, mais au format numérique brut, sur une seule ligne. Ce format est difficile à lire mais plus adapté au traitement automatique par des programmes. Si vous voulez utiliser le fichier stat dans vos programmes, consultez la page de manuel de proc qui décrit son contenu en invoquant man 5 proc.
  • statm contient des informations sur la mémoire utilisée par le processus. Le fichier statm est décrit dans la Section 7.2.6, « Statistiques Mémoire de Processus ».
  • status contient des informations statistiques et statut sur le processus formatée de façon à être lisibles par un humain. La Section 7.2.7, « Statistiques sur les Processus » présente une description du fichier status.
  • Le fichier cpu n'apparaît que sur les noyaux Linux SMP. Il contient un récapitulatif de la consommation en temps (utilisateur et système) du processus, par processeur.

Notez que pour des raisons de sécurité, les permissions de certains fichiers sont définies de façon à ce que seul l'utilisateur propriétaire du processus (ou le superutilisateur) puisse y accéder.

7-2-1. /proc/self

Une entrée particulière dans le système de fichiers /proc facilite son utilisation par un programme pour obtenir des informations sur le processus au sein duquel il s'exécute. L'entrée /proc/self est un lien symbolique vers le répertoire de /proc correspondant au processus courant. La destination du lien /proc/self dépend du processus qui l'utilise: chaque processus voit son propre répertoire comme destination du lien.

Par exemple, le programme du Listing getpid utilise la destination du lien /proc/self pour déterminer son identifiant de processus (nous ne faisons cela que dans un but d'illustration; l'appel de la fonction getpid, décrite dans le Chapitre processus, « Processus », Section idprocessus, « Identifiants de Processus » constitue une façon beaucoup plus simple d'arriver au même résultat). Ce programme utilise l'appel système readlink, présenté dans la Section 8.11, « readlink : Lire des Liens Symboliques », pour extraire la cible du lien.

Récupérer son PID à partir de /proc/self get-pid.c
Sélectionnez

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

/* Renvoie l'identifiant de processus de l'appelant, déterminé à partir du
   lien symbolique /proc/self. */

pid_t get_pid_from_proc_self ()
{
  char target[32];
  int pid;
  /* Lit la cible du lien symbolique. */
  readlink ("/proc/self", target, sizeof (target));
  /* La cible est un répertoire portant de nom du PID.  */
  sscanf (target, "%d", &amp;pid);
  return (pid_t) pid;
}
int main ()
{
  printf ("/proc/self renvoie l'identifiant %d\n",
          (int) get_pid_from_proc_self ());
  printf ("getpid() renvoie l'identifiant %d\n", (int) getpid ());
  return 0;
}

7-2-2. Liste d'Arguments d'un Processus

Le fichier cmdline contient la liste d'arguments du processus (consultez le Chapitre logicielsQualite, « Écrire des Logiciels GNU/Linux de Qualité », Section listeArgs, « La Liste d'Arguments »). Les arguments sont présentés sous forme d'une seule chaîne de caractères, les arguments étant séparés par des NUL. La plupart des fonctions de traitement de chaînes de caractères s'attendent à ce la chaîne en elle-même soit terminée par un NUL et ne géreront pas les NUL contenus dans la chaîne correctement, vous aurez donc à traiter le contenu de cette chaîne d'une façon spéciale.

NUL est le caractère dont la valeur décimale est 0. Il est différent de NULL, qui est un pointeur avec une valeur de 0. En C, une chaîne de caractères est habituellement terminée par un caractère NUL. Par exemple, la chaîne de caractères "Coucou !" occupe 9 octets car il y a un NUL implicite après le point d'exclamation indiquant la fin de la chaîne. NULL, par contre, est une valeur de pointeur dont vous pouvez être sûr qu'elle ne correspondra jamais à une adresse mémoire réelle dans votre programme. En C et en C++, NUL est représenté par la constante de caractère '0', ou (char) 0. La définition de NULL diffère selon le système d'exploitation; sous Linux, NULL est défini comme %%((void*)0)%% en C et tout simplement 0 en C++.

Dans la Section listeArgs, nous avons présenté un programme, Listing argcv, qui affichait sa liste d'arguments. En utilisant l'entrée cmdline du système de fichiers /proc, nous pouvons créer un programme qui affiche la liste d'arguments d'un autre processus. Le Listing printarglist est un programme de ce type; il affiche la liste d'arguments du processus dont l'identifiant est passé en paramètre. Comme il peut y avoir plusieurs NUL dans le contenu de cmdline et non un seul en fin de chaîne, nous ne pouvons pas déterminer la taille de la chaîne en utilisant strlen (qui se contente de compter le nombre de caractères jusqu'à ce qu'elle rencontre un NUL). Au lieu de cela, nous déterminons la longueur de cmdline grâce à read, qui renvoie le nombre d'octets lus.

Affiche la Liste d'Arguments d'un Processus print-arg-list.c
Sélectionnez

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

/* Affiche la liste d'aguments, un par ligne, du processus dont l'identifiant 
   est passé en paramètre. */

void print_process_arg_list (pid_t pid)
{
  int fd;
  char filename[24];
  char arg_list[1024];
  size_t length;
  char* next_arg;

  /* Génère le nom du fichier cmdline pour le processus. */
  snprintf (filename, sizeof (filename), "/proc/%d/cmdline", (int) pid);
  /* Lit le contenu du fichier. */
  fd = open (filename, O_RDONLY);
  length = read (fd, arg_list, sizeof (arg_list));
  close (fd);
  /* read n'ajoute pas de NULL à la fin du tempon, nous le faisons ici. */
  arg_list[length] = '\0';

  /* Boucle sur les arguments. Ceux-ci sont séparés par des NUL. */
  next_arg = arg_list;
  while (next_arg < arg_list + length) {
    /* Affiche l'argument. Chaque argument est terminé par NUL, nous le
       traitons donc comme une chaîne classique. */
    printf ("%s\n", next_arg);
    /* Avance à l'argument suivant. Puisque chaque argument est terminé par
       NUL, strlen renvoie la longueur de l'argument, 
       pas celle de la liste. */
    next_arg += strlen (next_arg) + 1;
  }
}

int main (int argc, char* argv[])
{
  pid_t pid = (pid_t) atoi (argv[1]);
  print_process_arg_list (pid);
  return 0;
}

Par exemple, supposons que le processus 372 soit le démon de journalisation système, syslogd.

 
Sélectionnez

% ps 372
   PID TTY     STAT   TIME COMMAND
   372 ?       S      0:00 syslogd -m 0

% ./print-arg-list 372
syslogd
-m
0

Dans ce cas, syslogd a été invoqué avec les arguments -m 0.

7-2-3. Environnement de Processus

Le fichier environ contient l'environnement du processus (consultez la Section environnement, « L'Environnement »). Comme pour cmdline, les différentes variables d'environnement sont séparées par des NUL. Le format de chaque élément est le même que celui utilisé dans la variable environ, à savoir VARIABLE=valeur.

Le Listing printenvironment présente une généralisation du programme du Listing printenv de la Section environnement. Cette version prend un identifiant du processus sur la ligne de commande et affiche son environnement en le lisant à partir de /proc.

Affiche l'Environnement d'un Processus print-environment.c
Sélectionnez

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

/* Affiche l'environnement du processus dont l'identifiant est passé en
   paramètre, une variable par ligne. */

void print_process_environment (pid_t pid)
{
  int fd;
  char filename[24];
  char environment[8192];
  size_t length;
  char* next_var;

  /* Génère le nom du fichier environ pour le processus. */
  snprintf (filename, sizeof (filename), "/proc/%d/environ", (int) pid);
  /* Lit le contenu du fichier. */
  fd = open (filename, O_RDONLY);
  length = read (fd, environment, sizeof (environment));
  close (fd);
     /* read ne place pas de caractère NUL à la fin du tampon. */
  environment[length] = '\0';

  /* Boucle sur les variables. Elles sont séparées par des NUL. */
  next_var = environment;
  while (next_var < environment + length) {
    /* Affiche la variable. Elle est terminée par un NUL, on la traite
       donc comme une chaîne ordinaire. */
    printf ("%s\n", next_var);
    /* Passe à la variable suivante. Puisque chaque variable est terminée
       par un NUL, strlen calcule bien la taille de la prochaine variable,
       et non pas de toute la liste. */
    next_var += strlen (next_var) + 1;
  }
}
int main (int argc, char* argv[])
{
  pid_t pid = (pid_t) atoi (argv[1]);
  print_process_environment (pid);
  return 0;
}

7-2-4. Exécutable de Processus

L'entrée exe pointe vers le fichier binaire exécuté par le processus. Dans la Section listeArgs, nous avons expliqué que le nom de ce fichier est habituellement passé comme premier élément de la liste d'argument. Notez cependant qu'il s'agit d'une convention; un programme peut être invoqué avec n'importe quelle liste d'arguments. Utiliser l'entrée exe du système de fichiers /proc est une façon plus fiable de déterminer le fichier binaire en cours d'exécution.

De même, il est possible d'extraire l'emplacement absolu de l'exécutable, à partir du système de fichiers /proc. Pour beaucoup de programmes, les fichiers auxiliaires se trouvent dans des répertoires relatifs à l'exécutable, il est donc nécessaire de déterminer où se trouve réellement le fichier binaire. La fonction get_executable_path du Listing getexepath détermine le chemin du fichier binaire s'exécutant au sein du processus appelant en examinant le lien symbolique /proc/self/exe.

Obtient l'Emplacement du Fichier Binaire en Cours d'Exécution get-exe-path.c
Sélectionnez

#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

/* Recherche l'emplacement du fichier binaire en cours d'exécution.
   Ce chemin est placé dans BUFFER, de taille LEN. Renvoie le nombre de
   caractères dans le chemin ou -1 en cas d'erreur. */

size_t get_executable_path (char* buffer, size_t len)
{
  char* path_end;
  /* Lit la cible de /proc/self/exe. */
  if (readlink ("/proc/self/exe", buffer, len) <= 0)
    return -1;
  /* Recherche la dernière occurrence du caractère slash. */
  path_end = strrchr (buffer, "/");
  if (path_end == NULL)
    return -1;
  /* Se place sur le caractère suivant le dernier slash. */
  ++path_end;
  /* Récupère le répertoire contenant le programme en tronquant le chemin
     après le dernier slash. */
  *path_end = "\0";



  /* La longueur du chemin est le nombre de caractères
     jusqu'au dernier slash. */
  return (size_t) (path_end - buffer);
}

int main ()
{
  char path[PATH_MAX];
  get_executable_path (path, sizeof (path));
  printf ("ce programme se trouve dans le répertoire %s\n", path);
  return 0;
}

7-2-5. Descripteurs de Fichiers d'un Processus

Le répertoire fd contient des sous-répertoires correspondant aux descripteurs de fichiers ouverts par un processus. Chaque entrée est un lien symbolique vers le fichier ou le périphérique désigné par le descripteur de fichier. Vous pouvez lire ou écrire sur ces liens symboliques; cela revient à écrire ou à lire depuis le fichier ou le périphérique ouvert dans le processus cible. Les noms des entrées du sous-répertoire fd correspondent aux numéros des descripteurs de fichiers.

Voici une astuce amusante que vous pouvez essayer avec les entrées fd de /proc. Ouvrez une nouvelle fenêtre de terminal et récupérez l'identifiant de processus du processus shell enlançant ps.

 
Sélectionnez

% ps
  PID TTY       TIME CMD
 1261 pts/4 00:00:00 bash
 2455 pts/4 00:00:00 ps

Dans ce cas, le shell (bash) s'exécute au sein du processus 1261. Ouvrez maintenant une seconde fenêtre et jetez un oeil au contenu du sous-répertoire fd pour ce processus.

 
Sélectionnez

% ls -l /proc/1261/fd
total 0
lrwx------    1 samuel samuel 64 Jan 30 01:02 0 -> /dev/pts/4
lrwx------    1 samuel samuel 64 Jan 30 01:02 1 -> /dev/pts/4
lrwx------    1 samuel samuel 64 Jan 30 01:02 2 -> /dev/pts/4

(Il peut y avoir d'autres lignes correspondant à d'autres descripteurs de fichiers ouverts). Souvenez-vous de ce que nous avons dit dans la Section ESStandards, « E/S Standards » : les descripteurs de fichiers 0, 1 et 2 sont initialisés pour pointer vers l'entrée, la sortie et la sortie d'erreurs standards, respectivement. Donc, en écrivant dans le fichier /proc/1261/fd/1 vous pouvez écrire sur le périphérique attaché à stdout pour le processus shell -- dans ce cas, un pseudo TTY correspondant à la première fenêtre. Dans la seconde fenêtre, essayez d'écrire un message dans ce fichier:

 
Sélectionnez

% echo "Coucou." >> /proc/1261/fd/1

Le texte apparaît dans la première fenêtre.

Les descripteurs de fichiers autres que l'entrée, la sortie et la sortie d'erreurs standards apparaissent dans le sous-répertoire fd. Le Listing openandspin présente un programme qui se contente d'ouvrir un descripteur pointant vers un fichier passé sur la ligne de commande et de boucler indéfiniment.

Ouvre un Fichier en Lecture open-and-spin.c
Sélectionnez

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main (int argc, char* argv[])
{
  const char* const filename = argv[1];
  int fd = open (filename, O_RDONLY);
  printf ("dans le processus %d, le descripteur %d pointe vers %s\n",
          (int) getpid (), (int) fd, filename);
  while (1);
  return 0;
}

Essayez de le lancer dans une fenêtre:

 
Sélectionnez

% ./open-and-spin /etc/fstab
dans le processus 2570, le descripteur 3 pointe vers /etc/fstab

Dans une autre fenêtre, observez le contenu du sous-répertoire fd correspondant

à ce processus.

 
Sélectionnez

% ls -l /proc/2570/fd
total 0
lrwx------    1 samuel samuel 64 Jan 30 01:30 0 -> /dev/pts/2
lrwx------ 1 samuel samuel 64 Jan 30 01:30 1 -> /dev/pts/2
lrwx------ 1 samuel samuel 64 Jan 30 01:30 2 -> /dev/pts/2
lr-x------ 1 samuel samuel 64 Jan 30 01:30 3 -> /etc/fstab

Notez que l'entrée du descripteur de fichier 3 est liée au fichier /etc/fstab vers lequel pointe le descripteur.

Les descripteurs de fichiers peuvent pointer vers des sockets ou des tubes (consultez le Chapitre IPC pour plus d'informations). Dans un tel cas, la cible du lien symbolique correspondant au descripteur de fichier indiquera « socket » ou « pipe » au lieu de pointer vers un fichier ou un périphérique classique.

7-2-6. Statistiques Mémoire de Processus

L'entrée statm contient une liste de sept nombres, séparés par des espaces. Chaque valeur correspond au nombre de pages mémoire utilisées par le processus dans une catégorie donnée. Les voici , dans l'ordre:

  • Taille totale du processus.
  • Taille du processus résident en mémoire.
  • Mémoire partagée avec d'autres processus -- c'est-à-dire les pages mises en correspondance avec l'espace mémoire du processus et d'au moins un autre (comme les bibliothèques partagées ou les pages en copie à l'écriture non modifiées).
  • Taille du texte du processus -- c'est-à-dire la taille du code chargé.
  • Taille des bibliothèques partagées chargées pour le processus.
  • Mémoire utilisée pour la pile du processus.
  • Le nombre de pages modifiées par le programme.

7-2-7. Statistiques sur les Processus

L'entrée status contient un certain nombre d'informations à propos du processus, formatées de façon à être compréhensibles par un humain. Parmi ces informations on trouve l'identifiant du processus et de son père, les identifiants d'utilisateur et de groupe réel et effectif, l'utilisation mémoire et des masques binaires indiquant quels signaux sont interceptés, ignorés et bloqués.

7-3. Informations sur le Matériel

Plusieurs autres fichiers du système de fichiers /proc donnent accès à des informations sur le matériel. Bien qu'elles n'intéressent généralement que les administrateurs système, ces informations peuvent parfois être utiles aux programmeurs. Nous présenterons ici les plus utiles.

7-3-1. Informations sur le Processeur

Comme nous l'avons dit précédemment, /proc/cpuinfo contient des informations sur le ou les processeur(s) du système. Le champ Processor indique le numéro du processeur; il est à 0 sur un système monoprocesseur. Les champs Vendor, CPU Family, Model et Stepping vous permettent de déterminer le modèle et la révision exacts du processeur. Plus utile, le champ Flags indique quels indicateurs sont positionnés, ils indiquent les fonctionnalités disponibles pour processeur. Par exemple, mmx, indique que les instructions MMX(Reportez-vous au IA-32 Intel Architecture Software Developer's Manuel pour une documentation complète sur les instructions MMX, et consultez le Chapitre 9, « Code Assembleur en Ligne », dans ce livre pour plus d'informations sur leur utilisation au sein de programmes GNU/Linux.) sont disponibles.

La plupart des informations renvoyées par /proc/cpuinfo sont obtenues à partir de l'instruction assembleur x86 cpuid. Il s'agit d'un mécanisme de bas niveau permettant d'obtenir des informations sur le processeur. Pour mieux comprendre l'affichage de /proc/cpuinfo, consultez la documentation de l'instruction cpuid dans le IA-32 Intel Architecture Software Developer's Manual, Volume 2: Instruction Set Reference d'Intel (en anglais). Ce manuel est disponible sur http://developer.intel.com/design.

Le dernier champ, bogomips, est une valeur propre à Linux. Il s'agit d'un indicateur de la vitesse du processeur mesurée au moyen d'une boucle et qui est donc relativement mauvais.

7-3-2. Informations sur les Périphériques

Le fichier /proc/devices dresse la liste des numéros de périphérique majeurs pour les périphériques caractères et bloc disponibles pour le système. Consultez le Chapitre peripheriques, « Périphériques », pour plus d'informations sur les types de périphériques et leurs numéros.

7-3-3. Informations sur le Bus PCI

Le fichier /proc/pci donne un aperçu des périphériques attachés au(x) bus PCI. Il s'agit de cartes d'extension PCI mais cela peut aussi inclure les périphériques intégrés à la carte mère ainsi que les cartes graphiques AGP. Le listing inclut le type de périphérique; son identifiant et son constructeur; son nom s'il est disponible; des informations sur ses capacités et sur les ressources PCI qu'il utilise.

7-3-4. Informations sur le Port Série

Le fichier /proc/tty/driver/serial contient des informations de configuration et des statistiques sur les ports série. Ceux-ci sont numérotés à partir de 0(Notez que sous DOS et Windows, les port série sont numérotés à partir de 1, donc COM1 correspond au port série 0 sous Linux.). Les informations de configuration sur les ports série peuvent également être obtenues, ainsi que modifiées, via la commande setserial. Cependant, /proc/tty/driver/serial contient des statistiques supplémentaires sur le nombre d'interruptions reçues par chaque port série.

Par exemple, cette ligne de /proc/tty/driver/serial pourrait décrire le port série 1 (qui serait COM2 sous Windows):

 
Sélectionnez

1: uart:16550A port:2F8 irq:3 baud:9600 tx:11 rx:0

Elle indique que le port série est géré par un USART (Universal Synchronous Asynchronous Receiver Transmitter) de type 16550, utilise le port 0x2f8 et l'IRQ 3 pour la communication et tourne à 9 600 bauds. Le port a reçu 11 interruptions d'émission et 0 interruption de réception.

Consultez la Section periphmat, « Périphériques Matériels » pour des informations sur les périphériques série.

7-4. Informations sur le Noyau

La plupart des entrées de /proc donnent accès à des informations sur la configuration et l'état du noyau en cours d'exécution. Certaines de ces entrées sont à la racine de /proc; d'autres se trouvent sous /proc/sys/kernel.

7-4-1. Informations de Version

Le fichier /proc/version contient une chaîne décrivant la version du noyau et donnant des informations sur sa compilation. Elle comprend également des informations sur la façon dont il a été compilé: par qui, sur quelle machine, quand et avec quel compilateur -- par exemple:

 
Sélectionnez

% cat /proc/version
Linux version 2.2.14-5.0 (root@porky.devel.redhat.com) (gcc version
egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)) #1 Tue Mar 7
21:07:39 EST 2000

Cette commande indique que le système s'exécute sur une version 2.2.14 du noyau Linux, compilé avec la version 1.1.2 de EGCS (EGC, l'Experimental GNU Compiler System, était un précurseur du projet GCC actuel).

Les informations les plus intéressantes de cet affichage, le nom de l'OS et la version et la révision du noyau, sont également disponibles dans des fichiers individuels de /proc. Il s'agit de /proc/sys/kernel/ostype, /proc/sys/kernel/osrelease et /proc/sys/kernel/version, respectivement.

 
Sélectionnez

% cat /proc/sys/kernel/ostype
Linux
% cat /proc/sys/kernel/osrelease
2.2.14-5.0
% cat /proc/sys/kernel/version
#1 Tue Mar 7 21:07:39 EST 2000

7-4-2. Noms d'Hôte et de Domaine

Les fichiers /proc/sys/kernel/hostname et /proc/sys/kernel/domainname contiennent les noms d'hôte et de domaine de l'ordinateur, respectivement. Ces informations sont les mêmes que celles renvoyées par l'appel système uname, décrit dans la Section 8.15.

7-4-3. Utilisation Mémoire

Le fichier /proc/meminfo contient des informations sur l'utilisation mémoire du système. Les informations sont présentées à la fois pour la mémoire physique et pour l'espace d'échange (swap). Les trois premières lignes présentent les totaux, en octets; les lignes suivantes reprennent ces informations en kilooctets -- par exemple:

 
Sélectionnez

% cat /proc/meminfo
        total:    used:    free: shared: buffers: cached:
Mem: 529694720 519610368 10084352 82612224 10977280 82108416
Swap: 271392768 44003328 227389440
MemTotal:    517280 kB
MemFree:       9848 kB
MemShared:    80676 kB
Buffers:      10720 kB
Cached:       80184 kB
BigTotal:         0 kB
BigFree:          0 kB
SwapTotal:   265032 kB
SwapFree:    222060 kB

Cet affichage montre un total de 512 Mo de mémoire physique, dont environ 9 Mo sont libres et 258 Mo d'espace d'échange (swap), dont 216 Mo sont libres. Dans la ligne correspondant à la mémoire physique, trois autres valeurs sont présentées:

  • La colonne Shared affiche la quantité de mémoire partagée actuellement allouée sur le système (consultez la Section memoirepartagee, « Mémoire Partagée »).
  • La colonne Buffers donne la mémoire allouée par Linux pour les tampons des périphériques bloc. Ces tampons sont utilisés par les pilotes de périphériques pour conserver les blocs de données lus ou écrits sur le disque.
  • La colonne Cached indique la mémoire allouée par Linux pour le cache de page. Cette mémoire est utilisée pour mettre en cache les accès à des fichiers mis en correspondance avec la mémoire.

Vous pouvez utiliser la commande free pour afficher les mêmes informations sur la mémoire.

7-5. Lecteurs et Systèmes de Fichiers

Le système de fichiers /proc contient également des informations sur les lecteurs de disques présents sur le système et les systèmes de fichiers montés qui y correspondent.

7-5-1. Systèmes de Fichiers

L'entrée /proc/filesystems dresse la liste de tous les types de systèmes de fichiers connus par le noyau. Notez qu'elle n'est pas très utile car elle n'est pas complète: des systèmes de fichiers peuvent être chargés et déchargés dynamiquement sous forme de modules noyau. Le contenu de /proc/filesystems ne reflète que les types de systèmes de fichiers liés statiquement au noyau ou actuellement chargés. D'autres types de systèmes de fichiers peuvent être disponibles sous forme de modules mais ne pas être chargés.

7-5-2. Lecteurs et Partitions

Le système de fichiers /proc donne également des informations sur les périphériques connectés aux contrôleurs IDE ou SCSI (si le système en dispose).

Sur un système classique, le répertoire /proc/ide peut contenir un ou deux sous-répertoires, ide0 et ide1, relatifs aux contrôleurs primaire et secondaire du système(S'il est correctement configuré, le noyau Linux peut prendre en charge des contrôleurs IDE supplémentaires. Ils sont numérotés de façon séquentielle à partir de ide2.). Ils contiennent d'autres sous-répertoires correspondants aux périphériques physiques connectés à ces contrôleurs. Les répertoires de chaque contrôleur ou périphérique peuvent être absents si Linux n'a détecté aucun périphérique connecté. Les chemins absolus des quatre périphériques IDE possibles sont présentés dans le Tableau periphide.

Chemins Absolus des Quatre Périphériques IDE Possibles

Contrôleur Périphérique Répertoire
Primaire Maître /proc/ide/ide0/hda/
Primaire Esclave /proc/ide/ide0/hdb/
Secondaire Maître /proc/ide/ide1/hdc/
Secondaire Esclave /proc/ide/ide1/hdd/

Consultez la Section periphmat, « Périphériques Matériels », pour plus d'informations sur les noms des périphériques IDE.

Chaque répertoire de périphérique IDE contient plusieurs entrées donnant accès à des informations d'identification et de configuration sur le périphérique. Voici les plus utiles:

  • model contient la chaîne d'identification du modèle de périphérique.
  • media donne le type de média lu par le périphérique. Les valeurs possibles sont disk, cdrom, tape (cassette), floppy (disquette) et UNKNOWN (inconnu).
  • capacity indique la capacité du périphérique en blocs de 512 octets. Notez que pour les lecteurs de CD-ROM, cette valeur sera 2<sup>31</sup>-1, et non pas la capacité du disque présent dans le lecteur. La valeur de capacity représente la capacité total du disque physique; la capacité des systèmes de fichiers contenus dans les partitions du disque sera plus petite.

Par exemple, ces commandes vous montrent comment déterminer le type de média et le périphérique primaire connecté au contrôleur IDE secondaire. Dans ce cas, il s'agit d'un lecteur CD-ROM Toshiba.

 
Sélectionnez

% cat /proc/ide/ide1/hdc/media
cdrom
% cat /proc/ide/ide1/hdc/model
TOSHIBA CD-ROM XM-6702B

Si des périphériques SCSI sont présents, /proc/scsi/scsi contient la liste de leurs identifiants. Par exemple, son contenu peut ressembler à cela:

 
Sélectionnez

% cat /proc/scsi/scsi
Attached devices:
Host: scsi0 Channel: 00 Id: 00 Lun: 00
  Vendor: QUANTUM Model: ATLAS_V%%__%%9_WLS Rev: 0230
  Type:   Direct-Access                 ANSI SCSI revision: 03
Host: scsi0 Channel: 00 Id: 04 Lun: 00
  Vendor: QUANTUM Model: QM39100TD-SW   Rev: N491
  Type:   Direct-Access                 ANSI SCSI revision: 02

Cet ordinateur contient un contrôleur SCSI simple canal (appelé scsi0), auquel sont connectés deux disques Quantum, avec les identifiants de périphérique SCSI 0 et 4.

Le fichier /proc/partitions contient des informations sur les partitions des lecteurs de disque reconnus. Pour chaque partition, il décrit les numéros de périphérique majeur et mineur, le nombre de blocs de 1024 octets qu'elle contient et le nom du périphérique correspondant à cette partition.

L'entrée /proc/sys/dev/cdrom/info donne diverses informations sur les fonctionnalités des lecteurs CD-ROM. Les informations n'ont pas besoin d'explication.

 
Sélectionnez

% cat /proc/sys/dev/cdrom/info
CD-ROM information, Id: cdrom.c 2.56 1999/09/09

drive name: hdc
drive speed: 48
drive # of slots: 0
Can close tray: 1
Can open tray: 1
Can lock tray: 1
Can change speed: 1
Can select disk: 0
Can read multisession:  1
Can read MCN: 1
Reports media changed:  1
Can play audio: 1

7-5-3. Points de Montage

Le fichier /proc/mounts donne un aperçu des systèmes de fichiers montés. Chaque ligne correspond à un descripteur de montage et donne le périphérique monté, le point de montage et d'autres informations. Notez que /proc/mounts contient les mêmes informations que le fichier traditionnel /etc/mtab, qui est automatiquement mis à jour par la commande mount.

Voici les différents éléments d'un descripteur de point de montage:

  • Le premier élément de la ligne est le périphérique monté (consultez le autoref{chap:peripheriques}).
  • Le second élément est le point de montage, l'emplacement dans le système de fichiers racine où le contenu du système de fichiers apparaît. Pour le système de fichiers racine lui-même, le point de montage est /. Pour les espaces d'échange, le point de montage est noté swap.
  • Le troisième élément est le type de système de fichiers. Actuellement, la plupart des systèmes GNU/Linux utilisent le système de fichiers ext2 (ou ext3) pour les lecteurs de disques, mais des disques DOS ou Windows peuvent être montés et seront alors de type fat ou vfat. La plupart des CD-ROM sont au format iso9660. Consultez la page de manuel de la commande mount pour une liste des types de systèmes de fichiers.

Les deux derniers éléments des lignes de /proc/mounts sont toujours à 0 et n'ont pas de signification.

Consultez la page de manuel de fstab pour plus de détail sur le format des descripteurs de point de montage(Le fichier /etc/fstab décrit la configuration des points de montage statiques d'un système GNU/Linux.). GNU/Linux dispose de fonction destinées à vous aider à analyser ces descripteurs; consultez la page de manuel de la fonction getmntent pour plus d'informations sur leur utilisation.

7-5-4. Verrous

La Section 8.3, « fcntl : Verrous et Autres Opérations sur les Fichiers », décrit l'utilisation de l'appel système fcntl pour manipuler des verrous en lecture ou en écriture sur les fichiers. Le fichier /proc/locks décrit tous les verrous de fichiers actuellement en place sur le système. Chaque ligne correspond à un verrou.

Pour les verrous créés avec fcntl, les deux premières mentions de la ligne sont POSIX ADVISORY. La troisième est WRITE ou READ, selon le type de verrou. Le nombre qui suit les l'identifiant du processus possédant le verrou. Les trois chiffres suivants, séparés par deux-points, sont les numéros de périphérique majeur et mineur du périphérique sur lequel se trouve le fichier et le numéro d'inode, qui situe le fichier dans le système de fichiers. Le reste de la ligne est constitué de valeurs utilisées en interne par le noyau et qui ne sont généralement d'aucune utilité.

Traduire le contenu de /proc/locks en informations utiles demande un petit travail d'investigation. Vous pouvez observer l'évolution de /proc/locks en exécutant le programme du Listing 8.2 qui crée un verrou en lecture sur le fichier /tmp/test-file.

 
Sélectionnez

% touch /tmp/test-file
% ./lock-file /tmp/test-file
fichier /tmp/test-file
ouverture de /tmp/test-file
verrouillage
verrouillé ; appuyez sur entrée pour déverrouiller...

Dans une autre fenêtre, observez le contenu de /proc/locks.

 
Sélectionnez

% cat /proc/locks
1: POSIX ADVISORY WRITE 5467 08:05:181288 0 2147483647 d1b5f740 00000000
dfea7d40 00000000 00000000

Il peut y avoir des lignes supplémentaires si d'autres programmes ont posé des verrous. Dans notre cas, 5467 est l'identifiant de processus du programme lock-file. Utilisez ps pour observer ce qu'est en train d'exécuter ce processus.

 
Sélectionnez

% ps 5467
  PID TTY    STAT TIME COMMAND
 5467 pts/28 S    0:00 ./lock-file /tmp/test-file

Le fichier verrouillé, /tmp/test-file, se trouve sur le périphérique avec les numéros majeur et mineur 8 et 5, respectivement. Ces nombres correspondent à /dev/sda5.

 
Sélectionnez

% df /tmp
Filesystem           1k-blocks    Used Available Use% Mounted on
/dev/sda5              8459764 5094292   2935736 63% /
% ls -l /dev/sda5
brw-rw----    1 root     disk     8,   5 May  5  1998 /dev/sda5

Le fichier /tmp/test-file se trouve au niveau de l'inode 181 288 sur ce périphérique.

 
Sélectionnez

% ls --inode /tmp/test-file
 181288 /tmp/test-file

Consultez la Section noperiph, « Numéros de Périphérique » pour plus d'informations sur ceux-ci.

7-6. Statistiques Système

Deux entrées de /proc contiennent des statistiques utiles sur le système. Le fichier /proc/loadavg donne des informations sur sa charge. Les trois premiers nombres représentent le nombre de tâches actives sur le système -- processus en cours d'exécution -- avec une moyenne sur les 1, 5 et 15 dernières minutes. Le chiffre suivant indique le nombre courant de tâches exécutables -- processus programmés pour être exécutés, à l'opposé de ceux bloqués dans un appel système -- et le nombre total de processus sur le système. Le dernier champ correspond à l'identifiant du processus ayant eu la main le plus récemment.

Le fichier /proc/uptime contient le temps écoulé depuis le démarrage du système, ainsi que la durée pendant laquelle le système a été inactif. Ces deux valeurs sont données sous forme décimale, en secondes.

 
Sélectionnez

% cat /proc/uptime
3248936.18 3072330.49

Le programme du Listing printuptime extrait le temps depuis lequel le système est démarré ainsi que sa durée d'inactivité et les affiche de façon lisible.

Affiche des Informations sur les Temps Système print-uptime.c
Sélectionnez
#include <stdio.h>

/* Affiche une durée sur la sortie standard de façon lisible. TIME est la 
   durée, en secondes, et LABEL est une légende courte. */

void print_time (char* label, long time)
{
  /* Constantes de conversion. */
  const long minute = 60;
  const long hour = minute * 60;
  const long day = hour * 24;
  /* Affiche la durée. */
  printf ("%s: %ld jours, %ld: ld: ld\n", label, time / day,
          (time % day) / hour, (time % hour) / minute, time % minute);
}

int main ()
{
  FILE* fp;
  double uptime, idle_time;
  /* Lit le temps écoulé depuis le démarrage et le temps d'inactivité à
     partir de /proc/uptime. */
  fp = fopen ("/proc/uptime", "r");
  fscanf (fp, "%lf %lf\n", &uptime, &idle_time);
  fclose (fp);
  /* L'affiche. */
  print_time ("Temps écoulé depuis le démarrage ", (long) uptime);
  print_time ("Temps d'inactivité               ", (long) idle_time);
  return 0;
}

La commande uptime et l'appel système sysinfo (décrit dans la Section 8.14, « sysinfo : Obtenir des Statistiques Système ») permettent également d'obtenir le temps écoulé depuis le démarrage. La commande uptime affiche également les moyennes de charge système contenues dans /proc/loadavg.


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Copyright © 2007 Mark Mitchell, Jeffrey Oldham et Alex Samuel. Ce document ne peut être distribué que dans le respect des termes et conditions définies par l?Open Poublication License, v1.0 ou ultérieure (la dernière version est disponible sur http://www.opencontent.org/openpub/).