Skip to content

Commit c47a81b

Browse files
committed
make VM cpu and memory configurable
Signed-off-by: Amory Hoste <[email protected]>
1 parent 7687152 commit c47a81b

File tree

10 files changed

+92
-28
lines changed

10 files changed

+92
-28
lines changed

cri/firecracker/coordinator.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,13 @@ func (c *coordinator) setIdleInstance(fi *funcInstance) {
9898
c.idleInstances[fi.Image] = append(c.idleInstances[fi.Image], fi)
9999
}
100100

101-
func (c *coordinator) startVM(ctx context.Context, image string) (*funcInstance, error) {
101+
func (c *coordinator) startVM(ctx context.Context, image string, memSizeMib, vCPUCount uint32) (*funcInstance, error) {
102102
if fi := c.getIdleInstance(image); c.orch != nil && c.orch.GetSnapshotsEnabled() && fi != nil {
103103
err := c.orchLoadInstance(ctx, fi)
104104
return fi, err
105105
}
106106

107-
return c.orchStartVM(ctx, image)
107+
return c.orchStartVM(ctx, image, memSizeMib, vCPUCount)
108108
}
109109

110110
func (c *coordinator) stopVM(ctx context.Context, containerID string) error {
@@ -150,7 +150,7 @@ func (c *coordinator) insertActive(containerID string, fi *funcInstance) error {
150150
return nil
151151
}
152152

153-
func (c *coordinator) orchStartVM(ctx context.Context, image string) (*funcInstance, error) {
153+
func (c *coordinator) orchStartVM(ctx context.Context, image string, memSizeMib, vCPUCount uint32) (*funcInstance, error) {
154154
vmID := strconv.Itoa(int(atomic.AddUint64(&c.nextID, 1)))
155155
logger := log.WithFields(
156156
log.Fields{
@@ -170,7 +170,7 @@ func (c *coordinator) orchStartVM(ctx context.Context, image string) (*funcInsta
170170
defer cancel()
171171

172172
if !c.withoutOrchestrator {
173-
resp, _, err = c.orch.StartVM(ctxTimeout, vmID, image)
173+
resp, _, err = c.orch.StartVM(ctxTimeout, vmID, image, memSizeMib, vCPUCount)
174174
if err != nil {
175175
logger.WithError(err).Error("coordinator failed to start VM")
176176
}

cri/firecracker/coordinator_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func TestMain(m *testing.M) {
4545

4646
func TestStartStop(t *testing.T) {
4747
containerID := "1"
48-
fi, err := coord.startVM(context.Background(), containerID)
48+
fi, err := coord.startVM(context.Background(), containerID, 0, 0)
4949
require.NoError(t, err, "could not start VM")
5050

5151
err = coord.insertActive(containerID, fi)
@@ -72,7 +72,7 @@ func TestParallelStartStop(t *testing.T) {
7272
defer wg.Done()
7373

7474
containerID := strconv.Itoa(i)
75-
fi, err := coord.startVM(context.Background(), containerID)
75+
fi, err := coord.startVM(context.Background(), containerID, 0, 0)
7676
require.NoError(t, err, "could not start VM")
7777

7878
err = coord.insertActive(containerID, fi)

cri/firecracker/service.go

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ package firecracker
2525
import (
2626
"context"
2727
"errors"
28+
"strconv"
2829
"sync"
2930

3031
"github.com/ease-lab/vhive/cri"
@@ -34,11 +35,13 @@ import (
3435
)
3536

3637
const (
37-
userContainerName = "user-container"
38-
queueProxyName = "queue-proxy"
39-
guestIPEnv = "GUEST_ADDR"
40-
guestPortEnv = "GUEST_PORT"
41-
guestImageEnv = "GUEST_IMAGE"
38+
userContainerName = "user-container"
39+
queueProxyName = "queue-proxy"
40+
guestIPEnv = "GUEST_ADDR"
41+
guestPortEnv = "GUEST_PORT"
42+
guestImageEnv = "GUEST_IMAGE"
43+
guestMemorySizeMibEnv = "MEM_SIZE_MB"
44+
guestvCPUCount = "VCPU_COUNT"
4245
)
4346

4447
type FirecrackerService struct {
@@ -110,7 +113,19 @@ func (fs *FirecrackerService) createUserContainer(ctx context.Context, r *criapi
110113
return nil, err
111114
}
112115

113-
funcInst, err := fs.coordinator.startVM(context.Background(), guestImage)
116+
memSizeMib, err := getMemorySize(config)
117+
if err != nil {
118+
log.WithError(err).Error()
119+
return nil, err
120+
}
121+
122+
vCPUCount, err := getvCPUCount(config)
123+
if err != nil {
124+
log.WithError(err).Error()
125+
return nil, err
126+
}
127+
128+
funcInst, err := fs.coordinator.startVM(context.Background(), guestImage, memSizeMib, vCPUCount)
114129
if err != nil {
115130
log.WithError(err).Error("failed to start VM")
116131
return nil, err
@@ -215,6 +230,39 @@ func getEnvVal(key string, config *criapi.ContainerConfig) (string, error) {
215230

216231
}
217232

218-
return "", errors.New("failed to provide non empty guest image in user container config")
233+
return "", errors.New("failed to retrieve environment variable from user container config")
234+
}
235+
236+
func getMemorySize(config *criapi.ContainerConfig) (uint32, error) {
237+
envs := config.GetEnvs()
238+
for _, kv := range envs {
239+
if kv.GetKey() == guestMemorySizeMibEnv {
240+
memSize, err := strconv.Atoi(kv.GetValue())
241+
if err == nil {
242+
return uint32(memSize), nil
243+
} else {
244+
return 0, err
245+
}
246+
}
219247

248+
}
249+
250+
return uint32(256), nil
220251
}
252+
253+
func getvCPUCount(config *criapi.ContainerConfig) (uint32, error) {
254+
envs := config.GetEnvs()
255+
for _, kv := range envs {
256+
if kv.GetKey() == guestvCPUCount {
257+
vCPUCount, err := strconv.Atoi(kv.GetValue())
258+
if err == nil {
259+
return uint32(vCPUCount), nil
260+
} else {
261+
return 0, err
262+
}
263+
}
264+
265+
}
266+
267+
return uint32(1), nil
268+
}

ctriface/bench_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func TestBenchmarkStart(t *testing.T) {
7575
for i := 0; i < benchCount; i++ {
7676
dropPageCache()
7777

78-
_, metric, err := orch.StartVM(ctx, vmIDString, imageName)
78+
_, metric, err := orch.StartVM(ctx, vmIDString, imageName, 0, 0)
7979
require.NoError(t, err, "Failed to start VM")
8080
startMetrics[i] = metric
8181

ctriface/failing_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func TestStartSnapStop(t *testing.T) {
5555

5656
vmID := "2"
5757

58-
_, _, err := orch.StartVM(ctx, vmID, testImageName)
58+
_, _, err := orch.StartVM(ctx, vmID, testImageName, 0, 0)
5959
require.NoError(t, err, "Failed to start VM")
6060

6161
err = orch.PauseVM(ctx, vmID)

ctriface/iface.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,12 @@ type StartVMResponse struct {
6161

6262
const (
6363
testImageName = "ghcr.io/ease-lab/helloworld:var_workload"
64+
defaultVcpuCount = 1
65+
defaultMemsizeMib = 256
6466
)
6567

6668
// StartVM Boots a VM if it does not exist
67-
func (o *Orchestrator) StartVM(ctx context.Context, vmID, imageName string) (_ *StartVMResponse, _ *metrics.Metric, retErr error) {
69+
func (o *Orchestrator) StartVM(ctx context.Context, vmID, imageName string, memSizeMib ,vCPUCount uint32) (_ *StartVMResponse, _ *metrics.Metric, retErr error) {
6870
var (
6971
startVMMetric *metrics.Metric = metrics.NewMetric()
7072
tStart time.Time
@@ -79,6 +81,18 @@ func (o *Orchestrator) StartVM(ctx context.Context, vmID, imageName string) (_ *
7981
return nil, nil, err
8082
}
8183

84+
// Set VM vCPU and Memory
85+
if memSizeMib != 0 {
86+
vm.MemSizeMib = memSizeMib
87+
} else {
88+
vm.MemSizeMib = defaultMemsizeMib
89+
}
90+
if vCPUCount != 0 {
91+
vm.VCPUCount = vCPUCount
92+
} else {
93+
vm.VCPUCount = defaultVcpuCount
94+
}
95+
8296
defer func() {
8397
// Free the VM from the pool if function returns error
8498
if retErr != nil {
@@ -300,8 +314,8 @@ func (o *Orchestrator) getVMConfig(vm *misc.VM) *proto.CreateVMRequest {
300314
TimeoutSeconds: 100,
301315
KernelArgs: kernelArgs,
302316
MachineCfg: &proto.FirecrackerMachineConfiguration{
303-
VcpuCount: 1,
304-
MemSizeMib: 256,
317+
VcpuCount: vm.VCPUCount,
318+
MemSizeMib: vm.MemSizeMib,
305319
},
306320
NetworkInterfaces: []*proto.FirecrackerNetworkInterface{{
307321
StaticConfig: &proto.StaticNetworkConfiguration{

ctriface/iface_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func TestPauseSnapResume(t *testing.T) {
6969

7070
vmID := "4"
7171

72-
_, _, err := orch.StartVM(ctx, vmID, testImageName)
72+
_, _, err := orch.StartVM(ctx, vmID, testImageName, 0, 0)
7373
require.NoError(t, err, "Failed to start VM")
7474

7575
err = orch.PauseVM(ctx, vmID)
@@ -112,7 +112,7 @@ func TestStartStopSerial(t *testing.T) {
112112

113113
vmID := "5"
114114

115-
_, _, err := orch.StartVM(ctx, vmID, testImageName)
115+
_, _, err := orch.StartVM(ctx, vmID, testImageName, 0, 0)
116116
require.NoError(t, err, "Failed to start VM")
117117

118118
err = orch.StopSingleVM(ctx, vmID)
@@ -146,7 +146,7 @@ func TestPauseResumeSerial(t *testing.T) {
146146

147147
vmID := "6"
148148

149-
_, _, err := orch.StartVM(ctx, vmID, testImageName)
149+
_, _, err := orch.StartVM(ctx, vmID, testImageName, 0, 0)
150150
require.NoError(t, err, "Failed to start VM")
151151

152152
err = orch.PauseVM(ctx, vmID)
@@ -196,7 +196,7 @@ func TestStartStopParallel(t *testing.T) {
196196
go func(i int) {
197197
defer vmGroup.Done()
198198
vmID := fmt.Sprintf("%d", i)
199-
_, _, err := orch.StartVM(ctx, vmID, testImageName)
199+
_, _, err := orch.StartVM(ctx, vmID, testImageName, 0, 0)
200200
require.NoError(t, err, "Failed to start VM "+vmID)
201201
}(i)
202202
}
@@ -255,7 +255,7 @@ func TestPauseResumeParallel(t *testing.T) {
255255
go func(i int) {
256256
defer vmGroup.Done()
257257
vmID := fmt.Sprintf("%d", i)
258-
_, _, err := orch.StartVM(ctx, vmID, testImageName)
258+
_, _, err := orch.StartVM(ctx, vmID, testImageName, 0, 0)
259259
require.NoError(t, err, "Failed to start VM")
260260
}(i)
261261
}

ctriface/manual_cleanup_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func TestSnapLoad(t *testing.T) {
6363

6464
vmID := "1"
6565

66-
_, _, err := orch.StartVM(ctx, vmID, testImageName)
66+
_, _, err := orch.StartVM(ctx, vmID, testImageName, 0, 0)
6767
require.NoError(t, err, "Failed to start VM")
6868

6969
err = orch.PauseVM(ctx, vmID)
@@ -113,7 +113,7 @@ func TestSnapLoadMultiple(t *testing.T) {
113113

114114
vmID := "3"
115115

116-
_, _, err := orch.StartVM(ctx, vmID, testImageName)
116+
_, _, err := orch.StartVM(ctx, vmID, testImageName, 0, 0)
117117
require.NoError(t, err, "Failed to start VM")
118118

119119
err = orch.PauseVM(ctx, vmID)
@@ -184,7 +184,7 @@ func TestParallelSnapLoad(t *testing.T) {
184184
defer vmGroup.Done()
185185
vmID := fmt.Sprintf("%d", i+vmIDBase)
186186

187-
_, _, err := orch.StartVM(ctx, vmID, testImageName)
187+
_, _, err := orch.StartVM(ctx, vmID, testImageName, 0, 0)
188188
require.NoError(t, err, "Failed to start VM, "+vmID)
189189

190190
err = orch.PauseVM(ctx, vmID)
@@ -246,7 +246,7 @@ func TestParallelPhasedSnapLoad(t *testing.T) {
246246
go func(i int) {
247247
defer vmGroup.Done()
248248
vmID := fmt.Sprintf("%d", i+vmIDBase)
249-
_, _, err := orch.StartVM(ctx, vmID, testImageName)
249+
_, _, err := orch.StartVM(ctx, vmID, testImageName, 0, 0)
250250
require.NoError(t, err, "Failed to start VM, "+vmID)
251251
}(i)
252252
}

functions.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ func (f *Function) AddInstance() *metrics.Metric {
356356
if f.isSnapshotReady {
357357
metr = f.LoadInstance()
358358
} else {
359-
resp, _, err := orch.StartVM(ctx, f.getVMID(), f.imageName)
359+
resp, _, err := orch.StartVM(ctx, f.getVMID(), f.imageName, 0, 0)
360360
if err != nil {
361361
log.Panic(err)
362362
}

misc/types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ type VM struct {
4040
TaskCh <-chan containerd.ExitStatus
4141
Ni *taps.NetworkInterface
4242
NetConfig *networking.NetworkConfig
43+
VCPUCount uint32
44+
MemSizeMib uint32
4345
}
4446

4547
// VMPool Pool of active VMs (can be in several states though)

0 commit comments

Comments
 (0)