After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 696387 - [review] dcbw/libnm-connection-replace: simplify replacing all of a connection's settings
[review] dcbw/libnm-connection-replace: simplify replacing all of a connectio...
Status: RESOLVED FIXED
Product: NetworkManager
Classification: Platform
Component: API
git master
Other Linux
: Normal normal
: ---
Assigned To: Jiri Klimes
NetworkManager maintainer(s)
Depends on:
Blocks:
 
 
Reported: 2013-03-22 13:05 UTC by Jiri Klimes
Modified: 2013-04-22 15:48 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Implement nm_connection_replace_settings_from_connection() (2.54 KB, patch)
2013-03-26 20:22 UTC, Dan Williams
none Details | Review
[PATCH] minor changes to the previous patch (5.58 KB, patch)
2013-04-10 11:07 UTC, Jiri Klimes
none Details | Review
[PATCH] make nm_connection_replace_settings_from_connection() safer (1.31 KB, patch)
2013-04-22 13:32 UTC, Jiri Klimes
none Details | Review

Description Jiri Klimes 2013-03-22 13:05:31 UTC
Maybe, I'm missing something. But when I want save/update connection with nm_remote_connection_commit_changes() it takes new settings out of the NMRemoteConnection (the first parameter). It is a problem because if I first save a connection via nm_remote_settings_add_connection(), a new NMRemoteConnection is created. On update I need to change this connection.

I guess the function should rather look like
nm_remote_connection_commit_changes (NMRemoteConnection *self,
                                     NMConnection *new_connection,
                                     NMRemoteConnectionCommitFunc callback,
                                     gpointer user_data)

'self' should be updated according to 'new_connection' and then send it to NM for storage.
or introduce such a function with a new name (nm_remote_connection_update())


At present, I use this code snippet:
GHashTable *new_settings;
new_settings = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL);
nm_connection_replace_settings  (NM_CONNECTION (rc), new_settings, NULL);
g_hash_table_destroy (new_settings);
nm_remote_connection_commit_changes (rc, update_connection_guided_cb, NULL);

Not related note:
While testing this, I noticed that ethernet properties like 'speed', 'port', 'duplex' are note saved when using ifcfg-rh plugin.
Comment 1 Dan Williams 2013-03-26 14:27:22 UTC
(In reply to comment #0)
> Not related note:
> While testing this, I noticed that ethernet properties like 'speed', 'port',
> 'duplex' are note saved when using ifcfg-rh plugin.

Yeah, they actually never got implemented in NM, a lower priority I guess.  We'd need to use ethtool to set these since I don't think libnl can do it.
Comment 2 Dan Williams 2013-03-26 20:21:19 UTC
(In reply to comment #0)
> Maybe, I'm missing something. But when I want save/update connection with
> nm_remote_connection_commit_changes() it takes new settings out of the
> NMRemoteConnection (the first parameter). It is a problem because if I first
> save a connection via nm_remote_settings_add_connection(), a new
> NMRemoteConnection is created. On update I need to change this connection.

nm_remote_settings_add_connection() should wait until NetworkManager signals the new remote connection is ready and then call your callback with the new RemoteConnection; it'll also emit the new-connection signal when the connection is ready.  If not we should fix it.

After this happens, what needs to be updated in the new RemoteConnection?  Are there additional properties that need to be set that weren't part of the original connection data sent to nm_remote_settings_add_connection() that the new RemoteConnection was created for?

Perhaps I don't understand the actual problem... if any of this doesn't make sense please let me know.

> I guess the function should rather look like
> nm_remote_connection_commit_changes (NMRemoteConnection *self,
>                                      NMConnection *new_connection,
>                                      NMRemoteConnectionCommitFunc callback,
>                                      gpointer user_data)
> 
> 'self' should be updated according to 'new_connection' and then send it to NM
> for storage.
> or introduce such a function with a new name (nm_remote_connection_update())

There are really two ways to change the remote connection data:

1) construct a completely new NMConnection and call nm_connection_replace_settings (remote, new_connection);

2) manipulate settings and properties of the RemoteConnection directly through nm_connection_get_setting (NM_CONNECTION (remote), XXX) and g_object_set() some property of the setting

In both these cases, of course the change is only made locally to the RemoteConnection and then it needs to be sent to NetworkManager, which is what commit_changes() is for.

I think for long-running operations, #1 is better, because if something else changes the connection at any point, the RemoteConnection object will be refreshed by libnm-glib automatically.

But for a short operation that doesn't run a mainloop iteration, such as changing one or two properties, method #2 is quicker and more direct.

Your suggestion, which is perfectly valid, would flip this around so that #2 would then become:

c = nm_connection_duplicate (NM_CONNECTION (remote));
s = nm_connection_get_setting (c, xxxx);
g_object_set (s, "foobar", "some value");
nm_remote_connection_commit_commit_changes (remote, c, xxx);

so I think it's no gain either way we do it.

> At present, I use this code snippet:
> GHashTable *new_settings;
> new_settings = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL);
> nm_connection_replace_settings  (NM_CONNECTION (rc), new_settings, NULL);
> g_hash_table_destroy (new_settings);
> nm_remote_connection_commit_changes (rc, update_connection_guided_cb, NULL);

Yeah, and you're totally correct that this is ugly too.  We should make this better.  So how about, instead of changing the commit_changes() function, we add a new libnm-util function like:

nm_connection_replace_settings_from_connection (old, new);

like the attached patch?  Then you could:

nm_connection_replace_settings_from_connection (NM_CONNECTION (remote), connection);
nm_remote_connection_commit_changes (remote, xxx);

instead of having to deal with the hash table?  Untested patch attached.
Comment 3 Dan Williams 2013-03-26 20:22:13 UTC
Created attachment 239894 [details] [review]
Implement nm_connection_replace_settings_from_connection()
Comment 4 Jiri Klimes 2013-04-10 11:01:28 UTC
(In reply to comment #2)
> (In reply to comment #0)
> > Maybe, I'm missing something. But when I want save/update connection with
> > nm_remote_connection_commit_changes() it takes new settings out of the
> > NMRemoteConnection (the first parameter). It is a problem because if I first
> > save a connection via nm_remote_settings_add_connection(), a new
> > NMRemoteConnection is created. On update I need to change this connection.
> 
> nm_remote_settings_add_connection() should wait until NetworkManager signals
> the new remote connection is ready and then call your callback with the new
> RemoteConnection; it'll also emit the new-connection signal when the connection
> is ready.  If not we should fix it.
> 
This work fine.

> After this happens, what needs to be updated in the new RemoteConnection?  Are
> there additional properties that need to be set that weren't part of the
> original connection data sent to nm_remote_settings_add_connection() that the
> new RemoteConnection was created for?
> 
> Perhaps I don't understand the actual problem... if any of this doesn't make
> sense please let me know.
> 
I probably didn't express myself clearly and have different expectations of 
nm_remote_connection_commit_commit_changes().
I kind of guessed it would take a new connection and update both NMRemoteConnection locally and send it to NM.
I now realize that I should update NMRemoteConnection first myself and then simply commit the changes with nm_remote_connection_commit_commit_changes().

Your patch of nm_connection_replace_settings_from_connection() will help in no messing with hashes. See my changes to the patch bellow.

My basic use case is:
- creating NMConnection object
- save it the first time with nm_remote_settings_add_connection
- continue changing the NMConnection object
- send updated connection to NM
Comment 5 Jiri Klimes 2013-04-10 11:05:18 UTC
Review of attachment 239894 [details] [review]:

The patch works fine.

Just minor changes:
- moving nm_connection_replace_settings_from_connection() right after nm_connection_replace_settings()
- renaming 'new' parameter to 'new_connection' (possible clash with 'new' keyword)
- adding 'Since: 0.9.10'
- updating libnm-util.ver
Comment 6 Jiri Klimes 2013-04-10 11:07:12 UTC
Created attachment 241133 [details] [review]
[PATCH] minor changes to the previous patch

Changes pointed out in the previous comment.
Comment 7 Dan Williams 2013-04-11 18:33:03 UTC
I consolidated jklimes' patch into the first commit and then converted the only(!) relevant user of nm_connection_to_hash() to use the new API.

Also see the applet git dcbw/editor-save-simplify branch for another conversion to the new API.
Comment 8 Pavel Simerda 2013-04-12 15:29:29 UTC
(In reply to comment #1)
> (In reply to comment #0)
> > Not related note:
> > While testing this, I noticed that ethernet properties like 'speed', 'port',
> > 'duplex' are note saved when using ifcfg-rh plugin.
> 
> Yeah, they actually never got implemented in NM, a lower priority I guess. 
> We'd need to use ethtool to set these since I don't think libnl can do it.

Feel free to add a RFE and assign it to me if you have something related to nm-platform.
Comment 9 Jiri Klimes 2013-04-16 17:31:16 UTC
(In reply to comment #7)
> I consolidated jklimes' patch into the first commit and then converted the
> only(!) relevant user of nm_connection_to_hash() to use the new API.
> 
> Also see the applet git dcbw/editor-save-simplify branch for another conversion
> to the new API.
I just wonder if it is guaranteed that self->>orig_connection is NM_REMOTE_CONNECTION and not a plain NM_CONNECTION in 

nm_remote_connection_commit_changes (
  NM_REMOTE_CONNECTION (self->orig_connection),
  updated_connection_cb, self);

Otherwise, it seems good.
Comment 10 Dan Winship 2013-04-16 17:38:10 UTC
(In reply to comment #9)
> I just wonder if it is guaranteed that self->>orig_connection is
> NM_REMOTE_CONNECTION and not a plain NM_CONNECTION

It is; self->connection is a plain NMConnection, but if orig_connection is non-NULL, it's always an NMRemoteConnection.
Comment 11 Dan Williams 2013-04-16 21:26:34 UTC
So it all looks good?
Comment 12 Pavel Simerda 2013-04-17 10:19:19 UTC
Looks good to me.
Comment 13 Dan Williams 2013-04-17 17:35:35 UTC
Merged.
Comment 14 Jiri Klimes 2013-04-22 13:32:23 UTC
Created attachment 242133 [details] [review]
[PATCH] make nm_connection_replace_settings_from_connection() safer

Reopening to add a small fix to nm_connection_replace_settings_from_connection()

Handle connection==new_connection condition gracefully so that 'connection' is not harmed.
Comment 15 Dan Winship 2013-04-22 14:39:33 UTC
Comment on attachment 242133 [details] [review]
[PATCH] make nm_connection_replace_settings_from_connection() safer

Hm... should this be a silent no-op or a g_return_if_fail()? What circumstances does this happen in?
Comment 16 Dan Williams 2013-04-22 15:33:19 UTC
I think silent no-op; I don't know why a client would try this (maybe it just makes the code easier?) but it doesn't seem like we should penalize the client if the solution is so simple.

Pushed the patch, thanks!
Comment 17 Jiri Klimes 2013-04-22 15:48:06 UTC
Basically, it was just an client (my ;-)) error. But I think it is not nice to destroy the connection due to that.
Thanks!