diff --git a/cri/firecracker/coordinator.go b/cri/firecracker/coordinator.go index ff7879103..ec7ab2e1b 100644 --- a/cri/firecracker/coordinator.go +++ b/cri/firecracker/coordinator.go @@ -26,13 +26,14 @@ import ( "context" "errors" "fmt" - "github.com/google/uuid" - "github.com/vhive-serverless/vhive/snapshotting" "strconv" "sync" "sync/atomic" "time" + "github.com/google/uuid" + "github.com/vhive-serverless/vhive/snapshotting" + log "github.com/sirupsen/logrus" "github.com/vhive-serverless/vhive/ctriface" ) @@ -181,7 +182,6 @@ func (c *coordinator) orchLoadInstance(ctx context.Context, snap *snapshotting.S ctxTimeout, cancel := context.WithTimeout(ctx, time.Second*30) defer cancel() - logger.Debug("FIXME: temp pass same lastVmID") resp, _, err := c.orch.LoadSnapshot(ctxTimeout, vmID, vmID, snap) if err != nil { logger.WithError(err).Error("failed to load VM") diff --git a/ctriface/Makefile b/ctriface/Makefile index 6d2811be7..7b57901f1 100644 --- a/ctriface/Makefile +++ b/ctriface/Makefile @@ -28,6 +28,12 @@ WITHLAZY:=-lazy GOBENCH:=-v -timeout 1500s CTRDLOGDIR:=/tmp/ctrd-logs +debug: + ./../scripts/clean_fcctr.sh + sudo mkdir -m777 -p $(CTRDLOGDIR) && sudo env "PATH=$(PATH)" /usr/local/bin/firecracker-containerd --config /etc/firecracker-containerd/config.toml 1>$(CTRDLOGDIR)/ctriface_log.out 2>$(CTRDLOGDIR)/ctriface_log.err & + sudo env "PATH=$(PATH)" go test $(EXTRATESTFILES) $(EXTRAGOARGS) -args $(WITHUPF) + ./../scripts/clean_fcctr.sh + test: ./../scripts/clean_fcctr.sh sudo mkdir -m777 -p $(CTRDLOGDIR) && sudo env "PATH=$(PATH)" /usr/local/bin/firecracker-containerd --config /etc/firecracker-containerd/config.toml 1>$(CTRDLOGDIR)/ctriface_log.out 2>$(CTRDLOGDIR)/ctriface_log.err & diff --git a/ctriface/failing_test.go b/ctriface/failing_test.go index d753c5df6..36cb30a61 100644 --- a/ctriface/failing_test.go +++ b/ctriface/failing_test.go @@ -22,62 +22,49 @@ package ctriface -import ( - "context" - "os" - "testing" - "time" +// func TestStartSnapStop(t *testing.T) { +// // BROKEN BECAUSE StopVM does not work yet. +// // t.Skip("skipping failing test") +// log.SetFormatter(&log.TextFormatter{ +// TimestampFormat: ctrdlog.RFC3339NanoFixed, +// FullTimestamp: true, +// }) +// //log.SetReportCaller(true) // FIXME: make sure it's false unless debugging - ctrdlog "github.com/containerd/containerd/log" - "github.com/containerd/containerd/namespaces" - log "github.com/sirupsen/logrus" - "github.com/stretchr/testify/require" - "github.com/vhive-serverless/vhive/snapshotting" -) +// log.SetOutput(os.Stdout) -func TestStartSnapStop(t *testing.T) { - // BROKEN BECAUSE StopVM does not work yet. - t.Skip("skipping failing test") - log.SetFormatter(&log.TextFormatter{ - TimestampFormat: ctrdlog.RFC3339NanoFixed, - FullTimestamp: true, - }) - //log.SetReportCaller(true) // FIXME: make sure it's false unless debugging +// log.SetLevel(log.DebugLevel) - log.SetOutput(os.Stdout) +// testTimeout := 120 * time.Second +// ctx, cancel := context.WithTimeout(namespaces.WithNamespace(context.Background(), namespaceName), testTimeout) +// defer cancel() - log.SetLevel(log.DebugLevel) +// orch := NewOrchestrator("devmapper", "", WithTestModeOn(true)) - testTimeout := 120 * time.Second - ctx, cancel := context.WithTimeout(namespaces.WithNamespace(context.Background(), namespaceName), testTimeout) - defer cancel() +// vmID := "2" - orch := NewOrchestrator("devmapper", "", WithTestModeOn(true)) +// _, _, err := orch.StartVM(ctx, vmID, testImageName) +// require.NoError(t, err, "Failed to start VM") - vmID := "2" +// err = orch.PauseVM(ctx, vmID) +// require.NoError(t, err, "Failed to pause VM") - _, _, err := orch.StartVM(ctx, vmID, testImageName) - require.NoError(t, err, "Failed to start VM") +// snap := snapshotting.NewSnapshot(vmID, "/fccd/snapshots", testImageName) +// err = orch.CreateSnapshot(ctx, vmID, snap) +// require.NoError(t, err, "Failed to create snapshot of VM") - err = orch.PauseVM(ctx, vmID) - require.NoError(t, err, "Failed to pause VM") +// err = orch.StopSingleVM(ctx, vmID) +// require.NoError(t, err, "Failed to stop VM") - snap := snapshotting.NewSnapshot(vmID, "/fccd/snapshots", testImageName) - err = orch.CreateSnapshot(ctx, vmID, snap) - require.NoError(t, err, "Failed to create snapshot of VM") +// _, _, err = orch.LoadSnapshot(ctx, "1", vmID, snap) +// require.NoError(t, err, "Failed to load snapshot of VM") - err = orch.StopSingleVM(ctx, vmID) - require.NoError(t, err, "Failed to stop VM") +// _, err = orch.ResumeVM(ctx, vmID) +// require.NoError(t, err, "Failed to resume VM") - _, _, err = orch.LoadSnapshot(ctx, "1", vmID, snap) - require.NoError(t, err, "Failed to load snapshot of VM") +// err = orch.StopSingleVM(ctx, vmID) +// require.NoError(t, err, "Failed to stop VM") - _, err = orch.ResumeVM(ctx, vmID) - require.NoError(t, err, "Failed to resume VM") - - err = orch.StopSingleVM(ctx, vmID) - require.NoError(t, err, "Failed to stop VM") - - _ = snap.Cleanup() - orch.Cleanup() -} +// _ = snap.Cleanup() +// orch.Cleanup() +// } diff --git a/ctriface/iface.go b/ctriface/iface.go index e39b0ad0a..ab66698ce 100644 --- a/ctriface/iface.go +++ b/ctriface/iface.go @@ -24,7 +24,6 @@ package ctriface import ( "context" - "github.com/vhive-serverless/vhive/snapshotting" "os" "os/exec" "path/filepath" @@ -33,6 +32,8 @@ import ( "syscall" "time" + "github.com/vhive-serverless/vhive/snapshotting" + log "github.com/sirupsen/logrus" "github.com/containerd/containerd" @@ -106,7 +107,7 @@ func (o *Orchestrator) StartVMWithEnvironment(ctx context.Context, vmID, imageNa tStart = time.Now() conf := o.getVMConfig(vm) - resp, err := o.fcClient.CreateVM(ctx, conf) + _, err = o.fcClient.CreateVM(ctx, conf) startVMMetric.MetricMap[metrics.FcCreateVM] = metrics.ToUS(time.Since(tStart)) if err != nil { return nil, nil, errors.Wrap(err, "failed to create the microVM in firecracker-containerd") @@ -216,11 +217,10 @@ func (o *Orchestrator) StartVMWithEnvironment(ctx context.Context, vmID, imageNa IsLazyMode: o.isLazyMode, VMMStatePath: o.getSnapshotFile(vmID), WorkingSetPath: o.getWorkingSetFile(vmID), - InstanceSockAddr: resp.GetSocketPath(), + InstanceSockAddr: o.uffdSockAddr, } logger.Debugf("TEST: show to-reg snapStat: %+v", stateCfg) - logger.Debugf("TEST: show socket path: %s", resp.GetSocketPath()) - if err := o.memoryManager.RegisterVM(stateCfg, false, ""); err != nil { + if err := o.memoryManager.RegisterVM(stateCfg); err != nil { return nil, nil, errors.Wrap(err, "failed to register VM with memory manager") // NOTE (Plamen): Potentially need a defer(DeregisteVM) here if RegisterVM is not last to execute } @@ -451,7 +451,7 @@ func (o *Orchestrator) CreateSnapshot(ctx context.Context, vmID string, snap *sn } // LoadSnapshot Loads a snapshot of a VM -func (o *Orchestrator) LoadSnapshot(ctx context.Context, lastVmID string, vmID string, snap *snapshotting.Snapshot) (_ *StartVMResponse, _ *metrics.Metric, retErr error) { +func (o *Orchestrator) LoadSnapshot(ctx context.Context, originVmID string, vmID string, snap *snapshotting.Snapshot) (_ *StartVMResponse, _ *metrics.Metric, retErr error) { var ( loadSnapshotMetric *metrics.Metric = metrics.NewMetric() tStart time.Time @@ -499,7 +499,7 @@ func (o *Orchestrator) LoadSnapshot(ctx context.Context, lastVmID string, vmID s conf.LoadSnapshot = true conf.SnapshotPath = snap.GetSnapshotFilePath() conf.ContainerSnapshotPath = containerSnap.GetDevicePath() - conf.MemBackend = &proto.MemoryBackend { + conf.MemBackend = &proto.MemoryBackend{ BackendType: fileBackend, BackendPath: snap.GetMemFilePath(), } @@ -507,24 +507,23 @@ func (o *Orchestrator) LoadSnapshot(ctx context.Context, lastVmID string, vmID s if o.GetUPFEnabled() { logger.Debug("TEST: UPF is enabled") conf.MemBackend.BackendType = uffdBackend - conf.MemBackend.BackendPath, err = o.memoryManager.GetUPFSockPath(lastVmID, true) + conf.MemBackend.BackendPath = o.uffdSockAddr logger.Debugf("TEST: the upf socket: %s", conf.MemBackend.BackendPath) if err != nil { return nil, nil, errors.Wrapf(err, "failed to get UPF socket path for uffd backend") } - if err := o.memoryManager.FetchState(lastVmID); err != nil { + if err := o.memoryManager.FetchState(originVmID); err != nil { return nil, nil, err } } tStart = time.Now() - newUPFSockPath := "" go func() { defer close(loadDone) - resp, loadErr := o.fcClient.CreateVM(ctx, conf) + _, loadErr := o.fcClient.CreateVM(ctx, conf) if loadErr != nil { logger.Error("Failed to load snapshot of the VM: ", loadErr) logger.Errorf("snapFilePath: %s, memFilePath: %s, newSnapshotPath: %s", snap.GetSnapshotFilePath(), snap.GetMemFilePath(), containerSnap.GetDevicePath()) @@ -551,12 +550,11 @@ func (o *Orchestrator) LoadSnapshot(ctx context.Context, lastVmID string, vmID s } logger.Error(snapFiles) } - newUPFSockPath = resp.GetSocketPath() }() logger.Debug("TEST: CreatVM request sent") if o.GetUPFEnabled() { - + logger.Debug("TEST: Registering VM with the memory manager") stateCfg := manager.SnapshotStateCfg{ @@ -567,13 +565,12 @@ func (o *Orchestrator) LoadSnapshot(ctx context.Context, lastVmID string, vmID s IsLazyMode: o.isLazyMode, VMMStatePath: o.getSnapshotFile(vmID), WorkingSetPath: o.getWorkingSetFile(vmID), - InstanceSockAddr: newUPFSockPath, + InstanceSockAddr: o.uffdSockAddr, } - if err := o.memoryManager.RegisterVM(stateCfg, true, vmID); err != nil { + if err := o.memoryManager.RegisterVM(stateCfg); err != nil { logger.Error(err, "failed to register new VM with memory manager") } - if activateErr = o.memoryManager.Activate(vmID); activateErr != nil { logger.Warn("Failed to activate VM in the memory manager", activateErr) } diff --git a/ctriface/iface_test.go b/ctriface/iface_test.go index c41a108fb..ad6ffee57 100644 --- a/ctriface/iface_test.go +++ b/ctriface/iface_test.go @@ -50,6 +50,56 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } +// Test for ctriface uffd feature +func TestStartSnapStop(t *testing.T) { + // BROKEN BECAUSE StopVM does not work yet. + // t.Skip("skipping failing test") + log.SetFormatter(&log.TextFormatter{ + TimestampFormat: ctrdlog.RFC3339NanoFixed, + FullTimestamp: true, + }) + //log.SetReportCaller(true) // FIXME: make sure it's false unless debugging + + log.SetOutput(os.Stdout) + + log.SetLevel(log.DebugLevel) + + testTimeout := 120 * time.Second + ctx, cancel := context.WithTimeout(namespaces.WithNamespace(context.Background(), namespaceName), testTimeout) + defer cancel() + + orch := NewOrchestrator("devmapper", "", WithTestModeOn(true)) + + vmID := "2" + + _, _, err := orch.StartVM(ctx, vmID, testImageName) + require.NoError(t, err, "Failed to start VM") + + err = orch.PauseVM(ctx, vmID) + require.NoError(t, err, "Failed to pause VM") + + snap := snapshotting.NewSnapshot(vmID, "/fccd/snapshots", testImageName) + err = orch.CreateSnapshot(ctx, vmID, snap) + require.NoError(t, err, "Failed to create snapshot of VM") + + err = orch.StopSingleVM(ctx, vmID) + require.NoError(t, err, "Failed to stop VM") + + _, _, err = orch.LoadSnapshot(ctx, "1", vmID, snap) + require.NoError(t, err, "Failed to load snapshot of VM") + + _, err = orch.ResumeVM(ctx, vmID) + require.NoError(t, err, "Failed to resume VM") + + time.Sleep(30 * time.Second) + + err = orch.StopSingleVM(ctx, vmID) + require.NoError(t, err, "Failed to stop VM") + + _ = snap.Cleanup() + orch.Cleanup() +} + func TestPauseSnapResume(t *testing.T) { log.SetFormatter(&log.TextFormatter{ TimestampFormat: ctrdlog.RFC3339NanoFixed, diff --git a/ctriface/manual_cleanup_test.go b/ctriface/manual_cleanup_test.go index 95488eb37..0536ea6bd 100644 --- a/ctriface/manual_cleanup_test.go +++ b/ctriface/manual_cleanup_test.go @@ -234,11 +234,11 @@ func TestParallelSnapLoad(t *testing.T) { err = orch.StopSingleVM(ctx, vmID) require.NoError(t, err, "Failed to offload VM, "+vmID) - lastVmID := vmID + originVmID := vmID vmIDInt, _ := strconv.Atoi(vmID) vmID = strconv.Itoa(vmIDInt + 1) - _, _, err = orch.LoadSnapshot(ctx, lastVmID, vmID, snap) + _, _, err = orch.LoadSnapshot(ctx, originVmID, vmID, snap) require.NoError(t, err, "Failed to load snapshot of VM, "+vmID) _, err = orch.ResumeVM(ctx, vmID) @@ -358,10 +358,10 @@ func TestParallelPhasedSnapLoad(t *testing.T) { defer vmGroup.Done() vmID := fmt.Sprintf("%d", i+vmIDBase) snap := snapshotting.NewSnapshot(vmID, "/fccd/snapshots", testImageName) - lastVmID := vmID + originVmID := vmID vmIDInt, _ := strconv.Atoi(vmID) vmID = strconv.Itoa(vmIDInt + 1) - _, _, err := orch.LoadSnapshot(ctx, lastVmID, vmID, snap) + _, _, err := orch.LoadSnapshot(ctx, originVmID, vmID, snap) require.NoError(t, err, "Failed to load snapshot of VM, "+vmID) }(i) } diff --git a/ctriface/orch.go b/ctriface/orch.go index d7dc5df7b..e481b7296 100644 --- a/ctriface/orch.go +++ b/ctriface/orch.go @@ -88,6 +88,7 @@ type Orchestrator struct { isUPFEnabled bool isLazyMode bool snapshotsDir string + uffdSockAddr string isMetricsMode bool netPoolSize int @@ -121,8 +122,16 @@ func NewOrchestrator(snapshotter, hostIface string, opts ...OrchestratorOption) } if o.GetUPFEnabled() { + // o.uffdSockAddr = "/tmp/uffd.sock" // "/tmp/uffd/firecracker-containerd#3-0/uffd.sock" + _, err = os.Create("/tmp/uffd.sock") + + if err != nil { + log.Fatal("TEST: failed to create uffd sock", err) + } + managerCfg := manager.MemoryManagerCfg{ MetricsModeOn: o.isMetricsMode, + UffdSockAddr: o.uffdSockAddr, } o.memoryManager = manager.NewMemoryManager(managerCfg) } @@ -208,6 +217,11 @@ func (o *Orchestrator) GetSnapshotsDir() string { return o.snapshotsDir } +// TODO: /tmp/uffd/firecracker-containerd#3-0/uffd.sock +func (o *Orchestrator) getUffdSockAddr(vmID string) string { + return filepath.Join(o.getVMBaseDir(vmID), "uffd.sock") +} + func (o *Orchestrator) getSnapshotFile(vmID string) string { return filepath.Join(o.getVMBaseDir(vmID), "snap_file") } diff --git a/functions.go b/functions.go index 28eadaf86..290815a84 100644 --- a/functions.go +++ b/functions.go @@ -25,7 +25,6 @@ package main import ( "context" "fmt" - "github.com/vhive-serverless/vhive/ctriface" "math/rand" "net" "os" @@ -35,6 +34,8 @@ import ( "syscall" "time" + "github.com/vhive-serverless/vhive/ctriface" + "golang.org/x/sync/semaphore" "google.golang.org/grpc" "google.golang.org/grpc/backoff" @@ -362,10 +363,10 @@ func (f *Function) AddInstance() *metrics.Metric { if f.isSnapshotReady { var resp *ctriface.StartVMResponse // resp, metr = f.LoadInstance(f.getVMID()) - - lastVmID := fmt.Sprintf("%s-%d", f.fID, f.lastInstanceID - 1) + + originVmID := fmt.Sprintf("%s-%d", f.fID, f.lastInstanceID-1) currVmID := f.getVMID() - resp, metr = f.LoadInstance(lastVmID, currVmID) + resp, metr = f.LoadInstance(originVmID, currVmID) f.guestIP = resp.GuestIP f.vmID = f.getVMID() @@ -483,7 +484,7 @@ func (f *Function) CreateInstanceSnapshot() { // LoadInstance Loads a new instance of the function from its snapshot and resumes it // The tap, the shim and the vmID remain the same -func (f *Function) LoadInstance(lastVmID string, vmID string) (*ctriface.StartVMResponse, *metrics.Metric) { +func (f *Function) LoadInstance(originVmID string, vmID string) (*ctriface.StartVMResponse, *metrics.Metric) { logger := log.WithFields(log.Fields{"fID": f.fID}) logger.Debug("Loading instance") @@ -496,7 +497,7 @@ func (f *Function) LoadInstance(lastVmID string, vmID string) (*ctriface.StartVM log.Panic(err) } - resp, loadMetr, err := orch.LoadSnapshot(ctx, lastVmID, vmID, snap) + resp, loadMetr, err := orch.LoadSnapshot(ctx, originVmID, vmID, snap) if err != nil { log.Panic(err) } diff --git a/memory/manager/manager.go b/memory/manager/manager.go index 8a5437785..29595530a 100644 --- a/memory/manager/manager.go +++ b/memory/manager/manager.go @@ -46,6 +46,7 @@ const ( // MemoryManagerCfg Global config of the manager type MemoryManagerCfg struct { MetricsModeOn bool + UffdSockAddr string // it could not be appropriate to put sock here } // MemoryManager Serves page faults coming from VMs @@ -53,7 +54,6 @@ type MemoryManager struct { sync.Mutex MemoryManagerCfg instances map[string]*SnapshotState // Indexed by vmID - origins map[string]string } // NewMemoryManager Initializes a new memory manager @@ -63,13 +63,12 @@ func NewMemoryManager(cfg MemoryManagerCfg) *MemoryManager { m := new(MemoryManager) m.instances = make(map[string]*SnapshotState) m.MemoryManagerCfg = cfg - m.origins = make(map[string]string) - + return m } // RegisterVM Registers a VM within the memory manager -func (m *MemoryManager) RegisterVM(cfg SnapshotStateCfg, isSnapshotReady bool, originID string) error { +func (m *MemoryManager) RegisterVM(cfg SnapshotStateCfg) error { m.Lock() defer m.Unlock() @@ -88,11 +87,6 @@ func (m *MemoryManager) RegisterVM(cfg SnapshotStateCfg, isSnapshotReady bool, o state := NewSnapshotState(cfg) m.instances[vmID] = state - // if isSnapshotReady { - // logger.Debugf("TEST: register current vmID %s with originID %s", vmID, originID) - // m.origins[vmID] = originID - // } - return nil } @@ -374,40 +368,41 @@ func (m *MemoryManager) GetUPFLatencyStats(vmID string) ([]*metrics.Metric, erro return state.latencyMetrics, nil } -func (m *MemoryManager) GetUPFSockPath(vmID string, isSnapshotReady bool) (string, error) { - logger := log.WithFields(log.Fields{"vmID": vmID}) - - logger.Debug("Get the path of firecracker unix domain socket") - - m.Lock() - - // id := "" - // if isSnapshotReady { - // logger.Debugf("TEST: to find originID by vmID %s", vmID) - // originID, ok := m.origins[vmID] - // if !ok { - // logger.Debug("TEST: not loaded from snapshot") - // } - // id = originID - // } - // state, ok := m.instances[id] - - state, ok := m.instances[vmID] - if !ok { - m.Unlock() - logger.Error("VM not registered with the memory manager") - return "", errors.New("VM not registered with the memory manager") - } - - m.Unlock() - - if state.isActive { - logger.Error("Cannot get stats while VM is active") - return "", errors.New("Cannot get stats while VM is active") - } - - return m.instances[vmID].SnapshotStateCfg.InstanceSockAddr, nil -} +// Deprecated +// func (m *MemoryManager) GetUPFSockPath(vmID string, isSnapshotReady bool) (string, error) { +// logger := log.WithFields(log.Fields{"vmID": vmID}) + +// logger.Debug("Get the path of firecracker unix domain socket") + +// m.Lock() + +// // id := "" +// // if isSnapshotReady { +// // logger.Debugf("TEST: to find originID by vmID %s", vmID) +// // originID, ok := m.origins[vmID] +// // if !ok { +// // logger.Debug("TEST: not loaded from snapshot") +// // } +// // id = originID +// // } +// // state, ok := m.instances[id] + +// state, ok := m.instances[vmID] +// if !ok { +// m.Unlock() +// logger.Error("VM not registered with the memory manager") +// return "", errors.New("VM not registered with the memory manager") +// } + +// m.Unlock() + +// if state.isActive { +// logger.Error("Cannot get stats while VM is active") +// return "", errors.New("Cannot get stats while VM is active") +// } + +// return m.instances[vmID].SnapshotStateCfg.InstanceSockAddr, nil +// } func getLazyHeaderStats(state *SnapshotState, functionName string) ([]string, []string) { header := []string{ diff --git a/memory/manager/snapshot_state.go b/memory/manager/snapshot_state.go index 7cce3e2af..ad23d2e97 100644 --- a/memory/manager/snapshot_state.go +++ b/memory/manager/snapshot_state.go @@ -49,6 +49,14 @@ import ( "unsafe" ) +// TODO: for test logging +type TestPageFault struct { + src uint64 + dst uint64 + mode uint64 + offset uint64 +} + // SnapshotStateCfg Config to initialize SnapshotState type SnapshotStateCfg struct { VMID string @@ -140,6 +148,7 @@ func (s *SnapshotState) getUFFD() error { time.Sleep(1 * time.Millisecond) continue } + log.Debugf("TEST: Dial uffd socket done: %s", s.InstanceSockAddr) defer c.Close() @@ -301,6 +310,7 @@ func (s *SnapshotState) pollUserPageFaults(readyCh chan int) { panic("Wrong number of events") } + logger.Debugf("TEST: epoller found %d event", nevents) for i := 0; i < nevents; i++ { event := events[i] @@ -374,14 +384,21 @@ func (s *SnapshotState) servePageFault(fd int, address uint64) error { workingSetInstalled bool ) + // log.SetOutput(os.Stdout) + // log.SetLevel(log.DebugLevel) + + log.Debugf("TEST: servePageFault(fd: %d, address: %d)", fd, address) + s.firstPageFaultOnce.Do( func() { s.startAddress = address + log.Debugf("TEST: first page fault address %d", address) if s.isRecordReady && !s.IsLazyMode { if s.metricsModeOn { tStart = time.Now() } + log.Debug("TEST: first page fault once installation") s.installWorkingSetPages(fd) if s.metricsModeOn { s.currentMetric.MetricMap[installWSMetric] = metrics.ToUS(time.Since(tStart)) @@ -401,6 +418,13 @@ func (s *SnapshotState) servePageFault(fd int, address uint64) error { dst := uint64(int64(address) & ^(int64(os.Getpagesize()) - 1)) mode := uint64(0) + testPF := TestPageFault{ + src: src, + dst: dst, + mode: mode, + offset: offset, + } + rec := Record{ offset: offset, } @@ -427,6 +451,7 @@ func (s *SnapshotState) servePageFault(fd int, address uint64) error { tStart = time.Now() } + log.Debugf("TEST: install happen for %v", testPF) err := installRegion(fd, src, dst, mode, 1) if s.metricsModeOn {