static int devopen(int num) { int devnum = 768 + (num<<6); char buf[32]; int nlocks; if (blkopen[num]) { blkopen[num]++; return 1; } snprintf(buf, sizeof(buf), "device/vbd/%d", devnum); rumpkern_unsched(&nlocks, NULL); blkdevs[num] = init_blkfront(buf, &blkinfos[num]); rumpkern_sched(nlocks, NULL); if (blkdevs[num] != NULL) { blkopen[num] = 1; return 0; } else { return EIO; /* guess something */ } }
int rumpuser_iovwrite(int fd, const struct rumpuser_iovec *ruiov, size_t iovlen, int64_t roff, size_t *retp) { const struct iovec *iov = (const struct iovec *)ruiov; off_t off = (off_t)roff; ssize_t nn; int rv; if (off == RUMPUSER_IOV_NOSEEK) { KLOCK_WRAP(nn = writev(fd, iov, iovlen)); } else { int nlocks; rumpkern_unsched(&nlocks, NULL); if (lseek(fd, off, SEEK_SET) == off) { nn = writev(fd, iov, iovlen); } else { nn = -1; } rumpkern_sched(nlocks, NULL); } if (nn == -1) { rv = errno; } else { *retp = (size_t)nn; rv = 0; } ET(rv); }
int rumpuser_clock_sleep(int enum_rumpclock, int64_t sec, long nsec) { enum rumpclock rclk = enum_rumpclock; struct thread *thread; uint32_t msec; int nlocks; rumpkern_unsched(&nlocks, NULL); switch (rclk) { case RUMPUSER_CLOCK_RELWALL: msec = sec * 1000 + nsec / (1000*1000UL); msleep(msec); break; case RUMPUSER_CLOCK_ABSMONO: thread = get_current(); thread->wakeup_time = sec * (1000*1000*1000ULL) + nsec; clear_runnable(thread); schedule(); break; } rumpkern_sched(nlocks, NULL); return 0; }
int rumpuser_clock_sleep(int enum_rumpclock, int64_t sec, long nsec) { enum rumpclock rclk = enum_rumpclock; struct timespec rqt, rmt; int nlocks; int rv; rumpkern_unsched(&nlocks, NULL); /*LINTED*/ rqt.tv_sec = sec; /*LINTED*/ rqt.tv_nsec = nsec; switch (rclk) { case RUMPUSER_CLOCK_RELWALL: do { rv = nanosleep(&rqt, &rmt); rqt = rmt; } while (rv == -1 && errno == EINTR); if (rv == -1) { rv = errno; } break; case RUMPUSER_CLOCK_ABSMONO: do { #ifdef HAVE_CLOCK_NANOSLEEP rv = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &rqt, NULL); #else /* le/la/der/die/das sigh. timevalspec tailspin */ struct timespec ts, tsr; clock_gettime(CLOCK_REALTIME, &ts); if (ts.tv_sec == rqt.tv_sec ? ts.tv_nsec > rqt.tv_nsec : ts.tv_sec > rqt.tv_sec) { rv = 0; } else { tsr.tv_sec = rqt.tv_sec - ts.tv_sec; tsr.tv_nsec = rqt.tv_nsec - ts.tv_nsec; if (tsr.tv_nsec < 0) { tsr.tv_sec--; tsr.tv_nsec += 1000*1000*1000; } rv = nanosleep(&tsr, NULL); } #endif } while (rv == -1 && errno == EINTR); if (rv == -1) { rv = errno; } break; default: abort(); } rumpkern_sched(nlocks, NULL); ET(rv); }
int rumpuser_sp_anonmmap(void *arg, size_t howmuch, void **addr) { struct spclient *spc = arg; void *resp, *rdata = NULL; /* XXXuninit */ int nlocks, rv; rumpkern_unsched(&nlocks, NULL); rv = anonmmap_req(spc, howmuch, &rdata); if (rv) { rv = EFAULT; goto out; } resp = *(void **)rdata; free(rdata); if (resp == NULL) { rv = ENOMEM; } *addr = resp; out: rumpkern_sched(nlocks, NULL); ET(rv); }
void VIFHYPER_SEND(struct virtif_user *viu, struct iovec *iov, size_t iovlen) { size_t tlen, i; int nlocks; void *d; char *d0; rumpkern_unsched(&nlocks, NULL); /* * netfront doesn't do scatter-gather, so just simply * copy the data into one lump here. */ if (iovlen == 1) { d = iov->iov_base; tlen = iov->iov_len; } else { for (i = 0, tlen = 0; i < iovlen; i++) { tlen += iov[i].iov_len; } d = d0 = malloc(tlen); for (i = 0; i < iovlen; i++) { memcpy(d0, iov[i].iov_base, iov[i].iov_len); d0 += iov[i].iov_len; } } netfront_xmit(viu->viu_dev, d, tlen); if (iovlen != 1) free(d); rumpkern_sched(nlocks, NULL); }
static void cv_unsched(struct rumpuser_mtx *mtx, int *nlocks) { rumpkern_unsched(nlocks, mtx); rumpuser_mutex_exit(mtx); }
void * rumpuser_component_unschedule(void) { int nlocks; rumpkern_unsched(&nlocks, NULL); return (void *)(intptr_t)nlocks; }
int rumpuser_sp_raise(void *arg, int signo) { struct spclient *spc = arg; int rv, nlocks; rumpkern_unsched(&nlocks, NULL); rv = send_raise_req(spc, signo); rumpkern_sched(nlocks, NULL); return rv; }
void rumpuser_mutex_enter(struct rumpuser_mtx *mtx) { int nlocks; if (rumpuser_mutex_tryenter(mtx) != 0) { rumpkern_unsched(&nlocks, NULL); while (rumpuser_mutex_tryenter(mtx) != 0) wait(&mtx->waiters, BMK_SCHED_BLOCK_INFTIME); rumpkern_sched(nlocks, NULL); } }
int rumpuser_close(int fd) { int nlocks; rumpkern_unsched(&nlocks, NULL); fsync(fd); close(fd); rumpkern_sched(nlocks, NULL); ET(0); }
static int sp_copyout(void *arg, const void *laddr, void *raddr, size_t dlen) { struct spclient *spc = arg; int nlocks, rv; rumpkern_unsched(&nlocks, NULL); rv = send_copyout_req(spc, raddr, laddr, dlen); rumpkern_sched(nlocks, NULL); if (rv) rv = EFAULT; ET(rv); }
void rumpuser_bio(int fd, int op, void *data, size_t dlen, int64_t off, rump_biodone_fn biodone, void *donearg) { static int bio_inited; struct biocb *bio = memalloc(sizeof(*bio), 0); struct blkfront_aiocb *aiocb = &bio->bio_aiocb; int nlocks; int num = fd - BLKFDOFF; rumpkern_unsched(&nlocks, NULL); if (!bio_inited) { rumpuser_mutex_enter_nowrap(bio_mtx); if (!bio_inited) { bio_inited = 1; rumpuser_mutex_exit(bio_mtx); create_thread("biopoll", biothread, NULL); } else { rumpuser_mutex_exit(bio_mtx); } } bio->bio_done = biodone; bio->bio_arg = donearg; bio->bio_num = num; aiocb->aio_dev = blkdevs[num]; aiocb->aio_buf = data; aiocb->aio_nbytes = dlen; aiocb->aio_offset = off; aiocb->aio_cb = biocomp; aiocb->data = bio; if (op & RUMPUSER_BIO_READ) blkfront_aio_read(aiocb); else blkfront_aio_write(aiocb); rumpuser_mutex_enter(bio_mtx); bio_outstanding_total++; blkdev_outstanding[num]++; rumpuser_cv_signal(bio_cv); rumpuser_mutex_exit(bio_mtx); rumpkern_sched(nlocks, NULL); }
static void biocomp(struct blkfront_aiocb *aiocb, int ret) { struct biocb *bio = aiocb->data; int dummy, num; rumpkern_sched(0, NULL); if (ret) bio->bio_done(bio->bio_arg, 0, EIO); else bio->bio_done(bio->bio_arg, bio->bio_aiocb.aio_nbytes, 0); rumpkern_unsched(&dummy, NULL); num = bio->bio_num; xfree(bio); rumpuser_mutex_enter_nowrap(bio_mtx); bio_outstanding_total--; blkdev_outstanding[num]--; rumpuser_mutex_exit(bio_mtx); }
static int sp_copyin(void *arg, const void *raddr, void *laddr, size_t *len, int wantstr) { struct spclient *spc = arg; void *rdata = NULL; /* XXXuninit */ int rv, nlocks; rumpkern_unsched(&nlocks, NULL); rv = copyin_req(spc, raddr, len, wantstr, &rdata); if (rv) goto out; memcpy(laddr, rdata, *len); free(rdata); out: rumpkern_sched(nlocks, NULL); if (rv) rv = EFAULT; ET(rv); }
void rumpuser_rw_enter(int enum_rumprwlock, struct rumpuser_rw *rw) { enum rumprwlock lk = enum_rumprwlock; struct waithead *w = NULL; int nlocks; switch (lk) { case RUMPUSER_RW_WRITER: w = &rw->wwait; break; case RUMPUSER_RW_READER: w = &rw->rwait; break; } if (rumpuser_rw_tryenter(enum_rumprwlock, rw) != 0) { rumpkern_unsched(&nlocks, NULL); while (rumpuser_rw_tryenter(enum_rumprwlock, rw) != 0) wait(w, BMK_SCHED_BLOCK_INFTIME); rumpkern_sched(nlocks, NULL); } }
int VIFHYPER_CREATE(int devnum, struct virtif_sc *vif_sc, uint8_t *enaddr, struct virtif_user **viup) { struct virtif_user *viu = NULL; int rv, nlocks; rumpkern_unsched(&nlocks, NULL); viu = malloc(sizeof(*viu)); if (viu == NULL) { rv = ENOMEM; goto out; } memset(viu, 0, sizeof(*viu)); viu->viu_vifsc = vif_sc; viu->viu_dev = init_netfront(NULL, myrecv, enaddr, NULL, viu); if (!viu->viu_dev) { rv = EINVAL; /* ? */ free(viu); goto out; } if (create_thread("xenifp", pusher, viu) == NULL) { printk("fatal thread creation failure\n"); /* XXX */ do_exit(); } rv = 0; out: rumpkern_sched(nlocks, NULL); *viup = viu; return rv; }