diff --git a/src/libsystemd/sd-device/device-private.c b/src/libsystemd/sd-device/device-private.c index 828697e617..d640eeb250 100644 --- a/src/libsystemd/sd-device/device-private.c +++ b/src/libsystemd/sd-device/device-private.c @@ -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) { diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h index 376a4a479c..90f4e103f5 100644 --- a/src/libsystemd/sd-device/device-private.h +++ b/src/libsystemd/sd-device/device-private.h @@ -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); diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 06686e3715..f0e4fbccfd 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -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)