diff options
Diffstat (limited to 'src/udev')
-rw-r--r-- | src/udev/net/link-config.c | 4 | ||||
-rw-r--r-- | src/udev/udev-builtin-hwdb.c | 2 | ||||
-rw-r--r-- | src/udev/udev-builtin-input_id.c | 146 | ||||
-rw-r--r-- | src/udev/udev-builtin-keyboard.c | 6 | ||||
-rw-r--r-- | src/udev/udev-builtin-net_id.c | 12 | ||||
-rw-r--r-- | src/udev/udev-builtin-path_id.c | 30 | ||||
-rw-r--r-- | src/udev/udev-builtin-usb_id.c | 2 | ||||
-rw-r--r-- | src/udev/udev-event.c | 26 | ||||
-rw-r--r-- | src/udev/udev-rules.c | 14 | ||||
-rw-r--r-- | src/udev/udev.h | 11 | ||||
-rw-r--r-- | src/udev/udevadm-test.c | 3 | ||||
-rw-r--r-- | src/udev/udevd.c | 214 |
12 files changed, 286 insertions, 184 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..4dcf8f2e1c 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); @@ -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..915371525f 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; @@ -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..eb43091190 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 */ @@ -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(); @@ -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) { |