libostree: Nearly complete move of API into OstreeSysroot

Move the deployment code too.
This commit is contained in:
Colin Walters committed 2013-09-15 20:16:20 -04:00
1 parent 95f07d486a
commit c6292942ff
17 files changed
+399 -542

No files matched your search

+240
View File
@@ -839,3 +839,243 @@ _ostree_sysroot_join_lines (GPtrArray *lines)
}
return g_string_free (buf, FALSE);
}
static gboolean
parse_kernel_commandline (OstreeOrderedHash **out_args,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
gs_unref_object GFile *proc_cmdline = g_file_new_for_path ("/proc/cmdline");
gs_free char *contents = NULL;
gsize len;
if (!g_file_load_contents (proc_cmdline, cancellable, &contents, &len, NULL,
error))
goto out;
ret = TRUE;
*out_args = _ostree_sysroot_parse_kernel_args (contents);;
out:
return ret;
}
/**
* ostree_sysroot_find_booted_deployment:
* @target_sysroot: Root directory
* @deployments: (element-type OstreeDeployment): Loaded deployments
* @out_deployment: (out): The currently booted deployment
* @cancellable:
* @error:
*
* If the system is currently booted into a deployment in
* @deployments, set @out_deployment. Note that if @target_sysroot is
* not equal to "/", @out_deployment will always be set to %NULL.
*/
gboolean
ostree_sysroot_find_booted_deployment (OstreeSysroot *self,
GPtrArray *deployments,
OstreeDeployment **out_deployment,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
gs_unref_object GFile *active_root = g_file_new_for_path ("/");
gs_unref_object OstreeSysroot *active_deployment_root = ostree_sysroot_new_default ();
gs_unref_object OstreeDeployment *ret_deployment = NULL;
if (g_file_equal (active_root, self->path))
{
guint i;
const char *bootlink_arg;
__attribute__((cleanup(_ostree_ordered_hash_cleanup))) OstreeOrderedHash *kernel_args = NULL;
guint32 root_device;
guint64 root_inode;
if (!_ostree_sysroot_get_devino (active_root, &root_device, &root_inode,
cancellable, error))
goto out;
if (!parse_kernel_commandline (&kernel_args, cancellable, error))
goto out;
bootlink_arg = g_hash_table_lookup (kernel_args->table, "ostree");
if (bootlink_arg)
{
for (i = 0; i < deployments->len; i++)
{
OstreeDeployment *deployment = deployments->pdata[i];
gs_unref_object GFile *deployment_path = ostree_sysroot_get_deployment_directory (active_deployment_root, deployment);
guint32 device;
guint64 inode;
if (!_ostree_sysroot_get_devino (deployment_path, &device, &inode,
cancellable, error))
goto out;
if (device == root_device && inode == root_inode)
{
ret_deployment = g_object_ref (deployment);
break;
}
}
if (ret_deployment == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Unexpected state: ostree= kernel argument found, but / is not a deployment root");
goto out;
}
}
else
{
/* Not an ostree system */
}
}
ret = TRUE;
ot_transfer_out_value (out_deployment, &ret_deployment);
out:
return ret;
}
gboolean
ostree_sysroot_require_deployment_or_osname (OstreeSysroot *sysroot,
GPtrArray *deployments,
const char *osname,
OstreeDeployment **out_deployment,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
gs_unref_object OstreeDeployment *ret_deployment = NULL;
if (!ostree_sysroot_find_booted_deployment (sysroot, deployments, &ret_deployment,
cancellable, error))
goto out;
if (ret_deployment == NULL && osname == NULL)
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Not currently booted into an OSTree system and no --os= argument given");
goto out;
}
ret = TRUE;
ot_transfer_out_value (out_deployment, &ret_deployment);
out:
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);
}
OstreeDeployment *
ostree_sysroot_get_merge_deployment (GPtrArray *deployments,
const char *osname,
OstreeDeployment *booted_deployment)
{
g_return_val_if_fail (osname != NULL || booted_deployment != NULL, NULL);
if (osname == NULL)
osname = ostree_deployment_get_osname (booted_deployment);
if (booted_deployment &&
g_strcmp0 (ostree_deployment_get_osname (booted_deployment), osname) == 0)
{
return g_object_ref (booted_deployment);
}
else
{
guint i;
for (i = 0; i < deployments->len; i++)
{
OstreeDeployment *deployment = deployments->pdata[i];
if (strcmp (ostree_deployment_get_osname (deployment), osname) != 0)
continue;
return g_object_ref (deployment);
}
}
return NULL;
}