summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2007-06-22 01:55:36 +0000
committerDan Williams <dcbw@redhat.com>2007-06-22 01:55:36 +0000
commit1becbb498c52b9bffd1c2c1ce9847cac816545ec (patch)
tree0821f87538e462c5ad74a65ec5b7b5e06df0dc3d
parentbd176dcdccf6f6f1402958cfc1ff1cb71da53c32 (diff)
downloadNetworkManager-1becbb498c52b9bffd1c2c1ce9847cac816545ec.tar.gz
2007-06-21 Dan Williams <dcbw@redhat.com>
* dispatcher-daemon/NetworkManagerDispatcher.c - Add MESH_READY and MESH_DOWN events - Keep a cache of interface <-> object path mappings, so that when NM goes away the dispatcher can still figure out what the interface is for the deactivated signal git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/branches/nm-0-6-olpc@2612 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
-rw-r--r--ChangeLog8
-rw-r--r--dispatcher-daemon/NetworkManagerDispatcher.c169
2 files changed, 148 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index f9c6624cbc..31e8e75ced 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2007-06-21 Dan Williams <dcbw@redhat.com>
+ * dispatcher-daemon/NetworkManagerDispatcher.c
+ - Add MESH_READY and MESH_DOWN events
+ - Keep a cache of interface <-> object path mappings, so that when NM
+ goes away the dispatcher can still figure out what the interface
+ is for the deactivated signal
+
+2007-06-21 Dan Williams <dcbw@redhat.com>
+
* configure.in
callouts/Makefile.am
- Add avahi-autoipd callouts
diff --git a/dispatcher-daemon/NetworkManagerDispatcher.c b/dispatcher-daemon/NetworkManagerDispatcher.c
index 8f1d366398..8d41352d95 100644
--- a/dispatcher-daemon/NetworkManagerDispatcher.c
+++ b/dispatcher-daemon/NetworkManagerDispatcher.c
@@ -44,6 +44,8 @@ enum NMDAction
NMD_DEVICE_DONT_KNOW,
NMD_DEVICE_NOW_INACTIVE,
NMD_DEVICE_NOW_ACTIVE,
+ NMD_MESH_READY,
+ NMD_MESH_DOWN
};
typedef enum NMDAction NMDAction;
@@ -52,6 +54,8 @@ typedef enum NMDAction NMDAction;
#define NMD_DEFAULT_PID_FILE LOCALSTATEDIR"/run/NetworkManagerDispatcher.pid"
+static GHashTable * ops_to_ifaces = NULL;
+
static DBusConnection *nmd_dbus_init (void);
/*
@@ -86,7 +90,7 @@ static inline gboolean nmd_permission_check (struct stat *s)
* Call scripts in /etc/NetworkManager.d when devices go down or up
*
*/
-static void nmd_execute_scripts (NMDAction action, char *iface_name)
+static void nmd_execute_scripts (NMDAction action, char *iface_name, char *iface2_name)
{
GDir * dir;
const char * file_name;
@@ -96,6 +100,10 @@ static void nmd_execute_scripts (NMDAction action, char *iface_name)
char_act = "up";
else if (action == NMD_DEVICE_NOW_INACTIVE)
char_act = "down";
+ else if (action == NMD_MESH_READY)
+ char_act = "meshready";
+ else if (action == NMD_MESH_DOWN)
+ char_act = "meshdown";
else
return;
@@ -117,7 +125,10 @@ static void nmd_execute_scripts (NMDAction action, char *iface_name)
char *cmd;
int ret;
- cmd = g_strdup_printf ("%s %s %s", file_path, iface_name, char_act);
+ if (!iface2_name)
+ cmd = g_strdup_printf ("%s %s %s", file_path, iface_name, char_act);
+ else
+ cmd = g_strdup_printf ("%s %s %s %s", file_path, iface_name, char_act, iface2_name);
ret = system (cmd);
if (ret == -1)
nm_warning ("nmd_execute_scripts(): system() failed with errno = %d", errno);
@@ -143,7 +154,11 @@ static char * nmd_get_device_name (DBusConnection *connection, char *path)
DBusMessage * reply;
DBusError error;
char * dbus_dev_name = NULL;
- char * dev_name = NULL;
+ char * iface = NULL;
+
+ iface = g_hash_table_lookup (ops_to_ifaces, path);
+ if (iface)
+ return iface;
if (!(message = dbus_message_new_method_call (NM_DBUS_SERVICE, path, NM_DBUS_INTERFACE, "getName")))
{
@@ -156,7 +171,7 @@ static char * nmd_get_device_name (DBusConnection *connection, char *path)
dbus_message_unref (message);
if (dbus_error_is_set (&error))
{
- nm_warning ("%s raised: %s", error.name, error.message);
+ nm_warning ("%s raised: %s (for %s)", error.name, error.message, path);
dbus_error_free (&error);
return NULL;
}
@@ -165,14 +180,16 @@ static char * nmd_get_device_name (DBusConnection *connection, char *path)
if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &dbus_dev_name, DBUS_TYPE_INVALID))
{
nm_warning ("There was an error getting the device name from NetworkManager." );
- dev_name = NULL;
+ iface = NULL;
+ }
+ else {
+ iface = g_strdup (dbus_dev_name);
+ g_hash_table_insert (ops_to_ifaces, path, iface);
}
- else
- dev_name = g_strdup (dbus_dev_name);
dbus_message_unref (reply);
- return dev_name;
+ return iface;
}
/*
@@ -192,6 +209,17 @@ static gboolean nmd_reinit_dbus (gpointer user_data)
return TRUE;
}
+static char *get_nm_match_string (const char *owner)
+{
+ g_return_val_if_fail (owner != NULL, NULL);
+
+ return g_strdup_printf ("type='signal',"
+ "interface='" NM_DBUS_INTERFACE "',"
+ "sender='%s',"
+ "path='" NM_DBUS_PATH "'",
+ owner);
+}
+
/*
* nmd_dbus_filter
*
@@ -201,7 +229,10 @@ static DBusHandlerResult nmd_dbus_filter (DBusConnection *connection, DBusMessag
{
const char *object_path;
DBusError error;
- char *dev_object_path = NULL;
+ char * dev_object_path = NULL;
+ char * dev_iface_name = NULL;
+ char * dev2_object_path = NULL;
+ char * dev2_iface_name = NULL;
gboolean handled = FALSE;
NMDAction action = NMD_DEVICE_DONT_KNOW;
@@ -212,41 +243,106 @@ static DBusHandlerResult nmd_dbus_filter (DBusConnection *connection, DBusMessag
{
dbus_connection_unref (connection);
connection = NULL;
+ g_hash_table_remove_all (ops_to_ifaces);
g_timeout_add (3000, nmd_reinit_dbus, NULL);
handled = TRUE;
+ goto out;
+ } else if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "NameOwnerChanged")) {
+ char * service;
+ char * old_owner;
+ char * new_owner;
+
+ if (dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &service,
+ DBUS_TYPE_STRING, &old_owner,
+ DBUS_TYPE_STRING, &new_owner,
+ DBUS_TYPE_INVALID)) {
+ gboolean old_owner_good = (old_owner && (strlen (old_owner) > 0));
+ gboolean new_owner_good = (new_owner && (strlen (new_owner) > 0));
+
+ if (strcmp (service, NM_DBUS_SERVICE) == 0) {
+ if (!old_owner_good && new_owner_good) {
+ char *match = get_nm_match_string (new_owner);
+ /* NM appeared */
+ dbus_bus_add_match (connection, match, NULL);
+ g_free (match);
+ handled = TRUE;
+ } else if (old_owner_good && !new_owner_good) {
+ char *match = get_nm_match_string (old_owner);
+ /* NM disappeared */
+ dbus_bus_remove_match (connection, match, NULL);
+ g_free (match);
+ g_hash_table_remove_all (ops_to_ifaces);
+ }
+ }
+ }
}
if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNoLongerActive"))
action = NMD_DEVICE_NOW_INACTIVE;
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNowActive"))
action = NMD_DEVICE_NOW_ACTIVE;
+ else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "MeshReady"))
+ action = NMD_MESH_READY;
+ else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "MeshDown"))
+ action = NMD_MESH_DOWN;
+ else
+ goto out;
- if (action != NMD_DEVICE_DONT_KNOW)
- {
- if (dbus_message_get_args (message, &error, DBUS_TYPE_OBJECT_PATH, &dev_object_path, DBUS_TYPE_INVALID))
- {
- char * dev_iface_name = NULL;
-
+ switch (action) {
+ case NMD_DEVICE_NOW_INACTIVE:
+ case NMD_DEVICE_NOW_ACTIVE:
+ if (!dbus_message_get_args (message, &error, DBUS_TYPE_OBJECT_PATH, &dev_object_path, DBUS_TYPE_INVALID))
+ break;
dev_object_path = nm_dbus_unescape_object_path (dev_object_path);
if (dev_object_path)
dev_iface_name = nmd_get_device_name (connection, dev_object_path);
- if (dev_object_path && dev_iface_name)
- {
- nm_info ("Device %s (%s) is now %s.", dev_object_path, dev_iface_name,
- (action == NMD_DEVICE_NOW_INACTIVE ? "down" :
- (action == NMD_DEVICE_NOW_ACTIVE ? "up" : "error")));
+ if (!dev_object_path || !dev_iface_name)
+ break;
- nmd_execute_scripts (action, dev_iface_name);
- }
+ nm_info ("Device %s (%s) is now %s.", dev_object_path, dev_iface_name,
+ (action == NMD_DEVICE_NOW_INACTIVE ? "down" : "up"));
- g_free (dev_object_path);
- g_free (dev_iface_name);
+ nmd_execute_scripts (action, dev_iface_name, NULL);
+ handled = TRUE;
+ break;
+
+ case NMD_MESH_DOWN:
+ case NMD_MESH_READY:
+ if (!dbus_message_get_args (message, &error,
+ DBUS_TYPE_OBJECT_PATH, &dev_object_path,
+ DBUS_TYPE_OBJECT_PATH, &dev2_object_path,
+ DBUS_TYPE_INVALID))
+ break;
+ dev_object_path = nm_dbus_unescape_object_path (dev_object_path);
+ if (dev_object_path)
+ dev_iface_name = nmd_get_device_name (connection, dev_object_path);
+ dev2_object_path = nm_dbus_unescape_object_path (dev2_object_path);
+ if (dev2_object_path)
+ dev2_iface_name = nmd_get_device_name (connection, dev2_object_path);
+
+ if (!dev_object_path || !dev_iface_name || !dev2_object_path || !dev2_iface_name)
+ break;
+
+ nm_info ("Mesh Device %s (%s) is now %s (primary dev %s).",
+ dev_object_path,
+ dev_iface_name,
+ (action == NMD_MESH_READY ? "ready" : "down"),
+ dev2_iface_name);
+ nmd_execute_scripts (action, dev_iface_name, dev2_iface_name);
handled = TRUE;
- }
+ break;
+
+ default:
+ break;
}
+out:
+ g_free (dev_object_path);
+ g_free (dev2_object_path);
+
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}
@@ -403,12 +499,27 @@ int main (int argc, char *argv[])
g_thread_init (NULL);
/* Connect to the NetworkManager dbus service and run the main loop */
- if ((connection = nmd_dbus_init ()))
- {
- loop = g_main_loop_new (NULL, FALSE);
- g_main_loop_run (loop);
+ if (!(connection = nmd_dbus_init ()))
+ goto done;
+
+ loop = g_main_loop_new (NULL, FALSE);
+ if (!loop) {
+ nm_warning ("Couldn't allocate mainloop!");
+ goto done;
}
+ ops_to_ifaces = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ g_free);
+ if (!ops_to_ifaces) {
+ nm_warning ("Couldn't allocate object path to interface hash table!");
+ goto done;
+ }
+
+ g_main_loop_run (loop);
+
+done:
/* Clean up pidfile */
if (pidfile)
unlink (pidfile);