--- embedaddon/smartmontools/smartctl.cpp 2012/10/09 09:36:45 1.1.1.2
+++ embedaddon/smartmontools/smartctl.cpp 2013/07/22 01:17:36 1.1.1.3
@@ -13,8 +13,7 @@
* any later version.
*
* You should have received a copy of the GNU General Public License
- * (for example COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * (for example COPYING); If not, see .
*
* This code was originally developed as a Senior Thesis by Michael Cornwell
* at the Concurrent Systems Laboratory (now part of the Storage Systems
@@ -41,10 +40,6 @@
#include
#endif
-#if defined(__QNXNTO__)
-#include // TODO: Why is this include necessary on QNX ?
-#endif
-
#include "int64.h"
#include "atacmds.h"
#include "dev_interface.h"
@@ -55,7 +50,7 @@
#include "smartctl.h"
#include "utility.h"
-const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp,v 1.1.1.2 2012/10/09 09:36:45 misho Exp $"
+const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp,v 1.1.1.3 2013/07/22 01:17:36 misho Exp $"
CONFIG_H_CVSID SMARTCTL_H_CVSID;
// Globals to control printing
@@ -87,8 +82,10 @@ static void Usage()
" Print license, copyright, and version information and exit\n\n"
" -i, --info\n"
" Show identity information for device\n\n"
+" --identify[=[w][nvb]]\n"
+" Show words and bits from IDENTIFY DEVICE data (ATA)\n\n"
" -g NAME, --get=NAME\n"
-" Get device setting: all, aam, apm, lookahead, security, wcache\n\n"
+" Get device setting: all, aam, apm, lookahead, security, wcache, rcache\n\n"
" -a, --all\n"
" Show all SMART information for device\n\n"
" -x, --xall\n"
@@ -124,7 +121,7 @@ static void Usage()
" -s NAME[,VALUE], --set=NAME[,VALUE]\n"
" Enable/disable/change device setting: aam,[N|off], apm,[N|off],\n"
" lookahead,[on|off], security-freeze, standby,[N|off|now],\n"
-" wcache,[on|off]\n\n"
+" wcache,[on|off], rcache,[on|off]\n\n"
);
printf(
"======================================= READ AND DISPLAY DATA OPTIONS =====\n\n"
@@ -146,13 +143,14 @@ static void Usage()
" -v N,OPTION , --vendorattribute=N,OPTION (ATA)\n"
" Set display OPTION for vendor Attribute N (see man page)\n\n"
" -F TYPE, --firmwarebug=TYPE (ATA)\n"
-" Use firmware bug workaround: none, samsung, samsung2,\n"
-" samsung3, swapid\n\n"
+" Use firmware bug workaround:\n"
+" %s, swapid\n\n"
" -P TYPE, --presets=TYPE (ATA)\n"
" Drive-specific presets: use, ignore, show, showall\n\n"
" -B [+]FILE, --drivedb=[+]FILE (ATA)\n"
" Read and replace [add] drive database from FILE\n"
" [default is +%s",
+ get_valid_firmwarebug_args(),
get_drivedb_path_add()
);
#ifdef SMARTMONTOOLS_DRIVEDBDIR
@@ -179,7 +177,7 @@ static void Usage()
}
// Values for --long only options, see parse_options()
-enum { opt_scan = 1000, opt_scan_open, opt_set, opt_smart };
+enum { opt_identify = 1000, opt_scan, opt_scan_open, opt_set, opt_smart };
/* Returns a string containing a formatted list of the valid arguments
to the option opt or empty on failure. Note 'v' case different */
@@ -214,18 +212,20 @@ static std::string getvalidarglist(int opt)
return "offline, short, long, conveyance, force, vendor,N, select,M-N, "
"pending,N, afterselect,[on|off]";
case 'F':
- return "none, samsung, samsung2, samsung3, swapid";
+ return std::string(get_valid_firmwarebug_args()) + ", swapid";
case 'n':
return "never, sleep, standby, idle";
case 'f':
return "old, brief, hex[,id|val]";
case 'g':
- return "aam, apm, lookahead, security, wcache";
+ return "aam, apm, lookahead, security, wcache, rcache";
case opt_set:
return "aam,[N|off], apm,[N|off], lookahead,[on|off], security-freeze, "
- "standby,[N|off|now], wcache,[on|off]";
+ "standby,[N|off|now], wcache,[on|off], rcache,[on|off]";
case 's':
return getvalidarglist(opt_smart)+", "+getvalidarglist(opt_set);
+ case opt_identify:
+ return "n, wn, w, v, wv, wb";
case 'v':
default:
return "";
@@ -300,6 +300,7 @@ static const char * parse_options(int argc, char** arg
{ "drivedb", required_argument, 0, 'B' },
{ "format", required_argument, 0, 'f' },
{ "get", required_argument, 0, 'g' },
+ { "identify", optional_argument, 0, opt_identify },
{ "set", required_argument, 0, opt_set },
{ "scan", no_argument, 0, opt_scan },
{ "scan-open", no_argument, 0, opt_scan_open },
@@ -439,19 +440,10 @@ static const char * parse_options(int argc, char** arg
scsiopts.smart_ss_media_log = true;
break;
case 'F':
- if (!strcmp(optarg,"none")) {
- ataopts.fix_firmwarebug = FIX_NONE;
- } else if (!strcmp(optarg,"samsung")) {
- ataopts.fix_firmwarebug = FIX_SAMSUNG;
- } else if (!strcmp(optarg,"samsung2")) {
- ataopts.fix_firmwarebug = FIX_SAMSUNG2;
- } else if (!strcmp(optarg,"samsung3")) {
- ataopts.fix_firmwarebug = FIX_SAMSUNG3;
- } else if (!strcmp(optarg,"swapid")) {
+ if (!strcmp(optarg, "swapid"))
ataopts.fix_swapped_id = true;
- } else {
+ else if (!parse_firmwarebug_def(optarg, ataopts.firmwarebugs))
badarg = true;
- }
break;
case 'c':
ataopts.smart_general_values = true;
@@ -498,7 +490,7 @@ static const char * parse_options(int argc, char** arg
unsigned interval = 0; int n1 = -1, n2 = -1, len = strlen(optarg);
if (!( sscanf(optarg,"scttempint,%u%n,p%n", &interval, &n1, &n2) == 1
&& 0 < interval && interval <= 0xffff && (n1 == len || n2 == len))) {
- strcpy(extraerror, "Option -l scttempint,N[,p] must have positive integer N\n");
+ snprintf(extraerror, sizeof(extraerror), "Option -l scttempint,N[,p] must have positive integer N\n");
badarg = true;
}
ataopts.sct_temp_int = interval;
@@ -554,7 +546,7 @@ static const char * parse_options(int argc, char** arg
ataopts.sct_erc_writetime = wt;
}
else {
- sprintf(extraerror, "Option -l scterc,[READTIME,WRITETIME] syntax error\n");
+ snprintf(extraerror, sizeof(extraerror), "Option -l scterc,[READTIME,WRITETIME] syntax error\n");
badarg = true;
}
} else if ( !strncmp(optarg, "gplog," , sizeof("gplog," )-1)
@@ -570,14 +562,14 @@ static const char * parse_options(int argc, char** arg
const char * erropt = (gpl ? "gplog" : "smartlog");
if (!( n1 == len || n2 == len
|| (n3 == len && (sign == '+' || sign == '-')))) {
- sprintf(extraerror, "Option -l %s,ADDR[,FIRST[-LAST|+SIZE]] syntax error\n", erropt);
+ snprintf(extraerror, sizeof(extraerror), "Option -l %s,ADDR[,FIRST[-LAST|+SIZE]] syntax error\n", erropt);
badarg = true;
}
else if (!( logaddr <= 0xff && page <= (gpl ? 0xffffU : 0x00ffU)
&& 0 < nsectors
&& (nsectors <= (gpl ? 0xffffU : 0xffU) || nsectors == ~0U)
&& (sign != '-' || page <= nsectors) )) {
- sprintf(extraerror, "Option -l %s,ADDR[,FIRST[-LAST|+SIZE]] parameter out of range\n", erropt);
+ snprintf(extraerror, sizeof(extraerror), "Option -l %s,ADDR[,FIRST[-LAST|+SIZE]] parameter out of range\n", erropt);
badarg = true;
}
else {
@@ -593,6 +585,22 @@ static const char * parse_options(int argc, char** arg
case 'i':
ataopts.drive_info = scsiopts.drive_info = true;
break;
+
+ case opt_identify:
+ ataopts.identify_word_level = ataopts.identify_bit_level = 0;
+ if (optarg) {
+ for (int i = 0; optarg[i]; i++) {
+ switch (optarg[i]) {
+ case 'w': ataopts.identify_word_level = 1; break;
+ case 'n': ataopts.identify_bit_level = -1; break;
+ case 'v': ataopts.identify_bit_level = 1; break;
+ case 'b': ataopts.identify_bit_level = 2; break;
+ default: badarg = true;
+ }
+ }
+ }
+ break;
+
case 'a':
ataopts.drive_info = scsiopts.drive_info = true;
ataopts.smart_check_status = scsiopts.smart_check_status = true;
@@ -618,11 +626,13 @@ static const char * parse_options(int argc, char** arg
ataopts.smart_logdir = ataopts.gp_logdir = true;
ataopts.sct_temp_sts = ataopts.sct_temp_hist = true;
ataopts.sct_erc_get = true;
+ ataopts.devstat_all_pages = true;
ataopts.sataphy = true;
ataopts.get_set_used = true;
ataopts.get_aam = ataopts.get_apm = true;
ataopts.get_security = true;
ataopts.get_lookahead = ataopts.get_wcache = true;
+ scsiopts.get_rcd = scsiopts.get_wce = true;
scsiopts.smart_background_log = true;
scsiopts.smart_ss_media_log = true;
scsiopts.sasphy = true;
@@ -680,6 +690,7 @@ static const char * parse_options(int argc, char** arg
ataopts.smart_selftest_type = CONVEYANCE_SELF_TEST;
} else if (!strcmp(optarg,"force")) {
ataopts.smart_selftest_force = true;
+ scsiopts.smart_selftest_force = true;
} else if (!strcmp(optarg,"afterselect,on")) {
// scan remainder of disk after doing selected segment
ataopts.smart_selective_args.scan_after_select = 2;
@@ -693,10 +704,10 @@ static const char * parse_options(int argc, char** arg
errno=0;
i=(int)strtol(optarg+strlen("pending,"), &tailptr, 10);
if (errno || *tailptr != '\0') {
- sprintf(extraerror, "Option -t pending,N requires N to be a non-negative integer\n");
+ snprintf(extraerror, sizeof(extraerror), "Option -t pending,N requires N to be a non-negative integer\n");
badarg = true;
} else if (i<0 || i>65535) {
- sprintf(extraerror, "Option -t pending,N (N=%d) must have 0 <= N <= 65535\n", i);
+ snprintf(extraerror, sizeof(extraerror), "Option -t pending,N (N=%d) must have 0 <= N <= 65535\n", i);
badarg = true;
} else {
ataopts.smart_selective_args.pending_time = i+1;
@@ -707,15 +718,15 @@ static const char * parse_options(int argc, char** arg
// parse range of LBAs to test
uint64_t start, stop; int mode;
if (split_selective_arg(optarg, &start, &stop, &mode)) {
- sprintf(extraerror, "Option -t select,M-N must have non-negative integer M and N\n");
+ snprintf(extraerror, sizeof(extraerror), "Option -t select,M-N must have non-negative integer M and N\n");
badarg = true;
} else {
if (ataopts.smart_selective_args.num_spans >= 5 || start > stop) {
if (start > stop) {
- sprintf(extraerror, "ERROR: Start LBA (%"PRIu64") > ending LBA (%"PRId64") in argument \"%s\"\n",
+ snprintf(extraerror, sizeof(extraerror), "ERROR: Start LBA (%"PRIu64") > ending LBA (%"PRId64") in argument \"%s\"\n",
start, stop, optarg);
} else {
- sprintf(extraerror,"ERROR: No more than five selective self-test spans may be"
+ snprintf(extraerror, sizeof(extraerror),"ERROR: No more than five selective self-test spans may be"
" defined\n");
}
badarg = true;
@@ -727,13 +738,13 @@ static const char * parse_options(int argc, char** arg
ataopts.smart_selftest_type = SELECTIVE_SELF_TEST;
}
} else if (!strncmp(optarg, "scttempint", sizeof("scstempint")-1)) {
- strcpy(extraerror, "-t scttempint is no longer supported, use -l scttempint instead\n");
+ snprintf(extraerror, sizeof(extraerror), "-t scttempint is no longer supported, use -l scttempint instead\n");
badarg = true;
} else if (!strncmp(optarg, "vendor,", sizeof("vendor,")-1)) {
unsigned subcmd = ~0U; int n = -1;
if (!( sscanf(optarg, "%*[a-z],0x%x%n", &subcmd, &n) == 1
&& subcmd <= 0xff && n == (int)strlen(optarg))) {
- strcpy(extraerror, "Option -t vendor,0xNN syntax error\n");
+ snprintf(extraerror, sizeof(extraerror), "Option -t vendor,0xNN syntax error\n");
badarg = true;
}
else
@@ -819,6 +830,7 @@ static const char * parse_options(int argc, char** arg
ataopts.get_aam = ataopts.get_apm = true;
ataopts.get_security = true;
ataopts.get_lookahead = ataopts.get_wcache = true;
+ scsiopts.get_rcd = scsiopts.get_wce = true;
}
else if (!strcmp(name, "aam")) {
if (get)
@@ -828,7 +840,7 @@ static const char * parse_options(int argc, char** arg
else if (val <= 254)
ataopts.set_aam = val + 1;
else {
- sprintf(extraerror, "Option -s aam,N must have 0 <= N <= 254\n");
+ snprintf(extraerror, sizeof(extraerror), "Option -s aam,N must have 0 <= N <= 254\n");
badarg = true;
}
}
@@ -840,13 +852,14 @@ static const char * parse_options(int argc, char** arg
else if (1 <= val && val <= 254)
ataopts.set_apm = val + 1;
else {
- sprintf(extraerror, "Option -s apm,N must have 1 <= N <= 254\n");
+ snprintf(extraerror, sizeof(extraerror), "Option -s apm,N must have 1 <= N <= 254\n");
badarg = true;
}
}
else if (!strcmp(name, "lookahead")) {
- if (get)
+ if (get) {
ataopts.get_lookahead = true;
+ }
else if (off)
ataopts.set_lookahead = -1;
else if (on)
@@ -854,6 +867,16 @@ static const char * parse_options(int argc, char** arg
else
badarg = true;
}
+ else if (!strcmp(name, "rcache")) {
+ if (get)
+ scsiopts.get_rcd = true;
+ else if (off)
+ scsiopts.set_rcd = -1;
+ else if (on)
+ scsiopts.set_rcd = 1;
+ else
+ badarg = true;
+ }
else if (get && !strcmp(name, "security")) {
ataopts.get_security = true;
}
@@ -869,17 +892,23 @@ static const char * parse_options(int argc, char** arg
else if (val <= 255)
ataopts.set_standby = val + 1;
else {
- sprintf(extraerror, "Option -s standby,N must have 0 <= N <= 255\n");
+ snprintf(extraerror, sizeof(extraerror), "Option -s standby,N must have 0 <= N <= 255\n");
badarg = true;
}
}
else if (!strcmp(name, "wcache")) {
- if (get)
+ if (get) {
ataopts.get_wcache = true;
- else if (off)
+ scsiopts.get_wce = true;
+ }
+ else if (off) {
ataopts.set_wcache = -1;
- else if (on)
+ scsiopts.set_wce = -1;
+ }
+ else if (on) {
ataopts.set_wcache = 1;
+ scsiopts.set_wce = 1;
+ }
else
badarg = true;
}
@@ -941,7 +970,8 @@ static const char * parse_options(int argc, char** arg
// a clean way to do it.
char optstr[] = { (char)optchar, 0 };
pout("=======> INVALID ARGUMENT TO -%s: %s\n",
- (optchar == opt_set ? "-set" :
+ (optchar == opt_identify ? "-identify" :
+ optchar == opt_set ? "-set" :
optchar == opt_smart ? "-smart" : optstr), optarg);
printvalidarglistmessage(optchar);
if (extraerror[0])
@@ -1190,7 +1220,7 @@ static int main_worker(int argc, char **argv)
if (!strcmp(name,"-")) {
// Parse "smartctl -r ataioctl,2 ..." output from stdin
if (type || print_type_only) {
- pout("Smartctl: -d option is not allowed in conjunction with device name \"-\".\n");
+ pout("-d option is not allowed in conjunction with device name \"-\".\n");
UsageSummary();
return FAILCMD;
}
@@ -1205,7 +1235,7 @@ static int main_worker(int argc, char **argv)
if (type)
printvalidarglistmessage('d');
else
- pout("Smartctl: please specify device type with the -d option.\n");
+ pout("Please specify device type with the -d option.\n");
UsageSummary();
return FAILCMD;
}