Skip to content

Commit 984e300

Browse files
committed
Add mmds version 2 support
Closes #437 Signed-off-by: Mathis Joffre <[email protected]>
1 parent 9a1efa1 commit 984e300

File tree

5 files changed

+124
-9
lines changed

5 files changed

+124
-9
lines changed

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ $(FC_TEST_BIN_PATH)/tc-redirect-tap:
122122
go get github.com/awslabs/tc-redirect-tap/cmd/tc-redirect-tap
123123

124124
$(FC_TEST_DATA_PATH)/ltag:
125-
GO111MODULE=off GOBIN=$(abspath $(FC_TEST_DATA_PATH)) \
126-
go get github.com/kunalkushwaha/ltag
125+
GO111MODULE=on GOBIN=$(abspath $(FC_TEST_BIN_PATH)) \
126+
go get github.com/kunalkushwaha/ltag@v0.2.3
127127

128128
$(FIRECRACKER_DIR):
129129
- git clone https://github.com/firecracker-microvm/firecracker.git $(FIRECRACKER_DIR)
@@ -144,6 +144,6 @@ firecracker-clean:
144144

145145
lint: deps
146146
gofmt -s -l .
147-
$(FC_TEST_DATA_PATH)/ltag -check -v -t .headers
147+
$(FC_TEST_DATA_PATH)/bin/ltag -check -v -t .headers
148148

149149
.PHONY: all generate clean distclean build test unit-tests all-tests check-kvm

handlers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ func NewSetMetadataHandler(metadata interface{}) Handler {
277277
var ConfigMmdsHandler = Handler{
278278
Name: ConfigMmdsHandlerName,
279279
Fn: func(ctx context.Context, m *Machine) error {
280-
return m.setMmdsConfig(ctx, m.Cfg.MmdsAddress, m.Cfg.NetworkInterfaces)
280+
return m.setMmdsConfig(ctx, m.Cfg.MmdsAddress, m.Cfg.NetworkInterfaces, m.Cfg.MmdsVersion)
281281
},
282282
}
283283

handlers_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ func TestHandlers(t *testing.T) {
532532
mmdsConfig := &models.MmdsConfig{
533533
IPV4Address: String(mmdsAddress.String()),
534534
NetworkInterfaces: []string{"1"},
535+
Version: String(string(MMDSv1)),
535536
}
536537

537538
cases := []struct {

machine.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ type SeccompConfig struct {
6565
// be started again.
6666
var ErrAlreadyStarted = errors.New("firecracker: machine already started")
6767

68+
type MMDSVersion string
69+
70+
const (
71+
MMDSv1 = MMDSVersion("V1")
72+
MMDSv2 = MMDSVersion("V2")
73+
)
74+
6875
// Config is a collection of user-configurable VMM settings
6976
type Config struct {
7077
// SocketPath defines the file path where the Firecracker control socket
@@ -152,6 +159,10 @@ type Config struct {
152159
// If not provided, the default address (169.254.169.254) will be used.
153160
MmdsAddress net.IP
154161

162+
// MmdsVersion is the MMDS version to use.
163+
// If not provided, the default version (1) will be used.
164+
MmdsVersion MMDSVersion
165+
155166
// Configuration for snapshot loading
156167
Snapshot SnapshotConfig
157168
}
@@ -907,8 +918,15 @@ func (m *Machine) sendCtrlAltDel(ctx context.Context) error {
907918
return err
908919
}
909920

910-
func (m *Machine) setMmdsConfig(ctx context.Context, address net.IP, ifaces NetworkInterfaces) error {
921+
func (m *Machine) setMmdsConfig(ctx context.Context, address net.IP, ifaces NetworkInterfaces, version MMDSVersion) error {
911922
var mmdsCfg models.MmdsConfig
923+
// MMDS config supports v1 and v2, v1 is going to be deprecated.
924+
// Default to the version 1 if no version is specified
925+
if version == MMDSv1 || version == MMDSv2 {
926+
mmdsCfg.Version = String(string(version))
927+
} else {
928+
mmdsCfg.Version = String(string(MMDSv1))
929+
}
912930
if address != nil {
913931
mmdsCfg.IPV4Address = String(address.String())
914932
}

machine_test.go

Lines changed: 100 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,100 @@ func TestWaitForSocket(t *testing.T) {
869869
}
870870
}
871871

872+
func TestMicroVMExecutionWithMmdsV2(t *testing.T) {
873+
fctesting.RequiresKVM(t)
874+
875+
var nCpus int64 = 2
876+
cpuTemplate := models.CPUTemplate(models.CPUTemplateT2)
877+
var memSz int64 = 256
878+
879+
dir, err := ioutil.TempDir("", t.Name())
880+
require.NoError(t, err)
881+
defer os.RemoveAll(dir)
882+
883+
socketPath := filepath.Join(dir, "TestMicroVMExecution.sock")
884+
logFifo := filepath.Join(dir, "firecracker.log")
885+
metricsFifo := filepath.Join(dir, "firecracker-metrics")
886+
capturedLog := filepath.Join(dir, "writer.fifo")
887+
fw, err := os.OpenFile(capturedLog, os.O_CREATE|os.O_RDWR, 0600)
888+
require.NoError(t, err, "failed to open fifo writer file")
889+
defer fw.Close()
890+
891+
vmlinuxPath := getVmlinuxPath(t)
892+
893+
networkIfaces := []NetworkInterface{{
894+
StaticConfiguration: &StaticNetworkConfiguration{
895+
MacAddress: "01-23-45-67-89-AB-CD-EF",
896+
HostDevName: "tap0",
897+
},
898+
}}
899+
900+
cfg := Config{
901+
SocketPath: socketPath,
902+
LogFifo: logFifo,
903+
MetricsFifo: metricsFifo,
904+
LogLevel: "Debug",
905+
MachineCfg: models.MachineConfiguration{
906+
VcpuCount: Int64(nCpus),
907+
CPUTemplate: cpuTemplate,
908+
MemSizeMib: Int64(memSz),
909+
Smt: Bool(false),
910+
},
911+
DisableValidation: true,
912+
NetworkInterfaces: networkIfaces,
913+
FifoLogWriter: fw,
914+
MmdsVersion: MMDSv2,
915+
}
916+
917+
ctx := context.Background()
918+
cmd := VMCommandBuilder{}.
919+
WithSocketPath(socketPath).
920+
WithBin(getFirecrackerBinaryPath()).
921+
Build(ctx)
922+
923+
m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t)))
924+
if err != nil {
925+
t.Fatalf("failed to create new machine: %v", err)
926+
}
927+
928+
m.Handlers.Validation = m.Handlers.Validation.Clear()
929+
930+
vmmCtx, vmmCancel := context.WithTimeout(ctx, 30*time.Second)
931+
defer vmmCancel()
932+
exitchannel := make(chan error)
933+
go func() {
934+
err := m.startVMM(vmmCtx)
935+
if err != nil {
936+
exitchannel <- err
937+
close(exitchannel)
938+
return
939+
}
940+
defer m.StopVMM()
941+
942+
exitchannel <- m.Wait(vmmCtx)
943+
close(exitchannel)
944+
}()
945+
946+
deadlineCtx, deadlineCancel := context.WithTimeout(vmmCtx, 250*time.Millisecond)
947+
defer deadlineCancel()
948+
if err := waitForAliveVMM(deadlineCtx, m.client); err != nil {
949+
t.Fatal(err)
950+
}
951+
952+
t.Run("TestCreateMachine", func(t *testing.T) { testCreateMachine(ctx, t, m) })
953+
t.Run("TestCreateBootSource", func(t *testing.T) { testCreateBootSource(ctx, t, m, vmlinuxPath) })
954+
t.Run("TestCreateNetworkInterface", func(t *testing.T) { testCreateNetworkInterfaceByID(ctx, t, m) })
955+
t.Run("TestAttachRootDrive", func(t *testing.T) { testAttachRootDrive(ctx, t, m) })
956+
t.Run("SetMetadata", func(t *testing.T) { testSetMetadata(ctx, t, m) })
957+
t.Run("UpdateMetadata", func(t *testing.T) { testUpdateMetadata(ctx, t, m) })
958+
t.Run("GetMetadata", func(t *testing.T) { testGetMetadata(ctx, t, m) }) // Should be after testSetMetadata and testUpdateMetadata
959+
960+
// unconditionally stop the VM here. TestShutdown may have triggered a shutdown, but if it
961+
// didn't for some reason, we still need to terminate it:
962+
err = m.StopVMM()
963+
assert.NoError(t, err, "failed to stop VM")
964+
}
965+
872966
func testSetMetadata(ctx context.Context, t *testing.T, m *Machine) {
873967
metadata := map[string]string{"key": "value"}
874968
err := m.SetMetadata(ctx, metadata)
@@ -1952,20 +2046,22 @@ func TestLoadSnapshot(t *testing.T) {
19522046
},
19532047
}
19542048

2049+
cfg.Snapshot.ResumeVM = false
2050+
19552051
m, err := NewMachine(ctx, cfg, func(m *Machine) {
19562052
// Rewriting m.cmd partially wouldn't work since Cmd has
19572053
// some unexported members
19582054
args := m.cmd.Args[1:]
19592055
m.cmd = exec.Command(getFirecrackerBinaryPath(), args...)
1960-
}, WithLogger(logrus.NewEntry(machineLogger)), WithSnapshot(memPath, snapPath))
2056+
}, WithLogger(logrus.NewEntry(machineLogger)), WithSnapshot(memPath, snapPath, func(config *SnapshotConfig) {
2057+
config.ResumeVM = true
2058+
}))
19612059
require.NoError(t, err)
2060+
require.Equal(t, m.Cfg.Snapshot.ResumeVM, true)
19622061

19632062
err = m.Start(ctx)
19642063
require.NoError(t, err)
19652064

1966-
err = m.ResumeVM(ctx)
1967-
require.NoError(t, err)
1968-
19692065
err = m.StopVMM()
19702066
require.NoError(t, err)
19712067
},

0 commit comments

Comments
 (0)