Am Donnerstag, den 09.07.2015, 14:11 +0100 schrieb Brian Potkin:
> The word "sometimes" isn't one which brings joy to the heart when bug
> hunting. :)
Yes, I know, sorry. It is also confusing for me. As I wrote in one of
my later follow-ups, if I "killall -9 usb" the backend, the next
printing attempt may work without a flaw. thus, I suspect something
like a race condition as the culprit.
> How ofter does this happen? Has it just appeared with cups 2.0.3?
No, it also happened with cups 1.x. I just didn't find the time and
nerves to report the bug, because - just as you said - "it sometimes
dosn't work" isn't a good bug description to start with. ;)
> > ioctl(15, USBDEVFS_CLAIMINTERFACE, 0x7fffad353bfc) = -1 EBUSY
> > (Device or resource busy)
I believe that the code which causes this is the following in
backend/usb-libusb.c:1515:
while ((errcode = libusb_claim_interface(printer->handle, number1)) < 0)
{
if (errcode != LIBUSB_ERROR_BUSY)
{
fprintf(stderr,
"DEBUG: Failed to claim interface %d for %04x:%04x: %s\n",
number1, devdesc.idVendor, devdesc.idProduct, strerror(errno));
goto error;
}
}
So, what it does is trying to claim the interface and if the error code
isn't LIBUSB_ERROR_BUSY it busts out. But what if the error code
actually is LIBUSB_ERROR_BUSY? then the code is dead-locked in this
loop and tries to claim the interface endlessly. I think this is what I
see on my system.
Well, it's not that easy. Actually, LIBUSB_ERROR_BUSY is only returned
if the USB interface is already claimed, e.g. by a kernel driver. This
is checked earlier in the code in line 1437: If the return value of
libusb_kernel_driver_active() is 1 then a kernel driver is active and
libusb_detach_kernel_driver() is called. So, it should be impossible
for the interface to be already claimed when the code in line 1515 is
called. But, one never knows, and repeatedly calling
libusb_claim_interface() over and over again won't help if the culprit
is LIBUSB_ERROR_BUSY but this is never checked for.
Thus, I assume that the following patch might work, but i am not sure
yet, because, you know, it only happens "sometimes". ;)
--- a/cups-2.0.3/backend/usb-libusb.c
+++ b/home/greffrath/usb-libusb.c
@@ -1522,6 +1522,16 @@ open_device(usb_printer_t *printer, /* I - Printer */
goto error;
}
+ else if ((errcode = libusb_detach_kernel_driver(printer->handle, printer->iface)) < 0)
+ {
+ fprintf(stderr,
+ "DEBUG: Failed to detach \"usblp\" module from %04x:%04x\n",
+ devdesc.idVendor, devdesc.idProduct);
+
+ goto error;
+ }
+
+ sleep (1);
}
/*
I added a sleep(1) call to prevent this loop from eating up 100% cpu as
it currently does. Do you think you could carry this issue and my
suggested patch upstream?
Thank you very much already!
Cheers,
Fabian
Attachment:
signature.asc
Description: This is a digitally signed message part