[ostree/wip/grub2-efi: 3/3] WIP: GRUB2+EFI
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree/wip/grub2-efi: 3/3] WIP: GRUB2+EFI
- Date: Sat, 18 Oct 2014 00:31:04 +0000 (UTC)
commit fbeccb95fd0a694a296bfc576b9893afb50b65fa
Author: Colin Walters <walters verbum org>
Date: Fri Oct 17 20:30:33 2014 -0400
WIP: GRUB2+EFI
src/libostree/ostree-bootloader-grub2.c | 52 +++++++++++++++++++++++----
src/libostree/ostree-bootloader-syslinux.c | 8 +++-
src/libostree/ostree-bootloader-uboot.c | 8 +++-
src/libostree/ostree-bootloader.c | 7 +++-
src/libostree/ostree-bootloader.h | 10 ++++-
src/libostree/ostree-sysroot-deploy.c | 5 ++-
src/libostree/ostree-sysroot-private.h | 5 ++-
src/libostree/ostree-sysroot.c | 53 ++++++++++++++++++----------
8 files changed, 111 insertions(+), 37 deletions(-)
---
diff --git a/src/libostree/ostree-bootloader-grub2.c b/src/libostree/ostree-bootloader-grub2.c
index 02a9a9f..faeaa66 100644
--- a/src/libostree/ostree-bootloader-grub2.c
+++ b/src/libostree/ostree-bootloader-grub2.c
@@ -36,7 +36,10 @@ struct _OstreeBootloaderGrub2
OstreeSysroot *sysroot;
GFile *config_path_bios;
GFile *config_path_efi_marker;
+ GFile *config_path_efi_dir;
GFile *config_path_efi_dest;
+ GFile *config_path_efi_new;
+ GFile *config_path_efi_old;
gboolean is_efi;
};
@@ -47,14 +50,22 @@ G_DEFINE_TYPE_WITH_CODE (OstreeBootloaderGrub2, _ostree_bootloader_grub2, G_TYPE
G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BOOTLOADER,
_ostree_bootloader_grub2_bootloader_iface_init));
static gboolean
-_ostree_bootloader_grub2_query (OstreeBootloader *bootloader)
+_ostree_bootloader_grub2_query (OstreeBootloader *bootloader,
+ gboolean *out_is_active,
+ GCancellable *cancellable,
+ GError **error)
{
+ gboolean ret = FALSE;
OstreeBootloaderGrub2 *self = OSTREE_BOOTLOADER_GRUB2 (bootloader);
gs_unref_object GFile *marker_parent = NULL;
gs_unref_object GFileInfo *file_info = NULL;
if (g_file_query_exists (self->config_path_bios, NULL))
- return TRUE;
+ {
+ *out_is_active = TRUE;
+ ret = TRUE;
+ goto out;
+ }
marker_parent = g_file_get_parent (self->config_path_efi_marker);
if (!ot_gfile_query_info_allow_noent (self->config_path_efi_marker, "standard::symlink-target",
@@ -67,10 +78,17 @@ _ostree_bootloader_grub2_query (OstreeBootloader *bootloader)
const char *target = g_file_info_get_symlink_target (file_info);
self->is_efi = TRUE;
self->config_path_efi_dest = g_file_resolve_relative_path (marker_parent, target);
- return TRUE;
+ self->config_path_efi_dir = g_file_get_parent (self->config_path_efi_dest);
+ self->config_path_efi_new = g_file_get_child (self->config_path_efi_dir, "grub.cfg.new");
+ self->config_path_efi_old = g_file_get_child (self->config_path_efi_dir, "grub.cfg.old");
+ *out_is_active = TRUE;
}
+ else
+ *out_is_active = FALSE;
- return FALSE;
+ ret = TRUE;
+ out:
+ return ret;
}
static const char *
@@ -197,6 +215,7 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader,
OstreeBootloaderGrub2 *self = OSTREE_BOOTLOADER_GRUB2 (bootloader);
gboolean ret = FALSE;
gs_unref_object GFile *efi_new_config_temp = NULL;
+ gs_unref_object GFile *efi_orig_config = NULL;
gs_unref_object GFile *new_config_path = NULL;
gs_unref_object GSSubprocessContext *procctx = NULL;
gs_unref_object GSSubprocess *proc = NULL;
@@ -205,8 +224,9 @@ _ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader,
if (self->is_efi)
{
- new_config_path = ot_gfile_resolve_path_printf (self->sysroot->path, "boot/loader.%d/grub.cfg",
- bootversion);
+ if (!ot_gfile_ensure_unlinked (self->config_path_efi_new, cancellable, error))
+ goto out;
+ new_config_path = g_object_ref (self->config_path_efi_new);
}
else
{
@@ -246,8 +266,23 @@ rm -f ${grub_cfg}.new
if (self->is_efi)
{
- gs_unref_object GFile *config_efi_dest_dir = g_file_get_parent (self->config_path_efi_dest);
- gs_unref_object GFile *config_efi_tmp = g_file_get_child (config_efi_dest_dir, "
+ /* copy current to old */
+ if (!ot_gfile_ensure_unlinked (self->config_path_efi_old, cancellable, error))
+ goto out;
+ if (!g_file_copy (self->config_path_efi_dest, self->config_path_efi_old,
+ G_FILE_COPY_OVERWRITE, cancellable, NULL, NULL, error))
+ goto out;
+ if (!ot_gfile_ensure_unlinked (self->config_path_efi_old, cancellable, error))
+ goto out;
+
+ /* NOTE: NON-ATOMIC REPLACEMENT; WE can't do anything else on FAT;
+ * see https://bugzilla.gnome.org/show_bug.cgi?id=724246
+ */
+ if (!ot_gfile_ensure_unlinked (self->config_path_efi_dest, cancellable, error))
+ goto out;
+ if (!gs_file_rename (self->config_path_efi_new, self->config_path_efi_dest,
+ cancellable, error))
+ goto out;
}
ret = TRUE;
@@ -258,6 +293,7 @@ rm -f ${grub_cfg}.new
static gboolean
_ostree_bootloader_grub2_is_atomic (OstreeBootloader *bootloader)
{
+ OstreeBootloaderGrub2 *self = OSTREE_BOOTLOADER_GRUB2 (bootloader);
return !self->is_efi;
}
diff --git a/src/libostree/ostree-bootloader-syslinux.c b/src/libostree/ostree-bootloader-syslinux.c
index 0934bb8..86b66fa 100644
--- a/src/libostree/ostree-bootloader-syslinux.c
+++ b/src/libostree/ostree-bootloader-syslinux.c
@@ -42,11 +42,15 @@ G_DEFINE_TYPE_WITH_CODE (OstreeBootloaderSyslinux, _ostree_bootloader_syslinux,
G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BOOTLOADER,
_ostree_bootloader_syslinux_bootloader_iface_init));
static gboolean
-_ostree_bootloader_syslinux_query (OstreeBootloader *bootloader)
+_ostree_bootloader_syslinux_query (OstreeBootloader *bootloader,
+ gboolean *out_is_active,
+ GCancellable *cancellable,
+ GError **error)
{
OstreeBootloaderSyslinux *self = OSTREE_BOOTLOADER_SYSLINUX (bootloader);
- return g_file_query_file_type (self->config_path, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL) ==
G_FILE_TYPE_SYMBOLIC_LINK;
+ *out_is_active = g_file_query_file_type (self->config_path, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL) ==
G_FILE_TYPE_SYMBOLIC_LINK;
+ return TRUE;
}
static const char *
diff --git a/src/libostree/ostree-bootloader-uboot.c b/src/libostree/ostree-bootloader-uboot.c
index cd25e56..84c5cdd 100644
--- a/src/libostree/ostree-bootloader-uboot.c
+++ b/src/libostree/ostree-bootloader-uboot.c
@@ -46,11 +46,15 @@ G_DEFINE_TYPE_WITH_CODE (OstreeBootloaderUboot, _ostree_bootloader_uboot, G_TYPE
G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BOOTLOADER,
_ostree_bootloader_uboot_bootloader_iface_init));
static gboolean
-_ostree_bootloader_uboot_query (OstreeBootloader *bootloader)
+_ostree_bootloader_uboot_query (OstreeBootloader *bootloader,
+ gboolean *out_is_active,
+ GCancellable *cancellable,
+ GError **error)
{
OstreeBootloaderUboot *self = OSTREE_BOOTLOADER_UBOOT (bootloader);
- return g_file_query_file_type (self->config_path, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL) ==
G_FILE_TYPE_SYMBOLIC_LINK;
+ *out_is_active = g_file_query_file_type (self->config_path, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL) ==
G_FILE_TYPE_SYMBOLIC_LINK;
+ return TRUE;
}
static const char *
diff --git a/src/libostree/ostree-bootloader.c b/src/libostree/ostree-bootloader.c
index 3721999..c95674c 100644
--- a/src/libostree/ostree-bootloader.c
+++ b/src/libostree/ostree-bootloader.c
@@ -30,11 +30,14 @@ _ostree_bootloader_default_init (OstreeBootloaderInterface *iface)
}
gboolean
-_ostree_bootloader_query (OstreeBootloader *self)
+_ostree_bootloader_query (OstreeBootloader *self,
+ gboolean *out_is_active,
+ GCancellable *cancellable,
+ GError **error)
{
g_return_val_if_fail (OSTREE_IS_BOOTLOADER (self), FALSE);
- return OSTREE_BOOTLOADER_GET_IFACE (self)->query (self);
+ return OSTREE_BOOTLOADER_GET_IFACE (self)->query (self, out_is_active, cancellable, error);
}
/**
diff --git a/src/libostree/ostree-bootloader.h b/src/libostree/ostree-bootloader.h
index a84ce6b..cbb25aa 100644
--- a/src/libostree/ostree-bootloader.h
+++ b/src/libostree/ostree-bootloader.h
@@ -37,7 +37,10 @@ struct _OstreeBootloaderInterface
GTypeInterface g_iface;
/* virtual functions */
- gboolean (* query) (OstreeBootloader *self);
+ gboolean (* query) (OstreeBootloader *bootloader,
+ gboolean *out_is_active,
+ GCancellable *cancellable,
+ GError **error);
const char * (* get_name) (OstreeBootloader *self);
gboolean (* write_config) (OstreeBootloader *self,
int bootversion,
@@ -48,7 +51,10 @@ struct _OstreeBootloaderInterface
GType _ostree_bootloader_get_type (void) G_GNUC_CONST;
-gboolean _ostree_bootloader_query (OstreeBootloader *self);
+gboolean _ostree_bootloader_query (OstreeBootloader *bootloader,
+ gboolean *out_is_active,
+ GCancellable *cancellable,
+ GError **error);
const char *_ostree_bootloader_get_name (OstreeBootloader *self);
diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c
index 9934e0f..8d9fe0c 100644
--- a/src/libostree/ostree-sysroot-deploy.c
+++ b/src/libostree/ostree-sysroot-deploy.c
@@ -1598,9 +1598,12 @@ ostree_sysroot_write_deployments (OstreeSysroot *self,
else
{
int new_bootversion = self->bootversion ? 0 : 1;
- gs_unref_object OstreeBootloader *bootloader = _ostree_sysroot_query_bootloader (self);
+ gs_unref_object OstreeBootloader *bootloader = NULL;
gs_unref_object GFile *new_loader_entries_dir = NULL;
+ if (!_ostree_sysroot_query_bootloader (self, &bootloader, cancellable, error))
+ goto out;
+
new_loader_entries_dir = ot_gfile_resolve_path_printf (self->path, "boot/loader.%d/entries",
new_bootversion);
if (!gs_shutil_rm_rf (new_loader_entries_dir, cancellable, error))
diff --git a/src/libostree/ostree-sysroot-private.h b/src/libostree/ostree-sysroot-private.h
index 0857e4c..28b0feb 100644
--- a/src/libostree/ostree-sysroot-private.h
+++ b/src/libostree/ostree-sysroot-private.h
@@ -75,7 +75,10 @@ _ostree_sysroot_get_devino (GFile *path,
char *_ostree_sysroot_join_lines (GPtrArray *lines);
-OstreeBootloader *_ostree_sysroot_query_bootloader (OstreeSysroot *sysroot);
+gboolean _ostree_sysroot_query_bootloader (OstreeSysroot *sysroot,
+ OstreeBootloader **out_bootloader,
+ GCancellable *cancellable,
+ GError **error);
G_END_DECLS
diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c
index 160fc07..60d5cb6 100644
--- a/src/libostree/ostree-sysroot.c
+++ b/src/libostree/ostree-sysroot.c
@@ -846,29 +846,44 @@ ostree_sysroot_get_repo (OstreeSysroot *self,
/**
* ostree_sysroot_query_bootloader:
* @sysroot: Sysroot
- *
- * Returns: (transfer full): Currently active bootloader in @sysroot
+ * @out_bootloader: (out) (transfer full) (allow-none): Return location for bootloader, may be %NULL
+ * @cancellable: Cancellable
+ * @error: Error
*/
-OstreeBootloader *
-_ostree_sysroot_query_bootloader (OstreeSysroot *self)
+gboolean
+_ostree_sysroot_query_bootloader (OstreeSysroot *sysroot,
+ OstreeBootloader **out_bootloader,
+ GCancellable *cancellable,
+ GError **error)
{
- OstreeBootloaderSyslinux *syslinux;
- OstreeBootloaderUboot *uboot;
- OstreeBootloaderGrub2 *grub2;
-
- syslinux = _ostree_bootloader_syslinux_new (self);
- if (_ostree_bootloader_query ((OstreeBootloader*)syslinux))
- return (OstreeBootloader*) (syslinux);
-
- grub2 = _ostree_bootloader_grub2_new (self);
- if (_ostree_bootloader_query ((OstreeBootloader*)grub2))
- return (OstreeBootloader*) (grub2);
+ gboolean ret = FALSE;
+ gboolean is_active;
+ gs_unref_object OstreeBootloader *ret_loader = NULL;
- uboot = _ostree_bootloader_uboot_new (self);
- if (_ostree_bootloader_query ((OstreeBootloader*)uboot))
- return (OstreeBootloader*) (uboot);
+ ret_loader = (OstreeBootloader*)_ostree_bootloader_syslinux_new (sysroot);
+ if (!_ostree_bootloader_query (ret_loader, &is_active,
+ cancellable, error))
+ goto out;
+ if (!is_active)
+ {
+ g_object_unref (ret_loader);
+ ret_loader = (OstreeBootloader*)_ostree_bootloader_grub2_new (sysroot);
+ if (!_ostree_bootloader_query (ret_loader, &is_active,
+ cancellable, error))
+ goto out;
+ }
+ if (!is_active)
+ {
+ g_object_unref (ret_loader);
+ ret_loader = (OstreeBootloader*)_ostree_bootloader_uboot_new (sysroot);
+ if (!_ostree_bootloader_query (ret_loader, &is_active, cancellable, error))
+ goto out;
+ }
- return NULL;
+ ret = TRUE;
+ gs_transfer_out_value (out_bootloader, &ret_loader);
+ out:
+ return ret;
}
char *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]