diff --git a/src/libsystemd/sd-device/device-private.h b/src/libsystemd/sd-device/device-private.h index d9a519a4d98..740c58438cf 100644 --- a/src/libsystemd/sd-device/device-private.h +++ b/src/libsystemd/sd-device/device-private.h @@ -38,6 +38,7 @@ void device_set_db_persist(sd_device *device); void device_set_devlink_priority(sd_device *device, int priority); int device_ensure_usec_initialized(sd_device *device, sd_device *device_old); int device_add_devlink(sd_device *device, const char *devlink); +void device_remove_devlink(sd_device *device, const char *devlink); bool device_has_devlink(sd_device *device, const char *devlink); int device_add_property(sd_device *device, const char *property, const char *value); int device_add_propertyf(sd_device *device, const char *key, const char *format, ...) _printf_(3, 4); diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index c3160b04bb7..8c65ee34698 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -1489,6 +1489,20 @@ int device_add_devlink(sd_device *device, const char *devlink) { return 0; } +void device_remove_devlink(sd_device *device, const char *devlink) { + _cleanup_free_ char *s = NULL; + + assert(device); + assert(devlink); + + s = set_remove(device->devlinks, devlink); + if (!s) + return; + + device->devlinks_generation++; + device->property_devlinks_outdated = true; +} + bool device_has_devlink(sd_device *device, const char *devlink) { assert(device); assert(devlink); diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 52bf66ab0b9..5bd09a64d1d 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -579,9 +579,6 @@ static int parse_token(UdevRules *rules, const char *key, char *attr, UdevRuleOp } else if (streq(key, "SYMLINK")) { if (attr) return log_token_invalid_attr(rules, key); - if (op == OP_REMOVE) - return log_token_invalid_op(rules, key); - if (!is_match) { check_value_format_and_warn(rules, key, value, false); r = rule_line_add_token(rule_line, TK_A_DEVLINK, op, value, NULL); @@ -2313,11 +2310,17 @@ static int udev_rule_apply_token_to_event( if (truncated) continue; - r = device_add_devlink(dev, filename); - if (r < 0) - return log_rule_error_errno(dev, rules, r, "Failed to add devlink '%s': %m", filename); + if (token->op == OP_REMOVE) { + device_remove_devlink(dev, filename); + log_rule_debug(dev, rules, "Dropped SYMLINK '%s'", p); + } else { + r = device_add_devlink(dev, filename); + if (r < 0) + return log_rule_error_errno(dev, rules, r, "Failed to add devlink '%s': %m", filename); + + log_rule_debug(dev, rules, "Added SYMLINK '%s'", p); + } - log_rule_debug(dev, rules, "LINK '%s'", p); p = next; } break;