27
avril 2015

Synology, lancer la sauvegarde automatiquement au branchement du disque dur USB

Au boulot on utilise un NAS Synology pour gérer nos sauvegardes externes mais aussi en prendre une copie sur un disque usb que j'emmène tout les soirs avec moi. Dans l'interface de DSM il est possible de définir une destination qui correspond à ce disque pour lui attribuer un plan de sauvegarde. Le problème est qu'il faut définir une heure de lancement ce qui m'arrange pas puisque j'y pense pas forcement tout de suite et puis si c'est pas moi qui le branche je ne veux pas que la personne est à ce connecter sur l'interface web... La solution : les règles udev.

 

Pour commencer il faut brancher votre disque sur le Synology, connectez-vous et aller dans "Sauvegarde et réplication", dans le menu de gauche sélectionnez "Destination de la sauvegarde" puis créez une nouvelle destination qui va correspondre à votre disque dur USB.


Créer une destination

Sur mon synology mon disque usb correspond à usbshare2. Donnez un nom à votre destination.

Dans la liste de gauche sélectionnez "Sauvegarder" puis créez une sauvegarde de type "Tâche de sauvegarde des données". Dans la liste déroulante choisissez le nom de la destination que vous avez créé à l'étape précédente.

Choisissez les répertoires à sauvegarder sur votre NAS

Paramétrez la sauvegarde de cette manière. Le champ "Répertoire" correspond au répertoire de destination sur votre disque USB.

 

Maintenant nous allons mettre en place la règle udev qui va vous permettre de lancer le plan de sauvegarde au branchement du disque dur USB. Vous devez vous connecter en ssh sur votre NAS, si vous ne savez pas faire aller sur cette page : http://blog.e-nnov.fr/synology-dsm/service-ssh/ et pour vous connectez depuis windows télécharger Putty : http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe.

Les règles udev sont stockés dans le répertoire /lib/udev/rules.d, mais avant il va nous falloir un peu d'informations sur votre disque. Nous allons utiliser la commande udevadm, l'idée est de récupérer le numéro de série de votre disque et d'autres informations de façon à appliquer la règle uniquement à ce disque.

Dabord le node utilisé par votre disque dur pour être utilisé par le système :

dmesg

[7255764.909797] scsi 70:0:0:0: Direct-Access     WD       Elements 10B8            1012 PQ: 0 ANSI: 6
[7255764.919927] sd 70:0:0:0: Attached scsi generic sg2 type 0
[7255764.922143] sd 70:0:0:0: [sdq] Spinning up disk.........ready
[7255770.980199] sd 70:0:0:0: [sdq] 3906963456 512-byte logical blocks: (2.00 TB/1.81 TiB)
[7255770.988745] sd 70:0:0:0: [sdq] Write Protect is off
[7255770.993828] sd 70:0:0:0: [sdq] Mode Sense: 47 00 10 08
[7255770.994373] sd 70:0:0:0: [sdq] No Caching mode page present
[7255771.000153] sd 70:0:0:0: [sdq] Assuming drive cache: write through
[7255771.008008] sd 70:0:0:0: [sdq] No Caching mode page present
[7255771.013792] sd 70:0:0:0: [sdq] Assuming drive cache: write through
[7255771.075722]  sdq: sdq1
[7255771.117117] sd 70:0:0:0: [sdq] No Caching mode page present
[7255771.122899] sd 70:0:0:0: [sdq] Assuming drive cache: write through
[7255771.129288] sd 70:0:0:0: [sdq] Attached SCSI disk

Mon disque est reconnu sur le node sdq, sdq1 est la parition du disque. Adaptez à votre installation. Un point important si vous branchez votre disque sur un autre port usb de votre Synology il sera reconnu sur un autre node donc il faut absolument le brancher sur le même port usb.

Maintenant udev :

udevadm info -a -p $(udevadm info -q path -n /dev/sdq)
...

  looking at parent device '/devices/pci0000:01/0000:01:00.0/usb4/4-2':
    KERNELS=="4-2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="80"
    ATTRS{bMaxPower}=="224mA"
    ATTRS{urbnum}=="4597082"
    ATTRS{idVendor}=="1058"
    ATTRS{idProduct}=="10b8"
    ATTRS{bcdDevice}=="1012"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="9"
    ATTRS{speed}=="5000"
    ATTRS{busnum}=="4"
    ATTRS{devnum}=="64"
    ATTRS{devpath}=="2"
    ATTRS{version}==" 3.00"
    ATTRS{maxchild}=="0"
    ATTRS{quirks}=="0x2"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="Western Digital"
    ATTRS{product}=="Elements 10B8"
    ATTRS{serial}=="575841314535344D434C3632"
...

Cette commande vous sort tout une liste de variables utilisables par udev, celles qui nous intéresse sont

ATTRS{idVendor}=="1058"
ATTRS{idProduct}=="10b8"    
ATTRS{serial}=="575841314535344D434C3632"

Aller dans le dossier /lib/udev/rules.d

cd /lib/udev/rules.d
vi 99-usb-backup-sdq.rules

99 correspond au niveau de priorités de la règle, plus le chiffre est grand et moins la règle est prioritaire. 99 permet de laisser toute les règles définit par Synology de s'éxecuter. Vi est l'éditeur de texte par défaut, pour entrer en mode insertion utiliser la touche i puis copier/coller ça dans votre fichier :

SUBSYSTEM!="block|scsi", GOTO="usb_end"
ENV{DEVTYPE}=="partition", GOTO="usb_end"
ACTION!="add", GOTO="usb_end"

ACTION=="add",ATTRS{busnum}!="",ATTRS{devnum}!="",ATTRS{idVendor}=="1058",ATTRS{idProduct}=="10b8",ATTRS{serial}=="575841314535344D434C3632",RUN+="/usr/syno/bin/synolocalbkp --backup -k 11"

LABEL="usb_end"

Adapter les valeurs ATTRS{idVendor}, ATTRS{idProduct} et  ATTRS{serial}=="..." par les valeurs que vous avez récupé avec la commande udevadm.

  • ACTION=="add" indique à udev que cette règle est uniquement dans le cas du banchement du disque dur.
  • RUN+="/usr/syno/bin/synolocalbkp --backup -k 11" est la commande utilisé par DSM pour lancer les plans de sauvegardes, -k 11 correspond au numéro du plan dans l'interface de DSM, pour moi c'est la 11eme de la liste.

Pour enregistrer utiliser la touche esc de votre clavier puis faite :

:wq

Puis la touche entrer.

Pour recharger les règles utilisez la commande

udevadm control --reload-rules

Ejectez votre disque puis débranchez / rebranchez le. Si tout va bien vous aller avoir des erreurs comme quoi il ne trouve pas la destination. C'est normal car la règle se lance avant que le système est totalement monté le disque dur. Nous allons devoir passer par un script intermédiaire.

Allez dans le répertoire /lib/udev/script

cd /lib/udev/script

Editer ou créer le fichier backup.sdq.sh

vi backup-sdq.sh

Taper sur la touche i pour entrer en modification puis copier / coller ce code

#!/bin/sh
/bin/sleep 10                                                       
MOUNT=`/bin/mount | /bin/grep sdq | /usr/bin/wc -l`                                                   
CHECK=`/bin/ps | /bin/grep synolocalbkp | grep -v grep | /usr/bin/wc -l`
                                                         
if [ $MOUNT -eq 1 ] && [ $CHECK -eq 0 ]                  
then                                                     
        /usr/syno/bin/synolocalbkp --backup -k 11          
fi

Taper sur la touche esc de votre clavier puis :

:wq

Puis la touche entrer.

Rendre votre script exécutable.

chmod 755 backup-sdq.sh

Ré-éditer votre règle udev et modifier la variable RUN

SUBSYSTEM!="block|scsi", GOTO="usb_end"
ENV{DEVTYPE}=="partition", GOTO="usb_end"
ACTION!="add", GOTO="usb_end"

ACTION=="add",ATTRS{busnum}!="",ATTRS{devnum}!="",ATTRS{idVendor}=="1058",ATTRS{idProduct}=="10b8",ATTRS{serial}=="575841314535344D434C3632",RUN+="/lib/udev/script/backup-sdq.sh"

LABEL="usb_end"

Sauvegarder votre fichier et recharger les règles udev

udevadm control --reload-rules

Il ne vous reste plus qu'à éjecter votre disque, le débrancher et le rebrancher.

Pour contrôler ce qui se passe vous pouvez utiliser la commande ps et chercher une ligne dans se genre

7110 root      3992 S    /bin/sh /lib/udev/script/backup-sdq.sh

Il y a deux contraintes :

  • la barre de progression n'apparait pas dans l'interface web donc penser à activer les notifications par mail pour savoir lorsque c'est fini.
  • si vous utilisez plusieurs disques dur vous aller devoir créer autant de plans de sauvegardes et autant de règles que de disque dur en adaptant le node utilisé votre Synology.

Administrateur système de métier mais surtout curieux de découvrir de nouvelles technos très orientées DIY. A mes heures perdues je fais de la photo avec toujours une petite envie d'intégrer des DIY sous forme de timelaps à base de raspberry.

5 commentaires

Insomniaque a dit

Dans les dernières versions d'udev, ton script de backup serait dans le même cgroups que le script initial. Tu ne pourras même plus le forker distinctement. Mais ça ne te concerne pas vraiment ici, c'est juste au cas où tu souhaites faire des règles udev similaires sur une distribution basée sur systemd.

L'UUID c'était surtout pour simplifier la règle udev et le montage avec "mount --uuid" mais je n'avais pas pris en compte que seuls les utilitaires busybox étaient présents. Le montage aurait été facile à vérifier avec blkid mais je ne sais plus à partir de quelle version de busybox la commande est disponible.
Tu n'aurais pas eu besoin de toucher au /etc/fstab.

Répondre

flipflip a dit

@Insomniaque : J'ai eu des problèmes de timeout mais avec le sleep, au début j'avais mis une valeur de 40s et effectivement je me prenais un timeout. Je suis passé à 10s ce qui est bien suffisant pour laisser le temps au système de monter le disque.

Ce matin je viens de brancher le disque à 10h25, il est 10h30 et le processus synolocalbkp tourne toujours mais pas de trace de mon script. Ce qui confirme le timeout mais comme synolocalbkp est un programme externe au script il n'est pas concerné par le timeout... Enfin c'est comme ça que j'interprète.

L'option -C n'existe pas sur la version de ps utilisé sur le Synology (c'est du busybox).

Pour grep -q c'est une bonne idée mais comme le disque peut avoir plusieurs partitions il faut connaitre à l'avance ou alors utiliser la syntaxe grep -q /dev/sdq[09] /procs/mounts mais je n'ai pas réussi à avoir un résultat ou alors j'ai pas compris comment marche cette option.

L'UUID... pourquoi pas mais je vois pas trop comment le récupérer sachant que je ne touche pas au fichier /etc/fstab ?

Répondre

Insomniaque a dit

udev est en effet très pratique mais il y a malheureusement des problèmes de timeout avec les dernières versions d'udev (couplées avec systemd). Tu risques de voir des processus longs (>120s) tués par systemd (comme ta sauvegarde). Je suis surpris que tu n'aies pas eu le cas.

Sinon en passant, tu peux simplifier ton script en utilisant directement: "ps -C synolocalbkp" ou "grep -q /dev/sdq /proc/mounts"

Pourquoi ne pas passer directement par le champ UUID pour reconnaître ta clé? Cela te permettra de brancher sur n'importe quelle prise USB à l'avenir.

Répondre

flipflip a dit

@benja : Merci Benja pour tes remarques, j'ai apporté les modifications que tu m'a indiqué.
1) corrigé
2) effectivement lorsque je fais un grep synolocalbkp il se retrouve c'est pour ça que j'ai utilisé le test -ge 1 sauf que j'ai inversé, c'est bien -lt qu'il faut utiliser
3) l'idée de la boucle est peut être plus propre mais tu ne teste pas si il n'y a pas déjà un backup qui tourne sauf à le mettre avant la boucle
3bis) j'y ai pensé mais j'ai pas eu plus le temps que ça de creuser cette partie.
4) corrigé

Répondre

benja a dit

Quelques remarques:
1) taper sur 'i' dans vi avant de coller. Idem, taper sur la touche 'ESC' avant de d'introduire ':wq' (basculement mode commande -> mode insertion -> mode commande).
2) '/bin/grep synolocalbkp' peut avantagement être remplacé par 'grep [s]ynolocalbkp' afin de ne pas comptabiliser le grep (sa commande contient la chaine "synolocalbkp"). Autre solution c'est d'utiliser un deuxième grep pour retirer la ligne contenant le processus grep: 'grep -v grep'. La logique du test $CHECK -ge 1 me semble douteuse aussi: tu semble vouloir lancer la commande que si tu as un process contenant cette chaine qui tourne déja (-ge = 'greater of equal')... Amha cela ne marche que parceque justement le grep se trouve lui même. Btw tu peux aussi combiner les deux conditions en une seule invocation de 'test' en utilisant -a, i.e. [ $MOUNT -eq 1 -a $CHECK -lt 1 ].
3) préfère faire une boucle avec un timeout au lieu de simplement attendre 10 secondes. Genre
MAX_RETRIES=30
while ! /bin/mount | grep -q /dev/sdq
do
if [ 0$NRETRIES -ge $MAX_RETRIES ]
then
exit 1
else
NRETRIES=`expr 0$NRETRIES + 1`
sleep 1
fi
done
3bis) essayer d'obtenir le nom du device via udev.. rajoute un "env > /tmp/liste_des_variables" dans ton script pour connaitre à coup sûr ses variables d’environnements, je parierais qu'udev renseigne déjà le nom du device... :) Ensuite remplace les occurrences de /dev/sdq par "$VARIABLE UDEV"... Dans le cas où tu voudrais tester ton script à la main tu peux: soit toi même positionner la bonne variable d’environnement avant de lancer ton script (i.e. VARIABLE_UDEV=/dev/sdq /path/to/backup_sdq.sh), ou bien ajouter ceci au début du script MADEVICE=${VARIABLEUDEV:-/dev/sdq}, ce qui défini la variable MADEVICE à VARIABLEUDEV si elle existe, à /dev/sdq sinon...
4) ton explication n'est pas conforme au fichier udev: c'est bien le script backup-sdq.sh qui est dans le RUN.

Répondre

Écrire un commentaire

Quelle est la quatrième lettre du mot chfos ? :

Synology, lancer la sauvegarde automatiquement au branchement du disque dur USB - Philippe Maladjian - Péripéties bucoliques d'un administrateur systèmes au royaume de la virtualisation, du stockage et accessoirement photographe à ses heures perdues