qemu: add fw_cfg flag to config

Signed-off-by: Salvatore Mazzarino <dev@mazzarino.cz>
This commit is contained in:
Salvatore Mazzarino 2020-10-09 10:17:58 +02:00
parent 6fa954a506
commit 29ba5a9012
2 changed files with 104 additions and 0 deletions

View File

@ -2103,6 +2103,54 @@ type Kernel struct {
Params string
}
// FwCfg allows QEMU to pass entries to the guest
// File and Str are mutually exclusive
type FwCfg struct {
Name string
File string
Str string
}
// Valid returns true if the FwCfg structure is valid and complete.
func (fwcfg FwCfg) Valid() bool {
if fwcfg.Name == "" {
return false
}
if fwcfg.File != "" && fwcfg.Str != "" {
return false
}
if fwcfg.File == "" && fwcfg.Str == "" {
return false
}
return true
}
// QemuParams returns the qemu parameters built out of the FwCfg object
func (fwcfg FwCfg) QemuParams(config *Config) []string {
var fwcfgParams []string
var qemuParams []string
if config.FwCfg.Name != "" {
fwcfgParams = append(fwcfgParams, fmt.Sprintf("name=%q", config.FwCfg.Name))
if config.FwCfg.File != "" {
fwcfgParams = append(fwcfgParams, fmt.Sprintf(",file=%q", config.FwCfg.File))
}
if config.FwCfg.Str != "" {
fwcfgParams = append(fwcfgParams, fmt.Sprintf(",string=%q", config.FwCfg.Str))
}
}
qemuParams = append(qemuParams, "-fw_cfg")
qemuParams = append(qemuParams, strings.Join(fwcfgParams, ""))
return qemuParams
}
// Knobs regroups a set of qemu boolean settings
type Knobs struct {
// NoUserConfig prevents qemu from loading user config files.
@ -2236,6 +2284,9 @@ type Config struct {
// fds is a list of open file descriptors to be passed to the spawned qemu process
fds []*os.File
// FwCfg is the -fw_cfg parameter
FwCfg FwCfg
IOThreads []IOThread
// PidFile is the -pidfile parameter
@ -2568,6 +2619,19 @@ func (config *Config) appendLogFile() {
}
}
func (config *Config) appendFwCfg(logger QMPLog) {
if logger == nil {
logger = qmpNullLogger{}
}
if !config.FwCfg.Valid() {
logger.Errorf("fw_cfg is not valid: %+v", config.FwCfg)
return
}
config.qemuParams = append(config.qemuParams, config.FwCfg.QemuParams(config)...)
}
// LaunchQemu can be used to launch a new qemu instance.
//
// The Config parameter contains a set of qemu parameters and settings.
@ -2595,6 +2659,7 @@ func LaunchQemu(config Config, logger QMPLog) (string, error) {
config.appendIncoming()
config.appendPidFile()
config.appendLogFile()
config.appendFwCfg(logger)
if err := config.appendCPUs(); err != nil {
return "", err

View File

@ -44,6 +44,9 @@ func testConfigAppend(config *Config, structure interface{}, expected string, t
case Machine:
config.Machine = s
config.appendMachine()
case FwCfg:
config.FwCfg = s
config.appendFwCfg(nil)
case Device:
config.Devices = []Device{s}
@ -1141,6 +1144,26 @@ func TestBadCPUs(t *testing.T) {
}
}
func TestBadFwcfg(t *testing.T) {
c := &Config{}
c.appendFwCfg(nil)
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
c = &Config{
FwCfg: FwCfg{
Name: "name=opt/com.mycompany/blob",
File: "./my_blob.bin",
Str: "foo",
},
}
c.appendFwCfg(nil)
if len(c.qemuParams) != 0 {
t.Errorf("Expected empty qemuParams, found %s", c.qemuParams)
}
}
var (
vIommuString = "-device intel-iommu,intremap=on,device-iotlb=on,caching-mode=on"
vIommuNoCacheString = "-device intel-iommu,intremap=on,device-iotlb=on,caching-mode=off"
@ -1164,3 +1187,19 @@ func TestIommu(t *testing.T) {
testAppend(iommu, vIommuNoCacheString, t)
}
func TestAppendFwcfg(t *testing.T) {
fwcfgString := "-fw_cfg name=\"opt/com.mycompany/blob\",file=\"./my_blob.bin\""
fwcfg := FwCfg{
Name: "opt/com.mycompany/blob",
File: "./my_blob.bin",
}
testAppend(fwcfg, fwcfgString, t)
fwcfgString = "-fw_cfg name=\"opt/com.mycompany/blob\",string=\"foo\""
fwcfg = FwCfg{
Name: "opt/com.mycompany/blob",
Str: "foo",
}
testAppend(fwcfg, fwcfgString, t)
}