mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-05 07:40:28 +01:00
core: merge branch 'th/checkpoint-preserve-external-ports'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1131
This commit is contained in:
commit
fbee64e979
5 changed files with 114 additions and 15 deletions
|
|
@ -76,6 +76,7 @@
|
|||
#include "nm-hostname-manager.h"
|
||||
|
||||
#include "nm-device-generic.h"
|
||||
#include "nm-device-bridge.h"
|
||||
#include "nm-device-vlan.h"
|
||||
#include "nm-device-vrf.h"
|
||||
#include "nm-device-wireguard.h"
|
||||
|
|
@ -481,9 +482,12 @@ typedef struct _NMDevicePrivate {
|
|||
|
||||
NMUtilsStableType current_stable_id_type : 3;
|
||||
|
||||
bool activation_state_preserve_external_ports : 1;
|
||||
|
||||
bool nm_owned : 1; /* whether the device is a device owned and created by NM */
|
||||
|
||||
bool assume_state_guess_assume : 1;
|
||||
bool assume_state_guess_assume : 1;
|
||||
|
||||
char *assume_state_connection_uuid;
|
||||
|
||||
guint64 udi_id;
|
||||
|
|
@ -7669,8 +7673,19 @@ nm_device_master_release_slaves(NMDevice *self)
|
|||
c_list_for_each_safe (iter, safe, &priv->slaves) {
|
||||
SlaveInfo *info = c_list_entry(iter, SlaveInfo, lst_slave);
|
||||
|
||||
if (priv->activation_state_preserve_external_ports
|
||||
&& nm_device_sys_iface_state_is_external(info->slave)) {
|
||||
_LOGT(LOGD_DEVICE,
|
||||
"master: preserve external port %s",
|
||||
nm_device_get_iface(info->slave));
|
||||
continue;
|
||||
}
|
||||
nm_device_master_release_one_slave(self, info->slave, TRUE, FALSE, reason);
|
||||
}
|
||||
|
||||
/* We only need this flag for a short time. It served its purpose. Clear
|
||||
* it again. */
|
||||
nm_device_activation_state_set_preserve_external_ports(self, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -15389,6 +15404,16 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason,
|
|||
if (state > NM_DEVICE_STATE_DISCONNECTED)
|
||||
nm_device_assume_state_reset(self);
|
||||
|
||||
if (state < NM_DEVICE_STATE_UNAVAILABLE
|
||||
|| (state >= NM_DEVICE_STATE_IP_CONFIG && state < NM_DEVICE_STATE_ACTIVATED)) {
|
||||
/* preserve-external-ports is used by NMCheckpoint to activate a master
|
||||
* device, and preserve already attached ports. This means, this state is only
|
||||
* relevant during the deactivation and the following activation of the
|
||||
* right profile. Once we are sufficiently far in the activation of the
|
||||
* intended profile, we clear the state again. */
|
||||
nm_device_activation_state_set_preserve_external_ports(self, FALSE);
|
||||
}
|
||||
|
||||
if (state <= NM_DEVICE_STATE_UNAVAILABLE) {
|
||||
if (available_connections_del_all(self))
|
||||
_notify(self, PROP_AVAILABLE_CONNECTIONS);
|
||||
|
|
@ -15793,6 +15818,50 @@ nm_device_get_state(NMDevice *self)
|
|||
return NM_DEVICE_GET_PRIVATE(self)->state;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_device_activation_state_set_preserve_external_ports:
|
||||
* @self: the NMDevice.
|
||||
* @flag: whether to set or clear the the flag.
|
||||
*
|
||||
* This sets an internal flag to true, which does something specific.
|
||||
* For non-master devices, it has no effect. For master devices, this
|
||||
* will prevent to detach all external ports, until the next activation
|
||||
* completes.
|
||||
*
|
||||
* This is used during checkpoint/rollback. We may want to preserve
|
||||
* externally attached ports during the restore. NMCheckpoint will
|
||||
* call this before doing a re-activation. By setting the flag,
|
||||
* we basically preserve such ports.
|
||||
*
|
||||
* Once we reach again ACTIVATED state, the flag gets cleared. This
|
||||
* only has effect for the next activation cycle. */
|
||||
void
|
||||
nm_device_activation_state_set_preserve_external_ports(NMDevice *self, gboolean flag)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
g_return_if_fail(NM_IS_DEVICE(self));
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
|
||||
if (!NM_IS_DEVICE_BRIDGE(self)) {
|
||||
/* This is actually only implemented for bridge devices. While it might
|
||||
* make sense for bond/team or OVS, it's not clear that it is actually
|
||||
* useful or desirable. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->activation_state_preserve_external_ports == flag)
|
||||
return;
|
||||
|
||||
priv->activation_state_preserve_external_ports = flag;
|
||||
_LOGD(LOGD_DEVICE,
|
||||
"activation-state: preserve-external-ports %s",
|
||||
flag ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* NMConfigDevice interface related stuff */
|
||||
|
||||
|
|
|
|||
|
|
@ -443,6 +443,8 @@ NMDeviceType nm_device_get_device_type(NMDevice *dev);
|
|||
NMLinkType nm_device_get_link_type(NMDevice *dev);
|
||||
NMMetered nm_device_get_metered(NMDevice *dev);
|
||||
|
||||
void nm_device_activation_state_set_preserve_external_ports(NMDevice *self, gboolean flag);
|
||||
|
||||
guint32 nm_device_get_route_table(NMDevice *self, int addr_family);
|
||||
guint32 nm_device_get_route_metric(NMDevice *dev, int addr_family);
|
||||
|
||||
|
|
|
|||
|
|
@ -282,6 +282,11 @@ restore_and_activate_connection(NMCheckpoint *self, DeviceCheckpoint *dev_checkp
|
|||
* an internal subject. */
|
||||
if (nm_device_get_state(dev_checkpoint->device) > NM_DEVICE_STATE_DISCONNECTED
|
||||
&& nm_device_get_state(dev_checkpoint->device) < NM_DEVICE_STATE_DEACTIVATING) {
|
||||
if (!NM_FLAGS_HAS(priv->flags, NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS)) {
|
||||
nm_device_activation_state_set_preserve_external_ports(dev_checkpoint->device,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
nm_device_state_changed(dev_checkpoint->device,
|
||||
NM_DEVICE_STATE_DEACTIVATING,
|
||||
NM_DEVICE_STATE_REASON_NEW_ACTIVATION);
|
||||
|
|
|
|||
|
|
@ -7600,15 +7600,31 @@ impl_manager_checkpoint_create(NMDBusObject *obj,
|
|||
GDBusMethodInvocation *invocation,
|
||||
GVariant *parameters)
|
||||
{
|
||||
NMManager *self = NM_MANAGER(obj);
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
|
||||
NMAuthChain *chain;
|
||||
char **devices;
|
||||
guint32 rollback_timeout;
|
||||
guint32 flags;
|
||||
NMManager *self = NM_MANAGER(obj);
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
|
||||
NMAuthChain *chain;
|
||||
gs_strfreev char **devices = NULL;
|
||||
guint32 rollback_timeout;
|
||||
guint32 flags;
|
||||
|
||||
G_STATIC_ASSERT_EXPR(sizeof(flags) <= sizeof(NMCheckpointCreateFlags));
|
||||
|
||||
g_variant_get(parameters, "(^aouu)", &devices, &rollback_timeout, &flags);
|
||||
|
||||
if ((NMCheckpointCreateFlags) flags != flags
|
||||
|| NM_FLAGS_ANY(flags,
|
||||
~((guint32) (NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL
|
||||
| NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS
|
||||
| NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES
|
||||
| NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING
|
||||
| NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS)))) {
|
||||
g_dbus_method_invocation_return_error_literal(invocation,
|
||||
NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_INVALID_ARGUMENTS,
|
||||
"Invalid flags");
|
||||
return;
|
||||
}
|
||||
|
||||
chain = nm_auth_chain_new_context(invocation, checkpoint_auth_done_cb, self);
|
||||
if (!chain) {
|
||||
g_dbus_method_invocation_return_error_literal(invocation,
|
||||
|
|
@ -7618,11 +7634,12 @@ impl_manager_checkpoint_create(NMDBusObject *obj,
|
|||
return;
|
||||
}
|
||||
|
||||
g_variant_get(parameters, "(^aouu)", &devices, &rollback_timeout, &flags);
|
||||
|
||||
c_list_link_tail(&priv->auth_lst_head, nm_auth_chain_parent_lst_list(chain));
|
||||
nm_auth_chain_set_data(chain, "audit-op", NM_AUDIT_OP_CHECKPOINT_CREATE, NULL);
|
||||
nm_auth_chain_set_data(chain, "devices", devices, (GDestroyNotify) g_strfreev);
|
||||
nm_auth_chain_set_data(chain,
|
||||
"devices",
|
||||
g_steal_pointer(&devices),
|
||||
(GDestroyNotify) g_strfreev);
|
||||
nm_auth_chain_set_data(chain, "flags", GUINT_TO_POINTER(flags), NULL);
|
||||
nm_auth_chain_set_data(chain, "timeout", GUINT_TO_POINTER(rollback_timeout), NULL);
|
||||
nm_auth_chain_add_call(chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, TRUE);
|
||||
|
|
|
|||
|
|
@ -959,17 +959,23 @@ typedef enum {
|
|||
* overlapping younger checkpoints. This opts-in that the
|
||||
* checkpoint can be automatically destroyed by the rollback
|
||||
* of an older checkpoint. Since: 1.12.
|
||||
* @NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS: during rollback,
|
||||
* by default externally added ports attached to bridge devices are preserved.
|
||||
* With this flag, the rollback detaches all external ports.
|
||||
* This only has an effect for bridge ports. Before 1.38, this was the default
|
||||
* behavior. Since: 1.38.
|
||||
*
|
||||
* The flags for CheckpointCreate call
|
||||
*
|
||||
* Since: 1.4 (gi flags generated since 1.12)
|
||||
*/
|
||||
typedef enum /*< flags >*/ {
|
||||
NM_CHECKPOINT_CREATE_FLAG_NONE = 0,
|
||||
NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL = 0x01,
|
||||
NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS = 0x02,
|
||||
NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES = 0x04,
|
||||
NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING = 0x08,
|
||||
NM_CHECKPOINT_CREATE_FLAG_NONE = 0,
|
||||
NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL = 0x01,
|
||||
NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS = 0x02,
|
||||
NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES = 0x04,
|
||||
NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING = 0x08,
|
||||
NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS = 0x10,
|
||||
} NMCheckpointCreateFlags;
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue