]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udevadm-verify: check for unused labels
authorDmitry V. Levin <ldv@strace.io>
Sun, 5 Mar 2023 08:00:00 +0000 (08:00 +0000)
committerDmitry V. Levin <ldv@strace.io>
Wed, 8 Mar 2023 18:55:40 +0000 (18:55 +0000)
Check for unused labels in the specified udev rules files, report such
labels and exit with a non-zero exit code if any unused labels are
found.

src/udev/udev-rules.c

index c2e98e9a9e82efc293b758e12b1e0354ba1b077b..21223e01186da5985b8e137c30f65e7860f463bf 100644 (file)
@@ -137,6 +137,7 @@ typedef enum {
         LINE_HAS_GOTO         = 1 << 3, /* has GOTO= */
         LINE_HAS_LABEL        = 1 << 4, /* has LABEL= */
         LINE_UPDATE_SOMETHING = 1 << 5, /* has other TK_A_* or TK_M_IMPORT tokens */
+        LINE_IS_REFERENCED    = 1 << 6, /* is referenced by GOTO */
 } UdevRuleLineType;
 
 typedef struct UdevRuleFile UdevRuleFile;
@@ -1191,6 +1192,7 @@ static void rule_resolve_goto(UdevRuleFile *rule_file) {
                 LIST_FOREACH(rule_lines, i, line->rule_lines_next)
                         if (streq_ptr(i->label, line->goto_label)) {
                                 line->goto_line = i;
+                                SET_FLAG(i->type, LINE_IS_REFERENCED, true);
                                 break;
                         }
 
@@ -1202,10 +1204,11 @@ static void rule_resolve_goto(UdevRuleFile *rule_file) {
                         SET_FLAG(line->type, LINE_HAS_GOTO, false);
                         line->goto_label = NULL;
 
-                        if ((line->type & ~LINE_HAS_LABEL) == 0) {
+                        if ((line->type & ~(LINE_HAS_LABEL|LINE_IS_REFERENCED)) == 0) {
                                 log_line_notice(rule_file, line->line_number,
                                                 "The line takes no effect any more, dropping");
-                                if (line->type == LINE_HAS_LABEL)
+                                /* LINE_IS_REFERENCED implies LINE_HAS_LABEL */
+                                if (line->type & LINE_HAS_LABEL)
                                         udev_rule_line_clear_tokens(line);
                                 else
                                         udev_rule_line_free(line);
@@ -1321,6 +1324,14 @@ int udev_rules_parse_file(UdevRules *rules, const char *filename) {
         return 0;
 }
 
+static void udev_check_rule_line(UdevRuleFile *rule_file, const UdevRuleLine *line) {
+        /* check for unused labels */
+        if (FLAGS_SET(line->type, LINE_HAS_LABEL) &&
+            !FLAGS_SET(line->type, LINE_IS_REFERENCED))
+                log_line_warning(rule_file, line->line_number,
+                                 "LABEL=\"%s\" is unused.", line->label);
+}
+
 unsigned udev_check_current_rule_file(UdevRules *rules) {
         assert(rules);
 
@@ -1328,6 +1339,9 @@ unsigned udev_check_current_rule_file(UdevRules *rules) {
         if (!rule_file)
                 return 0;
 
+        LIST_FOREACH(rule_lines, line, rule_file->rule_lines)
+                udev_check_rule_line(rule_file, line);
+
         return rule_file->issues;
 }