📄 ataprint.cpp
字号:
// If this is an error in an "optional" SMART command if (type==OPTIONAL_CMD){ if (con->conservative){ pout("An optional SMART command failed: exiting. Remove '-T conservative' option to continue.\n"); EXIT(returnvalue); } return; } // If this is an error in a "mandatory" SMART command if (type==MANDATORY_CMD){ if (con->permissive--) return; pout("A mandatory SMART command failed: exiting. To continue, add one or more '-T permissive' options.\n"); EXIT(returnvalue); } pout("Smartctl internal error in failuretest(type=%d). Please contact developers at " PACKAGE_HOMEPAGE "\n",type); EXIT(returnvalue|FAILCMD);}// Used to warn users about invalid checksums. Action to be taken may be// altered by the user.void checksumwarning(const char *string){ // user has asked us to ignore checksum errors if (con->checksumignore) return; pout("Warning! %s error: invalid SMART checksum.\n",string); // user has asked us to fail on checksum errors if (con->checksumfail) EXIT(FAILSMART); return;}// Initialize to zero just in case some SMART routines don't workstruct ata_identify_device drive;struct ata_smart_values smartval;struct ata_smart_thresholds_pvt smartthres;struct ata_smart_errorlog smarterror;struct ata_smart_selftestlog smartselftest;int ataPrintMain (int fd){ int timewait,code; int returnval=0, retid=0, supported=0, needupdate=0, known=0; const char * powername = 0; char powerchg = 0; // If requested, check power mode first if (con->powermode) { unsigned char powerlimit = 0xff; int powermode = ataCheckPowerMode(fd); switch (powermode) { case -1: if (errno == ENOSYS) { pout("CHECK POWER STATUS not implemented, ignoring -n Option\n"); break; } powername = "SLEEP"; powerlimit = 2; break; case 0: powername = "STANDBY"; powerlimit = 3; break; case 0x80: powername = "IDLE"; powerlimit = 4; break; case 0xff: powername = "ACTIVE or IDLE"; break; default: pout("CHECK POWER STATUS returned %d, not ATA compliant, ignoring -n Option\n", powermode); break; } if (powername) { if (con->powermode >= powerlimit) { pout("Device is in %s mode, exit(%d)\n", powername, FAILPOWER); return FAILPOWER; } powerchg = (powermode != 0xff); // SMART tests will spin up drives } } // Start by getting Drive ID information. We need this, to know if SMART is supported. if ((retid=ataReadHDIdentity(fd,&drive))<0){ pout("Smartctl: Device Read Identity Failed (not an ATA/ATAPI device)\n\n"); failuretest(MANDATORY_CMD, returnval|=FAILID); } // If requested, show which presets would be used for this drive and exit. if (con->showpresets) { showpresets(&drive); EXIT(0); } // Use preset vendor attribute options unless user has requested otherwise. if (!con->ignorepresets){ unsigned char *charptr; if ((charptr=con->attributedefs)) applypresets(&drive, &charptr, con); else { pout("Fatal internal error in ataPrintMain()\n"); EXIT(returnval|=FAILCMD); } } // Print most drive identity information if requested if (con->driveinfo){ pout("=== START OF INFORMATION SECTION ===\n"); known = ataPrintDriveInfo(&drive); } // Was this a packet device? if (retid>0){ pout("SMART support is: Unavailable - Packet Interface Devices [this device: %s] don't support ATA SMART\n", packetdevicetype(retid-1)); failuretest(MANDATORY_CMD, returnval|=FAILSMART); } // if drive does not supports SMART it's time to exit supported=ataSmartSupport(&drive); if (supported != 1){ if (supported==0) { pout("SMART support is: Unavailable - device lacks SMART capability.\n"); failuretest(MANDATORY_CMD, returnval|=FAILSMART); pout(" Checking to be sure by trying SMART ENABLE command.\n"); } else { pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 82-83 don't show if SMART supported.\n"); if (!known) failuretest(MANDATORY_CMD, returnval|=FAILSMART); pout(" Checking for SMART support by trying SMART ENABLE command.\n"); } if (ataEnableSmart(fd)){ pout(" SMART ENABLE failed - this establishes that this device lacks SMART functionality.\n"); failuretest(MANDATORY_CMD, returnval|=FAILSMART); supported=0; } else { pout(" SMART ENABLE appeared to work! Continuing.\n"); supported=1; } if (!con->driveinfo) pout("\n"); } // Now print remaining drive info: is SMART enabled? if (con->driveinfo){ int ison=ataIsSmartEnabled(&drive),isenabled=ison; if (ison==-1) { pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 85-87 don't show if SMART is enabled.\n"); failuretest(MANDATORY_CMD, returnval|=FAILSMART); // check SMART support by trying a command pout(" Checking to be sure by trying SMART RETURN STATUS command.\n"); isenabled=ataDoesSmartWork(fd); } else { pout("SMART support is: Available - device has SMART capability.\n");#ifdef HAVE_ATA_IDENTIFY_IS_CACHED if (ata_identify_is_cached(fd)) { pout(" %sabled status cached by OS, trying SMART RETURN STATUS cmd.\n", (isenabled?"En":"Dis")); isenabled=ataDoesSmartWork(fd); }#endif } if (isenabled) pout("SMART support is: Enabled\n"); else { if (ison==-1) pout("SMART support is: Unavailable\n"); else pout("SMART support is: Disabled\n"); } // Print the (now possibly changed) power mode if available if (powername) pout("Power mode %s %s\n", (powerchg?"was:":"is: "), powername); pout("\n"); } // START OF THE ENABLE/DISABLE SECTION OF THE CODE if (con->smartenable || con->smartdisable || con->smartautosaveenable || con->smartautosavedisable || con->smartautoofflineenable || con->smartautoofflinedisable) pout("=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n"); // Enable/Disable SMART commands if (con->smartenable){ if (ataEnableSmart(fd)) { pout("Smartctl: SMART Enable Failed.\n\n"); failuretest(MANDATORY_CMD, returnval|=FAILSMART); } else pout("SMART Enabled.\n"); } // From here on, every command requires that SMART be enabled... if (!ataDoesSmartWork(fd)) { pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n"); return returnval; } // Turn off SMART on device if (con->smartdisable){ if (ataDisableSmart(fd)) { pout( "Smartctl: SMART Disable Failed.\n\n"); failuretest(MANDATORY_CMD,returnval|=FAILSMART); } pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n"); return returnval; } // Let's ALWAYS issue this command to get the SMART status code=ataSmartStatus2(fd); if (code==-1) failuretest(MANDATORY_CMD, returnval|=FAILSMART); // Enable/Disable Auto-save attributes if (con->smartautosaveenable){ if (ataEnableAutoSave(fd)){ pout( "Smartctl: SMART Enable Attribute Autosave Failed.\n\n"); failuretest(MANDATORY_CMD, returnval|=FAILSMART); } else pout("SMART Attribute Autosave Enabled.\n"); } if (con->smartautosavedisable){ if (ataDisableAutoSave(fd)){ pout( "Smartctl: SMART Disable Attribute Autosave Failed.\n\n"); failuretest(MANDATORY_CMD, returnval|=FAILSMART); } else pout("SMART Attribute Autosave Disabled.\n"); } // for everything else read values and thresholds are needed if (ataReadSmartValues(fd, &smartval)){ pout("Smartctl: SMART Read Values failed.\n\n"); failuretest(OPTIONAL_CMD, returnval|=FAILSMART); } if (ataReadSmartThresholds(fd, &smartthres)){ pout("Smartctl: SMART Read Thresholds failed.\n\n"); failuretest(OPTIONAL_CMD, returnval|=FAILSMART); } // Enable/Disable Off-line testing if (con->smartautoofflineenable){ if (!isSupportAutomaticTimer(&smartval)){ pout("Warning: device does not support SMART Automatic Timers.\n\n"); failuretest(OPTIONAL_CMD, returnval|=FAILSMART); } needupdate=1; if (ataEnableAutoOffline(fd)){ pout( "Smartctl: SMART Enable Automatic Offline Failed.\n\n"); failuretest(OPTIONAL_CMD, returnval|=FAILSMART); } else pout("SMART Automatic Offline Testing Enabled every four hours.\n"); } if (con->smartautoofflinedisable){ if (!isSupportAutomaticTimer(&smartval)){ pout("Warning: device does not support SMART Automatic Timers.\n\n"); failuretest(OPTIONAL_CMD, returnval|=FAILSMART); } needupdate=1; if (ataDisableAutoOffline(fd)){ pout("Smartctl: SMART Disable Automatic Offline Failed.\n\n"); failuretest(OPTIONAL_CMD, returnval|=FAILSMART); } else pout("SMART Automatic Offline Testing Disabled.\n"); } if (needupdate && ataReadSmartValues(fd, &smartval)){ pout("Smartctl: SMART Read Values failed.\n\n"); failuretest(OPTIONAL_CMD, returnval|=FAILSMART); } // all this for a newline! if (con->smartenable || con->smartdisable || con->smartautosaveenable || con->smartautosavedisable || con->smartautoofflineenable || con->smartautoofflinedisable) pout("\n"); // START OF READ-ONLY OPTIONS APART FROM -V and -i if ( con->checksmart || con->generalsmartvalues || con->smartvendorattrib || con->smarterrorlog || con->smartselftestlog || con->selectivetestlog || con->scttempsts || con->scttemphist ) pout("=== START OF READ SMART DATA SECTION ===\n"); // Check SMART status (use previously returned value) if (con->checksmart){ switch (code) { case 0: // The case where the disk health is OK pout("SMART overall-health self-assessment test result: PASSED\n"); if (ataCheckSmart(&smartval, &smartthres,0)){ if (con->smartvendorattrib) pout("See vendor-specific Attribute list for marginal Attributes.\n\n"); else { PRINT_ON(con); pout("Please note the following marginal Attributes:\n"); PrintSmartAttribWithThres(&smartval, &smartthres,2); } returnval|=FAILAGE; } else pout("\n"); break; case 1: // The case where the disk health is NOT OK PRINT_ON(con); pout("SMART overall-health self-assessment test result: FAILED!\n" "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n"); PRINT_OFF(con); if (ataCheckSmart(&smartval, &smartthres,1)){ returnval|=FAILATTR; if (con->smartvendorattrib) pout("See vendor-specific Attribute list for failed Attributes.\n\n"); else { PRINT_ON(con); pout("Failed Attributes:\n"); PrintSmartAttribWithThres(&smartval, &smartthres,1); } } else pout("No failed Attributes found.\n\n"); returnval|=FAILSTATUS; PRINT_OFF(con); break; case -1: default: // The case where something went wrong with HDIO_DRIVE_TASK ioctl() if (ataCheckSmart(&smartval, &smartthres,1)){ PRINT_ON(con); pout("SMART overall-health self-assessment test result: FAILED!\n" "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n"); PRINT_OFF(con); returnval|=FAILATTR; returnval|=FAILSTATUS; if (con->smartvendorattrib) pout("See vendor-specific Attribute list for failed Attributes.\n\n"); else { PRINT_ON(con); pout("Failed Attributes:\n"); PrintSmartAttribWithThres(&smartval, &smartthres,1); } } else { pout("SMART overall-health self-assessment test result: PASSED\n"); if (ataCheckSmart(&smartval, &smartthres,0)){ if (con->smartvendorattrib) pout("See vendor-specific Attribute list for marginal Attributes.\n\n"); else { PRINT_ON(con); pout("Please note the following marginal Attributes:\n"); PrintSmartAttribWithThres(&smartval, &smartthres,2); } returnval|=FAILAGE; } else pout("\n"); } PRINT_OFF(con); break; } // end of switch statement PRINT_OFF(con); } // end of checking SMART Status // Print general SMART values if (con->generalsmartvalues) ataPrintGeneralSmartValues(&smartval, &drive); // Print vendor-specific attributes if (con->smartvendorattrib){ PRINT_ON(con); PrintSmartAttribWithThres(&smartval, &smartthres,con->printing_switchable?2:0); PRINT_OFF(con); } // Print SMART log Directory if (con->smartlogdirectory){ struct ata_smart_log_directory smartlogdirectory; if (!isGeneralPurposeLoggingCapable(&drive)){ pout("Warning: device do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -