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

Annotation of src/lib/librumpclient/rumpclient.c, Revision 1.8

1.8     ! pooka       1: /*      $NetBSD: rumpclient.c,v 1.7 2010/11/30 14:24:40 pooka Exp $    */
1.1       pooka       2:
                      3: /*
                      4:  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  *
                     15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
                     16:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     18:  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     19:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     20:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     21:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     22:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     23:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     24:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     25:  * SUCH DAMAGE.
                     26:  */
                     27:
                     28: /*
                     29:  * Client side routines for rump syscall proxy.
                     30:  */
                     31:
                     32: #include <sys/cdefs.h>
                     33: __RCSID("$NetBSD");
                     34:
1.5       pooka      35: #include <sys/param.h>
1.1       pooka      36: #include <sys/mman.h>
                     37: #include <sys/socket.h>
                     38:
                     39: #include <arpa/inet.h>
                     40: #include <netinet/in.h>
                     41: #include <netinet/tcp.h>
                     42:
                     43: #include <assert.h>
                     44: #include <errno.h>
                     45: #include <fcntl.h>
                     46: #include <poll.h>
                     47: #include <pthread.h>
                     48: #include <stdarg.h>
                     49: #include <stdio.h>
                     50: #include <stdlib.h>
                     51: #include <string.h>
                     52: #include <unistd.h>
                     53:
                     54: #include <rump/rumpclient.h>
                     55:
                     56: #include "sp_common.c"
                     57:
                     58: static struct spclient clispc;
                     59:
                     60: static int
1.3       pooka      61: syscall_req(struct spclient *spc, int sysnum,
                     62:        const void *data, size_t dlen, void **resp)
1.1       pooka      63: {
                     64:        struct rsp_hdr rhdr;
1.3       pooka      65:        struct respwait rw;
                     66:        int rv;
1.1       pooka      67:
                     68:        rhdr.rsp_len = sizeof(rhdr) + dlen;
1.3       pooka      69:        rhdr.rsp_class = RUMPSP_REQ;
                     70:        rhdr.rsp_type = RUMPSP_SYSCALL;
1.1       pooka      71:        rhdr.rsp_sysnum = sysnum;
                     72:
1.6       pooka      73:        do {
                     74:                putwait(spc, &rw, &rhdr);
                     75:                rv = dosend(spc, &rhdr, sizeof(rhdr));
                     76:                rv = dosend(spc, data, dlen);
                     77:                if (rv) {
                     78:                        unputwait(spc, &rw);
                     79:                        return rv;
                     80:                }
                     81:
                     82:                rv = waitresp(spc, &rw);
                     83:        } while (rv == EAGAIN);
1.3       pooka      84:
                     85:        *resp = rw.rw_data;
                     86:        return rv;
1.1       pooka      87: }
                     88:
                     89: static int
1.5       pooka      90: send_copyin_resp(struct spclient *spc, uint64_t reqno, void *data, size_t dlen,
                     91:        int wantstr)
1.1       pooka      92: {
                     93:        struct rsp_hdr rhdr;
1.3       pooka      94:        int rv;
1.1       pooka      95:
1.5       pooka      96:        if (wantstr)
                     97:                dlen = MIN(dlen, strlen(data)+1);
                     98:
1.1       pooka      99:        rhdr.rsp_len = sizeof(rhdr) + dlen;
                    100:        rhdr.rsp_reqno = reqno;
1.3       pooka     101:        rhdr.rsp_class = RUMPSP_RESP;
                    102:        rhdr.rsp_type = RUMPSP_COPYIN;
1.1       pooka     103:        rhdr.rsp_sysnum = 0;
                    104:
1.3       pooka     105:        sendlock(spc);
                    106:        rv = dosend(spc, &rhdr, sizeof(rhdr));
                    107:        rv = dosend(spc, data, dlen);
                    108:        sendunlock(spc);
1.1       pooka     109:
1.3       pooka     110:        return rv;
1.1       pooka     111: }
                    112:
                    113: static int
                    114: send_anonmmap_resp(struct spclient *spc, uint64_t reqno, void *addr)
                    115: {
                    116:        struct rsp_hdr rhdr;
1.3       pooka     117:        int rv;
1.1       pooka     118:
                    119:        rhdr.rsp_len = sizeof(rhdr) + sizeof(addr);
                    120:        rhdr.rsp_reqno = reqno;
1.3       pooka     121:        rhdr.rsp_class = RUMPSP_RESP;
                    122:        rhdr.rsp_type = RUMPSP_ANONMMAP;
1.1       pooka     123:        rhdr.rsp_sysnum = 0;
                    124:
1.3       pooka     125:        sendlock(spc);
                    126:        rv = dosend(spc, &rhdr, sizeof(rhdr));
                    127:        rv = dosend(spc, &addr, sizeof(addr));
                    128:        sendunlock(spc);
1.1       pooka     129:
1.3       pooka     130:        return rv;
1.1       pooka     131: }
                    132:
                    133: int
                    134: rumpclient_syscall(int sysnum, const void *data, size_t dlen,
                    135:        register_t *retval)
                    136: {
                    137:        struct rsp_sysresp *resp;
1.3       pooka     138:        void *rdata;
                    139:        int rv;
                    140:
                    141:        DPRINTF(("rumpsp syscall_req: syscall %d with %p/%zu\n",
                    142:            sysnum, data, dlen));
                    143:
                    144:        rv = syscall_req(&clispc, sysnum, data, dlen, &rdata);
                    145:        if (rv)
                    146:                return rv;
                    147:
                    148:        resp = rdata;
                    149:        DPRINTF(("rumpsp syscall_resp: syscall %d error %d, rv: %d/%d\n",
                    150:            sysnum, rv, resp->rsys_retval[0], resp->rsys_retval[1]));
1.1       pooka     151:
1.3       pooka     152:        memcpy(retval, &resp->rsys_retval, sizeof(resp->rsys_retval));
                    153:        rv = resp->rsys_error;
                    154:        free(rdata);
1.1       pooka     155:
1.3       pooka     156:        return rv;
                    157: }
1.1       pooka     158:
1.3       pooka     159: static void
                    160: handlereq(struct spclient *spc)
                    161: {
                    162:        struct rsp_copydata *copydata;
                    163:        void *mapaddr;
                    164:        size_t maplen;
1.5       pooka     165:        int reqtype = spc->spc_hdr.rsp_type;
1.1       pooka     166:
1.5       pooka     167:        switch (reqtype) {
1.3       pooka     168:        case RUMPSP_COPYIN:
1.5       pooka     169:        case RUMPSP_COPYINSTR:
1.3       pooka     170:                /*LINTED*/
                    171:                copydata = (struct rsp_copydata *)spc->spc_buf;
                    172:                DPRINTF(("rump_sp handlereq: copyin request: %p/%zu\n",
                    173:                    copydata->rcp_addr, copydata->rcp_len));
                    174:                send_copyin_resp(spc, spc->spc_hdr.rsp_reqno,
1.5       pooka     175:                    copydata->rcp_addr, copydata->rcp_len,
                    176:                    reqtype == RUMPSP_COPYINSTR);
1.3       pooka     177:                break;
                    178:        case RUMPSP_COPYOUT:
1.5       pooka     179:        case RUMPSP_COPYOUTSTR:
1.3       pooka     180:                /*LINTED*/
                    181:                copydata = (struct rsp_copydata *)spc->spc_buf;
                    182:                DPRINTF(("rump_sp handlereq: copyout request: %p/%zu\n",
                    183:                    copydata->rcp_addr, copydata->rcp_len));
                    184:                /*LINTED*/
                    185:                memcpy(copydata->rcp_addr, copydata->rcp_data,
                    186:                    copydata->rcp_len);
                    187:                break;
                    188:        case RUMPSP_ANONMMAP:
                    189:                /*LINTED*/
                    190:                maplen = *(size_t *)spc->spc_buf;
                    191:                mapaddr = mmap(NULL, maplen, PROT_READ|PROT_WRITE,
                    192:                    MAP_ANON, -1, 0);
                    193:                if (mapaddr == MAP_FAILED)
                    194:                        mapaddr = NULL;
                    195:                DPRINTF(("rump_sp handlereq: anonmmap: %p\n", mapaddr));
                    196:                send_anonmmap_resp(spc, spc->spc_hdr.rsp_reqno, mapaddr);
                    197:                break;
                    198:        default:
                    199:                printf("PANIC: INVALID TYPE\n");
                    200:                abort();
                    201:                break;
1.1       pooka     202:        }
                    203:
1.6       pooka     204:        spcfreebuf(spc);
1.1       pooka     205: }
                    206:
                    207: int
                    208: rumpclient_init()
                    209: {
                    210:        struct sockaddr *sap;
                    211:        char *p;
                    212:        unsigned idx;
                    213:        int error, s;
                    214:
1.7       pooka     215:        if ((p = getenv("RUMP_SERVER")) == NULL) {
1.2       pooka     216:                errno = ENOENT;
                    217:                return -1;
                    218:        }
1.1       pooka     219:
1.2       pooka     220:        if ((error = parseurl(p, &sap, &idx, 0)) != 0) {
                    221:                errno = error;
                    222:                return -1;
                    223:        }
1.1       pooka     224:
                    225:        s = socket(parsetab[idx].domain, SOCK_STREAM, 0);
                    226:        if (s == -1)
1.2       pooka     227:                return -1;
1.1       pooka     228:
1.8     ! pooka     229:        if (connect(s, sap, (socklen_t)sap->sa_len) == -1) {
1.2       pooka     230:                error = errno;
1.1       pooka     231:                fprintf(stderr, "rump_sp: client connect failed\n");
1.2       pooka     232:                errno = error;
                    233:                return -1;
1.1       pooka     234:        }
1.4       pooka     235:
1.1       pooka     236:        if ((error = parsetab[idx].connhook(s)) != 0) {
1.2       pooka     237:                error = errno;
1.1       pooka     238:                fprintf(stderr, "rump_sp: connect hook failed\n");
1.2       pooka     239:                errno = error;
                    240:                return -1;
1.1       pooka     241:        }
                    242:        clispc.spc_fd = s;
1.3       pooka     243:        TAILQ_INIT(&clispc.spc_respwait);
                    244:        pthread_mutex_init(&clispc.spc_mtx, NULL);
                    245:        pthread_cond_init(&clispc.spc_cv, NULL);
1.1       pooka     246:
                    247:        return 0;
                    248: }

CVSweb <webmaster@jp.NetBSD.org>