Skip to content

Commit

Permalink
Merge branch 'jb53294' into 'master'
Browse files Browse the repository at this point in the history
Fix crashing when removing service caused by double removal via inotify

See merge request mer-core/connman!311
  • Loading branch information
LaakkonenJussi committed Mar 12, 2021
2 parents a745409 + f5ea074 commit 60dcd1b
Showing 1 changed file with 29 additions and 29 deletions.
58 changes: 29 additions & 29 deletions connman/src/storage.c
Expand Up @@ -306,6 +306,14 @@ static bool is_user_dir(const char *name)
return is_user_wifi(name) || is_user_vpn(name);
}

static GList *subdir_for(const char *name)
{
if (is_user_dir(name))
return storage.user_subdirs;
else
return storage.subdirs;
}

static const char *storagedir_for(const char *name)
{
DBG("name %s", name);
Expand Down Expand Up @@ -502,6 +510,12 @@ static void storage_inotify_cb(struct inotify_event *event, const char *ident,

DBG("delete/move-from %s", event->name);

subdirs = subdir_for(event->name);

pos = g_list_find_custom(subdirs, &key, storage_subdir_cmp);
if (!pos)
return;

/*
* To support manual removal of services as well call the
* unload callback to propagate the notify about the removal
Expand Down Expand Up @@ -529,23 +543,15 @@ static void storage_inotify_cb(struct inotify_event *event, const char *ident,
storage.only_unload = unload_state;
}

if (is_user_dir(event->name))
subdirs = storage.user_subdirs;
else
subdirs = storage.subdirs;

/*
* If the service was manually removed it is removed also from
* subdirs when the unload callback reaches back to service/
* provider removal in unload only mode. But in case it was
* removed using internal functionality it must be removed from
* the subdirs here.
*/
pos = g_list_find_custom(subdirs, &key, storage_subdir_cmp);
if (pos) {
storage_subdir_unregister(pos->data);
debug_subdirs();
}
storage_subdir_unregister(pos->data);
debug_subdirs();

return;
}
Expand Down Expand Up @@ -1244,6 +1250,9 @@ static int remove_dir(const char *service_id)

bool __connman_storage_remove_service(const char *service_id)
{
struct storage_subdir key = { .name = (gchar*) service_id };
GList *subdirs;
GList *pos;
bool removed = false;
gchar *pathname;
const char *storagedir;
Expand All @@ -1253,26 +1262,20 @@ bool __connman_storage_remove_service(const char *service_id)
if (!service_id || !service_id_is_valid(service_id))
return false;

if (storage.only_unload) {
struct storage_subdir key = { .name = (gchar*) service_id };
GList *subdirs;
GList *pos;
subdirs = subdir_for(service_id);

DBG("Unload service %s", service_id);

if (is_user_dir(service_id))
subdirs = storage.user_subdirs;
else
subdirs = storage.subdirs;
pos = g_list_find_custom(subdirs, &key, storage_subdir_cmp);
if (pos)
storage_subdir_unregister(pos->data);

pos = g_list_find_custom(subdirs, &key, storage_subdir_cmp);
if (!pos) {
if (storage.only_unload) {
if (pos) {
DBG("Unregister service %s", service_id);
return true;
} else {
DBG("cannot unregister %s", service_id);
return false;
}

storage_subdir_unregister(pos->data);
return true;
}

storagedir = storagedir_for(service_id);
Expand Down Expand Up @@ -1391,10 +1394,7 @@ static bool remove_all(const char *id)

DBG("Unload provider %s", id);

if (is_user_dir(id))
subdirs = storage.user_subdirs;
else
subdirs = storage.subdirs;
subdirs = subdir_for(id);

pos = g_list_find_custom(subdirs, &key, storage_subdir_cmp);
if (!pos) {
Expand Down

0 comments on commit 60dcd1b

Please sign in to comment.