Skip to content

Commit 27e693c

Browse files
committed
add separate option for new snapshots
Signed-off-by: Amory Hoste <[email protected]>
1 parent 974e3c5 commit 27e693c

33 files changed

+1951
-615
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:e290046f2e24c117ef450a3bef6c8f8e3b1ec387decc76ccc936e1f54c827327
3-
size 26355405
2+
oid sha256:5b48fcdff74c342e8b4f65659139056dea1c27fdb99a0c2f267070b6b3b97b0b
3+
size 26530283

bin/firecracker

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:561cff75b2e1d768d2a4e7dad01cffb3eaff194e1b1696ad3ede5284c404fb0c
3-
size 4010736
2+
oid sha256:d42ddb2c3d970d6a234e0d3f92980e085fc04a9ae17e29e05bb4ca73debfe0b8
3+
size 4016240

bin/firecracker-containerd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:89c20c096978dafa7f3ba3b1d66a9e574f2fd89f3781ee0537da30120aea6455
3-
size 46999272
2+
oid sha256:cc908873170a25ca713ca2e80323cf1496d5d9b7a3449778d0018a84825dd0f7
3+
size 47224352

bin/firecracker-ctr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:1b0bab69371a224e9eaed86edb26dd57e2a0b04eaa7e9b4da7e3e8c7c38e0016
3-
size 34476496
2+
oid sha256:51a994f7cb2cd48087a4b5a27476577c60d9fd6ce34a470435de5f33c2fb3508
3+
size 34510472

bin/jailer

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:375abd369c55ad8057ec6cd39ee77e8f68933fd7a97e1d1901881805f22815f8
3-
size 3060760
2+
oid sha256:80284269eb8b44483b84a527bf7f4012932d94410e32bd20e4d25d09303336ea
3+
size 3072784

cri/firecracker/coordinator.go

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,30 @@ package firecracker
2525
import (
2626
"context"
2727
"fmt"
28+
"github.com/ease-lab/vhive/ctriface"
2829
"github.com/ease-lab/vhive/metrics"
2930
"github.com/ease-lab/vhive/snapshotting"
31+
"github.com/ease-lab/vhive/snapshotting/deduplicated"
32+
"github.com/ease-lab/vhive/snapshotting/regular"
3033
"github.com/pkg/errors"
3134
"strconv"
3235
"sync"
3336
"sync/atomic"
3437
"time"
3538

36-
"github.com/ease-lab/vhive/ctriface"
3739
log "github.com/sirupsen/logrus"
3840
)
3941

4042
const snapshotsDir = "/fccd/snapshots"
4143

44+
// TODO: interface for orchestrator
45+
4246
type coordinator struct {
4347
sync.Mutex
4448
orch *ctriface.Orchestrator
4549
nextID uint64
4650
isSparseSnaps bool
51+
isDeduplicatedSnaps bool
4752

4853
activeInstances map[string]*FuncInstance
4954
snapshotManager *snapshotting.SnapshotManager
@@ -59,12 +64,18 @@ func withoutOrchestrator() coordinatorOption {
5964
}
6065
}
6166

62-
func newFirecrackerCoordinator(orch *ctriface.Orchestrator, snapsCapacityMiB int64, isSparseSnaps bool, opts ...coordinatorOption) *coordinator {
67+
func newFirecrackerCoordinator(orch *ctriface.Orchestrator, snapsCapacityMiB int64, isSparseSnaps bool, isDeduplicatedSnaps bool, opts ...coordinatorOption) *coordinator {
6368
c := &coordinator{
6469
activeInstances: make(map[string]*FuncInstance),
6570
orch: orch,
66-
snapshotManager: snapshotting.NewSnapshotManager(snapshotsDir, snapsCapacityMiB),
67-
isSparseSnaps: isSparseSnaps,
71+
isSparseSnaps: isSparseSnaps,
72+
isDeduplicatedSnaps: isDeduplicatedSnaps,
73+
}
74+
75+
if isDeduplicatedSnaps {
76+
c.snapshotManager = snapshotting.NewSnapshotManager(deduplicated.NewSnapshotManager(snapshotsDir, snapsCapacityMiB))
77+
} else {
78+
c.snapshotManager = snapshotting.NewSnapshotManager(regular.NewRegularSnapshotManager(snapshotsDir))
6879
}
6980

7081
for _, opt := range opts {
@@ -76,12 +87,24 @@ func newFirecrackerCoordinator(orch *ctriface.Orchestrator, snapsCapacityMiB int
7687

7788
func (c *coordinator) startVM(ctx context.Context, image string, revision string, memSizeMib, vCPUCount uint32) (*FuncInstance, error) {
7889
if c.orch != nil && c.orch.GetSnapshotsEnabled() {
90+
id := image
91+
if c.isDeduplicatedSnaps {
92+
id = revision
93+
}
94+
7995
// Check if snapshot is available
80-
if snap, err := c.snapshotManager.AcquireSnapshot(revision); err == nil {
96+
if snap, err := c.snapshotManager.AcquireSnapshot(id); err == nil {
8197
if snap.MemSizeMib != memSizeMib || snap.VCPUCount != vCPUCount {
8298
return nil, errors.New("Please create a new revision when updating uVM memory size or vCPU count")
8399
} else {
84-
return c.orchStartVMSnapshot(ctx, snap, memSizeMib, vCPUCount)
100+
vmID := ""
101+
if c.isDeduplicatedSnaps {
102+
vmID = strconv.Itoa(int(atomic.AddUint64(&c.nextID, 1)))
103+
} else {
104+
vmID = snap.GetId()
105+
}
106+
107+
return c.orchStartVMSnapshot(ctx, snap, memSizeMib, vCPUCount, vmID)
85108
}
86109
} else {
87110
return c.orchStartVM(ctx, image, revision, memSizeMib, vCPUCount)
@@ -106,17 +129,30 @@ func (c *coordinator) stopVM(ctx context.Context, containerID string) error {
106129
return nil
107130
}
108131

132+
if c.orch == nil || ! c.orch.GetSnapshotsEnabled() {
133+
return c.orchStopVM(ctx, fi)
134+
}
135+
136+
id := fi.vmID
137+
if c.isDeduplicatedSnaps {
138+
id = fi.revisionId
139+
}
140+
109141
if fi.snapBooted {
110-
defer c.snapshotManager.ReleaseSnapshot(fi.revisionId)
111-
} else if c.orch != nil && c.orch.GetSnapshotsEnabled() {
142+
defer c.snapshotManager.ReleaseSnapshot(id)
143+
} else {
112144
// Create snapshot
113145
err := c.orchCreateSnapshot(ctx, fi)
114146
if err != nil {
115147
log.Printf("Err creating snapshot %s\n", err)
116148
}
117149
}
118150

119-
return c.orchStopVM(ctx, fi)
151+
if c.isDeduplicatedSnaps {
152+
return c.orchStopVM(ctx, fi)
153+
} else {
154+
return c.orchOffloadVM(ctx, fi)
155+
}
120156
}
121157

122158
// for testing
@@ -178,9 +214,8 @@ func (c *coordinator) orchStartVM(ctx context.Context, image, revision string, m
178214
return fi, err
179215
}
180216

181-
func (c *coordinator) orchStartVMSnapshot(ctx context.Context, snap *snapshotting.Snapshot, memSizeMib, vCPUCount uint32) (*FuncInstance, error) {
217+
func (c *coordinator) orchStartVMSnapshot(ctx context.Context, snap *snapshotting.Snapshot, memSizeMib, vCPUCount uint32, vmID string) (*FuncInstance, error) {
182218
tStartCold := time.Now()
183-
vmID := strconv.Itoa(int(atomic.AddUint64(&c.nextID, 1)))
184219
logger := log.WithFields(
185220
log.Fields{
186221
"vmID": vmID,
@@ -210,7 +245,7 @@ func (c *coordinator) orchStartVMSnapshot(ctx context.Context, snap *snapshottin
210245
}
211246

212247
coldStartTimeMs := metrics.ToMs(time.Since(tStartCold))
213-
fi := NewFuncInstance(vmID, snap.GetImage(), snap.GetRevisionId(), resp, true, memSizeMib, vCPUCount, coldStartTimeMs)
248+
fi := NewFuncInstance(vmID, snap.GetImage(), snap.GetId(), resp, true, memSizeMib, vCPUCount, coldStartTimeMs)
214249
logger.Debug("successfully loaded instance from snapshot")
215250

216251
return fi, err
@@ -224,17 +259,23 @@ func (c *coordinator) orchCreateSnapshot(ctx context.Context, fi *FuncInstance)
224259
},
225260
)
226261

227-
removeContainerSnaps, snap, err := c.snapshotManager.InitSnapshot(fi.revisionId, fi.image, fi.coldStartTimeMs, fi.memSizeMib, fi.vCPUCount, c.isSparseSnaps)
262+
id := fi.vmID
263+
if c.isDeduplicatedSnaps {
264+
id = fi.revisionId
265+
}
266+
267+
removeContainerSnaps, snap, err := c.snapshotManager.InitSnapshot(id, fi.image, fi.coldStartTimeMs, fi.memSizeMib, fi.vCPUCount, c.isSparseSnaps)
268+
228269
if err != nil {
229270
if fmt.Sprint(err) == "There is not enough free space available" {
230271
fi.logger.Info(fmt.Sprintf("There is not enough space available for snapshots of %s", fi.revisionId))
231272
}
232273
return nil
233274
}
234275

235-
if removeContainerSnaps != nil {
276+
if c.isDeduplicatedSnaps && removeContainerSnaps != nil {
236277
for _, cleanupSnapId := range *removeContainerSnaps {
237-
if err := c.orch.CleanupRevisionSnapshot(ctx, cleanupSnapId); err != nil {
278+
if err := c.orch.CleanupSnapshot(ctx, cleanupSnapId); err != nil {
238279
return errors.Wrap(err, "removing devmapper revision snapshot")
239280
}
240281
}
@@ -257,7 +298,7 @@ func (c *coordinator) orchCreateSnapshot(ctx context.Context, fi *FuncInstance)
257298
return nil
258299
}
259300

260-
if err := c.snapshotManager.CommitSnapshot(fi.revisionId); err != nil {
301+
if err := c.snapshotManager.CommitSnapshot(id); err != nil {
261302
fi.logger.WithError(err).Error("failed to commit snapshot")
262303
return err
263304
}
@@ -277,3 +318,16 @@ func (c *coordinator) orchStopVM(ctx context.Context, fi *FuncInstance) error {
277318

278319
return nil
279320
}
321+
322+
func (c *coordinator) orchOffloadVM(ctx context.Context, fi *FuncInstance) error {
323+
if c.withoutOrchestrator {
324+
return nil
325+
}
326+
327+
if err := c.orch.OffloadVM(ctx, fi.vmID); err != nil {
328+
fi.logger.WithError(err).Error("failed to offload VM")
329+
return err
330+
}
331+
332+
return nil
333+
}

cri/firecracker/coordinator_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ var (
4242
)
4343

4444
func TestMain(m *testing.M) {
45-
coord = newFirecrackerCoordinator(nil, 10240, false, withoutOrchestrator())
45+
coord = newFirecrackerCoordinator(nil, 10240, false, false, withoutOrchestrator())
4646

4747
ret := m.Run()
4848
os.Exit(ret)

cri/firecracker/service.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ package firecracker
2525
import (
2626
"context"
2727
"errors"
28+
"github.com/ease-lab/vhive/ctriface"
2829
"strconv"
2930
"sync"
3031

3132
"github.com/ease-lab/vhive/cri"
32-
"github.com/ease-lab/vhive/ctriface"
3333
log "github.com/sirupsen/logrus"
3434
criapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
3535
)
@@ -61,15 +61,15 @@ type VMConfig struct {
6161
guestPort string
6262
}
6363

64-
func NewFirecrackerService(orch *ctriface.Orchestrator, snapsCapacityMiB int64, isSparseSnaps bool) (*FirecrackerService, error) {
64+
func NewFirecrackerService(orch *ctriface.Orchestrator, snapsCapacityMiB int64, isSparseSnaps, isDeduplicatedSnaps bool) (*FirecrackerService, error) {
6565
fs := new(FirecrackerService)
6666
stockRuntimeClient, err := cri.NewStockRuntimeServiceClient()
6767
if err != nil {
6868
log.WithError(err).Error("failed to create new stock runtime service client")
6969
return nil, err
7070
}
7171
fs.stockRuntimeClient = stockRuntimeClient
72-
fs.coordinator = newFirecrackerCoordinator(orch, snapsCapacityMiB, isSparseSnaps)
72+
fs.coordinator = newFirecrackerCoordinator(orch, snapsCapacityMiB, isSparseSnaps, isDeduplicatedSnaps)
7373
fs.vmConfigs = make(map[string]*VMConfig)
7474
return fs, nil
7575
}

ctriface/bench_test.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ package ctriface
2424

2525
import (
2626
"context"
27+
"github.com/ease-lab/vhive/ctriface/regular"
2728
"os"
2829
"os/exec"
2930
"path/filepath"
@@ -43,6 +44,22 @@ const (
4344
)
4445

4546
func TestBenchmarkStart(t *testing.T) {
47+
orch := NewOrchestrator(regular.NewRegOrchestrator(
48+
"devmapper",
49+
"",
50+
"fc-dev-thinpool",
51+
"",
52+
10,
53+
regular.WithTestModeOn(true),
54+
regular.WithUPF(*isUPFEnabled),
55+
))
56+
57+
benchCount := 10
58+
vmID := 0
59+
benchmarkStart(t, orch, benchCount, vmID)
60+
}
61+
62+
func benchmarkStart(t *testing.T, orch *Orchestrator, benchCount, vmID int) {
4663
log.SetFormatter(&log.TextFormatter{
4764
TimestampFormat: ctrdlog.RFC3339NanoFixed,
4865
FullTimestamp: true,
@@ -53,14 +70,10 @@ func TestBenchmarkStart(t *testing.T) {
5370
log.SetLevel(log.InfoLevel)
5471

5572
testTimeout := 2000 * time.Second
56-
ctx, cancel := context.WithTimeout(namespaces.WithNamespace(context.Background(), namespaceName), testTimeout)
73+
ctx, cancel := context.WithTimeout(namespaces.WithNamespace(context.Background(), regular.NamespaceName), testTimeout)
5774
defer cancel()
5875

59-
orch := NewOrchestrator("devmapper", "", "fc-dev-thinpool","",10, WithTestModeOn(true), WithUPF(*isUPFEnabled))
60-
6176
images := getAllImages()
62-
benchCount := 10
63-
vmID := 0
6477

6578
createResultsDir()
6679

@@ -69,7 +82,7 @@ func TestBenchmarkStart(t *testing.T) {
6982
startMetrics := make([]*metrics.Metric, benchCount)
7083

7184
// Pull image
72-
_, err := orch.imageManager.GetImage(ctx, imageName)
85+
_, err := orch.GetImage(ctx, imageName)
7386
require.NoError(t, err, "Failed to pull image "+imageName)
7487

7588
for i := 0; i < benchCount; i++ {

0 commit comments

Comments
 (0)