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

📄 atacmds.cpp

📁 硬盘各项性能的测试,如温度容量版本健康度型号
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * atacmds.cpp *  * Home page of code is: http://smartmontools.sourceforge.net * * Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * 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. * * This code was originally developed as a Senior Thesis by Michael Cornwell * at the Concurrent Systems Laboratory (now part of the Storage Systems * Research Center), Jack Baskin School of Engineering, University of * California, Santa Cruz. http://ssrc.soe.ucsc.edu/ *  */#include <stdio.h>#include <string.h>#include <errno.h>#include <stdlib.h>#include <ctype.h>#include "config.h"#include "int64.h"#include "atacmds.h"#include "scsiata.h"#include "extern.h"#include "utility.h"const char *atacmds_c_cvsid="$Id: atacmds.cpp,v 1.190 2008/03/04 22:09:47 ballen4705 Exp $"ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSIATA_H_CVSID UTILITY_H_CVSID;// to hold onto exit code for atexit routineextern int exitstatus;// for passing global control variablesextern smartmonctrl *con;// These Drive Identity tables are taken from hdparm 5.2, and are also// given in the ATA/ATAPI specs for the IDENTIFY DEVICE command.  Note// that SMART was first added into the ATA/ATAPI-3 Standard with// Revision 3 of the document, July 25, 1995.  Look at the "Document// Status" revision commands at the beginning of// http://www.t13.org/project/d2008r6.pdf to see this.#define NOVAL_0                 0x0000#define NOVAL_1                 0xffff/* word 81: minor version number */#define MINOR_MAX 0x22const char *minor_str[] = {                     /* word 81 value: */  "Device does not report version",             /* 0x0000       */  "ATA-1 X3T9.2 781D prior to revision 4",      /* 0x0001       */  "ATA-1 published, ANSI X3.221-1994",          /* 0x0002       */  "ATA-1 X3T9.2 781D revision 4",               /* 0x0003       */  "ATA-2 published, ANSI X3.279-1996",          /* 0x0004       */  "ATA-2 X3T10 948D prior to revision 2k",      /* 0x0005       */  "ATA-3 X3T10 2008D revision 1",               /* 0x0006       */ /* SMART NOT INCLUDED */  "ATA-2 X3T10 948D revision 2k",               /* 0x0007       */  "ATA-3 X3T10 2008D revision 0",               /* 0x0008       */   "ATA-2 X3T10 948D revision 3",                /* 0x0009       */  "ATA-3 published, ANSI X3.298-199x",          /* 0x000a       */  "ATA-3 X3T10 2008D revision 6",               /* 0x000b       */ /* 1st VERSION WITH SMART */  "ATA-3 X3T13 2008D revision 7 and 7a",        /* 0x000c       */  "ATA/ATAPI-4 X3T13 1153D revision 6",         /* 0x000d       */  "ATA/ATAPI-4 T13 1153D revision 13",          /* 0x000e       */  "ATA/ATAPI-4 X3T13 1153D revision 7",         /* 0x000f       */  "ATA/ATAPI-4 T13 1153D revision 18",          /* 0x0010       */  "ATA/ATAPI-4 T13 1153D revision 15",          /* 0x0011       */  "ATA/ATAPI-4 published, ANSI NCITS 317-1998", /* 0x0012       */  "ATA/ATAPI-5 T13 1321D revision 3",           /* 0x0013       */  "ATA/ATAPI-4 T13 1153D revision 14",          /* 0x0014       */  "ATA/ATAPI-5 T13 1321D revision 1",           /* 0x0015       */  "ATA/ATAPI-5 published, ANSI NCITS 340-2000", /* 0x0016       */  "ATA/ATAPI-4 T13 1153D revision 17",          /* 0x0017       */  "ATA/ATAPI-6 T13 1410D revision 0",           /* 0x0018       */  "ATA/ATAPI-6 T13 1410D revision 3a",          /* 0x0019       */  "ATA/ATAPI-7 T13 1532D revision 1",           /* 0x001a       */  "ATA/ATAPI-6 T13 1410D revision 2",           /* 0x001b       */  "ATA/ATAPI-6 T13 1410D revision 1",           /* 0x001c       */  "ATA/ATAPI-7 published, ANSI INCITS 397-2005",/* 0x001d       */  "ATA/ATAPI-7 T13 1532D revision 0",           /* 0x001e       */  "reserved",                                   /* 0x001f       */  "reserved",                                   /* 0x0020       */  "ATA/ATAPI-7 T13 1532D revision 4a",          /* 0x0021       */  "ATA/ATAPI-6 published, ANSI INCITS 361-2002" /* 0x0022       */};// NOTE ATA/ATAPI-4 REV 4 was the LAST revision where the device// attribute structures were NOT completely vendor specific.  So any// disk that is ATA/ATAPI-4 or above can not be trusted to show the// vendor values in sensible format.// Negative values below are because it doesn't support SMARTconst int actual_ver[] = {   /* word 81 value: */  0,            /* 0x0000       WARNING:        */  1,            /* 0x0001       WARNING:        */  1,            /* 0x0002       WARNING:        */  1,            /* 0x0003       WARNING:        */  2,            /* 0x0004       WARNING:   This array           */  2,            /* 0x0005       WARNING:   corresponds          */  -3, /*<== */  /* 0x0006       WARNING:   *exactly*            */  2,            /* 0x0007       WARNING:   to the ATA/          */  -3, /*<== */  /* 0x0008       WARNING:   ATAPI version        */  2,            /* 0x0009       WARNING:   listed in            */  3,            /* 0x000a       WARNING:   the                  */  3,            /* 0x000b       WARNING:   minor_str            */  3,            /* 0x000c       WARNING:   array                */  4,            /* 0x000d       WARNING:   above.               */  4,            /* 0x000e       WARNING:                        */  4,            /* 0x000f       WARNING:   If you change        */  4,            /* 0x0010       WARNING:   that one,            */  4,            /* 0x0011       WARNING:   change this one      */  4,            /* 0x0012       WARNING:   too!!!               */  5,            /* 0x0013       WARNING:        */  4,            /* 0x0014       WARNING:        */  5,            /* 0x0015       WARNING:        */  5,            /* 0x0016       WARNING:        */  4,            /* 0x0017       WARNING:        */  6,            /* 0x0018       WARNING:        */  6,            /* 0x0019       WARNING:        */  7,            /* 0x001a       WARNING:        */  6,            /* 0x001b       WARNING:        */  6,            /* 0x001c       WARNING:        */  7,            /* 0x001d       WARNING:        */  7,            /* 0x001e       WARNING:        */  0,            /* 0x001f       WARNING:        */  0,            /* 0x0020       WARNING:        */  7,            /* 0x0021       WARNING:        */  6             /* 0x0022       WARNING:        */};// When you add additional items to this list, you should then:// 0 -- update this list// 1 -- modify the following function parse_attribute_def()// 2 -- if needed, modify ataPrintSmartAttribRawValue()// 3 -  if needed, modify ataPrintSmartAttribName()// 4 -- add #define PRESET_N_DESCRIPTION at top of knowndrives.c// 5 -- add drive in question into knowndrives[] table in knowndrives.c// 6 -- update smartctl.8// 7 -- update smartd.8// 8 -- do "make smartd.conf.5" to update smartd.conf.5// 9 -- update CHANGELOG fileconst char *vendorattributeargs[] = {  // 0  defs[9]=1  "9,minutes",  // 1  defs[9]=3  "9,seconds",  // 2  defs[9]=2  "9,temp",  // 3  defs[220]=1  "220,temp",  // 4  defs[*]=253  "N,raw8",  // 5  defs[*]=254  "N,raw16",  // 6  defs[*]=255  "N,raw48",  // 7  defs[200]=1  "200,writeerrorcount",  // 8  defs[9]=4  "9,halfminutes",  // 9  defs[194]=1  "194,10xCelsius",  // 10 defs[194]=2  "194,unknown",  // 11 defs[193]=1  "193,loadunload",  // 12 defs[201]=1  "201,detectedtacount",  // 13 defs[192]=1  "192,emergencyretractcyclect",  // 14 defs[198]=1  "198,offlinescanuncsectorct",  // NULL should always terminate the array  NULL};// This are the meanings of the Self-test failure checkpoint byte.// This is in the self-test log at offset 4 bytes into the self-test// descriptor and in the SMART READ DATA structure at byte offset// 371. These codes are not well documented.  The meanings returned by// this routine are used (at least) by Maxtor and IBM. Returns NULL if// not recognized.  Currently the maximum length is 15 bytes.const char *SelfTestFailureCodeName(unsigned char which){    switch (which) {  case 0:    return "Write_Test";  case 1:    return "Servo_Basic";  case 2:    return "Servo_Random";  case 3:    return "G-list_Scan";  case 4:    return "Handling_Damage";  case 5:    return "Read_Scan";  default:    return NULL;  }}// This is a utility function for parsing pairs like "9,minutes" or// "220,temp", and putting the correct flag into the attributedefs// array.  Returns 1 if problem, 0 if pair has been recongized.int parse_attribute_def(char *pair, unsigned char **defsptr){  int i,j;  char temp[32];  unsigned char *defs;  // If array does not exist, allocate it  if (!*defsptr && !(*defsptr=(unsigned char *)calloc(MAX_ATTRIBUTE_NUM, 1))){    pout("Out of memory in parse_attribute_def\n");    EXIT(1);  }  defs=*defsptr;  // look along list and see if we find the pair  for (i=0; vendorattributeargs[i] && strcmp(pair, vendorattributeargs[i]); i++);  switch (i) {  case 0:    // attribute 9 is power on time in minutes    defs[9]=1;    return 0;  case 1:    // attribute 9 is power-on-time in seconds    defs[9]=3;    return 0;  case 2:    // attribute 9 is temperature in celsius    defs[9]=2;    return 0;  case 3:    // attribute 220 is temperature in celsius    defs[220]=1;    return 0;  case 4:    // print all attributes in raw 8-bit form    for (j=0; j<MAX_ATTRIBUTE_NUM; j++)      defs[j]=253;    return 0;  case 5:    // print all attributes in raw 16-bit form    for (j=0; j<MAX_ATTRIBUTE_NUM; j++)      defs[j]=254;    return 0;  case 6:    // print all attributes in raw 48-bit form    for (j=0; j<MAX_ATTRIBUTE_NUM; j++)      defs[j]=255;    return 0;  case 7:    // attribute 200 is write error count    defs[200]=1;    return 0;  case 8:    // attribute 9 increments once every 30 seconds (power on time    // measure)    defs[9]=4;    return 0;  case 9:    // attribute 194 is ten times disk temp in Celsius    defs[194]=1;    return 0;  case 10:    // attribute 194 is unknown    defs[194]=2;    return 0;  case 11:    // Hitachi : Attributes 193 has 2 values : 1 load, 1 normal unload    defs[193]=1;    return 0;  case 12:    // Fujitsu    defs[201]=1;    return 0;  case 13:    // Fujitsu    defs[192]=1;    return 0;  case 14:    // Fujitsu    defs[198]=1;    return 0;  default:    // pair not found    break;  }  // At this point, either the pair was not found, or it is of the  // form N,uninterpreted, in which case we need to parse N  j=sscanf(pair,"%d,%14s", &i, temp);   // if no match to pattern, unrecognized  if (j!=2 || i<0 || i >255)    return 1;  // check for recognized strings  if (!strcmp(temp, "raw8")) {    defs[i]=253;    return 0;  }    // check for recognized strings  if (!strcmp(temp, "raw16")) {    defs[i]=254;    return 0;  }    // check for recognized strings  if (!strcmp(temp, "raw48")) {    defs[i]=255;    return 0;  }   // didn't recognize the string  return 1;}// Structure used in sorting the array vendorattributeargs[].typedef struct vaa_pair_s {  const char *vaa;  const char *padded_vaa;} vaa_pair;// Returns a copy of s with all numbers of less than three digits padded with// leading zeros.  Returns NULL if there isn't enough memory available.  The// memory for the string is dynamically allocated and should be freed by the// caller.char *pad_numbers(const char *s){  char c, *t, *u;  const char *r;  int i, len, ndigits = 0;  // Allocate the maximum possible amount of memory needed.  if (!(t = (char *)malloc(strlen(s)*2+2)))    return NULL;  // Copy the string s to t, padding any numbers of less than three digits  // with leading zeros.  The string is copied backwards to simplify the code.  r = s + strlen(s);  u = t;  while (( r-- >= s)) {    if (isdigit((int)*r))      ndigits++;    else if (ndigits > 0) {      while (ndigits++ < 3)        *u++ = '0';      ndigits = 0;    }    *u++ = *r;  }  *u = '\0';  // Reverse the string in t.  len = strlen(t);  for (i = 0; i < len/2; i++) {    c          = t[i];    t[i]       = t[len-1-i];    t[len-1-i] = c;  }  return t;}// Comparison function for qsort().  Used by sort_vendorattributeargs().int compare_vaa_pairs(const void *a, const void *b){  vaa_pair *p = (vaa_pair *)a;  vaa_pair *q = (vaa_pair *)b;  return strcmp(p->padded_vaa, q->padded_vaa);}// Returns a sorted list of vendorattributeargs or NULL if there is not enough// memory available.  The memory for the list is allocated dynamically and// should be freed by the caller.// To perform the sort, any numbers in the strings are padded out to three// digits by adding leading zeros.  For example,////    "9,minutes"  becomes  "009,minutes"//    "N,raw16"    becomes  "N,raw016"//// and the original strings are paired with the padded strings.  The list of// pairs is then sorted by comparing the padded strings (using strcmp) and the// result is then the list of unpadded strings.//const char **sort_vendorattributeargs(void) {  const char **ps, **sorted_list = NULL;  vaa_pair *pairs, *pp;  int count, i;  // Figure out how many strings are in vendorattributeargs[] (not including  // the terminating NULL).  count = (sizeof vendorattributeargs) / sizeof(char *) - 1;  // Construct a list of pairs of strings from vendorattributeargs[] and their  // padded equivalents.  if (!(pairs = (vaa_pair *)malloc(sizeof(vaa_pair) * count)))    goto END;  for (ps = vendorattributeargs, pp = pairs; *ps; ps++, pp++) {    pp->vaa = *ps;    if (!(pp->padded_vaa = pad_numbers(*ps)))      goto END;  }  // Sort the array of vaa_pair structures by comparing the padded strings  // using strcmp().  qsort(pairs, count, sizeof(vaa_pair), compare_vaa_pairs);

⌨️ 快捷键说明

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