Skip to content

Commit e8092e4

Browse files
committed
Add listener to uffd socket before epolling
1 parent 97f714e commit e8092e4

File tree

3 files changed

+61
-15
lines changed

3 files changed

+61
-15
lines changed

ctriface/iface_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ func TestStartSnapStop(t *testing.T) {
6868
ctx, cancel := context.WithTimeout(namespaces.WithNamespace(context.Background(), namespaceName), testTimeout)
6969
defer cancel()
7070

71-
// uffdSockAddr := "/tmp/uffd.sock"
7271
// uffdSockDir := "/home/char/uffd"
7372
// uffdSockAddr := uffdSockDir + "/uffd.sock"
7473
uffdSockAddr := "/tmp/uffd.sock"

ctriface/orch.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,13 @@ func NewOrchestrator(snapshotter, hostIface string, opts ...OrchestratorOption)
128128
log.Fatalf("Failed to create socket file: %v", err)
129129
}
130130
defer file.Close()
131-
131+
132132
managerCfg := manager.MemoryManagerCfg{
133133
MetricsModeOn: o.isMetricsMode,
134134
UffdSockAddr: o.uffdSockAddr,
135135
}
136136
o.memoryManager = manager.NewMemoryManager(managerCfg)
137+
go o.memoryManager.ListenUffdSocket(o.uffdSockAddr)
137138
}
138139

139140
log.Info("Creating containerd client")

memory/manager/manager.go

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"encoding/csv"
2727
"errors"
2828
"fmt"
29+
"net"
2930
"os"
3031
"strconv"
3132
"sync"
@@ -53,8 +54,10 @@ type MemoryManagerCfg struct {
5354
type MemoryManager struct {
5455
sync.Mutex
5556
MemoryManagerCfg
56-
instances map[string]*SnapshotState // Indexed by vmID
57-
origins map[string]string // Track parent vm for vm loaded from snapshot
57+
instances map[string]*SnapshotState // Indexed by vmID
58+
origins map[string]string // Track parent vm for vm loaded from snapshot
59+
startEpollingCh chan struct{}
60+
startEpollingOnce sync.Once
5861
}
5962

6063
// NewMemoryManager Initializes a new memory manager
@@ -64,7 +67,9 @@ func NewMemoryManager(cfg MemoryManagerCfg) *MemoryManager {
6467
m := new(MemoryManager)
6568
m.instances = make(map[string]*SnapshotState)
6669
m.origins = make(map[string]string)
70+
m.startEpollingCh = make(chan struct{}, 1)
6771
m.MemoryManagerCfg = cfg
72+
m.startEpollingOnce = sync.Once{}
6873

6974
return m
7075
}
@@ -182,21 +187,29 @@ func (m *MemoryManager) Activate(vmID string) error {
182187
return errors.New("VM already active")
183188
}
184189

185-
if err := state.mapGuestMemory(); err != nil {
186-
logger.Error("Failed to map guest memory")
187-
return err
188-
}
190+
select {
191+
case <-m.startEpollingCh:
192+
if err := state.mapGuestMemory(); err != nil {
193+
logger.Error("Failed to map guest memory")
194+
return err
195+
}
189196

190-
if err := state.getUFFD(); err != nil {
191-
logger.Error("Failed to get uffd")
192-
return err
193-
}
197+
if err := state.getUFFD(); err != nil {
198+
logger.Error("Failed to get uffd")
199+
return err
200+
}
194201

195-
state.setupStateOnActivate()
202+
state.setupStateOnActivate()
196203

197-
go state.pollUserPageFaults(readyCh)
204+
go state.pollUserPageFaults(readyCh)
198205

199-
<-readyCh
206+
<-readyCh
207+
208+
case <-time.After(100 * time.Second):
209+
return errors.New("Uffd connection to firecracker timeout")
210+
default:
211+
return errors.New("Failed to start epoller")
212+
}
200213

201214
return nil
202215
}
@@ -396,6 +409,39 @@ func (m *MemoryManager) GetUPFLatencyStats(vmID string) ([]*metrics.Metric, erro
396409
return state.latencyMetrics, nil
397410
}
398411

412+
func (m *MemoryManager) ListenUffdSocket(uffdSockAddr string) error {
413+
log.Debug("Start listening to uffd socket")
414+
415+
m.startEpollingOnce.Do(func() {
416+
m.startEpollingCh = make(chan struct{})
417+
})
418+
419+
ln, err := net.Listen("unix", uffdSockAddr)
420+
if err != nil {
421+
log.Errorf("Failed to listen on uffd socket: %v", err)
422+
return errors.New("Failed to listen on uffd socket")
423+
}
424+
defer ln.Close()
425+
426+
for {
427+
conn, err := ln.Accept()
428+
if err != nil {
429+
log.Printf("Failed to accept connection on uffd socket: %v", err)
430+
continue
431+
}
432+
go func(conn net.Conn) {
433+
defer conn.Close()
434+
if err := ln.Close(); err != nil {
435+
log.Printf("Failed to close uffd socket listener: %v", err)
436+
}
437+
close(m.startEpollingCh)
438+
}(conn)
439+
break
440+
}
441+
442+
return nil
443+
}
444+
399445
// Deprecated
400446
// func (m *MemoryManager) GetUPFSockPath(vmID string, isSnapshotReady bool) (string, error) {
401447
// logger := log.WithFields(log.Fields{"vmID": vmID})

0 commit comments

Comments
 (0)