mirror of
https://github.com/flatpak/flatpak.git
synced 2026-01-26 14:13:26 +00:00
kill: Do not kill pid 0 and embrace races
There are a number of races, and failure conditions which can lead to a pid of 0 being returned from flatpak_instance_get_child_pid. This would lead to a whole bunch of things getting killed. We will skip the instance in those cases now, and retry a few times. We also notice when the instance just goes away by itself now. This should make killing more robust, and especially not SIGKILL pid 0.
This commit is contained in:
parent
0fc61c1aff
commit
8354ee56cf
@ -36,37 +36,91 @@
|
||||
#include "flatpak-builtins.h"
|
||||
#include "flatpak-instance.h"
|
||||
|
||||
#define FLATPAK_BUILTIN_KILL_N_RETRIES 5
|
||||
#define FLATPAK_BUILTIN_KILL_RETRY_SLEEP_USEC (G_USEC_PER_SEC / 10)
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static gboolean
|
||||
kill_instance (const char *id,
|
||||
GError **error)
|
||||
instance_equal (FlatpakInstance *a,
|
||||
FlatpakInstance *b)
|
||||
{
|
||||
g_autoptr(GPtrArray) instances = NULL;
|
||||
int j;
|
||||
int killed = 0;
|
||||
return g_strcmp0 (flatpak_instance_get_id (a),
|
||||
flatpak_instance_get_id (b)) == 0;
|
||||
}
|
||||
|
||||
instances = flatpak_instance_get_all ();
|
||||
static GPtrArray *
|
||||
kill_instances (GPtrArray *kill_list)
|
||||
{
|
||||
g_autoptr(GPtrArray) instances = flatpak_instance_get_all ();
|
||||
g_autoptr(GPtrArray) remaining =
|
||||
g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
for (j = 0; j < instances->len; j++)
|
||||
for (size_t i = 0; i < kill_list->len; i++)
|
||||
{
|
||||
FlatpakInstance *instance = (FlatpakInstance *) g_ptr_array_index (instances, j);
|
||||
if (g_strcmp0 (id, flatpak_instance_get_app (instance)) == 0 ||
|
||||
strcmp (id, flatpak_instance_get_id (instance)) == 0)
|
||||
FlatpakInstance *to_kill = g_ptr_array_index (kill_list, i);
|
||||
pid_t pid;
|
||||
|
||||
if (!g_ptr_array_find_with_equal_func (instances, to_kill,
|
||||
(GEqualFunc) instance_equal,
|
||||
NULL))
|
||||
{
|
||||
pid_t pid = flatpak_instance_get_child_pid (instance);
|
||||
kill (pid, SIGKILL);
|
||||
killed++;
|
||||
g_info ("Instance %s disappeared", flatpak_instance_get_id (to_kill));
|
||||
continue;
|
||||
}
|
||||
|
||||
pid = flatpak_instance_get_child_pid (to_kill);
|
||||
if (pid != 0)
|
||||
{
|
||||
kill (pid, SIGKILL);
|
||||
g_info ("Instance %s killed", flatpak_instance_get_id (to_kill));
|
||||
continue;
|
||||
}
|
||||
|
||||
g_ptr_array_add (remaining, g_object_ref (to_kill));
|
||||
}
|
||||
|
||||
g_info ("Killed %d instances", killed);
|
||||
return g_steal_pointer (&remaining);
|
||||
}
|
||||
|
||||
if (killed == 0)
|
||||
static gboolean
|
||||
kill_id (const char *id,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GPtrArray) instances = flatpak_instance_get_all ();
|
||||
g_autoptr(GPtrArray) kill_list =
|
||||
g_ptr_array_new_with_free_func (g_object_unref);
|
||||
|
||||
for (size_t i = 0; i < instances->len; i++)
|
||||
{
|
||||
FlatpakInstance *instance = g_ptr_array_index (instances, i);
|
||||
|
||||
if (g_strcmp0 (id, flatpak_instance_get_app (instance)) != 0 &&
|
||||
g_strcmp0 (id, flatpak_instance_get_id (instance)) != 0)
|
||||
continue;
|
||||
|
||||
g_info ("Found instance %s to kill", flatpak_instance_get_id (instance));
|
||||
|
||||
g_ptr_array_add (kill_list, g_object_ref (instance));
|
||||
}
|
||||
|
||||
if (kill_list->len == 0)
|
||||
return flatpak_fail (error, _("%s is not running"), id);
|
||||
|
||||
for (size_t i = 0; i < FLATPAK_BUILTIN_KILL_N_RETRIES && kill_list->len > 0; i++)
|
||||
{
|
||||
g_autoptr (GPtrArray) remaining = NULL;
|
||||
|
||||
if (i > 0)
|
||||
g_usleep (FLATPAK_BUILTIN_KILL_RETRY_SLEEP_USEC);
|
||||
|
||||
remaining = kill_instances (kill_list);
|
||||
g_clear_pointer (&kill_list, g_ptr_array_unref);
|
||||
kill_list = g_steal_pointer (&remaining);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -77,7 +131,7 @@ flatpak_builtin_kill (int argc,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GOptionContext) context = NULL;
|
||||
const char *instance;
|
||||
const char *id;
|
||||
|
||||
context = g_option_context_new (_("INSTANCE - Stop a running application"));
|
||||
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
|
||||
@ -97,9 +151,9 @@ flatpak_builtin_kill (int argc,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
instance = argv[1];
|
||||
id = argv[1];
|
||||
|
||||
return kill_instance (instance, error);
|
||||
return kill_id (id, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user