The current tag concept has been introduced by
e77b146f825ef1bb63c297cc713962b94422d2c6 (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.
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) {
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);
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)