[systemd-devel] [PATCH] hostnamed: Fix the way that static and transient host names interact

Lennart Poettering lennart at poettering.net
Tue May 27 18:36:12 PDT 2014


On Wed, 12.02.14 09:46, Stef Walter (stef at thewalter.net) wrote:

heya!

I finally merged this patch. Sorry for the delay!

I wasn't sure about the rationale, but this appears to be the right
thing to do after all, so I merged it!

Thank you!

Lennart

> It is almost always incorrect to allow DHCP or other sources of
> transient host names to override an explicitly configured static host
> name.
> 
> This commit changes things so that if a static host name is set, this
> will override the transient host name (eg: provided via DHCP). Transient
> host names can still be used to provide host names for machines that have
> not been explicitly configured with a static host name.
> 
> The exception to this rule is if the static host name is set to
> "localhost" or matches "localhost.*". In those cases we act as if no
> static host name has been explicitly set.
> 
> As discussed elsewhere, systemd may want to have an fd based ownership
> of the transient name. That part is not included in this commit.
> ---
>  man/hostnamectl.xml      |  8 +++-----
>  src/hostname/hostnamed.c | 36 +++++++++++++++++++++++++++++++-----
>  2 files changed, 34 insertions(+), 10 deletions(-)
> 
> diff --git a/man/hostnamectl.xml b/man/hostnamectl.xml
> index 4bc05f5..80e8cde 100644
> --- a/man/hostnamectl.xml
> +++ b/man/hostnamectl.xml
> @@ -68,11 +68,9 @@
>                  (e.g. "Lennart's Laptop"), the static hostname which
>                  is used to initialize the kernel hostname at boot
>                  (e.g. "lennarts-laptop"), and the transient hostname
> -                which might be assigned temporarily due to network
> -                configuration and might revert back to the static
> -                hostname if network connectivity is lost and is only
> -                temporarily written to the kernel hostname
> -                (e.g. "dhcp-47-11").</para>
> +                which is a default received from network configuration.
> +                If a static hostname is set, and is valid (something other
> +                than localhost) then the transient hostname is not used.</para>
>  
>                  <para>Note that the pretty hostname has little
>                  restrictions on the characters used, while the static
> diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c
> index e57891b..5174fa8 100644
> --- a/src/hostname/hostnamed.c
> +++ b/src/hostname/hostnamed.c
> @@ -228,16 +228,36 @@ static char* context_fallback_icon_name(Context *c) {
>          return strdup("computer");
>  }
>  
> -static int context_write_data_hostname(Context *c) {
> +static bool hostname_is_useful(const char *hn) {
> +        return !isempty(hn) && !streq(hn, "localhost") &&
> +               !startswith(hn, "localhost.");
> +}
> +
> +static int context_update_kernel_hostname(Context *c) {
> +        const char *static_hn;
>          const char *hn;
>  
>          assert(c);
>  
> -        if (isempty(c->data[PROP_HOSTNAME]))
> -                hn = "localhost";
> -        else
> +        static_hn = c->data[PROP_STATIC_HOSTNAME];
> +
> +        /* /etc/hostname with something other than "localhost"
> +         * has the highest preference ... */
> +        if (hostname_is_useful(static_hn))
> +                hn = static_hn;
> +
> +        /* ... the transient host name, (ie: DHCP) comes next ...*/
> +        else if (!isempty(c->data[PROP_HOSTNAME]))
>                  hn = c->data[PROP_HOSTNAME];
>  
> +        /* ... fallback to static "localhost.*" ignored above ... */
> +        else if (!isempty(static_hn))
> +                hn = static_hn;
> +
> +        /* ... and the ultimate fallback */
> +        else
> +                hn = "localhost";
> +
>          if (sethostname(hn, strlen(hn)) < 0)
>                  return -errno;
>  
> @@ -389,7 +409,7 @@ static int method_set_hostname(sd_bus *bus, sd_bus_message *m, void *userdata, s
>          free(c->data[PROP_HOSTNAME]);
>          c->data[PROP_HOSTNAME] = h;
>  
> -        r = context_write_data_hostname(c);
> +        r = context_update_kernel_hostname(c);
>          if (r < 0) {
>                  log_error("Failed to set host name: %s", strerror(-r));
>                  return sd_bus_error_set_errnof(error, r, "Failed to set hostname: %s", strerror(-r));
> @@ -441,6 +461,12 @@ static int method_set_static_hostname(sd_bus *bus, sd_bus_message *m, void *user
>                  c->data[PROP_STATIC_HOSTNAME] = h;
>          }
>  
> +        r = context_update_kernel_hostname(c);
> +        if (r < 0) {
> +                log_error("Failed to set host name: %s", strerror(-r));
> +                return sd_bus_error_set_errnof(error, r, "Failed to set hostname: %s", strerror(-r));
> +        }
> +
>          r = context_write_data_static_hostname(c);
>          if (r < 0) {
>                  log_error("Failed to write static host name: %s", strerror(-r));


Lennart

-- 
Lennart Poettering, Red Hat


More information about the systemd-devel mailing list