summaryrefslogtreecommitdiff
path: root/src/udev
diff options
context:
space:
mode:
Diffstat (limited to 'src/udev')
-rw-r--r--src/udev/Makefile.am5
-rw-r--r--src/udev/udev-builtin-blkid.c15
-rw-r--r--src/udev/udev-builtin-btrfs.c5
-rw-r--r--src/udev/udev-builtin-hwdb.c2
-rw-r--r--src/udev/udev-builtin-input_id.c73
-rw-r--r--src/udev/udev-builtin-keyboard.c8
-rw-r--r--src/udev/udev-builtin-kmod.c26
-rw-r--r--src/udev/udev-builtin-net_id.c4
-rw-r--r--src/udev/udev-builtin-path_id.c110
-rw-r--r--src/udev/udev-builtin-usb_id.c2
-rw-r--r--src/udev/udev-builtin.c2
-rw-r--r--src/udev/udev-ctrl.c18
-rw-r--r--src/udev/udev-event.c64
-rw-r--r--src/udev/udev-node.c16
-rw-r--r--src/udev/udev-rules.c59
-rw-r--r--src/udev/udev-watch.c10
-rw-r--r--src/udev/udev.h16
-rw-r--r--src/udev/udevadm-control.c25
-rw-r--r--src/udev/udevadm-hwdb.c8
-rw-r--r--src/udev/udevadm-info.c78
-rw-r--r--src/udev/udevadm-monitor.c25
-rw-r--r--src/udev/udevadm-settle.c32
-rw-r--r--src/udev/udevadm-test-builtin.c12
-rw-r--r--src/udev/udevadm-test.c25
-rw-r--r--src/udev/udevadm-trigger.c115
-rw-r--r--src/udev/udevadm-util.c49
-rw-r--r--src/udev/udevadm-util.h22
-rw-r--r--src/udev/udevadm.c17
-rw-r--r--src/udev/udevd.c146
29 files changed, 619 insertions, 370 deletions
diff --git a/src/udev/Makefile.am b/src/udev/Makefile.am
index f9af997ffe..652cb67006 100644
--- a/src/udev/Makefile.am
+++ b/src/udev/Makefile.am
@@ -34,7 +34,10 @@ udevadm_SOURCES = \
udevadm-settle.c \
udevadm-trigger.c \
udevadm-test.c \
- udevadm-test-builtin.c
+ udevadm-test-builtin.c \
+ udevadm-util.c \
+ udevadm-util.h
+
udevadm_LDADD = \
libudev-core.la
diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c
index f97f516462..93563d867b 100644
--- a/src/udev/udev-builtin-blkid.c
+++ b/src/udev/udev-builtin-blkid.c
@@ -138,6 +138,7 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
blkid_probe pr;
const char *data;
const char *name;
+ const char *prtype = NULL;
int nvals;
int i;
int err = 0;
@@ -172,7 +173,8 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
blkid_probe_set_superblocks_flags(pr,
BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE |
- BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION);
+ BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION |
+ BLKID_SUBLKS_BADCSUM);
if (noraid)
blkid_probe_filter_superblocks_usage(pr, BLKID_FLTR_NOTIN, BLKID_USAGE_RAID);
@@ -194,6 +196,15 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t
err = probe_superblocks(pr);
if (err < 0)
goto out;
+ if (blkid_probe_has_value(pr, "SBBADCSUM")) {
+ if (!blkid_probe_lookup_value(pr, "TYPE", &prtype, NULL))
+ log_warning("incorrect %s checksum on %s",
+ prtype, udev_device_get_devnode(dev));
+ else
+ log_warning("incorrect checksum on %s",
+ udev_device_get_devnode(dev));
+ goto out;
+ }
nvals = blkid_probe_numof_values(pr);
for (i = 0; i < nvals; i++) {
@@ -214,6 +225,6 @@ out:
const struct udev_builtin udev_builtin_blkid = {
.name = "blkid",
.cmd = builtin_blkid,
- .help = "filesystem and partition probing",
+ .help = "Filesystem and partition probing",
.run_once = true,
};
diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c
index 2e2112fd92..3643596a70 100644
--- a/src/udev/udev-builtin-btrfs.c
+++ b/src/udev/udev-builtin-btrfs.c
@@ -24,6 +24,7 @@
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
+
#ifdef HAVE_LINUX_BTRFS_H
#include <linux/btrfs.h>
#endif
@@ -32,7 +33,7 @@
#include "udev.h"
static int builtin_btrfs(struct udev_device *dev, int argc, char *argv[], bool test) {
- struct btrfs_ioctl_vol_args args;
+ struct btrfs_ioctl_vol_args args = {};
_cleanup_close_ int fd = -1;
int err;
@@ -48,7 +49,7 @@ static int builtin_btrfs(struct udev_device *dev, int argc, char *argv[], bool t
if (err < 0)
return EXIT_FAILURE;
- udev_builtin_add_property(dev, test, "ID_BTRFS_READY", err == 0 ? "1" : "0");
+ udev_builtin_add_property(dev, test, "ID_BTRFS_READY", one_zero(err == 0));
return EXIT_SUCCESS;
}
diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c
index 695a31a12f..1eddf86b61 100644
--- a/src/udev/udev-builtin-hwdb.c
+++ b/src/udev/udev-builtin-hwdb.c
@@ -214,5 +214,5 @@ const struct udev_builtin udev_builtin_hwdb = {
.init = builtin_hwdb_init,
.exit = builtin_hwdb_exit,
.validate = builtin_hwdb_validate,
- .help = "hardware database",
+ .help = "Hardware database",
};
diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
index 1a1121ef94..26c723225d 100644
--- a/src/udev/udev-builtin-input_id.c
+++ b/src/udev/udev-builtin-input_id.c
@@ -1,9 +1,11 @@
/*
- * compose persistent device path
+ * expose input properties via udev
*
* Copyright (C) 2009 Martin Pitt <martin.pitt@ubuntu.com>
* Portions Copyright (C) 2004 David Zeuthen, <david@fubar.dk>
* Copyright (C) 2011 Kay Sievers <kay@vrfy.org>
+ * Copyright (C) 2014 Carlos Garnacho <carlosg@gnome.org>
+ * Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,6 +31,7 @@
#include <linux/input.h>
#include "udev.h"
+#include "util.h"
/* we must use this kernel-compatible implementation */
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
@@ -38,6 +41,34 @@
#define LONG(x) ((x)/BITS_PER_LONG)
#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
+static inline int abs_size_mm(const struct input_absinfo *absinfo) {
+ /* Resolution is defined to be in units/mm for ABS_X/Y */
+ return (absinfo->maximum - absinfo->minimum) / absinfo->resolution;
+}
+
+static void extract_info(struct udev_device *dev, const char *devpath, bool test) {
+ char width[DECIMAL_STR_MAX(int)], height[DECIMAL_STR_MAX(int)];
+ struct input_absinfo xabsinfo = {}, yabsinfo = {};
+ _cleanup_close_ int fd = -1;
+
+ fd = open(devpath, O_RDONLY|O_CLOEXEC);
+ if (fd < 0)
+ return;
+
+ if (ioctl(fd, EVIOCGABS(ABS_X), &xabsinfo) < 0 ||
+ ioctl(fd, EVIOCGABS(ABS_Y), &yabsinfo) < 0)
+ return;
+
+ if (xabsinfo.resolution <= 0 || yabsinfo.resolution <= 0)
+ return;
+
+ snprintf(width, sizeof(width), "%d", abs_size_mm(&xabsinfo));
+ snprintf(height, sizeof(height), "%d", abs_size_mm(&yabsinfo));
+
+ udev_builtin_add_property(dev, test, "ID_INPUT_WIDTH_MM", width);
+ udev_builtin_add_property(dev, test, "ID_INPUT_HEIGHT_MM", height);
+}
+
/*
* Read a capability attribute and return bitmask.
* @param dev udev_device
@@ -48,12 +79,17 @@ static void get_cap_mask(struct udev_device *dev,
struct udev_device *pdev, const char* attr,
unsigned long *bitmask, size_t bitmask_size,
bool test) {
+ const char *v;
char text[4096];
unsigned i;
char* word;
unsigned long val;
- snprintf(text, sizeof(text), "%s", udev_device_get_sysattr_value(pdev, attr));
+ v = udev_device_get_sysattr_value(pdev, attr);
+ if (!v)
+ v = "";
+
+ snprintf(text, sizeof(text), "%s", v);
log_debug("%s raw kernel attribute: %s", attr, text);
memzero(bitmask, bitmask_size);
@@ -196,6 +232,7 @@ static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], boo
unsigned long bitmask_abs[NBITS(ABS_MAX)];
unsigned long bitmask_key[NBITS(KEY_MAX)];
unsigned long bitmask_rel[NBITS(REL_MAX)];
+ const char *sysname, *devnode;
/* walk up the parental chain until we find the real input device; the
* argument is very likely a subdevice of this, like eventN */
@@ -203,24 +240,28 @@ static int builtin_input_id(struct udev_device *dev, int argc, char *argv[], boo
while (pdev != NULL && udev_device_get_sysattr_value(pdev, "capabilities/ev") == NULL)
pdev = udev_device_get_parent_with_subsystem_devtype(pdev, "input", NULL);
- /* not an "input" class device */
- if (pdev == NULL)
- return EXIT_SUCCESS;
-
- /* Use this as a flag that input devices were detected, so that this
- * program doesn't need to be called more than once per device */
- udev_builtin_add_property(dev, test, "ID_INPUT", "1");
- get_cap_mask(dev, pdev, "capabilities/ev", bitmask_ev, sizeof(bitmask_ev), test);
- get_cap_mask(dev, pdev, "capabilities/abs", bitmask_abs, sizeof(bitmask_abs), test);
- get_cap_mask(dev, pdev, "capabilities/rel", bitmask_rel, sizeof(bitmask_rel), test);
- get_cap_mask(dev, pdev, "capabilities/key", bitmask_key, sizeof(bitmask_key), test);
- test_pointers(dev, bitmask_ev, bitmask_abs, bitmask_key, bitmask_rel, test);
- test_key(dev, bitmask_ev, bitmask_key, test);
+ if (pdev) {
+ /* Use this as a flag that input devices were detected, so that this
+ * program doesn't need to be called more than once per device */
+ udev_builtin_add_property(dev, test, "ID_INPUT", "1");
+ get_cap_mask(dev, pdev, "capabilities/ev", bitmask_ev, sizeof(bitmask_ev), test);
+ get_cap_mask(dev, pdev, "capabilities/abs", bitmask_abs, sizeof(bitmask_abs), test);
+ get_cap_mask(dev, pdev, "capabilities/rel", bitmask_rel, sizeof(bitmask_rel), test);
+ get_cap_mask(dev, pdev, "capabilities/key", bitmask_key, sizeof(bitmask_key), test);
+ test_pointers(dev, bitmask_ev, bitmask_abs, bitmask_key, bitmask_rel, test);
+ test_key(dev, bitmask_ev, bitmask_key, test);
+ }
+
+ devnode = udev_device_get_devnode(dev);
+ sysname = udev_device_get_sysname(dev);
+ if (devnode && sysname && startswith(sysname, "event"))
+ extract_info(dev, devnode, test);
+
return EXIT_SUCCESS;
}
const struct udev_builtin udev_builtin_input_id = {
.name = "input_id",
.cmd = builtin_input_id,
- .help = "input device properties",
+ .help = "Input device properties",
};
diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c
index d6b7dbbac0..118e797c96 100644
--- a/src/udev/udev-builtin-keyboard.c
+++ b/src/udev/udev-builtin-keyboard.c
@@ -62,7 +62,7 @@ static int install_force_release(struct udev_device *dev, const unsigned int *re
log_debug("keyboard: updating force-release list with '%s'", codes);
ret = udev_device_set_sysattr_value(atkbd, "force_release", codes);
if (ret < 0)
- log_error("Error writing force-release attribute: %s", strerror(-ret));
+ log_error_errno(ret, "Error writing force-release attribute: %m");
return ret;
}
@@ -140,7 +140,7 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo
fd = open(udev_device_get_devnode(dev), O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
if (fd < 0) {
- log_error("Error, opening device '%s': %m", node);
+ log_error_errno(errno, "Error, opening device '%s': %m", node);
return EXIT_FAILURE;
}
@@ -149,7 +149,7 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo
log_debug("keyboard: mapping scan code %d (0x%x) to key code %d (0x%x)",
map[i].scan, map[i].scan, map[i].key, map[i].key);
if (ioctl(fd, EVIOCSKEYCODE, &map[i]) < 0)
- log_error("Error calling EVIOCSKEYCODE on device node '%s' (scan code 0x%x, key code %d): %m", node, map[i].scan, map[i].key);
+ log_error_errno(errno, "Error calling EVIOCSKEYCODE on device node '%s' (scan code 0x%x, key code %d): %m", node, map[i].scan, map[i].key);
}
/* install list of force-release codes */
@@ -165,5 +165,5 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo
const struct udev_builtin udev_builtin_keyboard = {
.name = "keyboard",
.cmd = builtin_keyboard,
- .help = "keyboard scan code to key mapping",
+ .help = "Keyboard scan code to key mapping",
};
diff --git a/src/udev/udev-builtin-kmod.c b/src/udev/udev-builtin-kmod.c
index b83fd523d9..f39b01a452 100644
--- a/src/udev/udev-builtin-kmod.c
+++ b/src/udev/udev-builtin-kmod.c
@@ -34,7 +34,7 @@
#include "udev.h"
-static struct kmod_ctx *ctx;
+static struct kmod_ctx *ctx = NULL;
static int load_module(struct udev *udev, const char *alias) {
int err;
@@ -47,18 +47,18 @@ static int load_module(struct udev *udev, const char *alias) {
return err;
if (list == NULL)
- log_debug("no module matches '%s'", alias);
+ log_debug("No module matches '%s'", alias);
kmod_list_foreach(l, list) {
struct kmod_module *mod = kmod_module_get_module(l);
err = kmod_module_probe_insert_module(mod, KMOD_PROBE_APPLY_BLACKLIST, NULL, NULL, NULL, NULL);
if (err == KMOD_PROBE_APPLY_BLACKLIST)
- log_debug("module '%s' is blacklisted", kmod_module_get_name(mod));
+ log_debug("Module '%s' is blacklisted", kmod_module_get_name(mod));
else if (err == 0)
- log_debug("inserted '%s'", kmod_module_get_name(mod));
+ log_debug("Inserted '%s'", kmod_module_get_name(mod));
else
- log_debug("failed to insert '%s'", kmod_module_get_name(mod));
+ log_debug("Failed to insert '%s'", kmod_module_get_name(mod));
kmod_module_unref(mod);
}
@@ -85,10 +85,8 @@ static int load_module(struct udev *udev, const char *alias) {
return err;
}
-_printf_(6,0)
-static void udev_kmod_log(void *data, int priority, const char *file, int line,
- const char *fn, const char *format, va_list args) {
- udev_main_log(data, priority, file, line, fn, format, args);
+_printf_(6,0) static void udev_kmod_log(void *data, int priority, const char *file, int line, const char *fn, const char *format, va_list args) {
+ log_internalv(priority, 0, file, line, fn, format, args);
}
static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test) {
@@ -106,7 +104,7 @@ static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool te
}
for (i = 2; argv[i]; i++) {
- log_debug("execute '%s' '%s'", argv[1], argv[i]);
+ log_debug("Execute '%s' '%s'", argv[1], argv[i]);
load_module(udev, argv[i]);
}
@@ -123,7 +121,7 @@ static int builtin_kmod_init(struct udev *udev) {
if (!ctx)
return -ENOMEM;
- log_debug("load module index");
+ log_debug("Load module index");
kmod_set_log_fn(ctx, udev_kmod_log, udev);
kmod_load_resources(ctx);
#endif
@@ -133,7 +131,7 @@ static int builtin_kmod_init(struct udev *udev) {
/* called on udev shutdown and reload request */
static void builtin_kmod_exit(struct udev *udev) {
#ifdef HAVE_LIBKMOD
- log_debug("unload module index");
+ log_debug("Unload module index");
ctx = kmod_unref(ctx);
#endif
}
@@ -141,7 +139,7 @@ static void builtin_kmod_exit(struct udev *udev) {
#ifdef HAVE_LIBKMOD
/* called every couple of seconds during event activity; 'true' if config has changed */
static bool builtin_kmod_validate(struct udev *udev) {
- log_debug("validate module index");
+ log_debug("Validate module index");
if (!ctx)
return false;
return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK);
@@ -156,6 +154,6 @@ const struct udev_builtin udev_builtin_kmod = {
#ifdef HAVE_LIBKMOD
.validate = builtin_kmod_validate,
#endif
- .help = "kernel module loader",
+ .help = "Kernel module loader",
.run_once = false,
};
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index 4731a860b0..5f350abd68 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -307,7 +307,7 @@ static int names_usb(struct udev_device *dev, struct netnames *names) {
s[0] = '\0';
interf = s+1;
- /* prefix every port number in the chain with "u"*/
+ /* prefix every port number in the chain with "u" */
s = ports;
while ((s = strchr(s, '.')))
s[0] = 'u';
@@ -562,5 +562,5 @@ out:
const struct udev_builtin udev_builtin_net_id = {
.name = "net_id",
.cmd = builtin_net_id,
- .help = "network device properties",
+ .help = "Network device properties",
};
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
index 0d247f6b5a..b6749aab76 100644
--- a/src/udev/udev-builtin-path_id.c
+++ b/src/udev/udev-builtin-path_id.c
@@ -118,7 +118,7 @@ out:
return parent;
}
-static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **path) {
+static struct udev_device *handle_scsi_sas_wide_port(struct udev_device *parent, char **path) {
struct udev *udev = udev_device_get_udev(parent);
struct udev_device *targetdev;
struct udev_device *target_parent;
@@ -154,6 +154,100 @@ out:
return parent;
}
+static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **path)
+{
+ struct udev *udev = udev_device_get_udev(parent);
+ struct udev_device *targetdev;
+ struct udev_device *target_parent;
+ struct udev_device *port;
+ struct udev_device *expander;
+ struct udev_device *target_sasdev = NULL;
+ struct udev_device *expander_sasdev = NULL;
+ struct udev_device *port_sasdev = NULL;
+ const char *sas_address = NULL;
+ const char *phy_id;
+ const char *phy_count;
+ char *lun = NULL;
+
+ targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target");
+ if (targetdev == NULL)
+ return NULL;
+
+ target_parent = udev_device_get_parent(targetdev);
+ if (target_parent == NULL)
+ return NULL;
+
+ /* Get sas device */
+ target_sasdev = udev_device_new_from_subsystem_sysname(udev,
+ "sas_device", udev_device_get_sysname(target_parent));
+ if (target_sasdev == NULL)
+ return NULL;
+
+ /* The next parent is sas port */
+ port = udev_device_get_parent(target_parent);
+ if (port == NULL) {
+ parent = NULL;
+ goto out;
+ }
+
+ /* Get port device */
+ port_sasdev = udev_device_new_from_subsystem_sysname(udev,
+ "sas_port", udev_device_get_sysname(port));
+
+ phy_count = udev_device_get_sysattr_value(port_sasdev, "num_phys");
+ if (phy_count == NULL) {
+ parent = NULL;
+ goto out;
+ }
+
+ /* Check if we are simple disk */
+ if (strncmp(phy_count, "1", 2) != 0) {
+ parent = handle_scsi_sas_wide_port(parent, path);
+ goto out;
+ }
+
+ /* Get connected phy */
+ phy_id = udev_device_get_sysattr_value(target_sasdev, "phy_identifier");
+ if (phy_id == NULL) {
+ parent = NULL;
+ goto out;
+ }
+
+ /* The port's parent is either hba or expander */
+ expander = udev_device_get_parent(port);
+ if (expander == NULL) {
+ parent = NULL;
+ goto out;
+ }
+
+ /* Get expander device */
+ expander_sasdev = udev_device_new_from_subsystem_sysname(udev,
+ "sas_device", udev_device_get_sysname(expander));
+ if (expander_sasdev != NULL) {
+ /* Get expander's address */
+ sas_address = udev_device_get_sysattr_value(expander_sasdev,
+ "sas_address");
+ if (sas_address == NULL) {
+ parent = NULL;
+ goto out;
+ }
+ }
+
+ format_lun_number(parent, &lun);
+ if (sas_address)
+ path_prepend(path, "sas-exp%s-phy%s-%s", sas_address, phy_id, lun);
+ else
+ path_prepend(path, "sas-phy%s-%s", phy_id, lun);
+
+ if (lun)
+ free(lun);
+out:
+ udev_device_unref(target_sasdev);
+ udev_device_unref(expander_sasdev);
+ udev_device_unref(port_sasdev);
+ return parent;
+}
+
static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **path) {
struct udev *udev = udev_device_get_udev(parent);
struct udev_device *transportdev;
@@ -548,9 +642,9 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
}
/*
- * Do return devices with have an unknown type of parent device, they
- * might produce conflicting IDs below multiple independent parent
- * devices.
+ * Do not return devices with an unknown parent device type. They
+ * might produce conflicting IDs if the parent does not provide a
+ * unique and predictable name.
*/
if (!supported_parent) {
free(path);
@@ -558,9 +652,9 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
}
/*
- * Do not return a have-only a single-parent block devices, some
- * have entire hidden buses behind it, and not create predictable
- * IDs that way.
+ * Do not return block devices without a well-known transport. Some
+ * devices do not expose their buses and do not provide a unique
+ * and predictable name that way.
*/
if (streq(udev_device_get_subsystem(dev), "block") && !supported_transport) {
free(path);
@@ -609,6 +703,6 @@ out:
const struct udev_builtin udev_builtin_path_id = {
.name = "path_id",
.cmd = builtin_path_id,
- .help = "compose persistent device path",
+ .help = "Compose persistent device path",
.run_once = true,
};
diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c
index 06d4191584..ab0d96e377 100644
--- a/src/udev/udev-builtin-usb_id.c
+++ b/src/udev/udev-builtin-usb_id.c
@@ -471,6 +471,6 @@ fallback:
const struct udev_builtin udev_builtin_usb_id = {
.name = "usb_id",
.cmd = builtin_usb_id,
- .help = "usb device properties",
+ .help = "USB device properties",
.run_once = true,
};
diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c
index 70b7ab4332..e4440a6e99 100644
--- a/src/udev/udev-builtin.c
+++ b/src/udev/udev-builtin.c
@@ -86,7 +86,7 @@ void udev_builtin_list(struct udev *udev) {
unsigned int i;
for (i = 0; i < ELEMENTSOF(builtins); i++)
- fprintf(stderr, " %-12s %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) {
diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c
index 2fdf4561a9..898ef54514 100644
--- a/src/udev/udev-ctrl.c
+++ b/src/udev/udev-ctrl.c
@@ -85,7 +85,7 @@ struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd) {
if (fd < 0) {
uctrl->sock = socket(AF_LOCAL, SOCK_SEQPACKET|SOCK_NONBLOCK|SOCK_CLOEXEC, 0);
if (uctrl->sock < 0) {
- log_error("error getting socket: %m");
+ log_error_errno(errno, "error getting socket: %m");
udev_ctrl_unref(uctrl);
return NULL;
}
@@ -95,7 +95,7 @@ struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd) {
}
r = setsockopt(uctrl->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
if (r < 0)
- log_warning("could not set SO_PASSCRED: %m");
+ log_warning_errno(errno, "could not set SO_PASSCRED: %m");
uctrl->saddr.sun_family = AF_LOCAL;
strscpy(uctrl->saddr.sun_path, sizeof(uctrl->saddr.sun_path), "/run/udev/control");
@@ -119,14 +119,14 @@ int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl) {
if (err < 0) {
err = -errno;
- log_error("bind failed: %m");
+ log_error_errno(errno, "bind failed: %m");
return err;
}
err = listen(uctrl->sock, 0);
if (err < 0) {
err = -errno;
- log_error("listen failed: %m");
+ log_error_errno(errno, "listen failed: %m");
return err;
}
@@ -209,14 +209,14 @@ struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl) {
if (conn->sock < 0) {
if (errno != EINTR)
- log_error("unable to receive ctrl connection: %m");
+ log_error_errno(errno, "unable to receive ctrl connection: %m");
goto err;
}
/* check peer credential of connection */
r = getpeercred(conn->sock, &ucred);
if (r < 0) {
- log_error("unable to receive credentials of ctrl connection: %s", strerror(-r));
+ log_error_errno(r, "unable to receive credentials of ctrl connection: %m");
goto err;
}
if (ucred.uid > 0) {
@@ -227,7 +227,7 @@ struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl) {
/* enable receiving of the sender credentials in the messages */
r = setsockopt(conn->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
if (r < 0)
- log_warning("could not set SO_PASSCRED: %m");
+ log_warning_errno(errno, "could not set SO_PASSCRED: %m");
udev_ctrl_ref(uctrl);
return conn;
@@ -383,7 +383,7 @@ struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn) {
goto err;
} else {
if (!(pfd[0].revents & POLLIN)) {
- log_error("ctrl connection error: %m");
+ log_error_errno(errno, "ctrl connection error: %m");
goto err;
}
}
@@ -396,7 +396,7 @@ struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn) {
size = recvmsg(conn->sock, &smsg, 0);
if (size < 0) {
- log_error("unable to receive ctrl message: %m");
+ log_error_errno(errno, "unable to receive ctrl message: %m");
goto err;
}
cmsg = CMSG_FIRSTHDR(&smsg);
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index e86f9cb059..5c1352b1b9 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -388,7 +388,7 @@ static int spawn_exec(struct udev_event *event,
if (fd_stderr < 0)
dup2(fd, STDERR_FILENO);
} else
- log_error("open /dev/null failed: %m");
+ log_error_errno(errno, "open /dev/null failed: %m");
/* connect pipes to std{out,err} */
if (fd_stdout >= 0) {
@@ -410,7 +410,7 @@ static int spawn_exec(struct udev_event *event,
execve(argv[0], argv, envp);
/* exec failed */
- log_error("failed to execute '%s' '%s': %m", argv[0], cmd);
+ log_error_errno(errno, "failed to execute '%s' '%s': %m", argv[0], cmd);
return -errno;
}
@@ -438,14 +438,14 @@ static void spawn_read(struct udev_event *event,
fd_ep = epoll_create1(EPOLL_CLOEXEC);
if (fd_ep < 0) {
- log_error("error creating epoll fd: %m");
+ log_error_errno(errno, "error creating epoll fd: %m");
return;
}
if (fd_stdout >= 0) {
r = epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_stdout, &ep_outpipe);
if (r < 0) {
- log_error("fail to add stdout fd to epoll: %m");
+ log_error_errno(errno, "fail to add stdout fd to epoll: %m");
return;
}
}
@@ -453,7 +453,7 @@ static void spawn_read(struct udev_event *event,
if (fd_stderr >= 0) {
r = epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_stderr, &ep_errpipe);
if (r < 0) {
- log_error("fail to add stderr fd to epoll: %m");
+ log_error_errno(errno, "fail to add stderr fd to epoll: %m");
return;
}
}
@@ -482,7 +482,7 @@ static void spawn_read(struct udev_event *event,
if (fdcount < 0) {
if (errno == EINTR)
continue;
- log_error("failed to poll: %m");
+ log_error_errno(errno, "failed to poll: %m");
return;
} else if (fdcount == 0) {
log_error("timeout '%s'", cmd);
@@ -528,7 +528,7 @@ static void spawn_read(struct udev_event *event,
} else if (ev[i].events & EPOLLHUP) {
r = epoll_ctl(fd_ep, EPOLL_CTL_DEL, *fd, NULL);
if (r < 0) {
- log_error("failed to remove fd from epoll: %m");
+ log_error_errno(errno, "failed to remove fd from epoll: %m");
return;
}
*fd = -1;
@@ -577,7 +577,7 @@ static int spawn_wait(struct udev_event *event,
if (errno == EINTR)
continue;
err = -errno;
- log_error("failed to poll: %m");
+ log_error_errno(errno, "failed to poll: %m");
goto out;
}
if (fdcount == 0) {
@@ -588,7 +588,7 @@ static int spawn_wait(struct udev_event *event,
if (errno == EINTR)
continue;
err = -errno;
- log_error("failed to poll: %m");
+ log_error_errno(errno, "failed to poll: %m");
goto out;
}
if (fdcount == 0) {
@@ -677,7 +677,6 @@ int udev_event_spawn(struct udev_event *event,
usec_t timeout_warn_usec,
const char *cmd, char **envp, const sigset_t *sigmask,
char *result, size_t ressize) {
- struct udev *udev = event->udev;
int outpipe[2] = {-1, -1};
int errpipe[2] = {-1, -1};
pid_t pid;
@@ -690,17 +689,17 @@ int udev_event_spawn(struct udev_event *event,
udev_build_argv(event->udev, arg, NULL, argv);
/* pipes from child to parent */
- if (result != NULL || udev_get_log_priority(udev) >= LOG_INFO) {
+ if (result != NULL || log_get_max_level() >= LOG_INFO) {
if (pipe2(outpipe, O_NONBLOCK) != 0) {
err = -errno;
- log_error("pipe failed: %m");
+ log_error_errno(errno, "pipe failed: %m");
goto out;
}
}
- if (udev_get_log_priority(udev) >= LOG_INFO) {
+ if (log_get_max_level() >= LOG_INFO) {
if (pipe2(errpipe, O_NONBLOCK) != 0) {
err = -errno;
- log_error("pipe failed: %m");
+ log_error_errno(errno, "pipe failed: %m");
goto out;
}
}
@@ -737,7 +736,7 @@ int udev_event_spawn(struct udev_event *event,
_exit(2 );
case -1:
- log_error("fork of '%s' failed: %m", cmd);
+ log_error_errno(errno, "fork of '%s' failed: %m", cmd);
err = -1;
goto out;
default:
@@ -785,7 +784,7 @@ static int rename_netif_dev_fromname_toname(struct udev_device *dev,const char *
sk = socket(PF_INET, SOCK_DGRAM, 0);
if (sk < 0) {
err = -errno;
- log_error("error opening socket: %m\n");
+ log_error("error opening socket: %m");
return err;
}
@@ -799,11 +798,11 @@ static int rename_netif_dev_fromname_toname(struct udev_device *dev,const char *
int loop;
if (err == 0) {
- log_info("renamed network interface %s to %s\n", ifr.ifr_name, ifr.ifr_newname);
+ log_info("renamed network interface %s to %s", ifr.ifr_name, ifr.ifr_newname);
goto out;
}
/* keep trying if the destination interface name already exists */
- log_debug("collision on rename of network interface %s to %s , retrying until timeout\n",
+ log_debug("collision on rename of network interface %s to %s , retrying until timeout",
ifr.ifr_name, ifr.ifr_newname);
err = -errno;
@@ -819,7 +818,7 @@ static int rename_netif_dev_fromname_toname(struct udev_device *dev,const char *
err = ioctl(sk, SIOCSIFNAME, &ifr);
if (err == 0) {
- log_info("renamed network interface %s to %s\n", ifr.ifr_name, ifr.ifr_newname);
+ log_info("renamed network interface %s to %s", ifr.ifr_name, ifr.ifr_newname);
break;
}
err = -errno;
@@ -829,13 +828,13 @@ static int rename_netif_dev_fromname_toname(struct udev_device *dev,const char *
out:
if (err < 0)
- log_error("error changing net interface name %s to %s: %m\n", ifr.ifr_name, ifr.ifr_newname);
+ log_error("error changing net interface name %s to %s: %m", ifr.ifr_name, ifr.ifr_newname);
#else
if (err >= 0) {
- log_info("renamed network interface %s to %s\n", ifr.ifr_name, ifr.ifr_newname);
+ log_info("renamed network interface %s to %s", ifr.ifr_name, ifr.ifr_newname);
} else {
err = -errno;
- log_error("error changing net interface name %s to %s: %m\n", ifr.ifr_name, ifr.ifr_newname);
+ log_error("error changing net interface name %s to %s: %m", ifr.ifr_name, ifr.ifr_newname);
}
#endif
@@ -848,9 +847,10 @@ 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_rules *rules, const sigset_t *sigmask) {
+ usec_t timeout_usec, usec_t timeout_warn_usec,
+ struct udev_list *properties_list,
+ struct udev_rules *rules,
+ const sigset_t *sigmask) {
struct udev_device *dev = event->dev;
if (udev_device_get_subsystem(dev) == NULL)
@@ -864,7 +864,10 @@ void udev_event_execute_rules(struct udev_event *event,
if (major(udev_device_get_devnum(dev)) != 0)
udev_watch_end(event->udev, dev);
- udev_rules_apply_to_event(rules, event, timeout_usec, timeout_warn_usec, sigmask);
+ udev_rules_apply_to_event(rules, event,
+ timeout_usec, timeout_warn_usec,
+ properties_list,
+ sigmask);
if (major(udev_device_get_devnum(dev)) != 0)
udev_node_remove(dev);
@@ -898,7 +901,10 @@ void udev_event_execute_rules(struct udev_event *event,
}
}
- udev_rules_apply_to_event(rules, event, timeout_usec, timeout_warn_usec, sigmask);
+ udev_rules_apply_to_event(rules, event,
+ timeout_usec, timeout_warn_usec,
+ properties_list,
+ sigmask);
/* rename a new network interface, if needed */
@@ -955,9 +961,9 @@ void udev_event_execute_rules(struct udev_event *event,
r = rename_netif_dev_fromname_toname(dev,udev_device_get_sysname(dev),newifname);
if (r == 0) {
finalifname = newifname;
- log_debug("renamed netif to '%s' for collision avoidance\n", newifname);
+ log_debug("renamed netif to '%s' for collision avoidance", newifname);
} else {
- log_error("could not rename netif to '%s' for collision avoidance\n",newifname);
+ log_error("could not rename netif to '%s' for collision avoidance",newifname);
}
}
/* rename it now to its final target if its not already there */
diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c
index 4ac6f71490..c30a428ea1 100644
--- a/src/udev/udev-node.c
+++ b/src/udev/udev-node.c
@@ -112,12 +112,12 @@ static int node_symlink(struct udev_device *dev, const char *node, const char *s
mac_selinux_create_file_clear();
} while (err == -ENOENT);
if (err != 0) {
- log_error("symlink '%s' '%s' failed: %m", target, slink_tmp);
+ log_error_errno(errno, "symlink '%s' '%s' failed: %m", target, slink_tmp);
goto exit;
}
err = rename(slink_tmp, slink);
if (err != 0) {
- log_error("rename '%s' '%s' failed: %m", slink_tmp, slink);
+ log_error_errno(errno, "rename '%s' '%s' failed: %m", slink_tmp, slink);
unlink(slink_tmp);
}
exit:
@@ -264,7 +264,7 @@ static int node_permissions_apply(struct udev_device *dev, bool apply,
if (lstat(devnode, &stats) != 0) {
err = -errno;
- log_debug("can not stat() node '%s' (%m)", devnode);
+ log_debug_errno(errno, "can not stat() node '%s' (%m)", devnode);
goto out;
}
@@ -283,10 +283,10 @@ static int node_permissions_apply(struct udev_device *dev, bool apply,
log_debug("set permissions %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid);
err = chmod(devnode, mode);
if (err < 0)
- log_warning("setting mode of %s to %#o failed: %m", devnode, mode);
+ log_warning_errno(errno, "setting mode of %s to %#o failed: %m", devnode, mode);
err = chown(devnode, uid, gid);
if (err < 0)
- log_warning("setting owner of %s to uid=%u, gid=%u failed: %m", devnode, uid, gid);
+ log_warning_errno(errno, "setting owner of %s to uid=%u, gid=%u failed: %m", devnode, uid, gid);
} else {
log_debug("preserve permissions %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid);
}
@@ -304,7 +304,7 @@ static int node_permissions_apply(struct udev_device *dev, bool apply,
r = mac_selinux_apply(devnode, label);
if (r < 0)
- log_error("SECLABEL: failed to set SELinux label '%s': %s", label, strerror(-r));
+ log_error_errno(r, "SECLABEL: failed to set SELinux label '%s': %m", label);
else
log_debug("SECLABEL: set SELinux label '%s'", label);
@@ -313,7 +313,7 @@ static int node_permissions_apply(struct udev_device *dev, bool apply,
r = mac_smack_apply(devnode, label);
if (r < 0)
- log_error("SECLABEL: failed to set SMACK label '%s': %s", label, strerror(-r));
+ log_error_errno(r, "SECLABEL: failed to set SMACK label '%s': %m", label);
else
log_debug("SECLABEL: set SMACK label '%s'", label);
@@ -323,7 +323,7 @@ static int node_permissions_apply(struct udev_device *dev, bool apply,
/* set the defaults */
if (!selinux)
- label_fix(devnode, true, false);
+ mac_selinux_fix(devnode, true, false);
if (!smack)
mac_smack_apply(devnode, NULL);
}
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index b8fc35e11a..f51691143b 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -479,9 +479,9 @@ static uid_t add_uid(struct udev_rules *rules, const char *owner) {
r = get_user_creds(&owner, &uid, NULL, NULL, NULL);
if (r < 0) {
if (r == -ENOENT || r == -ESRCH)
- udev_err(rules->udev, "specified user '%s' unknown\n", owner);
+ log_error("specified user '%s' unknown", owner);
else
- udev_err(rules->udev, "error resolving user '%s': %s\n", owner, strerror(-r));
+ log_error_errno(r, "error resolving user '%s': %m", owner);
}
/* grow buffer if needed */
@@ -526,9 +526,9 @@ static gid_t add_gid(struct udev_rules *rules, const char *group) {
r = get_group_creds(&group, &gid);
if (r < 0) {
if (r == -ENOENT || r == -ESRCH)
- udev_err(rules->udev, "specified group '%s' unknown\n", group);
+ log_error("specified group '%s' unknown", group);
else
- udev_err(rules->udev, "error resolving group '%s': %s\n", group, strerror(-r));
+ log_error_errno(r, "error resolving group '%s': %m", group);
}
/* grow buffer if needed */
@@ -1047,11 +1047,11 @@ static int add_rule(struct udev_rules *rules, char *line,
const char *filename, unsigned int filename_off, unsigned int lineno) {
char *linepos;
const char *attr;
- struct rule_tmp rule_tmp;
+ struct rule_tmp rule_tmp = {
+ .rules = rules,
+ .rule.type = TK_RULE,
+ };
- memzero(&rule_tmp, sizeof(struct rule_tmp));
- rule_tmp.rules = rules;
- rule_tmp.rule.type = TK_RULE;
/* the offset in the rule is limited to unsigned short */
if (filename_off < USHRT_MAX)
rule_tmp.rule.rule.filename_off = filename_off;
@@ -1072,14 +1072,14 @@ static int add_rule(struct udev_rules *rules, char *line,
/* If we aren't at the end of the line, this is a parsing error.
* Make a best effort to describe where the problem is. */
- if (*linepos != '\n') {
- char buf[2] = {linepos[1]};
+ if (!strchr(NEWLINE, *linepos)) {
+ char buf[2] = {*linepos};
_cleanup_free_ char *tmp;
tmp = cescape(buf);
- log_error("invalid key/value pair in file %s on line %u, starting at character %tu ('%s')\n",
+ log_error("invalid key/value pair in file %s on line %u, starting at character %tu ('%s')",
filename, lineno, linepos - line + 1, tmp);
- if (linepos[1] == '#')
+ if (*linepos == '#')
log_error("hint: comments can only start at beginning of line");
}
break;
@@ -1420,12 +1420,12 @@ static int add_rule(struct udev_rules *rules, char *line,
} else {
if (streq(value, "%k")) {
log_error("NAME=\"%%k\" is ignored, because it breaks kernel supplied names, "
- "please remove it from %s:%u\n", filename, lineno);
+ "please remove it from %s:%u", filename, lineno);
continue;
}
if (value[0] == '\0') {
log_debug("NAME=\"\" is ignored, because udev will not delete any device nodes, "
- "please remove it from %s:%u\n", filename, lineno);
+ "please remove it from %s:%u", filename, lineno);
continue;
}
rule_add_key(&rule_tmp, TK_A_NAME, op, value, NULL);
@@ -1690,7 +1690,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) {
r = conf_files_list_strv(&files, ".rules", NULL, rules_dirs);
if (r < 0) {
- log_error("failed to enumerate rules files: %s", strerror(-r));
+ log_error_errno(r, "failed to enumerate rules files: %m");
return udev_rules_unref(rules);
}
@@ -1916,9 +1916,9 @@ int udev_rules_assigning_name_to(struct udev_rules *rules, const char *match_nam
strscpy(name_str,UTIL_PATH_SIZE,name);
count = util_replace_chars(name_str, "/");
if (count > 0)
- log_debug("%i character(s) replaced\n", count);
+ log_debug("%i character(s) replaced", count);
if (streq(name_str,match_name)) {
- log_debug("found a match! NAME assigns %s in: %s:%u\n",
+ log_debug("found a match! NAME assigns %s in: %s:%u",
name,
rules_str(rules, rule->rule.filename_off),
rule->rule.filename_line);
@@ -1945,6 +1945,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 token *cur;
struct token *rule;
@@ -2334,9 +2335,9 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
r = get_user_creds(&ow, &event->uid, NULL, NULL, NULL);
if (r < 0) {
if (r == -ENOENT || r == -ESRCH)
- udev_err(event->udev, "specified user '%s' unknown\n", owner);
+ log_error("specified user '%s' unknown", owner);
else
- udev_err(event->udev, "error resolving user '%s': %s\n", owner, strerror(-r));
+ log_error_errno(r, "error resolving user '%s': %m", owner);
event->uid = 0;
}
@@ -2360,9 +2361,9 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
r = get_group_creds(&gr, &event->gid);
if (r < 0) {
if (r == -ENOENT || r == -ESRCH)
- udev_err(event->udev, "specified group '%s' unknown\n", group);
+ log_error("specified group '%s' unknown", group);
else
- udev_err(event->udev, "error resolving group '%s': %s\n", group, strerror(-r));
+ log_error_errno(r, "error resolving group '%s': %m", group);
event->gid = 0;
}
@@ -2517,7 +2518,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
if (major(udev_device_get_devnum(event->dev)) &&
(!streq(name_str, udev_device_get_devnode(event->dev) + strlen("/dev/")))) {
log_error("NAME=\"%s\" ignored, kernel device nodes "
- "can not be renamed; please fix it in %s:%u\n", name,
+ "can not be renamed; please fix it in %s:%u", name,
rules_str(rules, rule->rule.filename_off), rule->rule.filename_line);
break;
}
@@ -2592,10 +2593,10 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
f = fopen(attr, "we");
if (f != NULL) {
if (fprintf(f, "%s", value) <= 0)
- log_error("error writing ATTR{%s}: %m", attr);
+ log_error_errno(errno, "error writing ATTR{%s}: %m", attr);
fclose(f);
} else {
- log_error("error opening ATTR{%s} for writing: %m", attr);
+ log_error_errno(errno, "error opening ATTR{%s} for writing: %m", attr);
}
break;
}
@@ -2710,7 +2711,7 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) {
strscpyl(tags_dir, sizeof(tags_dir), "/run/udev/static_node-tags/", *t, "/", NULL);
r = mkdir_p(tags_dir, 0755);
if (r < 0) {
- log_error("failed to create %s: %s", tags_dir, strerror(-r));
+ log_error_errno(r, "failed to create %s: %m", tags_dir);
return r;
}
@@ -2718,10 +2719,10 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) {
strscpyl(tag_symlink, sizeof(tag_symlink), tags_dir, unescaped_filename, NULL);
r = symlink(device_node, tag_symlink);
- if (r < 0 && errno != EEXIST) {
- log_error("failed to create symlink %s -> %s: %m", tag_symlink, device_node);
- return -errno;
- } else
+ if (r < 0 && errno != EEXIST)
+ return log_error_errno(errno, "failed to create symlink %s -> %s: %m",
+ tag_symlink, device_node);
+ else
r = 0;
}
}
diff --git a/src/udev/udev-watch.c b/src/udev/udev-watch.c
index 061bd05875..6ba8674d77 100644
--- a/src/udev/udev-watch.c
+++ b/src/udev/udev-watch.c
@@ -39,7 +39,7 @@ static int inotify_fd = -1;
int udev_watch_init(struct udev *udev) {
inotify_fd = inotify_init1(IN_CLOEXEC);
if (inotify_fd < 0)
- log_error("inotify_init failed: %m");
+ log_error_errno(errno, "inotify_init failed: %m");
return inotify_fd;
}
@@ -56,7 +56,7 @@ void udev_watch_restore(struct udev *udev) {
dir = opendir("/run/udev/watch.old");
if (dir == NULL) {
- log_error("unable to open old watches dir /run/udev/watch.old; old watches will not be restored: %m");
+ log_error_errno(errno, "unable to open old watches dir /run/udev/watch.old; old watches will not be restored: %m");
return;
}
@@ -88,7 +88,7 @@ unlink:
rmdir("/run/udev/watch.old");
} else if (errno != ENOENT) {
- log_error("unable to move watches dir /run/udev/watch; old watches will not be restored: %m");
+ log_error_errno(errno, "unable to move watches dir /run/udev/watch; old watches will not be restored: %m");
}
}
@@ -103,7 +103,7 @@ void udev_watch_begin(struct udev *udev, struct udev_device *dev) {
log_debug("adding watch on '%s'", udev_device_get_devnode(dev));
wd = inotify_add_watch(inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE);
if (wd < 0) {
- log_error("inotify_add_watch(%d, %s, %o) failed: %m",
+ log_error_errno(errno, "inotify_add_watch(%d, %s, %o) failed: %m",
inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE);
return;
}
@@ -113,7 +113,7 @@ void udev_watch_begin(struct udev *udev, struct udev_device *dev) {
unlink(filename);
r = symlink(udev_device_get_id_filename(dev), filename);
if (r < 0)
- log_error("Failed to create symlink %s: %m", filename);
+ log_error_errno(errno, "Failed to create symlink %s: %m", filename);
udev_device_set_watch_handle(dev, wd);
}
diff --git a/src/udev/udev.h b/src/udev/udev.h
index 5a1f5488cb..fae0408672 100644
--- a/src/udev/udev.h
+++ b/src/udev/udev.h
@@ -71,7 +71,9 @@ struct udev_rules;
struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names);
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,
+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);
int udev_rules_apply_static_dev_perms(struct udev_rules *rules);
@@ -86,8 +88,11 @@ int udev_event_spawn(struct udev_event *event,
usec_t timeout_warn_usec,
const char *cmd, char **envp, const sigset_t *sigmask,
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_rules *rules, const sigset_t *sigset);
+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);
int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]);
@@ -193,11 +198,6 @@ int udev_builtin_add_property(struct udev_device *dev, bool test, const char *ke
int udev_builtin_hwdb_lookup(struct udev_device *dev, const char *prefix, const char *modalias,
const char *filter, bool test);
-/* udev logging */
-void udev_main_log(struct udev *udev, int priority,
- const char *file, int line, const char *fn,
- const char *format, va_list args) _printf_(6, 0);
-
/* udevadm commands */
struct udevadm_cmd {
const char *name;
diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c
index 6e3bc2ae98..6af7163d47 100644
--- a/src/udev/udevadm-control.c
+++ b/src/udev/udevadm-control.c
@@ -29,16 +29,19 @@
#include "udev-util.h"
static void print_help(void) {
- printf("Usage: udevadm control COMMAND\n"
- " -e,--exit instruct the daemon to cleanup and exit\n"
- " -l,--log-priority=LEVEL set the udev log level for the daemon\n"
- " -s,--stop-exec-queue do not execute events, queue only\n"
- " -S,--start-exec-queue execute events, flush queue\n"
- " -R,--reload reload rules and databases\n"
- " -p,--property=KEY=VALUE set a global property for all events\n"
- " -m,--children-max=N maximum number of children\n"
- " --timeout=SECONDS maximum time to block for a reply\n"
- " -h,--help print this help text\n\n");
+ printf("%s control COMMAND\n\n"
+ "Control the udev daemon.\n\n"
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " -e --exit Instruct the daemon to cleanup and exit\n"
+ " -l --log-priority=LEVEL Set the udev log level for the daemon\n"
+ " -s --stop-exec-queue Do not execute events, queue only\n"
+ " -S --start-exec-queue Execute events, flush queue\n"
+ " -R --reload Reload rules and databases\n"
+ " -p --property=KEY=VALUE Set a global property for all events\n"
+ " -m --children-max=N Maximum number of children\n"
+ " --timeout=SECONDS Maximum time to block for a reply\n"
+ , program_invocation_short_name);
}
static int adm_control(struct udev *udev, int argc, char *argv[]) {
@@ -161,5 +164,5 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) {
const struct udevadm_cmd udevadm_control = {
.name = "control",
.cmd = adm_control,
- .help = "control the udev daemon",
+ .help = "Control the udev daemon",
};
diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c
index 4a3f35c2af..a3f93ba343 100644
--- a/src/udev/udevadm-hwdb.c
+++ b/src/udev/udevadm-hwdb.c
@@ -435,6 +435,10 @@ static int insert_data(struct trie *trie, struct udev_list *match_list,
value[0] = '\0';
value++;
+ /* libudev requires properties to start with a space */
+ while (isblank(line[0]) && isblank(line[1]))
+ line++;
+
if (line[0] == '\0' || value[0] == '\0') {
log_error("Error, empty key or value '%s' in '%s':", line, filename);
return -EINVAL;
@@ -615,7 +619,7 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
err = conf_files_list_strv(&files, ".hwdb", root, conf_file_dirs);
if (err < 0) {
- log_error("failed to enumerate hwdb files: %s", strerror(-err));
+ log_error_errno(err, "failed to enumerate hwdb files: %m");
rc = EXIT_FAILURE;
goto out;
}
@@ -648,7 +652,7 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
mkdir_parents(hwdb_bin, 0755);
err = trie_store(trie, hwdb_bin);
if (err < 0) {
- log_error("Failure writing database %s: %s", hwdb_bin, strerror(-err));
+ log_error_errno(err, "Failure writing database %s: %m", hwdb_bin);
rc = EXIT_FAILURE;
}
}
diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c
index 3cb503fc1f..c845df7a23 100644
--- a/src/udev/udevadm-info.c
+++ b/src/udev/udevadm-info.c
@@ -31,6 +31,7 @@
#include "udev.h"
#include "udev-util.h"
+#include "udevadm-util.h"
#include "util.h"
static bool skip_attribute(const char *name) {
@@ -258,33 +259,29 @@ static void cleanup_db(struct udev *udev) {
}
}
-static struct udev_device *find_device(struct udev *udev, const char *id, const char *prefix) {
- char name[UTIL_PATH_SIZE];
-
- if (prefix && !startswith(id, prefix)) {
- strscpyl(name, sizeof(name), prefix, id, NULL);
- id = name;
- }
-
- if (startswith(id, "/dev/")) {
- struct stat statbuf;
- char type;
-
- if (stat(id, &statbuf) < 0)
- return NULL;
-
- if (S_ISBLK(statbuf.st_mode))
- type = 'b';
- else if (S_ISCHR(statbuf.st_mode))
- type = 'c';
- else
- return NULL;
-
- return udev_device_new_from_devnum(udev, type, statbuf.st_rdev);
- } else if (startswith(id, "/sys/"))
- return udev_device_new_from_syspath(udev, id);
- else
- return NULL;
+static void help(void) {
+
+ printf("%s info [OPTIONS] [DEVPATH|FILE]\n\n"
+ "Query sysfs or the udev database.\n\n"
+ " -h --help Print this message\n"
+ " --version Print version of the program\n"
+ " -q --query=TYPE Query device information:\n"
+ " name Name of device node\n"
+ " symlink Pointing to node\n"
+ " path sysfs device path\n"
+ " property The device properties\n"
+ " all All values\n"
+ " -p --path=SYSPATH sysfs device path used for query or attribute walk\n"
+ " -n --name=NAME Node or symlink name used for query or attribute walk\n"
+ " -r --root Prepend dev directory to path names\n"
+ " -a --attribute-walk Print all key matches walking along the chain\n"
+ " of parent devices\n"
+ " -d --device-id-of-file=FILE Print major:minor of device containing this file\n"
+ " -x --export Export key/value pairs\n"
+ " -P --export-prefix Export the key name with a prefix\n"
+ " -e --export-db Export the content of the udev database\n"
+ " -c --cleanup-db Clean up the udev database\n"
+ , program_invocation_short_name);
}
static int uinfo(struct udev *udev, int argc, char *argv[]) {
@@ -312,27 +309,6 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) {
{}
};
- static const char *usage =
- "Usage: udevadm info [OPTIONS] [DEVPATH|FILE]\n"
- " -q,--query=TYPE query device information:\n"
- " name name of device node\n"
- " symlink pointing to node\n"
- " path sys device path\n"
- " property the device properties\n"
- " all all values\n"
- " -p,--path=SYSPATH sys device path used for query or attribute walk\n"
- " -n,--name=NAME node or symlink name used for query or attribute walk\n"
- " -r,--root prepend dev directory to path names\n"
- " -a,--attribute-walk print all key matches walking along the chain\n"
- " of parent devices\n"
- " -d,--device-id-of-file=FILE print major:minor of device containing this file\n"
- " -x,--export export key/value pairs\n"
- " -P,--export-prefix export the key name with a prefix\n"
- " -e,--export-db export the content of the udev database\n"
- " -c,--cleanup-db cleanup the udev database\n"
- " --version print version of the program\n"
- " -h,--help print this message\n";
-
enum action_type {
ACTION_QUERY,
ACTION_ATTRIBUTE_WALK,
@@ -417,7 +393,7 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) {
printf("%s\n", UDEV_VERSION);
return 0;
case 'h':
- printf("%s\n", usage);
+ help();
return 0;
default:
return 1;
@@ -427,7 +403,7 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) {
case ACTION_QUERY:
if (!device) {
if (!argv[optind]) {
- fprintf(stderr, "%s\n", usage);
+ help();
return 2;
}
device = find_device(udev, argv[optind], NULL);
@@ -518,5 +494,5 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) {
const struct udevadm_cmd udevadm_info = {
.name = "info",
.cmd = uinfo,
- .help = "query sysfs or the udev database",
+ .help = "Query sysfs or the udev database",
};
diff --git a/src/udev/udevadm-monitor.c b/src/udev/udevadm-monitor.c
index e776fb99dc..15ded09339 100644
--- a/src/udev/udevadm-monitor.c
+++ b/src/udev/udevadm-monitor.c
@@ -64,13 +64,16 @@ static void print_device(struct udev_device *device, const char *source, int pro
}
static void help(void) {
- printf("Usage: udevadm monitor [--property] [--kernel] [--udev] [--help]\n"
- " -p,--property print the event properties\n"
- " -k,--kernel print kernel uevents\n"
- " -u,--udev print udev events\n"
- " -s,--subsystem-match=SUBSYSTEM[/DEVTYPE] filter events by subsystem\n"
- " -t,--tag-match=TAG filter events by tag\n"
- " -h,--help\n\n");
+ printf("%s monitor [--property] [--kernel] [--udev] [--help]\n\n"
+ "Listen to kernel and udev events.\n\n"
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " -p --property Print the event properties\n"
+ " -k --kernel Print kernel uevents\n"
+ " -u --udev Print udev events\n"
+ " -s --subsystem-match=SUBSYSTEM[/DEVTYPE] Filter events by subsystem\n"
+ " -t --tag-match=TAG Filter events by tag\n"
+ , program_invocation_short_name);
}
static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
@@ -155,7 +158,7 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
fd_ep = epoll_create1(EPOLL_CLOEXEC);
if (fd_ep < 0) {
- log_error("error creating epoll fd: %m");
+ log_error_errno(errno, "error creating epoll fd: %m");
return 1;
}
@@ -195,7 +198,7 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
ep_udev.events = EPOLLIN;
ep_udev.data.fd = fd_udev;
if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) {
- log_error("fail to add fd to epoll: %m");
+ log_error_errno(errno, "fail to add fd to epoll: %m");
return 2;
}
@@ -229,7 +232,7 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
ep_kernel.events = EPOLLIN;
ep_kernel.data.fd = fd_kernel;
if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_kernel, &ep_kernel) < 0) {
- log_error("fail to add fd to epoll: %m");
+ log_error_errno(errno, "fail to add fd to epoll: %m");
return 5;
}
@@ -276,5 +279,5 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
const struct udevadm_cmd udevadm_monitor = {
.name = "monitor",
.cmd = adm_monitor,
- .help = "listen to kernel and udev events",
+ .help = "Listen to kernel and udev events",
};
diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c
index 0a8f535c4a..fff5de7a8b 100644
--- a/src/udev/udevadm-settle.c
+++ b/src/udev/udevadm-settle.c
@@ -37,20 +37,23 @@
#include "util.h"
static void help(void) {
- printf("Usage: udevadm settle OPTIONS\n"
- " -t,--timeout=<seconds> maximum time to wait for events\n"
- " -E,--exit-if-exists=<file> stop waiting if file exists\n"
- " -h,--help\n\n");
+ printf("%s settle OPTIONS\n\n"
+ "Wait for pending udev events.\n\n"
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " -t --timeout=SECONDS Maximum time to wait for events\n"
+ " -E --exit-if-exists=FILE Stop waiting if file exists\n"
+ , program_invocation_short_name);
}
static int adm_settle(struct udev *udev, int argc, char *argv[]) {
static const struct option options[] = {
- { "seq-start", required_argument, NULL, '\0' }, /* removed */
- { "seq-end", required_argument, NULL, '\0' }, /* removed */
{ "timeout", required_argument, NULL, 't' },
{ "exit-if-exists", required_argument, NULL, 'E' },
- { "quiet", no_argument, NULL, 'q' }, /* removed */
{ "help", no_argument, NULL, 'h' },
+ { "seq-start", required_argument, NULL, 's' }, /* removed */
+ { "seq-end", required_argument, NULL, 'e' }, /* removed */
+ { "quiet", no_argument, NULL, 'q' }, /* removed */
{}
};
const char *exists = NULL;
@@ -60,8 +63,9 @@ static int adm_settle(struct udev *udev, int argc, char *argv[]) {
struct udev_queue *queue;
int rc = EXIT_FAILURE;
- while ((c = getopt_long(argc, argv, "s:e:t:E:qh", options, NULL)) >= 0) {
+ while ((c = getopt_long(argc, argv, "t:E:hs:e:q", options, NULL)) >= 0) {
switch (c) {
+
case 't': {
int r;
@@ -73,14 +77,24 @@ static int adm_settle(struct udev *udev, int argc, char *argv[]) {
};
break;
}
+
case 'E':
exists = optarg;
break;
+
case 'h':
help();
return EXIT_SUCCESS;
+
+ case 's':
+ case 'e':
+ case 'q':
+ log_info("Option -%c no longer supported.", c);
+ return EXIT_FAILURE;
+
case '?':
return EXIT_FAILURE;
+
default:
assert_not_reached("Unknown argument");
}
@@ -145,5 +159,5 @@ out:
const struct udevadm_cmd udevadm_settle = {
.name = "settle",
.cmd = adm_settle,
- .help = "wait for pending udev events",
+ .help = "Wait for pending udev events",
};
diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c
index f25608c486..baaeca9352 100644
--- a/src/udev/udevadm-test-builtin.c
+++ b/src/udev/udevadm-test-builtin.c
@@ -34,10 +34,14 @@
#include "udev.h"
static void help(struct udev *udev) {
- fprintf(stderr, "\n");
- fprintf(stderr, "Usage: udevadm builtin [--help] COMMAND SYSPATH\n");
+ printf("%s builtin [--help] COMMAND SYSPATH\n\n"
+ "Test a built-in command.\n\n"
+ " -h --help Print this message\n"
+ " --version Print version of the program\n\n"
+ "Commands:\n"
+ , program_invocation_short_name);
+
udev_builtin_list(udev);
- fprintf(stderr, "\n");
}
static int adm_builtin(struct udev *udev, int argc, char *argv[]) {
@@ -112,6 +116,6 @@ out:
const struct udevadm_cmd udevadm_test_builtin = {
.name = "test-builtin",
.cmd = adm_builtin,
- .help = "test a built-in command",
+ .help = "Test a built-in command",
.debug = true,
};
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
index 4738b611c3..4922b5b6ac 100644
--- a/src/udev/udevadm-test.c
+++ b/src/udev/udevadm-test.c
@@ -31,6 +31,17 @@
#include "udev.h"
#include "udev-util.h"
+static void help(void) {
+
+ printf("%s test OPTIONS <syspath>\n\n"
+ "Test an event run.\n"
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " -a --action=ACTION Set action string\n"
+ " -N --resolve-names=early|late|never When to resolve names\n"
+ , program_invocation_short_name);
+}
+
static int adm_test(struct udev *udev, int argc, char *argv[]) {
int resolve_names = 1;
char filename[UTIL_PATH_SIZE];
@@ -71,11 +82,7 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) {
}
break;
case 'h':
- printf("Usage: udevadm test OPTIONS <syspath>\n"
- " -a,--action=ACTION set action string\n"
- " -N,--resolve-names=early|late|never when to resolve names\n"
- " -h,--help print this help string\n"
- "\n");
+ help();
exit(EXIT_SUCCESS);
case '?':
exit(EXIT_FAILURE);
@@ -136,7 +143,11 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) {
goto out;
}
- udev_event_execute_rules(event, 60 * USEC_PER_SEC, 20 * USEC_PER_SEC, rules, &sigmask_orig);
+ udev_event_execute_rules(event,
+ 60 * USEC_PER_SEC, 20 * USEC_PER_SEC,
+ NULL,
+ rules,
+ &sigmask_orig);
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));
@@ -157,6 +168,6 @@ out:
const struct udevadm_cmd udevadm_test = {
.name = "test",
.cmd = adm_test,
- .help = "test an event run",
+ .help = "Test an event run",
.debug = true,
};
diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c
index a52d1b5ad5..4dc756a28b 100644
--- a/src/udev/udevadm-trigger.c
+++ b/src/udev/udevadm-trigger.c
@@ -32,6 +32,7 @@
#include "udev.h"
#include "udev-util.h"
+#include "udevadm-util.h"
#include "util.h"
static int verbose;
@@ -53,7 +54,7 @@ static void exec_list(struct udev_enumerate *udev_enumerate, const char *action)
if (fd < 0)
continue;
if (write(fd, action, strlen(action)) < 0)
- log_debug("error writing '%s' to '%s': %m", action, filename);
+ log_debug_errno(errno, "error writing '%s' to '%s': %m", action, filename);
close(fd);
}
}
@@ -72,39 +73,48 @@ static const char *keyval(const char *str, const char **val, char *buf, size_t s
}
static void help(void) {
- printf("Usage: udevadm trigger OPTIONS\n"
- " -v,--verbose print the list of devices while running\n"
- " -n,--dry-run do not actually trigger the events\n"
- " -t,--type= type of events to trigger\n"
- " devices sys devices (default)\n"
- " subsystems sys subsystems and drivers\n"
- " -c,--action=<action> event action value, default is \"change\"\n"
- " -s,--subsystem-match=<subsystem> trigger devices from a matching subsystem\n"
- " -S,--subsystem-nomatch=<subsystem> exclude devices from a matching subsystem\n"
- " -a,--attr-match=<file[=<value>]> trigger devices with a matching attribute\n"
- " -A,--attr-nomatch=<file[=<value>]> exclude devices with a matching attribute\n"
- " -p,--property-match=<key>=<value> trigger devices with a matching property\n"
- " -g,--tag-match=<key>=<value> trigger devices with a matching property\n"
- " -y,--sysname-match=<name> trigger devices with a matching name\n"
- " -b,--parent-match=<name> trigger devices with that parent device\n"
- " -h,--help\n\n");
+ printf("%s trigger OPTIONS\n\n"
+ "Request events from the kernel.\n\n"
+ " -h --help Show this help\n"
+ " --version Show package version\n"
+ " -v --verbose Print the list of devices while running\n"
+ " -n --dry-run Do not actually trigger the events\n"
+ " -t --type= Type of events to trigger\n"
+ " devices sysfs devices (default)\n"
+ " subsystems sysfs subsystems and drivers\n"
+ " -c --action=ACTION Event action value, default is \"change\"\n"
+ " -s --subsystem-match=SUBSYSTEM Trigger devices from a matching subsystem\n"
+ " -S --subsystem-nomatch=SUBSYSTEM Exclude devices from a matching subsystem\n"
+ " -a --attr-match=FILE[=VALUE] Trigger devices with a matching attribute\n"
+ " -A --attr-nomatch=FILE[=VALUE] Exclude devices with a matching attribute\n"
+ " -p --property-match=KEY=VALUE Trigger devices with a matching property\n"
+ " -g --tag-match=KEY=VALUE Trigger devices with a matching property\n"
+ " -y --sysname-match=NAME Trigger devices with this /sys path\n"
+ " --name-match=NAME Trigger devices with this /dev name\n"
+ " -b --parent-match=NAME Trigger devices with that parent device\n"
+ , program_invocation_short_name);
}
static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
+ enum {
+ ARG_NAME = 0x100,
+ };
+
static const struct option options[] = {
- { "verbose", no_argument, NULL, 'v' },
- { "dry-run", no_argument, NULL, 'n' },
- { "type", required_argument, NULL, 't' },
- { "action", required_argument, NULL, 'c' },
- { "subsystem-match", required_argument, NULL, 's' },
- { "subsystem-nomatch", required_argument, NULL, 'S' },
- { "attr-match", required_argument, NULL, 'a' },
- { "attr-nomatch", required_argument, NULL, 'A' },
- { "property-match", required_argument, NULL, 'p' },
- { "tag-match", required_argument, NULL, 'g' },
- { "sysname-match", required_argument, NULL, 'y' },
- { "parent-match", required_argument, NULL, 'b' },
- { "help", no_argument, NULL, 'h' },
+ { "verbose", no_argument, NULL, 'v' },
+ { "dry-run", no_argument, NULL, 'n' },
+ { "type", required_argument, NULL, 't' },
+ { "action", required_argument, NULL, 'c' },
+ { "subsystem-match", required_argument, NULL, 's' },
+ { "subsystem-nomatch", required_argument, NULL, 'S' },
+ { "attr-match", required_argument, NULL, 'a' },
+ { "attr-nomatch", required_argument, NULL, 'A' },
+ { "property-match", required_argument, NULL, 'p' },
+ { "tag-match", required_argument, NULL, 'g' },
+ { "sysname-match", required_argument, NULL, 'y' },
+ { "name-match", required_argument, NULL, ARG_NAME },
+ { "parent-match", required_argument, NULL, 'b' },
+ { "help", no_argument, NULL, 'h' },
{}
};
enum {
@@ -174,25 +184,31 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
udev_enumerate_add_match_sysname(udev_enumerate, optarg);
break;
case 'b': {
- char path[UTIL_PATH_SIZE];
- struct udev_device *dev;
-
- /* add sys dir if needed */
- if (!startswith(optarg, "/sys"))
- strscpyl(path, sizeof(path), "/sys", optarg, NULL);
- else
- strscpy(path, sizeof(path), optarg);
- util_remove_trailing_chars(path, '/');
- dev = udev_device_new_from_syspath(udev, path);
+ _cleanup_udev_device_unref_ struct udev_device *dev;
+
+ dev = find_device(udev, optarg, "/sys");
+ if (dev == NULL) {
+ log_error("unable to open the device '%s'", optarg);
+ return 2;
+ }
+
+ udev_enumerate_add_match_parent(udev_enumerate, dev);
+ break;
+ }
+
+ case ARG_NAME: {
+ _cleanup_udev_device_unref_ struct udev_device *dev;
+
+ dev = find_device(udev, optarg, "/dev/");
if (dev == NULL) {
log_error("unable to open the device '%s'", optarg);
return 2;
}
+
udev_enumerate_add_match_parent(udev_enumerate, dev);
- /* drop reference immediately, enumerate pins the device as long as needed */
- udev_device_unref(dev);
break;
}
+
case 'h':
help();
return 0;
@@ -203,9 +219,16 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
}
}
- if (optind < argc) {
- fprintf(stderr, "Extraneous argument: '%s'\n", argv[optind]);
- return 1;
+ for (; optind < argc; optind++) {
+ _cleanup_udev_device_unref_ struct udev_device *dev;
+
+ dev = find_device(udev, argv[optind], NULL);
+ if (dev == NULL) {
+ log_error("unable to open the device '%s'", argv[optind]);
+ return 2;
+ }
+
+ udev_enumerate_add_match_parent(udev_enumerate, dev);
}
switch (device_type) {
@@ -225,5 +248,5 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
const struct udevadm_cmd udevadm_trigger = {
.name = "trigger",
.cmd = adm_trigger,
- .help = "request events from the kernel",
+ .help = "Request events from the kernel",
};
diff --git a/src/udev/udevadm-util.c b/src/udev/udevadm-util.c
new file mode 100644
index 0000000000..37e80c31df
--- /dev/null
+++ b/src/udev/udevadm-util.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008-2009 Kay Sievers <kay@vrfy.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "udevadm-util.h"
+
+struct udev_device *find_device(struct udev *udev,
+ const char *id,
+ const char *prefix) {
+
+ assert(udev);
+ assert(id);
+
+ if (prefix && !startswith(id, prefix))
+ id = strappenda(prefix, id);
+
+ if (startswith(id, "/dev/")) {
+ struct stat statbuf;
+ char type;
+
+ if (stat(id, &statbuf) < 0)
+ return NULL;
+
+ if (S_ISBLK(statbuf.st_mode))
+ type = 'b';
+ else if (S_ISCHR(statbuf.st_mode))
+ type = 'c';
+ else
+ return NULL;
+
+ return udev_device_new_from_devnum(udev, type, statbuf.st_rdev);
+ } else if (startswith(id, "/sys/"))
+ return udev_device_new_from_syspath(udev, id);
+ else
+ return NULL;
+}
diff --git a/src/udev/udevadm-util.h b/src/udev/udevadm-util.h
new file mode 100644
index 0000000000..dba651fddb
--- /dev/null
+++ b/src/udev/udevadm-util.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "udev.h"
+
+struct udev_device *find_device(struct udev *udev,
+ const char *id,
+ const char *prefix);
diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c
index fda5aecd83..3e57cf6dee 100644
--- a/src/udev/udevadm.c
+++ b/src/udev/udevadm.c
@@ -26,12 +26,6 @@
#include "udev.h"
-void udev_main_log(struct udev *udev, int priority,
- const char *file, int line, const char *fn,
- const char *format, va_list args) {
- log_metav(priority, file, line, fn, format, args);
-}
-
static int adm_version(struct udev *udev, int argc, char *argv[]) {
printf("%s\n", UDEV_VERSION);
return 0;
@@ -65,11 +59,14 @@ static const struct udevadm_cmd *udevadm_cmds[] = {
static int adm_help(struct udev *udev, int argc, char *argv[]) {
unsigned int i;
- fprintf(stderr, "Usage: udevadm [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n");
+ printf("%s [--help] [--version] [--debug] COMMAND [COMMAND OPTIONS]\n\n"
+ "Send control commands or test the device manager.\n\n"
+ "Commands:\n"
+ , program_invocation_short_name);
+
for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++)
if (udevadm_cmds[i]->help != NULL)
- printf(" %-12s %s\n", udevadm_cmds[i]->name, udevadm_cmds[i]->help);
- fprintf(stderr, "\n");
+ printf(" %-12s %s\n", udevadm_cmds[i]->name, udevadm_cmds[i]->help);
return 0;
}
@@ -97,7 +94,6 @@ int main(int argc, char *argv[]) {
goto out;
log_open();
- udev_set_log_fn(udev, udev_main_log);
mac_selinux_init("/dev");
while ((c = getopt_long(argc, argv, "+dhV", options, NULL)) >= 0)
@@ -105,7 +101,6 @@ int main(int argc, char *argv[]) {
case 'd':
log_set_max_level(LOG_DEBUG);
- udev_set_log_priority(udev, LOG_DEBUG);
break;
case 'h':
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index a74906aa62..e835bef8df 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -53,12 +53,6 @@
#include "dev-setup.h"
#include "fileio.h"
-void udev_main_log(struct udev *udev, int priority,
- const char *file, int line, const char *fn,
- const char *format, va_list args) {
- log_metav(priority, file, line, fn, format, args);
-}
-
static struct udev_rules *rules;
static struct udev_ctrl *udev_ctrl;
static struct udev_monitor *monitor;
@@ -80,6 +74,7 @@ static sigset_t sigmask_orig;
static UDEV_LIST(event_list);
static UDEV_LIST(worker_list);
static char *udev_cgroup;
+static struct udev_list properties_list;
static bool udev_exit;
enum event_state {
@@ -223,14 +218,14 @@ static void worker_new(struct event *event) {
sigfillset(&mask);
fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
if (fd_signal < 0) {
- log_error("error creating signalfd %m");
+ log_error_errno(errno, "error creating signalfd %m");
rc = 2;
goto out;
}
fd_ep = epoll_create1(EPOLL_CLOEXEC);
if (fd_ep < 0) {
- log_error("error creating epoll fd: %m");
+ log_error_errno(errno, "error creating epoll fd: %m");
rc = 3;
goto out;
}
@@ -246,7 +241,7 @@ static void worker_new(struct event *event) {
if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_signal, &ep_signal) < 0 ||
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_monitor, &ep_monitor) < 0) {
- log_error("fail to add fds to epoll: %m");
+ log_error_errno(errno, "fail to add fds to epoll: %m");
rc = 4;
goto out;
}
@@ -296,7 +291,7 @@ static void worker_new(struct event *event) {
if (d) {
fd_lock = open(udev_device_get_devnode(d), O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK);
if (fd_lock >= 0 && flock(fd_lock, LOCK_SH|LOCK_NB) < 0) {
- log_debug("Unable to flock(%s), skipping event handling: %m", udev_device_get_devnode(d));
+ log_debug_errno(errno, "Unable to flock(%s), skipping event handling: %m", udev_device_get_devnode(d));
err = -EWOULDBLOCK;
fd_lock = safe_close(fd_lock);
goto skip;
@@ -305,9 +300,15 @@ static void worker_new(struct event *event) {
}
/* apply rules, create node, symlinks */
- udev_event_execute_rules(udev_event, arg_event_timeout_usec, arg_event_timeout_warn_usec, rules, &sigmask_orig);
+ udev_event_execute_rules(udev_event,
+ arg_event_timeout_usec, arg_event_timeout_warn_usec,
+ &properties_list,
+ rules,
+ &sigmask_orig);
- udev_event_execute_run(udev_event, arg_event_timeout_usec, arg_event_timeout_warn_usec, &sigmask_orig);
+ udev_event_execute_run(udev_event,
+ arg_event_timeout_usec, arg_event_timeout_warn_usec,
+ &sigmask_orig);
/* apply/restore inotify watch */
if (udev_event->inotify_watch) {
@@ -349,7 +350,7 @@ skip:
if (fdcount < 0) {
if (errno == EINTR)
continue;
- log_error("failed to poll: %m");
+ log_error_errno(errno, "failed to poll: %m");
goto out;
}
@@ -389,7 +390,7 @@ out:
udev_monitor_unref(worker_monitor);
event->state = EVENT_QUEUED;
free(worker);
- log_error("fork of child failed: %m");
+ log_error_errno(errno, "fork of child failed: %m");
break;
default:
/* close monitor, but keep address around */
@@ -420,7 +421,7 @@ static void event_run(struct event *event) {
count = udev_monitor_send_device(monitor, worker->monitor, event->dev);
if (count < 0) {
- log_error("worker [%u] did not accept message %zi (%m), kill it", worker->pid, count);
+ log_error_errno(errno, "worker [%u] did not accept message %zi (%m), kill it", worker->pid, count);
kill(worker->pid, SIGKILL);
worker->state = WORKER_KILLED;
continue;
@@ -636,7 +637,6 @@ static struct udev_ctrl_connection *handle_ctrl_msg(struct udev_ctrl *uctrl) {
if (i >= 0) {
log_debug("udevd message (SET_LOG_LEVEL) received, log_priority=%i", i);
log_set_max_level(i);
- udev_set_log_priority(udev, i);
worker_kill(udev);
}
@@ -669,10 +669,10 @@ static struct udev_ctrl_connection *handle_ctrl_msg(struct udev_ctrl *uctrl) {
val = &val[1];
if (val[0] == '\0') {
log_debug("udevd message (ENV) received, unset '%s'", key);
- udev_add_property(udev, key, NULL);
+ udev_list_entry_add(&properties_list, key, NULL);
} else {
log_debug("udevd message (ENV) received, set '%s=%s'", key, val);
- udev_add_property(udev, key, val);
+ udev_list_entry_add(&properties_list, key, val);
}
} else {
log_error("wrong key format '%s'", key);
@@ -807,41 +807,34 @@ static int synthesize_change(struct udev_device *dev) {
}
static int handle_inotify(struct udev *udev) {
- int nbytes, pos;
- char *buf;
- struct inotify_event *ev;
- int r;
+ union inotify_event_buffer buffer;
+ struct inotify_event *e;
+ ssize_t l;
- r = ioctl(fd_inotify, FIONREAD, &nbytes);
- if (r < 0 || nbytes <= 0)
- return -errno;
+ l = read(fd_inotify, &buffer, sizeof(buffer));
+ if (l < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ return 0;
- buf = malloc(nbytes);
- if (!buf) {
- log_error("error getting buffer for inotify");
- return -ENOMEM;
+ return log_error_errno(errno, "Failed to read inotify fd: %m");
}
- nbytes = read(fd_inotify, buf, nbytes);
-
- for (pos = 0; pos < nbytes; pos += sizeof(struct inotify_event) + ev->len) {
+ FOREACH_INOTIFY_EVENT(e, buffer, l) {
struct udev_device *dev;
- ev = (struct inotify_event *)(buf + pos);
- dev = udev_watch_lookup(udev, ev->wd);
+ dev = udev_watch_lookup(udev, e->wd);
if (!dev)
continue;
- log_debug("inotify event: %x for %s", ev->mask, udev_device_get_devnode(dev));
- if (ev->mask & IN_CLOSE_WRITE)
+ log_debug("inotify event: %x for %s", e->mask, udev_device_get_devnode(dev));
+ if (e->mask & IN_CLOSE_WRITE)
synthesize_change(dev);
- else if (ev->mask & IN_IGNORED)
+ else if (e->mask & IN_IGNORED)
udev_watch_end(udev, dev);
udev_device_unref(dev);
}
- free(buf);
return 0;
}
@@ -966,7 +959,7 @@ static void static_dev_create_from_modules(struct udev *udev) {
strscpyl(filename, sizeof(filename), "/dev/", devname, NULL);
mkdir_parents_label(filename, 0755);
mac_selinux_create_file_prepare(filename, mode);
- log_debug("mknod '%s' %c%u:%u\n", filename, type, maj, min);
+ log_debug("mknod '%s' %c%u:%u", filename, type, maj, min);
if (mknod(filename, mode, makedev(maj, min)) < 0 && errno == EEXIST)
utimensat(AT_FDCWD, filename, NULL, 0);
mac_selinux_create_file_clear();
@@ -976,7 +969,7 @@ static void static_dev_create_from_modules(struct udev *udev) {
}
/*
- * read the kernel commandline, in case we need to get into debug mode
+ * read the kernel command line, in case we need to get into debug mode
* udev.log-priority=<level> syslog priority
* udev.children-max=<number of workers> events are fully serialized if set to 1
* udev.exec-delay=<number of seconds> delay execution of every executed program
@@ -988,13 +981,13 @@ static void kernel_cmdline_options(struct udev *udev) {
int r;
r = proc_cmdline(&line);
- if (r < 0)
- log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
- if (r <= 0)
+ if (r < 0) {
+ log_warning_errno(r, "Failed to read /proc/cmdline, ignoring: %m");
return;
+ }
FOREACH_WORD_QUOTED(word, l, line, state) {
- char *s, *opt;
+ char *s, *opt, *value;
s = strndup(word, l);
if (!s)
@@ -1006,24 +999,23 @@ static void kernel_cmdline_options(struct udev *udev) {
else
opt = s;
- if (startswith(opt, "udev.log-priority=")) {
+ if ((value = startswith(opt, "udev.log-priority="))) {
int prio;
- prio = util_log_priority(opt + 18);
+ prio = util_log_priority(value);
log_set_max_level(prio);
- udev_set_log_priority(udev, prio);
- } else if (startswith(opt, "udev.children-max=")) {
- r = safe_atoi(opt + 18, &arg_children_max);
+ } else if ((value = startswith(opt, "udev.children-max="))) {
+ r = safe_atoi(value, &arg_children_max);
if (r < 0)
- log_warning("Invalid udev.children-max ignored: %s", opt + 18);
- } else if (startswith(opt, "udev.exec-delay=")) {
- r = safe_atoi(opt + 16, &arg_exec_delay);
+ log_warning("Invalid udev.children-max ignored: %s", value);
+ } else if ((value = startswith(opt, "udev.exec-delay="))) {
+ r = safe_atoi(value, &arg_exec_delay);
if (r < 0)
- log_warning("Invalid udev.exec-delay ignored: %s", opt + 16);
- } else if (startswith(opt, "udev.event-timeout=")) {
- r = safe_atou64(opt + 16, &arg_event_timeout_usec);
+ log_warning("Invalid udev.exec-delay ignored: %s", value);
+ } else if ((value = startswith(opt, "udev.event-timeout="))) {
+ r = safe_atou64(value, &arg_event_timeout_usec);
if (r < 0) {
- log_warning("Invalid udev.event-timeout ignored: %s", opt + 16);
+ log_warning("Invalid udev.event-timeout ignored: %s", value);
break;
}
arg_event_timeout_usec *= USEC_PER_SEC;
@@ -1037,14 +1029,15 @@ static void kernel_cmdline_options(struct udev *udev) {
static void help(void) {
printf("%s [OPTIONS...]\n\n"
"Manages devices.\n\n"
- " --daemon\n"
- " --debug\n"
- " --children-max=<maximum number of workers>\n"
- " --exec-delay=<seconds to wait before executing RUN=>\n"
- " --event-timeout=<seconds to wait before terminating an event>\n"
- " --resolve-names=early|late|never\n"
- " --version\n"
- " --help\n"
+ " -h --help Print this message\n"
+ " --version Print version of the program\n"
+ " --daemon Detach and run in the background\n"
+ " --debug Enable debug output\n"
+ " --children-max=INT Set maximum number of workers\n"
+ " --exec-delay=SECONDS Seconds to wait before executing RUN=\n"
+ " --event-timeout=SECONDS Seconds to wait before terminating an event\n"
+ " --resolve-names=early|late|never\n"
+ " When to resolve users and groups\n"
, program_invocation_short_name);
}
@@ -1146,19 +1139,14 @@ int main(int argc, char *argv[]) {
log_set_target(LOG_TARGET_AUTO);
log_open();
- udev_set_log_fn(udev, udev_main_log);
- log_set_max_level(udev_get_log_priority(udev));
-
r = parse_argv(argc, argv);
if (r <= 0)
goto exit;
kernel_cmdline_options(udev);
- if (arg_debug) {
+ if (arg_debug)
log_set_max_level(LOG_DEBUG);
- udev_set_log_priority(udev, LOG_DEBUG);
- }
if (getuid() != 0) {
log_error("root privileges required");
@@ -1167,22 +1155,24 @@ int main(int argc, char *argv[]) {
r = mac_selinux_init("/dev");
if (r < 0) {
- log_error("could not initialize labelling: %s", strerror(-r));
+ log_error_errno(r, "could not initialize labelling: %m");
goto exit;
}
/* set umask before creating any file/directory */
r = chdir("/");
if (r < 0) {
- log_error("could not change dir to /: %m");
+ log_error_errno(errno, "could not change dir to /: %m");
goto exit;
}
umask(022);
+ udev_list_init(udev, &properties_list, true);
+
r = mkdir("/run/udev", 0755);
if (r < 0 && errno != EEXIST) {
- log_error("could not create /run/udev: %m");
+ log_error_errno(errno, "could not create /run/udev: %m");
goto exit;
}
@@ -1237,7 +1227,7 @@ int main(int argc, char *argv[]) {
udev_monitor_set_receive_buffer_size(monitor, 128 * 1024 * 1024);
- log_info("starting version " VERSION "\n");
+ log_info("starting version " VERSION);
udev_builtin_init(udev);
@@ -1249,7 +1239,7 @@ int main(int argc, char *argv[]) {
rc = udev_rules_apply_static_dev_perms(rules);
if (rc < 0)
- log_error("failed to apply permissions on static device nodes - %s", strerror(-rc));
+ log_error_errno(rc, "failed to apply permissions on static device nodes - %m");
if (arg_daemonize) {
pid_t pid;
@@ -1259,7 +1249,7 @@ int main(int argc, char *argv[]) {
case 0:
break;
case -1:
- log_error("fork of daemon failed: %m");
+ log_error_errno(errno, "fork of daemon failed: %m");
rc = 4;
goto exit;
default:
@@ -1332,7 +1322,7 @@ int main(int argc, char *argv[]) {
fd_ep = epoll_create1(EPOLL_CLOEXEC);
if (fd_ep < 0) {
- log_error("error creating epoll fd: %m");
+ log_error_errno(errno, "error creating epoll fd: %m");
goto exit;
}
if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_ctrl, &ep_ctrl) < 0 ||
@@ -1340,7 +1330,7 @@ int main(int argc, char *argv[]) {
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_signal, &ep_signal) < 0 ||
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_netlink, &ep_netlink) < 0 ||
epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_worker, &ep_worker) < 0) {
- log_error("fail to add fds to epoll: %m");
+ log_error_errno(errno, "fail to add fds to epoll: %m");
goto exit;
}