From 54086127ef6dcabcf387101305668103bd5c3b1d Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 21 Feb 2017 10:14:50 +0100 Subject: [PATCH 1/6] ifcfg-rh: don't shortcut writing if the connection stays the same Some keys, such as MASTER may still be different as they may depend on other connections. svWriteFile() checks if the resulting file is different already anyway. --- .../ifcfg-rh/nms-ifcfg-rh-connection.c | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c index 33f4847ed..3833f3574 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c @@ -336,35 +336,12 @@ commit_changes (NMSettingsConnection *connection, gpointer user_data) { GError *error = NULL; - NMConnection *reread; - gboolean same = FALSE, success = FALSE; + gboolean success = FALSE; char *ifcfg_path = NULL; const char *filename; - /* To ensure we don't rewrite files that are only changed from other - * processes on-disk, read the existing connection back in and only rewrite - * it if it's really changed. - */ filename = nm_settings_connection_get_filename (connection); if (filename) { - gs_free char *unhandled = NULL; - - reread = connection_from_file (filename, &unhandled, NULL, NULL); - if (reread) { - same = nm_connection_compare (NM_CONNECTION (connection), - reread, - NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS | - NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS); - g_object_unref (reread); - - /* Don't bother writing anything out if in-memory and on-disk data are the same */ - if (same) { - /* But chain up to parent to handle success - emits updated signal */ - NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->commit_changes (connection, commit_reason, callback, user_data); - return; - } - } - success = writer_update_connection (NM_CONNECTION (connection), IFCFG_DIR, filename, From b47340fd3f70c2636bb5dae56a5310b59b88cf7a Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 21 Feb 2017 09:57:54 +0100 Subject: [PATCH 2/6] settings-connection: fix Save() Avoid using new_settings when they are none. Also, don't shortcut when the connection hasn't been changed -- let the settings plugin decide if it needs to rewrite the connection. --- src/settings/nm-settings-connection.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index e443920ef..827a67b2c 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -1711,6 +1711,17 @@ update_auth_cb (NMSettingsConnection *self, return; } + if (!info->new_settings) { + /* We're just calling Save(). Just commit the existing connection. */ + if (info->save_to_disk) { + nm_settings_connection_commit_changes (self, + NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION, + con_update_cb, + info); + } + return; + } + if (!any_secrets_present (info->new_settings)) { /* If the new connection has no secrets, we do not want to remove all * secrets, rather we keep all the existing ones. Do that by merging @@ -1860,11 +1871,7 @@ static void impl_settings_connection_save (NMSettingsConnection *self, GDBusMethodInvocation *context) { - /* Do nothing if the connection is already synced with disk */ - if (nm_settings_connection_get_unsaved (self)) - settings_connection_update_helper (self, context, NULL, TRUE); - else - g_dbus_method_invocation_return_value (context, NULL); + settings_connection_update_helper (self, context, NULL, TRUE); } static void From 8fce72360e36cef4551936c64e079fd666f6fd96 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 20 Feb 2017 19:05:42 +0100 Subject: [PATCH 3/6] tui/edit-connection-list: add routine to recommit connections in a list This is useful when master connections are saved potentially influencing how slave connections are serialized. --- clients/tui/nmt-edit-connection-list.c | 27 ++++++++++++++++++++++++++ clients/tui/nmt-edit-connection-list.h | 2 ++ 2 files changed, 29 insertions(+) diff --git a/clients/tui/nmt-edit-connection-list.c b/clients/tui/nmt-edit-connection-list.c index a1a59e014..e90140b3c 100644 --- a/clients/tui/nmt-edit-connection-list.c +++ b/clients/tui/nmt-edit-connection-list.c @@ -319,6 +319,33 @@ listbox_activated (NmtNewtWidget *listbox, gpointer list) edit_clicked (NMT_NEWT_BUTTON (priv->edit), list); } + +static void +connection_saved (GObject *conn, + GAsyncResult *result, + gpointer user_data) +{ + nm_remote_connection_save_finish (NM_REMOTE_CONNECTION (conn), result, NULL); +} + +void +nmt_edit_connection_list_recommit (NmtEditConnectionList *list) +{ + NmtEditConnectionListPrivate *priv = NMT_EDIT_CONNECTION_LIST_GET_PRIVATE (list); + NMConnection *conn; + GSList *iter; + + for (iter = priv->connections; iter; iter = iter->next) { + conn = iter->data; + + if ( NM_IS_REMOTE_CONNECTION (conn) + && (nm_remote_connection_get_unsaved (NM_REMOTE_CONNECTION (conn)) == FALSE)) { + nm_remote_connection_save_async (NM_REMOTE_CONNECTION (conn), + NULL, connection_saved, NULL); + } + } +} + static void nmt_edit_connection_list_finalize (GObject *object) { diff --git a/clients/tui/nmt-edit-connection-list.h b/clients/tui/nmt-edit-connection-list.h index fd492bce7..241bbe3ab 100644 --- a/clients/tui/nmt-edit-connection-list.h +++ b/clients/tui/nmt-edit-connection-list.h @@ -52,4 +52,6 @@ typedef gboolean (*NmtEditConnectionListFilter) (NmtEditConnectionList *list, NMConnection *connection, gpointer user_data); +void nmt_edit_connection_list_recommit (NmtEditConnectionList *list); + #endif /* NMT_EDIT_CONNECTION_LIST_H */ From c8969dbf8068d7e930fe1f556e1ff3c899c61cc2 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 20 Feb 2017 19:06:37 +0100 Subject: [PATCH 4/6] tui/editor: notify the pages after the connection is saved This will make it possible for the pages to commit slave connections when the master connection is saved. --- clients/tui/nmt-editor-page.c | 17 +++++++++++++++++ clients/tui/nmt-editor-page.h | 3 +++ clients/tui/nmt-editor.c | 12 ++++++++++++ 3 files changed, 32 insertions(+) diff --git a/clients/tui/nmt-editor-page.c b/clients/tui/nmt-editor-page.c index 44abe2731..99475a919 100644 --- a/clients/tui/nmt-editor-page.c +++ b/clients/tui/nmt-editor-page.c @@ -112,6 +112,23 @@ nmt_editor_page_add_section (NmtEditorPage *page, priv->sections = g_slist_append (priv->sections, g_object_ref_sink (section)); } +/** + * nmt_editor_page_saved: + * @page: the #NmtEditorPage + * + * This method is called when the user saves the connection. It gives + * the page a chance to do save its data outside the connections (such as + * recommit the slave connections). + */ +void +nmt_editor_page_saved (NmtEditorPage *page) +{ + NmtEditorPageClass *editor_page_class = NMT_EDITOR_PAGE_GET_CLASS (page); + + if (editor_page_class->saved) + editor_page_class->saved (page); +} + static void nmt_editor_page_set_property (GObject *object, guint prop_id, diff --git a/clients/tui/nmt-editor-page.h b/clients/tui/nmt-editor-page.h index 8da5ea9f5..ae55128ac 100644 --- a/clients/tui/nmt-editor-page.h +++ b/clients/tui/nmt-editor-page.h @@ -39,6 +39,7 @@ typedef struct { typedef struct { GObjectClass parent; + void (*saved) (NmtEditorPage *page); } NmtEditorPageClass; GType nmt_editor_page_get_type (void); @@ -47,6 +48,8 @@ NMConnection *nmt_editor_page_get_connection (NmtEditorPage *page); GSList *nmt_editor_page_get_sections (NmtEditorPage *page); +void nmt_editor_page_saved (NmtEditorPage *page); + /*< protected >*/ void nmt_editor_page_add_section (NmtEditorPage *page, NmtEditorSection *section); diff --git a/clients/tui/nmt-editor.c b/clients/tui/nmt-editor.c index 395e661ae..515e34717 100644 --- a/clients/tui/nmt-editor.c +++ b/clients/tui/nmt-editor.c @@ -145,6 +145,15 @@ connection_added (GObject *client, g_clear_error (&error); } +static void +page_saved (gpointer data, gpointer user_data) +{ + NmtEditorPage *page = data; + + nmt_editor_page_saved (page); +} + + static void save_connection_and_exit (NmtNewtButton *button, gpointer user_data) @@ -183,6 +192,9 @@ save_connection_and_exit (NmtNewtButton *button, } } + /* Let the page know that it was saved. */ + g_slist_foreach (priv->pages, page_saved, NULL); + nmt_newt_form_quit (NMT_NEWT_FORM (editor)); } From 9cc15d39eb5257f05d3e6633d46a5a428f417917 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 20 Feb 2017 19:07:41 +0100 Subject: [PATCH 5/6] tui: recommit bond, bridge and team slaves on master save The ifcfg-rh plugin may want to update its MASTER= key accordingly for better compatibility with the legacy network service. --- clients/tui/nmt-page-bond.c | 10 ++++++++++ clients/tui/nmt-page-bridge.c | 18 ++++++++++++++++++ clients/tui/nmt-page-team.c | 10 ++++++++++ 3 files changed, 38 insertions(+) diff --git a/clients/tui/nmt-page-bond.c b/clients/tui/nmt-page-bond.c index 259ecfc16..48070dbf1 100644 --- a/clients/tui/nmt-page-bond.c +++ b/clients/tui/nmt-page-bond.c @@ -423,12 +423,22 @@ nmt_page_bond_constructed (GObject *object) G_OBJECT_CLASS (nmt_page_bond_parent_class)->constructed (object); } +static void +nmt_page_bond_saved (NmtEditorPage *editor_page) +{ + NmtPageBondPrivate *priv = NMT_PAGE_BOND_GET_PRIVATE (editor_page); + + nmt_edit_connection_list_recommit (NMT_EDIT_CONNECTION_LIST (priv->slaves)); +} + static void nmt_page_bond_class_init (NmtPageBondClass *bond_class) { GObjectClass *object_class = G_OBJECT_CLASS (bond_class); + NmtEditorPageClass *editor_page_class = NMT_EDITOR_PAGE_CLASS (bond_class); g_type_class_add_private (bond_class, sizeof (NmtPageBondPrivate)); object_class->constructed = nmt_page_bond_constructed; + editor_page_class->saved = nmt_page_bond_saved; } diff --git a/clients/tui/nmt-page-bridge.c b/clients/tui/nmt-page-bridge.c index b5eb9ec88..08526db42 100644 --- a/clients/tui/nmt-page-bridge.c +++ b/clients/tui/nmt-page-bridge.c @@ -30,6 +30,12 @@ G_DEFINE_TYPE (NmtPageBridge, nmt_page_bridge, NMT_TYPE_EDITOR_PAGE_DEVICE) +#define NMT_PAGE_BRIDGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMT_TYPE_PAGE_BRIDGE, NmtPageBridgePrivate)) + +typedef struct { + NmtSlaveList *slaves; +} NmtPageBridgePrivate; + NmtEditorPage * nmt_page_bridge_new (NMConnection *conn, NmtDeviceEntry *deventry) @@ -58,6 +64,7 @@ static void nmt_page_bridge_constructed (GObject *object) { NmtPageBridge *bridge = NMT_PAGE_BRIDGE (object); + NmtPageBridgePrivate *priv = NMT_PAGE_BRIDGE_GET_PRIVATE (bridge); NmtEditorSection *section; NmtEditorGrid *grid; NMSettingBridge *s_bridge; @@ -80,6 +87,7 @@ nmt_page_bridge_constructed (GObject *object) widget = nmt_slave_list_new (conn, bridge_connection_type_filter, bridge); nmt_editor_grid_append (grid, NULL, widget, NULL); + priv->slaves = NMT_SLAVE_LIST (widget); widget = nmt_newt_entry_numeric_new (10, 0, 1000000); g_object_bind_property (s_bridge, NM_SETTING_BRIDGE_AGEING_TIME, @@ -144,10 +152,20 @@ nmt_page_bridge_constructed (GObject *object) G_OBJECT_CLASS (nmt_page_bridge_parent_class)->constructed (object); } +static void +nmt_page_bridge_saved (NmtEditorPage *editor_page) +{ + NmtPageBridgePrivate *priv = NMT_PAGE_BRIDGE_GET_PRIVATE (editor_page); + + nmt_edit_connection_list_recommit (NMT_EDIT_CONNECTION_LIST (priv->slaves)); +} + static void nmt_page_bridge_class_init (NmtPageBridgeClass *bridge_class) { GObjectClass *object_class = G_OBJECT_CLASS (bridge_class); + NmtEditorPageClass *editor_page_class = NMT_EDITOR_PAGE_CLASS (bridge_class); object_class->constructed = nmt_page_bridge_constructed; + editor_page_class->saved = nmt_page_bridge_saved; } diff --git a/clients/tui/nmt-page-team.c b/clients/tui/nmt-page-team.c index d7c4c4259..2523bd85d 100644 --- a/clients/tui/nmt-page-team.c +++ b/clients/tui/nmt-page-team.c @@ -179,12 +179,22 @@ nmt_page_team_constructed (GObject *object) G_OBJECT_CLASS (nmt_page_team_parent_class)->constructed (object); } +static void +nmt_page_team_saved (NmtEditorPage *editor_page) +{ + NmtPageTeamPrivate *priv = NMT_PAGE_TEAM_GET_PRIVATE (editor_page); + + nmt_edit_connection_list_recommit (NMT_EDIT_CONNECTION_LIST (priv->slaves)); +} + static void nmt_page_team_class_init (NmtPageTeamClass *team_class) { GObjectClass *object_class = G_OBJECT_CLASS (team_class); + NmtEditorPageClass *editor_page_class = NMT_EDITOR_PAGE_CLASS (team_class); g_type_class_add_private (team_class, sizeof (NmtPageTeamPrivate)); object_class->constructed = nmt_page_team_constructed; + editor_page_class->saved = nmt_page_team_saved; } From 9d2dfd9d977b21683d93c0facf303f52cee4347a Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 21 Feb 2017 12:00:27 +0100 Subject: [PATCH 6/6] ifcfg: avoid marking newly created connections as Unsaved --- src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c index 3833f3574..ba8ea323e 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c @@ -455,6 +455,11 @@ nm_ifcfg_connection_new (NMConnection *source, if (out_ignore_error) *out_ignore_error = FALSE; + if (full_path) { + /* The connection already is on the disk */ + update_unsaved = FALSE; + } + /* If we're given a connection already, prefer that instead of re-reading */ if (source) tmp = g_object_ref (source); @@ -465,9 +470,6 @@ nm_ifcfg_connection_new (NMConnection *source, out_ignore_error); if (!tmp) return NULL; - - /* If we just read the connection from disk, it's clearly not Unsaved */ - update_unsaved = FALSE; } if (unhandled_spec && g_str_has_prefix (unhandled_spec, "unmanaged:"))