From c4d44cba4d9bd9d92c86e06f21d5936cca1b8c16 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 25 Oct 2018 15:30:51 +0900 Subject: [PATCH] udev: introduce enum ResolveNameTiming for --resolve-names argument --- src/test/test-udev.c | 2 +- src/udev/udev-rules.c | 25 ++++++++++++++++++------- src/udev/udev.h | 13 ++++++++++++- src/udev/udevadm-test.c | 15 +++++---------- src/udev/udevd.c | 26 ++++++++++++-------------- 5 files changed, 48 insertions(+), 33 deletions(-) diff --git a/src/test/test-udev.c b/src/test/test-udev.c index 102da4adc6..7c70336e1b 100644 --- a/src/test/test-udev.c +++ b/src/test/test-udev.c @@ -84,7 +84,7 @@ int main(int argc, char *argv[]) { action = argv[1]; devpath = argv[2]; - rules = udev_rules_new(1); + rules = udev_rules_new(RESOLVE_NAME_EARLY); const char *syspath = strjoina("/sys", devpath); r = device_new_from_synthetic_event(&dev, syspath, action); diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index ad4b32abea..c8b905a873 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -30,6 +30,7 @@ #include "stat-util.h" #include "stdio-util.h" #include "strbuf.h" +#include "string-table.h" #include "string-util.h" #include "strv.h" #include "sysctl-util.h" @@ -57,7 +58,7 @@ static const char* const rules_dirs[] = { struct udev_rules { usec_t dirs_ts_usec; - int resolve_names; + ResolveNameTiming resolve_name_timing; /* every key in the rules file becomes a token */ struct token *tokens; @@ -1335,10 +1336,10 @@ static void add_rule(struct udev_rules *rules, char *line, uid = strtoul(value, &endptr, 10); if (endptr[0] == '\0') rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid); - else if (rules->resolve_names > 0 && strchr("$%", value[0]) == NULL) { + else if (rules->resolve_name_timing == RESOLVE_NAME_EARLY && strchr("$%", value[0]) == NULL) { uid = add_uid(rules, value); rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid); - } else if (rules->resolve_names >= 0) + } else if (rules->resolve_name_timing != RESOLVE_NAME_NEVER) rule_add_key(&rule_tmp, TK_A_OWNER, op, value, NULL); rule_tmp.rule.rule.can_set_name = true; @@ -1353,10 +1354,10 @@ static void add_rule(struct udev_rules *rules, char *line, gid = strtoul(value, &endptr, 10); if (endptr[0] == '\0') rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid); - else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) { + else if ((rules->resolve_name_timing == RESOLVE_NAME_EARLY) && strchr("$%", value[0]) == NULL) { gid = add_gid(rules, value); rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid); - } else if (rules->resolve_names >= 0) + } else if (rules->resolve_name_timing != RESOLVE_NAME_NEVER) rule_add_key(&rule_tmp, TK_A_GROUP, op, value, NULL); rule_tmp.rule.rule.can_set_name = true; @@ -1512,18 +1513,20 @@ static int parse_file(struct udev_rules *rules, const char *filename) { return 0; } -struct udev_rules *udev_rules_new(int resolve_names) { +struct udev_rules *udev_rules_new(ResolveNameTiming resolve_name_timing) { struct udev_rules *rules; struct token end_token; char **files, **f; int r; + assert(resolve_name_timing >= 0 && resolve_name_timing < _RESOLVE_NAME_TIMING_MAX); + rules = new(struct udev_rules, 1); if (!rules) return NULL; *rules = (struct udev_rules) { - .resolve_names = resolve_names, + .resolve_name_timing = resolve_name_timing, }; /* init token array and string buffer */ @@ -2598,3 +2601,11 @@ finish: return 0; } + +static const char* const resolve_name_timing_table[_RESOLVE_NAME_TIMING_MAX] = { + [RESOLVE_NAME_NEVER] = "never", + [RESOLVE_NAME_LATE] = "late", + [RESOLVE_NAME_EARLY] = "early", +}; + +DEFINE_STRING_TABLE_LOOKUP(resolve_name_timing, ResolveNameTiming); diff --git a/src/udev/udev.h b/src/udev/udev.h index fb2c6813ef..5c6ca6bf9f 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -48,9 +48,17 @@ struct udev_event { bool run_final; }; +typedef enum ResolveNameTiming { + RESOLVE_NAME_NEVER, + RESOLVE_NAME_LATE, + RESOLVE_NAME_EARLY, + _RESOLVE_NAME_TIMING_MAX, + _RESOLVE_NAME_TIMING_INVALID = -1, +} ResolveNameTiming; + /* udev-rules.c */ struct udev_rules; -struct udev_rules *udev_rules_new(int resolve_names); +struct udev_rules *udev_rules_new(ResolveNameTiming resolve_name_timing); struct udev_rules *udev_rules_unref(struct udev_rules *rules); bool udev_rules_check_timestamp(struct udev_rules *rules); int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, @@ -58,6 +66,9 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event Hashmap *properties_list); int udev_rules_apply_static_dev_perms(struct udev_rules *rules); +ResolveNameTiming resolve_name_timing_from_string(const char *s) _pure_; +const char *resolve_name_timing_to_string(ResolveNameTiming i) _const_; + /* udev-event.c */ struct udev_event *udev_event_new(sd_device *dev, usec_t exec_delay_usec, sd_netlink *rtnl); struct udev_event *udev_event_free(struct udev_event *event); diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c index cfaaf03db9..dd0fc4f91f 100644 --- a/src/udev/udevadm-test.c +++ b/src/udev/udevadm-test.c @@ -22,7 +22,7 @@ #include "udevadm.h" static const char *arg_action = "add"; -static int arg_resolve_names = 1; +static ResolveNameTiming arg_resolve_name_timing = RESOLVE_NAME_EARLY; static char arg_syspath[UTIL_PATH_SIZE] = {}; static int help(void) { @@ -55,14 +55,9 @@ static int parse_argv(int argc, char *argv[]) { arg_action = optarg; break; case 'N': - if (streq (optarg, "early")) { - arg_resolve_names = 1; - } else if (streq (optarg, "late")) { - arg_resolve_names = 0; - } else if (streq (optarg, "never")) { - arg_resolve_names = -1; - } else { - log_error("resolve-names must be early, late or never"); + arg_resolve_name_timing = resolve_name_timing_from_string(optarg); + if (arg_resolve_name_timing < 0) { + log_error("--resolve-names= must be early, late or never"); return -EINVAL; } break; @@ -115,7 +110,7 @@ int test_main(int argc, char *argv[], void *userdata) { udev_builtin_init(); - rules = udev_rules_new(arg_resolve_names); + rules = udev_rules_new(arg_resolve_name_timing); if (!rules) { log_error("Failed to read udev rules."); r = -ENOMEM; diff --git a/src/udev/udevd.c b/src/udev/udevd.c index c97e873942..4f93ec4c9a 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -61,7 +61,7 @@ static bool arg_debug = false; static int arg_daemonize = false; -static int arg_resolve_names = 1; +static ResolveNameTiming arg_resolve_name_timing = RESOLVE_NAME_EARLY; static unsigned arg_children_max = 0; static usec_t arg_exec_delay_usec = 0; static usec_t arg_event_timeout_usec = 180 * USEC_PER_SEC; @@ -851,7 +851,7 @@ static void event_queue_start(Manager *manager) { udev_builtin_init(); if (!manager->rules) { - manager->rules = udev_rules_new(arg_resolve_names); + manager->rules = udev_rules_new(arg_resolve_name_timing); if (!manager->rules) return; } @@ -1565,18 +1565,16 @@ static int parse_argv(int argc, char *argv[]) { case 'D': arg_debug = true; break; - case 'N': - if (streq(optarg, "early")) { - arg_resolve_names = 1; - } else if (streq(optarg, "late")) { - arg_resolve_names = 0; - } else if (streq(optarg, "never")) { - arg_resolve_names = -1; - } else { - log_error("resolve-names must be early, late or never"); - return 0; - } + case 'N': { + ResolveNameTiming t; + + t = resolve_name_timing_from_string(optarg); + if (t < 0) + log_warning("Invalid --resolve-names= value '%s', ignoring.", optarg); + else + arg_resolve_name_timing = t; break; + } case 'h': return help(); case 'V': @@ -1611,7 +1609,7 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg udev_builtin_init(); - manager->rules = udev_rules_new(arg_resolve_names); + manager->rules = udev_rules_new(arg_resolve_name_timing); if (!manager->rules) return log_error_errno(ENOMEM, "error reading rules");