]> Pileus Git - ~andy/linux/commitdiff
staging: usbip: userspace: eliminate glib dependency
authorIlija Hadzic <ihadzic@research.bell-labs.com>
Fri, 7 Dec 2012 21:49:42 +0000 (16:49 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 7 Jan 2013 20:38:54 +0000 (12:38 -0800)
USBIP daemon relies on functions available in glib2 library
to spawn handler code for incoming connection. This makes the
whole program dependent on glib2 library, which is a GNOME library
that on systems that don't have GNOME results in pulling more
dependency, only to be able to run a relatively trivial
socket-based program.

While this may not seem to be a problem on full-blown desktops
that already have the necessary libraries, it is a big issue
on small embedded systems (think USB hub with an Ethernet port)
that only have bare essentials in their file systems.

This patch eliminates glib2 dependency by reworking the
code to use lower level system calls to dispatch connection
handler. Instead of using glib2-style event loop and dispatching
mechanism, just do a ppoll(2) system call in our own loop and call
accept(2) followed by fork(2) on the socket that has incoming
connection. Stevens' books taught us that more than twenty
years ago. No need for anything smarter in a simple server, such
as usbipd.

Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/usbip/userspace/README
drivers/staging/usbip/userspace/configure.ac
drivers/staging/usbip/userspace/src/Makefile.am
drivers/staging/usbip/userspace/src/usbipd.c

index 63cd107190591d0ce2c7513335378df4a0a27d94..233d1d7aef928ff648597edd7be302b282b04ea1 100644 (file)
@@ -17,8 +17,6 @@
 
     - gcc >= 4.0
 
-    - libglib2.0-dev >= 2.6.0
-
     - libtool, automake >= 1.9, autoconf >= 2.5.0, pkg-config
 
 
index 43e641e5ac0610cbc26d02bad98d2d97d5236077..6d52841e1cf5acb2e7910c5cc4fe2e21f7f133e6 100644 (file)
@@ -91,10 +91,5 @@ AC_ARG_WITH([usbids-dir],
            [USBIDS_DIR=$withval], [USBIDS_DIR="/usr/share/hwdata/"])
 AC_SUBST([USBIDS_DIR])
 
-GLIB2_REQUIRED=2.6.0
-PKG_CHECK_MODULES([PACKAGE], [glib-2.0 >= $GLIB2_REQUIRED])
-AC_SUBST([PACKAGE_CFLAGS])
-AC_SUBST([PACKAGE_LIBS])
-
 AC_CONFIG_FILES([Makefile libsrc/Makefile src/Makefile])
 AC_OUTPUT
index c365a3fada904ff351d3bd39db7bc37b15562a79..a1130036139242b8b2bbca14812040f317d5537b 100644 (file)
@@ -1,6 +1,6 @@
 AM_CPPFLAGS = -I$(top_srcdir)/libsrc -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"'
-AM_CFLAGS   = @EXTRA_CFLAGS@ @PACKAGE_CFLAGS@
-LDADD       = $(top_builddir)/libsrc/libusbip.la @PACKAGE_LIBS@
+AM_CFLAGS   = @EXTRA_CFLAGS@
+LDADD       = $(top_builddir)/libsrc/libusbip.la
 
 sbin_PROGRAMS := usbip usbipd
 
index 8668a8092d4d0c9b3556b377c9999730eb14cf98..34760cc1d10e1777f234c3ac6e5102ce4b827163 100644 (file)
@@ -20,6 +20,7 @@
 #include "../config.h"
 #endif
 
+#define _GNU_SOURCE
 #include <errno.h>
 #include <unistd.h>
 #include <netdb.h>
 #include <tcpd.h>
 #endif
 
-#define _GNU_SOURCE
 #include <getopt.h>
-#include <glib.h>
 #include <signal.h>
+#include <poll.h>
 
 #include "usbip_host_driver.h"
 #include "usbip_common.h"
@@ -48,7 +48,7 @@
 #define PROGNAME "usbipd"
 #define MAXSOCKFD 20
 
-GMainLoop *main_loop;
+#define MAIN_LOOP_TIMEOUT 10
 
 static const char usbip_version_string[] = PACKAGE_STRING;
 
@@ -310,30 +310,22 @@ static int do_accept(int listenfd)
        return connfd;
 }
 
-gboolean process_request(GIOChannel *gio, GIOCondition condition,
-                        gpointer unused_data)
+int process_request(int listenfd)
 {
-       int listenfd;
+       pid_t childpid;
        int connfd;
 
-       (void) unused_data;
-
-       if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
-               err("unknown condition");
-               BUG();
-       }
-
-       if (condition & G_IO_IN) {
-               listenfd = g_io_channel_unix_get_fd(gio);
-               connfd = do_accept(listenfd);
-               if (connfd < 0)
-                       return TRUE;
-
+       connfd = do_accept(listenfd);
+       if (connfd < 0)
+               return -1;
+       childpid = fork();
+       if (childpid == 0) {
+               close(listenfd);
                recv_pdu(connfd);
-               close(connfd);
+               exit(0);
        }
-
-       return TRUE;
+       close(connfd);
+       return 0;
 }
 
 static void log_addrinfo(struct addrinfo *ai)
@@ -418,10 +410,7 @@ static struct addrinfo *do_getaddrinfo(char *host, int ai_family)
 
 static void signal_handler(int i)
 {
-       dbg("received signal: code %d", i);
-
-       if (main_loop)
-               g_main_loop_quit(main_loop);
+       dbg("received '%s' signal", strsignal(i));
 }
 
 static void set_signal(void)
@@ -433,14 +422,19 @@ static void set_signal(void)
        sigemptyset(&act.sa_mask);
        sigaction(SIGTERM, &act, NULL);
        sigaction(SIGINT, &act, NULL);
+       act.sa_handler = SIG_IGN;
+       sigaction(SIGCLD, &act, NULL);
 }
 
-static int do_standalone_mode(gboolean daemonize)
+static int do_standalone_mode(int daemonize)
 {
        struct addrinfo *ai_head;
        int sockfdlist[MAXSOCKFD];
        int nsockfd;
-       int i;
+       int i, terminate;
+       struct pollfd *fds;
+       struct timespec timeout;
+       sigset_t sigmask;
 
        if (usbip_names_init(USBIDS_FILE))
                err("failed to open %s", USBIDS_FILE);
@@ -456,7 +450,7 @@ static int do_standalone_mode(gboolean daemonize)
                        err("daemonizing failed: %s", strerror(errno));
                        return -1;
                }
-
+               umask(0);
                usbip_use_syslog = 1;
        }
        set_signal();
@@ -472,20 +466,40 @@ static int do_standalone_mode(gboolean daemonize)
                err("failed to open a listening socket");
                return -1;
        }
-
+       fds = calloc(nsockfd, sizeof(struct pollfd));
        for (i = 0; i < nsockfd; i++) {
-               GIOChannel *gio;
-
-               gio = g_io_channel_unix_new(sockfdlist[i]);
-               g_io_add_watch(gio, (G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL),
-                              process_request, NULL);
+               fds[i].fd = sockfdlist[i];
+               fds[i].events = POLLIN;
+       }
+       timeout.tv_sec = MAIN_LOOP_TIMEOUT;
+       timeout.tv_nsec = 0;
+
+       sigfillset(&sigmask);
+       sigdelset(&sigmask, SIGTERM);
+       sigdelset(&sigmask, SIGINT);
+
+       terminate = 0;
+       while (!terminate) {
+               int r;
+
+               r = ppoll(fds, nsockfd, &timeout, &sigmask);
+               if (r < 0) {
+                       dbg("%s", strerror(errno));
+                       terminate = 1;
+               } else if (r) {
+                       for (i = 0; i < nsockfd; i++) {
+                               if (fds[i].revents & POLLIN) {
+                                       dbg("read event on fd[%d]=%d",
+                                           i, sockfdlist[i]);
+                                       process_request(sockfdlist[i]);
+                               }
+                       }
+               } else
+                       dbg("heartbeat timeout on ppoll()");
        }
-
-       main_loop = g_main_loop_new(FALSE, FALSE);
-       g_main_loop_run(main_loop);
 
        info("shutting down " PROGNAME);
-
+       free(fds);
        freeaddrinfo(ai_head);
        usbip_host_driver_close();
        usbip_names_free();
@@ -509,7 +523,7 @@ int main(int argc, char *argv[])
                cmd_version
        } cmd;
 
-       gboolean daemonize = FALSE;
+       int daemonize = 0;
        int opt, rc = -1;
 
        usbip_use_stderr = 1;
@@ -527,7 +541,7 @@ int main(int argc, char *argv[])
 
                switch (opt) {
                case 'D':
-                       daemonize = TRUE;
+                       daemonize = 1;
                        break;
                case 'd':
                        usbip_use_debug = 1;