Source-Changes-HG archive

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

[src/trunk]: src/lib/librumpuser Once again, make the rump kernel hypercall l...



details:   https://anonhg.NetBSD.org/src/rev/3dd7168d2ec0
branches:  trunk
changeset: 780493:3dd7168d2ec0
user:      pooka <pooka%NetBSD.org@localhost>
date:      Fri Jul 27 09:09:05 2012 +0000

description:
Once again, make the rump kernel hypercall layer work on Linux.

diffstat:

 lib/librumpuser/rumpuser.c           |  80 ++++++++++++++++++++++++++---------
 lib/librumpuser/rumpuser_daemonize.c |   7 +-
 lib/librumpuser/rumpuser_dl.c        |  46 +++++++++++++++-----
 lib/librumpuser/rumpuser_net.c       |  11 +++-
 lib/librumpuser/rumpuser_port.h      |  76 ++++++++++++++++++++++++++++++++++
 lib/librumpuser/rumpuser_pth.c       |  31 +++++++++----
 lib/librumpuser/rumpuser_sp.c        |  57 +++++++++++++++++++++----
 lib/librumpuser/sp_common.c          |  42 +++++++++++++-----
 8 files changed, 279 insertions(+), 71 deletions(-)

diffs (truncated from 702 to 300 lines):

diff -r e0df578cca33 -r 3dd7168d2ec0 lib/librumpuser/rumpuser.c
--- a/lib/librumpuser/rumpuser.c        Fri Jul 27 09:06:01 2012 +0000
+++ b/lib/librumpuser/rumpuser.c        Fri Jul 27 09:09:05 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rumpuser.c,v 1.17 2012/06/25 22:32:47 abs Exp $        */
+/*     $NetBSD: rumpuser.c,v 1.18 2012/07/27 09:09:05 pooka Exp $      */
 
 /*
  * Copyright (c) 2007-2010 Antti Kantee.  All Rights Reserved.
@@ -25,30 +25,24 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/cdefs.h>
+#include "rumpuser_port.h"
+
 #if !defined(lint)
-__RCSID("$NetBSD: rumpuser.c,v 1.17 2012/06/25 22:32:47 abs Exp $");
+__RCSID("$NetBSD: rumpuser.c,v 1.18 2012/07/27 09:09:05 pooka Exp $");
 #endif /* !lint */
 
-/* thank the maker for this */
-#ifdef __linux__
-#define _XOPEN_SOURCE 500
-#define _BSD_SOURCE
-#define _FILE_OFFSET_BITS 64
-#include <features.h>
-#endif
-
-#include <sys/param.h>
-#include <sys/event.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <sys/uio.h>
+#include <sys/stat.h>
+#include <sys/time.h>
 
 #ifdef __NetBSD__
 #include <sys/disk.h>
 #include <sys/disklabel.h>
 #include <sys/dkio.h>
 #include <sys/sysctl.h>
+#include <sys/event.h>
 #endif
 
 #include <assert.h>
@@ -256,10 +250,16 @@
        void *rv;
        int prot;
 
+#ifndef MAP_ALIGNED
+#define MAP_ALIGNED(a) 0
+       if (alignbit)
+               fprintf(stderr, "rumpuser_anonmmap: warning, requested "
+                   "alignment not supported by hypervisor\n");
+#endif
+
        prot = PROT_READ|PROT_WRITE;
        if (exec)
                prot |= PROT_EXEC;
-       /* XXX: MAP_ALIGNED() is not portable */
        rv = mmap(prefaddr, size, prot,
            MAP_ANON | MAP_ALIGNED(alignbit), -1, 0);
        if (rv == MAP_FAILED) {
@@ -500,7 +500,24 @@
 rumpuser_getenv(const char *name, char *buf, size_t blen, int *error)
 {
 
+#ifdef __linux__
+       char *tmp;
+
+       *error = 0;
+       if ((tmp = getenv(name)) != NULL) {
+               if (strlen(tmp) >= blen) {
+                       *error = ERANGE;
+                       return -1;
+               }
+               strcpy(buf, tmp);
+               return 0;
+       } else {
+               *error = ENOENT;
+               return -1;
+       }
+#else
        DOCALL(int, getenv_r(name, buf, blen));
+#endif
 }
 
 int
@@ -550,6 +567,7 @@
        errno = error;
 }
 
+#ifdef __NetBSD__
 int
 rumpuser_writewatchfile_setup(int kq, int fd, intptr_t opaque, int *error)
 {
@@ -592,6 +610,7 @@
                *opaque = kev.udata;
        return rv;
 }
+#endif
 
 /*
  * This is meant for safe debugging prints from the kernel.
@@ -629,20 +648,39 @@
 int
 rumpuser_getnhostcpu(void)
 {
-       int ncpu;
-       size_t sz = sizeof(ncpu);
+       int ncpu = 1;
 
 #ifdef __NetBSD__
-       if (sysctlbyname("hw.ncpu", &ncpu, &sz, NULL, 0) == -1)
-               return 1;
+       size_t sz = sizeof(ncpu);
+
+       sysctlbyname("hw.ncpu", &ncpu, &sz, NULL, 0);
+#elif __linux__
+       FILE *fp;
+       char *line = NULL;
+       size_t n = 0;
+
+       /* If anyone knows a better way, I'm all ears */
+       if ((fp = fopen("/proc/cpuinfo", "r")) != NULL) {
+               ncpu = 0;
+               while (getline(&line, &n, fp) != -1) {
+                       if (strncmp(line,
+                           "processor", sizeof("processor")-1) == 0)
+                               ncpu++;
+               }
+               if (ncpu == 0)
+                       ncpu = 1;
+               free(line);
+               fclose(fp);
+       }
+#endif
+       
        return ncpu;
-#else
-       return 1;
-#endif
 }
 
+/* XXX: this hypercall needs a better name */
 uint32_t
 rumpuser_arc4random(void)
 {
+
        return arc4random();
 }
diff -r e0df578cca33 -r 3dd7168d2ec0 lib/librumpuser/rumpuser_daemonize.c
--- a/lib/librumpuser/rumpuser_daemonize.c      Fri Jul 27 09:06:01 2012 +0000
+++ b/lib/librumpuser/rumpuser_daemonize.c      Fri Jul 27 09:09:05 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rumpuser_daemonize.c,v 1.2 2011/01/22 14:18:55 pooka Exp $     */
+/*     $NetBSD: rumpuser_daemonize.c,v 1.3 2012/07/27 09:09:05 pooka Exp $     */
 
 /*
  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
@@ -25,9 +25,10 @@
  * SUCH DAMAGE.
  */
 
-#include <sys/cdefs.h>
+#include "rumpuser_port.h"
+
 #if !defined(lint)
-__RCSID("$NetBSD: rumpuser_daemonize.c,v 1.2 2011/01/22 14:18:55 pooka Exp $");
+__RCSID("$NetBSD: rumpuser_daemonize.c,v 1.3 2012/07/27 09:09:05 pooka Exp $");
 #endif /* !lint */
 
 #include <sys/types.h>
diff -r e0df578cca33 -r 3dd7168d2ec0 lib/librumpuser/rumpuser_dl.c
--- a/lib/librumpuser/rumpuser_dl.c     Fri Jul 27 09:06:01 2012 +0000
+++ b/lib/librumpuser/rumpuser_dl.c     Fri Jul 27 09:09:05 2012 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: rumpuser_dl.c,v 1.7 2011/03/22 22:27:33 pooka Exp $   */
+/*      $NetBSD: rumpuser_dl.c,v 1.8 2012/07/27 09:09:05 pooka Exp $   */
 
 /*
  * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
@@ -30,13 +30,16 @@
  * Called during rump bootstrap.
  */
 
-#include <sys/cdefs.h>
-__RCSID("$NetBSD: rumpuser_dl.c,v 1.7 2011/03/22 22:27:33 pooka Exp $");
+#include "rumpuser_port.h"
+
+#if !defined(lint)
+__RCSID("$NetBSD: rumpuser_dl.c,v 1.8 2012/07/27 09:09:05 pooka Exp $");
+#endif /* !lint */
 
 #include <sys/types.h>
 #include <sys/time.h>
+#include <assert.h>
 
-#include <assert.h>
 #include <dlfcn.h>
 #include <elf.h>
 #include <errno.h>
@@ -50,7 +53,7 @@
 #include <rump/rumpuser.h>
 
 #if defined(__ELF__) && (defined(__NetBSD__) || defined(__FreeBSD__)   \
-    || (defined(__sun__) && defined(__svr4__)))
+    || (defined(__sun__) && defined(__svr4__))) || defined(__linux__)
 static size_t symtabsize = 0, strtabsize = 0;
 static size_t symtaboff = 0, strtaboff = 0;
 static uint8_t *symtab = NULL;
@@ -62,6 +65,12 @@
 #define Elf_Symindx uint32_t
 #endif
 
+/*
+ * Linux ld.so requires a valid handle for dlinfo(), so use the main
+ * handle.  We initialize this variable in rumpuser_dl_bootstrap()
+ */
+static void *mainhandle;
+
 static void *
 reservespace(void *store, size_t *storesize,
        size_t storeoff, size_t required)
@@ -130,6 +139,18 @@
 
 #define SYM_GETSIZE() ((eident==ELFCLASS32)?sizeof(Elf32_Sym):sizeof(Elf64_Sym))
 
+/*
+ * On NetBSD, the dynamic section pointer values seem to be relative to
+ * the address the dso is mapped at.  On Linux, they seem to contain
+ * the absolute address.  I couldn't find anything definite from a quick
+ * read of the standard and therefore I will not go and figure beyond ifdef.
+ */
+#ifdef __linux__
+#define adjptr(_map_, _ptr_) ((void *)(_ptr_))
+#else
+#define adjptr(_map_, _ptr_) ((void *)(_map_->l_addr + (_ptr_)))
+#endif
+
 static int
 getsymbols(struct link_map *map)
 {
@@ -142,7 +163,7 @@
        unsigned i;
 
        if (map->l_addr) {
-               if (memcmp(map->l_addr, ELFMAG, SELFMAG) != 0)
+               if (memcmp((void *)map->l_addr, ELFMAG, SELFMAG) != 0)
                        return ENOEXEC;
                eident = *(unsigned char *)(map->l_addr + EI_CLASS);
                if (eident != ELFCLASS32 && eident != ELFCLASS64)
@@ -176,11 +197,11 @@
                switch (ed_tag) {
                case DT_SYMTAB:
                        DYNn_GETMEMBER(ed_base, i, d_un.d_ptr, edptr);
-                       syms_base = map->l_addr + edptr;
+                       syms_base = adjptr(map, edptr);
                        break;
                case DT_STRTAB:
                        DYNn_GETMEMBER(ed_base, i, d_un.d_ptr, edptr);
-                       str_base = map->l_addr + edptr;
+                       str_base = adjptr(map, edptr);
                        break;
                case DT_STRSZ:
                        DYNn_GETMEMBER(ed_base, i, d_un.d_val, edval);
@@ -188,7 +209,7 @@
                        break;
                case DT_HASH:
                        DYNn_GETMEMBER(ed_base, i, d_un.d_ptr, edptr);
-                       hashtab = (Elf_Symindx *)(map->l_addr + edptr);
+                       hashtab = (Elf_Symindx *)adjptr(map, edptr);
                        cursymcount = hashtab[1];
                        break;
                case DT_SYMENT:
@@ -307,7 +328,8 @@
        struct link_map *map, *origmap;
        int error;
 
-       if (dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &origmap) == -1) {
+       mainhandle = dlopen(NULL, RTLD_NOW);
+       if (dlinfo(mainhandle, RTLD_DI_LINKMAP, &origmap) == -1) {
                fprintf(stderr, "warning: rumpuser module bootstrap "
                    "failed: %s\n", dlerror());
                return;
@@ -329,7 +351,7 @@
                if (strstr(map->l_name, "librump") != NULL)
                        error = getsymbols(map);
                /* this should be the main object */
-               else if (map->l_addr == NULL && map->l_prev == NULL)
+               else if (!map->l_addr && map->l_prev == NULL)
                        error = getsymbols(map);
        }
 
@@ -372,7 +394,7 @@
 {
        struct link_map *map;
 
-       if (dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &map) == -1) {



Home | Main Index | Thread Index | Old Index