firstboot: apply hostname via hostnamed varlink API
Previously we just wrote /etc/hostname and returned. The kernel hostname was left at whatever PID 1 sethostname()'d very early in boot (before /etc/hostname existed), which meant hostnamectl reported the transient hostname instead of the static one until the next reboot. Call io.systemd.Hostname.SetStaticHostname on the running system so hostnamed writes /etc/hostname and updates the kernel hostname in one step. If hostnamed is unreachable (masked or absent on minimal images) fall back to writing /etc/hostname directly. --root=/--image= also keeps writing the file directly, since hostnamed only manages the running system.
This commit is contained in:
committed by
Yu Watanabe
parent
3d0ef4aefe
commit
c7837840f5
@@ -777,19 +777,46 @@ static int process_hostname(int rfd, sd_varlink **mute_console_link) {
|
||||
* and let it be resolved on each first boot. */
|
||||
const char *hostname = arg_hostname;
|
||||
_cleanup_free_ char *resolved = NULL;
|
||||
_cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
|
||||
if (!arg_root) {
|
||||
r = hostname_substitute_wildcards(arg_hostname, &resolved);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to resolve wildcards in hostname '%s', writing it verbatim: %m", arg_hostname);
|
||||
else if (!hostname_is_valid(resolved, VALID_HOSTNAME_TRAILING_DOT))
|
||||
log_warning("Resolved hostname '%s' is invalid, writing template '%s' verbatim instead.", resolved, arg_hostname);
|
||||
else
|
||||
else {
|
||||
hostname = resolved;
|
||||
|
||||
r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.Hostname");
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to connect to systemd-hostnamed, writing /etc/hostname directly: %m");
|
||||
}
|
||||
}
|
||||
|
||||
r = write_string_file_full_label(pfd, f, hostname,
|
||||
WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_SYNC|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL,
|
||||
/* ts= */ NULL, /* label_fn= */ NULL, arg_label_context);
|
||||
if (vl) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *reply = NULL;
|
||||
const char *error_id = NULL;
|
||||
r = sd_varlink_callbo(
|
||||
vl,
|
||||
"io.systemd.Hostname.SetStaticHostname",
|
||||
&reply,
|
||||
&error_id,
|
||||
SD_JSON_BUILD_PAIR_STRING("newValue", hostname));
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to call io.systemd.Hostname.SetStaticHostname, writing /etc/hostname directly: %m");
|
||||
else if (error_id)
|
||||
log_warning_errno(sd_varlink_error_to_errno(error_id, reply),
|
||||
"Failed to set static hostname, writing /etc/hostname directly: %s", error_id);
|
||||
else {
|
||||
log_info("Static hostname configured via systemd-hostnamed.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
r = write_string_file_full_label(
|
||||
pfd, f, hostname,
|
||||
WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_SYNC|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL,
|
||||
/* ts= */ NULL, /* label_fn= */ NULL, arg_label_context);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write /etc/hostname: %m");
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ After=systemd-sysusers.service systemd-tmpfiles-setup.service
|
||||
# Let vconsole-setup do its setup before starting user interaction:
|
||||
After=systemd-vconsole-setup.service
|
||||
After=systemd-mute-console.socket
|
||||
After=systemd-hostnamed.socket
|
||||
|
||||
Wants=first-boot-complete.target
|
||||
Before=first-boot-complete.target sysinit.target
|
||||
|
||||
Reference in New Issue
Block a user