All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lars Gunnarsson <gunnarsson.lars@gmail.com>
To: Valentina Manea <valentina.manea.m@gmail.com>,
	Shuah Khan <shuah@kernel.org>,
	linux-usb@vger.kernel.org
Subject: [PATCH v1 1/3] tools/usbip: support use case reconnect: prepare
Date: Wed, 6 Oct 2021 22:48:17 +0200	[thread overview]
Message-ID: <20211006204817.GA43927@dell-precision-T3610> (raw)

This patch implements an usb monitor into libusbip to await usb events,
example connect and disconnect.

Signed-off-by: Lars Gunnarsson <gunnarsson.lars@gmail.com>
---
 tools/usb/usbip/.gitignore             |   1 +
 tools/usb/usbip/libsrc/Makefile.am     |   3 +-
 tools/usb/usbip/libsrc/usbip_common.h  |   1 +
 tools/usb/usbip/libsrc/usbip_monitor.c | 147 +++++++++++++++++++++++++
 tools/usb/usbip/libsrc/usbip_monitor.h |  21 ++++
 5 files changed, 172 insertions(+), 1 deletion(-)
 create mode 100644 tools/usb/usbip/libsrc/usbip_monitor.c
 create mode 100644 tools/usb/usbip/libsrc/usbip_monitor.h

diff --git a/tools/usb/usbip/.gitignore b/tools/usb/usbip/.gitignore
index 597361a96dbb..6304adefb5e1 100644
--- a/tools/usb/usbip/.gitignore
+++ b/tools/usb/usbip/.gitignore
@@ -28,6 +28,7 @@ libsrc/libusbip_la-usbip_common.lo
 libsrc/libusbip_la-usbip_device_driver.lo
 libsrc/libusbip_la-usbip_host_common.lo
 libsrc/libusbip_la-usbip_host_driver.lo
+libsrc/libusbip_la-usbip_monitor.lo
 libsrc/libusbip_la-vhci_driver.lo
 src/usbip
 src/usbipd
diff --git a/tools/usb/usbip/libsrc/Makefile.am b/tools/usb/usbip/libsrc/Makefile.am
index dabd2c91d311..3e31e33729cf 100644
--- a/tools/usb/usbip/libsrc/Makefile.am
+++ b/tools/usb/usbip/libsrc/Makefile.am
@@ -8,4 +8,5 @@ libusbip_la_SOURCES := names.c names.h usbip_host_driver.c usbip_host_driver.h \
 		       usbip_device_driver.c usbip_device_driver.h \
 		       usbip_common.c usbip_common.h usbip_host_common.h \
 		       usbip_host_common.c vhci_driver.c vhci_driver.h \
-		       sysfs_utils.c sysfs_utils.h
+		       sysfs_utils.c sysfs_utils.h \
+		       usbip_monitor.c
diff --git a/tools/usb/usbip/libsrc/usbip_common.h b/tools/usb/usbip/libsrc/usbip_common.h
index 73a367a7fa10..13f1d4ca47c5 100644
--- a/tools/usb/usbip/libsrc/usbip_common.h
+++ b/tools/usb/usbip/libsrc/usbip_common.h
@@ -30,6 +30,7 @@
 
 /* kernel module names */
 #define USBIP_CORE_MOD_NAME	"usbip-core"
+#define USBIP_USB_DRV_NAME	"usb"
 #define USBIP_HOST_DRV_NAME	"usbip-host"
 #define USBIP_DEVICE_DRV_NAME	"usbip-vudc"
 #define USBIP_VHCI_DRV_NAME	"vhci_hcd"
diff --git a/tools/usb/usbip/libsrc/usbip_monitor.c b/tools/usb/usbip/libsrc/usbip_monitor.c
new file mode 100644
index 000000000000..731d344f2965
--- /dev/null
+++ b/tools/usb/usbip/libsrc/usbip_monitor.c
@@ -0,0 +1,147 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/**
+ * Copyright (C) 2021 Lars Gunnarsson
+ */
+#include <libudev.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/poll.h>
+
+#include "usbip_monitor.h"
+
+static const size_t MAX_STRLEN = 32;
+
+struct usbip_monitor {
+	const char *busid;
+	struct udev *udev;
+	struct udev_monitor *udev_monitor;
+};
+
+usbip_monitor_t *usbip_monitor_new(void)
+{
+	usbip_monitor_t *monitor = NULL;
+	struct udev *udev = udev_new();
+
+	if (udev) {
+		struct udev_monitor *udev_monitor =
+			udev_monitor_new_from_netlink(udev, "udev");
+		udev_monitor_filter_add_match_subsystem_devtype(
+			udev_monitor,
+			/*subsystem=*/"usb",
+			/*devtype=*/"usb_device");
+		udev_monitor_enable_receiving(udev_monitor);
+		monitor = malloc(sizeof(struct usbip_monitor));
+		monitor->busid = NULL;
+		monitor->udev = udev;
+		monitor->udev_monitor = udev_monitor;
+	}
+	return monitor;
+}
+
+void usbip_monitor_delete(usbip_monitor_t *monitor)
+{
+	if (monitor) {
+		udev_monitor_unref(monitor->udev_monitor);
+		udev_unref(monitor->udev);
+		free(monitor);
+	}
+}
+
+void usbip_monitor_set_busid(usbip_monitor_t *monitor, const char *busid)
+{
+	monitor->busid = busid;
+}
+
+static struct udev_device *await_udev_event(const usbip_monitor_t *monitor)
+{
+	struct udev_device *dev = NULL;
+	int fd = udev_monitor_get_fd(monitor->udev_monitor);
+	const int timeout = -1;
+	const int nfds = 1; // number of file descriptors
+	struct pollfd pollfd[] = { { fd, POLLIN, 0 } };
+	int nfd = poll(pollfd, nfds, timeout);
+
+	if (nfd) {
+		dev = udev_monitor_receive_device(monitor->udev_monitor);
+	}
+	return dev;
+}
+
+static int optional_filter_busid(const char *busid, const char *udev_busid)
+{
+	int filter_match = 0;
+
+	if (busid) {
+		if (strncmp(busid, udev_busid, MAX_STRLEN) == 0) {
+			filter_match = 1;
+		}
+	} else {
+		filter_match = 1;
+	}
+	return filter_match;
+}
+
+static void await_usb_with_driver(const usbip_monitor_t *monitor,
+				  const char *driver, const char *action)
+{
+	while (1) {
+		struct udev_device *dev = await_udev_event(monitor);
+
+		if (dev) {
+			const char *udev_action = udev_device_get_action(dev);
+			const char *udev_driver = udev_device_get_driver(dev);
+			const char *udev_busid = udev_device_get_sysname(dev);
+
+			if (strncmp(udev_action, action, MAX_STRLEN) == 0 &&
+			    strncmp(udev_driver, driver, MAX_STRLEN) == 0) {
+				if (optional_filter_busid(monitor->busid,
+							  udev_busid)) {
+					break;
+				}
+			}
+			udev_device_unref(dev);
+		}
+	}
+}
+
+void usbip_monitor_await_usb_add(const usbip_monitor_t *monitor,
+				 const char *driver)
+{
+	await_usb_with_driver(monitor, driver, "add");
+}
+
+void usbip_monitor_await_usb_bind(const usbip_monitor_t *monitor,
+				  const char *driver)
+{
+	await_usb_with_driver(monitor, driver, "bind");
+}
+
+static void await_usb(const usbip_monitor_t *monitor, const char *action)
+{
+	while (1) {
+		struct udev_device *dev = await_udev_event(monitor);
+
+		if (dev) {
+			const char *udev_action = udev_device_get_action(dev);
+			const char *udev_busid = udev_device_get_sysname(dev);
+
+			if (strncmp(udev_action, action, MAX_STRLEN) == 0) {
+				if (optional_filter_busid(monitor->busid,
+							  udev_busid)) {
+					break;
+				}
+			}
+			udev_device_unref(dev);
+		}
+	}
+}
+
+void usbip_monitor_await_usb_unbind(const usbip_monitor_t *monitor)
+{
+	await_usb(monitor, "unbind");
+}
+
+void usbip_monitor_await_usb_delete(const usbip_monitor_t *monitor)
+{
+	await_usb(monitor, "delete");
+}
diff --git a/tools/usb/usbip/libsrc/usbip_monitor.h b/tools/usb/usbip/libsrc/usbip_monitor.h
new file mode 100644
index 000000000000..474b95c80452
--- /dev/null
+++ b/tools/usb/usbip/libsrc/usbip_monitor.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/**
+ * Copyright (C) 2021 Lars Gunnarsson
+ */
+#ifndef __USBIP_MONITOR_H
+#define __USBIP_MONITOR_H
+
+typedef struct usbip_monitor usbip_monitor_t;
+
+usbip_monitor_t *usbip_monitor_new(void);
+void usbip_monitor_delete(usbip_monitor_t *monitor);
+
+void usbip_monitor_set_busid(usbip_monitor_t *monitor, const char *busid);
+void usbip_monitor_await_usb_add(const usbip_monitor_t *monitor,
+				 const char *driver);
+void usbip_monitor_await_usb_bind(const usbip_monitor_t *monitor,
+				  const char *driver);
+void usbip_monitor_await_usb_unbind(const usbip_monitor_t *monitor);
+void usbip_monitor_await_usb_delete(const usbip_monitor_t *monitor);
+
+#endif /* __USBIP_MONITOR_H */
-- 
2.25.1


             reply	other threads:[~2021-10-06 20:48 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-06 20:48 Lars Gunnarsson [this message]
2021-10-06 23:37 ` [PATCH v1 1/3] tools/usbip: support use case reconnect: prepare Shuah Khan
2021-10-07 21:04   ` Lars Gunnarsson
2021-10-07  5:33 ` Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211006204817.GA43927@dell-precision-T3610 \
    --to=gunnarsson.lars@gmail.com \
    --cc=linux-usb@vger.kernel.org \
    --cc=shuah@kernel.org \
    --cc=valentina.manea.m@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.