mirror of
https://github.com/ostreedev/ostree.git
synced 2025-01-09 01:18:35 +03:00
deploy: Rework kernel arguments, add --karg-append to "admin deploy"
The "ordered hash" code was really just for kernel arguments. And it turns out it needs to be a multihash (for e.g. multiple console= arguments). So turn the OstreeOrderedHash into OstreeKernelArgs, and move the bits to split key=value and such into there. Now we're not making this public API yet - the public OstreeSysroot just takes char **kargs. To facilitate code reuse between ostree/ and libostree/, make it a noinst libtool library. It'll be duplicated in the binary and library, but that's OK for now. We can investigate making OstreeKernelArgs public later. https://bugzilla.gnome.org/show_bug.cgi?id=721136
This commit is contained in:
parent
7db2031fa0
commit
b2d0ba7ac1
@ -19,6 +19,15 @@
|
||||
|
||||
include Makefile-libostree-defines.am
|
||||
|
||||
noinst_LTLIBRARIES += libostree-kernel-args.la
|
||||
|
||||
libostree_kernel_args_la_SOURCES = \
|
||||
src/libostree/ostree-kernel-args.h \
|
||||
src/libostree/ostree-kernel-args.c \
|
||||
$(NULL)
|
||||
libostree_kernel_args_la_CFLAGS = $(OT_INTERNAL_GIO_UNIX_CFLAGS)
|
||||
libostree_kernel_args_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS)
|
||||
|
||||
lib_LTLIBRARIES += libostree-1.la
|
||||
|
||||
libostreeincludedir = $(includedir)/ostree-1
|
||||
@ -59,8 +68,6 @@ libostree_1_la_SOURCES = \
|
||||
src/libostree/ostree-bootloader-syslinux.c \
|
||||
src/libostree/ostree-bootloader-uboot.h \
|
||||
src/libostree/ostree-bootloader-uboot.c \
|
||||
src/libostree/ostree-ordered-hash.h \
|
||||
src/libostree/ostree-ordered-hash.c \
|
||||
src/libostree/ostree-gpg-verifier.c \
|
||||
src/libostree/ostree-gpg-verifier.h \
|
||||
$(NULL)
|
||||
@ -72,7 +79,7 @@ endif
|
||||
|
||||
libostree_1_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/libgsystem -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -DLOCALEDIR=\"$(datadir)/locale\" $(OT_INTERNAL_GIO_UNIX_CFLAGS)
|
||||
libostree_1_la_LDFLAGS = -version-number 1:0:0 -Bsymbolic-functions -export-symbols-regex '^ostree_'
|
||||
libostree_1_la_LIBADD = libotutil.la $(OT_INTERNAL_GIO_UNIX_LIBS)
|
||||
libostree_1_la_LIBADD = libotutil.la libostree-kernel-args.la $(OT_INTERNAL_GIO_UNIX_LIBS)
|
||||
|
||||
if USE_LIBARCHIVE
|
||||
libostree_1_la_CFLAGS += $(OT_DEP_LIBARCHIVE_CFLAGS)
|
||||
|
@ -65,7 +65,7 @@ ostree_SOURCES += \
|
||||
$(NULL)
|
||||
|
||||
ostree_bin_shared_cflags = $(AM_CFLAGS) -I$(srcdir)/src/libgsystem -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -I$(srcdir)/src/ostree -DLOCALEDIR=\"$(datadir)/locale\"
|
||||
ostree_bin_shared_ldadd = libotutil.la libostree-1.la
|
||||
ostree_bin_shared_ldadd = libotutil.la libostree-kernel-args.la libostree-1.la
|
||||
|
||||
ostree_CFLAGS = $(ostree_bin_shared_cflags) $(OT_INTERNAL_GIO_UNIX_CFLAGS)
|
||||
ostree_LDADD = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_GIO_UNIX_LIBS)
|
||||
|
263
src/libostree/ostree-kernel-args.c
Normal file
263
src/libostree/ostree-kernel-args.c
Normal file
@ -0,0 +1,263 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2013,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-kernel-args.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
struct _OstreeKernelArgs {
|
||||
GPtrArray *order;
|
||||
GHashTable *table;
|
||||
};
|
||||
|
||||
static char *
|
||||
split_keyeq (char *arg)
|
||||
{
|
||||
char *eq;
|
||||
|
||||
eq = strchr (arg, '=');
|
||||
if (eq)
|
||||
{
|
||||
/* Note key/val are in one malloc block,
|
||||
* so we don't free val...
|
||||
*/
|
||||
*eq = '\0';
|
||||
return eq+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ...and this allows us to insert a constant
|
||||
* string.
|
||||
*/
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
OstreeKernelArgs *
|
||||
_ostree_kernel_args_new (void)
|
||||
{
|
||||
OstreeKernelArgs *ret;
|
||||
ret = g_new0 (OstreeKernelArgs, 1);
|
||||
ret->order = g_ptr_array_new_with_free_func (g_free);
|
||||
ret->table = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, (GDestroyNotify)g_ptr_array_unref);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_free (OstreeKernelArgs *kargs)
|
||||
{
|
||||
if (!kargs)
|
||||
return;
|
||||
g_ptr_array_unref (kargs->order);
|
||||
g_hash_table_unref (kargs->table);
|
||||
g_free (kargs);
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_cleanup (void *loc)
|
||||
{
|
||||
_ostree_kernel_args_free (*((OstreeKernelArgs**)loc));
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_replace_take (OstreeKernelArgs *kargs,
|
||||
char *arg)
|
||||
{
|
||||
gboolean existed;
|
||||
GPtrArray *values = g_ptr_array_new_with_free_func (g_free);
|
||||
const char *value = split_keyeq (arg);
|
||||
|
||||
existed = g_hash_table_remove (kargs->table, arg);
|
||||
if (!existed)
|
||||
g_ptr_array_add (kargs->order, arg);
|
||||
g_ptr_array_add (values, g_strdup (value));
|
||||
g_hash_table_replace (kargs->table, arg, values);
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_replace (OstreeKernelArgs *kargs,
|
||||
const char *arg)
|
||||
{
|
||||
_ostree_kernel_args_replace_take (kargs, g_strdup (arg));
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_append (OstreeKernelArgs *kargs,
|
||||
const char *arg)
|
||||
{
|
||||
gboolean existed = TRUE;
|
||||
GPtrArray *values;
|
||||
char *duped = g_strdup (arg);
|
||||
const char *val = split_keyeq (duped);
|
||||
|
||||
values = g_hash_table_lookup (kargs->table, duped);
|
||||
if (!values)
|
||||
{
|
||||
values = g_ptr_array_new_with_free_func (g_free);
|
||||
existed = FALSE;
|
||||
}
|
||||
|
||||
g_ptr_array_add (values, g_strdup (val));
|
||||
|
||||
if (!existed)
|
||||
{
|
||||
g_hash_table_replace (kargs->table, duped, values);
|
||||
g_ptr_array_add (kargs->order, duped);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (duped);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_replace_argv (OstreeKernelArgs *kargs,
|
||||
char **argv)
|
||||
{
|
||||
char **strviter;
|
||||
|
||||
for (strviter = argv; strviter && *strviter; strviter++)
|
||||
{
|
||||
const char *arg = *strviter;
|
||||
_ostree_kernel_args_replace (kargs, arg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_append_argv (OstreeKernelArgs *kargs,
|
||||
char **argv)
|
||||
{
|
||||
char **strviter;
|
||||
|
||||
for (strviter = argv; strviter && *strviter; strviter++)
|
||||
{
|
||||
const char *arg = *strviter;
|
||||
_ostree_kernel_args_append (kargs, arg);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_kernel_args_parse_append (OstreeKernelArgs *kargs,
|
||||
const char *options)
|
||||
{
|
||||
char **args = NULL;
|
||||
char **iter;
|
||||
|
||||
if (!options)
|
||||
return;
|
||||
|
||||
args = g_strsplit (options, " ", -1);
|
||||
for (iter = args; *iter; iter++)
|
||||
{
|
||||
char *arg = *iter;
|
||||
_ostree_kernel_args_append (kargs, arg);
|
||||
}
|
||||
g_strfreev (args);
|
||||
}
|
||||
|
||||
OstreeKernelArgs *
|
||||
_ostree_kernel_args_from_string (const char *options)
|
||||
{
|
||||
OstreeKernelArgs *ret;
|
||||
|
||||
ret = _ostree_kernel_args_new ();
|
||||
_ostree_kernel_args_parse_append (ret, options);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char **
|
||||
_ostree_kernel_args_to_strv (OstreeKernelArgs *kargs)
|
||||
{
|
||||
GPtrArray *strv = g_ptr_array_new ();
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < kargs->order->len; i++)
|
||||
{
|
||||
const char *key = kargs->order->pdata[i];
|
||||
GPtrArray *values = g_hash_table_lookup (kargs->table, key);
|
||||
guint j;
|
||||
|
||||
g_assert (values != NULL);
|
||||
|
||||
for (j = 0; j < values->len; j++)
|
||||
{
|
||||
const char *value = values->pdata[j];
|
||||
|
||||
g_ptr_array_add (strv, g_strconcat (key, "=", value, NULL));
|
||||
}
|
||||
}
|
||||
g_ptr_array_add (strv, NULL);
|
||||
|
||||
return (char**)g_ptr_array_free (strv, FALSE);
|
||||
}
|
||||
|
||||
char *
|
||||
_ostree_kernel_args_to_string (OstreeKernelArgs *kargs)
|
||||
{
|
||||
GString *buf = g_string_new ("");
|
||||
gboolean first = TRUE;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < kargs->order->len; i++)
|
||||
{
|
||||
const char *key = kargs->order->pdata[i];
|
||||
GPtrArray *values = g_hash_table_lookup (kargs->table, key);
|
||||
guint j;
|
||||
|
||||
g_assert (values != NULL);
|
||||
|
||||
for (j = 0; j < values->len; j++)
|
||||
{
|
||||
const char *value = values->pdata[j];
|
||||
|
||||
if (first)
|
||||
first = FALSE;
|
||||
else
|
||||
g_string_append_c (buf, ' ');
|
||||
|
||||
if (value && *value)
|
||||
{
|
||||
g_string_append (buf, key);
|
||||
g_string_append_c (buf, '=');
|
||||
g_string_append (buf, value);
|
||||
}
|
||||
else
|
||||
g_string_append (buf, key);
|
||||
}
|
||||
}
|
||||
|
||||
return g_string_free (buf, FALSE);
|
||||
}
|
||||
|
||||
const char *
|
||||
_ostree_kernel_args_get_last_value (OstreeKernelArgs *kargs, const char *key)
|
||||
{
|
||||
GPtrArray *values = g_hash_table_lookup (kargs->table, key);
|
||||
|
||||
if (!values)
|
||||
return NULL;
|
||||
|
||||
g_assert (values->len > 0);
|
||||
return (char*)values->pdata[values->len-1];
|
||||
}
|
54
src/libostree/ostree-kernel-args.h
Normal file
54
src/libostree/ostree-kernel-args.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2013,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 <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _OstreeKernelArgs OstreeKernelArgs;
|
||||
|
||||
OstreeKernelArgs *_ostree_kernel_args_new (void);
|
||||
void _ostree_kernel_args_free (OstreeKernelArgs *kargs);
|
||||
void _ostree_kernel_args_cleanup (void *loc);
|
||||
void _ostree_kernel_args_replace_take (OstreeKernelArgs *kargs,
|
||||
char *key);
|
||||
void _ostree_kernel_args_replace (OstreeKernelArgs *kargs,
|
||||
const char *key);
|
||||
void _ostree_kernel_args_replace_argv (OstreeKernelArgs *kargs,
|
||||
char **argv);
|
||||
void _ostree_kernel_args_append (OstreeKernelArgs *kargs,
|
||||
const char *key);
|
||||
void _ostree_kernel_args_append_argv (OstreeKernelArgs *kargs,
|
||||
char **argv);
|
||||
|
||||
void _ostree_kernel_args_parse_append (OstreeKernelArgs *kargs,
|
||||
const char *options);
|
||||
|
||||
const char *_ostree_kernel_args_get_last_value (OstreeKernelArgs *kargs, const char *key);
|
||||
|
||||
OstreeKernelArgs * _ostree_kernel_args_from_string (const char *options);
|
||||
|
||||
char ** _ostree_kernel_args_to_strv (OstreeKernelArgs *kargs);
|
||||
char * _ostree_kernel_args_to_string (OstreeKernelArgs *kargs);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -1,83 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2013 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-ordered-hash.h"
|
||||
#include "libgsystem.h"
|
||||
|
||||
OstreeOrderedHash *
|
||||
_ostree_ordered_hash_new (void)
|
||||
{
|
||||
OstreeOrderedHash *ret;
|
||||
ret = g_new0 (OstreeOrderedHash, 1);
|
||||
ret->order = g_ptr_array_new_with_free_func (g_free);
|
||||
ret->table = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_ordered_hash_free (OstreeOrderedHash *ohash)
|
||||
{
|
||||
if (!ohash)
|
||||
return;
|
||||
g_ptr_array_unref (ohash->order);
|
||||
g_hash_table_unref (ohash->table);
|
||||
g_free (ohash);
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_ordered_hash_cleanup (void *loc)
|
||||
{
|
||||
_ostree_ordered_hash_free (*((OstreeOrderedHash**)loc));
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_ordered_hash_replace_key_take (OstreeOrderedHash *ohash,
|
||||
char *key,
|
||||
const char *value)
|
||||
{
|
||||
gboolean existed;
|
||||
|
||||
existed = g_hash_table_remove (ohash->table, key);
|
||||
if (!existed)
|
||||
g_ptr_array_add (ohash->order, key);
|
||||
g_hash_table_insert (ohash->table, key, (char*)value);
|
||||
}
|
||||
|
||||
void
|
||||
_ostree_ordered_hash_replace_key (OstreeOrderedHash *ohash,
|
||||
const char *key,
|
||||
const char *val)
|
||||
{
|
||||
GString *buf;
|
||||
gsize keylen;
|
||||
char *valp;
|
||||
char *valblock;
|
||||
|
||||
buf = g_string_new (key);
|
||||
keylen = buf->len;
|
||||
g_string_append_c (buf, '\0');
|
||||
g_string_append (buf, val);
|
||||
valblock = g_string_free (buf, FALSE);
|
||||
valp = valblock + keylen + 1;
|
||||
|
||||
_ostree_ordered_hash_replace_key_take (ohash, valblock, valp);
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
||||
*
|
||||
* Copyright (C) 2013 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 <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct {
|
||||
GPtrArray *order;
|
||||
GHashTable *table;
|
||||
} OstreeOrderedHash;
|
||||
|
||||
OstreeOrderedHash *_ostree_ordered_hash_new (void);
|
||||
void _ostree_ordered_hash_free (OstreeOrderedHash *ohash);
|
||||
void _ostree_ordered_hash_cleanup (void *loc);
|
||||
void _ostree_ordered_hash_replace_key_take (OstreeOrderedHash *ohash,
|
||||
char *key,
|
||||
const char *value);
|
||||
void _ostree_ordered_hash_replace_key (OstreeOrderedHash *ohash,
|
||||
const char *key,
|
||||
const char *val);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -601,7 +601,7 @@ install_deployment_kernel (OstreeSysroot *sysroot,
|
||||
gs_free char *version_key = NULL;
|
||||
gs_free char *ostree_kernel_arg = NULL;
|
||||
gs_free char *options_key = NULL;
|
||||
__attribute__((cleanup(_ostree_ordered_hash_cleanup))) OstreeOrderedHash *ohash = NULL;
|
||||
__attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL;
|
||||
const char *val;
|
||||
OstreeBootconfigParser *bootconfig;
|
||||
gsize len;
|
||||
@ -693,12 +693,14 @@ install_deployment_kernel (OstreeSysroot *sysroot,
|
||||
}
|
||||
|
||||
val = ostree_bootconfig_parser_get (bootconfig, "options");
|
||||
ostree_kernel_arg = g_strdup_printf ("/ostree/boot.%d/%s/%s/%d",
|
||||
|
||||
ostree_kernel_arg = g_strdup_printf ("ostree=/ostree/boot.%d/%s/%s/%d",
|
||||
new_bootversion, osname, bootcsum,
|
||||
ostree_deployment_get_bootserial (deployment));
|
||||
ohash = _ostree_sysroot_parse_kernel_args (val);
|
||||
_ostree_ordered_hash_replace_key (ohash, "ostree", ostree_kernel_arg);
|
||||
options_key = _ostree_sysroot_kernel_arg_string_serialize (ohash);
|
||||
kargs = _ostree_kernel_args_from_string (val);
|
||||
_ostree_kernel_args_replace_take (kargs, ostree_kernel_arg);
|
||||
ostree_kernel_arg = NULL;
|
||||
options_key = _ostree_kernel_args_to_string (kargs);
|
||||
ostree_bootconfig_parser_set (bootconfig, "options", options_key);
|
||||
|
||||
if (!ostree_bootconfig_parser_write (ostree_deployment_get_bootconfig (deployment), bootconfpath,
|
||||
@ -773,14 +775,14 @@ bootconfig_counts_for_deployment_list (GPtrArray *deployments)
|
||||
const char *boot_options = ostree_bootconfig_parser_get (bootconfig, "options");
|
||||
GChecksum *bootconfig_checksum = g_checksum_new (G_CHECKSUM_SHA256);
|
||||
const char *bootconfig_checksum_str;
|
||||
__attribute__((cleanup(_ostree_ordered_hash_cleanup))) OstreeOrderedHash *ohash = NULL;
|
||||
__attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL;
|
||||
gs_free char *boot_options_without_ostree = NULL;
|
||||
guint count;
|
||||
|
||||
/* We checksum the kernel arguments *except* ostree= */
|
||||
ohash = _ostree_sysroot_parse_kernel_args (boot_options);
|
||||
_ostree_ordered_hash_replace_key (ohash, "ostree", "");
|
||||
boot_options_without_ostree = _ostree_sysroot_kernel_arg_string_serialize (ohash);
|
||||
kargs = _ostree_kernel_args_from_string (boot_options);
|
||||
_ostree_kernel_args_replace (kargs, "ostree");
|
||||
boot_options_without_ostree = _ostree_kernel_args_to_string (kargs);
|
||||
|
||||
g_checksum_update (bootconfig_checksum, (guint8*)bootcsum, strlen (bootcsum));
|
||||
g_checksum_update (bootconfig_checksum, (guint8*)boot_options_without_ostree,
|
||||
@ -1049,13 +1051,13 @@ allocate_deployserial (OstreeSysroot *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_sysroot_deploy_one_tree:
|
||||
* ostree_sysroot_deploy_tree:
|
||||
* @self: Sysroot
|
||||
* @osname: (allow-none): osname to use for merge deployment
|
||||
* @revision: Checksum to add
|
||||
* @origin: (allow-none): Origin to use for upgrades
|
||||
* @add_kernel_argv: (allow-none): Append these arguments to kernel configuration
|
||||
* @provided_merge_deployment: (allow-none): Use this deployment for merge path
|
||||
* @override_kernel_argv: (allow-none) (array zero-terminated=1) (element-type utf8): Use these as kernel arguments; if %NULL, inherit options from provided_merge_deployment
|
||||
* @out_new_deployment: (out): The new deployment path
|
||||
* @cancellable: Cancellable
|
||||
* @error: Error
|
||||
@ -1064,15 +1066,15 @@ allocate_deployserial (OstreeSysroot *self,
|
||||
* way merge with @provided_merge_deployment for configuration.
|
||||
*/
|
||||
gboolean
|
||||
ostree_sysroot_deploy_one_tree (OstreeSysroot *self,
|
||||
const char *osname,
|
||||
const char *revision,
|
||||
GKeyFile *origin,
|
||||
char **add_kernel_argv,
|
||||
OstreeDeployment *provided_merge_deployment,
|
||||
OstreeDeployment **out_new_deployment,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
ostree_sysroot_deploy_tree (OstreeSysroot *self,
|
||||
const char *osname,
|
||||
const char *revision,
|
||||
GKeyFile *origin,
|
||||
OstreeDeployment *provided_merge_deployment,
|
||||
char **override_kernel_argv,
|
||||
OstreeDeployment **out_new_deployment,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gint new_deployserial;
|
||||
@ -1160,30 +1162,17 @@ ostree_sysroot_deploy_one_tree (OstreeSysroot *self,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* We have inherited kernel arguments from the previous deployment;
|
||||
* now, override/extend that with arguments provided by the command
|
||||
* line.
|
||||
*
|
||||
* After this, install_deployment_kernel() will set the other boot
|
||||
/* After this, install_deployment_kernel() will set the other boot
|
||||
* options and write it out to disk.
|
||||
*/
|
||||
if (add_kernel_argv)
|
||||
if (override_kernel_argv)
|
||||
{
|
||||
char **strviter;
|
||||
__attribute__((cleanup(_ostree_ordered_hash_cleanup))) OstreeOrderedHash *ohash = NULL;
|
||||
__attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL;
|
||||
gs_free char *new_options = NULL;
|
||||
|
||||
ohash = _ostree_sysroot_parse_kernel_args (ostree_bootconfig_parser_get (bootconfig, "options"));
|
||||
|
||||
for (strviter = add_kernel_argv; *strviter; strviter++)
|
||||
{
|
||||
char *karg = g_strdup (*strviter);
|
||||
const char *val = _ostree_sysroot_split_keyeq (karg);
|
||||
|
||||
_ostree_ordered_hash_replace_key_take (ohash, karg, val);
|
||||
}
|
||||
|
||||
new_options = _ostree_sysroot_kernel_arg_string_serialize (ohash);
|
||||
kargs = _ostree_kernel_args_new ();
|
||||
_ostree_kernel_args_append_argv (kargs, override_kernel_argv);
|
||||
new_options = _ostree_kernel_args_to_string (kargs);
|
||||
ostree_bootconfig_parser_set (bootconfig, "options", new_options);
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "ostree.h"
|
||||
#include "ostree-ordered-hash.h"
|
||||
#include "ostree-kernel-args.h"
|
||||
#include "ostree-bootloader.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@ -75,12 +75,6 @@ _ostree_sysroot_get_devino (GFile *path,
|
||||
|
||||
char *_ostree_sysroot_join_lines (GPtrArray *lines);
|
||||
|
||||
char *_ostree_sysroot_split_keyeq (char *str);
|
||||
|
||||
OstreeOrderedHash *_ostree_sysroot_parse_kernel_args (const char *options);
|
||||
|
||||
char * _ostree_sysroot_kernel_arg_string_serialize (OstreeOrderedHash *ohash);
|
||||
|
||||
OstreeBootloader *_ostree_sysroot_query_bootloader (OstreeSysroot *sysroot);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -884,9 +884,9 @@ _ostree_sysroot_join_lines (GPtrArray *lines)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_kernel_commandline (OstreeOrderedHash **out_args,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
parse_kernel_commandline (OstreeKernelArgs **out_args,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gs_unref_object GFile *proc_cmdline = g_file_new_for_path ("/proc/cmdline");
|
||||
@ -897,8 +897,10 @@ parse_kernel_commandline (OstreeOrderedHash **out_args,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
g_strchomp (contents);
|
||||
|
||||
ret = TRUE;
|
||||
*out_args = _ostree_sysroot_parse_kernel_args (contents);;
|
||||
*out_args = _ostree_kernel_args_from_string (contents);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
@ -919,7 +921,7 @@ find_booted_deployment (OstreeSysroot *self,
|
||||
gs_unref_object OstreeSysroot *active_deployment_root = ostree_sysroot_new_default ();
|
||||
guint i;
|
||||
const char *bootlink_arg;
|
||||
__attribute__((cleanup(_ostree_ordered_hash_cleanup))) OstreeOrderedHash *kernel_args = NULL;
|
||||
__attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kernel_args = NULL;
|
||||
guint32 root_device;
|
||||
guint64 root_inode;
|
||||
|
||||
@ -930,7 +932,7 @@ find_booted_deployment (OstreeSysroot *self,
|
||||
if (!parse_kernel_commandline (&kernel_args, cancellable, error))
|
||||
goto out;
|
||||
|
||||
bootlink_arg = g_hash_table_lookup (kernel_args->table, "ostree");
|
||||
bootlink_arg = _ostree_kernel_args_get_last_value (kernel_args, "ostree");
|
||||
if (bootlink_arg)
|
||||
{
|
||||
for (i = 0; i < deployments->len; i++)
|
||||
@ -969,88 +971,6 @@ find_booted_deployment (OstreeSysroot *self,
|
||||
return ret;
|
||||
}
|
||||
|
||||
OstreeOrderedHash *
|
||||
_ostree_sysroot_parse_kernel_args (const char *options)
|
||||
{
|
||||
OstreeOrderedHash *ret;
|
||||
char **args;
|
||||
char **iter;
|
||||
|
||||
ret = _ostree_ordered_hash_new ();
|
||||
|
||||
if (!options)
|
||||
return ret;
|
||||
|
||||
args = g_strsplit (options, " ", -1);
|
||||
for (iter = args; *iter; iter++)
|
||||
{
|
||||
char *arg = *iter;
|
||||
char *val;
|
||||
|
||||
val = _ostree_sysroot_split_keyeq (arg);
|
||||
|
||||
g_ptr_array_add (ret->order, arg);
|
||||
g_hash_table_insert (ret->table, arg, val);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Modify @arg which should be of the form key=value to make @arg just
|
||||
* contain key. Return a pointer to the start of value.
|
||||
*/
|
||||
char *
|
||||
_ostree_sysroot_split_keyeq (char *arg)
|
||||
{
|
||||
char *eq;
|
||||
|
||||
eq = strchr (arg, '=');
|
||||
if (eq)
|
||||
{
|
||||
/* Note key/val are in one malloc block,
|
||||
* so we don't free val...
|
||||
*/
|
||||
*eq = '\0';
|
||||
return eq+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ...and this allows us to insert a constant
|
||||
* string.
|
||||
*/
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
_ostree_sysroot_kernel_arg_string_serialize (OstreeOrderedHash *ohash)
|
||||
{
|
||||
guint i;
|
||||
GString *buf = g_string_new ("");
|
||||
gboolean first = TRUE;
|
||||
|
||||
for (i = 0; i < ohash->order->len; i++)
|
||||
{
|
||||
const char *key = ohash->order->pdata[i];
|
||||
const char *val = g_hash_table_lookup (ohash->table, key);
|
||||
|
||||
g_assert (val != NULL);
|
||||
|
||||
if (first)
|
||||
first = FALSE;
|
||||
else
|
||||
g_string_append_c (buf, ' ');
|
||||
|
||||
if (*val)
|
||||
g_string_append_printf (buf, "%s=%s", key, val);
|
||||
else
|
||||
g_string_append (buf, key);
|
||||
}
|
||||
|
||||
return g_string_free (buf, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* ostree_sysroot_get_merge_deployment:
|
||||
* @self: Sysroot
|
||||
|
@ -71,15 +71,15 @@ gboolean ostree_sysroot_write_deployments (OstreeSysroot *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_sysroot_deploy_one_tree (OstreeSysroot *self,
|
||||
const char *osname,
|
||||
const char *revision,
|
||||
GKeyFile *origin,
|
||||
char **add_kernel_argv,
|
||||
OstreeDeployment *provided_merge_deployment,
|
||||
OstreeDeployment **out_new_deployment,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean ostree_sysroot_deploy_tree (OstreeSysroot *self,
|
||||
const char *osname,
|
||||
const char *revision,
|
||||
GKeyFile *origin,
|
||||
OstreeDeployment *provided_merge_deployment,
|
||||
char **override_kernel_argv,
|
||||
OstreeDeployment **out_new_deployment,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
OstreeDeployment *ostree_sysroot_get_merge_deployment (OstreeSysroot *self,
|
||||
const char *osname);
|
||||
|
@ -27,11 +27,14 @@
|
||||
#include "ostree.h"
|
||||
#include "otutil.h"
|
||||
|
||||
#include "../libostree/ostree-kernel-args.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
static gboolean opt_no_bootloader;
|
||||
static gboolean opt_retain;
|
||||
static char **opt_kernel_argv;
|
||||
static char **opt_kernel_argv_append;
|
||||
static gboolean opt_kernel_proc_cmdline;
|
||||
static char *opt_osname;
|
||||
static char *opt_origin_path;
|
||||
@ -42,7 +45,8 @@ static GOptionEntry options[] = {
|
||||
{ "no-bootloader", 0, 0, G_OPTION_ARG_NONE, &opt_no_bootloader, "Don't update bootloader", NULL },
|
||||
{ "retain", 0, 0, G_OPTION_ARG_NONE, &opt_retain, "Do not delete previous deployment", NULL },
|
||||
{ "karg-proc-cmdline", 0, 0, G_OPTION_ARG_NONE, &opt_kernel_proc_cmdline, "Import current /proc/cmdline", NULL },
|
||||
{ "karg", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_kernel_argv, "Set kernel argument, like --karg=root=/dev/sda1", NULL },
|
||||
{ "karg", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_kernel_argv, "Set kernel argument, like root=/dev/sda1; this overrides any earlier argument with the same name", "KEY=VALUE" },
|
||||
{ "karg-append", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_kernel_argv_append, "Append kernel argument; useful with e.g. console= that can be used multiple times", "KEY=VALUE" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@ -58,7 +62,7 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeSysroot *sysroot, GCancell
|
||||
gs_unref_object OstreeDeployment *new_deployment = NULL;
|
||||
gs_unref_object OstreeDeployment *merge_deployment = NULL;
|
||||
gs_free char *revision = NULL;
|
||||
gs_unref_ptrarray GPtrArray *kargs = NULL;
|
||||
__attribute__((cleanup(_ostree_kernel_args_cleanup))) OstreeKernelArgs *kargs = NULL;
|
||||
|
||||
context = g_option_context_new ("REFSPEC - Checkout revision REFSPEC as the new default deployment");
|
||||
|
||||
@ -121,51 +125,56 @@ ot_admin_builtin_deploy (int argc, char **argv, OstreeSysroot *sysroot, GCancell
|
||||
goto out;
|
||||
}
|
||||
|
||||
kargs = g_ptr_array_new_with_free_func (g_free);
|
||||
kargs = _ostree_kernel_args_new ();
|
||||
|
||||
/* If they want the current kernel's args, they very likely don't
|
||||
* want the ones from the merge.
|
||||
*/
|
||||
if (opt_kernel_proc_cmdline)
|
||||
{
|
||||
gs_unref_object GFile *proc_cmdline_path = g_file_new_for_path ("/proc/cmdline");
|
||||
gs_free char *proc_cmdline = NULL;
|
||||
gsize proc_cmdline_len = 0;
|
||||
gs_strfreev char **proc_cmdline_args = NULL;
|
||||
char **strviter;
|
||||
|
||||
if (!g_file_load_contents (proc_cmdline_path, cancellable,
|
||||
&proc_cmdline, &proc_cmdline_len,
|
||||
NULL, error))
|
||||
goto out;
|
||||
|
||||
g_strchomp (proc_cmdline);
|
||||
|
||||
proc_cmdline_args = g_strsplit (proc_cmdline, " ", -1);
|
||||
for (strviter = proc_cmdline_args; strviter && *strviter; strviter++)
|
||||
{
|
||||
char *arg = *strviter;
|
||||
g_strchomp (arg);
|
||||
g_ptr_array_add (kargs, arg);
|
||||
*strviter = NULL; /* transfer ownership */
|
||||
}
|
||||
_ostree_kernel_args_replace_argv (kargs, proc_cmdline_args);
|
||||
}
|
||||
else if (merge_deployment)
|
||||
{
|
||||
OstreeBootconfigParser *bootconfig = ostree_deployment_get_bootconfig (merge_deployment);
|
||||
gs_strfreev char **previous_args = g_strsplit (ostree_bootconfig_parser_get (bootconfig, "options"), " ", -1);
|
||||
|
||||
_ostree_kernel_args_replace_argv (kargs, previous_args);
|
||||
}
|
||||
|
||||
if (opt_kernel_argv)
|
||||
{
|
||||
char **strviter;
|
||||
for (strviter = opt_kernel_argv; strviter && *strviter; strviter++)
|
||||
{
|
||||
const char *arg = *strviter;
|
||||
char *val = g_strdup (arg);
|
||||
g_strchomp (val);
|
||||
g_ptr_array_add (kargs, val);
|
||||
}
|
||||
_ostree_kernel_args_replace_argv (kargs, opt_kernel_argv);
|
||||
}
|
||||
|
||||
g_ptr_array_add (kargs, NULL);
|
||||
if (opt_kernel_argv_append)
|
||||
{
|
||||
_ostree_kernel_args_append_argv (kargs, opt_kernel_argv_append);
|
||||
}
|
||||
|
||||
if (!ostree_sysroot_deploy_one_tree (sysroot,
|
||||
opt_osname, revision, origin,
|
||||
(char**)kargs->pdata, merge_deployment,
|
||||
&new_deployment,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
{
|
||||
gs_strfreev char **kargs_strv = _ostree_kernel_args_to_strv (kargs);
|
||||
|
||||
if (!ostree_sysroot_deploy_tree (sysroot,
|
||||
opt_osname, revision, origin,
|
||||
merge_deployment, kargs_strv,
|
||||
&new_deployment,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ot_admin_complete_deploy_one (sysroot, opt_osname,
|
||||
new_deployment, merge_deployment, opt_retain,
|
||||
|
@ -147,12 +147,12 @@ ot_admin_builtin_upgrade (int argc, char **argv, OstreeSysroot *sysroot, GCancel
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ostree_sysroot_deploy_one_tree (sysroot,
|
||||
opt_osname, new_revision, origin,
|
||||
NULL,
|
||||
merge_deployment,
|
||||
&new_deployment,
|
||||
cancellable, error))
|
||||
if (!ostree_sysroot_deploy_tree (sysroot,
|
||||
opt_osname, new_revision, origin,
|
||||
merge_deployment,
|
||||
NULL,
|
||||
&new_deployment,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ot_admin_complete_deploy_one (sysroot, opt_osname,
|
||||
|
@ -52,3 +52,13 @@ ostree admin --sysroot=sysroot deploy --karg-proc-cmdline --os=testos testos:tes
|
||||
assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'options.*root=.'
|
||||
|
||||
echo "ok deploy --karg-proc-cmdline"
|
||||
|
||||
ostree admin --sysroot=sysroot status
|
||||
ostree admin --sysroot=sysroot undeploy 0
|
||||
|
||||
ostree admin --sysroot=sysroot deploy --os=testos --karg-append=APPENDARG=VALAPPEND --karg-append=APPENDARG=2NDAPPEND testos:testos/buildmaster/x86_64-runtime
|
||||
assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'options.*FOO=BAR'
|
||||
assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'options.*TESTARG=TESTVALUE'
|
||||
assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'options.*APPENDARG=VALAPPEND .*APPENDARG=2NDAPPEND'
|
||||
|
||||
echo "ok deploy --karg-append"
|
||||
|
Loading…
Reference in New Issue
Block a user