chip_discovery 发表于 2024-11-28 13:26

PVE如何优雅地实现硬盘柜随需开机,用完下线

本帖最后由 chip_discovery 于 2024-11-28 13:28 编辑

目前在PVE上其他功能算是基本上都实现了,但是就一个功能比较困难:

外接的硬盘柜是USB的,本身对它的定位就是备份和存冷数据,也不用一直在线,徒增功耗且万一局域网被破解那就一锅端。

现状是:
         1.按需开机用智能插座手动通电
         2.直通给虚拟机win,上线后可以读写其中的文件
         3.用完关机就不太方便了,弹出USB柜后,实际上只是相当于设备管理权还给了PVE,因此设备还在线,直接插座断电的话应该会不安全次数+1好像,长期来看也不是办法,但是也不能每次都是去手动插拔USB,太麻烦了

家里已经好几台主机了,再弄一个win 物理机专门管这个硬盘柜也不合适

之前在用群晖的时候倒是操作逻辑整体和win差不多,所以在PVE上有什么办法能“优雅”实现对USB硬盘柜的随用随开,用完弹出USB,硬盘自动下线,然后就可以关智能插座呢?

大头吃小头 发表于 2024-11-28 13:34

太难了
我也在等完美解决的办法

不过给这个机器扔柜子里24小时待机眼不见心不烦就完事了

lnron 发表于 2024-11-28 14:12

物理开关搞一个,做插拔的动作,远程控制,应该是可以做到的吧

Aapejiang 发表于 2024-11-28 23:47

看硬盘柜用的什么方案,USB HUB的话可以试下uhubctl https://github.com/mvp/uhubctl
我用在给冷备硬盘盒自动开关电源上,简单好用

chip_discovery 发表于 2024-11-29 08:43

本帖最后由 chip_discovery 于 2024-11-29 09:03 编辑

Aapejiang 发表于 2024-11-28 23:47
看硬盘柜用的什么方案,USB HUB的话可以试下uhubctl https://github.com/mvp/uhubctl
我用在给冷备硬盘盒自 ...

这个项目牛啊,不过好像没看到我那个的型号,VID:PID 那列好像没找到,我那个是152d开头的。
toolfree 贺禧的机架式硬盘柜,有USB和esata两个接口。
我昨天晚上后来想了个办法,让chat*g*p*t写了个脚本,大致思路就是检测到虚拟机102关机后就判断是否还有USB的硬盘,有的话就给他power off

chip_discovery 发表于 2024-11-29 09:02

找chatg*p*t 写的代码,亲测四个硬盘,只要第一个power off,后面三个也自动下线了
本人非程序员,不是很懂代码,如有错误望大佬不吝赐教
#!/bin/bash

# 虚拟机编号
VM_ID=102
# 轮询间隔时间(秒)
POLL_INTERVAL=60
# 最大轮询次数
MAX_RETRIES=10

# 检查虚拟机是否已关机
check_vm_status() {
    local vm_id=$1
    local status=$(qm status "$vm_id" | awk '{print $2}')
    if [[ "$status" == "stopped" ]]; then
      return 0
    else
      return 1
    fi
}

# 动态筛选 USB 类型的硬盘设备
get_usb_devices() {
    lsblk -o NAME,TRAN | grep -i "usb" | awk '{print $1}'
}

# 安全断开 USB 设备
safely_remove_usb() {
    local device=$1

    # 检查设备是否存在
    if [[ ! -e /dev/$device ]]; then
      echo "Device /dev/$device not found. Skipping."
      return
    fi

    # 检查是否安装了 udisksctl
    if command -v udisksctl >/dev/null 2>&1; then
      echo "Using udisksctl to safely remove /dev/$device..."
      
      # 卸载设备的所有分区
      for part in $(lsblk -ln -o NAME /dev/$device); do
            if mount | grep -q "/dev/$part"; then
                udisksctl unmount -b /dev/$part 2>/dev/null
                echo "Unmounted /dev/$part"
            fi
      done

      # 关闭设备电源
      udisksctl power-off -b /dev/$device
      echo "Device /dev/$device powered off."
    else
      echo "udisksctl not found. Falling back to /sys method for /dev/$device..."
      
      # 卸载设备的所有分区
      for part in $(lsblk -ln -o NAME /dev/$device); do
            if mount | grep -q "/dev/$part"; then
                umount /dev/$part 2>/dev/null
                echo "Unmounted /dev/$part"
            fi
      done

      # 从系统中移除设备
      echo 1 > /sys/block/$device/device/delete
      echo "Device /dev/$device removed from system."
    fi
}

# 主逻辑
main() {
    local retries=0

    while true; do
      if (( retries >= MAX_RETRIES )); then
            echo "Maximum retries reached. Exiting."
            exit 1
      fi

      # 检查虚拟机状态
      if check_vm_status "$VM_ID"; then
            echo "VM $VM_ID is offline. Proceeding with USB device removal."

            # 动态获取所有 USB 类型硬盘设备
            local usb_devices=$(get_usb_devices)
            
            if [[ -z "$usb_devices" ]]; then
                echo "No USB devices found. Exiting."
                break
            fi

            # 安全断开所有筛选出的 USB 设备
            for device in $usb_devices; do
                safely_remove_usb "$device"
            done

            echo "All USB devices have been safely removed."
            break
      else
            echo "VM $VM_ID is still running. Retrying in $POLL_INTERVAL seconds..."
      fi

      retries=$((retries + 1))
      sleep "$POLL_INTERVAL"
    done
}

main

qp6g3o 发表于 2025-4-24 14:06

有点意思
页: [1]
查看完整版本: PVE如何优雅地实现硬盘柜随需开机,用完下线