[BACK]Return to rumpclient.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / librumpclient

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/lib/librumpclient/rumpclient.c between version 1.48 and 1.49

version 1.48, 2012/03/21 10:10:37 version 1.49, 2012/08/03 11:31:34
Line 29 
Line 29 
  * Client side routines for rump syscall proxy.   * Client side routines for rump syscall proxy.
  */   */
   
   #include "rumpuser_port.h"
   
   /*
    * We use kqueue on NetBSD, poll elsewhere.  Theoretically we could
    * use kqueue on other BSD's too, but I haven't tested those.  We
    * want to use kqueue because it will give us the ability to get signal
    * notifications but defer their handling to a stage where we do not
    * hold the communication lock.  Taking a signal while holding on to
    * that lock may cause a deadlock.  Therefore, block signals throughout
    * the RPC when using poll.  This unfortunately means that the normal
    * SIGINT way of stopping a process while it is undergoing rump kernel
    * RPC will not work.  If anyone know which Linux system call handles
    * the above scenario correctly, I'm all ears.
    */
   
   #ifdef __NetBSD__
   #define USE_KQUEUE
   #endif
   
 #include <sys/cdefs.h>  #include <sys/cdefs.h>
 __RCSID("$NetBSD$");  __RCSID("$NetBSD$");
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/event.h>  
 #include <sys/mman.h>  #include <sys/mman.h>
 #include <sys/socket.h>  #include <sys/socket.h>
   #include <sys/time.h>
   
   #ifdef USE_KQUEUE
   #include <sys/event.h>
   #endif
   
 #include <arpa/inet.h>  #include <arpa/inet.h>
 #include <netinet/in.h>  #include <netinet/in.h>
Line 70  ssize_t (*host_sendmsg)(int, const struc
Line 93  ssize_t (*host_sendmsg)(int, const struc
 int     (*host_setsockopt)(int, int, int, const void *, socklen_t);  int     (*host_setsockopt)(int, int, int, const void *, socklen_t);
 int     (*host_dup)(int);  int     (*host_dup)(int);
   
   #ifdef USE_KQUEUE
 int     (*host_kqueue)(void);  int     (*host_kqueue)(void);
 int     (*host_kevent)(int, const struct kevent *, size_t,  int     (*host_kevent)(int, const struct kevent *, size_t,
                        struct kevent *, size_t, const struct timespec *);                         struct kevent *, size_t, const struct timespec *);
   #endif
   
 int     (*host_execve)(const char *, char *const[], char *const[]);  int     (*host_execve)(const char *, char *const[], char *const[]);
   
Line 197  cliwaitresp(struct spclient *spc, struct
Line 222  cliwaitresp(struct spclient *spc, struct
   
                 /* are we free to receive? */                  /* are we free to receive? */
                 if (spc->spc_istatus == SPCSTATUS_FREE) {                  if (spc->spc_istatus == SPCSTATUS_FREE) {
                         struct kevent kev[8];                          int gotresp, dosig, rv;
                         int gotresp, dosig, rv, i;  
   
                         spc->spc_istatus = SPCSTATUS_BUSY;                          spc->spc_istatus = SPCSTATUS_BUSY;
                         pthread_mutex_unlock(&spc->spc_mtx);                          pthread_mutex_unlock(&spc->spc_mtx);
   
                         dosig = 0;                          dosig = 0;
                         for (gotresp = 0; !gotresp; ) {                          for (gotresp = 0; !gotresp; ) {
   #ifdef USE_KQUEUE
                                   struct kevent kev[8];
                                   int i;
   
                                 /*                                  /*
                                  * typically we don't have a frame waiting                                   * typically we don't have a frame waiting
                                  * when we come in here, so call kevent now                                   * when we come in here, so call kevent now
Line 239  cliwaitresp(struct spclient *spc, struct
Line 267  cliwaitresp(struct spclient *spc, struct
                                  * determine what happens next.                                   * determine what happens next.
                                  */                                   */
  activity:   activity:
   #else /* USE_KQUEUE */
                                   struct pollfd pfd;
   
                                   pfd.fd = clispc.spc_fd;
                                   pfd.events = POLLIN;
   
                                   rv = host_poll(&pfd, 1, -1);
   #endif /* !USE_KQUEUE */
   
                                 switch (readframe(spc)) {                                  switch (readframe(spc)) {
                                 case 0:                                  case 0:
                                         continue;                                          continue;
Line 343  handshake_req(struct spclient *spc, int 
Line 380  handshake_req(struct spclient *spc, int 
         if (type == HANDSHAKE_FORK) {          if (type == HANDSHAKE_FORK) {
                 bonus = sizeof(rf);                  bonus = sizeof(rf);
         } else {          } else {
   #ifdef __NetBSD__
                   /* would procfs work on NetBSD too? */
                 myprogname = getprogname();                  myprogname = getprogname();
   #else
                   int fd = open("/proc/self/comm", O_RDONLY);
                   if (fd == -1) {
                           myprogname = "???";
                   } else {
                           static char commname[128];
   
                           if (read(fd, commname, sizeof(commname)) > 0) {
                                   char *n;
   
                                   n = strrchr(commname, '\n');
                                   if (n)
                                           *n = '\0';
                                   myprogname = commname;
                           } else {
                                   myprogname = "???";
                           }
                           close(fd);
                   }
   #endif
                 bonus = strlen(myprogname)+1;                  bonus = strlen(myprogname)+1;
         }          }
   
Line 620  doconnect(void)
Line 679  doconnect(void)
 {  {
         struct respwait rw;          struct respwait rw;
         struct rsp_hdr rhdr;          struct rsp_hdr rhdr;
         struct kevent kev[NSIG+1];  
         char banner[MAXBANNER];          char banner[MAXBANNER];
         struct pollfd pfd;          struct pollfd pfd;
         int s, error, flags, i;          int s, error, flags;
         ssize_t n;          ssize_t n;
   
         if (kq != -1)          if (kq != -1)
Line 668  doconnect(void)
Line 726  doconnect(void)
   
         pfd.fd = s;          pfd.fd = s;
         pfd.events = POLLIN;          pfd.events = POLLIN;
         while (host_connect(s, serv_sa, (socklen_t)serv_sa->sa_len) == -1) {          while (host_connect(s, serv_sa, parsetab[ptab_idx].slen) == -1) {
                 if (errno == EINTR)                  if (errno == EINTR)
                         continue;                          continue;
                 ERRLOG(("rump_sp: client connect failed: %s\n",                  ERRLOG(("rump_sp: client connect failed: %s\n",
Line 702  doconnect(void)
Line 760  doconnect(void)
         clispc.spc_state = SPCSTATE_RUNNING;          clispc.spc_state = SPCSTATE_RUNNING;
         clispc.spc_reconnecting = 0;          clispc.spc_reconnecting = 0;
   
   #ifdef USE_KQUEUE
   {
           struct kevent kev[NSIG+1];
           int i;
   
         /* setup kqueue, we want all signals and the fd */          /* setup kqueue, we want all signals and the fd */
         if ((kq = dupgood(host_kqueue(), 0)) == -1) {          if ((kq = dupgood(host_kqueue(), 0)) == -1) {
                 ERRLOG(("rump_sp: cannot setup kqueue"));                  ERRLOG(("rump_sp: cannot setup kqueue"));
Line 717  doconnect(void)
Line 780  doconnect(void)
                 ERRLOG(("rump_sp: kevent() failed"));                  ERRLOG(("rump_sp: kevent() failed"));
                 return -1;                  return -1;
         }          }
   }
   #endif /* USE_KQUEUE */
   
         return 0;          return 0;
 }  }
Line 733  doinit(void)
Line 798  doinit(void)
 }  }
   
 void *rumpclient__dlsym(void *, const char *);  void *rumpclient__dlsym(void *, const char *);
 void *rumphijack_dlsym(void *, const char *) __attribute__((__weak__));  
 void *  void *
 rumpclient__dlsym(void *handle, const char *symbol)  rumpclient__dlsym(void *handle, const char *symbol)
 {  {
   
         return dlsym(handle, symbol);          return dlsym(handle, symbol);
 }  }
 __weak_alias(rumphijack_dlsym,rumpclient__dlsym)  void *rumphijack_dlsym(void *, const char *)
       __attribute__((__weak__, alias("rumpclient__dlsym")));
   
 static pid_t init_done = 0;  static pid_t init_done = 0;
   
Line 771  rumpclient_init(void)
Line 836  rumpclient_init(void)
         sigfillset(&fullset);          sigfillset(&fullset);
   
         /*          /*
          * sag mir, wo die symbol sind.  zogen fort, der krieg beginnt.           * sag mir, wo die symbols sind.  zogen fort, der krieg beginnt.
          * wann wird man je verstehen?  wann wird man je verstehen?           * wann wird man je verstehen?  wann wird man je verstehen?
          */           */
 #define FINDSYM2(_name_,_syscall_)                                      \  #define FINDSYM2(_name_,_syscall_)                                      \
Line 784  rumpclient_init(void)
Line 849  rumpclient_init(void)
                             dlerror());                                 \                              dlerror());                                 \
         }          }
 #define FINDSYM(_name_) FINDSYM2(_name_,_name_)  #define FINDSYM(_name_) FINDSYM2(_name_,_name_)
   #ifdef __NetBSD__
         FINDSYM2(socket,__socket30)          FINDSYM2(socket,__socket30)
   #else
           FINDSYM(socket)
   #endif
   
         FINDSYM(close)          FINDSYM(close)
         FINDSYM(connect)          FINDSYM(connect)
         FINDSYM(fcntl)          FINDSYM(fcntl)
Line 793  rumpclient_init(void)
Line 863  rumpclient_init(void)
         FINDSYM(sendmsg)          FINDSYM(sendmsg)
         FINDSYM(setsockopt)          FINDSYM(setsockopt)
         FINDSYM(dup)          FINDSYM(dup)
         FINDSYM(kqueue)  
         FINDSYM(execve)          FINDSYM(execve)
   
   #ifdef USE_KQUEUE
           FINDSYM(kqueue)
 #if !__NetBSD_Prereq__(5,99,7)  #if !__NetBSD_Prereq__(5,99,7)
         FINDSYM(kevent)          FINDSYM(kevent)
 #else  #else
         FINDSYM2(kevent,_sys___kevent50)          FINDSYM2(kevent,_sys___kevent50)
 #endif  #endif
   #endif /* USE_KQUEUE */
   
 #undef  FINDSYM  #undef  FINDSYM
 #undef  FINDSY2  #undef  FINDSY2
   
Line 960  rumpclient__closenotify(int *fdp, enum r
Line 1034  rumpclient__closenotify(int *fdp, enum r
         case RUMPCLIENT_CLOSE_CLOSE:          case RUMPCLIENT_CLOSE_CLOSE:
         case RUMPCLIENT_CLOSE_DUP2:          case RUMPCLIENT_CLOSE_DUP2:
                 if (fd == clispc.spc_fd) {                  if (fd == clispc.spc_fd) {
                         struct kevent kev[2];  
   
                         newfd = dupgood(clispc.spc_fd, 1);                          newfd = dupgood(clispc.spc_fd, 1);
                         if (newfd == -1)                          if (newfd == -1)
                                 return -1;                                  return -1;
   
   #ifdef USE_KQUEUE
                           {
                           struct kevent kev[2];
   
                         /*                          /*
                          * now, we have a new socket number, so change                           * now, we have a new socket number, so change
                          * the file descriptor that kqueue is                           * the file descriptor that kqueue is
Line 981  rumpclient__closenotify(int *fdp, enum r
Line 1058  rumpclient__closenotify(int *fdp, enum r
                                 return -1;                                  return -1;
                         }                          }
                         clispc.spc_fd = newfd;                          clispc.spc_fd = newfd;
                           }
                 }                  }
                 if (fd == kq) {                  if (fd == kq) {
                         newfd = dupgood(kq, 1);                          newfd = dupgood(kq, 1);
                         if (newfd == -1)                          if (newfd == -1)
                                 return -1;                                  return -1;
                         kq = newfd;                          kq = newfd;
   #else /* USE_KQUEUE */
                           clispc.spc_fd = newfd;
   #endif /* !USE_KQUEUE */
                 }                  }
                 break;                  break;
         }          }

Legend:
Removed from v.1.48  
changed lines
  Added in v.1.49

CVSweb <webmaster@jp.NetBSD.org>