Le problème
Une partition de disque ne se monte pas après un démarrage du système, que le redémarrage ait été planifié ou non. Avant le redémarrage, la partition de disque était montée et fonctionnait correctement. Le disque s'est monté correctement après le redémarrage d'autres systèmes, mais ne fonctionne plus.
Ce comportement peut se produire quel que soit le type de système de fichiers sur la partition et n'est pas lié au type de système de fichiers. Des pannes de disques avec des systèmes de fichiers EXT4 ou OCFS2 ont été signalées, mais peuvent survenir avec n'importe quel type de système de fichiers.
Une entrée typique dans le fichier /etc/fstab pourrait ressembler à :
/dev/sda1 /mydir ext4 defaults 0 0 /dev/mapper/mpath2 /otherdir ocfs2 _netdev 0 0
ou diverses combinaisons de ceux-ci.
La solution
Les disques durs et les partitions sont adressés géographiquement sous Linux, selon leur position sur le bus et leur ordre de découverte. Les périphériques SAN sont particulièrement vulnérables aux changements dans l'ordre de découverte en raison des délais de redémarrage variables pour le SAN ou le client.
Les noms de fichiers sous Linux, généralement dans le répertoire /dev/, sont attribués dynamiquement à chaque démarrage du système. Au démarrage du noyau, chaque périphérique disponible est détecté et une notification est envoyée au sous-système UDEV (gestion des périphériques de l'espace utilisateur). En comparant les informations de l'identification de périphérique du noyau aux ensembles de règles UDEV dans le répertoire /etc/udev/rules.d, UDEV attribue un nom au périphérique et crée un nœud de périphérique tel que /dev/sda ou /dev/mapper/mpath1 afin que les applications peuvent accéder à l'appareil. Si le périphérique détecté est un périphérique structuré en blocs, il possède souvent des partitions contenant des systèmes de fichiers qui peuvent être montés conformément aux spécifications du fichier /etc/fstab.
Bien que Linux s'efforce de conserver le même nom de périphérique lors des redémarrages du système, des modifications de l'environnement externe peuvent affecter les choix de noms réels. Par exemple :la même partition SAN peut être /dev/sda sur un client, mais /dev/sdf sur un autre nœud de cluster, en fonction de l'ordre dans lequel chaque hôte a découvert le périphérique ou de la liaison multi-accès en premier. Un nœud découvre généralement ses périphériques dans le même ordre à chaque démarrage, mais cela n'est pas garanti. Une méthode pour garantir une identification persistante et prévisible de l'appareil est nécessaire.
Bien que Linux essaie de réattribuer le même nom de périphérique à chaque redémarrage, il n'y a pas une telle coordination entre les nœuds du cluster. Une partition qui apparaît de manière fiable comme /dev/sda1 sur un nœud de cluster pourrait facilement, et légitimement, apparaître de manière cohérente comme /dev/sdj sur un autre nœud de cluster. Cela peut rendre l'administration système à l'échelle du cluster plus difficile que nécessaire. La solution fournie ci-dessous s'applique également aux clusters où ce problème de redémarrage ne se produit pas.
D'autres techniques sont disponibles pour avoir un nom de périphérique persistant et prévisible. Ils sont présentés ci-dessous, par ordre de difficulté.
Montage par étiquette
De nombreux types de systèmes de fichiers prennent en charge l'association d'une chaîne arbitraire, ou étiquette, à chaque système de fichiers. Le système de fichiers EXT3 en est un exemple :
# /sbin/e2label /dev/sda5 /home
Il est courant de voir une entrée /etc/fstab similaire à celle-ci :
LABEL=/HOME /home auto defaults 0 0
pour localiser la partition de disque étiquetée /HOME, quel que soit le périphérique sur lequel elle apparaît.
Les systèmes de fichiers OCFS2 fournissent également une étiquette reconnaissable qui peut être utilisée de la même manière. Voir l'exemple OCFS2 ci-dessous pour savoir comment déterminer l'étiquette OCFS2.
Montage par UUID
De nombreux types de systèmes de fichiers attribuent un identificateur universel unique, ou UUID, à chaque partition de disque formatée. Les systèmes de fichiers EXT3 et OCFS2 en sont des exemples. L'UUID est généralement attribué automatiquement et les administrateurs système sont généralement découragés de modifier manuellement la valeur.
Sur un système de fichiers EXT3 et d'autres types, utilisez l'utilitaire blkid fourni dans le package RPM e2fsprogs. Pour notre exemple, la sortie ressemble à ceci :
# /sbin/blkid /dev/sda5 /dev/sda5: LABEL="/home" UUID="0c960108-7649-4d8c-a28c-2f75e2f906d3" SEC_TYPE="ext2" TYPE="ext3"
Notez que l'UUID est, à proprement parler, uniquement les chiffres hexadécimaux. Les caractères "-" sont simplement des signes de ponctuation à ignorer.
Sur un système de fichiers OCFS2, l'UUID est toujours signalé par l'utilitaire fsck.ocfs2. Cet utilitaire peut être utilisé en toute sécurité sur une partition de disque montée si le commutateur "-n" est utilisé pour garantir un test en lecture seule :
# /sbin/fsck.ocfs2 -n /dev/hda1 Checking OCFS2 filesystem in /dev/hda1: label: OCFS2 uuid: bc d0 de d0 58 ea 43 11 bd a9 e0 66 e6 cb 37 b4 number of blocks: 209632 bytes per block: 1024 number of clusters: 52408 bytes per cluster: 4096 max slots: 4 /dev/hda1 is clean. It will be checked after 20 additional mounts.
Encore une fois, notez que l'UUID proprement dit est une chaîne de chiffres hexadécimaux. Ici, ils sont ponctués d'espaces, mais le véritable UUID n'est que les chiffres. Pour obtenir uniquement l'UUID, un court programme awk(1) suffit :
# /sbin/fsck.ocfs2 -n /dev/hda1 | /bin/awk '/uuid/ { $1 = ""; gsub( / /, "" ); print }' bcd0ded058ea4311bda9e066e6cb37b4
Maintenant que nous avons l'UUID, une entrée /etc/fstab telle que celle-ci monterait les partitions EXT3 ou OCFS2 :
UUID=bcd0ded058ea4311bda9e066e6cb37b4 /ocfs2 ocfs2 _netdev 0 2 UUID=0c96010876494d8ca28c2f75e2f906d3 /home ext3 defaults 0 2
Étant donné que l'UUID est stocké dans la partition de disque elle-même, peu importe si le nom réel de l'appareil change, nous avons une méthode garantie persistante et prévisible pour y accéder.
Utilisation des ensembles de règles UDEV
Une autre méthode pour avoir des noms de périphériques persistants et prévisibles consiste à tirer parti du même service UDEV que celui utilisé par le noyau pour attribuer les noms de périphériques. Cela implique de créer une règle de correspondance UDEV qui utilise les attributs d'appareil pour identifier l'appareil, puis de créer un nœud d'appareil pour celui-ci. Souvent, la règle crée simplement un lien symbolique vers le nœud de périphérique de bas niveau réel attribué par le noyau.
Il s'agit de la technique utilisée pour implémenter les périphériques multivoies du mappeur de périphériques. Le noyau crée un périphérique /dev/dm-X; puis les règles UDEV et le démon multipathing créent un lien /dev/mpath/
Le type de nom de fichier /dev/mapper/ créé est contrôlé par le paramètre user_friendly_names du fichier /etc/multipath.conf. Le paramètre par défaut est :
default { user_friendly_names yes }
ce qui, curieusement, crée les noms /dev/mapper/mpathN totalement dénués de sens. En commentant cela, les noms de formulaire /dev/mapper/
Vous trouverez ci-dessous un exemple de règle de correspondance UDEV. La ligne commence par une série de prédicats ou d'expressions correspondantes ; ceux-ci sont marqués par les opérateurs "==". Si tous les prédicats correspondent à ceux du périphérique découvert, les actions indiquées par les clauses "=" sont prises.
SYSFS{vendor}=="iriver" SYSFS{model}=="T10" OWNER="user" MODE="0600" SYMLINK+="iriver%n"
Cet exemple crée le lien symbolique /dev/iriver0 lorsque le premier lecteur IRiver T10 est branché sur un port USB. Le périphérique appartiendra à l'utilisateur avec les autorisations d'accès aux fichiers 0600. Le sous-système USB remarque que le périphérique a été branché et notifie le noyau ; les attributs découverts sur le périphérique sont également transmis au noyau. Ces informations parviennent finalement au sous-système UDEV qui commence à lire les ensembles de règles dans /etc/udev/rules.d et à faire correspondre les attributs de l'appareil aux prédicats de chaque règle. Si tous les prédicats correspondent à une règle, toutes les actions spécifiées par cette règle sont exécutées.
La documentation sur le système UDEV, y compris la syntaxe pour écrire une règle UDEV, est disponible en ligne via la page de manuel udev.
La partie difficile de l'écriture d'une règle UDEV est de savoir quels attributs sont disponibles afin que le périphérique puisse être correctement identifié par la règle. L'utilitaire udevinfo affichera le nom du périphérique et les attributs disponibles pour la règle. Pour notre exemple, vérifier /var/log/messages montre que le périphérique IRiver a été détecté en tant que périphérique bloc et le nom /dev/sdb a été attribué. Maintenant, nous pouvons obtenir toutes les informations et attributs de l'appareil en regardant sous les informations système /block/sdb :
# /usr/bin/udevinfo -q all -p /block/sdb P: /block/sdb N: sdb S: disk/by-id/usb-iriver_T10 S: disk/by-path/pci-0000:00:07.2-usb-0:1:1.0-scsi-0:0:0:0 E: ID_VENDOR=iriver E: ID_MODEL=T10 E: ID_REVISION=1.00 E: ID_SERIAL=iriver_T10 E: ID_TYPE=disk E: ID_BUS=usb E: ID_PATH=pci-0000:00:07.2-usb-0:1:1.0-scsi-0:0:0:0Remarque que le chemin est relatif au répertoire /sys/, pas à la racine traditionnelle. Le nom de fichier complet serait /sys/block/sdb mais udevinfo assume la partie /sys.
Choisir l'ensemble minimal d'attributs peut être délicat, mais évitez la tentation de trop spécifier. Notre choix ici est d'utiliser le nom du fournisseur et le nom du modèle, mais tout ensemble d'attributs qui identifie le périphérique objet peut être utilisé. Une fois les prédicats et les actions choisis, placez vos règles dans leurs propres fichiers dans le répertoire /etc/udev/rules.d. Ne modifiez pas un ensemble de règles à partir de la distribution, sinon vos modifications pourraient être perdues lors de la mise à jour du package. Dans notre exemple, nous avons utilisé /etc/udev/rules.d/49-iriver.rules pour le nom de fichier.
Une fois votre règle UDEV en place, utilisez l'utilitaire udevtest pour simuler une exécution UDEV et montrer ce qui serait fait.