During undeploy, keep files around if they are in use

We check for a lock on the .ref file to detect if anything
is using a partilular checkout before we remove it.
tingping/wmclass
Alexander Larsson 2015-02-05 22:31:01 +01:00
parent f1091127c5
commit 6ea2391583
4 changed files with 55 additions and 10 deletions

View File

@ -12,10 +12,12 @@
static char *opt_arch;
static gboolean opt_keep_ref;
static gboolean opt_force_remove;
static GOptionEntry options[] = {
{ "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, "Arch to uninstall", "ARCH" },
{ "keep-ref", 0, 0, G_OPTION_ARG_NONE, &opt_keep_ref, "Keep ref in local repository", NULL },
{ "force-remove", 0, 0, G_OPTION_ARG_NONE, &opt_force_remove, "Remove files even if running", NULL },
{ NULL }
};
@ -115,7 +117,7 @@ xdg_app_builtin_uninstall_runtime (int argc, char **argv, GCancellable *cancella
for (i = 0; deployed[i] != NULL; i++)
{
g_debug ("undeploying %s", deployed[i]);
if (!xdg_app_dir_undeploy (dir, ref, deployed[i], cancellable, error))
if (!xdg_app_dir_undeploy (dir, ref, deployed[i], opt_force_remove, cancellable, error))
goto out;
}
@ -229,7 +231,7 @@ xdg_app_builtin_uninstall_app (int argc, char **argv, GCancellable *cancellable,
for (i = 0; deployed[i] != NULL; i++)
{
g_debug ("undeploying %s", deployed[i]);
if (!xdg_app_dir_undeploy (dir, ref, deployed[i], cancellable, error))
if (!xdg_app_dir_undeploy (dir, ref, deployed[i], opt_force_remove, cancellable, error))
goto out;
}

View File

@ -12,10 +12,12 @@
static char *opt_arch;
static char *opt_commit;
static gboolean opt_force_remove;
static GOptionEntry options[] = {
{ "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, "Arch to update for", "ARCH" },
{ "commit", 0, 0, G_OPTION_ARG_STRING, &opt_commit, "Commit to deploy", "COMMIT" },
{ "force-remove", 0, 0, G_OPTION_ARG_NONE, &opt_force_remove, "Remove old files even if running", NULL },
{ NULL }
};
@ -83,6 +85,7 @@ xdg_app_builtin_update_runtime (int argc, char **argv, GCancellable *cancellable
if (previous_deployment != NULL)
{
if (!xdg_app_dir_undeploy (dir, ref, previous_deployment,
opt_force_remove,
cancellable, error))
goto out;
@ -161,6 +164,7 @@ xdg_app_builtin_update_app (int argc, char **argv, GCancellable *cancellable, GE
if (previous_deployment != NULL)
{
if (!xdg_app_dir_undeploy (dir, ref, previous_deployment,
opt_force_remove,
cancellable, error))
goto out;

View File

@ -158,7 +158,13 @@ xdg_app_dir_get_deploy_dir (XdgAppDir *self,
GFile *
xdg_app_dir_get_exports_dir (XdgAppDir *self)
{
return g_file_resolve_relative_path (self->basedir, "exports");
return g_file_get_child (self->basedir, "exports");
}
GFile *
xdg_app_dir_get_removed_dir (XdgAppDir *self)
{
return g_file_get_child (self->basedir, ".removed");
}
GFile *
@ -990,17 +996,43 @@ xdg_app_dir_list_deployed (XdgAppDir *self,
}
static gboolean
dir_is_locked (GFile *dir)
{
gs_fd_close int ref_fd = -1;
struct flock lock = {0};
gs_unref_object GFile *reffile = NULL;
reffile = g_file_resolve_relative_path (dir, "files/.ref");
ref_fd = open (gs_file_get_path_cached (reffile), O_RDWR | O_CLOEXEC);
if (ref_fd != -1)
{
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
if (fcntl (ref_fd, F_GETLK, &lock) == 0)
return lock.l_type != F_UNLCK;
}
return FALSE;
}
gboolean
xdg_app_dir_undeploy (XdgAppDir *self,
const char *ref,
const char *checksum,
gboolean force_remove,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
gs_unref_object GFile *deploy_base = NULL;
gs_unref_object GFile *checkoutdir = NULL;
gs_unref_object GFile *removeddir = NULL;
gs_unref_object GFile *removed_subdir = NULL;
gs_unref_object GFile *removed_dir = NULL;
gs_free char *tmpname = NULL;
gs_free char *active = NULL;
gboolean is_app;
@ -1051,18 +1083,23 @@ xdg_app_dir_undeploy (XdgAppDir *self,
goto out;
}
tmpname = gs_fileutil_gen_tmp_name (".removed-", checksum);
removed_dir = xdg_app_dir_get_removed_dir (self);
if (!gs_file_ensure_directory (removed_dir, TRUE, cancellable, error))
goto out;
checkoutdir = g_file_get_child (deploy_base, checksum);
removeddir = g_file_get_child (deploy_base, tmpname);
tmpname = gs_fileutil_gen_tmp_name ("", checksum);
removed_subdir = g_file_get_child (removed_dir, tmpname);
if (!gs_file_rename (checkoutdir,
removeddir,
removed_subdir,
cancellable, error))
goto out;
if (!gs_shutil_rm_rf (removeddir, cancellable, error))
goto out;
if (force_remove || !dir_is_locked (removed_subdir))
{
if (!gs_shutil_rm_rf (removed_subdir, cancellable, error))
goto out;
}
is_app = g_str_has_prefix (ref, "app");

View File

@ -33,6 +33,7 @@ GFile * xdg_app_dir_get_path (XdgAppDir *self);
GFile * xdg_app_dir_get_deploy_dir (XdgAppDir *self,
const char *ref);
GFile * xdg_app_dir_get_exports_dir (XdgAppDir *self);
GFile * xdg_app_dir_get_removed_dir (XdgAppDir *self);
GFile * xdg_app_dir_get_if_deployed (XdgAppDir *self,
const char *ref,
const char *checksum,
@ -72,6 +73,7 @@ gboolean xdg_app_dir_deploy (XdgAppDir *self,
gboolean xdg_app_dir_undeploy (XdgAppDir *self,
const char *ref,
const char *checksum,
gboolean force_remove,
GCancellable *cancellable,
GError **error);
gboolean xdg_app_dir_prune (XdgAppDir *self,