Skip to content

Commit

Permalink
Merge pull request systemd#10603 from yuwata/udevd-parser
Browse files Browse the repository at this point in the history
udevd: several cleanups for parsing options
  • Loading branch information
poettering committed Nov 12, 2018
2 parents cd0504a + 6f19b42 commit 60d540f
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 144 deletions.
1 change: 0 additions & 1 deletion src/libudev/libudev-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ void udev_list_entry_set_num(struct udev_list_entry *list_entry, int num);
#define UTIL_NAME_SIZE 512
#define UTIL_LINE_SIZE 16384
#define UDEV_ALLOWED_CHARS_INPUT "/ $%?,"
int util_log_priority(const char *priority);
size_t util_path_encode(const char *src, char *dest, size_t size);
int util_replace_whitespace(const char *str, char *to, size_t len);
int util_replace_chars(char *str, const char *white);
Expand Down
16 changes: 0 additions & 16 deletions src/libudev/libudev-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "MurmurHash2.h"
#include "device-nodes.h"
#include "libudev-private.h"
#include "syslog-util.h"
#include "utf8.h"

/**
Expand Down Expand Up @@ -84,21 +83,6 @@ int util_resolve_subsys_kernel(const char *string,
return 0;
}

int util_log_priority(const char *priority) {
char *endptr;
int prio;

prio = strtoul(priority, &endptr, 10);
if (endptr[0] == '\0' || isspace(endptr[0])) {
if (prio >= 0 && prio <= 7)
return prio;
else
return -ERANGE;
}

return log_level_from_string(priority);
}

size_t util_path_encode(const char *src, char *dest, size_t size) {
size_t i, j;

Expand Down
2 changes: 1 addition & 1 deletion src/test/test-udev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions src/udev/udev-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ typedef struct Spawn {
size_t result_len;
} Spawn;

struct udev_event *udev_event_new(sd_device *dev, int exec_delay, sd_netlink *rtnl) {
struct udev_event *udev_event_new(sd_device *dev, usec_t exec_delay_usec, sd_netlink *rtnl) {
struct udev_event *event;

assert(dev);
Expand All @@ -54,7 +54,7 @@ struct udev_event *udev_event_new(sd_device *dev, int exec_delay, sd_netlink *rt
*event = (struct udev_event) {
.dev = sd_device_ref(dev),
.birth_usec = now(CLOCK_MONOTONIC),
.exec_delay = exec_delay,
.exec_delay_usec = exec_delay_usec,
.rtnl = sd_netlink_ref(rtnl),
};

Expand Down Expand Up @@ -896,9 +896,9 @@ void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_
if (builtin_cmd >= 0 && builtin_cmd < _UDEV_BUILTIN_MAX)
udev_builtin_run(event->dev, builtin_cmd, command, false);
else {
if (event->exec_delay > 0) {
if (event->exec_delay_usec > 0) {
log_debug("delay execution of '%s'", command);
sleep(event->exec_delay);
(void) usleep(event->exec_delay_usec);
}

udev_event_spawn(event, timeout_usec, timeout_warn_usec, false, command, NULL, 0);
Expand Down
25 changes: 18 additions & 7 deletions src/udev/udev-rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -2598,3 +2601,11 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) {

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);
17 changes: 14 additions & 3 deletions src/udev/udev.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct udev_event {
gid_t gid;
Hashmap *seclabel_list;
Hashmap *run_list;
int exec_delay;
usec_t exec_delay_usec;
usec_t birth_usec;
sd_netlink *rtnl;
unsigned builtin_run;
Expand All @@ -48,18 +48,29 @@ 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,
usec_t timeout_usec, usec_t timeout_warn_usec,
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, int exec_delay, sd_netlink *rtnl);
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);
ssize_t udev_event_apply_format(struct udev_event *event,
const char *src, char *dest, size_t size,
Expand Down
15 changes: 6 additions & 9 deletions src/udev/udevadm-control.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
#include <string.h>
#include <unistd.h>

#include "libudev-private.h"
#include "parse-util.h"
#include "process-util.h"
#include "syslog-util.h"
#include "time-util.h"
#include "udevadm.h"
#include "udev-ctrl.h"
Expand Down Expand Up @@ -84,18 +84,15 @@ int control_main(int argc, char *argv[], void *userdata) {
if (r < 0)
return r;
break;
case 'l': {
int i;

i = util_log_priority(optarg);
if (i < 0)
return log_error_errno(i, "invalid number '%s'", optarg);
case 'l':
r = log_level_from_string(optarg);
if (r < 0)
return log_error_errno(r, "Failed to parse log priority '%s': %m", optarg);

r = udev_ctrl_send_set_log_level(uctrl, i, timeout);
r = udev_ctrl_send_set_log_level(uctrl, r, timeout);
if (r < 0)
return r;
break;
}
case 's':
r = udev_ctrl_send_stop_exec_queue(uctrl, timeout);
if (r < 0)
Expand Down
15 changes: 5 additions & 10 deletions src/udev/udevadm-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit 60d540f

Please sign in to comment.