|
| 1 | +diff --git a/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/CtrlSnapshotRestoreApiCallHandler.java b/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/CtrlSnapshotRestoreApiCallHandler.java |
| 2 | +index a639c27cc..4dabc1a83 100644 |
| 3 | +--- a/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/CtrlSnapshotRestoreApiCallHandler.java |
| 4 | ++++ b/controller/src/main/java/com/linbit/linstor/core/apicallhandler/controller/CtrlSnapshotRestoreApiCallHandler.java |
| 5 | +@@ -434,26 +434,39 @@ public class CtrlSnapshotRestoreApiCallHandler |
| 6 | + } |
| 7 | + } |
| 8 | + |
| 9 | +- /* |
| 10 | +- * When a snapshot was received as a backup, it is marked to re-create its local metadata. Before the |
| 11 | +- * snapshot was sent the new DRBD_INITIALIZED flag and the VlmDfn property InitialUpToDateOn were |
| 12 | ++ /** |
| 13 | ++ * <p>Sets the {@value InternalApiConsts#KEY_LINSTOR_DRBD_INITIAL_UPTODATE_ON} property to the nodeName |
| 14 | ++ * of the first Snapshot (which has to have a disk) of the given SnapshotDefinition.</p> |
| 15 | ++ * |
| 16 | ++ * <p>If this SnapshotDefinition is a backup, we also unset the {@link VolumeDefinition.Flags#DRBD_INITIALIZED} |
| 17 | ++ * flag. Otherwise we ensure the same flag is set.</p> |
| 18 | ++ * |
| 19 | ++ * <p>Backup path: When a snapshot was received as a backup, it is marked to re-create its local metadata. |
| 20 | ++ * Before the snapshot was sent the new DRBD_INITIALIZED flag and the VlmDfn property InitialUpToDateOn were |
| 21 | + * cleared. If DRBD_INITIALZED would be set, no peer would even read the property (on purpose). |
| 22 | + * Without the property, no peer would think of itself as a winner, thus the DRBD resource would never |
| 23 | + * become UpToDate. |
| 24 | + * To avoid this, this method sets the InitialUpToDateOn property to let the first resource win the |
| 25 | +- * race, so it can become UpToDate and therefore also pull the other peers eventually into UpToDate state. |
| 26 | ++ * race, so it can become UpToDate and therefore also pull the other peers eventually into UpToDate state. </p> |
| 27 | + * |
| 28 | +- * If the given SnapDfn had also non-backup snapshots, those should be able to keep their metadata. |
| 29 | ++ * <p>If the given SnapDfn had also non-backup snapshots, those should be able to keep their metadata. |
| 30 | + * In that case we do not have to do anything. If however all snapshots are descendants from backups |
| 31 | + * we must pick one and decide the UpToDate race upfront so that the winner can set its local DRBD |
| 32 | +- * as UpToDate, which also triggers the controller to set the DRBD_INITIALZED flag eventually. |
| 33 | ++ * as UpToDate, which also triggers the controller to set the DRBD_INITIALZED flag eventually.</p> |
| 34 | ++ * |
| 35 | ++ * <p>Non-Backup path: When a regular snapshot (i.e. not from a backup) is restored, we can or even should |
| 36 | ++ * assume that the backing snapshot LVs have correct metadata which do not need be be initialized. When |
| 37 | ++ * a SnapshotVolumeDefinition is created it unfortunately does not properly store the VolumeDefinition's flags, |
| 38 | ++ * therefore the restored VolumeDefinition will also not have the DRBD_INITIALIZED flag set, although it |
| 39 | ++ * refers to a device with healthy and UpToDate metadata. To fix this issue we simply set the flag in this case.</p> |
| 40 | + */ |
| 41 | + private void checkDrbdInitializedState(ResourceDefinition rscDfnRef) throws AccessDeniedException |
| 42 | + { |
| 43 | + AccessContext accCtx = peerAccCtx.get(); |
| 44 | +- if (DrbdLayerUtils.isForceInitialSyncSet(accCtx, rscDfnRef) && rscDfnRef.getDiskfulCount(accCtx) > 0) |
| 45 | ++ if (rscDfnRef.getDiskfulCount(accCtx) > 0) |
| 46 | + { |
| 47 | + String winnerNodeName = rscDfnRef.getDiskfulResources(accCtx).get(0).getNode().getName().value; |
| 48 | ++ boolean uninitializeDrbd = DrbdLayerUtils.isForceInitialSyncSet(accCtx, rscDfnRef); |
| 49 | + Iterator<VolumeDefinition> vlmDfnIt = rscDfnRef.iterateVolumeDfn(accCtx); |
| 50 | + while (vlmDfnIt.hasNext()) |
| 51 | + { |
| 52 | +@@ -462,7 +475,14 @@ public class CtrlSnapshotRestoreApiCallHandler |
| 53 | + { |
| 54 | + vlmDfn.getProps(accCtx) |
| 55 | + .setProp(InternalApiConsts.KEY_LINSTOR_DRBD_INITIAL_UPTODATE_ON, winnerNodeName); |
| 56 | +- vlmDfn.getFlags().disableFlags(accCtx, VolumeDefinition.Flags.DRBD_INITIALIZED); |
| 57 | ++ if (uninitializeDrbd) |
| 58 | ++ { |
| 59 | ++ vlmDfn.getFlags().disableFlags(accCtx, VolumeDefinition.Flags.DRBD_INITIALIZED); |
| 60 | ++ } |
| 61 | ++ else |
| 62 | ++ { |
| 63 | ++ vlmDfn.getFlags().enableFlags(accCtx, VolumeDefinition.Flags.DRBD_INITIALIZED); |
| 64 | ++ } |
| 65 | + } |
| 66 | + catch (InvalidKeyException | InvalidValueException exc) |
| 67 | + { |
0 commit comments