libnvme(2)

πŸ’– NAME πŸ’–

struct nvme_smart_log β€” the SMART / Health Information Log (Log Identifier 02h), aka the glow-up report card for your NVMe drive, bestie πŸ’…

This is a page from the libnvme API manual, and we're about to read your SSD's diary fr fr πŸ“–βœ¨


🌸 SYNOPSIS 🌸

struct nvme_smart_log {
    __u8 critical_warning;
    __u8 temperature[2];
    __u8 avail_spare;
    __u8 spare_thresh;
    __u8 percent_used;
    __u8 endu_grp_crit_warn_sumry;
    __u8 rsvd7[25];
    __u8 data_units_read[16];
    __u8 data_units_written[16];
    __u8 host_reads[16];
    __u8 host_writes[16];
    __u8 ctrl_busy_time[16];
    __u8 power_cycles[16];
    __u8 power_on_hours[16];
    __u8 unsafe_shutdowns[16];
    __u8 media_errors[16];
    __u8 num_err_log_entries[16];
    __le32 warning_temp_time;
    __le32 critical_comp_time;
    __le16 temp_sensor[8];
    __le32 thm_temp1_trans_count;
    __le32 thm_temp2_trans_count;
    __le32 thm_temp1_total_time;
    __le32 thm_temp2_total_time;
    __u8 rsvd232[280];
};

✨ Members ✨

okay so, member by member, no skipping, we're eating the whole plate πŸ“

  • critical_warning β€” 🚨 this one is the drama flag. It tells you about critical warnings for the state of the controller, and bestie, those can trigger an asynchronous event notification to the host. The bits here describe the current associated state β€” they are not persistent, so don't go treating them like a saved status, they're giving live-update energy (see enum nvme_smart_crit).
  • temperature β€” Composite Temperature πŸ”₯ holds a value corresponding to a temperature in Kelvins, and it represents the current composite temperature of the controller plus the namespace(s) associated with that controller. The way this number gets computed is implementation specific, and it may not represent the actual temperature of any physical point in the NVM subsystem. The warning and critical overheating composite temperature thresholds? Those get reported by the WCTEMP and CCTEMP fields in the Identify Controller data structure. so like… vibe check, not a thermometer probe 🫢
  • avail_spare β€” Available Spare: a normalized percentage (0% to 100%) of the remaining spare capacity you still have available. it's your little emergency reserve, protect it πŸŽ€
  • spare_thresh β€” Available Spare Threshold: when the Available Spare drops below the threshold in this field, an asynchronous event completion may occur. The value is a normalized percentage (0% to 100%). The values 101 to 255 are reserved. so don't be out here writing 200, it means nothing πŸ’€
  • percent_used β€” Percentage Used: a vendor specific estimate of the percentage of NVM subsystem life used, based on actual usage plus the manufacturer's prediction of NVM life. A value of 100 means the estimated endurance of the NVM in the NVM subsystem has been consumed β€” but heads up, it may not indicate an NVM subsystem failure. The value is allowed to exceed 100. Percentages greater than 254 shall be represented as 255. This value shall be updated once per power-on hour (when the controller is not in a sleep state). iconically still going after 100 like a true main character πŸ‘‘
  • endu_grp_crit_warn_sumry β€” Endurance Group Critical Warning Summary: critical warnings for the state of Endurance Groups. The bits in this field represent the current associated state and are not persistent (see enum nvme_smart_egcw). same non-persistent vibe as critical_warning, they're twins fr πŸ’œ
  • rsvd7 β€” Reserved πŸ›Œ
  • data_units_read β€” πŸ“₯ Data Units Read: the number of 512 byte data units the host has read from the controller β€” and nope, this value does not include metadata. It's reported in thousands (so a value of 1 corresponds to 1000 units of 512 bytes read) and it's rounded up (e.g., one indicates that the number of 512 byte data units read is from 1 to 1000, three indicates that the number of 512 byte data units read is from 2001 to 3000). When the LBA size is a value other than 512 bytes, the controller shall convert the amount of data read to 512 byte units. For the NVM command set, logical blocks read as part of Compare, Read, and Verify operations shall be included in this value. A value of 0h in this field indicates that the number of Data Units Read is not reported. it's giving ✨approximate✨
  • data_units_written β€” πŸ“€ Data Units Written: the number of 512 byte data units the host has written to the controller; again, this value does not include metadata. Reported in thousands (a value of 1 corresponds to 1000 units of 512 bytes written) and rounded up (e.g., one indicates that the number of 512 byte data units written is from 1 to 1,000, three indicates that the number of 512 byte data units written is from 2001 to 3000). When the LBA size is a value other than 512 bytes, the controller shall convert the amount of data written to 512 byte units. For the NVM command set, logical blocks written as part of Write operations shall be included in this value. Write Uncorrectable commands and Write Zeroes commands shall not impact this value. A value of 0h in this field indicates that the number of Data Units Written is not reported.
  • host_reads β€” Host Read Commands: the number of read commands completed by the controller. For the NVM command set, this value is the sum of the number of Compare commands and the number of Read commands. two for one, we love a bundle πŸŽ€
  • host_writes β€” Host Write Commands: the number of write commands completed by the controller. For the NVM command set, this is the number of Write commands.
  • ctrl_busy_time β€” ⏳ Controller Busy Time: how much time the controller spent busy with I/O commands. The controller counts as busy when there is a command outstanding to an I/O Queue β€” specifically, a command was issued via an I/O Submission Queue Tail doorbell write and the corresponding completion queue entry has not been posted yet to the associated I/O Completion Queue. This value is reported in minutes. busy era, we've all been there 😭
  • power_cycles β€” Power Cycles: the number of power cycles πŸ”Œ
  • power_on_hours β€” Power On Hours: the number of power-on hours. This may not include time that the controller was powered and in a non-operational power state β€” so it's not the full story, ngl.
  • unsafe_shutdowns β€” πŸ’€ Unsafe Shutdowns: the number of unsafe shutdowns. This count gets incremented when a Shutdown Notification (CC.SHN) is not received prior to loss of power. if you yanked the cable, the drive remembers. it always remembers πŸ™ˆ
  • media_errors β€” Media and Data Integrity Errors: the number of occurrences where the controller detected an unrecovered data integrity error. Errors such as uncorrectable ECC, CRC checksum failure, or LBA tag mismatch are included in this field. Errors introduced as a result of a Write Uncorrectable command may or may not be included in this field. so it's a maybe, we're being honest about the maybe πŸ”₯
  • num_err_log_entries β€” Number of Error Information Log Entries: the number of Error Information log entries over the life of the controller. the full receipts, all of them πŸ“‹
  • warning_temp_time β€” 🌑️ <orange>Warning Composite Temperature Time</orange>: the amount of time in minutes that the controller is operational and the Composite Temperature is greater than or equal to the Warning Composite Temperature Threshold (WCTEMP) field and less than the Critical Composite Temperature Threshold (CCTEMP) field in the Identify Controller data structure. Warning: if the value of the WCTEMP or CCTEMP field is 0h, then this field is always cleared to 0h regardless of the Composite Temperature value. yup, even if your drive is literally melting, 0h it is 🧊
  • critical_comp_time β€” πŸ”₯ Critical Composite Temperature Time: the amount of time in minutes that the controller is operational and the Composite Temperature is greater than or equal to the Critical Composite Temperature Threshold (CCTEMP) field in the Identify Controller data structure. Warning: if the value of the CCTEMP field is 0h, then this field is always cleared to 0h regardless of the Composite Temperature value.
  • temp_sensor β€” Temperature Sensor 1-8: the current temperature in degrees Kelvin reported by temperature sensors 1-8. The physical point in the NVM subsystem whose temperature is reported by the temperature sensor, and the temperature accuracy, are both implementation specific. An implementation that does not implement the temperature sensor reports a value of 0h. eight little sensors, eight little moods 🌈
  • thm_temp1_trans_count β€” Thermal Management Temperature 1 Transition Count: the number of times the controller transitioned to lower power active power states or performed vendor specific thermal management actions while minimizing the impact on performance, in order to attempt to reduce the Composite Temperature β€” this happens because of the host controlled thermal management feature (i.e., the Composite Temperature rose above the Thermal Management Temperature 1). This counter shall not wrap once the value FFFFFFFFh is reached. A value of 0h indicates that this transition has never occurred or that this field is not implemented. capped and never looping, periodt βœ‹
  • thm_temp2_trans_count β€” Thermal Management Temperature 2 Transition Count (that's the whole description, bestie, it's a short one 😌)
  • thm_temp1_total_time β€” Total Time For Thermal Management Temperature 1: the number of seconds that the controller had transitioned to lower power active power states or performed vendor specific thermal management actions while minimizing the impact on performance, in order to attempt to reduce the Composite Temperature β€” because of the host controlled thermal management feature. This counter shall not wrap once the value FFFFFFFFh is reached. A value of 0h indicates that this transition has never occurred or that this field is not implemented.
  • thm_temp2_total_time β€” Total Time For Thermal Management Temperature 2 (yeah, same deal, that's all she wrote πŸ’…)
  • rsvd232 β€” Reserved πŸ›Œ

ok bestie real talk: this whole struct is a log, so like β€” read it, admire it, but don't go assuming those non-persistent warning bits stick around between reads. they're current-state only, no cap 🫢

and that's the whole page, we ate and left no crumbs πŸ’–βœ¨

this slice of the libnvme API manual (covering struct nvme_smart_log, the SMART / Health Information Log with Log Identifier 02h) is dated July 2026, so live laugh log πŸŽ€ ily, go check your drive's temperature, drink some water, bye πŸ‘‘

πŸ“¦ where this page comes from