Skip to content

Commit

Permalink
udev: always create device symlinks for USB disks
Browse files Browse the repository at this point in the history
Previously, ata_id might not be able to retrieve attributes correctly,
and properties from usb_id were used as a fallback. See issue systemd#24921
and PR systemd#24923. To keep backward compatibility, still we need to create
symlinks based on USB serial.

Fixes systemd#25179.
  • Loading branch information
yuwata authored and bluca committed Oct 30, 2022
1 parent 269585d commit 479da11
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 14 deletions.
10 changes: 8 additions & 2 deletions rules.d/60-persistent-storage.rules
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,20 @@ KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="scsi", ATTRS{type}==
# Run ata_id on non-removable USB Mass Storage (SATA/PATA disks in enclosures)
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", ATTR{removable}=="0", SUBSYSTEMS=="usb", IMPORT{program}="ata_id --export $devnode"

# Fall back usb_id for USB devices
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
# Also import properties from usb_id for USB devices
KERNEL=="sd*[!0-9]|sr*", SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"

# SCSI devices
KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --export --whitelisted -d $devnode", ENV{ID_BUS}="scsi"
KERNEL=="cciss*", ENV{DEVTYPE}=="disk", ENV{ID_SERIAL}!="?*", IMPORT{program}="scsi_id --export --whitelisted -d $devnode", ENV{ID_BUS}="cciss"
KERNEL=="sd*|sr*|cciss*", ENV{DEVTYPE}=="disk", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}"
KERNEL=="sd*|cciss*", ENV{DEVTYPE}=="partition", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n"
# Previously, ata_id in the above might not be able to retrieve attributes correctly,
# and properties from usb_id were used as a fallback. See issue #24921 and PR #24923.
# To keep backward compatibility, still we need to create symlinks based on USB serial.
# See issue #25179.
KERNEL=="sd*|sr*|cciss*", ENV{DEVTYPE}=="disk", ENV{ID_USB_SERIAL}=="?*", SYMLINK+="disk/by-id/usb-$env{ID_USB_SERIAL}"
KERNEL=="sd*|cciss*", ENV{DEVTYPE}=="partition", ENV{ID_USB_SERIAL}=="?*", SYMLINK+="disk/by-id/usb-$env{ID_USB_SERIAL}-part%n"

# PMEM devices
KERNEL=="pmem*", ENV{DEVTYPE}=="disk", ATTRS{uuid}=="?*", SYMLINK+="disk/by-id/pmem-$attr{uuid}"
Expand Down
55 changes: 43 additions & 12 deletions src/udev/udev-builtin-usb_id.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,21 +427,52 @@ static int builtin_usb_id(sd_device *dev, sd_netlink **rtnl, int argc, char *arg
if (!isempty(instance_str))
strpcpyl(&s, l, "-", instance_str, NULL);

udev_builtin_add_property(dev, test, "ID_VENDOR", vendor_str);
udev_builtin_add_property(dev, test, "ID_VENDOR_ENC", vendor_str_enc);
udev_builtin_add_property(dev, test, "ID_VENDOR_ID", vendor_id);
udev_builtin_add_property(dev, test, "ID_MODEL", model_str);
udev_builtin_add_property(dev, test, "ID_MODEL_ENC", model_str_enc);
udev_builtin_add_property(dev, test, "ID_MODEL_ID", product_id);
udev_builtin_add_property(dev, test, "ID_REVISION", revision_str);
udev_builtin_add_property(dev, test, "ID_SERIAL", serial);
if (sd_device_get_property_value(dev, "ID_BUS", NULL) >= 0)
log_device_debug(dev, "ID_BUS property is already set, setting only properties prefixed with \"ID_USB_\".");
else {
udev_builtin_add_property(dev, test, "ID_BUS", "usb");

udev_builtin_add_property(dev, test, "ID_MODEL", model_str);
udev_builtin_add_property(dev, test, "ID_MODEL_ENC", model_str_enc);
udev_builtin_add_property(dev, test, "ID_MODEL_ID", product_id);

udev_builtin_add_property(dev, test, "ID_SERIAL", serial);
if (!isempty(serial_str))
udev_builtin_add_property(dev, test, "ID_SERIAL_SHORT", serial_str);

udev_builtin_add_property(dev, test, "ID_VENDOR", vendor_str);
udev_builtin_add_property(dev, test, "ID_VENDOR_ENC", vendor_str_enc);
udev_builtin_add_property(dev, test, "ID_VENDOR_ID", vendor_id);

udev_builtin_add_property(dev, test, "ID_REVISION", revision_str);

if (!isempty(type_str))
udev_builtin_add_property(dev, test, "ID_TYPE", type_str);

if (!isempty(instance_str))
udev_builtin_add_property(dev, test, "ID_INSTANCE", instance_str);
}

/* Also export the same values in the above by prefixing ID_USB_. */
udev_builtin_add_property(dev, test, "ID_USB_MODEL", model_str);
udev_builtin_add_property(dev, test, "ID_USB_MODEL_ENC", model_str_enc);
udev_builtin_add_property(dev, test, "ID_USB_MODEL_ID", product_id);
udev_builtin_add_property(dev, test, "ID_USB_SERIAL", serial);
if (!isempty(serial_str))
udev_builtin_add_property(dev, test, "ID_SERIAL_SHORT", serial_str);
udev_builtin_add_property(dev, test, "ID_USB_SERIAL_SHORT", serial_str);

udev_builtin_add_property(dev, test, "ID_USB_VENDOR", vendor_str);
udev_builtin_add_property(dev, test, "ID_USB_VENDOR_ENC", vendor_str_enc);
udev_builtin_add_property(dev, test, "ID_USB_VENDOR_ID", vendor_id);

udev_builtin_add_property(dev, test, "ID_USB_REVISION", revision_str);

if (!isempty(type_str))
udev_builtin_add_property(dev, test, "ID_TYPE", type_str);
udev_builtin_add_property(dev, test, "ID_USB_TYPE", type_str);

if (!isempty(instance_str))
udev_builtin_add_property(dev, test, "ID_INSTANCE", instance_str);
udev_builtin_add_property(dev, test, "ID_BUS", "usb");
udev_builtin_add_property(dev, test, "ID_USB_INSTANCE", instance_str);

if (!isempty(packed_if_str))
udev_builtin_add_property(dev, test, "ID_USB_INTERFACES", packed_if_str);
if (ifnum)
Expand Down

0 comments on commit 479da11

Please sign in to comment.