[network-manager-applet/danw/sriov: 2/2] connection-editor: improve handling of NPAR/SR-IOV devices (rh #804527)



commit 7339f618af7dde5a33876dfdfbd9c060bc71a0c0
Author: Dan Winship <danw gnome org>
Date:   Mon Nov 4 15:28:19 2013 -0500

    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.

 src/connection-editor/nm-connection-editor.c |   30 +++++++--
 src/connection-editor/page-bond.c            |    1 +
 src/connection-editor/page-master.c          |   90 ++++++++++++++++++++++++++
 src/connection-editor/page-master.h          |    2 +
 src/connection-editor/page-team.c            |    1 +
 5 files changed, 118 insertions(+), 6 deletions(-)
---
diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c
index 3024244..eb4055a 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/page-bond.c b/src/connection-editor/page-bond.c
index cf6abc3..492f928 100644
--- a/src/connection-editor/page-bond.c
+++ b/src/connection-editor/page-bond.c
@@ -544,6 +544,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 727d434..5709563 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 5bd0575..56cc6c4 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 bbae0bf..e3c6e20 100644
--- a/src/connection-editor/page-team.c
+++ b/src/connection-editor/page-team.c
@@ -310,6 +310,7 @@ validate (CEPage *page, NMConnection *connection, GError **error)
 static void
 ce_page_team_init (CEPageTeam *self)
 {
+       CE_PAGE_MASTER (self)->aggregating = TRUE;
 }
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]