1*789Sahrens /* 2*789Sahrens * CDDL HEADER START 3*789Sahrens * 4*789Sahrens * The contents of this file are subject to the terms of the 5*789Sahrens * Common Development and Distribution License, Version 1.0 only 6*789Sahrens * (the "License"). You may not use this file except in compliance 7*789Sahrens * with the License. 8*789Sahrens * 9*789Sahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*789Sahrens * or http://www.opensolaris.org/os/licensing. 11*789Sahrens * See the License for the specific language governing permissions 12*789Sahrens * and limitations under the License. 13*789Sahrens * 14*789Sahrens * When distributing Covered Code, include this CDDL HEADER in each 15*789Sahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*789Sahrens * If applicable, add the following below this CDDL HEADER, with the 17*789Sahrens * fields enclosed by brackets "[]" replaced with your own identifying 18*789Sahrens * information: Portions Copyright [yyyy] [name of copyright owner] 19*789Sahrens * 20*789Sahrens * CDDL HEADER END 21*789Sahrens */ 22*789Sahrens /* 23*789Sahrens * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*789Sahrens * Use is subject to license terms. 25*789Sahrens */ 26*789Sahrens 27*789Sahrens #pragma ident "%Z%%M% %I% %E% SMI" 28*789Sahrens 29*789Sahrens #include <assert.h> 30*789Sahrens #include <sys/zfs_context.h> 31*789Sahrens #include <poll.h> 32*789Sahrens #include <string.h> 33*789Sahrens #include <stdio.h> 34*789Sahrens #include <stdlib.h> 35*789Sahrens #include <fcntl.h> 36*789Sahrens #include <sys/stat.h> 37*789Sahrens #include <sys/spa.h> 38*789Sahrens #include <sys/processor.h> 39*789Sahrens 40*789Sahrens /* 41*789Sahrens * Emulation of kernel services in userland. 42*789Sahrens */ 43*789Sahrens 44*789Sahrens uint64_t physmem; 45*789Sahrens vnode_t *rootdir = (vnode_t *)0xabcd1234; 46*789Sahrens 47*789Sahrens /* 48*789Sahrens * ========================================================================= 49*789Sahrens * threads 50*789Sahrens * ========================================================================= 51*789Sahrens */ 52*789Sahrens /*ARGSUSED*/ 53*789Sahrens kthread_t * 54*789Sahrens zk_thread_create(void (*func)(), void *arg) 55*789Sahrens { 56*789Sahrens thread_t tid; 57*789Sahrens 58*789Sahrens VERIFY(thr_create(0, 0, (void *(*)(void *))func, arg, THR_DETACHED, 59*789Sahrens &tid) == 0); 60*789Sahrens 61*789Sahrens return ((void *)(uintptr_t)tid); 62*789Sahrens } 63*789Sahrens 64*789Sahrens /* 65*789Sahrens * ========================================================================= 66*789Sahrens * mutexes 67*789Sahrens * ========================================================================= 68*789Sahrens */ 69*789Sahrens void 70*789Sahrens zmutex_init(kmutex_t *mp) 71*789Sahrens { 72*789Sahrens mp->m_owner = NULL; 73*789Sahrens (void) _mutex_init(&mp->m_lock, USYNC_THREAD, NULL); 74*789Sahrens } 75*789Sahrens 76*789Sahrens void 77*789Sahrens zmutex_destroy(kmutex_t *mp) 78*789Sahrens { 79*789Sahrens ASSERT(mp->m_owner == NULL); 80*789Sahrens (void) _mutex_destroy(&(mp)->m_lock); 81*789Sahrens mp->m_owner = (void *)-1UL; 82*789Sahrens } 83*789Sahrens 84*789Sahrens void 85*789Sahrens mutex_enter(kmutex_t *mp) 86*789Sahrens { 87*789Sahrens ASSERT(mp->m_owner != (void *)-1UL); 88*789Sahrens ASSERT(mp->m_owner != curthread); 89*789Sahrens (void) mutex_lock(&mp->m_lock); 90*789Sahrens ASSERT(mp->m_owner == NULL); 91*789Sahrens mp->m_owner = curthread; 92*789Sahrens } 93*789Sahrens 94*789Sahrens int 95*789Sahrens mutex_tryenter(kmutex_t *mp) 96*789Sahrens { 97*789Sahrens ASSERT(mp->m_owner != (void *)-1UL); 98*789Sahrens if (0 == mutex_trylock(&mp->m_lock)) { 99*789Sahrens ASSERT(mp->m_owner == NULL); 100*789Sahrens mp->m_owner = curthread; 101*789Sahrens return (1); 102*789Sahrens } else { 103*789Sahrens return (0); 104*789Sahrens } 105*789Sahrens } 106*789Sahrens 107*789Sahrens void 108*789Sahrens mutex_exit(kmutex_t *mp) 109*789Sahrens { 110*789Sahrens ASSERT(mutex_owner(mp) == curthread); 111*789Sahrens mp->m_owner = NULL; 112*789Sahrens (void) mutex_unlock(&mp->m_lock); 113*789Sahrens } 114*789Sahrens 115*789Sahrens void * 116*789Sahrens mutex_owner(kmutex_t *mp) 117*789Sahrens { 118*789Sahrens return (mp->m_owner); 119*789Sahrens } 120*789Sahrens 121*789Sahrens /* 122*789Sahrens * ========================================================================= 123*789Sahrens * rwlocks 124*789Sahrens * ========================================================================= 125*789Sahrens */ 126*789Sahrens /*ARGSUSED*/ 127*789Sahrens void 128*789Sahrens rw_init(krwlock_t *rwlp, char *name, int type, void *arg) 129*789Sahrens { 130*789Sahrens rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL); 131*789Sahrens rwlp->rw_owner = NULL; 132*789Sahrens } 133*789Sahrens 134*789Sahrens void 135*789Sahrens rw_destroy(krwlock_t *rwlp) 136*789Sahrens { 137*789Sahrens rwlock_destroy(&rwlp->rw_lock); 138*789Sahrens rwlp->rw_owner = (void *)-1UL; 139*789Sahrens } 140*789Sahrens 141*789Sahrens void 142*789Sahrens rw_enter(krwlock_t *rwlp, krw_t rw) 143*789Sahrens { 144*789Sahrens ASSERT(!RW_LOCK_HELD(rwlp)); 145*789Sahrens ASSERT(rwlp->rw_owner != (void *)-1UL); 146*789Sahrens ASSERT(rwlp->rw_owner != curthread); 147*789Sahrens 148*789Sahrens if (rw == RW_READER) 149*789Sahrens (void) rw_rdlock(&rwlp->rw_lock); 150*789Sahrens else 151*789Sahrens (void) rw_wrlock(&rwlp->rw_lock); 152*789Sahrens 153*789Sahrens rwlp->rw_owner = curthread; 154*789Sahrens } 155*789Sahrens 156*789Sahrens void 157*789Sahrens rw_exit(krwlock_t *rwlp) 158*789Sahrens { 159*789Sahrens ASSERT(rwlp->rw_owner != (void *)-1UL); 160*789Sahrens 161*789Sahrens rwlp->rw_owner = NULL; 162*789Sahrens (void) rw_unlock(&rwlp->rw_lock); 163*789Sahrens } 164*789Sahrens 165*789Sahrens int 166*789Sahrens rw_tryenter(krwlock_t *rwlp, krw_t rw) 167*789Sahrens { 168*789Sahrens int rv; 169*789Sahrens 170*789Sahrens ASSERT(rwlp->rw_owner != (void *)-1UL); 171*789Sahrens 172*789Sahrens if (rw == RW_READER) 173*789Sahrens rv = rw_tryrdlock(&rwlp->rw_lock); 174*789Sahrens else 175*789Sahrens rv = rw_trywrlock(&rwlp->rw_lock); 176*789Sahrens 177*789Sahrens if (rv == 0) { 178*789Sahrens rwlp->rw_owner = curthread; 179*789Sahrens return (1); 180*789Sahrens } 181*789Sahrens 182*789Sahrens return (0); 183*789Sahrens } 184*789Sahrens 185*789Sahrens /*ARGSUSED*/ 186*789Sahrens int 187*789Sahrens rw_tryupgrade(krwlock_t *rwlp) 188*789Sahrens { 189*789Sahrens ASSERT(rwlp->rw_owner != (void *)-1UL); 190*789Sahrens 191*789Sahrens return (0); 192*789Sahrens } 193*789Sahrens 194*789Sahrens /* 195*789Sahrens * ========================================================================= 196*789Sahrens * condition variables 197*789Sahrens * ========================================================================= 198*789Sahrens */ 199*789Sahrens /*ARGSUSED*/ 200*789Sahrens void 201*789Sahrens cv_init(kcondvar_t *cv, char *name, int type, void *arg) 202*789Sahrens { 203*789Sahrens (void) cond_init(cv, type, NULL); 204*789Sahrens } 205*789Sahrens 206*789Sahrens void 207*789Sahrens cv_destroy(kcondvar_t *cv) 208*789Sahrens { 209*789Sahrens (void) cond_destroy(cv); 210*789Sahrens } 211*789Sahrens 212*789Sahrens void 213*789Sahrens cv_wait(kcondvar_t *cv, kmutex_t *mp) 214*789Sahrens { 215*789Sahrens ASSERT(mutex_owner(mp) == curthread); 216*789Sahrens mp->m_owner = NULL; 217*789Sahrens (void) cond_wait(cv, &mp->m_lock); 218*789Sahrens mp->m_owner = curthread; 219*789Sahrens } 220*789Sahrens 221*789Sahrens clock_t 222*789Sahrens cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime) 223*789Sahrens { 224*789Sahrens int error; 225*789Sahrens timestruc_t ts; 226*789Sahrens clock_t delta; 227*789Sahrens 228*789Sahrens top: 229*789Sahrens delta = abstime - lbolt; 230*789Sahrens if (delta <= 0) 231*789Sahrens return (-1); 232*789Sahrens 233*789Sahrens ts.tv_sec = delta / hz; 234*789Sahrens ts.tv_nsec = (delta % hz) * (NANOSEC / hz); 235*789Sahrens 236*789Sahrens ASSERT(mutex_owner(mp) == curthread); 237*789Sahrens mp->m_owner = NULL; 238*789Sahrens error = cond_reltimedwait(cv, &mp->m_lock, &ts); 239*789Sahrens mp->m_owner = curthread; 240*789Sahrens 241*789Sahrens if (error == ETIME) 242*789Sahrens return (-1); 243*789Sahrens 244*789Sahrens if (error == EINTR) 245*789Sahrens goto top; 246*789Sahrens 247*789Sahrens ASSERT(error == 0); 248*789Sahrens 249*789Sahrens return (1); 250*789Sahrens } 251*789Sahrens 252*789Sahrens void 253*789Sahrens cv_signal(kcondvar_t *cv) 254*789Sahrens { 255*789Sahrens (void) cond_signal(cv); 256*789Sahrens } 257*789Sahrens 258*789Sahrens void 259*789Sahrens cv_broadcast(kcondvar_t *cv) 260*789Sahrens { 261*789Sahrens (void) cond_broadcast(cv); 262*789Sahrens } 263*789Sahrens 264*789Sahrens /* 265*789Sahrens * ========================================================================= 266*789Sahrens * vnode operations 267*789Sahrens * ========================================================================= 268*789Sahrens */ 269*789Sahrens /* 270*789Sahrens * Note: for the xxxat() versions of these functions, we assume that the 271*789Sahrens * starting vp is always rootdir (which is true for spa_directory.c, the only 272*789Sahrens * ZFS consumer of these interfaces). We assert this is true, and then emulate 273*789Sahrens * them by adding '/' in front of the path. 274*789Sahrens */ 275*789Sahrens 276*789Sahrens /*ARGSUSED*/ 277*789Sahrens int 278*789Sahrens vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3) 279*789Sahrens { 280*789Sahrens int fd; 281*789Sahrens vnode_t *vp; 282*789Sahrens int old_umask; 283*789Sahrens char realpath[MAXPATHLEN]; 284*789Sahrens struct stat64 st; 285*789Sahrens 286*789Sahrens /* 287*789Sahrens * If we're accessing a real disk from userland, we need to use 288*789Sahrens * the character interface to avoid caching. This is particularly 289*789Sahrens * important if we're trying to look at a real in-kernel storage 290*789Sahrens * pool from userland, e.g. via zdb, because otherwise we won't 291*789Sahrens * see the changes occurring under the segmap cache. 292*789Sahrens * On the other hand, the stupid character device returns zero 293*789Sahrens * for its size. So -- gag -- we open the block device to get 294*789Sahrens * its size, and remember it for subsequent VOP_GETATTR(). 295*789Sahrens */ 296*789Sahrens if (strncmp(path, "/dev/", 5) == 0) { 297*789Sahrens char *dsk; 298*789Sahrens fd = open64(path, O_RDONLY); 299*789Sahrens if (fd == -1) 300*789Sahrens return (errno); 301*789Sahrens if (fstat64(fd, &st) == -1) { 302*789Sahrens close(fd); 303*789Sahrens return (errno); 304*789Sahrens } 305*789Sahrens close(fd); 306*789Sahrens (void) sprintf(realpath, "%s", path); 307*789Sahrens dsk = strstr(path, "/dsk/"); 308*789Sahrens if (dsk != NULL) 309*789Sahrens (void) sprintf(realpath + (dsk - path) + 1, "r%s", 310*789Sahrens dsk + 1); 311*789Sahrens } else { 312*789Sahrens (void) sprintf(realpath, "%s", path); 313*789Sahrens if (!(flags & FCREAT) && stat64(realpath, &st) == -1) 314*789Sahrens return (errno); 315*789Sahrens } 316*789Sahrens 317*789Sahrens if (flags & FCREAT) 318*789Sahrens old_umask = umask(0); 319*789Sahrens 320*789Sahrens /* 321*789Sahrens * The construct 'flags - FREAD' conveniently maps combinations of 322*789Sahrens * FREAD and FWRITE to the corresponding O_RDONLY, O_WRONLY, and O_RDWR. 323*789Sahrens */ 324*789Sahrens fd = open64(realpath, flags - FREAD, mode); 325*789Sahrens 326*789Sahrens if (flags & FCREAT) 327*789Sahrens (void) umask(old_umask); 328*789Sahrens 329*789Sahrens if (fd == -1) 330*789Sahrens return (errno); 331*789Sahrens 332*789Sahrens if (fstat64(fd, &st) == -1) { 333*789Sahrens close(fd); 334*789Sahrens return (errno); 335*789Sahrens } 336*789Sahrens 337*789Sahrens (void) fcntl(fd, F_SETFD, FD_CLOEXEC); 338*789Sahrens 339*789Sahrens *vpp = vp = umem_zalloc(sizeof (vnode_t), UMEM_NOFAIL); 340*789Sahrens 341*789Sahrens vp->v_fd = fd; 342*789Sahrens vp->v_size = st.st_size; 343*789Sahrens vp->v_path = spa_strdup(path); 344*789Sahrens 345*789Sahrens return (0); 346*789Sahrens } 347*789Sahrens 348*789Sahrens int 349*789Sahrens vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, 350*789Sahrens int x3, vnode_t *startvp) 351*789Sahrens { 352*789Sahrens char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL); 353*789Sahrens int ret; 354*789Sahrens 355*789Sahrens ASSERT(startvp == rootdir); 356*789Sahrens (void) sprintf(realpath, "/%s", path); 357*789Sahrens 358*789Sahrens ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3); 359*789Sahrens 360*789Sahrens umem_free(realpath, strlen(path) + 2); 361*789Sahrens 362*789Sahrens return (ret); 363*789Sahrens } 364*789Sahrens 365*789Sahrens /*ARGSUSED*/ 366*789Sahrens int 367*789Sahrens vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset, 368*789Sahrens int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp) 369*789Sahrens { 370*789Sahrens ssize_t iolen, split; 371*789Sahrens 372*789Sahrens if (uio == UIO_READ) { 373*789Sahrens iolen = pread64(vp->v_fd, addr, len, offset); 374*789Sahrens } else { 375*789Sahrens /* 376*789Sahrens * To simulate partial disk writes, we split writes into two 377*789Sahrens * system calls so that the process can be killed in between. 378*789Sahrens */ 379*789Sahrens split = (len > 0 ? rand() % len : 0); 380*789Sahrens iolen = pwrite64(vp->v_fd, addr, split, offset); 381*789Sahrens iolen += pwrite64(vp->v_fd, (char *)addr + split, 382*789Sahrens len - split, offset + split); 383*789Sahrens } 384*789Sahrens 385*789Sahrens if (iolen == -1) 386*789Sahrens return (errno); 387*789Sahrens if (residp) 388*789Sahrens *residp = len - iolen; 389*789Sahrens else if (iolen != len) 390*789Sahrens return (EIO); 391*789Sahrens return (0); 392*789Sahrens } 393*789Sahrens 394*789Sahrens void 395*789Sahrens vn_close(vnode_t *vp) 396*789Sahrens { 397*789Sahrens close(vp->v_fd); 398*789Sahrens spa_strfree(vp->v_path); 399*789Sahrens umem_free(vp, sizeof (vnode_t)); 400*789Sahrens } 401*789Sahrens 402*789Sahrens #ifdef ZFS_DEBUG 403*789Sahrens 404*789Sahrens /* 405*789Sahrens * ========================================================================= 406*789Sahrens * Figure out which debugging statements to print 407*789Sahrens * ========================================================================= 408*789Sahrens */ 409*789Sahrens 410*789Sahrens static char *dprintf_string; 411*789Sahrens static int dprintf_print_all; 412*789Sahrens 413*789Sahrens int 414*789Sahrens dprintf_find_string(const char *string) 415*789Sahrens { 416*789Sahrens char *tmp_str = dprintf_string; 417*789Sahrens int len = strlen(string); 418*789Sahrens 419*789Sahrens /* 420*789Sahrens * Find out if this is a string we want to print. 421*789Sahrens * String format: file1.c,function_name1,file2.c,file3.c 422*789Sahrens */ 423*789Sahrens 424*789Sahrens while (tmp_str != NULL) { 425*789Sahrens if (strncmp(tmp_str, string, len) == 0 && 426*789Sahrens (tmp_str[len] == ',' || tmp_str[len] == '\0')) 427*789Sahrens return (1); 428*789Sahrens tmp_str = strchr(tmp_str, ','); 429*789Sahrens if (tmp_str != NULL) 430*789Sahrens tmp_str++; /* Get rid of , */ 431*789Sahrens } 432*789Sahrens return (0); 433*789Sahrens } 434*789Sahrens 435*789Sahrens void 436*789Sahrens dprintf_setup(int *argc, char **argv) 437*789Sahrens { 438*789Sahrens int i, j; 439*789Sahrens 440*789Sahrens /* 441*789Sahrens * Debugging can be specified two ways: by setting the 442*789Sahrens * environment variable ZFS_DEBUG, or by including a 443*789Sahrens * "debug=..." argument on the command line. The command 444*789Sahrens * line setting overrides the environment variable. 445*789Sahrens */ 446*789Sahrens 447*789Sahrens for (i = 1; i < *argc; i++) { 448*789Sahrens int len = strlen("debug="); 449*789Sahrens /* First look for a command line argument */ 450*789Sahrens if (strncmp("debug=", argv[i], len) == 0) { 451*789Sahrens dprintf_string = argv[i] + len; 452*789Sahrens /* Remove from args */ 453*789Sahrens for (j = i; j < *argc; j++) 454*789Sahrens argv[j] = argv[j+1]; 455*789Sahrens argv[j] = NULL; 456*789Sahrens (*argc)--; 457*789Sahrens } 458*789Sahrens } 459*789Sahrens 460*789Sahrens if (dprintf_string == NULL) { 461*789Sahrens /* Look for ZFS_DEBUG environment variable */ 462*789Sahrens dprintf_string = getenv("ZFS_DEBUG"); 463*789Sahrens } 464*789Sahrens 465*789Sahrens /* 466*789Sahrens * Are we just turning on all debugging? 467*789Sahrens */ 468*789Sahrens if (dprintf_find_string("on")) 469*789Sahrens dprintf_print_all = 1; 470*789Sahrens } 471*789Sahrens 472*789Sahrens /* 473*789Sahrens * ========================================================================= 474*789Sahrens * debug printfs 475*789Sahrens * ========================================================================= 476*789Sahrens */ 477*789Sahrens void 478*789Sahrens __dprintf(const char *file, const char *func, int line, const char *fmt, ...) 479*789Sahrens { 480*789Sahrens const char *newfile; 481*789Sahrens va_list adx; 482*789Sahrens 483*789Sahrens /* 484*789Sahrens * Get rid of annoying "../common/" prefix to filename. 485*789Sahrens */ 486*789Sahrens newfile = strrchr(file, '/'); 487*789Sahrens if (newfile != NULL) { 488*789Sahrens newfile = newfile + 1; /* Get rid of leading / */ 489*789Sahrens } else { 490*789Sahrens newfile = file; 491*789Sahrens } 492*789Sahrens 493*789Sahrens if (dprintf_print_all || 494*789Sahrens dprintf_find_string(newfile) || 495*789Sahrens dprintf_find_string(func)) { 496*789Sahrens /* Print out just the function name if requested */ 497*789Sahrens flockfile(stdout); 498*789Sahrens if (dprintf_find_string("pid")) 499*789Sahrens (void) printf("%d ", getpid()); 500*789Sahrens if (dprintf_find_string("tid")) 501*789Sahrens (void) printf("%u ", thr_self()); 502*789Sahrens if (dprintf_find_string("cpu")) 503*789Sahrens (void) printf("%u ", getcpuid()); 504*789Sahrens if (dprintf_find_string("time")) 505*789Sahrens (void) printf("%llu ", gethrtime()); 506*789Sahrens if (dprintf_find_string("long")) 507*789Sahrens (void) printf("%s, line %d: ", newfile, line); 508*789Sahrens (void) printf("%s: ", func); 509*789Sahrens va_start(adx, fmt); 510*789Sahrens (void) vprintf(fmt, adx); 511*789Sahrens va_end(adx); 512*789Sahrens funlockfile(stdout); 513*789Sahrens } 514*789Sahrens } 515*789Sahrens 516*789Sahrens #endif /* ZFS_DEBUG */ 517*789Sahrens 518*789Sahrens /* 519*789Sahrens * ========================================================================= 520*789Sahrens * cmn_err() and panic() 521*789Sahrens * ========================================================================= 522*789Sahrens */ 523*789Sahrens static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" }; 524*789Sahrens static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" }; 525*789Sahrens 526*789Sahrens void 527*789Sahrens vpanic(const char *fmt, va_list adx) 528*789Sahrens { 529*789Sahrens (void) fprintf(stderr, "error: "); 530*789Sahrens (void) vfprintf(stderr, fmt, adx); 531*789Sahrens (void) fprintf(stderr, "\n"); 532*789Sahrens 533*789Sahrens abort(); /* think of it as a "user-level crash dump" */ 534*789Sahrens } 535*789Sahrens 536*789Sahrens void 537*789Sahrens panic(const char *fmt, ...) 538*789Sahrens { 539*789Sahrens va_list adx; 540*789Sahrens 541*789Sahrens va_start(adx, fmt); 542*789Sahrens vpanic(fmt, adx); 543*789Sahrens va_end(adx); 544*789Sahrens } 545*789Sahrens 546*789Sahrens /*PRINTFLIKE2*/ 547*789Sahrens void 548*789Sahrens cmn_err(int ce, const char *fmt, ...) 549*789Sahrens { 550*789Sahrens va_list adx; 551*789Sahrens 552*789Sahrens va_start(adx, fmt); 553*789Sahrens if (ce == CE_PANIC) 554*789Sahrens vpanic(fmt, adx); 555*789Sahrens if (ce != CE_NOTE) { /* suppress noise in userland stress testing */ 556*789Sahrens (void) fprintf(stderr, "%s", ce_prefix[ce]); 557*789Sahrens (void) vfprintf(stderr, fmt, adx); 558*789Sahrens (void) fprintf(stderr, "%s", ce_suffix[ce]); 559*789Sahrens } 560*789Sahrens va_end(adx); 561*789Sahrens } 562*789Sahrens 563*789Sahrens /* 564*789Sahrens * ========================================================================= 565*789Sahrens * misc routines 566*789Sahrens * ========================================================================= 567*789Sahrens */ 568*789Sahrens 569*789Sahrens void 570*789Sahrens delay(clock_t ticks) 571*789Sahrens { 572*789Sahrens poll(0, 0, ticks * (1000 / hz)); 573*789Sahrens } 574*789Sahrens 575*789Sahrens /* 576*789Sahrens * Find highest one bit set. 577*789Sahrens * Returns bit number + 1 of highest bit that is set, otherwise returns 0. 578*789Sahrens * High order bit is 31 (or 63 in _LP64 kernel). 579*789Sahrens */ 580*789Sahrens int 581*789Sahrens highbit(ulong_t i) 582*789Sahrens { 583*789Sahrens register int h = 1; 584*789Sahrens 585*789Sahrens if (i == 0) 586*789Sahrens return (0); 587*789Sahrens #ifdef _LP64 588*789Sahrens if (i & 0xffffffff00000000ul) { 589*789Sahrens h += 32; i >>= 32; 590*789Sahrens } 591*789Sahrens #endif 592*789Sahrens if (i & 0xffff0000) { 593*789Sahrens h += 16; i >>= 16; 594*789Sahrens } 595*789Sahrens if (i & 0xff00) { 596*789Sahrens h += 8; i >>= 8; 597*789Sahrens } 598*789Sahrens if (i & 0xf0) { 599*789Sahrens h += 4; i >>= 4; 600*789Sahrens } 601*789Sahrens if (i & 0xc) { 602*789Sahrens h += 2; i >>= 2; 603*789Sahrens } 604*789Sahrens if (i & 0x2) { 605*789Sahrens h += 1; 606*789Sahrens } 607*789Sahrens return (h); 608*789Sahrens } 609*789Sahrens 610*789Sahrens static int 611*789Sahrens random_get_bytes_common(uint8_t *ptr, size_t len, char *devname) 612*789Sahrens { 613*789Sahrens int fd = open(devname, O_RDONLY); 614*789Sahrens size_t resid = len; 615*789Sahrens ssize_t bytes; 616*789Sahrens 617*789Sahrens ASSERT(fd != -1); 618*789Sahrens 619*789Sahrens while (resid != 0) { 620*789Sahrens bytes = read(fd, ptr, resid); 621*789Sahrens ASSERT(bytes >= 0); 622*789Sahrens ptr += bytes; 623*789Sahrens resid -= bytes; 624*789Sahrens } 625*789Sahrens 626*789Sahrens close(fd); 627*789Sahrens 628*789Sahrens return (0); 629*789Sahrens } 630*789Sahrens 631*789Sahrens int 632*789Sahrens random_get_bytes(uint8_t *ptr, size_t len) 633*789Sahrens { 634*789Sahrens return (random_get_bytes_common(ptr, len, "/dev/random")); 635*789Sahrens } 636*789Sahrens 637*789Sahrens int 638*789Sahrens random_get_pseudo_bytes(uint8_t *ptr, size_t len) 639*789Sahrens { 640*789Sahrens return (random_get_bytes_common(ptr, len, "/dev/urandom")); 641*789Sahrens } 642*789Sahrens 643*789Sahrens /* 644*789Sahrens * ========================================================================= 645*789Sahrens * kernel emulation setup & teardown 646*789Sahrens * ========================================================================= 647*789Sahrens */ 648*789Sahrens static int 649*789Sahrens umem_out_of_memory(void) 650*789Sahrens { 651*789Sahrens char errmsg[] = "out of memory -- generating core dump\n"; 652*789Sahrens 653*789Sahrens write(fileno(stderr), errmsg, sizeof (errmsg)); 654*789Sahrens abort(); 655*789Sahrens return (0); 656*789Sahrens } 657*789Sahrens 658*789Sahrens void 659*789Sahrens kernel_init(int mode) 660*789Sahrens { 661*789Sahrens umem_nofail_callback(umem_out_of_memory); 662*789Sahrens 663*789Sahrens physmem = sysconf(_SC_PHYS_PAGES); 664*789Sahrens 665*789Sahrens dprintf("physmem = %llu pages (%.2f GB)\n", physmem, 666*789Sahrens (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30)); 667*789Sahrens 668*789Sahrens spa_init(mode); 669*789Sahrens } 670*789Sahrens 671*789Sahrens void 672*789Sahrens kernel_fini(void) 673*789Sahrens { 674*789Sahrens spa_fini(); 675*789Sahrens } 676