qemu-ga-win: Fail loudly on bare 'set-time'
The command is not implemented correctly yet. The documentation allows to not pass any value to set, in which case the time is re-read from RTC. However, reading CMOS on Windows is not trivial to implement. So instead of pretending we've set the correct time, fail explicitly. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
This commit is contained in:
		
							parent
							
								
									0dd38a03f5
								
							
						
					
					
						commit
						ee17cbdc3c
					
				| @ -625,31 +625,31 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp) | ||||
|     FILETIME tf; | ||||
|     LONGLONG time; | ||||
| 
 | ||||
|     if (has_time) { | ||||
|         /* Okay, user passed a time to set. Validate it. */ | ||||
|         if (time_ns < 0 || time_ns / 100 > INT64_MAX - W32_FT_OFFSET) { | ||||
|             error_setg(errp, "Time %" PRId64 "is invalid", time_ns); | ||||
|             return; | ||||
|         } | ||||
|     if (!has_time) { | ||||
|         /* Unfortunately, Windows libraries don't provide an easy way to access
 | ||||
|          * RTC yet: | ||||
|          * | ||||
|          * https://msdn.microsoft.com/en-us/library/aa908981.aspx
 | ||||
|          */ | ||||
|         error_setg(errp, "Time argument is required on this platform"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|         time = time_ns / 100 + W32_FT_OFFSET; | ||||
|     /* Validate time passed by user. */ | ||||
|     if (time_ns < 0 || time_ns / 100 > INT64_MAX - W32_FT_OFFSET) { | ||||
|         error_setg(errp, "Time %" PRId64 "is invalid", time_ns); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|         tf.dwLowDateTime = (DWORD) time; | ||||
|         tf.dwHighDateTime = (DWORD) (time >> 32); | ||||
|     time = time_ns / 100 + W32_FT_OFFSET; | ||||
| 
 | ||||
|         if (!FileTimeToSystemTime(&tf, &ts)) { | ||||
|             error_setg(errp, "Failed to convert system time %d", | ||||
|                        (int)GetLastError()); | ||||
|             return; | ||||
|         } | ||||
|     } else { | ||||
|         /* Otherwise read the time from RTC which contains the correct value.
 | ||||
|          * Hopefully. */ | ||||
|         GetSystemTime(&ts); | ||||
|         if (ts.wYear < 1601 || ts.wYear > 30827) { | ||||
|             error_setg(errp, "Failed to get time"); | ||||
|             return; | ||||
|         } | ||||
|     tf.dwLowDateTime = (DWORD) time; | ||||
|     tf.dwHighDateTime = (DWORD) (time >> 32); | ||||
| 
 | ||||
|     if (!FileTimeToSystemTime(&tf, &ts)) { | ||||
|         error_setg(errp, "Failed to convert system time %d", | ||||
|                    (int)GetLastError()); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     acquire_privilege(SE_SYSTEMTIME_NAME, &local_err); | ||||
|  | ||||
| @ -121,7 +121,10 @@ | ||||
| # given value, then sets the Hardware Clock (RTC) to the | ||||
| # current System Time. This will make it easier for a guest | ||||
| # to resynchronize without waiting for NTP. If no @time is | ||||
| # specified, then the time to set is read from RTC. | ||||
| # specified, then the time to set is read from RTC. However, | ||||
| # this may not be supported on all platforms (i.e. Windows). | ||||
| # If that's the case users are advised to always pass a | ||||
| # value. | ||||
| # | ||||
| # @time: #optional time of nanoseconds, relative to the Epoch | ||||
| #        of 1970-01-01 in UTC. | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Michal Privoznik
						Michal Privoznik