[dm-devel] [PATCH 5/7] multipathd: set DAEMON_CONFIGURE from uxlsnr thread
Martin Wilck
mwilck at suse.com
Tue Oct 30 16:55:06 UTC 2018
On Fri, 2018-10-26 at 15:19 -0500, Benjamin Marzinski wrote:
> On Wed, Oct 24, 2018 at 12:05:50AM +0200, Martin Wilck wrote:
> > Commit ee01e841 had the intention to make multipathd quit if
> > the client socket couldn't be set up, because the unix socket
> > listener is vital for signal handling in multipathd.
> > But during startup, this condition might be lost if the main
> > thread doesn't wait for the unix listener to initialize.
> >
> > Fixes: ee01e841 "multipathd: handle errors in uxlsnr as fatal"
> > Signed-off-by: Martin Wilck <mwilck at suse.com>
> > ---
> > multipathd/main.c | 43 ++++++++++++++++++++++++++++++++-----------
> > 1 file changed, 32 insertions(+), 11 deletions(-)
> >
> > diff --git a/multipathd/main.c b/multipathd/main.c
> > index 50f69171..c71e7d03 100644
> > --- a/multipathd/main.c
> > +++ b/multipathd/main.c
> > @@ -2726,11 +2736,26 @@ child (void * param)
> > */
> > conf = NULL;
> >
> > - /*
> > - * Signal start of configuration
> > - */
> > - post_config_state(DAEMON_CONFIGURE);
> > + pthread_cleanup_push(config_cleanup, NULL);
> > + pthread_mutex_lock(&config_lock);
> >
> > + __post_config_state(DAEMON_IDLE);
>
> I don't really understand the need for
> __post_config_state(). Couldn't
> you just call post_config_state(DAEMON_IDLE), and then grab the
> config_lock after checking that the thread was created
> successfully. If
> the scheduler decides to run the uxlsnrloop thread before continuing
> with the child thread, it would be better if uxlsnrloop thread was
> free
> to grab the config lock anyway.
I wanted to enforce ordering here. The uxlsnr won't be able to grab the
lock and change running_state until the child enters
pthread_cond_wait() below, which is intentional. running_state
shouldn't be read or written without holding the lock, so this actually
saves us an unlock/lock operation, as child() would otherwise need to
release the lock before calling pthread_create(), and reacquire it
afterwards. This way the startup sequence is fully deterministic and
doesn't depend on scheduler decisions. I like it that way :-)
> At any rate, what you have is perfectly correct, so
>
> Reviewed-by: Benjamin Marzinsk <bmarzins at redhat.com>
Thanks a lot.
Martin
>
> > + rc = pthread_create(&uxlsnr_thr, &misc_attr, uxlsnrloop, vecs);
> > + if (!rc) {
> > + /* Wait for uxlsnr startup */
> > + while (running_state == DAEMON_IDLE)
> > + pthread_cond_wait(&config_cond, &config_lock);
> > + }
> > + pthread_cleanup_pop(1);
> > +
> > + if (rc) {
> > + condlog(0, "failed to create cli listener: %d", rc);
> > + goto failed;
> > + }
> > + else if (running_state != DAEMON_CONFIGURE) {
> > + condlog(0, "cli listener failed to start");
> > + goto failed;
> > + }
> >
> > if (poll_dmevents) {
> > if (init_dmevent_waiter(vecs)) {
> > @@ -2753,10 +2778,6 @@ child (void * param)
> > goto failed;
> > }
> > pthread_attr_destroy(&uevent_attr);
> > - if ((rc = pthread_create(&uxlsnr_thr, &misc_attr, uxlsnrloop,
> > vecs))) {
> > - condlog(0, "failed to create cli listener: %d", rc);
> > - goto failed;
> > - }
> >
> > /*
> > * start threads
> > --
> > 2.19.1
--
Dr. Martin Wilck <mwilck at suse.com>, Tel. +49 (0)911 74053 2107
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
More information about the dm-devel
mailing list