diff options
author | Dan Winship <danw@gnome.org> | 2013-11-04 15:28:19 -0500 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2013-11-06 10:27:53 -0500 |
commit | 3dd9102947845abd5145e3d688df9ff989eb362f (patch) | |
tree | 0398f690e0db3e188cfb31141680dbd4e1cc3604 | |
parent | 736dfcc59547d77a82b474f28ce47ecc47baf660 (diff) | |
download | network-manager-applet-3dd9102947845abd5145e3d688df9ff989eb362f.tar.gz |
connection-editor: improve handling of NPAR/SR-IOV devices (rh #804527)
Warn the user when a bond or team connection contains multiple slaves
on the same physical port.
-rw-r--r-- | src/connection-editor/nm-connection-editor.c | 30 | ||||
-rw-r--r-- | src/connection-editor/nm-connection-editor.h | 4 | ||||
-rw-r--r-- | src/connection-editor/page-bond.c | 1 | ||||
-rw-r--r-- | src/connection-editor/page-master.c | 90 | ||||
-rw-r--r-- | src/connection-editor/page-master.h | 2 | ||||
-rw-r--r-- | src/connection-editor/page-team.c | 1 |
6 files changed, 122 insertions, 6 deletions
diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c index 3024244f..eb4055a0 100644 --- a/src/connection-editor/nm-connection-editor.c +++ b/src/connection-editor/nm-connection-editor.c @@ -1103,22 +1103,20 @@ nm_connection_editor_set_busy (NMConnectionEditor *editor, gboolean busy) } } -void -nm_connection_editor_error (GtkWindow *parent, const char *heading, const char *format, ...) +static void +nm_connection_editor_dialog (GtkWindow *parent, GtkMessageType type, const char *heading, + const char *format, va_list args) { GtkWidget *dialog; - va_list args; char *message; dialog = gtk_message_dialog_new (parent, GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, + type, GTK_BUTTONS_CLOSE, "%s", heading); - va_start (args, format); message = g_strdup_vprintf (format, args); - va_end (args); gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", message); g_free (message); @@ -1129,3 +1127,23 @@ nm_connection_editor_error (GtkWindow *parent, const char *heading, const char * gtk_widget_destroy (dialog); } +void +nm_connection_editor_error (GtkWindow *parent, const char *heading, const char *format, ...) +{ + va_list args; + + va_start (args, format); + nm_connection_editor_dialog (parent, GTK_MESSAGE_ERROR, heading, format, args); + va_end (args); +} + +void +nm_connection_editor_warning (GtkWindow *parent, const char *heading, const char *format, ...) +{ + va_list args; + + va_start (args, format); + nm_connection_editor_dialog (parent, GTK_MESSAGE_WARNING, heading, format, args); + va_end (args); +} + diff --git a/src/connection-editor/nm-connection-editor.h b/src/connection-editor/nm-connection-editor.h index 4798b0fe..0a13afda 100644 --- a/src/connection-editor/nm-connection-editor.h +++ b/src/connection-editor/nm-connection-editor.h @@ -93,5 +93,9 @@ void nm_connection_editor_error (GtkWindow *parent, const char *heading, const char *format, ...); +void nm_connection_editor_warning (GtkWindow *parent, + const char *heading, + const char *format, + ...); #endif diff --git a/src/connection-editor/page-bond.c b/src/connection-editor/page-bond.c index 9c2c8895..69746859 100644 --- a/src/connection-editor/page-bond.c +++ b/src/connection-editor/page-bond.c @@ -548,6 +548,7 @@ validate (CEPage *page, NMConnection *connection, GError **error) static void ce_page_bond_init (CEPageBond *self) { + CE_PAGE_MASTER (self)->aggregating = TRUE; } static void diff --git a/src/connection-editor/page-master.c b/src/connection-editor/page-master.c index dfa75e34..e9c928ab 100644 --- a/src/connection-editor/page-master.c +++ b/src/connection-editor/page-master.c @@ -176,6 +176,94 @@ connection_updated (NMRemoteConnection *connection, gpointer user_data) -1); } +static NMDevice * +get_device_for_connection (NMClient *client, NMConnection *conn) +{ + const GPtrArray *devices; + NMSettingConnection *s_con; + int i; + + devices = nm_client_get_devices (client); + if (!devices) + return NULL; + + /* Make sure the connection is actually locked to a specific device */ + s_con = nm_connection_get_setting_connection (conn); + if ( !nm_setting_connection_get_interface_name (s_con) + && !nm_connection_get_virtual_iface_name (conn)) { + NMSetting *s_hw; + GByteArray *mac_address; + + s_hw = nm_connection_get_setting_by_name (conn, nm_setting_connection_get_connection_type (s_con)); + if (!s_hw || !g_object_class_find_property (G_OBJECT_GET_CLASS (s_hw), "mac-address")) + return NULL; + + g_object_get (G_OBJECT (s_hw), "mac-address", &mac_address, NULL); + if (!mac_address) + return NULL; + g_byte_array_unref (mac_address); + } + + /* OK, now find that device */ + for (i = 0; i < devices->len; i++) { + NMDevice *device = devices->pdata[i]; + + if (nm_device_connection_compatible (device, conn, NULL)) + return device; + } + + return NULL; +} + +static void +check_new_slave_physical_port (CEPageMaster *self, NMConnection *conn) +{ + CEPageMasterPrivate *priv = CE_PAGE_MASTER_GET_PRIVATE (self); + NMConnection *conn2; + NMDevice *dev, *dev2; + const char *id, *id2; + GtkTreeIter iter; + + dev = get_device_for_connection (CE_PAGE (self)->client, conn); + if (!dev) + return; + id = nm_device_get_physical_port_id (dev); + if (!id) + return; + + if (!gtk_tree_model_get_iter_first (priv->connections_model, &iter)) + return; + do { + gtk_tree_model_get (priv->connections_model, &iter, 0, &conn2, -1); + g_object_unref (conn2); /* gtk_tree_model_get() adds a ref */ + dev2 = get_device_for_connection (CE_PAGE (self)->client, conn2); + if (!dev2) + continue; + if (dev == dev2) { + nm_connection_editor_warning (CE_PAGE (self)->parent_window, + _("Duplicate slaves"), + _("Slaves '%s' and '%s' both apply to device '%s'"), + nm_connection_get_id (conn), + nm_connection_get_id (conn2), + nm_device_get_iface (dev)); + return; + } + + id2 = nm_device_get_physical_port_id (dev2); + if (self->aggregating && id && id2 && !strcmp (id, id2)) { + nm_connection_editor_warning (CE_PAGE (self)->parent_window, + _("Duplicate slaves"), + _("Slaves '%s' and '%s' apply to different virtual " + "ports ('%s' and '%s') of the same physical device."), + nm_connection_get_id (conn), + nm_connection_get_id (conn2), + nm_device_get_iface (dev), + nm_device_get_iface (dev2)); + return; + } + } while (gtk_tree_model_iter_next (priv->connections_model, &iter)); +} + static void connection_added (NMRemoteSettings *settings, NMRemoteConnection *connection, @@ -208,6 +296,8 @@ connection_added (NMRemoteSettings *settings, if (strcmp (master, interface_name) != 0 && strcmp (master, priv->uuid) != 0) return; + check_new_slave_physical_port (self, NM_CONNECTION (connection)); + gtk_list_store_append (GTK_LIST_STORE (priv->connections_model), &iter); gtk_list_store_set (GTK_LIST_STORE (priv->connections_model), &iter, COL_CONNECTION, connection, diff --git a/src/connection-editor/page-master.h b/src/connection-editor/page-master.h index 5bd05756..56cc6c41 100644 --- a/src/connection-editor/page-master.h +++ b/src/connection-editor/page-master.h @@ -38,6 +38,8 @@ typedef struct { CEPage parent; + + gboolean aggregating; } CEPageMaster; typedef struct { diff --git a/src/connection-editor/page-team.c b/src/connection-editor/page-team.c index 9b2e0f5c..1c79a76d 100644 --- a/src/connection-editor/page-team.c +++ b/src/connection-editor/page-team.c @@ -314,6 +314,7 @@ validate (CEPage *page, NMConnection *connection, GError **error) static void ce_page_team_init (CEPageTeam *self) { + CE_PAGE_MASTER (self)->aggregating = TRUE; } static void |