diff mbox series

[v2] qga: fence guest-set-time if hwclock not available

Message ID 20191128181100.23187-1-cohuck@redhat.com
State New
Headers show
Series [v2] qga: fence guest-set-time if hwclock not available | expand

Commit Message

Cornelia Huck Nov. 28, 2019, 6:11 p.m. UTC
The Posix implementation of guest-set-time invokes hwclock to
set/retrieve the time to/from the hardware clock. If hwclock
is not available, the user is currently informed that "hwclock
failed to set hardware clock to system time", which is quite
misleading. This may happen e.g. on s390x, which has a different
timekeeping concept anyway.

Let's check for the availability of the hwclock command and
return QERR_UNSUPPORTED for guest-set-time if it is not available.

Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---

v1 (RFC) -> v2:
- use hwclock_path[]
- use access() instead of stat()

---
 qga/commands-posix.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

Comments

Laszlo Ersek Nov. 28, 2019, 6:38 p.m. UTC | #1
Hi Cornelia,

On 11/28/19 19:11, Cornelia Huck wrote:
> The Posix implementation of guest-set-time invokes hwclock to
> set/retrieve the time to/from the hardware clock. If hwclock
> is not available, the user is currently informed that "hwclock
> failed to set hardware clock to system time", which is quite
> misleading. This may happen e.g. on s390x, which has a different
> timekeeping concept anyway.
> 
> Let's check for the availability of the hwclock command and
> return QERR_UNSUPPORTED for guest-set-time if it is not available.
> 
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
> 
> v1 (RFC) -> v2:
> - use hwclock_path[]
> - use access() instead of stat()
> 
> ---
>  qga/commands-posix.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> index 1c1a165daed8..ffb6420fa9cd 100644
> --- a/qga/commands-posix.c
> +++ b/qga/commands-posix.c
> @@ -156,6 +156,17 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
>      pid_t pid;
>      Error *local_err = NULL;
>      struct timeval tv;
> +    const char hwclock_path[] = "/sbin/hwclock";

Did you drop the "static" storage-class specifier on purpose?

> +    static int hwclock_available = -1;
> +
> +    if (hwclock_available < 0) {
> +        hwclock_available = (access(hwclock_path, X_OK) == 0);
> +    }
> +
> +    if (!hwclock_available) {
> +        error_setg(errp, QERR_UNSUPPORTED);
> +        return;
> +    }
>  
>      /* If user has passed a time, validate and set it. */
>      if (has_time) {
> @@ -195,7 +206,7 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
>  
>          /* Use '/sbin/hwclock -w' to set RTC from the system time,
>           * or '/sbin/hwclock -s' to set the system time from RTC. */
> -        execle("/sbin/hwclock", "hwclock", has_time ? "-w" : "-s",
> +        execle(hwclock_path, "hwclock", has_time ? "-w" : "-s",

I think it's somewhat obscure now that arg="hwclock" is supposed to
match the last pathname component in hwclock_path="/sbin/hwclock".

There are multiple ways to compute "arg" like that, of course. But I
think they all look uglier than the above. So I'm fine if we just keep this.


If you purposely dropped the "static", then:

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

If you just missed the "static" and now intend to add it back, then for v3:

Reviewed-by: Laszlo Ersek <lersek@redhat.com>

Thanks
Laszlo



>                 NULL, environ);
>          _exit(EXIT_FAILURE);
>      } else if (pid < 0) {
>
Cornelia Huck Nov. 29, 2019, 7:56 a.m. UTC | #2
On Thu, 28 Nov 2019 19:38:00 +0100
Laszlo Ersek <lersek@redhat.com> wrote:

> Hi Cornelia,
> 
> On 11/28/19 19:11, Cornelia Huck wrote:
> > The Posix implementation of guest-set-time invokes hwclock to
> > set/retrieve the time to/from the hardware clock. If hwclock
> > is not available, the user is currently informed that "hwclock
> > failed to set hardware clock to system time", which is quite
> > misleading. This may happen e.g. on s390x, which has a different
> > timekeeping concept anyway.
> > 
> > Let's check for the availability of the hwclock command and
> > return QERR_UNSUPPORTED for guest-set-time if it is not available.
> > 
> > Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> > ---
> > 
> > v1 (RFC) -> v2:
> > - use hwclock_path[]
> > - use access() instead of stat()
> > 
> > ---
> >  qga/commands-posix.c | 13 ++++++++++++-
> >  1 file changed, 12 insertions(+), 1 deletion(-)
> > 
> > diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> > index 1c1a165daed8..ffb6420fa9cd 100644
> > --- a/qga/commands-posix.c
> > +++ b/qga/commands-posix.c
> > @@ -156,6 +156,17 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
> >      pid_t pid;
> >      Error *local_err = NULL;
> >      struct timeval tv;
> > +    const char hwclock_path[] = "/sbin/hwclock";  
> 
> Did you drop the "static" storage-class specifier on purpose?

No, I just need to do patches when I'm less tired :/

> 
> > +    static int hwclock_available = -1;
> > +
> > +    if (hwclock_available < 0) {
> > +        hwclock_available = (access(hwclock_path, X_OK) == 0);
> > +    }
> > +
> > +    if (!hwclock_available) {
> > +        error_setg(errp, QERR_UNSUPPORTED);
> > +        return;
> > +    }
> >  
> >      /* If user has passed a time, validate and set it. */
> >      if (has_time) {
> > @@ -195,7 +206,7 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
> >  
> >          /* Use '/sbin/hwclock -w' to set RTC from the system time,
> >           * or '/sbin/hwclock -s' to set the system time from RTC. */
> > -        execle("/sbin/hwclock", "hwclock", has_time ? "-w" : "-s",
> > +        execle(hwclock_path, "hwclock", has_time ? "-w" : "-s",  
> 
> I think it's somewhat obscure now that arg="hwclock" is supposed to
> match the last pathname component in hwclock_path="/sbin/hwclock".
> 
> There are multiple ways to compute "arg" like that, of course. But I
> think they all look uglier than the above. So I'm fine if we just keep this.

Yes, I was not able to come up with something elegant, either.

[Side note: does really everyone put hwclock under /sbin (i.e., nobody
doing something creative?)]

> 
> 
> If you purposely dropped the "static", then:
> 
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> 
> If you just missed the "static" and now intend to add it back, then for v3:
> 
> Reviewed-by: Laszlo Ersek <lersek@redhat.com>
> 
> Thanks
> Laszlo

Thanks for looking! There'll be a v3.

> 
> 
> 
> >                 NULL, environ);
> >          _exit(EXIT_FAILURE);
> >      } else if (pid < 0) {
> >   
>
Daniel P. Berrangé Nov. 29, 2019, 9:35 a.m. UTC | #3
On Thu, Nov 28, 2019 at 07:11:00PM +0100, Cornelia Huck wrote:
> The Posix implementation of guest-set-time invokes hwclock to
> set/retrieve the time to/from the hardware clock. If hwclock
> is not available, the user is currently informed that "hwclock
> failed to set hardware clock to system time", which is quite
> misleading. This may happen e.g. on s390x, which has a different
> timekeeping concept anyway.
> 
> Let's check for the availability of the hwclock command and
> return QERR_UNSUPPORTED for guest-set-time if it is not available.
> 
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
> 
> v1 (RFC) -> v2:
> - use hwclock_path[]
> - use access() instead of stat()
> 
> ---
>  qga/commands-posix.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>


Regards,
Daniel
Cornelia Huck Dec. 4, 2019, 2:12 p.m. UTC | #4
On Thu, 28 Nov 2019 19:11:00 +0100
Cornelia Huck <cohuck@redhat.com> wrote:

> The Posix implementation of guest-set-time invokes hwclock to
> set/retrieve the time to/from the hardware clock. If hwclock
> is not available, the user is currently informed that "hwclock
> failed to set hardware clock to system time", which is quite
> misleading. This may happen e.g. on s390x, which has a different
> timekeeping concept anyway.
> 
> Let's check for the availability of the hwclock command and
> return QERR_UNSUPPORTED for guest-set-time if it is not available.
> 
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>

Michael, any comments before I send a v3?

> ---
> 
> v1 (RFC) -> v2:
> - use hwclock_path[]
> - use access() instead of stat()
> 
> ---
>  qga/commands-posix.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> index 1c1a165daed8..ffb6420fa9cd 100644
> --- a/qga/commands-posix.c
> +++ b/qga/commands-posix.c
> @@ -156,6 +156,17 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
>      pid_t pid;
>      Error *local_err = NULL;
>      struct timeval tv;
> +    const char hwclock_path[] = "/sbin/hwclock";
> +    static int hwclock_available = -1;
> +
> +    if (hwclock_available < 0) {
> +        hwclock_available = (access(hwclock_path, X_OK) == 0);
> +    }
> +
> +    if (!hwclock_available) {
> +        error_setg(errp, QERR_UNSUPPORTED);
> +        return;
> +    }
>  
>      /* If user has passed a time, validate and set it. */
>      if (has_time) {
> @@ -195,7 +206,7 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
>  
>          /* Use '/sbin/hwclock -w' to set RTC from the system time,
>           * or '/sbin/hwclock -s' to set the system time from RTC. */
> -        execle("/sbin/hwclock", "hwclock", has_time ? "-w" : "-s",
> +        execle(hwclock_path, "hwclock", has_time ? "-w" : "-s",
>                 NULL, environ);
>          _exit(EXIT_FAILURE);
>      } else if (pid < 0) {
Michael Roth Dec. 4, 2019, 3:05 p.m. UTC | #5
Quoting Cornelia Huck (2019-11-28 12:11:00)
> The Posix implementation of guest-set-time invokes hwclock to
> set/retrieve the time to/from the hardware clock. If hwclock
> is not available, the user is currently informed that "hwclock
> failed to set hardware clock to system time", which is quite
> misleading. This may happen e.g. on s390x, which has a different
> timekeeping concept anyway.
> 
> Let's check for the availability of the hwclock command and
> return QERR_UNSUPPORTED for guest-set-time if it is not available.
> 
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>

Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>

> ---
> 
> v1 (RFC) -> v2:
> - use hwclock_path[]
> - use access() instead of stat()
> 
> ---
>  qga/commands-posix.c | 13 ++++++++++++-
>  1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> index 1c1a165daed8..ffb6420fa9cd 100644
> --- a/qga/commands-posix.c
> +++ b/qga/commands-posix.c
> @@ -156,6 +156,17 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
>      pid_t pid;
>      Error *local_err = NULL;
>      struct timeval tv;
> +    const char hwclock_path[] = "/sbin/hwclock";
> +    static int hwclock_available = -1;
> +
> +    if (hwclock_available < 0) {
> +        hwclock_available = (access(hwclock_path, X_OK) == 0);
> +    }
> +
> +    if (!hwclock_available) {
> +        error_setg(errp, QERR_UNSUPPORTED);
> +        return;
> +    }
>  
>      /* If user has passed a time, validate and set it. */
>      if (has_time) {
> @@ -195,7 +206,7 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
>  
>          /* Use '/sbin/hwclock -w' to set RTC from the system time,
>           * or '/sbin/hwclock -s' to set the system time from RTC. */
> -        execle("/sbin/hwclock", "hwclock", has_time ? "-w" : "-s",
> +        execle(hwclock_path, "hwclock", has_time ? "-w" : "-s",
>                 NULL, environ);
>          _exit(EXIT_FAILURE);
>      } else if (pid < 0) {
> -- 
> 2.21.0
>
diff mbox series

Patch

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 1c1a165daed8..ffb6420fa9cd 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -156,6 +156,17 @@  void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
     pid_t pid;
     Error *local_err = NULL;
     struct timeval tv;
+    const char hwclock_path[] = "/sbin/hwclock";
+    static int hwclock_available = -1;
+
+    if (hwclock_available < 0) {
+        hwclock_available = (access(hwclock_path, X_OK) == 0);
+    }
+
+    if (!hwclock_available) {
+        error_setg(errp, QERR_UNSUPPORTED);
+        return;
+    }
 
     /* If user has passed a time, validate and set it. */
     if (has_time) {
@@ -195,7 +206,7 @@  void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
 
         /* Use '/sbin/hwclock -w' to set RTC from the system time,
          * or '/sbin/hwclock -s' to set the system time from RTC. */
-        execle("/sbin/hwclock", "hwclock", has_time ? "-w" : "-s",
+        execle(hwclock_path, "hwclock", has_time ? "-w" : "-s",
                NULL, environ);
         _exit(EXIT_FAILURE);
     } else if (pid < 0) {