Home | History | Annotate | Line # | Download | only in librumpuser
rumpuser.c revision 1.19.2.4
      1  1.19.2.3    tls /*	$NetBSD: rumpuser.c,v 1.19.2.4 2014/08/20 00:02:21 tls Exp $	*/
      2       1.1  pooka 
      3       1.1  pooka /*
      4       1.1  pooka  * Copyright (c) 2007-2010 Antti Kantee.  All Rights Reserved.
      5       1.1  pooka  *
      6       1.1  pooka  * Redistribution and use in source and binary forms, with or without
      7       1.1  pooka  * modification, are permitted provided that the following conditions
      8       1.1  pooka  * are met:
      9       1.1  pooka  * 1. Redistributions of source code must retain the above copyright
     10       1.1  pooka  *    notice, this list of conditions and the following disclaimer.
     11       1.1  pooka  * 2. Redistributions in binary form must reproduce the above copyright
     12       1.1  pooka  *    notice, this list of conditions and the following disclaimer in the
     13       1.1  pooka  *    documentation and/or other materials provided with the distribution.
     14       1.1  pooka  *
     15       1.1  pooka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     16       1.1  pooka  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17       1.1  pooka  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18       1.1  pooka  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     19       1.1  pooka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     20       1.1  pooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21       1.1  pooka  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22       1.1  pooka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     23       1.1  pooka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     24       1.1  pooka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25       1.1  pooka  * SUCH DAMAGE.
     26       1.1  pooka  */
     27       1.1  pooka 
     28      1.18  pooka #include "rumpuser_port.h"
     29      1.18  pooka 
     30       1.1  pooka #if !defined(lint)
     31  1.19.2.3    tls __RCSID("$NetBSD: rumpuser.c,v 1.19.2.4 2014/08/20 00:02:21 tls Exp $");
     32       1.1  pooka #endif /* !lint */
     33       1.1  pooka 
     34      1.18  pooka #include <sys/stat.h>
     35      1.18  pooka #include <sys/time.h>
     36  1.19.2.4    tls #include <sys/types.h>
     37  1.19.2.2    tls 
     38       1.1  pooka #include <assert.h>
     39       1.1  pooka #include <errno.h>
     40       1.1  pooka #include <fcntl.h>
     41  1.19.2.1    tls #include <netdb.h>
     42       1.2  pooka #include <signal.h>
     43       1.1  pooka #include <stdarg.h>
     44       1.1  pooka #include <stdint.h>
     45       1.1  pooka #include <stdio.h>
     46       1.1  pooka #include <stdlib.h>
     47       1.1  pooka #include <string.h>
     48       1.1  pooka #include <time.h>
     49       1.1  pooka #include <unistd.h>
     50       1.1  pooka 
     51       1.1  pooka #include <rump/rumpuser.h>
     52       1.1  pooka 
     53       1.1  pooka #include "rumpuser_int.h"
     54       1.1  pooka 
     55  1.19.2.3    tls struct rumpuser_hyperup rumpuser__hyp;
     56  1.19.2.3    tls 
     57       1.1  pooka int
     58  1.19.2.3    tls rumpuser_init(int version, const struct rumpuser_hyperup *hyp)
     59       1.8  pooka {
     60  1.19.2.4    tls 	int rv;
     61       1.8  pooka 
     62  1.19.2.3    tls 	if (version != RUMPUSER_VERSION) {
     63  1.19.2.3    tls 		fprintf(stderr, "rumpuser mismatch, kern: %d, hypervisor %d\n",
     64  1.19.2.3    tls 		    version, RUMPUSER_VERSION);
     65  1.19.2.4    tls 		abort();
     66  1.19.2.3    tls 	}
     67  1.19.2.3    tls 
     68  1.19.2.4    tls 	rv = rumpuser__random_init();
     69  1.19.2.4    tls 	if (rv != 0) {
     70  1.19.2.4    tls 		ET(rv);
     71  1.19.2.3    tls 	}
     72  1.19.2.3    tls 
     73  1.19.2.3    tls 	rumpuser__thrinit();
     74  1.19.2.3    tls 	rumpuser__hyp = *hyp;
     75  1.19.2.3    tls 
     76  1.19.2.3    tls 	return 0;
     77       1.8  pooka }
     78       1.8  pooka 
     79       1.8  pooka int
     80  1.19.2.3    tls rumpuser_clock_gettime(int enum_rumpclock, int64_t *sec, long *nsec)
     81       1.1  pooka {
     82  1.19.2.3    tls 	enum rumpclock rclk = enum_rumpclock;
     83  1.19.2.3    tls 	struct timespec ts;
     84  1.19.2.3    tls 	clockid_t clk;
     85       1.1  pooka 	int rv;
     86       1.1  pooka 
     87  1.19.2.3    tls 	switch (rclk) {
     88  1.19.2.3    tls 	case RUMPUSER_CLOCK_RELWALL:
     89  1.19.2.3    tls 		clk = CLOCK_REALTIME;
     90  1.19.2.3    tls 		break;
     91  1.19.2.3    tls 	case RUMPUSER_CLOCK_ABSMONO:
     92  1.19.2.3    tls #ifdef HAVE_CLOCK_NANOSLEEP
     93  1.19.2.3    tls 		clk = CLOCK_MONOTONIC;
     94  1.19.2.3    tls #else
     95  1.19.2.3    tls 		clk = CLOCK_REALTIME;
     96  1.19.2.3    tls #endif
     97  1.19.2.3    tls 		break;
     98  1.19.2.3    tls 	default:
     99  1.19.2.3    tls 		abort();
    100       1.1  pooka 	}
    101       1.1  pooka 
    102  1.19.2.3    tls 	if (clock_gettime(clk, &ts) == -1) {
    103  1.19.2.3    tls 		rv = errno;
    104      1.13  pooka 	} else {
    105  1.19.2.3    tls 		*sec = ts.tv_sec;
    106  1.19.2.3    tls 		*nsec = ts.tv_nsec;
    107  1.19.2.3    tls 		rv = 0;
    108      1.13  pooka 	}
    109      1.13  pooka 
    110  1.19.2.3    tls 	ET(rv);
    111       1.1  pooka }
    112       1.1  pooka 
    113       1.1  pooka int
    114  1.19.2.3    tls rumpuser_clock_sleep(int enum_rumpclock, int64_t sec, long nsec)
    115       1.1  pooka {
    116  1.19.2.3    tls 	enum rumpclock rclk = enum_rumpclock;
    117  1.19.2.3    tls 	struct timespec rqt, rmt;
    118  1.19.2.3    tls 	int nlocks;
    119  1.19.2.3    tls 	int rv;
    120       1.1  pooka 
    121  1.19.2.3    tls 	rumpkern_unsched(&nlocks, NULL);
    122       1.1  pooka 
    123  1.19.2.3    tls 	/*LINTED*/
    124  1.19.2.3    tls 	rqt.tv_sec = sec;
    125  1.19.2.3    tls 	/*LINTED*/
    126  1.19.2.3    tls 	rqt.tv_nsec = nsec;
    127       1.1  pooka 
    128  1.19.2.3    tls 	switch (rclk) {
    129  1.19.2.3    tls 	case RUMPUSER_CLOCK_RELWALL:
    130  1.19.2.3    tls 		do {
    131  1.19.2.3    tls 			rv = nanosleep(&rqt, &rmt);
    132  1.19.2.3    tls 			rqt = rmt;
    133  1.19.2.3    tls 		} while (rv == -1 && errno == EINTR);
    134  1.19.2.3    tls 		if (rv == -1) {
    135  1.19.2.3    tls 			rv = errno;
    136  1.19.2.3    tls 		}
    137  1.19.2.3    tls 		break;
    138  1.19.2.3    tls 	case RUMPUSER_CLOCK_ABSMONO:
    139  1.19.2.3    tls 		do {
    140  1.19.2.3    tls #ifdef HAVE_CLOCK_NANOSLEEP
    141  1.19.2.3    tls 			rv = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
    142  1.19.2.3    tls 			    &rqt, NULL);
    143  1.19.2.3    tls #else
    144  1.19.2.3    tls 			/* le/la/der/die/das sigh. timevalspec tailspin */
    145  1.19.2.3    tls 			struct timespec ts, tsr;
    146  1.19.2.3    tls 			clock_gettime(CLOCK_REALTIME, &ts);
    147  1.19.2.3    tls 			if (ts.tv_sec == rqt.tv_sec ?
    148  1.19.2.3    tls 			    ts.tv_nsec > rqt.tv_nsec : ts.tv_sec > rqt.tv_sec) {
    149  1.19.2.3    tls 				rv = 0;
    150  1.19.2.3    tls 			} else {
    151  1.19.2.3    tls 				tsr.tv_sec = rqt.tv_sec - ts.tv_sec;
    152  1.19.2.3    tls 				tsr.tv_nsec = rqt.tv_nsec - ts.tv_nsec;
    153  1.19.2.3    tls 				if (tsr.tv_nsec < 0) {
    154  1.19.2.3    tls 					tsr.tv_sec--;
    155  1.19.2.3    tls 					tsr.tv_nsec += 1000*1000*1000;
    156  1.19.2.3    tls 				}
    157  1.19.2.3    tls 				rv = nanosleep(&tsr, NULL);
    158  1.19.2.3    tls 			}
    159  1.19.2.3    tls #endif
    160  1.19.2.3    tls 		} while (rv == -1 && errno == EINTR);
    161  1.19.2.3    tls 		if (rv == -1) {
    162  1.19.2.3    tls 			rv = errno;
    163  1.19.2.3    tls 		}
    164  1.19.2.3    tls 		break;
    165  1.19.2.3    tls 	default:
    166  1.19.2.3    tls 		abort();
    167  1.19.2.3    tls 	}
    168       1.1  pooka 
    169  1.19.2.3    tls 	rumpkern_sched(nlocks, NULL);
    170       1.1  pooka 
    171  1.19.2.3    tls 	ET(rv);
    172       1.1  pooka }
    173       1.1  pooka 
    174  1.19.2.3    tls static int
    175  1.19.2.3    tls gethostncpu(void)
    176       1.1  pooka {
    177  1.19.2.4    tls 	int ncpu = 1; /* unknown, really */
    178       1.1  pooka 
    179  1.19.2.4    tls #ifdef _SC_NPROCESSORS_ONLN
    180  1.19.2.3    tls 	ncpu = sysconf(_SC_NPROCESSORS_ONLN);
    181  1.19.2.3    tls #endif
    182  1.19.2.3    tls 
    183  1.19.2.3    tls 	return ncpu;
    184       1.1  pooka }
    185       1.1  pooka 
    186       1.1  pooka int
    187  1.19.2.3    tls rumpuser_getparam(const char *name, void *buf, size_t blen)
    188       1.1  pooka {
    189       1.1  pooka 	int rv;
    190       1.1  pooka 
    191  1.19.2.3    tls 	if (strcmp(name, RUMPUSER_PARAM_NCPU) == 0) {
    192  1.19.2.3    tls 		int ncpu;
    193  1.19.2.1    tls 
    194  1.19.2.3    tls 		if (getenv_r("RUMP_NCPU", buf, blen) == -1) {
    195  1.19.2.4    tls 			sprintf(buf, "2"); /* default */
    196  1.19.2.4    tls 		} else if (strcmp(buf, "host") == 0) {
    197  1.19.2.3    tls 			ncpu = gethostncpu();
    198  1.19.2.3    tls 			snprintf(buf, blen, "%d", ncpu);
    199  1.19.2.1    tls 		}
    200  1.19.2.3    tls 		rv = 0;
    201  1.19.2.3    tls 	} else if (strcmp(name, RUMPUSER_PARAM_HOSTNAME) == 0) {
    202  1.19.2.3    tls 		char tmp[MAXHOSTNAMELEN];
    203  1.19.2.1    tls 
    204  1.19.2.3    tls 		if (gethostname(tmp, sizeof(tmp)) == -1) {
    205  1.19.2.3    tls 			snprintf(buf, blen, "rump-%05d", (int)getpid());
    206  1.19.2.3    tls 		} else {
    207  1.19.2.3    tls 			snprintf(buf, blen, "rump-%05d.%s",
    208  1.19.2.3    tls 			    (int)getpid(), tmp);
    209  1.19.2.3    tls 		}
    210  1.19.2.3    tls 		rv = 0;
    211  1.19.2.3    tls 	} else if (*name == '_') {
    212  1.19.2.3    tls 		rv = EINVAL;
    213  1.19.2.3    tls 	} else {
    214  1.19.2.3    tls 		if (getenv_r(name, buf, blen) == -1)
    215  1.19.2.3    tls 			rv = errno;
    216  1.19.2.3    tls 		else
    217  1.19.2.3    tls 			rv = 0;
    218  1.19.2.1    tls 	}
    219  1.19.2.1    tls 
    220  1.19.2.3    tls 	ET(rv);
    221  1.19.2.1    tls }
    222  1.19.2.1    tls 
    223  1.19.2.3    tls void
    224  1.19.2.3    tls rumpuser_putchar(int c)
    225  1.19.2.1    tls {
    226  1.19.2.1    tls 
    227  1.19.2.3    tls 	putchar(c);
    228  1.19.2.1    tls }
    229  1.19.2.2    tls 
    230  1.19.2.4    tls __dead void
    231  1.19.2.3    tls rumpuser_exit(int rv)
    232  1.19.2.2    tls {
    233  1.19.2.2    tls 
    234  1.19.2.3    tls 	if (rv == RUMPUSER_PANIC)
    235  1.19.2.3    tls 		abort();
    236  1.19.2.3    tls 	else
    237  1.19.2.3    tls 		exit(rv);
    238  1.19.2.2    tls }
    239  1.19.2.2    tls 
    240  1.19.2.3    tls void
    241  1.19.2.3    tls rumpuser_seterrno(int error)
    242  1.19.2.2    tls {
    243  1.19.2.2    tls 
    244  1.19.2.3    tls 	errno = error;
    245  1.19.2.2    tls }
    246       1.1  pooka 
    247       1.1  pooka /*
    248       1.1  pooka  * This is meant for safe debugging prints from the kernel.
    249       1.1  pooka  */
    250  1.19.2.3    tls void
    251       1.1  pooka rumpuser_dprintf(const char *format, ...)
    252       1.1  pooka {
    253       1.1  pooka 	va_list ap;
    254       1.1  pooka 
    255       1.1  pooka 	va_start(ap, format);
    256  1.19.2.3    tls 	vfprintf(stderr, format, ap);
    257       1.1  pooka 	va_end(ap);
    258       1.1  pooka }
    259       1.2  pooka 
    260       1.2  pooka int
    261  1.19.2.4    tls rumpuser_kill(int64_t pid, int rumpsig)
    262       1.4  pooka {
    263  1.19.2.4    tls 	int sig;
    264      1.18  pooka 
    265  1.19.2.4    tls 	sig = rumpuser__sig_rump2host(rumpsig);
    266  1.19.2.4    tls 	if (sig > 0)
    267  1.19.2.4    tls 		raise(sig);
    268  1.19.2.4    tls 	return 0;
    269      1.16    tls }
    270