Clone the connection upon activation. This makes it safe for the user
to modify the original connection while it is activated.
This involves several changes:
- NMActiveConnection gets @settings_connection and @applied_connection.
To support add-and-activate, we constructing a NMActiveConnection with
no connection set. Previously, we would set the "connection" field to
a temporary NMConnection. Now NMManager piggybacks this temporary
connection as object-data (TAG_ACTIVE_CONNETION_ADD_AND_ACTIVATE).
- get rid of the functions nm_active_connection_get_connection_type()
and nm_active_connection_get_connection_uuid(). From their names
it is unclear whether this returns the settings or applied connection.
The (few) callers should figure that out themselves.
- rename nm_active_connection_get_id() to
nm_active_connection_get_settings_connection_id(). This function
is only used internally for logging.
- dispatcher calls now get two connections as well. The
applied-connection is used for the connection data, while
the settings-connection is used for the connection path.
- needs special handling for properties that apply immediately
when changed (nm_device_reapply_settings_immediately()).
Co-Authored-By: Thomas Haller <thaller@redhat.com>
https://bugzilla.gnome.org/show_bug.cgi?id=724041
Refactor agent-manager to always invoke the complete function for
nm_agent_manager_get_secrets().
In general, the complete function is always invoked asnychronously
when starting the operation. On the other hand, when cancelling the
operation or disposing the manager with pending operations, we now
(always) synchronously invoke the callback.
This makes it simpler for the user to reliably cancel the request
and perform potential cleanup.
This behavior bubbles up through NMSettingsConnection and NMActRequest,
and other callers that make directly or indicrectly make use of
nm_agent_manager_get_secrets().
Instead of having the call_id of type guint32, make it an (opaque)
pointer type.
This has the advantage of strong typing and avoids the possiblity
of reusing an invalid integer (or overflow of the call-id counter).
OTOH, it has the disadvantage, that after a call_id is disposed,
it might be reused for future invocations (because malloc might
reuse the memory).
In fact, it is always an error to use a call_id that is already
completed. This commit also adds assertions to the cancel() calls
that the provided call_id is a pending call. Hence, such a bug
will be uncovered by assertions (that only might not tigger in
certain unlikely cases where a call-id got reused).
Note that for NMAgentManager, save_secrets() and delete_secrets()
both returned a call_id. But they didn't also provide a callback when
the operation completes. So the user trying to cancel such a call,
cannot know whether the operation is still in process and he cannot
avoid triggering an assertion.
Fix that by not returning a call-id for these operations. No caller
cared about it anyway.
For NMSettingsConnection, also track the internally scheduled requests
for so that we can cancel them on dispose.
There's no point in calling setpgid() on short-lived processes, so
remove the setpgid() calls when spawning dispatcher scripts, iptables,
iscsiadmin, and netconf.
Replace the pthread_sigwait()-based signal handling with
g_unix_signal_add()-based handling, and get rid of all the
now-unnecessary calls to nm_unblock_posix_signals() when spawning
subprocesses.
As a bonus, this also fixes the "^C in gdb kills NM too" bug.
For some reason, the flags used by o.fd.NM.SecretAgent.GetSecrets were
defined as both NMSecretAgentGetSecretsFlags in
libnm{,-glib}/nm-secret-agent.h, and then separately as
NMSettingsGetSecretsFlags in include/nm-settings-flags.h.
(NMSettingsGetSecretsFlags also had an additional internal-use-only
value, but that was added later after the duplication already
existed.)
Fix this by moving NMSecretAgentGetSecretsFlags from libnm to
nm-dbus-interface.h, adding the internal-use-only value to it as well,
updating the core code to use that, and then removing
nm-settings-flags.h.
Clean up some of the cross-includes between headers (which made it so
that, eg, if you included NetworkManagerUtils.h in a test program, you
would need to build the test with -I$(top_srcdir)/src/platform, and if
you included nm-device.h you'd need $(POLKIT_CFLAGS)) by moving all
GObject struct definitions for src/ and src/settings/ into nm-types.h
(which already existed to solve the NMDevice/NMActRequest circular
references).
Update various .c files to explicitly include the headers they used to
get implicitly, and remove some now-unnecessary -I options from
Makefiles.
Dependencies may fail before the activation actually starts, like
when a software device gets removed while the activation is
scheduled but before it has started. In these cases, the
activation request should fail.
e19f48ec was incomplete; it failed to handle device disconnections.
NMDevice will clear its internal activation request *before*
emitting the state change, which meant that when the
NMActRequest processes the DISCONNECTED state change, the:
if (NM_ACTIVE_CONNECTION (nm_device_get_act_request (device)) != active)
return;
statement triggered and the DISCONNECTED state change was not
processed.
Instead of having NMDevice keep the activation request alive over
the entire DISCONNECTED state transition, which may have much
greater implications, handle the special-case locally in the
NMActRequest code itself.
When a new activation request comes in and the device is already
activated, two NMActRequests will exist for the device in parallel.
The old one handles de-activation of the device and is then disposed,
while the new one waits until the device is de-activated and then
takes over and starts the new activation.
Both requests are watching device state, and the new request may
mis-interpret the de-activation states and clean up its device pointer,
leading to assertion failures when the new activation starts.
To fix this (and because NMVPNConnection *does* always want to see
de-activation events from the device) remove the code that tries to
ignore de-activation from NMActiveConnection's device state handler.
Instead, have NMActRequest skip any reaction to device state changes
unless it is the current activation request on the device. The VPN
code always wants to see the device's state, so it doesn't need this
check.
Add IP and DHCP config properties to the D-Bus ActiveConnection
objects.
For device connections, this is redundant with the properties already
on the Device object, but for VPN connections, this information was
not previously available.
Rather than explicitly passing around a UID and a flag saying whether
or not it's relevant.
(This also fixes a bug where the wrong UID was being recorded in
nm-settings-connection.c::auth_start(), which caused problems such as
agent-owned secrets not getting saved because of a perceived UID
mismatch.)
The device may not be created yet (in the case of software devices)
when the ActiveConnection is created; in that case we still want to
proceed with authorization for the connection, but we'll create the
device when authorization is complete.
Both NMActRequest and NMVPNConnection need to track their device's state,
so instead of both subclasses having to do so, consolidate that code into
the superclass.
We want to create the object earlier now, and figuring out the master is
a lot of code that we don't want to run before creating the object. The
master still must be set before exporting the object over D-Bus though,
as before.
When we eventually do authorization in the ActiveConnection itself,
we want to make sure the AC doesn't get exported until everything
is authorized. Thus let the manager handle exporting the objects
since it knows when the AC will be authorized or not.
Whether an active connection is assumed or connected from scratch is
only important during nm_device_activate(). When the activation process
is set up, there's no difference from any other active connection.
Acked-by: Dan Winship <danw@gnome.org>
Acked-by: Thomas Haller <thaller@redhat.com>
Previously I didn't think they'd be used for anything other than connection secrets
which only have one hint, but in the future we'll want to pass more information.
If a device becomes unmanaged or unavailable (eg, due to loss of carrier, becoming
unmanaged, rfkilled, supplicant crashing, etc), the ActiveConnection would simply
set state to UNKNOWN and the Manager wouldn't tear it down and remove it from the
ActiveConnections property list. Instead, these states should be treated the same
as if the device was deactivated cleanly so that the AC will accurately reflect
the device state and the Manager will clean the AC up.
Fixes comment #12 in:
https://bugzilla.gnome.org/show_bug.cgi?id=676285
This is a regression introduced by reworked active connections tracking:
7258dd270f core: add the NM_ACTIVE_CONNECTION_STATE_DEACTIVATED state
59420add04 core: track active connections directly in the manager
Because nm-manager.c:active_connection_state_changed() postpones active
connection removal to an idle handler (to be able to receive last property
change notifications), we also need to ensure that NM_ACTIVE_CONNECTION_STATE_DEACTIVATED
state is not changed again in the meantime in nm-activation-request.c:device_state_changed().
After the NMActRequest was deactivated (which is a terminal state) it was still
listening to state changes of its child NMDevice which could be starting a
new activation request. Thus the new activation's NMDevice state would cause
the old activation request's state to change from DEACTIVATED. To fix this
stop listening to the child NMDevice when DEACTIVATED becuase there's no point
to doing so anyway.
Reproducer:
Just activate already active connection by clicking it in nm-applet or
run 'nmcli con up id <connnection name>' several times, and then check
active connections with 'nmcli c s'.
This is a regression introduced by reworked active connections tracking:
7258dd270f core: add the NM_ACTIVE_CONNECTION_STATE_DEACTIVATED state
59420add04 core: track active connections directly in the manager
Because nm-manager.c:active_connection_state_changed() postpones active
connection removal to an idle handler (to be able to receive last property
change notifications), we also need to ensure that NM_ACTIVE_CONNECTION_STATE_DEACTIVATED
state is not changed again in the meantime in nm-activation-request.c:device_state_changed().
Reproducer:
Just activate already active connection by clicking it in nm-applet or
run 'nmcli con up id <connnection name>' several times, and then check
active connections with 'nmcli c s'.
We'll want to use NMActiveConnection more in the manager and also fold
the PendingActivation functionality into it. All this functionality
applies to the VPN connections too, so it makes sense to have it all
in the base class instead of both NMActRequest and NMVPNConnection.
Allows agents to provide different behavior depending on whether the
secrets request was initiated by a user (eg by picking a connection
from a UI menu or by 'nmcli con up') or was automatically started by
NetworkManager.
See https://bugzilla.gnome.org/show_bug.cgi?id=660293
Commit 217c5bf6ac fixed processing of unix
signals: signals are blocked in all threads and a dedicated thread handles the
signals using sigwait().
However, the commit forgot that child processes inherit signal mask as well.
That is why we have to unblock signals for child processes we spawn from NM, so
that they can receive signals.
We already have the master device kept in the active connection, so
we can just use that instead of having the Policy determine and set
it manually. This also should allow slaves to auto-activate their
master connections if the master is able to activate.
Track a master active connection and emit wait/ready/fail when
it changes state. This signal is intended for devices to
delay their activation until a master device is ready.
They are the basic class that tracks active connections, and we're
going to use them for connection dependencies. So use the fact that
both NMVPNConnection and NMActRequest have the same base class
instead of using object paths.
That was always the goal, but never got there. This time we need it
for real to abstract handling of dependent connections so bite the
bullet and make it happen.
Adds a new "master" property to NMActiveConnection containing the path
of the master NMDevice if the connection has a master.
Signed-off-by: Thomas Graf <tgraf@redhat.com>
A convenience so that clients which might key certain operations off
which connections are active (checking work mail only when on VPN for
example) can more easily get which connections are active. This would
allow those apps to store the UUID (which they would already be doing)
and not have to create a Connection proxy and then get the connection
properties just to retrieve the UUID of the connection. Instead they
can now get it from GetAll of the ActiveConnection object, which they
would already be doing.