GNU/Linux >> Tutoriels Linux >  >> Linux

Monter automatiquement des clés USB avec systemd

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

Linux
  1. Gestion des ressources avec les cgroups dans systemd

  2. Comment monter une clé USB en tant qu'utilisateur non root avec autorisation d'écriture

  3. Comment désactiver le montage automatique des disques externes ?

  4. Debian USB Automount ?

  5. Démarrage non graphique avec Systemd ?

Comment créer des lecteurs USB multiboot avec Ventoy sous Linux

Créer des clés USB et des cartes SD amorçables avec Etcher sous Linux

Désencombrer la gestion des processus avec ps ou systemd

Gestion des cgroups avec systemd

Monter un dossier distant avec sshfs

Commande de montage Linux avec exemples