image titre avec un NAS Raspberry Pi et le titre de l'article : Script BASH pour éviter le blocage d'un NAS Raspberry Pi au démarrage en cas de défaillance d'un disque Publié le 16 avril 2022 - par

Éviter le blocage de votre Raspberry Pi en cas de défaillance d’un disque externe

Tristan est déjà intervenu sur le blog fin 2021. Le voici de retour avec cet article qui explique comment résoudre le problème d’un Raspberry Pi qui ne boote plus à cause de la défaillance d’un disque dur qui lui est relié. Je laisse volontiers la parole à Tristan (@BlindVador)

Éviter le blocage de votre Raspberry Pi en cas de défaillance d’un disque externe

Salut a toutes et tous!

Je reviens vers vous avec un petit bout de code tout bête en python, mais qui fait bien des miracles!

J’ai à la maison un NAS fait avec un Raspberry Pi et Samba, mon Pi me sert en temps normal a faire tourner octoPrint, mais le temps ou je ne m’en sert pas il fait aussi d’autres trucs, entre autre Samba.

Hors il y a peu j’ai eu une défaillance sur mon hub USB qui me permet d’alimenter les deux disques durs que j’emploie dans ma configuration.

Mon Pi s’est alors mis a tenter de booter en boucle sans y parvenir, finissant par s’éteindre, j’ai du retélécharger une distro linux (que je n’avais plus sous le coude…) flasher une carte SSD vide, éteindre le Pi, mettre la carte sSD dans le Pi, mettre ma carte habituelle dans le convertisseur SD vers USB, allumer le Pi, me connecter, brancher, tout ça pour aller commenter trois lignes dans /etc/fstab.

Je me suis dit qu’a l’avenir je voulais un système qui soit moins méchant avec ma pauvre framboise, j’aime pas la voir toute paniquée comme ça… alors il me faut un script qui tienne compte des conditions réelles, si un disque est défaillant ou si quelque chose ne va pas, soit on gère le problème soit on me demande de le gérer.

Pour rappel a ceux qui ne me connaissent pas, je suis totalement aveugle, faute de place sur mon Pi je n’ai pas le loisir d’y installer des logiciels de lecture d’écran, pour ne pas dégrader les performances, je n’ai aucun clavier de libre, je n’ai même pas un écran dans tout mon foutu labo pour brancher le Pi et demander a quelqu’un de regarder quand ça déconne, il faut que je me débrouille en SSH.
Donc moins je perds la connexion avec le Pi, mieux c’est. Voilà donc le script du jour.

Prérequis:

Comme dit je n’ai aucun écran, et se script doit de toute manière être exécuté par la crontab root, donc ne rien afficher a l’écran, pour changer un peu de nos habitudes, on va miser sur une sortie vocale via un TTS.

Si vous voulez que le rendu soit plus visuel, je vous invite a adapter le script a votre convenance. Pour ceux qui sont aventuriers, vous aurez besoin de:
espeak installé sur le Pi.
sudo apt-get install espeak
les voix de chez mbrola pour rendre ça un peu moins gerbant.
un périphérique audio branché et fonctionnel sur le Pi.

Un excellent article de François vous expliquera super bien comment faire parler votre Raspberry Pi, et ça vous sera souvent utile si à l’avenir vous lisez et utilisez mes script.
Nous aurons besoin de Python installé sur la machine également, (j’ai essayé de faire le script en bash mais ça m’a soulé, alors c’est du Python et c’est tout… 😀 )

Avant de débuter, se script est fait pour être adaptable facilement, il est lourdement commenté, je préfère toujours en dire trop que pas assez,  et pas juste balancer un bout de code comme ça et débrouillez vous avec ça.

Le script fonctionne selon un concept rudimentaire, on va tout simplement monter le disque, si le disque se monte bien, on le verra en récupérant la liste des éléments prévus au point de montage.
un dossier clean pour recevoir le montage du disque, ou il n’y a rien d’autre, histoire que lorsque votre disque est monté, le dossier soit rempli avec des données contenus sur le disque, si évidemment il y a d’autres trucs dans votre dossier point de montage, le script les détectera et croira que le disque est présent alors que non.
Un article du blog explique là encore très bien comment créer son NAS avec Samba et Raspberry Pi, je vous invite a le consulter.

Le script:

# — coding: utf-8 —

#on commence par importer le module os qui va nous permettre de
#faire d’une pierre deux coups, passer des comandes bash au pi et aussi
#lister les fichiers présents aux points de montage.
import os

#On prépare une variable qu’on appelera confirmed avec une valeur de 0
#a chaque fois qu’on confirmera qu’un disque est monté, on incrémentera
# sa valeur pour dire combien de disque sont
# présents sur le système actuellement;
confirmed=0

#La variable suivante détermine les paramètres de la voix que
# nous allons utilisé pour faire parler notre pi
# libre a chacun de les ajuster, changer la langue, (il faudra réécrire les messages)
# débit, hauteur… autant de paramètres qu’on peut avoir envie de modifier
# en une seule fois au lieu de parcourir tout le script.
# consultez l’aide de espeak pour trouver les différents paramètres utilisables.
# veuillez noter qu’a la fin entre le dernier paramètre et le guillemet il y a un espace
# ceci pour éviter toute anomalie lors de l’interprétation de la commande,
# veuillez conserver un espace entre
# le paramètre et le guillemet.
speaking_cmd= »espeak -v mb/mb-fr1 -s 140 « 

# décryptons un peu la ligne suivante.
# os.system() on fait appel a la method system du module os.
# system attend de nous comme paramètre une chaine de caractère
# représentant une commande a envoyer a l’interpréteur.
# juste après la ( on trouve speaking_cmd+ »\ »
# cette syntaxe un peu déconcertante viens du fait que on passe en paramètre une chaine
# de caractères qui est en fait le résultat de la concaténation de deux chaines
# speaking_cmd qui contient les paramètres et la commande espeak,
# + l’opérateur de concaténation,
#  » qui marque l’entrée dans la nouvelle chaine de caractère comprenant
# elle le message envoyer a espeak.
# vous noterez que la chaine commence par: \ » et se termine comme ça aussi.
# tout simplement parce que pour éviter toute incohérence lors du traitement de la commande
# espeak, il est préférable d’encadrer son texte avec des guillemets.

# ors, quelqu’un d’autre ici interprète les guillemets… python, pour éviter que python ne pense
# que les guillemets de la chaine de caractère sont pour lui et les traite, on les échappe;

os.system(speaking_cmd+ »\ »Vérification de la présence des disques pour le système nas.\ » »)

# on commence par monter un disque. adaptez le script selon combien vous en avez.
# on retrouve os.system, la chaine de caractère mount… qui représente la ligne de commande
# pour monter un disque sur un point de notre arborescence.
# adaptez le chemin de celle-ci selon votre propre besoin.
os.system(« mount /dev/sda1 /media/nas/nd1 »)

# ici on va tester une condition très simple pour vérifier si le disque qu’on vient
# de monter a bien été trouvé.
#on utilise la methode listdir de os en lui passant en paramètre un chemin
# vers le point de montage pour remonter la liste des fichiers présent dans le dossier.
# mais avant tout on récupère la longueur de cette dite liste,
# c’est pour cela qu’on obtient len(listdir(chemin))
# ou traduit en bon français
# longueur de la liste(liste du contenu de(chemin vers le point de montage))
# on obtient donc en sortie un integer qu’on va tester de ce pas pour vérifier s’il est égal a 0.
# si c’est 0, alors la liste est vide, et de fait il n’y a rien dans le dossier indiqué
# comme point de montage
# deux cas de figure alors, soit votre disque n’est pas monté, soit votre disque est vide.
# C’est une des limites de se système on présuppose que le disque n’est pas vide.
# pour détecter qu’il est bien là. Je n’ai pas trouvé après mes recherches d’autres méthodes
# pour détecter et confirmer la présence d’un disque

if(len(os.listdir(« /media/nas/nd1 »))==0):
disca_status= »Oups! le disque de sauvegarde semble être déconnecté… veuillez vérifier votre installation, puis réessayer. « 
else:
# si le disque a bien été détecté comme étant en ligne,
# alors on incrémente confirmed qui passe de 0 à 1,
# ceci pouvant par exemple permettre d’adapter le message a la fin du script
# pour savoir combien de disques tournent actuellement.
# notez que je nomme explicitement les disques, parce que c’est la fonction
# que je leur ai donné.
# adaptez ça a votre propre installation.
confirmed=confirmed+1
disca_status= »Disque de sauvegarde en ligne et paré! « 

# on reprend comme tout a l’heure, référez vous au commentaires explicatifs
# précédant le bloc d’instructions similaires.
# vous pouvez copier ces blocs selon le nombre de disques vous avez chez vous.
os.system(« mount /dev/sdb1 /media/nas/nd2 »)
if(len(os.listdir(« /media/nas/nd2 »))==0):
discb_status= »aïe! le disque principal de stockage semble être déconnecté. Veuillez vérifier votre installation, puis essayer a nouveau . »
else:
discb_status= »Le disque principal de stockage fonctionne selon des paramètres nominaux. »
confirmed=confirmed+1

# on teste si au moins un disque a bien été monté.
if(confirmed>0):
# si tel est le cas, alors on peu démarrer samba
os.system(« samba start »)
#on en profite pour faire dire a espeak un petit message qui récap
# combien de disque sont en ligne et ce qu’il se passe.
# Vous noterez cette fois que j’utilise str(confirmed) qui permet de convertir a la volée
# confirmed qui est un entier et donc pas concaténable avec une chaine
# en une chaine qui elle peut être utilisée.
os.system(speaking_cmd+ »\ » »+str(confirmed)+ »disques trouvé. « +disca_status+ » « +discb_status+ » Démarrage du NAS terminé.\ » »)
else:
os.system(speaking_cmd+ »\ »Aucun disque trouvé en ligne. Serveur NAS en attente, veuillez vérifier votre installation, puis réessayer.\ » »)

Le script sans les commentaires

Pour télécharger le script au format zip cliquez sur ce lien

Installer le script

pour que le script soit exécuté au démarage du raspberry, il faut éditer la crontab de l’utilisateur root. Pour ce faire, entrer:

sudo crontab -e

puis ajouter la ligne:

@reboot python /chemin/vers/le/fichier.py

faire ctrl x puis y et Entrée pour sauvegarder et rebooter le Raspberry Pi pour tester.

N’oubliez surtout pas le sudo avant crontab, sinon vous éditerez la crontab avec les privilèges standards et votre script nécessitant plusieurs autorisations superuser ne pourra pas s’executer normalement.

« 

Share Button

À propos blind_vador

Développeur web de formation (php et mysql) je m'interresse au python et à l'électronique. Je suis aussi aveugle à plains temps... du coup, bien obligé de trouver des astuces. Je tenterai de vous proposer des articles pour parler de comment le matériel grand publique peu nous permettre de contourner facilement des problèmes de la vie de tout les jours sans recourir à du matériel spécifique. Comment l'inovation technologique peu nous permettre de prendre notre autonomie sans passer par des milieux spécialisés qui on tendence à nous vider les poches.

2 réflexions au sujet de « Éviter le blocage de votre Raspberry Pi en cas de défaillance d’un disque externe »

  1. Ping : Éviter le blocage de votre Raspberry Pi en cas de défaillance d’un disque externe – Jhc Info

  2. blind_vador

    Hello.

     

    Je reviens ici pour dire que j’ai découvert une faiblaisse sur se script.

    j’ai pas eu des masses de temps pour m’en occuper, mais c’est un problème qu’il va me faloir corriger.

     

    En gros, régulièrement mon raspberry intervertie le disque 1 et le disque 2, alors dans se cas le nas fonctionne parfaitement mais du coup windows ne peu plus y accèder, c’est énervant parce que entre autre certaines machines ici on des racourcis qui pointe vers des dossier du nas pour simplifier l’accet a des documents partagés.

     

    Ce que je pense faire, c’est créer ma uellement sur le disque un fichier sans extention, dont le nom sera genre nd1. ou nd2.

    python recherchera la présence d’un des deux fichiers sur le disque et modifiera /etc/samba/smb.conf fonction de ce qu’il a trouvé…

    si quelqu’un vois une solussion pour fixer les disque sans intervertir leur point de montage ou sans risquer de bloquer le nas au démarage… je serais ravie… :d

     

    Merci encore a tous pour la lecture.

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.

Complétez ce captcha SVP *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.