* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <assert.h>
#include <sys/zfs_context.h>
#include <sys/zmod.h>
#include <sys/utsname.h>
+#include <sys/systeminfo.h>
/*
* Emulation of kernel services in userland.
*/
+int aok;
uint64_t physmem;
vnode_t *rootdir = (vnode_t *)0xabcd1234;
-char hw_serial[11];
+char hw_serial[HW_HOSTID_LEN];
struct utsname utsname = {
"userland", "libzpool", "1", "1", "na"
};
+/* this only exists to have its address taken */
+struct proc p0;
+
/*
* =========================================================================
* threads
clock_t delta;
top:
- delta = abstime - lbolt;
+ delta = abstime - ddi_get_lbolt();
if (delta <= 0)
return (-1);
int old_umask;
char realpath[MAXPATHLEN];
struct stat64 st;
+ int err;
/*
* If we're accessing a real disk from userland, we need to use
return (errno);
if (fstat64(fd, &st) == -1) {
+ err = errno;
close(fd);
- return (errno);
+ return (err);
}
(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp)
{
- ssize_t iolen, split;
+ ssize_t rc, done = 0, split;
if (uio == UIO_READ) {
- iolen = pread64(vp->v_fd, addr, len, offset);
+ rc = pread64(vp->v_fd, addr, len, offset);
} else {
/*
* To simulate partial disk writes, we split writes into two
* system calls so that the process can be killed in between.
*/
split = (len > 0 ? rand() % len : 0);
- iolen = pwrite64(vp->v_fd, addr, split, offset);
- iolen += pwrite64(vp->v_fd, (char *)addr + split,
- len - split, offset + split);
+ rc = pwrite64(vp->v_fd, addr, split, offset);
+ if (rc != -1) {
+ done = rc;
+ rc = pwrite64(vp->v_fd, (char *)addr + split,
+ len - split, offset + split);
+ }
}
- if (iolen == -1)
+ if (rc == -1)
return (errno);
+
+ done += rc;
+
if (residp)
- *residp = len - iolen;
- else if (iolen != len)
+ *residp = len - done;
+ else if (done != len)
return (EIO);
return (0);
}
umem_free(vp, sizeof (vnode_t));
}
+/*
+ * At a minimum we need to update the size since vdev_reopen()
+ * will no longer call vn_openat().
+ */
+int
+fop_getattr(vnode_t *vp, vattr_t *vap)
+{
+ struct stat64 st;
+
+ if (fstat64(vp->v_fd, &st) == -1) {
+ close(vp->v_fd);
+ return (errno);
+ }
+
+ vap->va_size = st.st_size;
+ return (0);
+}
+
#ifdef ZFS_DEBUG
/*
return (0);
}
+int
+ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result)
+{
+ char *end;
+
+ *result = strtoull(str, &end, base);
+ if (*result == 0)
+ return (errno);
+ return (0);
+}
+
/*
* =========================================================================
* kernel emulation setup & teardown
{
char errmsg[] = "out of memory -- generating core dump\n";
- write(fileno(stderr), errmsg, sizeof (errmsg));
+ (void) fprintf(stderr, "%s", errmsg);
abort();
return (0);
}
dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
(double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
- snprintf(hw_serial, sizeof (hw_serial), "%ld", gethostid());
+ (void) snprintf(hw_serial, sizeof (hw_serial), "%ld",
+ (mode & FWRITE) ? gethostid() : 0);
VERIFY((random_fd = open("/dev/random", O_RDONLY)) != -1);
VERIFY((urandom_fd = open("/dev/urandom", O_RDONLY)) != -1);
{
spa_fini();
+ system_taskq_fini();
+
close(random_fd);
close(urandom_fd);
spa_strfree(ksid->kd_name);
umem_free(ksid, sizeof (ksiddomain_t));
}
+
+/*
+ * Do not change the length of the returned string; it must be freed
+ * with strfree().
+ */
+char *
+kmem_asprintf(const char *fmt, ...)
+{
+ int size;
+ va_list adx;
+ char *buf;
+
+ va_start(adx, fmt);
+ size = vsnprintf(NULL, 0, fmt, adx) + 1;
+ va_end(adx);
+
+ buf = kmem_alloc(size, KM_SLEEP);
+
+ va_start(adx, fmt);
+ size = vsnprintf(buf, size, fmt, adx);
+ va_end(adx);
+
+ return (buf);
+}
+
+/* ARGSUSED */
+int
+zfs_onexit_fd_hold(int fd, minor_t *minorp)
+{
+ *minorp = 0;
+ return (0);
+}
+
+/* ARGSUSED */
+void
+zfs_onexit_fd_rele(int fd)
+{
+}
+
+/* ARGSUSED */
+int
+zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
+ uint64_t *action_handle)
+{
+ return (0);
+}
+
+/* ARGSUSED */
+int
+zfs_onexit_del_cb(minor_t minor, uint64_t action_handle, boolean_t fire)
+{
+ return (0);
+}
+
+/* ARGSUSED */
+int
+zfs_onexit_cb_data(minor_t minor, uint64_t action_handle, void **data)
+{
+ return (0);
+}