[systemd-devel] [PATCH 2/2] [V3] systemctl: switch-root check, if we switch to a systemd init

Lennart Poettering lennart at poettering.net
Thu Mar 6 06:23:31 PST 2014


On Thu, 06.03.14 09:12, harald at redhat.com (harald at redhat.com) wrote:

> From: Harald Hoyer <harald at redhat.com>
> 
> If "systemctl switch-root" is called with a specific "INIT" or
> /proc/cmdline contains "init=", then systemd would not serialize
> itsself.
> 
> Let systemctl check, if the new init is in the standard systemd
> installation path and if so, clear the INIT parameter,
> to let systemd serialize itsself.
> ---
>  src/systemctl/systemctl.c | 27 +++++++++++++++++++++------
>  1 file changed, 21 insertions(+), 6 deletions(-)
> 
> diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
> index f395265..852616d 100644
> --- a/src/systemctl/systemctl.c
> +++ b/src/systemctl/systemctl.c
> @@ -4295,19 +4295,34 @@ static int switch_root(sd_bus *bus, char **args) {
>  
>          root = args[1];
>  
> -        if (l >= 3)
> +        if (l >= 3) {
>                  init = strdup(args[2]);
> +                if (!init)
> +                        return log_oom();
> +        }
>          else {
>                  parse_env_file("/proc/cmdline", WHITESPACE,
>                                 "init", &init,
>                                 NULL);
> -
> -                if (!init)
> -                        init = strdup("");
>          }
>  
> -        if (!init)
> -                return log_oom();
> +        if (init && init[0]) {
> +                _cleanup_free_ char *root_init_path = NULL;
> +                _cleanup_free_ char *root_systemd_path = NULL;
> +
> +                root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
> +                if (!root_systemd_path)
> +                        return log_oom();


strappenda() is based on alloca() and allocates on the stack. You are
not supposed to free() that, and it cannot fail. Hence _cleanup_free_
does not apply to it, and you don't have tp check for the successful
allocation.

> +
> +                root_init_path = strjoin(root, "/", init, NULL);
> +                if (!root_init_path)
> +                        return log_oom();
> +
> +                if (files_same(root_init_path, root_systemd_path) > 0) {
> +                        free(init);
> +                        init = NULL;
> +                }
> +        }
>  
>          log_debug("switching root - root: %s; init: %s", root, init);
>  


Lennart

-- 
Lennart Poettering, Red Hat


More information about the systemd-devel mailing list