static gboolean
append_config_from_boostree_loader_entries (OstreeBootloaderSyslinux  *self,
                                        gboolean               regenerate_default,
                                        int                    bootversion,
                                        GPtrArray             *new_lines,
                                        GCancellable          *cancellable,
                                        GError               **error)
{
  gboolean ret = FALSE;
  gs_unref_ptrarray GPtrArray *boostree_loader_configs = NULL;
  guint i;

  if (!_ostree_sysroot_read_boot_loader_configs (self->sysroot, bootversion, &boostree_loader_configs,
                                                 cancellable, error))
    goto out;

  for (i = 0; i < boostree_loader_configs->len; i++)
    {
      OstreeBootconfigParser *config = boostree_loader_configs->pdata[i];
      const char *val;

      val = ostree_bootconfig_parser_get (config, "title");
      if (!val)
        val = "(Untitled)";

      if (regenerate_default && i == 0)
        {
          g_ptr_array_add (new_lines, g_strdup_printf ("DEFAULT %s", val));
        }

      g_ptr_array_add (new_lines, g_strdup_printf ("LABEL %s", val));
      
      val = ostree_bootconfig_parser_get (config, "linux");
      if (!val)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "No \"linux\" key in bootloader config");
          goto out;
        }
      g_ptr_array_add (new_lines, g_strdup_printf ("\tKERNEL %s", val));

      val = ostree_bootconfig_parser_get (config, "initrd");
      if (val)
        g_ptr_array_add (new_lines, g_strdup_printf ("\tINITRD %s", val));

      val = ostree_bootconfig_parser_get (config, "options");
      if (val)
        g_ptr_array_add (new_lines, g_strdup_printf ("\tAPPEND %s", val));
    }

  ret = TRUE;
 out:
  return ret;
}
static gboolean
append_config_from_loader_entries (OstreeBootloaderSyslinux  *self,
                                   gboolean               regenerate_default,
                                   int                    bootversion,
                                   GPtrArray             *new_lines,
                                   GCancellable          *cancellable,
                                   GError               **error)
{
  g_autoptr(GPtrArray) loader_configs = NULL;
  if (!_ostree_sysroot_read_boot_loader_configs (self->sysroot, bootversion, &loader_configs,
                                                 cancellable, error))
    return FALSE;

  for (guint i = 0; i < loader_configs->len; i++)
    {
      OstreeBootconfigParser *config = loader_configs->pdata[i];
      const char *val = ostree_bootconfig_parser_get (config, "title");
      if (!val)
        val = "(Untitled)";

      if (regenerate_default && i == 0)
        g_ptr_array_add (new_lines, g_strdup_printf ("DEFAULT %s", val));

      g_ptr_array_add (new_lines, g_strdup_printf ("LABEL %s", val));

      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));

      val = ostree_bootconfig_parser_get (config, "initrd");
      if (val)
        g_ptr_array_add (new_lines, g_strdup_printf ("\tINITRD %s", val));

      val = ostree_bootconfig_parser_get (config, "devicetree");
      if (val)
        g_ptr_array_add (new_lines, g_strdup_printf ("\tDEVICETREE %s", val));

      val = ostree_bootconfig_parser_get (config, "options");
      if (val)
        g_ptr_array_add (new_lines, g_strdup_printf ("\tAPPEND %s", val));
    }

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

  if (!_ostree_sysroot_read_boot_loader_configs (self->sysroot, bootversion, &boot_loader_configs,
                                                 cancellable, error))
    return FALSE;

  /* U-Boot doesn't support a menu so just pick the first one since the list is ordered */
  config = boot_loader_configs->pdata[0];

  val = ostree_bootconfig_parser_get (config, "linux");
  if (!val)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "No \"linux\" key in bootloader config");
      return FALSE;
    }
  g_ptr_array_add (new_lines, g_strdup_printf ("kernel_image=%s", val));
  bootdir = strndup (val, strrchr(val, '/') - val);
  g_ptr_array_add (new_lines, g_strdup_printf ("bootdir=%s/", bootdir));

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

  val = ostree_bootconfig_parser_get (config, "options");
  if (val)
    g_ptr_array_add (new_lines, g_strdup_printf ("bootargs=%s", val));

  return TRUE;
}
Esempio n. 4
0
/**
 * ostree_sysroot_load:
 * @self: Sysroot
 * @cancellable: Cancellable
 * @error: Error
 *
 * Load deployment list, bootversion, and subbootversion from the
 * rootfs @self.
 */
gboolean
ostree_sysroot_load (OstreeSysroot  *self,
                     GCancellable   *cancellable,
                     GError        **error)
{
  gboolean ret = FALSE;
  guint i;
  int bootversion = 0;
  int subbootversion = 0;
  g_autoptr(GPtrArray) boot_loader_configs = NULL;
  g_autoptr(GPtrArray) deployments = NULL;

  g_clear_pointer (&self->deployments, g_ptr_array_unref);
  g_clear_pointer (&self->booted_deployment, g_object_unref);
  self->bootversion = -1;
  self->subbootversion = -1;

  if (!ensure_sysroot_fd (self, error))
    goto out;

  if (!read_current_bootversion (self, &bootversion, cancellable, error))
    goto out;

  if (!_ostree_sysroot_read_current_subbootversion (self, bootversion, &subbootversion,
                                                    cancellable, error))
    goto out;

  if (!_ostree_sysroot_read_boot_loader_configs (self, bootversion, &boot_loader_configs,
                                                 cancellable, error))
    goto out;

  deployments = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);

  for (i = 0; i < boot_loader_configs->len; i++)
    {
      OstreeBootconfigParser *config = boot_loader_configs->pdata[i];

      if (!list_deployments_process_one_boot_entry (self, config, deployments,
                                                    cancellable, error))
        goto out;
    }

  g_ptr_array_sort (deployments, compare_deployments_by_boot_loader_version_reversed);
  for (i = 0; i < deployments->len; i++)
    {
      OstreeDeployment *deployment = deployments->pdata[i];
      ostree_deployment_set_index (deployment, i);
    }

  if (!find_booted_deployment (self, deployments, &self->booted_deployment,
                               cancellable, error))
    goto out;

  self->bootversion = bootversion;
  self->subbootversion = subbootversion;
  self->deployments = deployments;
  deployments = NULL; /* Transfer ownership */
  self->loaded = TRUE;

  ret = TRUE;
 out:
  return ret;
}
gboolean
_ostree_bootloader_grub2_generate_config (OstreeSysroot                 *sysroot,
                                          int                            bootversion,
                                          int                            target_fd,
                                          GCancellable                  *cancellable,
                                          GError                       **error)
{
  gboolean ret = FALSE;
  GString *output = g_string_new ("");
  gs_unref_object GOutputStream *out_stream = NULL;
  gs_unref_ptrarray GPtrArray *loader_configs = NULL;
  guint i;
  gsize bytes_written;
  gboolean is_efi;
  /* 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";
  const char *grub2_boot_device_id =
    g_getenv ("GRUB2_BOOT_DEVICE_ID");
  const char *grub2_prepare_root_cache =
    g_getenv ("GRUB2_PREPARE_ROOT_CACHE");

  /* We must have been called via the wrapper script */
  g_assert (grub2_boot_device_id != NULL);
  g_assert (grub2_prepare_root_cache != NULL);

  /* Passed from the parent */
  is_efi = g_getenv ("_OSTREE_GRUB2_IS_EFI") != NULL;

  out_stream = g_unix_output_stream_new (target_fd, FALSE);

  if (!_ostree_sysroot_read_boot_loader_configs (sysroot, bootversion,
                                                 &loader_configs,
                                                 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 *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-%s", (guint)i, grub2_boot_device_id);
      quoted_uuid = g_shell_quote (uuid);
      g_string_append_printf (output, "menuentry %s --class gnu-linux --class gnu --class os --unrestricted %s {\n", quoted_title, quoted_uuid);
      g_free (uuid);
      g_free (quoted_title);
      g_free (quoted_uuid);

      /* Hardcoded sections */
      g_string_append (output, hardcoded_video);
      g_string_append (output, hardcoded_insmods);
      g_string_append (output, grub2_prepare_root_cache);
      g_string_append_c (output, '\n');
      
      if (!kernel)
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "No \"linux\" key in bootloader config");
          goto out;
        }
      if (is_efi)
        g_string_append (output, "linuxefi ");
      else
        g_string_append (output, "linux16 ");
      g_string_append (output, kernel);

      options = ostree_bootconfig_parser_get (config, "options");
      if (options)
        {
          g_string_append_c (output, ' ');
          g_string_append (output, options);
        }
      g_string_append_c (output, '\n');

      initrd = ostree_bootconfig_parser_get (config, "initrd");
      if (initrd)
        {
          if (is_efi)
            g_string_append (output, "initrdefi ");
          else
            g_string_append (output, "initrd16 ");
          g_string_append (output, initrd);
          g_string_append_c (output, '\n');
        }

      g_string_append (output, "}\n");
    }

  if (!g_output_stream_write_all (out_stream, output->str, output->len,
                                  &bytes_written, cancellable, error))
    goto out;

  ret = TRUE;
 out:
  if (output)
    g_string_free (output, TRUE);
  return ret;
}