Skip to content

Storage & Filesystem Hierarchy

Organisation des fichiers et gestion avancée du stockage.

Linux Filesystem Hierarchy


Filesystem Hierarchy Standard (FHS)

Répertoires Critiques pour l'Ops

Répertoire Contenu Criticité
/etc Configuration système Haute - Backuper régulièrement
/var Données variables (logs, BDD, mail) Haute - Peut grossir rapidement
/var/log Logs système et applicatifs Haute - Surveillance espace
/var/lib Données persistantes (Docker, MySQL) Haute - Ne pas supprimer
/tmp Fichiers temporaires (disque) Moyenne - Nettoyé au reboot
/run Runtime (RAM, tmpfs) Basse - Volatile
/usr Binaires et libs (read-only) Moyenne - Stable
/home Données utilisateurs Variable - Quotas recommandés
/opt Applications tierces Basse - Installations manuelles
/srv Données de services (web, ftp) Variable - Dépend de l'usage

SecNumCloud : Cloisonnement des Partitions

Recommandation ANSSI : Séparer les partitions critiques pour :

  1. Éviter la saturation de / - Un /var/log plein ne doit pas bloquer le système
  2. Sécuriser /tmp - Empêcher l'exécution de binaires malveillants
  3. Isoler /home - Protéger les données utilisateur

Schéma de partitionnement recommandé :

Partition Taille Options de montage
/ 20-50 Go defaults
/boot 1 Go defaults
/tmp 5-10 Go noexec,nosuid,nodev
/var 20+ Go defaults
/var/log 10+ Go defaults
/var/tmp 5 Go noexec,nosuid,nodev
/home Reste noexec,nosuid,nodev (optionnel)
swap 2-8 Go -

Exemple fstab sécurisé :

# /etc/fstab
/dev/mapper/vg0-tmp    /tmp      ext4  defaults,noexec,nosuid,nodev  0 2
/dev/mapper/vg0-var    /var      ext4  defaults                       0 2
/dev/mapper/vg0-home   /home     ext4  defaults,nosuid,nodev          0 2

Options de sécurité :

  • noexec : Interdit l'exécution de binaires
  • nosuid : Ignore les bits SUID/SGID
  • nodev : Ignore les fichiers de périphériques

Gestion des Disques Physiques

Commandes Essentielles

lsblk (Vision Arborescente)

lsblk

# Output:
NAME                  MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                     8:0    0   500G  0 disk
├─sda1                  8:1    0   512M  0 part /boot/efi
├─sda2                  8:2    0     1G  0 part /boot
└─sda3                  8:3    0 498.5G  0 part
  ├─vg0-root          253:0    0    50G  0 lvm  /
  ├─vg0-swap          253:1    0     8G  0 lvm  [SWAP]
  ├─vg0-var           253:2    0    50G  0 lvm  /var
  └─vg0-home          253:3    0   390G  0 lvm  /home
sdb                     8:16   0   200G  0 disk
└─sdb1                  8:17   0   200G  0 part
  └─vg0-home          253:3    0   390G  0 lvm  /home

# Avec infos filesystem
lsblk -f

blkid (UUID pour fstab)

blkid

# Output:
/dev/sda1: UUID="ABCD-1234" TYPE="vfat" PARTLABEL="EFI"
/dev/sda2: UUID="12345678-abcd-..." TYPE="ext4" PARTLABEL="boot"
/dev/mapper/vg0-root: UUID="87654321-..." TYPE="ext4"

# UUID d'un device spécifique
blkid /dev/sda1

# Utilisation dans fstab (plus fiable que /dev/sdX)
UUID=12345678-abcd-... /boot ext4 defaults 0 2

df (Espace Disque)

# Espace avec type de filesystem
df -hT

# Output:
Filesystem           Type   Size  Used Avail Use% Mounted on
/dev/mapper/vg0-root ext4    50G   15G   32G  32% /
/dev/mapper/vg0-var  ext4    50G   20G   28G  42% /var
/dev/mapper/vg0-home ext4   390G  150G  220G  41% /home
tmpfs                tmpfs  7.8G     0  7.8G   0% /dev/shm

# Trier par utilisation
df -hT | sort -k6 -h

Focus : Les Inodes

Disque \"plein\" avec de l'espace libre ?

Un filesystem a deux ressources limitées :

  1. Espace disque (octets)
  2. Inodes (métadonnées des fichiers)

Un inode est créé pour chaque fichier/répertoire. Même avec de l'espace libre, zéro inode = impossible de créer des fichiers.

# Vérifier les inodes
df -i

# Output:
Filesystem            Inodes   IUsed   IFree IUse% Mounted on
/dev/mapper/vg0-root 3276800  125000 3151800    4% /
/dev/mapper/vg0-var  3276800 3276800       0  100% /var   PROBLÈME!

Causes Typiques :

  • Millions de fichiers de session PHP (/var/lib/php/sessions/)
  • Cache applicatif non nettoyé
  • Logs rotationnés en milliers de fichiers
  • Maildir avec des millions de mails

Diagnostic :

# Trouver le répertoire avec le plus de fichiers
find /var -xdev -type f | cut -d "/" -f 2-3 | sort | uniq -c | sort -rn | head

# Compter les fichiers dans un répertoire
find /var/lib/php/sessions -type f | wc -l

# Fichiers créés ces dernières 24h
find /var -type f -mtime -1 | wc -l

Solutions :

# Nettoyer les sessions PHP
find /var/lib/php/sessions -type f -mtime +1 -delete

# Recreer le filesystem avec plus d'inodes (dernier recours)
mkfs.ext4 -N 10000000 /dev/sdb1   # 10M inodes

Focus : Le umask

Le umask (user file-creation mode mask) détermine les permissions par défaut d'un fichier ou d'un répertoire lors de sa création. C'est une mesure de sécurité préventive.

  • Permissions par défaut pour les fichiers : 666 (rw-rw-rw-)
  • Permissions par défaut pour les répertoires : 777 (rwxrwxrwx)

Le umask est un masque qui retire des permissions.

Calcul des permissions :

  • Pour les fichiers : 666 - umask (si le résultat donne un bit d'exécution, il est ignoré pour un fichier)
  • Pour les répertoires : 777 - umask

Exemple :

  • Si umask est 022 :
    • Fichier : 666 - 022 = 644 (rw-r--r--)
    • Répertoire : 777 - 022 = 755 (rwxr-xr-x)
  • Si umask est 077 (plus restrictif, souvent pour root) :
    • Fichier : 666 - 077 = 600 (rw-------)
    • Répertoire : 777 - 077 = 700 (rwx------)

Vérifier le umask actuel :

umask

# Output: 0022

Définir le umask :

Le umask est souvent défini dans les fichiers de configuration du shell (.bashrc, .profile, /etc/profile, /etc/bash.bashrc).

# Définir un umask plus restrictif (temporaire)
umask 077

# Pour le rendre permanent (par exemple dans .bashrc)
echo "umask 027" >> ~/.bashrc

Architecture du Stockage Linux (Storage Stack)

Comprendre comment une donnée traverse le kernel pour atteindre le disque.

flowchart TB
    A[Application (User Space)] -->|syscall: write| B[VFS (Virtual File System)]
    B -->|fichier| C[Filesystem (ext4, xfs, btrfs)]
    C -->|blocs| D[Block Layer (BIO)]

    subgraph "Block Layer"
    D --> E[I/O Scheduler]
    E --> F[Device Mapper (LVM, Crypt, RAID)]
    end

    F -->|requêtes| G[Driver (SCSI, NVMe, VirtIO)]
    G --> H[Disque Physique (Hardware)]

    style A fill:#9C27B0,stroke:#333,stroke-width:2px
    style B fill:#2196F3,stroke:#333,stroke-width:2px
    style H fill:#4CAF50,stroke:#333,stroke-width:2px

1. VFS (Virtual File System)

L'interface unifiée. L'application parle au VFS, qui redirige vers le bon driver (ext4, nfs, cifs). C'est ce qui permet de monter un disque USB (vfat) ou un partage réseau (nfs) sans changer le code de l'application.

2. I/O Schedulers (Ordonnanceurs)

Le "chef de gare" des écritures disque. Il optimise l'ordre des requêtes pour la performance.

Scheduler Cas d'Usage Description
mq-deadline Serveurs Database Priorise les lectures pour éviter la latence. Bon pour tout.
kyber NVMe Rapides Optimisé pour les SSD modernes ultra-rapides.
bfq Desktop / Copie Garantit une bonne réactivité interactive (évite le freeze pendant une copie).
none VM / Cloud Laisse l'hyperviseur gérer. Idéal pour EC2/Azure.

Vérifier et changer le scheduler :

# Voir le scheduler actuel (celui entre crochets)
cat /sys/block/sda/queue/scheduler
# [mq-deadline] kyber bfq none

# Changer à chaud (sans reboot)
echo "none" > /sys/block/sda/queue/scheduler


LVM (Logical Volume Manager)

Architecture LVM

flowchart TB
    subgraph "Disques Physiques"
        HD1["/dev/sda3<br/>500 Go"]
        HD2["/dev/sdb1<br/>200 Go"]
        HD3["/dev/sdc1<br/>500 Go"]
    end

    subgraph "Physical Volumes (PV)"
        PV1["pv: /dev/sda3"]
        PV2["pv: /dev/sdb1"]
        PV3["pv: /dev/sdc1"]
    end

    subgraph "Volume Group (VG)"
        VG["vg_data<br/>1.2 To total"]
    end

    subgraph "Logical Volumes (LV)"
        LV1["lv_root<br/>50 Go"]
        LV2["lv_var<br/>100 Go"]
        LV3["lv_home<br/>500 Go"]
        LV4["Free Space<br/>550 Go"]
    end

    subgraph "Filesystems"
        FS1["ext4 → /"]
        FS2["ext4 → /var"]
        FS3["xfs → /home"]
    end

    HD1 --> PV1
    HD2 --> PV2
    HD3 --> PV3
    PV1 --> VG
    PV2 --> VG
    PV3 --> VG
    VG --> LV1
    VG --> LV2
    VG --> LV3
    VG --> LV4
    LV1 --> FS1
    LV2 --> FS2
    LV3 --> FS3

Avantages de LVM

Avantage Description
Redimensionnement Agrandir/réduire les partitions à chaud
Agrégation Combiner plusieurs disques en un seul volume
Snapshots Sauvegardes instantanées
Migration Déplacer des données entre disques
Thin Provisioning Sur-allocation de l'espace

Cheatsheet LVM

Physical Volumes (PV)

# Lister les PV
pvs
pvdisplay

# Créer un PV
pvcreate /dev/sdb1

# Supprimer un PV (doit être vide)
pvremove /dev/sdb1

# Voir les détails
pvdisplay /dev/sdb1

Volume Groups (VG)

# Lister les VG
vgs
vgdisplay

# Créer un VG
vgcreate vg_data /dev/sdb1

# Ajouter un disque au VG (EXTENSION)
vgextend vg_data /dev/sdc1

# Retirer un disque du VG
vgreduce vg_data /dev/sdc1

# Voir les détails
vgdisplay vg_data

Logical Volumes (LV)

# Lister les LV
lvs
lvdisplay

# Créer un LV (taille fixe)
lvcreate -L 50G -n lv_data vg_data

# Créer un LV (% de l'espace libre)
lvcreate -l 100%FREE -n lv_data vg_data

# Agrandir un LV (ajouter 10 Go)
lvextend -L +10G /dev/vg_data/lv_data

# Agrandir un LV (utiliser tout l'espace libre)
lvextend -l +100%FREE /dev/vg_data/lv_data

# Réduire un LV (DANGER - voir procédure)
lvreduce -L 30G /dev/vg_data/lv_data

# Supprimer un LV
lvremove /dev/vg_data/lv_data

# Voir les détails
lvdisplay /dev/vg_data/lv_data

Procédure : Agrandir un Disque à Chaud

Scénario : /var est plein, on veut ajouter 20 Go.

Étape 1 : Vérifier l'Espace Disponible

# Espace libre dans le VG
vgs

# Output:
VG       #PV #LV #SN Attr   VSize    VFree
vg_data    2   4   0 wz--n- 700.00g  150.00g   150 Go libres

Étape 2 : Agrandir le LV

# Ajouter 20 Go au LV
sudo lvextend -L +20G /dev/vg_data/lv_var

# Ou utiliser tout l'espace libre
sudo lvextend -l +100%FREE /dev/vg_data/lv_var

Étape 3 : Agrandir le Filesystem

CRITIQUE : Le LV est agrandi, mais le filesystem ne le sait pas encore !

# Pour ext4 (à chaud, sans unmount)
sudo resize2fs /dev/vg_data/lv_var

# Pour XFS (à chaud, monté)
sudo xfs_growfs /var

# Vérifier
df -h /var

Raccourci : lvextend + resize en une commande

# L'option -r (resize) fait les deux étapes
sudo lvextend -L +20G -r /dev/vg_data/lv_var

Si Pas d'Espace dans le VG

# 1. Ajouter un nouveau disque physique
sudo pvcreate /dev/sdd1

# 2. L'ajouter au VG
sudo vgextend vg_data /dev/sdd1

# 3. Maintenant, agrandir le LV
sudo lvextend -L +20G -r /dev/vg_data/lv_var

Procédure : Réduire un LV (DANGER)

Réduire = Risque de Perte de Données

  • XFS ne peut pas être réduit (seulement agrandi)
  • ext4 doit être démonté pour réduction
  • Toujours faire un backup avant
# 1. Démonter
sudo umount /var

# 2. Vérifier le filesystem
sudo e2fsck -f /dev/vg_data/lv_var

# 3. Réduire le filesystem D'ABORD
sudo resize2fs /dev/vg_data/lv_var 30G

# 4. Réduire le LV
sudo lvreduce -L 30G /dev/vg_data/lv_var

# 5. Remonter
sudo mount /var

Swap

Rappel

La swap est une extension de la RAM sur disque.

Utilisations :

  • Éviter les crashs OOM (Out of Memory)
  • Hibernation (suspend-to-disk)
  • Décharger les pages mémoire inactives

Fichier Swap vs Partition

Aspect Fichier Swap Partition Swap
Flexibilité Facile à redimensionner Nécessite repartitionnement
Performance Légèrement inférieure Optimale
Création Simple (fallocate) Nécessite fdisk/parted
Recommandation Préféré pour flexibilité Installations initiales

Créer un Fichier Swap

# 1. Créer le fichier (4 Go)
sudo fallocate -l 4G /swapfile

# Alternative si fallocate échoue (btrfs)
sudo dd if=/dev/zero of=/swapfile bs=1M count=4096

# 2. Sécuriser les permissions
sudo chmod 600 /swapfile

# 3. Formater en swap
sudo mkswap /swapfile

# 4. Activer
sudo swapon /swapfile

# 5. Vérifier
swapon --show
free -h

# 6. Rendre permanent (ajouter à fstab)
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Modifier la Swap Existante

# Désactiver
sudo swapoff /swapfile

# Redimensionner (ex: 8 Go)
sudo fallocate -l 8G /swapfile
sudo mkswap /swapfile

# Réactiver
sudo swapon /swapfile

Swappiness

Contrôle l'agressivité du swap (0-100).

Valeur Comportement
0 Swap uniquement pour éviter OOM
10 Swap minimal (serveurs avec beaucoup de RAM)
60 Défaut Ubuntu
100 Swap agressif
# Voir la valeur actuelle
cat /proc/sys/vm/swappiness

# Modifier temporairement
sudo sysctl vm.swappiness=10

# Modifier définitivement
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf

Référence Rapide

# Disques
lsblk                              # Vue arborescente
lsblk -f                           # Avec filesystems
df -hT                             # Espace + type
df -i                              # Inodes
blkid                              # UUID

# LVM
pvs / vgs / lvs                    # Lister
pvcreate /dev/sdX                  # Créer PV
vgextend vg_name /dev/sdX          # Ajouter disque
lvextend -L +10G -r /dev/vg/lv     # Agrandir LV + FS

# Filesystem resize
resize2fs /dev/vg/lv               # ext4
xfs_growfs /mount/point            # xfs

# Swap
fallocate -l 4G /swapfile          # Créer fichier
mkswap /swapfile                   # Formater
swapon /swapfile                   # Activer
swapon --show                      # Vérifier

Voir aussi