UDev
Sources
Objectif
Le but est d'utiliser UDEV pour :
- reconnaitre un disque dur (ou un quelconque périphérique de stockage) lorsqu'on le branche à l'ordinateur
- lancer un script qui va créer backup sur ce périphérique automatiquement
- prévenir l'utilisateur que le backup est en cours (boites de dialogue zenity + mail)
Pour ce faire il faudra :
- identifier le périphérique qui servira de support au backup
- créer les règles UDEV pour ce périphérique
- créer le script de backup automatique (utilisation de RSync)
Identification du périphérique de sauvegarde
Brancher le périphérique et lancer aussitôt la commande suivante dans un terminal
ordinateur:/home/user# dmesg
Vous devriez trouver des données sur le périphérique connecté ressemblant à ceci :
[ 1701.911387] usb 5-1: new high speed USB device using ehci_hcd and address 10
[ 1702.060525] usb 5-1: configuration #1 chosen from 1 choice
[ 1702.063465] scsi6 : SCSI emulation for USB Mass Storage devices
[ 1702.063465] usb-storage: device found at 10
[ 1702.063465] usb-storage: waiting for device to settle before scanning
[ 1702.063465] usb 5-1: New USB device found, idVendor=059f, idProduct=101a
[ 1702.063465] usb 5-1: New USB device strings: Mfr=10, Product=11, SerialNumber=3
[ 1702.063465] usb 5-1: Product: LaCie Hard Drive USB
[ 1702.063465] usb 5-1: Manufacturer: LaCie
[ 1702.063465] usb 5-1: SerialNumber: 00E0010223082
[ 1707.083907] usb-storage: device scan complete
[ 1707.083922] scsi 6:0:0:0: Direct-Access Hitachi HTS543225L9SA00 PQ: 0 ANSI: 2 CCS
Les informations qui vont particulièrement nous intéresser pour identifier le périphérique de manière unique seront les suivantes :
- Manufacturer: LaCie
- SerialNumber: 00E0010223082
Vous pouvez choisir d'autres informations, celles-ci m'ont personnellement suffit.
Ajout des règles locales à UDEV
Créer/modifier le fichier des règles locales :
# vim /etc/udev/rules.d/z99_local.rules
# Création d'un symlink /dev/backupdevice en plus du symlink std /dev/sd...
SUBSYSTEMS=="usb", ATTRS{serial}=="00E0010223082", ATTRS{manufacturer}=="LaCie", KERNEL=="sd[a-z]", NAME:="%k", SYMLINK:="backupdevice", OPTIONS="last_rule"
# Création d'un symlink pour la partition
SUBSYSTEMS=="usb", ATTRS{serial}=="00E0010223082", ATTRS{manufacturer}=="LaCie", ACTION=="add", KERNEL=="sd[a-z]1", SYMLINK:="backuppartition", GROUP:="users", NAME:="%k"
# Montage automatique du disque
SUBSYSTEMS=="usb", ATTRS{serial}=="00E0010223082", ATTRS{manufacturer}=="LaCie", ACTION=="add", KERNEL=="sd[a-z]1", RUN+="/bin/mount -t vfat -o user,umask=000,noauto /dev/%k /mnt/backup"
# Lancement du script de backup
SUBSYSTEMS=="usb", ATTRS{serial}=="00E0010223082", ATTRS{manufacturer}=="LaCie", ACTION=="add", KERNEL=="sd[a-z]1", RUN+="/home/user/bin/rsync/rsync_backup.sh", OPTIONS="last_rule"
NB : en cas d'utilisation de plusieurs disques (sauvegarde tournante) d'un même modèle, il est pratique d'utiliser les attributs "idVendor" et "idProduct" du périphérique USB obtenus avec un simple
lsusb (il est aussi possible d'ajouter le serial si besoin)
# Création d'un symlink /dev/backupdevice en plus du symlink std /dev/sd...
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1058", ATTRS{idProduct}=="0748", KERNEL=="sd[a-z]", NAME:="%k", SYMLINK:="backupdevice", OPTIONS="last_rule"
# Création d'un symlink pour la partition
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1058", ATTRS{idProduct}=="0748", ACTION=="add", KERNEL=="sd[a-z]1", SYMLINK:="backuppartition", GROUP:="users", NAME:="%k"
# Montage automatique du disque
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1058", ATTRS{idProduct}=="0748", ACTION=="add", KERNEL=="sd[a-z]1", RUN+="/bin/mount -t vfat -o user,umask=000,noauto /dev/%k /mnt/backup"
# Lancement du script de backup
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1058", ATTRS{idProduct}=="0748", ACTION=="add", KERNEL=="sd[a-z]1", RUN+="/home/user/bin/rsync/rsync_backup.sh", OPTIONS="last_rule"
Script de backup
#!/bin/sh
# Déclaration des variables entrant en option dans la commande rsync
USERNAME="user" # utilisateur (pour popups graphiques)
ORIGINPATH="/home/user/data" # chemin du répertoire à sauvegarder, d'origine
DESTMOUNTPOINT="/mnt/backup/" # point de montage du répertoire de destination
DESTREP="backupdir" # répertoire de destination de la sauvegarde
EMAIL="user@domain.fr"
# variables internes au script
RSYNC="/usr/bin/rsync"
DESTPATH=${DESTMOUNTPOINT}${DESTREP} # chemin du répertoire de destination de la sauvegarde
LOGFILE="/home/user/bin/rsync/rsync_${DESTREP}-result.log"
EMAIL_TITLE="Sauvegarde ${ORIGINPATH} vers ${DESTPATH}"
#-----------------------------------
# DEBUT SCRIPT
#-----------------------------------
# Trace du début de la sauvegarde dans le fichier de LOG
echo `date`" - DEBUT DE COPIE RSYNC de ${ORIGINPATH} vers ${DESTPATH}" > ${LOGFILE}
su - ${USERNAME} -c "DISPLAY=:0.0 zenity --info --text='Début de la sauvegarde \nde ${ORIGINPATH} \nvers ${DESTPATH} \n\nLogfile : ${LOGFILE}'"
# Envoi d'un mail pour prévenir du début de la sauvegarde
echo "la sauvegarde vient d etre lancee, un Email vous sera envoye lorsque celle ci sera finie et reussie" | mail -s "[RSync Notification - Start] ${EMAIL_TITLE}" ${EMAIL}
# Lancement de la sauvegarde
if [ -d ${DESTPATH} ]
then
$RSYNC -avz --delete-after ${ORIGINPATH} ${DESTPATH}/ 2>&1 >> ${LOGFILE}
# Liste des fichiers sur le repertoire de destination
echo ""
echo "Voici les données contenues dans le répertoire de destination:"
ls -l "${DESTPATH}"
echo ""
# Trace de la fin de sauvegarde dans le fichier de LOG
echo `date`" - FIN DE COPIE RSYNC" >> ${LOGFILE}
# Résultat par mail
if [ $? -eq 0 ]
then
STRMAIL="La sauvegarde de vos données est terminée, une trace a été laissée dans le fichier ${LOGFILE}."
STRMAILSUB="[RSync Notification - OK]"
else
STRMAIL="La sauvegarde a retourné une erreur <$?>, une trace a été laissée dans le fichier ${LOGFILE}.\nAide : http://www.delafond.org/traducmanfr/man/man1/rsync.1.html#lbAY."
STRMAILSUB="[RSync Notification - ERROR]"
fi
else
# Trace de la fin de sauvegarde dans le fichier de LOG
echo `date`" - COPIE RSYNC ABANDONNEE" >> ${LOGFILE}
# résultat par mail
STRMAIL="Sauvegarde abandonnée (répertoire de destination inexistant)."
STRMAILSUB="[RSync Notification - ABANDON]"
fi
# TRACE
echo ${STRMAIL}
su - ${USERNAME} -c "DISPLAY=:0.0 zenity --info --text='${STRMAIL}'"
echo ${STRMAIL} | mail -s "${STRMAILSUB} ${EMAIL_TITLE}" ${EMAIL_TITLE} ${EMAIL}
# synchronisation des données
sync
# =============================================================================================================================================================
# Demande de démontage du périphérique
# => on démonte automatiquement car sinon HAL retournera une erreur come quoi c'est pas lui qui a monté ce péiphérique
# => si on veut utiliser le disque après la sauvegarde il suffira de cliquer dessus sur l'IHM => HAL le montera => on pourra le démonter proprement ensuite
# =============================================================================================================================================================
#su - ${USERNAME} -c "DISPLAY=:0.0 zenity --question --text='Sauvegarde terminée, démonter le disque ?'"
#if [ $? = "0" ]
#then
# # démontage du volume externe à la fin de la sauvegarde
# echo "Démontage du disque ${DESTMOUNTPOINT}"
# umount ${DESTMOUNTPOINT}
#fi
# =============================================================================================================================================================
# Démontage automatique du périphérique
echo "Démontage du disque ${DESTMOUNTPOINT}"
umount ${DESTMOUNTPOINT}
su - ${USERNAME} -c "DISPLAY=:0.0 zenity --info --text='Le périphérique a été démonté.'"
# =============================================================================================================================================================