[ostree] admin: Don't delete the running deployment
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree] admin: Don't delete the running deployment
- Date: Tue, 5 Mar 2013 03:53:12 +0000 (UTC)
commit 30d46f9a022f7688796d6c3342f19d8e7186e551
Author: Colin Walters <walters verbum org>
Date: Mon Mar 4 18:00:23 2013 -0500
admin: Don't delete the running deployment
https://bugzilla.gnome.org/show_bug.cgi?id=694762
src/ostree/ot-admin-builtin-prune.c | 74 +---------
src/ostree/ot-admin-functions.c | 251 +++++++++++++++++++++++++++++++++++
src/ostree/ot-admin-functions.h | 12 ++
3 files changed, 271 insertions(+), 66 deletions(-)
---
diff --git a/src/ostree/ot-admin-builtin-prune.c b/src/ostree/ot-admin-builtin-prune.c
index 2a3c42f..4d60099 100644
--- a/src/ostree/ot-admin-builtin-prune.c
+++ b/src/ostree/ot-admin-builtin-prune.c
@@ -35,67 +35,6 @@ static GOptionEntry options[] = {
{ NULL }
};
-static gboolean
-list_deployments (GFile *from_dir,
- GPtrArray *inout_deployments,
- GCancellable *cancellable,
- GError **error)
-{
- gboolean ret = FALSE;
- GError *temp_error = NULL;
- ot_lobj GFileEnumerator *dir_enum = NULL;
- ot_lobj GFileInfo *file_info = NULL;
-
- dir_enum = g_file_enumerate_children (from_dir, OSTREE_GIO_FAST_QUERYINFO,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- NULL, error);
- if (!dir_enum)
- goto out;
-
- while ((file_info = g_file_enumerator_next_file (dir_enum, cancellable, error)) != NULL)
- {
- const char *name;
- ot_lobj GFile *child = NULL;
- ot_lobj GFile *possible_etc = NULL;
- ot_lobj GFile *possible_usr = NULL;
-
- name = g_file_info_get_name (file_info);
-
- if (g_str_has_suffix (name, "-etc"))
- goto next;
- if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
- goto next;
-
- child = g_file_get_child (from_dir, name);
-
- possible_etc = ot_gfile_get_child_strconcat (from_dir, name, "-etc", NULL);
- /* Bit of a hack... */
- possible_usr = g_file_get_child (child, "usr");
-
- if (g_file_query_exists (possible_etc, cancellable))
- g_ptr_array_add (inout_deployments, g_file_get_child (from_dir, name));
- else if (g_file_query_exists (possible_usr, cancellable))
- goto next;
- else
- {
- if (!list_deployments (child, inout_deployments,
- cancellable, error))
- goto out;
- }
-
- next:
- g_clear_object (&file_info);
- }
- if (temp_error != NULL)
- {
- g_propagate_error (error, temp_error);
- goto out;
- }
-
- ret = TRUE;
- out:
- return ret;
-}
gboolean
ot_admin_builtin_prune (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, GError **error)
@@ -109,7 +48,9 @@ ot_admin_builtin_prune (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, G
ot_lobj GFile *deploy_dir = NULL;
ot_lobj GFile *current_deployment = NULL;
ot_lobj GFile *previous_deployment = NULL;
+ ot_lobj GFile *active_deployment = NULL;
ot_lptrarray GPtrArray *deployments = NULL;
+ gs_free char *active_osname = NULL;
__attribute__((unused)) GCancellable *cancellable = NULL;
context = g_option_context_new ("OSNAME - Delete untagged deployments and repository objects");
@@ -127,16 +68,16 @@ ot_admin_builtin_prune (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, G
osname = argv[1];
- deploy_dir = ot_gfile_get_child_build_path (ostree_dir, "deploy", osname, NULL);
-
- deployments = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
- if (!list_deployments (deploy_dir, deployments, cancellable, error))
+ if (!ot_admin_list_deployments (ostree_dir, osname, &deployments,
+ cancellable, error))
goto out;
if (!ot_admin_get_current_deployment (ostree_dir, osname, ¤t_deployment,
cancellable, error));
if (!ot_admin_get_previous_deployment (ostree_dir, osname, &previous_deployment,
cancellable, error));
+ if (!ot_admin_get_active_deployment (ostree_dir, &active_osname, &active_deployment,
+ cancellable, error));
for (i = 0; i < deployments->len; i++)
{
@@ -145,7 +86,8 @@ ot_admin_builtin_prune (int argc, char **argv, OtAdminBuiltinOpts *admin_opts, G
ot_lobj GFile *parent = NULL;
if ((current_deployment && g_file_equal (deployment, current_deployment))
- || (previous_deployment && g_file_equal (deployment, previous_deployment)))
+ || (previous_deployment && g_file_equal (deployment, previous_deployment))
+ || (active_deployment && g_file_equal (deployment, active_deployment)))
continue;
parent = g_file_get_parent (deployment);
diff --git a/src/ostree/ot-admin-functions.c b/src/ostree/ot-admin-functions.c
index 6cc4ff0..c642ab8 100644
--- a/src/ostree/ot-admin-functions.c
+++ b/src/ostree/ot-admin-functions.c
@@ -181,6 +181,257 @@ ot_admin_get_previous_deployment (GFile *ostree_dir,
cancellable, error);
}
+/*
+static gboolean
+ot_admin_list_osnames (GFile *ostree_dir,
+ GPtrArray **out_osnames,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ ot_lobj GFileEnumerator *dir_enum = NULL;
+ ot_lobj GFileInfo *file_info = NULL;
+ ot_lobj GFile *deploy_dir = NULL;
+ ot_lptrarray GPtrArray *ret_osnames = NULL;
+ GError *temp_error = NULL;
+
+ deploy_dir = g_file_get_child (ostree_dir, "deploy");
+
+ dir_enum = g_file_enumerate_children (deploy_dir, OSTREE_GIO_FAST_QUERYINFO,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL, error);
+ if (!dir_enum)
+ goto out;
+
+ while ((file_info = g_file_enumerator_next_file (dir_enum, NULL, error)) != NULL)
+ {
+ if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
+ {
+ char *name = g_strdup (g_file_info_get_name (file_info));
+ g_ptr_array_add (ret_osnames, name);
+ }
+ g_clear_object (&file_info);
+ }
+
+ if (temp_error != NULL)
+ {
+ g_propagate_error (error, temp_error);
+ goto out;
+ }
+
+ ret = TRUE;
+ ot_transfer_out_value (out_osnames, &ret_osnames);
+ out:
+ return ret;
+}
+*/
+
+static gboolean
+list_deployments_internal (GFile *from_dir,
+ GPtrArray *inout_deployments,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GError *temp_error = NULL;
+ ot_lobj GFileEnumerator *dir_enum = NULL;
+ ot_lobj GFileInfo *file_info = NULL;
+
+ dir_enum = g_file_enumerate_children (from_dir, OSTREE_GIO_FAST_QUERYINFO,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL, error);
+ if (!dir_enum)
+ goto out;
+
+ while ((file_info = g_file_enumerator_next_file (dir_enum, cancellable, error)) != NULL)
+ {
+ const char *name;
+ ot_lobj GFile *child = NULL;
+ ot_lobj GFile *possible_etc = NULL;
+ ot_lobj GFile *possible_usr = NULL;
+
+ name = g_file_info_get_name (file_info);
+
+ if (g_str_has_suffix (name, "-etc"))
+ goto next;
+ if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_DIRECTORY)
+ goto next;
+
+ child = g_file_get_child (from_dir, name);
+
+ possible_etc = ot_gfile_get_child_strconcat (from_dir, name, "-etc", NULL);
+ /* Bit of a hack... */
+ possible_usr = g_file_get_child (child, "usr");
+
+ if (g_file_query_exists (possible_etc, cancellable))
+ g_ptr_array_add (inout_deployments, g_file_get_child (from_dir, name));
+ else if (g_file_query_exists (possible_usr, cancellable))
+ goto next;
+ else
+ {
+ if (!list_deployments_internal (child, inout_deployments,
+ cancellable, error))
+ goto out;
+ }
+
+ next:
+ g_clear_object (&file_info);
+ }
+ if (temp_error != NULL)
+ {
+ g_propagate_error (error, temp_error);
+ goto out;
+ }
+
+ ret = TRUE;
+ out:
+ return ret;
+}
+
+gboolean
+ot_admin_list_deployments (GFile *ostree_dir,
+ const char *osname,
+ GPtrArray **out_deployments,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ ot_lobj GFileEnumerator *dir_enum = NULL;
+ ot_lobj GFileInfo *file_info = NULL;
+ ot_lobj GFile *osdir = NULL;
+ ot_lptrarray GPtrArray *ret_deployments = NULL;
+
+ osdir = ot_gfile_get_child_build_path (ostree_dir, "deploy", osname, NULL);
+ ret_deployments = g_ptr_array_new_with_free_func (g_object_unref);
+
+ if (!list_deployments_internal (osdir, ret_deployments, cancellable, error))
+ goto out;
+
+ ret = TRUE;
+ ot_transfer_out_value (out_deployments, &ret_deployments);
+ out:
+ return ret;
+}
+
+static gboolean
+ot_admin_get_booted_os (char **out_osname,
+ char **out_tree,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ gs_free char *ret_osname = NULL;
+ gs_free char *ret_tree = NULL;
+ gs_free char *cmdline_contents = NULL;
+ const char *iter;
+ gsize len;
+
+ if (!g_file_get_contents ("/proc/cmdline", &cmdline_contents, &len,
+ error))
+ goto out;
+
+ iter = cmdline_contents;
+ do
+ {
+ const char *next = strchr (iter, ' ');
+ if (next)
+ next += 1;
+ if (g_str_has_prefix (iter, "ostree="))
+ {
+ const char *slash = strchr (iter, '/');
+ if (slash)
+ {
+ const char *start = iter + strlen ("ostree=");
+ ret_osname = g_strndup (start, slash - start);
+ if (next)
+ ret_tree = g_strndup (slash + 1, next - slash - 1);
+ else
+ ret_tree = g_strdup (slash + 1);
+ break;
+ }
+ }
+ iter = next;
+ }
+ while (iter != NULL);
+
+ ret = TRUE;
+ out:
+ ot_transfer_out_value (out_osname, &ret_osname);
+ ot_transfer_out_value (out_tree, &ret_tree);
+ return ret;
+}
+
+gboolean
+ot_admin_get_active_deployment (GFile *ostree_dir,
+ char **out_osname,
+ GFile **out_deployment,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ ot_lptrarray GPtrArray *osnames = NULL;
+ ot_lptrarray GPtrArray *deployments = NULL;
+ gs_free char *ret_osname = NULL;
+ gs_unref_object GFile *ret_deployment = NULL;
+
+ if (!ot_admin_get_booted_os (&ret_osname, NULL, cancellable, error))
+ goto out;
+
+ if (ret_osname != NULL)
+ {
+ gs_unref_object GFile *rootfs_path = NULL;
+ gs_unref_object GFileInfo *rootfs_info = NULL;
+ guint32 root_dev;
+ guint64 root_inode;
+ guint i;
+
+ rootfs_path = g_file_new_for_path ("/");
+ rootfs_info = g_file_query_info (rootfs_path, OSTREE_GIO_FAST_QUERYINFO,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ cancellable, error);
+ if (!rootfs_info)
+ goto out;
+
+ root_dev = g_file_info_get_attribute_uint32 (rootfs_info, "unix::device");
+ root_inode = g_file_info_get_attribute_uint64 (rootfs_info, "unix::inode");
+
+ if (!ot_admin_list_deployments (ostree_dir, ret_osname, &deployments,
+ cancellable, error))
+ goto out;
+
+ for (i = 0; i < deployments->len; i++)
+ {
+ GFile *deployment = deployments->pdata[i];
+ gs_unref_object GFileInfo *deployment_info = NULL;
+ guint32 deploy_dev;
+ guint64 deploy_inode;
+
+ deployment_info = g_file_query_info (rootfs_path, OSTREE_GIO_FAST_QUERYINFO,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ cancellable, error);
+ if (!deployment_info)
+ goto out;
+
+ deploy_dev = g_file_info_get_attribute_uint32 (deployment_info, "unix::device");
+ deploy_inode = g_file_info_get_attribute_uint64 (deployment_info, "unix::inode");
+
+ if (root_dev == deploy_dev && root_inode == deploy_inode)
+ {
+ ret_deployment = g_object_ref (deployment);
+ break;
+ }
+ }
+
+ g_assert (ret_deployment != NULL);
+ }
+
+ ret = TRUE;
+ ot_transfer_out_value (out_osname, &ret_osname);
+ ot_transfer_out_value (out_deployment, &ret_deployment);
+ out:
+ return ret;
+}
+
gboolean
ot_admin_get_default_ostree_dir (GFile **out_ostree_dir,
GCancellable *cancellable,
diff --git a/src/ostree/ot-admin-functions.h b/src/ostree/ot-admin-functions.h
index c189b24..d74d768 100644
--- a/src/ostree/ot-admin-functions.h
+++ b/src/ostree/ot-admin-functions.h
@@ -42,6 +42,18 @@ gboolean ot_admin_get_previous_deployment (GFile *ostree_dir,
GCancellable *cancellable,
GError **error);
+gboolean ot_admin_list_deployments (GFile *ostree_dir,
+ const char *osname,
+ GPtrArray **out_deployments,
+ GCancellable *cancellable,
+ GError **error);
+
+gboolean ot_admin_get_active_deployment (GFile *ostree_dir,
+ char **out_osname,
+ GFile **out_deployment,
+ GCancellable *cancellable,
+ GError **error);
+
gboolean ot_admin_get_default_ostree_dir (GFile **out_ostree_dir,
GCancellable *cancellable,
GError **error);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]