31

When running SMART-Tests using smartmontools, they never finish. I always get "Interrupted (host reset.)" on various different systems and disks, including Debian in x86 and ARM, OS X on x64, with external and internal drives.

Even when run in captive mode with disks all empty (zeroed with dd).

What am I doing wrong?

Giacomo1968
  • 58,727
bot47
  • 1,922

5 Answers5

22

When the drive does not handle any input/output activity during the test, it may go to standby, which raises the Interrupted (host reset) condition. Try to read from the disk at suitable intervals:

while true; do dd if=/dev/disk1 of=/dev/null count=1; sleep 60; done

(replace /dev/disk1 with the appropriate device; reads one sector from that device every 60 seconds until you hit ctrl-c)

This helped in my environment: OS X 10.6.8, WD Elements USB-connected drive, SAT-SMART-driver 0.8.

A captive test should theoretically keep the drive online. Yet the hardware command send by smartctl may time out before the test completes, causing the kernel to reset the link and ending up in the same situation as above (bug #303).

See this thread on the smartmontools-support mailing list for further details. I acknowledge Christian Franke for the insight given here.

Tobu
  • 2,781
sve.g
  • 321
15

A variation on Ari's answer is to use watch, because the smartctl output may in fact be interesting to keep track of the status:

sudo watch -d -n 60 smartctl -a /dev/sdx

This will auto-update the output of smartctl -a every 60 seconds, so you can see how much of the self-test time remains, and highlight the changes (so it's easier to spot that the test is indeed progressing).

Giacomo1968
  • 58,727
7

I tried the solution from sve.g, in my case the I kept finding the external USB drive in sleep mode regardless sometime after starting the test and interrupting it, it seems dd ended up reading from a kernel cache and the cache was large enough for the disk to enter sleep mode.

I noticed that calling smartctl to ask for status was always able to "wake up" the disk. So: this version of the same idea did the trick for me:

sudo bash -c 'while true; do smartctl -a /dev/sdb > /dev/null; sleep 60; done'

After 5 hours the external USB disk is still spinning. For the first time I could see a smartctl long test finish in an external disk.

I believe this solution also has the advantage that the disk heads are not moved unnecesarily every minute. The long run finished almost exactly in the predicted time (the keep-awake script did not add time to the run)

Giacomo1968
  • 58,727
Ari
  • 411
2

The captive test may not work if it takes more than 20 seconds.

Source: ticket #303, titled "In smart test captive mode, extend the timeout as described by the ATA device".

1

As GreatEmerald noted, probing the smart data every few minutes keeps external USB drives from going to sleep. I wrote a script that checks the smart data every 5 minutes, until the test has exited.

I rely on the "Self-test execution status" code to check if the Smart test has completed. This script needs to run as root.

smartctl -a $DEVICE | grep "Self-test execution status" | cut -d "(" -f2 | cut -d ")" -f1 extracts the status code of the self test. This has been tested with smartctl version 7.3

You'll need to edit the line that specifies the device UUID. You can find the UUID of your device using the command ls /dev/disk/by-id

#!/bin/bash

SMART test status reference

240 to 250 - test running

0 - The previous self-test routine completed without error

33 - The self-test routine was interrupted by the host with a hard or soft reset

This script runs a SMART long test and prevents the disk from going to sleep until the test has completed

Probing a drive with smartctl seems to keep it spinning

DEVICE="/dev/disk/by-id/usb-WD_Elements_2621_575835324136314656444C4E-0:0" smartctl -t long $DEVICE >/dev/null 2>&1 STATUS=$(smartctl -a $DEVICE | grep "Self-test execution status" | cut -d "(" -f2 | cut -d ")" -f1)

while [ $STATUS -gt 240 ] do sleep 300 STATUS=$(smartctl -a $DEVICE | grep "Self-test execution status" | cut -d "(" -f2 | cut -d ")" -f1) done

Giacomo1968
  • 58,727