]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev-dump: also show written sysfs attributes and sysctl entries 36091/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 11 Jan 2025 07:38:02 +0000 (16:38 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 22 Jan 2025 16:50:13 +0000 (01:50 +0900)
This should be useful to know what is changed by processing an event.

src/udev/udev-dump.c
src/udev/udev-dump.h
src/udev/udev-event.c
src/udev/udev-event.h
src/udev/udev-rules.c

index 26e65979eb7e2d86ffc3ae22ab5843ee6de8ffed..918c966c4e17530368bd4d26a1557d142f693dbe 100644 (file)
 #include "udev-event.h"
 #include "user-util.h"
 
+static void event_cache_written_value(Hashmap **values, const char *attr, const char *value) {
+        assert(values);
+
+        _unused_ _cleanup_free_ void *key = NULL;
+        free(hashmap_remove2(*values, attr, &key));
+
+        if (hashmap_put_strdup_full(values, &path_hash_ops_free_free, attr, value) < 0)
+                log_oom_debug();
+}
+
+void event_cache_written_sysattr(UdevEvent *event, const char *attr, const char *value) {
+        event_cache_written_value(&event->written_sysattrs, attr, value);
+}
+
+void event_cache_written_sysctl(UdevEvent *event, const char *attr, const char *value) {
+        event_cache_written_value(&event->written_sysctls, attr, value);
+}
+
 void dump_event(UdevEvent *event, FILE *f) {
         sd_device *dev = ASSERT_PTR(ASSERT_PTR(event)->dev);
 
         if (!f)
                 f = stdout;
 
+        if (!hashmap_isempty(event->written_sysattrs)) {
+                const char *key, *value;
+
+                fprintf(f, "%sWritten sysfs attributes:%s\n", ansi_highlight(), ansi_normal());
+                HASHMAP_FOREACH_KEY(value, key, event->written_sysattrs)
+                        fprintf(f, "  %s : %s\n", key, value);
+        }
+
+        if (!hashmap_isempty(event->written_sysctls)) {
+                const char *key, *value;
+
+                fprintf(f, "%sWritten sysctl entries:%s\n", ansi_highlight(), ansi_normal());
+                HASHMAP_FOREACH_KEY(value, key, event->written_sysctls)
+                        fprintf(f, "  %s : %s\n", key, value);
+        }
+
         fprintf(f, "%sProperties:%s\n", ansi_highlight(), ansi_normal());
         FOREACH_DEVICE_PROPERTY(dev, key, value)
                 fprintf(f, "  %s=%s\n", key, value);
index 6e3f1368ce412d5c15104b66af04b5cd876c1137..514f8267a7a2d78ae9b57b39d41a303f596a21f9 100644 (file)
@@ -5,4 +5,6 @@
 
 typedef struct UdevEvent UdevEvent;
 
+void event_cache_written_sysattr(UdevEvent *event, const char *attr, const char *value);
+void event_cache_written_sysctl(UdevEvent *event, const char *attr, const char *value);
 void dump_event(UdevEvent *event, FILE *f);
index e3661f5bf88877aeb4d4ff2a03f82d66d013e701..fc4c9f9fd1b1fd01dc1a37ea8d38b9cbfc59a9f9 100644 (file)
@@ -54,6 +54,8 @@ static UdevEvent* udev_event_free(UdevEvent *event) {
         sd_netlink_unref(event->rtnl);
         ordered_hashmap_free_free_key(event->run_list);
         ordered_hashmap_free_free_free(event->seclabel_list);
+        hashmap_free(event->written_sysattrs);
+        hashmap_free(event->written_sysctls);
         free(event->program_result);
         free(event->name);
         strv_free(event->altnames);
index 11e2c700e63505f589abdb99941b2807211f936a..d18fb0978bf1dffef456986fa36bd5d84fbc0fea 100644 (file)
@@ -36,6 +36,8 @@ typedef struct UdevEvent {
         gid_t gid;
         OrderedHashmap *seclabel_list;
         OrderedHashmap *run_list;
+        Hashmap *written_sysattrs;
+        Hashmap *written_sysctls;
         usec_t birth_usec;
         unsigned builtin_run;
         unsigned builtin_ret;
index d94fc6fdbd3011754c0b553c2d76b782af68ac71..dfe521378fcc3a188522ca6e51e3f1d702850b1c 100644 (file)
@@ -2949,11 +2949,19 @@ static int udev_rule_apply_token_to_event(
                                               WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE);
                         if (r < 0)
                                 log_event_error_errno(event, token, r, "Failed to write \"%s\" to sysfs attribute \"%s\", ignoring: %m", value, buf);
-                        else
+                        else {
+                                event_cache_written_sysattr(event, buf, value);
                                 log_event_done(event, token);
-                } else
+                        }
+                } else {
                         log_event_debug(event, token, "Running in test mode, skipping writing \"%s\" to sysfs attribute \"%s\".", value, buf);
 
+                        r = verify_regular_at(AT_FDCWD, buf, /* follow = */ false);
+                        if (r < 0 && !ERRNO_IS_NEG_PRIVILEGE(r))
+                                log_event_error_errno(event, token, r, "Failed to verify sysfs attribute \"%s\" is a regular file: %m", buf);
+                        else
+                                event_cache_written_sysattr(event, buf, value);
+                }
                 return true;
         }
         case TK_A_SYSCTL: {
@@ -2972,11 +2980,23 @@ static int udev_rule_apply_token_to_event(
                         r = sysctl_write(buf, value);
                         if (r < 0)
                                 log_event_error_errno(event, token, r, "Failed to write \"%s\" to sysctl entry \"%s\", ignoring: %m", value, buf);
-                        else
+                        else {
+                                event_cache_written_sysctl(event, buf, value);
                                 log_event_done(event, token);
-                } else
+                        }
+                } else {
                         log_event_debug(event, token, "Running in test mode, skipping writing \"%s\" to sysctl entry \"%s\".", value, buf);
 
+                        _cleanup_free_ char *path = path_join("/proc/sys/", buf);
+                        if (!path)
+                                return log_oom();
+
+                        r = verify_regular_at(AT_FDCWD, path, /* follow = */ true);
+                        if (r < 0 && !ERRNO_IS_NEG_PRIVILEGE(r))
+                                log_event_error_errno(event, token, r, "Failed to verify sysctl entry \"%s\" is a regular file: %m", buf);
+                        else
+                                event_cache_written_sysctl(event, buf, value);
+                }
                 return true;
         }
         case TK_A_RUN_BUILTIN: