summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2021-01-22 11:20:50 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2021-02-09 13:49:15 +0900
commit2d79e90a1fb5cff8a94a936196533e4450e155a6 (patch)
tree51699733fdb4ace535f061fee93090ea50765352
parent957991b7acec20ccf2c21f0162e9da54ea22d2dd (diff)
downloadsystemd-2d79e90a1fb5cff8a94a936196533e4450e155a6.tar.gz
hostnamectl: try to set transient hostname even if updating static or pretty hostname failed
If no target (--pretty, --static, or --transient) is specified, then let's try to set transient hostname even if setting static or pretty hostname failed. This may be useful for read-only filesystem.
-rw-r--r--src/hostname/hostnamectl.c57
1 files changed, 44 insertions, 13 deletions
diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c
index 99c9883efa..aaba1deacd 100644
--- a/src/hostname/hostnamectl.c
+++ b/src/hostname/hostnamectl.c
@@ -11,6 +11,7 @@
#include "alloc-util.h"
#include "architecture.h"
+#include "bus-common-errors.h"
#include "bus-error.h"
#include "bus-map-properties.h"
#include "hostname-util.h"
@@ -222,36 +223,45 @@ static int show_status(int argc, char **argv, void *userdata) {
}
}
-static int set_simple_string(sd_bus *bus, const char *target, const char *method, const char *value) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+static int set_simple_string_internal(sd_bus *bus, sd_bus_error *error, const char *target, const char *method, const char *value) {
+ _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
int r;
polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
+ if (!error)
+ error = &e;
+
r = sd_bus_call_method(
bus,
"org.freedesktop.hostname1",
"/org/freedesktop/hostname1",
"org.freedesktop.hostname1",
method,
- &error, NULL,
+ error, NULL,
"sb", value, arg_ask_password);
if (r < 0)
- return log_error_errno(r, "Could not set %s: %s", target, bus_error_message(&error, r));
+ return log_error_errno(r, "Could not set %s: %s", target, bus_error_message(error, r));
return 0;
}
+static int set_simple_string(sd_bus *bus, const char *target, const char *method, const char *value) {
+ return set_simple_string_internal(bus, NULL, target, method, value);
+}
+
static int set_hostname(int argc, char **argv, void *userdata) {
_cleanup_free_ char *h = NULL;
const char *hostname = argv[1];
sd_bus *bus = userdata;
- int r;
+ bool implicit = false, show_hint = false;
+ int r, ret = 0;
if (!arg_pretty && !arg_static && !arg_transient)
- arg_pretty = arg_static = arg_transient = true;
+ arg_pretty = arg_static = arg_transient = implicit = true;
if (arg_pretty) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
const char *p;
/* If the passed hostname is already valid, then assume the user doesn't know anything about pretty
@@ -262,9 +272,17 @@ static int set_hostname(int argc, char **argv, void *userdata) {
else
p = hostname; /* Use the passed name as pretty hostname */
- r = set_simple_string(bus, "pretty hostname", "SetPrettyHostname", p);
- if (r < 0)
- return r;
+ r = set_simple_string_internal(bus, &error, "pretty hostname", "SetPrettyHostname", p);
+ if (r < 0) {
+ if (implicit &&
+ sd_bus_error_has_names(&error,
+ BUS_ERROR_FILE_IS_PROTECTED,
+ BUS_ERROR_READ_ONLY_FILESYSTEM)) {
+ show_hint = true;
+ ret = r;
+ } else
+ return r;
+ }
/* Now that we set the pretty hostname, let's clean up the parameter and use that as static
* hostname. If the hostname was already valid as static hostname, this will only chop off the trailing
@@ -280,9 +298,19 @@ static int set_hostname(int argc, char **argv, void *userdata) {
}
if (arg_static) {
- r = set_simple_string(bus, "static hostname", "SetStaticHostname", hostname);
- if (r < 0)
- return r;
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+
+ r = set_simple_string_internal(bus, &error, "static hostname", "SetStaticHostname", hostname);
+ if (r < 0) {
+ if (implicit &&
+ sd_bus_error_has_names(&error,
+ BUS_ERROR_FILE_IS_PROTECTED,
+ BUS_ERROR_READ_ONLY_FILESYSTEM)) {
+ show_hint = true;
+ ret = r;
+ } else
+ return r;
+ }
}
if (arg_transient) {
@@ -291,7 +319,10 @@ static int set_hostname(int argc, char **argv, void *userdata) {
return r;
}
- return 0;
+ if (show_hint)
+ log_info("Hint: use --transient option when /etc/machine-info or /etc/hostname cannot be modified (e.g. located in read-only filesystem).");
+
+ return ret;
}
static int set_icon_name(int argc, char **argv, void *userdata) {