summaryrefslogtreecommitdiff
path: root/opendc-simulator
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-06-22 15:23:57 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2021-06-22 15:23:57 +0200
commita29a61334adb8432c69800b19508eca4eff4bfd1 (patch)
treef73ae85051238ff87bfba045e314003f61b01fb9 /opendc-simulator
parent8a2b475f082572033438eb5b8703d211323f1b52 (diff)
simulator: Add support for storage devices (v1)
This change adds initial support for storage devices in the OpenDC simulator. Currently, we focus on local disks attached to the machine. In the future, we plan to support networked storage devices using the networking support in OpenDC.
Diffstat (limited to 'opendc-simulator')
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt27
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt5
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimStorageInterface.kt50
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/model/MachineModel.kt6
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/model/StorageDevice.kt40
-rw-r--r--opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt50
6 files changed, 175 insertions, 3 deletions
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt
index 99f9397d..139c66e0 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimAbstractMachine.kt
@@ -30,6 +30,7 @@ import org.opendc.simulator.compute.device.SimPeripheral
import org.opendc.simulator.compute.model.MachineModel
import org.opendc.simulator.compute.model.MemoryUnit
import org.opendc.simulator.compute.model.NetworkAdapter
+import org.opendc.simulator.compute.model.StorageDevice
import org.opendc.simulator.compute.workload.SimWorkload
import org.opendc.simulator.resources.*
import kotlin.coroutines.Continuation
@@ -77,6 +78,11 @@ public abstract class SimAbstractMachine(
protected val net: List<SimNetworkInterface> = model.net.mapIndexed { i, adapter -> NetworkAdapterImpl(adapter, i) }
/**
+ * The network interfaces available to the machine.
+ */
+ protected val storage: List<SimStorageInterface> = model.storage.mapIndexed { i, device -> StorageDeviceImpl(interpreter, device, i) }
+
+ /**
* The peripherals of the machine.
*/
public override val peripherals: List<SimPeripheral> = net.map { it as SimNetworkAdapter }
@@ -181,6 +187,8 @@ public abstract class SimAbstractMachine(
override val net: List<SimNetworkInterface> = this@SimAbstractMachine.net
+ override val storage: List<SimStorageInterface> = this@SimAbstractMachine.storage
+
override fun close() = cancel()
}
@@ -217,4 +225,23 @@ public abstract class SimAbstractMachine(
override fun toString(): String = "SimAbstractMachine.NetworkAdapterImpl[name=$name,bandwidth=$bandwidth]"
}
+
+ /**
+ * The [SimStorageInterface] implementation for a machine.
+ */
+ private class StorageDeviceImpl(
+ interpreter: SimResourceInterpreter,
+ model: StorageDevice,
+ index: Int
+ ) : SimStorageInterface {
+ override val name: String = "disk$index"
+
+ override val capacity: Double = model.capacity
+
+ override val read: SimResourceProvider = SimResourceSource(model.readBandwidth, interpreter)
+
+ override val write: SimResourceProvider = SimResourceSource(model.writeBandwidth, interpreter)
+
+ override fun toString(): String = "SimAbstractMachine.StorageDeviceImpl[name=$name,capacity=$capacity]"
+ }
}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt
index 68a7fb63..6996a30d 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimMachineContext.kt
@@ -56,6 +56,11 @@ public interface SimMachineContext : AutoCloseable {
public val net: List<SimNetworkInterface>
/**
+ * The storage devices available to the workload.
+ */
+ public val storage: List<SimStorageInterface>
+
+ /**
* Stop the workload.
*/
public override fun close()
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimStorageInterface.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimStorageInterface.kt
new file mode 100644
index 00000000..21a801f1
--- /dev/null
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/SimStorageInterface.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2021 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.opendc.simulator.compute
+
+import org.opendc.simulator.resources.SimResourceProvider
+
+/**
+ * A firmware interface to a storage device.
+ */
+public interface SimStorageInterface {
+ /**
+ * The name of the storage device.
+ */
+ public val name: String
+
+ /**
+ * The capacity of the storage device in MBs.
+ */
+ public val capacity: Double
+
+ /**
+ * The resource provider for the read operations of the storage device.
+ */
+ public val read: SimResourceProvider
+
+ /**
+ * The resource consumer for the write operation of the storage device.
+ */
+ public val write: SimResourceProvider
+}
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/model/MachineModel.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/model/MachineModel.kt
index d40aff53..7e4d7191 100644
--- a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/model/MachineModel.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/model/MachineModel.kt
@@ -27,10 +27,12 @@ package org.opendc.simulator.compute.model
*
* @property cpus The list of processing units available to the image.
* @property memory The list of memory units available to the image.
- * @property net A list of network adapters available for the machine.
+ * @property net A list of network adapters available to the machine.
+ * @property storage A list of storage devices available to the machine.
*/
public data class MachineModel(
public val cpus: List<ProcessingUnit>,
public val memory: List<MemoryUnit>,
- public val net: List<NetworkAdapter> = emptyList()
+ public val net: List<NetworkAdapter> = emptyList(),
+ public val storage: List<StorageDevice> = emptyList()
)
diff --git a/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/model/StorageDevice.kt b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/model/StorageDevice.kt
new file mode 100644
index 00000000..2621ad6d
--- /dev/null
+++ b/opendc-simulator/opendc-simulator-compute/src/main/kotlin/org/opendc/simulator/compute/model/StorageDevice.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2021 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package org.opendc.simulator.compute.model
+
+/**
+ * Model for a physical storage device attached to a machine.
+ *
+ * @property vendor The vendor of the storage device.
+ * @property modelName The model name of the device.
+ * @property capacity The capacity of the device.
+ * @property readBandwidth The read bandwidth of the device in MBps.
+ * @property writeBandwidth The write bandwidth of the device in MBps.
+ */
+public data class StorageDevice(
+ public val vendor: String,
+ public val modelName: String,
+ public val capacity: Double,
+ public val readBandwidth: Double,
+ public val writeBandwidth: Double
+)
diff --git a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt
index 47ae119c..892d5223 100644
--- a/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt
+++ b/opendc-simulator/opendc-simulator-compute/src/test/kotlin/org/opendc/simulator/compute/SimMachineTest.kt
@@ -58,7 +58,8 @@ class SimMachineTest {
machineModel = MachineModel(
cpus = List(cpuNode.coreCount) { ProcessingUnit(cpuNode, it, 1000.0) },
memory = List(4) { MemoryUnit("Crucial", "MTA18ASF4G72AZ-3G2B1", 3200.0, 32_000) },
- net = listOf(NetworkAdapter("Mellanox", "ConnectX-5", 25000.0))
+ net = listOf(NetworkAdapter("Mellanox", "ConnectX-5", 25000.0)),
+ storage = listOf(StorageDevice("Samsung", "EVO", 1000.0, 250.0, 250.0))
)
}
@@ -260,6 +261,53 @@ class SimMachineTest {
}
@Test
+ fun testDiskReadUsage() = runBlockingSimulation {
+ val interpreter = SimResourceInterpreter(coroutineContext, clock)
+ val machine = SimBareMetalMachine(
+ interpreter,
+ machineModel,
+ SimplePowerDriver(ConstantPowerModel(0.0))
+ )
+
+ try {
+ machine.run(object : SimWorkload {
+ override fun onStart(ctx: SimMachineContext) {
+ val lifecycle = SimWorkloadLifecycle(ctx)
+ val disk = ctx.storage[0]
+ disk.read.startConsumer(lifecycle.waitFor(SimWorkConsumer(disk.read.capacity, utilization = 0.8)))
+ }
+ })
+
+ assertEquals(1250, clock.millis())
+ } finally {
+ machine.close()
+ }
+ }
+
+ fun testDiskWriteUsage() = runBlockingSimulation {
+ val interpreter = SimResourceInterpreter(coroutineContext, clock)
+ val machine = SimBareMetalMachine(
+ interpreter,
+ machineModel,
+ SimplePowerDriver(ConstantPowerModel(0.0))
+ )
+
+ try {
+ machine.run(object : SimWorkload {
+ override fun onStart(ctx: SimMachineContext) {
+ val lifecycle = SimWorkloadLifecycle(ctx)
+ val disk = ctx.storage[0]
+ disk.write.startConsumer(lifecycle.waitFor(SimWorkConsumer(disk.write.capacity, utilization = 0.8)))
+ }
+ })
+
+ assertEquals(1250, clock.millis())
+ } finally {
+ machine.close()
+ }
+ }
+
+ @Test
fun testCancellation() = runBlockingSimulation {
val machine = SimBareMetalMachine(
SimResourceInterpreter(coroutineContext, clock),