summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2020-09-05 12:08:54 +0000
committerAlyssa Ross <hi@alyssa.is>2020-09-05 12:08:54 +0000
commit47626b1be81ca93b6693671ca5a687b48d225027 (patch)
tree849209832bcd340100113e621732cb1735cf2eb2
parent8814bf8bcce4b48fb4622a5188016aef81ea9685 (diff)
downloadnixpkgs-usbip.tar
nixpkgs-usbip.tar.gz
nixpkgs-usbip.tar.bz2
nixpkgs-usbip.tar.lz
nixpkgs-usbip.tar.xz
nixpkgs-usbip.tar.zst
nixpkgs-usbip.zip
linuxPackages.usbip: add s6 readiness support usbip
-rw-r--r--pkgs/os-specific/linux/usbip/default.nix4
-rw-r--r--pkgs/os-specific/linux/usbip/usbipd-add-s6-readiness-notification.patch165
2 files changed, 168 insertions, 1 deletions
diff --git a/pkgs/os-specific/linux/usbip/default.nix b/pkgs/os-specific/linux/usbip/default.nix
index ffd33b6ff85..76ab79f7b72 100644
--- a/pkgs/os-specific/linux/usbip/default.nix
+++ b/pkgs/os-specific/linux/usbip/default.nix
@@ -5,7 +5,9 @@ stdenv.mkDerivation {
 
   src = kernel.src;
 
-  patches = lib.optionals (lib.versionAtLeast "5.4" kernel.version) [
+  patches = [
+    ./usbipd-add-s6-readiness-notification.patch
+  ] ++ lib.optionals (lib.versionAtLeast "5.4" kernel.version) [
     # fixes build with gcc8
     ./fix-snprintf-truncation.patch
     # fixes build with gcc9
diff --git a/pkgs/os-specific/linux/usbip/usbipd-add-s6-readiness-notification.patch b/pkgs/os-specific/linux/usbip/usbipd-add-s6-readiness-notification.patch
new file mode 100644
index 00000000000..dc74e7df9b3
--- /dev/null
+++ b/pkgs/os-specific/linux/usbip/usbipd-add-s6-readiness-notification.patch
@@ -0,0 +1,165 @@
+From 112a36a9dfddfbcb757c61a81cd7fe528622a307 Mon Sep 17 00:00:00 2001
+From: Alyssa Ross <hi@alyssa.is>
+Date: Sat, 5 Sep 2020 11:45:03 +0000
+Subject: [PATCH] usbip: tools: usbipd: add s6 readiness notification
+
+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
+---
+ 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
+