diff --git a/ciao-launcher/qemu.go b/ciao-launcher/qemu.go index 53000ebe7..43e7d65ea 100644 --- a/ciao-launcher/qemu.go +++ b/ciao-launcher/qemu.go @@ -419,21 +419,45 @@ func launchQemuWithSpice(params []string, fds []*os.File, ipAddress string) (int return port, err } -func (q *qemu) startVM(vnicName, ipAddress string) error { - - var fds []*os.File - - glog.Info("Launching qemu") - - vmImage := path.Join(q.instanceDir, "image.qcow2") - qmpSocket := path.Join(q.instanceDir, "socket") +func generateQEMULaunchParams(cfg *vmConfig, isoPath, instanceDir string, networkParams []string) []string { + vmImage := path.Join(instanceDir, "image.qcow2") + qmpSocket := path.Join(instanceDir, "socket") fileParam := fmt.Sprintf("file=%s,if=virtio,aio=threads,format=qcow2", vmImage) - isoParam := fmt.Sprintf("file=%s,if=virtio,media=cdrom", q.isoPath) + isoParam := fmt.Sprintf("file=%s,if=virtio,media=cdrom", isoPath) qmpParam := fmt.Sprintf("unix:%s,server,nowait", qmpSocket) params := make([]string, 0, 32) params = append(params, "-drive", fileParam) params = append(params, "-drive", isoParam) + params = append(params, networkParams...) + + params = append(params, "-enable-kvm") + params = append(params, "-cpu", "host") + params = append(params, "-daemonize") + params = append(params, "-qmp", qmpParam) + + if cfg.Mem > 0 { + memoryParam := fmt.Sprintf("%d", cfg.Mem) + params = append(params, "-m", memoryParam) + } + if cfg.Cpus > 0 { + cpusParam := fmt.Sprintf("cpus=%d", cfg.Cpus) + params = append(params, "-smp", cpusParam) + } + + if !cfg.Legacy { + params = append(params, "-bios", qemuEfiFw) + } + return params +} + +func (q *qemu) startVM(vnicName, ipAddress string) error { + + var fds []*os.File + + glog.Info("Launching qemu") + + networkParams := make([]string, 0, 32) if vnicName != "" { if q.cfg.NetworkNode { @@ -446,36 +470,20 @@ func (q *qemu) startVM(vnicName, ipAddress string) error { return err } defer cleanupFds(fds, len(fds)) - params = append(params, macvtapParam...) + networkParams = append(networkParams, macvtapParam...) } else { tapParam, err := computeTapParam(vnicName, q.cfg.VnicMAC) if err != nil { return err } - params = append(params, tapParam...) + networkParams = append(networkParams, tapParam...) } } else { - params = append(params, "-net", "nic,model=virtio") - params = append(params, "-net", "user") + networkParams = append(networkParams, "-net", "nic,model=virtio") + networkParams = append(networkParams, "-net", "user") } - params = append(params, "-enable-kvm") - params = append(params, "-cpu", "host") - params = append(params, "-daemonize") - params = append(params, "-qmp", qmpParam) - - if q.cfg.Mem > 0 { - memoryParam := fmt.Sprintf("%d", q.cfg.Mem) - params = append(params, "-m", memoryParam) - } - if q.cfg.Cpus > 0 { - cpusParam := fmt.Sprintf("cpus=%d", q.cfg.Cpus) - params = append(params, "-smp", cpusParam) - } - - if !q.cfg.Legacy { - params = append(params, "-bios", qemuEfiFw) - } + params := generateQEMULaunchParams(q.cfg, q.isoPath, q.instanceDir, networkParams) var err error diff --git a/ciao-launcher/qemu_test.go b/ciao-launcher/qemu_test.go index a333119fc..282c49068 100644 --- a/ciao-launcher/qemu_test.go +++ b/ciao-launcher/qemu_test.go @@ -18,6 +18,7 @@ package main import ( "bytes" + "reflect" "testing" ) @@ -126,3 +127,73 @@ func TestExtractImageInfo(t *testing.T) { } } } + +func genQEMUParams(networkParams []string) []string { + baseParams := []string{ + "-drive", + "file=/var/lib/ciao/instance/1/image.qcow2,if=virtio,aio=threads,format=qcow2", + "-drive", + "file=/var/lib/ciao/instance/1/seed.iso,if=virtio,media=cdrom", + } + baseParams = append(baseParams, networkParams...) + baseParams = append(baseParams, "-enable-kvm", "-cpu", "host", "-daemonize", + "-qmp", "unix:/var/lib/ciao/instance/1/socket,server,nowait") + + return baseParams +} + +func TestGenerateQEMULaunchParams(t *testing.T) { + var cfg vmConfig + + params := genQEMUParams(nil) + cfg.Legacy = true + genParams := generateQEMULaunchParams(&cfg, "/var/lib/ciao/instance/1/seed.iso", + "/var/lib/ciao/instance/1", nil) + if !reflect.DeepEqual(params, genParams) { + t.Fatalf("%s and %s do not match", params, genParams) + } + + params = genQEMUParams(nil) + cfg.Legacy = false + cfg.Mem = 0 + cfg.Cpus = 0 + params = append(params, "-bios", qemuEfiFw) + genParams = generateQEMULaunchParams(&cfg, "/var/lib/ciao/instance/1/seed.iso", + "/var/lib/ciao/instance/1", nil) + if !reflect.DeepEqual(params, genParams) { + t.Fatalf("%s and %s do not match", params, genParams) + } + + params = genQEMUParams(nil) + cfg.Mem = 100 + cfg.Cpus = 0 + cfg.Legacy = true + params = append(params, "-m", "100") + genParams = generateQEMULaunchParams(&cfg, "/var/lib/ciao/instance/1/seed.iso", + "/var/lib/ciao/instance/1", nil) + if !reflect.DeepEqual(params, genParams) { + t.Fatalf("%s and %s do not match", params, genParams) + } + + params = genQEMUParams(nil) + cfg.Mem = 0 + cfg.Cpus = 4 + cfg.Legacy = true + params = append(params, "-smp", "cpus=4") + genParams = generateQEMULaunchParams(&cfg, "/var/lib/ciao/instance/1/seed.iso", + "/var/lib/ciao/instance/1", nil) + if !reflect.DeepEqual(params, genParams) { + t.Fatalf("%s and %s do not match", params, genParams) + } + + netParams := []string{"-net", "nic,model=virtio", "-net", "user"} + params = genQEMUParams(netParams) + cfg.Mem = 0 + cfg.Cpus = 0 + cfg.Legacy = true + genParams = generateQEMULaunchParams(&cfg, "/var/lib/ciao/instance/1/seed.iso", + "/var/lib/ciao/instance/1", netParams) + if !reflect.DeepEqual(params, genParams) { + t.Fatalf("%s and %s do not match", params, genParams) + } +}