diff --git a/src/core/main.c b/src/core/main.c index 1a1e09035b..f7cda72fdd 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -318,7 +318,6 @@ static int set_machine_id(const char *m) { } static int parse_proc_cmdline_item(const char *key, const char *value, void *data) { - int r; assert(key); @@ -330,10 +329,8 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat if (!unit_name_is_valid(value, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) log_warning("Unit name specified on %s= is not valid, ignoring: %s", key, value); - else if (in_initrd() == !!startswith(key, "rd.")) { - if (free_and_strdup(&arg_default_unit, value) < 0) - return log_oom(); - } + else if (in_initrd() == !!startswith(key, "rd.")) + return free_and_strdup_warn(&arg_default_unit, value); } else if (proc_cmdline_key_streq(key, "systemd.dump_core")) { @@ -510,7 +507,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat /* SysV compatibility */ target = runlevel_to_target(key); if (target) - return free_and_strdup(&arg_default_unit, target); + return free_and_strdup_warn(&arg_default_unit, target); } return 0; @@ -987,11 +984,9 @@ static int parse_argv(int argc, char *argv[]) { case 'b': case 's': case 'z': - /* Just to eat away the sysvinit kernel - * cmdline args without getopt() error - * messages that we'll parse in - * parse_proc_cmdline_word() or ignore. */ - + /* Just to eat away the sysvinit kernel cmdline args that we'll parse in + * parse_proc_cmdline_item() or ignore, without any getopt() error messages. + */ case '?': if (getpid_cached() != 1) return -EINVAL; diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 07f060e953..ba3fe9ec2f 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -2065,22 +2065,55 @@ static int list_machines(int argc, char *argv[], void *userdata) { return rc; } -static int get_default(int argc, char *argv[], void *userdata) { - _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; - _cleanup_free_ char *_path = NULL; - const char *path; +static int parse_proc_cmdline_item(const char *key, const char *value, void *data) { + char **ret = data; + + if (streq(key, "systemd.unit")) { + if (proc_cmdline_value_missing(key, value)) + return 0; + if (!unit_name_is_valid(value, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) + return log_warning("Unit name specified on %s= is not valid, ignoring: %s", key, value); + + return free_and_strdup_warn(ret, key); + + } else if (!value) { + if (runlevel_to_target(key)) + return free_and_strdup_warn(ret, key); + } + + return 0; +} + +static void emit_cmdline_warning(void) { + if (arg_quiet || arg_root) + /* don't bother checking the commandline if we're operating on a container */ + return; + + _cleanup_free_ char *override = NULL; + int r; + + r = proc_cmdline_parse(parse_proc_cmdline_item, &override, 0); + if (r < 0) + log_debug_errno(r, "Failed to parse kernel command line, ignoring: %m"); + if (override) + log_notice("Note: found \"%s\" on the kernel commandline, which overrides the default unit.", + override); +} + +static int determine_default(char **ret_name) { int r; if (install_client_side()) { - r = unit_file_get_default(arg_scope, arg_root, &_path); + r = unit_file_get_default(arg_scope, arg_root, ret_name); if (r < 0) return log_error_errno(r, "Failed to get default target: %m"); - path = _path; + return 0; - r = 0; } else { - _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus *bus; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + const char *name; r = acquire_bus(BUS_MANAGER, &bus); if (r < 0) @@ -2098,13 +2131,25 @@ static int get_default(int argc, char *argv[], void *userdata) { if (r < 0) return log_error_errno(r, "Failed to get default target: %s", bus_error_message(&error, r)); - r = sd_bus_message_read(reply, "s", &path); + r = sd_bus_message_read(reply, "s", &name); if (r < 0) return bus_log_parse_error(r); - } - if (path) - printf("%s\n", path); + return free_and_strdup_warn(ret_name, name); + } +} + +static int get_default(int argc, char *argv[], void *userdata) { + _cleanup_free_ char *name = NULL; + int r; + + r = determine_default(&name); + if (r < 0) + return r; + + printf("%s\n", name); + + emit_cmdline_warning(); return 0; } @@ -2164,6 +2209,19 @@ static int set_default(int argc, char *argv[], void *userdata) { r = 0; } + emit_cmdline_warning(); + + if (!arg_quiet) { + _cleanup_free_ char *final = NULL; + + r = determine_default(&final); + if (r < 0) + return r; + + if (!streq(final, unit)) + log_notice("Note: \"%s\" is the default unit (possibly a runtime override).", final); + } + finish: unit_file_changes_free(changes, n_changes);