跳到主要内容

威联通硬盘休眠

排查

因为 QNAP 选择将每一块硬盘都分出来两个区块,然后将这部分区块组成了 RAID-1 系统分区,我把他称为两个任务,一个是 /dev/md9 ,另一个是 /dev/md13,也就是说只要任何一块硬盘有读写,那所有硬盘都将不能休眠

我们可以通过命令确认是不是md9和md13的问题。

执行

mdadm -D /dev/md9
0 8 17 0 active sync /dev/sdb1
65 8 1 2 active sync /dev/sda1
mdadm -D /dev/md13
0 8 20 0 active sync /dev/sdb4
65 8 4 2 active sync /dev/sda4

查看 active 项目,可以看到硬盘的1分区和4分区是 active sync 状态,说明确实有这个问题。

下面看一下硬盘分区情况,查看备份程序使用哪些分区。

查看硬盘挂载及分区情况

# parted 是用来对硬盘进行分区和格式化的命令
parted /dev/sda print

Model: WDC WD80EZAZ-11TDBA0 (scsi)
Disk /dev/sda: 8002GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number Start End Size File system Name Flags
1 20.5kB 543MB 543MB ext3 primary
2 543MB 1086MB 543MB linux-swap(v1) primary
3 1086MB 7992GB 7991GB primary
4 7992GB 7993GB 543MB ext3 primary
5 7993GB 8002GB 8554MB linux-swap(v1) primary

硬盘被分成了5个区,第一分区sdc1和其它硬盘组成了raid md9,第四分区sdc4和其它硬盘组成了raid md13。这两个分区是我们要系统raid-1分开的两个分区。

分析

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

然后在 RAID 上去划分卷

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

修复,解除 raid md9 和 raid md13

/share/Public 创建 fail_raid1.shreadd_raid1.sh

文件内容如下

#!/bin/sh
# fail_raid1.sh(断开系统RAID1)
mdadm /dev/md9 --fail /dev/sda1
mdadm /dev/md13 --fail /dev/sda4

#!/bin/sh
# readd_raid1.sh(恢复系统RAID1)
mdadm /dev/md9 --re-add /dev/sda1
mdadm /dev/md13 --re-add /dev/sda4

在 /etc/config 下编辑 crontab 文件加入

# 每天 0 点恢复系统 RAID1
echo "0 0 * * * /share/Public/sh/readd_raid1.sh" >> /etc/config/crontab
# 每天 0 点 15 分恢复系统 RAID1
echo "15 0 * * * /share/Public/sh/fail_raid1.sh" >> /etc/config/crontab
# 每 10 分钟检测 HDD 是否休眠,结果保存在 raid1_monitor.log 中
echo "*/10 * * * * /bin/bash /share/Public/sh/raid1_monitor.sh" >> /etc/config/crontab
# 重启 crontab
crontab /etc/config/crontab && /etc/init.d/crond.sh restart

表示 0 点开始运行备份程序,0点15份解除备份程序。

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

查看硬盘活动状态

hdparm -C /dev/sd号
  • 如果输出 drive state is: active/idle 则表示硬盘是唤醒状态
  • 如果输出 drive state is: standby 则表示硬盘已休眠(低功耗模式)

监控

#!/bin/sh
# raid1_monitor.sh(监控 HDD 是否休眠)
# 写入日志可能会唤醒硬盘,可以写入到内存中
echo `date '+%Y-%m-%d %H:%M:%S'` 8T `hdparm -C /dev/sda | grep state` >> /share/Public/sh/raid1_monitor.log 2>&1

日志写入内存方法

#!/bin/sh
path=/tmp/hdd_status # 放在内存里,防止写入而唤醒硬盘
echo $path
mkdir -p $path
dsk=$(ls /dev/ | grep 'sd[a-z]$') # 硬盘一般是sda sdb sdc以此类推
for t in {1..12}; do
echo $(date +%c)
for i in $dsk; do
echo -n "/dev/$i : "
s=$(hdparm -C /dev/$i | grep "drive state is:" | awk '{print $4}' | awk -F "/" '{print $1}')
if [[ -f "$path/$i.status" ]]; then
st=$(cat $path/$i.status)
else
st=''
touch $path/$i.status
fi
echo $s >$path/$i.status
if [[ $s != $st ]]; then
echo $(date +%c) >>$path/hdparm.log
echo -n "/dev/$i : " >>$path/hdparm.log
echo $s >>$path/hdparm.log
fi
echo $s
done
sleep 5
done
exit

问题

机器重启之后,硬盘设备号可能发生变化。需要修改调整上面脚本中的硬盘编号。