]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/blob - cddl/contrib/opensolaris/lib/libzpool/common/kernel.c
MFC r260138: MFV r242733:
[FreeBSD/stable/8.git] / cddl / contrib / opensolaris / lib / libzpool / common / kernel.c
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24
25 #include <assert.h>
26 #include <fcntl.h>
27 #include <poll.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <zlib.h>
32 #include <sys/spa.h>
33 #include <sys/stat.h>
34 #include <sys/processor.h>
35 #include <sys/zfs_context.h>
36 #include <sys/rrwlock.h>
37 #include <sys/zmod.h>
38 #include <sys/utsname.h>
39 #include <sys/systeminfo.h>
40
41 /*
42  * Emulation of kernel services in userland.
43  */
44
45 int aok;
46 uint64_t physmem;
47 vnode_t *rootdir = (vnode_t *)0xabcd1234;
48 char hw_serial[HW_HOSTID_LEN];
49
50 struct utsname utsname = {
51         "userland", "libzpool", "1", "1", "na"
52 };
53
54 /* this only exists to have its address taken */
55 struct proc p0;
56
57 /*
58  * =========================================================================
59  * threads
60  * =========================================================================
61  */
62 /*ARGSUSED*/
63 kthread_t *
64 zk_thread_create(void (*func)(), void *arg)
65 {
66         thread_t tid;
67
68         VERIFY(thr_create(0, 0, (void *(*)(void *))func, arg, THR_DETACHED,
69             &tid) == 0);
70
71         return ((void *)(uintptr_t)tid);
72 }
73
74 /*
75  * =========================================================================
76  * kstats
77  * =========================================================================
78  */
79 /*ARGSUSED*/
80 kstat_t *
81 kstat_create(char *module, int instance, char *name, char *class,
82     uchar_t type, ulong_t ndata, uchar_t ks_flag)
83 {
84         return (NULL);
85 }
86
87 /*ARGSUSED*/
88 void
89 kstat_install(kstat_t *ksp)
90 {}
91
92 /*ARGSUSED*/
93 void
94 kstat_delete(kstat_t *ksp)
95 {}
96
97 /*
98  * =========================================================================
99  * mutexes
100  * =========================================================================
101  */
102 void
103 zmutex_init(kmutex_t *mp)
104 {
105         mp->m_owner = NULL;
106         mp->initialized = B_TRUE;
107         (void) _mutex_init(&mp->m_lock, USYNC_THREAD, NULL);
108 }
109
110 void
111 zmutex_destroy(kmutex_t *mp)
112 {
113         ASSERT(mp->initialized == B_TRUE);
114         ASSERT(mp->m_owner == NULL);
115         (void) _mutex_destroy(&(mp)->m_lock);
116         mp->m_owner = (void *)-1UL;
117         mp->initialized = B_FALSE;
118 }
119
120 int
121 zmutex_owned(kmutex_t *mp)
122 {
123         ASSERT(mp->initialized == B_TRUE);
124
125         return (mp->m_owner == curthread);
126 }
127
128 void
129 mutex_enter(kmutex_t *mp)
130 {
131         ASSERT(mp->initialized == B_TRUE);
132         ASSERT(mp->m_owner != (void *)-1UL);
133         ASSERT(mp->m_owner != curthread);
134         VERIFY(mutex_lock(&mp->m_lock) == 0);
135         ASSERT(mp->m_owner == NULL);
136         mp->m_owner = curthread;
137 }
138
139 int
140 mutex_tryenter(kmutex_t *mp)
141 {
142         ASSERT(mp->initialized == B_TRUE);
143         ASSERT(mp->m_owner != (void *)-1UL);
144         if (0 == mutex_trylock(&mp->m_lock)) {
145                 ASSERT(mp->m_owner == NULL);
146                 mp->m_owner = curthread;
147                 return (1);
148         } else {
149                 return (0);
150         }
151 }
152
153 void
154 mutex_exit(kmutex_t *mp)
155 {
156         ASSERT(mp->initialized == B_TRUE);
157         ASSERT(mutex_owner(mp) == curthread);
158         mp->m_owner = NULL;
159         VERIFY(mutex_unlock(&mp->m_lock) == 0);
160 }
161
162 void *
163 mutex_owner(kmutex_t *mp)
164 {
165         ASSERT(mp->initialized == B_TRUE);
166         return (mp->m_owner);
167 }
168
169 /*
170  * =========================================================================
171  * rwlocks
172  * =========================================================================
173  */
174 /*ARGSUSED*/
175 void
176 rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
177 {
178         rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL);
179         rwlp->rw_owner = NULL;
180         rwlp->initialized = B_TRUE;
181         rwlp->rw_count = 0;
182 }
183
184 void
185 rw_destroy(krwlock_t *rwlp)
186 {
187         ASSERT(rwlp->rw_count == 0);
188         rwlock_destroy(&rwlp->rw_lock);
189         rwlp->rw_owner = (void *)-1UL;
190         rwlp->initialized = B_FALSE;
191 }
192
193 void
194 rw_enter(krwlock_t *rwlp, krw_t rw)
195 {
196         //ASSERT(!RW_LOCK_HELD(rwlp));
197         ASSERT(rwlp->initialized == B_TRUE);
198         ASSERT(rwlp->rw_owner != (void *)-1UL);
199         ASSERT(rwlp->rw_owner != curthread);
200
201         if (rw == RW_READER) {
202                 VERIFY(rw_rdlock(&rwlp->rw_lock) == 0);
203                 ASSERT(rwlp->rw_count >= 0);
204                 atomic_add_int(&rwlp->rw_count, 1);
205         } else {
206                 VERIFY(rw_wrlock(&rwlp->rw_lock) == 0);
207                 ASSERT(rwlp->rw_count == 0);
208                 rwlp->rw_count = -1;
209                 rwlp->rw_owner = curthread;
210         }
211 }
212
213 void
214 rw_exit(krwlock_t *rwlp)
215 {
216         ASSERT(rwlp->initialized == B_TRUE);
217         ASSERT(rwlp->rw_owner != (void *)-1UL);
218
219         if (rwlp->rw_owner == curthread) {
220                 /* Write locked. */
221                 ASSERT(rwlp->rw_count == -1);
222                 rwlp->rw_count = 0;
223                 rwlp->rw_owner = NULL;
224         } else {
225                 /* Read locked. */
226                 ASSERT(rwlp->rw_count > 0);
227                 atomic_add_int(&rwlp->rw_count, -1);
228         }
229         VERIFY(rw_unlock(&rwlp->rw_lock) == 0);
230 }
231
232 int
233 rw_tryenter(krwlock_t *rwlp, krw_t rw)
234 {
235         int rv;
236
237         ASSERT(rwlp->initialized == B_TRUE);
238         ASSERT(rwlp->rw_owner != (void *)-1UL);
239         ASSERT(rwlp->rw_owner != curthread);
240
241         if (rw == RW_READER)
242                 rv = rw_tryrdlock(&rwlp->rw_lock);
243         else
244                 rv = rw_trywrlock(&rwlp->rw_lock);
245
246         if (rv == 0) {
247                 ASSERT(rwlp->rw_owner == NULL);
248                 if (rw == RW_READER) {
249                         ASSERT(rwlp->rw_count >= 0);
250                         atomic_add_int(&rwlp->rw_count, 1);
251                 } else {
252                         ASSERT(rwlp->rw_count == 0);
253                         rwlp->rw_count = -1;
254                         rwlp->rw_owner = curthread;
255                 }
256                 return (1);
257         }
258
259         return (0);
260 }
261
262 /*ARGSUSED*/
263 int
264 rw_tryupgrade(krwlock_t *rwlp)
265 {
266         ASSERT(rwlp->initialized == B_TRUE);
267         ASSERT(rwlp->rw_owner != (void *)-1UL);
268
269         return (0);
270 }
271
272 int
273 rw_lock_held(krwlock_t *rwlp)
274 {
275
276         return (rwlp->rw_count != 0);
277 }
278
279 /*
280  * =========================================================================
281  * condition variables
282  * =========================================================================
283  */
284 /*ARGSUSED*/
285 void
286 cv_init(kcondvar_t *cv, char *name, int type, void *arg)
287 {
288         VERIFY(cond_init(cv, name, NULL) == 0);
289 }
290
291 void
292 cv_destroy(kcondvar_t *cv)
293 {
294         VERIFY(cond_destroy(cv) == 0);
295 }
296
297 void
298 cv_wait(kcondvar_t *cv, kmutex_t *mp)
299 {
300         ASSERT(mutex_owner(mp) == curthread);
301         mp->m_owner = NULL;
302         int ret = cond_wait(cv, &mp->m_lock);
303         VERIFY(ret == 0 || ret == EINTR);
304         mp->m_owner = curthread;
305 }
306
307 clock_t
308 cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
309 {
310         int error;
311         struct timespec ts;
312         struct timeval tv;
313         clock_t delta;
314
315         abstime += ddi_get_lbolt();
316 top:
317         delta = abstime - ddi_get_lbolt();
318         if (delta <= 0)
319                 return (-1);
320
321         if (gettimeofday(&tv, NULL) != 0)
322                 assert(!"gettimeofday() failed");
323
324         ts.tv_sec = tv.tv_sec + delta / hz;
325         ts.tv_nsec = tv.tv_usec * 1000 + (delta % hz) * (NANOSEC / hz);
326         ASSERT(ts.tv_nsec >= 0);
327
328         if (ts.tv_nsec >= NANOSEC) {
329                 ts.tv_sec++;
330                 ts.tv_nsec -= NANOSEC;
331         }
332
333         ASSERT(mutex_owner(mp) == curthread);
334         mp->m_owner = NULL;
335         error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);
336         mp->m_owner = curthread;
337
338         if (error == EINTR)
339                 goto top;
340
341         if (error == ETIMEDOUT)
342                 return (-1);
343
344         ASSERT(error == 0);
345
346         return (1);
347 }
348
349 /*ARGSUSED*/
350 clock_t
351 cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
352     int flag)
353 {
354         int error;
355         timestruc_t ts;
356         hrtime_t delta;
357
358         ASSERT(flag == 0);
359
360 top:
361         delta = tim - gethrtime();
362         if (delta <= 0)
363                 return (-1);
364
365         ts.tv_sec = delta / NANOSEC;
366         ts.tv_nsec = delta % NANOSEC;
367
368         ASSERT(mutex_owner(mp) == curthread);
369         mp->m_owner = NULL;
370         error = pthread_cond_timedwait(cv, &mp->m_lock, &ts);
371         mp->m_owner = curthread;
372
373         if (error == ETIMEDOUT)
374                 return (-1);
375
376         if (error == EINTR)
377                 goto top;
378
379         ASSERT(error == 0);
380
381         return (1);
382 }
383
384 void
385 cv_signal(kcondvar_t *cv)
386 {
387         VERIFY(cond_signal(cv) == 0);
388 }
389
390 void
391 cv_broadcast(kcondvar_t *cv)
392 {
393         VERIFY(cond_broadcast(cv) == 0);
394 }
395
396 /*
397  * =========================================================================
398  * vnode operations
399  * =========================================================================
400  */
401 /*
402  * Note: for the xxxat() versions of these functions, we assume that the
403  * starting vp is always rootdir (which is true for spa_directory.c, the only
404  * ZFS consumer of these interfaces).  We assert this is true, and then emulate
405  * them by adding '/' in front of the path.
406  */
407
408 /*ARGSUSED*/
409 int
410 vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
411 {
412         int fd;
413         vnode_t *vp;
414         int old_umask;
415         char realpath[MAXPATHLEN];
416         struct stat64 st;
417
418         /*
419          * If we're accessing a real disk from userland, we need to use
420          * the character interface to avoid caching.  This is particularly
421          * important if we're trying to look at a real in-kernel storage
422          * pool from userland, e.g. via zdb, because otherwise we won't
423          * see the changes occurring under the segmap cache.
424          * On the other hand, the stupid character device returns zero
425          * for its size.  So -- gag -- we open the block device to get
426          * its size, and remember it for subsequent VOP_GETATTR().
427          */
428         if (strncmp(path, "/dev/", 5) == 0) {
429                 char *dsk;
430                 fd = open64(path, O_RDONLY);
431                 if (fd == -1)
432                         return (errno);
433                 if (fstat64(fd, &st) == -1) {
434                         close(fd);
435                         return (errno);
436                 }
437                 close(fd);
438                 (void) sprintf(realpath, "%s", path);
439                 dsk = strstr(path, "/dsk/");
440                 if (dsk != NULL)
441                         (void) sprintf(realpath + (dsk - path) + 1, "r%s",
442                             dsk + 1);
443         } else {
444                 (void) sprintf(realpath, "%s", path);
445                 if (!(flags & FCREAT) && stat64(realpath, &st) == -1)
446                         return (errno);
447         }
448
449         if (flags & FCREAT)
450                 old_umask = umask(0);
451
452         /*
453          * The construct 'flags - FREAD' conveniently maps combinations of
454          * FREAD and FWRITE to the corresponding O_RDONLY, O_WRONLY, and O_RDWR.
455          */
456         fd = open64(realpath, flags - FREAD, mode);
457
458         if (flags & FCREAT)
459                 (void) umask(old_umask);
460
461         if (fd == -1)
462                 return (errno);
463
464         if (fstat64(fd, &st) == -1) {
465                 close(fd);
466                 return (errno);
467         }
468
469         (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
470
471         *vpp = vp = umem_zalloc(sizeof (vnode_t), UMEM_NOFAIL);
472
473         vp->v_fd = fd;
474         vp->v_size = st.st_size;
475         vp->v_path = spa_strdup(path);
476
477         return (0);
478 }
479
480 /*ARGSUSED*/
481 int
482 vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
483     int x3, vnode_t *startvp, int fd)
484 {
485         char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL);
486         int ret;
487
488         ASSERT(startvp == rootdir);
489         (void) sprintf(realpath, "/%s", path);
490
491         /* fd ignored for now, need if want to simulate nbmand support */
492         ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3);
493
494         umem_free(realpath, strlen(path) + 2);
495
496         return (ret);
497 }
498
499 /*ARGSUSED*/
500 int
501 vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
502         int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp)
503 {
504         ssize_t iolen, split;
505
506         if (uio == UIO_READ) {
507                 iolen = pread64(vp->v_fd, addr, len, offset);
508         } else {
509                 /*
510                  * To simulate partial disk writes, we split writes into two
511                  * system calls so that the process can be killed in between.
512                  */
513                 int sectors = len >> SPA_MINBLOCKSHIFT;
514                 split = (sectors > 0 ? rand() % sectors : 0) <<
515                     SPA_MINBLOCKSHIFT;
516                 iolen = pwrite64(vp->v_fd, addr, split, offset);
517                 iolen += pwrite64(vp->v_fd, (char *)addr + split,
518                     len - split, offset + split);
519         }
520
521         if (iolen == -1)
522                 return (errno);
523         if (residp)
524                 *residp = len - iolen;
525         else if (iolen != len)
526                 return (EIO);
527         return (0);
528 }
529
530 void
531 vn_close(vnode_t *vp, int openflag, cred_t *cr, kthread_t *td)
532 {
533         close(vp->v_fd);
534         spa_strfree(vp->v_path);
535         umem_free(vp, sizeof (vnode_t));
536 }
537
538 /*
539  * At a minimum we need to update the size since vdev_reopen()
540  * will no longer call vn_openat().
541  */
542 int
543 fop_getattr(vnode_t *vp, vattr_t *vap)
544 {
545         struct stat64 st;
546
547         if (fstat64(vp->v_fd, &st) == -1) {
548                 close(vp->v_fd);
549                 return (errno);
550         }
551
552         vap->va_size = st.st_size;
553         return (0);
554 }
555
556 #ifdef ZFS_DEBUG
557
558 /*
559  * =========================================================================
560  * Figure out which debugging statements to print
561  * =========================================================================
562  */
563
564 static char *dprintf_string;
565 static int dprintf_print_all;
566
567 int
568 dprintf_find_string(const char *string)
569 {
570         char *tmp_str = dprintf_string;
571         int len = strlen(string);
572
573         /*
574          * Find out if this is a string we want to print.
575          * String format: file1.c,function_name1,file2.c,file3.c
576          */
577
578         while (tmp_str != NULL) {
579                 if (strncmp(tmp_str, string, len) == 0 &&
580                     (tmp_str[len] == ',' || tmp_str[len] == '\0'))
581                         return (1);
582                 tmp_str = strchr(tmp_str, ',');
583                 if (tmp_str != NULL)
584                         tmp_str++; /* Get rid of , */
585         }
586         return (0);
587 }
588
589 void
590 dprintf_setup(int *argc, char **argv)
591 {
592         int i, j;
593
594         /*
595          * Debugging can be specified two ways: by setting the
596          * environment variable ZFS_DEBUG, or by including a
597          * "debug=..."  argument on the command line.  The command
598          * line setting overrides the environment variable.
599          */
600
601         for (i = 1; i < *argc; i++) {
602                 int len = strlen("debug=");
603                 /* First look for a command line argument */
604                 if (strncmp("debug=", argv[i], len) == 0) {
605                         dprintf_string = argv[i] + len;
606                         /* Remove from args */
607                         for (j = i; j < *argc; j++)
608                                 argv[j] = argv[j+1];
609                         argv[j] = NULL;
610                         (*argc)--;
611                 }
612         }
613
614         if (dprintf_string == NULL) {
615                 /* Look for ZFS_DEBUG environment variable */
616                 dprintf_string = getenv("ZFS_DEBUG");
617         }
618
619         /*
620          * Are we just turning on all debugging?
621          */
622         if (dprintf_find_string("on"))
623                 dprintf_print_all = 1;
624 }
625
626 int
627 sysctl_handle_64(SYSCTL_HANDLER_ARGS)
628 {
629         return (0);
630 }
631
632 /*
633  * =========================================================================
634  * debug printfs
635  * =========================================================================
636  */
637 void
638 __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
639 {
640         const char *newfile;
641         va_list adx;
642
643         /*
644          * Get rid of annoying "../common/" prefix to filename.
645          */
646         newfile = strrchr(file, '/');
647         if (newfile != NULL) {
648                 newfile = newfile + 1; /* Get rid of leading / */
649         } else {
650                 newfile = file;
651         }
652
653         if (dprintf_print_all ||
654             dprintf_find_string(newfile) ||
655             dprintf_find_string(func)) {
656                 /* Print out just the function name if requested */
657                 flockfile(stdout);
658                 if (dprintf_find_string("pid"))
659                         (void) printf("%d ", getpid());
660                 if (dprintf_find_string("tid"))
661                         (void) printf("%ul ", thr_self());
662 #if 0
663                 if (dprintf_find_string("cpu"))
664                         (void) printf("%u ", getcpuid());
665 #endif
666                 if (dprintf_find_string("time"))
667                         (void) printf("%llu ", gethrtime());
668                 if (dprintf_find_string("long"))
669                         (void) printf("%s, line %d: ", newfile, line);
670                 (void) printf("%s: ", func);
671                 va_start(adx, fmt);
672                 (void) vprintf(fmt, adx);
673                 va_end(adx);
674                 funlockfile(stdout);
675         }
676 }
677
678 #endif /* ZFS_DEBUG */
679
680 /*
681  * =========================================================================
682  * cmn_err() and panic()
683  * =========================================================================
684  */
685 static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" };
686 static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" };
687
688 void
689 vpanic(const char *fmt, va_list adx)
690 {
691         (void) fprintf(stderr, "error: ");
692         (void) vfprintf(stderr, fmt, adx);
693         (void) fprintf(stderr, "\n");
694
695         abort();        /* think of it as a "user-level crash dump" */
696 }
697
698 void
699 panic(const char *fmt, ...)
700 {
701         va_list adx;
702
703         va_start(adx, fmt);
704         vpanic(fmt, adx);
705         va_end(adx);
706 }
707
708 void
709 vcmn_err(int ce, const char *fmt, va_list adx)
710 {
711         if (ce == CE_PANIC)
712                 vpanic(fmt, adx);
713         if (ce != CE_NOTE) {    /* suppress noise in userland stress testing */
714                 (void) fprintf(stderr, "%s", ce_prefix[ce]);
715                 (void) vfprintf(stderr, fmt, adx);
716                 (void) fprintf(stderr, "%s", ce_suffix[ce]);
717         }
718 }
719
720 /*PRINTFLIKE2*/
721 void
722 cmn_err(int ce, const char *fmt, ...)
723 {
724         va_list adx;
725
726         va_start(adx, fmt);
727         vcmn_err(ce, fmt, adx);
728         va_end(adx);
729 }
730
731 /*
732  * =========================================================================
733  * kobj interfaces
734  * =========================================================================
735  */
736 struct _buf *
737 kobj_open_file(char *name)
738 {
739         struct _buf *file;
740         vnode_t *vp;
741
742         /* set vp as the _fd field of the file */
743         if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir,
744             -1) != 0)
745                 return ((void *)-1UL);
746
747         file = umem_zalloc(sizeof (struct _buf), UMEM_NOFAIL);
748         file->_fd = (intptr_t)vp;
749         return (file);
750 }
751
752 int
753 kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
754 {
755         ssize_t resid;
756
757         vn_rdwr(UIO_READ, (vnode_t *)file->_fd, buf, size, (offset_t)off,
758             UIO_SYSSPACE, 0, 0, 0, &resid);
759
760         return (size - resid);
761 }
762
763 void
764 kobj_close_file(struct _buf *file)
765 {
766         vn_close((vnode_t *)file->_fd, 0, NULL, NULL);
767         umem_free(file, sizeof (struct _buf));
768 }
769
770 int
771 kobj_get_filesize(struct _buf *file, uint64_t *size)
772 {
773         struct stat64 st;
774         vnode_t *vp = (vnode_t *)file->_fd;
775
776         if (fstat64(vp->v_fd, &st) == -1) {
777                 vn_close(vp, 0, NULL, NULL);
778                 return (errno);
779         }
780         *size = st.st_size;
781         return (0);
782 }
783
784 /*
785  * =========================================================================
786  * misc routines
787  * =========================================================================
788  */
789
790 void
791 delay(clock_t ticks)
792 {
793         poll(0, 0, ticks * (1000 / hz));
794 }
795
796 #if 0
797 /*
798  * Find highest one bit set.
799  *      Returns bit number + 1 of highest bit that is set, otherwise returns 0.
800  * High order bit is 31 (or 63 in _LP64 kernel).
801  */
802 int
803 highbit(ulong_t i)
804 {
805         register int h = 1;
806
807         if (i == 0)
808                 return (0);
809 #ifdef _LP64
810         if (i & 0xffffffff00000000ul) {
811                 h += 32; i >>= 32;
812         }
813 #endif
814         if (i & 0xffff0000) {
815                 h += 16; i >>= 16;
816         }
817         if (i & 0xff00) {
818                 h += 8; i >>= 8;
819         }
820         if (i & 0xf0) {
821                 h += 4; i >>= 4;
822         }
823         if (i & 0xc) {
824                 h += 2; i >>= 2;
825         }
826         if (i & 0x2) {
827                 h += 1;
828         }
829         return (h);
830 }
831 #endif
832
833 static int random_fd = -1, urandom_fd = -1;
834
835 static int
836 random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
837 {
838         size_t resid = len;
839         ssize_t bytes;
840
841         ASSERT(fd != -1);
842
843         while (resid != 0) {
844                 bytes = read(fd, ptr, resid);
845                 ASSERT3S(bytes, >=, 0);
846                 ptr += bytes;
847                 resid -= bytes;
848         }
849
850         return (0);
851 }
852
853 int
854 random_get_bytes(uint8_t *ptr, size_t len)
855 {
856         return (random_get_bytes_common(ptr, len, random_fd));
857 }
858
859 int
860 random_get_pseudo_bytes(uint8_t *ptr, size_t len)
861 {
862         return (random_get_bytes_common(ptr, len, urandom_fd));
863 }
864
865 int
866 ddi_strtoul(const char *hw_serial, char **nptr, int base, unsigned long *result)
867 {
868         char *end;
869
870         *result = strtoul(hw_serial, &end, base);
871         if (*result == 0)
872                 return (errno);
873         return (0);
874 }
875
876 int
877 ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result)
878 {
879         char *end;
880
881         *result = strtoull(str, &end, base);
882         if (*result == 0)
883                 return (errno);
884         return (0);
885 }
886
887 /*
888  * =========================================================================
889  * kernel emulation setup & teardown
890  * =========================================================================
891  */
892 static int
893 umem_out_of_memory(void)
894 {
895         char errmsg[] = "out of memory -- generating core dump\n";
896
897         write(fileno(stderr), errmsg, sizeof (errmsg));
898         abort();
899         return (0);
900 }
901
902 void
903 kernel_init(int mode)
904 {
905         extern uint_t rrw_tsd_key;
906
907         umem_nofail_callback(umem_out_of_memory);
908
909         physmem = sysconf(_SC_PHYS_PAGES);
910
911         dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
912             (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
913
914         (void) snprintf(hw_serial, sizeof (hw_serial), "%lu",
915             (mode & FWRITE) ? (unsigned long)gethostid() : 0);
916
917         VERIFY((random_fd = open("/dev/random", O_RDONLY)) != -1);
918         VERIFY((urandom_fd = open("/dev/urandom", O_RDONLY)) != -1);
919
920         system_taskq_init();
921
922         spa_init(mode);
923
924         tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
925 }
926
927 void
928 kernel_fini(void)
929 {
930         spa_fini();
931
932         system_taskq_fini();
933
934         close(random_fd);
935         close(urandom_fd);
936
937         random_fd = -1;
938         urandom_fd = -1;
939 }
940
941 int
942 z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen)
943 {
944         int ret;
945         uLongf len = *dstlen;
946
947         if ((ret = uncompress(dst, &len, src, srclen)) == Z_OK)
948                 *dstlen = (size_t)len;
949
950         return (ret);
951 }
952
953 int
954 z_compress_level(void *dst, size_t *dstlen, const void *src, size_t srclen,
955     int level)
956 {
957         int ret;
958         uLongf len = *dstlen;
959
960         if ((ret = compress2(dst, &len, src, srclen, level)) == Z_OK)
961                 *dstlen = (size_t)len;
962
963         return (ret);
964 }
965
966 uid_t
967 crgetuid(cred_t *cr)
968 {
969         return (0);
970 }
971
972 uid_t
973 crgetruid(cred_t *cr)
974 {
975         return (0);
976 }
977
978 gid_t
979 crgetgid(cred_t *cr)
980 {
981         return (0);
982 }
983
984 int
985 crgetngroups(cred_t *cr)
986 {
987         return (0);
988 }
989
990 gid_t *
991 crgetgroups(cred_t *cr)
992 {
993         return (NULL);
994 }
995
996 int
997 zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
998 {
999         return (0);
1000 }
1001
1002 int
1003 zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
1004 {
1005         return (0);
1006 }
1007
1008 int
1009 zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
1010 {
1011         return (0);
1012 }
1013
1014 ksiddomain_t *
1015 ksid_lookupdomain(const char *dom)
1016 {
1017         ksiddomain_t *kd;
1018
1019         kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL);
1020         kd->kd_name = spa_strdup(dom);
1021         return (kd);
1022 }
1023
1024 void
1025 ksiddomain_rele(ksiddomain_t *ksid)
1026 {
1027         spa_strfree(ksid->kd_name);
1028         umem_free(ksid, sizeof (ksiddomain_t));
1029 }
1030
1031 /*
1032  * Do not change the length of the returned string; it must be freed
1033  * with strfree().
1034  */
1035 char *
1036 kmem_asprintf(const char *fmt, ...)
1037 {
1038         int size;
1039         va_list adx;
1040         char *buf;
1041
1042         va_start(adx, fmt);
1043         size = vsnprintf(NULL, 0, fmt, adx) + 1;
1044         va_end(adx);
1045
1046         buf = kmem_alloc(size, KM_SLEEP);
1047
1048         va_start(adx, fmt);
1049         size = vsnprintf(buf, size, fmt, adx);
1050         va_end(adx);
1051
1052         return (buf);
1053 }
1054
1055 /* ARGSUSED */
1056 int
1057 zfs_onexit_fd_hold(int fd, minor_t *minorp)
1058 {
1059         *minorp = 0;
1060         return (0);
1061 }
1062
1063 /* ARGSUSED */
1064 void
1065 zfs_onexit_fd_rele(int fd)
1066 {
1067 }
1068
1069 /* ARGSUSED */
1070 int
1071 zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
1072     uint64_t *action_handle)
1073 {
1074         return (0);
1075 }
1076
1077 /* ARGSUSED */
1078 int
1079 zfs_onexit_del_cb(minor_t minor, uint64_t action_handle, boolean_t fire)
1080 {
1081         return (0);
1082 }
1083
1084 /* ARGSUSED */
1085 int
1086 zfs_onexit_cb_data(minor_t minor, uint64_t action_handle, void **data)
1087 {
1088         return (0);
1089 }
1090
1091 #ifdef __FreeBSD__
1092 /* ARGSUSED */
1093 int
1094 zvol_create_minors(const char *name)
1095 {
1096         return (0);
1097 }
1098 #endif
1099
1100 #ifdef illumos
1101 void
1102 bioinit(buf_t *bp)
1103 {
1104         bzero(bp, sizeof (buf_t));
1105 }
1106
1107 void
1108 biodone(buf_t *bp)
1109 {
1110         if (bp->b_iodone != NULL) {
1111                 (*(bp->b_iodone))(bp);
1112                 return;
1113         }
1114         ASSERT((bp->b_flags & B_DONE) == 0);
1115         bp->b_flags |= B_DONE;
1116 }
1117
1118 void
1119 bioerror(buf_t *bp, int error)
1120 {
1121         ASSERT(bp != NULL);
1122         ASSERT(error >= 0);
1123
1124         if (error != 0) {
1125                 bp->b_flags |= B_ERROR;
1126         } else {
1127                 bp->b_flags &= ~B_ERROR;
1128         }
1129         bp->b_error = error;
1130 }
1131
1132
1133 int
1134 geterror(struct buf *bp)
1135 {
1136         int error = 0;
1137
1138         if (bp->b_flags & B_ERROR) {
1139                 error = bp->b_error;
1140                 if (!error)
1141                         error = EIO;
1142         }
1143         return (error);
1144 }
1145 #endif