Some vpnd patches to prevent vpnd exit and better support for .config files

This commit is contained in:
lfiebach 2013-03-07 21:46:46 +01:00
parent 88d4f01f4d
commit fe5019c88b
2 changed files with 277 additions and 0 deletions

View File

@ -0,0 +1,66 @@
diff --git a/vpn/vpn-manager.c b/vpn/vpn-manager.c
index 44684dd..1ba745b 100644
--- a/vpn/vpn-manager.c
+++ b/vpn/vpn-manager.c
@@ -85,8 +85,6 @@ static DBusMessage *get_connections(DBusConnection *conn, DBusMessage *msg,
if (reply == NULL)
return __connman_error_failed(msg, -EINVAL);
- __vpn_provider_check_connections();
-
return reply;
}
diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c
index 63a00ea..d885b46 100644
--- a/vpn/vpn-provider.c
+++ b/vpn/vpn-provider.c
@@ -1027,8 +1027,6 @@ static void configuration_count_del(void)
if (__sync_fetch_and_sub(&configuration_count, 1) != 1)
return;
-
- raise(SIGTERM);
}
int __vpn_provider_disconnect(struct vpn_provider *provider)
@@ -2507,28 +2505,6 @@ void vpn_provider_driver_unregister(struct vpn_provider_driver *driver)
}
}
-static gboolean check_vpn_count(gpointer data)
-{
- if (configuration_count == 0) {
- connman_info("No VPN configurations found, quitting.");
- raise(SIGTERM);
- }
-
- return FALSE;
-}
-
-void __vpn_provider_check_connections(void)
-{
- /*
- * If we were started when there is no providers configured,
- * then just quit. This happens when connman starts and its
- * vpn plugin asks connman-vpnd if it has any connections
- * configured. If there are none, then we can stop the vpn
- * daemon.
- */
- g_timeout_add(1000, check_vpn_count, NULL);
-}
-
const char *vpn_provider_get_name(struct vpn_provider *provider)
{
return provider->name;
diff --git a/vpn/vpn.h b/vpn/vpn.h
index 56e7a5c..53b117d 100644
--- a/vpn/vpn.h
+++ b/vpn/vpn.h
@@ -95,7 +95,6 @@ int __vpn_provider_connect_path(const char *path);
int __vpn_provider_disconnect(struct vpn_provider *provider);
int __vpn_provider_remove(const char *path);
int __vpn_provider_delete(struct vpn_provider *provider);
-void __vpn_provider_check_connections(void);
void __vpn_provider_cleanup(void);
int __vpn_provider_init(gboolean handle_routes);

View File

@ -0,0 +1,211 @@
diff --git a/plugins/vpn.c b/plugins/vpn.c
index cbba396..f60a658 100644
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -1438,6 +1438,8 @@ static void destroy_provider(struct connection_data *data)
if (data->call != NULL)
dbus_pending_call_cancel(data->call);
+ connman_provider_set_data(data->provider, NULL);
+
connman_provider_put(data->provider);
data->provider = NULL;
diff --git a/vpn/vpn-config.c b/vpn/vpn-config.c
index 1ece7e9..a1a2ed5 100644
--- a/vpn/vpn-config.c
+++ b/vpn/vpn-config.c
@@ -539,28 +539,40 @@ static void config_notify_handler(struct inotify_event *event,
}
if (event->mask & IN_CREATE)
- create_config(ident);
+ return;
+
+ if (event->mask & IN_DELETE) {
+ g_hash_table_remove(config_table, ident);
+ return;
+ }
if (event->mask & IN_MODIFY) {
struct vpn_config *config;
+ char *path = get_dir();
config = g_hash_table_lookup(config_table, ident);
if (config != NULL) {
- char *path = get_dir();
-
g_hash_table_remove_all(config->provider_table);
load_config(config, path, REMOVE);
/* Re-scan the config file for any changes */
g_hash_table_remove_all(config->provider_table);
load_config(config, path, ADD);
-
- g_free(path);
+ } else {
+ /*
+ * Inotify will send create event followed by modify
+ * event for any config file that is copied to
+ * monitored directory. So in practice we should just
+ * ignore the create event and trust only the modify
+ * one in order to avoid create/remove/create loop
+ */
+ config = create_config(ident);
+ if (config != NULL)
+ load_config(config, path, ADD);
}
- }
- if (event->mask & IN_DELETE)
- g_hash_table_remove(config_table, ident);
+ g_free(path);
+ }
}
int __vpn_config_init(void)
diff --git a/src/connman.h b/src/connman.h
index fc6d528..19bca74 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -559,7 +559,7 @@ int __connman_provider_indicate_state(struct connman_provider *provider,
int __connman_provider_indicate_error(struct connman_provider *provider,
enum connman_provider_error error);
int __connman_provider_connect(struct connman_provider *provider);
-int __connman_provider_remove(const char *path);
+int __connman_provider_remove_by_path(const char *path);
void __connman_provider_cleanup(void);
int __connman_provider_init(void);
diff --git a/src/manager.c b/src/manager.c
index 1d09267..e56f2e1 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -161,7 +161,7 @@ static DBusMessage *remove_provider(DBusConnection *conn,
dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID);
- err = __connman_provider_remove(path);
+ err = __connman_provider_remove_by_path(path);
if (err < 0)
return __connman_error_failed(msg, -err);
diff --git a/src/provider.c b/src/provider.c
index ca86880..b86e7d6 100644
--- a/src/provider.c
+++ b/src/provider.c
@@ -174,7 +174,7 @@ int __connman_provider_connect(struct connman_provider *provider)
return 0;
}
-int __connman_provider_remove(const char *path)
+int __connman_provider_remove_by_path(const char *path)
{
struct connman_provider *provider;
GHashTableIter iter;
diff --git a/include/provider.h b/include/provider.h
index bfefaed..fdd8ae0 100644
--- a/include/provider.h
+++ b/include/provider.h
@@ -79,6 +79,7 @@ void connman_provider_unref_debug(struct connman_provider *provider,
const char *file, int line, const char *caller);
int connman_provider_disconnect(struct connman_provider *provider);
+int connman_provider_remove(struct connman_provider *provider);
int connman_provider_set_string(struct connman_provider *provider,
const char *key, const char *value);
diff --git a/src/provider.c b/src/provider.c
index b86e7d6..f7bb4e1 100644
--- a/src/provider.c
+++ b/src/provider.c
@@ -150,6 +150,19 @@ int connman_provider_disconnect(struct connman_provider *provider)
return 0;
}
+int connman_provider_remove(struct connman_provider *provider)
+{
+ DBG("Removing VPN %s", provider->identifier);
+
+ provider_remove(provider);
+
+ connman_provider_set_state(provider, CONNMAN_PROVIDER_STATE_IDLE);
+
+ g_hash_table_remove(provider_hash, provider->identifier);
+
+ return 0;
+}
+
int __connman_provider_connect(struct connman_provider *provider)
{
int err;
diff --git a/plugins/vpn.c b/plugins/vpn.c
index f60a658..cda0c1b 100644
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -1440,7 +1440,7 @@ static void destroy_provider(struct connection_data *data)
connman_provider_set_data(data->provider, NULL);
- connman_provider_put(data->provider);
+ connman_provider_remove(data->provider);
data->provider = NULL;
}
diff --git a/plugins/vpn.c b/plugins/vpn.c
index cda0c1b..f15796d 100644
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -252,6 +252,8 @@ static void set_provider_state(struct connection_data *data)
enum connman_provider_state state = CONNMAN_PROVIDER_STATE_UNKNOWN;
int err = 0;
+ DBG("provider %p new state %s", data->provider, data->state);
+
if (g_str_equal(data->state, "ready") == TRUE) {
state = CONNMAN_PROVIDER_STATE_READY;
goto set;
diff --git a/plugins/vpn.c b/plugins/vpn.c
index f15796d..04318a9 100644
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -796,6 +796,14 @@ static int provider_remove(struct connman_provider *provider)
DBG("provider %p data %p", provider, data);
+ if (data == NULL) {
+ /*
+ * This means the provider is already removed,
+ * just ignore the dbus in this case.
+ */
+ return -EALREADY;
+ }
+
/*
* When provider.c:provider_remove() calls this function,
* it will remove the provider itself after the call.
diff --git a/plugins/vpn.c b/plugins/vpn.c
index 04318a9..038a833 100644
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -1508,6 +1508,7 @@ static gboolean connection_removed(DBusConnection *conn, DBusMessage *message,
{
const char *path;
const char *signature = DBUS_TYPE_OBJECT_PATH_AS_STRING;
+ struct connection_data *data;
if (dbus_message_has_signature(message, signature) == FALSE) {
connman_error("vpn removed signature \"%s\" does not match "
@@ -1518,7 +1519,11 @@ static gboolean connection_removed(DBusConnection *conn, DBusMessage *message,
dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
DBUS_TYPE_INVALID);
- remove_connection(conn, path);
+
+ data = g_hash_table_lookup(vpn_connections, get_ident(path));
+ if (data != NULL)
+ remove_connection(conn, path);
+
return TRUE;
}