Switch to using udevadm info to query drive serial numbers (#263)
A user reported that GParted was displaying binary data for the serial
number of their USB key. This was because hdparm -I was reporting
binary data for the serial number. It looked like this (except the
question marks were binary non-printable bytes).
$ LANG=C sudo hdparm -I /dev/sdh
/dev/sdh:
ATA device, with non-removable media
Model Number: ?|??t??L??|??
Serial Number: ?@>??8
u
Firmware Revision: u???
Standards:
Likely used: 1
...
Back in 2015 when reporting of drive serial numbers was being added
[1][2], using hdparm -I was the best option because it reported the
serial number of all hard drives including those in virtual machines,
worked the same everywhere and was available by default in most
distributions, but didn't work for USB keys. Where as lsblk -o SERIAL
was a new option not available yet on some distributions and didn't
report the serial number of drives in virtual machines.
Now hdparm -I capabilities are still the same; only working for hard
drives, including SSDs, but not USB keys. Except for the above case
hdparm has always found to not report serial numbers for USB keys, like
this:
# hdparm -I /dev/sde
/dev/sde:
SG_IO: bad/missing sense data, sb[]: 70 00 05 00 00 00 00 15 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00
ATA device, with non-removable media
Standards:
Likely used: 1
....
Now the lsblk -o SERIAL option is available on all distributions and
reports the serial numbers of all drives including for virtual machine
disks and USB keys.
From an older but still supported Ubuntu 20.04 LTS virtual machine:
# lsblk -o KNAME,VENDOR,MODEL,SERIAL,TYPE,TRAN -d
KNAME VENDOR MODEL SERIAL TYPE TRAN
sda ATA VBOX HARDDISK VB13d4e080-b35e62d3 disk sata
sdb ATA VBOX HARDDISK VB221202cf-092e5857 disk sata
sdc ATA VBOX HARDDISK VB04fefadd-5a185f96 disk sata
sr0 VBOX CD-ROM VB2-01700376 rom ata
From a physical machine running older but still supported Rocky Linux 8
with 2 SSDs, 2 HDDs, and 6 USB keys:
# lsblk -o KNAME,VENDOR,MODEL,SERIAL,TYPE,TRAN -d
KNAME VENDOR MODEL SERIAL TYPE TRAN
sda ATA Samsung SSD 860 S3Z9NY0M620872V disk sata
sdb ATA SAMSUNG SSD UM41 DCF4300940SE940B4507 disk sata
sdc ATA WDC WD10JFCX-68N WD-WXE1EB6C3MHY disk sata
sdd ATA MM0500EBKAE 9XF132MW disk sata
sde SanDisk U3 Cruzer Micro 00001853E473AABA disk usb
sdf Kingston DataTraveler 3.0 408D5C1658F7E31079051DB9 disk usb
sdg Kingston DataTraveler 2.0 1C6F654FF40FBE50D9341059 disk usb
sdh Patriot Memory 07082AA3E0944E31 disk usb
sdi Corsair Slider 3.0 12240400400016361397 disk usb
sdj SMI USB DISK SMI_USB_DISK-0:0 disk usb
sr0 ASUS DRW-24B3LT B5D0CL213444 rom sata
sr1 SanDisk U3 Cruzer Micro 00001853E473AABA rom usb
lsblk gets it's information from udev. lsblk reports the SERIAL column
from the udev device property ID_SERIAL_SHORT, except when that is blank
it uses the ID_SERIAL property instead [3]. Note that ID_SERIAL is
composed from vendor and model information [4].
USB key with a serial number:
# udevadm info --query=property --name=/dev/sde | grep SERIAL
ID_SERIAL=SanDisk_U3_Cruzer_Micro_00001853E473AABA-0:0
ID_SERIAL_SHORT=00001853E473AABA
# lsblk -o KNAME,VENDOR,MODEL,SERIAL,TYPE,TRAN -d /dev/sde
KNAME VENDOR MODEL SERIAL TYPE TRAN
sde SanDisk U3 Cruzer Micro 00001853E473AABA disk usb
USB key without a serial number:
# udevadm info --query=property --name=/dev/sdj | grep SERIAL
ID_SERIAL=SMI_USB_DISK-0:0
# lsblk -o KNAME,VENDOR,MODEL,SERIAL,TYPE,TRAN -d /dev/sdj
KNAME VENDOR MODEL SERIAL TYPE TRAN
sdj SMI USB DISK SMI_USB_DISK-0:0 disk usb
To only get the device serial number, or blank when not available, query
the udev ID_SERIAL_SHORT property directly using udevadm info rather
than using lsblk -o SERIAL. Previously GParted displayed "none" if
hdparm -I successfully found nothing, including for USB keys, and left
the serial number field blank on failure. Now the field will be blank
in both cases, no serial number and failure to query it.
[1] 4b72ecd44e
Display device serial numbers (#751251)
[2] Bug 751251 - Show serial number in device information
https://bugzilla.gnome.org/show_bug.cgi?id=751251
[3] misc-utils/lsblk-properties.c:get_properties_by_udev()
https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/tree/misc-utils/lsblk-properties.c?h=v2.40.2#n121
[4] what is the difference between ID_SERIAL and ID_SERIAL_SHORT udev
attributes for a USB descriptor
https://stackoverflow.com/questions/45940014/what-is-the-difference-between-id-serial-and-id-serial-short-udev-attributes-for
"The ID_SERIAL_SHORT value comes from the iSerial string (if
present) in the USB device descriptor. The ID_SERIAL value is
constructed in software and made up from various strings (vendor
or manufacturer, model or product, and serial number if present)
separated with _.
"
Closes #263 - Serial number for my USB key showing binary data
This commit is contained in:
parent
188ffcc06b
commit
a0f5b02f59
|
@ -63,7 +63,6 @@ const std::time_t SETTLE_DEVICE_PROBE_MAX_WAIT_SECONDS = 1;
|
||||||
const std::time_t SETTLE_DEVICE_APPLY_MAX_WAIT_SECONDS = 10;
|
const std::time_t SETTLE_DEVICE_APPLY_MAX_WAIT_SECONDS = 10;
|
||||||
|
|
||||||
static bool udevadm_found = false;
|
static bool udevadm_found = false;
|
||||||
static bool hdparm_found = false;
|
|
||||||
|
|
||||||
static const Glib::ustring GPARTED_BUG( _("GParted Bug") );
|
static const Glib::ustring GPARTED_BUG( _("GParted Bug") );
|
||||||
|
|
||||||
|
@ -115,7 +114,6 @@ Glib::ustring GParted_Core::get_version_and_config_string()
|
||||||
void GParted_Core::find_supported_core()
|
void GParted_Core::find_supported_core()
|
||||||
{
|
{
|
||||||
udevadm_found = ! Glib::find_program_in_path( "udevadm" ).empty();
|
udevadm_found = ! Glib::find_program_in_path( "udevadm" ).empty();
|
||||||
hdparm_found = ! Glib::find_program_in_path( "hdparm" ).empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -772,38 +770,17 @@ void GParted_Core::set_device_from_disk( Device & device, const Glib::ustring &
|
||||||
|
|
||||||
void GParted_Core::set_device_serial_number( Device & device )
|
void GParted_Core::set_device_serial_number( Device & device )
|
||||||
{
|
{
|
||||||
if ( ! hdparm_found )
|
if (! udevadm_found)
|
||||||
// Serial number left blank when the hdparm command is not installed.
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Glib::ustring output;
|
Glib::ustring output;
|
||||||
Glib::ustring error;
|
Glib::ustring error;
|
||||||
Utils::execute_command( "hdparm -I " + Glib::shell_quote( device.get_path() ), output, error, true );
|
Utils::execute_command("udevadm info --query=property --name=" + Glib::shell_quote(device.get_path()),
|
||||||
if ( ! error.empty() )
|
output, error, true);
|
||||||
{
|
device.serial_number = Utils::regexp_label(output, "^ID_SERIAL_SHORT=([^\n]*)$");
|
||||||
// hdparm reported an error message to stderr. Assume it's a device
|
|
||||||
// without a hard drive serial number.
|
|
||||||
//
|
|
||||||
// Using hdparm -I to query Linux software RAID arrays and BIOS fake RAID
|
|
||||||
// arrays, both devices without their own hard drive serial numbers,
|
|
||||||
// produce this error:
|
|
||||||
// HDIO_DRIVE_CMD(identify) failed: Inappropriate ioctl for device
|
|
||||||
//
|
|
||||||
// And querying USB flash drives, also a device type without their own
|
|
||||||
// hard drive serial numbers, generates this error:
|
|
||||||
// SG_IO: bad/missing sense data, sb[]: 70 00 05 00 00 00 00 0a ...
|
|
||||||
device.serial_number = "none";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Glib::ustring serial_number = Utils::trim( Utils::regexp_label( output,
|
|
||||||
"^[[:blank:]]*Serial Number:[[:blank:]]*(.*)[[:blank:]]*$" ) );
|
|
||||||
if ( ! serial_number.empty() )
|
|
||||||
device.serial_number = serial_number;
|
|
||||||
}
|
|
||||||
// Otherwise serial number left blank when not found in the hdparm output.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fills the device.partitions member of device by scanning
|
* Fills the device.partitions member of device by scanning
|
||||||
* all partitions
|
* all partitions
|
||||||
|
|
Loading…
Reference in New Issue