package org.ovirt.engine.core.bll.scheduling.policyunits; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.ovirt.engine.core.bll.scheduling.PolicyUnitImpl; import org.ovirt.engine.core.bll.scheduling.SchedulingUnit; import org.ovirt.engine.core.bll.scheduling.SlaValidator; import org.ovirt.engine.core.bll.scheduling.pending.PendingResourceManager; import org.ovirt.engine.core.bll.scheduling.utils.CpuPinningHelper; import org.ovirt.engine.core.common.businessentities.Cluster; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.errors.EngineMessage; import org.ovirt.engine.core.common.scheduling.PerHostMessages; import org.ovirt.engine.core.common.scheduling.PolicyUnit; import org.ovirt.engine.core.common.scheduling.PolicyUnitType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Policy unit which checks if provided hosts satisfy the cpu pinning requirements. */ @SchedulingUnit( guid = "6d636bf6-a35c-4f9d-b68d-0731f731cddc", name = "CpuPinning", type = PolicyUnitType.FILTER, description = "Filters out hosts which do not satisfy a VMs cpu pinning constraints" ) public class CpuPinningPolicyUnit extends PolicyUnitImpl { private static final Logger log = LoggerFactory.getLogger(CpuPinningPolicyUnit.class); public CpuPinningPolicyUnit(PolicyUnit policyUnit, PendingResourceManager pendingResourceManager) { super(policyUnit, pendingResourceManager); } @Override public List<VDS> filter(Cluster cluster, final List<VDS> hosts, final VM vm, final Map<String, String> parameters, final PerHostMessages messages) { final String cpuPinning = vm.getCpuPinning(); // return all hosts when no host pinning is requested if (StringUtils.isEmpty(cpuPinning)) { return hosts; } // collect all pinned host cpus and merge them into one set final Set<Integer> pinnedCpus = CpuPinningHelper.getAllPinnedPCpus(cpuPinning); // only add hosts as candidates which have all required CPUs up and running final List<VDS> candidates = new ArrayList<>(); for (final VDS host : hosts) { final Collection<Integer> onlineHostCpus = SlaValidator.getOnlineCpus(host); final Collection difference = CollectionUtils.subtract(pinnedCpus, onlineHostCpus); if (difference.isEmpty()) { candidates.add(host); } else { messages.addMessage(host.getId(), EngineMessage.VAR__DETAIL__VM_PINNING_PCPU_DOES_NOT_EXIST.name()); messages.addMessage(host.getId(), String.format("$missingCores %1$s", StringUtils.join(difference, ", "))); log.debug("Host {} does not satisfy the cpu pinning constraints because of missing or offline cpus {}.", host.getId(), StringUtils.join(difference, ", ")); } } return candidates; } }