Compare commits

...

No commits in common. "c9s" and "c8" have entirely different histories.
c9s ... c8

19 changed files with 1075 additions and 420 deletions

17
.gitignore vendored
View File

@ -1,16 +1 @@
smartmontools-5.39.1.tar.gz
/smartmontools-r3169.tar.gz
/smartmontools-5.40.tar.gz
/smartmontools-5.41.tar.gz
/smartmontools-5.42.tar.gz
/smartmontools-5.43.tar.gz
/smartmontools-6.0.tar.gz
/smartmontools-6.1.tar.gz
/smartmontools-6.2.tar.gz
/smartmontools-6.3.tar.gz
/smartmontools-6.4.tar.gz
/smartmontools-6.5.tar.gz
/smartmontools-6.6.tar.gz
/smartmontools-7.0.tar.gz
/smartmontools-7.1.tar.gz
/smartmontools-7.2.tar.gz
SOURCES/smartmontools-7.1.tar.gz

View File

@ -1,10 +1,10 @@
/*
* drivedb.h - smartmontools 7.2 drive database file
* drivedb.h - smartmontools drive database file
*
* Home page of code is: https://www.smartmontools.org
*
* Copyright (C) 2003-11 Philip Williams, Bruce Allen
* Copyright (C) 2008-24 Christian Franke
* Copyright (C) 2008-23 Christian Franke
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
@ -68,7 +68,7 @@
/*
const drive_settings builtin_knowndrives[] = {
*/
{ "VERSION: 7.2/5577 2024-01-12 18:07:33 $Id$",
{ "VERSION: 7.3 $Id$",
"-", "-",
"Version information",
""
@ -290,65 +290,6 @@ const drive_settings builtin_knowndrives[] = {
//"-v 199,raw48,UDMA_CRC_Error_Count "
//"-v 240,raw48,Unknown_SSD_Attribute "
},
{ "ATP SATA III Value Line SSDs",
"ATP SATA III (M.2 (2242|2280)|mSATA|mSATA SSD|2.5 inch)",
// tested M.2 2280 with firmware version SBFMBB.3 (Value Line),
// ATP SATA III M.2 2280/SBFMBB.3
"SBFMB1.1|SBFMBB.3|SBFMT1.3",
"",
"-v 1,raw48,Raw_Read_Error_Count "
//"-v 9,raw24(raw8),Power_On_Hours "
//"-v 12,raw48,Power_Cycle_Count "
"-v 168,raw48,SATA_PHY_Error_Count "
"-v 170,raw16,Bad_Bl_Ct_LATER_0_EARLY " // Raw value: Byte [5~4] Later bad block count
// Byte [3~2] 0
// Byte [1~0] Early bad block count (meaning see ticket #1642)
"-v 173,raw16,Erase_Count_0_AVG_MAX " // Raw value: Byte [5~4] 0
// Byte [3~2] Average erase count
// Byte [1~0] Max erase count
"-v 192,raw48,Unexpected_Power_Loss "
//"-v 194,tempminmax,Device_Temperature "
"-v 218,raw48,CRC_Errors "
"-v 231,raw48,Percent_Lifetime_Remain "
"-v 241,raw48,Host_Writes_GiB "
},
{ "ATP SATA III Superior Line SSDs",
"ATP (SATA III|SATAIII|I-Temp. SATA III|I-Temp. SATAIII) (M.2 (2242|2280)|mSATA|2.5 inch) SSD",
// tested M.2 2242 & 2280 with firmware version T0205B (Superior Line with PLP),
// ATP SATA III M.2 2280 SSD/T0205B
"T0205B|U0316B",
"",
"-v 1,raw48,Raw_Read_Error_Count "
"-v 5,raw16(raw16),Realloc_Flash_Blocks_Ct "
//"-v 9,raw24(raw8),Power_On_Hours "
//"-v 12,raw48,Power_Cycle_Count "
"-v 14,raw48,Device_Raw_Capacity "
"-v 15,raw48,Device_User_Capacity "
"-v 16,raw48,Initial_Spare_Blocks "
"-v 17,raw48,Remaining_Spare_Blocks "
"-v 100,raw48,Total_Erease_Count "
"-v 160,raw48,Uncorrectable_Sectors "
"-v 172,raw48,Block_Erase_Failures "
"-v 173,raw48,Maximum_Erase_Count "
"-v 174,raw48,Unexpected_Power_Loss "
"-v 175,raw48,Average_Erase_Count "
"-v 181,raw48,Block_Program_Failures "
"-v 187,raw48,Reported_Uncorr_Errors "
//"-v 194,tempminmax,Device_Temperature "
//"-v 195,raw48,Hardware_ECC_Recovered "
"-v 197,raw48,Current_Pending_ECC_Cnt " // Like Crucial MX500: May flip 0 <> 1 (ticket #1227)
"-v 198,raw48,Offline_UErr_Media_Scan "
"-v 199,raw48,SATA_FIS_CRC_Errors "
"-v 202,raw48,Percent_Lifetime_Used "
"-v 205,raw48,Thermal_Asperity_Rate "
"-v 231,tempminmax,Controller_Temperature "
"-v 234,raw48,Sectors_Read_from_NAND "
"-v 235,raw48,Sectors_Written_to_SSD "
"-v 241,raw48,Sectors_Written_to_NAND "
"-v 242,raw48,Sectors_Read_from_SSD "
"-v 248,raw48,Percent_Lifetime_Remain "
"-v 249,raw48,Spare_Blocks_Remaining " // same as ID 17 (Remaining_Spare_Blocks)
},
{ "ATP SATA III aMLC M.2 2242/80 Embedded SSDs",
"ATP I-Temp M\\.2 22(42|80)", // tested with ATP I-Temp M.2 2242/R0822A,
// ATP I-Temp M.2 2280/R0822A
@ -669,33 +610,6 @@ const drive_settings builtin_knowndrives[] = {
"-v 241,raw48,Lifetime_Writes_GiB "
"-v 242,raw48,Lifetime_Reads_GiB"
},
{ "SandForce Driven SSDs",
"SanDisk SDSSDA(120|240|480)G|" // SanDisk SSD Plus, tested with SanDisk SDSSDA240G/U21010RL
"SanDisk SD8S[BFN]AT128G1(00|12)2", // SanDisk Z400s, tested with
// SanDisk SD8SFAT128G1122/Z2333000, SanDisk SD8SNAT128G1002/Z2317002
// SanDisk SD8SBAT128G1002/Z2317002
"", "",
"-v 5,raw48,Retired_Block_Count "
//"-v 9,raw24(raw8),Power_On_Hours "
//"-v 12,raw48,Power_Cycle_Count "
"-v 166,raw48,Min_PE_Cycles "
"-v 167,raw48,Max_Bad_Blocks_Per_Die "
"-v 168,raw48,Max_PE_Cycles "
"-v 169,raw48,Total_Bad_Blocks "
"-v 170,raw48,Grown_Bad_Blocks "
"-v 171,raw48,Program_Fail_Count "
"-v 172,raw48,Erase_Fail_Count "
"-v 173,raw48,Average_PE_Cycles "
"-v 174,raw48,Unexpect_Power_Loss_Ct "
//"-v 187,raw48,Reported_Uncorrect "
//"-v 194,tempminmax,Temperature_Celsius "
//"-v 199,raw48,UDMA_CRC_Error_Count "
"-v 230,raw48,Media_Wearout_Indicator "
//"-v 232,raw48,Available_Reservd_Space "
"-v 233,raw48,NAND_GiB_Written "
"-v 241,raw48,Lifetime_Writes_GiB "
"-v 242,raw48,Lifetime_Reads_GiB"
},
{ "SandForce Driven SSDs",
"SandForce 1st Ed\\.|" // Demo Drive, tested with firmware 320A13F0
"ADATA SSD S(396|510|599) .?..GB|" // tested with ADATA SSD S510 60GB/320ABBF0,
@ -766,6 +680,7 @@ const drive_settings builtin_knowndrives[] = {
"Patriot Pyro|" // tested with Patriot Pyro/332ABBF0
"SanDisk SDSSDX(60|120|240|480)GG25|" // SanDisk Extreme, SF-2281, tested with
// SDSSDX240GG25/R201
"SanDisk SDSSDA(120|240|480)G|" // SanDisk SSD Plus, tested with SanDisk SDSSDA240G/U21010RL
"SuperSSpeed S301 [0-9]*GB|" // SF-2281, tested with SuperSSpeed S301 128GB/503
"SG9XCS2D(0?50|100|200|400)GESLT|" // Smart Storage Systems XceedIOPS2, tested with
// SG9XCS2D200GESLT/SA03L370
@ -848,10 +763,9 @@ const drive_settings builtin_knowndrives[] = {
// KINGSTON RBUSNS4180S3256GJ/SBFK61D1, KINGSTON RBUSNS8180S3512GJ/SBFK61D1
"KINGSTON SEDC400S37(400|480|800|960|1600|1800)G|" // DC400, tested with
// KINGSTON SEDC400S37480G/SAFM02.[GH], KINGSTON SEDC400S37960G/SAFM32.I
"KINGSTON SEDC(450R|500[MR]|600M)(480|960|1920|3840|7680)G|" // DC450R, DC500M/R, DC600M, tested with
"KINGSTON SEDC(450R|500[MR])(480|960|1920|3840|7680)G|" // DC450R, DC500M/R, tested with
// KINGSTON SEDC450R480G/SCEKH3. KINGSTON SEDC500M1920G/SCEKJ2.3,
// KINGSTON SEDC500R480G/SCEKJ2.3, KINGSTON SEDC450R7680G/SCEKH3.4,
// KINGSTON SEDC600M7680G/SCEKH5.1
// KINGSTON SEDC500R480G/SCEKJ2.3, KINGSTON SEDC450R7680G/SCEKH3.4
"KINGSTON SM2280S3G2(120)G|" // KINGSTON SM2280S3G2120G/SAFM01.R
"KINGSTON SUV300S37A(120|240|480)G|" // UV300 SSD, tested with KINGSTON SUV300S37A120G/SAFM11.K
"KINGSTON SKC310S3B?7A960G|" // SSDNow KC310, KINGSTON SKC310S37A960G/SAFM00.r
@ -1734,9 +1648,9 @@ const drive_settings builtin_knowndrives[] = {
},
{ "Intel S4510/S4610/S4500/S4600 Series SSDs", // INTEL SSDSC2KB480G7/SCV10100,
// INTEL SSDSC2KB960G7/SCV10100, INTEL SSDSC2KB038T7/SCV10100,
// INTEL SSDSC2KB038T7/SCV10121, INTEL SSDSC2KG240G7/SCV10100,
// INTEL SSDSC2KB480GZ/7CV10100, INTEL SSDSC2KB076T8/XCV10132
"INTEL SSDSC(2K|KK)(B|G)(240G|480G|960G|019T|038T|076T)[78Z].?",
// INTEL SSDSC2KB038T7/SCV10121, INTEL SSDSC2KG240G7/SCV10100
// INTEL SSDSC2KB480GZ/7CV10100
"INTEL SSDSC(2K|KK)(B|G)(240G|480G|960G|019T|038T)(7|8|Z).?",
"", "",
//"-v 5,raw16(raw16),Reallocated_Sector_Ct "
//"-v 9,raw24(raw8),Power_On_Hours "
@ -2013,8 +1927,7 @@ const drive_settings builtin_knowndrives[] = {
"SAMSUNG MZ7L3(240|480|960|1T9|3T8|7T6)H(B[LN][AT]|CHQ|CJR)-.*|" // PM893/897, tested with
// SAMSUNG MZ7L3240HCHQ-00A07/JXTC104Q, SAMSUNG MZ7L3480HCHQ-00A07/JXTC104Q,
// SAMSUNG MZ7L3480HBLT-00A07/JXTE004Q, SAMSUNG MZ7L33T8HBLT-00A07/JXTC104Q
"MK000(240|480|960)GZXR[AB]|" // MK000960GZXRB/HPG0 (HPE MZ7L3960HBLT-00AH3)
// MK000480GZXRA/HPG0 (HPE P18432-B21)
"MK000(240|480|960)GZXRB|" // MK000960GZXRB/HPG0 (HPE MZ7L3960HBLT-00AH3)
"SAMSUNG MZ7KH(240|480|960|1T9|3T8)HA(HQ|JR|LS)-.*|" //SM883
"SAMSUNG MZ[7N](LF|TY)(128|192|256)H[CD](GS|HP)-.*|" // CM871/871a, tested with SAMSUNG MZNLF128HCHP-000H1/FXT21H1Q,
// SAMSUNG MZNTY256HDHP-000/MAT21K0Q, SAMSUNG MZ7LF192HCGS-000L1/FXT03L1Q
@ -2076,24 +1989,21 @@ const drive_settings builtin_knowndrives[] = {
},
{ "Marvell based SanDisk SSDs",
"SanDisk SD5SG2[0-9]*G1052E|" // X100 (88SS9174), tested with SanDisk SD5SG2256G1052E/10.04.01
"SanDisk SD6S[BFP][12]M[0-9]*G(1022I?|1102)?|" // X110/X210 (88SS9175/187?), tested with SanDisk SD6SB1M064G1022I/X231600,
"SanDisk SD6S[BF][12]M[0-9]*G(1022I?)?|" // X110/X210 (88SS9175/187?), tested with SanDisk SD6SB1M064G1022I/X231600,
// SanDisk SD6SB1M256G1022I/X231600, SanDisk SD6SF1M128G1022/X231200, SanDisk SD6SB2M512G1022I/X210400
// SanDisk SD6SP1M128G1102/X231302
"SanDisk SD7S[BN][67]S-?(128|256|512|960)G(1122|-1006)?|" // X300 (88SS9189?), tested with
// SanDisk SD7SB6S128G1122/X3310000, SanDisk SD7SN6S-512G-1006/X3511006, SanDisk SD7SB7S960G/X36310DC
"SanDisk SD8[ST][BN]8U-?((128|256|512)G|1T00)(1122|-10[01]6)|" // X400 (88SS1074), tested with SanDisk SD8SB8U128G1122/X4120000
// SanDisk SD8TB8U-512G-1016/X4163116
"SanDisk SD9S[BN]8W-?((128|256|512)G|[12]T00)(1122|-1006|1020)|" // X600, tested with SanDisk SD9SB8W128G1122/X6107000, SD9SB8W-512G-1006/X6103006
// SanDisk SD9SB8W1T001122/X6107000, SD9SB8W256G1122/X6107000, SanDisk SD9SN8W128G1020/X6101020
"SanDisk SD7S[BN]6S-?(128|256|512)G(1122|-1006)|" // X300 (88SS9189?), tested with
// SanDisk SD7SB6S128G1122/X3310000, SanDisk SD7SN6S-512G-1006/X3511006
"SanDisk SD8S[BN]8U-?((128|256|512)G|1T00)(1122|-1006)|" // X400 (88SS1074), tested with SanDisk SD8SB8U128G1122/X4120000
"SanDisk SD9S[BN]8W-?((128|256|512)G|[12]T00)(1122|-1006)|" // X600, tested with SanDisk SD9SB8W128G1122/X6107000, SD9SB8W-512G-1006/X6103006
// SanDisk SD9SB8W1T001122/X6107000, SD9SB8W256G1122/X6107000
"SanDisk SDSSDA-((120|240|480)G|[12]T00)|" // Plus, tested with SanDisk SDSSDA-2T00/411040RL
"SanDisk SDSSDHP[0-9]*G|" // Ultra Plus (88SS9175), tested with SanDisk SDSSDHP128G/X23[01]6RL
"SanDisk (SDSSDHII|Ultra II )[0-9]*GB?|" // Ultra II (88SS9190/88SS9189), tested with
// SanDisk SDSSDHII120G/X31200RL, SanDisk Ultra II 960GB/X41100RL
"SanDisk SDSSDH2(128|256)G|" // SanDisk SDSSDH2128G/X211200
"SanDisk SDSSDH3((250|500| 512|1000|1024|2000)G| [124]T00)|" // Ultra 3D, tested with SanDisk SDSSDH3250G/X61170RL,
"SanDisk SDSSDH3((250|500|1000|1024|2000)G| [124]T00)|" // Ultra 3D, tested with SanDisk SDSSDH3250G/X61170RL,
// SanDisk SDSSDH3500G/X61110RL, SanDisk SDSSDH31024G/X6107000, SanDisk SDSSDH3 2T00/411040RL,
// SanDisk SDSSDH3 4T00/411040RL, SanDisk SDSSDH3 1T00/415020RL,
// SanDisk SDSSDH3 512G/40101000
// SanDisk SDSSDH3 4T00/411040RL, SanDisk SDSSDH3 1T00/415020RL
"SanDisk SDSSDXPS?[0-9]*G|" // Extreme II/Pro (88SS9187), tested with SanDisk SDSSDXP480G/R1311,
// SanDisk SDSSDXPS480G/X21200RL
"SanDisk SSD G5 BICS4|" // WD Blue SSD WDS100T2B0A (#1378), tested with SanDisk SSD G5 BICS4/415000WD
@ -2140,8 +2050,7 @@ const drive_settings builtin_knowndrives[] = {
"SanDisk SSD i100 [0-9]*GB|" // tested with SanDisk SSD i100 8GB/11.56.04, 24GB/11.56.04
"SanDisk SSD U100 ([0-9]*GB|SMG2)|" // tested with SanDisk SSD U100 8GB/10.56.00, 256GB/10.01.02, SMG2/10.56.04
"SanDisk SSD U110 (8|16|24|32|64|128)GB|" // tested with SanDisk SSD U110 32GB/U221000
"SanDisk SDSA6[DGM]M-[0-9]*G-.*|" // tested with SanDisk SDSA6GM-016G-1006/U221006, SanDisk SDSA6MM-016G-1006/U221006,
// SanDisk SDSA6GM-016G-1006/U221006
"SanDisk SDSA6[GM]M-[0-9]*G-.*|" // tested with SanDisk SDSA6GM-016G-1006/U221006, SanDisk SDSA6MM-016G-1006/U221006
"SanDisk SD7[SU]B[23]Q(064|128|256|512)G.*", // tested with SD7SB3Q064G1122/SD7UB3Q256G1122/SD7SB3Q128G/SD7UB2Q512G1122
"", "",
//"-v 5,raw16(raw16),Reallocated_Sector_Ct "
@ -2351,9 +2260,9 @@ const drive_settings builtin_knowndrives[] = {
"Dogfish SSD (128|256|512)GB|" // tested with Dogfish SSD 128GB/S1211A0
"GIM(16|32|64|128|256|512)|"// GUDGA GIM, tested with GIM128/U0401A0
"INTENSO( SSD)?|" // tested with INTENSO/S1211A0 (Portable SSD 256GB premium edition),
// INTENSO/V0609A0, INTENSO SSD/V0823A0, INTENSO/V0718B0
"Intenso ?SSD( S(ata|ATA) ?III)?|" // tested with Intenso SSD/Q1107A0, Intenso SSD Sata III/P0510E,
// Intenso SSD Sata III/R0817B0, Intenso SSD Sata III/V0303B0, Intenso SSD SATAIII/W0825A0
// INTENSO/V0609A0, INTENSO SSD/V0823A0
"Intenso ?SSD( Sata III)?|" // tested with Intenso SSD/Q1107A0, Intenso SSD Sata III/P0510E,
// Intenso SSD Sata III/R0817B0, Intenso SSD Sata III/V0303B0
"KingFast|" // tested with KingFast/P0725A (F6M), KingFast/S0424A0 (120GB), KingFast/S1128B0 (512GB)
"KSM512|" // KingSpec, tested with KSM512/S0509A0
"LDLC|" // tested with LDLC/KFS03005
@ -2369,7 +2278,7 @@ const drive_settings builtin_knowndrives[] = {
"Verbatim Vi550 S3", // may also exist with different controller (tickets #1626 <> #1629),
// tested with Verbatim Vi550 S3/U1124A0 (128GB)
"HPS2227I|KFS03005|P0510E|P0725A|Q(0627|1107)A0|R0817B0|S(0424|0509|0618|1211|1230)A0|"
"S112[78]B0|T0(311|519|910)A0|U(0202|0401|0506|1124)A0|V0((609|823)A|(303|718)B)0|V1027A0|W0825A0",
"S112[78]B0|T0(311|519|910)A0|U(0202|0401|0506|1124)A0|V0((606|823)A|303B)0",
"",
"-v 148,raw48,Total_SLC_Erase_Ct "
"-v 149,raw48,Max_SLC_Erase_Ct "
@ -3741,8 +3650,8 @@ const drive_settings builtin_knowndrives[] = {
"", "", ""
},
{ "HGST Ultrastar HC310/320", // tested with HGST HUS726T6TALE6L4/VKGNW40H,
// HGST HUS728T8TALE6L4/V8GNW460, HGST HUS726T4TALA6L1/VLGNX41C
"HGST HUS72(6T[46]|8T8)TAL[AE]6L[14]",
// HGST HUS728T8TALE6L4/V8GNW460
"HGST HUS72(6T[46]|8T8)TALE6L4",
"", "", ""
},
{ "HGST Ultrastar He6", // tested with HGST HUS726060ALA640/AHGNT1E2
@ -3964,21 +3873,17 @@ const drive_settings builtin_knowndrives[] = {
"TOSHIBA MG03ACA[1234]00Y?",
"", "", ""
},
{ "Toshiba MD04ACA... Enterprise HDD", // tested with TOSHIBA MD04ACA500/FP1A
"TOSHIBA MD04ACA[2-6]00N?",
"", "", ""
},
{ "Toshiba MG04ACA... Enterprise HDD", // tested with TOSHIBA MG04ACA600A/FS2B,
// TOSHIBA MG04ACA400NY/FK5D (Dell)
"TOSHIBA MG04ACA[1-6]00[AEN]Y?",
{ "Toshiba MG04ACA... Enterprise HDD", // tested with TOSHIBA MD04ACA500/FP1A,
// TOSHIBA MG04ACA600A/FS2B, TOSHIBA MG04ACA400NY/FK5D (Dell)
"TOSHIBA MG04ACA[23456]00([AEN].?)?",
"", "", ""
},
{ "Toshiba MG05ACA... Enterprise Capacity HDD", // tested with TOSHIBA MG05ACA800E/GX2A
"TOSHIBA MG05ACA800[AE]",
"", "", ""
},
{ "Toshiba MG06ACA... Enterprise Capacity HDD", // tested with TOSHIBA MG06ACA800E/0109,
// TOSHIBA MG06ACA800E/4303, TOSHIBA MG06ACA10TE/0103,
{ "Toshiba MG06ACA... Enterprise Capacity HDD", // tested with TOSHIBA MG06ACA800E/4303,
// TOSHIBA MG06ACA10TE/0103
"TOSHIBA MG06ACA([68]00|10T)[AE]Y?",
"", "", ""
},
@ -3995,11 +3900,6 @@ const drive_settings builtin_knowndrives[] = {
"-v 23,raw48,Helium_Condition_Lower "
"-v 24,raw48,Helium_Condition_Upper"
},
{ "Toshiba MG08ADA... Enterprise Capacity HDD", // tested with TOSHIBA MG08ADA800E/0101,
// TOSHIBA MG08ADA800E/4303, TOSHIBA MG08ADA800E/4304
"TOSHIBA MG08ADA[468]00[AEN]Y?",
"", "", ""
},
{ "Toshiba MG09ACA... Enterprise Capacity HDD", // tested with TOSHIBA MG09ACA18TE/0102
"TOSHIBA MG09ACA1[68]T[AE]Y?",
"", "",
@ -4014,13 +3914,6 @@ const drive_settings builtin_knowndrives[] = {
"-v 24,raw48,Helium_Condition_Upper "
"-v 27,raw48,MAMR_Health_Monitor"
},
{ "Toshiba MG10AFA... Enterprise Capacity HDD", // tested with TOSHIBA MG10AFA22TE/0102
"TOSHIBA MG10AFA22T[AE]Y?",
"", "",
"-v 23,raw48,Helium_Condition_Lower "
"-v 24,raw48,Helium_Condition_Upper "
"-v 27,raw48,MAMR_Health_Monitor"
},
{ "Toshiba 3.5\" DT01ABA... Desktop HDD", // tested with TOSHIBA DT01ABA300/MZ6OABB0
"TOSHIBA DT01ABA(100|150|200|300)",
"", "", ""
@ -4031,10 +3924,10 @@ const drive_settings builtin_knowndrives[] = {
"", "", ""
},
{ "Toshiba N300/MN NAS HDD", // tested with TOSHIBA HDWQ140/FJ1M, TOSHIBA HDWN160/FS1M,
// TOSHIBA HDWN180/GX2M, TOSHIBA HDWG440/0601 (4TB), TOSHIBA HDWG480/0601 (8TB),
// TOSHIBA HDWG11A/0603 (10TB), TOSHIBA HDWG21C/0601 (12TB), TOSHIBA HDWG21E/0601 (14TB),
// TOSHIBA HDWN180/GX2M, TOSHIBA HDWG480/0601 (8TB), TOSHIBA HDWG11A/0603 (10TB),
// TOSHIBA HDWG21C/0601 (12TB), TOSHIBA HDWG21E/0601 (14TB),
// TOSHIBA MN07ACA12T/0601, TOSHIBA MN08ACA14T/0601
"TOSHIBA HDW([GNQ]1[468]0|G(440|480|11A|21[CE]|31G))|" // 31G: 16TB
"TOSHIBA HDW([GNQ]1[468]0|G(480|11A|21[CE]|31G))|" // 31G: 16TB
"TOSHIBA MN0(4ACA400|6ACA([68]00|10T)|7ACA1[24]T|8ACA1[46]T)",
"", "",
"-v 23,raw48,Helium_Condition_Lower " // ] >= 12TB
@ -4048,14 +3941,8 @@ const drive_settings builtin_knowndrives[] = {
"TOSHIBA HDWD2[246]0",
"", "", ""
},
{ "Toshiba S300 (SMR)", // tested with TOSHIBA HDWT860/KQ0H1L
"TOSHIBA HDWT(7[24]|8[46])0",
"", "", ""
},
{ "Toshiba X300", // tested with TOSHIBA HDWE160/FS2A, TOSHIBA HDWF180/GX0B
// TOSHIBA HDWR480/0601
"TOSHIBA HDW(E1[456]0|[FR]180|R(4[468]0|11A|21[CE]|31[EG]|51J))", // 4n0:nTB, 11A:10TB,
// 21C:12TB, 21E:14TB, 31E:14TB, 31G:16TB, 51J:18TB
"TOSHIBA HDW(E1[456]0|[FR]180|R(11A|21[CE]|31G))", // 11A:10TB, 21C:12TB, 21E:14TB, 31G: 16TB
"", "",
"-v 23,raw48,Helium_Condition_Lower " // ] >= 12TB
"-v 24,raw48,Helium_Condition_Upper" // ]
@ -4817,9 +4704,8 @@ const drive_settings builtin_knowndrives[] = {
// WDC WDBNCE2500PNC/X61130WD, WDC WDBNCE0010PNC-WRSN/X41110WD,
// WDC WDS200T1R0A-68A4W0/411000WR, WDC WDS400T1R0A-68A4W0/411000WR
"WDC WDBNCE(250|500|00[124])0PNC(-.*)?|" // Blue 3D
"WDC ?WDS((120|240|250|480|500)G|[124]00T)(1B|2B|1G|2G|1R)0[AB](-.*)?|"
"WDC ?WDS((120|240|250|480|500)G|[124]00T)(1B|2B|1G|2G|1R)0[AB](-.*)?",
// *B* = Blue, *G* = Green, *2B* = Blue 3D NAND, *1R* = Red SA500
"WD Blue SA510 2.5 1000GB", // tested with WD Blue SA510 2.5 1000GB/52008100
"", "",
//"-v 5,raw16(raw16),Reallocated_Sector_Ct " // Reassigned Block Count
//"-v 9,raw24(raw8),Power_On_Hours "
@ -5110,16 +4996,15 @@ const drive_settings builtin_knowndrives[] = {
},
{ "Western Digital Red", // tested with WDC WD10EFRX-68JCSN0/01.01A01,
// WDC WD10JFCX-68N6GN0/01.01A01, WDC WD30EFRX-68EUZN0/82.00A82,
// WDC WD40EFRX-68WT0N0/80.00A80, WDC WD40EFPX-68C6CN0/81.00A81,
// WDC WD60EFRX-68MYMN1/82.00A82, WDC WD60EFPX-68C5ZN0/81.00A81,
// WDC WD40EFRX-68WT0N0/80.00A80, WDC WD60EFRX-68MYMN1/82.00A82,
// WDC WD80EFAX-68LHPN0/83.H0A83, WDC WD80EFZX-68UW8N0/83.H0A83,
// WDC WD80EZZX-11CSGA0/83.H0A03 (My Book 0x1058:0x25ee),
// WDC WD100EFAX-68LHPN0/83.H0A83, WDC WD120EFBX-68B0EN0/85.00A85
// WDC WD100EFAX-68LHPN0/83.H0A83,
// WDC WD120EMFZ-11A6JA0/81.00A81 (Easystore 0x1058:0x25fb)
// WDC WD160EMFZ-11AFXA0/81.00A81
// WDC WD40EFZX-68AWUN0/81.00B81, WDC WD20EFZX-68AWUN0/81.00B81
// WDC WD140EFFX-68VBXN0/81.00A81
"WDC WD(7500BFCX|10JFCX|[1-6]0EFRX|1(20|01)EFBX|[2-8]0EFPX|[2468]0E[FZ]ZX|80EFZZ|(8|10)0EFAX|1[26]0EMFZ|140E(FF|FG)X)-.*",
"WDC WD(7500BFCX|10JFCX|[1-6]0EFRX|[2468]0E[FZ]ZX|(8|10)0EFAX|1[26]0EMFZ|140E(FF|FG)X)-.*",
"", "",
"-v 22,raw48,Helium_Level" // WD80EFAX, WD80EFZX, WD100EFAX, WD120EMFZ, WD160EMFZ
},
@ -5415,7 +5300,7 @@ const drive_settings builtin_knowndrives[] = {
"0x04e8:0x(4001|61fb)", // 0x61fb: T7 Shield
"", // 0x0100
"",
"" // smartmontools >= r5168: -d sntasmedia
"-d sntasmedia"
},
{ "USB: Samsung Story Station; ",
"0x04e8:0x5f0[56]",
@ -5908,12 +5793,6 @@ const drive_settings builtin_knowndrives[] = {
"",
"-d sat,12" // 0x50a1: "-d sat" does not work (ticket #151)
},
{ "USB: Seagate FireCuda Gaming SSD; ASMedia ASM2364",
"0x0bc2:0xaa1a",
"", // 0x100
"",
"" // smartmontools >= r5168: -d sntasmedia
},
{ "USB: Seagate; ",
"0x0bc2:0x....",
"",
@ -6167,8 +6046,8 @@ const drive_settings builtin_knowndrives[] = {
"-d sat"
},
{ "USB: ; JMicron JMS583", // USB->PCIe (NVMe)
"0x152d:0x[0a]583",
"", // 0x214
"0x152d:0x0583",
"",
"",
"-d sntjmicron"
},
@ -6304,7 +6183,7 @@ const drive_settings builtin_knowndrives[] = {
"0x174c:0x236[24]",
"",
"",
"" // smartmontools >= r5168: -d sntasmedia
"-d sntasmedia"
},
{ "USB: ; ASMedia",
"0x174c:0x....",

View File

@ -3,7 +3,7 @@
# Send mail
if which mail >/dev/null 2>&1
then
echo "$SMARTD_FULLMESSAGE" | mail -s "$SMARTD_SUBJECT" "$SMARTD_ADDRESS"
echo "$SMARTD_MESSAGE" | mail -s "$SMARTD_FAILTYPE" "$SMARTD_ADDRESS"
fi
# Notify desktop user

View File

@ -0,0 +1,85 @@
From da45fc39390208c30b3ba656ccfb478e217b7401 Mon Sep 17 00:00:00 2001
From: "Milan P. Gandhi" <mgandhi@redhat.com>
Date: Mon, 17 Oct 2022 14:23:54 +0530
Subject: [PATCH 1/3] scsiprint.cpp: Attempted fix to tickets 1272, 1331 and
1346: Log sub-page handling
---
smartmontools-7.1/scsiprint.cpp | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/smartmontools-7.1/scsiprint.cpp b/smartmontools-7.1/scsiprint.cpp
index 4c52268..1edb7c2 100644
--- a/smartmontools-7.1/scsiprint.cpp
+++ b/smartmontools-7.1/scsiprint.cpp
@@ -118,8 +118,10 @@ static void
scsiGetSupportedLogPages(scsi_device * device)
{
bool got_subpages = false;
- int k, bump, err, payload_len, num_unreported, num_unreported_spg;
- int payload_len_pg0_0 = 0;
+ int k, bump, err, resp_len, num_unreported, num_unreported_spg;
+ int resp_len_pg0_0 = 0;
+ int resp_len_pg0_ff = 0; /* in SPC-4, response length of supported
+ * log pages _and_ log subpages */
const uint8_t * up;
uint8_t sup_lpgs[LOG_RESP_LEN];
@@ -143,7 +145,7 @@ scsiGetSupportedLogPages(scsi_device * device)
(scsi_version <= SCSI_VERSION_HIGHEST)) {
/* unclear what code T10 will choose for SPC-6 */
memcpy(sup_lpgs, gBuf, LOG_RESP_LEN);
- payload_len_pg0_0 = sup_lpgs[3];
+ resp_len_pg0_0 = sup_lpgs[3];
if ((err = scsiLogSense(device, SUPPORTED_LPAGES, SUPP_SPAGE_L_SPAGE,
gBuf, LOG_RESP_LONG_LEN,
-1 /* just single not double fetch */))) {
@@ -160,33 +162,38 @@ scsiGetSupportedLogPages(scsi_device * device)
if (scsi_debugmode > 0)
pout("%s supported subpages is bad SPF=%u SUBPG=%u\n",
logSenRspStr, !! (0x40 & gBuf[0]), gBuf[2]);
- } else
+ } else {
+ resp_len_pg0_ff = sg_get_unaligned_be16(gBuf + 2);
got_subpages = true;
+ }
}
- } else
+ } else {
memcpy(sup_lpgs, gBuf, LOG_RESP_LEN);
+ resp_len_pg0_0 = sup_lpgs[3];
+ }
if (got_subpages) {
- payload_len = sg_get_unaligned_be16(gBuf + 2);
- if (payload_len <= payload_len_pg0_0) {
+ resp_len = sg_get_unaligned_be16(gBuf + 2);
+ if (resp_len_pg0_ff <= resp_len_pg0_0) {
/* something is rotten ....., ignore SUPP_SPAGE_L_SPAGE */
- payload_len = payload_len_pg0_0;
+ resp_len = resp_len_pg0_0;
bump = 1;
up = sup_lpgs + LOGPAGEHDRSIZE;
got_subpages = false;
(void)got_subpages; // not yet used below, suppress warning
} else {
+ resp_len = resp_len_pg0_ff;
bump = 2;
up = gBuf + LOGPAGEHDRSIZE;
}
} else {
- payload_len = payload_len_pg0_0;
+ resp_len = resp_len_pg0_0;
bump = 1;
up = sup_lpgs + LOGPAGEHDRSIZE;
}
num_unreported_spg = 0;
- for (num_unreported = 0, k = 0; k < payload_len; k += bump, up += bump) {
+ for (num_unreported = 0, k = 0; k < resp_len; k += bump, up += bump) {
uint8_t pg_num = 0x3f & up[0];
uint8_t sub_pg_num = (0x40 & up[0]) ? up[1] : 0;
--
2.35.1

View File

@ -0,0 +1,185 @@
From b6064d5ba30ee355e71e7543fdb66ea99fcebae4 Mon Sep 17 00:00:00 2001
From: "Milan P. Gandhi" <mgandhi@redhat.com>
Date: Mon, 17 Oct 2022 14:24:42 +0530
Subject: [PATCH 2/3] scsiprint.cpp: Add 'Accumulated power on time' field to
'smartctl -a'
---
smartmontools-7.1/scsiprint.cpp | 82 ++++++++++++++++++++++-----------
1 file changed, 56 insertions(+), 26 deletions(-)
diff --git a/smartmontools-7.1/scsiprint.cpp b/smartmontools-7.1/scsiprint.cpp
index 1edb7c2..81bed88 100644
--- a/smartmontools-7.1/scsiprint.cpp
+++ b/smartmontools-7.1/scsiprint.cpp
@@ -120,7 +120,7 @@ scsiGetSupportedLogPages(scsi_device * device)
bool got_subpages = false;
int k, bump, err, resp_len, num_unreported, num_unreported_spg;
int resp_len_pg0_0 = 0;
- int resp_len_pg0_ff = 0; /* in SPC-4, response length of supported
+ int resp_len_pg0_ff = 0; /* in SPC-4, response length of supported
* log pages _and_ log subpages */
const uint8_t * up;
uint8_t sup_lpgs[LOG_RESP_LEN];
@@ -163,13 +163,13 @@ scsiGetSupportedLogPages(scsi_device * device)
pout("%s supported subpages is bad SPF=%u SUBPG=%u\n",
logSenRspStr, !! (0x40 & gBuf[0]), gBuf[2]);
} else {
- resp_len_pg0_ff = sg_get_unaligned_be16(gBuf + 2);
+ resp_len_pg0_ff = sg_get_unaligned_be16(gBuf + 2);
got_subpages = true;
- }
+ }
}
} else {
memcpy(sup_lpgs, gBuf, LOG_RESP_LEN);
- resp_len_pg0_0 = sup_lpgs[3];
+ resp_len_pg0_0 = sup_lpgs[3];
}
if (got_subpages) {
@@ -182,7 +182,7 @@ scsiGetSupportedLogPages(scsi_device * device)
got_subpages = false;
(void)got_subpages; // not yet used below, suppress warning
} else {
- resp_len = resp_len_pg0_ff;
+ resp_len = resp_len_pg0_ff;
bump = 2;
up = gBuf + LOGPAGEHDRSIZE;
}
@@ -1162,12 +1162,14 @@ static const char * reassign_status[] = {
// Returns 0 if ok else FAIL* bitmask. Note can have a status entry
// and up to 2048 events (although would hope to have less). May set
// FAILLOG if serious errors detected (in the future).
+// When only_pow_time is true only print "Accumulated power on time"
+// data, if available.
static int
-scsiPrintBackgroundResults(scsi_device * device)
+scsiPrintBackgroundResults(scsi_device * device, bool only_pow_time)
{
+ bool noheader = true;
+ bool firstresult = true;
int num, j, m, err, truncated;
- int noheader = 1;
- int firstresult = 1;
int retval = 0;
uint8_t * ucp;
static const char * hname = "Background scan results";
@@ -1188,9 +1190,12 @@ scsiPrintBackgroundResults(scsi_device * device)
// compute page length
num = sg_get_unaligned_be16(gBuf + 2) + 4;
if (num < 20) {
- print_on();
- pout("%s %s length is %d, no scan status\n", hname, logSenStr, num);
- print_off();
+ if (! only_pow_time) {
+ print_on();
+ pout("%s %s length is %d, no scan status\n", hname, logSenStr,
+ num);
+ print_off();
+ }
return FAILSMART;
}
truncated = (num > LOG_RESP_LONG_LEN) ? num : 0;
@@ -1205,22 +1210,32 @@ scsiPrintBackgroundResults(scsi_device * device)
switch (pc) {
case 0:
if (noheader) {
- noheader = 0;
- pout("%s log\n", hname);
+ noheader = false;
+ if (! only_pow_time)
+ pout("%s log\n", hname);
}
- pout(" Status: ");
+ if (! only_pow_time)
+ pout(" Status: ");
if ((pl < 16) || (num < 16)) {
- pout("\n");
+ if (! only_pow_time)
+ pout("\n");
break;
}
j = ucp[9];
- if (j < (int)(sizeof(bms_status) / sizeof(bms_status[0])))
- pout("%s\n", bms_status[j]);
- else
- pout("unknown [0x%x] background scan status value\n", j);
+ if (! only_pow_time) {
+ if (j < (int)(sizeof(bms_status) / sizeof(bms_status[0])))
+ pout("%s\n", bms_status[j]);
+ else
+ pout("unknown [0x%x] background scan status value\n", j);
+ }
j = sg_get_unaligned_be32(ucp + 4);
- pout(" Accumulated power on time, hours:minutes %d:%02d "
- "[%d minutes]\n", (j / 60), (j % 60), j);
+ pout("%sAccumulated power on time, hours:minutes %d:%02d",
+ (only_pow_time ? "" : " "), (j / 60), (j % 60));
+ if (only_pow_time) {
+ pout("\n");
+ break;
+ } else
+ pout(" [%d minutes]\n", j);
jglb["power_on_time"]["hours"] = j / 60;
jglb["power_on_time"]["minutes"] = j % 60;
pout(" Number of background scans performed: %d, ",
@@ -1232,9 +1247,12 @@ scsiPrintBackgroundResults(scsi_device * device)
break;
default:
if (noheader) {
- noheader = 0;
- pout("\n%s log\n", hname);
+ noheader = false;
+ if (! only_pow_time)
+ pout("\n%s log\n", hname);
}
+ if (only_pow_time)
+ break;
if (firstresult) {
firstresult = 0;
pout("\n # when lba(hex) [sk,asc,ascq] "
@@ -1262,10 +1280,11 @@ scsiPrintBackgroundResults(scsi_device * device)
num -= pl;
ucp += pl;
}
- if (truncated)
+ if (truncated && (! only_pow_time))
pout(" >>>> log truncated, fetched %d of %d available "
"bytes\n", LOG_RESP_LONG_LEN, truncated);
- pout("\n");
+ if (! only_pow_time)
+ pout("\n");
return retval;
}
@@ -2447,6 +2466,17 @@ scsiPrintMain(scsi_device * device, const scsi_print_options & options)
scsiGetSupportedLogPages(device);
if (gTempLPage)
scsiPrintTemp(device);
+ }
+ // in the 'smartctl -a" case only want: "Accumulated power on time"
+ if ((! options.smart_background_log) && is_disk) {
+ if (! checkedSupportedLogPages)
+ scsiGetSupportedLogPages(device);
+ res = 0;
+ if (gBackgroundResultsLPage)
+ res = scsiPrintBackgroundResults(device, true);
+ any_output = true;
+ }
+ if (options.smart_vendor_attrib) {
if (gStartStopLPage)
scsiGetStartStopData(device);
if (is_disk) {
@@ -2488,7 +2518,7 @@ scsiPrintMain(scsi_device * device, const scsi_print_options & options)
scsiGetSupportedLogPages(device);
res = 0;
if (gBackgroundResultsLPage)
- res = scsiPrintBackgroundResults(device);
+ res = scsiPrintBackgroundResults(device, false);
else {
pout("Device does not support Background scan results logging\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
--
2.35.1

View File

@ -0,0 +1,31 @@
Index: trunk/smartmontools/scsiprint.cpp
===================================================================
--- smartmontools/scsiprint.cpp (revision 5076)
+++ smartmontools/scsiprint.cpp (revision 5090)
@@ -2340,6 +2340,6 @@
!wce ? "Disabled" : "Enabled");
}
- } else
any_output = true;
+ }
if (options.drive_info)
@@ -2463,12 +2463,10 @@
if (gTempLPage)
scsiPrintTemp(device);
- }
- // in the 'smartctl -a" case only want: "Accumulated power on time"
- if ((! options.smart_background_log) && is_disk) {
- if (! checkedSupportedLogPages)
- scsiGetSupportedLogPages(device);
- res = 0;
- if (gBackgroundResultsLPage)
- res = scsiPrintBackgroundResults(device, true);
+ // in the 'smartctl -A' case only want: "Accumulated power on time"
+ if ((! options.smart_background_log) && is_disk) {
+ res = 0;
+ if (gBackgroundResultsLPage)
+ res = scsiPrintBackgroundResults(device, true);
+ }
any_output = true;
}

View File

@ -0,0 +1,200 @@
diff -up smartmontools-7.1/nvmecmds.cpp.r5121 smartmontools-7.1/nvmecmds.cpp
--- smartmontools-7.1/nvmecmds.cpp.r5121 2019-07-01 22:54:14.000000000 +0200
+++ smartmontools-7.1/nvmecmds.cpp 2023-11-22 12:56:02.927324622 +0100
@@ -3,7 +3,7 @@
*
* Home page of code is: https://www.smartmontools.org
*
- * Copyright (C) 2016-19 Christian Franke
+ * Copyright (C) 2016-20 Christian Franke
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
@@ -132,6 +132,7 @@ bool nvme_read_id_ctrl(nvme_device * dev
swapx(&id_ctrl.vid);
swapx(&id_ctrl.ssvid);
swapx(&id_ctrl.cntlid);
+ swapx(&id_ctrl.ver);
swapx(&id_ctrl.oacs);
swapx(&id_ctrl.wctemp);
swapx(&id_ctrl.cctemp);
@@ -181,30 +182,54 @@ bool nvme_read_id_ns(nvme_device * devic
return true;
}
-// Read NVMe log page with identifier LID.
-bool nvme_read_log_page(nvme_device * device, unsigned char lid, void * data,
- unsigned size, bool broadcast_nsid)
+static bool nvme_read_log_page_1(nvme_device * device, unsigned nsid,
+ unsigned char lid, void * data, unsigned size, unsigned offset = 0)
{
- if (!(4 <= size && size <= 0x4000 && (size % 4) == 0))
- throw std::logic_error("nvme_read_log_page(): invalid size");
+ if (!(4 <= size && size <= 0x1000 && !(size % 4) && !(offset % 4)))
+ return device->set_err(EINVAL, "Invalid NVMe log size %u or offset %u", size, offset);
memset(data, 0, size);
nvme_cmd_in in;
in.set_data_in(nvme_admin_get_log_page, data, size);
- in.nsid = broadcast_nsid ? 0xffffffff : device->get_nsid();
+ in.nsid = nsid;
in.cdw10 = lid | (((size / 4) - 1) << 16);
+ in.cdw12 = offset; // LPOL, NVMe 1.2.1
return nvme_pass_through(device, in);
}
+// Read NVMe log page with identifier LID.
+unsigned nvme_read_log_page(nvme_device * device, unsigned nsid, unsigned char lid,
+ void * data, unsigned size, bool nvme_121, unsigned offset /* = 0 */)
+{
+ unsigned n, bs;
+ for (n = 0; n < size; n += bs) {
+ if (!nvme_121 && offset + n > 0) {
+ device->set_err(ENOSYS, "Log Page Offset requires NVMe >= 1.2.1");
+ break;
+ }
+
+ // Limit transfer size to one page to avoid problems with
+ // limits of NVMe pass-through layer or too low MDTS values.
+ bs = size - n;
+ if (bs > 0x1000)
+ bs = 0x1000;
+ if (!nvme_read_log_page_1(device, nsid, lid, (char *)data + n, bs, offset + n))
+ break;
+ }
+
+ return n;
+}
+
// Read NVMe Error Information Log.
-bool nvme_read_error_log(nvme_device * device, nvme_error_log_page * error_log, unsigned num_entries)
+unsigned nvme_read_error_log(nvme_device * device, nvme_error_log_page * error_log,
+ unsigned num_entries, bool nvme_121)
{
- if (!nvme_read_log_page(device, 0x01, error_log, num_entries * sizeof(*error_log), true))
- return false;
+ unsigned n = nvme_read_log_page(device, 0xffffffff, 0x01, error_log,
+ num_entries * sizeof(*error_log), nvme_121);
if (isbigendian()) {
- for (unsigned i = 0; i < num_entries; i++) {
+ for (unsigned i = 0; i < n; i++) {
swapx(&error_log[i].error_count);
swapx(&error_log[i].sqid);
swapx(&error_log[i].cmdid);
@@ -215,13 +240,13 @@ bool nvme_read_error_log(nvme_device * d
}
}
- return true;
+ return n / sizeof(*error_log);
}
// Read NVMe SMART/Health Information log.
bool nvme_read_smart_log(nvme_device * device, nvme_smart_log & smart_log)
{
- if (!nvme_read_log_page(device, 0x02, &smart_log, sizeof(smart_log), true))
+ if (!nvme_read_log_page_1(device, 0xffffffff, 0x02, &smart_log, sizeof(smart_log)))
return false;
if (isbigendian()) {
diff -up smartmontools-7.1/nvmecmds.h.r5121 smartmontools-7.1/nvmecmds.h
--- smartmontools-7.1/nvmecmds.h.r5121 2019-07-01 22:54:14.000000000 +0200
+++ smartmontools-7.1/nvmecmds.h 2023-11-22 12:56:02.927324622 +0100
@@ -3,7 +3,7 @@
*
* Home page of code is: https://www.smartmontools.org
*
- * Copyright (C) 2016-19 Christian Franke
+ * Copyright (C) 2016-20 Christian Franke
*
* Original code from <linux/nvme.h>:
* Copyright (C) 2011-2014 Intel Corporation
@@ -236,12 +236,12 @@ bool nvme_read_id_ctrl(nvme_device * dev
bool nvme_read_id_ns(nvme_device * device, unsigned nsid, smartmontools::nvme_id_ns & id_ns);
// Read NVMe log page with identifier LID.
-bool nvme_read_log_page(nvme_device * device, unsigned char lid, void * data,
- unsigned size, bool broadcast_nsid);
+unsigned nvme_read_log_page(nvme_device * device, unsigned nsid, unsigned char lid,
+ void * data, unsigned size, bool nvme_121, unsigned offset = 0);
// Read NVMe Error Information Log.
-bool nvme_read_error_log(nvme_device * device, smartmontools::nvme_error_log_page * error_log,
- unsigned num_entries);
+unsigned nvme_read_error_log(nvme_device * device, smartmontools::nvme_error_log_page * error_log,
+ unsigned num_entries, bool nvme_121);
// Read NVMe SMART/Health Information log.
bool nvme_read_smart_log(nvme_device * device, smartmontools::nvme_smart_log & smart_log);
diff -up smartmontools-7.1/nvmeprint.cpp.r5121 smartmontools-7.1/nvmeprint.cpp
--- smartmontools-7.1/nvmeprint.cpp.r5121 2023-11-22 12:56:02.927324622 +0100
+++ smartmontools-7.1/nvmeprint.cpp 2023-11-22 13:00:34.472659814 +0100
@@ -524,6 +524,9 @@ int nvmePrintMain(nvme_device * device,
}
}
+ // Log Page Offset requires NVMe >= 1.2.1
+ bool nvme_121 = (id_ctrl.ver >= 0x10201);
+
// Print Error Information Log
if (options.error_log_entries) {
unsigned num_entries = id_ctrl.elpe + 1; // 0-based value
@@ -531,39 +534,47 @@ int nvmePrintMain(nvme_device * device,
nvme_error_log_page * error_log =
reinterpret_cast<nvme_error_log_page *>(error_log_buf.data());
- if (!nvme_read_error_log(device, error_log, num_entries)) {
+ unsigned read_entries = nvme_read_error_log(device, error_log, num_entries, nvme_121);
+ if (!read_entries) {
jerr("Read Error Information Log failed: %s\n\n", device->get_errmsg());
return retval | FAILSMART;
}
+ if (read_entries < num_entries)
+ jerr("Read Error Information Log failed, %u entries missing: %s\n",
+ num_entries - read_entries, device->get_errmsg());
- print_error_log(error_log, num_entries, options.error_log_entries);
+ print_error_log(error_log, read_entries, options.error_log_entries);
}
// Dump log page
if (options.log_page_size) {
// Align size to dword boundary
unsigned size = ((options.log_page_size + 4-1) / 4) * 4;
- bool broadcast_nsid;
raw_buffer log_buf(size);
+ unsigned nsid;
switch (options.log_page) {
case 1:
case 2:
case 3:
- broadcast_nsid = true;
+ nsid = 0xffffffff;
break;
default:
- broadcast_nsid = false;
+ nsid = device->get_nsid();
break;
}
- if (!nvme_read_log_page(device, options.log_page, log_buf.data(),
- size, broadcast_nsid)) {
+ unsigned read_bytes = nvme_read_log_page(device, nsid, options.log_page, log_buf.data(),
+ size, nvme_121);
+ if (!read_bytes) {
jerr("Read NVMe Log 0x%02x failed: %s\n\n", options.log_page, device->get_errmsg());
return retval | FAILSMART;
}
+ if (read_bytes < size)
+ jerr("Read NVMe Log 0x%02x failed, 0x%x bytes missing: %s\n",
+ options.log_page, size - read_bytes, device->get_errmsg());
- pout("NVMe Log 0x%02x (0x%04x bytes)\n", options.log_page, size);
- dStrHex(log_buf.data(), size, 0);
+ pout("NVMe Log 0x%02x (0x%04x bytes)\n", options.log_page, read_bytes);
+ dStrHex(log_buf.data(), read_bytes, 0);
pout("\n");
}

View File

@ -0,0 +1,312 @@
diff -up smartmontools-7.1/dev_interface.cpp.r5471 smartmontools-7.1/dev_interface.cpp
--- smartmontools-7.1/dev_interface.cpp.r5471 2019-11-24 19:19:24.000000000 +0100
+++ smartmontools-7.1/dev_interface.cpp 2023-11-22 14:07:37.647756091 +0100
@@ -15,6 +15,7 @@
#include "dev_tunnelled.h"
#include "atacmds.h" // ATA_SMART_CMD/STATUS
#include "scsicmds.h" // scsi_cmnd_io
+#include "nvmecmds.h" // nvme_status_*()
#include "utility.h"
#include <errno.h>
@@ -235,12 +236,11 @@ bool scsi_device::scsi_pass_through_and_
bool nvme_device::set_nvme_err(nvme_cmd_out & out, unsigned status, const char * msg /* = 0 */)
{
- if (!status)
- throw std::logic_error("nvme_device: set_nvme_err() called with status=0");
-
out.status = status;
out.status_valid = true;
- return set_err(EIO, "%sNVMe Status 0x%02x", (msg ? msg : ""), status);
+ char buf[64];
+ return set_err(nvme_status_to_errno(status), "%s%s (0x%03x)", (msg ? msg : ""),
+ nvme_status_to_info_str(buf, status), status);
}
diff -up smartmontools-7.1/nvmecmds.cpp.r5471 smartmontools-7.1/nvmecmds.cpp
--- smartmontools-7.1/nvmecmds.cpp.r5471 2023-11-22 14:07:37.646756079 +0100
+++ smartmontools-7.1/nvmecmds.cpp 2023-11-22 14:07:37.648756102 +0100
@@ -258,3 +258,221 @@ bool nvme_read_smart_log(nvme_device * d
return true;
}
+
+// Return flagged error message for NVMe status SCT/SC fields or nullptr if unknown.
+// If message starts with '-', the status indicates an invalid command (EINVAL).
+static const char * nvme_status_to_flagged_str(uint16_t status)
+{
+ // Section 3.3.3.2.1 of NVM Express Base Specification Revision 2.0c, October 4, 2022
+ uint8_t sc = (uint8_t)status;
+ switch ((status >> 8) & 0x7) {
+ case 0x0: // Generic Command Status
+ if (sc < 0x80) switch (sc) {
+ case 0x00: return "Successful Completion";
+ case 0x01: return "-Invalid Command Opcode";
+ case 0x02: return "-Invalid Field in Command";
+ case 0x03: return "Command ID Conflict";
+ case 0x04: return "Data Transfer Error";
+ case 0x05: return "Commands Aborted due to Power Loss Notification";
+ case 0x06: return "Internal Error";
+ case 0x07: return "Command Abort Requested";
+ case 0x08: return "Command Aborted due to SQ Deletion";
+ case 0x09: return "Command Aborted due to Failed Fused Command";
+ case 0x0a: return "Command Aborted due to Missing Fused Command";
+ case 0x0b: return "-Invalid Namespace or Format";
+ case 0x0c: return "Command Sequence Error";
+ case 0x0d: return "-Invalid SGL Segment Descriptor";
+ case 0x0e: return "-Invalid Number of SGL Descriptors";
+ case 0x0f: return "-Data SGL Length Invalid";
+ case 0x10: return "-Metadata SGL Length Invalid";
+ case 0x11: return "-SGL Descriptor Type Invalid";
+ case 0x12: return "-Invalid Use of Controller Memory Buffer";
+ case 0x13: return "-PRP Offset Invalid";
+ case 0x14: return "Atomic Write Unit Exceeded";
+ case 0x15: return "Operation Denied";
+ case 0x16: return "-SGL Offset Invalid";
+ case 0x18: return "Host Identifier Inconsistent Format";
+ case 0x19: return "Keep Alive Timer Expired";
+ case 0x1a: return "-Keep Alive Timeout Invalid";
+ case 0x1b: return "Command Aborted due to Preempt and Abort";
+ case 0x1c: return "Sanitize Failed";
+ case 0x1d: return "Sanitize In Progress";
+ case 0x1e: return "SGL Data Block Granularity Invalid";
+ case 0x1f: return "Command Not Supported for Queue in CMB";
+ case 0x20: return "Namespace is Write Protected";
+ case 0x21: return "Command Interrupted";
+ case 0x22: return "Transient Transport Error";
+ case 0x23: return "Command Prohibited by Command and Feature Lockdown";
+ case 0x24: return "Admin Command Media Not Ready";
+ // 0x25-0x7f: Reserved
+ }
+ else switch (sc) {
+ // 0x80-0xbf: I/O Command Set Specific
+ case 0x80: return "LBA Out of Range";
+ case 0x81: return "Capacity Exceeded";
+ case 0x82: return "Namespace Not Ready";
+ case 0x83: return "Reservation Conflict";
+ case 0x84: return "Format In Progress";
+ case 0x85: return "-Invalid Value Size";
+ case 0x86: return "-Invalid Key Size";
+ case 0x87: return "KV Key Does Not Exist";
+ case 0x88: return "Unrecovered Error";
+ case 0x89: return "Key Exists";
+ // 0x90-0xbf: Reserved
+ // 0xc0-0xff: Vendor Specific
+ }
+ break;
+
+ case 0x1: // Command Specific Status
+ if (sc < 0x80) switch (sc) {
+ case 0x00: return "-Completion Queue Invalid";
+ case 0x01: return "-Invalid Queue Identifier";
+ case 0x02: return "-Invalid Queue Size";
+ case 0x03: return "Abort Command Limit Exceeded";
+ case 0x04: return "Abort Command Is Missing";
+ case 0x05: return "Asynchronous Event Request Limit Exceeded";
+ case 0x06: return "-Invalid Firmware Slot";
+ case 0x07: return "-Invalid Firmware Image";
+ case 0x08: return "-Invalid Interrupt Vector";
+ case 0x09: return "-Invalid Log Page";
+ case 0x0a: return "-Invalid Format";
+ case 0x0b: return "Firmware Activation Requires Conventional Reset";
+ case 0x0c: return "-Invalid Queue Deletion";
+ case 0x0d: return "Feature Identifier Not Saveable";
+ case 0x0e: return "Feature Not Changeable";
+ case 0x0f: return "Feature Not Namespace Specific";
+ case 0x10: return "Firmware Activation Requires NVM Subsystem Reset";
+ case 0x11: return "Firmware Activation Requires Controller Level Reset";
+ case 0x12: return "Firmware Activation Requires Maximum Time Violation";
+ case 0x13: return "Firmware Activation Prohibited";
+ case 0x14: return "Overlapping Range";
+ case 0x15: return "Namespace Insufficient Capacity";
+ case 0x16: return "-Namespace Identifier Unavailable";
+ case 0x18: return "Namespace Already Attached";
+ case 0x19: return "Namespace Is Private";
+ case 0x1a: return "Namespace Not Attached";
+ case 0x1b: return "Thin Provisioning Not Supported";
+ case 0x1c: return "-Controller List Invalid";
+ case 0x1d: return "Device Self-test In Progress";
+ case 0x1e: return "Boot Partition Write Prohibited";
+ case 0x1f: return "Invalid Controller Identifier";
+ case 0x20: return "-Invalid Secondary Controller State";
+ case 0x21: return "-Invalid Number of Controller Resources";
+ case 0x22: return "-Invalid Resource Identifier";
+ case 0x23: return "Sanitize Prohibited While Persistent Memory Region is Enabled";
+ case 0x24: return "-ANA Group Identifier Invalid";
+ case 0x25: return "ANA Attach Failed";
+ case 0x26: return "Insufficient Capacity";
+ case 0x27: return "Namespace Attachment Limit Exceeded";
+ case 0x28: return "Prohibition of Command Execution Not Supported";
+ case 0x29: return "I/O Command Set Not Supported";
+ case 0x2a: return "I/O Command Set Not Enabled";
+ case 0x2b: return "I/O Command Set Combination Rejected";
+ case 0x2c: return "-Invalid I/O Command Set";
+ case 0x2d: return "-Identifier Unavailable";
+ // 0x2e-0x6f: Reserved
+ // 0x70-0x7f: Directive Specific
+ }
+ else if (sc < 0xb8) switch (sc) {
+ // 0x80-0xbf: I/O Command Set Specific (overlap with Fabrics Command Set)
+ case 0x80: return "-Conflicting Attributes";
+ case 0x81: return "-Invalid Protection Information";
+ case 0x82: return "Attempted Write to Read Only Range";
+ case 0x83: return "Command Size Limit Exceeded";
+ // 0x84-0xb7: Reserved
+ }
+ else switch (sc) {
+ case 0xb8: return "Zoned Boundary Error";
+ case 0xb9: return "Zone Is Full";
+ case 0xba: return "Zone Is Read Only";
+ case 0xbb: return "Zone Is Offline";
+ case 0xbc: return "Zone Invalid Write";
+ case 0xbd: return "Too Many Active Zones";
+ case 0xbe: return "Too Many Open Zones";
+ case 0xbf: return "Invalid Zone State Transition";
+ // 0xc0-0xff: Vendor Specific
+ }
+ break;
+
+ case 0x2: // Media and Data Integrity Errors
+ switch (sc) {
+ // 0x00-0x7f: Reserved
+ case 0x80: return "Write Fault";
+ case 0x81: return "Unrecovered Read Error";
+ case 0x82: return "End-to-end Guard Check Error";
+ case 0x83: return "End-to-end Application Tag Check Error";
+ case 0x84: return "End-to-end Reference Tag Check Error";
+ case 0x85: return "Compare Failure";
+ case 0x86: return "Access Denied";
+ case 0x87: return "Deallocated or Unwritten Logical Block";
+ case 0x88: return "End-to-End Storage Tag Check Error";
+ // 0x89-0xbf: Reserved
+ // 0xc0-0xff: Vendor Specific
+ }
+ break;
+
+ case 0x3: // Path Related Status
+ switch (sc) {
+ case 0x00: return "Internal Path Error";
+ case 0x01: return "Asymmetric Access Persistent Loss";
+ case 0x02: return "Asymmetric Access Inaccessible";
+ case 0x03: return "Asymmetric Access Transition";
+ // 0x04-0x5f: Reserved
+ // 0x60-0x6f: Controller Detected Pathing Errors
+ case 0x60: return "Controller Pathing Error";
+ // 0x61-0x6f: Reserved
+ // 0x70-0x7f: Host Detected Pathing Errors
+ case 0x70: return "Host Pathing Error";
+ case 0x71: return "Command Aborted By Host";
+ // 0x72-0x7f: Reserved
+ // 0x80-0xbf: I/O Command Set Specific
+ // 0xc0-0xff: Vendor Specific
+ }
+ break;
+
+ // 0x4-0x6: Reserved
+ // 0x7: Vendor Specific
+ }
+ return nullptr;
+}
+
+// Return errno for NVMe status SCT/SC fields: 0, EINVAL or EIO.
+int nvme_status_to_errno(uint16_t status)
+{
+ if (!nvme_status_is_error(status))
+ return 0;
+ const char * s = nvme_status_to_flagged_str(status);
+ if (s && *s == '-')
+ return EINVAL;
+ return EIO;
+}
+
+// Return error message for NVMe status SCT/SC fields or nullptr if unknown.
+const char * nvme_status_to_str(uint16_t status)
+{
+ const char * s = nvme_status_to_flagged_str(status);
+ return (s && *s == '-' ? s + 1 : s);
+}
+
+// Return error message for NVMe status SCT/SC fields or explanatory message if unknown.
+const char * nvme_status_to_info_str(char * buf, size_t bufsize, uint16_t status)
+{
+ const char * s = nvme_status_to_str(status);
+ if (s)
+ return s;
+
+ uint8_t sct = (status >> 8) & 0x7, sc = (uint8_t)status;
+ const char * pfx = (sc >= 0xc0 ? "Vendor Specific " : "Unknown ");
+ switch (sct) {
+ case 0x0: s = "Generic Command Status"; break;
+ case 0x1: s = "Command Specific Status"; break;
+ case 0x2: s = "Media and Data Integrity Error"; break;
+ case 0x3: s = "Path Related Status"; break;
+ case 0x7: s = "Vendor Specific Status"; pfx = ""; break;
+ }
+ if (s)
+ snprintf(buf, bufsize, "%s%s 0x%02x", pfx, s, sc);
+ else
+ snprintf(buf, bufsize, "Unknown Status 0x%x/0x%02x", sct, sc);
+ return buf;
+}
diff -up smartmontools-7.1/nvmecmds.h.r5471 smartmontools-7.1/nvmecmds.h
--- smartmontools-7.1/nvmecmds.h.r5471 2023-11-22 14:07:37.646756079 +0100
+++ smartmontools-7.1/nvmecmds.h 2023-11-22 14:09:29.911084240 +0100
@@ -18,6 +18,8 @@
#include "static_assert.h"
+#include <errno.h>
+#include <stddef.h>
#include <stdint.h>
// The code below was originally imported from <linux/nvme.h> include file from
@@ -246,4 +248,22 @@ unsigned nvme_read_error_log(nvme_device
// Read NVMe SMART/Health Information log.
bool nvme_read_smart_log(nvme_device * device, smartmontools::nvme_smart_log & smart_log);
+// Return true if NVMe status indicates an error.
+constexpr bool nvme_status_is_error(uint16_t status)
+ { return !!(status & 0x07ff); }
+
+// Return errno for NVMe status SCT/SC fields: 0, EINVAL or EIO.
+int nvme_status_to_errno(uint16_t status);
+
+// Return error message for NVMe status SCT/SC fields or nullptr if unknown.
+const char * nvme_status_to_str(uint16_t status);
+
+// Return error message for NVMe status SCT/SC fields or explanatory message if unknown.
+const char * nvme_status_to_info_str(char * buf, size_t bufsize, uint16_t status);
+
+// Version of above for fixed size buffers.
+template <size_t SIZE>
+inline const char * nvme_status_to_info_str(char (& buf)[SIZE], unsigned status)
+ { return nvme_status_to_info_str(buf, SIZE, status); }
+
#endif // NVMECMDS_H
diff -up smartmontools-7.1/nvmeprint.cpp.r5471 smartmontools-7.1/nvmeprint.cpp
--- smartmontools-7.1/nvmeprint.cpp.r5471 2023-11-22 14:07:37.648756102 +0100
+++ smartmontools-7.1/nvmeprint.cpp 2023-11-22 14:11:35.899574762 +0100
@@ -420,7 +420,7 @@ static void print_error_log(const nvme_e
continue;
if (cnt == 1)
- pout("Num ErrCount SQId CmdId Status PELoc LBA NSID VS\n");
+ pout("Num ErrCount SQId CmdId Status PELoc LBA NSID VS Message\n");
char sq[16] = "-", cm[16] = "-", st[16] = "-", pe[16] = "-";
char lb[32] = "-", ns[16] = "-", vs[8] = "-";
@@ -439,8 +439,10 @@ static void print_error_log(const nvme_e
if (e.vs != 0x00)
snprintf(vs, sizeof(vs), "0x%02x", e.vs);
- pout("%3u %10" PRIu64 " %5s %7s %7s %6s %12s %5s %5s\n",
- i, e.error_count, sq, cm, st, pe, lb, ns, vs);
+ char buf[64];
+ pout("%3u %10" PRIu64 " %5s %7s %7s %6s %12s %5s %5s %s\n",
+ i, e.error_count, sq, cm, st, pe, lb, ns, vs,
+ nvme_status_to_info_str(buf, e.status_field >> 1));
}
if (!cnt)

View File

@ -0,0 +1,159 @@
diff -U0 smartmontools-7.1/ChangeLog.r5472 smartmontools-7.1/ChangeLog
diff -up smartmontools-7.1/smartd.conf.5.in.r5472 smartmontools-7.1/smartd.conf.5.in
--- smartmontools-7.1/smartd.conf.5.in.r5472 2019-12-13 21:20:45.000000000 +0100
+++ smartmontools-7.1/smartd.conf.5.in 2023-11-22 12:32:37.341051288 +0100
@@ -696,6 +696,20 @@ error log has increased since the last c
.I error
\- [NVMe] report if the "Number of Error Information Log Entries" from the
SMART/Health Information log has increased since the last check.
+.br
+[NEW EXPERIMENTAL SMARTD FEATURE]
+This will only be logged as LOG_CRIT if at least one of the new errors is
+still present in the Error Information log and its status indicates a
+device related error.
+Up to eight of the most recent of these errors are logged as LOG_INFO then.
+This is useful because the NVMe Error Information log is not persistent
+across power cycles or device resets.
+.br
+If all new errors are either no longer present in the log or are not device
+related (e.g. invalid command, invalid field in command, ...), a LOG_INFO
+message is generated instead.
+This avoids misleading warnings if the operating system issues unsupported
+commands and the device firmware also logs these kind of errors.
.Sp
.\" %ENDIF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
.I xerror
diff -up smartmontools-7.1/smartd.cpp.r5472 smartmontools-7.1/smartd.cpp
--- smartmontools-7.1/smartd.cpp.r5472 2019-12-29 14:10:18.000000000 +0100
+++ smartmontools-7.1/smartd.cpp 2023-11-22 12:35:19.254046678 +0100
@@ -2,7 +2,7 @@
* Home page of code is: https://www.smartmontools.org
*
* Copyright (C) 2002-11 Bruce Allen
- * Copyright (C) 2008-19 Christian Franke
+ * Copyright (C) 2008-23 Christian Franke
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* Copyright (C) 2008 Oliver Bock <brevilo@users.sourceforge.net>
*
@@ -410,6 +410,9 @@ struct dev_config
ata_vendor_attr_defs attribute_defs; // -v options
+ // NVMe only
+ unsigned nvme_err_log_max_entries{}; // size of error log
+
dev_config();
};
@@ -2628,6 +2631,74 @@ static int nvme_get_max_temp_kelvin(cons
return k;
}
+// Check the NVMe Error Information log for device related errors.
+static bool check_nvme_error_log(const dev_config & cfg, dev_state & state, nvme_device * nvmedev,
+ uint64_t newcnt = 0)
+{
+ // Limit transfer size to one page (64 entries) to avoid problems with
+ // limits of NVMe pass-through layer or too low MDTS values.
+ unsigned want_entries = 64;
+ if (want_entries > cfg.nvme_err_log_max_entries)
+ want_entries = cfg.nvme_err_log_max_entries;
+ raw_buffer error_log_buf(want_entries * sizeof(nvme_error_log_page));
+ nvme_error_log_page * error_log =
+ reinterpret_cast<nvme_error_log_page *>(error_log_buf.data());
+ unsigned read_entries = nvme_read_error_log(nvmedev, error_log, want_entries, false /*!lpo_sup*/);
+ if (!read_entries) {
+ PrintOut(LOG_INFO, "Device: %s, Read %u entries from Error Information Log failed\n",
+ cfg.name.c_str(), want_entries);
+ return false;
+ }
+
+ if (!newcnt)
+ return true; // Support check only
+
+ // Scan log, find device related errors
+ uint64_t oldcnt = state.nvme_err_log_entries, mincnt = newcnt;
+ int err = 0, ign = 0;
+ for (unsigned i = 0; i < read_entries; i++) {
+ const nvme_error_log_page & e = error_log[i];
+ if (!e.error_count)
+ continue; // unused
+ if (e.error_count <= oldcnt)
+ break; // stop on first old entry
+ if (e.error_count < mincnt)
+ mincnt = e.error_count; // min known error
+ if (e.error_count > newcnt)
+ newcnt = e.error_count; // adjust maximum
+ uint16_t status = e.status_field >> 1;
+ if (!nvme_status_is_error(status) || nvme_status_to_errno(status) == EINVAL) {
+ ign++; // Not a device related error
+ continue;
+ }
+
+ // Log the most recent 8 errors
+ if (++err > 8)
+ continue;
+ char buf[64];
+ PrintOut(LOG_INFO, "Device: %s, NVMe error [%u], count %" PRIu64 ", status 0x%04x: %s\n",
+ cfg.name.c_str(), i, e.error_count, e.status_field,
+ nvme_status_to_info_str(buf, e.status_field >> 1));
+ }
+
+ std::string msg = strprintf("Device: %s, NVMe error count increased from %" PRIu64 " to %" PRIu64
+ " (%d new, %d ignored, %" PRIu64 " unknown)",
+ cfg.name.c_str(), oldcnt, newcnt, err, ign,
+ (mincnt > oldcnt + 1 ? mincnt - oldcnt - 1 : 0));
+ // LOG_CRIT only if device related errors are found
+ if (!err) {
+ PrintOut(LOG_INFO, "%s\n", msg.c_str());
+ }
+ else {
+ PrintOut(LOG_CRIT, "%s\n", msg.c_str());
+ MailWarning(cfg, state, 4, "%s", msg.c_str());
+ }
+
+ state.nvme_err_log_entries = newcnt;
+ state.must_write = true;
+ return true;
+}
+
static int NVMeDeviceScan(dev_config & cfg, dev_state & state, nvme_device * nvmedev,
const dev_config_vector * prev_cfgs)
{
@@ -2687,8 +2758,14 @@ static int NVMeDeviceScan(dev_config & c
}
// Init total error count
+ cfg.nvme_err_log_max_entries = id_ctrl.elpe + 1; // 0's based value
if (cfg.errorlog || cfg.xerrorlog) {
- state.nvme_err_log_entries = le128_to_uint64(smart_log.num_err_log_entries);
+ if (!check_nvme_error_log(cfg, state, nvmedev)) {
+ PrintOut(LOG_INFO, "Device: %s, Error Information unavailable, ignoring -l [x]error\n", name);
+ cfg.errorlog = cfg.xerrorlog = false;
+ }
+ else
+ state.nvme_err_log_entries = le128_to_uint64(smart_log.num_err_log_entries);
}
// If no supported tests selected, return
@@ -3760,16 +3837,12 @@ static int NVMeCheckDevice(const dev_con
// Check if number of errors has increased
if (cfg.errorlog || cfg.xerrorlog) {
- uint64_t oldcnt = state.nvme_err_log_entries;
uint64_t newcnt = le128_to_uint64(smart_log.num_err_log_entries);
- if (newcnt > oldcnt) {
- PrintOut(LOG_CRIT, "Device: %s, number of Error Log entries increased from %" PRIu64 " to %" PRIu64 "\n",
- name, oldcnt, newcnt);
- MailWarning(cfg, state, 4, "Device: %s, number of Error Log entries increased from %" PRIu64 " to %" PRIu64,
- name, oldcnt, newcnt);
- state.must_write = true;
+ if (newcnt > state.nvme_err_log_entries) {
+ // Warn only if device related errors are found
+ check_nvme_error_log(cfg, state, nvmedev, newcnt);
}
- state.nvme_err_log_entries = newcnt;
+ // else // TODO: Handle decrease of count?
}
CloseDevice(nvmedev, name);

View File

@ -1,6 +1,6 @@
# command line options for smartd
# Add -s /var/lib/smartmontools to enable state persistence
smartd_opts="-q never --capabilities"
smartd_opts="-q never"
# autogenerated config file options
# smartd_conf_opts="-H -m root"

View File

@ -1,8 +1,9 @@
Summary: Tools for monitoring SMART capable hard disks
Name: smartmontools
Version: 7.2
Release: 9%{?dist}
Version: 7.1
Release: 3%{?dist}
Epoch: 1
Group: System Environment/Base
License: GPLv2+
URL: http://smartmontools.sourceforge.net/
Source0: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.gz
@ -14,21 +15,25 @@ Source5: drivedb.h
#fedora/rhel specific
Patch1: smartmontools-5.38-defaultconf.patch
Patch2: smartmontools-7.2-capnotify.patch
Patch3: smartmontools-7.2-permsfix.patch
Patch2: smartmontools-7.2-logsuppagefix1.patch
Patch3: smartmontools-7.2-logsuppagefix2.patch
Patch4: smartmontools-7.2-logsuppagefix3.patch
Patch5: smartmontools-7.2-logsuppagefix4.patch
# from upstream, for < 7.4, #RHEL-11400
Patch5: smartmontools-7.2-r5448.patch
# 3x from upstream, for smartmontools <= 7.4, #RHEL-6982
Patch6: smartmontools-7.4-r5121.patch
Patch7: smartmontools-7.4-r5471.patch
Patch8: smartmontools-7.4-r5472.patch
# from upstream, for <= 7.4, #RHEL-15505
Patch6: smartmontools-7.2-fixfdclose.patch
BuildRequires: make
BuildRequires: gcc-c++ readline-devel ncurses-devel automake util-linux groff gettext
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
#new rpm does not handle this (yet?)
#Requires(triggerun): systemd-units
Requires(post): systemd-units
Requires(preun): systemd-units
Requires(postun): systemd-units
BuildRequires: readline-devel ncurses-devel automake util-linux groff gettext
BuildRequires: libselinux-devel libcap-ng-devel
BuildRequires: systemd systemd-devel
%{?systemd_requires}
BuildRequires: systemd-units systemd-devel
%description
The smartmontools package contains two utility programs (smartctl
@ -41,26 +46,31 @@ failure.
%prep
%setup -q
%patch -P 1 -p1 -b .defaultconf
%patch -P 2 -p1 -b .capnotify
%patch -P 3 -p1 -b .permsfix
%patch -P 2 -p2 -b .logsuppagefix1
%patch -P 3 -p2 -b .logsuppagefix2
%patch -P 4 -p2 -b .logsuppagefix3
%patch -P 5 -p1 -b .r5448
%patch -P 6 -p1 -b .fixfdclose
%patch -P 5 -p1 -b .logsuppagefix4
%patch -P 6 -p1 -b .r5121
%patch -P 7 -p1 -b .r5471
%patch -P 8 -p1 -b .r5472
# update SOURCE5 on maintainer's machine prior commiting, there's no internet connection on builders
curl %{UrlSource5} -o %{SOURCE5} ||:
cp %{SOURCE5} .
%build
autoreconf -i
%configure --with-selinux --with-libcap-ng=yes --with-libsystemd --with-systemdsystemunitdir=%{_unitdir} --sysconfdir=%{_sysconfdir}/%{name}/ --with-systemdenvfile=%{_sysconfdir}/sysconfig/%{name}
# update SOURCE5 on maintainer's machine prior commiting, there's no internet connection on builders
%make_build update-smart-drivedb
./update-smart-drivedb -s - -u sf drivedb.h ||:
cp drivedb.h ../drivedb.h ||:
%make_build CXXFLAGS="$RPM_OPT_FLAGS -fpie" LDFLAGS="-pie -Wl,-z,relro,-z,now"
%ifarch sparc64
make CXXFLAGS="$RPM_OPT_FLAGS -fPIE" LDFLAGS="-pie -Wl,-z,relro,-z,now"
%else
make CXXFLAGS="$RPM_OPT_FLAGS -fpie" LDFLAGS="-pie -Wl,-z,relro,-z,now"
%endif
%install
%make_install
rm -rf $RPM_BUILD_ROOT
make DESTDIR=$RPM_BUILD_ROOT install
rm -f examplescripts/Makefile*
chmod a-x -R examplescripts/*
@ -68,12 +78,26 @@ install -D -p -m 644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/smartmon
install -D -p -m 755 %{SOURCE4} $RPM_BUILD_ROOT/%{_libexecdir}/%{name}/smartdnotify
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/%{name}/smartd_warning.d
rm -rf $RPM_BUILD_ROOT/etc/{rc.d,init.d}
rm -rf $RPM_BUILD_ROOT%{_docdir}/%{name}
mkdir -p $RPM_BUILD_ROOT%{_sharedstatedir}/%{name}
rm -rf $RPM_BUILD_ROOT/%{_docdir}/%{name}
mkdir -p $RPM_BUILD_ROOT/%{_sharedstatedir}/%{name}
%clean
rm -rf $RPM_BUILD_ROOT
%preun
%systemd_preun smartd.service
%pre
if [ $1 = 2 ] # only during update
then
# for Fedora 19-22
if [ -f %{_sysconfdir}/smartd.conf -a ! -e %{_sysconfdir}/%name ]
then
mkdir -p %{_sysconfdir}/%{name}
cp -p %{_sysconfdir}/smartd.conf %{_sysconfdir}/%{name}
fi
fi
%post
%systemd_post smartd.service
@ -81,9 +105,9 @@ mkdir -p $RPM_BUILD_ROOT%{_sharedstatedir}/%{name}
%systemd_postun_with_restart smartd.service
%files
%doc AUTHORS ChangeLog INSTALL NEWS README
%defattr(-,root,root,-)
%doc AUTHORS ChangeLog COPYING INSTALL NEWS README
%doc TODO examplescripts smartd.conf
%license COPYING
%dir %{_sysconfdir}/%name
%dir %{_sysconfdir}/%name/smartd_warning.d
%config(noreplace) %{_sysconfdir}/%{name}/smartd.conf
@ -100,75 +124,14 @@ mkdir -p $RPM_BUILD_ROOT%{_sharedstatedir}/%{name}
%{_sharedstatedir}/%{name}
%changelog
* Tue Jan 16 2024 Michal Hlavinka <mhlavink@redhat.com> - 1:7.2-9
- smartd would not start with huge FD limits (#RHEL-15505)
* Wed Nov 22 2023 Michal Hlavinka <mhlavink@redhat.com> - 1:7.1-3
- don't report new non-device related errors as critical (#RHEL-6982)
* Wed Dec 06 2023 Michal Hlavinka <mhlavink@redhat.com> - 1:7.2-8
- fix segfault after read of NVMe error log on big endian (#RHEL-11400)
* Mon May 29 2023 Michal Hlavinka <mhlavink@redhat.com> - 1:7.1-2
- support reporting of Error Counter logging details (#2136439)
* Mon May 29 2023 Michal Hlavinka <mhlavink@redhat.com> - 1:7.2-7
- support reporting of Error Counter logging details (#2137279)
* Wed Nov 03 2021 Michal Hlavinka <mhlavink@redhat.com> - 1:7.2-6
- make notification work with capabilities (#1962593)
* Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com> - 1:7.2-5
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 1:7.2-4
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Wed Jan 27 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1:7.2-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Mon Jan 25 2021 Michal Hlavinka <mhlavink@redhat.com> - 1:7.2-2
- make sure correct version of drivedb.h is used (#1918946)
* Mon Jan 18 2021 Michal Hlavinka <mhlavink@redhat.com> - 1:7.2-1
- smartmontools updated to 7.2
* Mon Jan 18 2021 Michal Hlavinka <mhlavink@redhat.com> - 1:7.1-10
- use capabilites by default
* Wed Jul 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1:7.1-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Thu Jan 30 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1:7.1-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Mon Jan 06 2020 Michal Hlavinka <mhlavink@redhat.com> - 1:7.1-7
- smartmontools updated to 7.1
* Fri Jul 26 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1:7.0-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Fri Apr 12 2019 Daniel Axelrod <daxelrod@datto.com> - 1:7.0-6
- Remove unused patches
- Drop pre script for migrating from unsupported Fedora versions
- Replace sed with configure switch
* Wed Apr 03 2019 Michal Hlavinka <mhlavink@redhat.com> - 1:7.0-5
- revert smartd_warning related changes
* Sat Feb 02 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1:7.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Thu Jan 03 2019 Michal Hlavinka <mhlavink@redhat.com> - 1:7.0-3
- update default config
* Thu Jan 03 2019 Michal Hlavinka <mhlavink@redhat.com> - 1:7.0-2
- use smartd_warning plugin to notify users (bug #1647534)
- spec cleanup
* Thu Jan 03 2019 Michal Hlavinka <mhlavink@redhat.com> - 1:7.0-1
- smartmontools updated to 7.0
* Sat Jul 14 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1:6.6-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Wed Mar 07 2018 Michal Hlavinka <mhlavink@redhat.com> - 1:6.6-4
- add gcc-c++ buildrequire
* Wed Apr 22 2020 Michal Hlavinka <mhlavink@redhat.com> - 1:7.1-1
- smartmontools updated to 7.1 (#1671154)
* Fri Feb 09 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1:6.6-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild

View File

@ -1,7 +0,0 @@
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional}

View File

@ -1,32 +0,0 @@
diff -up smartmontools-7.2/smartd.cpp.capnotify smartmontools-7.2/smartd.cpp
--- smartmontools-7.2/smartd.cpp.capnotify 2020-11-23 19:25:16.000000000 +0100
+++ smartmontools-7.2/smartd.cpp 2021-06-16 12:06:03.985526022 +0200
@@ -1020,6 +1020,8 @@ static void capabilities_drop_now()
capng_clear(CAPNG_SELECT_BOTH);
capng_updatev(CAPNG_ADD, (capng_type_t)(CAPNG_EFFECTIVE|CAPNG_PERMITTED),
CAP_SYS_ADMIN, CAP_MKNOD, CAP_SYS_RAWIO, -1);
+ capng_updatev(CAPNG_ADD, (capng_type_t)(CAPNG_BOUNDING_SET),
+ CAP_SETGID, CAP_SETUID, CAP_CHOWN, CAP_FOWNER, CAP_DAC_OVERRIDE, -1);
capng_apply(CAPNG_SELECT_BOTH);
}
@@ -1030,9 +1032,8 @@ static void capabilities_check_config(de
for (unsigned i = 0; i < configs.size(); i++) {
dev_config & cfg = configs[i];
if (!cfg.emailaddress.empty() || !cfg.emailcmdline.empty()) {
- PrintOut(LOG_INFO, "Device: %s, --capabilites is set, mail will be suppressed.\n",
+ PrintOut(LOG_INFO, "Device: %s, --capabilites is set, mail notification may not work.\n",
cfg.name.c_str());
- cfg.emailaddress.clear(); cfg.emailcmdline.clear();
}
}
}
@@ -1633,7 +1634,7 @@ static void Usage()
#ifdef HAVE_LIBCAP_NG
PrintOut(LOG_INFO," -C, --capabilities\n");
PrintOut(LOG_INFO," Drop unneeded Linux process capabilities.\n"
- " Warning: Mail notification does not work when used.\n\n");
+ " Warning: Mail notification may not work when used.\n\n");
#endif
PrintOut(LOG_INFO," -d, --debug\n");
PrintOut(LOG_INFO," Start smartd in debug mode\n\n");

View File

@ -1,42 +0,0 @@
diff -up smartmontools-7.2/configure.ac.fixfdclose smartmontools-7.2/configure.ac
--- smartmontools-7.2/configure.ac.fixfdclose 2024-01-10 16:45:10.994784319 +0100
+++ smartmontools-7.2/configure.ac 2024-01-10 16:47:27.985999103 +0100
@@ -121,6 +121,16 @@ AM_CONDITIONAL(NEED_GETOPT_LONG, [test "
AC_CHECK_FUNCS([clock_gettime ftime gettimeofday])
+case "$host_os" in
+ mingw*)
+ # Older MinGW-w64 (5.0.3) require -lwinpthread
+ AC_SEARCH_LIBS([clock_gettime], [winpthread])
+ ;;
+ *)
+ AC_CHECK_FUNCS([close_range])
+ ;;
+esac
+
# Check byte ordering (defines WORDS_BIGENDIAN)
AC_C_BIGENDIAN
diff -up smartmontools-7.2/smartd.cpp.fixfdclose smartmontools-7.2/smartd.cpp
--- smartmontools-7.2/smartd.cpp.fixfdclose 2024-01-10 16:45:10.996784336 +0100
+++ smartmontools-7.2/smartd.cpp 2024-01-10 16:46:33.786518090 +0100
@@ -1475,8 +1475,16 @@ static int daemon_init()
}
// close any open file descriptors
- for (int i = getdtablesize(); --i >= 0; )
- close(i);
+ int open_max = sysconf(_SC_OPEN_MAX);
+#ifdef HAVE_CLOSE_RANGE
+ if (close_range(0, open_max - 1, 0))
+#endif
+ {
+ // Limit number of close() calls under the assumption that there
+ // are no large gaps between open FDs
+ for (int i = 0, failed = 0; i < open_max && failed < 1024; i++)
+ failed = (!close(i) ? 0 : failed + 1);
+ }
// redirect any IO attempts to /dev/null and change to root directory
int fd = open("/dev/null", O_RDWR);

View File

@ -1,38 +0,0 @@
diff -up smartmontools-7.2/os_linux.cpp.permsfix smartmontools-7.2/os_linux.cpp
--- smartmontools-7.2/os_linux.cpp.permsfix 2021-11-02 22:08:51.956425716 +0100
+++ smartmontools-7.2/os_linux.cpp 2021-11-02 22:09:55.928583584 +0100
@@ -1022,7 +1022,7 @@ bool linux_aacraid_device::open()
return set_err(ENOENT, "aac entry not found in /proc/devices");
//Create misc device file in /dev/ used for communication with driver
- if(mknod(dev_name,S_IFCHR,makedev(mjr,aHost)))
+ if(mknod(dev_name,S_IFCHR|0600,makedev(mjr,aHost)))
return set_err(errno,"cannot create %s:%s",dev_name,strerror(errno));
afd = ::open(dev_name,O_RDWR);
@@ -1298,14 +1298,14 @@ bool linux_megaraid_device::open()
while (fgets(line, sizeof(line), fp) != NULL) {
int n1 = 0;
if (sscanf(line, "%d megaraid_sas_ioctl%n", &mjr, &n1) == 1 && n1 == 22) {
- n1=mknod("/dev/megaraid_sas_ioctl_node", S_IFCHR, makedev(mjr, 0));
+ n1=mknod("/dev/megaraid_sas_ioctl_node", S_IFCHR|0600, makedev(mjr, 0));
if(report > 0)
pout("Creating /dev/megaraid_sas_ioctl_node = %d\n", n1 >= 0 ? 0 : errno);
if (n1 >= 0 || errno == EEXIST)
break;
}
else if (sscanf(line, "%d megadev%n", &mjr, &n1) == 1 && n1 == 11) {
- n1=mknod("/dev/megadev0", S_IFCHR, makedev(mjr, 0));
+ n1=mknod("/dev/megadev0", S_IFCHR|0600, makedev(mjr, 0));
if(report > 0)
pout("Creating /dev/megadev0 = %d\n", n1 >= 0 ? 0 : errno);
if (n1 >= 0 || errno == EEXIST)
@@ -2970,7 +2970,7 @@ bool linux_smart_interface::get_dev_mega
n1=0;
if (sscanf(line, "%d megaraid_sas_ioctl%n", &mjr, &n1) == 1 && n1 == 22) {
scan_megasas = true;
- n1=mknod("/dev/megaraid_sas_ioctl_node", S_IFCHR, makedev(mjr, 0));
+ n1=mknod("/dev/megaraid_sas_ioctl_node", S_IFCHR|0600, makedev(mjr, 0));
if(scsi_debugmode > 0)
pout("Creating /dev/megaraid_sas_ioctl_node = %d\n", n1 >= 0 ? 0 : errno);
if (n1 >= 0 || errno == EEXIST)

View File

@ -1,24 +0,0 @@
diff -U0 smartmontools-7.2/ChangeLog.r5448 smartmontools-7.2/ChangeLog
diff -up smartmontools-7.2/nvmecmds.cpp.r5448 smartmontools-7.2/nvmecmds.cpp
--- smartmontools-7.2/nvmecmds.cpp.r5448 2020-12-04 21:40:43.000000000 +0100
+++ smartmontools-7.2/nvmecmds.cpp 2023-09-20 12:33:35.212784397 +0200
@@ -230,8 +230,9 @@ unsigned nvme_read_error_log(nvme_device
unsigned n = nvme_read_log_page(device, 0xffffffff, 0x01, error_log,
num_entries * sizeof(*error_log), lpo_sup);
+ unsigned read_entries = n / sizeof(*error_log);
if (isbigendian()) {
- for (unsigned i = 0; i < n; i++) {
+ for (unsigned i = 0; i < read_entries; i++) {
swapx(&error_log[i].error_count);
swapx(&error_log[i].sqid);
swapx(&error_log[i].cmdid);
@@ -242,7 +243,7 @@ unsigned nvme_read_error_log(nvme_device
}
}
- return n / sizeof(*error_log);
+ return read_entries;
}
// Read NVMe SMART/Health Information log.

View File

@ -1 +0,0 @@
SHA512 (smartmontools-7.2.tar.gz) = d7e724295b5d53797b5e4136eea5f5cc278db81e4016ba65142438b8c68c54f85a32c582c147a1590b9bc8f74a58952bcb57b9923dd69d34582530a0985799ea