[libvirt] [PATCH v4 7/7] nodedev: Work around the uevent race by hooking up virFileWaitForAccess

Erik Skultety eskultet at redhat.com
Thu Sep 28 10:09:11 UTC 2017


On Wed, Sep 20, 2017 at 10:33:14AM -0400, John Ferlan wrote:
>
>
> On 09/18/2017 12:34 PM, Erik Skultety wrote:
> > If we find ourselves in the situation that the 'add' uevent has been
> > fired earlier than the sysfs tree for a device was created, we should
> > use the best-effort approach and give kernel some predetermined amount
> > of time, thus waiting for the attributes to be ready rather than
> > discarding the device from our device list forever. If those don't appear
> > in the given time frame, we need to move on, since libvirt can't wait
> > indefinitely.
> >
> > Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1463285
> >
> > Signed-off-by: Erik Skultety <eskultet at redhat.com>
> > ---
> >  src/node_device/node_device_udev.c | 16 +++++++++++++++-
> >  1 file changed, 15 insertions(+), 1 deletion(-)
> >
> > diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
> > index 70e15ffb8..2f63256a3 100644
> > --- a/src/node_device/node_device_udev.c
> > +++ b/src/node_device/node_device_udev.c
> > @@ -1166,9 +1166,23 @@ udevProcessMediatedDevice(struct udev_device *dev,
> >      char *canonicalpath = NULL;
> >      virNodeDevCapMdevPtr data = &def->caps->data.mdev;
> >
> > -    if (virAsprintf(&linkpath, "%s/mdev_type", udev_device_get_syspath(dev)) < 0)
> > +    /* Because of a kernel uevent race, we might get the 'add' event prior to
> > +     * the sysfs tree being ready, so any attempt to access any sysfs attribute
> > +     * would result in ENOENT and us dropping the device, so let's work around
> > +     * it by waiting for the attributes to become available.
> > +     */
> > +
> > +    if (virAsprintf(&linkpath, "%s/mdev_type",
> > +                    udev_device_get_syspath(dev)) < 0)
> >          goto cleanup;
> >
> > +    if (virFileWaitForExists(linkpath, 1, 100) < 0) {
> > +        virReportSystemError(errno,
> > +                             _("failed to wait for file '%s' to appear"),
> > +                             linkpath);
> > +        goto cleanup;
> > +    }
> > +
>
> So the linkpath gets created after the canonicalpath... and we don't

Well, I would assume so, I believe that the kernel wouldn't create symlinks
first and the canonical paths second, such a design would be sooo broken.

Thanks,
Erik

> have to check that right?
>
> Considering what I pointed out in my previous review - I wouldn't be
> able to use virFileWaitForExists, but a similar loop would be possible.
> For NPIV the file exists, it's the contents that are bogus momentarily.
>
> Other consumers waiting that I looked at usually wait on some sort of
> open() and usleep() when ENOENT is returned (there's multiple examples
> if you search on ulseep).  Wonder if any of those could utilize
> something like this...  I know patches welcome ;-)
>
> Reviewed-by: John Ferlan <jferlan at redhat.com>
>
>
> >      if (virFileResolveLink(linkpath, &canonicalpath) < 0) {
> >          virReportSystemError(errno, _("failed to resolve '%s'"), linkpath);
> >          goto cleanup;
> >




More information about the libvir-list mailing list