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

📄 ataprint.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  // print data structure revision number  pout("SMART Selective self-test log data structure revision number %d\n",(int)log->logversion);  if (1 != log->logversion)    pout("Warning: ATA Specification requires selective self-test log data structure revision number = 1\n");    switch((sv->self_test_exec_status)>>4){  case  0:msg="Completed";    break;  case  1:msg="Aborted_by_host";    break;  case  2:msg="Interrupted";    break;  case  3:msg="Fatal_error";    break;  case  4:msg="Completed_unknown_failure";    break;  case  5:msg="Completed_electrical_failure";    break;  case  6:msg="Completed_servo/seek_failure";    break;  case  7:msg="Completed_read_failure";    break;  case  8:msg="Completed_handling_damage??";    break;  case 15:msg="Self_test_in_progress";    break;  default:msg="Unknown_status ";    break;  }  // find the number of columns needed for printing. If in use, the  // start/end of span being read-scanned...  if (log->currentspan>5) {    maxl=current;    maxr=currentend;  }  for (i=0; i<5; i++) {    uint64_t start=log->span[i].start;    uint64_t end  =log->span[i].end;     // ... plus max start/end of each of the five test spans.    if (start>maxl)      maxl=start;    if (end > maxr)      maxr=end;  }    // we need at least 7 characters wide fields to accomodate the  // labels  if ((field1=snprintf(tmp,64, "%"PRIu64, maxl))<7)    field1=7;  if ((field2=snprintf(tmp,64, "%"PRIu64, maxr))<7)    field2=7;  // now print the five test spans  pout(" SPAN  %*s  %*s  CURRENT_TEST_STATUS\n", field1, "MIN_LBA", field2, "MAX_LBA");  for (i=0; i<5; i++) {    uint64_t start=log->span[i].start;    uint64_t end=log->span[i].end;        if ((i+1)==(int)log->currentspan)      // this span is currently under test      pout("    %d  %*"PRIu64"  %*"PRIu64"  %s [%01d0%% left] (%"PRIu64"-%"PRIu64")\n",	   i+1, field1, start, field2, end, msg,	   (int)(sv->self_test_exec_status & 0xf), current, currentend);    else      // this span is not currently under test      pout("    %d  %*"PRIu64"  %*"PRIu64"  Not_testing\n",	   i+1, field1, start, field2, end);  }      // if we are currently read-scanning, print LBAs and the status of  // the read scan  if (log->currentspan>5)    pout("%5d  %*"PRIu64"  %*"PRIu64"  Read_scanning %s\n",	 (int)log->currentspan, field1, current, field2, currentend,	 OfflineDataCollectionStatus(sv->offline_data_collection_status));    /* Print selective self-test flags.  Possible flag combinations are     (numbering bits from 0-15):     Bit-1 Bit-3   Bit-4     Scan  Pending Active     0     *       *       Don't scan     1     0       0       Will carry out scan after selective test     1     1       0       Waiting to carry out scan after powerup     1     0       1       Currently scanning            1     1       1       Currently scanning  */    pout("Selective self-test flags (0x%x):\n", (unsigned int)log->flags);  if (log->flags & SELECTIVE_FLAG_DOSCAN) {    if (log->flags & SELECTIVE_FLAG_ACTIVE)      pout("  Currently read-scanning the remainder of the disk.\n");    else if (log->flags & SELECTIVE_FLAG_PENDING)      pout("  Read-scan of remainder of disk interrupted; will resume %d min after power-up.\n",	   (int)log->pendingtime);    else      pout("  After scanning selected spans, read-scan remainder of disk.\n");  }  else    pout("  After scanning selected spans, do NOT read-scan remainder of disk.\n");    // print pending time  pout("If Selective self-test is pending on power-up, resume after %d minute delay.\n",       (int)log->pendingtime);  return; }// return value is:// bottom 8 bits: number of entries found where self-test showed an error// remaining bits: if nonzero, power on hours of last self-test where error was foundint ataPrintSmartSelfTestlog(struct ata_smart_selftestlog *data,int allentries){  int i,j,noheaderprinted=1;  int retval=0, hours=0, testno=0;  if (allentries)    pout("SMART Self-test log structure revision number %d\n",(int)data->revnumber);  if ((data->revnumber!=0x0001) && allentries && con->fixfirmwarebug != FIX_SAMSUNG)    pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");  if (data->mostrecenttest==0){    if (allentries)      pout("No self-tests have been logged.  [To run self-tests, use: smartctl -t]\n\n");    return 0;  }  // print log        for (i=20;i>=0;i--){        struct ata_smart_selftestlog_struct *log;    // log is a circular buffer    j=(i+data->mostrecenttest)%21;    log=data->selftest_struct+j;    if (nonempty((unsigned char*)log,sizeof(*log))){      char *msgtest,*msgstat,percent[64],firstlba[64];      int errorfound=0;            // count entry based on non-empty structures -- needed for      // Seagate only -- other vendors don't have blank entries 'in      // the middle'      testno++;      // test name      switch(log->selftestnumber){      case   0: msgtest="Offline            "; break;      case   1: msgtest="Short offline      "; break;      case   2: msgtest="Extended offline   "; break;      case   3: msgtest="Conveyance offline "; break;      case   4: msgtest="Selective offline  "; break;      case 127: msgtest="Abort offline test "; break;      case 129: msgtest="Short captive      "; break;      case 130: msgtest="Extended captive   "; break;      case 131: msgtest="Conveyance captive "; break;      case 132: msgtest="Selective captive  "; break;      default:          if ( log->selftestnumber>=192 ||            (log->selftestnumber>= 64 && log->selftestnumber<=126))          msgtest="Vendor offline     ";        else          msgtest="Reserved offline   ";      }            // test status      switch((log->selfteststatus)>>4){      case  0:msgstat="Completed without error      "; break;      case  1:msgstat="Aborted by host              "; break;      case  2:msgstat="Interrupted (host reset)     "; break;      case  3:msgstat="Fatal or unknown error       "; errorfound=1; break;      case  4:msgstat="Completed: unknown failure   "; errorfound=1; break;      case  5:msgstat="Completed: electrical failure"; errorfound=1; break;      case  6:msgstat="Completed: servo/seek failure"; errorfound=1; break;      case  7:msgstat="Completed: read failure      "; errorfound=1; break;      case  8:msgstat="Completed: handling damage?? "; errorfound=1; break;      case 15:msgstat="Self-test routine in progress"; break;      default:msgstat="Unknown/reserved test status ";      }      retval+=errorfound;      sprintf(percent,"%1d0%%",(log->selfteststatus)&0xf);      // T13/1321D revision 1c: (Data structure Rev #1)      //The failing LBA shall be the LBA of the uncorrectable sector      //that caused the test to fail. If the device encountered more      //than one uncorrectable sector during the test, this field      //shall indicate the LBA of the first uncorrectable sector      //encountered. If the test passed or the test failed for some      //reason other than an uncorrectable sector, the value of this      //field is undefined.      // This is true in ALL ATA-5 specs            if (!errorfound || log->lbafirstfailure==0xffffffff || log->lbafirstfailure==0x00000000)        sprintf(firstlba,"%s","-");      else              sprintf(firstlba,"%u",log->lbafirstfailure);      // print out a header if needed      if (noheaderprinted && (allentries || errorfound)){        pout("Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error\n");        noheaderprinted=0;      }            // print out an entry, either if we are printing all entries OR      // if an error was found      if (allentries || errorfound)        pout("#%2d  %s %s %s  %8d         %s\n", testno, msgtest, msgstat, percent, (int)log->timestamp, firstlba);      // keep track of time of most recent error      if (errorfound && !hours)        hours=log->timestamp;    }  }  if (!allentries && retval)    pout("\n");  hours = hours << 8;  return (retval | hours);}void ataPseudoCheckSmart ( struct ata_smart_values *data,                            struct ata_smart_thresholds_pvt *thresholds) {  int i;  int failed = 0;  for (i = 0 ; i < NUMBER_ATA_SMART_ATTRIBUTES ; i++) {    if (data->vendor_attributes[i].id &&           thresholds->thres_entries[i].id &&        ATTRIBUTE_FLAGS_PREFAILURE(data->vendor_attributes[i].flags) &&        (data->vendor_attributes[i].current <= thresholds->thres_entries[i].threshold) &&        (thresholds->thres_entries[i].threshold != 0xFE)){      pout("Attribute ID %d Failed\n",(int)data->vendor_attributes[i].id);      failed = 1;    }   }     pout("%s\n", ( failed )?         "SMART overall-health self-assessment test result: FAILED!\n"         "Drive failure expected in less than 24 hours. SAVE ALL DATA":         "SMART overall-health self-assessment test result: PASSED");}// Format SCT Temperature valuestatic const char * sct_ptemp(signed char x, char * buf){  if (x == -128 /*0x80 = unknown*/)    strcpy(buf, " ?");  else    sprintf(buf, "%2d", x);  return buf;}static const char * sct_pbar(int x, char * buf){  if (x <= 19)    x = 0;  else    x -= 19;  bool ov = false;  if (x > 40) {    x = 40; ov = true;  }  if (x > 0) {    memset(buf, '*', x);    if (ov)      buf[x-1] = '+';    buf[x] = 0;  }  else {    buf[0] = '-'; buf[1] = 0;  }  return buf;}static const char * sct_device_state_msg(unsigned char state){  switch (state) {    case 0: return "Active";    case 1: return "Stand-by";    case 2: return "Sleep";    case 3: return "DST executing in background";    case 4: return "SMART Off-line Data Collection executing in background";    case 5: return "SCT command executing in background";    default:return "Unknown";  }}// Print SCT Statusstatic int ataPrintSCTStatus(const ata_sct_status_response * sts){  pout("SCT Status Version:                  %u\n", sts->format_version);  pout("SCT Version (vendor specific):       %u (0x%04x)\n", sts->sct_version, sts->sct_version);  pout("SCT Support Level:                   %u\n", sts->sct_spec);  pout("Device State:                        %s (%u)\n",    sct_device_state_msg(sts->device_state), sts->device_state);  char buf1[20], buf2[20];  if (   !sts->min_temp && !sts->life_min_temp && !sts->byte205      && !sts->under_limit_count && !sts->over_limit_count     ) {    // "Reserved" fields not set, assume "old" format version 2    // Table 11 of T13/1701DT Revision 5    // Table 54 of T13/1699-D Revision 3e    pout("Current Temperature:                 %s Celsius\n",      sct_ptemp(sts->hda_temp, buf1));    pout("Power Cycle Max Temperature:         %s Celsius\n",      sct_ptemp(sts->max_temp, buf2));    pout("Lifetime    Max Temperature:         %s Celsius\n",      sct_ptemp(sts->life_max_temp, buf2));  }  else {    // Assume "new" format version 2 or version 3    // T13/e06152r0-3 (Additional SCT Temperature Statistics)    // Table 60 of T13/1699-D Revision 3f    pout("Current Temperature:                    %s Celsius\n",      sct_ptemp(sts->hda_temp, buf1));    pout("Power Cycle Min/Max Temperature:     %s/%s Celsius\n",      sct_ptemp(sts->min_temp, buf1), sct_ptemp(sts->max_temp, buf2));    pout("Lifetime    Min/Max Temperature:     %s/%s Celsius\n",      sct_ptemp(sts->life_min_temp, buf1), sct_ptemp(sts->life_max_temp, buf2));    if (sts->byte205) // e06152r0-2, removed in e06152r3      pout("Lifetime    Average Temperature:        %s Celsius\n",        sct_ptemp((signed char)sts->byte205, buf1));    pout("Under/Over Temperature Limit Count:  %2u/%u\n",      sts->under_limit_count, sts->over_limit_count);  }  return 0;}// Print SCT Temperature History Tablestatic int ataPrintSCTTempHist(const ata_sct_temperature_history_table * tmh){  char buf1[20], buf2[80];  pout("SCT Temperature History Version:     %u\n", tmh->format_version);  pout("Temperature Sampling Period:         %u minute%s\n",    tmh->sampling_period, (tmh->sampling_period==1?"":"s"));  pout("Temperature Logging Interval:        %u minute%s\n",    tmh->interval,        (tmh->interval==1?"":"s"));  pout("Min/Max recommended Temperature:     %s/%s Celsius\n",    sct_ptemp(tmh->min_op_limit, buf1), sct_ptemp(tmh->max_op_limit, buf2));  pout("Min/Max Temperature Limit:           %s/%s Celsius\n",    sct_ptemp(tmh->under_limit, buf1), sct_ptemp(tmh->over_limit, buf2));  pout("Temperature History Size (Index):    %u (%u)\n", tmh->cb_size, tmh->cb_index);  if (!(0 < tmh->cb_size && tmh->cb_size <= sizeof(tmh->cb) && tmh->cb_index < tmh->cb_size)) {    pout("Error invalid Temperature History Size or Index\n");    return 0;  }  // Print table  pout("\nIndex    Estimated Time   Temperature Celsius\n");  unsigned n = 0, i = (tmh->cb_index+1) % tmh->cb_size;  unsigned interval = (tmh->interval > 0 ? tmh->interval : 1);  time_t t = time(0) - (tmh->cb_size-1) * interval * 60;  t -= t % (interval * 60);  while (n < tmh->cb_size) {    // Find range of identical temperatures    unsigned n1 = n, n2 = n+1, i2 = (i+1) % tmh->cb_size;    while (n2 < tmh->cb_size && tmh->cb[i2] == tmh->cb[i]) {      n2++; i2 = (i2+1) % tmh->cb_size;    }    // Print range    while (n < n2) {      if (n == n1 || n == n2-1 || n2 <= n1+3) {        char date[30];        // TODO: Don't print times < boot time        strftime(date, sizeof(date), "%Y-%m-%d %H:%M", localtime(&t));        pout(" %3u    %s    %s  %s\n", i, date,          sct_ptemp(tmh->cb[i], buf1), sct_pbar(tmh->cb[i], buf2));      }      else if (n == n1+1) {        pout(" ...    ..(%3u skipped).    ..  %s\n",          n2-n1-2, sct_pbar(tmh->cb[i], buf2));      }      t += interval * 60; i = (i+1) % tmh->cb_size; n++;    }  }  //assert(n == tmh->cb_size && i == (tmh->cb_index+1) % tmh->cb_size);  return 0;}// Compares failure type to policy in effect, and either exits or// simply returns to the calling routine.void failuretest(int type, int returnvalue){

⌨️ 快捷键说明

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