将 Home Assistant 从 HAOS 迁移到 Ubuntu Server
HAOS 固然好，但是不提供 pi-hole 组件。Ubuntu 也不错，但是 Home Assistant Core 没有组件支持。为了合并两台小主机，只能把 Home Assistant 迁移到 Ubuntu 下面，通过 docker 提供附加组件。 这次需要转移的服务如下： Home Assistant Core Mosquitto Zigbee2MQTT (SONOFF Zigbee 3.0 Stick) Zwave-JS UI (Zooz Z-wave Stick ZST10) ESPhome AI 是个好东西，Grok 对这次迁移过程提供了很大帮助。不过，Grok 也有不太准确的地方。本文不仅是对迁移过程进行记录，也修正了 Grok 不准确的地方。 0. 备份 Home Assistant 进入 Home Assistant 管理页面，在 Settings -> System -> Backups 页面里面找到 Backup Settings 部分。点击 Configure Backup Settings。然后在 Location 部分找到 This system，点击后面的设置图标。在弹出的窗口中关掉 Encryption（加密）。 然后退回 Backup 页面，点击右下方的 Backup Now，按提示备份。注意备份要包括所有的 addons。 备份完成后，去 Manual backups 里面找到刚刚的备份文件，下载回来，解包。 比较关键的有以下几个。 homeassistant.tar.gz core_mosquitto.tar.gz xxxxxxxx_zwavejs2mqtt.tar.gz 注意：以上文件名会根据版本不同而改变，但是都会包含对应组件的关键字。 1. 导入设置数据 将上面的备份文件传到 Ubuntu 机器上。 # Restore Home Assistant backup mkdir -p /data/homeassistant cd /data/homeassistant cp /path/to/homeassistant.tar.gz . tar -xzf homeassistant.tar.gz rm homeassistant.tar.gz # Restore Mosquitto backup mkdir -p /data/mosquitto cd /data/mosquitto cp /path/to/core_mosquitto.tar.gz . tar -xzf core_mosquitto.tar.gz rm core_mosquitto.tar.gz # Restore Zigbee2MQTT backup mkdir -p /data/zigbee2mqtt cd /data/zigbee2mqtt cp -r /data/homeassistant/data/zigbee2mqtt/* . # Restore Zwave-JS UI backup mkdir -p /data/zwave-js-ui cd /data/zwave-js-ui cp /path/to/xxxxxxxx_zwavejs2mqtt.tar.gz . tar -xzf xxxxxxxx_zwavejs2mqtt.tar.gz rm xxxxxxxx_zwavejs2mqtt.tar.gz # Restore ESPhome backup mkdir -p /data/esphome/config cd /data/esphome/config cp -r /data/homeassistant/data/esphome/* . 2. 创建 Mosquitto 设置文件 将以下内容写入到 /data/mosquitto/config/mosquitto.conf persistence true persistence_location /mosquitto/data/ log_dest file /mosquitto/log/mosquitto.log listener 1883 allow_anonymous false password_file /mosquitto/config/password.txt 然后运行下面的命令，建立 Mosquitto 用户账号。注意替换 <username> sudo docker run -it --rm -v /data/mosquitto:/mosquitto eclipse-mosquitto mosquitto_passwd -c /mosquitto/config/password.txt <username> 3. 修正 Zigbee2MQTT 和 Zwave-JS UI 到 Mosquitto 的连接 将上一步创建的 Mosquitto 用户名/密码更新到 Zigbee2MQTT 和 Zwave-JS UI 设置当中。注意，要把 Mosquitto 主机地址也改成本机地址，不要用 localhost 或者 127.0.0.1。 /data/zigbee2mqtt/configuration.yaml /data/zwave-js-ui/store/settings.json 4. 修正 Zigbee Stick 和 Z-wave Stick 在系统中的路径 首先，用 lsusb 命令获取两个 USB 棒的 Vender ID 和 Product ID。 然后，创建文件 /etc/udev/rules.d/99-usb.rules，内容如下。注意替换正确的 ID SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="zwave" SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="55d4", SYMLINK+="zigbee" 重启系统。 5. 部署 Docker 先为 Zwave-JS UI 生成 SESSION_SECRET openssl rand -base64 32 最终的 docker-compose.yaml 内容如下。注意替换 <secret> version: '3' services: homeassistant: image: homeassistant/home-assistant:latest container_name: homeassistant network_mode: host volumes: - /data/homeassistant/data:/config environment: - TZ=America/Toronto ports: - "8123:8123" restart: unless-stopped mosquitto: image: eclipse-mosquitto:latest container_name: mosquitto volumes: - /data/mosquitto:/mosquitto - /data/mosquitto/data:/mosquitto/data - /data/mosquitto/log:/mosquitto/log ports: - "1883:1883" - "9001:9001" restart: unless-stopped zigbee2mqtt: image: koenkk/zigbee2mqtt:latest container_name: zigbee2mqtt volumes: - /data/zigbee2mqtt:/app/data - /run/udev:/run/udev:ro ports: - "8099:8099" environment: - TZ=America/Toronto devices: - /dev/zigbee:/dev/ttyACM0 restart: unless-stopped zwave-js-ui: image: zwavejs/zwave-js-ui:latest container_name: zwave-js-ui tty: true stop_signal: SIGINT volumes: - /data/zwave-js-ui/store:/usr/src/app/store ports: - "8091:8091" - "3000:3000" environment: - SESSION_SECRET=<secret> - TZ=America/Toronto devices: - /dev/zwave:/dev/ttyUSB0 restart: unless-stopped esphome: image: esphome/esphome:latest container_name: esphome privileged: true network_mode: host volumes: - /data/esphome/config:/config - /etc/localtime:/etc/localtime:ro ports: - "6052:6052" environment: - ESPHOME_DASHBOARD_USE_PING=true restart: always 访问 http://<server-ip>:8123 确认 Home Assistant 是否正常工作。 6. 在 Home Assistant 设备集成中重新设置附加组件的服务连接 在 Home Assistant 中选择 Settings -> Device & services。 进入 MQTT 集成，点击 core-mosquitto 右面的三个点，选择 Reconfigure，填写本机 IP 地址，和上面重新设置的 Mosquitto 用户名密码。 进入 Z-Wave 集成，点击 Z-Wave JS 右面的三个点，选择 Reconfigure，在弹出选项里面选择 Re-configure the current controller，将地址中的主机名改成本机 IP。 7. 将 Zigbee2MQTT、Zwave-JS UI 和 ESPhome 添加到 Home Assistant 侧栏 从 HACS 里面安装 Ingress 扩展。 然后，在 /data/homeassistant/data/configuration.yaml 里面加上下面一段 ingress: esphome: require_admin: true title: ESPHome icon: mdi:chip url: http://<server-ip>:6052 zigbee2mqtt: require_admin: true title: Zigbee2MQTT icon: mdi:zigbee url: http://<server-ip>:8099 zwave_js_ui: require_admin: true title: Zwave-JS UI icon: mdi:z-wave url: http://<server-ip>:8091
让 pi-hole docker 的 DHCP 与 libvirt dnsmasq 共存
不得不说，Linux 开发者都是一帮偏执的“天才”程序员。曾经有人质疑 dnsmasq 是否应该强制将 67 端口绑定至 0.0.0.0（所有网络界面），但是几位“天才”非要固执地说，这是为了负载平衡。结果，由 dnsmasq 魔改的 pihole-FTL，真的就和 libvirt 依赖的 dnsmasq 冲突了…… 依照前人的解决办法，依然无法让 pi-hole 正常工作。在参阅了 pi-hole docker 文档和另一位前人的笔记之后，终于找到了目前为止最好的解决方案。 背景 libvirt 安装好之后，会默认使用 NAT 模式将虚拟机连接到网络上。NAT 会生成一个网桥，并在网桥里面启用 dnsmasq。 解决办法就是完全停用 libvirt 生成的网桥，然后在 Linux 系统里手工建立一个网桥，并将虚拟机挂载到 Linux 网桥上。 完全关闭 libvirt 里面的默认网桥 virsh net-destroy default virsh net-autostart --disable default 启动 pi-hole docker sudo docker run -d \ --name pihole \ ... -e DNSMASQ_LISTENING=all \ -e IPv6=false \ ... --cap-add=NET_ADMIN \ --net=host \ pihole/pihole:latest 其中，DNSMASQ_LISTENING=all 可以在网络管理页面里面设置 Settings -> DNS -> Interface settings -> Permit all origins 建立系统网桥 这个步骤在不同的 Linux 发行版并没有统一的操作步骤，取决于 Linux 发行版采用哪种网络管理方式。 我使用的是 Ubuntu 24.04 LTS，采用的是 NetworkManager + Netplan 来管理网络。 首先，打开 Network Manager。 nm-connection-editor & 点击左下角的 + 号，然后设备类型选择 Bridge（网桥）。 在新建网桥的窗口中，填写网桥名称，然后点 Add 向网桥中添加网卡。 弹出的窗口里面选好物理网卡，点击保存。 切换到 IPv4 选项卡，设置 IP。在这里我使用了固定 IP，如果不需要固定 IP 的话，可以在第 2 步选择 DHCP，然后忽略第 3-5 步。 最后，切换到 IPv6 选项卡，这里我关闭了 IPv6。然后点击保存。 这样，网桥就建好了。 将虚拟机直接挂载到网桥 在虚拟机描述文件（domain XML）里面使用下面的方式定义网络连接。 <interface type='bridge'> <mac address='52:54:00:3c:ac:6c'/> <model type='virtio'/> </interface> 在启动虚拟机之后，libvirt 会自动将虚拟机网卡加入到网桥中。
如果访问 微软账户的 App Access 页面 显示“Sorry, something went wrong.”，到 应用与服务页面 里面移除 Synology Cloud Sync 的访问权限可以解决问题。
Unraid 通过虚拟 SCSI 控制器将硬盘直通给黑群晖虚拟机
写在前面：为什么不将 SAS 卡整体直通给虚拟机？如果能做到，我也不用研究硬盘直通了…… 在 Unraid 系统下建立虚拟机的时候，存储设备可以选 USB、SATA、SCSI。 USB 即虚拟成 U 盘，对于黑群晖这种需要 U 盘引导的系统来说很方便，不需要像 Proxmox VE 那样在 VM 设置里加一大堆 QEMU args SATA 即通过虚拟 SATA 控制器（Intel ICH9）挂载硬盘 SCSI 即通过虚拟 SCSI 控制器（默认为 virtio-scsi）挂载硬盘 底层 libvirt 提供了几种不同的 SCSI 虚拟控制器，可以通过修改 XML 的方式更换控制器。（更改 model） <controller type='scsi' index='0' model='virtio-scsi' /> 根据 Redhat 文档，我实验了以下几个型号。（仅记录目前最新版黑群晖引导 24.6.0 的使用情况） virtio-scsi 默认型号 使用驱动 virtio_blk 目前 可以识别并加载，但是与 SATA 硬盘存在编号冲突，混合使用 SATA 和 SCSI 方式挂载硬盘有大概率会丢盘。 lsilogic 虚拟成 LSI 53c895a 使用驱动 sym53c8xx rr 本身支持，但是没有提供 DSM modules，进入 DSM 后无法识别控制器 lsisas1068 虚拟成 LSI SAS1068 使用驱动 mptsas 仅支持 2TB 以下硬盘，2TB 以上硬盘系统无法识别，猜测是默认用了 IR 模式 lsisas1078 虚拟成 LSI MegaRAID SAS 1078 使用驱动 megaraid_sas 在 DSM 里可以识别硬盘但无法正常使用，猜测是因为没有启用 JBOD 模式 vmpvscsi 虚拟成 VMware PVSCSI 使用驱动 vmw_pvscsi 需要在 XML 设置里将挂载硬盘的 target 和 unit 的值对调（target 值递增，unit 值为 0），否则会报错 bad scsi device lun 进入 DSM 可正常识别和使用硬盘
Plex + TvHeadend, 在 DSM 7.2 以上版本使用 USB 电视接收棒！
DSM 7.2 版本以上移除了对 USB 电视接收棒的支持，Plex 的 Live TV + DVR 功能也无法使用了。目前网上主流的解决方案就是买个 HDHomeRun，专门用来接受电视信号。 既然手上有电视接收棒，为什么不自制一个 HDHomeRun 呢？查了一下，网上鲜有教程，于是只能自己研究了 首先，要让 USB 电视接收棒能正常使用，需要一台 Ubuntu 电脑（或者虚拟机）。我用的 Ubuntu 22.04 配合 Hauppauge 官方驱动。如果在 DSM 里面开虚拟机的话，需要将 USB 电视接收棒直通给虚拟机。 $ sudo add-apt-repository ppa:b-rad/kernel+mediatree+hauppauge $ sudo apt update && sudo apt install linux-mediatree -y 如果驱动正确安装的话，应该能看到 /dev/dvb 设备。 $ ls /dev/dvb adapter0 然后，Ubuntu 下面安装 TvHeadend，用来做 TV -> IP（将接收下来的电视信号桥接到本地网络）。这里直接用最简单的 Docker 镜像方式，需要事先安装 Docker 环境。 docker run -d \ --name=tvheadend \ -e PUID=1000 \ -e PGID=1000 \ -e TZ=America/Toronto \ -p 9981:9981 \ -p 9982:9982 \ -v /appdata/tvheadend/config:/config \ -v /appdata/tvheadend/recordings:/recordings \ --device /dev/dvb:/dev/dvb \ --restart unless-stopped \ lscr.io/linuxserver/tvheadend:latest 具体 TvHeadend 的配置方法在这里不详细展开了。 由于 Plex 无法支持 TvHeadend 格式，但是可以支持 HDHomeRun 格式，所以这里需要用 Antennas 来做个桥接转换。依旧是用 Docker。这个桥接器可以放在 Ubuntu 下面，也可以放在 DSM 里面。 docker run -d \ --name=antennas \ -p 5004:5004 \ -e ANTENNAS_URL=http://<local-ip>:5004 \ -e TVHEADEND_URL=http://<tvheadend-ip>:9981 \ --restart unless-stopped \ thejf/antennas 去 http://<local-ip>:5004 看一下 Antennas 是否正常启动了，能显示出网页就表示已经正常工作了。 然后在 Plex 里面添加电视来源，需要点击“手动添加 HDHomeRun”，然后用 http://<local-ip>:5004 作为 HDHomeRun 地址。 注意：如果使用 DVA3221 需要用到 GTX1650 硬件转码的话，只能在 DSM 套件中心里面安装 Plex Media Server 并忽略掉更新提示，不能使用 Docker 版本的 PMS。 最后附一个 ATSC-T 频道频率表（仅限北美）。TvHeadend 自带的 mux 列表不完整，会导致无法接收到某些电视台，需要在 mux 设置里面手工把频道补足（只需要补足 7 到 36 频道即可），然后再搜台。
之前因为 Pi-Hole 在家庭网络里的重要地位，甚至导致家庭控制器的 Ubuntu 系统升级推迟了一年。毕竟从 20.04 升级到 22.04 需要大量的重新配置工作。所以，把 Pi-Hole 移到 Docker 里面便成为一个必要的步骤。 之前尝试将设置导出，并且直接创建 Pi-Hole 容器，直接使用导出的设置。但是结果是 FTL 崩溃，不管是 bridge 网络还是 host 网络均以 FTL 崩溃告终。 后来发现，如果把 DHCP 关掉，只用 DNS 部分是没问题的。再进一步，终于找到了解决办法。 1. 清理 DHCP 的 IP 分配租约 IP 租约数据库是放在容器内路径 /etc/pihole/pihole-FTL.db。所以我们只要删了主机端映射目录下的文件就好。 rm /docker/pihole/etc-pihole/pihole-FTL.db 2. （可选）将主机端的 cloudflared 上游解析绑定到所有 IPv4 地址 这个通过向 /etc/cloudflared/config.yml 中加入以下一行即可实现。 proxy-dns-address: 0.0.0.0 3. 确保使用 host 网络并加入 NET_ADMIN 权限 具体 docker 命令可以参考以下示例。 sudo docker run -d \ --name pihole \ -v "/docker/pihole/etc-pihole:/etc/pihole" \ -v "/docker/pihole/etc-dnsmasq.d:/etc/dnsmasq.d" \ -v "/docker/pihole/log:/var/log/pihole" \ --restart=unless-stopped \ -e DNSMASQ_USER=root \ -e FTLCONF_LOCAL_IPV4=192.168.1.1 \ -e TZ="America/Toronto" \ -e DNSMASQ_LISTENING=all \ -e WEB_PORT=8080 \ --cap-add=NET_ADMIN \ --net=host \ pihole/pihole:latest 4. 关掉 DHCPv6 支持 浏览器访问 Pi-Hole 管理界面，在左面导航栏点击“settings”，然后右侧上面选择“DHCP”选项卡，在右面的“Advanced DHCP settings”中，将“Enable IPv6 Support (SLAAC+RA)”一项关掉，拉到页面底部点“save”即可。 5. 有问题，查日志 日志在容器中的 /var/log/pihole 路径下，对应主机端的文件就是 tail /docker/pihole/log/FTL.log
在 Proxmox 环境中使用虚拟 USB 存储设备 + ARPL 引导 DSM（黑群晖）
网上有很多使用 Proxmox + ARPL 的教程，这里不再赘述。但是这些教程都是使用虚拟硬盘来引导 DSM。经研究，Proxmox 底层虚拟技术 QEMU 支持虚拟 USB 存储设备，这样就可以把 ARPL 做成 USB 引导，方便日后在虚拟机和实机（baremetal）之间转换。 首先，安装 PVE。安装完成后从 SSH 登录，下载 ARPL。（本文使用 arpl-i18n） apt install unzip wget https://github.com/wjz304/arpl-i18n/releases/download/23.6.7/arpl-i18n-23.6.7.img.zip unzip arpl-i18n-23.6.7.img.zip 然后，通过网页界面建立虚拟机，注意需要使用以下设置： 机器类型：q35 BIOS类型：OVMF (UEFI) 网卡：vmxnet3 SCSI：VirtIO SCSI 虚拟机建好之后，打开配置文件 nano /etc/pve/qemu-server/100.conf 在文件最开始的地方加入以下内容 args: -drive id=arpl,if=none,file=/root/arpl.img,format=raw,cache=none -device usb-storage,drive=arpl,removable=on,bootindex=1 （其中 file= 后面是 ARPL 镜像文件的位置，需按照实际情况填写。注意不能使用 iso/ 来访问 PVE 的镜像存储区域，只能使用绝对路径） 启动虚拟机，系统会进入 ARPL 引导器。 参考资料：Attach a raw image as a USB disk to the VM
在 Ubuntu 22.04 LTS 中安装 Omada SDN Controller 5.x
Omada SDN Controller 需要以下依赖项 Java JRE 8 MongoDB 安装 Java JRE 8 注意：如果使用 sudo apt-get install -f 安装依赖项，Ubuntu 22.04 会自动安装 Java JRE 11，之后再安装 Omada SDN Controller 会报错找不到 Java VM。所以这里手工安装 Java JRE 8。 $ sudo apt-get install curl openjdk-8-jre-headless jsvc 安装 MongoDB 4.4 因为 Omada SDN Controller 需要低版本的 MongoDB（3.0.0 - 4.5.0），这里安装 MongoDB 4.4。 由于 MangoDB 4.4 需要 libssl1.1 支持，但是 Ubuntu 22.04 LTS 已经去掉了 libssl1.1，所以这里只能手工安装。 $ wget http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.16_amd64.deb $ sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.16_amd64.deb 注意：Jammy 分支下面没有 mangodb-org，所以这里使用 focal 分支。 $ curl -fsSL https://www.mongodb.org/static/pgp/server-4.4.asc | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/mongodb-org-4.4.gpg $ echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list $ sudo apt update && sudo apt install mongodb-org 安装 Omada SDN Controller $ wget https://static.tp-link.com/upload/software/2022/202208/20220822/Omada_SDN_Controller_v5.5.6_Linux_x64.deb $ sudo dpkg -i Omada_SDN_Controller_v5.5.6_Linux_x64.deb 在 UFW 中打开 8088 端口。 $ sudo ufw allow 8088/tcp
起因就是家里两个小家伙总是争抢一台电脑玩游戏，抢不到就唧唧歪歪。想想 Minecraft 也不是什么吃显卡的游戏，目前显卡价格虽然降了一些，但还是很贵。而且 Intel UHD 核显也的确性能拉跨。家里正好躺着一块 Nvidia GT 1030 “亮机卡”，性能足够两个人同时玩 Minecraft。 搜刮了一下互联网，看来我不是第一个研究“把一块显卡掰成两半使用”的人，不仅已经有人实现了，还记录了详细的步骤，另外还有人做了视频教程。 说搞就搞，打开 Kijiji 开始捡垃圾。CPU 得要个强劲的，核心数量优势在 AMD Ryzen 这边，相应的主板就选择 B450，内存 32GB。于是捡了一圈垃圾，又从我的电脑上拆了两条内存，加上刚换下来的电源，组装了这么一台奇怪的机器： AMD Ryzen 7 2700 (8-core, 16-thread) Asrock B450M-HDV R4.0 2x16GB Vulcan T-force 3200MHz Nvidia GT 1030 2GB (D5) 硬件搞定，接下来就是软件部分了。遵照教程，软件使用 Proxmox 7.2 虚拟环境 + Windows 10。 -1. 原理介绍 其实拆分显卡利用的是 Nvidia 给数据中心提供的驱动（破解版），把消费级显卡当作同代核心的商用显卡使用。比如把使用 GP108 核心的 GT 1030（Pascal 架构）识别成 Tesla P40。原教程里面提到，目前只有 Pascal 和 Turing 架构的消费级显卡可以拆分，所以 Ampere 架构的 30 系显卡目前还没法拆分使用。 消费级显卡拆分的最大限制是显存。拆分之后的虚拟显卡可以使用 GPU 全部可用的算力，但是只能使用预先设置好的显存容量。而显存容量又会影响 3D 游戏的渲染性能，所以在装机的时候就要先考虑好究竟买多大显存的显卡。对于我家这种只玩 Minecraft 的情况，就算 2GB 显存对半分，每人 1GB 显存也绰绰有余了。 0. 准备工作 在新窗口/标签页打开 Proxmox 7 vGPU 教程。最好通读一遍，虽然本文记录了详细过程，但是源教程里面还有一些背景知识介绍。 记得去 BIOS/UEFI 里面将所有跟虚拟化有关的项目都打开。 Intel VT-d 或者 AMD SVM IOMMU SR-IOV Above 4G decode + Resizeable BAR 接着安装好 Proxmox 7.2，通过 https:// <ip> :8006 登录管理页面，上传 Windows 10 安装镜像，上传 VirtIO 驱动光盘镜像。 SSH 进入后台，将 apt 源更换为非氪金用户专用地址。 $ mv /etc/apt/sources.list.d/pve-enterprise.list ~ $ echo "deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription" | tee /etc/apt/sources.list.d/pve-no-subscription.list 安装接下来必需的工具包。 apt update && apt upgrade -y apt install -y git build-essential pve-headers-`uname -r` dkms jq cargo mdevctl unzip uuid 1. 设置虚拟化环境 首先，编辑 /etc/default/grub 文件， 根据 CPU 品牌，将 GRUB_CMDLINE_LINUX_DEFAULT 一项改为 # Intel GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt" # AMD GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on iommu=pt" 然后更新 grub。 update-grub 然后，将下面几行添加到 /etc/modules-load.d/modules.conf 最后。 vfio vfio_iommu_type1 vfio_pci vfio_virqfd 再设置一些启动参数。 $ echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modprobe.d/iommu_unsafe_interrupts.conf $ echo "options kvm ignore_msrs=1" > /etc/modprobe.d/kvm.conf $ echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf 更新 initramfs 并重启 $ update-initramfs -u $ reboot 2. 在主机端安装（破解版）显卡驱动 这是先人已经做好的破解版显卡驱动，版本定格在 460.73.01。需要其他版本的话，需要参考原教程里面的 The hard way 部分，给新版驱动打了补丁才能使用。 chmod +x NVIDIA-Linux-x86_64-460.73.01-grid-vgpu-kvm-v5.run ./NVIDIA-Linux-x86_64-460.73.01-grid-vgpu-kvm-v5.run --dkms 然后安装 vgpu_unlock 和对应的启动程序。 $ git clone https://github.com/DualCoder/vgpu_unlock $ chmod -R +x vgpu_unlock $ git clone https://github.com/mbilker/vgpu_unlock-rs.git $ cd vgpu_unlock-rs $ cargo build --release $ cp target/release/libvgpu_unlock_rs.so /lib/nvidia/libvgpu_unlock_rs.so 重启主机加载显卡驱动。 $ reboot 3. 设置虚拟显卡 首先，先生成 UUID，原则是需要拆分几个虚拟显卡，就生成几个 UUID。我这里只生成两个 UUID。打开记事本，把生成的 UUID 粘贴进去，接下来要用。 $ uuid -n 2 接下来，查看一下显卡的 PCI 地址。这个地址在每台机器上都不一样，所以照例粘贴到记事本里面去备用。我的显卡 PCI 地址是 09:00.0，前面多加几个零，记录成 0000:09:00.0。 $ lspci | grep -i nvidia 09:00.0 VGA compatible controller: NVIDIA Corporation GP108 [GeForce GT 1030] (rev a1) 09:00.1 Audio device: NVIDIA Corporation GP108 High Definition Audio Controller (rev a1) 然后查看可用的虚拟显卡预设。 $ mdevctl types 预设的命名规则是：显卡型号-显存容量 使用目的。比如我选的 P40-1Q，就是说这块显卡被识别成 P40，给虚拟显卡分配 1GB 显存，用于工作站。 nvidia-46 Available instances: 0 Device API: vfio-pci Name: GRID P40-1Q Description: num_heads=4, frl_config=60, framebuffer=1024M, max_resolution=5120x2880, max_instance=24 选好了预设之后，就可以创建虚拟显卡了。（-u 后面是 UUID，-p 后面是 PCI 地址，-t 后面是预设） $ mdevctl start -u <uuid> -p 0000:09:00.0 -t nvidia-46 $ mdevctl define -a -u <uuid> 每一个 UUID 都要运行一遍上面两行命令 4. 创建虚拟机 按照正常流程创建虚拟机，注意以下几点： 设置 CPU 的时候，CPU 类型要选择 Host（列表最下面那个） 电脑类型要设置成 q35 BIOS 类型要选择 UEFI SCSI 控制器选择 Default（因为 VirtIO 会造成主机死机） 5. 分配虚拟显卡 编辑虚拟机配置文件，例如 /etc/pve/qemu-server/100.conf，加入下面一行。将 <uuid> 替换成虚拟显卡的 UUID。 args: -device 'vfio-pci,sysfsdev=/sys/bus/mdev/devices/<uuid>,display=off,id=hostpci0.0,bus=ich9-pcie-port-1,addr=0x0.0,x-pci-vendor-id=0x10de,x-pci-device-id=0x1c31' -uuid 00000000-0000-0000-0000-000000000100 然后用同样的方法修改 101, 102, ... 等等虚拟机的配置文件，注意更换虚拟显卡的 UUID。也要注意最后那个一串 0 的虚拟机 UUID 也要跟虚拟机编号对应上。 注意，上面那一行代码会把虚拟显卡标记成 Quadro P2200。若使用 Turing 架构的显卡，需要去原教程里面寻找对应的分配代码（标记成 Quadro RTX6000）. 此时，确认显卡上没有接任何显示器。如果接了显示器，需要拔掉显示器并重启主机。 $ reboot 6. 在虚拟机上安装驱动 去 Nvidia 官网下载对应的 Quadro 驱动（Pascal 架构下载 P2200 驱动，Turing 架构下载 RTX6000 驱动），安装。 在 Windows 设置中开启远程桌面。 注意：如果登录微软账户时使用了验证器而不是输入密码，需要先同步账户密码才能登录远程桌面。在虚拟机中打开命令行，执行下面命令，强制 Windows 从微软账户服务器同步密码。 > runas /u:MicrosoftAccount\<Microsoft account email> cmd.exe 关闭虚拟机电源。 然后在管理页面上找到虚拟机，选择 Hardware，双击 Display，把类型改成 none。 重新启动虚拟机，通过远程桌面登录，确认驱动正常工作。 到这一步，已经可以通过远程桌面运行游戏了。 7. 连接键盘和物理显示器 远程桌面毕竟还需要一台电脑，如果能直接把鼠标和显示器接到虚拟机上，就省了一台远程桌面客户机。 连接键盘很简单，将 USB 接收器插到主机上，然后去虚拟机设置里面选择 Hardware，添加 USB 设备，选择 Use USB Vendor/Device ID，然后在列表里面选择 USB 接收器即可。 连接物理显示器需要一个 USB-to-HDMI 转接器，推荐使用 DisplayLink 方案的转接器，然后用上面的方法把 USB-to-HDMI 转接器直通给虚拟机即可。亚马逊上卖的使用 Fresco Logic 方案的转接器经测试无法工作，该系列转接器的特点是使用了 USB-to-VGA + VGA-to-HDMI 两块芯片。 注意：连接物理显示器之后，首次启动时，显示器会黑屏，这是因为 Windows 系统把挂载在虚拟显卡上的虚拟显示器当成主显示器，而物理显示器则是当成第二显示器。此时要么盲操作登录系统进入桌面，要么按 Win + P 组合键切换显示器。 8. vsync（垂直同步） 在进行 Minecraft 测试时，使用 Win + G 调用 Xbox 覆盖界面发现游戏只有可怜的 30 FPS，同时 CPU 和 GPU 的占用只有区区 20%。这就是传说中的“垂直同步逆向优化”。需要打开 Nvidia 控制面板，在图形设置里面把 vertical sync 设置成 Off（全局强制关闭）。反正 GT 1030 也用不上什么垂直同步嘛。 9. 电源设置 在进行系统测试的时候，发现虚拟机放了一会儿，进入睡眠状态之后就再也活不过来了。这是 Proxmox VE 虚拟机系统的问题，严格说是 Qemu 的问题。需要到虚拟机的 Windows 电源设置里面把进入睡眠状态的时间调整为 Never（永不）。 50. 系统更新 如果更新了 PVE 系统的内核，需要重新使用新内核生成并安装驱动。 # 安装新内核的头文件 $ apt install -y pve-headers-`uname -r` # 重新安装 NVIDIA 驱动 $ ./NVIDIA-Linux-x86_64-460.73.01-grid-vgpu-kvm-v5.run --dkms # 重新安装 vgpu_unlock-rs $ cd vgpu_unlock-rs $ cargo clean $ cargo build --release $ cp target/release/libvgpu_unlock_rs.so /lib/nvidia/libvgpu_unlock_rs.so # 重启系统 $ reboot 51. 更换显卡 如果 460.73.01 驱动也支持新显卡（10xx/16xx/20xx 系列显卡），则不需要重新安装驱动，只需要重新配置虚拟显卡即可。 首先需要移除现有的虚拟显卡。 $ mdevctl list $ mdevctl stop <uuid> $ mdevctl undefine <uuid> 然后根据第 3 步重新设置虚拟显卡。推荐重用之前的 UUID，否则还需要根据第 5 步重新分配虚拟显卡。 如果从显卡从 10xx 升级到 20xx（从 P40 升级到 RTX 6000），则需要根据第 5 步重新设置伪装的硬件识别码，并在虚拟机中更新对应型号的驱动。 99. 后记 从一个点子，开始找资料，捡垃圾，拼好之后调整设置，到实际放到桌子上给娃使用，用了整整一个星期时间。两个小家伙都有了自己的“电脑”，可以同时玩游戏不打架，小家伙们也很高兴。另外还有个好处，现在两个“电脑”可以分开进行家长控制了，之后应该不会再听到“他玩多了我没玩够”的抱怨了。 100. Q&A？ Q：AMD 的显卡能拆分么？ A：目前不能，因为 AMD 没有提供虚拟化驱动。AMD 显卡只能直通（passthrough）。 Q：为啥不用 Aster？ A：的确这个拆分显卡就是 multiseat，但是 Aster 要花钱啊！另外，如果两个人同时玩一个游戏，使用 Aster 还要配沙盒软件 Sandboxie…… Q：为啥不用 Parsec？ A：同上，花钱啊，而且不仅仅是 Parsec 花钱，远程桌面客户端还需要再准备一台电脑。 Q：为啥不用 Hyper-V？ A：因为 Hyper-V 没法给虚拟机接物理显示器，而且还要浪费一个 Windows 序列号。 Q：为什么不直接插两块 GT 1030，全部做直通？这样还能节省 DisplayLink 转接器的花销。 A：主要原因是为了今后升级显卡考虑，升级一块显卡和升级两块显卡的开销差别还是很大的。另外就是主板上的插槽也不够插两块卡的。
本文仅记录 RedPill Tinycore 的设置安装流程。 # Update script and components ./rploader.sh clean now ./rploader.sh update now ./rploader.sh fullupgrade now # Prepair user_config.json # Or, use backup and skip this section ./rploader.sh serialgen DS918+ ./rploader.sh identifyusb now ./rploader.sh satamap now # Add ACPI module for power button ./rploader.sh ext apollolake-7.1.0-42661 add https://raw.githubusercontent.com/pocopico/redpill-load/develop/redpill-acpid/rpext-index.json # Build loader ./rploader.sh build apollolake-7.1.0-42661 # Clean up ./rploader.sh clean now rm -rf /mnt/sdb3/auxfiles rm -rf /home/tc/custom-module # Backup settings ./rploader.sh backup now; user_config.json 示例 { "extra_cmdline": { "pid": "0x0005", "vid": "0x0e0f", "sn": "1780PDN123456", "netif_num": "2", "mac1": "001122334455", "mac2": "001122334456", "SataPortMap": "6", "DiskIdxMap": "00" }, "synoinfo": { "internalportcfg": "0xffff", "maxdisks": "16", "support_bde_internal_10g": "no", "support_disk_compatibility": "no", "support_memory_compatibility": "no" }, "ramdisk_copy": {} }
Ubuntu 环境下 Plex Media Server + TV tuner 设置笔记
Linux 系统下使用 Hauppauge TV tuner 踩了一堆坑。所以我决定单独写一篇文章记录一下各种问题和解决方法。 安装与设置 1. 安装 TV tuner 驱动 Hauppauge 官方给了详细的驱动安装方式，而且还提供了 PPA 源，可以直接通过 apt 安装。 # Ubuntu 20.04 LTS $ sudo add-apt-repository ppa:b-rad/kernel+mediatree+hauppauge $ sudo apt update && sudo apt install linux-hwe-mediatree -y # Ubuntu 22.04 LTS $ sudo add-apt-repository ppa:b-rad/kernel+mediatree+hauppauge $ sudo apt update && sudo apt install linux-mediatree -y 2. 安装 Plex Media Server Plex 官网主页上给出的是 deb 下载，但是经过搜索，找到了 Plex 官方提供的 PPA 源。这里推荐用 PPA 方式安装，方便升级。 # Ubuntu 20.04 LTS $ curl https://downloads.plex.tv/plex-keys/PlexSign.key | sudo apt-key add - $ echo deb https://downloads.plex.tv/repo/deb public main | sudo tee /etc/apt/sources.list.d/plexmediaserver.list $ sudo apt update && sudo apt install plexmediaserver -y # Ubuntu 22.04 LTS $ curl https://downloads.plex.tv/plex-keys/PlexSign.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/plexmediaserver.gpg $ echo deb https://downloads.plex.tv/repo/deb public main | sudo tee /etc/apt/sources.list.d/plexmediaserver.list # If using Intel UHD Graphics, Install Intel Packages # Note: For now, intel-opencl-icd must stay at 21.49.21786. $ wget https://github.com/intel/compute-runtime/releases/download/21.49.21786/intel-gmmlib_21.3.3_amd64.deb $ wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.9441/intel-igc-core_1.0.9441_amd64.deb $ wget https://github.com/intel/intel-graphics-compiler/releases/download/igc-1.0.9441/intel-igc-opencl_1.0.9441_amd64.deb $ wget https://github.com/intel/compute-runtime/releases/download/21.49.21786/intel-opencl-icd_21.49.21786_amd64.deb $ sudo dpkg -i intel-gmmlib_21.3.3_amd64.deb intel-igc-core_1.0.9441_amd64.deb intel-igc-opencl_1.0.9441_amd64.deb intel-opencl-icd_21.49.21786_amd64.deb $ sudo apt-mark hold intel-opencl-icd $ sudo apt update && sudo apt install plexmediaserver -y 3. 确认 TV tuner 正常工作 我这里使用的是 TV tuner for Xbox，实际上就是 WinTV-HVR-955Q 的换壳版本。可以通过 dmesg 确认 TV tuner 的内核驱动工作正常。 $ dmesg | grep -P "(dvb)|(cx231xx)" [ 3.459264] rc rc0: Conexant Hybrid TV (cx231xx) MCE IR no TX (2040:b123) as /devices/pci0000:00/0000:00:17.1/0000:14:00.0/usb3/3-3/3-3:1.0/rc/rc0 [ 3.459347] input: Conexant Hybrid TV (cx231xx) MCE IR no TX (2040:b123) as /devices/pci0000:00/0000:00:17.1/0000:14:00.0/usb3/3-3/3-3:1.0/rc/rc0/input6 [ 3.809380] cx231xx 3-3:1.1: New device Hauppauge Hauppauge Device @ 480 Mbps (2040:b123) with 7 interfaces [ 3.809704] cx231xx 3-3:1.1: Identified as Hauppauge WinTV-HVR-955Q (111401) (card=21) [ 4.037824] cx25840 4-0044: cx23102 A/V decoder found @ 0x88 (cx231xx #0-0) [ 6.266374] cx25840 4-0044: loaded v4l-cx231xx-avcore-01.fw firmware (16382 bytes) [ 6.358990] cx231xx 3-3:1.1: v4l2 driver version 0.0.3 [ 6.538517] cx231xx 3-3:1.1: Registered video device video0 [v4l2] [ 6.538570] cx231xx 3-3:1.1: Registered VBI device vbi0 [ 6.538572] cx231xx 3-3:1.1: video EndPoint Addr 0x84, Alternate settings: 5 [ 6.538574] cx231xx 3-3:1.1: VBI EndPoint Addr 0x85, Alternate settings: 2 [ 6.538575] cx231xx 3-3:1.1: sliced CC EndPoint Addr 0x86, Alternate settings: 2 [ 6.538576] cx231xx 3-3:1.1: TS EndPoint Addr 0x81, Alternate settings: 6 [ 6.538691] usbcore: registered new interface driver cx231xx [ 6.568896] cx231xx 3-3:1.1: audio EndPoint Addr 0x83, Alternate settings: 3 [ 6.568900] cx231xx 3-3:1.1: Cx231xx Audio Extension initialized [ 6.660767] dvbdev: DVB: registering new adapter (cx231xx #0) [ 6.660769] cx231xx 3-3:1.1: DVB: registering adapter 0 frontend 0 (LG Electronics LGDT3306A VSB/QAM Frontend)... [ 6.660771] dvbdev: dvb_create_media_entity: media entity 'LG Electronics LGDT3306A VSB/QAM Frontend' registered. [ 6.661006] dvbdev: dvb_create_media_entity: media entity 'dvb-demux' registered. [ 6.661306] cx231xx 3-3:1.1: Successfully loaded cx231xx-dvb [ 6.661308] cx231xx 3-3:1.1: Cx231xx dvb Extension initialized ESXi 下，如果出现 Error 27 或者 Error 110 之类的，则意味着虚拟化不成功。如果使用 USB 直通可能会被误标记成鼠标设备。推荐使用单独的 PCIe 转 USB 3.0/3.1 卡，然后将整个卡直通给虚拟机使用。 驱动成功之后就可以进入 Plex 的 Live TV & DVR 里面扫描频道了。 给 Plex 录制功能分配临时空间 在使用 Live TV 时，Plex 需要将节目实时录制。此项功能无法关掉，猜测是为了加入暂停和回放功能。虽然在退出 Live TV 的时候，Plex 会自动回收相应的临时存储空间，但是如果要长时间看电视的话，依然要分配足够多的时间给视频录制功能。 这个临时空间是在 设置 -> 转码器（Transcoder） 下面设置的。将 Transcoder temporary directory 设置到一块独立硬盘上面，避免塞满 root 造成系统运行异常。 另外，也有教程指导将转码临时空间设置到内存上去（/dev/shm），这个就要取决于系统内存大小了。毕竟家用服务器上吃内存的服务也挺多的，机械硬盘的写入速度也完全够用，还是放到硬盘上比较好。 重启 TV tuner Live TV 在使用过程中经常会遇到服务崩溃的情况，Plex 官方修了很久也没完全修好。有时候重启 Plex Media Server 服务之后，Live TV 依然报错，这个时候就要重启 TV tuner 了。 首先，找到 TV tuner 所在的 USB 控制器以及接口（USB 树节点）。 $ sudo grep Hauppauge /sys/bus/usb/devices/*/product /sys/bus/usb/devices/3-3/product:Hauppauge Device 然后，通过禁用再重新启用对应的 USB 接口，来重启 TV tuner。 $ sudo systemctl stop plexmediaserver.service $ echo 0 | sudo tee /sys/bus/usb/devices/3-3/authorized 0 $ echo 1 | sudo tee /sys/bus/usb/devices/3-3/authorized 1 $ sudo systemctl start plexmediaserver.service 用这种方式可以单独重启 TV tuner，避免重启整个系统。 重置 PCIe to USB 3.0 转换卡 在使用过程中，我还遇到过完全找不到 TV Tuner 的情况。可以通过重置 PCIe to USB 3.0 转换卡来解决。 首先，找到 USB 卡的 PCI 总线 ID。 $ lspci ... 14:00.0 USB controller: Renesas Technology Corp. uPD720201 USB 3.0 Host Controller (rev 03) ... 然后，重置 PCIe 设备 $ echo 1 | sudo tee /sys/bus/pci/devices/0000\:14\:00.0/remove 1 $ sleep 1 $ echo 1 | sudo tee /sys/bus/pci/rescan 1 然后再通过 dmesg | grep dvb 来确认系统已找到并成功驱动 TV tuner。
盘点那些在 ESXi 虚拟环境下翻车的硬件 （WIP）
折腾家用服务器有一段时间了，期间碰到了各种硬件不兼容、直通失败、驱动不工作等等各类问题。本文总结一下那些曾经翻车的硬件（还有可以正常使用的硬件），仅作为记录。 SATA 控制器 Marvell 88SE92xx - FAIL Marvell 88SE92xx 是一个系列，包括 88SE9210、88SE9215、88SE9230、88SE9235。其中，0 结尾的型号带有 RAID 功能，5 结尾的型号只是普通的 SATA 控制器。 我手上的 88SE9215 在 PCIe 直通之后，UEFI 引导具体故障如下： Linux 内核驱动报错，softreset failed Windows 10 无法启动 据说需要 BIOS 引导模式才可以用，因为需要重装系统，我没有尝试。 ASMedia ASM1061 - MOSTLY FAIL ASM1061 会严重拖慢虚拟机启动。进入系统之后仍需要较长时间才能检测到所有硬盘。 我在测试过程中，有一块 WD Green 1.5TB 硬盘一直报错softreset failed (1st FIS failed)，情况与 88SE9215 一样。猜测是 SATA II (3Gbps) 模式兼容性问题，未进一步证实。 不推荐使用。 JMicron JMB585 - PASS SATA III (6Gbps) 和 SATA II (3Gbps) 的硬盘均能识别和正常使用。 USB 控制器 VIA VL805/VL806 - FAIL VIA 这个芯片很奇怪，PCIe 直通之后驱动程序是可以正常工作的，连在上面的 USB 设备也能正常识别，但是 USB 设备却无法使用，错误代码 110（供电不足）。 网上的说法是要在 grub 设置里加上 iommu=soft，或者干脆关掉 IOMMU。但是虚拟环境需要 IOMMU，所以这个芯片无法在虚拟环境下正常工作。 Renesas/NEC uPD720201 - PASS 经测试，此芯片可通过 PCIe 直通正常工作。
家用存储服务器软件存储阵列方案简单对比
一直在折腾家里的服务器，根据不同服务拆分之后又合并，期间试过了三种比较常见的软件存储阵列方案。先说结论，没有完美的软件存储阵列方案，三种方案都有各自的优缺点。 这三种方案分别是 Windows Storage Spaces ZFS Linux RAID (MD RAID) Windows Storage Spaces（Windows 存储空间） 从名字就能看出来，这是 Windows 系统里特有的软件存储阵列方案，Windows Server 2012 之后的版本都包含的功能，但是在针对消费市场的系统中，只有 Windows 10 Pro 才能使用 Storage Spaces 功能。 Windows Storage Spaces 的运作理念是，首先将硬盘都放在一个池子（Pool）里面，得出一个总容量（存储池容量）。然后，在池子里创建虚拟的硬盘，来进行容量分配。 优点 虚拟硬盘的总量可以大于池容量。比如说系统只有 3 x 4TB = 12TB 的池容量，但是却可以创建一个 20TB 的虚拟硬盘。 WSS 会在池容量填满之后报告存储空间不足。这么做的好处就是可以在数据量增大的过程中逐渐加入新物理硬盘，而不是在一开始的时候就必须提供足够的池空间。另外这也节省了在增加物理硬盘之后，重新分配虚拟硬盘过程中所需的分区数据移动的开销。 可以减少存储池中的硬盘数量。WSS 是三种方案中唯一一个可以缩减物理硬盘数量的方案。在组建存储池时比其他两种方案更灵活。 方便数据恢复。只需要一台 Windows 电脑，就可以读取出物理硬盘里的 Windows 存储空间信息，自动从存储空间中加载虚拟磁盘，自动分配盘符。换句话说，只要物理硬盘中的 Windows 存储空间信息不丢失，系统就会自动重新组建存储空间并加载数据。 缺点 Parity（带冗余校验的）虚拟磁盘写入性能低下。Parity 虚拟硬盘（等同于RAID-5/6）的正常工作状态下写入速度只有 20MB/s 也不奇怪。就算做了分布优化（详情参阅之前的文章），在我的服务器上最快的写入速度也只有不到 100MB/s。 无法对物理硬盘进行编组。在创建虚拟硬盘时，可以设置柱面数量，但是并不能指定对应的物理硬盘。比如服务器有 10 个物理硬盘，现在创建一个 5 柱面的 Parity 虚拟硬盘（4 数据 + 1 冗余），WSS 会根据情况自主把数据分布到 10 个物理硬盘上，并不会先选取 5 个物理硬盘，填满了之后再去填另外 5 个物理磁盘。 ZFS ZFS 其实是一个可以跨平台的软件存储阵列方案。目前市场上最成熟的 ZFS 系统就是 TrueNAS（之前叫 FreeNAS）。另外 Ubuntu 原生支持 ZFS 系统，安装即可用。 严格来说，ZFS 是一个分布在多硬盘上面的文件系统。一般我们接触到的文件系统，都是建立在“硬盘分区（partition）”上面的。但是，ZFS 作为文件系统，直接建立在多个物理硬盘上面，其中也包含了管理物理硬盘的功能。 （注意“文件系统”和“分区”的区别。“分区”只是划拨一块空间，“文件系统”包括文件分配表，即文件存储位置的记录） 优点 读写和管理效率高。因为省略了“池”、“虚拟硬盘”、“分区”这几层，ZFS 直接对物理硬盘操作则省下了很多开销。读写效率基本上能达到 ZFS 中物理硬盘的性能之和。（注：尽管 ZFS 依然把所有加入的物理硬盘称作一个“池（Pool）”，但是 ZFS 池本质上就是一个文件系统） 可以对硬盘进行编组。此功能等同于 RAID-50 之类的既有冗余又使用条带的磁盘阵列，但是更灵活，每一个编组（TrueNAS 中称为“磁盘集”）都可以单独选择冗余方式。比如说，对 10 块物理硬盘进行 8 + 2 编组，第一组 8 块盘使用 RAIDZ2 冗余（等同于 RAID-6），第二组 2 块盘使用镜像方式（mirror）。这样一来，因为空间已被条带化，扩展空间的时候只需要在条带上新增一个编组就可以了。 对不同的子文件系统（存储分区）仅实行配额管理。换句话说，所有的子文件系统都共享整个 ZFS 空间，如果有多个容量不确定的子文件系统，可以让一个子文件系统挤占另外一个子文件系统的空间，达到最大化利用存储空间的目的。也可以对子文件系统进行配额管理，阻止其占用更多空间。 缺点 无法添加或移除单个物理硬盘。因为 ZFS 的最小单位是硬盘编组，所以无法在一个 RAIDz 编组上添加或者删除硬盘，只能对整个编组进行操作。虽然 ZFS 开发人员一直试图加入 RAIDz 扩展功能（目前还没有正式发布，最新进展），但是实际上扩展之后的数据/冗余比例并没有改变。举例来说，现在有 5 块硬盘组成 RAIDz1 编组（4 数据 + 1 冗余），扩充一块物理硬盘之后，依然是 4 数据 + 1 冗余这个比例，只不过分布到了 6 块物理硬盘上。（详情参阅官方文档） Linux 下没有好用的图形化管理工具。这个只是针对不使用 TrueNAS 的用户。毕竟 Linux 可以实现比 TrueNAS 系统更多的功能，所以组建服务器时选用 Linux 也是很正常的决定。但是，目前除了 Cockpit + ZFS manager 插件，我还不知道有什么图形化管理工具能用来方便管理 ZFS 空间。 Linux RAID（MD RAID） 又是从名字就能看出来，这是一个 Linux 下才有的软阵列方案。目前市场上使用 Linux RAID 打造的存储系统，最流行的可能就是群晖 DSM。 Linux RAID 的工作原理是将加入阵列的物理硬盘分区（注意不是硬盘而是分区）组成一个超大的虚拟硬盘，然后再在这个硬盘上分区，划分存储空间。 优点 可以将一个物理硬盘切成小块，加入不同的阵列。由于参与阵列的是硬盘分区，所以对于一个 8TB + 6TB 的硬盘组合，我们可以把 8TB 切成 4TB + 2TB + 2TB，6TB 切成 4TB + 2TB，然后两个 4TB 组成一个阵列，三个 2TB 组成一个阵列。这非常适合家里有一大堆老硬盘，各个硬盘容量又不一样的情况。但是这样一来，也会损失一些冗余，比如上面这个例子，3 x 2TB 分区组成 RAID-5 之后，只要 8TB 硬盘挂了，这个 RAID-5 阵列也就丢了。冗余不够，拿物理硬盘数量来凑。 Linux 都支持。而且在 Linux 启动时会自动扫描并挂载 Linux RAID 阵列中的分区。 可以加入新物理硬盘分区扩展阵列，但是不能减少阵列中的物理硬盘分区的数量。扩展之后相当于组合成的超大硬盘的空间增多了，但是增加的部分都处于未使用状态，这时候需要手动重新调整分区的位置与大小。使用图形化的 Gparted 可以减少手工输入命令，简化分区调整工作。 缺点 操作相对复杂。上面的优点里面也都提到了这个缺点，灵活的应用，也伴随着复杂的操作。虽然可以使用 Cockpit、Gparted 这些图形化工具，但是真正操作起来依然步骤繁琐。（群晖 DSM 做了大量的工作将这些操作流程化，所以 DSM 中的操作才能如此简单） 上面讲了三种软件存储阵列的优缺点。再一次说明一下，并没有完美的存储方案，只能根据实际情况选择最适合的。比如，在我的服务器上，就使用 ZFS 存放电影（因为要最大化利用空间），同时也使用 MD RAID 存放网站数据和个人资料（因为要方便容量扩展）。 P.S. 写这篇文章的时候，我尽量避开了“磁盘”一词，而是以“存储”和“物理硬盘”来明确替代。毕竟现在不仅仅有靠磁性保存数据的硬盘，还有靠电子状态来保存数据的硬盘（SSD 固态硬盘）。
由于实在受不了 Windows Storage Spaces 的读写性能，一拍脑门，转向 Linux。顺便体验一下大红大紫的 ZFS。 说干就干，虚拟机上安装 Ubuntu 20.04 LTS。选择 Ubuntu 是因为用的人多，apt 仓库里可用的软件多。选择 LTS 是因为稳定。照例，ESXi 上新开个虚拟机，很快就安装好了。 接下来就是一些配置。 1. 设置开机自动开启 Vino Server（VNC Server） 先将 Vino 设置为不需要密码就可以连接。 $ gsettings set org.gnome.Vino require-encryption false 然后创建自启动描述文件 $ nano ~/.config/autostart/vino-server.desktop 自启动文件内容如下 [Desktop Entry] Type=Application Name=Vino VNC server Exec=/usr/lib/vino/vino-server NoDisplay=true 参考来源 2. 安装 Cockpit（网页管理前端） 这里我直接选用 45Drives 的仓库，因为要用到他们家的 Samba/NFS 共享管理插件。 $ curl -sSL https://repo.45drives.com/setup | sudo bash $ sudo apt install cockpit cockpit-file-sharing cockpit-zfs-manager cockpit-zfs-manager 会自动安装一个 znapzend（ZFS 自动快照服务），不需要的话可以关掉，否则系统会报告服务启动失败。 $ sudo systemctl disable znapzend.service 安装之后就可以使用 http://localhost:9090/ 来管理服务器了。 3. 修正 mpt2sas 启动参数 基本上所有基于 mpt2sas 的 HBA 卡都会存在启动失败的问题，需要限制内核驱动的 queue size 设置。这是一个已知的 bug。 首先编辑 grub 配置文件 $ sudo nano /etc/default/grub 把 GRUB_CMDLINE_LINUX_DEFAULT 那一行更改为 GRUB_CMDLINE_LINUX_DEFAULT="quiet splash mpt3sas.max_queue_depth=10000" 保存后更新 grub 设置并重启。 $ sudo update-grub 4. 将用户加入 sudo 用户组 虽然从安全角度来讲，不应该给普通用户 sudo 权限，但是如果服务器只用于家庭内网，人人都是超级管理员也没什么大问题。加入 sudo 用户组之后，每次使用 sudo 提权（比如更新系统，更改权限之类的操作）就不需要再输入密码了。 # Ubuntu 20.04 $ sudo usermod -aG sudo <username> # Ubuntu 22.04 $ echo "$USER ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/$USER 5. 为文件添加用户访问权限 Linux 系统中，通常情况下文件访问权限都是通过所有者和用户组来确定的。但是如果我们需要其他特殊账户（例如 www-data 或者 plex 之类的应用软件特定账户）也能访问文件，则需要通过 ACL 来赋予访问权限。 $ sudo apt-get install acl $ sudo setfacl -R -m u:www-data:rwx /path 6. 定位硬盘 如果服务器用了支持 SES 的 SAS 背板，可以点亮硬盘对应的报警灯来定位硬盘。 $ sudo apt-get install ledmon $ sudo ledctl locate=/dev/sdk 安装驱动和软件 Plex Media Server
如何找出黑群晖中的硬盘与实际物理硬盘的对应关系
首先，本文并不是教程，只是记录一下我在黑群晖上爬行的经验。 然后，本文只针对在 ESXi 6.7u3 上，使用 RDM 硬盘直通的黑群晖虚拟机。 最后， 操作有风险！操作有风险！操作有风险！ 重要的事情说三遍！ 黑群晖嘛，既然是黑的，我也不好意思多说什么。对 SAS 支持不好，如果将硬盘通过虚拟 SATA 控制器直通到 DSM 又无法显示原始信息。 这怎么找出对应的物理硬盘嘛！让人抓狂。 然后，想起了 ESXi 里面能看到硬盘分区表，那么如果我在 DSM 里面把硬盘分区表抹掉，这样不就知道到底是对应哪块物理硬盘了么。 如果一个硬盘已经在 DSM 中初始化，那么分区表大概是这样的。 现在要把分区表清理掉。 首先，SSH 进入 DSM，先查看有哪些硬盘 ls /dev/sd? 然后，查看一下存储池都在使用哪些硬盘。 cat /proc/mdstat 其中 md0 和 md1 是系统分区阵列，md2 和 md3 是跟存储池相关的阵列。可以看出，在我这个例子当中，sda 和 sdb 并没有参与到阵列当中，也就是说这两块硬盘是可以安全弹出的。 操作之前先来看一下 /dev/sda 的分区表信息。 sudo fdisk -l /dev/sda 可以看到，这块硬盘上只有两个系统分区，并没有数据分区，也就是已经被初始化，但是没有加入到任何阵列当中。 接下来，清理掉这两块硬盘的分区表。再次声明，此操作有风险，操作不慎会导致数据丢失！ sudo dd if=/dev/zero of=/dev/<sd?> bs=512 count=1 然后，再来看一下清理之后的分区表信息。 分区表已经空啦！ 回到 ESXi 找到那个被清空分区表的硬盘。 然后根据 naa 地址，点亮硬盘灯。 esxcli storage core device set -d <naa_id> -l=locator -L=60 到服务器上就能找到对应的物理硬盘啦！ 提醒一下，使用 RDM 直通的硬盘，不支持热插拔。要更换硬盘必须先彻底关机，而且要在虚拟机设置里将对应的硬盘连带 vmdk 都删掉，然后重新通过 Add raw disk 将新硬盘添加到虚拟机中。
已经稳定运行了很长一段时间的黑群晖 DSM 6.2.3，最近在一起停电事故之后开始了诡异的丢盘现象。 首先先介绍一下黑群晖所在服务器的情况： 虚拟机：ESXi 6.7u3 存储卡：LSI 9207-8i + IBM SAS Expander，通过 PCIe 直通交给虚拟机使用 硬盘：8 x SAS + 2 x SATA，均为 2TB 存储池设置：SHR2（两块盘冗余），9 块盘组成阵列，1 块盘做热备份 问题一开始很简单，丢了两块 SAS 硬盘。停电丢硬盘很正常，既然已经有 1 块盘做热备份，再加一块 2TB 硬盘就完全修复了存储池。 没过几天，又丢了两块 SAS 硬盘。还好使用了 SHR2，没有造成数据丢失。但是家里没有多余的硬盘了，只能赶紧下单，硬着头皮等硬盘到货。 在几次重启之后，居然丢掉的 4 块硬盘回来了！只是带有错误“无法访问系统分区”。然后再重启，又丢失了。这 4 块硬盘就进入了薛定谔状态。 为了排解故障，我还特意把整个虚拟机迁移到另一台服务器上，将 IBM SAS Expander 换成了 Supermicro BPN-SAS-836EL1，结果也一样，4 块薛定谔硬盘随机消失。而且我还注意到了 ESXi 在启动的时候会在加载 lsi_msgpt2/mpt2sas 模块时卡很长时间。后来证明这是 Supermicro BPN-SAS-836EL1 的问题（在混用 SAS 和 SATA 硬盘时会出现卡死），再换到 BPN-SAS-836TQ，虽然走线麻烦，但是这个背板提供从 HBA 到硬盘的直接连接，少了一个扩展卡就少了一个可能出现故障的地方。然后，为了能挂多于 8 块硬盘，我还多加了一块 LSI 9211-8i，将 3 块 SATA 硬盘连到上面，也设置好 PCIe 直通。 重启之后，故障依旧。居然将 SAS 硬盘和 SATA 硬盘区别对待之后，还是一样的故障，证明不是扩展卡问题，HBA 出问题的可能性也不大。最有可能出问题的就是系统了。 这时，我想起来 XPEnology 论坛上，IG-88 大神曾经在他的自制驱动贴子里面提到过，DS918+ 可能缺少组件，导致 mpt2sas 无法正常工作，不管是官方的驱动，还是大神自编译的驱动，都是残血状态，有各种各样的问题（比如开了硬盘休眠就会掉盘之类的）。 于是灵机一动，把 PCIe 直通给撤了，改用 RDM 硬盘直通，并且挂载到虚拟 SATA 控制器上。 开机，4 块硬盘稳稳地归队了，并且再也没有掉过队。至此，问题完美的解决了……一半。 而另外一半问题，就是如何找出 DSM 里面列出的硬盘，到底跟物理硬盘是怎么样的对应关系（换句话说，就是如何找出是哪 4 块硬盘进入了薛定谔状态） 补充说明一下，为了证实确实是 DSM 系统中 mpt2sas 驱动的问题，我尝试将 RDM 硬盘挂载到虚拟 SCSI 控制器上，模式选成 LSI SAS，那 4 块硬盘又进入了薛定谔状态。 目前还不确定到底是 DSM 在驱动 HBA 时就有问题，还是只是在挂载 SAS 硬盘的时候出的问题。如果是前者的话，就算挂载 SATA 硬盘，也会有隐患。可能，最终最完美的解决办法，就是将 DS918+ 换成 DS3617xs。
解决 ESXi 6.7u3 + LSI SAS2308 使用 RDM 时的性能问题
目前我的服务器上用一块 LSI 9207-4i4e (SAS2308) 连接 16 盘位 SAS 背板。这些硬盘分别属于两个虚拟机。所以，无法将整个 LSI 9207-4i4e 直通给任何一个虚拟机使用。这个时候，硬盘直通（RDM，Raw Device Mapping）就是一个非常好的解决方案了。 但是，将硬盘直通给 Windows 10 虚拟机的时候，性能出现了问题。硬盘的读写速度降到了 20MB/s 以下！ 经过几天的摸索，发现问题主要出在 SAS2308 的驱动上。另外，做硬盘直通时的设置可能也影响了读写性能（并不确定）。 首先解决驱动问题。 ESXi 6.7u3 默认使用 lsi_msgpt2 原生驱动，版本 20.00.06.00-2vmw.670.3.73.14320388。所以 reddit 老兄说要将 SAS 卡的固件回退到 20.00.06 版本（最新版本为 20.00.07）。但是刷固件太麻烦了。 于是又翻了一圈，发现可以禁用 lsi_msgpt2，让 ESXi 使用 mpt2sas 驱动。具体步骤如下： 先去下载 mpt2sas version 20.00.00.00.1vmw 然后安装 VIB 包# Enable SSH on ESXi and Upload driver VIB scp mpt2sas-20.00.00.00.1vmw-offline_bundle-2253936.zip root@esxi:/tmp/ # Login to ESXi and install VIB esxcli software vib install -d /tmp/mpt2sas-20.00.00.00.1vmw-offline_bundle-2253936.zip 最后禁用 lsi_msgpt2 驱动esxcli system module set --enabled=false --module=lsi_msgpt2 重启服务器 至于为什么 mpt2sas 的性能比 lsi_msgpt2 要好，这就只能让 LSI 或者 VMware 的工程师来解答了。 驱动解决了之后，还要调整直通控制器的设置。 去虚拟机设置里面，将 SCSI Controller 的虚拟硬件设置为 VMware Paravirtual。 重启虚拟机，硬盘性能问题解决。
为了让服务器更拉风，把主板从 ASRock Z390-Pro4 换成了 Asus Z390-A，这样一来就有 PCIe x8 + x8 + x4 插槽可以插各种卡。但是，机器装好，开机进入 ESXi 6.7 的时候，紫屏崩溃了。报错“Firmware bug: RMRR overlaps system memory”。 网上能查到的解决办法，一种是调整 PCI 子系统让其不占用 4GB 以上的内存空间，另外一种就是升级 BIOS。但是，我这里已经更新了目前最新的 1903 BIOS，依然报错。 仔细看了一下报错原因，是 UEFI 固件里面缺少对主板某些功能的内存预留记录。那是不是说换成功能更少的老固件就可以了呢？ 于是，经过一个版本一个版本的尝试，终于找到了可以成功引导 ESXi 的版本：1602。 顺便记录一下需要注意的设置项目： 将 Intel Virtualization 设置成 Enabled 将 VT-d 设置成 Enabled 将 Decode above 4G memory 设置成 Enabled 将 Memory remap 设置成 Enabled 将 SR-IOV 设置成 Enabled 另外，为了能将 UHD 630 集显直通给 Plex 服务器，我又多插了一张 Zotac ION GT218 亮机卡。这卡的优点是，只需要一个 PCIe x1 插槽。但是，在 BIOS 里面将主显卡设置成 PCIE 之后，开机一长三短提示音报错无法找到显卡。原来这块主板的 BIOS 认为 PCIE 显卡就只能插在那两个 x16 插槽上。后来摸索了半天，找到的解决方案如下 将 Primary graphics 设置成 Auto 将 iGPU Multi-display 设置成 Enabled 打开 CSM 这样就可以使用 PCIe x1 插槽上的亮机卡了。
因为架设在虚拟机上的 Plex Server 需要 Intel UHD 显卡正确驱动才能使用硬件转码，所以服务器上插了一块亮机卡，然后在 ESXi 里面将 Intel UHD Graphics 显卡直通给了 Windows 虚拟机。 但是，虚拟机通过 Windows 更新打上各种驱动之后，Intel UHD 显卡报错代码 43，无法启动。 折腾了一圈，大概发现了问题所在。Intel 显卡驱动程序在 7000（版本号最后四位）版本之后，加入了 CPUID 检查。如果 ESXi 向 Windows 系统报告的是“虚拟处理器”，那么就会造成显卡无法驱动。 所以，通过降级到 v26.20.100.6911 就可以搞定。 但是，真的这么简单吗？非也。 通过降级驱动的方法，的确可以在 Core i7 8700 + Z370 组合上修复 Intel UHD 驱动问题。但是换到 Core i7 8700K + Z390 组合上就不行了。有可能是驱动版本太低了，不支持 Z390 芯片组？ 那么，换了高版本之后就要把真实的 CPUID 报告给虚拟机才行。这时候需要在 .vmx 里面加入下面这个设置（也可以在 ESXi 界面中编辑虚拟机，在 VM Options -> Advanced -> Edit Configuration 里面添加） hypervisor.cpuid.v0 = FALSE 目前为止，一直到 v27.20.100.9466 版本都可以正常驱动 Intel UHD Graphics 630。不知道今后 Intel 会不会再在驱动里面搞些莫名其妙的检查。
最近一直在折腾完全虚拟化的家庭服务器，其中虚拟 Xpenology 一直是一个头疼的问题。按照 Xpenology 论坛给出的虚拟化安装方式，将 loader 做成一块 SATA 硬盘挂载，结果就是在系统更新的时候总会出现代号 13 错误（安装包已损坏）。 另外一个解决方案，先制作实体 USB 启动盘，然后在 ESXi 中将 USB 直通给 Xpenology 虚拟机。但是还要在机器上插一个 U 盘太麻烦，遇到 U 盘故障的话，恢复系统也是一个麻烦事。如果能虚拟 USB 启动盘就好了。但是，ESXi 虚拟机设置里面并没有虚拟 USB 存储设备的选项。 设置页面里面没有，不代表不能做！ 经过几天的研究，终于在 VMware 官方论坛中发现了一个未公开的功能，可以将 vmdk 虚拟盘挂载成 USB 存储设备。 1. 准备 USB 引导盘 >> 懒人包 下载 VMware 专用的 Jun's DSM 6.2 loader 虚拟 USB 引导盘 使用懒人包的话可以跳过下面的分解步骤，直接进行下一步。 >> 分解步骤 首先，下载 Jun's DSM 6.2 loader。 注意，因为 ESXi 虚拟机仅在 UEFI 模式下支持从 USB 存储设备引导系统，所以，在写下这篇文章时，只能选择 1.04b 版本的引导盘。 然后，用 OSFMount 挂载引导盘镜像的第一分区，修改 grub/grub.cfg 文件，写入正确的 USB 设备 VID/PID。 # VMware virtual USB mass storage set vid=0x0e0f set pid=0x0005 如果有正版 Synology DS918+ 的机器序列号和网卡 MAC 地址（旧机器上抄一下），也可以在这一步设好。没有的话可以忽略，在 DSM 系统设置完成之后也可以重新设置序列号和 MAC。 之后，用 StarWind V2V Converter 将引导镜像转成 vmdk 格式。（网上有很多教程） 2. 建立虚拟机 在 ESXi 中建立一个虚拟机，添加 USB 控制器并设置成 USB 3.0 模式。 将虚拟机操作系统选成 Other 4.x or later Linux (64-bit)。 启动模式选择 EFI，去掉 Secure boot，并且勾选 Force BIOS setup 选项。 根据需要设置 SAS 卡直通，或者建立虚拟硬盘。如果使用虚拟硬盘的话，需要将硬盘模式设置成 Independent - persistent，并且挂载到 SATA controller 上面。 虚拟机建立好之后先不要开机。 3. 挂载虚拟 USB 存储设备 在 ESXi 存储管理下面打开 Datastore browser，将 synoboot 上传至虚拟机文件夹。 如果在第 1 步使用 StarWind V2V Converter 转换 vmdk，则需要上传 synoboot.vmdk 和 synoboot-flat.vmdk 两个文件 如果使用懒人包，则需要上传 synoboot.vmdk 和 synoboot.img 两个文件 然后将 .vmx（虚拟机设置文件）下载回本地编辑。 首先确认 .vmx 文件中存在下面一行。没有的话给加到文件最下方。 usb_xhci.present = "TRUE" 在 .vmx 文件最下方加入下面四行。 usb_xhci:3.present = "TRUE" usb_xhci:3.deviceType = "disk" usb_xhci:3.fileName = "synoboot.vmdk" usb_xhci:3.readonly = "FALSE" 保存 .vmx 文件，并上传回 ESXi。 4. 设置从 USB 设备启动 第一次开启虚拟机之后，首先进入 UEFI BIOS 设置界面。选择 Enter setup -> Configure boot option -> Enable or disable boot option。将除了 EFI USB Device 以外的选项都设置成 Disabled。 选择 Commit changes and exit -> Exit the Boot Maintenance Manager -> Reset the system。 虚拟机重启之后会自动从虚拟 U 盘引导系统。然后就可以通过 Synology Web Assistant 查找并设置 NAS 了。 5. 修改序列号和 MAC 地址 在 DSM 上线，完成所有初始化设置（设置用户名/密码）之后，依然可以通过 SSH 后台挂载 synoboot 的方式修改机器序列号和 MAC 地址。 首先，在 DSM 的 控制面板 -> 信息中心 -> 服务 里面开启 SSH。 然后通过 SSH 登录 DSM（可以使用 Windows 命令行、PowerShell 或者 PuTTY）。用户名密码就是之前设置 DSM 时建立的账号。 登录之后先转成 root 账户。密码依旧是刚才的登录密码（不是 root 账户的密码）。 sudo -i 然后挂载 synoboot。 mkdir -p /tmp/synoboot cd /dev mount -t vfat synoboot1 /tmp/synoboot cd /tmp/synoboot 编辑 grub/grub.cfg。 vi grub/grub.cfg 修改下面几行。 set sn=xxxxxxxxxxxx set mac1=001122334455 set mac2=001122334466 重启 DSM 之后会有个 NAS 数据迁移的过程（系统认为已将硬盘移到另外一台 NAS），按照提示操作即可。
如何正确使用 HP 764285-B21 10GbE/40GbE 双口 FlexibleLOM 网卡
在《改造服务器》里面提到 HP 764285-B21 544+FLR-QSFP 10GbE/40GbE 实际上就是定制版的 Mellanox ConnectX-3 Pro 网卡，只是采用了 HP 自己的 FlexibleLOM 接口，无法插到 PCIe 插槽里面直接使用，需要转接。其实已经有前人设计了转接卡，但是估计因为需求太少，没有批量生产。所以只能从 GitHub 下载 PCB 设计，自己去下单定制 PCB。 （实际上我选择了另外一个备选设计） PCB 做好了之后，还要自己焊一个 PCIe x8 插槽上去，成品如下图。 这个时候就可以将 HP 764285-B21 插进机器里面了。 开机先看一下网卡的信息。 设备管理器里面能看到网卡，但是显示是 IPoIB。 应该是网卡的模式不对，再看一下网卡模式。 果然，网卡目前模式设置成了 VPI，如果需要跟其他 Ethernet 网卡互联的话，需要改成 ETH 模式。 这里要说一下这张网卡支持的网络模式 IB（InfiniBand） ETH（Ethernet） VPI（Virtual Protocol Interconnect） 重启之后，再查看一下网卡模式，已经改成了 Ethernet。 而且在设备管理器里面也显示为 Ethernet 网卡了。 然后我想到了一个新玩法：如果将一个端口设置成 Ethernet 模式，另外一个端口设置成 InfiniBand 模式，那么这张网卡不就是一个 Eth/IB 网桥了么。
利用虚拟环境实现家用服务器的（全能）改造
不知不觉间，已经在家里组建了三台服务器 一台运行 Windows 10 Pro 的文件服务器，同时提供 Plex 视频串流 一台运行 Xpenology 的监控服务器，同时做手机照片备份 一台运行了各种服务的综合服务器，提供包括智能家居控制、个人网站等等各项服务 这次又按耐不住，开始折腾第四台服务器了。 改造需求 这次第四台服务器主要为了满足两个需求，一是为移动设备提供 4k HDR 转码服务，二是尝试一下更快的数据传输速度，直接上 10Gbps 网络。 但是，服务器多了费电。之前的 #3 服务器就因为耗电问题，各项服务都陆续转移到其他两台服务器里面去了。所以这次折腾服务器的另外一个目标：整合服务，只留两台服务器。 改造方案 目标有了，行动方案也很清楚了：新服务器替换掉 #1 服务器，将 #2 和 #3 服务器整合。然后在整合之后的 #2 服务器上安装 10Gbps 网卡，制作软交换机（网桥）。 这个方案是根据 #2 和 #3 服务器的配置来制定的。 服务器 #2：Core i7-4790，Dell Inspiron 3647 主板（仅有一条 PCIe x16 插槽和一条 x1 插槽） 服务器 #3：Core i7-4770，Asus ROG G30AK 主板（有三条 PCIe x16 插槽，分别是 x8/x8/x4 模式，和一条 x1 插槽） 整合之后的服务器会使用 Asus ROG G30AK 主板配合 Core i7-4790 处理器。因为四代酷睿已经能很好支持虚拟化技术，可以挂上下列板卡（按插槽顺序），并使用硬件直通分配给各个虚拟机 PCIe x8：LSI 9207-8i SAS 卡（直通给 NAS 虚拟机） PCIe x1：Intel I350-T4 四口千兆网卡（分别直通给：NAS 虚拟机、软交换虚拟机、智能家居虚拟机、杂务虚拟机） PCIe x8：多口万兆网卡（所有端口均直通给软交换虚拟机） PCIe x4：单口或多口万兆网卡（其中一个端口直通给 NAS 虚拟机） 说句题外话，这种组合暴露出普通桌面电脑的弱项：PCIe 通道不够多。Core i7-4790 仅有 16 条 PCIe 3.0 通道，Z97 芯片组仅能扩展出最多 8 个 PCIe 2.0 通道，其中还有一部分要分给主板上的其他设备（板载声卡、网卡等等）。这次插入四张板卡就已经是 Haswell + Z97 平台的极限了，如果要塞入更多卡就只能换成 Xeon 处理器 + 服务器主板了。 之所以要考虑 PCIe 通道数量，是因为扩展卡需要足够的通道数量才不会造成性能瓶颈。比如将 40GbE + 10GbE 网卡插入 PCIe 2.0 x4 插槽仅能获得 5GT/s x 4 = 20GT/s（略少于 20Gbps）带宽，离满速运行所需要的 50Gbps 相去甚远。当然，带宽只要够用就行，实际使用 PCIe x8 插槽最多也就只能达到不超过 40Gbps 速率，但是这个速率已经完全可以满足三台 10Gbps 设备之间的数据交换需求。 回归主题，既然用了硬件直通，那么底层虚拟机 Hypervisor 一定要操作简单、功能强大、最好还要免费。大概答案只有一个：VMware ESXi。 NAS 部分继续使用 Xpenology。软交换机大概可以选比较通用的 OpenWrt。 硬件采购 既然方案已经确定了，接下来就是采购工作。这次照例还是去 eBay 捡垃圾。本着“尝试有风险，一张卡不行就再换一张”的原则，购买了下面几张万兆网卡。 从上到下依次是 Mellanox MHZH29B-XTR ConnectX-2 40GbE (QSFP+) + 10GbE (SFP+) 双口网卡 HP 764285-B21 544+FLR-QSFP 10GbE/40GbE 双口网卡（Mellanox ConnectX-3 Pro） Broadcom NetXtreme II BCM57711 双口 10GbE (SFP+) 网卡 Emulex OneConnect OCe11102-NX 双口 10GbE (SFP+) 网卡 Intel X520-DA1 单口 10GbE (SFP+) 网卡 其中 #2 拿到手之后发现，其使用的是 HP 自己的 FlexibleLOM 插槽规格，看着像是 PCIe 引脚，但是跟标准的 PCIe 3.0 引脚规范还是有区别的，插到主板上不识别，需要 FlexibleLOM to PCIe 转换卡。这部分详见《如何正确使用 HP 764285-B21 10GbE/40GbE 双口 FlexibleLOM 网卡》。 另外，收到的第一张 #1 是坏的，插到机器里只能识别出 Mellanox Technologies MT25408 [ConnectX IB Flash Recovery] (rev b0)，尝试刷写硬件会报 MFE_NO_FLASH_DETECTED 错误（见下图）。于是只能联系卖家更换。好在卖家很痛快地又发了一张卡给我。 2021-04-15 更新： Mellanox ConnectX-2 仅支持 40Gbps InfiniBand 或者 10Gbps Ethernet。如果使用 QSFP+ to SFP+ breakout cable 的话，仅第一个 SFP+ 可以建立 10GbE 连接，其他的 SFP+ 插头不工作。 软件兼容性 板卡线材都拿到手了之后，才发现软件兼容性是一个很让人头疼的问题。因为这些板卡都年代久远，基本上要么属于完全过时不予支持（obsolete），要么已经到支持周期边缘。 ESXi 7.0 不支持 #1 和 #4，需要降级到 ESXi 6.7。 OpenWrt 需要 21 以上版本才能支持这些网卡（后面会说明如何设置）。 Xpenology 目前我在用的 DSM 6.x Loader v1.04b 模拟出来的 DS918+ 环境仅支持 #5。 硬件直通 ESXi 上面设置硬件直通在这里不多做赘述，网上各种教程有很多。 这次硬件直通的经验总结如下： LSI 9207-8i（显示为 LSI2308）可以整体直通给 NAS，这样就不用针对每个硬盘做直通，方便快捷。 Intel I350-T4 可以将不同的端口直通给不同的虚拟机。 Emulex OneConnect OCe11102-NX 也可以将不同的端口直通给不同的虚拟机。 Broadcom NetXtreme II BCM57711 不可以将不同的端口直通给不同的虚拟机，要注意。 网卡直通不需要设置 SR-IOV，只需要将 PCIe 设备直通给虚拟机就好。 而对于“网卡直通给软交换机”和“使用 ESXi 虚拟交换机桥接网卡”之间的性能区别，我并没有花时间做对比，在此也不多做评论。 最终配置清单 把兼容性问题都搞明白了之后，就可以决定到底使用那些硬件了。 PCIe 3.0 x8: LSI 9208-8i 八口 SAS 存储卡 PCIe 2.0 x1: Intel I350-T4 四口 1GbE (RJ45) 网卡 PCIe 3.0 x8: Mellanox MHZH29B-XTR ConnectX-2 40GbE (QSFP+) + 10GbE (SFP+) 双口网卡 PCIe 2.0 x4: Intel X520-DA1 单口 10GbE (SFP+) 网卡 软件方面。 虚拟机：ESXi 6.7 U3 软路由：OpenWRT 定制版（直通：#2 的一个端口，#3） NAS：Xpenology loader v1.04b + DSM 6.2.3（直通：#2 的一个端口，#4） 智能家居：Home Assistant（直通：#2 的一个端口） 科学下载：Ubuntu 20.04 + VPN + qBittorrent（直通：#2 的一个端口） 安装 OpenWRT 在写下本文时，OpenWRT 的最新稳定版本为 19.07.7。然而这个版本对于网卡的支持有限。要支持所有上面的网卡，尤其是 Mellanox ConnectX-2，需要至少 21.xx 版本。所以这里我们需要下载正在开发中的每日生成版本。 启动虚拟机之后，先关掉 DHCP、DNS 和防火墙。 # Disable DHCP and DNS /etc/init.d/dnsmasq disable /etc/init.d/dnsmasq stop # Disable DHCPv6 /etc/init.d/odhcpd disable /etc/init.d/odhcpd stop # Disable firewall /etc/init.d/firewall disable /etc/init.d/firewall stop 之后，设置 IP 地址。（需要重启让设置生效） # vi /etc/config/network config interface 'lan' option proto 'static' option ifname 'eth0' option ipaddr '192.168.x.x' option netmask '255.255.255.0' option gateway '192.168.x.x' option dns '192.168.x.x' option ip6assign '60' 这个版本的 OpenWRT 安装之后是不带网络管理界面的，需要手动安装。各个驱动也需要手动安装。 opkg update opkg install luci opkg install kmod-mlx4-core 各个网卡的驱动程序包名字如下 (Mellanox ConnectX-2) -> kmod-mlx4-core (Broadcom NetXtreme II BCM57711) -> kmod-bnx2x (Emulex OneConnect OCe11102-NX) -> kmod-be2net (Intel X520-DA1) -> kmod-ixgbe Mellanox ConnectX-2 是一块 Ethernet/InfiniBand 双模网卡，这里我需要连接到其他 Ethernet 设备，所以需要在 OpenWRT 加载驱动的时候强制网卡选择 Ethernet 模式。（需要重启让设置生效） # vi /etc/modules.d/mlx4 mlx4_core port_type_array=2,2 mlx4_en 然后，设置网络桥接。（需要重启让设置生效） # vi /etc/config/network config interface 'lan' option proto 'static' option type 'bridge' option ifname 'eth0 eth1 eth2' option ipaddr '192.168.x.x' option netmask '255.255.255.0' option gateway '192.168.x.x' option dns '192.168.x.x' option ip6assign '60' 最后，将 QSFP+ -> 4 x SFP+ breakout cable 插到 Mellanox ConnectX-2 的 QSFP+ 端口上，将其中分出来的一条插到 Intel X520-DA1 的 SFP+ 端口上，在 DSM 里面就能看到 10Gbps 连接了。 跑了一下 iPerf，确认 10Gbps 连接无误。 安装 VMware Tools OpenWRT 下安装 VM Tools。 opkg update opkg install open-vm-tools Ubuntu 下安装 VM Tools。 # On Ubuntu server (without GUI) sudo apt-get install open-vm-tools # On Ubuntu desktop (with GUI) sudo apt-get install open-vm-tools-desktop open-vm-tools DSM 下安装 VM Tools，需要先下载 SPK 软件包，然后再在套件中心里面安装。 插曲：CPU 开盖 在服务器上线试运行的时候，开机之后不久就马上花屏死机。本来以为是散热器没装好，重新安装之后故障依旧。于是意识到，大概是该换 CPU 内部的散热硅脂了。于是从亚马逊搞来一套 CPU 手术工具，打开一看，果然内部散热硅脂已经干掉了。 清理之后重新涂了 Youtube 主播都赞不绝口的 Thermal Grizzly Kryonaut，装好散热器重新上电之后果然 CPU 比以前清爽了很多。空载温度由 40°C 降到了 32°C。 这里要补充说一下，最好选择不导电的散热硅脂，这样就算涂的稍微多一点也不用担心。而且，不管是 CPU 内部的散热硅脂，还是 CPU 和散热器之间的散热硅脂，只要涂的不太少就可以，稍微多涂一些无所谓。对于采用钎焊的 CPU 不推荐开盖换硅脂。 另外还有一种散热改良方案是在开盖之后直接裸露运行（direct die）。这种方式对于散热器的高度和散热性能都有特殊要求。因为不加盖的话，CPU 会比正常状态下矮几个毫米，如果散热器高度不可调的话，这几个毫米的空隙会对散热造成很大影响。
之前曾经写过一篇《为 Windows Server 2012 远程桌面主机配置服务器证书》。当服务器升级到 Windows 10 Pro 之后，发现老方法已经不管用了。于是，查找资料，总结出来适用于 Windows 10 Pro 的证书配置攻略。 首先，依然是申请证书。 然后，导入证书。可以双击证书文件选择导入至“本地计算机”，也可以打开 mmc 用“证书”管理单元进行导入。 之后，在 mmc 证书单元中找到刚刚导入的“服务器证书”，右键点击，选择“所有任务”下面的“管理私钥”。 在权限对话框里面添加“NETWORK SERVICE”用户，并赋给“读取”权限。 打开“注册表编辑器”并定位到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp。添加一个“二进制值” SSLCertificateSHA1Hash，值为证书指纹。 或者，制作一个注册表文件导入指纹。 Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp] "SSLCertificateSHA1Hash"=hex:00,11,22,33,44,55,66,77,88,99,aa,bb,cc,dd,ee,ff... 重启远程桌面服务或者重启服务器。 参考资料：https://superuser.com/a/1093160
自从服务器换装 Windows 10 专业版之后，大部分存储空间的操作都可以通过控制面板搞定（开始菜单内搜索“storage spaces”）。但是有些细节设置在控制面板里面没有，最典型的例子就是“柱面数量”（Number of Columns）。 本文将会记录一些必须要用 PowerShell 搞定的存储空间操作。 背景知识 不同的容错场景。 错误的 Logical Sector Size 可以导致存储池读写效率大幅降低 获取信息 1. 列出现有物理硬盘 Get-PhysicalDisk | Format-Table FriendlyName, MediaType, SerialNumber, UniqueId, Size, CanPool, CannotPoolReason 2. 列出现有虚拟硬盘的柱面数量设置 Get-VirtualDisk | ft FriendlyName, Size, NumberOfColumns 3. 查看存储空间正在执行的后台任务 Get-StorageJob 具体操作 1. 使用正确的 Logical Sector Size 建立存储池 $Disks = Get-PhysicalDisk | ? CanPool | ? MediaType –eq HDD New-StoragePool -FriendlyName "Pool" -StorageSubsystemFriendlyName "Windows Storage*" -PhysicalDisks $Disks -LogicalSectorSizeDefault 4096 在建立存储池之后需要将存储池标记成“带备用电源保护”以提高读写性能 Set-StoragePool -FriendlyName "Pool" -IsPowerProtected $True 2. 新建虚拟硬盘 新建虚拟硬盘时可以加入柱面数量设置 New-VirtualDisk -StoragePoolFriendlyName "Pool" -FriendlyName "New" -Size 1TB -ProvisioningType Thin -ResiliencySettingName "Parity" -NumberOfColumns 5 -PhysicalDiskRedundancy 1 -Interleave 16K NumberOfColumns 就是柱面数量 PhysicalDiskRedundancy 是冗余信息所需的磁盘数量（同时也是柱面数量） Interleave 是每柱面一次性写入数据量（详细请见这里，搜索用户 Apamnapat 的回复，注意格式化虚拟硬盘的时候需要根据 Interleave 来调整 Cluster Size。或者参照下表） 所以，上例中，新建的虚拟硬盘将会分布到 5 块物理硬盘上，并且用其中 1 块存储冗余信息，剩下的 4 块硬盘存储数据。 注：根据个人经验，最好不要让虚拟磁盘横跨所有的物理硬盘。例如有 10 块硬盘的情况下，5 柱面 1 冗余的方案要优于 10 柱面 2 冗余。原因是一旦存储空间出问题，需要转移数据，使用 5 柱面的方案可以将数据先集中在 5 块物理硬盘，然后将闲置的 5 块物理硬盘移除存储池做数据暂存使用，这样灵活性更高。如果使用了 10 柱面方案，则需要将数据完全移出存储池才能着手解决存储空间的问题。 3. 重置硬盘 如果遇到“Insufficient Capacity”原因无法将硬盘加入，需要先重置硬盘。 Reset-PhysicalDisk -FriendlyName "HDD1" 如果几个硬盘都有同样的 FriendlyName，可以用 SerialNumber 来区分 Get-PhysicalDisk -SerialNumber 123456 | Reset-PhysicalDisk 4. 将硬盘加入存储池 如果遇到 0x00000075 错误（无法初始化，提示有其他软件使用硬盘），可以用以下命令将所有闲置硬盘加入存储池 Add-PhysicalDisk -StoragePoolFriendlyName "Pool" -PhysicalDisks (Get-PhysicalDisk -CanPool $True) 如果要将硬盘作为热备份（hot spare）加入存储池，需要在命令中加入 -usage 选项 Add-PhysicalDisk -StoragePoolFriendlyName "Pool" -PhysicalDisks (Get-PhysicalDisk -CanPool $True) -Usage HotSpare 5. 从存储空间中删除物理硬盘 如果需要从存储空间中删除一块物理硬盘，首先要标记硬盘退役 Set-PhysicalDisk -FriendlyName 'HDD1' -Usage Retired 标记之后系统会将硬盘上的数据重新分布到其他硬盘上。等数据转移完成后 Remove-PhysicalDisk -FriendlyName 'HDD1' 6. 重命名硬盘 同型号的硬盘 FriendlyName 都一样，如果想要改名区分，可以用以下命令 Set-PhysicalDisk -UniqueId "ID" -NewFriendlyName "HDD1" 7. 更改“存储空间不足”报警的阈值 Windows 系统默认在存储空间容量达到 70% 以后，如果有动态分配空间的虚拟磁盘（Thin Provision）存在，就会报警“存储空间不足，请添加 x 个硬盘”（英文为：Low capacity）。可以通过以下命令将报警阈值提高到 90%。 Set-StoragePool -FriendlyName "Pool" -ThinProvisioningAlertThresholds 90
家用服务器之网络篇：网络连接聚合 vs 多通道SMB
之前我曾经写过一篇《家用服务器之网络篇：1Gbps已经不够用了！》，里面提到了使用网络连接聚合（LAG，Link Aggregation Group）把四个 1Gbps 的连接合并成一个 4Gbps 的连接。 但是，最近在做网络调试的时候发现，两台都配有 4Gbps 网络连接聚合的服务器，它们之间的通信速度居然只有约 1Gbps！就算使用 802.3ad LACP 作为聚合方式，最高也只能跑到 1Gbps。后来查了资料，发现网络连接聚合的目的 并不是加大点到点通信的带宽， 只是可以增加点到多点通信的能力， 顺便可以提供备用链路 这与我需要的“增大文件传输带宽”目的想去甚远，于是又寄希望于多通道 SMB（SMB Multichannel）。 在 Windows 10 下使用多通道 SMB 非常方便，只要去掉网络连接聚合，让每一块网卡都有自己的 IP 地址，Windows 会自动利用两台电脑之间所有的可用连接来进行文件传输。 从图上看，四块网卡基本上都跑在 500Mbps 左右，总体文件传输速度更是达到了 2100Mbps（2.1Gbps）。这个结果受限于接收方的磁盘写入速度，如果使用了更强劲的 NVMe SSD 或者磁盘阵列，可能传输速度还能更快些。 总结一下，如果要增加文件传输速度，还是需要多通道 SMB。大概唯一的缺点就是要占用大量的 IP 地址，如果网络内设备较多的话，需要好好安排一下 DHCP 预留地址。
家用服务器之网络篇：1Gbps已经不够用了！
1Gbps 真的不够用了吗？或许吧。但是考虑到现在的路由器动不动就 AC1900、AC2600、AC3200，只接一根 gigabit 网线肯定是无法提供那么大带宽的。这时候就需要靠网络连接聚合（LAG，Link Aggregation Group）来提升速度了。原理很简单，一根网线 1Gbps，两跟网线就是 2Gbps，三根网线就是 3Gbps…… 服务器当然也可以这样搞。于是最近热衷于淘垃圾的我，又打开 eBay，在垃圾堆里找了一块四口 gigabit 网卡。 Intel PRO/1000 PT Quad Port LP Server Adapter 是的，这块网卡就是垃圾。网卡本身早就停产了，PCIe 接口还是 1.1 版本的，Intel 官方也从今年开始不再支持这块网卡了。但是能用就行，虽然是 1.1 版本，PCIe 4x 也能提供 10Gbps 的带宽，用来驱动四个 gigabit 连接绰绰有余。 安装驱动 Intel 官方支持页面说最后包含这块网卡驱动的软件版本是 24.0，但实际上这块网卡就没有 Windows 10 驱动。官方 24.0 驱动包里给的是 Windows Server 2008 的驱动，正常来说是无法应用在 Win 10 系统上的。 但是 INF 可以改的啊。把旧版本驱动伪装成支持 Win 10，再重启系统去掉驱动签名验证，安装上 Intel 本家的驱动之后，运行起来没有任何问题。 在交换机端设置连接聚合 我用的是 Netgear 24 口交换机，需要登录到管理页面设置参与聚合的端口。 然后打开连接聚合组。 在服务器端设置连接聚合 由于这块网卡官方已经明确表示在 Windows 10 下面不支持 Teaming 功能，所以也无法按照官方教程在硬件属性页面上设置 Teaming，因为属性页上就没有 Teaming 一项。 好在 Intel 提供了 PowerShell 工具。 首先加载 Intel ANS 模块。 Import-Module -Name "C:\Program Files\Intel\Wired Networking\IntelNetCmdlets\IntelNetCmdlets" 然后设置 Teaming。这里只要把网卡名称复制粘贴上就行。至于 Teaming 的模式，因为我的交换机只支持最基本的静态 LAG，所以我就选了 StaticLinkAggregation。如果交换机支持动态 LAG，也可以使用 IEEE802_3adDynamicLinkAggregation 模式。 Get-IntelNetAdapter New-IntelNetTeam 最后设置首选卡。 Set-IntelNetTeam -TeamName "TeamEthernet" -PrimaryAdapterName "Intel(R) PRO/1000 PT Quad Port LP Server Adapter" -SecondaryAdapterName "Intel(R) PRO/1000 PT Quad Port LP Server Adapter #2" 这样 Teaming 就设置好了。 结局 好了，现在我有一条 4Gbps 的连接了，下面的问题是如何能用满这 4Gbps，看来还需要再开发其他的新玩法。 后续 为什么没有使用 Broadcom 或者 Realtek 的四口网卡？ 因为 Intel 这块网卡便宜啊！ 其实同为 Intel 网卡，其他还能获得官方支持的型号，比如 Intel I350-T4，都要比 PRO/1000 系列网卡贵很多，价格大概是 2-3 倍的关系吧。 运行 PowerShell 时提示必须包括使用 Intel 网络技术的网卡？ 这是因为驱动程序没有正确安装。这块网卡默认安装的是微软提供的驱动程序，需要手动更新为 Intel 驱动。更新之后有时需要重启才能生效。 交换机不支持连接聚合？ 其实还有个折衷的方案：利用 Hyper-V 的虚拟交换机做聚合。这种聚合方式一般是为了提供网络冗余容错，也就是一条连接断掉了还有其他连接可以使用。目的并不是增加网络带宽。 使用这种聚合方式要先启用 Hyper-V 功能，然后使用 PowerShell 命令 New-NetSwitchTeam -Name "以太网组合" -TeamMembers "以太网 2","以太网 3","以太网 4","以太网 5" 注意这里使用的是网络连接名称，而不是网卡名称。 为什么不能用 New-NetLbfoTeam 因为 Windows 10 1809 更新之后去掉了对 LBFO 的支持。
因为嫌之前用的 Asus Z97-C 上面有太多用不到的 PCI 接口（不是 PCIe），而且仅有的一条 PCIe x16 又没办法分成两个 x8 使用，用来做外部扩展的 Dell H310 只能跑在 x4 模式下面，性能损失较大。于是就去 eBay 买了块很便宜的拆机主板 Asus Z97M/G30AK。 首先这款主板是 mATX 尺寸，机箱里就省出三个 PCIe 插槽的位置可以放 HP SAS Expander 卡。其次这款主板上面的四个扩展槽全部都是是 PCIe，而且可以把 x16 分成两个 x8 使用。完美符合我的需求。 但是，有个问题，这主板的 BIOS 没有 NVMe 支持，也没有内置 SLIC（很怀疑之前机器上怎么装的 Windows）。于是，只能通过修改 BIOS，至少加入 NVMe 支持。 备份 BIOS 所需工具：AfuWinX64 afuwinx64.exe G30AK.ROM /O 加入 NVMe 所需工具：UEFITool 通过对比 Z97M 和 Z97-C 的 BIOS，发现 Z97M 缺少了四个跟 NVMe 相关的模块。 GptRecovery Nvme NvmeSmm NVMEINT13 从 Z97-C BIOS 里面抽取上面四个模块，并加到 Z97M BIOS 中 USBINT13 模块下面。 这样 NVMe 支持就加好了。 加入 SLIC 所需工具：PhoenixTool 这方面教程太多了，在这里就不说了。就是强调一下只需要填写以下几项，其他留空。 Manufacturer SLIC KEY：9C134SIMF51GYI8HEDJ2F47ZW 刷写 BIOS 所需工具：AfuWinX64（3.06 版本或更低） Z97M 这款主板带有 BIOS 写入保护，所以改版的 BIOS 没办法通过 EzFlash 刷入。最简单的办法就是利用 AfuWin 的工程模式。 afuwinx64.exe G30AK.ROM /GAN 注意：AfuWin 3.07 版本开始去掉了所有未公开的功能，其中包括/GAN选项。所以只能使用老版本的 AfuWin。 会出现的问题 AfuWinX64 提示文件大小错误 所需工具：UEFITool 遇到这种情况说明修改时没有使用备份 BIOS，而是使用官方 BIOS 文件（.CAP 文件）。要解决这个问题需要对 CAP 进行脱壳处理。 具体做法就是 使用 UEFITools 打开 CAP 文件 右键单击最顶层的 AMI Aptio capsule 选择 Extract body... 另存为 .ROM 文件 网卡的 MAC 地址变成 88-88-88-88-87-88 所需工具：Rufus，EEUpdate 这也是因为没有使用备份 BIOS，造成 MAC 地址被清掉了。要恢复的话，首先要找到正确的 MAC 地址。G30AK 的 MAC 地址写在 ATX 24 针接口侧面的贴纸上。然后根据这个视频教程重新写入 MAC 地址就可以了。（原教程） 其他资料 PhoenixTool 发布页面
经过几年的积攒，服务器的硬盘位终于塞满了。于是再扩展硬盘位就变成了一个问题。 之前一直靠 USB 3.0 外置硬盘盒，但是每个硬盘位都需要至少 $20 扩展成本（买硬盘盒）。而且连接速度和稳定性也不够理想，在将外置硬盘加入存储池时也会遇到各种各样的问题。 直到发现 HP SAS Expander 这块扩展卡之后，这个问题终于能得到比较可靠的解决方法了。（关于扩展卡，详见我之前的文章《家用服务器之存储篇：大规模存储背后的简单实现》） 因为自己拼装一个硬盘架需要各种零件，各个订单的到货时间也都不一样，这将会是一个持续得比较久的工程，所以本文将尝试采用更新记录的方式，边做边更新，看看需要花费多长时间，进行多少尝试，才能完成这么一个硬盘架。 设想 一天，我萌生了一个想法：为什么不利用 SAS 系统的特性，直接做一个 SAS 外置硬盘盒呢？正好我放网络交换机的机架上还有空位，干脆把硬盘盒装到机架上，只需要供电和 SAS 电缆，便可以扩展出很多盘位。 由于机架深度只有 11 英寸，所以只能使用短机箱。 施工 2019/05/14 - 2019/05/15 eBay 正好有个 8% 返点优惠，于是下订单买了 iStarUSA D-118V2-ITX 1U Rackmount 机箱 - $62.14 2x HP SAS Expander - 共 $31.95 Amphenol Mini-SAS Cable 2M Rev. A12 (038-003-787) 数据线 - $25.98 PCIe x16 Riser，用来给 HP SAS Expander 供电 - $10.79 PCIe kickstand，用来固定 HP SAS Expander 卡 - $29.00 12V 迷你供电板（接 5.5/2.5 柱状电源） - $23.17 ATX 电源开关，用来启动电源供电 - $7.61 然后又去亚马逊买了 2x Kingwin Multifunction HDD Rack - 5.25" 尺寸，分为 3.5" 和 2.5" 两个硬盘抽屉 - $46 x 2 + tax = $103.96 设想是将机箱前面板拆下来，摆上两个 Kingwin 硬盘抽屉，剩余空间放置 HP SAS Expander 和电源。 2019/05/16 机箱和硬盘抽屉到货，等其他配件 2019/05/22 正好看见 eBay 上卖二手服务器，直接下单 HP StorageWorks D2D4004fc，2U，12 x 3.5" 盘位 - $148.57 2019/05/28 HP 服务器 和 HP SAS Expander 到货。 挂在服务器上把 HP SAS Expander 升级到最新的 2.10 固件。 然后把服务器的硬盘架拆下来。 这个服务器的硬盘架特别简单，只需要接两个 10 针的电源线和一个 SFF-8484 接口的 SAS 数据线就行。不需要额外接主板信息线。 更新一下外置硬盘架的设计，1U 机箱里面还是放电源和 SAS Expander 卡，上面再加个 2U 硬盘架。这样的话，Kingwin 的硬盘抽屉就无所谓了，可有可无。 2019/05/30 研究了一下服务器硬盘架的电源插头。 按照颜色区分，黄色是 +12V，红色是 +5V，黑色接地，没有 +3.3V，这一点非常好。几个网站上都看了一下，没有找到同样接线方式的电源线，看来只能自制了。 于是去 eBay 买了 20x 10-Pin 5557 插头外壳 - $8.88 200x 5557 插头接线针 - $11.86 2019/06/01 开始安装 SAS Expander 卡和电源了。 把各个零件简单在机箱里排了一下，发现 Kingwin 硬盘抽屉根本放不下。索性不放了，1U 机箱只用来提供电源和数据转接。 2019/06/02 又把 1U 机箱的前面板装上了。既然前面板留出了两个 3.5mm 风扇的位置，那当然要装上风扇了。 加上 SAS Expander 卡和 PCIe Riser 供电板之后，发现悬空，下面还多出大概 1.5cm 的空间。于是拼了一排乐高积木把下面的空间填上了。 考虑了一下硬盘的散热问题。在服务器机箱里，散热是靠硬盘架后面的一排风扇。所以就算硬盘架脱离服务器机箱使用，也还要再加一排风扇。 然后发现之前买的这个迷你 ATX 供电板根本不行，家里最大的 12V 变压器只能提供 150W 电源，而且体积巨大。 去 eBay 刚好看到有 FlexATX 300W 电源清仓，买了。 考虑到 1U 机箱和 HP 服务器硬盘架上面的电源键都是按钮的，所以又去买了一个按钮开关对应的信号板，用来产生持续的开机信号。 今日 eBay 下单 5x PCI slot 80mm 风扇架 - $21.60 4x 3.5mm 风扇 - $10.83 Athena Power 300 Watt FlexATX (AP-MFATX30) Power Supply - $37.88 5V Bistable Relay Switch - $14.34 2019/06/03 本来在亚马逊看好 Arctic F8 80mm 风扇，但是今天突然卖光了。没办法，继续 eBay 下单。 10x 80mm 风扇 - $32.31 因为 Kingwin 的那个硬盘抽屉实在太单薄，放到服务器上也没法用，干脆去给退货了（-$103.96）。 2019/06/05 既然 1U 服务器机箱和硬盘架上面都有 USB 2.0 接口，不能浪费了，于是加了一个集线器。 这次零件都是从亚马逊来的。 SAS SFF-8087 to SFF-8484 连接线 50cm - $12.99 Panel mount USB 2.0 B-to-B 1ft - $8.61 机箱内置 9-pin USB 2.0 集线器 - $9.99 因为那一条 panel mount USB 线是 USB B 工头转母头，所以拿到手自己改装了一下，中间剪断加上四个 2.54mm DuPont 插头，然后插到内置 USB 集线器上面。 顺便记录一下 USB 2.0 的接线。 50cm 的 SAS 连接线有点短，可能需要换线。 2019/06/14 好长时间没更新了，这几天都在等各种零件。现在可算大部分零件都到货了。 首先，先自制了一个 Molex 4-pin (IDE) to HP 10-pin 电源线。 然后，选了一块硬盘装在硬盘托盘上。Toshiba 1TB HDD，已经忘了是哪里来的了。 下面要测试 HP 的硬盘架到底能不能在非 HP 环境下正常工作。如果无法工作的话，就前功尽弃了。 于是用 SAS SFF-8087 to SFF-8484 将硬盘架直连到家用服务器的 SAS 存储控制卡上，接上电源。将硬盘插进去。 开机进 Ubuntu 测试环境，查看 SAS 拓扑结构。 成功了！硬盘架可以正常使用！这一个月以来的努力没有白费！ 好了，接下来要继续折腾这个 1U 机箱了，毕竟最终目标是将外置硬盘整体上机架。 考虑到 HP SAS Expander 卡发热量挺大，所以打算在前面放上三个风扇，增加机箱内部空气流动。 好了，今天先到这里，接下来还要再研究一下硬盘架的风扇怎么弄。 2019/06/15 加了个开关电路板。因为开关按钮按下之后，只会给出一个瞬间信号，并不会保持信号，而供电电源需要一个持续信号。这就需要用继电器来维持这个开关机信号。 2019/06/18 把 1U 机箱的前面板装上看了一下，之前加的三个风扇正好被挡住了，面板上对应的位置并没有开口，于是就决定把三个风扇移到机箱里面。这就需要再做一个风扇架，架住三个风扇。 3D 打印我不会，那么怎么做风扇架呢？小块可拼接的乐高积木是最好的选择。 这里很奢侈地用了一个 10 风扇配电板，因为它便宜嘛。 从前面看的效果是这样的。前面板背后的的这个槽会形成一个风道，空气会从这个风道流入扩展卡区域，给 SAS Expander 卡降温。 前置风扇需要 12V 电源，于是又手工制作了一个机箱电源配电板。把常用的 5V 和 12V 引出来，这样可以方便风扇等等设备直接取电。 而且顺便把电源开关也做上了。插好线之后大概是这样的。 2019/06/23 电源装上了。这电源配的线有点多啊，把 1U 机箱塞满了。然后把各个电源都连好之后，就可以试车了。 整体效果（临时）。 这是继上一次部分测试（验证硬盘架）之后，第一次进行系统测试。这次测试需要验证服务器和外置硬盘架之间可以使用一条 Mini SAS SFF-8088 线缆连接。 这次用来测试的是这块 Kingston SSD。 结果很成功，系统可以检测到硬盘。而且确认了从服务器主机到外置硬盘架之间的数据连接带宽是 4 x 6Gbps = 24Gbps. 2019/07/20 查了一下，硬盘架的固件版本是 1.12，目前最高版本已经到 2.02，所以决定自己手工升级。过程参照之前给 HP SAS Expander 的升级步骤，居然成功了。 之前的 1.12 版本只能建立 1.5Gb/s（SATA I）连接（SATA I 速度），更新到 2.02 之后可以建立 3Gb/s（SATA II）连接了。 2020/01/20 在无风扇运行半年之后，我终于下定决心放弃了外置硬盘架这个方案，改为复活 HP StorageWorks 服务器并将其升级为全功能网络存储服务器。
家用服务器之存储篇：大规模存储背后的简单实现
上一篇《家用服务器之存储篇：选择SATA/SAS控制卡》里面推荐了 Dell PERC H310 这款 SAS/SATA 控制卡。但是一块 Dell H310 只能接 8 块硬盘，两块 Dell H310 加上主板上的 SATA 接口一共能接 20 块硬盘。那么如果多于 20 块硬盘呢？如果以后还要扩展外置存储呢？ 接下来我就要再介绍一个实用的 SAS Expander 扩展卡。 HP SAS Expander Card 这块 HP SAS Expander 扩展卡的配件编号很多，468406-001、487738-001、468405-001、468405-002。eBay 上的售价只要 CAD$16，包邮。 最早的时候，HP 的固件只能提供 SATA 1.5Gb/s（SATA 150，第一代 SATA），也就导致这块卡的性能并不理想。但是升级到 1.52 固件版本之后，这块卡就可以支持 SATA 3Gb/s（SATA 300，第二代 SATA）。这个带宽对于机械硬盘，尤其是 NAS 使用的低转速硬盘，已经绰绰有余。但是 SSD 就不行了。因为受到 SATA 3Gb/s 带宽限制，注定 SSD 没办法跑到满速。 数据接口 卡上一共有 8 个内部 SFF-8087 接口和 1 个外部 SFF-8088 接口。连接控制卡时，可以选择使用单接口连接还是双接口。单接口连接可以提供 24Gb/s 带宽，双接口可以提供 48Gb/s 带宽。剩下的内部接口可以连接 24 到 28 个硬盘。按照机械硬盘平均 150MB/s 读取性能计算，所有硬盘全部满速运行需要 36Gb/s 到 42Gb/s 带宽。也就是说双接口连接完全能满足机械硬盘的带宽需求。 卡上的 1 个外部接口，同样可以提供 24Gb/s 连接外置存储/硬盘盒。就算以后要扩展外部硬盘，也有带宽保证。 供电 这块扩展卡的 PCIe 接口只是供电，并没有数据连接，所以完全可以只用 PCIe Riser 供电，不占用主板上的 PCIe 插槽，或者在组建外置存储时脱离主板独立使用。 固件升级 虽然说 HP 官方声称要升级固件只能通过 HP SmartArray 400 系列控制卡，但是实测 Dell PERC H310 使用 HBA/IT 模式，也可以通过 Linux 升级固件。 上面提到过，自从 1.52 版本固件之后，这块扩展卡就可以支持 SAS 6Gb/s 和 SATA 3Gb/s 模式。最新固件目前为 2.10，估计以后也不会再有固件更新了。 总结 HP SAS Expander 是一块性价比极高的存储扩展卡。超多的接口，不占插槽的供电，是家用服务器上连接大规模机械硬盘阵列的理想选择。 其他资料 Hard Forum 上的一篇跨度长达 10 年的讨论贴
之前家里的服务器一直用着破烂 AMD 推土机架构的 FX-6100，早就看着不爽了，于是这次趁着全家电脑升级，将服务器也升级到四代酷睿。同时也针对服务器最重要的存储部分做了一次彻底的升级。 其实，在此之前，家里服务器陆陆续续用过不少存储方案。本文将记录各种我使用过的存储方案，并一一分析其中的优缺点。 存储方案 家用服务器嘛，最一开始都是仅靠主板的那几个 SATA 接口。最早的时候里面插三四块硬盘就算很多了。但是随着时间的推移，硬盘空间不够用了，最直接的解决办法就是往服务器上堆硬盘。在这过程中，遇到的第一个困难就是主板上 SATA 接口插满了。 1. SATA 扩展卡 对于 SATA 接口不够用，最简单的解决方法，加一块 PCIe SATA 扩展卡。最一开始加装的是基于 ASMedia ASM1061 的扩展卡。后来看到网上说 Marvell 88SE92xx 更稳定，就陆续买了 88SE9230 和 88SE9215 扩展卡。陆陆续续插了三块扩展卡之后，主板插槽又不够用了。 ASMedia ASM1061 使用起来很友好，基本上即插即用，用 Windows 自带的驱动程序就能工作。但是缺点很明显，接口少。一块 ASM1061 卡只能扩展出来 2 x SATA 接口。而且只能用到 PCIe x1 单通道模式，对端口资源也是浪费。 Marvell 88SE9215 好一些，一个 PCIe x1 接口可以扩展出 4 x SATA 接口。但是必须安装驱动。而且 PCIe x1 接口也造成了一定的带宽瓶颈。 Marvell 88SE9230 使用了一个 PCIe x2 接口，也是扩展出 4 x SATA 接口，也是必须安装驱动。相比之下，PCIe x2 的带宽就好多了。但是相应的，因为主板上没有 PCIe x2 接口，所以很可能需要占用一个 PCIe x4 或者 x8 甚至 x16 接口。对于只提供 PCIe x16 和 x1 接口的主板，很有可能插了显卡之后就不能再插 88SE9230 扩展卡了。 此外，市场上还有一些 SATA Port Multiplier。但是因为会造成性能损失，所以并不在我考虑范围之内。 这个时候，有一块扩展卡引起了我的兴趣。 2. IO Crest IO-PCE9215-16I 这块板卡还有另外一个型号，Syba SI-PEX40097。接口使用的 PCIe 2.0 x4，理论上总速率可以达到 5 GT/s x 4 通道 = 2000MB/s 传输速度。卡上通过一个 Pericom 的 PCIe 交换芯片，将一个 x4 总线分成 4 个 x1 总线，然后每个 x1 总线各连一个 88SE9215。所以总共算下来就是一个 PCIe x4 转成 16 x SATA 接口（4 x Mini SAS SFF-8087）。也就是说我只需要一块扩展卡就够了。 至于带宽嘛，2000MB/s 分给 16 个接口，平均每个分到 125MB/s，给机械硬盘（WD Blue/Green）差不多够用了。 但是这块板卡有个最大的问题：贵！一块卡原价要卖到 CAD$250！某天正好看到 Amazon Warehouse Deal 有一个开箱货，只需要 CAD$125，就买回来了。用了一段时间感觉还不错。 3. Dell PERC H310 一个偶然的机会，看到网上有人说家用服务器就买二手 IBM M1015，刷成 LSI 9211-8i IT 模式使用。然后我研究了一下，就去 eBay 买了二手 Dell PERC H310。 这块卡使用 PCIe 2.0 x8 接口，扩展出 8 x SATA（实际卡上是 2 x Mini SAS SFF-8087 接口），带宽多一倍，接口少一半，平均每个 SATA 接口的速率提升到 500MB/s，这已经很接近 SATA III 6Gbps 的速度上限了。 这块卡本身是给服务器设计的，性能好，稳定可靠。Windows 自带驱动，即插即用。 而且，最关键的一点：便宜！一块卡只需要 CAD$36！这样就算我买两块卡，获得同样多的 SATA 接口数量，也只需要 CAD$72，也就是 IO-PCE9215-16I 开箱货的半价。当然首先要保证主板上能插两块 PCie x8 板卡。 再说一下为什么选了 Dell PERC H310 而不是同样使用 SAS2008 芯片的 H200 或者 IBM M1015。一个原因是 H310 的 SAS 接口在后侧，M1015 的 SAS 接口在上方，走线来说 H310 会更方便一些。另外一个原因就是 Dell 给 H310 提供 HBA 固件。就算不刷 LSI 9211-8i，用 Dell 官方固件也能做成 IT 模式。如果不考虑这两点，Dell PERC H200 或者 Fujisu D2607 可能是更经济的选择。 IT 模式：全称 Initiator Target，就是将硬盘信息和数据完全呈现给系统，板卡不会改动任何信息/数据，也不提供硬件 RAID。 性能差别 前面说了 Dell PERC H310 的每个 SATA 接口速率都是 IO Crest IO-PCE9215-16I 的 4 倍。那么具体使用的时候，究竟有多大的性能差别呢？我针对自己的使用场景做了个 benchmark。 我的使用场景很简单，我有一个 8 块机械硬盘（WD Blue/Green）组建的存储池，其中的虚拟硬盘分为 无复原信息 和 5 柱面 Parity 复原（相当于 RAID5） 两种。 硬盘型号 接口 存取速度 ========================================== WD Blue WD60EZRZ SATA 6Gbps 170MB/s WD Blue WD40EZRZ SATA 6Gbps 175MB/s WD Blue WD40EZRZ SATA 6Gbps 175MB/s WD Blue WD40EZRZ SATA 6Gbps 175MB/s WD Green WD20EARX SATA 6Gbps 110MB/s WD Green WD20EARX SATA 6Gbps 110MB/s WD Green WD20EARS SATA 3Gbps 110MB/s WD Green WD15EARX SATA 6Gbps 110MB/s 另外我还有一个 3 块 SSD 组建的存储池，其中的虚拟硬盘用的 3 柱面 Parity 复原。 SSD型号 接口 存取速度 ================================================================== KINGSTON SA400S37240G SATA 6Gbps 500MB/s (read) 350MB/s (write) KINGSTON SA400S37240G SATA 6Gbps 500MB/s (read) 350MB/s (write) KINGSTON SA400S37240G SATA 6Gbps 500MB/s (read) 350MB/s (write) 注：存取速度来源于官方规格说明。 场景 1：机械硬盘，无复原 因为机械硬盘的瓶颈在硬盘本身的存取速度，所以两块卡的结果都差不多。Dell H310 稍微快一点点。最快速度大概就是 WD Green 的上限（110MB/s）。 场景 2：机械硬盘，Parity 复原 5 柱面 Parity 布局是 4 柱面数据 + 1 柱面校验。理论读取速度应该是裸盘的 4 倍。但是这里跑分只有 3 倍左右，而且两边很一致，看样子除了 PCIe x1 接口以外还有其他的瓶颈。 因为 Parity 复原（RAID5）需要在写入时计算并检查校验信息，所以写入速度会很慢。从跑分中也可以看到写入速度对比无复原时大幅下降。Dell H310 的多线程读取比较好，但是写入速度居然不及 IO-PCE9215-16I。 场景 3：SSD，裸盘 因为 SSD 的高速存取特性，SSD 测试才能真正显示出扩展卡的性能。 不出意外，IO-PCE9215-16I 被 PCIe 2.0 x1 带宽所限，SSD 读取和写入均无法达到满速。而 Dell H310 基本上跟主板原生 SATA 接口性能相差无几。 场景 4：SSD，Pairty 复原 加了 Parity 复原之后，读取性能翻倍了。3 柱面 Parity 的布局是 2 柱面数据 + 1 柱面校验。所以读取性能翻倍完全符合预期。 这一次 Dell H310 仍然跟主板原生 SATA 接口性能一致，甚至略高。 然而在这个测试中 IO-PCE9215-16I 却翻车了。不管是将三块硬盘连到同一个 SAS 接口上，还是分别连到三个不同的 SAS 接口上，IO-PCE9215-16I 都会导致磁盘测试卡死（下图）。 小插曲 其一：SSD 丢失 在我测试 Dell PERC H310 的过程中，还发生了一件意外的事情。 我手上有一块 OCZ Vertex 3 SSD，已经很古老了。之前一直连到主板的 SATA 接口上使用。在做第一轮测试的时候，这块 SSD 突然不见了。而且不管是直连主板，还是接到 IO Crest IO-PCE9215-16I 上，都无法找到这块 SSD。 这时候 Windows 存储空间的 parity 复原就开始发挥作用了。在丢失一块硬盘的情况下，虚拟硬盘依然正常工作，数据没有损失。但是测试用的无复原虚拟硬盘就没那么幸运了，在 SSD 消失之后，无复原虚拟硬盘也无法访问了。 我决定死马当活马医，把这块 SSD 连到了 Dell H310 上。然后这块 SSD 居然神奇地复活了，而且至今依然正常工作。 然而，鉴于这块 SSD 目前处于不稳定状态，所以我又去买了两块 Kingston A400（看评论说这块 SSD 是垃圾，但是便宜啊），才重新组建好存储池，完成性能测试。 其二：Dell H310 刷写固件 在第二块 Dell H310 到货之后，我尝试直接在服务器上刷写 IT 固件（Asus Z97-C 主板）。但是在清除原有固件之后，刷写工具就无法操作 H310 卡了。提示错误如下： Failed to initialize PAL 换到 HP EliteDesk 800 G1 SFF 上面就没有问题，刷写很顺利。只是开机报警提示内存问题，需要拔掉所有内存条，只插一条在 DIMM 1 插槽。 看网上说貌似 换到 UEFI 环境刷写 或者 屏蔽SMBus 可能可以解决这个问题。 总结 经过测试之后，可以看出 Dell H310 的性能表现非常出色，加上二手卡的售价优势，对于家用服务器是一个很好的选择。 其他资料 Marvell 88SE9220/9230/9235/9215 Overview Dell PERC H310 Spec
Update 2019/05/26: 由于服务器已换装 Windows 10 做系统，本文将不再更新，缺失的屏幕截图也不会补上。 服务器上的硬盘越来越多，数据也存放得越来越乱。不仅出现了数据跨盘，在硬盘出现问题的时候也容易丢数据。自从发现了 Windows Server 的 Storage Spaces 功能之后，便琢磨将硬盘做成阵列，由系统控制，然后在上面搭建虚拟磁盘，或许是一个很好的解决办法。 无奈 Windows Server 2012 的 Storage Spaces 功能太有限，于是就更新到了 Windows Hyper-V Server 2016。至于原因嘛， 最小化系统，轻便。 原生支持文件共享（SMB/CIFS），其他机器可以直接访问数据。 可以用 Hyper-V 搭载 Linux/Android 等等虚拟机。 （最重要的）免费！ 安装 首先去微软的 Evaluation Center 下载 Windows Hyper-V Server 2016。（其实现在已经有 2019 版，但是因为 Windows 1809 更新出现问题暂时下架了） 这里要注意，虽然语言选择里面有中文，但是还是推荐安装英文版。因为 Hyper-V Server 没有图形界面只有 PowerShell，很多设置都要通过命令行更改，安装中文版的话，例如防火墙规则什么的都是中文版，跟网上找到的各种教程有出入，设置起来比较麻烦。 安装很快，重启进入系统之后，先设置密码，然后果然只有一个命令行和一个服务器设置工具（也是命令行）。 这里首先要确认远程管理和远程桌面都打开，远程桌面可以选择比较低的加密等级（反正局域网环境）。 开启远程管理工具访问权限 远程管理工具包括 服务器管理器（RSAT）、远程防火墙、远程计算机管理和远程磁盘管理。 服务器管理器（RSAT） 首先在服务器端开启 RSAT。在命令行窗口执行命令 PowerShell。然后执行以下命令。 Enable-PSRemoting Enable-WSManCredSSP -Role server 然后再客户端开启远程 RSAT。 Enable-PSRemoting Set-Item WSMan:\localhost\Client\TrustedHosts -Value "<ServerName>" Enable-WSManCredSSP -Role client -DelegateComputer "<ServerName>" Enable-WindowsOptionalFeature -Online -FeatureName:Microsoft-Hyper-V -All cmdkey /add:<ServerName> /user:Administrator /pass 如果服务器和客户端不在域里面而是使用工作组的话，需要在客户端打开 DCOM 匿名访问。首先打开 DCOM 设置。 dcomcnfg.exe 然后找到“组件服务” > “计算机” > “我的电脑”，右键单击“我的电脑”，选择“属性”。 在打开的对话框里选择“COM 安全”选项卡，在“访问权限”下面点击“编辑限制...”按钮。 将“ANONYMOUS LOGON”下面的“远程访问”设置成“允许”。 开启更多的远程管理 在服务器的 PowerShell 窗口里执行。（参考来源） netsh advfirewall set currentprofile settings remotemanagement enable netsh advfirewall firewall set rule group=”Remote Administration” new enable=yes netsh advfirewall firewall set rule group=”File and Printer Sharing” new enable=yes netsh advfirewall firewall set rule group=”Remote Service Management” new enable=yes netsh advfirewall firewall set rule group=”Performance Logs and Alerts” new enable=yes Netsh advfirewall firewall set rule group=”Remote Event Log Management” new enable=yes Netsh advfirewall firewall set rule group=”Remote Scheduled Tasks Management” new enable=yes netsh advfirewall firewall set rule group=”Remote Volume Management” new enable=yes netsh advfirewall firewall set rule group=”Remote Desktop” new enable=yes netsh advfirewall firewall set rule group=”Windows Firewall Remote Management” new enable =yes netsh advfirewall firewall set rule group=”Windows Management Instrumentation (WMI)” new enable =yes net start vds 安装驱动 一般来讲，装完系统之后还需要装一大堆驱动程序，比如主板、声卡、显卡、PCI-SATA 数据卡等等。 这里推荐在其他的电脑上下载驱动，解包，然后通过 U 盘把驱动程序复制到 Hyper-V Server 上。 如果需要在 Hyper-V Server 上下载驱动，需要用以下 PowerShell 指令。 Invoke-WebRequest <URL> -OutFile <FileName> 如果出现无法建立 SSL/TLS 连接，需要先设置安全协议。 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 解包需要用到以下 PowerShell 指令。（更多压缩包方面的指令请参见这里） Expand-Archive -LiteralPath <Zip-File> -DestinationPath <Path> 然后使用 PnPUtil 安装驱动程序。 pnputil -i -a <Driver-INF-File> 安装 GUI 工具 文件管理器推荐 Explorer++ 设置存储池和虚拟磁盘 备份数据 因为硬盘加入存储池的时候会清除其中的数据，所以数据备份还是必要的。 如果在备份数据的时候遇到文件权限问题，可以用以下命令解决。 takeown /f "C:\" /r icacls "C:\" /grant Administrators:F /t 建立存储池 首先将硬盘重新初始化。 在服务器管理工具中，重新扫描存储，然后这块刚刚重新初始化的硬盘就会出现在“原始池（Primordial）”里面了。 在把所有硬盘都重新初始化之后，就可以创建存储池了。 存储池建好之后，新建虚拟磁盘。我比较喜欢 parity 布局，就算是有一块硬盘工作不正常了，也可以根据 parity 尽量将数据恢复出来。精简类型则更有弹性，可以创建名义上比可用空间更多的磁盘。只要先创建一个足够大的虚拟，日后只要不停地加新硬盘，然后把新硬盘添到存储池里，不需要对虚拟磁盘做任何改动。但是虚拟磁盘的名义空间越大，其分配表所需要的空间也就越大。 提高存储池性能 如果虚拟磁盘选择了 parity 布局的话，复制文件的时候会发现速度不稳定，先是速度特别快，然后降为 0，如此往复。要修复这个问题，需要将存储池设为“已有备用电源保护”。 Get-StoragePool Set-StoragePool -FriendlyName <StoragePool> -IsPowerProtected $true 向存储池添加新硬盘 首先，新硬盘也要像之前那样先进行初始化操作。然后通过 RSAT 添加到已存在的存储池中。 添加完之后，虽然可用空间已经增加，但是写入的时候还会出现空间不足的提示。所以这里需要多加一个“重新平衡数据（rebalancing）”的操作。 Optimize-StoragePool -FriendlyName "<PoolName>" 从储存池中删除硬盘 首先，要先将硬盘标记为“Retired”，防止写入新数据。 Get-PhysicalDisk Set-PhysicalDisk -FriendlyName <hdd_name> -Usage Retired 然后，让系统将硬盘上的数据移走。这里要每个虚拟磁盘都执行一遍。 Get-VirtualDisk Repair-VirtualDisk -FriendlyName <vhd_name> 然后在RSAT里面确认硬盘中的数据已经全部移除（已用空间接近于0）。之后从存储池里删除磁盘。 Remove-PhysicalDisk -FriendlyName <hdd_name> 设置共享 建立非管理员用户 如果需要区分各个使用环境的权限（比如限制视频盒子只有读取权限），就需要建立非管理员用户。 $Password = Read-Host -AsSecureString New-LocalUser "<UserName>" -Password $Password -FullName "<FullName>" -Description "<Description>" 如果提示密码不符合复杂性要求，可以用以下命令关闭密码复杂性检查。 secedit /export /cfg c:\secpol.cfg (gc C:\secpol.cfg).replace("PasswordComplexity = 1", "PasswordComplexity = 0") | Out-File C:\secpol.cfg secedit /configure /db c:\windows\security\local.sdb /cfg c:\secpol.cfg /areas SECURITYPOLICY rm -force c:\secpol.cfg -confirm:$false 建立共享 最简单的新建共享的方法就是通过服务器管理器（RSAT） 设置权限 默认的权限是所有人只读，如果需要允许管理员更改内容，需要单独加入规则。
Windows Server 2012 服务器出现这个问题有一段时间了，具体来讲就是一个应用程序打开了服务端口，绑定地址 0.0.0.0 （所有网络接口），防火墙入站设置正确，端口可以通过 localhost 或者 127.0.0.1 访问，但是无法通过局域网 IP 访问。 然后把端口改到 50000 以上又可以访问了。 今天跟这个问题较上劲了，一点一点改端口，然后发现 47000 以下基本上都无法访问，47001 就没问题了。顺着这个线索找到了故障的根本原因：DirectAccess/WinNat 默认占用 6001-47000 端口，用来做 IPv6-to-IPv4 转换。 解决起来也很简单，重新分配一下 WinNat 占用的端口就好了。 Set-NetNatTransitionConfiguration -IPv4AddressPortPool @("192.168.1.100, 10000-47000") 或者干脆卸载 DirectAccess（远程访问角色）。 多说几句，自从使用了 Raspberry Pi（后来改用 Orange Pi）来做家里的 DHCP/DNS/VPN 服务器，家里网络比之前灵活多了。Windows Server 2012 安安心心做文件服务器，各取其所长，各司其职，网络问题也少了很多。
服务器证书，就是用来验证服务器身份，对连接进行加密的关键密钥。 windows server 的远程桌面主机都是默认使用自己签发的证书，所以在远程桌面连接的时候，总会提醒证书不正确。所以，最简单的办法就是用一个由证书签发机构颁发的、真正有效的证书。StartSSL 是个不错的选择。 之前在 Windows Server 2008 R2 当中，可以从“远程桌面会话主机设置”里面更改服务器证书。但是 Windows Server 2012 中却没有这个设置。 在找遍了网络之后，终于找到了比较简单的更换证书方法，一条命令搞定！其中的 THUMBPRINT 就是证书的 sha1 指纹。 wmic /namespace:\\root\cimv2\TerminalServices PATH Win32_TSGeneralSetting Set SSLCertificateSHA1Hash="THUMBPRINT" Update on 2013/08/27 ：恢复这篇文章的时候发现 Google 网页快照原文下面有三个回复。抱歉，数据库丢了没办法把回复给恢复回来了……至于那位问出处的朋友，请点击上面“找到了”三个字…… Update on 2019/01/26 ：在重新配置服务器的时候找到了一个更简单的办法——Microsoft Easy Fix 20151。只需要下载微软官方提供的诊断修复工具，然后导入证书即可。
服务器架好之后，就想着怎样把所有的服务统一管理。My Book 上的 Transmission，主机上的 eMule，还有 MiPony，这些程序都带有用于远程控制的 WebUI。但是这些服务分散在内网的多个机器上，需要设置逆向代理才能从外网统一访问。 首先根据教程安装上 Rewrite 2.0 和 Application Request Routing 2.0。但是，在设置 Rewrite Rule 的之后，远程访问总是报告 404 文件未找到。后来终于找到原因，在 IIS 7.5 上需要用“服务器场（Server Farm）”来引导请求指向。 首先，在新建一个服务器场，就叫做 eMule。这个服务器场只有一个服务器。（由于我的 eMule 远程控制端口开在 5000，所以要先把 httpPort 改成 5000，再点“添加”） 然后，在 Inbound Rewrite Rule 里面选择“指向直服务器场”。 逆向代理的好处不仅仅是中心管理，而且还能使用 SSL 加密连接和 IIS 集成的用户验证，这样可以使远程管理更加安全。 后记：有些时候 Geek == Freak（翻译成中文就叫“沙比”）。本来也想把 uTorrent WebUI 集成进来的，结果发现 uTorrent 的用户验证没办法关掉，而 IIS 7.5 又需要另外一套验证。uTorrent 官网上有很多人建议把用户验证作为可选项，可是得到的回复都是“为了安全起见，俺们不会那么做。否则小白的机器就会被别人控制，所有下载都会被删光光……” 就一个简单的明文验证还叫安全？难道坏蜀黍们就不会嗅探远程密码、得到控制权限么？做个可选项，并且默认启用会死？ 2011/02/06 更新： 终于把 uTorrent 也给设置好了。这里需要耍个小聪明，因为我的服务器使用的是简单密码登录，而 ARR 在做逆向代理的时候，会把 HTTP 头的验证部分也传递过去，所以只需要在 uTorrent 里面把用户名/密码设置成跟登录服务器的一致就可以了。 另外，uTorrent 2.0 以上版本的 WebUI 加入了 Auth Token，这个“安全巧妙”的设计却使用了一种非常傻缺的方法来实现：在 javascript 脚本里面不断请求 http://{host}/gui/?token= 或者http://{host}/gui/token.html。我的转向目录设置为 /utorrent/，所以请求 /gui/ 下面的东西 IIS 理所当然地回复 404 文件未找到。 解决方法也很麻烦，要在 uTorrent 程序配置路径中找到 webui.zip，用 WinZip/WinRAR 将里面的 webui.js.gz 解出来，再用 gunzip 解出 webui.js，把里面的 urlBase（在 3.8.0 中是 guiBase）变量强制改为“./”，再用 gzip 封包，然后替换到 webui.zip 中。到这里还没完，还需要重新启动 uTorrent 才能使更改生效！ 最后，终于把 uTorrent 也整合到中心管理中了。 2011/02/06 另更新： 如果在根节点设置 Rewrite Rule，则必须使用服务器场。如果在某一站点节点设置 Rewrite Rule，可以不使用服务器场，直接填写 http://server-address/service-url 即可。
首先，在讨论标题提出的问题之前，先鄙视一下 Linux！ 好吧，本人 Linux 小白，自认不知好歹，竟然自己在 Western Digital MyBook World Edition 上面装 CUPS。折腾了一整天，终于排除万难，成功打印测试页。期间经历“can't resolve symbol 'stderr'”、“/usr/lib/cups/filter/foomatic-rip failed”、“Job stopped due to filter errors.”、“getopts: not found”等等恐怕各位开源高手都前所未见的错误，但是本 Linux 小白全部克服了！在没有完整文档的情况下克服了！ 过五关斩六将之后，发现 Foomatics 驱动不能挂 Windows 客户端。好吧，咱用 PDF/PS 文件还不成么。无奈强大的 lp/lpr 命令直接“can't resolve symbol 'stderr'”（“老婆”不知错，罢工了，嘿嘿）。又找不到源代码来重新编译 lp/lpr。结局就是一整天的功夫全部白费了。 回归主题。这次麻烦的是 8 年半前买的 HP LaserJet 1000 激光打印机。这打印机没什么问题，这么长时间了一直正常工作，可是 HP 在 2005 年就终止了驱动程序更新。值得一提的是，HP 这款打印机使用了 Hostbase 技术，也就是说由驱动将要打印的页面转换为打印点阵，而打印机只负责打印就可以，无需任何计算。这种变态节省打印机设计复杂度的方案直接导致驱动无法与别的型号通用。 AMD 在 2004 年的时候划时代地推出了 64 位处理器，随后微软也赶时髦，搞了个 64 位操作系统。怎么说这也是科技的进步，可就是 HP 放出一句“我们正在开发 64 为驱动程序”之后就再无下文了。 如今是日历都以 201x 开头的年代，64 位马上就要取代 32 位。前几天组装服务器之后，Windows Server 2008 R2 直接默认安装为 64 位版本。 主板驱动很顺利就装上了。怎么说这块主板也有五六年历史了，正在感叹 Windows Server 2008 R2 对于驱动程序的兼容性真不错，HP LaserJet 1000 驱动直接拒绝安装。 于是，眼睁睁地看着还能正常工作的打印机却派不上用场，扔了可惜，留下来的话也就只能再装一台 Windows XP 电脑连接，如此一来家里真跟开网吧没什么区别了。 这到底是谁的错？HP 做出一台很耐用的打印机，AMD 带动科技发展趋势，微软将最新的科技普及，结果却是打印机再也无法使用了。一句话概括，这打印机跟现代高科技不兼容啊！
经过一个星期不屑不懈的努力，终于把服务器配置完成了。现在服务器的作用更强大了：下载、文件寄存、代码托管、RADIUS。 再次不得不感谢微软，MSDNAA 和 Dream Spark 提供了很多免费的工具：Windows Server 2008 R2 (Standard)、Microsoft SQL Server 2008 (Developer)、Team Foundation Server 2010、Visual Studio 2010 (Ultimate)…… 以下是 6 块硬盘的真相： 神主板：ASUS A8V-MX（竟然驱动程序在 Windows Server 2008 R2 还能正常使用）
粗略算了一下，家里面容量在 1TB 以下的“小硬盘”有好几块，再加上两台淘汰下来的主机，如果只用作下载机实在太浪费了。干脆拼装成一个服务器，顺便把前些日子写的 Windows Phone 7 代码托管上去，自己给自己 create issue、做 bug fix（纯粹没事闲的）。 想了就做，拼拼补补之后，有了这么一台服务器： CPU：AMD 3500+（已服役 5 年半） 内存：DDR 400 / PC 3200，因为内存条兼容问题，暂时为 1GB，正考虑换成 2GB 内存 硬盘 1：IBM 40GB EIDE（已服役 8 年半） 硬盘 2：西数 250GB EIDE（已服役至少 4 年，具体购买日期已经不记得了） 硬盘 3：迈拓 300GB SATA，第 6 代（已服役至少 4 年，具体购买日期已经不记得了） 硬盘 4：迈拓 300GB SATA x 2，第 7 代，RAID 1（已服役 5 年半） 硬盘 5：迈拓 500GB EIDE（已服役至少 3 年，具体购买日期已经不记得了） 读卡器（就是个摆设） 操作系统直接上 Windows Server 2008 R2，加挂 Team Foundation Server 2010。当然，uTorrent 和 Mipony 不能少。