[ostree/wip/grub2] WIP: grub2 support
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree/wip/grub2] WIP: grub2 support
- Date: Sat, 11 Oct 2014 12:59:37 +0000 (UTC)
commit d7903e11eb1d02a159d4c109c610abac8989370b
Author: Colin Walters <walters verbum org>
Date: Sat Oct 11 08:59:06 2014 -0400
WIP: grub2 support
Very, very hacky...
Makefile-libostree.am | 2 +
src/libostree/ostree-bootloader-grub2.c | 257 +++++++++++++++++++++++++++++++
src/libostree/ostree-bootloader-grub2.h | 38 +++++
src/libostree/ostree-sysroot.c | 6 +
4 files changed, 303 insertions(+), 0 deletions(-)
---
diff --git a/Makefile-libostree.am b/Makefile-libostree.am
index fbe173d..0a67ea7 100644
--- a/Makefile-libostree.am
+++ b/Makefile-libostree.am
@@ -74,6 +74,8 @@ libostree_1_la_SOURCES = \
src/libostree/ostree-deployment.c \
src/libostree/ostree-bootloader.h \
src/libostree/ostree-bootloader.c \
+ src/libostree/ostree-bootloader-grub2.h \
+ src/libostree/ostree-bootloader-grub2.c \
src/libostree/ostree-bootloader-syslinux.h \
src/libostree/ostree-bootloader-syslinux.c \
src/libostree/ostree-bootloader-uboot.h \
diff --git a/src/libostree/ostree-bootloader-grub2.c b/src/libostree/ostree-bootloader-grub2.c
new file mode 100644
index 0000000..621db5e
--- /dev/null
+++ b/src/libostree/ostree-bootloader-grub2.c
@@ -0,0 +1,257 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2014 Colin Walters <walters verbum org>
+ *
+ * This program 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 licence 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.
+ */
+
+#include "config.h"
+
+#include "ostree-sysroot-private.h"
+#include "ostree-bootloader-grub2.h"
+#include "otutil.h"
+#include <gio/gfiledescriptorbased.h>
+#include "libgsystem.h"
+
+#include <string.h>
+
+#define GRUB2_CONFIG_PATH "boot/grub2/grub.cfg"
+#define OSTREE_GRUB2_CONFIG_PATH "etc/grub.d/15_ostree"
+
+struct _OstreeBootloaderGrub2
+{
+ GObject parent_instance;
+
+ OstreeSysroot *sysroot;
+ GFile *config_path;
+};
+
+typedef GObjectClass OstreeBootloaderGrub2Class;
+
+static void _ostree_bootloader_grub2_bootloader_iface_init (OstreeBootloaderInterface *iface);
+G_DEFINE_TYPE_WITH_CODE (OstreeBootloaderGrub2, _ostree_bootloader_grub2, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (OSTREE_TYPE_BOOTLOADER,
_ostree_bootloader_grub2_bootloader_iface_init));
+
+static gboolean
+_ostree_bootloader_grub2_query (OstreeBootloader *bootloader)
+{
+ OstreeBootloaderGrub2 *self = OSTREE_BOOTLOADER_GRUB2 (bootloader);
+
+ return g_file_query_exists (self->config_path, NULL);
+}
+
+static const char *
+_ostree_bootloader_grub2_get_name (OstreeBootloader *bootloader)
+{
+ return "grub2";
+}
+
+static gboolean
+_ostree_bootloader_grub2_write_config (OstreeBootloader *bootloader,
+ int bootversion,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ OstreeBootloaderGrub2 *self = OSTREE_BOOTLOADER_GRUB2 (bootloader);
+ gs_unref_object GFile *subconfdir = NULL;
+ gs_unref_object GFile *tmp_subconf_path = NULL;
+ gs_unref_object GFile *ostree_subconf_path = NULL;
+ gs_unref_object GOutputStream *out_stream = NULL;
+ gs_unref_object GDataOutputStream *dataout = NULL;
+ gs_unref_ptrarray GPtrArray *loader_configs = NULL;
+ guint i;
+ int fd;
+ gs_free char *kernel_arg = NULL;
+ static const char prelude[] = "#!/bin/sh\n"
+ ". /usr/share/grub/grub-mkconfig_lib\n"
+ "boot_device_id=\"$(grub_get_device_id \"${GRUB_DEVICE}\")\"\n"
+ "prepare_root_cache=\"$(prepare_grub_to_access_device \"${GRUB_DEVICE_BOOT}\")\"\n"
+ "cat << EOF\n";
+ /* So... yeah. Just going to hardcode these. */
+ static const char hardcoded_video[] = "load_video\n"
+ "set gfxpayload=keep\n";
+ static const char hardcoded_insmods[] = "insmod gzio\n"
+ "insmod part_msdos\n"
+ "insmod xfs\n";
+
+ ostree_subconf_path = g_file_resolve_relative_path (self->sysroot->path, OSTREE_GRUB2_CONFIG_PATH);
+ subconfdir = g_file_get_parent (ostree_subconf_path);
+
+ if (!gs_file_open_in_tmpdir (subconfdir, 0755, &tmp_subconf_path, &out_stream,
+ cancellable, error))
+ goto out;
+
+ dataout = g_data_output_stream_new (out_stream);
+
+ fd = g_file_descriptor_based_get_fd (G_FILE_DESCRIPTOR_BASED (out_stream));
+
+ if (!_ostree_sysroot_read_boot_loader_configs (self->sysroot, bootversion,
+ &loader_configs,
+ cancellable, error))
+ goto out;
+
+ if (!g_data_output_stream_put_string (dataout, prelude, cancellable, error))
+ goto out;
+
+ for (i = 0; i < loader_configs->len; i++)
+ {
+ OstreeBootconfigParser *config = loader_configs->pdata[i];
+ const char *title;
+ const char *options;
+ const char *kernel;
+ const char *initrd;
+ char *line = NULL;
+ char *quoted_title = NULL;
+ char *uuid = NULL;
+ char *quoted_uuid = NULL;
+
+ title = ostree_bootconfig_parser_get (config, "title");
+ if (!title)
+ title = "(Untitled)";
+
+ kernel = ostree_bootconfig_parser_get (config, "linux");
+
+ quoted_title = g_shell_quote (title);
+ uuid = g_strdup_printf ("ostree-%u-${boot_device_id}", (guint)i);
+ quoted_uuid = g_shell_quote (uuid);
+ line = g_strdup_printf ("menuentry %s --class gnu-linux --class gnu --class os --unrestricted %s {\n",
quoted_title, quoted_uuid);
+ g_free (quoted_title);
+ g_free (quoted_uuid);
+
+ if (!g_data_output_stream_put_string (dataout, line, cancellable, error))
+ goto out;
+
+ /* Hardcoded sections */
+ if (!g_data_output_stream_put_string (dataout, hardcoded_video, cancellable, error))
+ goto out;
+ if (!g_data_output_stream_put_string (dataout, hardcoded_insmods, cancellable, error))
+ goto out;
+ if (!g_data_output_stream_put_string (dataout, "${prepare_root_cache}\n", cancellable, error))
+ goto out;
+
+ if (!kernel)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "No \"linux\" key in bootloader config");
+ goto out;
+ }
+ if (!g_data_output_stream_put_string (dataout, "linux16 ", cancellable, error))
+ goto out;
+ if (!g_data_output_stream_put_string (dataout, kernel, cancellable, error))
+ goto out;
+
+ options = ostree_bootconfig_parser_get (config, "options ");
+ if (options)
+ {
+ if (!g_data_output_stream_put_string (dataout, options, cancellable, error))
+ goto out;
+ }
+ if (!g_data_output_stream_put_byte (dataout, '\n', cancellable, error))
+ goto out;
+
+ initrd = ostree_bootconfig_parser_get (config, "initrd");
+ if (initrd)
+ {
+ if (!g_data_output_stream_put_string (dataout, "initrd16 ", cancellable, error))
+ goto out;
+ if (!g_data_output_stream_put_string (dataout, initrd, cancellable, error))
+ goto out;
+ if (!g_data_output_stream_put_byte (dataout, '\n', cancellable, error))
+ goto out;
+ }
+
+ if (!g_data_output_stream_put_string (dataout, "}\n", cancellable, error))
+ goto out;
+ }
+
+ if (!g_data_output_stream_put_string (dataout, "EOF\n", cancellable, error))
+ goto out;
+
+ if (!g_output_stream_flush ((GOutputStream*)dataout, cancellable, error))
+ goto out;
+
+ if (fsync (fd) != 0)
+ {
+ ot_util_set_error_from_errno (error, errno);
+ goto out;
+ }
+
+ if (!g_output_stream_close ((GOutputStream*)dataout, cancellable, error))
+ goto out;
+
+ if (!gs_file_rename (tmp_subconf_path, ostree_subconf_path, cancellable, error))
+ goto out;
+
+ /* From what I can see, this script doesn't even try to be atomic;
+ it just does:
+
+cat ${grub_cfg}.new > ${grub_cfg}
+rm -f ${grub_cfg}.new
+
+ Ugh. Well, we'll dive into this later...
+ */
+ if (!gs_subprocess_simple_run_sync (NULL,
+ GS_SUBPROCESS_STREAM_DISPOSITION_NULL,
+ cancellable, error,
+ "grub2-mkconfig", "-o", gs_file_get_path_cached (self->config_path),
NULL))
+ goto out;
+
+ ret = TRUE;
+ out:
+ return ret;
+}
+
+static void
+_ostree_bootloader_grub2_finalize (GObject *object)
+{
+ OstreeBootloaderGrub2 *self = OSTREE_BOOTLOADER_GRUB2 (object);
+
+ g_clear_object (&self->sysroot);
+ g_clear_object (&self->config_path);
+
+ G_OBJECT_CLASS (_ostree_bootloader_grub2_parent_class)->finalize (object);
+}
+
+void
+_ostree_bootloader_grub2_init (OstreeBootloaderGrub2 *self)
+{
+}
+
+static void
+_ostree_bootloader_grub2_bootloader_iface_init (OstreeBootloaderInterface *iface)
+{
+ iface->query = _ostree_bootloader_grub2_query;
+ iface->get_name = _ostree_bootloader_grub2_get_name;
+ iface->write_config = _ostree_bootloader_grub2_write_config;
+}
+
+void
+_ostree_bootloader_grub2_class_init (OstreeBootloaderGrub2Class *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->finalize = _ostree_bootloader_grub2_finalize;
+}
+
+OstreeBootloaderGrub2 *
+_ostree_bootloader_grub2_new (OstreeSysroot *sysroot)
+{
+ OstreeBootloaderGrub2 *self = g_object_new (OSTREE_TYPE_BOOTLOADER_GRUB2, NULL);
+ self->sysroot = g_object_ref (sysroot);
+ self->config_path = g_file_resolve_relative_path (self->sysroot->path, GRUB2_CONFIG_PATH);
+ return self;
+}
diff --git a/src/libostree/ostree-bootloader-grub2.h b/src/libostree/ostree-bootloader-grub2.h
new file mode 100644
index 0000000..5cbfba6
--- /dev/null
+++ b/src/libostree/ostree-bootloader-grub2.h
@@ -0,0 +1,38 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2014 Colin Walters <walters verbum org>
+ *
+ * This program 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 licence 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.
+ */
+
+#pragma once
+
+#include "ostree-bootloader.h"
+
+G_BEGIN_DECLS
+
+#define OSTREE_TYPE_BOOTLOADER_GRUB2 (_ostree_bootloader_grub2_get_type ())
+#define OSTREE_BOOTLOADER_GRUB2(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), OSTREE_TYPE_BOOTLOADER_GRUB2,
OstreeBootloaderGrub2))
+#define OSTREE_IS_BOOTLOADER_GRUB2(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), OSTREE_TYPE_BOOTLOADER_GRUB2))
+
+typedef struct _OstreeBootloaderGrub2 OstreeBootloaderGrub2;
+
+GType _ostree_bootloader_grub2_get_type (void) G_GNUC_CONST;
+
+OstreeBootloaderGrub2 * _ostree_bootloader_grub2_new (OstreeSysroot *sysroot);
+
+G_END_DECLS
+
diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c
index c88c6d4..160fc07 100644
--- a/src/libostree/ostree-sysroot.c
+++ b/src/libostree/ostree-sysroot.c
@@ -26,6 +26,7 @@
#include "ostree-sysroot-private.h"
#include "ostree-bootloader-uboot.h"
#include "ostree-bootloader-syslinux.h"
+#include "ostree-bootloader-grub2.h"
static gboolean
find_booted_deployment (OstreeSysroot *self,
@@ -853,11 +854,16 @@ _ostree_sysroot_query_bootloader (OstreeSysroot *self)
{
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);
+
uboot = _ostree_bootloader_uboot_new (self);
if (_ostree_bootloader_query ((OstreeBootloader*)uboot))
return (OstreeBootloader*) (uboot);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]