summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2016-09-07 17:47:17 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2016-09-20 18:28:31 +0200
commitd55610d6128c76f0e71a88aa842ae8985ce8a614 (patch)
treec287e63d7b9822eb070e0aca05c2712f3dd4a27c
parent5ce31c2a7d7197b3233848505f6e7c2135bd1f84 (diff)
downloadNetworkManager-d55610d6128c76f0e71a88aa842ae8985ce8a614.tar.gz
checkpoint: better handle unmanaged and unrealized devices
In order to better restore the previous system state, allow the inclusion of unmanaged devices in a checkpoint and try to revert to the old state taking also the realized/managed state into account.
-rw-r--r--src/nm-checkpoint.c71
1 files changed, 45 insertions, 26 deletions
diff --git a/src/nm-checkpoint.c b/src/nm-checkpoint.c
index f2d573574a..aebc25649a 100644
--- a/src/nm-checkpoint.c
+++ b/src/nm-checkpoint.c
@@ -56,6 +56,9 @@ typedef struct {
char *original_dev_path;
NMDevice *device;
NMConnection *connection;
+ NMDeviceState state;
+ bool realized:1;
+ bool unmanaged_explicit:1;
} DeviceCheckpoint;
typedef struct {
@@ -124,17 +127,45 @@ nm_checkpoint_rollback (NMCheckpoint *self)
guint32 result = NM_ROLLBACK_RESULT_OK;
const char *con_path;
- _LOGD ("rollback: restoring state of device %s", nm_device_get_iface (device));
-
- if (!nm_device_is_real (device)) {
- result = NM_ROLLBACK_RESULT_ERR_NO_DEVICE;
- _LOGD ("rollback: device is not realized");
+ _LOGD ("rollback: restoring device %s (state %d, realized %d, explicitly unmanaged %d)",
+ nm_device_get_iface (device),
+ (int) dev_checkpoint->state,
+ dev_checkpoint->realized,
+ dev_checkpoint->unmanaged_explicit);
+
+ if (nm_device_is_real (device)) {
+ if (!dev_checkpoint->realized) {
+ _LOGD ("rollback: device was not realized, unmanage it");
+ nm_device_set_unmanaged_by_flags_queue (device,
+ NM_UNMANAGED_USER_EXPLICIT,
+ TRUE,
+ NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
+ goto next_dev;
+ }
+ } else {
+ if (dev_checkpoint->realized) {
+ if (nm_device_is_software (device)) {
+ /* try to recreate software device */
+ _LOGD ("rollback: software device not realized, will re-activate");
+ goto activate;
+ } else {
+ _LOGD ("rollback: device is not realized");
+ result = NM_ROLLBACK_RESULT_ERR_FAILED;
+ }
+ }
goto next_dev;
}
- if (nm_device_get_state (device) <= NM_DEVICE_STATE_UNMANAGED) {
- result = NM_ROLLBACK_RESULT_ERR_DEVICE_UNMANAGED;
- _LOGD ("rollback: device is unmanaged");
+activate:
+ if (dev_checkpoint->state == NM_DEVICE_STATE_UNMANAGED) {
+ if ( nm_device_get_state (device) != NM_DEVICE_STATE_UNMANAGED
+ || dev_checkpoint->unmanaged_explicit) {
+ _LOGD ("rollback: explicitly unmanage device");
+ nm_device_set_unmanaged_by_flags_queue (device,
+ NM_UNMANAGED_USER_EXPLICIT,
+ TRUE,
+ NM_DEVICE_STATE_REASON_NOW_UNMANAGED);
+ }
goto next_dev;
}
@@ -216,30 +247,18 @@ device_checkpoint_create (NMDevice *device,
DeviceCheckpoint *dev_checkpoint;
NMConnection *connection;
const char *path;
-
- if (!nm_device_is_real (device)) {
- g_set_error (error,
- NM_MANAGER_ERROR,
- NM_MANAGER_ERROR_INVALID_ARGUMENTS,
- "device '%s' is not realized",
- nm_device_get_iface (device));
- return NULL;
- }
-
- if (nm_device_get_state (device) <= NM_DEVICE_STATE_UNMANAGED) {
- g_set_error (error,
- NM_MANAGER_ERROR,
- NM_MANAGER_ERROR_INVALID_ARGUMENTS,
- "device '%s' is unmanaged",
- nm_device_get_iface (device));
- return NULL;
- }
+ gboolean unmanaged_explicit;
path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (device));
+ unmanaged_explicit = !!nm_device_get_unmanaged_flags (device,
+ NM_UNMANAGED_USER_EXPLICIT);
dev_checkpoint = g_slice_new0 (DeviceCheckpoint);
dev_checkpoint->device = g_object_ref (device);
dev_checkpoint->original_dev_path = g_strdup (path);
+ dev_checkpoint->state = nm_device_get_state (device);
+ dev_checkpoint->realized = nm_device_is_real (device);
+ dev_checkpoint->unmanaged_explicit = unmanaged_explicit;
connection = nm_device_get_applied_connection (device);
if (connection)