বেশ কয়েকটি মিথ্যা শুরুর পরে আমি এটি বের করেছিলাম। কীটি হ'ল উদেব এবং মাউন্টিং স্ক্রিপ্টের মধ্যে একটি সিস্টেমড ইউনিট পরিষেবা যুক্ত করা।
(রেকর্ডের জন্য, আমি udisks2 ব্যবহার করে এই কাজটি করতে সক্ষম হইনি (যেমন কোনও কিছুর মাধ্যমে udisksctl mount -b /dev/sdb1
) হয় সরাসরি উদেব নিয়ম থেকে বা সিস্টেমড ইউনিট ফাইল থেকে ডাকা হয় There এখানে একটি জাতি শর্ত বলে মনে হচ্ছে এবং ডিভাইস নোডটি বেশ প্রস্তুত নয় , ফলে Error looking up object for device /dev/sdb1
। দু: খজনক, যেহেতু udisks2 সব যত্ন নিতে মাউন্ট পয়েন্ট messyness পারে ...)
ভারী উত্তোলন একটি শেল স্ক্রিপ্ট দ্বারা সম্পন্ন হয়, যা মাউন্ট পয়েন্টগুলি তৈরি এবং অপসারণ এবং ড্রাইভগুলি মাউন্ট এবং আনমাউন্টিংয়ের যত্ন নেয়।
/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
পরিবর্তে, স্ক্রিপ্টটি সিস্টেমড ইউনিট ফাইল দ্বারা ডাকা হয়। আমরা "@" ফাইলের নাম সিনট্যাক্স ব্যবহার করি যাতে আমরা ডিভাইসের নামটিকে একটি আর্গুমেন্ট হিসাবে পাস করতে পারি।
/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
অবশেষে, কিছু udev নিয়ম হটপ্লাগ / আনপ্লাগে সিস্টেমেড ইউনিট পরিষেবা শুরু করে এবং বন্ধ করে দেয়:
/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
আপনি বিধিগুলিতে ফাইলগুলি সংশোধন করার পরে ডির (প্রয়োজনীয় নাও হতে পারে তবে আঘাত করতে পারে না ...)।
systemctl daemon-reload
আপনি সিস্টেমড ইউনিট ফাইলগুলি সংশোধন করার পরে।