Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Require extra 8 GiB free space on the destination Storage Domain in the LSM flows #624

Merged
merged 2 commits into from
Sep 22, 2022
Merged
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 @@ -270,16 +270,7 @@ protected boolean validateSpaceRequirements() {
return true;
}

List<Guid> sdsToValidate = new ArrayList<>();
sdsToValidate.add(getStorageDomainId());

if (getActionType() == ActionType.LiveMigrateDisk) {
sdsToValidate.add(getParameters().getSourceDomainId());
}

MultipleStorageDomainsValidator storageDomainsValidator =
createMultipleStorageDomainsValidator(sdsToValidate);

MultipleStorageDomainsValidator storageDomainsValidator = createMultipleStorageDomainsValidator();
if (validate(storageDomainsValidator.allDomainsWithinThresholds())) {
// If we are copying a template's disk we do not want all its copies
if (getImage().getVmEntityType() == VmEntityType.TEMPLATE) {
Expand Down Expand Up @@ -724,7 +715,10 @@ protected MultipleDiskVmElementValidator createMultipleDiskVmElementValidator()
diskVmElementDao.getAllDiskVmElementsByDiskId(getParameters().getImageGroupID()));
}

public MultipleStorageDomainsValidator createMultipleStorageDomainsValidator(List<Guid> sdsToValidate) {
protected MultipleStorageDomainsValidator createMultipleStorageDomainsValidator() {
List<Guid> sdsToValidate = new ArrayList<>();
sdsToValidate.add(getStorageDomainId());
ahadas marked this conversation as resolved.
Show resolved Hide resolved

return new MultipleStorageDomainsValidator(getStoragePoolId(), sdsToValidate);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.ovirt.engine.core.bll.storage.lsm;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
Expand All @@ -25,6 +26,7 @@
import org.ovirt.engine.core.bll.tasks.CommandHelper;
import org.ovirt.engine.core.bll.tasks.interfaces.CommandCallback;
import org.ovirt.engine.core.bll.utils.PermissionSubject;
import org.ovirt.engine.core.bll.validator.storage.MultipleStorageDomainsValidator;
import org.ovirt.engine.core.bll.validator.storage.StorageDomainValidator;
import org.ovirt.engine.core.common.AuditLogType;
import org.ovirt.engine.core.common.FeatureSupported;
Expand Down Expand Up @@ -656,10 +658,6 @@ private StorageDomain getDstStorageDomain() {
}

protected boolean validateDestDomainsSpaceRequirements() {
if (!isStorageDomainWithinThresholds(getDstStorageDomain())) {
return false;
}

DiskImage diskImage = getDiskImageByImageId(getParameters().getImageId());
Copy link
Member Author

@barpavel barpavel Aug 31, 2022

Choose a reason for hiding this comment

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

@bennyz @ahadas
IMHO the whole LiveMigrateDiskCommand::validateDestDomainsSpaceRequirements() can be removed, since MoveOrCopyDiskCommand::validateSpaceRequirements() runs on both source & destination Storage Domains and checks both isDomainWithinThresholds() and Storage Domains available space.

I already removed isDomainWithinThresholds() check above, since it's exactly what the MoveOrCopyDiskCommand::validateSpaceRequirements() does (for both source and destination SDs).

But I want to be careful and be sure before I remove the rest of the method, there are 2 slight differences between what MoveOrCopyDiskCommand::validateSpaceRequirements() performs on both source and destination SDs and what this method does on destination only:

  1. In the MoveOrCopyDiskCommand::validateSpaceRequirements(), the DiskImage that is used to retrieve the snapshots is initialized using a getImage() call, that uses the CopyImageGroupCommand::getImage() implementation:


    While in LiveMigrateDiskCommand::validateDestDomainsSpaceRequirements() the getDiskImageByImageId() is called:

    But at the end it looks like they are returning pretty much the same diskImageDao.get(imageId);...

  2. In the MoveOrCopyDiskCommand::validateSpaceRequirements(), the available free space validation is performed by the hasSpaceForDisksWithSnapshots():

    public ValidationResult hasSpaceForDisksWithSnapshots(Collection<DiskImage> diskImages) {

While in LiveMigrateDiskCommand::validateDestDomainsSpaceRequirements() the hasSpaceForClonedDisks() is called:

public ValidationResult hasSpaceForClonedDisks(Collection<DiskImage> diskImages) {

Trying to compare them very carefully, I see they are almost the same with very minor nuances, and though maybe both methods need to stay, but anyway, in current implementation both are called and I don't think that we should verify in 2 different ways the same disk & target domain to allow Live Migration.
So which version is correct? The one in LiveMigrateDiskCommand::validateDestDomainsSpaceRequirements() or the MoveOrCopyDiskCommand::validateSpaceRequirements()?

Copy link
Member

Choose a reason for hiding this comment

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

yeah, they are similar yet different as you pointed out. I guess the validation in LiveMigrateDiskCommand should stay, but need to take a deeper look at the differences. @bennyz can you answer this from the top of you head? :)

Copy link
Member Author

Choose a reason for hiding this comment

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

@bennyz is there some code that can be united - moved to the MoveOrCopyDiskCommand base class?
For me it looks like LiveMigrateDiskCommand::validateDestDomainsSpaceRequirements() is redundant, but there are 2 slight potential differences.

  1. The way how DiskImage, used to retrieve the snapshots, is retrieved.
  2. hasSpaceForDisksWithSnapshots vs. hasSpaceForClonedDisks(), that are currently used both to test the destination SD free space, and I added 3 chunks' addition only to one of them.

List<DiskImage> allImageSnapshots = diskImageDao.getAllSnapshotsForLeaf(diskImage.getImageId());
diskImage.getSnapshots().addAll(allImageSnapshots);
Expand All @@ -672,8 +670,14 @@ protected boolean validateDestDomainsSpaceRequirements() {
return true;
}

protected boolean isStorageDomainWithinThresholds(StorageDomain storageDomain) {
return validate(new StorageDomainValidator(storageDomain).isDomainWithinThresholds());
@Override
protected MultipleStorageDomainsValidator createMultipleStorageDomainsValidator() {
List<Guid> sdsToValidate = new ArrayList<>();

sdsToValidate.add(getParameters().getSourceDomainId());
sdsToValidate.add(getParameters().getDestDomainId());

return new MultipleStorageDomainsValidator(getStoragePoolId(), sdsToValidate);
}

private DiskImage getDiskImageByImageId(Guid imageId) {
Expand Down Expand Up @@ -703,7 +707,17 @@ protected boolean isDiskSnapshotNotPluggedToOtherVmsThatAreNotDown(Guid imageId)
}

protected StorageDomainValidator createStorageDomainValidator(StorageDomain storageDomain) {
return new StorageDomainValidator(storageDomain);
return new StorageDomainValidator(storageDomain) {
@Override
protected double getTotalSizeForClonedDisk(DiskImage diskImage) {
double basicSize = super.getTotalSizeForClonedDisk(diskImage);
// Add additional snapshot overhead (relevant only for Live Storage flow, cluster version 4.7 or above).
if (FeatureSupported.isReplicateExtendSupported(getCluster().getCompatibilityVersion())) {
basicSize += ImagesHandler.computeImageInitialSizeInBytes(diskImage.getImage());
}
return basicSize;
}
};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ private double getTotalSizeForClonedDisks(Collection<DiskImage> diskImages) {
* currently in the VDSM code.
*
* */
private double getTotalSizeForClonedDisk(DiskImage diskImage) {
protected double getTotalSizeForClonedDisk(DiskImage diskImage) {
double sizeForDisk = ImagesHandler.getTotalActualSizeOfDisk(diskImage, storageDomain.getStorageStaticData());

if (diskImage.getVolumeFormat() == VolumeFormat.COW) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ protected void initializeCommand(DiskImage disk, VmEntityType vmEntityType) {
vm.setStatus(VMStatus.Down);
when(vmDao.get(any())).thenReturn(vm);

doReturn(multipleStorageDomainsValidator).when(command).createMultipleStorageDomainsValidator(any());
doReturn(multipleStorageDomainsValidator).when(command).createMultipleStorageDomainsValidator();
doReturn(multipleDiskVmElementValidator).when(command).createMultipleDiskVmElementValidator();
doReturn(diskValidator).when(command).createDiskValidator(disk);
doReturn(diskImagesValidator).when(command).createDiskImagesValidator(disk);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,6 @@ private void initStoragePool() {
private void mockValidators() {
doReturn(diskValidator).when(command).createDiskValidator(any());
doReturn(diskImagesValidator).when(command).createDiskImagesValidator(any());
doReturn(multipleStorageDomainsValidator).when(command).createMultipleStorageDomainsValidator(any());
doReturn(multipleStorageDomainsValidator).when(command).createMultipleStorageDomainsValidator();
}
}