कई झूठी शुरुआत के बाद मैंने यह पता लगाया। कुंजी udev और एक बढ़ते स्क्रिप्ट के बीच एक systemd इकाई सेवा को जोड़ने के लिए है।
(रिकॉर्ड के लिए, मैं udisks2 (जैसे कुछ के माध्यम से udisksctl mount -b /dev/sdb1
) का उपयोग करके इस काम को प्राप्त करने में सक्षम नहीं था, जिसे या तो सीधे एक udv नियम से या एक सिस्टम यूनिट फ़ाइल से कहा जाता है। एक दौड़ की स्थिति प्रतीत होती है और डिवाइस नोड काफी तैयार नहीं है। , जिसके परिणामस्वरूप, Error looking up object for device /dev/sdb1
दुर्भाग्यपूर्ण है, क्योंकि udisks2 सभी आरोह बिंदु गड़बड़ का ख्याल रख सकता है ...)
भारी उठाने का कार्य एक शेल स्क्रिप्ट द्वारा किया जाता है, जो माउंट पॉइंट्स को बनाने और निकालने का ध्यान रखता है, और ड्राइव को माउंट और अनमाउंट करता है।
/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
स्क्रिप्ट, बदले में, एक systemd इकाई फ़ाइल द्वारा कहा जाता है। हम "@" फ़ाइल नाम सिंटैक्स का उपयोग करते हैं ताकि हम डिवाइस नाम को एक तर्क के रूप में पारित कर सकें।
/etc/systemd/system/usb-mount@.service
[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
अंत में, कुछ udv नियम हॉटप्लग / अनप्लग पर सिस्टमड यूनिट सेवा को शुरू और बंद करते हैं:
/etc/udev/rules.d/99-local.rules
KERNEL=="sd[a-z][0-9]", SUBSYSTEMS=="usb", ACTION=="add", RUN+="/bin/systemctl start usb-mount@%k.service"
KERNEL=="sd[a-z][0-9]", SUBSYSTEMS=="usb", ACTION=="remove", RUN+="/bin/systemctl stop usb-mount@%k.service"
इस चाल को करने के लिए लगता है! सामान को डिबग करने के लिए कुछ उपयोगी कमांड इस प्रकार हैं:
udevadm control -l debug
वर्बोज़ लॉगिंग चालू करता है
/var/log/syslog
ताकि आप देख सकें कि क्या हो रहा है।
udevadm control --reload-rules
नियमों में फाइल को संशोधित करने के बाद। dir (आवश्यक नहीं हो सकता है, लेकिन चोट नहीं पहुँचा सकता है ...)।
systemctl daemon-reload
आपके द्वारा systemd इकाई फ़ाइलों को संशोधित करने के बाद।