summaryrefslogtreecommitdiff
path: root/src/udev
diff options
context:
space:
mode:
Diffstat (limited to 'src/udev')
-rw-r--r--src/udev/net/link-config.c4
-rw-r--r--src/udev/udev-builtin-hwdb.c2
-rw-r--r--src/udev/udev-builtin-input_id.c146
-rw-r--r--src/udev/udev-builtin-keyboard.c6
-rw-r--r--src/udev/udev-builtin-net_id.c12
-rw-r--r--src/udev/udev-builtin-path_id.c30
-rw-r--r--src/udev/udev-builtin-usb_id.c2
-rw-r--r--src/udev/udev-event.c32
-rw-r--r--src/udev/udev-rules.c16
-rw-r--r--src/udev/udev.h11
-rw-r--r--src/udev/udevadm-test.c3
-rw-r--r--src/udev/udevd.c218
12 files changed, 292 insertions, 190 deletions
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index ce038abee5..5610b2808e 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -240,6 +240,10 @@ int link_config_get(link_config_ctx *ctx, struct udev_device *device,
link_config **ret) {
link_config *link;
+ assert(ctx);
+ assert(device);
+ assert(ret);
+
LIST_FOREACH(links, link, ctx->links) {
const char* attr_value;
diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c
index 5e0e7ebb11..7dfc74e6fa 100644
--- a/src/udev/udev-builtin-hwdb.c
+++ b/src/udev/udev-builtin-hwdb.c
@@ -85,6 +85,8 @@ static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device
bool last = false;
int r = 0;
+ assert(dev);
+
for (d = srcdev; d && !last; d = udev_device_get_parent(d)) {
const char *dsubsys;
const char *modalias = NULL;
diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
index b14190e423..e3fa4bc162 100644
--- a/src/udev/udev-builtin-input_id.c
+++ b/src/udev/udev-builtin-input_id.c
@@ -133,79 +133,99 @@ static bool test_pointers(struct udev_device *dev,
const unsigned long* bitmask_rel,
const unsigned long* bitmask_props,
bool test) {
- int is_mouse = 0;
- int is_touchpad = 0;
- bool ret = false;
-
- if (test_bit(INPUT_PROP_ACCELEROMETER, bitmask_props)) {
+ bool has_abs_coordinates = false;
+ bool has_rel_coordinates = false;
+ bool has_mt_coordinates = false;
+ bool has_joystick_axes_or_buttons = false;
+ bool is_direct = false;
+ bool has_touch = false;
+ bool has_3d_coordinates = false;
+ bool has_keys = false;
+ bool stylus_or_pen = false;
+ bool finger_but_no_pen = false;
+ bool has_mouse_button = false;
+ bool is_mouse = false;
+ bool is_touchpad = false;
+ bool is_touchscreen = false;
+ bool is_tablet = false;
+ bool is_joystick = false;
+ bool is_accelerometer = false;
+ bool is_pointing_stick= false;
+
+ has_keys = test_bit(EV_KEY, bitmask_ev);
+ has_abs_coordinates = test_bit(ABS_X, bitmask_abs) && test_bit(ABS_Y, bitmask_abs);
+ has_3d_coordinates = has_abs_coordinates && test_bit(ABS_Z, bitmask_abs);
+ is_accelerometer = test_bit(INPUT_PROP_ACCELEROMETER, bitmask_props);
+
+ if (!has_keys && has_3d_coordinates)
+ is_accelerometer = true;
+
+ if (is_accelerometer) {
udev_builtin_add_property(dev, test, "ID_INPUT_ACCELEROMETER", "1");
return true;
}
- if (!test_bit(EV_KEY, bitmask_ev)) {
- if (test_bit(EV_ABS, bitmask_ev) &&
- test_bit(ABS_X, bitmask_abs) &&
- test_bit(ABS_Y, bitmask_abs) &&
- test_bit(ABS_Z, bitmask_abs)) {
- udev_builtin_add_property(dev, test, "ID_INPUT_ACCELEROMETER", "1");
- ret = true;
- }
- return ret;
- }
-
- if (test_bit(EV_ABS, bitmask_ev) &&
- test_bit(ABS_X, bitmask_abs) && test_bit(ABS_Y, bitmask_abs)) {
- if (test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key)) {
- udev_builtin_add_property(dev, test, "ID_INPUT_TABLET", "1");
- ret = true;
- } else if (test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key)) {
- is_touchpad = 1;
- } else if (test_bit(BTN_MOUSE, bitmask_key)) {
+ is_pointing_stick = test_bit(INPUT_PROP_POINTING_STICK, bitmask_props);
+ stylus_or_pen = test_bit(BTN_STYLUS, bitmask_key) || test_bit(BTN_TOOL_PEN, bitmask_key);
+ finger_but_no_pen = test_bit(BTN_TOOL_FINGER, bitmask_key) && !test_bit(BTN_TOOL_PEN, bitmask_key);
+ has_mouse_button = test_bit(BTN_LEFT, bitmask_key);
+ has_rel_coordinates = test_bit(EV_REL, bitmask_ev) && test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel);
+ has_mt_coordinates = test_bit(ABS_MT_POSITION_X, bitmask_abs) && test_bit(ABS_MT_POSITION_Y, bitmask_abs);
+
+ /* unset has_mt_coordinates if devices claims to have all abs axis */
+ if(has_mt_coordinates && test_bit(ABS_MT_SLOT, bitmask_abs) && test_bit(ABS_MT_SLOT - 1, bitmask_abs))
+ has_mt_coordinates = false;
+ is_direct = test_bit(INPUT_PROP_DIRECT, bitmask_props);
+ has_touch = test_bit(BTN_TOUCH, bitmask_key);
+ /* joysticks don't necessarily have buttons; e. g.
+ * rudders/pedals are joystick-like, but buttonless; they have
+ * other fancy axes */
+ has_joystick_axes_or_buttons = test_bit(BTN_TRIGGER, bitmask_key) ||
+ test_bit(BTN_A, bitmask_key) ||
+ test_bit(BTN_1, bitmask_key) ||
+ test_bit(ABS_RX, bitmask_abs) ||
+ test_bit(ABS_RY, bitmask_abs) ||
+ test_bit(ABS_RZ, bitmask_abs) ||
+ test_bit(ABS_THROTTLE, bitmask_abs) ||
+ test_bit(ABS_RUDDER, bitmask_abs) ||
+ test_bit(ABS_WHEEL, bitmask_abs) ||
+ test_bit(ABS_GAS, bitmask_abs) ||
+ test_bit(ABS_BRAKE, bitmask_abs);
+
+ if (has_abs_coordinates) {
+ if (stylus_or_pen)
+ is_tablet = true;
+ else if (finger_but_no_pen && !is_direct)
+ is_touchpad = true;
+ else if (has_mouse_button)
/* This path is taken by VMware's USB mouse, which has
* absolute axes, but no touch/pressure button. */
- is_mouse = 1;
- } else if (test_bit(BTN_TOUCH, bitmask_key)) {
- udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHSCREEN", "1");
- ret = true;
- /* joysticks don't necessarily have to have buttons; e. g.
- * rudders/pedals are joystick-like, but buttonless; they have
- * other fancy axes */
- } else if (test_bit(BTN_TRIGGER, bitmask_key) ||
- test_bit(BTN_A, bitmask_key) ||
- test_bit(BTN_1, bitmask_key) ||
- test_bit(ABS_RX, bitmask_abs) ||
- test_bit(ABS_RY, bitmask_abs) ||
- test_bit(ABS_RZ, bitmask_abs) ||
- test_bit(ABS_THROTTLE, bitmask_abs) ||
- test_bit(ABS_RUDDER, bitmask_abs) ||
- test_bit(ABS_WHEEL, bitmask_abs) ||
- test_bit(ABS_GAS, bitmask_abs) ||
- test_bit(ABS_BRAKE, bitmask_abs)) {
- udev_builtin_add_property(dev, test, "ID_INPUT_JOYSTICK", "1");
- ret = true;
- }
+ is_mouse = true;
+ else if (has_touch)
+ is_touchscreen = true;
+ else if (has_joystick_axes_or_buttons)
+ is_joystick = true;
}
+ if (has_mt_coordinates && is_direct)
+ is_touchscreen = true;
- if (test_bit(INPUT_PROP_POINTING_STICK, bitmask_props)) {
- udev_builtin_add_property(dev, test, "ID_INPUT_POINTINGSTICK", "1");
- ret = true;
- }
+ if (has_rel_coordinates && has_mouse_button)
+ is_mouse = true;
- if (test_bit(EV_REL, bitmask_ev) &&
- test_bit(REL_X, bitmask_rel) && test_bit(REL_Y, bitmask_rel) &&
- test_bit(BTN_MOUSE, bitmask_key))
- is_mouse = 1;
-
- if (is_mouse) {
+ if (is_pointing_stick)
+ udev_builtin_add_property(dev, test, "ID_INPUT_POINTINGSTICK", "1");
+ if (is_mouse)
udev_builtin_add_property(dev, test, "ID_INPUT_MOUSE", "1");
- ret = true;
- }
- if (is_touchpad) {
+ if (is_touchpad)
udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHPAD", "1");
- ret = true;
- }
-
- return ret;
+ if (is_touchscreen)
+ udev_builtin_add_property(dev, test, "ID_INPUT_TOUCHSCREEN", "1");
+ if (is_joystick)
+ udev_builtin_add_property(dev, test, "ID_INPUT_JOYSTICK", "1");
+ if (is_tablet)
+ udev_builtin_add_property(dev, test, "ID_INPUT_TABLET", "1");
+
+ return is_tablet || is_mouse || is_touchpad || is_touchscreen || is_joystick || is_pointing_stick;
}
/* key like devices */
@@ -268,6 +288,8 @@ static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], boo
bool is_pointer;
bool is_key;
+ assert(dev);
+
/* walk up the parental chain until we find the real input device; the
* argument is very likely a subdevice of this, like eventN */
pdev = dev;
diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c
index ed990c58fb..01f3879f37 100644
--- a/src/udev/udev-builtin-keyboard.c
+++ b/src/udev/udev-builtin-keyboard.c
@@ -37,6 +37,9 @@ static int install_force_release(struct udev_device *dev, const unsigned *releas
unsigned i;
int ret;
+ assert(dev);
+ assert(release);
+
atkbd = udev_device_get_parent_with_subsystem_devtype(dev, "serio", NULL);
if (!atkbd)
return -ENODEV;
@@ -152,6 +155,9 @@ static void set_trackpoint_sensitivity(struct udev_device *dev, const char *valu
char val_s[DECIMAL_STR_MAX(int)];
int r, val_i;
+ assert(dev);
+ assert(value);
+
/* The sensitivity sysfs attr belongs to the serio parent device */
pdev = udev_device_get_parent_with_subsystem_devtype(dev, "serio", NULL);
if (!pdev) {
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index 448920507a..6e7e1271fb 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -276,6 +276,9 @@ out:
static int names_pci(struct udev_device *dev, struct netnames *names) {
struct udev_device *parent;
+ assert(dev);
+ assert(names);
+
parent = udev_device_get_parent(dev);
if (!parent)
return -ENOENT;
@@ -302,6 +305,9 @@ static int names_usb(struct udev_device *dev, struct netnames *names) {
size_t l;
char *s;
+ assert(dev);
+ assert(names);
+
usbdev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface");
if (!usbdev)
return -ENOENT;
@@ -350,6 +356,9 @@ static int names_bcma(struct udev_device *dev, struct netnames *names) {
struct udev_device *bcmadev;
unsigned int core;
+ assert(dev);
+ assert(names);
+
bcmadev = udev_device_get_parent_with_subsystem_devtype(dev, "bcma", NULL);
if (!bcmadev)
return -ENOENT;
@@ -371,6 +380,9 @@ static int names_ccw(struct udev_device *dev, struct netnames *names) {
size_t bus_id_len;
int rc;
+ assert(dev);
+ assert(names);
+
/* Retrieve the associated CCW device */
cdev = udev_device_get_parent(dev);
if (!cdev)
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
index b6749aab76..4ca0a69d7d 100644
--- a/src/udev/udev-builtin-path_id.c
+++ b/src/udev/udev-builtin-path_id.c
@@ -77,6 +77,9 @@ static int format_lun_number(struct udev_device *dev, char **path) {
static struct udev_device *skip_subsystem(struct udev_device *dev, const char *subsys) {
struct udev_device *parent = dev;
+ assert(dev);
+ assert(subsys);
+
while (parent != NULL) {
const char *subsystem;
@@ -96,6 +99,9 @@ static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent,
const char *port;
char *lun = NULL;
+ assert(parent);
+ assert(path);
+
targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
if (targetdev == NULL)
return NULL;
@@ -126,6 +132,9 @@ static struct udev_device *handle_scsi_sas_wide_port(struct udev_device *parent,
const char *sas_address;
char *lun = NULL;
+ assert(parent);
+ assert(path);
+
targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
if (targetdev == NULL)
return NULL;
@@ -169,6 +178,9 @@ static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **pa
const char *phy_count;
char *lun = NULL;
+ assert(parent);
+ assert(path);
+
targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
if (targetdev == NULL)
return NULL;
@@ -259,6 +271,9 @@ static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **
const char *port;
char *lun = NULL;
+ assert(parent);
+ assert(path);
+
/* find iscsi session */
transportdev = parent;
for (;;) {
@@ -316,6 +331,9 @@ static struct udev_device *handle_scsi_default(struct udev_device *parent, char
struct dirent *dent;
int basenum;
+ assert(parent);
+ assert(path);
+
hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
if (hostdev == NULL)
return NULL;
@@ -398,6 +416,9 @@ static struct udev_device *handle_scsi_hyperv(struct udev_device *parent, char *
char guid[38];
size_t i, k;
+ assert(parent);
+ assert(path);
+
hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
if (!hostdev)
return NULL;
@@ -555,6 +576,10 @@ static struct udev_device *handle_bcma(struct udev_device *parent, char **path)
static struct udev_device *handle_ccw(struct udev_device *parent, struct udev_device *dev, char **path) {
struct udev_device *scsi_dev;
+ assert(parent);
+ assert(dev);
+ assert(path);
+
scsi_dev = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device");
if (scsi_dev != NULL) {
const char *wwpn;
@@ -582,6 +607,8 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
bool supported_transport = false;
bool supported_parent = false;
+ assert(dev);
+
/* S390 ccw bus */
parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccw", NULL);
if (parent != NULL) {
@@ -638,7 +665,8 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
supported_parent = true;
}
- parent = udev_device_get_parent(parent);
+ if (parent)
+ parent = udev_device_get_parent(parent);
}
/*
diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c
index 462efc5c86..d309dc31cb 100644
--- a/src/udev/udev-builtin-usb_id.c
+++ b/src/udev/udev-builtin-usb_id.c
@@ -252,6 +252,8 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool
size_t l;
char *s;
+ assert(dev);
+
/* shortcut, if we are called directly for a "usb_device" type */
if (udev_device_get_devtype(dev) != NULL && streq(udev_device_get_devtype(dev), "usb_device")) {
dev_if_packed_info(dev, packed_if_str, sizeof(packed_if_str));
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index a5c3edbff8..8d17c5e1e3 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -119,6 +119,8 @@ size_t udev_event_apply_format(struct udev_event *event, const char *src, char *
char *s;
size_t l;
+ assert(dev);
+
from = src;
s = dest;
l = size;
@@ -383,7 +385,7 @@ out:
}
static int spawn_exec(struct udev_event *event,
- const char *cmd, char *const argv[], char **envp, const sigset_t *sigmask,
+ const char *cmd, char *const argv[], char **envp,
int fd_stdout, int fd_stderr) {
_cleanup_close_ int fd = -1;
@@ -411,9 +413,8 @@ static int spawn_exec(struct udev_event *event,
/* terminate child in case parent goes away */
prctl(PR_SET_PDEATHSIG, SIGTERM);
- /* restore original udev sigmask before exec */
- if (sigmask)
- sigprocmask(SIG_SETMASK, sigmask, NULL);
+ /* restore sigmask before exec */
+ (void) reset_signal_mask();
execve(argv[0], argv, envp);
@@ -630,9 +631,9 @@ static int spawn_wait(struct udev_event *event,
if (timeout_warn_usec > 0 && timeout_warn_usec < timeout_usec && age_usec < timeout_warn_usec) {
spawn.timeout_warn = timeout_warn_usec - age_usec;
- r = sd_event_add_time(e, NULL, clock_boottime_or_monotonic(),
- usec + spawn.timeout_warn, USEC_PER_SEC,
- on_spawn_timeout_warning, &spawn);
+ r = sd_event_add_time(e, NULL, clock_boottime_or_monotonic(),
+ usec + spawn.timeout_warn, USEC_PER_SEC,
+ on_spawn_timeout_warning, &spawn);
if (r < 0)
return r;
}
@@ -697,7 +698,7 @@ out:
int udev_event_spawn(struct udev_event *event,
usec_t timeout_usec,
usec_t timeout_warn_usec,
- const char *cmd, char **envp, const sigset_t *sigmask,
+ const char *cmd, char **envp,
char *result, size_t ressize) {
int outpipe[2] = {-1, -1};
int errpipe[2] = {-1, -1};
@@ -747,7 +748,7 @@ int udev_event_spawn(struct udev_event *event,
log_debug("starting '%s'", cmd);
- spawn_exec(event, cmd, argv, envp, sigmask,
+ spawn_exec(event, cmd, argv, envp,
outpipe[WRITE_END], errpipe[WRITE_END]);
_exit(2 );
@@ -809,8 +810,7 @@ static int rename_netif(struct udev_event *event) {
void udev_event_execute_rules(struct udev_event *event,
usec_t timeout_usec, usec_t timeout_warn_usec,
struct udev_list *properties_list,
- struct udev_rules *rules,
- const sigset_t *sigmask) {
+ struct udev_rules *rules) {
struct udev_device *dev = event->dev;
if (udev_device_get_subsystem(dev) == NULL)
@@ -826,8 +826,7 @@ void udev_event_execute_rules(struct udev_event *event,
udev_rules_apply_to_event(rules, event,
timeout_usec, timeout_warn_usec,
- properties_list,
- sigmask);
+ properties_list);
if (major(udev_device_get_devnum(dev)) != 0)
udev_node_remove(dev);
@@ -845,8 +844,7 @@ void udev_event_execute_rules(struct udev_event *event,
udev_rules_apply_to_event(rules, event,
timeout_usec, timeout_warn_usec,
- properties_list,
- sigmask);
+ properties_list);
/* rename a new network interface, if needed */
if (udev_device_get_ifindex(dev) > 0 && streq(udev_device_get_action(dev), "add") &&
@@ -909,7 +907,7 @@ void udev_event_execute_rules(struct udev_event *event,
}
}
-void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec, const sigset_t *sigmask) {
+void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec) {
struct udev_list_entry *list_entry;
udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) {
@@ -932,7 +930,7 @@ void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_
udev_event_apply_format(event, cmd, program, sizeof(program));
envp = udev_device_get_properties_envp(event->dev);
- udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, sigmask, NULL, 0);
+ udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, NULL, 0);
}
}
}
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index 4262119886..7be9a2311a 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -633,7 +633,7 @@ static int import_file_into_properties(struct udev_device *dev, const char *file
static int import_program_into_properties(struct udev_event *event,
usec_t timeout_usec,
usec_t timeout_warn_usec,
- const char *program, const sigset_t *sigmask) {
+ const char *program) {
struct udev_device *dev = event->dev;
char **envp;
char result[UTIL_LINE_SIZE];
@@ -641,7 +641,7 @@ static int import_program_into_properties(struct udev_event *event,
int err;
envp = udev_device_get_properties_envp(dev);
- err = udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, sigmask, result, sizeof(result));
+ err = udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, result, sizeof(result));
if (err < 0)
return err;
@@ -664,6 +664,9 @@ static int import_parent_into_properties(struct udev_device *dev, const char *fi
struct udev_device *dev_parent;
struct udev_list_entry *list_entry;
+ assert(dev);
+ assert(filter);
+
dev_parent = udev_device_get_parent(dev);
if (dev_parent == NULL)
return -1;
@@ -1892,8 +1895,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
struct udev_event *event,
usec_t timeout_usec,
usec_t timeout_warn_usec,
- struct udev_list *properties_list,
- const sigset_t *sigmask) {
+ struct udev_list *properties_list) {
struct token *cur;
struct token *rule;
enum escape_type esc = ESCAPE_UNSET;
@@ -1939,7 +1941,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(event->dev)) {
const char *devlink;
- devlink = udev_list_entry_get_name(list_entry) + strlen("/dev/");
+ devlink = udev_list_entry_get_name(list_entry) + strlen("/dev/");
if (match_key(rules, cur, devlink) == 0) {
match = true;
break;
@@ -2129,7 +2131,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
rules_str(rules, rule->rule.filename_off),
rule->rule.filename_line);
- if (udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, sigmask, result, sizeof(result)) < 0) {
+ if (udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, result, sizeof(result)) < 0) {
if (cur->key.op != OP_NOMATCH)
goto nomatch;
} else {
@@ -2165,7 +2167,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
rules_str(rules, rule->rule.filename_off),
rule->rule.filename_line);
- if (import_program_into_properties(event, timeout_usec, timeout_warn_usec, import, sigmask) != 0)
+ if (import_program_into_properties(event, timeout_usec, timeout_warn_usec, import) != 0)
if (cur->key.op != OP_NOMATCH)
goto nomatch;
break;
diff --git a/src/udev/udev.h b/src/udev/udev.h
index 1b17c615b8..fd8504c424 100644
--- a/src/udev/udev.h
+++ b/src/udev/udev.h
@@ -20,7 +20,6 @@
#include <sys/types.h>
#include <sys/param.h>
-#include <signal.h>
#include "macro.h"
#include "sd-rtnl.h"
@@ -73,8 +72,7 @@ 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,
- struct udev_list *properties_list,
- const sigset_t *sigmask);
+ struct udev_list *properties_list);
int udev_rules_apply_static_dev_perms(struct udev_rules *rules);
/* udev-event.c */
@@ -86,14 +84,13 @@ int udev_event_apply_subsys_kernel(struct udev_event *event, const char *string,
int udev_event_spawn(struct udev_event *event,
usec_t timeout_usec,
usec_t timeout_warn_usec,
- const char *cmd, char **envp, const sigset_t *sigmask,
+ const char *cmd, char **envp,
char *result, size_t ressize);
void udev_event_execute_rules(struct udev_event *event,
usec_t timeout_usec, usec_t timeout_warn_usec,
struct udev_list *properties_list,
- struct udev_rules *rules,
- const sigset_t *sigset);
-void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec, const sigset_t *sigset);
+ struct udev_rules *rules);
+void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec);
int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]);
/* udev-watch.c */
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
index 46ec0e3225..d04e618d0d 100644
--- a/src/udev/udevadm-test.c
+++ b/src/udev/udevadm-test.c
@@ -135,8 +135,7 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) {
udev_event_execute_rules(event,
60 * USEC_PER_SEC, 20 * USEC_PER_SEC,
NULL,
- rules,
- &sigmask_orig);
+ rules);
udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev))
printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 34e88af539..2affb5944a 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -42,6 +42,8 @@
#include "sd-daemon.h"
#include "sd-event.h"
+
+#include "signal-util.h"
#include "event-util.h"
#include "rtnl-util.h"
#include "cgroup-util.h"
@@ -67,9 +69,8 @@ typedef struct Manager {
sd_event *event;
Hashmap *workers;
struct udev_list_node events;
- char *cgroup;
+ const char *cgroup;
pid_t pid; /* the process that originally allocated the manager object */
- sigset_t sigmask_orig;
struct udev_rules *rules;
struct udev_list properties;
@@ -306,7 +307,6 @@ static void manager_free(Manager *manager) {
udev_list_cleanup(&manager->properties);
udev_rules_unref(manager->rules);
- free(manager->cgroup);
safe_close(manager->fd_inotify);
safe_close_pair(manager->worker_watch);
@@ -401,6 +401,8 @@ static void worker_spawn(Manager *manager, struct event *event) {
struct udev_event *udev_event;
int fd_lock = -1;
+ assert(dev);
+
log_debug("seq %llu running", udev_device_get_seqnum(dev));
udev_event = udev_event_new(dev);
if (udev_event == NULL) {
@@ -446,12 +448,10 @@ static void worker_spawn(Manager *manager, struct event *event) {
udev_event_execute_rules(udev_event,
arg_event_timeout_usec, arg_event_timeout_warn_usec,
&manager->properties,
- manager->rules,
- &manager->sigmask_orig);
+ manager->rules);
udev_event_execute_run(udev_event,
- arg_event_timeout_usec, arg_event_timeout_warn_usec,
- &manager->sigmask_orig);
+ arg_event_timeout_usec, arg_event_timeout_warn_usec);
if (udev_event->rtnl)
/* in case rtnl was initialized */
@@ -875,7 +875,7 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat
continue;
}
- for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
+ CMSG_FOREACH(cmsg, &msghdr) {
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_CREDENTIALS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
@@ -1261,38 +1261,91 @@ static int on_post(sd_event_source *s, void *userdata) {
return 1;
}
-static int systemd_fds(int *rctrl, int *rnetlink) {
- int ctrl = -1, netlink = -1;
- int fd, n;
+static int listen_fds(int *rctrl, int *rnetlink) {
+ _cleanup_udev_unref_ struct udev *udev = NULL;
+ int ctrl_fd = -1, netlink_fd = -1;
+ int fd, n, r;
+
+ assert(rctrl);
+ assert(rnetlink);
n = sd_listen_fds(true);
- if (n <= 0)
- return -1;
+ if (n < 0)
+ return n;
for (fd = SD_LISTEN_FDS_START; fd < n + SD_LISTEN_FDS_START; fd++) {
if (sd_is_socket(fd, AF_LOCAL, SOCK_SEQPACKET, -1)) {
- if (ctrl >= 0)
- return -1;
- ctrl = fd;
+ if (ctrl_fd >= 0)
+ return -EINVAL;
+ ctrl_fd = fd;
continue;
}
if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1)) {
- if (netlink >= 0)
- return -1;
- netlink = fd;
+ if (netlink_fd >= 0)
+ return -EINVAL;
+ netlink_fd = fd;
continue;
}
- return -1;
+ return -EINVAL;
}
- if (ctrl < 0 || netlink < 0)
- return -1;
+ if (ctrl_fd < 0) {
+ _cleanup_udev_ctrl_unref_ struct udev_ctrl *ctrl = NULL;
+
+ udev = udev_new();
+ if (!udev)
+ return -ENOMEM;
+
+ ctrl = udev_ctrl_new(udev);
+ if (!ctrl)
+ return log_error_errno(EINVAL, "error initializing udev control socket");
+
+ r = udev_ctrl_enable_receiving(ctrl);
+ if (r < 0)
+ return log_error_errno(EINVAL, "error binding udev control socket");
+
+ fd = udev_ctrl_get_fd(ctrl);
+ if (fd < 0)
+ return log_error_errno(EIO, "could not get ctrl fd");
+
+ ctrl_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+ if (ctrl_fd < 0)
+ return log_error_errno(errno, "could not dup ctrl fd: %m");
+ }
+
+ if (netlink_fd < 0) {
+ _cleanup_udev_monitor_unref_ struct udev_monitor *monitor = NULL;
+
+ if (!udev) {
+ udev = udev_new();
+ if (!udev)
+ return -ENOMEM;
+ }
+
+ monitor = udev_monitor_new_from_netlink(udev, "kernel");
+ if (!monitor)
+ return log_error_errno(EINVAL, "error initializing netlink socket");
+
+ (void) udev_monitor_set_receive_buffer_size(monitor, 128 * 1024 * 1024);
+
+ r = udev_monitor_enable_receiving(monitor);
+ if (r < 0)
+ return log_error_errno(EINVAL, "error binding netlink socket");
+
+ fd = udev_monitor_get_fd(monitor);
+ if (fd < 0)
+ return log_error_errno(netlink_fd, "could not get uevent fd: %m");
+
+ netlink_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
+ if (ctrl_fd < 0)
+ return log_error_errno(errno, "could not dup netlink fd: %m");
+ }
+
+ *rctrl = ctrl_fd;
+ *rnetlink = netlink_fd;
- log_debug("ctrl=%i netlink=%i", ctrl, netlink);
- *rctrl = ctrl;
- *rnetlink = netlink;
return 0;
}
@@ -1437,11 +1490,13 @@ static int parse_argv(int argc, char *argv[]) {
return 1;
}
-static int manager_new(Manager **ret) {
+static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cgroup) {
_cleanup_(manager_freep) Manager *manager = NULL;
- int r, fd_ctrl, fd_uevent;
+ int r, fd_worker, one = 1;
assert(ret);
+ assert(fd_ctrl >= 0);
+ assert(fd_uevent >= 0);
manager = new0(Manager, 1);
if (!manager)
@@ -1464,57 +1519,15 @@ static int manager_new(Manager **ret) {
udev_list_node_init(&manager->events);
udev_list_init(manager->udev, &manager->properties, true);
- r = systemd_fds(&fd_ctrl, &fd_uevent);
- if (r >= 0) {
- /* get control and netlink socket from systemd */
- manager->ctrl = udev_ctrl_new_from_fd(manager->udev, fd_ctrl);
- if (!manager->ctrl)
- return log_error_errno(EINVAL, "error taking over udev control socket");
-
- manager->monitor = udev_monitor_new_from_netlink_fd(manager->udev, "kernel", fd_uevent);
- if (!manager->monitor)
- return log_error_errno(EINVAL, "error taking over netlink socket");
-
- /* get our own cgroup, we regularly kill everything udev has left behind */
- r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &manager->cgroup);
- if (r < 0)
- log_warning_errno(r, "failed to get cgroup: %m");
- } else {
- /* open control and netlink socket */
- manager->ctrl = udev_ctrl_new(manager->udev);
- if (!manager->ctrl)
- return log_error_errno(EINVAL, "error initializing udev control socket");
-
- fd_ctrl = udev_ctrl_get_fd(manager->ctrl);
-
- manager->monitor = udev_monitor_new_from_netlink(manager->udev, "kernel");
- if (!manager->monitor)
- return log_error_errno(EINVAL, "error initializing netlink socket");
-
- fd_uevent = udev_monitor_get_fd(manager->monitor);
-
- (void) udev_monitor_set_receive_buffer_size(manager->monitor, 128 * 1024 * 1024);
- }
-
- r = udev_monitor_enable_receiving(manager->monitor);
- if (r < 0)
- return log_error_errno(EINVAL, "error binding netlink socket");
-
- r = udev_ctrl_enable_receiving(manager->ctrl);
- if (r < 0)
- return log_error_errno(EINVAL, "error binding udev control socket");
+ manager->cgroup = cgroup;
- *ret = manager;
- manager = NULL;
+ manager->ctrl = udev_ctrl_new_from_fd(manager->udev, fd_ctrl);
+ if (!manager->ctrl)
+ return log_error_errno(EINVAL, "error taking over udev control socket");
- return 0;
-}
-
-static int manager_listen(Manager *manager) {
- sigset_t mask;
- int r, fd_worker, one = 1;
-
- assert(manager);
+ manager->monitor = udev_monitor_new_from_netlink_fd(manager->udev, "kernel", fd_uevent);
+ if (!manager->monitor)
+ return log_error_errno(EINVAL, "error taking over netlink socket");
/* unnamed socket from workers to the main daemon */
r = socketpair(AF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0, manager->worker_watch);
@@ -1534,8 +1547,7 @@ static int manager_listen(Manager *manager) {
udev_watch_restore(manager->udev);
/* block and listen to all signals on signalfd */
- sigfillset(&mask);
- sigprocmask(SIG_SETMASK, &mask, &manager->sigmask_orig);
+ assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, SIGHUP, SIGCHLD, -1) == 0);
r = sd_event_default(&manager->event);
if (r < 0)
@@ -1561,7 +1573,7 @@ static int manager_listen(Manager *manager) {
if (r < 0)
return log_error_errno(r, "error creating watchdog event source: %m");
- r = sd_event_add_io(manager->event, &manager->ctrl_event, udev_ctrl_get_fd(manager->ctrl), EPOLLIN, on_ctrl_msg, manager);
+ r = sd_event_add_io(manager->event, &manager->ctrl_event, fd_ctrl, EPOLLIN, on_ctrl_msg, manager);
if (r < 0)
return log_error_errno(r, "error creating ctrl event source: %m");
@@ -1577,7 +1589,7 @@ static int manager_listen(Manager *manager) {
if (r < 0)
return log_error_errno(r, "error creating inotify event source: %m");
- r = sd_event_add_io(manager->event, &manager->uevent_event, udev_monitor_get_fd(manager->monitor), EPOLLIN, on_uevent, manager);
+ r = sd_event_add_io(manager->event, &manager->uevent_event, fd_uevent, EPOLLIN, on_uevent, manager);
if (r < 0)
return log_error_errno(r, "error creating uevent event source: %m");
@@ -1589,12 +1601,16 @@ static int manager_listen(Manager *manager) {
if (r < 0)
return log_error_errno(r, "error creating post event source: %m");
+ *ret = manager;
+ manager = NULL;
+
return 0;
}
int main(int argc, char *argv[]) {
_cleanup_(manager_freep) Manager *manager = NULL;
- int r;
+ _cleanup_free_ char *cgroup = NULL;
+ int r, fd_ctrl, fd_uevent;
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
@@ -1622,7 +1638,7 @@ int main(int argc, char *argv[]) {
arg_children_max = 8;
if (sched_getaffinity(0, sizeof (cpu_set), &cpu_set) == 0) {
- arg_children_max += CPU_COUNT(&cpu_set) * 2;
+ arg_children_max += CPU_COUNT(&cpu_set) * 2;
}
log_debug("set children_max to %u", arg_children_max);
@@ -1651,13 +1667,20 @@ int main(int argc, char *argv[]) {
dev_setup(NULL, UID_INVALID, GID_INVALID);
- r = manager_new(&manager);
- if (r < 0)
- goto exit;
+ if (getppid() == 1) {
+ /* get our own cgroup, we regularly kill everything udev has left behind
+ we only do this on systemd systems, and only if we are directly spawned
+ by PID1. otherwise we are not guaranteed to have a dedicated cgroup */
+ r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup);
+ if (r < 0)
+ log_warning_errno(r, "failed to get cgroup: %m");
+ }
- r = udev_rules_apply_static_dev_perms(manager->rules);
- if (r < 0)
- log_error_errno(r, "failed to apply permissions on static device nodes: %m");
+ r = listen_fds(&fd_ctrl, &fd_uevent);
+ if (r < 0) {
+ r = log_error_errno(r, "could not listen on fds: %m");
+ goto exit;
+ }
if (arg_daemonize) {
pid_t pid;
@@ -1680,14 +1703,21 @@ int main(int argc, char *argv[]) {
setsid();
write_string_file("/proc/self/oom_score_adj", "-1000");
- } else
- sd_notify(false,
- "READY=1\n"
- "STATUS=Processing...");
+ }
- r = manager_listen(manager);
+ r = manager_new(&manager, fd_ctrl, fd_uevent, cgroup);
+ if (r < 0) {
+ r = log_error_errno(r, "failed to allocate manager object: %m");
+ goto exit;
+ }
+
+ r = udev_rules_apply_static_dev_perms(manager->rules);
if (r < 0)
- return log_error_errno(r, "failed to set up fds and listen for events: %m");
+ log_error_errno(r, "failed to apply permissions on static device nodes: %m");
+
+ (void) sd_notify(false,
+ "READY=1\n"
+ "STATUS=Processing...");
r = sd_event_loop(manager->event);
if (r < 0) {