[dm-devel] [PATCH 1/4] libmultipath: handle clock_gettime failures in tur checker
Benjamin Marzinski
bmarzins at redhat.com
Tue May 21 01:02:38 UTC 2019
On Fri, May 17, 2019 at 11:55:48PM +0200, Martin Wilck wrote:
> On Fri, 2019-05-17 at 11:14 -0500, Benjamin Marzinski wrote:
> > If clock_gettime() fails, and multipathd can't figure out when it
> > should
> > time out, it should just default to assuming that it has already
> > timed
> > out. Found by coverity.
> >
> > Signed-off-by: Benjamin Marzinski <bmarzins at redhat.com>
> > ---
> > libmultipath/checkers/tur.c | 19 +++++++++++++++----
> > 1 file changed, 15 insertions(+), 4 deletions(-)
>
> I know coverity picks on this, but I don't like the result. It's
> superfluous IMO, and uglifies the code.
>
> Other than passing an invalid address (unlikely because basically every
> caller uses memory from the stack), the only possible reason for
> failure in clock_gettime is "EINVAL - The clk_id specified is not
> supported on this system".
>
> We have this code in pthread_cond_init_mono():
>
> res = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
> assert(res == 0);
>
> this is called when initializing config_cond. So multipathd at least
> won't even start if CLOCK_MONOTONIC is unsupported.
>
> If that's not enough, I don't mind putting such a check in
> mpath_lib_init() and refuse to start on systems without
> CLOCK_MONOTONIC, then stop bothering with the return value of
> clock_gettime() in the rest of the code.
>
> Regards,
> Martin
I'm fine with dropping this one. We just have so many other checks for
the return on this call that I thought that there was possibly some
important error condition that the man page didn't mention.
I'll repost the set without it.
-Ben
>
>
> > diff --git a/libmultipath/checkers/tur.c
> > b/libmultipath/checkers/tur.c
> > index 6b08dbbb..717353ef 100644
> > --- a/libmultipath/checkers/tur.c
> > +++ b/libmultipath/checkers/tur.c
> > @@ -290,7 +290,12 @@ static void *tur_thread(void *ctx)
> >
> > static void tur_timeout(struct timespec *tsp)
> > {
> > - clock_gettime(CLOCK_MONOTONIC, tsp);
> > + if (clock_gettime(CLOCK_MONOTONIC, tsp) != 0) {
> > + /* can't get time. clear tsp to not wait */
> > + tsp->tv_sec = 0;
> > + tsp->tv_nsec = 0;
> > + return;
> > + }
> > tsp->tv_nsec += 1000 * 1000; /* 1 millisecond */
> > normalize_timespec(tsp);
> > }
> > @@ -300,8 +305,12 @@ static void tur_set_async_timeout(struct checker
> > *c)
> > struct tur_checker_context *ct = c->context;
> > struct timespec now;
> >
> > - clock_gettime(CLOCK_MONOTONIC, &now);
> > - ct->time = now.tv_sec + c->timeout;
> > + if (clock_gettime(CLOCK_MONOTONIC, &now) != 0)
> > + /* can't get time. clear time to always timeout on
> > + * next path check */
> > + ct->time = 0;
> > + else
> > + ct->time = now.tv_sec + c->timeout;
> > }
> >
> > static int tur_check_async_timeout(struct checker *c)
> > @@ -309,7 +318,9 @@ static int tur_check_async_timeout(struct checker
> > *c)
> > struct tur_checker_context *ct = c->context;
> > struct timespec now;
> >
> > - clock_gettime(CLOCK_MONOTONIC, &now);
> > + if (clock_gettime(CLOCK_MONOTONIC, &now) != 0)
> > + /* can't get time. assume we've timed out */
> > + return 1;
> > return (now.tv_sec > ct->time);
> > }
> >
>
More information about the dm-devel
mailing list