appstream deploy: Clean up temporary files on error

If during appstream deploy there is an error, the temporary files were
not deleted, resulting in leaked files in /var/lib/flatpak/appstream.
Over time these could add up to a significant size. In particular this
happes if several deploys happen in parallel, because then the final
move into place will fail with EEXIST.

This fixes the cleanup of both the temporary directory and the temporary
link on any error.

Fixes https://github.com/flatpak/flatpak/issues/4735

(cherry picked from commit 61f9297cbc2c046520c4c9807df67729ffb1855f)
This commit is contained in:
Alexander Larsson 2022-02-11 10:22:44 +01:00 committed by Alexander Larsson
parent dcd79527a1
commit 66f3cc462c

View File

@ -4384,7 +4384,6 @@ flatpak_dir_deploy_appstream (FlatpakDir *self,
g_autoptr(GFile) active_tmp_link = NULL;
g_autoptr(GError) tmp_error = NULL;
g_autofree char *new_dir = NULL;
g_autofree char *checkout_dir_path = NULL;
OstreeRepoCheckoutAtOptions options = { 0, };
glnx_autofd int dfd = -1;
g_autoptr(GFileInfo) file_info = NULL;
@ -4396,6 +4395,8 @@ flatpak_dir_deploy_appstream (FlatpakDir *self,
g_autoptr(GRegex) allow_refs = NULL;
g_autoptr(GRegex) deny_refs = NULL;
g_autofree char *subset = NULL;
g_auto(GLnxTmpDir) tmpdir = { 0, };
g_autoptr(FlatpakTempDir) tmplink = NULL;
/* Keep a shared repo lock to avoid prunes removing objects we're relying on
* while we do the checkout. This could happen if the ref changes after we
@ -4485,15 +4486,13 @@ flatpak_dir_deploy_appstream (FlatpakDir *self,
{
g_autofree char *template = g_strdup_printf (".%s-XXXXXX", new_dir);
g_autoptr(GFile) tmp_dir_template = g_file_get_child (arch_dir, template);
checkout_dir_path = g_file_get_path (tmp_dir_template);
if (g_mkdtemp_full (checkout_dir_path, 0755) == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
_("Can't create deploy directory"));
return FALSE;
}
if (!glnx_mkdtempat (AT_FDCWD, flatpak_file_get_path_cached (tmp_dir_template), 0755,
&tmpdir, error))
return FALSE;
}
checkout_dir = g_file_new_for_path (checkout_dir_path);
checkout_dir = g_file_new_for_path (tmpdir.path);
options.mode = OSTREE_REPO_CHECKOUT_MODE_USER;
options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES;
@ -4501,7 +4500,7 @@ flatpak_dir_deploy_appstream (FlatpakDir *self,
options.bareuseronly_dirs = TRUE; /* https://github.com/ostreedev/ostree/pull/927 */
if (!ostree_repo_checkout_at (self->repo, &options,
AT_FDCWD, checkout_dir_path, new_checksum,
AT_FDCWD, tmpdir.path, new_checksum,
cancellable, error))
return FALSE;
@ -4594,6 +4593,9 @@ flatpak_dir_deploy_appstream (FlatpakDir *self,
if (!g_file_make_symbolic_link (active_tmp_link, new_dir, cancellable, error))
return FALSE;
/* This is a link, not a dir, but it will remove the same way on destroy */
tmplink = g_object_ref (active_tmp_link);
if (syncfs (dfd) != 0)
{
glnx_set_error_from_errno (error);
@ -4607,6 +4609,9 @@ flatpak_dir_deploy_appstream (FlatpakDir *self,
cancellable, NULL, NULL, error))
return FALSE;
/* Don't delete tmpdir now that it's moved */
glnx_tmpdir_unset (&tmpdir);
if (syncfs (dfd) != 0)
{
glnx_set_error_from_errno (error);
@ -4618,6 +4623,9 @@ flatpak_dir_deploy_appstream (FlatpakDir *self,
cancellable, error))
return FALSE;
/* Don't delete tmplink now that it's moved */
g_object_unref (g_steal_pointer (&tmplink));
if (old_dir != NULL &&
g_strcmp0 (old_dir, new_dir) != 0)
{