Skip to content

Commit

Permalink
sysroot: Support customising /boot on root for syslinux and u-boot
Browse files Browse the repository at this point in the history
This introduces a new config value "sysroot.boot_path_on_disk":

> Tell ostree where the bootloader will be looking for the kernel.  This is
> the location of `/boot` relative to the root of the boot partition.
>
> This allows explicitly telling ostree that the boot partition is or is
> not separate from the root partition.  If `/boot` is on root set this to
> `/boot`.  If it's on seperate partition this should be set to `/`.
>
> This must be either an absolute path (starting with `/`) or `auto`.
> Defaults to `auto`.
>
> This setting currently only respected by the u-boot and syslinux
> bootloaders.

This commit is based on an original by Colin Walters (ostreedev#215), but takes a
different tack.  ostreedev#215 attempts to determine automatically whether `/boot`
is on root or not, but there are always situations where this isn't
possible so I'm adding a config option here so the user can make it
explicit.

Future commits can add the automatic detection in, but this means that we
don't need to be completely general with the auto-detection.
  • Loading branch information
wmanley committed Jul 8, 2020
1 parent a37d5c5 commit 1a77911
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 10 deletions.
1 change: 1 addition & 0 deletions Makefile-tests.am
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ _installed_or_uninstalled_test_scripts = \
tests/test-admin-upgrade-endoflife.sh \
tests/test-admin-upgrade-systemd-update.sh \
tests/test-admin-deploy-syslinux.sh \
tests/test-admin-deploy-syslinux-bootonslash.sh \
tests/test-admin-deploy-2.sh \
tests/test-admin-deploy-karg.sh \
tests/test-admin-deploy-switch.sh \
Expand Down
27 changes: 27 additions & 0 deletions man/ostree.repo-config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,33 @@ Boston, MA 02111-1307, USA.
</listitem>
</varlistentry>

<varlistentry>
<term><varname>boot_path_on_disk</varname></term>
<listitem>
<para>
Tell ostree where the bootloader will be looking for the kernel.
This is the location of <literal>/boot</literal> relative to the
root of the boot partition.
</para>
<para>
This allows explicitly telling ostree that the boot partition is or
is not seperate from the root partition. If
<literal>/boot</literal> is on root set this to
<literal>/boot</literal>. If it's on seperate partition this
should be set to <literal>/</literal>.
</para>
<para>
This must be either an absolute path (starting with
<literal>/</literal>) or <literal>auto</literal>. Defaults to
<literal>auto</literal>.
</para>
<para>
This setting currently only respected by the u-boot and syslinux
bootloaders.
</para>
</listitem>
</varlistentry>

</variablelist>

</refsect1>
Expand Down
23 changes: 19 additions & 4 deletions src/libostree/ostree-bootloader-syslinux.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ append_config_from_loader_entries (OstreeBootloaderSyslinux *self,
gboolean regenerate_default,
int bootversion,
GPtrArray *new_lines,
const char *boot_path_on_disk,
GCancellable *cancellable,
GError **error)
{
Expand All @@ -89,15 +90,22 @@ append_config_from_loader_entries (OstreeBootloaderSyslinux *self,
val = ostree_bootconfig_parser_get (config, "linux");
if (!val)
return glnx_throw (error, "No \"linux\" key in bootloader config");
g_ptr_array_add (new_lines, g_strdup_printf ("\tKERNEL %s", val));
g_autofree gchar *kernel = g_build_path ("/", boot_path_on_disk, val, NULL);
g_ptr_array_add (new_lines, g_strdup_printf ("\tKERNEL %s", kernel));

val = ostree_bootconfig_parser_get (config, "initrd");
if (val)
g_ptr_array_add (new_lines, g_strdup_printf ("\tINITRD %s", val));
{
g_autofree gchar *initrd = g_build_path ("/", boot_path_on_disk, val, NULL);
g_ptr_array_add (new_lines, g_strdup_printf ("\tINITRD %s", initrd));
}

val = ostree_bootconfig_parser_get (config, "devicetree");
if (val)
g_ptr_array_add (new_lines, g_strdup_printf ("\tDEVICETREE %s", val));
{
g_autofree gchar *devicetree = g_build_path ("/", boot_path_on_disk, val, NULL);
g_ptr_array_add (new_lines, g_strdup_printf ("\tDEVICETREE %s", devicetree));
}

val = ostree_bootconfig_parser_get (config, "options");
if (val)
Expand Down Expand Up @@ -130,6 +138,11 @@ _ostree_bootloader_syslinux_write_config (OstreeBootloader *bootloader,
g_autoptr(GPtrArray) new_lines = g_ptr_array_new_with_free_func (g_free);
g_autoptr(GPtrArray) tmp_lines = g_ptr_array_new_with_free_func (g_free);

g_autofree const char *boot_path_on_disk = _ostree_sysroot_get_boot_path_on_disk (
self->sysroot, error);
if (boot_path_on_disk == NULL)
return FALSE;

g_autofree char *kernel_arg = NULL;
gboolean saw_default = FALSE;
gboolean regenerate_default = FALSE;
Expand All @@ -142,6 +155,7 @@ _ostree_bootloader_syslinux_write_config (OstreeBootloader *bootloader,
{
const char *line = *iter;
gboolean skip = FALSE;
g_autofree char *nonostree_prefix = g_build_path ("/", boot_path_on_disk, "/ostree/", NULL);

if (parsing_label &&
(line == NULL || !g_str_has_prefix (line, "\t")))
Expand All @@ -153,7 +167,7 @@ _ostree_bootloader_syslinux_write_config (OstreeBootloader *bootloader,
/* If this is a non-ostree kernel, just emit the lines
* we saw.
*/
if (!g_str_has_prefix (kernel_arg, "/ostree/"))
if (!g_str_has_prefix (kernel_arg, nonostree_prefix))
{
for (guint i = 0; i < tmp_lines->len; i++)
{
Expand Down Expand Up @@ -211,6 +225,7 @@ _ostree_bootloader_syslinux_write_config (OstreeBootloader *bootloader,

if (!append_config_from_loader_entries (self, regenerate_default,
bootversion, new_lines,
boot_path_on_disk,
cancellable, error))
return FALSE;

Expand Down
17 changes: 11 additions & 6 deletions src/libostree/ostree-bootloader-uboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,20 @@ append_system_uenv (OstreeBootloaderUboot *self,

static gboolean
create_config_from_boot_loader_entries (OstreeBootloaderUboot *self,
int bootversion,
GPtrArray *new_lines,
GCancellable *cancellable,
GError **error)
int bootversion,
GPtrArray *new_lines,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GPtrArray) boot_loader_configs = NULL;
OstreeBootconfigParser *config;
const char *val;

g_autofree const char *boot_path_on_disk = _ostree_sysroot_get_boot_path_on_disk (
self->sysroot, error);
if (boot_path_on_disk == NULL)
return FALSE;

if (!_ostree_sysroot_read_boot_loader_configs (self->sysroot, bootversion, &boot_loader_configs,
cancellable, error))
return FALSE;
Expand All @@ -134,11 +139,11 @@ create_config_from_boot_loader_entries (OstreeBootloaderUboot *self,
"No \"linux\" key in bootloader config");
return FALSE;
}
g_ptr_array_add (new_lines, g_strdup_printf ("kernel_image%s=%s", index_suffix, val));
g_ptr_array_add (new_lines, g_strdup_printf ("kernel_image%s=%s%s", index_suffix, boot_path_on_disk, val));

val = ostree_bootconfig_parser_get (config, "initrd");
if (val)
g_ptr_array_add (new_lines, g_strdup_printf ("ramdisk_image%s=%s", index_suffix, val));
g_ptr_array_add (new_lines, g_strdup_printf ("ramdisk_image%s=%s%s", index_suffix, boot_path_on_disk, val));

val = ostree_bootconfig_parser_get (config, "devicetree");
if (val)
Expand Down
3 changes: 3 additions & 0 deletions src/libostree/ostree-sysroot-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,7 @@ gboolean _ostree_sysroot_cleanup_internal (OstreeSysroot *sysroot,
GCancellable *cancellable,
GError **error);

char * _ostree_sysroot_get_boot_path_on_disk (OstreeSysroot *sysroot,
GError **error);

G_END_DECLS
37 changes: 37 additions & 0 deletions src/libostree/ostree-sysroot.c
Original file line number Diff line number Diff line change
Expand Up @@ -2140,3 +2140,40 @@ ostree_sysroot_deployment_set_pinned (OstreeSysroot *self,

return TRUE;
}

/**
* _ostree_sysroot_get_boot_path_on_disk
*
* We need to provide absolute paths to the bootloader for the location of the
* kernel to boot into, but this needs to be relative to root on the filesystem
* that the kernel is on, rather than relative to root of the root filesystem.
* If boot is on a seperate filesystem to root this will typically return "/",
* otherwise it will typically be "/boot".
*/
char *
_ostree_sysroot_get_boot_path_on_disk (OstreeSysroot *sysroot, GError **error)
{
GKeyFile * config = ostree_repo_get_config (sysroot->repo);

g_autofree char * boot_path_on_disk = NULL;
if (!ot_keyfile_get_value_with_default_group_optional (config, "sysroot",
"boot_path_on_disk", "auto",
&boot_path_on_disk, error))
return NULL;

if (g_str_equal (boot_path_on_disk, "auto"))
{
/* TODO: Be smarter about working this out automatically */
g_free (boot_path_on_disk);
boot_path_on_disk = g_strdup ("/");
}

if (!boot_path_on_disk || boot_path_on_disk[0] != '/')
{
g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, "sysroot.boot_path_on_disk "
"must be an absolute path. It is \"%s\"", boot_path_on_disk);
return NULL;
}

return g_steal_pointer (&boot_path_on_disk);
}
47 changes: 47 additions & 0 deletions tests/test-admin-deploy-syslinux-bootonslash.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/bin/bash
#
# Copyright (C) 2016 Colin Walters <walters@verbum.org>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

set -euo pipefail

. $(dirname $0)/libtest.sh

# Exports OSTREE_SYSROOT so --sysroot not needed.
setup_os_repository "archive-z2" "syslinux"

echo "1..2"

${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmaster/x86_64-runtime

# Override the default and say that /boot is not a partition
${CMD_PREFIX} ostree --repo=sysroot/ostree/repo config set sysroot.boot_path_on_disk /boot
${CMD_PREFIX} ostree admin deploy --verbose --karg=root=LABEL=MOO --karg=quiet --os=testos testos:testos/buildmaster/x86_64-runtime

assert_file_has_content sysroot/boot/syslinux/syslinux.cfg "KERNEL /boot/ostree/testos.*vmlinuz"
assert_file_has_content sysroot/boot/syslinux/syslinux.cfg "INITRD /boot/ostree/testos.*initramfs"

echo "ok bootonslash"

${CMD_PREFIX} ostree admin undeploy 0

${CMD_PREFIX} ostree --repo=sysroot/ostree/repo config set sysroot.boot_path_on_disk /
${CMD_PREFIX} ostree admin deploy --karg=root=LABEL=MOO --karg=quiet --os=testos testos:testos/buildmaster/x86_64-runtime
assert_file_has_content sysroot/boot/syslinux/syslinux.cfg "KERNEL /ostree/testos.*vmlinuz"
assert_file_has_content sysroot/boot/syslinux/syslinux.cfg "INITRD /ostree/testos.*initramfs"

echo "ok bootpartition"

0 comments on commit 1a77911

Please sign in to comment.