GNU/Linux >> LINUX-Kenntnisse >  >> Linux

USB-Laufwerke automatisch mit systemd mounten

Lösung 1:

Nach mehreren Fehlstarts habe ich das herausgefunden. Der Schlüssel besteht darin, einen systemd-Unit-Dienst zwischen udev und einem Mount-Skript hinzuzufügen.

(Fürs Protokoll, ich konnte das mit udisks2 nicht zum Laufen bringen (über so etwas wie udisksctl mount -b /dev/sdb1 ) wird entweder direkt von einer udev-Regel oder von einer systemd-Unit-Datei aufgerufen. Es scheint eine Race-Condition zu geben und der Geräteknoten ist nicht ganz bereit, was zu Error looking up object for device /dev/sdb1 führt . Unglücklicherweise, da udisks2 sich um die ganze Unordnung der Einhängepunkte kümmern könnte...)

Die schwere Arbeit wird von einem Shell-Skript erledigt, das sich um das Erstellen und Entfernen von Mount-Punkten und das Mounten und Unmounten der Laufwerke kümmert.

/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

Das Skript wiederum wird von einer systemd-Unit-Datei aufgerufen. Wir verwenden die "@"-Dateinamensyntax, damit wir den Gerätenamen als Argument übergeben können.

/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

Schließlich starten und stoppen einige udev-Regeln den systemd-Unit-Dienst bei 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"

Das scheint zu funktionieren! Ein paar nützliche Befehle zum Debuggen von Dingen wie diesen:

  • udevadm control -l debug schaltet die ausführliche Protokollierung auf /var/log/syslog ein damit Sie sehen können, was passiert.
  • udevadm control --reload-rules nachdem Sie Dateien im therules.d-Verzeichnis geändert haben (muss nicht notwendig sein, kann aber nicht schaden...).
  • systemctl daemon-reload nachdem Sie systemd Unit-Dateien geändert haben.

Lösung 2:

es gibt einen neuen, prägnanten systemd Auto-Mount-Option, die mit fstab verwendet werden kann was Ihnen erlaubt, alle standardisierten Einhänge-Berechtigungsoptionen zu verwenden, und es sieht so aus:

  x-systemd.automount

ein Beispiel dafür in einem fstab Zeile:

  /dev/sdd1   /mnt/hitachi-one     auto     noauto,x-systemd.automount     0 2

die noauto Option bedeutet, dass es nicht versucht, beim Booten gemountet zu werden, wie bei älterer Software autofs .

nach Hinzufügen eines neuen x-systemd.automount Zeile bis fstab Sie müssen dann Folgendes ausführen:

  sudo systemctl daemon-reload

und dann beide oder eines der folgenden:

  sudo systemctl restart remote-fs.target
  sudo systemctl restart local-fs.target

für weitere Informationen darüber:

https://wiki.archlinux.org/index.php/Fstab#Automount_with_systemd

Lösung 3:

Mit pmount , systemd und Mike Blackwells Ansatz können Sie das Ganze vereinfachen:

/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 und danke Mike.

Lösung 4:

Ich habe das Skript von @MikeBlackwell geändert zu:

  • Erkennen Sie Gerätenamen, die mehrere Zeichen umfassen, nicht nur /dev/sd[a-z] aber /dev/sd[a-z]*; Dies ist häufig bei Servern der Fall, die eine größere Anzahl von Spindeln haben.
  • verfolgen Sie die Liste der automatisch gemounteten Laufwerke bei /var/log/usb-mount.track
  • protokollieren Sie die Aktionen in /var/log/messages mit dem Tag usb-mount.sh
  • Gerätenamen mit dem Gerätelabel für den Einhängepunkt voranstellen, damit es nicht zu Problemen mit Laufwerken kommt, denen kein Label zugewiesen wurde (leer?):/media/sdd2_usbtest , /media/sdd2_
  • eingeschlossene Wrapper-Skripte, um die Dateien richtig zu platzieren und bei Bedarf rückgängig zu machen

Da @MikeBlackwell bereits den größten Teil der schweren Arbeit erledigt hat, habe ich mich entschieden, es nicht neu zu schreiben; habe gerade die notwendigen Änderungen vorgenommen. Ich habe seine Arbeit anerkannt, indem ich seinen Namen und URI der ursprünglichen Antwort gesichtet habe.

Finden Sie es unter https://github.com/raamsri/automount-usb

Lösung 5:

Ich würde Warren Youngs Antwort folgen, an der ich ein paar Änderungen vorgenommen habe

Ich habe etwas Platzschutz hinzugefügt, da es Fehler bei der Bewertung der Umgebung für das Laufwerk gab.

Ich habe einen Abschnitt zum chmod einer USB-Festplatte hinzugefügt, damit alle Benutzer vollen Zugriff auf Nicht-NTFS- oder VFAT-Festplatten haben.

/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. Verwalten von Ressourcen mit cgroups in systemd

  2. So mounten Sie einen USB-Stick als Nicht-Root-Benutzer mit Schreibrechten

  3. Wie deaktiviere ich das automatische Mounten externer Laufwerke?

  4. Debian-USB-Automount?

  5. Nicht-grafischer Boot mit Systemd?

So erstellen Sie Multiboot-USB-Laufwerke mit Ventoy unter Linux

Erstellen Sie bootfähige USB-Laufwerke und SD-Karten mit Etcher in Linux

Entrümpeln des Prozessmanagements mit ps oder systemd

Verwalten von cgroups mit systemd

Mounten Sie einen Remote-Ordner mit sshfs

Linux-Mount-Befehl mit Beispielen