From 74df0fca09b3c31ed19e14ba80f996fdff772417 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Nov 2013 03:15:16 +0100 Subject: util: unify reading of /proc/cmdline Instead of individually checking for containers in each user do this once in a new call proc_cmdline() that read the file only if we are not in a container. --- src/backlight/backlight.c | 2 +- src/core/condition.c | 9 +++------ src/core/main.c | 19 ++++++++---------- src/core/shutdown.c | 4 ++-- src/cryptsetup/cryptsetup-generator.c | 18 +++++++++--------- src/fsck/fsck.c | 12 ++++-------- src/fstab-generator/fstab-generator.c | 24 ++++++++++------------- src/journal/journald-server.c | 22 +++++++++------------ src/modules-load/modules-load.c | 12 ++++-------- src/quotacheck/quotacheck.c | 10 +++------- src/rfkill/rfkill.c | 2 +- src/shared/util.c | 36 +++++++++++++++++++++++------------ src/shared/util.h | 4 +++- src/udev/net/link-config.c | 8 ++++---- src/udev/udevd.c | 11 +++++++---- 15 files changed, 92 insertions(+), 101 deletions(-) diff --git a/src/backlight/backlight.c b/src/backlight/backlight.c index 6c00b00d82..9ec29f79a4 100644 --- a/src/backlight/backlight.c +++ b/src/backlight/backlight.c @@ -291,7 +291,7 @@ int main(int argc, char *argv[]) { * device probing should be complete), so that the validity * check at boot time doesn't have to be reliable. */ - if (streq(argv[1], "load") && restore_state()) { + if (streq(argv[1], "load") && shall_restore_state()) { _cleanup_free_ char *value = NULL; if (!validate_device(udev, device)) diff --git a/src/core/condition.c b/src/core/condition.c index c53d406682..436e7840d0 100644 --- a/src/core/condition.c +++ b/src/core/condition.c @@ -86,14 +86,11 @@ static bool test_kernel_command_line(const char *parameter) { assert(parameter); - if (detect_container(NULL) > 0) - return false; - - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { + r = proc_cmdline(&line); + if (r < 0) log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + if (r <= 0) return false; - } equal = !!strchr(parameter, '='); pl = strlen(parameter); diff --git a/src/core/main.c b/src/core/main.c index b21fb493da..b62234ed45 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -691,19 +691,14 @@ static int parse_config_file(void) { static int parse_proc_cmdline(void) { _cleanup_free_ char *line = NULL; char *w, *state; - int r; size_t l; + int r; - /* Don't read /proc/cmdline if we are in a container, since - * that is only relevant for the host system */ - if (detect_container(NULL) > 0) - return 0; - - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { + r = proc_cmdline(&line); + if (r < 0) log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + if (r <= 0) return 0; - } FOREACH_WORD_QUOTED(w, l, line, state) { _cleanup_free_ char *word; @@ -979,11 +974,13 @@ static int parse_argv(int argc, char *argv[]) { * relevant for the container, hence we rely on argv[] * instead. */ - for (a = argv; a < argv + argc; a++) - if ((r = parse_proc_cmdline_word(*a)) < 0) { + for (a = argv; a < argv + argc; a++) { + r = parse_proc_cmdline_word(*a); + if (r < 0) { log_error("Failed on cmdline argument %s: %s", *a, strerror(-r)); return r; } + } } return 0; diff --git a/src/core/shutdown.c b/src/core/shutdown.c index ea02b60456..aa9548e2a4 100644 --- a/src/core/shutdown.c +++ b/src/core/shutdown.c @@ -140,8 +140,8 @@ int main(int argc, char *argv[]) { int cmd, r; /* suppress shutdown status output if 'quiet' is used */ - r = read_one_line_file("/proc/cmdline", &line); - if (r >= 0) { + r = proc_cmdline(&line); + if (r > 0) { char *w, *state; size_t l; diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index e1798a3e82..9c98f0b617 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -27,7 +27,6 @@ #include "util.h" #include "unit-name.h" #include "mkdir.h" -#include "virt.h" #include "strv.h" #include "fileio.h" @@ -241,20 +240,21 @@ static int create_disk( return 0; } -static int parse_proc_cmdline(char ***arg_proc_cmdline_disks, char ***arg_proc_cmdline_options, char **arg_proc_cmdline_keyfile) { +static int parse_proc_cmdline( + char ***arg_proc_cmdline_disks, + char ***arg_proc_cmdline_options, + char **arg_proc_cmdline_keyfile) { + _cleanup_free_ char *line = NULL; char *w = NULL, *state = NULL; - int r; size_t l; + int r; - if (detect_container(NULL) > 0) - return 0; - - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { + r = proc_cmdline(&line); + if (r < 0) log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + if (r <= 0) return 0; - } FOREACH_WORD_QUOTED(w, l, line, state) { _cleanup_free_ char *word = NULL; diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index 10c968678b..9b67ccfc0e 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -35,7 +35,6 @@ #include "bus-util.h" #include "bus-error.h" #include "bus-errors.h" -#include "virt.h" #include "fileio.h" #include "udev-util.h" @@ -75,17 +74,14 @@ static void start_target(const char *target) { static int parse_proc_cmdline(void) { char *line, *w, *state; - int r; size_t l; + int r; - if (detect_container(NULL) > 0) - return 0; - - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { + r = proc_cmdline(&line); + if (r < 0) log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + if (r <= 0) return 0; - } FOREACH_WORD_QUOTED(w, l, line, state) { diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 78d7609c6c..96b0906149 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -32,7 +32,6 @@ #include "mount-setup.h" #include "special.h" #include "mkdir.h" -#include "virt.h" #include "fileio.h" static const char *arg_dest = "/tmp"; @@ -395,16 +394,16 @@ static int parse_fstab(const char *prefix, bool initrd) { static int parse_new_root_from_proc_cmdline(void) { _cleanup_free_ char *what = NULL, *type = NULL, *opts = NULL, *line = NULL; + bool noauto, nofail; char *w, *state; - int r; size_t l; - bool noauto, nofail; + int r; - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { - log_error("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + r = proc_cmdline(&line); + if (r < 0) + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + if (r <= 0) return 0; - } opts = strdup("ro"); type = strdup("auto"); @@ -477,17 +476,14 @@ static int parse_new_root_from_proc_cmdline(void) { static int parse_proc_cmdline(void) { _cleanup_free_ char *line = NULL; char *w, *state; - int r; size_t l; + int r; - if (detect_container(NULL) > 0) - return 0; - - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { + r = proc_cmdline(&line); + if (r < 0) log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + if (r <= 0) return 0; - } FOREACH_WORD_QUOTED(w, l, line, state) { _cleanup_free_ char *word = NULL; diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 518e9ecc4e..ce419d48d8 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -27,10 +27,10 @@ #include #include -#include -#include -#include +#include "sd-journal.h" +#include "sd-messages.h" +#include "sd-daemon.h" #include "fileio.h" #include "mkdir.h" #include "hashmap.h" @@ -38,20 +38,19 @@ #include "socket-util.h" #include "cgroup-util.h" #include "list.h" -#include "virt.h" #include "missing.h" #include "conf-parser.h" +#include "selinux-util.h" #include "journal-internal.h" #include "journal-vacuum.h" #include "journal-authenticate.h" -#include "journald-server.h" #include "journald-rate-limit.h" #include "journald-kmsg.h" #include "journald-syslog.h" #include "journald-stream.h" #include "journald-console.h" #include "journald-native.h" -#include "selinux-util.h" +#include "journald-server.h" #ifdef HAVE_ACL #include @@ -1313,17 +1312,14 @@ static int open_signalfd(Server *s) { static int server_parse_proc_cmdline(Server *s) { _cleanup_free_ char *line = NULL; char *w, *state; - int r; size_t l; + int r; - if (detect_container(NULL) > 0) - return 0; - - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { + r = proc_cmdline(&line); + if (r < 0) log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + if (r <= 0) return 0; - } FOREACH_WORD_QUOTED(w, l, line, state) { _cleanup_free_ char *word; diff --git a/src/modules-load/modules-load.c b/src/modules-load/modules-load.c index 49ee4203dd..7772e3dc2a 100644 --- a/src/modules-load/modules-load.c +++ b/src/modules-load/modules-load.c @@ -33,7 +33,6 @@ #include "util.h" #include "strv.h" #include "conf-files.h" -#include "virt.h" #include "fileio.h" static char **arg_proc_cmdline_modules = NULL; @@ -78,17 +77,14 @@ static int add_modules(const char *p) { static int parse_proc_cmdline(void) { _cleanup_free_ char *line = NULL; char *w, *state; - int r; size_t l; + int r; - if (detect_container(NULL) > 0) - return 0; - - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { + r = proc_cmdline(&line); + if (r < 0) log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + if (r <= 0) return 0; - } FOREACH_WORD_QUOTED(w, l, line, state) { _cleanup_free_ char *word; diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c index 1f63785041..622952a6e9 100644 --- a/src/quotacheck/quotacheck.c +++ b/src/quotacheck/quotacheck.c @@ -26,7 +26,6 @@ #include #include "util.h" -#include "virt.h" #include "fileio.h" static bool arg_skip = false; @@ -38,14 +37,11 @@ static int parse_proc_cmdline(void) { size_t l; int r; - if (detect_container(NULL) > 0) - return 0; - - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { + r = proc_cmdline(&line); + if (r < 0) log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + if (r <= 0) return 0; - } FOREACH_WORD_QUOTED(w, l, line, state) { diff --git a/src/rfkill/rfkill.c b/src/rfkill/rfkill.c index d5b6f27b8d..65fd9bc478 100644 --- a/src/rfkill/rfkill.c +++ b/src/rfkill/rfkill.c @@ -95,7 +95,7 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - if (streq(argv[1], "load") && restore_state()) { + if (streq(argv[1], "load") && shall_restore_state()) { _cleanup_free_ char *value = NULL; r = read_one_line_file(saved, &value); diff --git a/src/shared/util.c b/src/shared/util.c index ef3b67b597..d753781c7a 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -5992,24 +5992,36 @@ int split_pair(const char *s, const char *sep, char **l, char **r) { return 0; } -bool restore_state(void) { +int shall_restore_state(void) { _cleanup_free_ char *line; char *w, *state; - int r; size_t l; + int r; - if (detect_container(NULL) > 0) - return true; + r = proc_cmdline(&line); + if (r < 0) + return r; + if (r == 0) /* Container ... */ + return 1; - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { - log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); - return true; /* something is very wrong, let's not make it worse */ + FOREACH_WORD_QUOTED(w, l, line, state) + if (l == 23 && memcmp(w, "systemd.restore_state=0", 23)) + return 0; + + return 1; +} + +int proc_cmdline(char **ret) { + int r; + + if (detect_container(NULL) > 0) { + *ret = NULL; + return 0; } - FOREACH_WORD_QUOTED(w, l, line, state) - if (strneq(w, "systemd.restore_state=0", l)) - return false; + r = read_one_line_file("/proc/cmdline", ret); + if (r < 0) + return r; - return true; + return 1; } diff --git a/src/shared/util.h b/src/shared/util.h index d90b808476..8b4c15512a 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -770,7 +770,7 @@ void parse_user_at_host(char *arg, char **user, char **host); int split_pair(const char *s, const char *sep, char **l, char **r); -bool restore_state(void); +int shall_restore_state(void); /** * Normal qsort requires base to be nonnull. Here were require @@ -783,3 +783,5 @@ static inline void qsort_safe(void *base, size_t nmemb, size_t size, qsort(base, nmemb, size, compar); } } + +int proc_cmdline(char **ret); diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index 9d0f23694c..726945816d 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -195,11 +195,11 @@ static bool enable_name_policy(void) { int r; size_t l; - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { + r = proc_cmdline(&line); + if (r < 0) log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); - return true; /* something is very wrong, let's not make it worse */ - } + if (r <= 0) + return true; FOREACH_WORD_QUOTED(w, l, line, state) if (strneq(w, "net.ifnames=0", l)) diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 1c2d00f03b..559d33e78f 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -857,10 +857,15 @@ static int systemd_fds(struct udev *udev, int *rctrl, int *rnetlink) */ 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) { @@ -890,8 +895,6 @@ static void kernel_cmdline_options(struct udev *udev) free(s); } - - free(line); } int main(int argc, char *argv[]) -- cgit v1.2.3