* [PATCH linux] usbip: tools: usbipd: add s6 readiness notification
@ 2021-03-15 14:02 Alyssa Ross
0 siblings, 0 replies; only message in thread
From: Alyssa Ross @ 2021-03-15 14:02 UTC (permalink / raw)
To: devel
This implements the s6 readiness notification protocol[1]. When the
daemon has started and is listening on its socket(s), it will emit a
readiness notification on a user-specified file descriptor.
systemd-based systems can also use the readiness notification, using
the sdnotify-wrapper program[2].
[1]: https://skarnet.org/software/s6/s6-supervise.html
[2]: https://skarnet.org/software/misc/sdnotify-wrapper.c
Signed-off-by: Alyssa Ross <hi@alyssa.is>
---
This is important for us in Spectrum to be able to run usbipd to
export USB devices to other VMs. I plan to add this patch to
linuxPackages.usbip in Spectrum nixpkgs. I might attempt to upstream
it to Linux, but I'm not sure yet -- the s6 protocol is perfect for
our needs but fairly obsure, so I'm not sure if they'd like it.
tools/usb/usbip/src/usbipd.c | 70 ++++++++++++++++++++++++++++--------
1 file changed, 55 insertions(+), 15 deletions(-)
diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c
index 48398a78e88af..4ee41040735f4 100644
--- a/tools/usb/usbip/src/usbipd.c
+++ b/tools/usb/usbip/src/usbipd.c
@@ -22,6 +22,7 @@
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <fcntl.h>
#ifdef HAVE_LIBWRAP
#include <tcpd.h>
@@ -65,6 +66,10 @@ static const char usbipd_help_string[] =
" -D, --daemon\n"
" Run as a daemon process.\n"
"\n"
+ " -nFD, --notify-fd FD\n"
+ " Once ready to receive connections, write a line feed\n"
+ " character to FD, then close it.\n"
+ "\n"
" -d, --debug\n"
" Print debugging information.\n"
"\n"
@@ -88,6 +93,30 @@ static void usbipd_help(void)
printf("%s\n", usbipd_help_string);
}
+static int parse_notify_fd(char *arg)
+{
+ dbg("parsing notify-fd arg '%s'", arg);
+ char *end;
+ unsigned long int notify_fd = strtoul(arg, &end, 10);
+
+ if (end == arg) {
+ err("notify-fd: could not parse '%s' as decimal integer", arg);
+ return -1;
+ }
+
+ if (*end != '\0') {
+ err("notify-fd: garbage at end of '%s'", arg);
+ return -1;
+ }
+
+ if (fcntl(notify_fd, F_GETFD) == -1) {
+ err("notify-fd: %s", strerror(errno));
+ return -1;
+ }
+
+ return notify_fd;
+}
+
static int recv_request_import(int sockfd)
{
struct op_import_request req;
@@ -488,7 +517,7 @@ static void remove_pid_file(void)
}
}
-static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
+static int do_standalone_mode(int daemonize, int notify_fd, int ipv4, int ipv6)
{
struct addrinfo *ai_head;
int sockfdlist[MAXSOCKFD];
@@ -543,6 +572,13 @@ static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
dbg("listening on %d address%s", nsockfd, (nsockfd == 1) ? "" : "es");
+ if (notify_fd != -1) {
+ const char lf[] = { '\n' };
+ if (write(notify_fd, lf, sizeof lf) == -1)
+ err("failed to notify readiness");
+ close(notify_fd);
+ }
+
fds = calloc(nsockfd, sizeof(struct pollfd));
for (i = 0; i < nsockfd; i++) {
fds[i].fd = sockfdlist[i];
@@ -586,17 +622,18 @@ static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
int main(int argc, char *argv[])
{
static const struct option longopts[] = {
- { "ipv4", no_argument, NULL, '4' },
- { "ipv6", no_argument, NULL, '6' },
- { "daemon", no_argument, NULL, 'D' },
- { "daemon", no_argument, NULL, 'D' },
- { "debug", no_argument, NULL, 'd' },
- { "device", no_argument, NULL, 'e' },
- { "pid", optional_argument, NULL, 'P' },
- { "tcp-port", required_argument, NULL, 't' },
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, 'v' },
- { NULL, 0, NULL, 0 }
+ { "ipv4", no_argument, NULL, '4' },
+ { "ipv6", no_argument, NULL, '6' },
+ { "daemon", no_argument, NULL, 'D' },
+ { "daemon", no_argument, NULL, 'D' },
+ { "notify-fd", required_argument, NULL, 'n' },
+ { "debug", no_argument, NULL, 'd' },
+ { "device", no_argument, NULL, 'e' },
+ { "pid", optional_argument, NULL, 'P' },
+ { "tcp-port", required_argument, NULL, 't' },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ { NULL, 0, NULL, 0 }
};
enum {
@@ -605,7 +642,7 @@ int main(int argc, char *argv[])
cmd_version
} cmd;
- int daemonize = 0;
+ int daemonize = 0, notify_fd = -1;
int ipv4 = 0, ipv6 = 0;
int opt, rc = -1;
@@ -620,7 +657,7 @@ int main(int argc, char *argv[])
cmd = cmd_standalone_mode;
driver = &host_driver;
for (;;) {
- opt = getopt_long(argc, argv, "46DdeP::t:hv", longopts, NULL);
+ opt = getopt_long(argc, argv, "46Dn:deP::t:hv", longopts, NULL);
if (opt == -1)
break;
@@ -635,6 +672,9 @@ int main(int argc, char *argv[])
case 'D':
daemonize = 1;
break;
+ case 'n':
+ notify_fd = parse_notify_fd(optarg);
+ break;
case 'd':
usbip_use_debug = 1;
break;
@@ -665,7 +705,7 @@ int main(int argc, char *argv[])
switch (cmd) {
case cmd_standalone_mode:
- rc = do_standalone_mode(daemonize, ipv4, ipv6);
+ rc = do_standalone_mode(daemonize, notify_fd, ipv4, ipv6);
remove_pid_file();
break;
case cmd_version:
--
2.27.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-03-15 14:03 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-15 14:02 [PATCH linux] usbip: tools: usbipd: add s6 readiness notification Alyssa Ross
Code repositories for project(s) associated with this public inbox
https://spectrum-os.org/git/crosvm
https://spectrum-os.org/git/doc
https://spectrum-os.org/git/mktuntap
https://spectrum-os.org/git/nixpkgs
https://spectrum-os.org/git/spectrum
https://spectrum-os.org/git/ucspi-vsock
https://spectrum-os.org/git/www
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).