Skip to content

Commit

Permalink
admin: Add an esp-upgrade subcommand
Browse files Browse the repository at this point in the history
The files in the EFI System Partition (ESP) are never updated by OSTree so
users will always have the same ESP that was created during installation.

This happens because the ESP uses a vfat filesystem which doesn't support
symbolic links so the upgrade can't be atomic and part of the transaction.

But since the ESP contains the bootloader components (shim, grub, etc) and
other important EFI binaries like the ones used for firmware update, there
should be a way to update the ESP with the latest version of these files.

These binaries are stored in the /usr/lib/ostree-boot/efi directory of a
deployment, because rpm-ostree places there everything that is in /boot.

Add a ostree-admin-esp-upgrade subcommand, that just copies the content of
/usr/lib/ostree-boot/efi to /boot/efi, so users can update the ESP and get
the latest version of the files that are present in the booted deployment.

This sub-command only works on a system that was booted with EFI and uses
/boot/efi as the mountpoint for the ESP.

Closes: ostreedev#1649
  • Loading branch information
martinezjavier committed Jun 14, 2019
1 parent 8d0ab6d commit c60b8f3
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Makefile-man.am
Expand Up @@ -26,7 +26,7 @@ ostree-admin-config-diff.1 ostree-admin-deploy.1 \
ostree-admin-init-fs.1 ostree-admin-instutil.1 ostree-admin-os-init.1 \
ostree-admin-status.1 ostree-admin-set-origin.1 ostree-admin-switch.1 \
ostree-admin-undeploy.1 ostree-admin-upgrade.1 ostree-admin-unlock.1 \
ostree-admin-pin.1 \
ostree-admin-pin.1 ostree-admin-esp-upgrade.1 \
ostree-admin.1 ostree-cat.1 ostree-checkout.1 ostree-checksum.1 \
ostree-commit.1 ostree-create-usb.1 ostree-export.1 ostree-gpg-sign.1 \
ostree-config.1 ostree-diff.1 ostree-find-remotes.1 ostree-fsck.1 \
Expand Down
1 change: 1 addition & 0 deletions Makefile-ostree.am
Expand Up @@ -79,6 +79,7 @@ ostree_SOURCES += \
src/ostree/ot-admin-builtin-status.c \
src/ostree/ot-admin-builtin-switch.c \
src/ostree/ot-admin-builtin-pin.c \
src/ostree/ot-admin-builtin-esp-upgrade.c \
src/ostree/ot-admin-builtin-upgrade.c \
src/ostree/ot-admin-builtin-unlock.c \
src/ostree/ot-admin-builtins.h \
Expand Down
70 changes: 70 additions & 0 deletions man/ostree-admin-esp-upgrade.xml
@@ -0,0 +1,70 @@
<?xml version='1.0'?> <!--*-nxml-*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">

<!--
Copyright 2019 Red Hat, Inc.
SPDX-License-Identifier: LGPL-2.0+
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.
-->

<refentry id="ostree">

<refentryinfo>
<title>ostree admin esp-upgrade</title>
<productname>OSTree</productname>

<authorgroup>
<author>
<contrib>Developer</contrib>
<firstname>Javier</firstname>
<surname>Martinez Canillas</surname>
<email>javierm@redhat.com</email>
</author>
</authorgroup>
</refentryinfo>

<refmeta>
<refentrytitle>ostree admin esp-upgrade</refentrytitle>
<manvolnum>1</manvolnum>
</refmeta>

<refnamediv>
<refname>ostree-admin-esp-upgrade</refname>
<refpurpose>Upgrade the EFI System Partition (ESP) with files from the current deployment</refpurpose>
</refnamediv>

<refsynopsisdiv>
<cmdsynopsis>
<command>ostree admin esp-upgrade</command>
</cmdsynopsis>
</refsynopsisdiv>

<refsect1>
<title>Description</title>

<para>
Upgrade the EFI System Partition (ESP) with the files in the /usr/lib/ostree-boot/efi directory of the current deployment.
</para>
</refsect1>

<refsect1>
<title>Example</title>
<para><command>$ ostree admin esp-upgrade</command></para>
</refsect1>
</refentry>
105 changes: 105 additions & 0 deletions src/ostree/ot-admin-builtin-esp-upgrade.c
@@ -0,0 +1,105 @@
/*
* Copyright (C) 2019 Red Hat, Inc.
*
* SPDX-License-Identifier: LGPL-2.0+
*
* 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.
*
* Author: Javier Martinez Canillas <javierm@redhat.com>
*/

#include "config.h"

#include "ostree-sysroot-private.h"
#include "ot-main.h"
#include "ot-admin-builtins.h"
#include "ot-admin-functions.h"
#include "otutil.h"

static GOptionEntry options[] = {
{ NULL }
};

gboolean
ot_admin_builtin_esp_upgrade (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
{
g_autoptr(GOptionContext) context = g_option_context_new ("");

g_autoptr(OstreeSysroot) sysroot = NULL;
if (!ostree_admin_option_context_parse (context, options, &argc, &argv,
OSTREE_ADMIN_BUILTIN_FLAG_UNLOCKED,
invocation, &sysroot, cancellable, error))
return FALSE;

g_autoptr(OstreeRepo) repo = NULL;
if (!ostree_sysroot_get_repo (sysroot, &repo, cancellable, error))
return FALSE;

g_autoptr(GPtrArray) deployments = ostree_sysroot_get_deployments (sysroot);
OstreeDeployment *booted_deployment = ostree_sysroot_get_booted_deployment (sysroot);

g_autoptr(OstreeDeployment) pending_deployment = NULL;
g_autoptr(OstreeDeployment) rollback_deployment = NULL;
if (booted_deployment)
ostree_sysroot_query_deployments_for (sysroot, NULL, &pending_deployment,
&rollback_deployment);

if (deployments->len == 0)
{
g_print ("No deployments.\n");
return TRUE;
}

struct stat stbuf;

if (!glnx_fstatat_allow_noent (sysroot->sysroot_fd, "/sys/firmware/efi", &stbuf, AT_SYMLINK_NOFOLLOW, error))
return FALSE;

if (errno == ENOENT)
{
g_print ("Not an EFI system.\n");
return TRUE;
}

if (!ot_is_rw_mount ("/boot/efi"))
{
if (ot_is_ro_mount ("/boot/efi"))
g_print ("The ESP can't be updated because /boot/efi is a read-only mountpoint.\n");
else
g_print ("Only ESP mounted in /boot/efi is supported.\n");
return TRUE;
}

g_autofree char *deployment_path = ostree_sysroot_get_deployment_dirpath (sysroot, booted_deployment);
g_autofree char *new_esp_path = g_strdup_printf ("%s/usr/lib/ostree-boot", deployment_path);

GLNX_AUTO_PREFIX_ERROR ("During copy files to the ESP", error);
glnx_autofd int old_esp_fd = -1;
if (!glnx_opendirat (sysroot->sysroot_fd, "/boot", TRUE, &old_esp_fd, error))
return FALSE;

glnx_autofd int new_esp_fd = -1;
if (!glnx_opendirat (sysroot->sysroot_fd, new_esp_path, TRUE, &new_esp_fd, error))
return FALSE;

/* The ESP filesystem is vfat so don't attempt to copy ownership, mode, and xattrs */
const OstreeSysrootDebugFlags flags = sysroot->debug_flags | OSTREE_SYSROOT_DEBUG_NO_XATTRS;

if (!ot_copy_dir_recurse (new_esp_fd, old_esp_fd, "efi", flags , cancellable, error))
return FALSE;

return TRUE;
}
1 change: 1 addition & 0 deletions src/ostree/ot-admin-builtins.h
Expand Up @@ -40,6 +40,7 @@ BUILTINPROTO(undeploy);
BUILTINPROTO(deploy);
BUILTINPROTO(cleanup);
BUILTINPROTO(pin);
BUILTINPROTO(esp_upgrade);
BUILTINPROTO(finalize_staged);
BUILTINPROTO(unlock);
BUILTINPROTO(status);
Expand Down
3 changes: 3 additions & 0 deletions src/ostree/ot-builtin-admin.c
Expand Up @@ -57,6 +57,9 @@ static OstreeCommand admin_subcommands[] = {
{ "pin", OSTREE_BUILTIN_FLAG_NO_REPO,
ot_admin_builtin_pin,
"Change the \"pinning\" state of a deployment" },
{ "esp-upgrade", OSTREE_BUILTIN_FLAG_NO_REPO,
ot_admin_builtin_esp_upgrade,
"Upgrade the ESP with the files from the current deployment" },
{ "set-origin", OSTREE_BUILTIN_FLAG_NO_REPO,
ot_admin_builtin_set_origin,
"Set Origin and create a new origin file" },
Expand Down

0 comments on commit c60b8f3

Please sign in to comment.