admin: Write out correct version fields in boot/loader/entries files

Before, we were writing the "bootversion", which is either 0 or 1, for
all entries.  This is completely wrong; the idea of the "version"
field is to compare between entries.

Fix this by writing out the inverted index - internally, index 0 is
the *first* boot entry, so we give it the highest version number, and
index N is the last, so give it version 0.

Then fix the deployment sorting code to correctly reverse the version
number comparison, so we read back the right order.

In practice before this bug didn't matter because "normally" you only
have at most two deployments.

https://bugzilla.gnome.org/show_bug.cgi?id=706546
This commit is contained in:
Colin Walters 2013-08-21 18:48:00 -04:00
parent 7e2e072ad4
commit 8abad0b452
3 changed files with 27 additions and 10 deletions

View File

@ -791,10 +791,16 @@ parse_os_release (const char *contents,
return ret;
}
/*
* install_deployment_kernel:
*
* Write out an entry in /boot/loader/entries for @deployment.
*/
static gboolean
install_deployment_kernel (GFile *sysroot,
int new_bootversion,
OtDeployment *deployment,
guint n_deployments,
GCancellable *cancellable,
GError **error)
@ -901,7 +907,7 @@ install_deployment_kernel (GFile *sysroot,
val);
ot_config_parser_set (bootconfig, "title", title_key);
version_key = g_strdup_printf ("%d", ot_deployment_get_bootserial (deployment));
version_key = g_strdup_printf ("%d", n_deployments - ot_deployment_get_index (deployment));
ot_config_parser_set (bootconfig, "version", version_key);
linux_relpath = g_file_get_relative_path (bootdir, dest_kernel_path);
@ -1000,7 +1006,8 @@ ot_admin_write_deployments (GFile *sysroot,
for (i = 0; i < new_deployments->len; i++)
{
OtDeployment *deployment = new_deployments->pdata[i];
if (!install_deployment_kernel (sysroot, new_bootversion, deployment,
if (!install_deployment_kernel (sysroot, new_bootversion,
deployment, new_deployments->len,
cancellable, error))
{
g_prefix_error (error, "Installing kernel: ");

View File

@ -717,7 +717,7 @@ list_deployments_process_one_boot_entry (GFile *sysroot,
}
static gint
compare_deployments_by_boot_loader_version (gconstpointer a_pp,
compare_deployments_by_boot_loader_version_reversed (gconstpointer a_pp,
gconstpointer b_pp)
{
OtDeployment *a = *((OtDeployment**)a_pp);
@ -728,11 +728,15 @@ compare_deployments_by_boot_loader_version (gconstpointer a_pp,
const char *b_version = ot_config_parser_get (b_bootconfig, "version");
if (a_version && b_version)
return strverscmp (a_version, b_version);
{
int r = strverscmp (a_version, b_version);
/* Reverse */
return -r;
}
else if (a_version)
return 1;
else
return -1;
else
return 1;
}
gboolean
@ -766,7 +770,7 @@ ot_admin_list_deployments (GFile *sysroot,
goto out;
}
g_ptr_array_sort (ret_deployments, compare_deployments_by_boot_loader_version);
g_ptr_array_sort (ret_deployments, compare_deployments_by_boot_loader_version_reversed);
for (i = 0; i < ret_deployments->len; i++)
{
OtDeployment *deployment = ret_deployments->pdata[i];

View File

@ -62,6 +62,8 @@ assert_file_has_content sysroot/boot/loader/entries/ostree-testos-${rev}-0.conf
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.1/etc/os-release 'NAME=TestOS'
assert_file_has_content sysroot/ostree/boot.0/testos/${bootcsum}/0/etc/os-release 'NAME=TestOS'
ostree admin --sysroot=sysroot status
echo "ok second deploy"
ostree admin --sysroot=sysroot deploy --os=testos testos:testos/buildmaster/x86_64-runtime
@ -123,6 +125,8 @@ assert_not_has_file sysroot/ostree/deploy/testos/deploy/${rev}.3/etc/aconfigfile
echo "ok upgrade bare"
ostree admin --sysroot=sysroot status
os_repository_new_commit
ostree --repo=sysroot/ostree/repo remote add testos file://$(pwd)/testos-repo testos/buildmaster/x86_64-runtime
ostree admin --sysroot=sysroot upgrade --os=testos
@ -134,14 +138,16 @@ assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/etc/os-r
echo "ok upgrade"
ostree admin --sysroot=sysroot status
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/etc/os-release 'NAME=TestOS'
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${origrev}.4/etc/os-release 'NAME=TestOS'
ostree admin --sysroot=sysroot undeploy 1
ostree admin --sysroot=sysroot undeploy 2
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/etc/os-release 'NAME=TestOS'
assert_not_has_dir sysroot/ostree/deploy/testos/deploy/${origrev}.4
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${origrev}.3/etc/os-release 'NAME=TestOS'
ostree admin --sysroot=sysroot undeploy 3
ostree admin --sysroot=sysroot undeploy 2
assert_not_has_dir sysroot/ostree/deploy/testos/deploy/${origrev}.3
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${newrev}.0/etc/os-release 'NAME=TestOS'