解决西部数据 C1 门,磁头频繁归位

发布时间 2023-07-11 20:26:00作者: 伞酱酱酱

目前在用的 All in One NAS 上面挂了一块远古时期的 2.5 寸西数 500G 蓝盘存数据,我自己都不记得这款硬盘是哪里来的,也许是之前的笔记本电脑里拆下来的 N 手盘。不过好在它还蛮争气,连续服役这么多年依旧没有坏道。

硬盘在平时经常出现 "啧啧" 的磁头归位声,隔几分钟就有一次,一开始以为是黑群晖的配置没有做好,反复尝试多次后发现不是群晖问题: 硬盘基本不会自行休眠,即使休眠了,也马上会被自己唤醒。其实之前在笔记本上用的时候也有这样的声音,只是当时没特别关注。

所谓的 "C1 门",就是指 SMART 值中的 C1 数据异常,百度说超过 2W 就是中招了,我一看好家伙,已经 5W 多了

(smartctl 读出来的并不是 C1,但是 Windows 下的软件读出来是 C1)

SMART Attributes Data Structure revision number: 16
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x0b00   200   200   051    Old_age   Offline      -       105
  3 Spin_Up_Time            0x0c00   150   143   021    Old_age   Offline      -       1466
  4 Start_Stop_Count        0xb700   093   093   000    Old_age   Offline      -       7450
  5 Reallocated_Sector_Ct   0xb800   200   200   140    Old_age   Offline      -       0
  7 Seek_Error_Rate         0xbb00   200   200   051    Old_age   Offline      -       0
  9 Power_On_Hours          0xbc00   085   085   000    Old_age   Offline      -       11431
 10 Spin_Retry_Count        0xbe00   100   100   051    Old_age   Offline      -       0
 11 Calibration_Retry_Count 0xbf00   100   100   000    Old_age   Offline      -       0
 12 Power_Cycle_Count       0xc000   097   097   000    Old_age   Offline      -       3421
183 Runtime_Bad_Block       0xc100   100   100   000    Old_age   Offline      -       0
184 End-to-End_Error        0xc200   100   100   000    Old_age   Offline      -       0
187 Reported_Uncorrect      0xc300   100   100   000    Old_age   Offline      -       0
188 Command_Timeout         0xc400   100   081   000    Old_age   Offline      -       90195755035
190 Airflow_Temperature_Cel 0xc500   066   046   000    Old_age   Offline      -       34
191 G-Sense_Error_Rate      0xc600   001   001   000    Old_age   Offline      -       390
192 Power-Off_Retract_Count 0xc700   200   200   000    Old_age   Offline      -       417
193 Load_Cycle_Count        0xc800   182   182   000    Old_age   Offline      -       56199
194 Temperature_Celsius     0xf000   109   089   000    Old_age   Offline      -       34
195 Hardware_ECC_Recovered  0xf100   200   200   000    Old_age   Offline      -       0
196 Reallocated_Event_Count 0xf200   200   200   000    Old_age   Offline      -       0
197 Current_Pending_Sector  0xfe00   200   200   000    Old_age   Offline      -       0
198 Offline_Uncorrectable   0x0000   100   253   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x1800   200   200   000    Old_age   Offline      -       0
200 Multi_Zone_Error_Rate   0x0000   100   253   051    Old_age   Offline      -       0
240 Head_Flying_Hours       0x0000   088   088   000    Old_age   Offline      -       9354
241 Total_LBAs_Written      0x0000   200   200   000    Old_age   Offline      -       17932771727
242 Total_LBAs_Read         0x2000   200   200   000    Old_age   Offline      -       18618376569
254 Free_Fall_Sensor        0x0000   200   200   000    Old_age   Offline      -       0

导致问题的原因就是西数的固件有问题,磁头复位间隔设置得太短,导致它频繁回收,可以用 wdidle3 工具修改一下休眠时间。不过 Linux 下并没有 wdidle3 工具,所以要用一个第三方工具修改: idle3-tools

下载源码并编译,得到可执行文件

root@ayabe:~/work/idle3-tools-0.9.1# make
cc -g -O2 -W -Wall -Wbad-function-cast -Wcast-align -Wpointer-arith -Wcast-qual -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -fkeep-inline-functions -Wwrite-strings -Waggregate-return -Wnested-externs -Wtrigraphs    -c -o idle3ctl.o idle3ctl.c
idle3ctl.c:47:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
   47 | int check_WDC_drive()
      |     ^~~~~~~~~~~~~~~
idle3ctl.c:88:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
   88 | int VSC_enable()
      |     ^~~~~~~~~~
idle3ctl.c:112:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
  112 | int VSC_disable()
      |     ^~~~~~~~~~~
idle3ctl.c:136:5: warning: no previous prototype for ‘VSC_send_key’ [-Wmissing-prototypes]
  136 | int VSC_send_key(char rw)
      |     ^~~~~~~~~~~~
idle3ctl.c:166:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
  166 | int VSC_send_write_key()
      |     ^~~~~~~~~~~~~~~~~~
idle3ctl.c:173:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
  173 | int VSC_send_read_key()
      |     ^~~~~~~~~~~~~~~~~
idle3ctl.c:182:5: warning: no previous prototype for ‘VSC_get_timer’ [-Wmissing-prototypes]
  182 | int VSC_get_timer(unsigned char *timer)
      |     ^~~~~~~~~~~~~
idle3ctl.c:213:5: warning: no previous prototype for ‘VSC_set_timer’ [-Wmissing-prototypes]
  213 | int VSC_set_timer(unsigned char timer)
      |     ^~~~~~~~~~~~~
idle3ctl.c:244:6: warning: no previous prototype for ‘cleanup’ [-Wmissing-prototypes]
  244 | void cleanup(void)
      |      ^~~~~~~
idle3ctl.c:252:6: warning: no previous prototype for ‘show_version’ [-Wmissing-prototypes]
  252 | void show_version(void)
      |      ^~~~~~~~~~~~
idle3ctl.c:258:6: warning: no previous prototype for ‘show_usage’ [-Wmissing-prototypes]
  258 | void show_usage(void)
      |      ^~~~~~~~~~
cc -g -O2 -W -Wall -Wbad-function-cast -Wcast-align -Wpointer-arith -Wcast-qual -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -fkeep-inline-functions -Wwrite-strings -Waggregate-return -Wnested-externs -Wtrigraphs    -c -o sgio.o sgio.c
cc -s -o idle3ctl idle3ctl.o sgio.o
#strip idle3ctl

root@ayabe:~/work/idle3-tools-0.9.1# ls -al
total 220
drwxr-xr-x 2 1000 1000  4096 Jul 11 19:58 .
drwxr-xr-x 3 root root  4096 Jul 11 19:57 ..
-rw-r--r-- 1 1000 1000 35148 May 31  2011 COPYING
-rwxr-xr-x 1 root root 26856 Jul 11 19:58 idle3ctl
-rw-r--r-- 1 1000 1000  1726 May 31  2011 idle3ctl.8
-rw-r--r-- 1 1000 1000  9158 May 31  2011 idle3ctl.c
-rw-r--r-- 1 root root 44360 Jul 11 19:58 idle3ctl.o
-rw-r--r-- 1 1000 1000  1821 May 31  2011 Makefile
-rw-r--r-- 1 1000 1000 13625 May 31  2011 sgio.c
-rw-r--r-- 1 1000 1000  5674 May 31  2011 sgio.h
-rw-r--r-- 1 root root 60824 Jul 11 19:58 sgio.o

把休眠等待时间设置为 300 秒

root@ayabe:~/work/idle3-tools-0.9.1# ./idle3ctl -s 300 /dev/sdb
Idle3 timer set to 44 (0x2c)
Please power cycle your drive off and on for the new setting to be taken into account. A reboot will not be enough!

提示我们需要完全关闭电源再启动而不是重启,关闭主机后拔掉电源线,等待半分钟左右再上电就行了