mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-2554: Ensuring that we honor hypervisor xen's memory constraints
When setting memory constraints on Xen guests we should honor: static-min <= dynamic-min <= dynamic-max <= static-max Our VmSpec while allows the guests to like between dynamic-min and dynamic-max the memory set by the resource set the static min to be equal to the dynamic max. This restricts the hypervisor from ensuring optimized memory handling of guests. see: http://wiki.xen.org/wiki/XCP_FAQ_Dynamic_Memory_Control#How_does_XCP_choose_targets_for_guests_in_dynamic_range_mode.3F Another fix was related the restrict_dmc option. when enabled (true) this option disallows scaling a vm. The logic was reverse handled allowing scaling when restrict_dmc was on. This control flow is now fixed. Signed-off-by: Prasanna Santhanam <tsp@apache.org>
This commit is contained in:
parent
6ea2b06aab
commit
7ea2c950f5
|
|
@ -335,6 +335,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
long _xs_memory_used = 128 * 1024 * 1024L; // xen hypervisor used 128 M
|
||||
double _xs_virtualization_factor = 63.0/64.0; // 1 - virtualization overhead
|
||||
|
||||
//static min values for guests on xen
|
||||
private static final long mem_128m = 134217728L;
|
||||
|
||||
protected boolean _canBridgeFirewall = false;
|
||||
protected boolean _isOvs = false;
|
||||
protected List<VIF> _tmpDom0Vif = new ArrayList<VIF>();
|
||||
|
|
@ -1208,8 +1211,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
}
|
||||
Set<VM> templates = VM.getByNameLabel(conn, guestOsTypeName);
|
||||
assert templates.size() == 1 : "Should only have 1 template but found " + templates.size();
|
||||
if (!templates.iterator().hasNext()) {
|
||||
throw new CloudRuntimeException("No matching OS type found for starting a [" + vmSpec.getOs()
|
||||
+ "] VM on host " + host.getHostname(conn));
|
||||
}
|
||||
VM template = templates.iterator().next();
|
||||
|
||||
VM vm = template.createClone(conn, vmSpec.getName());
|
||||
VM.Record vmr = vm.getRecord(conn);
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
|
|
@ -3503,8 +3509,21 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* WARN: static-min <= dynamic-min <= dynamic-max <= static-max
|
||||
* @see XcpServerResource#setMemory(com.xensource.xenapi.Connection, com.xensource.xenapi.VM, long, long)
|
||||
* @param conn
|
||||
* @param vm
|
||||
* @param minMemsize
|
||||
* @param maxMemsize
|
||||
* @throws XmlRpcException
|
||||
* @throws XenAPIException
|
||||
*/
|
||||
protected void setMemory(Connection conn, VM vm, long minMemsize, long maxMemsize) throws XmlRpcException, XenAPIException {
|
||||
vm.setMemoryLimits(conn, maxMemsize, maxMemsize, minMemsize, maxMemsize);
|
||||
vm.setMemoryStaticMin(conn, mem_128m);
|
||||
vm.setMemoryDynamicMin(conn, minMemsize);
|
||||
vm.setMemoryDynamicMax(conn, maxMemsize);
|
||||
vm.setMemoryStaticMax(conn, maxMemsize);
|
||||
}
|
||||
|
||||
protected void waitForTask(Connection c, Task task, long pollInterval, long timeout) throws XenAPIException, XmlRpcException {
|
||||
|
|
@ -4299,7 +4318,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
|||
* @throws XenAPIException
|
||||
* @throws XmlRpcException
|
||||
*
|
||||
* @see enableVlanNetwork
|
||||
* @see CitrixResourceBase#enableVlanNetwork
|
||||
*/
|
||||
protected XsLocalNetwork getNetworkByName(Connection conn, String name) throws XenAPIException, XmlRpcException {
|
||||
Set<Network> networks = Network.getByNameLabel(conn, name);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ import java.util.List;
|
|||
@Local(value=ServerResource.class)
|
||||
public class XcpServerResource extends CitrixResourceBase {
|
||||
private final static Logger s_logger = Logger.getLogger(XcpServerResource.class);
|
||||
private static final long mem_32m = 33554432L;
|
||||
|
||||
private String version;
|
||||
|
||||
public XcpServerResource() {
|
||||
|
|
@ -70,20 +72,6 @@ public class XcpServerResource extends CitrixResourceBase {
|
|||
return CitrixHelper.getXcpGuestOsType(stdType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setMemory(Connection conn, VM vm, long minMemsize, long maxMemsize) throws XmlRpcException, XenAPIException {
|
||||
|
||||
vm.setMemoryStaticMin(conn, 33554432L);
|
||||
//vm.setMemoryDynamicMin(conn, 33554432L);
|
||||
//vm.setMemoryDynamicMax(conn, 33554432L);
|
||||
vm.setMemoryStaticMax(conn, 33554432L);
|
||||
|
||||
//vm.setMemoryStaticMax(conn, maxMemsize );
|
||||
vm.setMemoryDynamicMax(conn, maxMemsize );
|
||||
vm.setMemoryDynamicMin(conn, minMemsize );
|
||||
//vm.setMemoryStaticMin(conn, maxMemsize );
|
||||
}
|
||||
|
||||
protected NetworkUsageAnswer execute(NetworkUsageCommand cmd) {
|
||||
try {
|
||||
Connection conn = getConnection();
|
||||
|
|
@ -100,4 +88,61 @@ public class XcpServerResource extends CitrixResourceBase {
|
|||
return new NetworkUsageAnswer(cmd, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
XCP provides four memory configuration fields through which
|
||||
administrators can control this behaviour:
|
||||
|
||||
* static-min
|
||||
* dynamic-min
|
||||
* dynamic-max
|
||||
* static-max
|
||||
|
||||
The fields static-{min,max} act as *hard* lower and upper
|
||||
bounds for a guest's memory. For a running guest:
|
||||
* it's not possible to assign the guest more memory than
|
||||
static-max without first shutting down the guest.
|
||||
* it's not possible to assign the guest less memory than
|
||||
static-min without first shutting down the guest.
|
||||
|
||||
The fields dynamic-{min,max} act as *soft* lower and upper
|
||||
bounds for a guest's memory. It's possible to change these
|
||||
fields even when a guest is running.
|
||||
|
||||
The dynamic range must lie wholly within the static range. To
|
||||
put it another way, XCP at all times ensures that:
|
||||
|
||||
static-min <= dynamic-min <= dynamic-max <= static-max
|
||||
|
||||
At all times, XCP will attempt to keep a guest's memory usage
|
||||
between dynamic-min and dynamic-max.
|
||||
|
||||
If dynamic-min = dynamic-max, then XCP will attempt to keep
|
||||
a guest's memory allocation at a constant size.
|
||||
|
||||
If dynamic-min < dynamic-max, then XCP will attempt to give
|
||||
the guest as much memory as possible, while keeping the guest
|
||||
within dynamic-min and dynamic-max.
|
||||
|
||||
If there is enough memory on a given host to give all resident
|
||||
guests dynamic-max, then XCP will attempt do so.
|
||||
|
||||
If there is not enough memory to give all guests dynamic-max,
|
||||
then XCP will ask each of the guests (on that host) to use
|
||||
an amount of memory that is the same *proportional* distance
|
||||
between dynamic-min and dynamic-max.
|
||||
|
||||
XCP will refuse to start guests if starting those guests would
|
||||
cause the sum of all the dynamic-min values to exceed the total
|
||||
host memory (taking into account various memory overheads).
|
||||
|
||||
cf: http://wiki.xen.org/wiki/XCP_FAQ_Dynamic_Memory_Control
|
||||
*/
|
||||
@Override
|
||||
protected void setMemory(Connection conn, VM vm, long minMemsize, long maxMemsize) throws XmlRpcException, XenAPIException {
|
||||
vm.setMemoryStaticMin(conn, mem_32m);
|
||||
vm.setMemoryDynamicMin(conn, minMemsize);
|
||||
vm.setMemoryDynamicMax(conn, maxMemsize);
|
||||
vm.setMemoryStaticMax(conn, maxMemsize);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,18 +17,6 @@
|
|||
package com.cloud.hypervisor.xen.resource;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.xmlrpc.XmlRpcException;
|
||||
|
||||
import com.cloud.agent.api.FenceAnswer;
|
||||
import com.cloud.agent.api.FenceCommand;
|
||||
import com.cloud.agent.api.to.VirtualMachineTO;
|
||||
|
|
@ -39,13 +27,23 @@ import com.cloud.template.VirtualMachineTemplate.BootloaderType;
|
|||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.script.Script;
|
||||
import com.xensource.xenapi.Connection;
|
||||
import com.xensource.xenapi.Console;
|
||||
import com.xensource.xenapi.Host;
|
||||
import com.xensource.xenapi.Types;
|
||||
import com.xensource.xenapi.Types.XenAPIException;
|
||||
import com.xensource.xenapi.VBD;
|
||||
import com.xensource.xenapi.VDI;
|
||||
import com.xensource.xenapi.VM;
|
||||
import com.xensource.xenapi.Types.XenAPIException;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.xmlrpc.XmlRpcException;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@Local(value=ServerResource.class)
|
||||
public class XenServer56FP1Resource extends XenServer56Resource {
|
||||
|
|
@ -137,17 +135,17 @@ public class XenServer56FP1Resource extends XenServer56Resource {
|
|||
record.nameLabel = vmSpec.getName();
|
||||
record.actionsAfterCrash = Types.OnCrashBehaviour.DESTROY;
|
||||
record.actionsAfterShutdown = Types.OnNormalExit.DESTROY;
|
||||
record.memoryDynamicMax = vmSpec.getMaxRam();
|
||||
record.memoryDynamicMin = vmSpec.getMinRam();
|
||||
record.memoryDynamicMax = vmSpec.getMaxRam();
|
||||
Map<String, String> hostParams = new HashMap<String, String>();
|
||||
hostParams = host.getLicenseParams(conn);
|
||||
if (hostParams.get("restrict_dmc").equalsIgnoreCase("false")) {
|
||||
record.memoryStaticMax = 8589934592L; //8GB
|
||||
record.memoryStaticMin = 134217728L; //128MB
|
||||
record.memoryStaticMin = vmSpec.getMinRam();
|
||||
record.memoryStaticMax = vmSpec.getMaxRam();
|
||||
} else {
|
||||
s_logger.warn("Host "+ _host.uuid + " does not support Dynamic Memory Control, so we cannot scale up the vm");
|
||||
record.memoryStaticMax = vmSpec.getMaxRam();
|
||||
record.memoryStaticMin = vmSpec.getMinRam();
|
||||
record.memoryStaticMin = 134217728L; //128MB
|
||||
record.memoryStaticMax = 8589934592L; //8GB
|
||||
}
|
||||
|
||||
if (guestOsTypeName.toLowerCase().contains("windows")) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue