威联通 qnap 硬盘单独休眠

3,558 阅读10分钟

qnap app 安装路径 /share/CACHEDEV1_DATA/.qpkg

背景

  • 机器型号:TS-453DMini
  • QTS 版本:5.0.0.1858

最近入手了 TS-453DMini 还配了一块希捷的8T银河系列企业级硬盘,装上之后发现企业级硬盘运行噪音太大了,于是换成了8T西数红盘Puls,顺便配了一块512G的固态做“系统盘”,一块2t的西数红盘Puls做下载盘。

三块硬盘都使用单一静态卷,所有的软件都放在固态盘中,这样软件运行速度不仅更快,而且固态硬盘不会产生噪音。bt下载等比较伤硬盘的任务都放在2t的西数红盘Puls中,2t的硬盘只有 5400转,噪音比 8T 的 7200 转小很多, 8T西数红盘Puls 作为仓库盘,只存放下载、整理好的文件,降低被使用的频率,减少噪音时间。

然后在系统中开启休眠

image.png

按理说这样配置后,没有任务的情况下,硬盘应该都处于休眠状态才对,但在使用过程中,发现硬盘很难进入休眠模式,反而一直高速旋转,吵个不停。查看硬盘使用情况,发现使用率又很低

image.png

可以看到,除了第一块固态,其余两个机械硬盘根本没什么活动,但两块硬盘却一直处于高速旋转中,噪音很大,这就很奇怪了?

直到我看了这几篇文章

Advanced guide to how I completely silenced my TS-453A

在威联通 NAS 上完美实现硬盘单独休眠

强烈建议使用 admin 账户进行以下操作,可有效减少各种权限不足的问题

原因

QNAP 会默默创建一个内部 RAID-1 系统分区,该分区横跨所有的硬盘,系统会并不断访问该分区,导致任何硬盘都无法休眠。也就是说,只要系统有活动,所有硬盘都无法休眠。

查看硬盘分区和RAID情况

QNAP 会为每一个硬盘创建 5个分区,两个系统分区,两个 linux swap 分区,还有一个是你初始化硬盘时设置的分区

查看硬盘挂载及分区情况

sudo parted /dev/sd号 print
  • parted 是用来对硬盘进行分区和格式化的命令
  • sd 代表磁盘的意思,linux 下的每一块硬盘都被抽象成一个文件,放在/dev/目录下,名称以 sd 开头,后面接一个小写的英文字母,从a开始

例如,以下是我的磁盘及分区情况

sdb   sdb1  sdb2  sdb3  sdb4  sdb5  sdc   sdc1  sdc2  sdc3  sdc4  sdc5  sdd   sdd1  sdd2  sdd3  sdd4  sdd5

由于我曾经拔出了一块硬盘,所以上面没有显示 sda,另外,除了sdb、c、d 外,每个磁盘后面还跟了 1、2、3、4、5,这其实就是上面提到的 5个分区,例如 sdb1,代表 sdb硬盘的第一个分区。

我们想看某块硬盘的整体情况,只需要执行上面的命令就好了,例如

image.png

  • model : 硬盘的型号。也可以用这个来判断这是你的哪一块硬盘
  • Disk : 硬盘编号及大小
  • Disk Flags: 硬盘分区信息
    • Number:分区号
    • Start:开始地址
    • End:结束地址
    • Size:分区大小
    • File system:文件系统

1、4 分区是 qnap 创建的系统分区,2、5是 qnap 创建的 linux swap分区(不知道为什么这块固态硬盘的2号分区没有识别出来是linux swap分区)

同理sdc 、sdd 也一样

image.png

总结

image.png

RAID 情况

一般磁盘完成分区后,就可以使用了,但 qnap 的系统不一样,qnap 的系统不直接使用磁盘分区,而是在分区的基础上在抽象出一层 RAID

image.png

然后在 RAID 上去划分

我们先来看系统中 RAID 的划分情况

sudo mdadm -D /dev/md号
  • mdadm : mdadm 命令是 multiple devices admin 的简称,它是 linux 下的一款标准的软件 RAID 管理工具,可以管理 linux 软 RAID,比如创建、调整、监控 RAID
  • -D:显示 RAID 设备的详细信息
  • /dev/md号 : 跟sd一样,这里的md是 RAID 号

例如我nas中的 md 情况

md1    md13   md2    md256  md3    md321  md322  md9

想查看某个 RAID 的具体情况,可以参考上面的命令,例如

sudo mdadm -D /dev/md13

image.png

  • Raid Level : Raid 的级别,如上是 RAID1
  • State : 对应的磁盘分区及活动状态

可以看出 md13 使用了sdb、c、d的4号分区组成了一个 RAID1

同理 md9 如下

image.png md9 使用了sdb、c、d的1号分区组成了一个 RAID1

而 md9、md13 就是导致磁盘不能休眠的元凶,他们两各自从每一块硬盘上划出一块分区组成 RAID1,组成 RAID1之后,系统在RAID1上读写时,每一块磁盘都会参与。而 md9、md13 又是留给系统用的,导致只要有系统活动,每一块磁盘都旋转,谁也别想休眠。

在看md1、2、3

image.png 可以看到 sdb上的3号分区,也就是用户可以使用的分区,也被组成了raid1,这个raid1下只有它一个分区,这就是我们在初始化硬盘时选择的静态卷后做的操作——创建指定大小的分区,然后用这一个分区组成raid1。

md2、3也一样

image.png

而剩下的 md256、md321、322都是在 linux swap 分区的基础上组 RAID1 image.png

image.png

总结

1639209217187.jpg

解决方案

我们将需要休眠的硬盘“移出” md9 和 md13 RAID,这样系统运行时,就不会影响硬盘休眠了

不要将系统硬盘“移出” md9 和 md13 RAID,系统容易出问题

我想让2T和8T的机械硬盘单独休眠,根据上面的总结图可以得知,需要将 sdc1、sdd1 分区与 md9 断开链接

sudo mdadm -D /dev/md9
sudo mdadm /dev/md9 --fail /dev/sdc1
sudo mdadm /dev/md9 --fail /dev/sdd1
sudo mdadm -D /dev/md9

还需要将 需要将 sdc4、sdd4 分区与 md13 断开链接

sudo mdadm -D /dev/md13
sudo mdadm /dev/md13 --fail /dev/sdc4
sudo mdadm /dev/md13 --fail /dev/sdd4
sudo mdadm -D /dev/md13

之后,静静等待一段时间,让硬盘处于休眠状态

查看硬盘活动状态

sudo hdparm -C /dev/sd号

如果输出 drive state is: active/idle 则表示硬盘是唤醒状态

如果输出 drive state is: standby 则表示硬盘已休眠(低功耗模式)

恢复 RAID

按照网友的说法,一直断开的话,系统可能会出问题,因此最好每天恢复一段时间

sudo mdadm -D /dev/md9
sudo mdadm /dev/md9 --re-add /dev/sdc1
sudo mdadm /dev/md9 --re-add /dev/sdd1
sudo mdadm -D /dev/md9

还需要将 需要将 sdc4、sdd4 分区与 md13 断开链接

sudo mdadm -D /dev/md13
sudo mdadm /dev/md13 --re-add /dev/sdc4
sudo mdadm /dev/md13 --re-add /dev/sdd4
sudo mdadm -D /dev/md13

自动化

以上命令都是手动输入的,很麻烦,我们可以把它们写成脚本

我是放在 /share/Public/sh ,这是在默认的共享文件夹下面建了一个sh文件夹专门用来存放脚本文件,放在这里的好处是,我可以不用ssh登陆机器,直接smb连上去编辑

vi /share/Public/sh/fail_raid1.sh
#!/bin/sh
# fail_raid1.sh(断开系统 RAID1)
mdadm /dev/md9 --fail /dev/sdc1
mdadm /dev/md9 --fail /dev/sdd1

mdadm /dev/md13 --fail /dev/sdc4
mdadm /dev/md13 --fail /dev/sdd4
vi /share/Public/sh/readd_raid1.sh 
#!/bin/sh
# readd_raid1.sh(恢复系统 RAID1)
mdadm /dev/md9 --re-add /dev/sdc1
mdadm /dev/md9 --re-add /dev/sdd1

mdadm /dev/md13 --re-add /dev/sdc4
mdadm /dev/md13 --re-add /dev/sdd4
vi /share/Public/sh/raid1_monitor.sh
#!/bin/sh
# raid1_monitor.sh(监控 HDD 是否休眠)
echo `date '+%Y-%m-%d %H:%M:%S'` 2T  `hdparm -C /dev/sdc | grep state` >> /share/Public/sh/raid1_monitor.log 2>&1
echo `date '+%Y-%m-%d %H:%M:%S'` 8T  `hdparm -C /dev/sdd | grep state` >> /share/Public/sh/raid1_monitor.log 2>&1

记得赋予文件执行权限

sudo chmod 775 fail_raid1.sh
sudo chmod 775 readd_raid1.sh
sudo chmod 775 raid1_monitor.sh
sudo chmod 775 autorun.sh

定时任务

按照网友的说法,一直断开的话,系统可能会出问题,因此最好每天恢复一段时间,我们可以配置一个定时任务,每晚链接30分钟后在断开。

添加定时任务的方式如下(需要使用 admin 账户操作)

echo "0 1 * * * /bin/bash /share/Public/sh/readd_raid1.sh" >> /etc/config/crontab
echo "0 2 * * * /bin/bash /share/Public/sh/fail_raid1.sh" >> /etc/config/crontab
echo "*/30 * * * * /bin/bash /share/Public/sh/raid1_monitor.sh" >> /etc/config/crontab
crontab /etc/config/crontab && /etc/init.d/crond.sh restart
cat /etc/config/crontab | grep '/share/Public/sh/'

以上命令分别对应

  1. 每天 1 点,执行 /share/Public/sh/readd_raid1.sh ,恢复系统 RAID1
  2. 每天 2 点,执行 /share/Public/sh/fail_raid1.sh , 分断开系统 RAID1
  3. 每 30 分钟,执行 /share/Public/sh/raid1_monitor.sh ,检测一次 HDD 是否休眠,结果保存在 raid1_monitor.log 中
  4. 重启 crontab
  5. 查看 crontab

需要注意的是,不要通过 crontab -e 这个方式添加的定时任务,因为 QNAP 的系统内部有一套逻辑会覆盖通过这种方法增加的定时任务

参考文档:Add_items_to_crontab

系统启动任务

有时我们想让系统在重启后自动执行一些任务,可以如下配置

参考Running Your Own Application at Startup

根据官方文档解释 TS-453Dmini 属于 HAL-based Intel and AMD NAS

因此只需如下操作

  1. 先在系统设置里面打开 “启动时运行用户自定义的进程” 选项: image.png

  2. 挂载特殊分区

mkdir /tmp/config
mount $(/sbin/hal_app --get_boot_pd port_id=0)6 /tmp/config

2. 新增启动脚本

vi /tmp/config/autorun.sh

并往文件中加入开机时需要执行的命令。当然,你也可以像我一样,加入如下命令

#!/bin/sh
/bin/bash /share/Public/sh/autorun.sh

然后再在 /share/Public/sh/ 目录下新建 autorun.sh 文件

vi /share/Public/sh/autorun.sh

并在里面添加需要的启动脚本,例如

# 加入 zerotier
zerotier-cli join xxx

之后有新的开机任务也只需要往这个脚本里面加,就不用每次都去 mount 前面那个特殊分区了。

  1. 增加可执行权限
chmod 775 /tmp/config/autorun.sh
chmod 775 /share/Public/sh/autorun.sh

4. 取消挂载

umount /tmp/config

后记(重要)

机器重启之后,硬盘设备号变了

500G固态2T机械8T机械
原来sdbsdcsdd
现在sdbsdcsda

注意,如果发现你的硬盘号不是从a开始的,建议重启后在构建脚本 在使用过程中,添加、取出、更换了硬盘后,都要重启机器,然后重新检查硬盘设备号,并更新脚本

磁盘设备号发生了变动时,只需更新以下3个脚本,以我这次变化为例,只需做如下更改

vi /share/Public/sh/fail_raid1.sh
#!/bin/sh
# fail_raid1.sh(断开系统 RAID1)
mdadm /dev/md9 --fail /dev/sda1
mdadm /dev/md9 --fail /dev/sdc1

mdadm /dev/md13 --fail /dev/sda4
mdadm /dev/md13 --fail /dev/sdc4
vi /share/Public/sh/readd_raid1.sh 
#!/bin/sh
# readd_raid1.sh(恢复系统 RAID1)
mdadm /dev/md9 --re-add /dev/sda1
mdadm /dev/md9 --re-add /dev/sdc1

mdadm /dev/md13 --re-add /dev/sda4
mdadm /dev/md13 --re-add /dev/sdc4
vi /share/Public/sh/raid1_monitor.sh
#!/bin/sh
# raid1_monitor.sh(监控 HDD 是否休眠)
echo `date '+%Y-%m-%d %H:%M:%S'` 2T `hdparm -C /dev/sdc | grep state` >> /share/Public/sh/log/raid1_monitor_`date '+%Y-%m-%d'`.log 2>&1
echo `date '+%Y-%m-%d %H:%M:%S'` 8T `hdparm -C /dev/sda | grep state` >> /share/Public/sh/log/raid1_monitor_`date '+%Y-%m-%d'`.log 2>&1