[Pcsclite-muscle] [PATCH V3] revamp libudev hotplug

Stefani Seibold stefani at seibold.net
Thu Nov 6 21:33:30 UTC 2014


Hi Ludovic,

this is a cleaned up version of your patch without the race. I moved the
activation of the udev monitor into HPRegisterForHotplugEvents(). So the
monitor will now started again before the scan.

But i have no idea why this was and is a problem. To scan for USB
devices before accepting a connection makes no difference, the USB
devices will sooner or later appear.

A client which assumes that there are available devices when open a
communication is wrong implemented since there are timing assumptions
which can fail. Imaging that some other devices will be added some other
devices to the same USB bus, then the PCSCD client could be started
before the device was enumerated by the kernel. 

So if no devices are found the client must do a rescan...  

Regards,
Stefani


Index: src/hotplug_libudev.c
===================================================================
--- src/hotplug_libudev.c	(revision 7029)
+++ src/hotplug_libudev.c	(working copy)
@@ -556,9 +556,9 @@
 }
 
 
-static void HPEstablishUSBNotifications(void *notused)
+static void HPEstablishUSBNotifications(void *arg)
 {
-	struct udev_monitor *udev_monitor;
+	struct udev_monitor *udev_monitor = arg;
 	int r;
 	int fd;
 	struct pollfd pfd;
@@ -566,29 +566,6 @@
 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
 	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
 
-	udev_monitor = udev_monitor_new_from_netlink(Udev, "udev");
-	if (NULL == udev_monitor)
-	{
-		Log1(PCSC_LOG_ERROR, "udev_monitor_new_from_netlink() error");
-		pthread_exit(NULL);
-	}
-
-	/* filter only the interfaces */
-	r = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb",
-		"usb_interface");
-	if (r)
-	{
-		Log2(PCSC_LOG_ERROR, "udev_monitor_filter_add_match_subsystem_devtype() error: %d\n", r);
-		pthread_exit(NULL);
-	}
-
-	r = udev_monitor_enable_receiving(udev_monitor);
-	if (r)
-	{
-		Log2(PCSC_LOG_ERROR, "udev_monitor_enable_receiving() error: %d\n", r);
-		pthread_exit(NULL);
-	}
-
 	/* udev monitor file descriptor */
 	fd = udev_monitor_get_fd(udev_monitor);
 	if (fd < 0)
@@ -706,6 +683,9 @@
  */
 ULONG HPRegisterForHotplugEvents(void)
 {
+	struct udev_monitor *udev_monitor;
+	int r;
+
 	if (driverSize <= 0)
 	{
 		Log1(PCSC_LOG_INFO, "No bundle files in pcsc drivers directory: "
@@ -722,11 +702,34 @@
 		return SCARD_F_INTERNAL_ERROR;
 	}
 
+	udev_monitor = udev_monitor_new_from_netlink(Udev, "udev");
+	if (NULL == udev_monitor)
+	{
+		Log1(PCSC_LOG_ERROR, "udev_monitor_new_from_netlink() error");
+		pthread_exit(NULL);
+	}
+
+	/* filter only the interfaces */
+	r = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb",
+		"usb_interface");
+	if (r)
+	{
+		Log2(PCSC_LOG_ERROR, "udev_monitor_filter_add_match_subsystem_devtype() error: %d\n", r);
+		pthread_exit(NULL);
+	}
+
+	r = udev_monitor_enable_receiving(udev_monitor);
+	if (r)
+	{
+		Log2(PCSC_LOG_ERROR, "udev_monitor_enable_receiving() error: %d\n", r);
+		pthread_exit(NULL);
+	}
+
 	/* scan the USB bus at least once before accepting client connections */
 	HPScanUSB(Udev);
 
 	if (ThreadCreate(&usbNotifyThread, 0,
-		(PCSCLITE_THREAD_FUNCTION( )) HPEstablishUSBNotifications, NULL))
+		(PCSCLITE_THREAD_FUNCTION( )) HPEstablishUSBNotifications, udev_monitor))
 	{
 		Log1(PCSC_LOG_ERROR, "ThreadCreate() failed");
 		return SCARD_F_INTERNAL_ERROR;





More information about the Pcsclite-muscle mailing list