sd-device,udev: several fixlets and cleanups for managing tags (#40786)

This commit is contained in:
Luca Boccassi
2026-02-23 21:53:28 +00:00
committed by GitHub
6 changed files with 63 additions and 36 deletions
+31 -11
View File
@@ -693,20 +693,46 @@ int device_clone_with_db(sd_device *device, sd_device **ret) {
return 0;
}
void device_cleanup_tags(sd_device *device) {
int device_copy_all_tags(sd_device *dest, sd_device *src) {
int r;
assert(dest);
if (!src)
return 0;
FOREACH_DEVICE_TAG(src, tag) {
r = device_add_tag(dest, tag, /* both= */ false);
if (r < 0)
return r;
}
return 0;
}
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) {
assert(device);
set_free(device->devlinks);
device->devlinks = NULL;
device->devlinks = set_free(device->devlinks);
device->property_devlinks_outdated = true;
device->devlinks_generation++;
}
@@ -743,15 +769,9 @@ static int device_tag(sd_device *device, const char *tag, bool add) {
return 0;
}
int device_tag_index(sd_device *device, sd_device *device_old, bool add) {
int device_tag_index(sd_device *device, bool add) {
int r = 0;
if (add && device_old)
/* delete possible left-over tags */
FOREACH_DEVICE_TAG(device_old, tag)
if (!sd_device_has_tag(device, tag))
RET_GATHER(r, device_tag(device_old, tag, false));
FOREACH_DEVICE_TAG(device, tag)
RET_GATHER(r, device_tag(device, tag, add));
+3 -2
View File
@@ -45,7 +45,8 @@ int device_add_property(sd_device *device, const char *key, const char *value);
int device_add_propertyf(sd_device *device, const char *key, const char *format, ...) _printf_(3, 4);
int device_add_tag(sd_device *device, const char *tag, bool both);
void device_remove_tag(sd_device *device, const char *tag);
void device_cleanup_tags(sd_device *device);
int device_copy_all_tags(sd_device *dest, sd_device *src);
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);
@@ -58,7 +59,7 @@ int device_get_properties_strv(sd_device *device, char ***ret);
int device_clone_with_db(sd_device *device, sd_device **ret);
int device_tag_index(sd_device *device, sd_device *device_old, bool add);
int device_tag_index(sd_device *device, bool add);
bool device_should_have_db(sd_device *device);
int device_has_db(sd_device *device);
int device_update_db(sd_device *device);
+20
View File
@@ -270,6 +270,20 @@ static int dump_event_json(UdevEvent *event, sd_json_format_flags_t flags, FILE
return r;
}
tags = strv_free(tags);
FOREACH_DEVICE_CURRENT_TAG(dev, tag) {
r = strv_extend(&tags, tag);
if (r < 0)
return r;
}
if (!strv_isempty(tags)) {
r = sd_json_variant_set_field_strv(&v, "currentTags", strv_sort(tags));
if (r < 0)
return r;
}
char **properties;
if (device_get_properties_strv(dev, &properties) >= 0 && !strv_isempty(properties)) {
r = sd_json_variant_set_field_strv(&v, "properties", strv_sort(properties));
@@ -417,6 +431,12 @@ int dump_event(UdevEvent *event, sd_json_format_flags_t flags, FILE *f) {
fprintf(f, " %s\n", tag);
}
if (sd_device_get_current_tag_first(dev)) {
fprintf(f, "%sCurrent Tags:%s\n", ansi_highlight(), ansi_normal());
FOREACH_DEVICE_CURRENT_TAG(dev, tag)
fprintf(f, " %s\n", tag);
}
char **properties;
if (device_get_properties_strv(dev, &properties) >= 0 && !strv_isempty(properties)) {
bool space = true;
+1 -1
View File
@@ -63,7 +63,7 @@ int device_broadcast_on_error(sd_device *dev, sd_device_monitor *monitor) {
/* delete state from disk */
(void) device_delete_db(dev);
(void) device_tag_index(dev, /* device_old= */ NULL, /* add= */ false);
(void) device_tag_index(dev, /* add= */ false);
r = device_monitor_send(monitor, /* destination= */ NULL, dev);
if (r < 0) {
+3 -20
View File
@@ -310,7 +310,7 @@ static int event_execute_rules_on_remove(UdevEvent *event, UdevRules *rules) {
log_device_debug_errno(dev, r, "Failed to read database under /run/udev/data/: %m");
if (EVENT_MODE_DESTRUCTIVE(event)) {
r = device_tag_index(dev, NULL, false);
r = device_tag_index(dev, /* add= */ false);
if (r < 0)
log_device_debug_errno(dev, r, "Failed to remove corresponding tag files under /run/udev/tag/, ignoring: %m");
@@ -329,23 +329,6 @@ static int event_execute_rules_on_remove(UdevEvent *event, UdevRules *rules) {
return r;
}
static int copy_all_tags(sd_device *d, sd_device *s) {
int r;
assert(d);
if (!s)
return 0;
FOREACH_DEVICE_TAG(s, tag) {
r = device_add_tag(d, tag, false);
if (r < 0)
return r;
}
return 0;
}
static int update_clone(UdevEvent *event) {
sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev_db_clone);
int r;
@@ -398,7 +381,7 @@ int udev_event_execute_rules(UdevEvent *event, UdevRules *rules) {
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to clone sd_device object: %m");
r = copy_all_tags(dev, event->dev_db_clone);
r = device_copy_all_tags(dev, event->dev_db_clone);
if (r < 0)
log_device_warning_errno(dev, r, "Failed to copy all tags from old database entry, ignoring: %m");
@@ -433,7 +416,7 @@ int udev_event_execute_rules(UdevEvent *event, UdevRules *rules) {
if (EVENT_MODE_DESTRUCTIVE(event)) {
/* (re)write database file */
r = device_tag_index(dev, event->dev_db_clone, true);
r = device_tag_index(dev, /* add= */ true);
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to update tags under /run/udev/tag/: %m");
}
+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)