动态驱动器热插拔

动态驱动器热插拔

设置很简单。我有一台机架式服务器,前面有 24 个 5" 驱动器托架。该服务器运行 PLEX。每个 HDD 均采用 NTFS 分区,并在根目录中包含可选文件夹。服务器运行的是 Debian8 (3.16.51-3)

要求:我需要能够即插即用 HDD、自动挂载 NTFS 分区、扫描是否存在预定义文件夹以及符号链接到面向 PLEX 的目录。挂载和符号链接应默认使用 UUID

可选文件夹/Plex 目录:

/plex
    /movies
    /tvseries
    /music
    /audiobooks

UDEV 挂钩:/etc/udev/rules.d/sata-rackmount.rules

ACTION=="add", KERNEL=="sd?", RUN+="/plex/new_drive.sh"

*注:udevadm control --reload-rules更改后重新加载 *注:udevadm monitor --udev可用于查看安装更改

bash:/plex/new_drive.sh

#!/bin/sh

echo "New Drive Detected" >> /plex/log.txt
echo "\tLABEL: ${ID_SERIAL_SHORT}" >> /plex/log.txt
echo "\tNAME: ${DEVNAME}" >> /plex/log.txt

echo "\tMOUNT required" >> /plex/log.txt
for block in $( blkid -t TYPE=ntfs | grep "${DEVNAME}" )
do
    echo "\t > Block Found"
    BLK=$(echo '$block' | sed -rn 's/^(\/dev\/sd[a-z][0-9]):.*\bUUID\b[=]["]([^"]*)["].*$/\1/p')
    UUID=$(echo '$block' | sed -rn 's/^(\/dev\/sd[a-z][0-9]):.*\bUUID\b[=]["]([^"]*)["].*$/\2/p')
    echo "\tMounting Point: $BLK > $UUID" >> /plex/log.txt
done

*注意:此脚本需要UDEVCHOWN root:root new_drive.sh才能CHMOD +x new_drive.sh访问

当前日志.txt:

New Drive Detected
    LABEL: WD-WCANKC405910
    NAME: /dev/sdf
    MOUNT required

blkid 的输出 | grep(foreach)

/dev/sdf1: UUID="A2F66547F6651CB3" TYPE="ntfs" PARTUUID="1549f232-01"

sed 的输出(上面的输出)

\1 = /dev/sdf1
\2 = A2F66547F6651CB3

目前的问题似乎与我的 for-in 循环有关,代码直接跳过了该循环。我所有的研究都表明这应该有效,但不确定为什么不行。

出于测试目的,如果您决定使用替代媒体源(如“sd?”),则必须针对您自己的系统修改 UDEV 挂钩。将仅匹配基于 SATA 的驱动器,仅在根驱动器上(IE 不是 /dev/sdf1),并假设在脚本运行之前对该驱动器一无所知。

答案1

有一些问题我必须解决。首先,for block in $(...)结果是4行数据,而不是单行。该行对于我添加变量的方式也非常吝啬,如果它不完美,就会跳过。在获取 BLK 和 UUID 时,需要注意的是撇号'不读取变量。

#!/bin/sh
echo "New Drive Detected" >> /plex/log.txt
echo "\tLABEL: ${ID_SERIAL_SHORT}" >> /plex/log.txt
echo "\tNAME: ${DEVNAME}" >> /plex/log.txt

#fixed to collect output line, instead of arguments
for block in "$( blkid -t TYPE=ntfs | grep ${DEVNAME} )";
do
    echo "\tPartition Found: $block" >> /plex/log.txt
    BLK=$(echo "$block" | sed -rn 's/^(\/dev\/sd[a-z][0-9]):.*\bUUID\b[=]["]([^"]*)["].*$/\1/p')
    UUID=$(echo "$block" | sed -rn 's/^(\/dev\/sd[a-z][0-9]):.*\bUUID\b[=]["]([^"]*)["].*$/\2/p')
    echo "\tMounting Point: $BLK > /media/$UUID" >> /plex/log.txt
    mkdir -p "/media/$UUID"
    #repair in case of exclusivity
    #ntfsfix "$BLK"
    mount -t ntfs-3g -U "$UUID" "/media/$UUID"
    if [ -d "/media/$UUID/movies" ]; then
        echo "\tMovie Directory Found" >> /plex/log.txt
        mkdir -p "/plex/movies"
        ln -s "/media/$UUID/movies" "/plex/movies/$UUID"
    fi
    if [ -d "/media/$UUID/tvseries" ]; then
        echo "\tTV Directory Found" >> /plex/log.txt
        mkdir -p "/plex/tvseries"
        ln -s "/media/$UUID/tvseries" "/plex/tvseries/$UUID"
    fi
    if [ -d "/media/$UUID/anime" ]; then
        echo "\tAnime Directory Found" >> /plex/log.txt
        mkdir -p "/plex/anime"
        ln -s "/media/$UUID/anime" "/plex/anime/$UUID"
    fi
    if [ -d "/media/$UUID/music" ]; then
        echo "\tMusic Directory Found" >> /plex/log.txt
                mkdir -p "/plex/music"
                ln -s "/media/$UUID/music" "/plex/music/$UUID"
    fi
    if [ -d "/media/$UUID/audiobooks" ]; then
        echo "\tAudio Book Directory Found" >> /plex/log.txt
        mkdir -p "/plex/audiobooks"
        ln -s "/media/$UUID/audiobooks" "/plex/audiobooks/$UUID"
    fi
done

只要驱动器没有“windows protected”标志(由 修复),该脚本就可以工作NTFSFIX "$BLK",但无论我如何努力,我都无法让它与脚本活动同步修复(我将遇到新问题)研究)。我已经确认它确实执行了,但后续安装似乎在完成之前执行。我这么认为是因为我必须先卸载驱动器,然后运行 ​​NTFSFIX,然后再次安装驱动器。我还发现了一个小问题,驱动器无法自动卸载,并且随后每次都会使用新的驱动器号重新安装。这是通过另一个带有另一个 UDEV 参数的脚本解决的:

UDEV:/etc/udev/rules.d/sata-rackmount.rules

ACTION=="add", KERNEL=="sd?", RUN+="/plex/new_drive.sh"
ACTION=="remove", KERNEL=="sd??", RUN+="/plex/rem_drive.sh"

/plex/rem_drive.sh

#!/bin/sh

echo "Drive Lost" >> /plex/log.txt
echo "\tLABEL: ${ID_SERIAL_SHORT}" >> /plex/log.txt
echo "\tNAME: ${DEVNAME}" >> /plex/log.txt

echo "\tDismounting..." >> /plex/log.txt
umount "${DEVNAME}"
echo "\tDone!" >> /plex/log.txt

相关内容