Skip to content

Commit

Permalink
qemu: Create OVMF vars copy in instance dir
Browse files Browse the repository at this point in the history
and cleanup on shutdown.

Signed-off-by: Jeremi Piotrowski <jpiotrowski@microsoft.com>
  • Loading branch information
jepio committed Sep 6, 2024
1 parent dbe965b commit 78a4688
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 30 deletions.
18 changes: 14 additions & 4 deletions platform/machine/qemu/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package qemu
import (
"fmt"
"os"
"path"
"path/filepath"
"strings"
"sync"
Expand Down Expand Up @@ -137,10 +138,19 @@ ExecStartPost=/usr/bin/ln -fs /run/metadata/flatcar /run/metadata/coreos
if err != nil {
return nil, fmt.Errorf("failed to canonicalize firmware path: %v", err)
}
ovmfVars, err := filepath.Abs(qc.flight.opts.OVMFVars)
if err != nil {
return nil, fmt.Errorf("failed to canonicalize ovmf vars path: %v", err)
ovmfVars := ""
if qc.flight.opts.OVMFVars != "" {
ovmfVars, err = platform.CreateOvmfVarsCopy(qm.subDir, qc.flight.opts.OVMFVars)
if err != nil {
return nil, err
}
defer func() {
if ovmfVars != "" {
os.Remove(path.Join(qm.subDir, ovmfVars))
}
}()
}

qmCmd, extraFiles, err := platform.CreateQEMUCommand(qc.flight.opts.Board, qm.id, firmware, ovmfVars, qm.consolePath, confPath, qc.flight.diskImagePath, qc.flight.opts.EnableSecureboot, conf.IsIgnition(), options)
if err != nil {
return nil, err
Expand Down Expand Up @@ -185,7 +195,7 @@ ExecStartPost=/usr/bin/ln -fs /run/metadata/flatcar /run/metadata/coreos

// from this point on Destroy() is responsible for cleaning up swtpm
qm.swtpm, swtpm = swtpm, nil

qm.ovmfVars, ovmfVars = ovmfVars, ""
plog.Debugf("qemu PID (manual cleanup needed if --remove=false): %v", qm.qemu.Pid())

if err := platform.StartMachine(qm, qm.journal); err != nil {
Expand Down
9 changes: 9 additions & 0 deletions platform/machine/qemu/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package qemu

import (
"io/ioutil"
"os"
"path"
"path/filepath"

"golang.org/x/crypto/ssh"
Expand All @@ -33,6 +35,7 @@ type machine struct {
journal *platform.Journal
consolePath string
console string
ovmfVars string
subDir string
swtpm *local.SoftwareTPM
}
Expand Down Expand Up @@ -76,6 +79,12 @@ func (m *machine) Destroy() {
if m.swtpm != nil {
m.swtpm.Stop()
}
if m.ovmfVars != "" {
err := os.Remove(path.Join(m.subDir, m.ovmfVars))
if err != nil {
plog.Errorf("Error removing OVMF vars: %v", err)
}
}
m.journal.Destroy()

if buf, err := ioutil.ReadFile(filepath.Join(m.subDir, m.consolePath)); err == nil {
Expand Down
19 changes: 15 additions & 4 deletions platform/machine/unprivqemu/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"io/ioutil"
"net"
"os"
"path"
"path/filepath"
"regexp"
"strconv"
Expand Down Expand Up @@ -143,16 +144,25 @@ LinkLocalAddressing=no
}
}()
}

ovmfVars := ""
if qc.flight.opts.OVMFVars != "" {
ovmfVars, err = platform.CreateOvmfVarsCopy(qm.subDir, qc.flight.opts.OVMFVars)
if err != nil {
return nil, err
}
defer func() {
if ovmfVars != "" {
os.Remove(path.Join(qm.subDir, ovmfVars))
}
}()
}
// This uses path arguments with path values being
// relative to the folder created for this machine
firmware, err := filepath.Abs(qc.flight.opts.Firmware)
if err != nil {
return nil, fmt.Errorf("failed to canonicalize firmware path: %v", err)
}
ovmfVars, err := filepath.Abs(qc.flight.opts.OVMFVars)
if err != nil {
return nil, fmt.Errorf("failed to canonicalize ovmf vars path: %v", err)
}
qmCmd, extraFiles, err := platform.CreateQEMUCommand(qc.flight.opts.Board, qm.id, firmware, ovmfVars, qm.consolePath, confPath, qc.flight.diskImagePath, qc.flight.opts.EnableSecureboot, conf.IsIgnition(), options)
if err != nil {
return nil, err
Expand Down Expand Up @@ -186,6 +196,7 @@ LinkLocalAddressing=no

// from this point on Destroy() is responsible for cleaning up swtpm
qm.swtpm, swtpm = swtpm, nil
qm.ovmfVars, ovmfVars = ovmfVars, ""
plog.Debugf("qemu PID (manual cleanup needed if --remove=false): %v", qm.qemu.Pid())

pid := strconv.Itoa(qm.qemu.Pid())
Expand Down
9 changes: 9 additions & 0 deletions platform/machine/unprivqemu/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ package unprivqemu

import (
"io/ioutil"
"os"
"path"
"path/filepath"

"golang.org/x/crypto/ssh"
Expand All @@ -32,6 +34,7 @@ type machine struct {
journal *platform.Journal
consolePath string
console string
ovmfVars string
subDir string
swtpm *local.SoftwareTPM
ip string
Expand Down Expand Up @@ -78,6 +81,12 @@ func (m *machine) Destroy() {
if m.swtpm != nil {
m.swtpm.Stop()
}
if m.ovmfVars != "" {
err := os.Remove(path.Join(m.subDir, m.ovmfVars))
if err != nil {
plog.Errorf("Error removing OVMF vars: %v", err)
}
}
m.journal.Destroy()

if buf, err := ioutil.ReadFile(filepath.Join(m.subDir, m.consolePath)); err == nil {
Expand Down
45 changes: 23 additions & 22 deletions platform/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"io/ioutil"
"os"
origExec "os/exec"
"path"
"path/filepath"
"regexp"
"runtime"
Expand Down Expand Up @@ -295,6 +296,27 @@ func mkpath(basedir string) (string, error) {
return f.Name(), nil
}

func CreateOvmfVarsCopy(dir, ovmfVars string) (string, error) {
ovmfVarsDst := path.Join(dir, path.Base(ovmfVars))
ovmfVarsSrc, err := os.Open(ovmfVars)
if err != nil {
return "", err
}
defer ovmfVarsSrc.Close()

ovmfVarsCopy, err := os.Create(ovmfVarsDst)
if err != nil {
return "", err
}
defer ovmfVarsCopy.Close()

if _, err := io.Copy(ovmfVarsCopy, ovmfVarsSrc); err != nil {
os.Remove(ovmfVarsCopy.Name())
return "", err
}
return path.Base(ovmfVars), nil
}

func CreateQEMUCommand(board, uuid, firmware, ovmfVars, consolePath, confPath, diskImagePath string, enableSecureboot, isIgnition bool, options MachineOptions) ([]string, []*os.File, error) {
var qmCmd []string

Expand Down Expand Up @@ -366,35 +388,14 @@ func CreateQEMUCommand(board, uuid, firmware, ovmfVars, consolePath, confPath, d
}

if ovmfVars != "" {
// Create a copy of the OVMF Vars
ovmfVarsSrc, err := os.Open(ovmfVars)
if err != nil {
return nil, nil, err
}
defer ovmfVarsSrc.Close()

ovmfVarsCopy, err := ioutil.TempFile("/var/tmp/", "mantle-qemu")
if err != nil {
return nil, nil, err
}

if _, err := io.Copy(ovmfVarsCopy, ovmfVarsSrc); err != nil {
return nil, nil, err
}

_, err = ovmfVarsCopy.Seek(0, 0)
if err != nil {
return nil, nil, err
}

if enableSecureboot {
qmCmd = append(qmCmd,
"-global", "ICH9-LPC.disable_s3=1",
"-global", "driver=cfi.pflash01,property=secure,value=on",
)
}
qmCmd = append(qmCmd,
"-drive", fmt.Sprintf("if=pflash,unit=1,file=%v,format=raw", ovmfVarsCopy.Name()),
"-drive", fmt.Sprintf("if=pflash,unit=1,file=%v,format=raw", ovmfVars),
)
}

Expand Down

0 comments on commit 78a4688

Please sign in to comment.