sd-device: do not clear sd_device.all_tags even on TAG="hoge"

The current tag concept has been introduced by
e77b146f82 (v247) to make symlinks in
/run/udev/tags/ are 'sticky'.

However, when TAG= (rather than TAG+=) is specified, then the tags
assigned in the previous events were also cleared.
This fixes the issue and now symlinks in /run/udev/tags/ are really
'sticky'.

Fortunately, TAG= is mostly unused. So, the issue should not affect
and the fix should not change anything on almost all systems.
This commit is contained in:
Yu Watanabe
2026-02-23 05:46:42 +09:00
parent 1c867dc71a
commit fc03d200c7
3 changed files with 18 additions and 5 deletions
+12 -2
View File
@@ -710,13 +710,23 @@ int device_copy_all_tags(sd_device *dest, sd_device *src) {
return 0;
}
void device_cleanup_tags(sd_device *device) {
int device_cleanup_tags(sd_device *device, sd_device *original) {
int r;
assert(device);
device->all_tags = set_free(device->all_tags);
_cleanup_set_free_ Set *saved = TAKE_PTR(device->all_tags);
device->current_tags = set_free(device->current_tags);
device->property_tags_outdated = true;
device->tags_generation++;
r = device_copy_all_tags(device, original);
if (r < 0) {
set_free_and_replace(device->all_tags, saved);
return r;
}
return 0;
}
void device_cleanup_devlinks(sd_device *device) {
+1 -1
View File
@@ -46,7 +46,7 @@ int device_add_propertyf(sd_device *device, const char *key, const char *format,
int device_add_tag(sd_device *device, const char *tag, bool both);
void device_remove_tag(sd_device *device, const char *tag);
int device_copy_all_tags(sd_device *dest, sd_device *src);
void device_cleanup_tags(sd_device *device);
int device_cleanup_tags(sd_device *device, sd_device *original);
void device_cleanup_devlinks(sd_device *device);
uint64_t device_get_properties_generation(sd_device *device);
+5 -2
View File
@@ -2900,8 +2900,11 @@ static int udev_rule_apply_token_to_event(
assert(IN_SET(token->op, OP_ASSIGN, OP_ADD));
if (token->op == OP_ASSIGN)
device_cleanup_tags(dev);
if (token->op == OP_ASSIGN) {
r = device_cleanup_tags(dev, event->dev_db_clone);
if (r < 0)
log_event_warning_errno(event, token, r, "Failed to clear previously assigned tags, ignoring: %m");
}
r = device_add_tag(dev, buf, /* both= */ true);
if (r == -ENOMEM)