package org.ovirt.engine.core.bll.validator;
import static org.ovirt.engine.core.bll.scheduling.utils.CpuPinningHelper.parseCpuPinning;
import java.util.HashSet;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.ovirt.engine.core.bll.ValidationResult;
import org.ovirt.engine.core.bll.scheduling.utils.CpuPinningHelper.PinnedCpu;
import org.ovirt.engine.core.common.businessentities.VmStatic;
import org.ovirt.engine.core.common.errors.EngineMessage;
public class CpuPinningValidator {
private static final Pattern cpuPinningPattern =
Pattern.compile("\\d+#(\\^\\d+|\\d+\\-\\d+|\\d+)(,(\\^\\d+|\\d+\\-\\d+|\\d+))*" +
"(_\\d+#(\\^\\d+|\\d+\\-\\d+|\\d+)(,(\\^\\d+|\\d+\\-\\d+|\\d+))*)*");
/**
* Check if the cpu pinning rules are syntactically correct
*
* @param cpuPinning rule description string
* @return true if valid
*/
public static boolean isValidCpuPinningSyntax(final String cpuPinning) {
return cpuPinningPattern.matcher(cpuPinning).matches();
}
/**
* Checks that a given CPU pinning string is valid. Adds an appropriate message to CanDoAction messages if
* validation fails
*
* @param cpuPinning String to validate
* @param vmStatic vm data, containing vcpu information
* @return if the given cpuPinning is valid
*/
public static ValidationResult isCpuPinningValid(final String cpuPinning, VmStatic vmStatic) {
if (StringUtils.isEmpty(cpuPinning)) {
return ValidationResult.VALID;
}
if (!CpuPinningValidator.isValidCpuPinningSyntax(cpuPinning)) {
return new ValidationResult(EngineMessage.VM_PINNING_FORMAT_INVALID);
}
// check if no dedicated vds was configured
if (vmStatic.getDedicatedVmForVdsList().isEmpty()) {
return new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_VM_CANNOT_BE_PINNED_TO_CPU_WITH_UNDEFINED_HOST);
}
HashSet<Integer> assignedVCpus = new HashSet<>();
int maxvCPU = vmStatic.getNumOfCpus();
// check if vcpu rules are valid
for (PinnedCpu pinnedCpu : parseCpuPinning(cpuPinning)) {
int vCpu = pinnedCpu.getvCpu();
if (vCpu >= maxvCPU) {
return new ValidationResult(EngineMessage.VM_PINNING_VCPU_DOES_NOT_EXIST);
}
if (!assignedVCpus.add(vCpu)) {
return new ValidationResult(EngineMessage.VM_PINNING_DUPLICATE_DEFINITION);
}
if (pinnedCpu.getpCpus().isEmpty()) {
// definition of pcpus is no cpu, e.g 0#1,^1
return new ValidationResult(EngineMessage.VM_PINNING_PINNED_TO_NO_CPU);
}
}
return ValidationResult.VALID;
}
}