Commit 9e343c01 authored by Rodrigo's avatar Rodrigo

Addition of ContainerCloudsim code

parent 20a7a55e
package org.cloudbus.cloudsim.examples.container;
import org.cloudbus.cloudsim.power.models.PowerModel;
import org.cloudbus.cloudsim.power.models.PowerModelSpecPowerHpProLiantMl110G4Xeon3040;
import org.cloudbus.cloudsim.power.models.PowerModelSpecPowerHpProLiantMl110G5Xeon3075;
import org.cloudbus.cloudsim.power.models.PowerModelSpecPowerIbmX3550XeonX5670;
/**
* In this class the specifications of the Cloudlets, Containers, VMs and Hosts are coded.
* Regarding to the hosts, the powermodel of each type of the hosts are all included in this class.
*/
public class ConstantsExamples {
/**
* Simulation parameters including the interval and limit
*/
public static final boolean ENABLE_OUTPUT = true;
public static final boolean OUTPUT_CSV = false;
public static final double SCHEDULING_INTERVAL = 300.0D;
public static final double SIMULATION_LIMIT = 87400.0D;
/**
* Cloudlet specs
*/
public static final int CLOUDLET_LENGTH = 30;
public static final int CLOUDLET_PES = 1;
/**
* Startup delay for VMs and the containers are mentioned here.
*/
public static final double CONTAINER_STARTTUP_DELAY = 0.4;//the amount is in seconds
public static final double VM_STARTTUP_DELAY = 100;//the amoun is in seconds
/**
* The available virtual machine types along with the specs.
*/
public static final int VM_TYPES = 4;
public static final int[] VM_MIPS = new int[]{37274 / 2, 37274 / 2, 37274 / 2, 37274 / 2};
public static final int[] VM_PES = new int[]{2, 4, 1, 8};
public static final int[] VM_RAM = new int[]{1024, 2048, 4096, 8192};//**MB*
public static final int VM_BW = 100000;
public static final int VM_SIZE = 2500;
/**
* The available types of container along with the specs.
*/
public static final int CONTAINER_TYPES = 3;
public static final int[] CONTAINER_MIPS = new int[]{4658, 9320, 18636};
public static final int[] CONTAINER_PES = new int[]{1, 1, 1};
public static final int[] CONTAINER_RAM = new int[]{128, 256, 512};
public static final int CONTAINER_BW = 2500;
/**
* The available types of hosts along with the specs.
*/
public static final int HOST_TYPES = 3;
public static final int[] HOST_MIPS = new int[]{37274, 37274, 37274};
public static final int[] HOST_PES = new int[]{4, 8, 16};
public static final int[] HOST_RAM = new int[]{65536, 131072, 262144};
public static final int HOST_BW = 1000000;
public static final int HOST_STORAGE = 1000000;
public static final PowerModel[] HOST_POWER = new PowerModel[]{new PowerModelSpecPowerHpProLiantMl110G4Xeon3040(),
new PowerModelSpecPowerHpProLiantMl110G5Xeon3075(), new PowerModelSpecPowerIbmX3550XeonX5670()};
/**
* The population of hosts, containers, and VMs are specified.
* The containers population is equal to the cloudlets population as each cloudlet is mapped to each container.
* However, depending on the simualtion scenario the container's population can also be different from cloudlet's
* population.
*/
public static final int NUMBER_HOSTS = 20;
public static final int NUMBER_VMS = 25;
public static final int NUMBER_CLOUDLETS = 50;
//-----------------------The Addresses
// public static String logAddress;
//
// public String getLogAddress() {
// return logAddress;
// }
//
// public void setLogAddress(String logAddress) {
// this.logAddress = logAddress;
// }
//
public ConstantsExamples() {
}
}
package org.cloudbus.cloudsim.examples.container;
import org.cloudbus.cloudsim.Log;
import org.cloudbus.cloudsim.core.CloudSim;
import java.util.Calendar;
/**
* This is the modified version of {@link org.cloudbus.cloudsim.examples.power.planetlab.PlanetLabRunner} in CloudSim Package.
* Created by sareh on 18/08/15.
*/
public class RunnerInitiator extends RunnerAbs {
/**
* Instantiates a new runner.
*
* @param enableOutput the enable output
* @param outputToFile the output to file
* @param inputFolder the input folder
* @param outputFolder the output folder
* // * @param workload the workload
* @param vmAllocationPolicy the vm allocation policy
* @param vmSelectionPolicy the vm selection policy
*/
public RunnerInitiator(
boolean enableOutput,
boolean outputToFile,
String inputFolder,
String outputFolder,
String vmAllocationPolicy,
String containerAllocationPolicy,
String vmSelectionPolicy,
String containerSelectionPolicy,
String hostSelectionPolicy,
double overBookingFactor, String runTime, String logAddress) {
super(enableOutput,
outputToFile,
inputFolder,
outputFolder,
vmAllocationPolicy,
containerAllocationPolicy,
vmSelectionPolicy,
containerSelectionPolicy,
hostSelectionPolicy,
overBookingFactor, runTime, logAddress);
}
/*
* (non-Javadoc)
*
* @see RunnerAbs
*/
@Override
protected void init(String inputFolder, double overBookingFactor) {
try {
CloudSim.init(1, Calendar.getInstance(), false);
// setOverBookingFactor(overBookingFactor);
broker = HelperEx.createBroker(overBookingFactor);
int brokerId = broker.getId();
cloudletList = HelperEx.createContainerCloudletList(brokerId, inputFolder, ConstantsExamples.NUMBER_CLOUDLETS);
containerList = HelperEx.createContainerList(brokerId, ConstantsExamples.NUMBER_CLOUDLETS);
vmList = HelperEx.createVmList(brokerId, ConstantsExamples.NUMBER_VMS);
hostList = HelperEx.createHostList(ConstantsExamples.NUMBER_HOSTS);
} catch (Exception e) {
e.printStackTrace();
Log.printLine("The simulation has been terminated due to an unexpected error");
System.exit(0);
}
}
}
package org.cloudbus.cloudsim.examples.container;
import java.io.IOException;
/**
* This Example is following the format for {@link org.cloudbus.cloudsim.examples.power.planetlab.Dvfs}
* It specifically studies the initial placement of containers.
*
* @author Sareh Fotuhi Piraghaj
*/
public class containerInitialPlacementTest {
/**
* The main method.
*
* @param args the arguments
* @throws IOException Signals that an I/O exception has occurred.
*/
public static void main(String[] args) throws IOException {
/**
* The experiments can be repeated for (repeat - runtime +1) times.
* Please set these values as the arguments of the main function or set them bellow:
*/
int runTime = Integer.parseInt(args[0]);
int repeat = Integer.parseInt(args[1]);
for (int i = runTime; i < repeat; ++i) {
boolean enableOutput = true;
boolean outputToFile = true;
/**
* Getting the path of the planet lab workload that is included in the cloudSim Package
*/
String inputFolder = containerOverbooking.class.getClassLoader().getResource("workload/planetlab").getPath();
/**
* The output folder for the logs. The log files would be located in this folder.
*/
String outputFolder = "~/Results";
/**
* The allocation policy for VMs.
*/
String vmAllocationPolicy = "MSThreshold-Under_0.80_0.70";
/**
* The selection policy for containers where a container migration is triggered.
*/
String containerSelectionPolicy = "MaxUsage";
/**
* The allocation policy used for allocating containers to VMs.
*/
String containerAllocationPolicy = "MostFull";
/**
* The host selection policy determines which hosts should be selected as the migration destination.
*/
String hostSelectionPolicy = "FirstFit";
/**
* The VM Selection Policy is used for selecting VMs to migrate when a host status is determined as
* "Overloaded"
*/
String vmSelectionPolicy = "VmMaxC";
/**
* The container overbooking factor is used for overbooking resources of the VM. In this specific case
* the overbooking is performed on CPU only.
*/
int OverBookingFactor = 80;
new RunnerInitiator(
enableOutput,
outputToFile,
inputFolder,
outputFolder,
vmAllocationPolicy,
containerAllocationPolicy,
vmSelectionPolicy,
containerSelectionPolicy,
hostSelectionPolicy,
OverBookingFactor, Integer.toString(i), outputFolder);
}
}
}
package org.cloudbus.cloudsim.examples.container;
import java.io.IOException;
/**
* This Example is following the format for {@link org.cloudbus.cloudsim.examples.power.planetlab.Dvfs}
* It specifically studies the placement of containers.
*
* @author Sareh Fotuhi Piraghaj
*/
public class containerOverbooking {
/**
* The main method.
*
* @param args the arguments
* @throws IOException Signals that an I/O exception has occurred.
*/
public static void main(String[] args) throws IOException {
/**
* The experiments can be repeated for (repeat - runtime +1) times.
* Please set these values as the arguments of the main function or set them bellow:
*/
int runTime = Integer.parseInt(args[0]);
int repeat = Integer.parseInt(args[1]);
for (int i = 10; i < repeat; i += 10) {
boolean enableOutput = true;
boolean outputToFile = true;
/**
* Getting the path of the planet lab workload that is included in the cloudSim Package
*/
String inputFolder = containerOverbooking.class.getClassLoader().getResource("workload/planetlab").getPath();
/**
* The output folder for the logs. The log files would be located in this folder.
*/
String outputFolder = "/Results";
/**
* The allocation policy for VMs. It has the under utilization and over utilization thresholds used for
* determining the underloaded and oberloaded hosts.
*/
String vmAllocationPolicy = "MSThreshold-Under_0.80_0.70"; // DVFS policy without VM migrations
/**
* The selection policy for containers where a container migration is triggered.
*/
String containerSelectionPolicy = "Cor";
/**
* The allocation policy used for allocating containers to VMs.
*/
String containerAllocationPolicy = "MostFull";
// String containerAllocationPolicy= "FirstFit";
// String containerAllocationPolicy= "LeastFull";
// String containerAllocationPolicy= "Simple";
// String containerAllocationPolicy = "Random";
/**
* The host selection policy determines which hosts should be selected as the migration destination.
*/
String hostSelectionPolicy = "FirstFit";
/**
* The VM Selection Policy is used for selecting VMs to migrate when a host status is determined as
* "Overloaded"
*/
String vmSelectionPolicy = "VmMaxC";
new RunnerInitiator(
enableOutput,
outputToFile,
inputFolder,
outputFolder,
vmAllocationPolicy,
containerAllocationPolicy,
vmSelectionPolicy,
containerSelectionPolicy,
hostSelectionPolicy,
i, Integer.toString(runTime), outputFolder);
}
}
}
package org.cloudbus.cloudsim.examples.container;
import java.io.IOException;
/**
* This Example is following the format for {@link org.cloudbus.cloudsim.examples.power.planetlab.Dvfs}
* It specifically studies the placement of containers.
*
* @author Sareh Fotuhi Piraghaj
*/
public class containerSelectionTest {
/**
* The main method.
*
* @param args the arguments
* @throws IOException Signals that an I/O exception has occurred.
*/
public static void main(String[] args) throws IOException {
/**
* The experiments can be repeated for (repeat - runtime +1) times.
* Please set these values as the arguments of the main function or set them bellow:
*/
int runTime = Integer.parseInt(args[0]);
int repeat = Integer.parseInt(args[1]);
for (int i = runTime ; i < repeat; ++i) {
boolean enableOutput = true;
boolean outputToFile = true;
/**
* Getting the path of the planet lab workload that is included in the cloudSim Package
*/
String inputFolder = containerOverbooking.class.getClassLoader().getResource("workload/planetlab").getPath();
/**
* The output folder for the logs. The log files would be located in this folder.
*/
String outputFolder = "~/Results";
/**
* The allocation policy for VMs.
*/
String vmAllocationPolicy = "MSThreshold-Under_0.80_0.70"; // DVFS policy without VM migrations
/**
* The selection policy for containers where a container migration is triggered.
*/
// String containerSelectionPolicy = "MaxUsage";
String containerSelectionPolicy = "Cor";
/**
* The allocation policy used for allocating containers to VMs.
*/
// String containerAllocationPolicy= "MostFull";
String containerAllocationPolicy= "FirstFit";
/**
* The host selection policy determines which hosts should be selected as the migration destination.
*/
String hostSelectionPolicy = "FirstFit";
/**
* The VM Selection Policy is used for selecting VMs to migrate when a host status is determined as
* "Overloaded"
*/
String vmSelectionPolicy = "VmMaxC";
/**
* The container overbooking factor is used for overbooking resources of the VM. In this specific case
* the overbooking is performed on CPU only.
*/
int OverBookingFactor = 80;
new RunnerInitiator(
enableOutput,
outputToFile,
inputFolder,
outputFolder,
vmAllocationPolicy,
containerAllocationPolicy,
vmSelectionPolicy,
containerSelectionPolicy,
hostSelectionPolicy,
OverBookingFactor, Integer.toString(i), outputFolder);
}
}
}
...@@ -644,7 +644,7 @@ public class Datacenter extends SimEntity { ...@@ -644,7 +644,7 @@ public class Datacenter extends SimEntity {
failed = true; failed = true;
} else { } else {
// has the cloudlet already finished? // has the cloudlet already finished?
if (cl.getCloudletStatus() == Cloudlet.SUCCESS) {// if yes, send it back to user if (cl.getCloudletStatusString() == "Success") {// if yes, send it back to user
int[] data = new int[3]; int[] data = new int[3];
data[0] = getId(); data[0] = getId();
data[1] = cloudletId; data[1] = cloudletId;
......
...@@ -94,4 +94,8 @@ public class UtilizationModelPlanetLabInMemory implements UtilizationModel { ...@@ -94,4 +94,8 @@ public class UtilizationModelPlanetLabInMemory implements UtilizationModel {
public double getSchedulingInterval() { public double getSchedulingInterval() {
return schedulingInterval; return schedulingInterval;
} }
public double[] getData(){
return data;
}
} }
package org.cloudbus.cloudsim.container.containerPlacementPolicies;
import org.cloudbus.cloudsim.container.core.ContainerVm;
import java.util.List;
import java.util.Set;
/**
* Created by sareh fotuhi Piraghaj on 16/12/15.
* For writing any container placement policies this class should be extend.
*/
public abstract class ContainerPlacementPolicy {
/**
* Gets the VM List, and the excluded VMs
*
* @param vmList the host
* @return the destination vm to place container
*/
public abstract ContainerVm getContainerVm(List<ContainerVm> vmList, Object obj, Set<? extends ContainerVm> excludedVmList);
}
package org.cloudbus.cloudsim.container.containerPlacementPolicies;
import org.cloudbus.cloudsim.container.core.ContainerVm;
import java.util.List;
import java.util.Set;
/**
* Created by sareh fotuhi Piraghaj on 16/12/15.
* For container placement First Fit policy.
*/
public class ContainerPlacementPolicyFirstFit extends ContainerPlacementPolicy {
@Override
public ContainerVm getContainerVm(List<ContainerVm> vmList, Object obj, Set<? extends ContainerVm> excludedVmList) {
ContainerVm containerVm = null;
for (ContainerVm containerVm1 : vmList) {
if (excludedVmList.contains(containerVm1)) {
continue;
}
containerVm = containerVm1;
break;
}
return containerVm;
}
}
package org.cloudbus.cloudsim.container.containerPlacementPolicies;
import org.cloudbus.cloudsim.container.core.ContainerVm;
import java.util.List;
import java.util.Set;
/**
* Created by sareh fotuhi Piraghaj on 16/12/15.
* For container placement Least-Full policy.
*/
public class ContainerPlacementPolicyLeastFull extends ContainerPlacementPolicy{
@Override
public ContainerVm getContainerVm(List<ContainerVm> vmList, Object obj, Set<? extends ContainerVm> excludedVmList) {
ContainerVm selectedVm = null;
double minMips = Double.MAX_VALUE;
for (ContainerVm containerVm1 : vmList) {
if (excludedVmList.contains(containerVm1)) {
continue;
}
double containerUsage = containerVm1.getContainerScheduler().getAvailableMips();
if ( containerUsage < minMips ) {
minMips = containerUsage;
selectedVm = containerVm1;
}
}
return selectedVm;
}
}
package org.cloudbus.cloudsim.container.containerPlacementPolicies;
import org.cloudbus.cloudsim.container.core.ContainerVm;
import java.util.List;
import java.util.Set;
/**
* Created by sareh fotuhi Piraghaj on 16/12/15.
* For container placement Most-Full policy.
*/
public class ContainerPlacementPolicyMostFull extends ContainerPlacementPolicy {
@Override
public ContainerVm getContainerVm(List<ContainerVm> vmList, Object obj, Set<? extends ContainerVm> excludedVmList) {
ContainerVm selectedVm = null;
double maxMips = Double.MIN_VALUE;
for (ContainerVm containerVm1 : vmList) {
if (excludedVmList.contains(containerVm1)) {
continue;
}
double containerUsage = containerVm1.getContainerScheduler().getAvailableMips();
if ( containerUsage > maxMips) {
maxMips = containerUsage;
selectedVm = containerVm1;
}
}
return selectedVm;
}
}
package org.cloudbus.cloudsim.container.containerPlacementPolicies;
import org.cloudbus.cloudsim.container.core.ContainerVm;
import org.cloudbus.cloudsim.container.utils.RandomGen;
import org.cloudbus.cloudsim.Log;
import java.util.List;
import java.util.Set;
/**
* Created by sareh fotuhi Piraghaj on 16/12/15.
* For container placement Random policy.
*/
public class ContainerPlacementPolicyRandomSelection extends ContainerPlacementPolicy {
@Override
public ContainerVm getContainerVm(List<ContainerVm> vmList, Object obj, Set<? extends ContainerVm> excludedVmList) {
ContainerVm containerVm = null;
while (true) {
if (vmList.size() > 0) {
int randomNum = new RandomGen().getNum(vmList.size());
containerVm = vmList.get(randomNum);
if (excludedVmList.contains(containerVm)) {
continue;
}
} else {
Log.print(String.format("Error: The VM list Size is: %d", vmList.size()));
}
return containerVm;
}
}
}
package org.cloudbus.cloudsim.container.containerProvisioners;
import org.cloudbus.cloudsim.container.core.Container;
/**
* ContainerBwProvisioner is an abstract class that represents the provisioning policy of bandwidth to
* containers inside a vm. When extending this class, care must be taken to guarantee that
* the field availableBw will always contain the amount of free bandwidth available for future
* allocations.
*
* @author Rodrigo N. Calheiros
* @author Sareh Fotuhi Piraghaj
*/
public abstract class ContainerBwProvisioner {
/**
* The vmBw.
*/
private long vmBw;
/**
* The available availableVmBw.
*/
private long availableVmBw;
/**
* Creates the new ContainerBwProvisioner.
*
* @param vmBw the Vm BW
* @pre bw >= 0
* @post $none
*/
public ContainerBwProvisioner(long vmBw) {
// TODO Auto-generated constructor stub
setVmBw(vmBw);
setAvailableVmBw(vmBw);
}
/**
* Allocates BW for a given container.
*
* @param container containercontainer for which the bw are being allocated
* @param bw the bw
* @return $true if the bw could be allocated; $false otherwise
* @pre $none
* @post $none
*/
public abstract boolean allocateBwForContainer(Container container, long bw);
/**
* Gets the allocated BW for container.
*
* @param container the container
* @return the allocated BW for container
*/
public abstract long getAllocatedBwForContainer(Container container);
/**
* Releases BW used by a container.
*
* @param container the container
* @pre $none
* @post none
*/
public abstract void deallocateBwForContainer(Container container);
/**
* Releases BW used by a all containers.
*
* @pre $none
* @post none
*/
public void deallocateBwForAllContainers() {
setAvailableVmBw(getBw());
}
/**
* Checks if BW is suitable for container.
*
* @param container the container
* @param bw the bw
* @return true, if BW is suitable for container
*/
public abstract boolean isSuitableForContainer(Container container, long bw);
/**
* Gets the amount of used BW in the vm.
*
* @return used bw
* @pre $none
* @post $none
*/
public long getUsedVmBw() {
return vmBw - availableVmBw;
}
/**
* @return the vmBw
*/
public long getBw() {
return vmBw;
}
/**
* @param vmBw the vmBw to set
*/
public void setVmBw(long vmBw) {
this.vmBw = vmBw;
}
/**
* @return the availableVmBw
*/
public long getAvailableVmBw() {
return availableVmBw;
}
/**
* @param availableVmBw the availableVmBw to set
*/
public void setAvailableVmBw(long availableVmBw) {
this.availableVmBw = availableVmBw;
}
}
/**
*
*/
package org.cloudbus.cloudsim.container.containerProvisioners;
import java.util.HashMap;
import java.util.Map;
import org.cloudbus.cloudsim.container.core.Container;
/**
* ContainerBwProvisionerSimple is a class that implements a simple best effort allocation policy: if there
* is bw available to request, it allocates; otherwise, it fails.
*
* @author Sareh Fotuhi Piraghaj
* @author Rodrigo N. Calheiros
* @author Anton Beloglazov
*/
public class ContainerBwProvisionerSimple extends ContainerBwProvisioner {
/**
* The container Bw table.
*/
private Map<String, Long> containerBwTable;
/**
* Instantiates a new container bw provisioner simple.
*
* @param containerBw the containerBw
*/
public ContainerBwProvisionerSimple(long containerBw) {
super(containerBw);
setContainerBwTable(new HashMap<String, Long>());
}
/**
* Allocate BW for the container
*
* @param container
* @param bw the bw
* @return
*/
@Override
public boolean allocateBwForContainer(Container container, long bw) {
deallocateBwForContainer(container);
if (getAvailableVmBw() >= bw) {
setAvailableVmBw(getAvailableVmBw() - bw);
getContainerBwTable().put(container.getUid(), bw);
container.setCurrentAllocatedBw(getAllocatedBwForContainer(container));
return true;
}
container.setCurrentAllocatedBw(getAllocatedBwForContainer(container));
return false;
}
/**
* Get allocated bandwidth for container
* @param container
* @return
*/
@Override
public long getAllocatedBwForContainer(Container container) {
if (getContainerBwTable().containsKey(container.getUid())) {
return getContainerBwTable().get(container.getUid());
}
return 0;
}
/**
* Release the allocated BW for the container
* @param container
*/
@Override
public void deallocateBwForContainer(Container container) {
if (getContainerBwTable().containsKey(container.getUid())) {
long amountFreed = getContainerBwTable().remove(container.getUid());
setAvailableVmBw(getAvailableVmBw() + amountFreed);
container.setCurrentAllocatedBw(0);
}
}
/**
* Release the VM bandwidth that is allocated to the container.
*/
@Override
public void deallocateBwForAllContainers() {
super.deallocateBwForAllContainers();
getContainerBwTable().clear();
}
/**
* Check if the VM has enough BW to allocate to the container
* @param container
* @param bw the bw
* @return
*/
@Override
public boolean isSuitableForContainer(Container container, long bw) {
long allocatedBw = getAllocatedBwForContainer(container);
boolean result = allocateBwForContainer(container, bw);
deallocateBwForContainer(container);
if (allocatedBw > 0) {
allocateBwForContainer(container, allocatedBw);
}
return result;
}
/**
* @return the containerBwTable
*/
protected Map<String, Long> getContainerBwTable() {
return containerBwTable;
}
/**
* @param containerBwTable the containerBwTable to set
*/
protected void setContainerBwTable(Map<String, Long> containerBwTable) {
this.containerBwTable = containerBwTable;
}
}
package org.cloudbus.cloudsim.container.containerProvisioners;
/**
*
* @author Sareh Fotuhi Piraghaj
*/
public class ContainerPe {
/**
* Denotes Pe is FREE for allocation.
*/
public static final int FREE = 1;
/**
* Denotes Pe is allocated and hence busy in processing Cloudlet.
*/
public static final int BUSY = 2;
/**
* Denotes Pe is failed and hence it can't process any Cloudlet at this moment. This Pe is
* failed because it belongs to a machine which is also failed.
*/
public static final int FAILED = 3;
/**
* The id.
*/
private int id;
// FOR SPACE SHARED RESOURCE: Jan 21
/**
* The status of Pe: FREE, BUSY, FAILED: .
*/
private int status;
/**
* The pe provisioner.
*/
private ContainerPeProvisioner containerPeProvisioner;
/**
* Allocates a new Pe object.
*
* @param id the Pe ID
* @param containerPeProvisioner the pe provisioner
* @pre id >= 0
* @pre peProvisioner != null
* @post $none
*/
public ContainerPe(int id, ContainerPeProvisioner containerPeProvisioner) {
setId(id);
setContainerPeProvisioner(containerPeProvisioner);
// when created it should be set to FREE, i.e. available for use.
status = FREE;
}
/**
* Sets the id.
*
* @param id the new id
*/
protected void setId(int id) {
this.id = id;
}
/**
* Gets the id.
*
* @return the id
*/
public int getId() {
return id;
}
/**
* Sets the MIPS Rating of this Pe.
*
* @param d the mips
* @pre mips >= 0
* @post $none
*/
public void setMips(double d) {
getContainerPeProvisioner().setMips(d);
}
/**
* Gets the MIPS Rating of this Pe.
*
* @return the MIPS Rating
* @pre $none
* @post $result >= 0
*/
public int getMips() {
return (int) getContainerPeProvisioner().getMips();
}
/**
* Gets the status of this Pe.
*
* @return the status of this Pe
* @pre $none
* @post $none
*/
public int getStatus() {
return status;
}
/**
* Sets Pe status to free, meaning it is available for processing. This should be used by SPACE
* shared hostList only.
*
* @pre $none
* @post $none
*/
public void setStatusFree() {
setStatus(FREE);
}
/**
* Sets Pe status to busy, meaning it is already executing Cloudlets. This should be used by
* SPACE shared hostList only.
*
* @pre $none
* @post $none
*/
public void setStatusBusy() {
setStatus(BUSY);
}
/**
* Sets this Pe to FAILED.
*
* @pre $none
* @post $none
*/
public void setStatusFailed() {
setStatus(FAILED);
}
/**
* Sets Pe status to either <tt>Pe.FREE</tt> or <tt>Pe.BUSY</tt>
*
* @param status Pe status, <tt>true</tt> if it is FREE, <tt>false</tt> if BUSY.
* @pre $none
* @post $none
*/
public void setStatus(int status) {
this.status = status;
}
public ContainerPeProvisioner getContainerPeProvisioner() {
return containerPeProvisioner;
}
/**
* Sets the pe provisioner.
*
* @param containerPeProvisioner the new pe provisioner
*/
public void setContainerPeProvisioner(ContainerPeProvisioner containerPeProvisioner) {
this.containerPeProvisioner = containerPeProvisioner;
}
}
package org.cloudbus.cloudsim.container.containerProvisioners;
import java.util.List;
import org.cloudbus.cloudsim.container.core.Container;
public abstract class ContainerPeProvisioner {
/** The mips. */
private double mips;
/** The available mips. */
private double availableMips;
/**
* Creates the new PeProvisioner.
*
* @param mips overall amount of MIPS available in the Pe
*
* @pre mips>=0
* @post $none
*/
public ContainerPeProvisioner(double mips) {
// TODO Auto-generated constructor stub
setMips(mips);
setAvailableMips(mips);
}
/**
* Allocates MIPS for a given Container.
*
* @param container container for which the MIPS are being allocated
* @param mips the mips
*
* @return $true if the MIPS could be allocated; $false otherwise
*
* @pre $none
* @post $none
*/
public abstract boolean allocateMipsForContainer(Container container, double mips);
/**
* Allocates MIPS for a given Container.
*
* @param containerUid the container uid
* @param mips the mips
*
* @return $true if the MIPS could be allocated; $false otherwise
*
* @pre $none
* @post $none
*/
public abstract boolean allocateMipsForContainer(String containerUid, double mips);
/**
* Allocates MIPS for a given container.
*
* @param container container for which the MIPS are being allocated
* @param mips the mips for each virtual Pe
*
* @return $true if the MIPS could be allocated; $false otherwise
*
* @pre $none
* @post $none
*/
public abstract boolean allocateMipsForContainer(Container container, List<Double> mips);
/**
* Gets allocated MIPS for a given VM.
*
* @param container container for which the MIPS are being allocated
*
* @return array of allocated MIPS
*
* @pre $none
* @post $none
*/
public abstract List<Double> getAllocatedMipsForContainer(Container container);
/**
* Gets total allocated MIPS for a given VM for all PEs.
*
* @param container container for which the MIPS are being allocated
*
* @return total allocated MIPS
*
* @pre $none
* @post $none
*/
public abstract double getTotalAllocatedMipsForContainer(Container container);
/**
* Gets allocated MIPS for a given container for a given virtual Pe.
*
* @param container container for which the MIPS are being allocated
* @param peId the pe id
*
* @return allocated MIPS
*
* @pre $none
* @post $none
*/
public abstract double getAllocatedMipsForContainerByVirtualPeId(Container container, int peId);
/**
* Releases MIPS used by a container.
*
* @param container the container
*
* @pre $none
* @post none
*/
public abstract void deallocateMipsForContainer(Container container);
/**
* Releases MIPS used by all containers.
*
* @pre $none
* @post none
*/
public void deallocateMipsForAllContainers() {
setAvailableMips(getMips());
}
/**
* Gets the MIPS.
*
* @return the MIPS
*/
public double getMips() {
return mips;
}
/**
* Sets the MIPS.
*
* @param mips the MIPS to set
*/
public void setMips(double mips) {
this.mips = mips;
}
/**
* Gets the available MIPS in the PE.
*
* @return available MIPS
*
* @pre $none
* @post $none
*/
public double getAvailableMips() {
return availableMips;
}
/**
* Sets the available MIPS.
*
* @param availableMips the availableMips to set
*/
protected void setAvailableMips(double availableMips) {
this.availableMips = availableMips;
}
/**
* Gets the total allocated MIPS.
*
* @return the total allocated MIPS
*/
public double getTotalAllocatedMips() {
double totalAllocatedMips = getMips() - getAvailableMips();
if (totalAllocatedMips > 0) {
return totalAllocatedMips;
}
return 0;
}
/**
* Gets the utilization of the Pe in percents.
*
* @return the utilization
*/
public double getUtilization() {
return getTotalAllocatedMips() / getMips();
}
}
package org.cloudbus.cloudsim.container.containerProvisioners;
import org.cloudbus.cloudsim.container.core.Container;
/**
* This class takes care of the provisioning of Container's ram .
* @author sareh
*/
public abstract class ContainerRamProvisioner {
/**
* The ram.
*/
private float ram;
/**
* The available availableContainerRam.
*/
private float availableVmRam;
/**
* Creates new Container Ram Provisioner
*
* @param availableContainerRam the vm ram
*/
public ContainerRamProvisioner(float availableContainerRam) {
setRam(availableContainerRam);
setAvailableVmRam(availableContainerRam);
}
/**
* allocate vms ram to the container
*
* @param container the container
* @param ram the ram
* @return $true if successful
*/
public abstract boolean allocateRamForContainer(Container container, float ram);
/**
* Get the allocated ram of the container
*
* @param container the container
* @return the allocated ram of the container
*/
public abstract float getAllocatedRamForContainer(Container container);
/**
* Release the allocated ram amount of the container
*
* @param container the container
*/
public abstract void deallocateRamForContainer(Container container);
/**
* Release the allocated ram of the vm.
*/
public void deallocateRamForAllContainers() {
setAvailableVmRam(getRam());
}
/**
* It checks whether or not the vm have enough ram for the container
*
* @param container the container
* @param ram the vm's ram
* @return $ture if it is suitable
*/
public abstract boolean isSuitableForContainer(Container container, float ram);
/**
* get the allocated ram of the Vm
*
* @return the used ram of the Vm
*/
public float getUsedVmRam() {
return getRam() - availableVmRam;
}
/**
* get the available ram
*
* @return the available ram of the Vm
*/
public float getAvailableVmRam() {
return availableVmRam;
}
/**
* It sets the available Ram of the virtual machine
*
* @param availableRam the availableVmRam
*/
public void setAvailableVmRam(float availableRam) {
this.availableVmRam = availableRam;
}
/**
* @return the ram
*/
public float getRam() {
return ram;
}
/**
* @param ram the ram to set
*/
public void setRam(float ram) {
this.ram = ram;
}
}
package org.cloudbus.cloudsim.container.containerProvisioners;
import java.util.HashMap;
import java.util.Map;
import org.cloudbus.cloudsim.container.core.Container;
/**
* @author sareh
*/
public class ContainerRamProvisionerSimple extends ContainerRamProvisioner {
/**
* The RAM table.
*/
private Map<String, Float> containerRamTable;
/**
* @param availableRam the available ram
*/
public ContainerRamProvisionerSimple(float availableRam) {
super(availableRam);
setContainerRamTable(new HashMap<String, Float>());
}
/**
* @see ContainerRamProvisioner#allocateRamForContainer(Container, float)
* @param container the container
* @param ram the ram
* @return
*/
@Override
public boolean allocateRamForContainer(Container container,
float ram) {
float maxRam = container.getRam();
if (ram >= maxRam) {
ram = maxRam;
}
deallocateRamForContainer(container);
if (getAvailableVmRam() >= ram) {
setAvailableVmRam(getAvailableVmRam() - ram);
getContainerRamTable().put(container.getUid(), ram);
container.setCurrentAllocatedRam(getAllocatedRamForContainer(container));
return true;
}
container.setCurrentAllocatedRam(getAllocatedRamForContainer(container));
return false;
}
/**
* @link ContainerRamProvisioner#getAllocatedRamForContainer(Container)
* @param container the container
* @return
*/
@Override
public float getAllocatedRamForContainer(Container container) {
if (getContainerRamTable().containsKey(container.getUid())) {
return getContainerRamTable().get(container.getUid());
}
return 0;
}
/**
* @see ContainerRamProvisioner#deallocateRamForContainer(Container)
* @param container the container
*/
@Override
public void deallocateRamForContainer(Container container) {
if (getContainerRamTable().containsKey(container.getUid())) {
float amountFreed = getContainerRamTable().remove(container.getUid());
setAvailableVmRam(getAvailableVmRam() + amountFreed);
container.setCurrentAllocatedRam(0);
}
}
/**
* @see ContainerRamProvisioner#deallocateRamForAllContainers()
*/
@Override
public void deallocateRamForAllContainers() {
super.deallocateRamForAllContainers();
getContainerRamTable().clear();
}
/**
* @see ContainerRamProvisioner#isSuitableForContainer(Container, float)
* @param container the container
* @param ram the vm's ram
* @return
*/
@Override
public boolean isSuitableForContainer(Container container,
float ram) {
float allocatedRam = getAllocatedRamForContainer(container);
boolean result = allocateRamForContainer(container, ram);
deallocateRamForContainer(container);
if (allocatedRam > 0) {
allocateRamForContainer(container, allocatedRam);
}
return result;
}
/**
*
* @return the containerRamTable
*/
protected Map<String, Float> getContainerRamTable() {
return containerRamTable;
}
/**
* @param containerRamTable the containerRamTable to set
*/
protected void setContainerRamTable(Map<String, Float> containerRamTable) {
this.containerRamTable = containerRamTable;
}
}
/**
*
*/
package org.cloudbus.cloudsim.container.containerProvisioners;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.cloudbus.cloudsim.container.core.Container;
/**
* @author Sareh Fotuhi Piraghaj
*/
public class CotainerPeProvisionerSimple extends ContainerPeProvisioner {
/**
* The pe table.
*/
private Map<String, List<Double>> peTable;
/**
* @param mips
*/
/**
* Creates the PeProvisionerSimple object.
*
* @param availableMips the available mips
* @pre $none
* @post $none
*/
public CotainerPeProvisionerSimple(double availableMips) {
super(availableMips);
setPeTable(new HashMap<String, ArrayList<Double>>());
}
/* (non-Javadoc)
* @see ContainerVmPeProvisioner#allocateMipsForContainer
*/
@Override
public boolean allocateMipsForContainer(Container container, double mips) {
// TODO Auto-generated method stub
return allocateMipsForContainer(container.getUid(), mips);
}
/* (non-Javadoc)
* @see ContainerVmPeProvisioner#allocateMipsForContainer(java.lang.String, double)
*/
@Override
public boolean allocateMipsForContainer(String containerUid, double mips) {
if (getAvailableMips() < mips) {
return false;
}
List<Double> allocatedMips;
if (getPeTable().containsKey(containerUid)) {
allocatedMips = getPeTable().get(containerUid);
} else {
allocatedMips = new ArrayList<>();
}
allocatedMips.add(mips);
setAvailableMips(getAvailableMips() - mips);
getPeTable().put(containerUid, allocatedMips);
return true;
}
/* (non-Javadoc)
* @see ContainerVmPeProvisioner#allocateMipsForContainer(Container, java.util.List)
*/
@Override
public boolean allocateMipsForContainer(Container container, List<Double> mips) {
int totalMipsToAllocate = 0;
for (double _mips : mips) {
totalMipsToAllocate += _mips;
}
if (getAvailableMips() + getTotalAllocatedMipsForContainer(container) < totalMipsToAllocate) {
return false;
}
setAvailableMips(getAvailableMips() + getTotalAllocatedMipsForContainer(container) - totalMipsToAllocate);
getPeTable().put(container.getUid(), mips);
return true;
}
/*
* (non-Javadoc)
* @see containerProvisioners.PeProvisioner#deallocateMipsForAllContainers()
*/
@Override
public void deallocateMipsForAllContainers() {
super.deallocateMipsForAllContainers();
getPeTable().clear();
}
/* (non-Javadoc)
* @see ContainerPeProvisioner#getAllocatedMipsForContainer
*/
@Override
public List<Double> getAllocatedMipsForContainer(Container container) {
if (getPeTable().containsKey(container.getUid())) {
return getPeTable().get(container.getUid());
}
return null;
}
/* (non-Javadoc)
* @see ContainerVmPeProvisioner#getTotalAllocatedMipsForContainer
*/
@Override
public double getTotalAllocatedMipsForContainer(Container container) {
if (getPeTable().containsKey(container.getUid())) {
double totalAllocatedMips = 0.0;
for (double mips : getPeTable().get(container.getUid())) {
totalAllocatedMips += mips;
}
return totalAllocatedMips;
}
return 0;
}
/* (non-Javadoc)
* @see ContainerVmPeProvisioner#getAllocatedMipsForContainerByVirtualPeId(Container, int)
*/
@Override
public double getAllocatedMipsForContainerByVirtualPeId(Container container,
int peId) {
if (getPeTable().containsKey(container.getUid())) {
try {
return getPeTable().get(container.getUid()).get(peId);
} catch (Exception e) {
}
}
return 0;
}
/* (non-Javadoc)
* @see ContainerVmPeProvisioner#deallocateMipsForContainer(Container)
*/
@Override
public void deallocateMipsForContainer(Container container) {
if (getPeTable().containsKey(container.getUid())) {
for (double mips : getPeTable().get(container.getUid())) {
setAvailableMips(getAvailableMips() + mips);
}
getPeTable().remove(container.getUid());
}
}
/**
* Gets the pe table.
*
* @return the peTable
*/
protected Map<String, List<Double>> getPeTable() {
return peTable;
}
/**
* Sets the pe table.
*
* @param peTable the peTable to set
*/
@SuppressWarnings("unchecked")
protected void setPeTable(Map<String, ? extends List<Double>> peTable) {
this.peTable = (Map<String, List<Double>>) peTable;
}
}
package org.cloudbus.cloudsim.container.containerSelectionPolicies;
import org.cloudbus.cloudsim.container.core.Container;
import org.cloudbus.cloudsim.container.core.PowerContainer;
import org.cloudbus.cloudsim.container.core.PowerContainerHost;
import org.cloudbus.cloudsim.container.core.PowerContainerVm;
import java.util.ArrayList;
import java.util.List;
/**
* Created by sareh on 31/07/15.
*/
public abstract class PowerContainerSelectionPolicy {
/**
* Gets the containers to migrate.
*
* @param host the host
* @return the container to migrate
*/
public abstract Container getContainerToMigrate(PowerContainerHost host);
/**
* Gets the migratable containers.
*
* @param host the host
* @return the migratable containers
*/
protected List<PowerContainer> getMigratableContainers(PowerContainerHost host) {
List<PowerContainer> migratableContainers= new ArrayList<>();
for (PowerContainerVm vm : host.<PowerContainerVm> getVmList()) {
if (!vm.isInMigration()) {
for (Container container: vm.getContainerList()){
if(!container.isInMigration() && !vm.getContainersMigratingIn().contains(container)){
migratableContainers.add((PowerContainer) container);}
}
}
}
return migratableContainers;
}
}
package org.cloudbus.cloudsim.container.containerSelectionPolicies;
import org.cloudbus.cloudsim.container.containerSelectionPolicies.PowerContainerSelectionPolicy;
import org.cloudbus.cloudsim.container.core.Container;
import org.cloudbus.cloudsim.container.core.PowerContainer;
import org.cloudbus.cloudsim.container.core.PowerContainerHost;
import org.cloudbus.cloudsim.container.core.PowerContainerHostUtilizationHistory;
import org.cloudbus.cloudsim.container.utils.Correlation;
import org.cloudbus.cloudsim.Log;
import java.util.List;
/**
* Created by sareh on 7/08/15.
*/
public class PowerContainerSelectionPolicyCor extends PowerContainerSelectionPolicy {
/**
* The fallback policy.
*/
private PowerContainerSelectionPolicy fallbackPolicy;
/**
* Instantiates a new power container selection policy maximum correlation.
*
* @param fallbackPolicy the fallback policy
*/
public PowerContainerSelectionPolicyCor(final PowerContainerSelectionPolicy fallbackPolicy) {
super();
setFallbackPolicy(fallbackPolicy);
}
/*
* (non-Javadoc)
*
* @see PowerContainerSelectionPolicy#getContainerToMigrate
*/
@Override
public Container getContainerToMigrate(final PowerContainerHost host) {
List<PowerContainer> migratableContainers = getMigratableContainers(host);
if (migratableContainers.isEmpty()) {
return null;
}
Container container= getContainer(migratableContainers, host);
migratableContainers.clear();
if (container!= null) {
// Log.printConcatLine("We have to migrate the container with ID", container.getId());
return container;
} else {
return getFallbackPolicy().getContainerToMigrate(host);
}
}
/**
* Gets the fallback policy.
*
* @return the fallback policy
*/
public PowerContainerSelectionPolicy getFallbackPolicy() {
return fallbackPolicy;
}
/**
* Sets the fallback policy.
*
* @param fallbackPolicy the new fallback policy
*/
public void setFallbackPolicy(final PowerContainerSelectionPolicy fallbackPolicy) {
this.fallbackPolicy = fallbackPolicy;
}
public Container getContainer(List<PowerContainer> migratableContainers, PowerContainerHost host) {
double[] corResult = new double[migratableContainers.size()];
Correlation correlation = new Correlation();
int i = 0;
double maxValue = -2.0;
int id = -1;
if (host instanceof PowerContainerHostUtilizationHistory) {
double[] hostUtilization = ((PowerContainerHostUtilizationHistory) host).getUtilizationHistory();
for (Container container : migratableContainers) {
double[] containerUtilization = ((PowerContainer) container).getUtilizationHistoryList();
double cor = correlation.getCor(hostUtilization, containerUtilization);
if (Double.isNaN(cor)) {
cor = -3;
}
corResult[i] = cor;
if(corResult[i] > maxValue){
maxValue = corResult[i];
id = i;
}
i++;
}
}
if (id == -1) {
Log.printConcatLine("Problem with correlation list.");
}
return migratableContainers.get(id);
}
}
package org.cloudbus.cloudsim.container.containerSelectionPolicies;
import org.cloudbus.cloudsim.container.core.Container;
import org.cloudbus.cloudsim.container.core.PowerContainer;
import org.cloudbus.cloudsim.container.core.PowerContainerHost;
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.cloudbus.cloudsim.util.MathUtil;
import java.util.LinkedList;
import java.util.List;
/**
* Created by sareh on 31/07/15.
*/
public class PowerContainerSelectionPolicyMaximumCorrelation extends PowerContainerSelectionPolicy {
/**
* The fallback policy.
*/
private PowerContainerSelectionPolicy fallbackPolicy;
/**
* Instantiates a new power container selection policy maximum correlation.
*
* @param fallbackPolicy the fallback policy
*/
public PowerContainerSelectionPolicyMaximumCorrelation(final PowerContainerSelectionPolicy fallbackPolicy) {
super();
setFallbackPolicy(fallbackPolicy);
}
/*
* (non-Javadoc)
*
* @see powerContainerSelectionPolicy#getContainerToMigrate()
*/
@Override
public Container getContainerToMigrate(final PowerContainerHost host) {
List<PowerContainer> migratableContainers = getMigratableContainers(host);
if (migratableContainers.isEmpty()) {
return null;
}
List<Double> metrics = null;
try {
metrics = getCorrelationCoefficients(getUtilizationMatrix(migratableContainers));
} catch (IllegalArgumentException e) { // the degrees of freedom must be greater than zero
return getFallbackPolicy().getContainerToMigrate(host);
}
double maxMetric = Double.MIN_VALUE;
int maxIndex = 0;
for (int i = 0; i < metrics.size(); i++) {
double metric = metrics.get(i);
if (metric > maxMetric) {
maxMetric = metric;
maxIndex = i;
}
}
return migratableContainers.get(maxIndex);
}
/**
* Gets the utilization matrix.
*
* @param powerContainers the powerContainers
* @return the utilization matrix
*/
protected double[][] getUtilizationMatrix(final List<PowerContainer> powerContainers) {
int n = powerContainers.size();
int m = getMinUtilizationHistorySize(powerContainers);
double[][] utilization = new double[n][m];
for (int i = 0; i < n; i++) {
List<Double> vmUtilization = powerContainers.get(i).getUtilizationHistory();
for (int j = 0; j < vmUtilization.size(); j++) {
utilization[i][j] = vmUtilization.get(j);
}
}
return utilization;
}
/**
* Gets the min utilization history size.
*
* @param containerList the container list
* @return the min utilization history size
*/
protected int getMinUtilizationHistorySize(final List<PowerContainer> containerList) {
int minSize = Integer.MAX_VALUE;
for (PowerContainer container : containerList) {
int size = container.getUtilizationHistory().size();
if (size < minSize) {
minSize = size;
}
}
return minSize;
}
/**
* Gets the correlation coefficients.
*
* @param data the data
* @return the correlation coefficients
*/
protected List<Double> getCorrelationCoefficients(final double[][] data) {
int n = data.length;
int m = data[0].length;
List<Double> correlationCoefficients = new LinkedList<Double>();
for (int i = 0; i < n; i++) {
double[][] x = new double[n - 1][m];
int k = 0;
for (int j = 0; j < n; j++) {
if (j != i) {
x[k++] = data[j];
}
}
// Transpose the matrix so that it fits the linear model
double[][] xT = new Array2DRowRealMatrix(x).transpose().getData();
// RSquare is the "coefficient of determination"
correlationCoefficients.add(MathUtil.createLinearRegression(xT,
data[i]).calculateRSquared());
}
return correlationCoefficients;
}
/**
* Gets the fallback policy.
*
* @return the fallback policy
*/
public PowerContainerSelectionPolicy getFallbackPolicy() {
return fallbackPolicy;
}
/**
* Sets the fallback policy.
*
* @param fallbackPolicy the new fallback policy
*/
public void setFallbackPolicy(final PowerContainerSelectionPolicy fallbackPolicy) {
this.fallbackPolicy = fallbackPolicy;
}
}
package org.cloudbus.cloudsim.container.containerSelectionPolicies;
import org.cloudbus.cloudsim.container.core.PowerContainerHost;
import org.cloudbus.cloudsim.container.core.Container;
import org.cloudbus.cloudsim.container.core.PowerContainer;
import java.util.List;
/**
* Created by sareh on 4/08/15.
*/
public class PowerContainerSelectionPolicyMaximumUsage extends PowerContainerSelectionPolicy {
/*
* (non-Javadoc)
* @see
* PowerContainerSelectionPolicy#getContainerToMigrate
*/
@Override
public Container getContainerToMigrate(PowerContainerHost host) {
List<PowerContainer> migratableContainers = getMigratableContainers(host);
if (migratableContainers.isEmpty()) {
return null;
}
Container containerToMigrate = null;
double maxMetric = Double.MIN_VALUE;
for (Container container : migratableContainers) {
if (container.isInMigration()) {
continue;
}
double metric = container.getCurrentRequestedTotalMips();
if (maxMetric < metric) {
maxMetric = metric;
containerToMigrate = container;
}
}
return containerToMigrate;
}
}
package org.cloudbus.cloudsim.container.containerSelectionPolicies;
import org.cloudbus.cloudsim.container.core.PowerContainerHost;
import org.cloudbus.cloudsim.container.core.Container;
import org.cloudbus.cloudsim.container.core.PowerContainer;
import java.util.List;
/**
* Created by sareh on 3/08/15.
*/
public class PowerContainerSelectionPolicyMinimumMigrationTime extends PowerContainerSelectionPolicy {
/*
* (non-Javadoc)
* @see
* PowerContainerSelectionPolicy#getContainerToMigrate
*/
@Override
public Container getContainerToMigrate(PowerContainerHost host) {
List<PowerContainer> migratableContainers = getMigratableContainers(host);
if (migratableContainers.isEmpty()) {
return null;
}
Container containerToMigrate = null;
double minMetric = Double.MAX_VALUE;
for (Container container : migratableContainers) {
if (container.isInMigration()) {
continue;
}
double metric = container.getRam();
if (metric < minMetric) {
minMetric = metric;
containerToMigrate = container;
}
}
return containerToMigrate;
}
}
package org.cloudbus.cloudsim.container.containerVmProvisioners;
import org.cloudbus.cloudsim.container.core.ContainerVm;
/**
* Created by sareh on 10/07/15.
*/
public abstract class ContainerVmBwProvisioner {
/**
* The bw.
*/
private long bw;
/**
* The available bw.
*/
private long availableBw;
/**
* Creates the new BwProvisioner.
*
* @param bw overall amount of bandwidth available in the host.
* @pre bw >= 0
* @post $none
*/
public ContainerVmBwProvisioner(long bw) {
setBw(bw);
setAvailableBw(bw);
}
/**
* Allocates BW for a given VM.
*
* @param containerVm virtual machine for which the bw are being allocated
* @param bw the bw
* @return $true if the bw could be allocated; $false otherwise
* @pre $none
* @post $none
*/
public abstract boolean allocateBwForContainerVm(ContainerVm containerVm, long bw);
/**
* Gets the allocated BW for VM.
*
* @param containerVm the VM
* @return the allocated BW for vm
*/
public abstract long getAllocatedBwForContainerVm(ContainerVm containerVm);
/**
* Releases BW used by a VM.
*
* @param containerVm the vm
* @pre $none
* @post none
*/
public abstract void deallocateBwForContainerVm(ContainerVm containerVm);
/**
* Releases BW used by a all VMs.
*
* @pre $none
* @post none
*/
public void deallocateBwForAllContainerVms() {
setAvailableBw(getBw());
}
/**
* Checks if BW is suitable for vm.
*
* @param containerVm the vm
* @param bw the bw
* @return true, if BW is suitable for vm
*/
public abstract boolean isSuitableForContainerVm(ContainerVm containerVm, long bw);
/**
* Gets the bw.
*
* @return the bw
*/
public long getBw() {
return bw;
}
/**
* Sets the bw.
*
* @param bw the new bw
*/
protected void setBw(long bw) {
this.bw = bw;
}
/**
* Gets the available BW in the host.
*
* @return available bw
* @pre $none
* @post $none
*/
public long getAvailableBw() {
return availableBw;
}
/**
* Gets the amount of used BW in the host.
*
* @return used bw
* @pre $none
* @post $none
*/
public long getUsedBw() {
return bw - availableBw;
}
/**
* Sets the available bw.
*
* @param availableBw the new available bw
*/
protected void setAvailableBw(long availableBw) {
this.availableBw = availableBw;
}
}
package org.cloudbus.cloudsim.container.containerVmProvisioners;
import org.cloudbus.cloudsim.container.core.ContainerVm;
import java.util.HashMap;
import java.util.Map;
/**
* Created by sareh on 10/07/15.
*/
public class ContainerVmBwProvisionerSimple extends ContainerVmBwProvisioner {
/**
* The bw table.
*/
private Map<String, Long> bwTable;
/**
* Instantiates a new bw provisioner simple.
*
* @param bw the bw
*/
public ContainerVmBwProvisionerSimple(long bw) {
super(bw);
setBwTable(new HashMap<String, Long>());
}
@Override
public boolean allocateBwForContainerVm(ContainerVm containerVm, long bw) {
deallocateBwForContainerVm(containerVm);
if (getAvailableBw() >= bw) {
setAvailableBw(getAvailableBw() - bw);
getBwTable().put(containerVm.getUid(), bw);
containerVm.setCurrentAllocatedBw(getAllocatedBwForContainerVm(containerVm));
return true;
}
containerVm.setCurrentAllocatedBw(getAllocatedBwForContainerVm(containerVm));
return false;
}
@Override
public long getAllocatedBwForContainerVm(ContainerVm containerVm) {
if (getBwTable().containsKey(containerVm.getUid())) {
return getBwTable().get(containerVm.getUid());
}
return 0;
}
@Override
public void deallocateBwForContainerVm(ContainerVm containerVm) {
if (getBwTable().containsKey(containerVm.getUid())) {
long amountFreed = getBwTable().remove(containerVm.getUid());
setAvailableBw(getAvailableBw() + amountFreed);
containerVm.setCurrentAllocatedBw(0);
}
}
/*
* (non-Javadoc)
* ContainerVmBwProvisioner#deallocateBwForAllContainerVms
*/
@Override
public void deallocateBwForAllContainerVms() {
super.deallocateBwForAllContainerVms();
getBwTable().clear();
}
@Override
public boolean isSuitableForContainerVm(ContainerVm containerVm, long bw) {
long allocatedBw = getAllocatedBwForContainerVm(containerVm);
boolean result = allocateBwForContainerVm(containerVm, bw);
deallocateBwForContainerVm(containerVm);
if (allocatedBw > 0) {
allocateBwForContainerVm(containerVm, allocatedBw);
}
return result;
}
/**
* Gets the bw table.
*
* @return the bw table
*/
protected Map<String, Long> getBwTable() {
return bwTable;
}
/**
* Sets the bw table.
*
* @param bwTable the bw table
*/
protected void setBwTable(Map<String, Long> bwTable) {
this.bwTable = bwTable;
}
}
package org.cloudbus.cloudsim.container.containerVmProvisioners;
/**
* Created by sareh on 10/07/15.
*/
public class ContainerVmPe {
/**
* Denotes Pe is FREE for allocation.
*/
public static final int FREE = 1;
/**
* Denotes Pe is allocated and hence busy in processing Cloudlet.
*/
public static final int BUSY = 2;
/**
* Denotes Pe is failed and hence it can't process any Cloudlet at this moment. This Pe is
* failed because it belongs to a machine which is also failed.
*/
public static final int FAILED = 3;
/**
* The id.
*/
private int id;
// FOR SPACE SHARED RESOURCE: Jan 21
/**
* The status of Pe: FREE, BUSY, FAILED: .
*/
private int status;
/**
* The pe provisioner.
*/
private ContainerVmPeProvisioner containerVmPeProvisioner;
/**
* Allocates a new Pe object.
*
* @param id the Pe ID
* @param containerVmPeProvisioner the pe provisioner
* @pre id >= 0
* @pre peProvisioner != null
* @post $none
*/
public ContainerVmPe(int id, ContainerVmPeProvisioner containerVmPeProvisioner) {
setId(id);
setContainerVmPeProvisioner(containerVmPeProvisioner);
// when created it should be set to FREE, i.e. available for use.
status = FREE;
}
/**
* Sets the id.
*
* @param id the new id
*/
protected void setId(int id) {
this.id = id;
}
/**
* Gets the id.
*
* @return the id
*/
public int getId() {
return id;
}
/**
* Sets the MIPS Rating of this Pe.
*
* @param d the mips
* @pre mips >= 0
* @post $none
*/
public void setMips(double d) {
getContainerVmPeProvisioner().setMips(d);
}
/**
* Gets the MIPS Rating of this Pe.
*
* @return the MIPS Rating
* @pre $none
* @post $result >= 0
*/
public int getMips() {
return (int) getContainerVmPeProvisioner().getMips();
}
/**
* Gets the status of this Pe.
*
* @return the status of this Pe
* @pre $none
* @post $none
*/
public int getStatus() {
return status;
}
/**
* Sets Pe status to free, meaning it is available for processing. This should be used by SPACE
* shared hostList only.
*
* @pre $none
* @post $none
*/
public void setStatusFree() {
setStatus(FREE);
}
/**
* Sets Pe status to busy, meaning it is already executing Cloudlets. This should be used by
* SPACE shared hostList only.
*
* @pre $none
* @post $none
*/
public void setStatusBusy() {
setStatus(BUSY);
}
/**
* Sets this Pe to FAILED.
*
* @pre $none
* @post $none
*/
public void setStatusFailed() {
setStatus(FAILED);
}
/**
* Sets Pe status to either <tt>Pe.FREE</tt> or <tt>Pe.BUSY</tt>
*
* @param status Pe status, <tt>true</tt> if it is FREE, <tt>false</tt> if BUSY.
* @pre $none
* @post $none
*/
public void setStatus(int status) {
this.status = status;
}
public ContainerVmPeProvisioner getContainerVmPeProvisioner() {
return containerVmPeProvisioner;
}
/**
* Sets the pe provisioner.
*
* @param containerVmPeProvisioner the new pe provisioner
*/
public void setContainerVmPeProvisioner(ContainerVmPeProvisioner containerVmPeProvisioner) {
this.containerVmPeProvisioner = containerVmPeProvisioner;
}
}
package org.cloudbus.cloudsim.container.containerVmProvisioners;
import org.cloudbus.cloudsim.container.core.ContainerVm;
import java.util.List;
/**
* Created by sareh on 10/07/15.
*/
public abstract class ContainerVmPeProvisioner {
/** The mips. */
private double mips;
/** The available mips. */
private double availableMips;
/**
* Creates the new PeProvisioner.
*
* @param mips overall amount of MIPS available in the Pe
*
* @pre mips>=0
* @post $none
*/
public ContainerVmPeProvisioner(double mips) {
// TODO Auto-generated constructor stub
setMips(mips);
setAvailableMips(mips);
}
/**
* Allocates MIPS for a given containerVm.
*
* @param containerVm virtual machine for which the MIPS are being allocated
* @param mips the mips
*
* @return $true if the MIPS could be allocated; $false otherwise
*
* @pre $none
* @post $none
*/
public abstract boolean allocateMipsForContainerVm(ContainerVm containerVm, double mips);
/**
* Allocates MIPS for a given VM.
*
* @param containerVmUid the containerVmUid
* @param mips the mips
*
* @return $true if the MIPS could be allocated; $false otherwise
*
* @pre $none
* @post $none
*/
public abstract boolean allocateMipsForContainerVm(String containerVmUid, double mips);
/**
* Allocates MIPS for a given VM.
*
* @param containerVm virtual machine for which the MIPS are being allocated
* @param mips the mips for each virtual Pe
*
* @return $true if the MIPS could be allocated; $false otherwise
*
* @pre $none
* @post $none
*/
public abstract boolean allocateMipsForContainerVm(ContainerVm containerVm, List<Double> mips);
/**
* Gets allocated MIPS for a given VM.
*
* @param containerVm virtual machine for which the MIPS are being allocated
*
* @return array of allocated MIPS
*
* @pre $none
* @post $none
*/
public abstract List<Double> getAllocatedMipsForContainerVm(ContainerVm containerVm);
/**
* Gets total allocated MIPS for a given VM for all PEs.
*
* @param containerVm virtual machine for which the MIPS are being allocated
*
* @return total allocated MIPS
*
* @pre $none
* @post $none
*/
public abstract double getTotalAllocatedMipsForContainerVm(ContainerVm containerVm);
/**
* Gets allocated MIPS for a given VM for a given virtual Pe.
*
* @param containerVm virtual machine for which the MIPS are being allocated
* @param peId the pe id
*
* @return allocated MIPS
*
* @pre $none
* @post $none
*/
public abstract double getAllocatedMipsForContainerVmByVirtualPeId(ContainerVm containerVm, int peId);
/**
* Releases MIPS used by a VM.
*
* @param containerVm the containerVm
*
* @pre $none
* @post none
*/
public abstract void deallocateMipsForContainerVm(ContainerVm containerVm);
/**
* Releases MIPS used by all VMs.
*
* @pre $none
* @post none
*/
public void deallocateMipsForAllContainerVms() {
setAvailableMips(getMips());
}
/**
* Gets the MIPS.
*
* @return the MIPS
*/
public double getMips() {
return mips;
}
/**
* Sets the MIPS.
*
* @param mips the MIPS to set
*/
public void setMips(double mips) {
this.mips = mips;
}
/**
* Gets the available MIPS in the PE.
*
* @return available MIPS
*
* @pre $none
* @post $none
*/
public double getAvailableMips() {
return availableMips;
}
/**
* Sets the available MIPS.
*
* @param availableMips the availableMips to set
*/
protected void setAvailableMips(double availableMips) {
this.availableMips = availableMips;
}
/**
* Gets the total allocated MIPS.
*
* @return the total allocated MIPS
*/
public double getTotalAllocatedMips() {
double totalAllocatedMips = getMips() - getAvailableMips();
if (totalAllocatedMips > 0) {
return totalAllocatedMips;
}
return 0;
}
/**
* Gets the utilization of the Pe in percents.
*
* @return the utilization
*/
public double getUtilization() {
return getTotalAllocatedMips() / getMips();
}
}
package org.cloudbus.cloudsim.container.containerVmProvisioners;
import org.cloudbus.cloudsim.container.core.ContainerVm;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by sareh on 10/07/15.
*/
public class ContainerVmPeProvisionerSimple extends ContainerVmPeProvisioner {
/** The pe table. */
private Map<String, List<Double>> peTable;
/**
* Creates the PeProvisionerSimple object.
*
* @param availableMips the available mips
*
* @pre $none
* @post $none
*/
public ContainerVmPeProvisionerSimple(double availableMips) {
super(availableMips);
setPeTable(new HashMap<String, ArrayList<Double>>());
}
@Override
public boolean allocateMipsForContainerVm(ContainerVm containerVm, double mips) {
return allocateMipsForContainerVm(containerVm.getUid(), mips);
}
@Override
public boolean allocateMipsForContainerVm(String containerVmUid, double mips) {
if (getAvailableMips() < mips) {
return false;
}
List<Double> allocatedMips;
if (getPeTable().containsKey(containerVmUid)) {
allocatedMips = getPeTable().get(containerVmUid);
} else {
allocatedMips = new ArrayList<>();
}
allocatedMips.add(mips);
setAvailableMips(getAvailableMips() - mips);
getPeTable().put(containerVmUid, allocatedMips);
return true;
}
@Override
public boolean allocateMipsForContainerVm(ContainerVm containerVm, List<Double> mips) {
int totalMipsToAllocate = 0;
for (double _mips : mips) {
totalMipsToAllocate += _mips;
}
if (getAvailableMips() + getTotalAllocatedMipsForContainerVm(containerVm)< totalMipsToAllocate) {
return false;
}
setAvailableMips(getAvailableMips() + getTotalAllocatedMipsForContainerVm(containerVm)- totalMipsToAllocate);
getPeTable().put(containerVm.getUid(), mips);
return true;
}
@Override
public List<Double> getAllocatedMipsForContainerVm(ContainerVm containerVm) {
if (getPeTable().containsKey(containerVm.getUid())) {
return getPeTable().get(containerVm.getUid());
}
return null;
}
@Override
public double getTotalAllocatedMipsForContainerVm(ContainerVm containerVm) {
if (getPeTable().containsKey( containerVm.getUid())) {
double totalAllocatedMips = 0.0;
for (double mips : getPeTable().get(containerVm.getUid())) {
totalAllocatedMips += mips;
}
return totalAllocatedMips;
}
return 0;
}
@Override
public double getAllocatedMipsForContainerVmByVirtualPeId(ContainerVm containerVm, int peId) {
if (getPeTable().containsKey(containerVm.getUid())) {
try {
return getPeTable().get(containerVm.getUid()).get(peId);
} catch (Exception e) {
}
}
return 0;
}
@Override
public void deallocateMipsForContainerVm(ContainerVm containerVm) {
if (getPeTable().containsKey(containerVm.getUid())) {
for (double mips : getPeTable().get(containerVm.getUid())) {
setAvailableMips(getAvailableMips() + mips);
}
getPeTable().remove(containerVm.getUid());
}
}
@Override
public void deallocateMipsForAllContainerVms() {
super.deallocateMipsForAllContainerVms();
getPeTable().clear();
}
/**
* Gets the pe table.
*
* @return the peTable
*/
protected Map<String, List<Double>> getPeTable() {
return peTable;
}
/**
* Sets the pe table.
*
* @param peTable the peTable to set
*/
@SuppressWarnings("unchecked")
protected void setPeTable(Map<String, ? extends List<Double>> peTable) {
this.peTable = (Map<String, List<Double>>) peTable;
}
}
package org.cloudbus.cloudsim.container.containerVmProvisioners;
import org.cloudbus.cloudsim.container.core.ContainerVm;
/**
* Created by sareh on 10/07/15.
*/
public abstract class ContainerVmRamProvisioner {
/**
* The ram.
*/
private float ram;
/**
* The available availableRam.
*/
private float availableRam;
/**
* Creates new Containervm Ram Provisioner
*
* @param availableContainerVmRam the vm ram
*/
public ContainerVmRamProvisioner(float availableContainerVmRam) {
setRam(availableContainerVmRam);
setAvailableRam(availableContainerVmRam);
}
/**
* allocate hosts ram to the VM
*
* @param containerVm the containerVm
* @param ram the ram
* @return $true if successful
*/
public abstract boolean allocateRamForContainerVm(ContainerVm containerVm, float ram);
/**
* Get the allocated ram of the containerVm
*
* @param containerVm the containerVm
* @return the allocated ram of the containerVM
*/
public abstract float getAllocatedRamForContainerVm(ContainerVm containerVm);
/**
* Release the allocated ram amount of the containerVm
*
* @param containerVm the containerVm
*/
public abstract void deallocateRamForContainerVm(ContainerVm containerVm);
/**
* Release the allocated ram of the vm.
*/
public void deallocateRamForAllContainerVms() {
setAvailableRam(getRam());
}
/**
* It checks whether or not the vm have enough ram for the containerVm
*
* @param containerVm the containerVm
* @param ram the vm's ram
* @return $ture if it is suitable
*/
public abstract boolean isSuitableForContainerVm(ContainerVm containerVm, float ram);
/**
* get the allocated ram of the Vm
*
* @return the used ram of the Vm
*/
public float getUsedVmRam() {
return getRam() - availableRam;
}
/**
* get the available ram
*
* @return the available ram of the Vm
*/
public float getAvailableRam() {
return availableRam;
}
/**
* It sets the available Ram of the virtual machine
*
* @param availableRam the availableRam
*/
public void setAvailableRam(float availableRam) {
this.availableRam = availableRam;
}
/**
* @return the ram
*/
public float getRam() {
return ram;
}
/**
* @param ram the ram to set
*/
public void setRam(float ram) {
this.ram = ram;
}
}
package org.cloudbus.cloudsim.container.containerVmProvisioners;
import org.cloudbus.cloudsim.container.core.ContainerVm;
import java.util.HashMap;
import java.util.Map;
/**
* Created by sareh on 10/07/15.
*/
public class ContainerVmRamProvisionerSimple extends ContainerVmRamProvisioner {
/**
* The RAM table.
*/
private Map<String, Float> containerVmRamTable;
/**
* @param availableRam the available ram
*/
public ContainerVmRamProvisionerSimple(int availableRam) {
super(availableRam);
setContainerVmRamTable(new HashMap<String, Float>());
}
@Override
public boolean allocateRamForContainerVm(ContainerVm containerVm, float ram) {
float maxRam = containerVm.getRam();
if (ram >= maxRam) {
ram = maxRam;
}
deallocateRamForContainerVm(containerVm);
if (getAvailableRam() >= ram) {
setAvailableRam(getAvailableRam() - ram);
getContainerVmRamTable().put(containerVm.getUid(), ram);
containerVm.setCurrentAllocatedRam(getAllocatedRamForContainerVm(containerVm));
return true;
}
containerVm.setCurrentAllocatedRam(getAllocatedRamForContainerVm(containerVm));
return false;
}
@Override
public float getAllocatedRamForContainerVm(ContainerVm containerVm) {
if (getContainerVmRamTable().containsKey(containerVm.getUid())) {
return getContainerVmRamTable().get(containerVm.getUid());
}
return 0;
}
@Override
public void deallocateRamForContainerVm(ContainerVm containerVm) {
if (getContainerVmRamTable().containsKey(containerVm.getUid())) {
float amountFreed = getContainerVmRamTable().remove(containerVm.getUid());
setAvailableRam(getAvailableRam() + amountFreed);
containerVm.setCurrentAllocatedRam(0);
}
}
@Override
public void deallocateRamForAllContainerVms() {
super.deallocateRamForAllContainerVms();
getContainerVmRamTable().clear();
}
@Override
public boolean isSuitableForContainerVm(ContainerVm containerVm, float ram) {
float allocatedRam = getAllocatedRamForContainerVm(containerVm);
boolean result = allocateRamForContainerVm(containerVm, ram);
deallocateRamForContainerVm(containerVm);
if (allocatedRam > 0) {
allocateRamForContainerVm(containerVm, allocatedRam);
}
return result;
}
/**
* @return the containerVmRamTable
*/
protected Map<String, Float> getContainerVmRamTable() {
return containerVmRamTable;
}
/**
* @param containerVmRamTable the containerVmRamTable to set
*/
protected void setContainerVmRamTable(Map<String, Float> containerVmRamTable) {
this.containerVmRamTable = containerVmRamTable;
}
}
package org.cloudbus.cloudsim.container.core;
import org.cloudbus.cloudsim.Cloudlet;
import org.cloudbus.cloudsim.UtilizationModel;
import java.util.List;
/**
* Created by sareh on 10/07/15.
*/
public class ContainerCloudlet extends Cloudlet {
public int containerId = -1;
public ContainerCloudlet(int cloudletId, long cloudletLength, int pesNumber, long cloudletFileSize, long cloudletOutputSize, UtilizationModel utilizationModelCpu, UtilizationModel utilizationModelRam, UtilizationModel utilizationModelBw) {
super(cloudletId, cloudletLength, pesNumber, cloudletFileSize, cloudletOutputSize, utilizationModelCpu, utilizationModelRam, utilizationModelBw);
}
public ContainerCloudlet(int cloudletId, long cloudletLength, int pesNumber, long cloudletFileSize, long cloudletOutputSize, UtilizationModel utilizationModelCpu, UtilizationModel utilizationModelRam, UtilizationModel utilizationModelBw, boolean record, List<String> fileList) {
super(cloudletId, cloudletLength, pesNumber, cloudletFileSize, cloudletOutputSize, utilizationModelCpu, utilizationModelRam, utilizationModelBw, record, fileList);
}
public ContainerCloudlet(int cloudletId, long cloudletLength, int pesNumber, long cloudletFileSize, long cloudletOutputSize, UtilizationModel utilizationModelCpu, UtilizationModel utilizationModelRam, UtilizationModel utilizationModelBw, List<String> fileList) {
super(cloudletId, cloudletLength, pesNumber, cloudletFileSize, cloudletOutputSize, utilizationModelCpu, utilizationModelRam, utilizationModelBw, fileList);
}
public ContainerCloudlet(int cloudletId, long cloudletLength, int pesNumber, long cloudletFileSize, long cloudletOutputSize, UtilizationModel utilizationModelCpu, UtilizationModel utilizationModelRam, UtilizationModel utilizationModelBw, boolean record) {
super(cloudletId, cloudletLength, pesNumber, cloudletFileSize, cloudletOutputSize, utilizationModelCpu, utilizationModelRam, utilizationModelBw, record);
}
public int getContainerId() {
return containerId;
}
public void setContainerId(int containerId) {
this.containerId = containerId;
}
}
package org.cloudbus.cloudsim.container.core;
import org.cloudbus.cloudsim.container.containerVmProvisioners.ContainerVmBwProvisioner;
import org.cloudbus.cloudsim.container.containerVmProvisioners.ContainerVmPe;
import org.cloudbus.cloudsim.container.containerVmProvisioners.ContainerVmRamProvisioner;
import org.cloudbus.cloudsim.container.schedulers.ContainerVmScheduler;
import org.cloudbus.cloudsim.power.models.PowerModel;
import org.cloudbus.cloudsim.util.MathUtil;
import java.util.List;
/**
* Created by sareh on 15/07/15.
*/
public class PowerContainerHostUtilizationHistory extends PowerContainerHost {
/**
* Instantiates a new power host utilization history.
*
* @param id the id
* @param ramProvisioner the ram provisioner
* @param bwProvisioner the bw provisioner
* @param storage the storage
* @param peList the pe list
* @param vmScheduler the vm scheduler
* @param powerModel the power model
*/
public PowerContainerHostUtilizationHistory(
int id,
ContainerVmRamProvisioner ramProvisioner,
ContainerVmBwProvisioner bwProvisioner,
long storage,
List<? extends ContainerVmPe> peList,
ContainerVmScheduler vmScheduler,
PowerModel powerModel) {
super(id, ramProvisioner, bwProvisioner, storage, peList, vmScheduler, powerModel);
}
/**
* Gets the host utilization history.
*
* @return the host utilization history
*/
public double[] getUtilizationHistory() {
double[] utilizationHistory = new double[PowerContainerVm.HISTORY_LENGTH];
double hostMips = getTotalMips();
for (PowerContainerVm vm : this.<PowerContainerVm>getVmList()) {
for (int i = 0; i < vm.getUtilizationHistory().size(); i++) {
utilizationHistory[i] += vm.getUtilizationHistory().get(i) * vm.getMips() / hostMips;
}
}
return MathUtil.trimZeroTail(utilizationHistory);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment