From 951e4e5c98e1e471ea3aeb1571909e4e1f048c77 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Thu, 15 Jan 2015 22:47:21 +0100 Subject: [PATCH] Add the ATA error count in the SMART report. And other minor changes. --- cmdline/device.c | 14 ++++++++++++-- cmdline/portable.h | 9 +++++++-- cmdline/unix.c | 19 ++++++++++++------- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/cmdline/device.c b/cmdline/device.c index 4073c5a6..6b81fd6a 100644 --- a/cmdline/device.c +++ b/cmdline/device.c @@ -161,10 +161,12 @@ static void state_smart(tommy_list* low) printf("\n"); printf(" Temp"); printf(" Power"); + printf(" Error"); printf("\n"); printf(" C°"); printf(" OnDays"); - printf(" AFR"); + printf(" Count"); + printf(" AFR"); printf(" Size"); printf(" Serial/Name"); printf("\n"); @@ -186,11 +188,19 @@ static void state_smart(tommy_list* low) else printf(" -"); + if (devinfo->smart[SMART_ERROR] != SMART_UNASSIGNED) + printf("%6" PRIu64, devinfo->smart[SMART_ERROR]); + else + printf(" -"); + afr = smart_afr(devinfo->smart); printf("%5.0f%%", afr * 100); - printf(" %2.1fT", devinfo->smart_size / 1E12); + if (devinfo->smart[SMART_SIZE] != SMART_UNASSIGNED) + printf(" %2.1fT", devinfo->smart[SMART_SIZE] / 1E12); + else + printf(" -"); printf(" %s", devinfo->smart_serial); diff --git a/cmdline/portable.h b/cmdline/portable.h index 97d19888..cac84d43 100644 --- a/cmdline/portable.h +++ b/cmdline/portable.h @@ -305,7 +305,13 @@ int randomize(void* ptr, size_t size); /** * SMART attributes. */ -#define SMART_COUNT 256 +#define SMART_COUNT (256+2) + +/** + * Additional info attributes. + */ +#define SMART_ERROR 256 /**< ATA Error count. */ +#define SMART_SIZE 257 /**< Size in bytes. */ /** * SMART max attribute length. @@ -327,7 +333,6 @@ struct devinfo_struct { char file[PATH_MAX]; /**< File device. */ struct devinfo_struct* parent; /**< Pointer at the parent if any. */ uint64_t smart[SMART_COUNT]; /**< SMART raw attributes. */ - uint64_t smart_size; /**< SMART size. */ char smart_serial[SMART_MAX]; /**< SMART serial number. */ #if HAVE_PTHREAD_CREATE pthread_t thread; diff --git a/cmdline/unix.c b/cmdline/unix.c index 9a251bd9..5c989537 100644 --- a/cmdline/unix.c +++ b/cmdline/unix.c @@ -541,7 +541,7 @@ static int devtree(const char* name, dev_t device, devinfo_t* parent, tommy_list /** * Gets SMART attributes. */ -static int devsmart(dev_t device, uint64_t* smart, uint64_t* size, char* serial) +static int devsmart(dev_t device, uint64_t* smart, char* serial) { char cmd[128]; FILE* f; @@ -551,6 +551,7 @@ static int devsmart(dev_t device, uint64_t* smart, uint64_t* size, char* serial) *serial = 0; for (i = 0; i < SMART_COUNT; ++i) smart[i] = SMART_UNASSIGNED; + *serial = 0; snprintf(cmd, sizeof(cmd), "smartctl -a /dev/block/%u:%u", major(device), minor(device)); @@ -581,15 +582,19 @@ static int devsmart(dev_t device, uint64_t* smart, uint64_t* size, char* serial) if (*s == 0) { inside = 0; - } else if (strncmp(s, "ID# ", 4) == 0) { + } else if (strncmp(s, "ID#", 3) == 0) { inside = 1; + } else if (strncmp(s, "No Errors Logged", 16) == 0) { + smart[SMART_ERROR] = 0; + } else if (sscanf(s, "ATA Error Count: %llu", &raw) == 1) { + smart[SMART_ERROR] = raw; } else if (sscanf(s, "Serial Number: %63s", serial) == 1) { } else if (sscanf(s, "User Capacity: %63s", attr) == 1) { - *size = 0; + smart[SMART_SIZE] = 0; for (i = 0; attr[i]; ++i) { if (isdigit(attr[i])) { - *size *= 10; - *size += attr[i] - '0'; + smart[SMART_SIZE] *= 10; + smart[SMART_SIZE] += attr[i] - '0'; } } } else if (inside) { @@ -600,7 +605,7 @@ static int devsmart(dev_t device, uint64_t* smart, uint64_t* size, char* serial) /* LCOV_EXCL_STOP */ } - if (id >= SMART_COUNT) { + if (id >= 256) { /* LCOV_EXCL_START */ fprintf(stderr, "Invalid SMART id '%u'.\n", id); return -1; @@ -775,7 +780,7 @@ static void* thread_smart(void* arg) { devinfo_t* devinfo = arg; - if (devsmart(devinfo->device, devinfo->smart, &devinfo->smart_size, devinfo->smart_serial) != 0) { + if (devsmart(devinfo->device, devinfo->smart, devinfo->smart_serial) != 0) { /* LCOV_EXCL_START */ return (void*)-1; /* LCOV_EXCL_STOP */