[libcamera-devel] [PATCH v2] libcamera: device_enumerator: Don't stop if one device fails
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Tue Feb 18 00:24:02 CET 2020
Hi Kieran,
On Mon, Feb 17, 2020 at 11:56:42AM +0000, Kieran Bingham wrote:
> On 17/02/2020 11:03, Laurent Pinchart wrote:
> > If one device fails to enumerate, which isn't supposed to happen under
> > normal conditions, both the sysfs and the udev enumerators stop
> > enumeration of further devices. This potentially prevents working
> > devices from being detected and handled. Fix it by skipping the faulty
> > device.
> >
> > Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
>
> The addition of the prints for /which/ device fails don't help my use
> case as I fail before getting to those prints
> (DeviceEnumerator::createDevice)
>
> We can't add any further introspection of the MediaDevice in
> ::createDevice anyway, so that can't be extended to say more information
> about the device.
Yes, if we fail to retrieve information from the device, then we can
hardly print it :-)
> MediaDevice::populate() however is painful, as it discards the actual
> return value of the MEDIA_IOC_DEVICE_INFO, and
> MEDIA_IOC_G_TOPOLOGY,ioctls in event of those failing and instead
> returns -EINVAL ...
>
> But that is not a topic for /this/ patch.
Agreed.
It could also be useful to make MediaDevice inherit from Loggable.
> Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> (and still Tested-by: KB too if you desire)
Absolutely, thank you.
> > ---
> > Changes since v1:
> >
> > - Add more warning messages to DeviceEnumeratorUdev
> > - Use media->deviceNode() and print the driver name where appropriate
> > ---
> > src/libcamera/device_enumerator_sysfs.cpp | 16 +++++++--------
> > src/libcamera/device_enumerator_udev.cpp | 25 ++++++++++++++++-------
> > 2 files changed, 26 insertions(+), 15 deletions(-)
> >
> > diff --git a/src/libcamera/device_enumerator_sysfs.cpp b/src/libcamera/device_enumerator_sysfs.cpp
> > index ad26affb38a3..197ca235879b 100644
> > --- a/src/libcamera/device_enumerator_sysfs.cpp
> > +++ b/src/libcamera/device_enumerator_sysfs.cpp
> > @@ -33,7 +33,6 @@ int DeviceEnumeratorSysfs::enumerate()
> > {
> > struct dirent *ent;
> > DIR *dir;
> > - int ret = 0;
> >
> > static const char * const sysfs_dirs[] = {
> > "/sys/subsystem/media/devices",
> > @@ -74,14 +73,15 @@ int DeviceEnumeratorSysfs::enumerate()
> > }
> >
> > std::shared_ptr<MediaDevice> media = createDevice(devnode);
> > - if (!media) {
> > - ret = -ENODEV;
> > - break;
> > - }
> > + if (!media)
> > + continue;
> >
> > if (populateMediaDevice(media) < 0) {
> > - ret = -ENODEV;
> > - break;
> > + LOG(DeviceEnumerator, Warning)
> > + << "Failed to populate media device "
> > + << media->deviceNode()
> > + << " (" << media->driver() << "), skipping";
> > + continue;
> > }
> >
> > addDevice(media);
> > @@ -89,7 +89,7 @@ int DeviceEnumeratorSysfs::enumerate()
> >
> > closedir(dir);
> >
> > - return ret;
> > + return 0;
> > }
> >
> > int DeviceEnumeratorSysfs::populateMediaDevice(const std::shared_ptr<MediaDevice> &media)
> > diff --git a/src/libcamera/device_enumerator_udev.cpp b/src/libcamera/device_enumerator_udev.cpp
> > index b2c5fd221dcd..87638c59761c 100644
> > --- a/src/libcamera/device_enumerator_udev.cpp
> > +++ b/src/libcamera/device_enumerator_udev.cpp
> > @@ -82,8 +82,15 @@ int DeviceEnumeratorUdev::addUdevDevice(struct udev_device *dev)
> > return -ENODEV;
> >
>
> Interestingly - actually in my testing of the failures, I don't get to
> the code below.
>
> The failure occurs during media->populate() which is called from
> createDevice, which has just returned -ENODEV above here.
>
> And while it is valid to call media->driver() below - it's not valid
> here, as the created device didn't get created :-D
>
> > int ret = populateMediaDevice(media);
> > - if (ret == 0)
> > - addDevice(media);
> > + if (ret < 0) {
> > + LOG(DeviceEnumerator, Warning)
> > + << "Failed to populate media device "
> > + << media->deviceNode()
> > + << " (" << media->driver() << "), skipping";
> > + return ret;
> > + }
> > +
> > + addDevice(media);
> > return 0;
> > }
> >
> > @@ -141,14 +148,18 @@ int DeviceEnumeratorUdev::enumerate()
> > devnode = udev_device_get_devnode(dev);
> > if (!devnode) {
> > udev_device_unref(dev);
> > - ret = -ENODEV;
> > - goto done;
> > + LOG(DeviceEnumerator, Warning)
> > + << "Failed to get device node for '"
> > + << syspath << "', skipping";
> > + continue;
> > }
> >
> > - ret = addUdevDevice(dev);
> > + if (addUdevDevice(dev) < 0)
> > + LOG(DeviceEnumerator, Warning)
> > + << "Failed to add device for '"
> > + << syspath << "', skipping";
> > +
> > udev_device_unref(dev);
> > - if (ret < 0)
> > - break;
> > }
> >
> > done:
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list