mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 10:51:54 -04:00
Share smartctl support between different platforms
This commit is contained in:
parent
467bf0256b
commit
f706da1cc6
4 changed files with 88 additions and 116 deletions
|
|
@ -1843,15 +1843,8 @@ static int devsmart(const char* file, uint64_t* smart, char* serial)
|
|||
{
|
||||
char cmd[128];
|
||||
FILE* f;
|
||||
int inside;
|
||||
unsigned i;
|
||||
int ret;
|
||||
|
||||
*serial = 0;
|
||||
for (i = 0; i < SMART_COUNT; ++i)
|
||||
smart[i] = SMART_UNASSIGNED;
|
||||
*serial = 0;
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "smartctl-nc.exe -a %s", file);
|
||||
|
||||
f = popen(cmd, "r");
|
||||
|
|
@ -1862,57 +1855,11 @@ static int devsmart(const char* file, uint64_t* smart, char* serial)
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
inside = 0;
|
||||
while (1) {
|
||||
char buf[256];
|
||||
char attr[64];
|
||||
unsigned id;
|
||||
uint64_t raw;
|
||||
char* s;
|
||||
|
||||
s = fgets(buf, sizeof(buf), f);
|
||||
|
||||
if (s == 0)
|
||||
break;
|
||||
|
||||
/* skip initial spaces */
|
||||
while (isspace(*s))
|
||||
++s;
|
||||
|
||||
if (*s == 0) {
|
||||
inside = 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: %" SCNu64, &raw) == 1) {
|
||||
smart[SMART_ERROR] = raw;
|
||||
} else if (sscanf(s, "Serial Number: %63s", serial) == 1) {
|
||||
} else if (sscanf(s, "User Capacity: %63s", attr) == 1) {
|
||||
smart[SMART_SIZE] = 0;
|
||||
for (i = 0; attr[i]; ++i) {
|
||||
if (isdigit(attr[i])) {
|
||||
smart[SMART_SIZE] *= 10;
|
||||
smart[SMART_SIZE] += attr[i] - '0';
|
||||
}
|
||||
}
|
||||
} else if (inside) {
|
||||
if (sscanf(s, "%u %*s %*s %*u %*u %*u %*s %*s %*s %" SCNu64, &id, &raw) != 2) {
|
||||
/* LCOV_EXCL_START */
|
||||
fprintf(stderr, "Invalid smartctl line '%s'.\n", buf);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (id >= 256) {
|
||||
/* LCOV_EXCL_START */
|
||||
fprintf(stderr, "Invalid SMART id '%u'.\n", id);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
smart[id] = raw;
|
||||
}
|
||||
if (smartctl_attribute(f, smart, serial) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
pclose(f);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
ret = pclose(f);
|
||||
|
|
|
|||
|
|
@ -394,4 +394,73 @@ char* strdup_nofail(const char* str)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* smartctl */
|
||||
|
||||
int smartctl_attribute(FILE* f, uint64_t* smart, char* serial)
|
||||
{
|
||||
unsigned i;
|
||||
int inside;
|
||||
|
||||
/* preclear attribute */
|
||||
*serial = 0;
|
||||
for (i = 0; i < SMART_COUNT; ++i)
|
||||
smart[i] = SMART_UNASSIGNED;
|
||||
|
||||
/* read the file */
|
||||
inside = 0;
|
||||
while (1) {
|
||||
char buf[256];
|
||||
char attr[64];
|
||||
unsigned id;
|
||||
uint64_t raw;
|
||||
char* s;
|
||||
|
||||
s = fgets(buf, sizeof(buf), f);
|
||||
|
||||
if (s == 0)
|
||||
break;
|
||||
|
||||
/* skip initial spaces */
|
||||
while (isspace(*s))
|
||||
++s;
|
||||
|
||||
if (*s == 0) {
|
||||
inside = 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: %" SCNu64, &raw) == 1) {
|
||||
smart[SMART_ERROR] = raw;
|
||||
} else if (sscanf(s, "Serial Number: %63s", serial) == 1) {
|
||||
} else if (sscanf(s, "User Capacity: %63s", attr) == 1) {
|
||||
smart[SMART_SIZE] = 0;
|
||||
for (i = 0; attr[i]; ++i) {
|
||||
if (isdigit(attr[i])) {
|
||||
smart[SMART_SIZE] *= 10;
|
||||
smart[SMART_SIZE] += attr[i] - '0';
|
||||
}
|
||||
}
|
||||
} else if (inside) {
|
||||
if (sscanf(s, "%u %*s %*s %*u %*u %*u %*s %*s %*s %" SCNu64, &id, &raw) != 2) {
|
||||
/* LCOV_EXCL_START */
|
||||
fprintf(stderr, "Invalid smartctl line '%s'.\n", buf);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (id >= 256) {
|
||||
/* LCOV_EXCL_START */
|
||||
fprintf(stderr, "Invalid SMART id '%u'.\n", id);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
smart[id] = raw;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,5 +121,14 @@ char* strdup_nofail(const char* str);
|
|||
*/
|
||||
void malloc_fail(size_t size);
|
||||
|
||||
/****************************************************************************/
|
||||
/* smartctl */
|
||||
|
||||
/**
|
||||
* Reads smartctl attributes from a stream.
|
||||
* Returns -1 on error.
|
||||
*/
|
||||
int smartctl_attribute(FILE* f, uint64_t* smart, char* serial);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -623,15 +623,8 @@ static int devsmart(dev_t device, uint64_t* smart, char* serial)
|
|||
{
|
||||
char cmd[128];
|
||||
FILE* f;
|
||||
int inside;
|
||||
unsigned i;
|
||||
int ret;
|
||||
|
||||
*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));
|
||||
|
||||
f = popen(cmd, "r");
|
||||
|
|
@ -642,57 +635,11 @@ static int devsmart(dev_t device, uint64_t* smart, char* serial)
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
inside = 0;
|
||||
while (1) {
|
||||
char buf[256];
|
||||
char attr[64];
|
||||
unsigned id;
|
||||
uint64_t raw;
|
||||
char* s;
|
||||
|
||||
s = fgets(buf, sizeof(buf), f);
|
||||
|
||||
if (s == 0)
|
||||
break;
|
||||
|
||||
/* skip initial spaces */
|
||||
while (isspace(*s))
|
||||
++s;
|
||||
|
||||
if (*s == 0) {
|
||||
inside = 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: %" SCNu64, &raw) == 1) {
|
||||
smart[SMART_ERROR] = raw;
|
||||
} else if (sscanf(s, "Serial Number: %63s", serial) == 1) {
|
||||
} else if (sscanf(s, "User Capacity: %63s", attr) == 1) {
|
||||
smart[SMART_SIZE] = 0;
|
||||
for (i = 0; attr[i]; ++i) {
|
||||
if (isdigit(attr[i])) {
|
||||
smart[SMART_SIZE] *= 10;
|
||||
smart[SMART_SIZE] += attr[i] - '0';
|
||||
}
|
||||
}
|
||||
} else if (inside) {
|
||||
if (sscanf(s, "%u %*s %*s %*u %*u %*u %*s %*s %*s %" SCNu64, &id, &raw) != 2) {
|
||||
/* LCOV_EXCL_START */
|
||||
fprintf(stderr, "Invalid smartctl line '%s'.\n", buf);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (id >= 256) {
|
||||
/* LCOV_EXCL_START */
|
||||
fprintf(stderr, "Invalid SMART id '%u'.\n", id);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
smart[id] = raw;
|
||||
}
|
||||
if (smartctl_attribute(f, smart, serial) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
pclose(f);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
ret = pclose(f);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue