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