[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.5

1.5     ! pooka       1: /*      $NetBSD: rumpclient.c,v 1.4 2010/11/24 17:03:39 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.3       pooka      73:        putwait(spc, &rw, &rhdr);
                     74:        rv = dosend(spc, &rhdr, sizeof(rhdr));
                     75:        rv = dosend(spc, data, dlen);
1.4       pooka      76:        if (rv) {
                     77:                unputwait(spc, &rw);
                     78:                return rv;
                     79:        }
1.3       pooka      80:
                     81:        rv = waitresp(spc, &rw);
                     82:        *resp = rw.rw_data;
                     83:        return rv;
1.1       pooka      84: }
                     85:
                     86: static int
1.5     ! pooka      87: send_copyin_resp(struct spclient *spc, uint64_t reqno, void *data, size_t dlen,
        !            88:        int wantstr)
1.1       pooka      89: {
                     90:        struct rsp_hdr rhdr;
1.3       pooka      91:        int rv;
1.1       pooka      92:
1.5     ! pooka      93:        if (wantstr)
        !            94:                dlen = MIN(dlen, strlen(data)+1);
        !            95:
1.1       pooka      96:        rhdr.rsp_len = sizeof(rhdr) + dlen;
                     97:        rhdr.rsp_reqno = reqno;
1.3       pooka      98:        rhdr.rsp_class = RUMPSP_RESP;
                     99:        rhdr.rsp_type = RUMPSP_COPYIN;
1.1       pooka     100:        rhdr.rsp_sysnum = 0;
                    101:
1.3       pooka     102:        sendlock(spc);
                    103:        rv = dosend(spc, &rhdr, sizeof(rhdr));
                    104:        rv = dosend(spc, data, dlen);
                    105:        sendunlock(spc);
1.1       pooka     106:
1.3       pooka     107:        return rv;
1.1       pooka     108: }
                    109:
                    110: static int
                    111: send_anonmmap_resp(struct spclient *spc, uint64_t reqno, void *addr)
                    112: {
                    113:        struct rsp_hdr rhdr;
1.3       pooka     114:        int rv;
1.1       pooka     115:
                    116:        rhdr.rsp_len = sizeof(rhdr) + sizeof(addr);
                    117:        rhdr.rsp_reqno = reqno;
1.3       pooka     118:        rhdr.rsp_class = RUMPSP_RESP;
                    119:        rhdr.rsp_type = RUMPSP_ANONMMAP;
1.1       pooka     120:        rhdr.rsp_sysnum = 0;
                    121:
1.3       pooka     122:        sendlock(spc);
                    123:        rv = dosend(spc, &rhdr, sizeof(rhdr));
                    124:        rv = dosend(spc, &addr, sizeof(addr));
                    125:        sendunlock(spc);
1.1       pooka     126:
1.3       pooka     127:        return rv;
1.1       pooka     128: }
                    129:
                    130: int
                    131: rumpclient_syscall(int sysnum, const void *data, size_t dlen,
                    132:        register_t *retval)
                    133: {
                    134:        struct rsp_sysresp *resp;
1.3       pooka     135:        void *rdata;
                    136:        int rv;
                    137:
                    138:        DPRINTF(("rumpsp syscall_req: syscall %d with %p/%zu\n",
                    139:            sysnum, data, dlen));
                    140:
                    141:        rv = syscall_req(&clispc, sysnum, data, dlen, &rdata);
                    142:        if (rv)
                    143:                return rv;
                    144:
                    145:        resp = rdata;
                    146:        DPRINTF(("rumpsp syscall_resp: syscall %d error %d, rv: %d/%d\n",
                    147:            sysnum, rv, resp->rsys_retval[0], resp->rsys_retval[1]));
1.1       pooka     148:
1.3       pooka     149:        memcpy(retval, &resp->rsys_retval, sizeof(resp->rsys_retval));
                    150:        rv = resp->rsys_error;
                    151:        free(rdata);
1.1       pooka     152:
1.3       pooka     153:        return rv;
                    154: }
1.1       pooka     155:
1.3       pooka     156: static void
                    157: handlereq(struct spclient *spc)
                    158: {
                    159:        struct rsp_copydata *copydata;
                    160:        void *mapaddr;
                    161:        size_t maplen;
1.5     ! pooka     162:        int reqtype = spc->spc_hdr.rsp_type;
1.1       pooka     163:
1.5     ! pooka     164:        switch (reqtype) {
1.3       pooka     165:        case RUMPSP_COPYIN:
1.5     ! pooka     166:        case RUMPSP_COPYINSTR:
1.3       pooka     167:                /*LINTED*/
                    168:                copydata = (struct rsp_copydata *)spc->spc_buf;
                    169:                DPRINTF(("rump_sp handlereq: copyin request: %p/%zu\n",
                    170:                    copydata->rcp_addr, copydata->rcp_len));
                    171:                send_copyin_resp(spc, spc->spc_hdr.rsp_reqno,
1.5     ! pooka     172:                    copydata->rcp_addr, copydata->rcp_len,
        !           173:                    reqtype == RUMPSP_COPYINSTR);
1.3       pooka     174:                break;
                    175:        case RUMPSP_COPYOUT:
1.5     ! pooka     176:        case RUMPSP_COPYOUTSTR:
1.3       pooka     177:                /*LINTED*/
                    178:                copydata = (struct rsp_copydata *)spc->spc_buf;
                    179:                DPRINTF(("rump_sp handlereq: copyout request: %p/%zu\n",
                    180:                    copydata->rcp_addr, copydata->rcp_len));
                    181:                /*LINTED*/
                    182:                memcpy(copydata->rcp_addr, copydata->rcp_data,
                    183:                    copydata->rcp_len);
                    184:                break;
                    185:        case RUMPSP_ANONMMAP:
                    186:                /*LINTED*/
                    187:                maplen = *(size_t *)spc->spc_buf;
                    188:                mapaddr = mmap(NULL, maplen, PROT_READ|PROT_WRITE,
                    189:                    MAP_ANON, -1, 0);
                    190:                if (mapaddr == MAP_FAILED)
                    191:                        mapaddr = NULL;
                    192:                DPRINTF(("rump_sp handlereq: anonmmap: %p\n", mapaddr));
                    193:                send_anonmmap_resp(spc, spc->spc_hdr.rsp_reqno, mapaddr);
                    194:                break;
                    195:        default:
                    196:                printf("PANIC: INVALID TYPE\n");
                    197:                abort();
                    198:                break;
1.1       pooka     199:        }
                    200:
1.3       pooka     201:        free(spc->spc_buf);
                    202:        spc->spc_off = 0;
                    203:        spc->spc_buf = NULL;
1.1       pooka     204: }
                    205:
                    206: int
                    207: rumpclient_init()
                    208: {
                    209:        struct sockaddr *sap;
                    210:        char *p;
                    211:        unsigned idx;
                    212:        int error, s;
                    213:
1.2       pooka     214:        if ((p = getenv("RUMP_SP_CLIENT")) == NULL) {
                    215:                errno = ENOENT;
                    216:                return -1;
                    217:        }
1.1       pooka     218:
1.2       pooka     219:        if ((error = parseurl(p, &sap, &idx, 0)) != 0) {
                    220:                errno = error;
                    221:                return -1;
                    222:        }
1.1       pooka     223:
                    224:        s = socket(parsetab[idx].domain, SOCK_STREAM, 0);
                    225:        if (s == -1)
1.2       pooka     226:                return -1;
1.1       pooka     227:
                    228:        if (connect(s, sap, sap->sa_len) == -1) {
1.2       pooka     229:                error = errno;
1.1       pooka     230:                fprintf(stderr, "rump_sp: client connect failed\n");
1.2       pooka     231:                errno = error;
                    232:                return -1;
1.1       pooka     233:        }
1.4       pooka     234:
1.1       pooka     235:        if ((error = parsetab[idx].connhook(s)) != 0) {
1.2       pooka     236:                error = errno;
1.1       pooka     237:                fprintf(stderr, "rump_sp: connect hook failed\n");
1.2       pooka     238:                errno = error;
                    239:                return -1;
1.1       pooka     240:        }
                    241:        clispc.spc_fd = s;
1.3       pooka     242:        TAILQ_INIT(&clispc.spc_respwait);
                    243:        pthread_mutex_init(&clispc.spc_mtx, NULL);
                    244:        pthread_cond_init(&clispc.spc_cv, NULL);
1.1       pooka     245:
                    246:        return 0;
                    247: }

CVSweb <webmaster@jp.NetBSD.org>