lib: Add a private helper to abort txns, use in sysroot cleanup
Steal some code from flatpak for this, which allows porting a few more things to new style. I started on a public API version of this but was trying to roll some other things into it and it snowballed. Let's do this version since it's easy for now. While here I changed things so that `generate_deployment_refs()` now just uses `_set_ref_immediate()` rather than requring a txn. Also, AFAICS there was no test coverage of `generate_deployment_refs()`; I tried commenting it out and at least `admin-test.sh` passed. Add some coverage of this - I verified that with this commenting out bits of that function cause the test to fail. Closes: #1132 Approved by: jlebon
This commit is contained in:
parent
6be4dfe66e
commit
3594bb2d0f
|
|
@ -158,6 +158,27 @@ struct OstreeRepo {
|
||||||
OstreeRepo *parent_repo;
|
OstreeRepo *parent_repo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Taken from flatpak; may be made into public API later */
|
||||||
|
typedef OstreeRepo _OstreeRepoAutoTransaction;
|
||||||
|
static inline void
|
||||||
|
_ostree_repo_auto_transaction_cleanup (void *p)
|
||||||
|
{
|
||||||
|
OstreeRepo *repo = p;
|
||||||
|
if (repo)
|
||||||
|
(void) ostree_repo_abort_transaction (repo, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline _OstreeRepoAutoTransaction *
|
||||||
|
_ostree_repo_auto_transaction_start (OstreeRepo *repo,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
|
||||||
|
return NULL;
|
||||||
|
return (_OstreeRepoAutoTransaction *)repo;
|
||||||
|
}
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC (_OstreeRepoAutoTransaction, _ostree_repo_auto_transaction_cleanup)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
ino_t ino;
|
ino_t ino;
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "otutil.h"
|
#include "otutil.h"
|
||||||
|
#include "ostree-repo-private.h"
|
||||||
#include "ostree-linuxfsutil.h"
|
#include "ostree-linuxfsutil.h"
|
||||||
|
|
||||||
#include "ostree-sysroot-private.h"
|
#include "ostree-sysroot-private.h"
|
||||||
|
|
@ -335,10 +336,7 @@ cleanup_old_deployments (OstreeSysroot *self,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* libostree holds a ref for each deployment's exact checksum to avoid it being
|
/* Delete the ref bindings for a non-active boot version */
|
||||||
* GC'd even if the origin ref changes. This function resets those refs
|
|
||||||
* to match active deployments.
|
|
||||||
*/
|
|
||||||
static gboolean
|
static gboolean
|
||||||
cleanup_ref_prefix (OstreeRepo *repo,
|
cleanup_ref_prefix (OstreeRepo *repo,
|
||||||
int bootversion,
|
int bootversion,
|
||||||
|
|
@ -346,30 +344,24 @@ cleanup_ref_prefix (OstreeRepo *repo,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
|
||||||
g_autofree char *prefix = g_strdup_printf ("ostree/%d/%d", bootversion, subbootversion);
|
g_autofree char *prefix = g_strdup_printf ("ostree/%d/%d", bootversion, subbootversion);
|
||||||
|
|
||||||
g_autoptr(GHashTable) refs = NULL;
|
g_autoptr(GHashTable) refs = NULL;
|
||||||
if (!ostree_repo_list_refs_ext (repo, prefix, &refs, OSTREE_REPO_LIST_REFS_EXT_NONE, cancellable, error))
|
if (!ostree_repo_list_refs_ext (repo, prefix, &refs, OSTREE_REPO_LIST_REFS_EXT_NONE, cancellable, error))
|
||||||
goto out;
|
return FALSE;
|
||||||
|
|
||||||
if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
GLNX_HASH_TABLE_FOREACH (refs, const char *, ref)
|
GLNX_HASH_TABLE_FOREACH (refs, const char *, ref)
|
||||||
{
|
{
|
||||||
ostree_repo_transaction_set_refspec (repo, ref, NULL);
|
if (!ostree_repo_set_ref_immediate (repo, NULL, ref, NULL, cancellable, error))
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
|
return TRUE;
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = TRUE;
|
|
||||||
out:
|
|
||||||
ostree_repo_abort_transaction (repo, cancellable, NULL);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* libostree holds a ref for each deployment's exact checksum to avoid it being
|
||||||
|
* GC'd even if the origin ref changes. This function resets those refs
|
||||||
|
* to match active deployments.
|
||||||
|
*/
|
||||||
static gboolean
|
static gboolean
|
||||||
generate_deployment_refs (OstreeSysroot *self,
|
generate_deployment_refs (OstreeSysroot *self,
|
||||||
OstreeRepo *repo,
|
OstreeRepo *repo,
|
||||||
|
|
@ -379,46 +371,38 @@ generate_deployment_refs (OstreeSysroot *self,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
int cleanup_bootversion = (bootversion == 0) ? 1 : 0;
|
||||||
int cleanup_bootversion;
|
int cleanup_subbootversion = (subbootversion == 0) ? 1 : 0;
|
||||||
int cleanup_subbootversion;
|
|
||||||
guint i;
|
|
||||||
|
|
||||||
cleanup_bootversion = (bootversion == 0) ? 1 : 0;
|
|
||||||
cleanup_subbootversion = (subbootversion == 0) ? 1 : 0;
|
|
||||||
|
|
||||||
if (!cleanup_ref_prefix (repo, cleanup_bootversion, 0,
|
if (!cleanup_ref_prefix (repo, cleanup_bootversion, 0,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
return FALSE;
|
||||||
|
|
||||||
if (!cleanup_ref_prefix (repo, cleanup_bootversion, 1,
|
if (!cleanup_ref_prefix (repo, cleanup_bootversion, 1,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
return FALSE;
|
||||||
|
|
||||||
if (!cleanup_ref_prefix (repo, bootversion, cleanup_subbootversion,
|
if (!cleanup_ref_prefix (repo, bootversion, cleanup_subbootversion,
|
||||||
cancellable, error))
|
cancellable, error))
|
||||||
goto out;
|
return FALSE;
|
||||||
|
|
||||||
for (i = 0; i < deployments->len; i++)
|
g_autoptr(_OstreeRepoAutoTransaction) txn =
|
||||||
|
_ostree_repo_auto_transaction_start (repo, cancellable, error);
|
||||||
|
if (!txn)
|
||||||
|
return FALSE;
|
||||||
|
for (guint i = 0; i < deployments->len; i++)
|
||||||
{
|
{
|
||||||
OstreeDeployment *deployment = deployments->pdata[i];
|
OstreeDeployment *deployment = deployments->pdata[i];
|
||||||
g_autofree char *refname = g_strdup_printf ("ostree/%d/%d/%u",
|
g_autofree char *refname = g_strdup_printf ("ostree/%d/%d/%u",
|
||||||
bootversion, subbootversion,
|
bootversion, subbootversion,
|
||||||
i);
|
i);
|
||||||
|
|
||||||
if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ostree_repo_transaction_set_refspec (repo, refname, ostree_deployment_get_csum (deployment));
|
ostree_repo_transaction_set_refspec (repo, refname, ostree_deployment_get_csum (deployment));
|
||||||
|
|
||||||
if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
ret = TRUE;
|
return TRUE;
|
||||||
out:
|
|
||||||
ostree_repo_abort_transaction (repo, cancellable, NULL);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,13 @@ function validate_bootloader() {
|
||||||
cd -
|
cd -
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Test generate_deployment_refs()
|
||||||
|
assert_ostree_deployment_refs() {
|
||||||
|
${CMD_PREFIX} ostree --repo=sysroot/ostree/repo refs ostree | sort > ostree-refs.txt
|
||||||
|
(for v in "$@"; do echo $v; done) | sort > ostree-refs-expected.txt
|
||||||
|
diff -u ostree-refs{-expected,}.txt
|
||||||
|
}
|
||||||
|
|
||||||
orig_mtime=$(stat -c '%.Y' sysroot/ostree/deploy)
|
orig_mtime=$(stat -c '%.Y' sysroot/ostree/deploy)
|
||||||
${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmaster/x86_64-runtime
|
${CMD_PREFIX} ostree --repo=sysroot/ostree/repo pull-local --remote=testos testos-repo testos/buildmaster/x86_64-runtime
|
||||||
rev=$(${CMD_PREFIX} ostree --repo=sysroot/ostree/repo rev-parse testos/buildmaster/x86_64-runtime)
|
rev=$(${CMD_PREFIX} ostree --repo=sysroot/ostree/repo rev-parse testos/buildmaster/x86_64-runtime)
|
||||||
|
|
@ -55,6 +62,7 @@ assert_file_has_content curdir ^`pwd`/sysroot/ostree/deploy/testos/deploy/${rev}
|
||||||
|
|
||||||
echo "ok --print-current-dir"
|
echo "ok --print-current-dir"
|
||||||
|
|
||||||
|
# Test layout of bootloader config and refs
|
||||||
assert_not_has_dir sysroot/boot/loader.0
|
assert_not_has_dir sysroot/boot/loader.0
|
||||||
assert_has_dir sysroot/boot/loader.1
|
assert_has_dir sysroot/boot/loader.1
|
||||||
assert_has_dir sysroot/ostree/boot.1.1
|
assert_has_dir sysroot/ostree/boot.1.1
|
||||||
|
|
@ -64,9 +72,8 @@ assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'option
|
||||||
assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/vmlinuz-3.6.0 'a kernel'
|
assert_file_has_content sysroot/boot/ostree/testos-${bootcsum}/vmlinuz-3.6.0 'a kernel'
|
||||||
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/etc/os-release 'NAME=TestOS'
|
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.0/etc/os-release 'NAME=TestOS'
|
||||||
assert_file_has_content sysroot/ostree/boot.1/testos/${bootcsum}/0/etc/os-release 'NAME=TestOS'
|
assert_file_has_content sysroot/ostree/boot.1/testos/${bootcsum}/0/etc/os-release 'NAME=TestOS'
|
||||||
|
assert_ostree_deployment_refs 1/1/0
|
||||||
${CMD_PREFIX} ostree admin status
|
${CMD_PREFIX} ostree admin status
|
||||||
|
|
||||||
|
|
||||||
echo "ok layout"
|
echo "ok layout"
|
||||||
|
|
||||||
orig_mtime=$(stat -c '%.Y' sysroot/ostree/deploy)
|
orig_mtime=$(stat -c '%.Y' sysroot/ostree/deploy)
|
||||||
|
|
@ -84,6 +91,7 @@ assert_not_has_dir sysroot/ostree/boot.1.1
|
||||||
assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'options.* root=LABEL=MOO'
|
assert_file_has_content sysroot/boot/loader/entries/ostree-testos-0.conf 'options.* root=LABEL=MOO'
|
||||||
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.1/etc/os-release 'NAME=TestOS'
|
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'
|
assert_file_has_content sysroot/ostree/boot.0/testos/${bootcsum}/0/etc/os-release 'NAME=TestOS'
|
||||||
|
assert_ostree_deployment_refs 0/1/{0,1}
|
||||||
${CMD_PREFIX} ostree admin status
|
${CMD_PREFIX} ostree admin status
|
||||||
validate_bootloader
|
validate_bootloader
|
||||||
|
|
||||||
|
|
@ -96,6 +104,7 @@ assert_not_has_dir sysroot/boot/loader.1
|
||||||
# But swap subbootversion
|
# But swap subbootversion
|
||||||
assert_has_dir sysroot/ostree/boot.0.0
|
assert_has_dir sysroot/ostree/boot.0.0
|
||||||
assert_not_has_dir sysroot/ostree/boot.0.1
|
assert_not_has_dir sysroot/ostree/boot.0.1
|
||||||
|
assert_ostree_deployment_refs 0/0/{0,1}
|
||||||
${CMD_PREFIX} ostree admin status
|
${CMD_PREFIX} ostree admin status
|
||||||
validate_bootloader
|
validate_bootloader
|
||||||
|
|
||||||
|
|
@ -110,6 +119,7 @@ assert_has_file sysroot/boot/loader/entries/ostree-testos-1.conf
|
||||||
assert_has_file sysroot/boot/loader/entries/ostree-otheros-0.conf
|
assert_has_file sysroot/boot/loader/entries/ostree-otheros-0.conf
|
||||||
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.1/etc/os-release 'NAME=TestOS'
|
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.1/etc/os-release 'NAME=TestOS'
|
||||||
assert_file_has_content sysroot/ostree/deploy/otheros/deploy/${rev}.0/etc/os-release 'NAME=TestOS'
|
assert_file_has_content sysroot/ostree/deploy/otheros/deploy/${rev}.0/etc/os-release 'NAME=TestOS'
|
||||||
|
assert_ostree_deployment_refs 1/1/{0,1,2}
|
||||||
${CMD_PREFIX} ostree admin status
|
${CMD_PREFIX} ostree admin status
|
||||||
validate_bootloader
|
validate_bootloader
|
||||||
|
|
||||||
|
|
@ -123,6 +133,7 @@ assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.2/etc/os-rele
|
||||||
assert_has_file sysroot/boot/loader/entries/ostree-testos-2.conf
|
assert_has_file sysroot/boot/loader/entries/ostree-testos-2.conf
|
||||||
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.3/etc/os-release 'NAME=TestOS'
|
assert_file_has_content sysroot/ostree/deploy/testos/deploy/${rev}.3/etc/os-release 'NAME=TestOS'
|
||||||
${CMD_PREFIX} ostree admin status
|
${CMD_PREFIX} ostree admin status
|
||||||
|
assert_ostree_deployment_refs 0/1/{0,1,2,3}
|
||||||
validate_bootloader
|
validate_bootloader
|
||||||
|
|
||||||
echo "ok fourth deploy (retain)"
|
echo "ok fourth deploy (retain)"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue