Skip to content

Commit 226c8ef

Browse files
authored
Add mmds version 2 support (#441)
Closes #437 Signed-off-by: Mathis Joffre <[email protected]>
1 parent c007a0c commit 226c8ef

File tree

4 files changed

+115
-2
lines changed

4 files changed

+115
-2
lines changed

handlers.go

+1-1
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

+1
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

+19-1
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

+94
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)

0 commit comments

Comments
 (0)