Re: Failing drive? S.M.A.R.T. utilities?

Nicholas J. Leon (nicholas@binary9.net)
Sat, 17 Apr 1999 19:03:36 -0400 (EDT)


On Sat, 17 Apr 1999, Dan Hollis wrote:

# On Sat, 17 Apr 1999, Steve Philp wrote:
# > Are there any utilities which will convert this to
# > usable (for humans) information? Maybe those contain some clues about
# > the problem?

I picked up the following program at some point. It seems to work just
hunky-dory and produces output like:

# smart /dev/hda

Id= 1, Status=11 {PreFailture , OnLine }, Value=200, Threshold= 51,
Passed
Id= 4, Status=18 {Advisory , OnLine }, Value=100, Threshold= 40,
Passed
Id= 5, Status=19 {PreFailture , OnLine }, Value=200, Threshold= 1,
Passed
Id= 10, Status=19 {PreFailture , OnLine }, Value=100, Threshold= 51,
Passed
Id= 11, Status=19 {PreFailture , OnLine }, Value=100, Threshold= 51,
Passed
Id=199, Status=10 {Advisory , OnLine }, Value=200, Threshold= 0,
Passed
Id=200, Status= 9 {PreFailture , OffLine}, Value=200, Threshold= 51,
Passed
OffLineStatus=4 {Suspended}, AutoOffLine=No, OffLineTimeout=32 minutes
OffLineCapability=3 {Immediate Auto SuspendOnCmd}
SmartRevision=5, CheckSum=212, SmartCapability=2 { AutoSave}

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <linux/hdreg.h>
#include <linux/types.h>

#define NR_ATTRIBUTES 30

typedef struct threshold_s {
__u8 id;
__u8 threshold;
__u8 reserved[10];
} __attribute__ ((packed)) threshold_t;

typedef struct thresholds_s {
__u16 revision;
threshold_t thresholds[NR_ATTRIBUTES];
__u8 reserved[18];
__u8 vendor[131];
__u8 checksum;
} __attribute__ ((packed)) thresholds_t;

typedef struct value_s {
__u8 id;
__u16 status;
__u8 value;
__u8 vendor[8];
} __attribute__ ((packed)) value_t;

typedef struct values_s {
__u16 revision;
value_t values[NR_ATTRIBUTES];
__u8 offline_status;
__u8 vendor1;
__u16 offline_timeout;
__u8 vendor2;
__u8 offline_capability;
__u16 smart_capability;
__u8 reserved[16];
__u8 vendor[125];
__u8 checksum;
} __attribute__ ((packed)) values_t;

#define NR_OFFLINE_TEXTS 5
struct {
__u8 value;
char *text;
} offline_status_text[NR_OFFLINE_TEXTS] = {
{ 0x00, "NeverStarted" },
{ 0x02, "Completed" },
{ 0x04, "Suspended" },
{ 0x05, "Aborted" },
{ 0x06, "Failed" }
};

int fd;
values_t values;
thresholds_t thresholds;

static char *get_offline_text(int status)
{
int i;

for (i = 0; i < NR_OFFLINE_TEXTS; i++)
if (offline_status_text[i].value == status)
return offline_status_text[i].text;
return "unknown";
}

static void smart_read_values(void)
{
__u8 args[4 + 512] = {WIN_SMART, 0, SMART_READ_VALUES, 1, };

if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
perror(" couldn't read values");
return;
}
memcpy(&values, args + 4, 512);
}

static void print_value(value_t *p, threshold_t *t)
{
if (!p->id || !t->id || p->id != t->id)
return;
printf("Id=%3d, Status=%2d {%s , %s}, Value=%3d, Threshold=%3d, %s\n", p->id, p->status,
p->status & 1 ? "PreFailture" : "Advisory ",
p->status & 2 ? "OnLine " : "OffLine",
p->value, t->threshold,
p->value > t->threshold ? "Passed" : "Failed");
}

static void print_values(values_t *p, thresholds_t *t)
{
value_t *value = p->values;
threshold_t *threshold = t->thresholds;
int i;

printf("\n");
for (i = 0; i < NR_ATTRIBUTES; i++)
print_value(value++, threshold++);
printf("OffLineStatus=%d {%s}, AutoOffLine=%s, OffLineTimeout=%d minutes\n",
p->offline_status, get_offline_text(p->offline_status & 0x7f),
p->offline_status & 0x80 ? "Yes" : "No",
p->offline_timeout / 60);
printf("OffLineCapability=%d {%s %s %s}\n", p->offline_capability,
p->offline_capability & 1 ? "Immediate" : "",
p->offline_capability & 2 ? "Auto" : "",
p->offline_capability & 4 ? "AbortOnCmd" : "SuspendOnCmd");
printf("SmartRevision=%d, CheckSum=%d, SmartCapability=%d {%s %s}\n",
p->revision, p->checksum, p->smart_capability,
p->smart_capability & 1 ? "SaveOnStandBy" : "",
p->smart_capability & 2 ? "AutoSave" : "");
printf("\n");
}

static void print_threshold(threshold_t *p)
{
if (!p->id)
return;
printf("Id=%3d, Threshold=%3d\n", p->id, p->threshold);
}

static void print_thresholds(thresholds_t *p)
{
threshold_t *threshold = p->thresholds;
int i;

printf("\n");
printf("SmartRevision=%d\n", p->revision);
for (i = 0; i < NR_ATTRIBUTES; i++)
print_threshold(threshold++);
printf("CheckSum=%d\n", p->checksum);
printf("\n");
}

static void smart_read_thresholds(void)
{
__u8 args[4 + 512] = {WIN_SMART, 0, SMART_READ_THRESHOLDS, 1, };

if (ioctl(fd, HDIO_DRIVE_CMD, &args)) {
perror(" SMART_READ_THRESHOLDS failed");
return;
}
memcpy(&thresholds, args + 4, 512);
}

static void smart_disable(void)
{
__u8 args[4] = {WIN_SMART, 0, SMART_DISABLE, 0};

if (ioctl(fd, HDIO_DRIVE_CMD, &args))
perror(" SMART_DISABLE failed");
}

static void smart_enable(void)
{
__u8 args[4] = {WIN_SMART, 0, SMART_ENABLE, 0};

if (ioctl(fd, HDIO_DRIVE_CMD, &args))
perror(" SMART_ENABLE failed");
}

static void smart_offline_immediate(void)
{
__u8 args[4] = {WIN_SMART, 0, SMART_IMMEDIATE_OFFLINE, 0};

if (ioctl(fd, HDIO_DRIVE_CMD, &args))
perror(" SMART_IMMEDIATE_OFFLINE falied");

}

int main(int argc, char *argv[])
{
if (argc != 2) {
printf("usage: ide-smart device\n");
return 0;
}
if ((fd = open(argv[1], O_RDONLY)) == -1) {
perror("couldn't open device");
return 0;
}
smart_enable();
#if 1
smart_offline_immediate();
#endif
smart_read_values();
smart_read_thresholds();
print_values(&values, &thresholds);
close(fd);
return 0;
}

G'day! <>
-- n i c h o l a s j l e o n
elegance through simplicity*http://mrnick.binary9.net*nicholas@binary9.net
good fortune through truth*ICQ#2170994*pattern?8,5,4,1,9,7,6,3,2,0*U+($++)
TRA#6805*not all questions have answers*pseudogeek:P+++($++)L+($++)W=lm@b9
2.3x10e-53*seek the path-not the destination*madison*pain builds character

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/