udev: modernize udev-rules.c

This does the following:
- rename enum udev_builtin_cmd -> UdevBuiltinCmd
- rename struct udev_builtin -> UdevBuiltin
- move type definitions to udev-rules.h
- move prototypes of functions defined in udev-rules.c to udev-rules.h
- drop to use strbuf
- propagate critical errors in applying rules,
- drop limitation for number of tokens per line.
This commit is contained in:
Yu Watanabe
2019-06-02 14:15:26 +09:00
parent 7e4831d296
commit 25de7aa7b9
24 changed files with 2155 additions and 2471 deletions
+1 -1
View File
@@ -14,7 +14,7 @@
#include "rm-rf.h" #include "rm-rf.h"
#include "string-util.h" #include "string-util.h"
#include "tests.h" #include "tests.h"
#include "udev.h" #include "udev-rules.h"
static struct fakefs { static struct fakefs {
const char *target; const char *target;
-2
View File
@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
#include <errno.h> #include <errno.h>
#include <string.h>
#include "alloc-util.h" #include "alloc-util.h"
#include "env-file.h" #include "env-file.h"
@@ -10,7 +9,6 @@
#include "string-table.h" #include "string-table.h"
#include "string-util.h" #include "string-util.h"
#include "udev-util.h" #include "udev-util.h"
#include "udev.h"
static const char* const resolve_name_timing_table[_RESOLVE_NAME_TIMING_MAX] = { static const char* const resolve_name_timing_table[_RESOLVE_NAME_TIMING_MAX] = {
[RESOLVE_NAME_NEVER] = "never", [RESOLVE_NAME_NEVER] = "never",
+1 -1
View File
@@ -22,7 +22,7 @@
#include "signal-util.h" #include "signal-util.h"
#include "string-util.h" #include "string-util.h"
#include "tests.h" #include "tests.h"
#include "udev.h" #include "udev-event.h"
static int fake_filesystems(void) { static int fake_filesystems(void) {
static const struct fakefs { static const struct fakefs {
+2 -2
View File
@@ -18,13 +18,14 @@ udevadm_sources = files('''
systemd_udevd_sources = files('udevd.c') systemd_udevd_sources = files('udevd.c')
libudev_core_sources = ''' libudev_core_sources = '''
udev.h
udev-ctrl.c udev-ctrl.c
udev-ctrl.h udev-ctrl.h
udev-event.c udev-event.c
udev-event.h
udev-node.c udev-node.c
udev-node.h udev-node.h
udev-rules.c udev-rules.c
udev-rules.h
udev-watch.c udev-watch.c
udev-watch.h udev-watch.h
udev-builtin.c udev-builtin.c
@@ -117,7 +118,6 @@ libudev_basic = static_library(
libudev_static = static_library( libudev_static = static_library(
'udev_static', 'udev_static',
'udev.h',
include_directories : includes, include_directories : includes,
link_with : udev_link_with, link_with : udev_link_with,
link_whole : libudev_basic) link_whole : libudev_basic)
+1 -1
View File
@@ -310,7 +310,7 @@ static int builtin_blkid(sd_device *dev, int argc, char *argv[], bool test) {
return 0; return 0;
} }
const struct udev_builtin udev_builtin_blkid = { const UdevBuiltin udev_builtin_blkid = {
.name = "blkid", .name = "blkid",
.cmd = builtin_blkid, .cmd = builtin_blkid,
.help = "Filesystem and partition probing", .help = "Filesystem and partition probing",
+1 -1
View File
@@ -33,7 +33,7 @@ static int builtin_btrfs(sd_device *dev, int argc, char *argv[], bool test) {
return 0; return 0;
} }
const struct udev_builtin udev_builtin_btrfs = { const UdevBuiltin udev_builtin_btrfs = {
.name = "btrfs", .name = "btrfs",
.cmd = builtin_btrfs, .cmd = builtin_btrfs,
.help = "btrfs volume management", .help = "btrfs volume management",
+1 -1
View File
@@ -208,7 +208,7 @@ static bool builtin_hwdb_validate(void) {
return hwdb_validate(hwdb); return hwdb_validate(hwdb);
} }
const struct udev_builtin udev_builtin_hwdb = { const UdevBuiltin udev_builtin_hwdb = {
.name = "hwdb", .name = "hwdb",
.cmd = builtin_hwdb, .cmd = builtin_hwdb,
.init = builtin_hwdb_init, .init = builtin_hwdb_init,
+1 -1
View File
@@ -357,7 +357,7 @@ static int builtin_input_id(sd_device *dev, int argc, char *argv[], bool test) {
return 0; return 0;
} }
const struct udev_builtin udev_builtin_input_id = { const UdevBuiltin udev_builtin_input_id = {
.name = "input_id", .name = "input_id",
.cmd = builtin_input_id, .cmd = builtin_input_id,
.help = "Input device properties", .help = "Input device properties",
+1 -1
View File
@@ -251,7 +251,7 @@ static int builtin_keyboard(sd_device *dev, int argc, char *argv[], bool test) {
return 0; return 0;
} }
const struct udev_builtin udev_builtin_keyboard = { const UdevBuiltin udev_builtin_keyboard = {
.name = "keyboard", .name = "keyboard",
.cmd = builtin_keyboard, .cmd = builtin_keyboard,
.help = "Keyboard scan code to key mapping", .help = "Keyboard scan code to key mapping",
+1 -1
View File
@@ -66,7 +66,7 @@ static bool builtin_kmod_validate(void) {
return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK); return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK);
} }
const struct udev_builtin udev_builtin_kmod = { const UdevBuiltin udev_builtin_kmod = {
.name = "kmod", .name = "kmod",
.cmd = builtin_kmod, .cmd = builtin_kmod,
.init = builtin_kmod_init, .init = builtin_kmod_init,
+1 -1
View File
@@ -927,7 +927,7 @@ static int builtin_net_id(sd_device *dev, int argc, char *argv[], bool test) {
return 0; return 0;
} }
const struct udev_builtin udev_builtin_net_id = { const UdevBuiltin udev_builtin_net_id = {
.name = "net_id", .name = "net_id",
.cmd = builtin_net_id, .cmd = builtin_net_id,
.help = "Network device properties", .help = "Network device properties",
+1 -1
View File
@@ -74,7 +74,7 @@ static bool builtin_net_setup_link_validate(void) {
return link_config_should_reload(ctx); return link_config_should_reload(ctx);
} }
const struct udev_builtin udev_builtin_net_setup_link = { const UdevBuiltin udev_builtin_net_setup_link = {
.name = "net_setup_link", .name = "net_setup_link",
.cmd = builtin_net_setup_link, .cmd = builtin_net_setup_link,
.init = builtin_net_setup_link_init, .init = builtin_net_setup_link_init,
+1 -1
View File
@@ -675,7 +675,7 @@ static int builtin_path_id(sd_device *dev, int argc, char *argv[], bool test) {
return 0; return 0;
} }
const struct udev_builtin udev_builtin_path_id = { const UdevBuiltin udev_builtin_path_id = {
.name = "path_id", .name = "path_id",
.cmd = builtin_path_id, .cmd = builtin_path_id,
.help = "Compose persistent device path", .help = "Compose persistent device path",
+1 -1
View File
@@ -73,7 +73,7 @@ finish:
return r; return r;
} }
const struct udev_builtin udev_builtin_uaccess = { const UdevBuiltin udev_builtin_uaccess = {
.name = "uaccess", .name = "uaccess",
.cmd = builtin_uaccess, .cmd = builtin_uaccess,
.help = "Manage device node user ACL", .help = "Manage device node user ACL",
+1 -1
View File
@@ -455,7 +455,7 @@ fallback:
return 0; return 0;
} }
const struct udev_builtin udev_builtin_usb_id = { const UdevBuiltin udev_builtin_usb_id = {
.name = "usb_id", .name = "usb_id",
.cmd = builtin_usb_id, .cmd = builtin_usb_id,
.help = "USB device properties", .help = "USB device properties",
+6 -6
View File
@@ -12,7 +12,7 @@
static bool initialized; static bool initialized;
static const struct udev_builtin *const builtins[_UDEV_BUILTIN_MAX] = { static const UdevBuiltin *const builtins[_UDEV_BUILTIN_MAX] = {
#if HAVE_BLKID #if HAVE_BLKID
[UDEV_BUILTIN_BLKID] = &udev_builtin_blkid, [UDEV_BUILTIN_BLKID] = &udev_builtin_blkid,
#endif #endif
@@ -75,7 +75,7 @@ void udev_builtin_list(void) {
fprintf(stderr, " %-14s %s\n", builtins[i]->name, builtins[i]->help); fprintf(stderr, " %-14s %s\n", builtins[i]->name, builtins[i]->help);
} }
const char *udev_builtin_name(enum udev_builtin_cmd cmd) { const char *udev_builtin_name(UdevBuiltinCommand cmd) {
assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX); assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX);
if (!builtins[cmd]) if (!builtins[cmd])
@@ -84,7 +84,7 @@ const char *udev_builtin_name(enum udev_builtin_cmd cmd) {
return builtins[cmd]->name; return builtins[cmd]->name;
} }
bool udev_builtin_run_once(enum udev_builtin_cmd cmd) { bool udev_builtin_run_once(UdevBuiltinCommand cmd) {
assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX); assert(cmd >= 0 && cmd < _UDEV_BUILTIN_MAX);
if (!builtins[cmd]) if (!builtins[cmd])
@@ -93,8 +93,8 @@ bool udev_builtin_run_once(enum udev_builtin_cmd cmd) {
return builtins[cmd]->run_once; return builtins[cmd]->run_once;
} }
enum udev_builtin_cmd udev_builtin_lookup(const char *command) { UdevBuiltinCommand udev_builtin_lookup(const char *command) {
enum udev_builtin_cmd i; UdevBuiltinCommand i;
size_t n; size_t n;
assert(command); assert(command);
@@ -108,7 +108,7 @@ enum udev_builtin_cmd udev_builtin_lookup(const char *command) {
return _UDEV_BUILTIN_INVALID; return _UDEV_BUILTIN_INVALID;
} }
int udev_builtin_run(sd_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test) { int udev_builtin_run(sd_device *dev, UdevBuiltinCommand cmd, const char *command, bool test) {
_cleanup_strv_free_ char **argv = NULL; _cleanup_strv_free_ char **argv = NULL;
assert(dev); assert(dev);
+22 -19
View File
@@ -5,7 +5,7 @@
#include "sd-device.h" #include "sd-device.h"
enum udev_builtin_cmd { typedef enum {
#if HAVE_BLKID #if HAVE_BLKID
UDEV_BUILTIN_BLKID, UDEV_BUILTIN_BLKID,
#endif #endif
@@ -25,9 +25,9 @@ enum udev_builtin_cmd {
#endif #endif
_UDEV_BUILTIN_MAX, _UDEV_BUILTIN_MAX,
_UDEV_BUILTIN_INVALID = -1, _UDEV_BUILTIN_INVALID = -1,
}; } UdevBuiltinCommand;
struct udev_builtin { typedef struct UdevBuiltin {
const char *name; const char *name;
int (*cmd)(sd_device *dev, int argc, char *argv[], bool test); int (*cmd)(sd_device *dev, int argc, char *argv[], bool test);
const char *help; const char *help;
@@ -35,32 +35,35 @@ struct udev_builtin {
void (*exit)(void); void (*exit)(void);
bool (*validate)(void); bool (*validate)(void);
bool run_once; bool run_once;
}; } UdevBuiltin;
#define PTR_TO_UDEV_BUILTIN_CMD(p) ((UdevBuiltinCommand) ((intptr_t) (p)-1))
#define UDEV_BUILTIN_CMD_TO_PTR(u) ((void *) ((intptr_t) (u)+1))
#if HAVE_BLKID #if HAVE_BLKID
extern const struct udev_builtin udev_builtin_blkid; extern const UdevBuiltin udev_builtin_blkid;
#endif #endif
extern const struct udev_builtin udev_builtin_btrfs; extern const UdevBuiltin udev_builtin_btrfs;
extern const struct udev_builtin udev_builtin_hwdb; extern const UdevBuiltin udev_builtin_hwdb;
extern const struct udev_builtin udev_builtin_input_id; extern const UdevBuiltin udev_builtin_input_id;
extern const struct udev_builtin udev_builtin_keyboard; extern const UdevBuiltin udev_builtin_keyboard;
#if HAVE_KMOD #if HAVE_KMOD
extern const struct udev_builtin udev_builtin_kmod; extern const UdevBuiltin udev_builtin_kmod;
#endif #endif
extern const struct udev_builtin udev_builtin_net_id; extern const UdevBuiltin udev_builtin_net_id;
extern const struct udev_builtin udev_builtin_net_setup_link; extern const UdevBuiltin udev_builtin_net_setup_link;
extern const struct udev_builtin udev_builtin_path_id; extern const UdevBuiltin udev_builtin_path_id;
extern const struct udev_builtin udev_builtin_usb_id; extern const UdevBuiltin udev_builtin_usb_id;
#if HAVE_ACL #if HAVE_ACL
extern const struct udev_builtin udev_builtin_uaccess; extern const UdevBuiltin udev_builtin_uaccess;
#endif #endif
void udev_builtin_init(void); void udev_builtin_init(void);
void udev_builtin_exit(void); void udev_builtin_exit(void);
enum udev_builtin_cmd udev_builtin_lookup(const char *command); UdevBuiltinCommand udev_builtin_lookup(const char *command);
const char *udev_builtin_name(enum udev_builtin_cmd cmd); const char *udev_builtin_name(UdevBuiltinCommand cmd);
bool udev_builtin_run_once(enum udev_builtin_cmd cmd); bool udev_builtin_run_once(UdevBuiltinCommand cmd);
int udev_builtin_run(sd_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test); int udev_builtin_run(sd_device *dev, UdevBuiltinCommand cmd, const char *command, bool test);
void udev_builtin_list(void); void udev_builtin_list(void);
bool udev_builtin_validate(void); bool udev_builtin_validate(void);
int udev_builtin_add_property(sd_device *dev, bool test, const char *key, const char *val); int udev_builtin_add_property(sd_device *dev, bool test, const char *key, const char *val);
+36 -14
View File
@@ -16,6 +16,7 @@
#include "device-private.h" #include "device-private.h"
#include "device-util.h" #include "device-util.h"
#include "fd-util.h" #include "fd-util.h"
#include "fs-util.h"
#include "format-util.h" #include "format-util.h"
#include "libudev-util.h" #include "libudev-util.h"
#include "netlink-util.h" #include "netlink-util.h"
@@ -28,10 +29,11 @@
#include "strv.h" #include "strv.h"
#include "strxcpyx.h" #include "strxcpyx.h"
#include "udev-builtin.h" #include "udev-builtin.h"
#include "udev-event.h"
#include "udev-node.h" #include "udev-node.h"
#include "udev-util.h" #include "udev-util.h"
#include "udev-watch.h" #include "udev-watch.h"
#include "udev.h" #include "user-util.h"
typedef struct Spawn { typedef struct Spawn {
const char *cmd; const char *cmd;
@@ -61,6 +63,9 @@ UdevEvent *udev_event_new(sd_device *dev, usec_t exec_delay_usec, sd_netlink *rt
.birth_usec = now(CLOCK_MONOTONIC), .birth_usec = now(CLOCK_MONOTONIC),
.exec_delay_usec = exec_delay_usec, .exec_delay_usec = exec_delay_usec,
.rtnl = sd_netlink_ref(rtnl), .rtnl = sd_netlink_ref(rtnl),
.uid = UID_INVALID,
.gid = GID_INVALID,
.mode = MODE_INVALID,
}; };
return event; return event;
@@ -753,19 +758,23 @@ static int update_devnode(UdevEvent *event) {
if (event->dev_db_clone) if (event->dev_db_clone)
(void) udev_node_update_old_links(dev, event->dev_db_clone); (void) udev_node_update_old_links(dev, event->dev_db_clone);
if (!event->owner_set) { if (!uid_is_valid(event->uid)) {
r = device_get_devnode_uid(dev, &event->uid); r = device_get_devnode_uid(dev, &event->uid);
if (r < 0 && r != -ENOENT) if (r == -ENOENT)
event->uid = 0;
else if (r < 0)
return log_device_error_errno(dev, r, "Failed to get devnode UID: %m"); return log_device_error_errno(dev, r, "Failed to get devnode UID: %m");
} }
if (!event->group_set) { if (!gid_is_valid(event->gid)) {
r = device_get_devnode_gid(dev, &event->gid); r = device_get_devnode_gid(dev, &event->gid);
if (r < 0 && r != -ENOENT) if (r == -ENOENT)
event->gid = 0;
else if (r < 0)
return log_device_error_errno(dev, r, "Failed to get devnode GID: %m"); return log_device_error_errno(dev, r, "Failed to get devnode GID: %m");
} }
if (!event->mode_set) { if (event->mode == MODE_INVALID) {
r = device_get_devnode_mode(dev, &event->mode); r = device_get_devnode_mode(dev, &event->mode);
if (r < 0 && r != -ENOENT) if (r < 0 && r != -ENOENT)
return log_device_error_errno(dev, r, "Failed to get devnode mode: %m"); return log_device_error_errno(dev, r, "Failed to get devnode mode: %m");
@@ -779,7 +788,10 @@ static int update_devnode(UdevEvent *event) {
} }
} }
apply = device_for_action(dev, DEVICE_ACTION_ADD) || event->owner_set || event->group_set || event->mode_set; apply = device_for_action(dev, DEVICE_ACTION_ADD) ||
uid_is_valid(event->uid) ||
gid_is_valid(event->gid) ||
event->mode != MODE_INVALID;
return udev_node_add(dev, apply, event->mode, event->uid, event->gid, event->seclabel_list); return udev_node_add(dev, apply, event->mode, event->uid, event->gid, event->seclabel_list);
} }
@@ -900,22 +912,32 @@ void udev_event_execute_run(UdevEvent *event, usec_t timeout_usec) {
const char *cmd; const char *cmd;
void *val; void *val;
Iterator i; Iterator i;
int r;
ORDERED_HASHMAP_FOREACH_KEY(val, cmd, event->run_list, i) { ORDERED_HASHMAP_FOREACH_KEY(val, cmd, event->run_list, i) {
enum udev_builtin_cmd builtin_cmd = PTR_TO_INT(val); UdevBuiltinCommand builtin_cmd = PTR_TO_UDEV_BUILTIN_CMD(val);
char command[UTIL_PATH_SIZE]; char command[UTIL_PATH_SIZE];
udev_event_apply_format(event, cmd, command, sizeof(command), false); (void) udev_event_apply_format(event, cmd, command, sizeof(command), false);
if (builtin_cmd >= 0 && builtin_cmd < _UDEV_BUILTIN_MAX) if (builtin_cmd != _UDEV_BUILTIN_INVALID) {
udev_builtin_run(event->dev, builtin_cmd, command, false); log_device_debug(event->dev, "Running built-in command \"%s\"", command);
else { r = udev_builtin_run(event->dev, builtin_cmd, command, false);
if (r < 0)
log_device_debug_errno(event->dev, r, "Failed to run built-in command \"%s\", ignoring: %m", command);
} else {
if (event->exec_delay_usec > 0) { if (event->exec_delay_usec > 0) {
log_debug("delay execution of '%s'", command); char buf[FORMAT_TIMESPAN_MAX];
log_device_debug(event->dev, "Delaying execution of \"%s\" for %s.",
command, format_timespan(buf, sizeof(buf), event->exec_delay_usec, USEC_PER_SEC));
(void) usleep(event->exec_delay_usec); (void) usleep(event->exec_delay_usec);
} }
(void) udev_event_spawn(event, timeout_usec, false, command, NULL, 0); log_device_debug(event->dev, "Running command \"%s\"", command);
r = udev_event_spawn(event, timeout_usec, false, command, NULL, 0);
if (r > 0) /* returned value is positive when program fails */
log_device_debug(event->dev, "Command \"%s\" returned %d (error), ignoring.", command, r);
} }
} }
} }
+15 -31
View File
@@ -10,6 +10,7 @@
#include "hashmap.h" #include "hashmap.h"
#include "macro.h" #include "macro.h"
#include "udev-rules.h"
#include "udev-util.h" #include "udev-util.h"
#include "util.h" #include "util.h"
@@ -32,38 +33,21 @@ typedef struct UdevEvent {
sd_netlink *rtnl; sd_netlink *rtnl;
unsigned builtin_run; unsigned builtin_run;
unsigned builtin_ret; unsigned builtin_ret;
bool inotify_watch; UdevRuleEscapeType esc:8;
bool inotify_watch_final; bool inotify_watch:1;
bool group_set; bool inotify_watch_final:1;
bool group_final; bool group_final:1;
bool owner_set; bool owner_final:1;
bool owner_final; bool mode_final:1;
bool mode_set; bool name_final:1;
bool mode_final; bool devlink_final:1;
bool name_final; bool run_final:1;
bool devlink_final;
bool run_final;
} UdevEvent; } UdevEvent;
/* udev-rules.c */
typedef struct UdevRules UdevRules;
int udev_rules_new(UdevRules **ret_rules, ResolveNameTiming resolve_name_timing);
UdevRules *udev_rules_free(UdevRules *rules);
bool udev_rules_check_timestamp(UdevRules *rules);
int udev_rules_apply_to_event(UdevRules *rules, UdevEvent *event,
usec_t timeout_usec,
Hashmap *properties_list);
int udev_rules_apply_static_dev_perms(UdevRules *rules);
static inline usec_t udev_warn_timeout(usec_t timeout_usec) {
return DIV_ROUND_UP(timeout_usec, 3);
}
/* udev-event.c */
UdevEvent *udev_event_new(sd_device *dev, usec_t exec_delay_usec, sd_netlink *rtnl); UdevEvent *udev_event_new(sd_device *dev, usec_t exec_delay_usec, sd_netlink *rtnl);
UdevEvent *udev_event_free(UdevEvent *event); UdevEvent *udev_event_free(UdevEvent *event);
DEFINE_TRIVIAL_CLEANUP_FUNC(UdevEvent*, udev_event_free);
ssize_t udev_event_apply_format(UdevEvent *event, ssize_t udev_event_apply_format(UdevEvent *event,
const char *src, char *dest, size_t size, const char *src, char *dest, size_t size,
bool replace_whitespace); bool replace_whitespace);
@@ -77,6 +61,6 @@ int udev_event_execute_rules(UdevEvent *event,
UdevRules *rules); UdevRules *rules);
void udev_event_execute_run(UdevEvent *event, usec_t timeout_usec); void udev_event_execute_run(UdevEvent *event, usec_t timeout_usec);
/* Cleanup functions */ static inline usec_t udev_warn_timeout(usec_t timeout_usec) {
DEFINE_TRIVIAL_CLEANUP_FUNC(UdevEvent*, udev_event_free); return DIV_ROUND_UP(timeout_usec, 3);
DEFINE_TRIVIAL_CLEANUP_FUNC(UdevRules*, udev_rules_free); }
+1841 -2381
View File
File diff suppressed because it is too large Load Diff
+217
View File
@@ -0,0 +1,217 @@
/* SPDX-License-Identifier: GPL-2.0+ */
#pragma once
#include "device-util.h"
#include "hashmap.h"
#include "list.h"
#include "time-util.h"
#include "udev-util.h"
typedef struct UdevRules UdevRules;
typedef struct UdevRuleFile UdevRuleFile;
typedef struct UdevRuleLine UdevRuleLine;
typedef struct UdevRuleToken UdevRuleToken;
typedef struct UdevEvent UdevEvent;
typedef enum {
OP_MATCH, /* == */
OP_NOMATCH, /* != */
OP_ADD, /* += */
OP_REMOVE, /* -= */
OP_ASSIGN, /* = */
OP_ASSIGN_FINAL, /* := */
_OP_TYPE_MAX,
_OP_TYPE_INVALID = -1
} UdevRuleOperatorType;
typedef enum {
MATCH_TYPE_EMPTY, /* empty string */
MATCH_TYPE_PLAIN, /* no special characters */
MATCH_TYPE_GLOB, /* shell globs ?,*,[] */
MATCH_TYPE_SUBSYSTEM, /* "subsystem", "bus", or "class" */
_MATCH_TYPE_MAX,
_MATCH_TYPE_INVALID = -1
} UdevRuleMatchType;
typedef enum {
SUBST_TYPE_PLAIN, /* no substitution */
SUBST_TYPE_FORMAT, /* % or $ */
SUBST_TYPE_SUBSYS, /* "[<SUBSYSTEM>/<KERNEL>]<attribute>" format */
_SUBST_TYPE_MAX,
_SUBST_TYPE_INVALID = -1
} UdevRuleSubstituteType;
typedef enum {
ESCAPE_UNSET,
ESCAPE_NONE, /* OPTIONS="string_escape=none" */
ESCAPE_REPLACE, /* OPTIONS="string_escape=replace" */
_ESCAPE_TYPE_MAX,
_ESCAPE_TYPE_INVALID = -1
} UdevRuleEscapeType;
typedef enum {
/* lvalues which take match or nomatch operator */
TK_M_ACTION, /* string, device_get_action() */
TK_M_DEVPATH, /* path, sd_device_get_devpath() */
TK_M_KERNEL, /* string, sd_device_get_sysname() */
TK_M_DEVLINK, /* strv, sd_device_get_devlink_first(), sd_device_get_devlink_next() */
TK_M_NAME, /* string, name of network interface */
TK_M_ENV, /* string, device property, takes key through attribute */
TK_M_TAG, /* strv, sd_device_get_tag_first(), sd_device_get_tag_next() */
TK_M_SUBSYSTEM, /* string, sd_device_get_subsystem() */
TK_M_DRIVER, /* string, sd_device_get_driver() */
TK_M_ATTR, /* string, takes filename through attribute, sd_device_get_sysattr_value(), util_resolve_subsys_kernel(), etc. */
TK_M_SYSCTL, /* string, takes kernel parameter through attribute */
/* matches parent paramters */
TK_M_PARENTS_KERNEL, /* string */
TK_M_PARENTS_SUBSYSTEM, /* string */
TK_M_PARENTS_DRIVER, /* string */
TK_M_PARENTS_ATTR, /* string */
TK_M_PARENTS_TAG, /* strv */
TK_M_TEST, /* path, optionally mode_t can be specified by attribute, test the existence of a file */
TK_M_PROGRAM, /* string, execute a program */
TK_M_IMPORT_FILE, /* path */
TK_M_IMPORT_PROGRAM, /* string, import properties from the result of program */
TK_M_IMPORT_BUILTIN, /* string, import properties from the result of built-in command */
TK_M_IMPORT_DB, /* string, import properties from database */
TK_M_IMPORT_CMDLINE, /* string, kernel command line */
TK_M_IMPORT_PARENT, /* string, parent property */
TK_M_RESULT, /* string, result of TK_M_PROGRAM */
#define _TK_M_MAX (TK_M_RESULT + 1)
#define _TK_A_MIN _TK_M_MAX
/* lvalues which take one of assign operators */
TK_A_OPTIONS_STRING_ESCAPE_NONE, /* no argument */
TK_A_OPTIONS_STRING_ESCAPE_REPLACE, /* no argument */
TK_A_OPTIONS_DB_PERSIST, /* no argument */
TK_A_OPTIONS_INOTIFY_WATCH, /* boolean */
TK_A_OPTIONS_DEVLINK_PRIORITY, /* int */
TK_A_OWNER, /* user name */
TK_A_GROUP, /* group name */
TK_A_MODE, /* mode string */
TK_A_OWNER_ID, /* uid_t */
TK_A_GROUP_ID, /* gid_t */
TK_A_MODE_ID, /* mode_t */
TK_A_TAG, /* string */
TK_A_OPTIONS_STATIC_NODE, /* device path, /dev/... */
TK_A_SECLABEL, /* string with attribute */
TK_A_ENV, /* string with attribute */
TK_A_NAME, /* ifname */
TK_A_DEVLINK, /* string */
TK_A_ATTR, /* string with attribute */
TK_A_SYSCTL, /* string with attribute */
TK_A_RUN_BUILTIN, /* string */
TK_A_RUN_PROGRAM, /* string */
_TK_TYPE_MAX,
_TK_TYPE_INVALID = -1,
} UdevRuleTokenType;
typedef enum {
LINE_HAS_NAME = 1 << 0, /* has NAME= */
LINE_HAS_DEVLINK = 1 << 1, /* has SYMLINK=, OWNER=, GROUP= or MODE= */
LINE_HAS_STATIC_NODE = 1 << 2, /* has OPTIONS=static_node */
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 */
} UdevRuleLineType;
struct UdevRuleToken {
UdevRuleTokenType type:8;
UdevRuleOperatorType op:8;
UdevRuleMatchType match_type:8;
UdevRuleSubstituteType attr_subst_type:7;
bool attr_match_remove_trailing_whitespace:1;
const char *value;
void *data;
LIST_FIELDS(UdevRuleToken, tokens);
};
struct UdevRuleLine {
char *line;
unsigned line_number;
UdevRuleLineType type;
const char *label;
const char *goto_label;
UdevRuleLine *goto_line;
UdevRuleFile *rule_file;
UdevRuleToken *current_token;
LIST_HEAD(UdevRuleToken, tokens);
LIST_FIELDS(UdevRuleLine, rule_lines);
};
struct UdevRuleFile {
char *filename;
UdevRuleLine *current_line;
LIST_HEAD(UdevRuleLine, rule_lines);
LIST_FIELDS(UdevRuleFile, rule_files);
};
struct UdevRules {
usec_t dirs_ts_usec;
ResolveNameTiming resolve_name_timing;
Hashmap *known_users;
Hashmap *known_groups;
UdevRuleFile *current_file;
LIST_HEAD(UdevRuleFile, rule_files);
};
int udev_rules_new(UdevRules **ret_rules, ResolveNameTiming resolve_name_timing);
UdevRules *udev_rules_free(UdevRules *rules);
DEFINE_TRIVIAL_CLEANUP_FUNC(UdevRules*, udev_rules_free);
bool udev_rules_check_timestamp(UdevRules *rules);
int udev_rules_apply_to_event(UdevRules *rules, UdevEvent *event,
usec_t timeout_usec,
Hashmap *properties_list);
int udev_rules_apply_static_dev_perms(UdevRules *rules);
#define log_rule_full(device, rules, level, error, fmt, ...) \
({ \
UdevRules *_r = (rules); \
UdevRuleFile *_f = _r ? _r->current_file : NULL; \
UdevRuleLine *_l = _f ? _f->current_line : NULL; \
const char *_n = _f ? _f->filename : NULL; \
\
log_device_full(device, level, error, "%s:%u " fmt, \
strna(_n), _l ? _l->line_number : 0, \
##__VA_ARGS__); \
})
#define log_rule_debug(device, rules, ...) log_rule_full(device, rules, LOG_DEBUG, 0, ##__VA_ARGS__)
#define log_rule_info(device, rules, ...) log_rule_full(device, rules, LOG_INFO, 0, ##__VA_ARGS__)
#define log_rule_notice(device, rules, ...) log_rule_full(device, rules, LOG_NOTICE, 0, ##__VA_ARGS__)
#define log_rule_warning(device, rules, ...) log_rule_full(device, rules, LOG_WARNING, 0, ##__VA_ARGS__)
#define log_rule_error(device, rules, ...) log_rule_full(device, rules, LOG_ERR, 0, ##__VA_ARGS__)
#define log_rule_debug_errno(device, rules, error, ...) log_rule_full(device, rules, LOG_DEBUG, error, ##__VA_ARGS__)
#define log_rule_info_errno(device, rules, error, ...) log_rule_full(device, rules, LOG_INFO, error, ##__VA_ARGS__)
#define log_rule_notice_errno(device, rules, error, ...) log_rule_full(device, rules, LOG_NOTICE, error, ##__VA_ARGS__)
#define log_rule_warning_errno(device, rules, error, ...) log_rule_full(device, rules, LOG_WARNING, error, ##__VA_ARGS__)
#define log_rule_error_errno(device, rules, error, ...) log_rule_full(device, rules, LOG_ERR, error, ##__VA_ARGS__)
#define log_token_full(rules, ...) log_rule_full(NULL, rules, ##__VA_ARGS__)
#define log_token_debug(rules, ...) log_token_full(rules, LOG_DEBUG, 0, ##__VA_ARGS__)
#define log_token_info(rules, ...) log_token_full(rules, LOG_INFO, 0, ##__VA_ARGS__)
#define log_token_notice(rules, ...) log_token_full(rules, LOG_NOTICE, 0, ##__VA_ARGS__)
#define log_token_warning(rules, ...) log_token_full(rules, LOG_WARNING, 0, ##__VA_ARGS__)
#define log_token_error(rules, ...) log_token_full(rules, LOG_ERR, 0, ##__VA_ARGS__)
#define log_token_debug_errno(rules, error, ...) log_token_full(rules, LOG_DEBUG, error, ##__VA_ARGS__)
#define log_token_info_errno(rules, error, ...) log_token_full(rules, LOG_INFO, error, ##__VA_ARGS__)
#define log_token_notice_errno(rules, error, ...) log_token_full(rules, LOG_NOTICE, error, ##__VA_ARGS__)
#define log_token_warning_errno(rules, error, ...) log_token_full(rules, LOG_WARNING, error, ##__VA_ARGS__)
#define log_token_error_errno(rules, error, ...) log_token_full(rules, LOG_ERR, error, ##__VA_ARGS__)
#define _log_token_invalid(rules, key, type) \
log_token_error_errno(rules, SYNTHETIC_ERRNO(EINVAL), \
"Invalid %s for %s.", type, key)
#define log_token_invalid_op(rules, key) _log_token_invalid(rules, key, "operator")
#define log_token_invalid_attr(rules, key) _log_token_invalid(rules, key, "attribute")
+1 -1
View File
@@ -63,7 +63,7 @@ static int parse_argv(int argc, char *argv[]) {
int builtin_main(int argc, char *argv[], void *userdata) { int builtin_main(int argc, char *argv[], void *userdata) {
_cleanup_(sd_device_unrefp) sd_device *dev = NULL; _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
enum udev_builtin_cmd cmd; UdevBuiltinCommand cmd;
int r; int r;
log_set_max_level(LOG_DEBUG); log_set_max_level(LOG_DEBUG);
+1 -1
View File
@@ -20,7 +20,7 @@
#include "string-util.h" #include "string-util.h"
#include "strxcpyx.h" #include "strxcpyx.h"
#include "udev-builtin.h" #include "udev-builtin.h"
#include "udev.h" #include "udev-event.h"
#include "udevadm.h" #include "udevadm.h"
static const char *arg_action = "add"; static const char *arg_action = "add";
+1 -1
View File
@@ -64,9 +64,9 @@
#include "syslog-util.h" #include "syslog-util.h"
#include "udev-builtin.h" #include "udev-builtin.h"
#include "udev-ctrl.h" #include "udev-ctrl.h"
#include "udev-event.h"
#include "udev-util.h" #include "udev-util.h"
#include "udev-watch.h" #include "udev-watch.h"
#include "udev.h"
#include "user-util.h" #include "user-util.h"
#define WORKER_NUM_MAX 2048U #define WORKER_NUM_MAX 2048U