diff --git a/qemu.go b/qemu.go index 6e2c06b291..3c42bfd394 100644 --- a/qemu.go +++ b/qemu.go @@ -329,16 +329,66 @@ func (dev SerialDevice) Valid() bool { return true } +// RTCBaseType is the qemu RTC base time type. +type RTCBaseType string + +// RTCClock is the qemu RTC clock type. +type RTCClock string + +// RTCDriftFix is the qemu RTC drift fix type. +type RTCDriftFix string + +const ( + // UTC is the UTC base time for qemu RTC. + UTC RTCBaseType = "utc" + + // LocalTime is the local base time for qemu RTC. + LocalTime = "localtime" +) + +const ( + // Host is for using the host clock as a reference. + Host RTCClock = "host" + + // VM is for using the guest clock as a reference + VM = "vm" +) + +const ( + // Slew is the qemu RTC Drift fix mechanism. + Slew RTCDriftFix = "slew" + + // NoDriftFix means we don't want/need to fix qemu's RTC drift. + NoDriftFix = "none" +) + // RTC represents a qemu Real Time Clock configuration. type RTC struct { // Base is the RTC start time. - Base string + Base RTCBaseType // Clock is the is the RTC clock driver. - Clock string + Clock RTCClock // DriftFix is the drift fixing mechanism. - DriftFix string + DriftFix RTCDriftFix +} + +// Valid returns true if the RTC structure is valid and complete. +func (rtc RTC) Valid() bool { + if rtc.Clock != "" { + if rtc.Clock != Host && rtc.Clock != VM { + return false + } + } + + if rtc.DriftFix != "" { + if rtc.DriftFix != Slew && rtc.DriftFix != NoDriftFix { + return false + } + } + + return true } // QMPSocket represents a qemu QMP socket configuration. @@ -725,23 +775,25 @@ func appendCPUs(params []string, config Config) []string { } func appendRTC(params []string, config Config) []string { - if config.RTC.Base != "" { - var RTCParams []string - - RTCParams = append(RTCParams, fmt.Sprintf("base=%s", config.RTC.Base)) - - if config.RTC.DriftFix != "" { - RTCParams = append(RTCParams, fmt.Sprintf(",driftfix=%s", config.RTC.DriftFix)) - } - - if config.RTC.Clock != "" { - RTCParams = append(RTCParams, fmt.Sprintf(",clock=%s", config.RTC.Clock)) - } - - params = append(params, "-rtc") - params = append(params, strings.Join(RTCParams, "")) + if config.RTC.Valid() == false { + return nil } + var RTCParams []string + + RTCParams = append(RTCParams, fmt.Sprintf("base=%s", string(config.RTC.Base))) + + if config.RTC.DriftFix != "" { + RTCParams = append(RTCParams, fmt.Sprintf(",driftfix=%s", config.RTC.DriftFix)) + } + + if config.RTC.Clock != "" { + RTCParams = append(RTCParams, fmt.Sprintf(",clock=%s", config.RTC.Clock)) + } + + params = append(params, "-rtc") + params = append(params, strings.Join(RTCParams, "")) + return params } diff --git a/qemu_test.go b/qemu_test.go index ec5a73af7f..fc5d7447cf 100644 --- a/qemu_test.go +++ b/qemu_test.go @@ -75,6 +75,13 @@ func testAppend(structure interface{}, expected string, t *testing.T) { } params = appendQMPSocket([]string{}, config) + + case RTC: + config := Config{ + RTC: s, + } + + params = appendRTC([]string{}, config) } result := strings.Join(params, " ") @@ -281,3 +288,15 @@ func TestAppendStrings(t *testing.T) { t.Fatalf("Failed to append parameters [%s] != [%s]", result, qemuString) } } + +var rtcString = "-rtc base=utc,driftfix=slew,clock=host" + +func TestAppendRTC(t *testing.T) { + rtc := RTC{ + Base: UTC, + Clock: Host, + DriftFix: Slew, + } + + testAppend(rtc, rtcString, t) +}