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 764402 - monitor-connection-files fails when file was not modified with an editor
monitor-connection-files fails when file was not modified with an editor
Status: RESOLVED FIXED
Product: NetworkManager
Classification: Platform
Component: general
1.0.x
Other Linux
: Normal normal
: ---
Assigned To: NetworkManager maintainer(s)
NetworkManager maintainer(s)
Depends on:
Blocks:
 
 
Reported: 2016-03-31 08:47 UTC by Benjamin Lefoul
Modified: 2016-03-31 12:59 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Benjamin Lefoul 2016-03-31 08:47:16 UTC
When monitor-connection-files is set to true, and a current connection file (in this case "Red Hat style" ifcfg-eth0) is edited with a text editor (emacs or vi, etc.) to change an IP, it works fine.

Doing the same thing with sudoedit, or sed fails to cause nm to pick up the change, even when loading, reloading or fully restarting, and even though the inode numbers change similarly to an edition with a text-editor.

Follow through this and notice how easy it is to change IP from *.155 to *.166 with emacs, but it fails when using sed to change to *.177. Note the inode numbers. The only way to finally get this noticed is to open it with a text editor (here: vi) and immediately close it with ":wq" without a change since this was already done with sed (just ":q" fails).


[root@server0 ~]# grep "monitor" /etc/NetworkManager/NetworkManager.conf
monitor-connection-files=true
[root@server0 ~]# systemctl restart NetworkManager
[root@server0 ~]# ls -li /etc/sysconfig/network-scripts/ifcfg-eth0
712059 -rw-r--r--. 1 root root 357 Mar 31 07:20 /etc/sysconfig/network-scripts/ifcfg-eth0
[root@server0 ~]# grep "IPADDR" /etc/sysconfig/network-scripts/ifcfg-eth0
IPADDR=192.168.4.155
[root@server0 ~]# ip a | grep "eth0"
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.4.155/24 brd 192.168.4.255 scope global eth0
[root@server0 ~]# emacs /etc/sysconfig/network-scripts/ifcfg-eth0
[root@server0 ~]# grep "IPADDR" /etc/sysconfig/network-scripts/ifcfg-eth0
IPADDR=192.168.4.166
[root@server0 ~]# ip a | grep "eth0"
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.4.166/24 brd 192.168.4.255 scope global eth0
[root@server0 ~]# ls -li /etc/sysconfig/network-scripts/ifcfg-eth0
712052 -rw-r--r--. 1 root root 357 Mar 31 07:24 /etc/sysconfig/network-scripts/ifcfg-eth0
[root@server0 ~]# grep "166" /etc/sysconfig/network-scripts/ifcfg-eth0
IPADDR=192.168.4.166
[root@server0 ~]# sed -i 's/166/177/g' /etc/sysconfig/network-scripts/ifcfg-eth0
[root@server0 ~]# ls -li /etc/sysconfig/network-scripts/ifcfg-eth0
590635 -rw-r--r--. 1 root root 357 Mar 31 07:28 /etc/sysconfig/network-scripts/ifcfg-eth0
[root@server0 ~]# grep "166" /etc/sysconfig/network-scripts/ifcfg-eth0
[root@server0 ~]# grep "177" /etc/sysconfig/network-scripts/ifcfg-eth0
IPADDR=192.168.4.177
[root@server0 ~]# ip a | grep "eth0"
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.4.166/24 brd 192.168.4.255 scope global eth0
[root@server0 ~]# nmcli con reload
[root@server0 ~]# ip a | grep "eth0"
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.4.166/24 brd 192.168.4.255 scope global eth0
[root@server0 ~]# nmcli con load /etc/sysconfig/network-scripts/ifcfg-eth0
[root@server0 ~]# ip a | grep "eth0"
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.4.166/24 brd 192.168.4.255 scope global eth0
[root@server0 ~]# systemctl restart NetworkManager
[root@server0 ~]# ip a | grep "eth0"
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.4.166/24 brd 192.168.4.255 scope global eth0
[root@server0 ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0
[root@server0 ~]# ls -li /etc/sysconfig/network-scripts/ifcfg-eth0
590639 -rw-r--r--. 1 root root 357 Mar 31 07:41 /etc/sysconfig/network-scripts/ifcfg-eth0
[root@server0 ~]# ip a | grep "eth0"
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    inet 192.168.4.177/24 brd 192.168.4.255 scope global eth0
Comment 1 Beniamino Galvani 2016-03-31 09:13:10 UTC
Hi,

I would say that NM is working as expected when using sed/sudoedit and
instead is behaving wrongly when using the editor.

When you have monitor-connection-files=true set, NM detects changes to
connections immediately, but is not supposed to apply the changes to
the currently active connection. For this to happen you have to
re-activate the connection.

Without monitor-connection-files enabled, the normal workflow would be:
 - edit the connection file
 - nmcli connection reload           # to reload the changes
 - nmcli connection up <con-name>    # to reapply changes to a connection

monitor-connection-files allows you to skip the intermediate step, but
still requires that you re-enable the connection if you want the
changes to have effect. If you don't, you will see that NM picked the
new parameters for the connection (use 'nmcli connection show
<con-name>') but they have not been applied.

When using an editor, the problem is that the connection file is first
deleted and then recreated and thus NM sees a deletion event (which
causes the connection to go down) followed by a creation event (which
causes a new instance of the connection to be created). So what we
should really fix in my opinion is this last problem.
Comment 2 Thomas Haller 2016-03-31 09:40:44 UTC
(In reply to Benjamin Lefoul from comment #0)
> When monitor-connection-files is set to true, and a current connection file
> (in this case "Red Hat style" ifcfg-eth0) is edited with a text editor
> (emacs or vi, etc.) to change an IP, it works fine.
> 
> Doing the same thing with sudoedit, or sed fails to cause nm to pick up the
> change, even when loading, reloading or fully restarting, and even though
> the inode numbers change similarly to an edition with a text-editor.
> 
> Follow through this and notice how easy it is to change IP from *.155 to
> *.166 with emacs, but it fails when using sed to change to *.177. Note the
> inode numbers. The only way to finally get this noticed is to open it with a
> text editor (here: vi) and immediately close it with ":wq" without a change
> since this was already done with sed (just ":q" fails).
> 
> 
> [root@server0 ~]# grep "monitor" /etc/NetworkManager/NetworkManager.conf
> monitor-connection-files=true
> [root@server0 ~]# systemctl restart NetworkManager
> [root@server0 ~]# ls -li /etc/sysconfig/network-scripts/ifcfg-eth0
> 712059 -rw-r--r--. 1 root root 357 Mar 31 07:20
> /etc/sysconfig/network-scripts/ifcfg-eth0
> [root@server0 ~]# grep "IPADDR" /etc/sysconfig/network-scripts/ifcfg-eth0
> IPADDR=192.168.4.155
> [root@server0 ~]# ip a | grep "eth0"
> 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state
> UP qlen 1000
>     inet 192.168.4.155/24 brd 192.168.4.255 scope global eth0

Ok, you started NM, it found connection ifcfg-eth0 and autoactivated that connection.

> [root@server0 ~]# emacs /etc/sysconfig/network-scripts/ifcfg-eth0
> [root@server0 ~]# grep "IPADDR" /etc/sysconfig/network-scripts/ifcfg-eth0
> IPADDR=192.168.4.166
> [root@server0 ~]# ip a | grep "eth0"
> 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state
> UP qlen 1000
>     inet 192.168.4.166/24 brd 192.168.4.255 scope global eth0
> [root@server0 ~]# ls -li /etc/sysconfig/network-scripts/ifcfg-eth0
> 712052 -rw-r--r--. 1 root root 357 Mar 31 07:24
> /etc/sysconfig/network-scripts/ifcfg-eth0
> [root@server0 ~]# grep "166" /etc/sysconfig/network-scripts/ifcfg-eth0
> IPADDR=192.168.4.166

When you do this, NM first sees that ifcfg-eth0 got removed. As consequence of this, it will tear down the currently active connection.

Shortly after, ifcfg-eth0 re-appears. But to NM it looks like a new connection.
Incidentally, eth0 just goes down and looks for a connection to autoactivate. Finding ifcfg-eth0, this connection gets autoactivated.
 

> [root@server0 ~]# sed -i 's/166/177/g'
> /etc/sysconfig/network-scripts/ifcfg-eth0
> [root@server0 ~]# ls -li /etc/sysconfig/network-scripts/ifcfg-eth0
> 590635 -rw-r--r--. 1 root root 357 Mar 31 07:28
> /etc/sysconfig/network-scripts/ifcfg-eth0
> [root@server0 ~]# grep "166" /etc/sysconfig/network-scripts/ifcfg-eth0
> [root@server0 ~]# grep "177" /etc/sysconfig/network-scripts/ifcfg-eth0
> IPADDR=192.168.4.177
> [root@server0 ~]# ip a | grep "eth0"
> 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state
> UP qlen 1000
>     inet 192.168.4.166/24 brd 192.168.4.255 scope global eth0

Either sed is a bit fast, or it does an atomic swap. Anyway, the events are different and NM sees that the file changed inplace (instead of remove+add). In this case, NM will reload the connection, as you could verify via `nmcli connection show $CONN`.
Note, that when you modify a connection that is currently active, those modifications don't migrate automatically to the device. The same happens when you do a `nmcli connection modify $CONN +ipv4.addresses 192.168.4.177/24`. To get those changes active on the device, you must either
  1) nmcli connection up $CONN
or (available on version 1.2)
  2) nmcli device reapply eth0

1) does a full down+up cycle, similar to what happened in the previous case during remove+up.
2) is more graceful and only applies what actually changed (without tearing down your device).


> [root@server0 ~]# nmcli con reload
> [root@server0 ~]# ip a | grep "eth0"
> 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state
> UP qlen 1000
>     inet 192.168.4.166/24 brd 192.168.4.255 scope global eth0
> [root@server0 ~]# nmcli con load /etc/sysconfig/network-scripts/ifcfg-eth0
> [root@server0 ~]# ip a | grep "eth0"
> 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state
> UP qlen 1000
>     inet 192.168.4.166/24 brd 192.168.4.255 scope global eth0

Same here. The connection was already reloaded automatically. Further reload|load does nothing as there are no changes.
Especially does a connection (re)load *not* push the changes to the currently active device. You need to up the connection again or device reapply.

> [root@server0 ~]# systemctl restart NetworkManager
> [root@server0 ~]# ip a | grep "eth0"
> 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state
> UP qlen 1000
>     inet 192.168.4.166/24 brd 192.168.4.255 scope global eth0

When restarting NM, it will leave eth0 up (so that you don't loose connectivity during a restart).

After restart, NM sees that there is already something configured on the device (192.168.4.166). It want's to preserve that configuration, so it searches for a connection that matches to what is configured and gracefully activates that one (preferably in a non-destructive way) -- we call this "assume connection".

There are two things that can happen, either one of your existing connections match and NM will gracefully activate that one. Otherwise, it will create a in-memory connection that reflects your current configuration and activate that.

From your next command, it seems that NM did the former and pretended that ifcfg-eth0 is active. It doesn't however update your configuration right away. After all, NM started and there was this IP address. It's not clear what the user wanted.

You can figure that out by looking at `nmcli device` and `nmcli connection`.

To fix that, you need again `nmcli connection up $CONN`.


> [root@server0 ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0
> [root@server0 ~]# ls -li /etc/sysconfig/network-scripts/ifcfg-eth0
> 590639 -rw-r--r--. 1 root root 357 Mar 31 07:41
> /etc/sysconfig/network-scripts/ifcfg-eth0
> [root@server0 ~]# ip a | grep "eth0"
> 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state
> UP qlen 1000
>     inet 192.168.4.177/24 brd 192.168.4.255 scope global eth0

Same as before. The connection ifcfg-eth0 gets deleted, NM tears down eth0. When it gets re-added, NM will autoactivate the new connection.



monitor-connection-files=true works as intended, but there are races involved. For that reason, it is turned off by default and require you to manually (re)load the connections.


I don't think there is a bug here.

NM just does not automatically propagate changes to a connection to the activated device. Except:
 - the properties connection.firewall-zone and connection.metered 
   propagate immediately (don't ask why :) ).
 - as seen, when you delete the connection, NM tears the device down
   (because an active device always needs a connection).
Comment 3 Thomas Haller 2016-03-31 09:43:24 UTC
(sorry for the duplicate answer. Beniamino was faster then me, and as I already typed it, I figured let's just comment too -- even if there is overlap)


I'll close as not a bug for now, but please feel free to reopen or explain what you think should be done.
Comment 4 Benjamin Lefoul 2016-03-31 11:59:54 UTC
Thank you very much Thomas and Beniamino.

I believe this will confuse other people and this sentiment seems to be shared over at the scientific-linux-users ML. A simple change could be to clarify the man NetworkManager.conf:

monitor-connection-files
    Whether the configured settings plugin(s) should set up file
    monitors and immediately pick up changes made to connection files
    while NetworkManager is running. This is disabled by default;
    NetworkManager will only read the connection files at startup, and
    when explicitly requested via the ReloadConnections D-Bus call. If
    this key is set to 'true', then NetworkManager will reload
    connection files any time they changed.

Specifically, it could be advised to edit connection files with sudoedit to avoid unexpected behavior, and reminded to run "nmcli connection up $CONN" or "nmcli dev reapply eth0".
Comment 5 Thomas Haller 2016-03-31 12:59:03 UTC
how about this: 

https://cgit.freedesktop.org/NetworkManager/NetworkManager/commit/?id=4db69c5b520c15f25390a5b9c26db53c6397e5c8



I think the advice for this issue is:

- just don't use monitor-connection-files=true, but instead use
    nmcli connection reload
  or
    nmcli connection load $FILENAME

  (those commands were exactly added to avoid the problem of automatic
  reloading, and automatic reloading was done historically, but is considered
  a mistake).

- after modifying/reloading a connection, the changes don't take effect
  on currently active devices. It needs:
    nmcli connection up $CONN
  or
    nmcli device reapply $DEV




Other then that, it works as expected.




Sidenote: if you do
  ifup eth0
then initscripts basically call for you:
  nmcli connection load /etc/sysconfig/network-scripts/ifcfg-eth0
  nmcli connection up uuid $UUID
and this works you would expect.