Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/librumphijack Rewrite to declare most dual-kernel calls ...



details:   https://anonhg.NetBSD.org/src/rev/1a8256b94c6a
branches:  trunk
changeset: 761356:1a8256b94c6a
user:      pooka <pooka%NetBSD.org@localhost>
date:      Tue Jan 25 12:18:33 2011 +0000

description:
Rewrite to declare most dual-kernel calls with macros.  This helps
with adding new calls and makes all existing fd-accepting hijacked
calls dual-kernel.  It would be better to autogenerate the code
from syscalls.master, but this is easier for now.

diffstat:

 lib/librumphijack/hijack.c |  742 +++++++++++++++++---------------------------
 1 files changed, 293 insertions(+), 449 deletions(-)

diffs (truncated from 954 to 300 lines):

diff -r 6cd4fee703bd -r 1a8256b94c6a lib/librumphijack/hijack.c
--- a/lib/librumphijack/hijack.c        Tue Jan 25 12:14:02 2011 +0000
+++ b/lib/librumphijack/hijack.c        Tue Jan 25 12:18:33 2011 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: hijack.c,v 1.16 2011/01/19 11:27:01 pooka Exp $       */
+/*      $NetBSD: hijack.c,v 1.17 2011/01/25 12:18:33 pooka Exp $       */
 
 /*-
  * Copyright (c) 2011 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: hijack.c,v 1.16 2011/01/19 11:27:01 pooka Exp $");
+__RCSID("$NetBSD: hijack.c,v 1.17 2011/01/25 12:18:33 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -53,160 +53,81 @@
 #include <time.h>
 #include <unistd.h>
 
-enum { RUMPCALL_SOCKET, RUMPCALL_ACCEPT, RUMPCALL_BIND, RUMPCALL_CONNECT,
-       RUMPCALL_GETPEERNAME, RUMPCALL_GETSOCKNAME, RUMPCALL_LISTEN,
-       RUMPCALL_RECVFROM, RUMPCALL_RECVMSG,
-       RUMPCALL_SENDTO, RUMPCALL_SENDMSG,
-       RUMPCALL_GETSOCKOPT, RUMPCALL_SETSOCKOPT,
-       RUMPCALL_SHUTDOWN,
-       RUMPCALL_READ, RUMPCALL_READV,
-       RUMPCALL_WRITE, RUMPCALL_WRITEV,
-       RUMPCALL_IOCTL, RUMPCALL_FCNTL,
-       RUMPCALL_CLOSE,
-       RUMPCALL_POLLTS,
-       RUMPCALL__NUM
+enum dualcall {
+       DUALCALL_WRITE, DUALCALL_WRITEV,
+       DUALCALL_IOCTL, DUALCALL_FCNTL,
+       DUALCALL_SOCKET, DUALCALL_ACCEPT, DUALCALL_BIND, DUALCALL_CONNECT,
+       DUALCALL_GETPEERNAME, DUALCALL_GETSOCKNAME, DUALCALL_LISTEN,
+       DUALCALL_RECVFROM, DUALCALL_RECVMSG,
+       DUALCALL_SENDTO, DUALCALL_SENDMSG,
+       DUALCALL_GETSOCKOPT, DUALCALL_SETSOCKOPT,
+       DUALCALL_SHUTDOWN,
+       DUALCALL_READ, DUALCALL_READV,
+       DUALCALL_DUP2, DUALCALL_CLOSE,
+       DUALCALL_POLLTS,
+       DUALCALL__NUM
 };
 
 #define RSYS_STRING(a) __STRING(a)
 #define RSYS_NAME(a) RSYS_STRING(__CONCAT(RUMP_SYS_RENAME_,a))
 
-const char *sysnames[] = {
-       RSYS_NAME(SOCKET),
-       RSYS_NAME(ACCEPT),
-       RSYS_NAME(BIND),
-       RSYS_NAME(CONNECT),
-       RSYS_NAME(GETPEERNAME),
-       RSYS_NAME(GETSOCKNAME),
-       RSYS_NAME(LISTEN),
-       RSYS_NAME(RECVFROM),
-       RSYS_NAME(RECVMSG),
-       RSYS_NAME(SENDTO),
-       RSYS_NAME(SENDMSG),
-       RSYS_NAME(GETSOCKOPT),
-       RSYS_NAME(SETSOCKOPT),
-       RSYS_NAME(SHUTDOWN),
-       RSYS_NAME(READ),
-       RSYS_NAME(READV),
-       RSYS_NAME(WRITE),
-       RSYS_NAME(WRITEV),
-       RSYS_NAME(IOCTL),
-       RSYS_NAME(FCNTL),
-       RSYS_NAME(CLOSE),
-       RSYS_NAME(POLLTS),
-};
-
-static int     (*host_socket)(int, int, int);
-static int     (*host_connect)(int, const struct sockaddr *, socklen_t);
-static int     (*host_bind)(int, const struct sockaddr *, socklen_t);
-static int     (*host_listen)(int, int);
-static int     (*host_accept)(int, struct sockaddr *, socklen_t *);
-static int     (*host_getpeername)(int, struct sockaddr *, socklen_t *);
-static int     (*host_getsockname)(int, struct sockaddr *, socklen_t *);
-static int     (*host_setsockopt)(int, int, int, const void *, socklen_t);
-
-static ssize_t (*host_read)(int, void *, size_t);
-static ssize_t (*host_readv)(int, const struct iovec *, int);
-static ssize_t (*host_write)(int, const void *, size_t);
-static ssize_t (*host_writev)(int, const struct iovec *, int);
-static int     (*host_ioctl)(int, unsigned long, ...);
-static int     (*host_fcntl)(int, int, ...);
-static int     (*host_close)(int);
-static int     (*host_pollts)(struct pollfd *, nfds_t,
-                              const struct timespec *, const sigset_t *);
-static pid_t   (*host_fork)(void);
-static int     (*host_dup2)(int, int);
-static int     (*host_shutdown)(int, int);
-/* XXX */
-static void    *host_sendto;
-static void    *host_recvfrom;
-
-static void *rumpcalls[RUMPCALL__NUM];
-
 /*
  * Would be nice to get this automatically in sync with libc.
  * Also, this does not work for compat-using binaries!
  */
-
 #if !__NetBSD_Prereq__(5,99,7)
-#define SELECT select
-#define POLLTS pollts
-#define POLL poll
+#define LIBCSELECT select
+#define LIBCPOLLTS pollts
+#define LIBCPOLL poll
 #else
-#define SELECT __select50
-#define POLLTS __pollts50
-#define POLL __poll50
+#define LIBCSELECT __select50
+#define LIBCPOLLTS __pollts50
+#define LIBCPOLL __poll50
+#endif
 
 int SELECT(int, fd_set *, fd_set *, fd_set *, struct timeval *);
 int POLLTS(struct pollfd *, nfds_t, const struct timespec *, const sigset_t *);
 int POLL(struct pollfd *, nfds_t, int);
-#endif
-
-/*
- * This is called from librumpclient in case of LD_PRELOAD.
- * It ensures correct RTLD_NEXT.
- */
-static void *
-hijackdlsym(void *handle, const char *symbol)
-{
-
-       return dlsym(handle, symbol);
-}
-
-/* low calorie sockets? */
-static bool hostlocalsockets = true;
-
-static void __attribute__((constructor))
-rcinit(void)
-{
-       int (*rumpcinit)(void);
-       void **rumpcdlsym;
-       void *hand;
-       int i;
-
-       hand = dlopen("librumpclient.so", RTLD_LAZY|RTLD_GLOBAL);
-       if (!hand)
-               err(1, "cannot open librumpclient.so");
-       rumpcinit = dlsym(hand, "rumpclient_init");
-       _DIAGASSERT(rumpcinit);
-
-       rumpcdlsym = dlsym(hand, "rumpclient_dlsym");
-       *rumpcdlsym = hijackdlsym;
 
-       host_socket = dlsym(RTLD_NEXT, "__socket30");
-       host_listen = dlsym(RTLD_NEXT, "listen");
-       host_connect = dlsym(RTLD_NEXT, "connect");
-       host_bind = dlsym(RTLD_NEXT, "bind");
-       host_accept = dlsym(RTLD_NEXT, "accept");
-       host_getpeername = dlsym(RTLD_NEXT, "getpeername");
-       host_getsockname = dlsym(RTLD_NEXT, "getsockname");
-       host_setsockopt = dlsym(RTLD_NEXT, "setsockopt");
+#define S(a) __STRING(a)
+struct sysnames {
+       enum dualcall scm_callnum;
+       const char *scm_hostname;
+       const char *scm_rumpname;
+} syscnames[] = {
+       { DUALCALL_SOCKET,      "__socket30",   RSYS_NAME(SOCKET)       },
+       { DUALCALL_ACCEPT,      "accept",       RSYS_NAME(ACCEPT)       },
+       { DUALCALL_BIND,        "bind",         RSYS_NAME(BIND)         },
+       { DUALCALL_CONNECT,     "connect",      RSYS_NAME(CONNECT)      },
+       { DUALCALL_GETPEERNAME, "getpeername",  RSYS_NAME(GETPEERNAME)  },
+       { DUALCALL_GETSOCKNAME, "getsockname",  RSYS_NAME(GETSOCKNAME)  },
+       { DUALCALL_LISTEN,      "listen",       RSYS_NAME(LISTEN)       },
+       { DUALCALL_RECVFROM,    "recvfrom",     RSYS_NAME(RECVFROM)     },
+       { DUALCALL_RECVMSG,     "recvmsg",      RSYS_NAME(RECVMSG)      },
+       { DUALCALL_SENDTO,      "sendto",       RSYS_NAME(SENDTO)       },
+       { DUALCALL_SENDMSG,     "sendmsg",      RSYS_NAME(SENDMSG)      },
+       { DUALCALL_GETSOCKOPT,  "getsockopt",   RSYS_NAME(GETSOCKOPT)   },
+       { DUALCALL_SETSOCKOPT,  "setsockopt",   RSYS_NAME(SETSOCKOPT)   },
+       { DUALCALL_SHUTDOWN,    "shutdown",     RSYS_NAME(SHUTDOWN)     },
+       { DUALCALL_READ,        "read",         RSYS_NAME(READ)         },
+       { DUALCALL_READV,       "readv",        RSYS_NAME(READV)        },
+       { DUALCALL_WRITE,       "write",        RSYS_NAME(WRITE)        },
+       { DUALCALL_WRITEV,      "writev",       RSYS_NAME(WRITEV)       },
+       { DUALCALL_IOCTL,       "ioctl",        RSYS_NAME(IOCTL)        },
+       { DUALCALL_FCNTL,       "fcntl",        RSYS_NAME(FCNTL)        },
+       { DUALCALL_DUP2,        "dup2",         RSYS_NAME(DUP2)         },
+       { DUALCALL_CLOSE,       "close",        RSYS_NAME(CLOSE)        },
+       { DUALCALL_POLLTS,      S(LIBCPOLLTS),  RSYS_NAME(POLLTS)       },
+};
+#undef S
 
-       host_read = dlsym(RTLD_NEXT, "read");
-       host_readv = dlsym(RTLD_NEXT, "readv");
-       host_write = dlsym(RTLD_NEXT, "write");
-       host_writev = dlsym(RTLD_NEXT, "writev");
-       host_ioctl = dlsym(RTLD_NEXT, "ioctl");
-       host_fcntl = dlsym(RTLD_NEXT, "fcntl");
-       host_close = dlsym(RTLD_NEXT, "close");
-       host_pollts = dlsym(RTLD_NEXT, "pollts");
-       host_fork = dlsym(RTLD_NEXT, "fork");
-       host_dup2 = dlsym(RTLD_NEXT, "dup2");
-       host_shutdown = dlsym(RTLD_NEXT, "shutdown");
-       host_sendto = dlsym(RTLD_NEXT, "sendto");
-       host_recvfrom = dlsym(RTLD_NEXT, "recvfrom");
+struct bothsys {
+       void *bs_host;
+       void *bs_rump;
+} syscalls[DUALCALL__NUM];
+#define GETSYSCALL(which, name) syscalls[DUALCALL_##name].bs_##which
 
-       for (i = 0; i < RUMPCALL__NUM; i++) {
-               rumpcalls[i] = dlsym(hand, sysnames[i]);
-               if (!rumpcalls[i]) {
-                       fprintf(stderr, "rumphijack: cannot find symbol: %s\n",
-                           sysnames[i]);
-                       exit(1);
-               }
-       }
-
-       if (rumpcinit() == -1)
-               err(1, "rumpclient init");
-}
+pid_t (*host_fork)(void);
 
 static unsigned dup2mask;
 #define ISDUP2D(fd) (1<<(fd) & dup2mask)
@@ -231,6 +152,84 @@
 #define DPRINTF(x)
 #endif
 
+#define FDCALL(type, name, rcname, args, proto, vars)                  \
+type name args                                                         \
+{                                                                      \
+       type (*fun) proto;                                              \
+                                                                       \
+       if (fd_isrump(fd)) {                                            \
+               fun = syscalls[rcname].bs_rump;                         \
+               fd = fd_host2rump(fd);                                  \
+       } else {                                                        \
+               fun = syscalls[rcname].bs_host;                         \
+       }                                                               \
+                                                                       \
+       return fun vars;                                                \
+}
+
+/*
+ * This is called from librumpclient in case of LD_PRELOAD.
+ * It ensures correct RTLD_NEXT.
+ */
+static void *
+hijackdlsym(void *handle, const char *symbol)
+{
+
+       return dlsym(handle, symbol);
+}
+
+/* low calorie sockets? */
+static bool hostlocalsockets = true;
+
+static void __attribute__((constructor))
+rcinit(void)
+{
+       int (*rumpcinit)(void);
+       void **rumpcdlsym;
+       void *hand;
+       int i, j;
+
+       hand = dlopen("librumpclient.so", RTLD_LAZY|RTLD_GLOBAL);
+       if (!hand)
+               err(1, "cannot open librumpclient.so");
+       rumpcinit = dlsym(hand, "rumpclient_init");
+       _DIAGASSERT(rumpcinit);
+
+       rumpcdlsym = dlsym(hand, "rumpclient_dlsym");
+       *rumpcdlsym = hijackdlsym;
+       host_fork = dlsym(RTLD_NEXT, "fork");
+
+       /*
+        * In theory cannot print anything during lookups because
+        * we might not have the call vector set up.  so, the errx()
+        * is a bit of a strech, but it might work.
+        */
+
+       for (i = 0; i < DUALCALL__NUM; i++) {
+               /* build runtime O(1) access */
+               for (j = 0; j < __arraycount(syscnames); j++) {
+                       if (syscnames[j].scm_callnum == i)
+                               break;
+               }
+



Home | Main Index | Thread Index | Old Index