TP1 : File Hierarchy Standard

Dans un système Linux, les fichiers sont organisés selon une arborescence bien précise. Elle suit effectivement le standard FHS (File Hierarchy Standard). Cette partie du TP est totalement inspiré du standard FHS (document à consulter absolument)

Nous pouvons grossièrement classer les répertoires d'après le fait que les fichiers soient partageables (ou pas) ou statiques (ou dynamique) :
Partageable Non partageable
Statiques /usr
/opt
/etc
/boot
Variables (ou dynamiques) /var/mail /var/run
/var/lock

Le noyau Linux fournit un mécanisme qui donne accès via une arborescence de fichiers aux informations internes du noyau et en permet la modification pendant son exécution grâce au système de fichiers /proc.

Le système de fichiers /proc est un mécanisme qui est utilisé par le noyau et ses modules pour communiquer des informations concernant processus. Il permet d'interagir avec les structures de données internes du noyau, d'acquérir des informations utiles sur les processus, et de changer certains paramètres du noyau à la volée. A la différence des autres systèmes de fichiers, /proc est stocké en mémoire plutôt que sur disque.

Si l'on exécute une commande « Is -l » sur /proc, on voit que la plupart des fichiers ont une longueur nulle. Cependant, quand le fichier est visualisé, on aperçoit un certain nombre d'informations. Cela est possible car /proc s'inscrit dans la couche système de fichier virtuel (VFS). En revanche, lorsque « VFS » fait des appels d'inodes adressant des fichiers/répertoires au système de fichiers /proc, ce dernier en réalité crée ces fichiers/répertoires à partir des informations contenues dans le noyau.

Exemple
$ file /proc/cpuinfo
L'exécution de cette commande vous montre que le fichier n'existe pas et pourtant... :
$ cat /proc/cpuinfo
Vous donne bien un ensemble d'informations relatives au CPU.

Le système de fichier /proc permet de rassembler des informations utiles sur le système et le fonctionnement du noyau. Voici un certain nombre de fichiers importants :

Il y a, bien évidemment, beaucoup plus de fichiers que ceux énumérés plus haut. Vous pouvez faire appel à la commande « more » pour scruter chaque fichier du répertoire /proc.

Le système de fichiers /proc peut servir à consulter les informations relatives aux processus en cours d'exécution. Le répertoire /proc contient des sous-répertoires numérotés qui correspondent au numéro d'identification des processus (PID). Ainsi, pour chaque processus en cours d'exécution, il y a un sous-répertoire de /proc qui porte comme nom, le PID de chaque processus. Ces sous-répertoires contiennent des fichiers qui fournissent chacun des détails concernant l'état actuel et l'environnement d'un processus.

$ ps -aef | grep firefox
hntran 21907 4962 36 17:07 tty2 00:00:04 /usr/lib/firefox/firefox

La commande ci-dessus montre qu'il y a un processus en cours de Mozilla avec le PID 21907. Par correspondance, il devrait exister un sous-répertoire dans /proc portant le numéro 21907.

$ ll /proc/21907
        
-r--r--r--   1 hntran hntran 0 sept. 10 17:08 cmdline
-rw-r--r--   1 hntran hntran 0 sept. 10 17:09 comm
-rw-r--r--   1 hntran hntran 0 sept. 10 17:09 coredump_filter
-r--r--r--   1 hntran hntran 0 sept. 10 17:09 cpuset
lrwxrwxrwx   1 hntran hntran 0 sept. 10 17:09 cwd -> /home/hntran/
-r--------   1 hntran hntran 0 sept. 10 17:09 environ
lrwxrwxrwx   1 hntran hntran 0 sept. 10 17:08 exe -> /usr/lib/firefox/firefox*
-rw-r--r--   1 hntran hntran 0 sept. 10 17:09 gid_map
-r--------   1 hntran hntran 0 sept. 10 17:09 io
-r--r--r--   1 hntran hntran 0 sept. 10 17:08 limits
-rw-r--r--   1 hntran hntran 0 sept. 10 17:09 loginuid
-r--r--r--   1 hntran hntran 0 sept. 10 17:08 maps
-rw-------   1 hntran hntran 0 sept. 10 17:09 mem
-r--r--r--   1 hntran hntran 0 sept. 10 17:08 mountinfo
-r--r--r--   1 hntran hntran 0 sept. 10 17:09 mounts
-r--------   1 hntran hntran 0 sept. 10 17:09 mountstats
-r--r--r--   1 hntran hntran 0 sept. 10 17:09 numa_maps
-rw-r--r--   1 hntran hntran 0 sept. 10 17:09 oom_adj
-r--r--r--   1 hntran hntran 0 sept. 10 17:09 oom_score
-rw-r--r--   1 hntran hntran 0 sept. 10 17:09 oom_score_adj
-r--------   1 hntran hntran 0 sept. 10 17:09 pagemap
-r--------   1 hntran hntran 0 sept. 10 17:09 patch_state
-r--------   1 hntran hntran 0 sept. 10 17:09 personality
-rw-r--r--   1 hntran hntran 0 sept. 10 17:09 projid_map
lrwxrwxrwx   1 hntran hntran 0 sept. 10 17:08 root -> //
-rw-r--r--   1 hntran hntran 0 sept. 10 17:09 sched
-r--r--r--   1 hntran hntran 0 sept. 10 17:09 schedstat
-r--r--r--   1 hntran hntran 0 sept. 10 17:09 sessionid
-rw-r--r--   1 hntran hntran 0 sept. 10 17:09 setgroups
-r--r--r--   1 hntran hntran 0 sept. 10 17:09 smaps
-r--r--r--   1 hntran hntran 0 sept. 10 17:09 smaps_rollup
-r--------   1 hntran hntran 0 sept. 10 17:09 stack
-r--r--r--   1 hntran hntran 0 sept. 10 17:08 stat
-r--r--r--   1 hntran hntran 0 sept. 10 17:09 statm
-r--r--r--   1 hntran hntran 0 sept. 10 17:08 status
        
    

Le fichier « cmdline » contient la commande invoquée pour démarrer le processus. Les variables d'environnement du processus sont incluses dans le fichier « environ ». Le fichier « status » contient des informations actualisées sur l'état du processus. Parmi lesquelles, le numéro utilisateur (UID) et le numéro du groupe d'utilisateurs (GID) de l'utilisateur qui a lancé le processus, le numéro d'identification du processus parent (PPID) qui a instancié le PID, et l'état courant du processus « Sleeping » (dormant) ou « Running » (en cours). Dans chaque répertoire dédié à un processus se trouvent plusieurs liens symboliques. Ainsi « cwd » est le lien au répertoire courant de travail du processus, le lien « exe » pointe sur le programme en cours d'exécution par le processus, « root » est le lien du processus à son répertoire racine (normalement « / »). Le répertoire « fd » contient des liens aux descripteurs de fichiers utilisés par le processus.

/proc/self est un sous-répertoire intéressant, il facilite l'utilisation de /proc par un programme pour trouver des informations sur ses propres processus. La commande /proc/self est un lien symbolique au répertoire /proc qui correspond au processus accédant au répertoire /proc.

La plupart des fichiers /proc précédemment présentés sont accessibles uniquement en lecture. Toutefois, à l'intérieur du système de fichiers /proc il est prévu d'interagir avec le noyau à partir de fichiers en lecture/écriture.

L'écriture dans ces fichiers peut changer l'état du noyau, il faut les modifier avec beaucoup de précaution. Le répertoire /proc/sys est celui qui contient tous les fichiers en lecture/écriture ce qui permet de modifier le fonctionnement du noyau.

Pour plus de détails concernant le système de fichiers /proc : /usr/src/linux/Documentation/filesystems/proc.txt (une fois le code source installé)

Explorer le contenu du répertoire /proc en vous aidant de la documentation.

  1. Développez un programme permettant d'afficher les caractéristique de votre machine et système en vous appuyant sur le répertoire virtuel /proc. Votre programme devra afficher les informations suivantes :
  2. Ecrirez un programme qui, une fois démarré, lance un processus enfant par duplication (fork), puis se déplace dans le dossier parent (chdir). Les 2 processus afficheront les informations suivantes : PID, PPID, répertoire courant, utilisateur réel. Utilisez les appels systèmes getpid(), getppid(), chdir(), getcwd(), et getuid() pour récupérer ces informations.
  3. Ecrivez un programme qui prend en paramètre un numéro de pid et qui affiche pour ce processus :
  4. Regrouper le programme de la question 1) avec celui de la question 3) en utilisant les options de ligne de commande. Par exemple, si votre programme s’appelle « my_procinfo », pour déterminer les informations du CPU, vous pouvez utiliser l’option « -c », pour la mémoire « -m » et pour les processus, « -p [pid] ». Pour ce faire, vous utiliserez la fonction getopt(). (Voici un exemple : https://linuxprograms.wordpress.com/2012/06/22/c-getopt-example/)
  5. Bonus : Il s’agit dans cette partie d’explorer l’utilisation de la primitive ptrace() permettant de tracer un processus fils par son père et de connaître l’ensemble des appels systèmes réalisés par ce dernier. Pour ce faire, vous allez suivre un tutoriel (bien fait) sur Linux Journal et qui se trouve ici : https://www.linuxjournal.com/article/6100
    Pour ce tutoriel, il est demandé de faire le premier (interception de l’exec) et le second exemple (celui de l’interception de l’appel à write). Pour le second exemple, n’utilisez pas « /bin/ls » comme commande pour l’execl. A la place, vous pouvez créer votre programme qui écrit dans un fichier, le compiler séparément et y faire appel avec un execl (à la place du « /bin/ls »).