diff --git a/include/openseachest_util_options.h b/include/openseachest_util_options.h index 1650154..d54ca55 100644 --- a/include/openseachest_util_options.h +++ b/include/openseachest_util_options.h @@ -52,7 +52,7 @@ extern "C" UTIL_EXIT_CANNOT_OPEN_FILE, UTIL_EXIT_FILE_ALREADY_EXISTS, UTIL_EXIT_NEED_ELEVATED_PRIVILEGES, - UTIL_EXIT_NOT_ENOUGH_RESOURCES, + UTIL_EXIT_NOT_ENOUGH_RESOURCES, //TODO: More generic exit codes go here UTIL_EXIT_ERROR_WRITING_FILE, //added 5/19/20 //Tool specific exit codes go here @@ -133,10 +133,10 @@ extern "C" #define SCAN_FLAGS_LONG_OPT_STRING "scanFlags" #define SCAN_FLAGS_LONG_OPT { SCAN_FLAGS_LONG_OPT_STRING, required_argument, NULL, SCAN_FLAGS_SHORT_OPT } - #define NO_BANNER_FLAG noBanner - #define NO_BANNER_VAR getOptBool NO_BANNER_FLAG = goFalse; - #define NO_BANNER_OPT_STRING "noBanner" - #define NO_BANNER_OPT { NO_BANNER_OPT_STRING, no_argument, &NO_BANNER_FLAG, goTrue} + #define NO_BANNER_FLAG noBanner + #define NO_BANNER_VAR getOptBool NO_BANNER_FLAG = goFalse; + #define NO_BANNER_OPT_STRING "noBanner" + #define NO_BANNER_OPT { NO_BANNER_OPT_STRING, no_argument, &NO_BANNER_FLAG, goTrue} #define SHOW_BANNER_FLAG showBanner #define SHOW_BANNER_VAR bool SHOW_BANNER_FLAG = false; @@ -157,11 +157,11 @@ extern "C" #define TEST_UNIT_READY_LONG_OPT_STRING "testUnitReady" #define TEST_UNIT_READY_LONG_OPT { TEST_UNIT_READY_LONG_OPT_STRING, no_argument, &TEST_UNIT_READY_FLAG, goTrue } - #define FAST_DISCOVERY_FLAG fastDiscovery - #define FAST_DISCOVERY_VAR \ - getOptBool FAST_DISCOVERY_FLAG = goFalse; - #define FAST_DISCOVERY_LONG_OPT_STRING "fastDiscovery" - #define FAST_DISCOVERY_LONG_OPT { FAST_DISCOVERY_LONG_OPT_STRING, no_argument, &FAST_DISCOVERY_FLAG, goTrue } + #define FAST_DISCOVERY_FLAG fastDiscovery + #define FAST_DISCOVERY_VAR \ + getOptBool FAST_DISCOVERY_FLAG = goFalse; + #define FAST_DISCOVERY_LONG_OPT_STRING "fastDiscovery" + #define FAST_DISCOVERY_LONG_OPT { FAST_DISCOVERY_LONG_OPT_STRING, no_argument, &FAST_DISCOVERY_FLAG, goTrue } #define ONLY_SEAGATE_FLAG onlySeagateDrives #define ONLY_SEAGATE_VAR getOptBool ONLY_SEAGATE_FLAG = goFalse; @@ -757,17 +757,75 @@ extern "C" #define SET_POWER_CONSUMPTION_LONG_OPT_STRING "setPowerConsumption" #define SET_POWER_CONSUMPTION_LONG_OPT { SET_POWER_CONSUMPTION_LONG_OPT_STRING, required_argument, NULL, 0 } - //sanitize TODO: This is incomplete. Need to expand this a bit more and then clean up the implementation for command line parsing in openSeaChest_Erase + //SATA Only Sanitize freeze/antifreeze lock variables. These can be used to block sanitize, or stop a system from blocking sanitize with a freezelock + #define SANITIZE_FREEZE sanitizeFreezeLock + #define SANITIZE_FREEZE_VAR getOptBool SANITIZE_FREEZE = goFalse; + #define SANITIZE_FREEZE_LONG_OPT_STRING "sanitizeFreeze" + #define SANITIZE_FREEZE_LONG_OPT { SANITIZE_FREEZE_LONG_OPT_STRING, no_argument, &SANITIZE_FREEZE, goTrue } + + #define SANITIZE_ANTIFREEZE sanitizeAntiFreezeLock + #define SANITIZE_ANTIFREEZE_VAR getOptBool SANITIZE_ANTIFREEZE = goFalse; + #define SANITIZE_ANTIFREEZE_LONG_OPT_STRING "sanitizeAntiFreeze" + #define SANITIZE_ANTIFREEZE_LONG_OPT { SANITIZE_ANTIFREEZE_LONG_OPT_STRING, no_argument, &SANITIZE_ANTIFREEZE, goTrue } + + + #define SANITIZE_BLOCK_ERASE_STR "blockerase" + #define SANITIZE_CRYPTO_ERASE_STR "cryptoerase" + #define SANITIZE_OVERWRITE_ERASE_STR "overwrite" + + #define SANITIZE_INFO_FLAG sanitizeCapabilities + #define SANITIZE_RUN_BLOCK_ERASE sanitizeBlockErase + #define SANITIZE_RUN_CRYPTO_ERASE sanitizeCryptoErase + #define SANITIZE_RUN_OVERWRITE_ERASE sanitizeOverwriteErase #define SANITIZE_RUN_FLAG sanitize #define SANITIZE_UTIL_VARS \ bool SANITIZE_RUN_FLAG = false; \ - bool sanitizeInfo = false; \ - bool sanblockErase = false; \ - bool sancryptoErase = false; \ - bool sanoverwrite = false; \ - bool sanfreezelock = false; \ - bool sanAntiFreezeLock = false; + bool SANITIZE_INFO_FLAG = false; \ + bool SANITIZE_RUN_BLOCK_ERASE = false; \ + bool SANITIZE_RUN_CRYPTO_ERASE = false; \ + bool SANITIZE_RUN_OVERWRITE_ERASE = false; #define SANITIZE_LONG_OPT_STRING "sanitize" + #define SANITIZE_LONG_OPT { SANITIZE_LONG_OPT_STRING, required_argument, NULL, 'e' } + + //allow unrestricted sanitize exit option + #define SANITIZE_AUSE sanitizeAUSE + #define SANITIZE_AUSE_VAR getOptBool SANITIZE_AUSE = goFalse; + #define SANITIZE_AUSE_LONG_OPT_STRING "ause" + #define SANITIZE_AUSE_LONG_OPT { SANITIZE_AUSE_LONG_OPT_STRING, no_argument, &SANITIZE_AUSE, goTrue } + + //Sanitize overwrite invert pattern flag (invert between overwrite passes) + #define SANITIZE_IPBP sanitizeIPBP + #define SANITIZE_IPBP_VAR getOptBool SANITIZE_IPBP = goFalse; + #define SANITIZE_IPBP_LONG_OPT_STRING "ipbp" + #define SANITIZE_IPBP_LONG_OPT { SANITIZE_IPBP_LONG_OPT_STRING, no_argument, &SANITIZE_IPBP, goTrue } + + //Sanitize overwrite number of overwrite passes flag + #define SANITIZE_OVERWRITE_PASSES sanitizeOverwritePasses + #define SANITIZE_OVERWRITE_PASSES_VAR uint8_t SANITIZE_OVERWRITE_PASSES = 1;//default to a single pass. Max number depends on the drive standard implemented. (ATA/NVMe = 16, SCSI = 31) + #define SANITIZE_OVERWRITE_PASSES_LONG_OPT_STRING "overwritepasses" + #define SANITIZE_OVERWRITE_PASSES_LONG_OPT { SANITIZE_OVERWRITE_PASSES_LONG_OPT_STRING, required_argument, NULL, 0 } + + //zone no reset bit. Can be used in Sanitize erases or ATA security erase. + //when set, zones are left full to allow for verification. When not set, all write pointers are reset to the beginning of the zones. + #define ZONE_NO_RESET zbdZoneNoReset + #define ZONE_NO_RESET_VAR getOptBool ZONE_NO_RESET = goFalse; + #define ZONE_NO_RESET_LONG_OPT_STRING "znr" + #define ZONE_NO_RESET_LONG_OPT { ZONE_NO_RESET_LONG_OPT_STRING, no_argument, &ZONE_NO_RESET, goTrue } + + //No deallocate (NVMe for Sanitize command)...not currently in SATA or SAS, but maybe it will be one day-TJE + //when set, and the controller is not inhibiting this behavior, it allows reading and verifying all LBAs were erased. + #define NO_DEALLOCATE_AFTER_ERASE nvmeNoDeallocate + #define NO_DEALLOCATE_AFTER_ERASE_VAR getOptBool NO_DEALLOCATE_AFTER_ERASE = goFalse; + #define NO_DEALLOCATE_AFTER_ERASE_LONG_OPT_STRING "nodeallocate" + #define NO_DEALLOCATE_AFTER_ERASE_LONG_OPT { NO_DEALLOCATE_AFTER_ERASE_LONG_OPT_STRING, no_argument, &NO_DEALLOCATE_AFTER_ERASE, goTrue } + + //Call the function to refresh the known filesystems in the OS. This can be very important to do after an erase is completed. + //If an erase is completed this is done automatically already, however if polling for progress or needing a write after erase (SAS crypto/block) + //then a user may need to call this another time as well manually. + #define REFRESH_FILE_SYSTEMS refreshFileSystems + #define REFRESH_FILE_SYSTEMS_VAR getOptBool REFRESH_FILE_SYSTEMS = goFalse; + #define REFRESH_FILE_SYSTEMS_LONG_OPT_STRING "refreshfs" + #define REFRESH_FILE_SYSTEMS_LONG_OPT { REFRESH_FILE_SYSTEMS_LONG_OPT_STRING, no_argument, &REFRESH_FILE_SYSTEMS, goTrue } //download FW #define FIRMWARE_FILE_NAME_MAX_LEN 4096 @@ -1548,15 +1606,15 @@ extern "C" //Seagate Power Balance options (SATA only since SAS can use the setPowerConsumption options) #define SEAGATE_POWER_BALANCE_FLAG powerBalanceFeature - #define POWER_BALANCE_MODE powerBalanceMode + #define POWER_BALANCE_MODE powerBalanceMode #define SEAGATE_POWER_BALANCE_ENABLE_FLAG powerBalanceEnable - #define SEAGATE_POWER_BALANCE_LIMITED_FLAG powerBalanceLimited + #define SEAGATE_POWER_BALANCE_LIMITED_FLAG powerBalanceLimited #define SEAGATE_POWER_BALANCE_INFO_FLAG powerBalanceInfo #define SEAGATE_POWER_BALANCE_VARS \ - uint8_t POWER_BALANCE_MODE = 0;\ + uint8_t POWER_BALANCE_MODE = 0;\ bool SEAGATE_POWER_BALANCE_FLAG = false;\ bool SEAGATE_POWER_BALANCE_ENABLE_FLAG = false;\ - bool SEAGATE_POWER_BALANCE_LIMITED_FLAG = false;\ + bool SEAGATE_POWER_BALANCE_LIMITED_FLAG = false;\ bool SEAGATE_POWER_BALANCE_INFO_FLAG = false; #define SEAGATE_POWER_BALANCE_LONG_OPT_STRING "powerBalanceFeature" #define SEAGATE_POWER_BALANCE_LONG_OPT { SEAGATE_POWER_BALANCE_LONG_OPT_STRING, required_argument, NULL, 0 } @@ -2459,6 +2517,20 @@ extern "C" //----------------------------------------------------------------------------- void print_Sanitize_Help(bool shortHelp, const char *utilName); + void print_Sanitize_Freeze_Help(bool shortHelp); + + void print_Sanitize_Anti_Freeze_Help(bool shortHelp); + + void print_Sanitize_Overwrite_Passes_Help(bool shortHelp); + + void print_Sanitize_Overwrite_Invert_Help(bool shortHelp); + + void print_Sanitize_AUSE_Help(bool shortHelp); + + void print_Zone_No_Reset_Help(bool shortHelp); + + void print_Sanitize_No_Deallocate_Help(bool shortHelp); + //----------------------------------------------------------------------------- // // print_Writesame_Help() @@ -3056,19 +3128,19 @@ extern "C" //----------------------------------------------------------------------------- void print_Test_Unit_Ready_Help(bool shortHelp); - //----------------------------------------------------------------------------- - // - // print_Fast_Discovery_Help() - // - //! \brief Description: This function prints out the short or long help for the fast discovery option - // - // Entry: - //! \param[in] shortUsage = bool used to select when to print short or long help - // - // Exit: - // - //----------------------------------------------------------------------------- - void print_Fast_Discovery_Help(bool shortUsage); + //----------------------------------------------------------------------------- + // + // print_Fast_Discovery_Help() + // + //! \brief Description: This function prints out the short or long help for the fast discovery option + // + // Entry: + //! \param[in] shortUsage = bool used to select when to print short or long help + // + // Exit: + // + //----------------------------------------------------------------------------- + void print_Fast_Discovery_Help(bool shortUsage); void print_Firmware_Download_Help(bool shortHelp); @@ -3478,7 +3550,7 @@ extern "C" void print_No_Time_Limit_Help(bool shortHelp); - void print_No_Banner_Help(bool shortUsage); + void print_No_Banner_Help(bool shortUsage); void print_SAS_Phy_Partial_Help(bool shortHelp); @@ -3564,6 +3636,8 @@ extern "C" void print_WRV_Help(bool shortHelp); + void print_Refresh_Filesystems_Help(bool shortHelp); + #define OUTPUTPATH_PARSE outputPathPtr = optarg; typedef struct _deviceScanFlags @@ -3685,56 +3759,6 @@ uint64_t eraseTimeStartLBA = 0; eraseTimeSeconds *= timeMultiplier;/*adjust to a time in seconds if something other than seconds were entered*/ \ } -#define SANITIZE_SUBOPT_PARSE \ -if (optarg != NULL) \ -{ \ - int index = optind - 1; \ - char *nextSubOpt = NULL; \ - while (index < argc) \ - { \ - nextSubOpt = strdup(argv[index]); /*get the next subopt*/ \ - if (strncmp("-", nextSubOpt, 1) != 0) /*check if optarg is next switch so that we break out of parsing suboptions*/ \ - { \ - if (strncmp("blockerase", nextSubOpt, strlen(nextSubOpt)) == 0) \ - { \ - sanitize = true; \ - sanblockErase = true; \ - } \ - else if (strncmp("cryptoerase", nextSubOpt, strlen(nextSubOpt)) == 0) \ - { \ - sanitize = true; \ - sancryptoErase = true; \ - } \ - else if (strncmp("overwrite", nextSubOpt, strlen(nextSubOpt)) == 0) \ - { \ - sanitize = true; \ - sanoverwrite = true; \ - } \ - else if (strncmp("freezelock", nextSubOpt, strlen(nextSubOpt)) == 0) \ - { \ - sanitize = true; \ - sanfreezelock = true; \ - } \ - else if (strncmp("antifreezelock", nextSubOpt, strlen(nextSubOpt)) == 0) \ - { \ - sanitize = true; \ - sanAntiFreezeLock = true; \ - } \ - else if (strncmp("info", nextSubOpt, strlen(nextSubOpt)) == 0) \ - { \ - sanitize = true; /*this flag is used to show the support sanitize commands*/ \ - sanitizeInfo = true; \ - } \ - } \ - else \ - { \ - break; \ - } \ - index++; \ - } \ - optind = index; /*reset this since we were searching for options to pull out around getopt*/ \ -} - #if defined (__cplusplus) } #endif diff --git a/meson.build b/meson.build index 8382232..2f40739 100644 --- a/meson.build +++ b/meson.build @@ -31,6 +31,11 @@ if c.get_id().contains('gcc') or c.get_id().contains('clang') '-Wchar-subscripts', '-Wundef' ] + if target_machine.cpu_family() == 'ppc64' + #power pc builds generate a lot of warnings/notes about ABI changes since GCC-5 + #this flag is disabling them because this is way too noisy. + warning_flags += ['-Wno-psabi'] + endif elif c.get_id().contains('msvc') #See here for enabling/disabling msvc warnings: #https://learn.microsoft.com/en-us/cpp/build/reference/compiler-option-warning-level?view=msvc-170 diff --git a/src/openseachest_util_options.c b/src/openseachest_util_options.c index bbc5884..54e6b01 100644 --- a/src/openseachest_util_options.c +++ b/src/openseachest_util_options.c @@ -516,6 +516,32 @@ void print_Erase_Time_Help(bool shortHelp) } } +void print_Sanitize_Freeze_Help(bool shortHelp) +{ + printf("\t--%s\t(SATA Only)\n", SANITIZE_FREEZE_LONG_OPT_STRING); + if (!shortHelp) + { + printf("\t\tFreezelock is a command to block processing of sanitize\n"); + printf("\t\toperations until a power cycle is performed on a device.\n"); + printf("\t\tIt is only available on ATA drives. Once this command has been\n"); + printf("\t\tsent, the freezelock status becomes immediate and cannot be\n"); + printf("\t\tcleared until the drive has been powered off. All sanitize\n"); + printf("\t\tcommands, except a sanitize status will be aborted.\n\n"); + } +} + +void print_Sanitize_Anti_Freeze_Help(bool shortHelp) +{ + printf("\t--%s\t(SATA Only)\n", SANITIZE_ANTIFREEZE_LONG_OPT_STRING); + if (!shortHelp) + { + printf("\t\tAntifreezelock is a command that is designed to block a\n"); + printf("\t\tfreezelock command from locking out the sanitize feature set.\n"); + printf("\t\tIt is only available on ATA drives that support the ACS3, or\n"); + printf("\t\tnewer specification.\n\n"); + } +} + void print_Sanitize_Help(bool shortHelp, const char *utilName) { printf("\t--%s [info | blockerase | cryptoerase |\n", SANITIZE_LONG_OPT_STRING); @@ -530,10 +556,31 @@ void print_Sanitize_Help(bool shortHelp, const char *utilName) printf("\t\tsanitize erase operations are persistent across a power cycle\n"); printf("\t\tand cannot be stopped\n"); printf("\t\tExample: --%s blockerase --%s\n\n", SANITIZE_LONG_OPT_STRING, POLL_LONG_OPT_STRING); -#if defined (_WIN32)//TODO: handle Win PE somehow when we support WinPE - printf("\t\tNote: Windows 8 and higher block sanitize commands. Sanitize\n"); - printf("\t\toperations will show a failure status on these systems.\n\n"); -#endif + printf("\t\tBy default, sanitize runs in restricted exit mode, meaning the\n"); + printf("\t\tonly way to exit a failed sanitize is to attempt sanitize again\n"); + printf("\t\tuntil it completes successfully. Add the --%s option to run\n", SANITIZE_AUSE_LONG_OPT_STRING); + printf("\t\tin unrestricted mode. In unrestricted mode, if sanitize fails\n"); + printf("\t\tyou can exit this mode with the \"exit failure mode\" command\n"); + printf("\t\tor a successful sanitize command.\n\n"); + printf("\t\tFor Zoned block devices, the --%s option can be used\n", ZONE_NO_RESET_LONG_OPT_STRING); + printf("\t\tto stop the write pointers from resetting allowing full\n"); + printf("\t\tdrive verification to be performed upon completion of sanitize\n"); + printf("\t\tFor NVMe devices that support the deallocate feature (TRIM), the\n"); + printf("\t\t--%s option can be used to prevent the deallocation of blocks at\n", NO_DEALLOCATE_AFTER_ERASE_LONG_OPT_STRING); + printf("\t\tcompletion of sanitize to allow for full drive verification.\n"); + printf("\t\tNOTE: An NVMe controller may inhibit the no deallocate behavior\n"); + printf("\t\t and may deallocate anyways or fail the sanitize command when\n"); + printf("\t\t no deallocate is specified.\n\n"); +#if defined (_WIN32) + if (!is_Windows_PE()) + { + printf("\t\tNote: Windows 8 and higher block sanitize commands. Sanitize\n"); + printf("\t\toperations will show a failure status on these systems.\n"); + printf("\t\tStarting in Windows 11 or Windows 10 21H1, sanitize crypto\n"); + printf("\t\tor block erase can be executed on NVMe data drives that\n"); + printf("\t\tsupport the sanitize command set.\n\n"); + } +#endif //_WIN32 //blockerase info printf("\t\t* blockerase on some solid state drives is very fast at less\n"); printf("\t\tthan one (1) second, while others may take more that 30 seconds\n"); @@ -546,26 +593,116 @@ void print_Sanitize_Help(bool shortHelp, const char *utilName) printf("\t\tdata causing all previous data to be useless.\n\n"); //overwrite info printf("\t\t* overwrite is a physical overwrite on all current, past, and\n"); - printf("\t\tpotential user data. The ATA and SCSI specifications allow a\n"); + printf("\t\tpotential user data. The ATA, NVMe, & SCSI specifications allow a\n"); printf("\t\tuser defined pattern and multiple passes. %s will\n", utilName); - printf("\t\tuse a zero pattern and a single pass for this operation.\n\n"); + printf("\t\tuse a zero pattern and a single pass for this operation\n"); + printf("\t\tby default. Use --%s and --%s to specify\n", SANITIZE_OVERWRITE_PASSES_LONG_OPT_STRING, SANITIZE_IPBP_LONG_OPT_STRING); + printf("\t\tthe number of passes and whether to invert the pattern between\n"); + printf("\t\teach overwrite pass.\n\n"); //freezelock info - printf("\t\t* freezelock is a command to block processing of sanitize\n"); - printf("\t\toperations until a power cycle is performed on a device.\n"); - printf("\t\tIt is only available on ATA drives. Once this command has been\n"); - printf("\t\tsent, the freezelock status becomes immediate and cannot be\n"); - printf("\t\tcleared until the drive has been powered off. All sanitize\n"); - printf("\t\tcommands, except a sanitize status will be aborted.\n\n"); + printf("\t\t* freezelock - migrate to use of --%s\n\n", SANITIZE_FREEZE_LONG_OPT_STRING); //anti freezlock info - printf("\t\t* antifreezelock is a command that is designed to block a\n"); - printf("\t\tfreezelock command from locking out the sanitize feature set.\n"); - printf("\t\tIt is only available on ATA drives that support the ACS3, or\n"); - printf("\t\tnewer specification.\n\n"); + printf("\t\t* antifreezelock - migrate to use of --%s\n\n", SANITIZE_ANTIFREEZE_LONG_OPT_STRING); printf("\t\tWARNING: Sanitize may affect all LUNs/namespaces for devices\n"); printf("\t\t with multiple logical units or namespaces.\n\n"); } } +void print_Sanitize_Overwrite_Passes_Help(bool shortHelp) +{ + printf("\t--%s [ number of overwrite passes ]\n", SANITIZE_OVERWRITE_PASSES_LONG_OPT_STRING); + if (!shortHelp) + { + printf("\t\tSpecify the number of overwrite passes to use during a sanitize\n"); + printf("\t\toverwrite operation. By default, only a single overwrite pass\n"); + printf("\t\tis used unless this option specifies a different value.\n"); + printf("\t\tThe maximum number of passes varies by drive type:\n"); + printf("\t\tATA: 16 passes\n"); + printf("\t\tNVMe: 16 passes\n"); + printf("\t\tSCSI: 31 passes\n"); + printf("\t\tUse the --%s option to instruct the device to invert\n", SANITIZE_IPBP_LONG_OPT_STRING); + printf("\t\tthe pattern between each overwrite pass.\n"); + printf("\n"); + } +} + +void print_Sanitize_Overwrite_Invert_Help(bool shortHelp) +{ + printf("\t--%s\n", SANITIZE_IPBP_LONG_OPT_STRING); + if (!shortHelp) + { + printf("\t\tUse this option to instruct the drive to invert the requested\n"); + printf("\t\tsanitize overwrite pattern between each overwrite pass.\n"); + printf("\t\tFor the default pattern of all zeroes, this means that after\n"); + printf("\t\ta first pass of zeroes, the second pass will be all 1's (binary)\n"); + printf("\t\tor all F's (hexadecimal)\n\n"); + } +} + +void print_Sanitize_AUSE_Help(bool shortHelp) +{ + printf("\t--%s\n", SANITIZE_AUSE_LONG_OPT_STRING); + if (!shortHelp) + { + printf("\t\tUse this option to allow running a sanitize operation in\n"); + printf("\t\tunrestricted mode. Without this option, all sanitize options\n"); + printf("\t\tare run in restricted mode by default.\n"); + printf("\t\tIn unrestricted mode, if a sanitize erase fails the drive enters\n"); + printf("\t\ta failure state. The failure state can be cleared with a Sanitize\n"); + printf("\t\texit failure mode command, or it can be cleared with a successful\n"); + printf("\t\tsanitize erase.\n"); + printf("\t\tIn restricted mode, if a sanitize fails, the failure state can only\n"); + printf("\t\tbe cleared with a successful sanitize erase.\n\n"); + } +} + +void print_Zone_No_Reset_Help(bool shortHelp) +{ + printf("\t--%s\n", ZONE_NO_RESET_LONG_OPT_STRING); + if (!shortHelp) + { + printf("\t\tFor ZBD's (Zoned Block Devices), use this option during a\n"); + printf("\t\tSanitize or ATA Security Erase to specify leaving all zones\n"); + printf("\t\tfull so that full verification of erasure can be performed.\n"); + printf("\t\tWhen this option is not specified, all zones will be empty\n"); + printf("\t\tupon completion of these erases.\n\n"); + } +} + +void print_Sanitize_No_Deallocate_Help(bool shortHelp) +{ + printf("\t--%s\t(NVMe Only)\n", NO_DEALLOCATE_AFTER_ERASE_LONG_OPT_STRING); + if (!shortHelp) + { + printf("\t\tFor NVMe devices, specify this option during a sanitize to\n"); + printf("\t\tleave all blocks allocated after a sanitize erase. By default\n"); + printf("\t\tan NVMe controller will deallocate (TRIM/Unmap) all the LBAs.\n"); + printf("\t\tUsing this option allows for full verification of erasure after\n"); + printf("\t\ta Sanitize command.\n"); + printf("\t\tNOTE: An NVMe controller may inhibit this option in certain\n"); + printf("\t\tconfigurations meaning the sanitize may produce a warning or\n"); + printf("\t\ta failure depending on how this is configured on the controller.\n"); + printf("\t\tAfter verifying an erasure with this option, run a deallocate/TRIM\n"); + printf("\t\tacross the entire device/namespace to match default behavior of\n"); + printf("\t\ta sanitize erase.\n\n"); + } +} + +void print_Refresh_Filesystems_Help(bool shortHelp) +{ + printf("\t--%s\n", REFRESH_FILE_SYSTEMS_LONG_OPT_STRING); + if (!shortHelp) + { + printf("\t\tThis option will call an OS unique low-level routine to rescan\n"); + printf("\t\ta device for any file systems it can detect through the\n"); + printf("\t\tpartition table. The detected filesystems will vary by OS\n"); + printf("\t\tand OS capabilities.\n"); + printf("\t\tThis option is useful to call after completing a full disk erase\n"); + printf("\t\tas it may make a cached volume in the OS go away or detect that a device\n"); + printf("\t\tis empty and ready to have a new file system written to it.\n\n"); + } +} + void print_Poll_Help(bool shortHelp) { printf("\t--%s\n", POLL_LONG_OPT_STRING); diff --git a/subprojects/opensea-common b/subprojects/opensea-common index 0d8dcf5..8a8517c 160000 --- a/subprojects/opensea-common +++ b/subprojects/opensea-common @@ -1 +1 @@ -Subproject commit 0d8dcf5874564f994d4da957010b9b56a35d46e9 +Subproject commit 8a8517c73e37b127a899ae44541dcc4730829f7e diff --git a/subprojects/opensea-operations b/subprojects/opensea-operations index c4ad138..e50037f 160000 --- a/subprojects/opensea-operations +++ b/subprojects/opensea-operations @@ -1 +1 @@ -Subproject commit c4ad138732d2971ff4b4e3c0ccf262937f425644 +Subproject commit e50037fa00705c16ff7f2d40aa5a7940a7982824 diff --git a/subprojects/opensea-transport b/subprojects/opensea-transport index 27ea0cf..f77727a 160000 --- a/subprojects/opensea-transport +++ b/subprojects/opensea-transport @@ -1 +1 @@ -Subproject commit 27ea0cfbbe57e9c1cbb32719e8e840914a2fb6b4 +Subproject commit f77727a0adb07fc29ea9106d12d33a354b1f2c86 diff --git a/utils/C/openSeaChest/openSeaChest_Erase.c b/utils/C/openSeaChest/openSeaChest_Erase.c index 6d23f3d..023ec10 100644 --- a/utils/C/openSeaChest/openSeaChest_Erase.c +++ b/utils/C/openSeaChest/openSeaChest_Erase.c @@ -47,7 +47,7 @@ // Global Variables // //////////////////////// const char *util_name = "openSeaChest_Erase"; -const char *buildVersion = "4.4.0"; +const char *buildVersion = "4.6.0"; typedef enum _eSeaChestEraseExitCodes { @@ -127,7 +127,14 @@ int32_t main(int argc, char *argv[]) ATA_SECURITY_ERASE_OP_VARS ATA_SECURITY_FORCE_SAT_VARS //sanitize + SANITIZE_FREEZE_VAR + SANITIZE_ANTIFREEZE_VAR SANITIZE_UTIL_VARS + SANITIZE_AUSE_VAR + SANITIZE_IPBP_VAR + SANITIZE_OVERWRITE_PASSES_VAR + ZONE_NO_RESET_VAR + NO_DEALLOCATE_AFTER_ERASE_VAR //NVMe Sanitize option only at this time. //write same WRITE_SAME_UTIL_VARS //tcgGenkey @@ -152,6 +159,7 @@ int32_t main(int argc, char *argv[]) HIDE_LBA_COUNTER_VAR LOWLEVEL_INFO_VAR ERASE_RESTORE_MAX_VAR + REFRESH_FILE_SYSTEMS_VAR int args = 0; int argIndex = 0; @@ -204,7 +212,14 @@ int32_t main(int argc, char *argv[]) TCG_SID_LONG_OPT, TCG_PSID_LONG_OPT, #endif - { "sanitize", required_argument, NULL, 'e' }, //has a purposely unadvertized short option + SANITIZE_FREEZE_LONG_OPT, + SANITIZE_ANTIFREEZE_LONG_OPT, + SANITIZE_LONG_OPT, + SANITIZE_AUSE_LONG_OPT, + SANITIZE_IPBP_LONG_OPT, + SANITIZE_OVERWRITE_PASSES_LONG_OPT, + ZONE_NO_RESET_LONG_OPT, + NO_DEALLOCATE_AFTER_ERASE_LONG_OPT, WRITE_SAME_LONG_OPTS, SHOW_ERASE_SUPPORT_LONG_OPT, PERFORM_FASTEST_ERASE_LONG_OPT, @@ -222,6 +237,7 @@ int32_t main(int argc, char *argv[]) NVM_FORMAT_OPTIONS_LONG_OPTS, ZERO_VERIFY_LONG_OPT, ERASE_RESTORE_MAX_PREP_LONG_OPT, + REFRESH_FILE_SYSTEMS_LONG_OPT, LONG_OPT_TERMINATOR }; @@ -812,7 +828,7 @@ int32_t main(int argc, char *argv[]) } } } - else if (strncmp(longopts[optionIndex].name, ZERO_VERIFY_LONG_OPT_STRING, M_Min(strlen(longopts[optionIndex].name), strlen(ZERO_VERIFY_LONG_OPT_STRING))) == 0) + else if (strcmp(longopts[optionIndex].name, ZERO_VERIFY_LONG_OPT_STRING) == 0) { ZERO_VERIFY_FLAG = true; if (strcmp(optarg, "full") == 0) @@ -829,6 +845,19 @@ int32_t main(int argc, char *argv[]) exit(UTIL_EXIT_ERROR_IN_COMMAND_LINE); } } + else if (strcmp(longopts[optionIndex].name, SANITIZE_OVERWRITE_PASSES_LONG_OPT_STRING) == 0) + { + uint64_t temp = 0; + if (get_And_Validate_Integer_Input(optarg, &temp)) + { + SANITIZE_OVERWRITE_PASSES = C_CAST(uint8_t, temp); + } + else + { + print_Error_In_Cmd_Line_Args(SANITIZE_OVERWRITE_PASSES_LONG_OPT_STRING, optarg); + exit(UTIL_EXIT_ERROR_IN_COMMAND_LINE); + } + } break; case PROGRESS_SHORT_OPT: //get test progress for a specific test PROGRESS_CHAR = optarg; @@ -886,7 +915,40 @@ int32_t main(int argc, char *argv[]) } exit(UTIL_EXIT_NO_ERROR); case 'e': //sanitize - SANITIZE_SUBOPT_PARSE + if (strcmp(SANITIZE_BLOCK_ERASE_STR, optarg) == 0) + { + SANITIZE_RUN_FLAG = true; + SANITIZE_RUN_BLOCK_ERASE = true; + } + else if (strcmp(SANITIZE_CRYPTO_ERASE_STR, optarg) == 0) + { + SANITIZE_RUN_FLAG = true; + SANITIZE_RUN_CRYPTO_ERASE = true; + } + else if (strcmp(SANITIZE_OVERWRITE_ERASE_STR, optarg) == 0) + { + SANITIZE_RUN_FLAG = true; + SANITIZE_RUN_OVERWRITE_ERASE = true; + } + else if (strcmp("freezelock", optarg) == 0) + { + SANITIZE_FREEZE = true; + printf("Please migrate to using --%s as this will be removed in future versions\n", SANITIZE_FREEZE_LONG_OPT_STRING); + } + else if (strcmp("antifreezelock", optarg) == 0) + { + SANITIZE_ANTIFREEZE = true; + printf("Please migrate to using --%s as this will be removed in future versions\n", SANITIZE_ANTIFREEZE_LONG_OPT_STRING); + } + else if (strcmp("info", optarg) == 0) + { + SANITIZE_INFO_FLAG = true; + } + else + { + print_Error_In_Cmd_Line_Args(SANITIZE_LONG_OPT_STRING, optarg); + exit(UTIL_EXIT_ERROR_IN_COMMAND_LINE); + } break; default: break; @@ -1145,8 +1207,8 @@ int32_t main(int argc, char *argv[]) } if ((FORCE_SCSI_FLAG && FORCE_ATA_FLAG) - || (FORCE_SCSI_FLAG && FORCE_NVME_FLAG) - || (FORCE_ATA_FLAG && FORCE_NVME_FLAG) + || (FORCE_SCSI_FLAG && FORCE_NVME_FLAG) + || (FORCE_ATA_FLAG && FORCE_NVME_FLAG) || (FORCE_ATA_PIO_FLAG && FORCE_ATA_DMA_FLAG && FORCE_ATA_UDMA_FLAG) || (FORCE_ATA_PIO_FLAG && FORCE_ATA_DMA_FLAG) || (FORCE_ATA_PIO_FLAG && FORCE_ATA_UDMA_FLAG) @@ -1171,7 +1233,10 @@ int32_t main(int argc, char *argv[]) || TCG_REVERT_SP_FLAG || TCG_REVERT_FLAG #endif - || sanitize + || SANITIZE_RUN_FLAG + || SANITIZE_FREEZE + || SANITIZE_ANTIFREEZE + || SANITIZE_INFO_FLAG || RUN_WRITE_SAME_FLAG || ATA_SECURITY_ERASE_OP || RUN_OVERWRITE_FLAG @@ -1184,6 +1249,7 @@ int32_t main(int argc, char *argv[]) || NVM_FORMAT_FLAG || ZERO_VERIFY_FLAG || ERASE_RESTORE_MAX_PREP + || REFRESH_FILE_SYSTEMS )) { utility_Usage(true); @@ -1540,10 +1606,10 @@ int32_t main(int argc, char *argv[]) #ifdef DISABLE_TCG_SUPPORT //TODO: Check the return method. get_Supported_Erase_Methods(&deviceList[deviceIter], eraseMethodList, &overwriteTimeMinutes); -#else +#else //!DISABLE_TCG_SUPPORT //get_Supported_Erase_Methods(&selectedDevice, &eraseMethodList);//switch this to method with TCG support later - TJE get_Supported_Erase_Methods_With_TCG(&deviceList[deviceIter], eraseMethodList, &overwriteTimeMinutes); -#endif +#endif //DISABLE_TCG_SUPPORT print_Supported_Erase_Methods(&deviceList[deviceIter], eraseMethodList, &overwriteTimeMinutes); } @@ -1610,16 +1676,16 @@ int32_t main(int argc, char *argv[]) break; #endif case ERASE_SANITIZE_OVERWRITE: - sanitize = true; - sanoverwrite = true; + SANITIZE_RUN_FLAG = true; + SANITIZE_RUN_OVERWRITE_ERASE = true; break; case ERASE_SANITIZE_BLOCK: - sanitize = true; - sanblockErase = true; + SANITIZE_RUN_FLAG = true; + SANITIZE_RUN_BLOCK_ERASE = true; break; case ERASE_SANITIZE_CRYPTO: - sanitize = true; - sancryptoErase = true; + SANITIZE_RUN_FLAG = true; + SANITIZE_RUN_CRYPTO_ERASE = true; break; case ERASE_NVM_FORMAT_USER_SECURE_ERASE: NVM_FORMAT_FLAG = true; @@ -1960,288 +2026,437 @@ int32_t main(int argc, char *argv[]) } } - if (sanitize) + if (SANITIZE_FREEZE) + { + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Sending Sanitize Freeze Lock Command.\n"); + } + switch (sanitize_Freezelock(&deviceList[deviceIter])) + { + case SUCCESS: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Sanitize Freezelock passed!\n"); + } + break; + case FAILURE: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Sanitize Freezelock failed!\n"); + } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + break; + case NOT_SUPPORTED: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Sanitize Freezelock not supported.\n"); + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + break; + case IN_PROGRESS: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("A Sanitize operation is already in progress, freezelock cannot be completed.\n"); + } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + break; + case DEVICE_ACCESS_DENIED: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Access Denied while attempting Sanitize. Please make sure security has unlocked the drive and try again.\n"); + } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + break; + default: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Unknown error in sanitize command.\n"); + } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + break; + } + } + if (SANITIZE_ANTIFREEZE) + { + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Sending Sanitize Anti Freeze Lock Command.\n"); + } + switch (sanitize_Anti_Freezelock(&deviceList[deviceIter])) + { + case SUCCESS: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Sanitize Anti Freezelock passed!\n"); + } + break; + case FAILURE: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Sanitize Anti Freezelock failed!\n"); + } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + break; + case NOT_SUPPORTED: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Sanitize Anti Freezelock not supported.\n"); + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + break; + case IN_PROGRESS: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("A Sanitize operation is already in progress, anti freezelock cannot be completed.\n"); + } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + break; + case DEVICE_ACCESS_DENIED: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Access Denied while attempting Sanitize. Please make sure security has unlocked the drive and try again.\n"); + } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + break; + default: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Unknown error in sanitize command.\n"); + } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + break; + } + } + + if (SANITIZE_INFO_FLAG) { - int sanitizeResult = UNKNOWN; sanitizeFeaturesSupported sanitizeOptions; memset(&sanitizeOptions, 0, sizeof(sanitizeFeaturesSupported)); - sanitizeResult = get_Sanitize_Device_Features(&deviceList[deviceIter], &sanitizeOptions); if (VERBOSITY_QUIET < toolVerbosity) { - printf("\nSanitize\n"); + printf("\nSanitize Info\n"); } - if (sanitizeInfo) + if (SUCCESS == get_Sanitize_Device_Features(&deviceList[deviceIter], &sanitizeOptions)) { - if (SUCCESS == sanitizeResult) + if (sanitizeOptions.sanitizeCmdEnabled) { - if (sanitizeOptions.crypto || sanitizeOptions.blockErase || sanitizeOptions.overwrite) + printf("\tThe following sanitize commands are supported:\n"); + if (sanitizeOptions.crypto) { - printf("\tThe following sanitize commands are supported:\n"); - if (sanitizeOptions.crypto) - { - printf("\t\tCrypto Erase\t--%s cryptoerase\n", SANITIZE_LONG_OPT_STRING); - } - if (sanitizeOptions.blockErase) + printf("\t\tCrypto Erase\t--%s cryptoerase\n", SANITIZE_LONG_OPT_STRING); + } + if (sanitizeOptions.writeAfterCryptoErase >= WAEREQ_MEDIUM_ERROR_OTHER_ASC) + { + if (sanitizeOptions.writeAfterCryptoErase == WAEREQ_PI_FORMATTED_MAY_REQUIRE_OVERWRITE) { - printf("\t\tBlock Erase\t--%s blockerase\n", SANITIZE_LONG_OPT_STRING); + printf("\t\t\tWrite after crypto erase may be required due to PI formatting! Reads may return an error until written!\n"); } - if (sanitizeOptions.overwrite) + else { - printf("\t\tOverwrite\t--%s overwrite\n", SANITIZE_LONG_OPT_STRING); + printf("\t\t\tWrite after crypto erase required! Reads will return an error until written!\n"); } } - else - { - printf("\tSanitize commands are not supported by this device.\n"); - } - } - else - { - if (VERBOSITY_QUIET < toolVerbosity) + if (sanitizeOptions.blockErase) { - printf("\tSanitize Features not supported.\n"); + printf("\t\tBlock Erase\t--%s blockerase\n", SANITIZE_LONG_OPT_STRING); } - exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; - } - } - //if sanitize features are supported and the user has input a sanitize command to run, then we can kick them off - if (sanitizeOptions.sanitizeCmdEnabled) - { - if (DATA_ERASE_FLAG && !(sanfreezelock || sanAntiFreezeLock || sanitizeInfo)) - { - bool sanitizeCommandRun = false; - if (sanblockErase) + if (sanitizeOptions.writeAfterBlockErase >= WAEREQ_MEDIUM_ERROR_OTHER_ASC) { - if (VERBOSITY_QUIET < toolVerbosity) + if (sanitizeOptions.writeAfterCryptoErase == WAEREQ_PI_FORMATTED_MAY_REQUIRE_OVERWRITE) { - printf("Starting Sanitize Block Erase\n"); + printf("\t\t\tWrite after block erase may be required due to PI formatting! Reads may return an error until written!\n"); } - sanitizeResult = run_Sanitize_Operation(&deviceList[deviceIter], SANITIZE_BLOCK_ERASE, POLL_FLAG, NULL, 0); - sanitizeCommandRun = true; - } - if (sancryptoErase) - { - if (VERBOSITY_QUIET < toolVerbosity) + else { - printf("Starting Sanitize Crypto Scramble\n"); + printf("\t\t\tWrite after block erase required! Reads will return an error until written!\n"); } - sanitizeResult = run_Sanitize_Operation(&deviceList[deviceIter], SANITIZE_CRYPTO_ERASE, POLL_FLAG, NULL, 0); - sanitizeCommandRun = true; } - if (sanoverwrite) + if (sanitizeOptions.overwrite) { - if (VERBOSITY_QUIET < toolVerbosity) - { - printf("Starting Sanitize Overwrite Erase\n"); - } - sanitizeResult = run_Sanitize_Operation(&deviceList[deviceIter], SANITIZE_OVERWRITE_ERASE, POLL_FLAG, PATTERN_BUFFER, deviceList[deviceIter].drive_info.deviceBlockSize); - sanitizeCommandRun = true; + printf("\t\tOverwrite\t--%s overwrite\n", SANITIZE_LONG_OPT_STRING); + printf("\t\t\tMaximum overwrite passes: %" PRIu8 "\n", sanitizeOptions.maximumOverwritePasses); + } + if (sanitizeOptions.freezelock) + { + printf("\t\tFreezelock\t--%s\n", SANITIZE_FREEZE_LONG_OPT_STRING); + } + if (sanitizeOptions.antiFreezeLock) + { + printf("\t\tAntifreezelock\t--%s\n", SANITIZE_ANTIFREEZE_LONG_OPT_STRING); } - if (sanitizeCommandRun) + if (sanitizeOptions.noDeallocateInhibited) { - switch (sanitizeResult) + printf("\t\tNo Deallocate Inhibited by controller.\n"); + switch (sanitizeOptions.responseMode) { - case SUCCESS: - if (VERBOSITY_QUIET < toolVerbosity) - { - if (POLL_FLAG) - { - printf("Sanitize command passed!\n"); - } - else - { - printf("Sanitize command has been started. Use the --%s sanitize option\n", PROGRESS_LONG_OPT_STRING); - printf("to check for progress.\n"); - } - if (deviceList[deviceIter].drive_info.numberOfLUs > 1) - { - printf("NOTE: This command may have affected more than 1 logical unit\n"); - } - } - if (sanitizeCommandRun && POLL_FLAG) - { - eraseCompleted = true; - } - break; - case FAILURE: - if (VERBOSITY_QUIET < toolVerbosity) - { - printf("Sanitize command failed!\n"); - #if defined (_WIN32)//TODO: handle Win PE somehow when we support WinPE - printf("\tNote: Windows 8 and higher block sanitize commands.\n"); - #endif - } - exitCode = UTIL_EXIT_OPERATION_FAILURE; - break; - case IN_PROGRESS: - if (VERBOSITY_QUIET < toolVerbosity) - { - printf("A sanitize command is already in progress.\n"); - } - break; - case FROZEN: - if (VERBOSITY_QUIET < toolVerbosity) - { - printf("Cannot run sanitize operation because drive is sanitize frozen.\n"); - } - exitCode = UTIL_EXIT_OPERATION_FAILURE; + case NO_DEALLOC_RESPONSE_INV: break; - case NOT_SUPPORTED: - if (VERBOSITY_QUIET < toolVerbosity) - { - printf("Sanitize command not supported by the device.\n"); - } - exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; - break; - case OS_PASSTHROUGH_FAILURE: - if (VERBOSITY_QUIET < toolVerbosity) - { - printf("Sanitize command was blocked by the OS.\n"); - #if defined (_WIN32)//TODO: handle Win PE somehow when we support WinPE - printf("\tNote: Windows 8 and higher block sanitize commands.\n"); - #endif - } - exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + case NO_DEALLOC_RESPONSE_WARNING: + printf("\t\t\tSanitize command will be accepted but warn about deallocation when no deallocate is specified.\n"); break; - case DEVICE_ACCESS_DENIED: - if (VERBOSITY_QUIET < toolVerbosity) - { - printf("Access Denied while attempting Sanitize. Please make sure security has unlocked the drive and try again.\n"); - } - exitCode = UTIL_EXIT_OPERATION_FAILURE; - break; - default: - if (VERBOSITY_QUIET < toolVerbosity) - { - printf("Unknown error in sanitize command.\n"); - } - exitCode = UTIL_EXIT_OPERATION_FAILURE; + case NO_DEALLOC_RESPONSE_ERROR: + printf("\t\t\tSanitize command will be aborted with an error when no deallocate is specified.\n"); break; } } + switch (sanitizeOptions.nodmmas) + { + case NODMMAS_NOT_DEFINED: + break; + case NODMMAS_NOT_ADDITIONALLY_MODIFIED_AFTER_SANITIZE: + printf("\t\tMedia does not have additional modifications after sanitize completes.\n"); + break; + case NODMMAS_MEDIA_MODIFIED_AFTER_SANITIZE: + printf("\t\tMedia is modified after sanitize completes.\n"); + break; + case NODMMAS_RESERVED: + break; + } + + } + else + { + printf("\tSanitize commands are not supported by this device.\n"); + } + } + else + { + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("\tSanitize Features not supported.\n"); + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + } + } + + if (SANITIZE_RUN_FLAG) + { + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("\nSanitize\n"); + } + if (DATA_ERASE_FLAG) + { + bool sanitizeCommandRun = false; + sanitizeOperationOptions sanitizeOp; + memset(&sanitizeOp, 0, sizeof(sanitizeOperationOptions)); + sanitizeOp.version = SANITIZE_OPERATION_OPTIONS_VERSION; + sanitizeOp.size = sizeof(sanitizeOperationOptions); + sanitizeOp.pollForProgress = POLL_FLAG; + sanitizeOp.commonOptions.allowUnrestrictedSanitizeExit = SANITIZE_AUSE; + //NOTE: The next two options are in a union to mean the same thing + // It is likely that a user will specify one for NVMe devices and one for SATA/SAS + // So if this is specified, keep the one set to true. + sanitizeOp.commonOptions.zoneNoReset = ZONE_NO_RESET; + if (!sanitizeOp.commonOptions.noDeallocate) + { + sanitizeOp.commonOptions.noDeallocate = NO_DEALLOCATE_AFTER_ERASE; } - else if (sanfreezelock) + if (SANITIZE_RUN_BLOCK_ERASE) { if (VERBOSITY_QUIET < toolVerbosity) { - printf("Sending Sanitize Freeze Lock Command.\n"); + printf("Starting Sanitize Block Erase\n"); } - sanitizeResult = run_Sanitize_Operation(&deviceList[deviceIter], SANTIZIE_FREEZE_LOCK, false, NULL, 0); - switch (sanitizeResult) + sanitizeOp.sanitizeEraseOperation = BLOCK_ERASE; + } + if (SANITIZE_RUN_CRYPTO_ERASE) + { + if (VERBOSITY_QUIET < toolVerbosity) { - case SUCCESS: - if (VERBOSITY_QUIET < toolVerbosity) - { - printf("Sanitize Freezelock passed!\n"); - } - break; - case FAILURE: - if (VERBOSITY_QUIET < toolVerbosity) - { - printf("Sanitize Freezelock failed!\n"); - } - exitCode = UTIL_EXIT_OPERATION_FAILURE; - break; - case NOT_SUPPORTED: - if (VERBOSITY_QUIET < toolVerbosity) + printf("Starting Sanitize Crypto Scramble\n"); + } + sanitizeOp.sanitizeEraseOperation = CRYPTO_ERASE; + } + if (SANITIZE_RUN_OVERWRITE_ERASE) + { + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Starting Sanitize Overwrite Erase\n"); + } + sanitizeOp.sanitizeEraseOperation = OVERWRITE_ERASE; + sanitizeOp.overwriteOptions.invertPatternBetweenPasses = SANITIZE_IPBP; + sanitizeOp.overwriteOptions.numberOfPasses = SANITIZE_OVERWRITE_PASSES; + if (PATTERN_FLAG) + { + sanitizeOp.overwriteOptions.pattern = M_BytesTo4ByteValue(patternBuffer[3], patternBuffer[2], patternBuffer[1], patternBuffer[0]); + } + } + //get the support information before starting sanitize to add warnings about write after block erase or write after crypto erase. + writeAfterErase writeReq; + memset(&writeReq, 0, sizeof(writeAfterErase)); + is_Write_After_Erase_Required(&deviceList[deviceIter], &writeReq); + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("If Sanitize appears to be taking much longer than expected, the system or HBA\n"); + printf("may not be handling the sanitize in progress state correctly. If this happens\n"); + printf("the next best thing to do is leave the drive powered on with the interface\n"); + printf("cable(SATA / SAS HBA cable) disconnected. Sanitize will continue running\n"); + printf("while the drive is powered onand the system will no longer be able to\n"); + printf("interrupt or slow down the sanitize operation.\n"); + printf("NOTE: On an HDD, the approximate overwrite time is 1.5-2 hours per terabyte\n"); + printf(" of the native capacity of the drive. Reduced size for maxLBA does not\n"); + printf(" reduce the time sanitize takes to overwrite the drive.\n"); + printf(" On an SSD, the overwrite time will be much faster and varies depending\n"); + printf(" on the capabilities of the SSD controller.\n\n"); + if (SANITIZE_RUN_BLOCK_ERASE && writeReq.blockErase > WAEREQ_READ_COMPLETES_GOOD_STATUS) + { + if (writeReq.blockErase == WAEREQ_PI_FORMATTED_MAY_REQUIRE_OVERWRITE) { - printf("Sanitize Freezelock not supported.\n"); + printf("ADVISORY: This device may require a write to all LBAs after a crypto erase!\n"); + printf(" PI bytes may be invalid and reading them results in logical block guard\n"); + printf(" check failures until a logical block has been written with new data.\n"); + printf(" Attempting to read any LBA will result in a failure until it\n"); + printf(" has been written with new data!\n\n"); } - exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; - break; - case IN_PROGRESS: - if (VERBOSITY_QUIET < toolVerbosity) + else { - printf("A Sanitize operation is already in progress, freezelock cannot be completed.\n"); + printf("ADVISORY: This device requires a write to all LBAs after a block erase!\n"); + printf(" Attempting to read any LBA will result in a failure until it\n"); + printf(" has been written with new data!\n\n"); } - exitCode = UTIL_EXIT_OPERATION_FAILURE; - break; - case DEVICE_ACCESS_DENIED: - if (VERBOSITY_QUIET < toolVerbosity) + } + if (SANITIZE_RUN_CRYPTO_ERASE && writeReq.cryptoErase > WAEREQ_READ_COMPLETES_GOOD_STATUS) + { + if (writeReq.blockErase == WAEREQ_PI_FORMATTED_MAY_REQUIRE_OVERWRITE) { - printf("Access Denied while attempting Sanitize. Please make sure security has unlocked the drive and try again.\n"); + printf("ADVISORY: This device may require a write to all LBAs after a crypto erase!\n"); + printf(" PI bytes may be scrambled and reading them results in logical block guard\n"); + printf(" check failures until a logical block has been written with new data.\n"); + printf(" Attempting to read any LBA will result in a failure until it\n"); + printf(" has been written with new data!\n\n"); } - exitCode = UTIL_EXIT_OPERATION_FAILURE; - break; - default: - if (VERBOSITY_QUIET < toolVerbosity) + else { - printf("Unknown error in sanitize command.\n"); + printf("ADVISORY: This device requires a write to all LBAs after a crypto erase!\n"); + printf(" Attempting to read any LBA will result in a failure until it\n"); + printf(" has been written with new data!\n\n"); } - exitCode = UTIL_EXIT_OPERATION_FAILURE; - break; } } - else if (sanAntiFreezeLock) + switch (run_Sanitize_Operation2(&deviceList[deviceIter], sanitizeOp)) { + case SUCCESS: if (VERBOSITY_QUIET < toolVerbosity) { - printf("Sending Sanitize Anti Freeze Lock Command.\n"); - } - sanitizeResult = run_Sanitize_Operation(&deviceList[deviceIter], SANITIZE_ANTI_FREEZE_LOCK, false, NULL, 0); - switch (sanitizeResult) - { - case SUCCESS: - if (VERBOSITY_QUIET < toolVerbosity) + if (POLL_FLAG) { - printf("Sanitize Anti Freezelock passed!\n"); + printf("Sanitize command passed!\n"); } - break; - case FAILURE: - if (VERBOSITY_QUIET < toolVerbosity) + else { - printf("Sanitize Anti Freezelock failed!\n"); + printf("Sanitize command has been started. Use the --%s sanitize option\n", PROGRESS_LONG_OPT_STRING); + printf("to check for progress.\n"); } - exitCode = UTIL_EXIT_OPERATION_FAILURE; - break; - case NOT_SUPPORTED: - if (VERBOSITY_QUIET < toolVerbosity) + if (deviceList[deviceIter].drive_info.numberOfLUs > 1) { - printf("Sanitize Anti Freezelock not supported.\n"); + printf("NOTE: This command may have affected more than 1 logical unit\n"); } - exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; - break; - case IN_PROGRESS: - if (VERBOSITY_QUIET < toolVerbosity) + if (SANITIZE_RUN_BLOCK_ERASE && writeReq.blockErase > WAEREQ_READ_COMPLETES_GOOD_STATUS) { - printf("A Sanitize operation is already in progress, anti freezelock cannot be completed.\n"); + printf("ADVISORY: This device requires a write to all LBAs after a block erase!\n"); + printf(" Attempting to read any LBA will result in a failure until it\n"); + printf(" has been written with new data!\n\n"); } - exitCode = UTIL_EXIT_OPERATION_FAILURE; - break; - case DEVICE_ACCESS_DENIED: - if (VERBOSITY_QUIET < toolVerbosity) + if (SANITIZE_RUN_CRYPTO_ERASE && writeReq.cryptoErase > WAEREQ_READ_COMPLETES_GOOD_STATUS) { - printf("Access Denied while attempting Sanitize. Please make sure security has unlocked the drive and try again.\n"); + printf("ADVISORY: This device requires a write to all LBAs after a crypto erase!\n"); + printf(" Attempting to read any LBA will result in a failure until it\n"); + printf(" has been written with new data!\n\n"); } - exitCode = UTIL_EXIT_OPERATION_FAILURE; - break; - default: - if (VERBOSITY_QUIET < toolVerbosity) + } + if (sanitizeCommandRun && POLL_FLAG) + { + eraseCompleted = true; + if ((SANITIZE_RUN_BLOCK_ERASE && writeReq.blockErase > WAEREQ_READ_COMPLETES_GOOD_STATUS) + || (SANITIZE_RUN_CRYPTO_ERASE && writeReq.cryptoErase > WAEREQ_READ_COMPLETES_GOOD_STATUS)) { - printf("Unknown error in sanitize command.\n"); + eraseCompleted = false;//turn this off otherwise the function to update file systems outputs errors to the screen since it tries to read the device. } - exitCode = UTIL_EXIT_OPERATION_FAILURE; - break; } - } - else if (!sanitizeInfo) - { + break; + case FAILURE: if (VERBOSITY_QUIET < toolVerbosity) { - printf("\n"); - printf("You must add the flag:\n\"%s\" \n", DATA_ERASE_ACCEPT_STRING); - printf("to the command line arguments to run a sanitize operation.\n\n"); - printf("e.g.: %s -d %s --%s blockerase --confirm %s\n\n", util_name, deviceHandleExample, SANITIZE_LONG_OPT_STRING, DATA_ERASE_ACCEPT_STRING); + printf("Sanitize command failed!\n"); + #if defined (_WIN32) + if (!is_Windows_PE()) + { + printf("\tNote: Windows 8 and higher block sanitize commands.\n"); + printf("\t Starting in Windows 11 or Windows 10 21H2, NVMe\n"); + printf("\t devices can issue Sanitize Block or Crypto erases\n"); + printf("\t but no other device types or sanitize operations\n"); + printf("\t are permitted.\n"); + printf("\t The Windows PE/RE environments allow all sanitize operations.\n"); + } + #endif //_WIN32 + } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + break; + case IN_PROGRESS: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("A sanitize command is already in progress.\n"); + } + break; + case FROZEN: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Cannot run sanitize operation because drive is sanitize frozen.\n"); + } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + break; + case NOT_SUPPORTED: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Sanitize command not supported by the device.\n"); + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + break; + case OS_PASSTHROUGH_FAILURE: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Sanitize command was blocked by the OS.\n"); +#if defined (_WIN32) + if (!is_Windows_PE()) + { + printf("\tNote: Windows 8 and higher block sanitize commands.\n"); + printf("\t Starting in Windows 11 or Windows 10 21H2, NVMe\n"); + printf("\t devices can issue Sanitize Block or Crypto erases\n"); + printf("\t but no other device types or sanitize operations\n"); + printf("\t are permitted.\n"); + printf("\t The Windows PE/RE environments allow all sanitize operations.\n"); + } +#endif //_WIN32 + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + break; + case DEVICE_ACCESS_DENIED: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Access Denied while attempting Sanitize. Please make sure security has unlocked the drive and try again.\n"); + } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + break; + default: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Unknown error in sanitize command.\n"); } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + break; } } - else if (!sanitizeInfo) + else { if (VERBOSITY_QUIET < toolVerbosity) { - printf("\tSanitize Features not supported.\n"); + printf("\n"); + printf("You must add the flag:\n\"%s\" \n", DATA_ERASE_ACCEPT_STRING); + printf("to the command line arguments to run a sanitize operation.\n\n"); + printf("e.g.: %s -d %s --%s blockerase --confirm %s\n\n", util_name, deviceHandleExample, SANITIZE_LONG_OPT_STRING, DATA_ERASE_ACCEPT_STRING); } - exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; } } @@ -2532,6 +2747,7 @@ int32_t main(int argc, char *argv[]) ataPassword.passwordType = ATA_SECURITY_USING_MASTER_PW; memcpy(ataPassword.password, ATA_SECURITY_PASSWORD, ATA_SECURITY_PASSWORD_BYTE_COUNT);//ATA_SECURITY_PASSWORD_BYTE_COUNT shouldn't ever be > 32. Should be caught above. ataPassword.passwordLength = ATA_SECURITY_PASSWORD_BYTE_COUNT; + ataPassword.zacSecurityOption = ZONE_NO_RESET; eATASecurityEraseType ataSecureEraseType = ATA_SECURITY_ERASE_STANDARD_ERASE; if (ATA_SECURITY_ERASE_ENHANCED_FLAG) { @@ -2932,10 +3148,37 @@ int32_t main(int argc, char *argv[]) break; } } - if (eraseCompleted) + if (eraseCompleted || REFRESH_FILE_SYSTEMS) { //update the FS cache since just about all actions in here will need this if they do not already handle it internally. - os_Update_File_System_Cache(&deviceList[deviceIter]); + int fsret = os_Update_File_System_Cache(&deviceList[deviceIter]); + if (REFRESH_FILE_SYSTEMS) + { + switch (fsret) + { + case SUCCESS: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Successfully refreshed the filesystems for the OS!\n"); + } + eraseCompleted = true; + break; + case NOT_SUPPORTED: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Refreshing the filesystems is not supported in this OS.\n"); + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + break; + default: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Failed to refresh the OS file systems.\n"); + } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + break; + } + } } //At this point, close the device handle since it is no longer needed. Do not put any further IO below this. close_Device(&deviceList[deviceIter]); @@ -3068,6 +3311,7 @@ void utility_Usage(bool shortUsage) #endif print_Time_Seconds_Help(shortUsage); print_Erase_Restore_Max_Prep_Help(shortUsage); + print_Refresh_Filesystems_Help(shortUsage); print_Show_Supported_Erase_Modes_Help(shortUsage); #if !defined(DISABLE_TCG_SUPPORT) print_TCG_SID_Help(shortUsage); @@ -3108,8 +3352,11 @@ void utility_Usage(bool shortUsage) printf("SATA - IO, and NVMexpress.\n"); printf("=========================\n"); //multiple interfaces + print_Sanitize_AUSE_Help(shortUsage); + print_Sanitize_Overwrite_Invert_Help(shortUsage); print_Overwrite_Help(shortUsage); print_Overwrite_Range_Help(shortUsage); + print_Sanitize_Overwrite_Passes_Help(shortUsage); print_Pattern_Help(shortUsage); print_Perform_Quickest_Erase_Help(shortUsage); #if !defined(DISABLE_TCG_SUPPORT) @@ -3121,14 +3368,18 @@ void utility_Usage(bool shortUsage) print_Trim_Unmap_Range_Help(shortUsage); print_Writesame_Help(shortUsage); print_Writesame_Range_Help(shortUsage); + print_Zone_No_Reset_Help(shortUsage); //SATA Only Options printf("\n\tSATA Only:\n\t=========\n"); print_ATA_Security_Erase_Help(shortUsage, "SeaChest"); + print_Sanitize_Anti_Freeze_Help(shortUsage); + print_Sanitize_Freeze_Help(shortUsage); //SAS Only Options printf("\n\tSAS Only:\n\t=========\n"); print_Fast_Format_Help(shortUsage); print_Format_Unit_Help(shortUsage); printf("\n\tNVMe Only:\n\t=========\n"); + print_Sanitize_No_Deallocate_Help(shortUsage); print_NVM_Format_Metadata_Setting_Help(shortUsage); print_NVM_Format_Metadata_Size_Help(shortUsage); print_NVM_Format_NSID_Help(shortUsage); diff --git a/utils/C/openSeaChest/openSeaChest_Info.c b/utils/C/openSeaChest/openSeaChest_Info.c index baa9867..2c9998e 100644 --- a/utils/C/openSeaChest/openSeaChest_Info.c +++ b/utils/C/openSeaChest/openSeaChest_Info.c @@ -925,6 +925,16 @@ int32_t main(int argc, char *argv[]) { case SUCCESS: print_DeviceStatistics(&deviceList[deviceIter], &deviceStats); + //if supported then print Seagate Device Statistics also + if (is_Seagate_DeviceStatistics_Supported(&deviceList[deviceIter])) + { + seagateDeviceStatistics seagateDeviceStats; + memset(&seagateDeviceStats, 0, sizeof(seagateDeviceStatistics)); + if (SUCCESS == get_Seagate_DeviceStatistics(&deviceList[deviceIter], &seagateDeviceStats)) + { + print_Seagate_DeviceStatistics(&deviceList[deviceIter], &seagateDeviceStats); + } + } break; case NOT_SUPPORTED: if (VERBOSITY_QUIET < toolVerbosity) diff --git a/utils/C/openSeaChest/openSeaChest_NVMe.c b/utils/C/openSeaChest/openSeaChest_NVMe.c index 38a7905..f1284a6 100644 --- a/utils/C/openSeaChest/openSeaChest_NVMe.c +++ b/utils/C/openSeaChest/openSeaChest_NVMe.c @@ -85,6 +85,7 @@ int32_t main(int argc, char *argv[]) NEW_FW_MATCH_VARS CHECK_POWER_VAR TRANSITION_POWER_STATE_VAR + SHOW_NVM_POWER_STATES_VAR GET_NVME_LOG_VAR GET_TELEMETRY_VAR TELEMETRY_DATA_AREA_VAR @@ -107,7 +108,12 @@ int32_t main(int argc, char *argv[]) PROGRESS_VAR SHOW_SUPPORTED_FORMATS_VAR LOWLEVEL_INFO_VAR - FORCE_DRIVE_TYPE_VARS + LIST_LOGS_VAR + FORCE_DRIVE_TYPE_VARS + +#if defined (ENABLE_HWRAID_SUPPORT) + RAID_PHYSICAL_DRIVE rDevice;//TODO: This should be a list so that we can talk to more than one raid device at a time! +#endif int args = 0; int argIndex = 0; @@ -144,6 +150,7 @@ int32_t main(int argc, char *argv[]) FIRMWARE_SLOT_BUFFER_ID_LONG_OPT, CHECK_POWER_LONG_OPT, TRANSITION_POWER_STATE_LONG_OPT, + SHOW_NVM_POWER_STATES_LONG_OPT, GET_NVME_LOG_LONG_OPT, GET_TELEMETRY_LONG_OPT, TELEMETRY_DATA_AREA_LONG_OPT, @@ -161,6 +168,7 @@ int32_t main(int argc, char *argv[]) SHOW_SUPPORTED_FORMATS_LONG_OPT, NVM_FORMAT_LONG_OPT, NVM_FORMAT_OPTIONS_LONG_OPTS, + LIST_LOGS_LONG_OPT, FORCE_DRIVE_TYPE_LONG_OPTS, LONG_OPT_TERMINATOR }; @@ -759,23 +767,25 @@ int32_t main(int argc, char *argv[]) } //check that we were given at least one test to perform...if not, set that we are dumping device information so we at least do something if (!(DEVICE_INFO_FLAG - || LOWLEVEL_INFO_FLAG - || DOWNLOAD_FW_FLAG - || ACTIVATE_DEFERRED_FW_FLAG - || SWITCH_FW_FLAG - || TEST_UNIT_READY_FLAG - || CHECK_POWER_FLAG - || (TRANSITION_POWER_STATE_TO >= 0) - || (GET_NVME_LOG_IDENTIFIER > 0) // Since 0 is Reserved - || (GET_TELEMETRY_IDENTIFIER > 0) - || (GET_FEATURES_FLAG) - || EXT_SMART_LOG_FLAG1 - || CLEAR_PCIE_CORRECTABLE_ERRORS_LOG_FLAG - || NVME_TEMP_STATS_FLAG - || NVME_PCI_STATS_FLAG - || SHOW_SUPPORTED_FORMATS_FLAG - || NVM_FORMAT_FLAG - || PROGRESS_CHAR != NULL + || LOWLEVEL_INFO_FLAG + || DOWNLOAD_FW_FLAG + || ACTIVATE_DEFERRED_FW_FLAG + || SWITCH_FW_FLAG + || TEST_UNIT_READY_FLAG + || CHECK_POWER_FLAG + || (TRANSITION_POWER_STATE_TO >= 0) + || SHOW_NVM_POWER_STATES + || (GET_NVME_LOG_IDENTIFIER > 0) // Since 0 is Reserved + || (GET_TELEMETRY_IDENTIFIER > 0) + || (GET_FEATURES_FLAG) + || EXT_SMART_LOG_FLAG1 + || CLEAR_PCIE_CORRECTABLE_ERRORS_LOG_FLAG + || NVME_TEMP_STATS_FLAG + || NVME_PCI_STATS_FLAG + || SHOW_SUPPORTED_FORMATS_FLAG + || NVM_FORMAT_FLAG + || PROGRESS_CHAR != NULL + || LIST_LOGS_FLAG //check for other tool specific options here )) { @@ -1044,6 +1054,30 @@ int32_t main(int argc, char *argv[]) print_Low_Level_Info(&deviceList[deviceIter]); } + if (LIST_LOGS_FLAG) + { + switch (print_Supported_Logs(&deviceList[deviceIter], 0)) + { + case SUCCESS: + break; + case NOT_SUPPORTED: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("\nListing supported logs is not supported for device %s.\n", \ + deviceList[deviceIter].drive_info.serialNumber); + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + break; + default: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("\nFailed to list logs for device %s\n", \ + deviceList[deviceIter].drive_info.serialNumber); + } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + } + } + if (SHOW_SUPPORTED_FORMATS_FLAG) { uint32_t numberOfSectorSizes = get_Number_Of_Supported_Sector_Sizes(&deviceList[deviceIter]); @@ -1126,7 +1160,8 @@ int32_t main(int argc, char *argv[]) uint64_t size = 0; uint8_t * logBuffer = NULL; nvmeGetLogPageCmdOpts cmdOpts; - if ((nvme_Get_Log_Size(&deviceList[deviceIter], GET_NVME_LOG_IDENTIFIER, &size) == SUCCESS) && size) + ret = nvme_Get_Log_Size(&deviceList[deviceIter], GET_NVME_LOG_IDENTIFIER, &size); + if (ret == SUCCESS && size) { memset(&cmdOpts, 0, sizeof(nvmeGetLogPageCmdOpts)); if (NVME_LOG_ERROR_ID == GET_NVME_LOG_IDENTIFIER) @@ -1140,7 +1175,8 @@ int32_t main(int argc, char *argv[]) cmdOpts.addr = logBuffer; cmdOpts.dataLen = C_CAST(uint32_t, size); cmdOpts.lid = GET_NVME_LOG_IDENTIFIER; - if (nvme_Get_Log_Page(&deviceList[deviceIter], &cmdOpts) == SUCCESS) + ret = nvme_Get_Log_Page(&deviceList[deviceIter], &cmdOpts); + if (ret == SUCCESS) { if (OUTPUT_MODE_IDENTIFIER == UTIL_OUTPUT_MODE_RAW) { @@ -1154,7 +1190,7 @@ int32_t main(int argc, char *argv[]) FILE * pLogFile = NULL; char identifyFileName[OPENSEA_PATH_MAX] = { 0 }; char * fileNameUsed = &identifyFileName[0]; - #define SEACHEST_NVME_LOG_NAME_LENGTH 16 +#define SEACHEST_NVME_LOG_NAME_LENGTH 16 char logName[SEACHEST_NVME_LOG_NAME_LENGTH] = { 0 }; snprintf(logName, SEACHEST_NVME_LOG_NAME_LENGTH, "LOG_PAGE_%d", GET_NVME_LOG_IDENTIFIER); if (SUCCESS == create_And_Open_Log_File(&deviceList[deviceIter], &pLogFile, NULL, \ @@ -1186,6 +1222,14 @@ int32_t main(int argc, char *argv[]) exitCode = UTIL_EXIT_OPERATION_FAILURE; } } + else if (ret == NOT_SUPPORTED) + { + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Log Page %" PRIu8 " is not supported. \n", GET_NVME_LOG_IDENTIFIER); + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + } else { if (VERBOSITY_QUIET < toolVerbosity) @@ -1205,13 +1249,21 @@ int32_t main(int argc, char *argv[]) exitCode = UTIL_EXIT_OPERATION_FAILURE; } } + else if (ret == NOT_SUPPORTED) + { + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Log Page %" PRIu8 " is not supported. \n", GET_NVME_LOG_IDENTIFIER); + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + } else { if (VERBOSITY_QUIET < toolVerbosity) { printf("Log Page %" PRIu8 " not available at this time. \n", GET_NVME_LOG_IDENTIFIER); } - exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + exitCode = UTIL_EXIT_OPERATION_FAILURE; } } else //Human Readable. @@ -1224,6 +1276,13 @@ int32_t main(int argc, char *argv[]) case SUCCESS: //nothing to print here since if it was successful, the log will be printed to the screen break; + case NOT_SUPPORTED: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("SMART/Health Information Log not supported\n"); + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + break; default: if (VERBOSITY_QUIET < toolVerbosity) { @@ -1239,6 +1298,13 @@ int32_t main(int argc, char *argv[]) case SUCCESS: //nothing to print here since if it was successful, the log will be printed to the screen break; + case NOT_SUPPORTED: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Error Information Log not supported\n"); + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + break; default: if (VERBOSITY_QUIET < toolVerbosity) { @@ -1254,6 +1320,13 @@ int32_t main(int argc, char *argv[]) case SUCCESS: //nothing to print here since if it was successful, the log will be printed to the screen break; + case NOT_SUPPORTED: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("FW Slot Information Log not supported\n"); + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + break; default: if (VERBOSITY_QUIET < toolVerbosity) { @@ -1269,6 +1342,13 @@ int32_t main(int argc, char *argv[]) case SUCCESS: //nothing to print here since if it was successful, the log will be printed to the screen break; + case NOT_SUPPORTED: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Commands Supported and Effects Information Log not supported\n"); + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + break; default: if (VERBOSITY_QUIET < toolVerbosity) { @@ -1284,6 +1364,13 @@ int32_t main(int argc, char *argv[]) case SUCCESS: //nothing to print here since if it was successful, the log will be printed to the screen break; + case NOT_SUPPORTED: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Device Self-test Information Log not supported\n"); + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + break; default: if (VERBOSITY_QUIET < toolVerbosity) { @@ -1572,6 +1659,32 @@ int32_t main(int argc, char *argv[]) } } + if (SHOW_NVM_POWER_STATES) + { + nvmeSupportedPowerStates ps; + memset(&ps, 0, sizeof(nvmeSupportedPowerStates)); + switch (get_NVMe_Power_States(&deviceList[deviceIter], &ps)) + { + case SUCCESS: + print_NVM_Power_States(&ps); + break; + case NOT_SUPPORTED: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("Showing NVM power states is not supported on this device\n"); + } + exitCode = UTIL_EXIT_OPERATION_NOT_SUPPORTED; + break; + default: + if (VERBOSITY_QUIET < toolVerbosity) + { + printf("ERROR: Could not read NVM power states from the device!\n"); + } + exitCode = UTIL_EXIT_OPERATION_FAILURE; + break; + } + } + //this option must come after --transition power so that these two options can be combined on the command line and produce the correct end result if (CHECK_POWER_FLAG) { diff --git a/utils/C/openSeaChest/openSeaChest_PowerControl.c b/utils/C/openSeaChest/openSeaChest_PowerControl.c index eb092f5..a65531d 100644 --- a/utils/C/openSeaChest/openSeaChest_PowerControl.c +++ b/utils/C/openSeaChest/openSeaChest_PowerControl.c @@ -2931,6 +2931,7 @@ void utility_Usage(bool shortUsage) print_Disable_APM_Help(shortUsage); print_DAPS_Help(shortUsage); print_DIPM_Help(shortUsage); + print_PUIS_Feature_Help(shortUsage); print_Set_APM_Level_Help(shortUsage); print_Show_APM_Level_Help(shortUsage); //SAS Only Options