]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: support '-=' operator for SYMLINK
authorFranck Bui <fbui@suse.com>
Tue, 17 Jan 2023 05:30:48 +0000 (14:30 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 17 Jan 2023 05:39:24 +0000 (14:39 +0900)
For some (corner) cases, it might be desirable to disable the generation of
some persistent storage symlinks that 60-persistent-storage.rules creates.

For example on big setups with a high number of partitions which uses the same
label name, this can result in a noticeable slow-down in the (re)start of the
udevd as there are many contenders for the symlink /dev/disk/by-partlabel.

However it's currently pretty hard to overwrite just some specific part of the
rule file. Indeed one need to copy and modify the whole rule file in /etc but
will lost any upcoming updates/fixes that the distro might release in the
future.

With this simple patch, one can now disable the generation of the
"by-partlabel" symlinks (for example) with the following single rule:

$ cat /etc/udev/rules.d/99-no-by-partlabel.rules
ENV{ID_PART_ENTRY_NAME}=="?*", SYMLINK-="disk/by-partlabel/$env{ID_PART_ENTRY_NAME}"

Closes #24607.

src/libsystemd/sd-device/device-private.h
src/libsystemd/sd-device/sd-device.c
src/udev/udev-rules.c

index d9a519a4d98f225ac13701e4c2e291c8681a3b9e..740c58438cfcf672ff85ce6293a3a767880204e2 100644 (file)
@@ -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);
index c3160b04bb7e44e4a791fe9175ee4d2727743551..8c65ee346984aa50189b40e313fb970d760df2cc 100644 (file)
@@ -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);
index 52bf66ab0b935d5bd3f7590a7a15a461dbe99b3c..5bd09a64d1d268e5a5cf89b656eb10ef0e4347b6 100644 (file)
@@ -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;