diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2014-01-13 18:16:50 -0500 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2014-01-13 18:16:50 -0500 |
commit | e33d2cfc5e0bafb10eb82bb32776c41e558a026c (patch) | |
tree | 619ae0451cd40f169d740a02f26bf46a17c854b1 | |
parent | 248ea81923ce671979ccbe0bca5683d4239feb70 (diff) |
src/udev: bring up to date with upstream.
These commits were authored by
Zbigniew Jędrzejewski-Szmek
Tom Gundersen
Kay Sievers
Lennart Poettering
Shawn Landden
Daniel Buch
Martin Pitt
Karel Zak
Yang Zhiyong
Note: udev_builtin_net_setup_link has *not* been imported. Also
still missing from udev-builtin is udev_builtin_uaccess.
Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
30 files changed, 1038 insertions, 795 deletions
diff --git a/configure.ac b/configure.ac index 6d85ad774e..13d74fcb15 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.68]) -AC_INIT([eudev],[1.3],[https://github.com/gentoo/eudev/issues]) +AC_INIT([eudev],[1.4],[https://github.com/gentoo/eudev/issues]) AC_SUBST(UDEV_VERSION, 207) AC_CONFIG_SRCDIR([src/udev/udevd.c]) diff --git a/src/libudev/Makefile.am b/src/libudev/Makefile.am index a588080d12..286dc4b62a 100644 --- a/src/libudev/Makefile.am +++ b/src/libudev/Makefile.am @@ -37,6 +37,7 @@ libudev_la_SOURCES =\ conf-files.c \ device-nodes.c \ exit-status.c \ + fileio.c \ hashmap.c \ log.c \ MurmurHash2.c \ @@ -56,6 +57,7 @@ noinst_HEADERS = \ def.h \ device-nodes.h \ exit-status.h \ + fileio.h \ hashmap.h \ ioprio.h \ log.h \ diff --git a/src/libudev/fileio.c b/src/libudev/fileio.c new file mode 100644 index 0000000000..8eb834dcd0 --- /dev/null +++ b/src/libudev/fileio.c @@ -0,0 +1,139 @@ +/*** + This file is part of eudev, forked from systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <unistd.h> +#include <sys/sendfile.h> +#include "fileio.h" +#include "util.h" +#include "strv.h" +#include "utf8.h" +#include "ctype.h" + +int write_string_to_file(FILE *f, const char *line) { + errno = 0; + fputs(line, f); + if (!endswith(line, "\n")) + fputc('\n', f); + + fflush(f); + + if (ferror(f)) + return errno ? -errno : -EIO; + + return 0; +} + +int write_string_file(const char *fn, const char *line) { + _cleanup_fclose_ FILE *f = NULL; + + assert(fn); + assert(line); + + f = fopen(fn, "we"); + if (!f) + return -errno; + + return write_string_to_file(f, line); +} +int read_one_line_file(const char *fn, char **line) { + _cleanup_fclose_ FILE *f = NULL; + char t[LINE_MAX], *c; + + assert(fn); + assert(line); + + f = fopen(fn, "re"); + if (!f) + return -errno; + + if (!fgets(t, sizeof(t), f)) { + + if (ferror(f)) + return errno ? -errno : -EIO; + + t[0] = 0; + } + + c = strdup(t); + if (!c) + return -ENOMEM; + truncate_nl(c); + + *line = c; + return 0; +} + +int read_full_file(const char *fn, char **contents, size_t *size) { + _cleanup_fclose_ FILE *f = NULL; + size_t n, l; + _cleanup_free_ char *buf = NULL; + struct stat st; + + assert(fn); + assert(contents); + + f = fopen(fn, "re"); + if (!f) + return -errno; + + if (fstat(fileno(f), &st) < 0) + return -errno; + + /* Safety check */ + if (st.st_size > 4*1024*1024) + return -E2BIG; + + n = st.st_size > 0 ? st.st_size : LINE_MAX; + l = 0; + + for (;;) { + char *t; + size_t k; + + t = realloc(buf, n+1); + if (!t) + return -ENOMEM; + + buf = t; + k = fread(buf + l, 1, n - l, f); + + if (k <= 0) { + if (ferror(f)) + return -errno; + + break; + } + + l += k; + n *= 2; + + /* Safety check */ + if (n > 4*1024*1024) + return -E2BIG; + } + + buf[l] = 0; + *contents = buf; + buf = NULL; /* do not free */ + + if (size) + *size = l; + + return 0; +} diff --git a/src/libudev/fileio.h b/src/libudev/fileio.h new file mode 100644 index 0000000000..c7997c58a2 --- /dev/null +++ b/src/libudev/fileio.h @@ -0,0 +1,27 @@ +/*** + This file is part of eudev, forked from systemd. + + Copyright 2010 Lennart Poettering + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ +#include <stddef.h> +#include <stdio.h> + +#include "macro.h" + +int write_string_to_file(FILE *f, const char *line); +int write_string_file(const char *fn, const char *line); +int read_one_line_file(const char *fn, char **line); +int read_full_file(const char *fn, char **contents, size_t *size); diff --git a/src/libudev/util.c b/src/libudev/util.c index 58377d548f..98be5307f6 100644 --- a/src/libudev/util.c +++ b/src/libudev/util.c @@ -69,6 +69,7 @@ #include "path-util.h" #include "exit-status.h" #include "hashmap.h" +#include "fileio.h" int saved_argc = 0; char **saved_argv = NULL; @@ -254,23 +255,6 @@ char* endswith(const char *s, const char *postfix) { return (char*) s + sl - pl; } -char* startswith(const char *s, const char *prefix) { - const char *a, *b; - - assert(s); - assert(prefix); - - a = s, b = prefix; - for (;;) { - if (*b == 0) - return (char*) a; - if (*a != *b) - return NULL; - - a++, b++; - } -} - int close_nointr(int fd) { int r; @@ -449,59 +433,6 @@ char *split_quoted(const char *c, size_t *l, char **state) { return (char*) current; } -int write_one_line_file(const char *fn, const char *line) { - _cleanup_fclose_ FILE *f = NULL; - - assert(fn); - assert(line); - - f = fopen(fn, "we"); - if (!f) - return -errno; - - errno = 0; - if (fputs(line, f) < 0) - return errno ? -errno : -EIO; - - if (!endswith(line, "\n")) - fputc('\n', f); - - fflush(f); - - if (ferror(f)) - return errno ? -errno : -EIO; - - return 0; -} - -int read_one_line_file(const char *fn, char **line) { - _cleanup_fclose_ FILE *f = NULL; - char t[LINE_MAX], *c; - - assert(fn); - assert(line); - - f = fopen(fn, "re"); - if (!f) - return -errno; - - if (!fgets(t, sizeof(t), f)) { - - if (ferror(f)) - return errno ? -errno : -EIO; - - t[0] = 0; - } - - c = strdup(t); - if (!c) - return -ENOMEM; - truncate_nl(c); - - *line = c; - return 0; -} - char *truncate_nl(char *s) { assert(s); @@ -794,6 +725,19 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) { return endswith(de->d_name, suffix); } +bool nulstr_contains(const char*nulstr, const char *needle) { + const char *i; + + if (!nulstr) + return false; + + NULSTR_FOREACH(i, nulstr) + if (streq(i, needle)) + return true; + + return false; +} + int execute_command(const char *command, char *const argv[]) { @@ -1161,3 +1105,56 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, } return NULL; } + +int proc_cmdline(char **ret) { + int r; + + /* disable containers for now + if (detect_container(NULL) > 0) { + char *buf, *p; + size_t sz = 0; + + r = read_full_file("/proc/1/cmdline", &buf, &sz); + if (r < 0) + return r; + + for (p = buf; p + 1 < buf + sz; p++) + if (*p == 0) + *p = ' '; + + *p = 0; + *ret = buf; + return 1; + } + */ + + r = read_one_line_file("/proc/cmdline", ret); + if (r < 0) + return r; + + return 1; +} + +int getpeercred(int fd, struct ucred *ucred) { + socklen_t n = sizeof(struct ucred); + struct ucred u; + int r; + + assert(fd >= 0); + assert(ucred); + + r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n); + if (r < 0) + return -errno; + + if (n != sizeof(struct ucred)) + return -EIO; + + /* Check if the data is actually useful and not suppressed due + * to namespacing issues */ + if (u.pid <= 0) + return -ENODATA; + + *ucred = u; + return 0; +} diff --git a/src/libudev/util.h b/src/libudev/util.h index 22f48b44ad..50e6a44af5 100644 --- a/src/libudev/util.h +++ b/src/libudev/util.h @@ -21,6 +21,7 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <string.h> #include <time.h> #include <stdlib.h> #include <stdio.h> @@ -30,6 +31,7 @@ #include <dirent.h> #include <stddef.h> #include <unistd.h> +#include <sys/socket.h> #include "macro.h" @@ -69,9 +71,12 @@ union dirent_storage { /* What is interpreted as whitespace? */ #define WHITESPACE " \t\n\r" -#define NEWLINE "\n\r" -#define QUOTES "\"\'" -#define COMMENTS "#;" +#define NEWLINE "\n\r" +#define QUOTES "\"\'" +#define COMMENTS "#;" +#define GLOB_CHARS "*?[" + +#define FORMAT_BYTES_MAX 8 #define ANSI_HIGHLIGHT_ON "\x1B[1;39m" #define ANSI_RED_ON "\x1B[31m" @@ -79,6 +84,7 @@ union dirent_storage { #define ANSI_GREEN_ON "\x1B[32m" #define ANSI_HIGHLIGHT_GREEN_ON "\x1B[1;32m" #define ANSI_HIGHLIGHT_YELLOW_ON "\x1B[1;33m" +#define ANSI_HIGHLIGHT_BLUE_ON "\x1B[1;34m" #define ANSI_HIGHLIGHT_OFF "\x1B[0m" #define ANSI_ERASE_TO_END_OF_LINE "\x1B[K" @@ -105,8 +111,13 @@ static inline bool isempty(const char *p) { return !p || !p[0]; } +static inline const char *startswith(const char *s, const char *prefix) { + if (strncmp(s, prefix, strlen(prefix)) == 0) + return s + strlen(prefix); + return NULL; +} + char *endswith(const char *s, const char *postfix) _pure_; -char *startswith(const char *s, const char *prefix) _pure_; int close_nointr(int fd); void close_nointr_nofail(int fd); @@ -123,9 +134,6 @@ char *split_quoted(const char *c, size_t *l, char **state); #define FOREACH_WORD_QUOTED(word, length, s, state) \ for ((state) = NULL, (word) = split_quoted((s), &(length), &(state)); (word); (word) = split_quoted((s), &(length), &(state))) -int write_one_line_file(const char *fn, const char *line); -int read_one_line_file(const char *fn, char **line); - char *strappend(const char *s, const char *suffix); char *strnappend(const char *s, const char *suffix, size_t length); @@ -206,10 +214,15 @@ int null_or_empty_path(const char *fn); int execute_command(const char *command, char *const argv[]); +bool nulstr_contains(const char*nulstr, const char *needle); + char *strjoin(const char *x, ...) _sentinel_; bool is_main_thread(void); +#define NULSTR_FOREACH(i, l) \ + for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) + #define NULSTR_FOREACH_PAIR(i, j, l) \ for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i)) @@ -247,6 +260,13 @@ static inline void freep(void *p) { free(*(void**) p); } +#define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \ + static inline void func##p(type *p) { \ + if (*p) \ + func(*p); \ + } \ + struct __useless_struct_to_allow_trailing_semicolon__ + static inline void fclosep(FILE **f) { if (*f) fclose(*f); @@ -274,6 +294,13 @@ _malloc_ _alloc_(1, 2) static inline void *malloc_multiply(size_t a, size_t b) return malloc(a * b); } +/** + * Check if a string contains any glob patterns. + */ +_pure_ static inline bool string_is_glob(const char *p) { + return !!strpbrk(p, GLOB_CHARS); +} + void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size, int (*compar) (const void *, const void *, void *), void *arg); @@ -300,3 +327,6 @@ static inline void qsort_safe(void *base, size_t nmemb, size_t size, qsort(base, nmemb, size, compar); } } + +int proc_cmdline(char **ret); +int getpeercred(int fd, struct ucred *ucred); diff --git a/src/udev/Makefile.am b/src/udev/Makefile.am index d395620abb..8722524e67 100644 --- a/src/udev/Makefile.am +++ b/src/udev/Makefile.am @@ -69,7 +69,8 @@ noinst_HEADERS = \ dev-setup.h \ label.h \ mkdir.h \ - smack-util.h + smack-util.h \ + udev-util.h include_HEADERS = \ udev.h diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c index b48dccc2fb..c806bd6ad8 100644 --- a/src/udev/udev-builtin-blkid.c +++ b/src/udev/udev-builtin-blkid.c @@ -190,7 +190,7 @@ static int builtin_blkid(struct udev_device *dev, int argc, char *argv[], bool t if (err < 0) goto out; - log_debug("probe %s %sraid offset=%llu\n", + log_debug("probe %s %sraid offset=%llu", udev_device_get_devnode(dev), noraid ? "no" : "", (unsigned long long) offset); diff --git a/src/udev/udev-builtin-firmware.c b/src/udev/udev-builtin-firmware.c index b80940b6ef..8cfeed663b 100644 --- a/src/udev/udev-builtin-firmware.c +++ b/src/udev/udev-builtin-firmware.c @@ -33,7 +33,7 @@ static bool set_loading(struct udev *udev, char *loadpath, const char *state) ldfile = fopen(loadpath, "we"); if (ldfile == NULL) { - log_error("error: can not open '%s'\n", loadpath); + log_error("error: can not open '%s'", loadpath); return false; }; fprintf(ldfile, "%s\n", state); @@ -53,7 +53,7 @@ static bool copy_firmware(struct udev *udev, const char *source, const char *tar return false; } - log_debug("writing '%s' (%zi) to '%s'\n", source, size, target); + log_debug("writing '%s' (%zi) to '%s'", source, size, target); fsource = fopen(source, "re"); if (fsource == NULL) @@ -90,7 +90,7 @@ static int builtin_firmware(struct udev_device *dev, int argc, char *argv[], boo firmware = udev_device_get_property_value(dev, "FIRMWARE"); if (firmware == NULL) { - log_error("firmware parameter missing\n\n"); + log_error("firmware parameter missing"); rc = EXIT_FAILURE; goto exit; } @@ -112,7 +112,7 @@ static int builtin_firmware(struct udev_device *dev, int argc, char *argv[], boo strscpyl(loadpath, sizeof(loadpath), udev_device_get_syspath(dev), "/loading", NULL); if (fwfile == NULL) { - log_debug("did not find firmware file '%s'\n", firmware); + log_debug("did not find firmware file '%s'", firmware); rc = EXIT_FAILURE; /* * Do not cancel the request in the initrd, the real root might have @@ -136,7 +136,7 @@ static int builtin_firmware(struct udev_device *dev, int argc, char *argv[], boo strscpyl(datapath, sizeof(datapath), udev_device_get_syspath(dev), "/data", NULL); if (!copy_firmware(udev, fwpath, datapath, statbuf.st_size)) { - log_error("error sending firmware '%s' to device\n", firmware); + log_error("error sending firmware '%s' to device", firmware); set_loading(udev, loadpath, "-1"); rc = EXIT_FAILURE; goto exit; diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c index 445b602f9c..4691fc073d 100644 --- a/src/udev/udev-builtin-input_id.c +++ b/src/udev/udev-builtin-input_id.c @@ -57,7 +57,7 @@ static void get_cap_mask(struct udev_device *dev, unsigned long val; snprintf(text, sizeof(text), "%s", udev_device_get_sysattr_value(pdev, attr)); - log_debug("%s raw kernel attribute: %s\n", attr, text); + log_debug("%s raw kernel attribute: %s", attr, text); memset (bitmask, 0, bitmask_size); i = 0; @@ -66,7 +66,7 @@ static void get_cap_mask(struct udev_device *dev, if (i < bitmask_size/sizeof(unsigned long)) bitmask[i] = val; else - log_debug("ignoring %s block %lX which is larger than maximum size\n", attr, val); + log_debug("ignoring %s block %lX which is larger than maximum size", attr, val); *word = '\0'; ++i; } @@ -74,12 +74,12 @@ static void get_cap_mask(struct udev_device *dev, if (i < bitmask_size / sizeof(unsigned long)) bitmask[i] = val; else - log_debug("ignoring %s block %lX which is larger than maximum size\n", attr, val); + log_debug("ignoring %s block %lX which is larger than maximum size", attr, val); if (test) { /* printf pattern with the right unsigned long number of hex chars */ snprintf(text, sizeof(text), " bit %%4u: %%0%zilX\n", 2 * sizeof(unsigned long)); - log_debug("%s decoded bit map:\n", attr); + log_debug("%s decoded bit map:", attr); val = bitmask_size / sizeof (unsigned long); /* skip over leading zeros */ while (bitmask[val-1] == 0 && val > 0) @@ -151,7 +151,7 @@ static void test_key (struct udev_device *dev, /* do we have any KEY_* capability? */ if (!test_bit (EV_KEY, bitmask_ev)) { - log_debug("test_key: no EV_KEY capability\n"); + log_debug("test_key: no EV_KEY capability"); return; } @@ -159,13 +159,13 @@ static void test_key (struct udev_device *dev, found = 0; for (i = 0; i < BTN_MISC/BITS_PER_LONG; ++i) { found |= bitmask_key[i]; - log_debug("test_key: checking bit block %lu for any keys; found=%i\n", (unsigned long)i*BITS_PER_LONG, found > 0); + log_debug("test_key: checking bit block %lu for any keys; found=%i", (unsigned long)i*BITS_PER_LONG, found > 0); } /* If there are no keys in the lower block, check the higher block */ if (!found) { for (i = KEY_OK; i < BTN_TRIGGER_HAPPY; ++i) { if (test_bit (i, bitmask_key)) { - log_debug("test_key: Found key %x in high block\n", i); + log_debug("test_key: Found key %x in high block", i); found = 1; break; } diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c index ddd853594e..614e44ec76 100644 --- a/src/udev/udev-builtin-keyboard.c +++ b/src/udev/udev-builtin-keyboard.c @@ -59,7 +59,7 @@ static int install_force_release(struct udev_device *dev, const unsigned int *re for (i = 0; i < release_count; i++) l = strpcpyf(&s, l, ",%d", release[i]); - log_debug("keyboard: updating force-release list with '%s'\n", codes); + 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)); @@ -88,9 +88,9 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo continue; /* KEYBOARD_KEY_<hex scan code>=<key identifier string> */ - scancode = strtol(key + 13, &endptr, 16); + scancode = strtoul(key + 13, &endptr, 16); if (endptr[0] != '\0') { - log_error("Error, unable to parse scan code from '%s'\n", key); + log_error("Error, unable to parse scan code from '%s'", key); continue; } @@ -111,7 +111,7 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo /* translate identifier to key code */ k = keyboard_lookup_key(keycode, strlen(keycode)); if (!k) { - log_error("Error, unknown key identifier '%s'\n", keycode); + log_error("Error, unknown key identifier '%s'", keycode); continue; } @@ -128,22 +128,22 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo node = udev_device_get_devnode(dev); if (!node) { - log_error("Error, no device node for '%s'\n", udev_device_get_syspath(dev)); + log_error("Error, no device node for '%s'", udev_device_get_syspath(dev)); return EXIT_FAILURE; } 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\n", node); + log_error("Error, opening device '%s': %m", node); return EXIT_FAILURE; } /* install list of map codes */ for (i = 0; i < map_count; i++) { - log_debug("keyboard: mapping scan code %d (0x%x) to key code %d (0x%x)\n", + 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: %m\n"); + log_error("Error calling EVIOCSKEYCODE (scan code 0x%x, key code %d): %m", map[i].scan, map[i].key); } /* install list of force-release codes */ diff --git a/src/udev/udev-builtin-kmod.c b/src/udev/udev-builtin-kmod.c index efd3e3e3cb..a9704c101c 100644 --- a/src/udev/udev-builtin-kmod.c +++ b/src/udev/udev-builtin-kmod.c @@ -33,7 +33,6 @@ #endif #include "udev.h" -#include "util.h" static struct kmod_ctx *ctx; @@ -49,18 +48,18 @@ static int load_module(struct udev *udev, const char *alias) return err; if (list == NULL) - log_debug("no module matches '%s'\n", 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\n", kmod_module_get_name(mod)); + log_debug("module '%s' is blacklisted", kmod_module_get_name(mod)); else if (err == 0) - log_debug("inserted '%s'\n", kmod_module_get_name(mod)); + log_debug("inserted '%s'", kmod_module_get_name(mod)); else - log_debug("failed to insert '%s'\n", kmod_module_get_name(mod)); + log_debug("failed to insert '%s'", kmod_module_get_name(mod)); kmod_module_unref(mod); } @@ -91,12 +90,12 @@ static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool te #endif if (argc < 3 || !streq(argv[1], "load")) { - log_error("expect: %s load <module>\n", argv[0]); + log_error("expect: %s load <module>", argv[0]); return EXIT_FAILURE; } for (i = 2; argv[i]; i++) { - log_debug("execute '%s' '%s'\n", argv[1], argv[i]); + log_debug("execute '%s' '%s'", argv[1], argv[i]); load_module(udev, argv[i]); } @@ -114,7 +113,7 @@ static int builtin_kmod_init(struct udev *udev) if (!ctx) return -ENOMEM; - log_debug("load module index\n"); + log_debug("load module index"); kmod_set_log_fn(ctx, udev_kmod_log, udev); kmod_load_resources(ctx); #endif @@ -125,7 +124,7 @@ static int builtin_kmod_init(struct udev *udev) static void builtin_kmod_exit(struct udev *udev) { #ifdef HAVE_LIBKMOD - log_debug("unload module index\n"); + log_debug("unload module index"); ctx = kmod_unref(ctx); #endif } @@ -134,7 +133,7 @@ static void builtin_kmod_exit(struct udev *udev) /* 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\n"); + log_debug("validate module index"); if (!ctx) return false; return (kmod_validate_resources(ctx) != KMOD_RESOURCES_OK); diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 0c68546907..f87d629c4b 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -28,6 +28,7 @@ * * Two character prefixes based on the type of interface: * en -- ethernet + * sl -- serial line IP (slip) * wl -- wlan * ww -- wwan * @@ -100,6 +101,8 @@ enum netname_type{ NET_PCI, NET_USB, NET_BCMA, + NET_VIRTIO, + NET_CCWGROUP, }; struct netnames { @@ -117,6 +120,10 @@ struct netnames { char usb_ports[IFNAMSIZ]; char bcma_core[IFNAMSIZ]; + + char virtio_core[IFNAMSIZ]; + + char ccw_core[IFNAMSIZ]; }; /* retrieve on-board index number and label from firmware */ @@ -158,30 +165,24 @@ static bool is_pci_multifunction(struct udev_device *dev) { if ((config[PCI_HEADER_TYPE] & 0x80) != 0) multi = true; out: - if(f) + if (f) fclose(f); return multi; } static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { struct udev *udev = udev_device_get_udev(names->pcidev); - unsigned int domain; - unsigned int bus; - unsigned int slot; - unsigned int func; - unsigned int dev_id = 0; + unsigned domain, bus, slot, func, dev_id = 0; size_t l; char *s; const char *attr; struct udev_device *pci = NULL; - char slots[256]; - DIR *dir; + char slots[256], str[256]; + _cleanup_closedir_ DIR *dir = NULL; struct dirent *dent; - char str[256]; - int hotplug_slot = 0; - int err = 0; + int hotplug_slot = 0, err = 0; - if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%d", &domain, &bus, &slot, &func) != 4) + if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%u", &domain, &bus, &slot, &func) != 4) return -ENOENT; /* kernel provided multi-device index */ @@ -238,7 +239,6 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { if (hotplug_slot > 0) break; } - closedir(dir); if (hotplug_slot > 0) { s = names->pci_slot; @@ -340,16 +340,73 @@ static int names_bcma(struct udev_device *dev, struct netnames *names) { return -ENOENT; /* bus num:core num */ - if (sscanf(udev_device_get_sysname(bcmadev), "bcma%*d:%d", &core) != 1) + if (sscanf(udev_device_get_sysname(bcmadev), "bcma%*u:%u", &core) != 1) return -EINVAL; /* suppress the common core == 0 */ if (core > 0) - snprintf(names->bcma_core, sizeof(names->bcma_core), "b%d", core); + snprintf(names->bcma_core, sizeof(names->bcma_core), "b%u", core); names->type = NET_BCMA; return 0; } +static int names_virtio(struct udev_device *dev, struct netnames *names) { + struct udev_device *virtdev; + unsigned int core; + + virtdev = udev_device_get_parent_with_subsystem_devtype(dev, "virtio", NULL); + if (!virtdev) + return -ENOENT; + + /* core num */ + if (sscanf(udev_device_get_sysname(virtdev), "virtio%u", &core) != 1) + return -EINVAL; + /* suppress the common core == 0 */ + if (core > 0) + snprintf(names->virtio_core, sizeof(names->virtio_core), "v%u", core); + + names->type = NET_VIRTIO; + return 0; +} + +static int names_ccw(struct udev_device *dev, struct netnames *names) { + struct udev_device *cdev; + const char *bus_id; + size_t bus_id_len; + int rc; + + /* Retrieve the associated CCW device */ + cdev = udev_device_get_parent(dev); + if (!cdev) + return -ENOENT; + + /* Network devices are always grouped CCW devices */ + if (!streq_ptr("ccwgroup", udev_device_get_subsystem(cdev))) + return -ENOENT; + + /* Retrieve bus-ID of the grouped CCW device. The bus-ID uniquely + * identifies the network device on the Linux on System z channel + * subsystem. Note that the bus-ID contains lowercase characters. + */ + bus_id = udev_device_get_sysname(cdev); + if (!bus_id) + return -ENOENT; + + /* Check the length of the bus-ID. Rely on that the kernel provides + * a correct bus-ID; alternatively, improve this check and parse and + * verify each bus-ID part... + */ + bus_id_len = strlen(bus_id); + if (!bus_id_len || bus_id_len < 8 || bus_id_len > 9) + return -EINVAL; + + /* Store the CCW bus-ID for use as network device name */ + rc = snprintf(names->ccw_core, sizeof(names->ccw_core), "ccw%s", bus_id); + if (rc >= 0 && rc < (int)sizeof(names->ccw_core)) + names->type = NET_CCWGROUP; + return 0; +} + static int names_mac(struct udev_device *dev, struct netnames *names) { const char *s; unsigned int i; @@ -408,13 +465,21 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool struct netnames names = {}; int err; - /* handle only ARPHRD_ETHER devices */ + /* handle only ARPHRD_ETHER and ARPHRD_SLIP devices */ s = udev_device_get_sysattr_value(dev, "type"); if (!s) return EXIT_FAILURE; i = strtoul(s, NULL, 0); - if (i != 1) + switch (i) { + case 1: /* ARPHRD_ETHER */ + prefix = "en"; + break; + case 256: /* ARPHRD_SLIP */ + prefix = "sl"; + break; + default: return 0; + } /* skip stacked devices, like VLANs, ... */ s = udev_device_get_sysattr_value(dev, "ifindex"); @@ -446,6 +511,16 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool ieee_oui(dev, &names, test); } + /* get path names for Linux on System z network devices */ + err = names_ccw(dev, &names); + if (err >= 0 && names.type == NET_CCWGROUP) { + char str[IFNAMSIZ]; + + if (snprintf(str, sizeof(str), "%s%s", prefix, names.ccw_core) < (int)sizeof(str)) + udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); + goto out; + } + /* get PCI based path names, we compose only PCI based paths */ err = names_pci(dev, &names); if (err < 0) @@ -503,6 +578,21 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool goto out; } + /* virtio bus */ + err = names_virtio(dev, &names); + if (err >= 0 && names.type == NET_VIRTIO) { + char str[IFNAMSIZ]; + + if (names.pci_path[0]) + if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.virtio_core) < (int)sizeof(str)) + udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); + + if (names.pci_slot[0]) + if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.virtio_core) < (int)sizeof(str)) + udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str); + goto out; + } + out: return EXIT_SUCCESS; } diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c index 7476330196..0599980a68 100644 --- a/src/udev/udev-builtin-path_id.c +++ b/src/udev/udev-builtin-path_id.c @@ -71,9 +71,9 @@ static int format_lun_number(struct udev_device *dev, char **path) /* address method 0, peripheral device addressing with bus id of zero */ if (lun < 256) - return path_prepend(path, "lun-%d", lun); + return path_prepend(path, "lun-%lu", lun); /* handle all other lun addressing methods by using a variant of the original lun format */ - return path_prepend(path, "lun-0x%04x%04x00000000", (lun & 0xffff), (lun >> 16) & 0xffff); + return path_prepend(path, "lun-0x%04lx%04lx00000000", lun & 0xffff, (lun >> 16) & 0xffff); } static struct udev_device *skip_subsystem(struct udev_device *dev, const char *subsys) diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c index 3e2f43e1a6..1b9f8246fb 100644 --- a/src/udev/udev-builtin-usb_id.c +++ b/src/udev/udev-builtin-usb_id.c @@ -275,7 +275,7 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool /* usb interface directory */ dev_interface = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface"); if (dev_interface == NULL) { - log_debug("unable to access usb_interface device of '%s'\n", + log_debug("unable to access usb_interface device of '%s'", udev_device_get_syspath(dev)); return EXIT_FAILURE; } @@ -285,7 +285,7 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool if_class = udev_device_get_sysattr_value(dev_interface, "bInterfaceClass"); if (!if_class) { - log_debug("%s: cannot get bInterfaceClass attribute\n", + log_debug("%s: cannot get bInterfaceClass attribute", udev_device_get_sysname(dev)); return EXIT_FAILURE; } @@ -300,13 +300,13 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool set_usb_iftype(type_str, if_class_num, sizeof(type_str)-1); } - log_debug("%s: if_class %d protocol %d\n", + log_debug("%s: if_class %d protocol %d", udev_device_get_syspath(dev_interface), if_class_num, protocol); /* usb device directory */ dev_usb = udev_device_get_parent_with_subsystem_devtype(dev_interface, "usb", "usb_device"); if (!dev_usb) { - log_debug("unable to find parent 'usb' device of '%s'\n", + log_debug("unable to find parent 'usb' device of '%s'", udev_device_get_syspath(dev)); return EXIT_FAILURE; } @@ -323,19 +323,19 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool /* get scsi device */ dev_scsi = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device"); if (dev_scsi == NULL) { - log_debug("unable to find parent 'scsi' device of '%s'\n", + log_debug("unable to find parent 'scsi' device of '%s'", udev_device_get_syspath(dev)); goto fallback; } if (sscanf(udev_device_get_sysname(dev_scsi), "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4) { - log_debug("invalid scsi device '%s'\n", udev_device_get_sysname(dev_scsi)); + log_debug("invalid scsi device '%s'", udev_device_get_sysname(dev_scsi)); goto fallback; } /* Generic SPC-2 device */ scsi_vendor = udev_device_get_sysattr_value(dev_scsi, "vendor"); if (!scsi_vendor) { - log_debug("%s: cannot get SCSI vendor attribute\n", + log_debug("%s: cannot get SCSI vendor attribute", udev_device_get_sysname(dev_scsi)); goto fallback; } @@ -345,7 +345,7 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool scsi_model = udev_device_get_sysattr_value(dev_scsi, "model"); if (!scsi_model) { - log_debug("%s: cannot get SCSI model attribute\n", + log_debug("%s: cannot get SCSI model attribute", udev_device_get_sysname(dev_scsi)); goto fallback; } @@ -355,7 +355,7 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool scsi_type = udev_device_get_sysattr_value(dev_scsi, "type"); if (!scsi_type) { - log_debug("%s: cannot get SCSI type attribute\n", + log_debug("%s: cannot get SCSI type attribute", udev_device_get_sysname(dev_scsi)); goto fallback; } @@ -363,7 +363,7 @@ static int builtin_usb_id(struct udev_device *dev, int argc, char *argv[], bool scsi_rev = udev_device_get_sysattr_value(dev_scsi, "rev"); if (!scsi_rev) { - log_debug("%s: cannot get SCSI revision attribute\n", + log_debug("%s: cannot get SCSI revision attribute", udev_device_get_sysname(dev_scsi)); goto fallback; } @@ -389,7 +389,7 @@ fallback: if (!usb_vendor) usb_vendor = vendor_id; if (!usb_vendor) { - log_debug("No USB vendor information available\n"); + log_debug("No USB vendor information available"); return EXIT_FAILURE; } udev_util_encode_string(usb_vendor, vendor_str_enc, sizeof(vendor_str_enc)); diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c index 095fe9f52c..6d4dc6543b 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\n"); + log_error("error getting socket: %m"); udev_ctrl_unref(uctrl); return NULL; } @@ -119,14 +119,14 @@ int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl) if (err < 0) { err = -errno; - log_error("bind failed: %m\n"); + log_error("bind failed: %m"); return err; } err = listen(uctrl->sock, 0); if (err < 0) { err = -errno; - log_error("listen failed: %m\n"); + log_error("listen failed: %m"); return err; } @@ -194,10 +194,10 @@ struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl) { struct udev_ctrl_connection *conn; struct ucred ucred; - socklen_t slen; const int on = 1; + int r; - conn = calloc(1, sizeof(struct udev_ctrl_connection)); + conn = new(struct udev_ctrl_connection, 1); if (conn == NULL) return NULL; conn->refcount = 1; @@ -215,18 +215,18 @@ 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\n"); + log_error("unable to receive ctrl connection: %m"); goto err; } /* check peer credential of connection */ - slen = sizeof(ucred); - if (getsockopt(conn->sock, SOL_SOCKET, SO_PEERCRED, &ucred, &slen) < 0) { - log_error("unable to receive credentials of ctrl connection: %m\n"); + r = getpeercred(conn->sock, &ucred); + if (r < 0) { + log_error("unable to receive credentials of ctrl connection: %s", strerror(-r)); goto err; } if (ucred.uid > 0) { - log_error("sender uid=%i, message ignored\n", ucred.uid); + log_error("sender uid=%i, message ignored", ucred.uid); goto err; } @@ -381,7 +381,7 @@ struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn) udev_ctrl_connection_ref(conn); /* wait for the incoming message */ - for(;;) { + for (;;) { struct pollfd pfd[1]; int r; @@ -394,11 +394,11 @@ struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn) continue; goto err; } else if (r == 0) { - log_error("timeout waiting for ctrl message\n"); + log_error("timeout waiting for ctrl message"); goto err; } else { if (!(pfd[0].revents & POLLIN)) { - log_error("ctrl connection error: %m\n"); + log_error("ctrl connection error: %m"); goto err; } } @@ -411,24 +411,24 @@ 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\n"); + log_error("unable to receive ctrl message: %m"); goto err; } cmsg = CMSG_FIRSTHDR(&smsg); cred = (struct ucred *) CMSG_DATA(cmsg); if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { - log_error("no sender credentials received, message ignored\n"); + log_error("no sender credentials received, message ignored"); goto err; } if (cred->uid != 0) { - log_error("sender uid=%i, message ignored\n", cred->uid); + log_error("sender uid=%i, message ignored", cred->uid); goto err; } if (uctrl_msg->ctrl_msg_wire.magic != UDEV_CTRL_MAGIC) { - log_error("message magic 0x%08x doesn't match, ignore it\n", uctrl_msg->ctrl_msg_wire.magic); + log_error("message magic 0x%08x doesn't match, ignore it", uctrl_msg->ctrl_msg_wire.magic); goto err; } diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 7867263b81..d4a54faf13 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -177,7 +177,7 @@ subst: from++; for (i = 0; from[i] != '}'; i++) { if (from[i] == '\0') { - log_error("missing closing brace for format '%s'\n", src); + log_error("missing closing brace for format '%s'", src); goto out; } } @@ -258,7 +258,7 @@ subst: cpos++; } if (i > 0) { - log_error("requested part of result string not found\n"); + log_error("requested part of result string not found"); break; } strscpy(tmp, sizeof(tmp), cpos); @@ -281,7 +281,7 @@ subst: int count; if (attr == NULL) { - log_error("missing file parameter for attr\n"); + log_error("missing file parameter for attr"); break; } @@ -308,7 +308,7 @@ subst: vbuf[len] = '\0'; count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT); if (count > 0) - log_debug("%i character(s) replaced\n" , count); + log_debug("%i character(s) replaced" , count); l = strpcpy(&s, l, vbuf); break; } @@ -366,7 +366,7 @@ subst: break; } default: - log_error("unknown substitution type=%i\n", type); + log_error("unknown substitution type=%i", type); break; } } @@ -393,7 +393,7 @@ static int spawn_exec(struct udev_event *event, dup2(fd, STDERR_FILENO); close(fd); } else { - log_error("open /dev/null failed: %m\n"); + log_error("open /dev/null failed: %m"); } /* connect pipes to std{out,err} */ @@ -417,7 +417,7 @@ static int spawn_exec(struct udev_event *event, /* exec failed */ err = -errno; - log_error("failed to execute '%s' '%s': %m\n", argv[0], cmd); + log_error("failed to execute '%s' '%s': %m", argv[0], cmd); return err; } @@ -436,7 +436,7 @@ 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\n"); + log_error("error creating epoll fd: %m"); goto out; } @@ -445,7 +445,7 @@ static void spawn_read(struct udev_event *event, ep_outpipe.events = EPOLLIN; ep_outpipe.data.ptr = &fd_stdout; if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_stdout, &ep_outpipe) < 0) { - log_error("fail to add fd to epoll: %m\n"); + log_error("fail to add fd to epoll: %m"); goto out; } } @@ -455,7 +455,7 @@ static void spawn_read(struct udev_event *event, ep_errpipe.events = EPOLLIN; ep_errpipe.data.ptr = &fd_stderr; if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_stderr, &ep_errpipe) < 0) { - log_error("fail to add fd to epoll: %m\n"); + log_error("fail to add fd to epoll: %m"); goto out; } } @@ -472,7 +472,7 @@ static void spawn_read(struct udev_event *event, age_usec = now(CLOCK_MONOTONIC) - event->birth_usec; if (age_usec >= event->timeout_usec) { - log_error("timeout '%s'\n", cmd); + log_error("timeout '%s'", cmd); goto out; } timeout = ((event->timeout_usec - age_usec) / 1000) + 1000; @@ -484,11 +484,11 @@ static void spawn_read(struct udev_event *event, if (fdcount < 0) { if (errno == EINTR) continue; - log_error("failed to poll: %m\n"); + log_error("failed to poll: %m"); goto out; } if (fdcount == 0) { - log_error("timeout '%s'\n", cmd); + log_error("timeout '%s'", cmd); goto out; } @@ -510,7 +510,7 @@ static void spawn_read(struct udev_event *event, memcpy(&result[respos], buf, count); respos += count; } else { - log_error("'%s' ressize %zd too short\n", cmd, ressize); + log_error("'%s' ressize %zd too short", cmd, ressize); } } @@ -522,12 +522,12 @@ static void spawn_read(struct udev_event *event, pos = buf; while ((line = strsep(&pos, "\n"))) { if (pos != NULL || line[0] != '\0') - log_debug("'%s'(%s) '%s'\n", cmd, *fd == fd_stdout ? "out" : "err" , line); + log_debug("'%s'(%s) '%s'", cmd, *fd == fd_stdout ? "out" : "err" , line); } } } else if (ev[i].events & EPOLLHUP) { if (epoll_ctl(fd_ep, EPOLL_CTL_DEL, *fd, NULL) < 0) { - log_error("failed to remove fd from epoll: %m\n"); + log_error("failed to remove fd from epoll: %m"); goto out; } *fd = -1; @@ -572,11 +572,11 @@ static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid) if (errno == EINTR) continue; err = -errno; - log_error("failed to poll: %m\n"); + log_error("failed to poll: %m"); goto out; } if (fdcount == 0) { - log_error("timeout: killing '%s' [%u]\n", cmd, pid); + log_error("timeout: killing '%s' [%u]", cmd, pid); kill(pid, SIGKILL); } @@ -597,20 +597,20 @@ static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid) if (waitpid(pid, &status, WNOHANG) < 0) break; if (WIFEXITED(status)) { - log_debug("'%s' [%u] exit with return code %i\n", cmd, pid, WEXITSTATUS(status)); + log_debug("'%s' [%u] exit with return code %i", cmd, pid, WEXITSTATUS(status)); if (WEXITSTATUS(status) != 0) err = -1; } else if (WIFSIGNALED(status)) { - log_error("'%s' [%u] terminated by signal %i (%s)\n", cmd, pid, WTERMSIG(status), strsignal(WTERMSIG(status))); + log_error("'%s' [%u] terminated by signal %i (%s)", cmd, pid, WTERMSIG(status), strsignal(WTERMSIG(status))); err = -1; } else if (WIFSTOPPED(status)) { - log_error("'%s' [%u] stopped\n", cmd, pid); + log_error("'%s' [%u] stopped", cmd, pid); err = -1; } else if (WIFCONTINUED(status)) { - log_error("'%s' [%u] continued\n", cmd, pid); + log_error("'%s' [%u] continued", cmd, pid); err = -1; } else { - log_error("'%s' [%u] exit with status 0x%04x\n", cmd, pid, status); + log_error("'%s' [%u] exit with status 0x%04x", cmd, pid, status); err = -1; } pid = 0; @@ -676,14 +676,14 @@ int udev_event_spawn(struct udev_event *event, if (result != NULL || udev_get_log_priority(udev) >= LOG_INFO) { if (pipe2(outpipe, O_NONBLOCK) != 0) { err = -errno; - log_error("pipe failed: %m\n"); + log_error("pipe failed: %m"); goto out; } } if (udev_get_log_priority(udev) >= LOG_INFO) { if (pipe2(errpipe, O_NONBLOCK) != 0) { err = -errno; - log_error("pipe failed: %m\n"); + log_error("pipe failed: %m"); goto out; } } @@ -713,14 +713,14 @@ int udev_event_spawn(struct udev_event *event, errpipe[READ_END] = -1; } - log_debug("starting '%s'\n", cmd); + log_debug("starting '%s'", cmd); spawn_exec(event, cmd, argv, envp, sigmask, outpipe[WRITE_END], errpipe[WRITE_END]); _exit(2 ); case -1: - log_error("fork of '%s' failed: %m\n", cmd); + log_error("fork of '%s' failed: %m", cmd); err = -1; goto out; default: @@ -944,7 +944,7 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, err = rename_netif(event); #endif if (err == 0) { - log_debug("renamed netif to '%s'\n", finalifname); + log_debug("renamed netif to '%s'", finalifname); /* remember old name */ udev_device_add_property(dev, "INTERFACE_OLD", udev_device_get_sysname(dev)); @@ -957,7 +957,7 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, strscpy(pos, sizeof(syspath) - (pos - syspath), finalifname); udev_device_set_syspath(event->dev, syspath); udev_device_add_property(dev, "INTERFACE", udev_device_get_sysname(dev)); - log_debug("changed devpath to '%s'\n", udev_device_get_devpath(dev)); + log_debug("changed devpath to '%s'", udev_device_get_devpath(dev)); } } } @@ -1027,7 +1027,7 @@ void udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask) char **envp; if (event->exec_delay > 0) { - log_debug("delay execution of '%s'\n", program); + log_debug("delay execution of '%s'", program); sleep(event->exec_delay); } diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index 026cb8359a..200e24fb41 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -66,7 +66,7 @@ static int node_symlink(struct udev_device *dev, const char *node, const char *s /* preserve link with correct target, do not replace node of other device */ if (lstat(slink, &stats) == 0) { if (S_ISBLK(stats.st_mode) || S_ISCHR(stats.st_mode)) { - log_error("conflicting device node '%s' found, link to '%s' will not be created\n", slink, node); + log_error("conflicting device node '%s' found, link to '%s' will not be created", slink, node); goto exit; } else if (S_ISLNK(stats.st_mode)) { char buf[UTIL_PATH_SIZE]; @@ -76,7 +76,7 @@ static int node_symlink(struct udev_device *dev, const char *node, const char *s if (len > 0 && len < (int)sizeof(buf)) { buf[len] = '\0'; if (streq(target, buf)) { - log_debug("preserve already existing symlink '%s' to '%s'\n", slink, target); + log_debug("preserve already existing symlink '%s' to '%s'", slink, target); label_fix(slink, true, false); utimensat(AT_FDCWD, slink, NULL, AT_SYMLINK_NOFOLLOW); goto exit; @@ -84,7 +84,7 @@ static int node_symlink(struct udev_device *dev, const char *node, const char *s } } } else { - log_debug("creating symlink '%s' to '%s'\n", slink, target); + log_debug("creating symlink '%s' to '%s'", slink, target); do { err = mkdir_parents_label(slink, 0755); if (err != 0 && err != -ENOENT) @@ -99,7 +99,7 @@ static int node_symlink(struct udev_device *dev, const char *node, const char *s goto exit; } - log_debug("atomically replace '%s'\n", slink); + log_debug("atomically replace '%s'", slink); strscpyl(slink_tmp, sizeof(slink_tmp), slink, ".tmp-", udev_device_get_id_filename(dev), NULL); unlink(slink_tmp); do { @@ -113,12 +113,12 @@ static int node_symlink(struct udev_device *dev, const char *node, const char *s label_context_clear(); } while (err == -ENOENT); if (err != 0) { - log_error("symlink '%s' '%s' failed: %m\n", target, slink_tmp); + log_error("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\n", slink_tmp, slink); + log_error("rename '%s' '%s' failed: %m", slink_tmp, slink); unlink(slink_tmp); } exit: @@ -152,7 +152,7 @@ static const char *link_find_prioritized(struct udev_device *dev, bool add, cons if (dent->d_name[0] == '.') continue; - log_debug("found '%s' claiming '%s'\n", dent->d_name, stackdir); + log_debug("found '%s' claiming '%s'", dent->d_name, stackdir); /* did we find ourself? */ if (streq(dent->d_name, udev_device_get_id_filename(dev))) @@ -165,7 +165,7 @@ static const char *link_find_prioritized(struct udev_device *dev, bool add, cons devnode = udev_device_get_devnode(dev_db); if (devnode != NULL) { if (target == NULL || udev_device_get_devlink_priority(dev_db) > priority) { - log_debug("'%s' claims priority %i for '%s'\n", + log_debug("'%s' claims priority %i for '%s'", udev_device_get_syspath(dev_db), udev_device_get_devlink_priority(dev_db), stackdir); priority = udev_device_get_devlink_priority(dev_db); strscpy(buf, bufsize, devnode); @@ -198,11 +198,11 @@ static void link_update(struct udev_device *dev, const char *slink, bool add) target = link_find_prioritized(dev, add, dirname, buf, sizeof(buf)); if (target == NULL) { - log_debug("no reference left, remove '%s'\n", slink); + log_debug("no reference left, remove '%s'", slink); if (unlink(slink) == 0) util_delete_path(udev, slink); } else { - log_debug("creating link '%s' to '%s'\n", slink, target); + log_debug("creating link '%s' to '%s'", slink, target); node_symlink(dev, target, slink); } @@ -247,7 +247,7 @@ void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev if (found) continue; - log_debug("update old name, '%s' no longer belonging to '%s'\n", + log_debug("update old name, '%s' no longer belonging to '%s'", name, udev_device_get_devpath(dev)); link_update(dev, name, false); } @@ -269,13 +269,13 @@ 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)\n", devnode); + log_debug("can not stat() node '%s' (%m)", devnode); goto out; } if (((stats.st_mode & S_IFMT) != (mode & S_IFMT)) || (stats.st_rdev != devnum)) { err = -EEXIST; - log_debug("found node '%s' with non-matching devnum %s, skip handling\n", + log_debug("found node '%s' with non-matching devnum %s, skip handling", udev_device_get_devnode(dev), udev_device_get_id_filename(dev)); goto out; } @@ -285,12 +285,11 @@ static int node_permissions_apply(struct udev_device *dev, bool apply, bool smack = false; if ((stats.st_mode & 0777) != (mode & 0777) || stats.st_uid != uid || stats.st_gid != gid) { - log_debug("set permissions %s, %#o, uid=%u, gid=%u\n", devnode, mode, uid, gid); + log_debug("set permissions %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid); chmod(devnode, mode); - if (chown(devnode, uid, gid) < 0) - log_debug("Failed to change ownership of %s to uid=%u, gid=%u\n", devnode, uid, gid); + chown(devnode, uid, gid); } else { - log_debug("preserve permissions %s, %#o, uid=%u, gid=%u\n", devnode, mode, uid, gid); + log_debug("preserve permissions %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid); } /* apply SECLABEL{$module}=$label */ @@ -337,7 +336,7 @@ void udev_node_add(struct udev_device *dev, bool apply, char filename[UTIL_PATH_SIZE]; struct udev_list_entry *list_entry; - log_debug("handling device node '%s', devnum=%s, mode=%#o, uid=%d, gid=%d\n", + log_debug("handling device node '%s', devnum=%s, mode=%#o, uid=%d, gid=%d", udev_device_get_devnode(dev), udev_device_get_id_filename(dev), mode, uid, gid); if (node_permissions_apply(dev, apply, mode, uid, gid, seclabel_list) < 0) diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 18749f5edb..a57dd8ebd3 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -46,10 +46,20 @@ struct uid_gid { }; }; +static const char* const rules_dirs[] = { + UDEV_CONF_DIR "/rules.d", + UDEV_RULES_DIR, + "/run/udev/rules.d", + UDEV_LIBEXEC_DIR "/rules.d", +#ifdef HAVE_SPLIT_USR + "/lib/udev/rules.d", + "/usr/lib/udev/rules.d", +#endif + NULL}; + struct udev_rules { struct udev *udev; - char **dirs; - usec_t *dirs_ts_usec; + usec_t dirs_ts_usec; int resolve_names; /* every key in the rules file becomes a token */ @@ -324,7 +334,7 @@ static void dump_token(struct udev_rules *rules, struct token *token) const char *tk_ptr = (char *)token; unsigned int idx = (tk_ptr - tks_ptr) / sizeof(struct token); - log_debug("* RULE %s:%u, token: %u, count: %u, label: '%s'\n", + log_debug("* RULE %s:%u, token: %u, count: %u, label: '%s'", &rules->buf[token->rule.filename_off], token->rule.filename_line, idx, token->rule.token_count, &rules->buf[token->rule.label_off]); @@ -356,68 +366,68 @@ static void dump_token(struct udev_rules *rules, struct token *token) case TK_A_MODE: case TK_A_RUN_BUILTIN: case TK_A_RUN_PROGRAM: - log_debug("%s %s '%s'(%s)\n", + log_debug("%s %s '%s'(%s)", token_str(type), operation_str(op), value, string_glob_str(glob)); break; case TK_M_IMPORT_BUILTIN: - log_debug("%s %i '%s'\n", token_str(type), token->key.builtin_cmd, value); + log_debug("%s %i '%s'", token_str(type), token->key.builtin_cmd, value); break; case TK_M_ATTR: case TK_M_ATTRS: case TK_M_ENV: case TK_A_ATTR: case TK_A_ENV: - log_debug("%s %s '%s' '%s'(%s)\n", + log_debug("%s %s '%s' '%s'(%s)", token_str(type), operation_str(op), attr, value, string_glob_str(glob)); break; case TK_M_TAG: case TK_A_TAG: - log_debug("%s %s '%s'\n", token_str(type), operation_str(op), value); + log_debug("%s %s '%s'", token_str(type), operation_str(op), value); break; case TK_A_STRING_ESCAPE_NONE: case TK_A_STRING_ESCAPE_REPLACE: case TK_A_DB_PERSIST: - log_debug("%s\n", token_str(type)); + log_debug("%s", token_str(type)); break; case TK_M_TEST: - log_debug("%s %s '%s'(%s) %#o\n", + log_debug("%s %s '%s'(%s) %#o", token_str(type), operation_str(op), value, string_glob_str(glob), token->key.mode); break; case TK_A_INOTIFY_WATCH: - log_debug("%s %u\n", token_str(type), token->key.watch); + log_debug("%s %u", token_str(type), token->key.watch); break; case TK_A_DEVLINK_PRIO: - log_debug("%s %u\n", token_str(type), token->key.devlink_prio); + log_debug("%s %u", token_str(type), token->key.devlink_prio); break; case TK_A_OWNER_ID: - log_debug("%s %s %u\n", token_str(type), operation_str(op), token->key.uid); + log_debug("%s %s %u", token_str(type), operation_str(op), token->key.uid); break; case TK_A_GROUP_ID: - log_debug("%s %s %u\n", token_str(type), operation_str(op), token->key.gid); + log_debug("%s %s %u", token_str(type), operation_str(op), token->key.gid); break; case TK_A_MODE_ID: - log_debug("%s %s %#o\n", token_str(type), operation_str(op), token->key.mode); + log_debug("%s %s %#o", token_str(type), operation_str(op), token->key.mode); break; case TK_A_STATIC_NODE: - log_debug("%s '%s'\n", token_str(type), value); + log_debug("%s '%s'", token_str(type), value); break; case TK_A_SECLABEL: - log_debug("%s %s '%s' '%s'\n", token_str(type), operation_str(op), attr, value); + log_debug("%s %s '%s' '%s'", token_str(type), operation_str(op), attr, value); break; case TK_M_EVENT_TIMEOUT: - log_debug("%s %u\n", token_str(type), token->key.event_timeout); + log_debug("%s %u", token_str(type), token->key.event_timeout); break; case TK_A_GOTO: - log_debug("%s '%s' %u\n", token_str(type), value, token->key.rule_goto); + log_debug("%s '%s' %u", token_str(type), value, token->key.rule_goto); break; case TK_END: - log_debug("* %s\n", token_str(type)); + log_debug("* %s", token_str(type)); break; case TK_M_PARENTS_MIN: case TK_M_PARENTS_MAX: case TK_M_MAX: case TK_UNSET: - log_debug("unknown type %u\n", type); + log_debug("unknown type %u", type); break; } } @@ -426,12 +436,12 @@ static void dump_rules(struct udev_rules *rules) { unsigned int i; - log_debug("dumping %u (%zu bytes) tokens, %u (%zu bytes) strings\n", + log_debug("dumping %u (%zu bytes) tokens, %u (%zu bytes) strings", rules->token_cur, rules->token_cur * sizeof(struct token), rules->buf_count, rules->buf_cur); - for(i = 0; i < rules->token_cur; i++) + for (i = 0; i < rules->token_cur; i++) dump_token(rules, &rules->tokens[i]); } #else @@ -551,6 +561,7 @@ static int import_property_from_string(struct udev_device *dev, char *line) char *key; char *val; size_t len; + struct udev_list_entry *entry; /* find key */ key = line; @@ -594,29 +605,18 @@ static int import_property_from_string(struct udev_device *dev, char *line) /* unquote */ if (val[0] == '"' || val[0] == '\'') { if (val[len-1] != val[0]) { - log_debug("inconsistent quoting: '%s', skip\n", line); + log_debug("inconsistent quoting: '%s', skip", line); return -1; } val[len-1] = '\0'; val++; } - /* handle device, renamed by external tool, returning new path */ - if (streq(key, "DEVPATH")) { - char syspath[UTIL_PATH_SIZE]; - - log_debug("updating devpath from '%s' to '%s'\n", - udev_device_get_devpath(dev), val); - strscpyl(syspath, sizeof(syspath), "/sys", val, NULL); - udev_device_set_syspath(dev, syspath); - } else { - struct udev_list_entry *entry; - - entry = udev_device_add_property(dev, key, val); - /* store in db, skip private keys */ - if (key[0] != '.') - udev_list_entry_set_num(entry, true); - } + entry = udev_device_add_property(dev, key, val); + /* store in db, skip private keys */ + if (key[0] != '.') + udev_list_entry_set_num(entry, true); + return 0; } @@ -708,18 +708,18 @@ static int wait_for_file(struct udev_device *dev, const char *file, int timeout) /* lookup file */ if (stat(file, &stats) == 0) { - log_debug("file '%s' appeared after %i loops\n", file, (timeout * WAIT_LOOP_PER_SECOND) - loop-1); + log_debug("file '%s' appeared after %i loops", file, (timeout * WAIT_LOOP_PER_SECOND) - loop-1); return 0; } /* make sure, the device did not disappear in the meantime */ if (devicepath[0] != '\0' && stat(devicepath, &stats) != 0) { - log_debug("device disappeared while waiting for '%s'\n", file); + log_debug("device disappeared while waiting for '%s'", file); return -2; } - log_debug("wait for '%s' for %i mseconds\n", file, 1000 / WAIT_LOOP_PER_SECOND); + log_debug("wait for '%s' for %i mseconds", file, 1000 / WAIT_LOOP_PER_SECOND); nanosleep(&duration, NULL); } - log_debug("waiting for '%s' failed\n", file); + log_debug("waiting for '%s' failed", file); return -1; } @@ -859,7 +859,7 @@ static const char *get_key_attribute(struct udev *udev, char *str) attr++; pos = strchr(attr, '}'); if (pos == NULL) { - log_error("missing closing brace for format\n"); + log_error("missing closing brace for format"); return NULL; } pos[0] = '\0'; @@ -960,7 +960,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, case TK_M_MAX: case TK_END: case TK_UNSET: - log_error("wrong type %u\n", type); + log_error("wrong type %u", type); return -1; } @@ -971,7 +971,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, int has_glob; has_split = (strchr(value, '|') != NULL); - has_glob = (strchr(value, '*') != NULL || strchr(value, '?') != NULL || strchr(value, '[') != NULL); + has_glob = string_is_glob(value); if (has_split && has_glob) { glob = GL_SPLIT_GLOB; } else if (has_split) { @@ -1011,7 +1011,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, token->key.op = op; rule_tmp->token_cur++; if (rule_tmp->token_cur >= ELEMENTSOF(rule_tmp->token)) { - log_error("temporary rule array too small\n"); + log_error("temporary rule array too small"); return -1; } return 0; @@ -1091,14 +1091,14 @@ static int add_rule(struct udev_rules *rules, char *line, "starting at character %tu ('%s')\n", filename, lineno, linepos - line + 1, tmp); if (linepos[1] == '#') - log_info("hint: comments can only start at beginning of line"); + log_error("hint: comments can only start at beginning of line"); } break; } if (streq(key, "ACTION")) { if (op > OP_MATCH_MAX) { - log_error("invalid ACTION operation\n"); + log_error("invalid ACTION operation"); goto invalid; } rule_add_key(&rule_tmp, TK_M_ACTION, op, value, NULL); @@ -1107,7 +1107,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (streq(key, "DEVPATH")) { if (op > OP_MATCH_MAX) { - log_error("invalid DEVPATH operation\n"); + log_error("invalid DEVPATH operation"); goto invalid; } rule_add_key(&rule_tmp, TK_M_DEVPATH, op, value, NULL); @@ -1116,7 +1116,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (streq(key, "KERNEL")) { if (op > OP_MATCH_MAX) { - log_error("invalid KERNEL operation\n"); + log_error("invalid KERNEL operation"); goto invalid; } rule_add_key(&rule_tmp, TK_M_KERNEL, op, value, NULL); @@ -1125,7 +1125,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (streq(key, "SUBSYSTEM")) { if (op > OP_MATCH_MAX) { - log_error("invalid SUBSYSTEM operation\n"); + log_error("invalid SUBSYSTEM operation"); goto invalid; } /* bus, class, subsystem events should all be the same */ @@ -1133,7 +1133,7 @@ static int add_rule(struct udev_rules *rules, char *line, streq(value, "bus") || streq(value, "class")) { if (streq(value, "bus") || streq(value, "class")) - log_error("'%s' must be specified as 'subsystem' \n" + log_error("'%s' must be specified as 'subsystem' " "please fix it in %s:%u", value, filename, lineno); rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, "subsystem|class|bus", NULL); } else @@ -1143,7 +1143,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (streq(key, "DRIVER")) { if (op > OP_MATCH_MAX) { - log_error("invalid DRIVER operation\n"); + log_error("invalid DRIVER operation"); goto invalid; } rule_add_key(&rule_tmp, TK_M_DRIVER, op, value, NULL); @@ -1153,7 +1153,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (startswith(key, "ATTR{")) { attr = get_key_attribute(rules->udev, key + sizeof("ATTR")-1); if (attr == NULL) { - log_error("error parsing ATTR attribute\n"); + log_error("error parsing ATTR attribute"); goto invalid; } if (op < OP_MATCH_MAX) { @@ -1167,7 +1167,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (startswith(key, "SECLABEL{")) { attr = get_key_attribute(rules->udev, key + sizeof("SECLABEL")-1); if (!attr) { - log_error("error parsing SECLABEL attribute\n"); + log_error("error parsing SECLABEL attribute"); goto invalid; } @@ -1177,7 +1177,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (streq(key, "KERNELS")) { if (op > OP_MATCH_MAX) { - log_error("invalid KERNELS operation\n"); + log_error("invalid KERNELS operation"); goto invalid; } rule_add_key(&rule_tmp, TK_M_KERNELS, op, value, NULL); @@ -1186,7 +1186,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (streq(key, "SUBSYSTEMS")) { if (op > OP_MATCH_MAX) { - log_error("invalid SUBSYSTEMS operation\n"); + log_error("invalid SUBSYSTEMS operation"); goto invalid; } rule_add_key(&rule_tmp, TK_M_SUBSYSTEMS, op, value, NULL); @@ -1195,7 +1195,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (streq(key, "DRIVERS")) { if (op > OP_MATCH_MAX) { - log_error("invalid DRIVERS operation\n"); + log_error("invalid DRIVERS operation"); goto invalid; } rule_add_key(&rule_tmp, TK_M_DRIVERS, op, value, NULL); @@ -1204,12 +1204,12 @@ static int add_rule(struct udev_rules *rules, char *line, if (startswith(key, "ATTRS{")) { if (op > OP_MATCH_MAX) { - log_error("invalid ATTRS operation\n"); + log_error("invalid ATTRS operation"); goto invalid; } attr = get_key_attribute(rules->udev, key + sizeof("ATTRS")-1); if (attr == NULL) { - log_error("error parsing ATTRS attribute\n"); + log_error("error parsing ATTRS attribute"); goto invalid; } if (startswith(attr, "device/")) @@ -1224,7 +1224,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (streq(key, "TAGS")) { if (op > OP_MATCH_MAX) { - log_error("invalid TAGS operation\n"); + log_error("invalid TAGS operation"); goto invalid; } rule_add_key(&rule_tmp, TK_M_TAGS, op, value, NULL); @@ -1234,7 +1234,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (startswith(key, "ENV{")) { attr = get_key_attribute(rules->udev, key + sizeof("ENV")-1); if (attr == NULL) { - log_error("error parsing ENV attribute\n"); + log_error("error parsing ENV attribute"); goto invalid; } if (op < OP_MATCH_MAX) { @@ -1259,7 +1259,7 @@ static int add_rule(struct udev_rules *rules, char *line, for (i = 0; i < ELEMENTSOF(blacklist); i++) { if (!streq(attr, blacklist[i])) continue; - log_error("invalid ENV attribute, '%s' can not be set %s:%u\n", attr, filename, lineno); + log_error("invalid ENV attribute, '%s' can not be set %s:%u", attr, filename, lineno); goto invalid; } if (rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr) != 0) @@ -1283,7 +1283,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (streq(key, "RESULT")) { if (op > OP_MATCH_MAX) { - log_error("invalid RESULT operation\n"); + log_error("invalid RESULT operation"); goto invalid; } rule_add_key(&rule_tmp, TK_M_RESULT, op, value, NULL); @@ -1293,7 +1293,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (startswith(key, "IMPORT")) { attr = get_key_attribute(rules->udev, key + sizeof("IMPORT")-1); if (attr == NULL) { - log_error("IMPORT{} type missing, ignoring IMPORT %s:%u\n", filename, lineno); + log_error("IMPORT{} type missing, ignoring IMPORT %s:%u", filename, lineno); continue; } if (streq(attr, "program")) { @@ -1303,7 +1303,7 @@ static int add_rule(struct udev_rules *rules, char *line, cmd = udev_builtin_lookup(value); if (cmd < UDEV_BUILTIN_MAX) { - log_debug("IMPORT found builtin '%s', replacing %s:%u\n", + log_debug("IMPORT found builtin '%s', replacing %s:%u", value, filename, lineno); rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd); continue; @@ -1316,7 +1316,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (cmd < UDEV_BUILTIN_MAX) rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd); else - log_error("IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno); + log_error("IMPORT{builtin}: '%s' unknown %s:%u", value, filename, lineno); } else if (streq(attr, "file")) { rule_add_key(&rule_tmp, TK_M_IMPORT_FILE, op, value, NULL); } else if (streq(attr, "db")) { @@ -1326,7 +1326,7 @@ static int add_rule(struct udev_rules *rules, char *line, } else if (streq(attr, "parent")) { rule_add_key(&rule_tmp, TK_M_IMPORT_PARENT, op, value, NULL); } else - log_error("IMPORT{} unknown type, ignoring IMPORT %s:%u\n", filename, lineno); + log_error("IMPORT{} unknown type, ignoring IMPORT %s:%u", filename, lineno); continue; } @@ -1334,7 +1334,7 @@ static int add_rule(struct udev_rules *rules, char *line, mode_t mode = 0; if (op > OP_MATCH_MAX) { - log_error("invalid TEST operation\n"); + log_error("invalid TEST operation"); goto invalid; } attr = get_key_attribute(rules->udev, key + sizeof("TEST")-1); @@ -1358,13 +1358,13 @@ static int add_rule(struct udev_rules *rules, char *line, if (cmd < UDEV_BUILTIN_MAX) rule_add_key(&rule_tmp, TK_A_RUN_BUILTIN, op, value, &cmd); else - log_error("IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno); + log_error("IMPORT{builtin}: '%s' unknown %s:%u", value, filename, lineno); } else if (streq(attr, "program")) { enum udev_builtin_cmd cmd = UDEV_BUILTIN_MAX; rule_add_key(&rule_tmp, TK_A_RUN_PROGRAM, op, value, &cmd); } else { - log_error("RUN{} unknown type, ignoring RUN %s:%u\n", filename, lineno); + log_error("RUN{} unknown type, ignoring RUN %s:%u", filename, lineno); } continue; @@ -1514,7 +1514,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - log_error("unknown key '%s' in %s:%u\n", key, filename, lineno); + log_error("unknown key '%s' in %s:%u", key, filename, lineno); goto invalid; } @@ -1529,7 +1529,7 @@ static int add_rule(struct udev_rules *rules, char *line, return 0; invalid: - log_error("invalid rule '%s:%u'\n", filename, lineno); + log_error("invalid rule '%s:%u'", filename, lineno); return -1; } @@ -1543,10 +1543,10 @@ static int parse_file(struct udev_rules *rules, const char *filename) unsigned int i; if (null_or_empty_path(filename)) { - log_debug("skip empty file: %s\n", filename); + log_debug("skip empty file: %s", filename); return 0; } - log_debug("read rules file: %s\n", filename); + log_debug("read rules file: %s", filename); f = fopen(filename, "re"); if (f == NULL) @@ -1584,7 +1584,7 @@ static int parse_file(struct udev_rules *rules, const char *filename) } if (len+1 >= sizeof(line)) { - log_error("line too long '%s':%u, ignored\n", filename, line_nr); + log_error("line too long '%s':%u, ignored", filename, line_nr); continue; } add_rule(rules, key, filename, filename_off, line_nr); @@ -1608,7 +1608,7 @@ static int parse_file(struct udev_rules *rules, const char *filename) break; } if (rules->tokens[i].key.rule_goto == 0) - log_error("GOTO '%s' has no matching label in: '%s'\n", label, filename); + log_error("GOTO '%s' has no matching label in: '%s'", label, filename); } } return 0; @@ -1639,33 +1639,11 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) if (!rules->strbuf) return udev_rules_unref(rules); - rules->dirs = strv_new(UDEV_CONF_DIR "/rules.d", - UDEV_RULES_DIR, - "/run/udev/rules.d", - UDEV_LIBEXEC_DIR "/rules.d", -#ifdef HAVE_SPLIT_USR - "/lib/udev/rules.d", - "/usr/lib/udev/rules.d", -#endif - NULL); - if (!rules->dirs) { - log_error("failed to build config directory array"); - return udev_rules_unref(rules); - } - if (!path_strv_canonicalize(rules->dirs)) { - log_error("failed to canonicalize config directories\n"); - return udev_rules_unref(rules); - } - strv_uniq(rules->dirs); - - rules->dirs_ts_usec = calloc(strv_length(rules->dirs), sizeof(usec_t)); - if(!rules->dirs_ts_usec) - return udev_rules_unref(rules); udev_rules_check_timestamp(rules); - r = conf_files_list_strv(&files, ".rules", NULL, (const char **)rules->dirs); + r = conf_files_list_strv(&files, ".rules", NULL, rules_dirs); if (r < 0) { - log_error("failed to enumerate rules files: %s\n", strerror(-r)); + log_error("failed to enumerate rules files: %s", strerror(-r)); return udev_rules_unref(rules); } @@ -1684,11 +1662,11 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) memset(&end_token, 0x00, sizeof(struct token)); end_token.type = TK_END; add_token(rules, &end_token); - log_debug("rules contain %zu bytes tokens (%u * %zu bytes), %zu bytes strings\n", + log_debug("rules contain %zu bytes tokens (%u * %zu bytes), %zu bytes strings", rules->token_max * sizeof(struct token), rules->token_max, sizeof(struct token), rules->strbuf->len); /* cleanup temporary strbuf data */ - log_debug("%zu strings (%zu bytes), %zu de-duplicated (%zu bytes), %zu trie nodes used\n", + log_debug("%zu strings (%zu bytes), %zu de-duplicated (%zu bytes), %zu trie nodes used", rules->strbuf->in_count, rules->strbuf->in_len, rules->strbuf->dedup_count, rules->strbuf->dedup_len, rules->strbuf->nodes_count); strbuf_complete(rules->strbuf); @@ -1715,15 +1693,16 @@ struct udev_rules *udev_rules_unref(struct udev_rules *rules) strbuf_cleanup(rules->strbuf); free(rules->uids); free(rules->gids); - strv_free(rules->dirs); - free(rules->dirs_ts_usec); free(rules); return NULL; } bool udev_rules_check_timestamp(struct udev_rules *rules) { - return paths_check_timestamp(rules->dirs, rules->dirs_ts_usec, true); + if (!rules) + return false; + + return paths_check_timestamp(rules_dirs, &rules->dirs_ts_usec, true); } static int match_key(struct udev_rules *rules, struct token *token, const char *val) @@ -2116,7 +2095,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event break; } case TK_M_EVENT_TIMEOUT: - log_debug("OPTIONS event_timeout=%u\n", cur->key.event_timeout); + log_debug("OPTIONS event_timeout=%u", cur->key.event_timeout); event->timeout_usec = cur->key.event_timeout * 1000 * 1000; break; case TK_M_PROGRAM: { @@ -2128,7 +2107,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event event->program_result = NULL; udev_event_apply_format(event, rules_str(rules, cur->key.value_off), program, sizeof(program)); envp = udev_device_get_properties_envp(event->dev); - log_debug("PROGRAM '%s' %s:%u\n", + log_debug("PROGRAM '%s' %s:%u", program, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); @@ -2143,7 +2122,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event if (esc == ESCAPE_UNSET || esc == ESCAPE_REPLACE) { count = util_replace_chars(result, UDEV_ALLOWED_CHARS_INPUT); if (count > 0) - log_debug("%i character(s) replaced\n" , count); + log_debug("%i character(s) replaced" , count); } event->program_result = strdup(result); if (cur->key.op == OP_NOMATCH) @@ -2164,7 +2143,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event char import[UTIL_PATH_SIZE]; udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import)); - log_debug("IMPORT '%s' %s:%u\n", + log_debug("IMPORT '%s' %s:%u", import, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); @@ -2180,7 +2159,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event if (udev_builtin_run_once(cur->key.builtin_cmd)) { /* check if we ran already */ if (event->builtin_run & (1 << cur->key.builtin_cmd)) { - log_debug("IMPORT builtin skip '%s' %s:%u\n", + log_debug("IMPORT builtin skip '%s' %s:%u", udev_builtin_name(cur->key.builtin_cmd), rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); @@ -2195,14 +2174,14 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event } udev_event_apply_format(event, rules_str(rules, cur->key.value_off), command, sizeof(command)); - log_debug("IMPORT builtin '%s' %s:%u\n", + log_debug("IMPORT builtin '%s' %s:%u", udev_builtin_name(cur->key.builtin_cmd), rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); if (udev_builtin_run(event->dev, cur->key.builtin_cmd, command, false) != 0) { /* remember failure */ - log_debug("IMPORT builtin '%s' returned non-zero\n", + log_debug("IMPORT builtin '%s' returned non-zero", udev_builtin_name(cur->key.builtin_cmd)); event->builtin_ret |= (1 << cur->key.builtin_cmd); if (cur->key.op != OP_NOMATCH) @@ -2310,7 +2289,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event udev_event_apply_format(event, rules_str(rules, cur->key.value_off), owner, sizeof(owner)); event->owner_set = true; event->uid = util_lookup_user(event->udev, owner); - log_debug("OWNER %u %s:%u\n", + log_debug("OWNER %u %s:%u", event->uid, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); @@ -2326,7 +2305,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event udev_event_apply_format(event, rules_str(rules, cur->key.value_off), group, sizeof(group)); event->group_set = true; event->gid = util_lookup_group(event->udev, group); - log_debug("GROUP %u %s:%u\n", + log_debug("GROUP %u %s:%u", event->gid, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); @@ -2342,14 +2321,14 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event udev_event_apply_format(event, rules_str(rules, cur->key.value_off), mode_str, sizeof(mode_str)); mode = strtol(mode_str, &endptr, 8); if (endptr[0] != '\0') { - log_error("ignoring invalid mode '%s'\n", mode_str); + log_error("ignoring invalid mode '%s'", mode_str); break; } if (cur->key.op == OP_ASSIGN_FINAL) event->mode_final = true; event->mode_set = true; event->mode = mode; - log_debug("MODE %#o %s:%u\n", + log_debug("MODE %#o %s:%u", event->mode, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); @@ -2362,7 +2341,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event event->owner_final = true; event->owner_set = true; event->uid = cur->key.uid; - log_debug("OWNER %u %s:%u\n", + log_debug("OWNER %u %s:%u", event->uid, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); @@ -2374,7 +2353,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event event->group_final = true; event->group_set = true; event->gid = cur->key.gid; - log_debug("GROUP %u %s:%u\n", + log_debug("GROUP %u %s:%u", event->gid, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); @@ -2386,7 +2365,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event event->mode_final = true; event->mode_set = true; event->mode = cur->key.mode; - log_debug("MODE %#o %s:%u\n", + log_debug("MODE %#o %s:%u", event->mode, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); @@ -2399,7 +2378,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL) udev_list_cleanup(&event->seclabel_list); udev_list_entry_add(&event->seclabel_list, name, label); - log_debug("SECLABEL{%s}='%s' %s:%u\n", + log_debug("SECLABEL{%s}='%s' %s:%u", name, label, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); @@ -2449,7 +2428,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event (*p >= '0' && *p <= '9') || *p == '-' || *p == '_') continue; - log_error("ignoring invalid tag name '%s'\n", tag); + log_error("ignoring invalid tag name '%s'", tag); break; } udev_device_add_tag(event->dev, tag); @@ -2469,7 +2448,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event if (esc == ESCAPE_UNSET || esc == ESCAPE_REPLACE) { 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 (major(udev_device_get_devnum(event->dev)) && (!streq(name_str, udev_device_get_devnode(event->dev) + strlen("/dev/")))) { @@ -2480,7 +2459,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event } free(event->name); event->name = strdup(name_str); - log_debug("NAME '%s' %s:%u\n", + log_debug("NAME '%s' %s:%u", event->name, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); @@ -2508,14 +2487,14 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event else if (esc == ESCAPE_REPLACE) count = util_replace_chars(temp, "/"); if (count > 0) - log_debug("%i character(s) replaced\n" , count); + log_debug("%i character(s) replaced" , count); pos = temp; while (isspace(pos[0])) pos++; next = strchr(pos, ' '); while (next != NULL) { next[0] = '\0'; - log_debug("LINK '%s' %s:%u\n", pos, + log_debug("LINK '%s' %s:%u", pos, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); strscpyl(filename, sizeof(filename), "/dev/", pos, NULL); udev_device_add_devlink(event->dev, filename); @@ -2525,7 +2504,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event next = strchr(pos, ' '); } if (pos[0] != '\0') { - log_debug("LINK '%s' %s:%u\n", pos, + log_debug("LINK '%s' %s:%u", pos, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); strscpyl(filename, sizeof(filename), "/dev/", pos, NULL); udev_device_add_devlink(event->dev, filename); @@ -2543,16 +2522,16 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event attr_subst_subdir(attr, sizeof(attr)); udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value)); - log_debug("ATTR '%s' writing '%s' %s:%u\n", attr, value, + log_debug("ATTR '%s' writing '%s' %s:%u", attr, value, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); f = fopen(attr, "we"); if (f != NULL) { if (fprintf(f, "%s", value) <= 0) - log_error("error writing ATTR{%s}: %m\n", attr); + log_error("error writing ATTR{%s}: %m", attr); fclose(f); } else { - log_error("error opening ATTR{%s} for writing: %m\n", attr); + log_error("error opening ATTR{%s} for writing: %m", attr); } break; } @@ -2562,7 +2541,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL) udev_list_cleanup(&event->run_list); - log_debug("RUN '%s' %s:%u\n", + log_debug("RUN '%s' %s:%u", rules_str(rules, cur->key.value_off), rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); @@ -2582,7 +2561,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event case TK_M_PARENTS_MAX: case TK_M_MAX: case TK_UNSET: - log_error("wrong type %u\n", cur->type); + log_error("wrong type %u", cur->type); goto nomatch; } @@ -2667,7 +2646,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\n", tags_dir, strerror(-r)); + log_error("failed to create %s: %s", tags_dir, strerror(-r)); return r; } @@ -2676,7 +2655,7 @@ 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: %s\n", tag_symlink, device_node, strerror(errno)); + log_error("failed to create symlink %s -> %s: %m", tag_symlink, device_node); return -errno; } else r = 0; @@ -2696,19 +2675,19 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) if (mode != (stats.st_mode & 01777)) { r = chmod(device_node, mode); if (r < 0) { - log_error("failed to chmod '%s' %#o\n", device_node, mode); + log_error("failed to chmod '%s' %#o", device_node, mode); return -errno; } else - log_debug("chmod '%s' %#o\n", device_node, mode); + log_debug("chmod '%s' %#o", device_node, mode); } if ((uid != 0 && uid != stats.st_uid) || (gid != 0 && gid != stats.st_gid)) { r = chown(device_node, uid, gid); if (r < 0) { - log_error("failed to chown '%s' %u %u \n", device_node, uid, gid); + log_error("failed to chown '%s' %u %u ", device_node, uid, gid); return -errno; } else - log_debug("chown '%s' %u %u\n", device_node, uid, gid); + log_debug("chown '%s' %u %u", device_node, uid, gid); } utimensat(AT_FDCWD, device_node, NULL, 0); diff --git a/src/udev/udev-util.h b/src/udev/udev-util.h new file mode 100644 index 0000000000..40f8b776ce --- /dev/null +++ b/src/udev/udev-util.h @@ -0,0 +1,44 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#pragma once + +/*** + This file is part of systemd. + + Copyright 2013 Zbigniew Jędrzejewski-Szmek + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include "udev.h" +#include "util.h" + +DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev*, udev_unref); +DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_device*, udev_device_unref); +DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_enumerate*, udev_enumerate_unref); +DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_event*, udev_event_unref); +DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_rules*, udev_rules_unref); +DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_ctrl*, udev_ctrl_unref); +DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_monitor*, udev_monitor_unref); +DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_queue*, udev_queue_unref); + +#define _cleanup_udev_unref_ _cleanup_(udev_unrefp) +#define _cleanup_udev_device_unref_ _cleanup_(udev_device_unrefp) +#define _cleanup_udev_enumerate_unref_ _cleanup_(udev_enumerate_unrefp) +#define _cleanup_udev_event_unref_ _cleanup_(udev_event_unrefp) +#define _cleanup_udev_rules_unref_ _cleanup_(udev_rules_unrefp) +#define _cleanup_udev_ctrl_unref_ _cleanup_(udev_ctrl_unrefp) +#define _cleanup_udev_monitor_unref_ _cleanup_(udev_monitor_unrefp) +#define _cleanup_udev_queue_unref_ _cleanup_(udev_queue_unrefp) +#define _cleanup_udev_list_cleanup_ _cleanup_(udev_list_cleanup) diff --git a/src/udev/udev-watch.c b/src/udev/udev-watch.c index 9b694c6666..cbe0c37a4f 100644 --- a/src/udev/udev-watch.c +++ b/src/udev/udev-watch.c @@ -40,7 +40,7 @@ int udev_watch_init(struct udev *udev) { inotify_fd = inotify_init1(IN_CLOEXEC); if (inotify_fd < 0) - log_error("inotify_init failed: %m\n"); + log_error("inotify_init failed: %m"); return inotify_fd; } @@ -79,7 +79,7 @@ void udev_watch_restore(struct udev *udev) if (dev == NULL) goto unlink; - log_debug("restoring old watch on '%s'\n", udev_device_get_devnode(dev)); + log_debug("restoring old watch on '%s'", udev_device_get_devnode(dev)); udev_watch_begin(udev, dev); udev_device_unref(dev); unlink: @@ -103,10 +103,10 @@ void udev_watch_begin(struct udev *udev, struct udev_device *dev) if (inotify_fd < 0) return; - log_debug("adding watch on '%s'\n", udev_device_get_devnode(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\n", + log_error("inotify_add_watch(%d, %s, %o) failed: %m", inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE); return; } @@ -133,7 +133,7 @@ void udev_watch_end(struct udev *udev, struct udev_device *dev) if (wd < 0) return; - log_debug("removing watch on '%s'\n", udev_device_get_devnode(dev)); + log_debug("removing watch on '%s'", udev_device_get_devnode(dev)); inotify_rm_watch(inotify_fd, wd); snprintf(filename, sizeof(filename), "/run/udev/watch/%d", wd); diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c index c5a189257d..3a6c8ef4fe 100644 --- a/src/udev/udevadm-control.c +++ b/src/udev/udevadm-control.c @@ -26,39 +26,40 @@ #include <sys/un.h> #include "udev.h" +#include "udev-util.h" static void print_help(void) { printf("Usage: udevadm control COMMAND\n" - " --exit instruct the daemon to cleanup and exit\n" - " --log-priority=<level> set the udev log level for the daemon\n" - " --stop-exec-queue do not execute events, queue only\n" - " --start-exec-queue execute events, flush queue\n" - " --reload reload rules and databases\n" - " --property=<KEY>=<value> set a global property for all events\n" - " --children-max=<N> maximum number of children\n" - " --timeout=<seconds> maximum time to block for a reply\n" - " --help print this help text\n\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"); } static int adm_control(struct udev *udev, int argc, char *argv[]) { - struct udev_ctrl *uctrl = NULL; + _cleanup_udev_ctrl_unref_ struct udev_ctrl *uctrl = NULL; int timeout = 60; - int rc = 1; + int rc = 1, c; static const struct option options[] = { - { "exit", no_argument, NULL, 'e' }, - { "log-priority", required_argument, NULL, 'l' }, - { "stop-exec-queue", no_argument, NULL, 's' }, - { "start-exec-queue", no_argument, NULL, 'S' }, - { "reload", no_argument, NULL, 'R' }, - { "reload-rules", no_argument, NULL, 'R' }, - { "property", required_argument, NULL, 'p' }, - { "env", required_argument, NULL, 'p' }, - { "children-max", required_argument, NULL, 'm' }, - { "timeout", required_argument, NULL, 't' }, - { "help", no_argument, NULL, 'h' }, + { "exit", no_argument, NULL, 'e' }, + { "log-priority", required_argument, NULL, 'l' }, + { "stop-exec-queue", no_argument, NULL, 's' }, + { "start-exec-queue", no_argument, NULL, 'S' }, + { "reload", no_argument, NULL, 'R' }, + { "reload-rules", no_argument, NULL, 'R' }, /* alias for -R */ + { "property", required_argument, NULL, 'p' }, + { "env", required_argument, NULL, 'p' }, /* alias for -p */ + { "children-max", required_argument, NULL, 'm' }, + { "timeout", required_argument, NULL, 't' }, + { "help", no_argument, NULL, 'h' }, {} }; @@ -71,14 +72,8 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) if (uctrl == NULL) return 2; - for (;;) { - int option; - - option = getopt_long(argc, argv, "el:sSRp:m:h", options, NULL); - if (option == -1) - break; - - switch (option) { + while ((c = getopt_long(argc, argv, "el:sSRp:m:h", options, NULL)) >= 0) + switch (c) { case 'e': if (udev_ctrl_send_exit(uctrl, timeout) < 0) rc = 2; @@ -91,7 +86,7 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) i = util_log_priority(optarg); if (i < 0) { fprintf(stderr, "invalid number '%s'\n", optarg); - goto out; + return rc; } if (udev_ctrl_send_set_log_level(uctrl, util_log_priority(optarg), timeout) < 0) rc = 2; @@ -120,7 +115,7 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) case 'p': if (strchr(optarg, '=') == NULL) { fprintf(stderr, "expect <KEY>=<value> instead of '%s'\n", optarg); - goto out; + return rc; } if (udev_ctrl_send_set_env(uctrl, optarg, timeout) < 0) rc = 2; @@ -134,7 +129,7 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) i = strtoul(optarg, &endp, 0); if (endp[0] != '\0' || i < 1) { fprintf(stderr, "invalid number '%s'\n", optarg); - goto out; + return rc; } if (udev_ctrl_send_set_children_max(uctrl, i, timeout) < 0) rc = 2; @@ -157,14 +152,11 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) rc = 0; break; } - } - if (argv[optind] != NULL) - fprintf(stderr, "unknown option\n"); + if (optind < argc) + fprintf(stderr, "Extraneous argument: %s\n", argv[optind]); else if (optind == 1) - fprintf(stderr, "missing option\n"); -out: - udev_ctrl_unref(uctrl); + fprintf(stderr, "Option missing\n"); return rc; } diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c index 08126c6d41..65ea866f4d 100644 --- a/src/udev/udevadm-hwdb.c +++ b/src/udev/udevadm-hwdb.c @@ -123,20 +123,14 @@ static void trie_node_cleanup(struct trie_node *node) { free(node); } - -static __thread void* trie_values_cmp_param; -static int trie_values_cmp(const void *v1, const void *v2) { +static int trie_values_cmp(const void *v1, const void *v2, void *arg) { const struct trie_value_entry *val1 = v1; const struct trie_value_entry *val2 = v2; - struct trie *trie = trie_values_cmp_param; + struct trie *trie = arg; return strcmp(trie->strings->buf + val1->key_off, trie->strings->buf + val2->key_off); } -static int trie_values_cmp_r(const void *v1, const void *v2, void* arg) { - trie_values_cmp_param = arg; - return trie_values_cmp(v1, v2); -} static int trie_node_add_value(struct trie *trie, struct trie_node *node, const char *key, const char *value) { @@ -156,7 +150,7 @@ static int trie_node_add_value(struct trie *trie, struct trie_node *node, .value_off = v, }; - val = xbsearch_r(&search, node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp_r, trie); + val = xbsearch_r(&search, node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp, trie); if (val) { /* replace existing earlier key with new value */ val->value_off = v; @@ -173,8 +167,7 @@ static int trie_node_add_value(struct trie *trie, struct trie_node *node, node->values[node->values_count].key_off = k; node->values[node->values_count].value_off = v; node->values_count++; - trie_values_cmp_param = trie; - qsort(node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp); + qsort_r(node->values, node->values_count, sizeof(struct trie_value_entry), trie_values_cmp, trie); return 0; } @@ -320,14 +313,12 @@ static int64_t trie_store_nodes(struct trie_f *trie, struct trie_node *node) { /* write node */ node_off = ftello(trie->f); - if (fwrite(&n, sizeof(struct trie_node_f), 1, trie->f) != 1) - log_error("Failed to write sizeof struct trie_node_f to n in %s\n", "[udevadm-hwdb.c:trie_store_nodes]"); + fwrite(&n, sizeof(struct trie_node_f), 1, trie->f); trie->nodes_count++; /* append children array */ if (node->children_count) { - if (fwrite(children, sizeof(struct trie_child_entry_f), node->children_count, trie->f) != node->children_count) - log_error("Failed to write children_count in %s\n", "[udevadm-hwdb.c:trie_store_nodes]"); + fwrite(children, sizeof(struct trie_child_entry_f), node->children_count, trie->f); trie->children_count += node->children_count; free(children); } @@ -339,8 +330,7 @@ static int64_t trie_store_nodes(struct trie_f *trie, struct trie_node *node) { .value_off = htole64(trie->strings_off + node->values[i].value_off), }; - if (fwrite(&v, sizeof(struct trie_value_entry_f), 1, trie->f) != 1) - log_error("Failed to write sizeof trie_value_entry_f to v in %s\n", "[udevadm-hwdb.c:trie_store_nodes]"); + fwrite(&v, sizeof(struct trie_value_entry_f), 1, trie->f); trie->values_count++; } @@ -382,16 +372,14 @@ static int trie_store(struct trie *trie, const char *filename) { h.nodes_len = htole64(pos - sizeof(struct trie_header_f)); /* write string buffer */ - if (fwrite(trie->strings->buf, trie->strings->len, 1, t.f) != 1) - log_error("Failed to write into trie->strings->buf in %s\n", "[udevadm-hwdb.c:trie_store]"); + fwrite(trie->strings->buf, trie->strings->len, 1, t.f); h.strings_len = htole64(trie->strings->len); /* write header */ size = ftello(t.f); h.file_size = htole64(size); fseeko(t.f, 0, SEEK_SET); - if (fwrite(&h, sizeof(struct trie_header_f), 1, t.f) != 1) - log_error("Failed to write into h in %s\n", "[udevadm-hwdb.c:trie_store]"); + fwrite(&h, sizeof(struct trie_header_f), 1, t.f); err = ferror(t.f); if (err) err = -errno; @@ -401,17 +389,17 @@ static int trie_store(struct trie *trie, const char *filename) { goto out; } - log_debug("=== trie on-disk ===\n"); - log_debug("size: %8llu bytes\n", (unsigned long long)size); - log_debug("header: %8zu bytes\n", sizeof(struct trie_header_f)); - log_debug("nodes: %8llu bytes (%8llu)\n", + log_debug("=== trie on-disk ==="); + log_debug("size: %8llu bytes", (unsigned long long)size); + log_debug("header: %8zu bytes", sizeof(struct trie_header_f)); + log_debug("nodes: %8llu bytes (%8llu)", (unsigned long long)t.nodes_count * sizeof(struct trie_node_f), (unsigned long long)t.nodes_count); - log_debug("child pointers: %8llu bytes (%8llu)\n", + log_debug("child pointers: %8llu bytes (%8llu)", (unsigned long long)t.children_count * sizeof(struct trie_child_entry_f), (unsigned long long)t.children_count); - log_debug("value pointers: %8llu bytes (%8llu)\n", + log_debug("value pointers: %8llu bytes (%8llu)", (unsigned long long)t.values_count * sizeof(struct trie_value_entry_f), (unsigned long long)t.values_count); - log_debug("string store: %8llu bytes\n", (unsigned long long)trie->strings->len); - log_debug("strings start: %8llu\n", (unsigned long long) t.strings_off); + log_debug("string store: %8llu bytes", (unsigned long long)trie->strings->len); + log_debug("strings start: %8llu", (unsigned long long) t.strings_off); out: free(filename_tmp); return err; @@ -424,7 +412,7 @@ static int insert_data(struct trie *trie, struct udev_list *match_list, value = strchr(line, '='); if (!value) { - log_error("Error, key/value pair expected but got '%s' in '%s':\n", line, filename); + log_error("Error, key/value pair expected but got '%s' in '%s':", line, filename); return -EINVAL; } @@ -432,7 +420,7 @@ static int insert_data(struct trie *trie, struct udev_list *match_list, value++; if (line[0] == '\0' || value[0] == '\0') { - log_error("Error, empty key or value '%s' in '%s':\n", line, filename); + log_error("Error, empty key or value '%s' in '%s':", line, filename); return -EINVAL; } @@ -483,7 +471,7 @@ static int import_file(struct udev *udev, struct trie *trie, const char *filenam break; if (line[0] == ' ') { - log_error("Error, MATCH expected but got '%s' in '%s':\n", line, filename); + log_error("Error, MATCH expected but got '%s' in '%s':", line, filename); break; } @@ -494,7 +482,7 @@ static int import_file(struct udev *udev, struct trie *trie, const char *filenam case HW_MATCH: if (len == 0) { - log_error("Error, DATA expected but got empty line in '%s':\n", filename); + log_error("Error, DATA expected but got empty line in '%s':", filename); state = HW_NONE; udev_list_cleanup(&match_list); break; @@ -520,7 +508,7 @@ static int import_file(struct udev *udev, struct trie *trie, const char *filenam } if (line[0] != ' ') { - log_error("Error, DATA expected but got '%s' in '%s':\n", line, filename); + log_error("Error, DATA expected but got '%s' in '%s':", line, filename); state = HW_NONE; udev_list_cleanup(&match_list); break; @@ -538,36 +526,29 @@ static int import_file(struct udev *udev, struct trie *trie, const char *filenam static void help(void) { printf("Usage: udevadm hwdb OPTIONS\n" - " --update update the hardware database\n" - " --test=<modalias> query database and print result\n" - " --root=<path> alternative root path in the filesystem\n" - " --help\n\n"); + " -u,--update update the hardware database\n" + " -t,--test=MODALIAS query database and print result\n" + " -r,--root=PATH alternative root path in the filesystem\n" + " -h,--help\n\n"); } static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { static const struct option options[] = { - { "update", no_argument, NULL, 'u' }, - { "root", required_argument, NULL, 'r' }, - { "test", required_argument, NULL, 't' }, - { "help", no_argument, NULL, 'h' }, + { "update", no_argument, NULL, 'u' }, + { "test", required_argument, NULL, 't' }, + { "root", required_argument, NULL, 'r' }, + { "help", no_argument, NULL, 'h' }, {} }; const char *test = NULL; const char *root = ""; - char *udev_hwdb_path = UDEV_HWDB_BIN; bool update = false; struct trie *trie = NULL; - int err; + int err, c; int rc = EXIT_SUCCESS; - for (;;) { - int option; - - option = getopt_long(argc, argv, "ut:r:h", options, NULL); - if (option == -1) - break; - - switch (option) { + while ((c = getopt_long(argc, argv, "ut:r:h", options, NULL)) >= 0) + switch(c) { case 'u': update = true; break; @@ -580,16 +561,20 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { case 'h': help(); return EXIT_SUCCESS; + case '?': + return EXIT_FAILURE; + default: + assert_not_reached("Unknown option"); } - } if (!update && !test) { - help(); - return EXIT_SUCCESS; + log_error("Either --update or --test must be used"); + return EXIT_FAILURE; } if (update) { char **files, **f; + _cleanup_free_ char *hwdb_bin = UDEV_HWDB_BIN; trie = calloc(sizeof(struct trie), 1); if (!trie) { @@ -614,7 +599,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\n", strerror(-err)); + log_error("failed to enumerate hwdb files: %s", strerror(-err)); rc = EXIT_FAILURE; goto out; } @@ -626,38 +611,28 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { strbuf_complete(trie->strings); - log_debug("=== trie in-memory ===\n"); - log_debug("nodes: %8zu bytes (%8zu)\n", + log_debug("=== trie in-memory ==="); + log_debug("nodes: %8zu bytes (%8zu)", trie->nodes_count * sizeof(struct trie_node), trie->nodes_count); - log_debug("children arrays: %8zu bytes (%8zu)\n", + log_debug("children arrays: %8zu bytes (%8zu)", trie->children_count * sizeof(struct trie_child_entry), trie->children_count); - log_debug("values arrays: %8zu bytes (%8zu)\n", + log_debug("values arrays: %8zu bytes (%8zu)", trie->values_count * sizeof(struct trie_value_entry), trie->values_count); - log_debug("strings: %8zu bytes\n", + log_debug("strings: %8zu bytes", trie->strings->len); - log_debug("strings incoming: %8zu bytes (%8zu)\n", + log_debug("strings incoming: %8zu bytes (%8zu)", trie->strings->in_len, trie->strings->in_count); - log_debug("strings dedup'ed: %8zu bytes (%8zu)\n", + log_debug("strings dedup'ed: %8zu bytes (%8zu)", trie->strings->dedup_len, trie->strings->dedup_count); - if (root) { - if (asprintf(&udev_hwdb_path, - "%s/%s", root, udev_hwdb_path) < 0) { + if (asprintf(&hwdb_bin, "%s/%s", root, hwdb_bin) < 0) { rc = EXIT_FAILURE; goto out; - } - } - - mkdir_parents(udev_hwdb_path, 0755); - err = trie_store(trie, udev_hwdb_path); - - if (root) { - free(udev_hwdb_path); } - + mkdir_parents(hwdb_bin, 0755); + err = trie_store(trie, hwdb_bin); if (err < 0) { - log_error("Failure writing database %s: %s", - udev_hwdb_path, strerror(-err)); + log_error("Failure writing database %s: %s", hwdb_bin, strerror(-err)); rc = EXIT_FAILURE; } } diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c index a5872efbc3..87225a8fec 100644 --- a/src/udev/udevadm-info.c +++ b/src/udev/udevadm-info.c @@ -30,6 +30,8 @@ #include <sys/types.h> #include "udev.h" +#include "udev-util.h" +#include "util.h" static bool skip_attribute(const char *name) { @@ -296,49 +298,50 @@ static struct udev_device *find_device(struct udev *udev, const char *id, const static int uinfo(struct udev *udev, int argc, char *argv[]) { - struct udev_device *device = NULL; + _cleanup_udev_device_unref_ struct udev_device *device = NULL; bool root = 0; bool export = 0; const char *export_prefix = NULL; char name[UTIL_PATH_SIZE]; struct udev_list_entry *list_entry; - int rc = 0; + int c; static const struct option options[] = { - { "name", required_argument, NULL, 'n' }, - { "path", required_argument, NULL, 'p' }, - { "query", required_argument, NULL, 'q' }, - { "attribute-walk", no_argument, NULL, 'a' }, - { "cleanup-db", no_argument, NULL, 'c' }, - { "export-db", no_argument, NULL, 'e' }, - { "root", no_argument, NULL, 'r' }, + { "name", required_argument, NULL, 'n' }, + { "path", required_argument, NULL, 'p' }, + { "query", required_argument, NULL, 'q' }, + { "attribute-walk", no_argument, NULL, 'a' }, + { "cleanup-db", no_argument, NULL, 'c' }, + { "export-db", no_argument, NULL, 'e' }, + { "root", no_argument, NULL, 'r' }, { "device-id-of-file", required_argument, NULL, 'd' }, - { "export", no_argument, NULL, 'x' }, - { "export-prefix", required_argument, NULL, 'P' }, - { "version", no_argument, NULL, 'V' }, - { "help", no_argument, NULL, 'h' }, + { "export", no_argument, NULL, 'x' }, + { "export-prefix", required_argument, NULL, 'P' }, + { "version", no_argument, NULL, 'V' }, + { "help", no_argument, NULL, 'h' }, {} }; static const char *usage = - "Usage: udevadm info OPTIONS\n" - " --query=<type> query device information:\n" + "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" - " --path=<syspath> sys device path used for query or attribute walk\n" - " --name=<name> node or symlink name used for query or attribute walk\n" - " --root prepend dev directory to path names\n" - " --attribute-walk print all key matches while walking along the chain\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" - " --device-id-of-file=<file> print major:minor of device containing this file\n" - " --export export key/value pairs\n" - " --export-prefix export the key name with a prefix\n" - " --export-db export the content of the udev database\n" - " --cleanup-db cleanup the udev database\n" - " --help\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, @@ -354,59 +357,48 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) QUERY_ALL, } query = QUERY_ALL; - for (;;) { - int option; - - option = getopt_long(argc, argv, "aced:n:p:q:rxP:RVh", options, NULL); - if (option == -1) - break; - - switch (option) { + while ((c = getopt_long(argc, argv, "aced:n:p:q:rxP:RVh", options, NULL)) >= 0) + switch (c) { case 'n': { if (device != NULL) { fprintf(stderr, "device already specified\n"); - rc = 2; - goto exit; + return 2; } device = find_device(udev, optarg, "/dev/"); if (device == NULL) { fprintf(stderr, "device node not found\n"); - rc = 2; - goto exit; + return 2; } break; } case 'p': if (device != NULL) { fprintf(stderr, "device already specified\n"); - rc = 2; - goto exit; + return 2; } device = find_device(udev, optarg, "/sys"); if (device == NULL) { fprintf(stderr, "syspath not found\n"); - rc = 2; - goto exit; + return 2; } break; case 'q': action = ACTION_QUERY; - if (streq(optarg, "property") || streq(optarg, "env")) { + if (streq(optarg, "property") || streq(optarg, "env")) query = QUERY_PROPERTY; - } else if (streq(optarg, "name")) { + else if (streq(optarg, "name")) query = QUERY_NAME; - } else if (streq(optarg, "symlink")) { + else if (streq(optarg, "symlink")) query = QUERY_SYMLINK; - } else if (streq(optarg, "path")) { + else if (streq(optarg, "path")) query = QUERY_PATH; - } else if (streq(optarg, "all")) { + else if (streq(optarg, "all")) query = QUERY_ALL; - } else { + else { fprintf(stderr, "unknown query type\n"); - rc = 3; - goto exit; + return 3; } break; case 'r': @@ -421,10 +413,10 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) break; case 'e': export_devices(udev); - goto exit; + return 0; case 'c': cleanup_db(udev); - goto exit; + return 0; case 'x': export = true; break; @@ -433,29 +425,25 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) break; case 'V': printf("%s\n", UDEV_VERSION); - goto exit; + return 0; case 'h': printf("%s\n", usage); - goto exit; + return 0; default: - rc = 1; - goto exit; + return 1; } - } switch (action) { case ACTION_QUERY: if (!device) { if (!argv[optind]) { fprintf(stderr, "%s\n", usage); - rc = 2; - goto exit; + return 2; } device = find_device(udev, argv[optind], NULL); if (!device) { fprintf(stderr, "Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected.\n"); - rc = 4; - goto exit; + return 4; } } @@ -465,8 +453,7 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) if (node == NULL) { fprintf(stderr, "no device node found\n"); - rc = 5; - goto exit; + return 5; } if (root) @@ -490,7 +477,7 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) break; case QUERY_PATH: printf("%s\n", udev_device_get_devpath(device)); - goto exit; + return 0; case QUERY_PROPERTY: list_entry = udev_device_get_properties_list_entry(device); while (list_entry != NULL) { @@ -521,26 +508,22 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) device = find_device(udev, argv[optind], NULL); if (!device) { fprintf(stderr, "Unknown device, absolute path in /dev/ or /sys expected.\n"); - rc = 4; - goto exit; + return 4; } } if (!device) { fprintf(stderr, "Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected.\n"); - rc = 4; - goto exit; + return 4; } print_device_chain(device); break; case ACTION_DEVICE_ID_FILE: if (stat_device(name, export, export_prefix) != 0) - rc = 1; + return 1; break; } -exit: - udev_device_unref(device); - return rc; + return 0; } const struct udevadm_cmd udevadm_info = { diff --git a/src/udev/udevadm-monitor.c b/src/udev/udevadm-monitor.c index a390ee6c34..6022e8db82 100644 --- a/src/udev/udevadm-monitor.c +++ b/src/udev/udevadm-monitor.c @@ -33,6 +33,7 @@ #include <linux/netlink.h> #include "udev.h" +#include "udev-util.h" static bool udev_exit; @@ -64,43 +65,48 @@ 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"); +} + static int adm_monitor(struct udev *udev, int argc, char *argv[]) { - struct sigaction act; + struct sigaction act = {}; sigset_t mask; - int option; bool prop = false; bool print_kernel = false; bool print_udev = false; - struct udev_list subsystem_match_list; - struct udev_list tag_match_list; - struct udev_monitor *udev_monitor = NULL; - struct udev_monitor *kernel_monitor = NULL; - int fd_ep = -1; + _cleanup_udev_list_cleanup_ struct udev_list subsystem_match_list; + _cleanup_udev_list_cleanup_ struct udev_list tag_match_list; + _cleanup_udev_monitor_unref_ struct udev_monitor *udev_monitor = NULL; + _cleanup_udev_monitor_unref_ struct udev_monitor *kernel_monitor = NULL; + _cleanup_close_ int fd_ep = -1; int fd_kernel = -1, fd_udev = -1; struct epoll_event ep_kernel, ep_udev; - int rc = 0; + int c; static const struct option options[] = { - { "property", no_argument, NULL, 'p' }, - { "environment", no_argument, NULL, 'e' }, - { "kernel", no_argument, NULL, 'k' }, - { "udev", no_argument, NULL, 'u' }, + { "property", no_argument, NULL, 'p' }, + { "environment", no_argument, NULL, 'e' }, /* alias for -p */ + { "kernel", no_argument, NULL, 'k' }, + { "udev", no_argument, NULL, 'u' }, { "subsystem-match", required_argument, NULL, 's' }, - { "tag-match", required_argument, NULL, 't' }, - { "help", no_argument, NULL, 'h' }, + { "tag-match", required_argument, NULL, 't' }, + { "help", no_argument, NULL, 'h' }, {} }; udev_list_init(udev, &subsystem_match_list, true); udev_list_init(udev, &tag_match_list, true); - for (;;) { - option = getopt_long(argc, argv, "pekus:t:h", options, NULL); - if (option == -1) - break; - - switch (option) { + while((c = getopt_long(argc, argv, "pekus:t:h", options, NULL)) >= 0) + switch (c) { case 'p': case 'e': prop = true; @@ -129,19 +135,11 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) udev_list_entry_add(&tag_match_list, optarg, NULL); break; case 'h': - printf("Usage: udevadm monitor [--property] [--kernel] [--udev] [--help]\n" - " --property print the event properties\n" - " --kernel print kernel uevents\n" - " --udev print udev events\n" - " --subsystem-match=<subsystem[/devtype]> filter events by subsystem\n" - " --tag-match=<tag> filter events by tag\n" - " --help\n\n"); - goto out; + help(); + return 0; default: - rc = 1; - goto out; + return 1; } - } if (!print_kernel && !print_udev) { print_kernel = true; @@ -149,9 +147,7 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) } /* set signal handlers */ - memset(&act, 0x00, sizeof(struct sigaction)); act.sa_handler = sig_handler; - sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART; sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); @@ -162,8 +158,8 @@ 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\n"); - goto out; + log_error("error creating epoll fd: %m"); + return 1; } printf("monitor will print the received events for:\n"); @@ -173,8 +169,7 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) udev_monitor = udev_monitor_new_from_netlink(udev, "udev"); if (udev_monitor == NULL) { fprintf(stderr, "error: unable to create netlink socket\n"); - rc = 1; - goto out; + return 1; } udev_monitor_set_receive_buffer_size(udev_monitor, 128*1024*1024); fd_udev = udev_monitor_get_fd(udev_monitor); @@ -196,16 +191,15 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) if (udev_monitor_enable_receiving(udev_monitor) < 0) { fprintf(stderr, "error: unable to subscribe to udev events\n"); - rc = 2; - goto out; + return 2; } memset(&ep_udev, 0, sizeof(struct epoll_event)); 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\n"); - goto out; + log_error("fail to add fd to epoll: %m"); + return 2; } printf("UDEV - the event which udev sends out after rule processing\n"); @@ -217,8 +211,7 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) kernel_monitor = udev_monitor_new_from_netlink(udev, "kernel"); if (kernel_monitor == NULL) { fprintf(stderr, "error: unable to create netlink socket\n"); - rc = 3; - goto out; + return 3; } udev_monitor_set_receive_buffer_size(kernel_monitor, 128*1024*1024); fd_kernel = udev_monitor_get_fd(kernel_monitor); @@ -232,16 +225,15 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) if (udev_monitor_enable_receiving(kernel_monitor) < 0) { fprintf(stderr, "error: unable to subscribe to kernel events\n"); - rc = 4; - goto out; + return 4; } memset(&ep_kernel, 0, sizeof(struct epoll_event)); 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\n"); - goto out; + log_error("fail to add fd to epoll: %m"); + return 5; } printf("KERNEL - the kernel uevent\n"); @@ -280,14 +272,8 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) } } } -out: - if (fd_ep >= 0) - close(fd_ep); - udev_monitor_unref(udev_monitor); - udev_monitor_unref(kernel_monitor); - udev_list_cleanup(&subsystem_match_list); - udev_list_cleanup(&tag_match_list); - return rc; + + return 0; } const struct udevadm_cmd udevadm_monitor = { diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c index ed4128a2b2..5b879d8926 100644 --- a/src/udev/udevadm-settle.c +++ b/src/udev/udevadm-settle.c @@ -35,16 +35,28 @@ #include <sys/types.h> #include "udev.h" +#include "udev-util.h" +#include "util.h" + +static void help(void) { + printf("Usage: udevadm settle OPTIONS\n" + " -t,--timeout=<seconds> maximum time to wait for events\n" + " -s,--seq-start=<seqnum> first seqnum to wait for\n" + " -e,--seq-end=<seqnum> last seqnum to wait for\n" + " -E,--exit-if-exists=<file> stop waiting if file exists\n" + " -q,--quiet do not print list after timeout\n" + " -h,--help\n\n"); +} static int adm_settle(struct udev *udev, int argc, char *argv[]) { static const struct option options[] = { - { "seq-start", required_argument, NULL, 's' }, - { "seq-end", required_argument, NULL, 'e' }, - { "timeout", required_argument, NULL, 't' }, + { "seq-start", required_argument, NULL, 's' }, + { "seq-end", required_argument, NULL, 'e' }, + { "timeout", required_argument, NULL, 't' }, { "exit-if-exists", required_argument, NULL, 'E' }, - { "quiet", no_argument, NULL, 'q' }, - { "help", no_argument, NULL, 'h' }, + { "quiet", no_argument, NULL, 'q' }, + { "help", no_argument, NULL, 'h' }, {} }; usec_t start_usec = now(CLOCK_MONOTONIC); @@ -54,49 +66,46 @@ static int adm_settle(struct udev *udev, int argc, char *argv[]) const char *exists = NULL; unsigned int timeout = 120; struct pollfd pfd[1] = { {.fd = -1}, }; - struct udev_queue *udev_queue = NULL; - int rc = EXIT_FAILURE; - - for (;;) { - int option; - int seconds; - - option = getopt_long(argc, argv, "s:e:t:E:qh", options, NULL); - if (option == -1) - break; + _cleanup_udev_queue_unref_ struct udev_queue *udev_queue = NULL; + int rc = EXIT_FAILURE, c; - switch (option) { + while ((c = getopt_long(argc, argv, "s:e:t:E:qh", options, NULL)) >= 0) + switch (c) { case 's': start = strtoull(optarg, NULL, 0); break; case 'e': end = strtoull(optarg, NULL, 0); break; - case 't': - seconds = atoi(optarg); - if (seconds >= 0) - timeout = seconds; - else - fprintf(stderr, "invalid timeout value\n"); - break; - case 'q': - quiet = 1; + case 't': { + int r; + + r = safe_atou(optarg, &timeout); + if (r < 0) { + fprintf(stderr, "Invalid timeout value '%s': %s\n", + optarg, strerror(-r)); + exit(EXIT_FAILURE); + }; break; + } case 'E': exists = optarg; break; + case 'q': + quiet = 1; + break; case 'h': - printf("Usage: udevadm settle OPTIONS\n" - " --timeout=<seconds> maximum time to wait for events\n" - " --seq-start=<seqnum> first seqnum to wait for\n" - " --seq-end=<seqnum> last seqnum to wait for\n" - " --exit-if-exists=<file> stop waiting if file exists\n" - " --quiet do not print list after timeout\n" - " --help\n\n"); + help(); exit(EXIT_SUCCESS); - default: + case '?': exit(EXIT_FAILURE); + default: + assert_not_reached("Unkown argument"); } + + if (optind < argc) { + fprintf(stderr, "Extraneous argument: '%s'\n", argv[optind]); + exit(EXIT_FAILURE); } udev_queue = udev_queue_new(udev); @@ -113,20 +122,20 @@ static int adm_settle(struct udev *udev, int argc, char *argv[]) end = udev_queue_get_kernel_seqnum(udev_queue); if (start > end) { - log_error("seq-start larger than seq-end, ignoring\n"); + log_error("seq-start larger than seq-end, ignoring"); start = 0; end = 0; } if (start > kernel_seq || end > kernel_seq) { - log_error("seq-start or seq-end larger than current kernel value, ignoring\n"); + log_error("seq-start or seq-end larger than current kernel value, ignoring"); start = 0; end = 0; } - log_debug("start=%llu end=%llu current=%llu\n", (unsigned long long)start, (unsigned long long)end, kernel_seq); + log_debug("start=%llu end=%llu current=%llu", (unsigned long long)start, (unsigned long long)end, kernel_seq); } else { if (end > 0) { - log_error("seq-end needs seq-start parameter, ignoring\n"); + log_error("seq-end needs seq-start parameter, ignoring"); end = 0; } } @@ -138,7 +147,7 @@ static int adm_settle(struct udev *udev, int argc, char *argv[]) uctrl = udev_ctrl_new(udev); if (uctrl != NULL) { if (udev_ctrl_send_ping(uctrl, timeout) < 0) { - log_debug("no connection to daemon\n"); + log_debug("no connection to daemon"); udev_ctrl_unref(uctrl); rc = EXIT_SUCCESS; goto out; @@ -150,10 +159,10 @@ static int adm_settle(struct udev *udev, int argc, char *argv[]) pfd[0].events = POLLIN; pfd[0].fd = inotify_init1(IN_CLOEXEC); if (pfd[0].fd < 0) { - log_error("inotify_init failed: %m\n"); + log_error("inotify_init failed: %m"); } else { if (inotify_add_watch(pfd[0].fd, "/run/udev" , IN_MOVED_TO) < 0) { - log_error("watching /run/udev failed\n"); + log_error("watching /run/udev failed"); close(pfd[0].fd); pfd[0].fd = -1; } @@ -192,8 +201,7 @@ static int adm_settle(struct udev *udev, int argc, char *argv[]) if (poll(pfd, 1, delay) > 0 && pfd[0].revents & POLLIN) { char buf[sizeof(struct inotify_event) + PATH_MAX]; - if (read(pfd[0].fd, buf, sizeof(buf)) == -1) - log_error("Failed to read buf in %s\n", "[udevadm-settle:adm_settle]"); + read(pfd[0].fd, buf, sizeof(buf)); } } else { sleep(1); @@ -207,7 +215,7 @@ static int adm_settle(struct udev *udev, int argc, char *argv[]) struct udev_list_entry *list_entry; if (!quiet && udev_queue_get_queued_list_entry(udev_queue) != NULL) { - log_debug("timeout waiting for udev queue\n"); + log_debug("timeout waiting for udev queue"); printf("\nudevadm settle - timeout of %i seconds reached, the event queue contains:\n", timeout); udev_list_entry_foreach(list_entry, udev_queue_get_queued_list_entry(udev_queue)) printf(" %s (%s)\n", @@ -222,7 +230,6 @@ static int adm_settle(struct udev *udev, int argc, char *argv[]) out: if (pfd[0].fd >= 0) close(pfd[0].fd); - udev_queue_unref(udev_queue); return rc; } diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c index a02efe5ac3..7d68722569 100644 --- a/src/udev/udevadm-test-builtin.c +++ b/src/udev/udevadm-test-builtin.c @@ -37,7 +37,7 @@ static void help(struct udev *udev) { fprintf(stderr, "\n"); - fprintf(stderr, "Usage: udevadm builtin [--help] <command> <syspath>\n"); + fprintf(stderr, "Usage: udevadm builtin [--help] COMMAND SYSPATH\n"); udev_builtin_list(udev); fprintf(stderr, "\n"); } @@ -53,21 +53,14 @@ static int adm_builtin(struct udev *udev, int argc, char *argv[]) char filename[UTIL_PATH_SIZE]; struct udev_device *dev = NULL; enum udev_builtin_cmd cmd; - int rc = EXIT_SUCCESS; + int rc = EXIT_SUCCESS, c; - for (;;) { - int option; - - option = getopt_long(argc, argv, "h", options, NULL); - if (option == -1) - break; - - switch (option) { + while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) + switch (c) { case 'h': help(udev); goto out; } - } command = argv[optind++]; if (command == NULL) { @@ -79,7 +72,7 @@ static int adm_builtin(struct udev *udev, int argc, char *argv[]) syspath = argv[optind++]; if (syspath == NULL) { - fprintf(stderr, "syspath missing\n\n"); + fprintf(stderr, "syspath missing\n"); rc = 3; goto out; } diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c index df1409bff6..6cd311b27d 100644 --- a/src/udev/udevadm-test.c +++ b/src/udev/udevadm-test.c @@ -30,6 +30,7 @@ #include <sys/signalfd.h> #include "udev.h" +#include "udev-util.h" static int adm_test(struct udev *udev, int argc, char *argv[]) { @@ -37,13 +38,13 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) char filename[UTIL_PATH_SIZE]; const char *action = "add"; const char *syspath = NULL; - struct udev_event *event = NULL; - struct udev_device *dev = NULL; - struct udev_rules *rules = NULL; struct udev_list_entry *entry; + _cleanup_udev_rules_unref_ struct udev_rules *rules = NULL; + _cleanup_udev_device_unref_ struct udev_device *dev = NULL; + _cleanup_udev_event_unref_ struct udev_event *event = NULL; sigset_t mask, sigmask_orig; int err; - int rc = 0; + int rc = 0, c; static const struct option options[] = { { "action", required_argument, NULL, 'a' }, @@ -52,16 +53,10 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) {} }; - log_debug("version %s\n", VERSION); + log_debug("version %s", VERSION); - for (;;) { - int option; - - option = getopt_long(argc, argv, "a:s:N:fh", options, NULL); - if (option == -1) - break; - - switch (option) { + while((c = getopt_long(argc, argv, "a:N:h", options, NULL)) >= 0) + switch (c) { case 'a': action = optarg; break; @@ -74,21 +69,24 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) resolve_names = -1; } else { fprintf(stderr, "resolve-names must be early, late or never\n"); - log_error("resolve-names must be early, late or never\n"); + log_error("resolve-names must be early, late or never"); exit(EXIT_FAILURE); } break; case 'h': printf("Usage: udevadm test OPTIONS <syspath>\n" - " --action=<string> set action string\n" - " --help\n\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"); exit(EXIT_SUCCESS); - default: + case '?': exit(EXIT_FAILURE); + default: + assert_not_reached("Unknown option"); } - } - syspath = argv[optind]; + syspath = argv[optind]; if (syspath == NULL) { fprintf(stderr, "syspath parameter missing\n"); rc = 2; @@ -157,9 +155,6 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) out: if (event != NULL && event->fd_signal >= 0) close(event->fd_signal); - udev_event_unref(event); - udev_device_unref(dev); - udev_rules_unref(rules); udev_builtin_exit(udev); return rc; } diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c index f472996965..087ee4bfae 100644 --- a/src/udev/udevadm-trigger.c +++ b/src/udev/udevadm-trigger.c @@ -32,6 +32,8 @@ #include <sys/un.h> #include "udev.h" +#include "udev-util.h" +#include "util.h" static int verbose; static int dry_run; @@ -53,7 +55,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\n", action, filename); + log_debug("error writing '%s' to '%s': %m", action, filename); close(fd); } } @@ -72,22 +74,41 @@ static const char *keyval(const char *str, const char **val, char *buf, size_t s return buf; } +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"); +} + static int adm_trigger(struct udev *udev, int argc, char *argv[]) { 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' }, + { "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' }, + { "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' }, {} }; enum { @@ -95,26 +116,19 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) TYPE_SUBSYSTEMS, } device_type = TYPE_DEVICES; const char *action = "change"; - struct udev_enumerate *udev_enumerate; - int rc = 0; + _cleanup_udev_enumerate_unref_ struct udev_enumerate *udev_enumerate = NULL; + int c; udev_enumerate = udev_enumerate_new(udev); - if (udev_enumerate == NULL) { - rc = 1; - goto exit; - } + if (udev_enumerate == NULL) + return 1; - for (;;) { - int option; + while ((c = getopt_long(argc, argv, "vno:t:c:s:S:a:A:p:g:y:b:h", options, NULL)) >= 0) { const char *key; const char *val; char buf[UTIL_PATH_SIZE]; - option = getopt_long(argc, argv, "vng:o:t:hc:p:s:S:a:A:y:b:", options, NULL); - if (option == -1) - break; - - switch (option) { + switch (c) { case 'v': verbose = 1; break; @@ -122,18 +136,22 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) dry_run = 1; break; case 't': - if (streq(optarg, "devices")) { + if (streq(optarg, "devices")) device_type = TYPE_DEVICES; - } else if (streq(optarg, "subsystems")) { + else if (streq(optarg, "subsystems")) device_type = TYPE_SUBSYSTEMS; - } else { - log_error("unknown type --type=%s\n", optarg); - rc = 2; - goto exit; + else { + log_error("unknown type --type=%s", optarg); + return 2; } break; case 'c': - action = optarg; + if (!nulstr_contains("add\0" "remove\0" "change\0", optarg)) { + log_error("unknown action '%s'", optarg); + return 2; + } else + action = optarg; + break; case 's': udev_enumerate_add_match_subsystem(udev_enumerate, optarg); @@ -171,9 +189,8 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) util_remove_trailing_chars(path, '/'); dev = udev_device_new_from_syspath(udev, path); if (dev == NULL) { - log_error("unable to open the device '%s'\n", optarg); - rc = 2; - goto exit; + 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 */ @@ -181,44 +198,32 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) break; } case 'h': - printf("Usage: udevadm trigger OPTIONS\n" - " --verbose print the list of devices while running\n" - " --dry-run do not actually trigger the events\n" - " --type= type of events to trigger\n" - " devices sys devices (default)\n" - " subsystems sys subsystems and drivers\n" - " --action=<action> event action value, default is \"change\"\n" - " --subsystem-match=<subsystem> trigger devices from a matching subsystem\n" - " --subsystem-nomatch=<subsystem> exclude devices from a matching subsystem\n" - " --attr-match=<file[=<value>]> trigger devices with a matching attribute\n" - " --attr-nomatch=<file[=<value>]> exclude devices with a matching attribute\n" - " --property-match=<key>=<value> trigger devices with a matching property\n" - " --tag-match=<key>=<value> trigger devices with a matching property\n" - " --sysname-match=<name> trigger devices with a matching name\n" - " --parent-match=<name> trigger devices with that parent device\n" - " --help\n\n"); - goto exit; + help(); + return 0; + case '?': + return 1; default: - rc = 1; - goto exit; + assert_not_reached("Unknown option"); } } + if (optind < argc) { + fprintf(stderr, "Extraneous argument: '%s'\n", argv[optind]); + return 1; + } + switch (device_type) { case TYPE_SUBSYSTEMS: udev_enumerate_scan_subsystems(udev_enumerate); exec_list(udev_enumerate, action); - goto exit; + return 0; case TYPE_DEVICES: udev_enumerate_scan_devices(udev_enumerate); exec_list(udev_enumerate, action); - goto exit; + return 0; default: assert_not_reached("device_type"); } -exit: - udev_enumerate_unref(udev_enumerate); - return rc; } const struct udevadm_cmd udevadm_trigger = { diff --git a/src/udev/udevd.c b/src/udev/udevd.c index b769be7451..224763eaa5 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -48,6 +48,7 @@ #include "def.h" #include "cgroup-util.h" #include "dev-setup.h" +#include "fileio.h" static bool debug; @@ -144,7 +145,7 @@ static void event_queue_delete(struct event *event, bool export) if (export) { udev_queue_export_device_finished(udev_queue_export, event->dev); - log_debug("seq %llu done with %i\n", udev_device_get_seqnum(event->dev), event->exitcode); + log_debug("seq %llu done with %i", udev_device_get_seqnum(event->dev), event->exitcode); } udev_device_unref(event->dev); free(event); @@ -169,7 +170,7 @@ static void worker_unref(struct worker *worker) worker->refcount--; if (worker->refcount > 0) return; - log_debug("worker [%u] cleaned up\n", worker->pid); + log_debug("worker [%u] cleaned up", worker->pid); worker_cleanup(worker); } @@ -234,14 +235,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\n"); + log_error("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\n"); + log_error("error creating epoll fd: %m"); rc = 3; goto out; } @@ -257,7 +258,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\n"); + log_error("fail to add fds to epoll: %m"); rc = 4; goto out; } @@ -266,14 +267,14 @@ static void worker_new(struct event *event) prctl(PR_SET_PDEATHSIG, SIGTERM); /* reset OOM score, we only protect the main daemon */ - write_one_line_file("/proc/self/oom_score_adj", "0"); + write_string_file("/proc/self/oom_score_adj", "0"); for (;;) { struct udev_event *udev_event; struct worker_message msg; int err; - log_debug("seq %llu running\n", udev_device_get_seqnum(dev)); + log_debug("seq %llu running", udev_device_get_seqnum(dev)); udev_event = udev_event_new(dev); if (udev_event == NULL) { rc = 5; @@ -308,7 +309,7 @@ static void worker_new(struct event *event) msg.pid = getpid(); send(worker_watch[WRITE_END], &msg, sizeof(struct worker_message), 0); - log_debug("seq %llu processed with %i\n", udev_device_get_seqnum(dev), err); + log_debug("seq %llu processed with %i", udev_device_get_seqnum(dev), err); udev_device_unref(dev); dev = NULL; @@ -330,7 +331,7 @@ static void worker_new(struct event *event) if (fdcount < 0) { if (errno == EINTR) continue; - log_error("failed to poll: %m\n"); + log_error("failed to poll: %m"); goto out; } @@ -372,7 +373,7 @@ out: udev_monitor_unref(worker_monitor); event->state = EVENT_QUEUED; free(worker); - log_error("fork of child failed: %m\n"); + log_error("fork of child failed: %m"); break; default: /* close monitor, but keep address around */ @@ -385,7 +386,7 @@ out: event->state = EVENT_RUNNING; udev_list_node_append(&worker->node, &worker_list); children++; - log_debug("seq %llu forked new worker [%u]\n", udev_device_get_seqnum(event->dev), pid); + log_debug("seq %llu forked new worker [%u]", udev_device_get_seqnum(event->dev), pid); break; } } @@ -403,7 +404,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\n", worker->pid, count); + log_error("worker [%u] did not accept message %zi (%m), kill it", worker->pid, count); kill(worker->pid, SIGKILL); worker->state = WORKER_KILLED; continue; @@ -418,7 +419,7 @@ static void event_run(struct event *event) if (children >= children_max) { if (children_max > 1) - log_debug("maximum number (%i) of children reached\n", children); + log_debug("maximum number (%i) of children reached", children); return; } @@ -449,7 +450,7 @@ static int event_queue_insert(struct udev_device *dev) #endif udev_queue_export_device_queued(udev_queue_export, dev); - log_debug("seq %llu queued, '%s' '%s'\n", udev_device_get_seqnum(dev), + log_debug("seq %llu queued, '%s' '%s'", udev_device_get_seqnum(dev), udev_device_get_action(dev), udev_device_get_subsystem(dev)); event->state = EVENT_QUEUED; @@ -634,24 +635,24 @@ static struct udev_ctrl_connection *handle_ctrl_msg(struct udev_ctrl *uctrl) i = udev_ctrl_get_set_log_level(ctrl_msg); if (i >= 0) { - log_debug("udevd message (SET_LOG_PRIORITY) received, log_priority=%i\n", i); + 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); } if (udev_ctrl_get_stop_exec_queue(ctrl_msg) > 0) { - log_debug("udevd message (STOP_EXEC_QUEUE) received\n"); + log_debug("udevd message (STOP_EXEC_QUEUE) received"); stop_exec_queue = true; } if (udev_ctrl_get_start_exec_queue(ctrl_msg) > 0) { - log_debug("udevd message (START_EXEC_QUEUE) received\n"); + log_debug("udevd message (START_EXEC_QUEUE) received"); stop_exec_queue = false; } if (udev_ctrl_get_reload(ctrl_msg) > 0) { - log_debug("udevd message (RELOAD) received\n"); + log_debug("udevd message (RELOAD) received"); reload = true; } @@ -668,14 +669,14 @@ static struct udev_ctrl_connection *handle_ctrl_msg(struct udev_ctrl *uctrl) val[0] = '\0'; val = &val[1]; if (val[0] == '\0') { - log_debug("udevd message (ENV) received, unset '%s'\n", key); + log_debug("udevd message (ENV) received, unset '%s'", key); udev_add_property(udev, key, NULL); } else { - log_debug("udevd message (ENV) received, set '%s=%s'\n", key, val); + log_debug("udevd message (ENV) received, set '%s=%s'", key, val); udev_add_property(udev, key, val); } } else { - log_error("wrong key format '%s'\n", key); + log_error("wrong key format '%s'", key); } free(key); } @@ -684,15 +685,15 @@ static struct udev_ctrl_connection *handle_ctrl_msg(struct udev_ctrl *uctrl) i = udev_ctrl_get_set_children_max(ctrl_msg); if (i >= 0) { - log_debug("udevd message (SET_MAX_CHILDREN) received, children_max=%i\n", i); + log_debug("udevd message (SET_MAX_CHILDREN) received, children_max=%i", i); children_max = i; } if (udev_ctrl_get_ping(ctrl_msg) > 0) - log_debug("udevd message (SYNC) received\n"); + log_debug("udevd message (SYNC) received"); if (udev_ctrl_get_exit(ctrl_msg) > 0) { - log_debug("udevd message (EXIT) received\n"); + log_debug("udevd message (EXIT) received"); udev_exit = true; /* keep reference to block the client until we exit */ udev_ctrl_connection_ref(ctrl_conn); @@ -714,7 +715,7 @@ static int handle_inotify(struct udev *udev) buf = malloc(nbytes); if (buf == NULL) { - log_error("error getting buffer for inotify\n"); + log_error("error getting buffer for inotify"); return -1; } @@ -726,17 +727,17 @@ static int handle_inotify(struct udev *udev) ev = (struct inotify_event *)(buf + pos); dev = udev_watch_lookup(udev, ev->wd); if (dev != NULL) { - log_debug("inotify event: %x for %s\n", ev->mask, udev_device_get_devnode(dev)); + log_debug("inotify event: %x for %s", ev->mask, udev_device_get_devnode(dev)); if (ev->mask & IN_CLOSE_WRITE) { char filename[UTIL_PATH_SIZE]; int fd; - log_debug("device %s closed, synthesising 'change'\n", udev_device_get_devnode(dev)); + log_debug("device %s closed, synthesising 'change'", udev_device_get_devnode(dev)); strscpyl(filename, sizeof(filename), udev_device_get_syspath(dev), "/uevent", NULL); fd = open(filename, O_WRONLY); if (fd >= 0) { if (write(fd, "change", 6) < 0) - log_debug("error writing uevent: %m\n"); + log_debug("error writing uevent: %m"); close(fd); } } @@ -774,26 +775,26 @@ static void handle_signal(struct udev *udev, int signo) if (worker->pid != pid) continue; - log_debug("worker [%u] exit\n", pid); + log_debug("worker [%u] exit", pid); if (WIFEXITED(status)) { if (WEXITSTATUS(status) != 0) - log_error("worker [%u] exit with return code %i\n", + log_error("worker [%u] exit with return code %i", pid, WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { - log_error("worker [%u] terminated by signal %i (%s)\n", + log_error("worker [%u] terminated by signal %i (%s)", pid, WTERMSIG(status), strsignal(WTERMSIG(status))); } else if (WIFSTOPPED(status)) { - log_error("worker [%u] stopped\n", pid); + log_error("worker [%u] stopped", pid); } else if (WIFCONTINUED(status)) { - log_error("worker [%u] continued\n", pid); + log_error("worker [%u] continued", pid); } else { - log_error("worker [%u] exit with status 0x%04x\n", pid, status); + log_error("worker [%u] exit with status 0x%04x", pid, status); } if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { if (worker->event) { - log_error("worker [%u] failed while handling '%s'\n", + log_error("worker [%u] failed while handling '%s'", pid, worker->event->devpath); worker->event->exitcode = -32; event_queue_delete(worker->event, true); @@ -891,10 +892,15 @@ static void static_dev_create_from_modules(struct udev *udev) */ static void kernel_cmdline_options(struct udev *udev) { - char *line, *w, *state; + _cleanup_free_ char *line = NULL; + char *w, *state; size_t l; + int r; - if (read_one_line_file("/proc/cmdline", &line) < 0) + r = proc_cmdline(&line); + if (r < 0) + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + if (r <= 0) return; FOREACH_WORD_QUOTED(w, l, line, state) { @@ -924,8 +930,6 @@ static void kernel_cmdline_options(struct udev *udev) free(s); } - - free(line); } int main(int argc, char *argv[]) @@ -961,7 +965,7 @@ int main(int argc, char *argv[]) udev_set_log_fn(udev, udev_main_log); log_set_max_level(udev_get_log_priority(udev)); - log_debug("version %s\n", VERSION); + log_debug("version %s", VERSION); label_init("/dev"); for (;;) { @@ -995,7 +999,7 @@ int main(int argc, char *argv[]) resolve_names = -1; } else { fprintf(stderr, "resolve-names must be early, late or never\n"); - log_error("resolve-names must be early, late or never\n"); + log_error("resolve-names must be early, late or never"); goto exit; } break; @@ -1022,16 +1026,12 @@ int main(int argc, char *argv[]) if (getuid() != 0) { fprintf(stderr, "root privileges required\n"); - log_error("root privileges required\n"); + log_error("root privileges required"); goto exit; } /* set umask before creating any file/directory */ - if (chdir("/") == -1) { - fprintf(stderr, "Cannot chdir to /\n"); - log_error("Cannot chdir to /\n"); - goto exit; - } + chdir("/"); umask(022); mkdir("/run/udev", 0755); @@ -1053,7 +1053,7 @@ int main(int argc, char *argv[]) close(fd); } else { fprintf(stderr, "cannot open /dev/null\n"); - log_error("cannot open /dev/null\n"); + log_error("cannot open /dev/null"); } } @@ -1070,7 +1070,7 @@ int main(int argc, char *argv[]) monitor = udev_monitor_new_from_netlink(udev, "kernel"); if (monitor == NULL) { fprintf(stderr, "error initializing netlink socket\n"); - log_error("error initializing netlink socket\n"); + log_error("error initializing netlink socket"); rc = 3; goto exit; } @@ -1078,14 +1078,14 @@ int main(int argc, char *argv[]) if (udev_monitor_enable_receiving(monitor) < 0) { fprintf(stderr, "error binding netlink socket\n"); - log_error("error binding netlink socket\n"); + log_error("error binding netlink socket"); rc = 3; goto exit; } if (udev_ctrl_enable_receiving(udev_ctrl) < 0) { fprintf(stderr, "error binding udev control socket\n"); - log_error("error binding udev control socket\n"); + log_error("error binding udev control socket"); rc = 1; goto exit; } @@ -1095,7 +1095,7 @@ int main(int argc, char *argv[]) /* create queue file before signalling 'ready', to make sure we block 'settle' */ udev_queue_export = udev_queue_export_new(udev); if (udev_queue_export == NULL) { - log_error("error creating queue file\n"); + log_error("error creating queue file"); goto exit; } @@ -1107,7 +1107,7 @@ int main(int argc, char *argv[]) case 0: break; case -1: - log_error("fork of daemon failed: %m\n"); + log_error("fork of daemon failed: %m"); rc = 4; goto exit; default: @@ -1117,7 +1117,7 @@ int main(int argc, char *argv[]) setsid(); - write_one_line_file("/proc/self/oom_score_adj", "-1000"); + write_string_file("/proc/self/oom_score_adj", "-1000"); } print_kmsg("starting version " VERSION "\n"); @@ -1137,7 +1137,7 @@ int main(int argc, char *argv[]) fd_inotify = udev_watch_init(udev); if (fd_inotify < 0) { fprintf(stderr, "error initializing inotify\n"); - log_error("error initializing inotify\n"); + log_error("error initializing inotify"); rc = 4; goto exit; } @@ -1161,7 +1161,7 @@ int main(int argc, char *argv[]) fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC); if (fd_signal < 0) { fprintf(stderr, "error creating signalfd\n"); - log_error("error creating signalfd\n"); + log_error("error creating signalfd"); rc = 5; goto exit; } @@ -1169,7 +1169,7 @@ int main(int argc, char *argv[]) /* unnamed socket from workers to the main daemon */ if (socketpair(AF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC, 0, worker_watch) < 0) { fprintf(stderr, "error creating socketpair\n"); - log_error("error creating socketpair\n"); + log_error("error creating socketpair"); rc = 6; goto exit; } @@ -1179,7 +1179,7 @@ int main(int argc, char *argv[]) rules = udev_rules_new(udev, resolve_names); if (rules == NULL) { - log_error("error reading rules\n"); + log_error("error reading rules"); goto exit; } @@ -1205,7 +1205,7 @@ int main(int argc, char *argv[]) fd_ep = epoll_create1(EPOLL_CLOEXEC); if (fd_ep < 0) { - log_error("error creating epoll fd: %m\n"); + log_error("error creating epoll fd: %m"); goto exit; } if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_ctrl, &ep_ctrl) < 0 || @@ -1213,7 +1213,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\n"); + log_error("fail to add fds to epoll: %m"); goto exit; } @@ -1226,11 +1226,11 @@ int main(int argc, char *argv[]) children_max += CPU_COUNT(&cpu_set) * 2; } } - log_debug("set children_max to %u\n", children_max); + log_debug("set children_max to %u", children_max); rc = udev_rules_apply_static_dev_perms(rules); if (rc < 0) - log_error("failed to apply permissions on static device nodes - %s\n", strerror(-rc)); + log_error("failed to apply permissions on static device nodes - %s", strerror(-rc)); udev_list_node_init(&event_list); udev_list_node_init(&worker_list); @@ -1290,13 +1290,13 @@ int main(int argc, char *argv[]) /* timeout */ if (udev_exit) { - log_error("timeout, giving up waiting for workers to finish\n"); + log_error("timeout, giving up waiting for workers to finish"); break; } /* kill idle workers */ if (udev_list_node_is_empty(&event_list)) { - log_debug("cleanup idle workers\n"); + log_debug("cleanup idle workers"); worker_kill(udev); } @@ -1308,14 +1308,14 @@ int main(int argc, char *argv[]) continue; if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > 30 * 1000 * 1000) { - log_error("worker [%u] %s timeout; kill it\n", worker->pid, + log_error("worker [%u] %s timeout; kill it", worker->pid, worker->event ? worker->event->devpath : "<idle>"); kill(worker->pid, SIGKILL); worker->state = WORKER_KILLED; /* drop reference taken for state 'running' */ worker_unref(worker); if (worker && worker->event) { - log_error("seq %llu '%s' killed\n", + log_error("seq %llu '%s' killed", udev_device_get_seqnum(worker->event->dev), worker->event->devpath); worker->event->exitcode = -64; event_queue_delete(worker->event, true); |