Solution 1 :
Après plusieurs faux départs, j'ai compris cela. La clé est d'ajouter un service d'unité systemd entre udev et un script de montage.
(Pour mémoire, je n'ai pas pu faire fonctionner cela en utilisant udisks2 (via quelque chose comme udisksctl mount -b /dev/sdb1
) appelé soit directement à partir d'une règle udev, soit à partir d'un fichier d'unité systemd. Il semble y avoir une condition de concurrence et le nœud de l'appareil n'est pas tout à fait prêt, ce qui entraîne Error looking up object for device /dev/sdb1
. Dommage, car udisks2 pourrait s'occuper de tout le désordre des points de montage...)
Le gros du travail est effectué par un script shell, qui s'occupe de créer et de supprimer des points de montage, et de monter et démonter les disques.
/usr/local/bin/usb-mount.sh
#!/bin/bash
# This script is called from our systemd unit file to mount or unmount
# a USB drive.
usage()
{
echo "Usage: $0 {add|remove} device_name (e.g. sdb1)"
exit 1
}
if [[ $# -ne 2 ]]; then
usage
fi
ACTION=$1
DEVBASE=$2
DEVICE="/dev/${DEVBASE}"
# See if this drive is already mounted, and if so where
MOUNT_POINT=$(/bin/mount | /bin/grep ${DEVICE} | /usr/bin/awk '{ print $3 }')
do_mount()
{
if [[ -n ${MOUNT_POINT} ]]; then
echo "Warning: ${DEVICE} is already mounted at ${MOUNT_POINT}"
exit 1
fi
# Get info for this drive: $ID_FS_LABEL, $ID_FS_UUID, and $ID_FS_TYPE
eval $(/sbin/blkid -o udev ${DEVICE})
# Figure out a mount point to use
LABEL=${ID_FS_LABEL}
if [[ -z "${LABEL}" ]]; then
LABEL=${DEVBASE}
elif /bin/grep -q " /media/${LABEL} " /etc/mtab; then
# Already in use, make a unique one
LABEL+="-${DEVBASE}"
fi
MOUNT_POINT="/media/${LABEL}"
echo "Mount point: ${MOUNT_POINT}"
/bin/mkdir -p ${MOUNT_POINT}
# Global mount options
OPTS="rw,relatime"
# File system type specific mount options
if [[ ${ID_FS_TYPE} == "vfat" ]]; then
OPTS+=",users,gid=100,umask=000,shortname=mixed,utf8=1,flush"
fi
if ! /bin/mount -o ${OPTS} ${DEVICE} ${MOUNT_POINT}; then
echo "Error mounting ${DEVICE} (status = $?)"
/bin/rmdir ${MOUNT_POINT}
exit 1
fi
echo "**** Mounted ${DEVICE} at ${MOUNT_POINT} ****"
}
do_unmount()
{
if [[ -z ${MOUNT_POINT} ]]; then
echo "Warning: ${DEVICE} is not mounted"
else
/bin/umount -l ${DEVICE}
echo "**** Unmounted ${DEVICE}"
fi
# Delete all empty dirs in /media that aren't being used as mount
# points. This is kind of overkill, but if the drive was unmounted
# prior to removal we no longer know its mount point, and we don't
# want to leave it orphaned...
for f in /media/* ; do
if [[ -n $(/usr/bin/find "$f" -maxdepth 0 -type d -empty) ]]; then
if ! /bin/grep -q " $f " /etc/mtab; then
echo "**** Removing mount point $f"
/bin/rmdir "$f"
fi
fi
done
}
case "${ACTION}" in
add)
do_mount
;;
remove)
do_unmount
;;
*)
usage
;;
esac
Le script, à son tour, est appelé par un fichier d'unité systemd. Nous utilisons la syntaxe de nom de fichier "@" afin de pouvoir transmettre le nom de l'appareil en tant qu'argument.
/etc/systemd/system/[email protected]
[Unit]
Description=Mount USB Drive on %i
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/local/bin/usb-mount.sh add %i
ExecStop=/usr/local/bin/usb-mount.sh remove %i
Enfin, certaines règles udev démarrent et arrêtent le service d'unité systemd sur hotplug/unplug :
/etc/udev/rules.d/99-local.rules
KERNEL=="sd[a-z][0-9]", SUBSYSTEMS=="usb", ACTION=="add", RUN+="/bin/systemctl start [email protected]%k.service"
KERNEL=="sd[a-z][0-9]", SUBSYSTEMS=="usb", ACTION=="remove", RUN+="/bin/systemctl stop [email protected]%k.service"
Cela semble faire l'affaire ! Quelques commandes utiles pour déboguer des choses comme celle-ci :
udevadm control -l debug
active la journalisation détaillée à/var/log/syslog
afin que vous puissiez voir ce qui se passe.udevadm control --reload-rules
après avoir modifié les fichiers dans le répertoirerules.d (ce n'est peut-être pas nécessaire, mais ça ne peut pas faire de mal...).systemctl daemon-reload
après avoir modifié les fichiers d'unité systemd.
Solution 2 :
il y a un nouveau systemd
succinct option de montage automatique qui peut être utilisée avec fstab
qui vous permet d'utiliser toutes les options d'autorisation de montage standardisées, et cela ressemble à ceci :
x-systemd.automount
un exemple dans un fstab
ligne :
/dev/sdd1 /mnt/hitachi-one auto noauto,x-systemd.automount 0 2
le noauto
signifiera qu'il ne tentera pas d'être monté au démarrage, comme avec les anciens logiciels autofs
.
après avoir ajouté un nouveau x-systemd.automount
ligne vers fstab
vous devez ensuite exécuter :
sudo systemctl daemon-reload
puis les deux ou l'un des éléments suivants :
sudo systemctl restart remote-fs.target
sudo systemctl restart local-fs.target
pour plus d'informations à ce sujet :
https://wiki.archlinux.org/index.php/Fstab#Automount_with_systemd
Solution 3 :
Utilisation de pmount , systemd et l'approche de Mike Blackwell, vous pouvez simplifier le tout :
/etc/systemd/system/[email protected]
[Unit]
Description=Mount USB Drive on %i
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/pmount --umask 000 /dev/%i /media/%i
ExecStop=/usr/bin/pumount /dev/%i
/etc/udev/rules.d/99-usb-mount.rules
ACTION=="add",KERNEL=="sd[a-z][0-9]*",SUBSYSTEMS=="usb",RUN+="/bin/systemctl start [email protected]%k.service"
ACTION=="remove",KERNEL=="sd[a-z][0-9]*",SUBSYSTEMS=="usb",RUN+="/bin/systemctl stop [email protected]%k.service"
HTH et merci Mike.
Solution 4 :
J'ai modifié le script de @MikeBlackwell en :
- reconnaître les noms d'appareils qui comportent plusieurs caractères, pas seulement
/dev/sd[a-z]
mais/dev/sd[a-z]*
; souvent le cas avec les serveurs qui ont un plus grand nombre de piles. - suivez la liste des lecteurs montés automatiquement à
/var/log/usb-mount.track
- enregistrer les actions dans
/var/log/messages
avec la balise usb-mount.sh - préfixez le nom de l'appareil avec l'étiquette de l'appareil pour que le point de montage ne rencontre pas de problèmes avec les lecteurs qui n'ont pas reçu d'étiquette (vide ?) :
/media/sdd2_usbtest
,/media/sdd2_
- inclut des scripts wrapper pour placer les fichiers de manière appropriée et les annuler si nécessaire
Puisque @MikeBlackwell a déjà fait la plupart du gros du travail, j'ai choisi de ne pas le réécrire; vient d'apporter les modifications nécessaires. J'ai reconnu son travail en voyant son nom et l'URI de la réponse originale.
Trouvez-le sur https://github.com/raamsri/automount-usb
Solution 5 :
J'irais avec la réponse de Warren Young, j'ai apporté quelques modifications à
J'ai ajouté une protection de l'espace car cela provoquait des erreurs d'évaluation de l'environnement pour le lecteur.
J'ai ajouté une section pour chmoder un disque USB afin que tous les utilisateurs aient un accès complet aux disques non ntfs ou vfat.
/usr/local/bin/usb-mount.sh
#!/bin/bash
# This script is called from our systemd unit file to mount or unmount
# a USB drive.
usage()
{
echo "Usage: $0 {add|remove} device_name (e.g. sdb1)"
exit 1
}
if [[ $# -ne 2 ]]; then
usage
fi
ACTION="$1"
DEVBASE="$2"
DEVICE="/dev/${DEVBASE}"
# See if this drive is already mounted, and if so where
MOUNT_POINT=$(/bin/mount | /bin/grep ${DEVICE} | /usr/bin/awk '{ print $3 }')
do_mount()
{
if [[ -n "${MOUNT_POINT}" ]]; then
echo "Warning: ${DEVICE} is already mounted at ${MOUNT_POINT}"
exit 1
fi
# Get info for this drive: $ID_FS_LABEL, $ID_FS_UUID, and $ID_FS_TYPE
# added some sed's to avoid space issues
eval $(/sbin/blkid -o udev ${DEVICE}|sed 's/=/="/'|sed 's/$/"/')
# Figure out a mount point to use
LABEL="${ID_FS_LABEL}"
if [[ -z "${LABEL}" ]]; then
LABEL="${DEVBASE}"
elif /bin/grep -q " /media/${LABEL} " /etc/mtab; then
# Already in use, make a unique one
LABEL+="-${DEVBASE}"
fi
MOUNT_POINT="/media/${LABEL}"
echo "Mount point: ${MOUNT_POINT}"
/bin/mkdir -p "${MOUNT_POINT}"
# Global mount options
OPTS="rw,relatime"
#added a chmod checker for file systems that don't
#understand allow all to read write
CHMOD=no
# File system type specific mount options
if [[ ${ID_FS_TYPE} == "vfat" ]]; then
OPTS+=",users,gid=100,umask=000,shortname=mixed,utf8=1,flush"
#added options I wanted on ntfs
elif [[ ${ID_FS_TYPE} == "ntfs" ]]; then
OPTS+=",user,users,umask=000,allow_other"
else
CHMOD=yes
fi
if ! /bin/mount -o "${OPTS}" ${DEVICE} "${MOUNT_POINT}"; then
echo "Error mounting ${DEVICE} (status = $?)"
/bin/rmdir "${MOUNT_POINT}"
exit 1
fi
echo "**** Mounted ${DEVICE} at ${MOUNT_POINT} ****"
if [ "${CHMOD}" = "yes" ];then
/usr/bin/find "${MOUNT_POINT}" -type f -exec chmod 0666 {} \;
/usr/bin/find "${MOUNT_POINT}" -type d -exec chmod 0777 {} \;
fi
}
do_unmount()
{
if [[ -z ${MOUNT_POINT} ]]; then
echo "Warning: ${DEVICE} is not mounted"
else
/bin/umount -l ${DEVICE}
echo "**** Unmounted ${DEVICE}"
fi
# Delete all empty dirs in /media that aren't being used as mount
# points. This is kind of overkill, but if the drive was unmounted
# prior to removal we no longer know its mount point, and we don't
# want to leave it orphaned...
for f in /media/* ; do
if [[ -n $(/usr/bin/find "$f" -maxdepth 0 -type d -empty) ]]; then
if ! /bin/grep -q " $f " /etc/mtab; then
echo "**** Removing mount point $f"
/bin/rmdir "$f"
fi
fi
done
}
case "${ACTION}" in
add)
do_mount
;;
remove)
do_unmount
;;
*)
usage
;;
esac