Solusi 1:
Setelah beberapa awal yang salah, saya menemukan jawabannya. Kuncinya adalah menambahkan layanan unit sistem antara udev dan skrip pemasangan.
(Sebagai catatan, saya tidak bisa membuatnya berfungsi menggunakan udisks2 (melalui sesuatu seperti udisksctl mount -b /dev/sdb1
) dipanggil baik langsung dari aturan udev atau dari file unit systemd. Tampaknya ada kondisi balapan dan node perangkat belum siap, menghasilkan Error looking up object for device /dev/sdb1
. Sayangnya, karena udisks2 dapat mengatasi semua kekacauan titik pemasangan...)
Pengangkatan berat dilakukan oleh skrip shell, yang menangani pembuatan dan penghapusan titik pemasangan, serta pemasangan dan pelepasan drive.
/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
Skrip, pada gilirannya, dipanggil oleh file unit systemd. Kami menggunakan sintaks nama file "@" sehingga kami dapat meneruskan nama perangkat sebagai argumen.
/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
Terakhir, beberapa aturan udev memulai dan menghentikan layanan unit sistem pada 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"
Ini sepertinya berhasil! Beberapa perintah berguna untuk men-debug hal-hal seperti ini:
udevadm control -l debug
mengaktifkan logging panjang ke/var/log/syslog
sehingga Anda dapat melihat apa yang terjadi.udevadm control --reload-rules
setelah Anda memodifikasi file di direktori therules.d (mungkin tidak diperlukan, tapi tidak ada salahnya...).systemctl daemon-reload
setelah Anda memodifikasi file unit systemd.
Solusi 2:
ada systemd
baru yang ringkas opsi pemasangan otomatis yang dapat digunakan dengan fstab
yang memungkinkan Anda menggunakan semua opsi izin pemasangan standar, dan tampilannya seperti ini:
x-systemd.automount
contohnya dalam fstab
baris:
/dev/sdd1 /mnt/hitachi-one auto noauto,x-systemd.automount 0 2
noauto
opsi berarti tidak akan mencoba untuk dipasang saat boot, seperti pada perangkat lunak yang lebih lama autofs
.
setelah menambahkan x-systemd.automount
baru baris ke fstab
Anda kemudian perlu menjalankan:
sudo systemctl daemon-reload
lalu keduanya, atau salah satu, berikut ini:
sudo systemctl restart remote-fs.target
sudo systemctl restart local-fs.target
untuk informasi lebih lanjut tentangnya:
https://wiki.archlinux.org/index.php/Fstab#Automount_with_systemd
Solusi 3:
Menggunakan pmount , systemd dan pendekatan Mike Blackwell, Anda dapat menyederhanakan semuanya:
/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 dan terima kasih Mike.
Solusi 4:
Saya telah memodifikasi skrip dari @MikeBlackwell ke:
- mengenali nama perangkat yang terdiri dari beberapa karakter, bukan hanya
/dev/sd[a-z]
tapi/dev/sd[a-z]*
; sering terjadi pada server yang memiliki jumlah spindel lebih besar. - lacak daftar drive yang dipasang otomatis di
/var/log/usb-mount.track
- catat tindakan ke
/var/log/messages
dengan tag usb-mount.sh - awali nama perangkat dengan label perangkat agar titik pemasangan tidak mengalami masalah dengan drive yang belum diberi label (kosong?):
/media/sdd2_usbtest
,/media/sdd2_
- menyertakan skrip pembungkus untuk menempatkan file dengan tepat dan membatalkan jika diperlukan
Karena @MikeBlackwell telah melakukan sebagian besar pekerjaan berat, saya memilih untuk tidak menulis ulang; hanya membuat perubahan yang diperlukan. Saya telah mengakui karyanya melihat namanya dan URI dari jawaban aslinya.
Temukan di https://github.com/raamsri/automount-usb
Solusi 5:
Saya akan memilih jawaban Warren Young. Saya memiliki beberapa perubahan yang saya buat
Saya menambahkan beberapa perlindungan ruang karena memberikan kesalahan dari evaluasi lingkungan untuk drive.
Saya menambahkan bagian untuk chmod disk usb sehingga semua pengguna memiliki akses penuh ke disk non ntfs atau 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