content: // Licensed to the Apache Software Foundation (ASF) under one
  // or more contributor license agreements.  See the NOTICE file
  // distributed with this work for additional information
  // regarding copyright ownership.  The ASF licenses this file
  // to you under the Apache License, Version 2.0 (the
  // "License"); you may not use this file except in compliance
  // with the License.  You may obtain a copy of the License at
  //
  //   http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing,
  // software distributed under the License is distributed on an
  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  // KIND, either express or implied.  See the License for the
  // specific language governing permissions and limitations
  // under the License.
  package com.cloud.hypervisor.xenserver.resource;
  
  import org.apache.commons.lang3.StringUtils;
  import org.apache.xmlrpc.XmlRpcException;
  
  import com.xensource.xenapi.Connection;
  import com.xensource.xenapi.Host;
  import com.xensource.xenapi.Types.XenAPIException;
  import com.xensource.xenapi.VM;
  
  import static com.cloud.utils.NumbersUtil.toHumanReadableSize;
  
  public class XcpServerResource extends CitrixResourceBase {
  
      private final static long mem_32m = 33554432L;
  
      @Override
      protected String getPatchFilePath() {
          return "scripts/vm/hypervisor/xenserver/xcpserver/patch";
      }
  
      /**
       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: https://wiki.xenserver.org/index.php?title=XCP_FAQ_Dynamic_Memory_Control
       */
      @Override
      protected void setMemory(final Connection conn, final VM vm, final long minMemsize, final long maxMemsize) throws XmlRpcException, XenAPIException {
          //setMemoryLimits(staticMin, staticMax, dynamicMin, dynamicMax)
          if (logger.isDebugEnabled()) {
             logger.debug("Memory Limits for VM [" + vm.getNameLabel(conn) + "[staticMin:" + toHumanReadableSize(mem_32m) + ", staticMax:" + toHumanReadableSize(maxMemsize) + ", dynamicMin: " + toHumanReadableSize(minMemsize) +
                      ", dynamicMax:" + toHumanReadableSize(maxMemsize) + "]]");
          }
          vm.setMemoryLimits(conn, mem_32m, maxMemsize, minMemsize, maxMemsize);
      }
  
      @Override
      public boolean isDmcEnabled(final Connection conn, final Host host) {
          //Dynamic Memory Control (DMC) is a technology provided by Xen Cloud Platform (XCP), starting from the 0.5 release
          //For the supported XCPs dmc is default enabled, XCP 1.0.0, 1.1.0, 1.4.x, 1.5 beta, 1.6.x;
          return true;
      }
  
      @Override
      public String networkUsage(final Connection conn, final String privateIpAddress, final String option, final String vif, final String publicIp) {
          String args = "";
          if (option.equals("get")) {
              args += "-g";
              if (StringUtils.isNotEmpty(publicIp)) {
                  args += " -l " + publicIp;
              }
          } else if (option.equals("create")) {
              args += "-c";
          } else if (option.equals("reset")) {
              args += "-r";
          } else if (option.equals("addVif")) {
              args += "-a ";
              args += vif;
          } else if (option.equals("deleteVif")) {
              args += "-d ";
              args += vif;
          }
  
          return executeInVR(privateIpAddress, "netusage.sh", args).getDetails();
      }
  }
  