⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smartctl.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	// don't scan remainder of disk after doing selected segments	con->scanafterselect=1;      } else if (!strncmp(optarg,"pending,",strlen("pending,"))) {	// parse number of minutes that test should be pending	int i;	char *tailptr=NULL;	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");	  badarg = TRUE;	} else if (i<0 || i>65535) {	  sprintf(extraerror, "Option -t pending,N (N=%d) must have 0 <= N <= 65535\n", i);	  badarg = TRUE;	} else {	  con->pendingtime=i+1;	}      } else if (!strncmp(optarg,"select",strlen("select"))) {        // 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");          badarg = TRUE;        } else {          if (con->smartselectivenumspans >= 5 || start > stop) {            if (start > stop) {              sprintf(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"                " defined\n");            }	    badarg = TRUE;          }          con->smartselectivespan[con->smartselectivenumspans][0] = start;          con->smartselectivespan[con->smartselectivenumspans][1] = stop;          con->smartselectivemode[con->smartselectivenumspans] = mode;          con->smartselectivenumspans++;          con->testcase            = SELECTIVE_SELF_TEST;        }      } else if (!strncmp(optarg, "scttempint,", sizeof("scstempint,")-1)) {        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 -t scttempint,N[,p] must have positive integer N\n");            badarg = TRUE;        }        con->scttempint = interval;        con->scttempintp = (n2 == len);      } else {        badarg = TRUE;      }      break;    case 'C':      captive = TRUE;      break;    case 'X':      con->smartselftestabort = TRUE;      con->testcase           = ABORT_SELF_TEST;      break;    case 'n':      // skip disk check if in low-power mode      if (!strcmp(optarg, "never"))        con->powermode = 1; // do not skip, but print mode      else if (!strcmp(optarg, "sleep"))        con->powermode = 2;      else if (!strcmp(optarg, "standby"))        con->powermode = 3;      else if (!strcmp(optarg, "idle"))        con->powermode = 4;      else        badarg = TRUE;      break;    case 'h':      con->dont_print=FALSE;      printslogan();      Usage();      EXIT(0);        break;    case '?':    default:      con->dont_print=FALSE;      printslogan();#ifdef HAVE_GETOPT_LONG      // Point arg to the argument in which this option was found.      arg = argv[optind-1];      // Check whether the option is a long option that doesn't map to -h.      if (arg[1] == '-' && optchar != 'h') {        // Iff optopt holds a valid option then argument must be missing.        if (optopt && (strchr(shortopts, optopt) != NULL)) {          pout("=======> ARGUMENT REQUIRED FOR OPTION: %s\n", arg+2);          printvalidarglistmessage(optopt);        } else          pout("=======> UNRECOGNIZED OPTION: %s\n",arg+2);	if (extraerror[0])	  pout("=======> %s", extraerror);        UsageSummary();        EXIT(FAILCMD);      }#endif      if (optopt) {        // Iff optopt holds a valid option then argument must be        // missing.  Note (BA) this logic seems to fail using Solaris        // getopt!        if (strchr(shortopts, optopt) != NULL) {          pout("=======> ARGUMENT REQUIRED FOR OPTION: %c\n", optopt);          printvalidarglistmessage(optopt);        } else          pout("=======> UNRECOGNIZED OPTION: %c\n",optopt);	if (extraerror[0])	  pout("=======> %s", extraerror);        UsageSummary();        EXIT(FAILCMD);      }      Usage();      EXIT(0);      } // closes switch statement to process command-line options        // Check to see if option had an unrecognized or incorrect argument.    if (badarg) {      printslogan();      // It would be nice to print the actual option name given by the user      // here, but we just print the short form.  Please fix this if you know      // a clean way to do it.      pout("=======> INVALID ARGUMENT TO -%c: %s\n", optchar, optarg);      printvalidarglistmessage(optchar);      if (extraerror[0])	pout("=======> %s", extraerror);      UsageSummary();      EXIT(FAILCMD);    }  }  // At this point we have processed all command-line options.  If the  // print output is switchable, then start with the print output  // turned off  if (con->printing_switchable)    con->dont_print=TRUE;  // error message if user has asked for more than one test  if (1<(con->smartexeoffimmediate+con->smartshortselftest+con->smartextendselftest+         con->smartshortcapselftest+con->smartextendcapselftest+con->smartselftestabort + (con->smartselectivenumspans>0?1:0))){    con->dont_print=FALSE;    printslogan();    pout("\nERROR: smartctl can only run a single test type (or abort) at a time.\n");    UsageSummary();    EXIT(FAILCMD);  }  // error message if user has set selective self-test options without  // asking for a selective self-test  if ((con->pendingtime || con->scanafterselect) && !con->smartselectivenumspans){    con->dont_print=FALSE;    printslogan();    if (con->pendingtime)      pout("\nERROR: smartctl -t pending,N must be used with -t select,N-M.\n");    else      pout("\nERROR: smartctl -t afterselect,(on|off) must be used with -t select,N-M.\n");    UsageSummary();    EXIT(FAILCMD);  }  // If captive option was used, change test type if appropriate.  if (captive && con->smartshortselftest) {    con->smartshortselftest    = FALSE;    con->smartshortcapselftest = TRUE;    con->testcase              = SHORT_CAPTIVE_SELF_TEST;  } else if (captive && con->smartextendselftest) {    con->smartextendselftest    = FALSE;    con->smartextendcapselftest = TRUE;    con->testcase               = EXTEND_CAPTIVE_SELF_TEST;  }  else if (captive && con->smartconveyanceselftest) {    con->smartconveyanceselftest    = FALSE;    con->smartconveyancecapselftest = TRUE;    con->testcase                   = CONVEYANCE_CAPTIVE_SELF_TEST;  }  else if (captive && con->smartselectiveselftest) {    con->smartselectiveselftest    = FALSE;    con->smartselectivecapselftest = TRUE;    con->testcase                  = SELECTIVE_CAPTIVE_SELF_TEST;  }   // From here on, normal operations...  printslogan();    // Warn if the user has provided no device name  if (argc-optind<1){    pout("ERROR: smartctl requires a device name as the final command-line argument.\n\n");    UsageSummary();    EXIT(FAILCMD);  }    // Warn if the user has provided more than one device name  if (argc-optind>1){    int i;    pout("ERROR: smartctl takes ONE device name as the final command-line argument.\n");    pout("You have provided %d device names:\n",argc-optind);    for (i=0; i<argc-optind; i++)      pout("%s\n",argv[optind+i]);    UsageSummary();    EXIT(FAILCMD);  }  }// Printing function (controlled by global con->dont_print) // [From GLIBC Manual: Since the prototype doesn't specify types for// optional arguments, in a call to a variadic function the default// argument promotions are performed on the optional argument// values. This means the objects of type char or short int (whether// signed or not) are promoted to either int or unsigned int, as// appropriate.]void pout(const char *fmt, ...){  va_list ap;    // initialize variable argument list   va_start(ap,fmt);  if (con->dont_print){    va_end(ap);    return;  }  // print out  vprintf(fmt,ap);  va_end(ap);  fflush(stdout);  return;}// This function is used by utility.cpp to report LOG_CRIT errors.// The smartctl version prints to stdout instead of syslog().void PrintOut(int priority, const char *fmt, ...) {  va_list ap;  // avoid warning message about unused variable from gcc -W: just  // change value of local copy.  priority=0;  va_start(ap,fmt);  vprintf(fmt,ap);  va_end(ap);  return;}/* Main Program */int main (int argc, char **argv){  int fd,retval=0;  char *device;  smartmonctrl control;  char *mode=NULL;  // define control block for external functions  con=&control;  // Part input arguments  ParseOpts(argc,argv);  device = argv[argc-1];  // Device name "-": Parse "smartctl -r ataioctl,2 ..." output  if (!strcmp(device,"-")) {    if (con->controller_type != CONTROLLER_UNKNOWN) {      pout("Smartctl: -d option is not allowed in conjunction with device name \"-\".\n");      UsageSummary();      return FAILCMD;    }    con->controller_type = CONTROLLER_PARSEDEV;  }  // If use has specified 3ware controller, determine which interface   if (con->controller_type == CONTROLLER_3WARE) {    con->controller_type=guess_device_type(device);    if (con->controller_type!=CONTROLLER_3WARE_9000_CHAR && con->controller_type!=CONTROLLER_3WARE_678K_CHAR)      con->controller_type = CONTROLLER_3WARE_678K;  }  if (con->controller_type == CONTROLLER_UNKNOWN)    con->controller_type=guess_device_type(device);    if (con->controller_type == CONTROLLER_UNKNOWN) {    pout("Smartctl: please specify device type with the -d option.\n");    UsageSummary();    return FAILCMD;  }    // set up mode for open() call.  SCSI case is:  switch (con->controller_type) {  case CONTROLLER_SCSI:  case CONTROLLER_SAT:    mode="SCSI";    break;  case CONTROLLER_3WARE_9000_CHAR:    mode="ATA_3WARE_9000";    break;  case CONTROLLER_3WARE_678K_CHAR:    mode="ATA_3WARE_678K";    break;  case CONTROLLER_CCISS:    mode="CCISS";    break;  default:    mode="ATA";    break;  }    // open device - SCSI devices are opened (O_RDWR | O_NONBLOCK) so the  // scsi generic device can be used (needs write permission for MODE   // SELECT command) plus O_NONBLOCK to stop open hanging if media not  // present (e.g. with st).  Opening is retried O_RDONLY if read-only  // media prevents opening O_RDWR (it cannot happen for scsi generic  // devices, but it can for the others).  if (con->controller_type != CONTROLLER_PARSEDEV)    fd = deviceopen(device, mode);  else    fd = parsedev_open(device);  if (fd<0) {    char errmsg[256];    snprintf(errmsg,256,"Smartctl open device: %s failed",argv[argc-1]);    errmsg[255]='\0';    syserror(errmsg);    return FAILDEV;  }  // now call appropriate ATA or SCSI routine  switch (con->controller_type) {  case CONTROLLER_UNKNOWN:    // we should never fall into this branch!    pout("Smartctl: please specify device type with the -d option.\n");    UsageSummary();    retval = FAILCMD;    break;  case CONTROLLER_SCSI:    retval = scsiPrintMain(fd);    if ((0 == retval) && (CONTROLLER_SAT == con->controller_type))        retval = ataPrintMain(fd);    break;  case CONTROLLER_CCISS:    // route the cciss command through scsiPrintMain.     // cciss pass-throughs will separeate from the SCSI data-path.    retval = scsiPrintMain(fd);    break;  default:    retval = ataPrintMain(fd);    break;  }    if (con->controller_type != CONTROLLER_PARSEDEV)    deviceclose(fd);  else    parsedev_close(fd);  return retval;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -