Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,13 @@ private static boolean isFinalized(Status status) {
public abstract void finalizeLayoutFeature(LayoutFeature lf, T context)
throws UpgradeException;

public void finalizeLayoutFeatures(Iterable<LayoutFeature> features, T context)
throws UpgradeException {
for (LayoutFeature lf : features) {
finalizeLayoutFeature(lf, context);
}
}

protected void finalizeLayoutFeature(LayoutFeature lf, Optional<?
extends UpgradeAction> action, Storage storage)
throws UpgradeException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@ public void execute(T component, BasicUpgradeFinalizer<T, ?> finalizer)
protected void finalizeFeatures(T component,
BasicUpgradeFinalizer<T, ?> finalizer, Iterable<LayoutFeature> lfs)
throws UpgradeException {
for (LayoutFeature lf: lfs) {
finalizer.finalizeLayoutFeature(lf, component);
}
finalizer.finalizeLayoutFeatures(lfs, component);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public interface FinalizationStateManager {
void removeFinalizingMark() throws IOException;

@Replicate
void finalizeLayoutFeature(Integer layoutVersion)
void finalizeLayoutFeatures(Integer toLayoutVersion)
throws IOException;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,11 @@ public void addFinalizingMark() throws IOException {
}

@Override
public void finalizeLayoutFeature(Integer layoutVersion) throws IOException {
finalizeLayoutFeatureLocal(layoutVersion);
public void finalizeLayoutFeatures(Integer toVersion) throws IOException {
int startLayoutVersion = versionManager.getMetadataLayoutVersion() + 1;
for (int version = startLayoutVersion; version <= toVersion; version++) {
finalizeLayoutFeatureLocal(version);
}
}

/**
Expand All @@ -115,9 +118,15 @@ private void finalizeLayoutFeatureLocal(Integer layoutVersion)
// version. This is updated in the replicated finalization steps.
// Layout version will be written to the DB as well so followers can
// finalize from a snapshot.
HDDSLayoutFeature feature =
(HDDSLayoutFeature)versionManager.getFeature(layoutVersion);
upgradeFinalizer.replicatedFinalizationSteps(feature, upgradeContext);
if (versionManager.getMetadataLayoutVersion() >= layoutVersion) {
LOG.warn("Attempting to finalize layout feature for layout version {}, but " +
"current metadata layout version is {}. Skipping finalization for this layout version.",
layoutVersion, versionManager.getMetadataLayoutVersion());
} else {
HDDSLayoutFeature feature =
(HDDSLayoutFeature) versionManager.getFeature(layoutVersion);
upgradeFinalizer.replicatedFinalizationSteps(feature, upgradeContext);
}
} finally {
checkpointLock.writeLock().unlock();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,33 @@ public void preFinalizeUpgrade(SCMUpgradeFinalizationContext context)

@Override
public void finalizeLayoutFeature(LayoutFeature lf,
SCMUpgradeFinalizationContext context) throws UpgradeException {
// Run upgrade actions, update VERSION file, and update layout version in
// DB.
SCMUpgradeFinalizationContext context) throws UpgradeException {
throw new UnsupportedOperationException("FinalizeLayoutFeature is not supported in this implemementation. " +
"Please use finalizeLayoutFeatures instead.");
}

@Override
public void finalizeLayoutFeatures(Iterable<LayoutFeature> features, SCMUpgradeFinalizationContext context)
throws UpgradeException {
int lastLv = -1;
for (LayoutFeature lf : features) {
lastLv = lf.layoutVersion();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should it be inside if (-1 != lf.layoutVersion()) check?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was intentionally like this, as we want to store the first and last value in the iterator. However I have refactored this a bit in the latest version as we don't actually need the firstLv to be passed through.

}
try {
context.getFinalizationStateManager()
.finalizeLayoutFeature(lf.layoutVersion());
if (lastLv > -1) {
// If there are no feature to finalize we just skip this and the finalize operation is a noop.
context.getFinalizationStateManager().finalizeLayoutFeatures(lastLv);
} else {
LOG.info("No layout features to finalize.");
}
} catch (IOException ex) {
throw new UpgradeException(ex,
UpgradeException.ResultCodes.LAYOUT_FEATURE_FINALIZATION_FAILED);
throw new UpgradeException(ex, UpgradeException.ResultCodes.LAYOUT_FEATURE_FINALIZATION_FAILED);
}
}

/**
* Run on each SCM (leader and follower) when a layout feature is being
* finalized to run its finalization actions, update the VERSION file, and
* move the state of its in memory datanodes to healthy readonly.
* finalized to run its finalization actions, update the VERSION file.
*
* @param lf The layout feature that is being finalized.
* @param context Supplier of objects needed to run the steps.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,33 +114,17 @@ public void testUpgradeStateToCheckpointMapping() throws Exception {
.build();
stateManager.setUpgradeContext(context);

assertCurrentCheckpoint(scmContext, stateManager,
FinalizationCheckpoint.FINALIZATION_REQUIRED);
assertCurrentCheckpoint(scmContext, stateManager, FinalizationCheckpoint.FINALIZATION_REQUIRED);
stateManager.addFinalizingMark();
assertCurrentCheckpoint(scmContext, stateManager,
FinalizationCheckpoint.FINALIZATION_STARTED);

for (HDDSLayoutFeature feature: HDDSLayoutFeature.values()) {
// Cannot finalize initial version since we are already there.
if (!feature.equals(HDDSLayoutFeature.INITIAL_VERSION)) {
stateManager.finalizeLayoutFeature(feature.layoutVersion());
if (versionManager.needsFinalization()) {
assertCurrentCheckpoint(scmContext, stateManager,
FinalizationCheckpoint.FINALIZATION_STARTED);
} else {
assertCurrentCheckpoint(scmContext, stateManager,
FinalizationCheckpoint.MLV_EQUALS_SLV);
}
}
}
// Make sure we reached this checkpoint if we finished finalizing all
// layout features.
assertCurrentCheckpoint(scmContext, stateManager,
FinalizationCheckpoint.MLV_EQUALS_SLV);
assertCurrentCheckpoint(scmContext, stateManager, FinalizationCheckpoint.FINALIZATION_STARTED);

HDDSLayoutFeature[] finalizationFeatures = HDDSLayoutFeature.values();
HDDSLayoutFeature finalVersion = finalizationFeatures[finalizationFeatures.length - 1];
assertCurrentCheckpoint(scmContext, stateManager, FinalizationCheckpoint.FINALIZATION_STARTED);
stateManager.finalizeLayoutFeatures(finalVersion.layoutVersion());
assertCurrentCheckpoint(scmContext, stateManager, FinalizationCheckpoint.MLV_EQUALS_SLV);
stateManager.removeFinalizingMark();
assertCurrentCheckpoint(scmContext, stateManager,
FinalizationCheckpoint.FINALIZATION_COMPLETE);
assertCurrentCheckpoint(scmContext, stateManager, FinalizationCheckpoint.FINALIZATION_COMPLETE);
}

private void assertCurrentCheckpoint(SCMContext context,
Expand Down