Print drive database version in smartctl and smartd.

knowndrives.cpp, knowndrives.h: Parse VERSION string.
ataprint.cpp: Print version.  Remove '-P showall' help string.
smartd.cpp: Print version.

git-svn-id: http://svn.code.sf.net/p/smartmontools/code/trunk@5207 4ea69e1a-61f1-4043-bf83-b5c94c648137
pull/91/head
chrfranke 2 years ago
parent f2e3d7126e
commit 6cc32bf1fb
  1. 7
      smartmontools/ChangeLog
  2. 18
      smartmontools/ataprint.cpp
  3. 45
      smartmontools/knowndrives.cpp
  4. 6
      smartmontools/knowndrives.h
  5. 13
      smartmontools/smartd.cpp

@ -1,5 +1,12 @@
$Id$
2021-02-09 Christian Franke <franke@computer.org>
Print drive database version in smartctl and smartd.
knowndrives.cpp, knowndrives.h: Parse VERSION string.
ataprint.cpp: Print version. Remove '-P showall' help string.
smartd.cpp: Print version.
2021-02-07 Christian Franke <franke@computer.org>
Makefile.am: 'check' target now also checks the built-in database.

@ -620,7 +620,7 @@ static void print_sata_version_and_speed(unsigned short word222,
static void print_drive_info(const ata_identify_device * drive,
const ata_size_info & sizes, int rpm,
const drive_settings * dbentry)
const drive_settings * dbentry, const char * dbversion)
{
// format drive information (with byte swapping as needed)
char model[40+1], serial[20+1], firmware[8+1];
@ -739,9 +739,9 @@ static void print_drive_info(const ata_identify_device * drive,
}
// See if drive is recognized
jout("Device is: %s\n", !dbentry ?
"Not in smartctl database [for details use: -P showall]":
"In smartctl database [for details use: -P show]");
jout("Device is: %s%s%s\n",
(dbentry ? "In smartctl database" : "Not in smartctl database"),
(*dbversion ? " " : ""), (*dbversion ? dbversion : ""));
jglb["in_smartctl_database"] = !!dbentry;
// Print ATA version
@ -3468,10 +3468,14 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
// Use preset vendor attribute options unless user has requested otherwise.
ata_vendor_attr_defs attribute_defs = options.attribute_defs;
firmwarebug_defs firmwarebugs = options.firmwarebugs;
std::string dbversion;
const drive_settings * dbentry = 0;
if (!options.ignore_presets)
if (!options.ignore_presets) {
dbentry = lookup_drive_apply_presets(&drive, attribute_defs,
firmwarebugs);
firmwarebugs, dbversion);
if (!dbversion.empty())
jglb["smartctl"]["drive_database_version"]["string"] = dbversion;
}
// Get capacity, sector sizes and rotation rate
ata_size_info sizes;
@ -3488,7 +3492,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
// Print most drive identity information if requested
if (options.drive_info) {
pout("=== START OF INFORMATION SECTION ===\n");
print_drive_info(&drive, sizes, rpm, dbentry);
print_drive_info(&drive, sizes, rpm, dbentry, dbversion.c_str());
}
// Check and print SMART support and state

@ -1,10 +1,10 @@
/*
* knowndrives.cpp
*
* Home page of code is: http://www.smartmontools.org
* Home page of code is: https://www.smartmontools.org
*
* Copyright (C) 2003-11 Philip Williams, Bruce Allen
* Copyright (C) 2008-18 Christian Franke
* Copyright (C) 2008-21 Christian Franke
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
@ -135,6 +135,7 @@ static drive_database knowndrives;
enum dbentry_type {
DBENTRY_VERSION,
DBENTRY_ATA_DEFAULT,
DBENTRY_ATA,
DBENTRY_USB
@ -143,9 +144,11 @@ enum dbentry_type {
// Return type of entry
static dbentry_type get_modelfamily_type(const char * modelfamily)
{
if (modelfamily[0] == 'D' && !strcmp(modelfamily, "DEFAULT"))
if (modelfamily[0] == 'V' && str_starts_with(modelfamily, "VERSION:"))
return DBENTRY_VERSION;
else if (modelfamily[0] == 'D' && !strcmp(modelfamily, "DEFAULT"))
return DBENTRY_ATA_DEFAULT;
else if(modelfamily[0] == 'U' && str_starts_with(modelfamily, "USB:"))
else if (modelfamily[0] == 'U' && str_starts_with(modelfamily, "USB:"))
return DBENTRY_USB;
else
return DBENTRY_ATA;
@ -156,6 +159,23 @@ static inline dbentry_type get_dbentry_type(const drive_settings * dbentry)
return get_modelfamily_type(dbentry->modelfamily);
}
// Extract "BRANCH/REV" from "VERSION: ..." string.
static void parse_version(std::string & dbversion, const char * verstr)
{
static const regular_expression regex(
"^VERSION: ([0-9]+\\.[0-9]+)(/([0-9]+) | \\$[^0-9]* ([0-9]+) )"
// (1 )( (3 ) (4 ) )
);
const int nmatch = 1+4;
regular_expression::match_range match[nmatch];
if (!regex.execute(verstr, nmatch, match))
return;
dbversion.assign(verstr + match[1].rm_so, match[1].rm_eo - match[1].rm_so);
int i = (match[3].rm_so >= 0 ? 3 : 4); // "BRANCH/REV" or "BRANCH ... SVN-REV"
dbversion += '/';
dbversion.append(verstr + match[i].rm_so, match[i].rm_eo - match[i].rm_so);
}
// Compile regular expression, print message on failure.
static bool compile(regular_expression & regex, const char *pattern)
{
@ -181,7 +201,8 @@ static bool match(const char * pattern, const char * str)
// string. If either the drive's model or firmware strings are not set by the
// manufacturer then values of NULL may be used. Returns the entry of the
// first match in knowndrives[] or 0 if no match if found.
static const drive_settings * lookup_drive(const char * model, const char * firmware)
static const drive_settings * lookup_drive(const char * model, const char * firmware,
std::string * dbversion = nullptr)
{
if (!model)
model = "";
@ -189,8 +210,16 @@ static const drive_settings * lookup_drive(const char * model, const char * firm
firmware = "";
for (unsigned i = 0; i < knowndrives.size(); i++) {
dbentry_type t = get_dbentry_type(&knowndrives[i]);
// Get version if requested
if (t == DBENTRY_VERSION) {
if (dbversion)
parse_version(*dbversion, knowndrives[i].modelfamily);
continue;
}
// Skip DEFAULT and USB entries
if (get_dbentry_type(&knowndrives[i]) != DBENTRY_ATA)
if (t != DBENTRY_ATA)
continue;
// Check whether model matches the regular expression in knowndrives[i].
@ -554,7 +583,7 @@ void show_presets(const ata_identify_device * drive)
// Returns pointer to database entry or nullptr if none found
const drive_settings * lookup_drive_apply_presets(
const ata_identify_device * drive, ata_vendor_attr_defs & defs,
firmwarebug_defs & firmwarebugs)
firmwarebug_defs & firmwarebugs, std::string & dbversion)
{
// get the drive's model/firmware strings
char model[MODEL_STRING_LENGTH+1], firmware[FIRMWARE_STRING_LENGTH+1];
@ -562,7 +591,7 @@ const drive_settings * lookup_drive_apply_presets(
ata_format_id_string(firmware, drive->fw_rev, sizeof(firmware)-1);
// Look up the drive in knowndrives[].
const drive_settings * dbentry = lookup_drive(model, firmware);
const drive_settings * dbentry = lookup_drive(model, firmware, &dbversion);
if (!dbentry)
return 0;

@ -1,10 +1,10 @@
/*
* knowndrives.h
*
* Home page of code is: http://www.smartmontools.org
* Home page of code is: https://www.smartmontools.org
*
* Copyright (C) 2003-11 Philip Williams, Bruce Allen
* Copyright (C) 2008-15 Christian Franke
* Copyright (C) 2008-21 Christian Franke
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
@ -52,7 +52,7 @@ int showmatchingpresets(const char *model, const char *firmware);
// Returns pointer to database entry or nullptr if none found.
const drive_settings * lookup_drive_apply_presets(
const ata_identify_device * drive, ata_vendor_attr_defs & defs,
firmwarebug_defs & firmwarebugs);
firmwarebug_defs & firmwarebugs, std::string & dbversion);
// Get path for additional database file
const char * get_drivedb_path_add();

@ -2,7 +2,7 @@
* Home page of code is: https://www.smartmontools.org
*
* Copyright (C) 2002-11 Bruce Allen
* Copyright (C) 2008-20 Christian Franke
* Copyright (C) 2008-21 Christian Franke
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* Copyright (C) 2008 Oliver Bock <brevilo@users.sourceforge.net>
*
@ -1977,13 +1977,16 @@ static int ATADeviceScan(dev_config & cfg, dev_state & state, ata_device * atade
PrintOut(LOG_INFO, "Device: %s, smartd database not searched (Directive: -P ignore).\n", name);
else {
// Apply vendor specific presets, print warning if present
std::string dbversion;
const drive_settings * dbentry = lookup_drive_apply_presets(
&drive, cfg.attribute_defs, cfg.firmwarebugs);
&drive, cfg.attribute_defs, cfg.firmwarebugs, dbversion);
if (!dbentry)
PrintOut(LOG_INFO, "Device: %s, not found in smartd database.\n", name);
PrintOut(LOG_INFO, "Device: %s, not found in smartd database%s%s.\n", name,
(!dbversion.empty() ? " " : ""), (!dbversion.empty() ? dbversion.c_str() : ""));
else {
PrintOut(LOG_INFO, "Device: %s, found in smartd database%s%s\n",
name, (*dbentry->modelfamily ? ": " : "."), (*dbentry->modelfamily ? dbentry->modelfamily : ""));
PrintOut(LOG_INFO, "Device: %s, found in smartd database%s%s%s%s\n",
name, (!dbversion.empty() ? " " : ""), (!dbversion.empty() ? dbversion.c_str() : ""),
(*dbentry->modelfamily ? ": " : "."), (*dbentry->modelfamily ? dbentry->modelfamily : ""));
if (*dbentry->warningmsg)
PrintOut(LOG_CRIT, "Device: %s, WARNING: %s\n", name, dbentry->warningmsg);
}

Loading…
Cancel
Save