Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 1 Jul 2012 07:57:18 +0000 (UTC)
From:      Martin Matuska <mm@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r237895 - in vendor/illumos/dist: cmd/pyzfs cmd/stat cmd/stat/common cmd/zdb cmd/zfs cmd/zhack cmd/zinject cmd/zlook cmd/zpool cmd/zstreamdump cmd/ztest head lib/libnvpair lib/libuutil ...
Message-ID:  <201207010757.q617vIxa075119@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mm
Date: Sun Jul  1 07:57:18 2012
New Revision: 237895
URL: http://svn.freebsd.org/changeset/base/237895

Log:
  Add userland ZFS to vendor/illumos
  illumos-gate revision 13742:b6bbdd77139c

Added:
  vendor/illumos/dist/cmd/pyzfs/
  vendor/illumos/dist/cmd/pyzfs/pyzfs.py
  vendor/illumos/dist/cmd/stat/
  vendor/illumos/dist/cmd/stat/common/
  vendor/illumos/dist/cmd/stat/common/statcommon.h
  vendor/illumos/dist/cmd/stat/common/timestamp.c
  vendor/illumos/dist/cmd/zdb/
  vendor/illumos/dist/cmd/zdb/zdb.c
  vendor/illumos/dist/cmd/zdb/zdb_il.c
  vendor/illumos/dist/cmd/zfs/
  vendor/illumos/dist/cmd/zfs/zfs_iter.c
  vendor/illumos/dist/cmd/zfs/zfs_iter.h
  vendor/illumos/dist/cmd/zfs/zfs_main.c
  vendor/illumos/dist/cmd/zfs/zfs_util.h
  vendor/illumos/dist/cmd/zhack/
  vendor/illumos/dist/cmd/zhack/zhack.c
  vendor/illumos/dist/cmd/zinject/
  vendor/illumos/dist/cmd/zinject/translate.c
  vendor/illumos/dist/cmd/zinject/zinject.c
  vendor/illumos/dist/cmd/zinject/zinject.h
  vendor/illumos/dist/cmd/zlook/
  vendor/illumos/dist/cmd/zlook/zlook.c
  vendor/illumos/dist/cmd/zpool/
  vendor/illumos/dist/cmd/zpool/zpool_iter.c
  vendor/illumos/dist/cmd/zpool/zpool_main.c
  vendor/illumos/dist/cmd/zpool/zpool_util.c
  vendor/illumos/dist/cmd/zpool/zpool_util.h
  vendor/illumos/dist/cmd/zpool/zpool_vdev.c
  vendor/illumos/dist/cmd/zstreamdump/
  vendor/illumos/dist/cmd/zstreamdump/zstreamdump.c
  vendor/illumos/dist/cmd/ztest/
  vendor/illumos/dist/cmd/ztest/ztest.c
  vendor/illumos/dist/head/atomic.h
  vendor/illumos/dist/head/libintl.h
  vendor/illumos/dist/head/stdio_ext.h
  vendor/illumos/dist/head/synch.h
  vendor/illumos/dist/head/thread.h
  vendor/illumos/dist/lib/libnvpair/
  vendor/illumos/dist/lib/libnvpair/libnvpair.c
  vendor/illumos/dist/lib/libnvpair/libnvpair.h
  vendor/illumos/dist/lib/libnvpair/nvpair_alloc_system.c
  vendor/illumos/dist/lib/libuutil/
  vendor/illumos/dist/lib/libuutil/common/
  vendor/illumos/dist/lib/libuutil/common/libuutil.h
  vendor/illumos/dist/lib/libuutil/common/libuutil_common.h
  vendor/illumos/dist/lib/libuutil/common/libuutil_impl.h
  vendor/illumos/dist/lib/libuutil/common/uu_alloc.c
  vendor/illumos/dist/lib/libuutil/common/uu_avl.c
  vendor/illumos/dist/lib/libuutil/common/uu_dprintf.c
  vendor/illumos/dist/lib/libuutil/common/uu_ident.c
  vendor/illumos/dist/lib/libuutil/common/uu_list.c
  vendor/illumos/dist/lib/libuutil/common/uu_misc.c
  vendor/illumos/dist/lib/libuutil/common/uu_open.c
  vendor/illumos/dist/lib/libuutil/common/uu_pname.c
  vendor/illumos/dist/lib/libuutil/common/uu_string.c
  vendor/illumos/dist/lib/libuutil/common/uu_strtoint.c
  vendor/illumos/dist/lib/libzfs/
  vendor/illumos/dist/lib/libzfs/common/
  vendor/illumos/dist/lib/libzfs/common/libzfs.h
  vendor/illumos/dist/lib/libzfs/common/libzfs_changelist.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_config.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_diff.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_fru.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_impl.h
  vendor/illumos/dist/lib/libzfs/common/libzfs_import.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_iter.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_mount.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_pool.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_sendrecv.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_status.c
  vendor/illumos/dist/lib/libzfs/common/libzfs_util.c
  vendor/illumos/dist/lib/libzpool/
  vendor/illumos/dist/lib/libzpool/common/
  vendor/illumos/dist/lib/libzpool/common/kernel.c
  vendor/illumos/dist/lib/libzpool/common/sys/
  vendor/illumos/dist/lib/libzpool/common/sys/zfs_context.h
  vendor/illumos/dist/lib/libzpool/common/taskq.c
  vendor/illumos/dist/lib/libzpool/common/util.c
  vendor/illumos/dist/lib/pyzfs/
  vendor/illumos/dist/lib/pyzfs/common/
  vendor/illumos/dist/lib/pyzfs/common/__init__.py
  vendor/illumos/dist/lib/pyzfs/common/allow.py
  vendor/illumos/dist/lib/pyzfs/common/dataset.py
  vendor/illumos/dist/lib/pyzfs/common/groupspace.py
  vendor/illumos/dist/lib/pyzfs/common/holds.py
  vendor/illumos/dist/lib/pyzfs/common/ioctl.c
  vendor/illumos/dist/lib/pyzfs/common/table.py
  vendor/illumos/dist/lib/pyzfs/common/unallow.py
  vendor/illumos/dist/lib/pyzfs/common/userspace.py
  vendor/illumos/dist/lib/pyzfs/common/util.py

Added: vendor/illumos/dist/cmd/pyzfs/pyzfs.py
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/illumos/dist/cmd/pyzfs/pyzfs.py	Sun Jul  1 07:57:18 2012	(r237895)
@@ -0,0 +1,82 @@
+#! /usr/bin/python2.6 -S
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+# Note, we want SIGINT (control-c) to exit the process quietly, to mimic
+# the standard behavior of C programs.  The best we can do with pure
+# Python is to run with -S (to disable "import site"), and start our
+# program with a "try" statement.  Hopefully nobody hits ^C before our
+# try statement is executed.
+
+try:
+	import site
+	import gettext
+	import zfs.util
+	import zfs.ioctl
+	import sys
+	import errno
+	import solaris.misc
+
+	"""This is the main script for doing zfs subcommands.  It doesn't know
+	what subcommands there are, it just looks for a module zfs.<subcommand>
+	that implements that subcommand."""
+
+	try:
+		_ = gettext.translation("SUNW_OST_OSCMD", "/usr/lib/locale",
+		    fallback=True).gettext
+	except:
+		_ = solaris.misc.gettext
+
+	if len(sys.argv) < 2:
+		sys.exit(_("missing subcommand argument"))
+
+	zfs.ioctl.set_cmdstr(" ".join(["zfs"] + sys.argv[1:]))
+
+	try:
+		# import zfs.<subcommand>
+		# subfunc =  zfs.<subcommand>.do_<subcommand>
+
+		subcmd = sys.argv[1]
+		__import__("zfs." + subcmd)
+		submod = getattr(zfs, subcmd)
+		subfunc = getattr(submod, "do_" + subcmd)
+	except (ImportError, AttributeError):
+		sys.exit(_("invalid subcommand"))
+
+	try:
+		subfunc()
+	except zfs.util.ZFSError, e:
+		print(e)
+		sys.exit(1)
+
+except IOError, e:
+	import errno
+	import sys
+
+	if e.errno == errno.EPIPE:
+		sys.exit(1)
+	raise
+except KeyboardInterrupt:
+	import sys
+
+	sys.exit(1)

Added: vendor/illumos/dist/cmd/stat/common/statcommon.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/illumos/dist/cmd/stat/common/statcommon.h	Sun Jul  1 07:57:18 2012	(r237895)
@@ -0,0 +1,328 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Common routines for acquiring snapshots of kstats for
+ * iostat, mpstat, and vmstat.
+ */
+
+#ifndef	_STATCOMMON_H
+#define	_STATCOMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <kstat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/buf.h>
+#include <sys/dnlc.h>
+#include <sys/sysinfo.h>
+#include <sys/processor.h>
+#include <sys/pset.h>
+#include <sys/avl.h>
+
+/* No CPU present at this CPU position */
+#define	ID_NO_CPU -1
+/* CPU belongs to no pset (we number this as "pset 0")  */
+#define	ID_NO_PSET 0
+/* CPU is usable */
+#define	CPU_ONLINE(s) ((s) == P_ONLINE || (s) == P_NOINTR)
+/* will the CPU have kstats */
+#define	CPU_ACTIVE(c) (CPU_ONLINE((c)->cs_state) && (c)->cs_id != ID_NO_CPU)
+/* IO device has no identified ID */
+#define	IODEV_NO_ID -1
+/* no limit to iodevs to collect */
+#define	UNLIMITED_IODEVS ((size_t)-1)
+
+#define	NODATE	0	/* Default:  No time stamp */
+#define	DDATE	1	/* Standard date format */
+#define	UDATE	2	/* Internal representation of Unix time */
+
+
+enum snapshot_types {
+	/* All CPUs separately */
+	SNAP_CPUS 		= 1 << 0,
+	/* Aggregated processor sets */
+	SNAP_PSETS		= 1 << 1,
+	/* sys-wide stats including aggregated CPU stats */
+	SNAP_SYSTEM		= 1 << 2,
+	/* interrupt sources and counts */
+	SNAP_INTERRUPTS 	= 1 << 3,
+	/* disk etc. stats */
+	SNAP_IODEVS		= 1 << 4,
+	/* disk controller aggregates */
+	SNAP_CONTROLLERS	= 1 << 5,
+	/* mpxio L I (multipath) paths: -X: Lun,LunInitiator */
+	SNAP_IOPATHS_LI		= 1 << 6,
+	/* mpxio LTI (multipath) paths: -Y: Lun,LunTarget,LunTargetInitiator */
+	SNAP_IOPATHS_LTI	= 1 << 7,
+	/* disk error stats */
+	SNAP_IODEV_ERRORS	= 1 << 8,
+	/* pretty names for iodevs */
+	SNAP_IODEV_PRETTY	= 1 << 9,
+	/* devid for iodevs */
+	SNAP_IODEV_DEVID	= 1 << 10
+};
+
+struct cpu_snapshot {
+	/* may be ID_NO_CPU if no CPU present */
+	processorid_t cs_id;
+	/* may be ID_NO_PSET if no pset */
+	psetid_t cs_pset_id;
+	/* as in p_online(2) */
+	int cs_state;
+	/* stats for this CPU */
+	kstat_t cs_vm;
+	kstat_t cs_sys;
+};
+
+struct pset_snapshot {
+	/* ID may be zero to indicate the "none set" */
+	psetid_t ps_id;
+	/* number of CPUs in set */
+	size_t ps_nr_cpus;
+	/* the CPUs in this set */
+	struct cpu_snapshot **ps_cpus;
+};
+
+struct intr_snapshot {
+	/* name of interrupt source */
+	char is_name[KSTAT_STRLEN];
+	/* total number of interrupts from this source */
+	ulong_t is_total;
+};
+
+struct sys_snapshot {
+	sysinfo_t ss_sysinfo;
+	vminfo_t ss_vminfo;
+	struct nc_stats ss_nc;
+	/* vm/sys stats aggregated across all CPUs */
+	kstat_t ss_agg_vm;
+	kstat_t ss_agg_sys;
+	/* ticks since boot */
+	ulong_t ss_ticks;
+	long ss_deficit;
+};
+
+/* order is significant (see sort_before()) */
+enum iodev_type {
+	IODEV_CONTROLLER	= 1 << 0,
+	IODEV_DISK		= 1 << 1,
+	IODEV_PARTITION		= 1 << 2,
+	IODEV_TAPE		= 1 << 3,
+	IODEV_NFS		= 1 << 4,
+	IODEV_IOPATH_LT		= 1 << 5,	/* synthetic LunTarget */
+	IODEV_IOPATH_LI		= 1 << 6,	/* synthetic LunInitiator */
+	IODEV_IOPATH_LTI	= 1 << 7,	/* LunTgtInitiator (pathinfo) */
+	IODEV_UNKNOWN		= 1 << 8
+};
+
+/* identify a disk, partition, etc. */
+struct iodev_id {
+	int id;
+	/* target id (for disks) */
+	char tid[KSTAT_STRLEN];
+};
+
+/*
+ * Used for disks, partitions, tapes, nfs, controllers, iopaths
+ * Each entry can be a branch of a tree; for example, the disks
+ * of a controller constitute the children of the controller
+ * iodev_snapshot. This relationship is not strictly maintained
+ * if is_pretty can't be found.
+ */
+struct iodev_snapshot {
+	/* original kstat name */
+	char is_name[KSTAT_STRLEN];
+	/* type of kstat */
+	enum iodev_type is_type;
+	/* ID if meaningful */
+	struct iodev_id is_id;
+	/* parent ID if meaningful */
+	struct iodev_id is_parent_id;
+	/* user-friendly name if found */
+	char *is_pretty;
+	/* device ID if applicable */
+	char *is_devid;
+	/* mount-point if applicable */
+	char *is_dname;
+	/* number of direct children */
+	int is_nr_children;
+	/* children of this I/O device */
+	struct iodev_snapshot *is_children;
+	/* standard I/O stats */
+	kstat_io_t is_stats;
+	/* iodev error stats */
+	kstat_t is_errors;
+	/* creation time of the stats */
+	hrtime_t is_crtime;
+	/* time at which iodev snapshot was taken */
+	hrtime_t is_snaptime;
+	/* kstat module */
+	char is_module[KSTAT_STRLEN];
+	/* kstat instance */
+	int is_instance;
+	/* kstat (only used temporarily) */
+	kstat_t *is_ksp;
+	struct iodev_snapshot *is_prev;
+	struct iodev_snapshot *is_next;
+	/* AVL structures to speedup insertion */
+	avl_tree_t *avl_list;	/* list this element belongs to */
+	avl_node_t avl_link;
+};
+
+/* which iodevs to show. */
+struct iodev_filter {
+	/* nr. of iodevs to choose */
+	size_t if_max_iodevs;
+	/* bit mask of enum io_types to allow */
+	int if_allowed_types;
+	/* should we show floppy ? if_names can override this */
+	int if_skip_floppy;
+	/* nr. of named iodevs */
+	size_t if_nr_names;
+	char **if_names;
+};
+
+/* The primary structure of a system snapshot. */
+struct snapshot {
+	/* what types were *requested* */
+	enum snapshot_types s_types;
+	size_t s_nr_cpus;
+	struct cpu_snapshot *s_cpus;
+	size_t s_nr_psets;
+	struct pset_snapshot *s_psets;
+	size_t s_nr_intrs;
+	struct intr_snapshot *s_intrs;
+	size_t s_nr_iodevs;
+	struct iodev_snapshot *s_iodevs;
+	size_t s_iodevs_is_name_maxlen;
+	struct sys_snapshot s_sys;
+	struct biostats s_biostats;
+};
+
+/* print a message and exit with failure */
+void fail(int do_perror, char *message, ...);
+
+/* strdup str, or exit with failure */
+char *safe_strdup(char *str);
+
+/* malloc successfully, or exit with failure */
+void *safe_alloc(size_t size);
+
+/*
+ * Copy a kstat from src to dst. If the source kstat contains no data,
+ * then set the destination kstat data to NULL and size to zero.
+ * Returns 0 on success.
+ */
+int kstat_copy(const kstat_t *src, kstat_t *dst);
+
+/*
+ * Look up the named kstat, and give the ui64 difference i.e.
+ * new - old, or if old is NULL, return new.
+ */
+uint64_t kstat_delta(kstat_t *old, kstat_t *new, char *name);
+
+/* Return the number of ticks delta between two hrtime_t values. */
+uint64_t hrtime_delta(hrtime_t old, hrtime_t new);
+
+/*
+ * Add the integer-valued stats from "src" to the
+ * existing ones in "dst". If "dst" does not contain
+ * stats, then a kstat_copy() is performed.
+ */
+int kstat_add(const kstat_t *src, kstat_t *dst);
+
+/* return the number of CPUs with kstats (i.e. present and online) */
+int nr_active_cpus(struct snapshot *ss);
+
+/*
+ * Return the difference in CPU ticks between the two sys
+ * kstats.
+ */
+uint64_t cpu_ticks_delta(kstat_t *old, kstat_t *new);
+
+/*
+ * Open the kstat chain. Cannot fail.
+ */
+kstat_ctl_t *open_kstat(void);
+
+/*
+ * Return a struct snapshot based on the snapshot_types parameter
+ * passed in. iodev_filter may be NULL in which case all iodevs
+ * are selected if SNAP_IODEVS is passed.
+ */
+struct snapshot *acquire_snapshot(kstat_ctl_t *, int, struct iodev_filter *);
+
+/* free a snapshot */
+void free_snapshot(struct snapshot *ss);
+
+typedef void (*snapshot_cb)(void *old, void *new, void *data);
+
+/*
+ * Call the call back for each pair of data items of the given type,
+ * passing the data pointer passed in as well. If an item has been
+ * added, the first pointer will be NULL; if removed, the second pointer
+ * will be NULL.
+ *
+ * A non-zero return value indicates configuration has changed.
+ */
+int snapshot_walk(enum snapshot_types type, struct snapshot *old,
+    struct snapshot *new, snapshot_cb cb, void *data);
+
+/*
+ * Output a line detailing any configuration changes such as a CPU
+ * brought online, etc, bracketed by << >>.
+ */
+void snapshot_report_changes(struct snapshot *old, struct snapshot *new);
+
+/* Return non-zero if configuration has changed. */
+int snapshot_has_changed(struct snapshot *old, struct snapshot *new);
+
+/* free the given iodev */
+void free_iodev(struct iodev_snapshot *iodev);
+
+/* acquire the I/O devices */
+int acquire_iodevs(struct snapshot *ss, kstat_ctl_t *kc,
+    struct iodev_filter *df);
+
+/* strcmp-style I/O device comparator */
+int iodev_cmp(struct iodev_snapshot *io1, struct iodev_snapshot *io2);
+
+/* sleep until *wakeup + interval, keeping cadence where desired */
+void sleep_until(hrtime_t *wakeup, hrtime_t interval, int forever,
+    int *caught_cont);
+
+/* signal handler - so we can be aware of SIGCONT */
+void cont_handler(int sig_number);
+
+/* Print a timestamp in either Unix or standard format. */
+void print_timestamp(uint_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STATCOMMON_H */

Added: vendor/illumos/dist/cmd/stat/common/timestamp.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/illumos/dist/cmd/stat/common/timestamp.c	Sun Jul  1 07:57:18 2012	(r237895)
@@ -0,0 +1,54 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include "statcommon.h"
+
+#include <langinfo.h>
+
+/*
+ * Print timestamp as decimal reprentation of time_t value (-T u was specified)
+ * or in date(1) format (-T d was specified).
+ */
+void
+print_timestamp(uint_t timestamp_fmt)
+{
+	time_t t = time(NULL);
+	static char *fmt = NULL;
+
+	/* We only need to retrieve this once per invocation */
+	if (fmt == NULL)
+		fmt = nl_langinfo(_DATE_FMT);
+
+	if (timestamp_fmt == UDATE) {
+		(void) printf("%ld\n", t);
+	} else if (timestamp_fmt == DDATE) {
+		char dstr[64];
+		int len;
+
+		len = strftime(dstr, sizeof (dstr), fmt, localtime(&t));
+		if (len > 0)
+			(void) printf("%s\n", dstr);
+	}
+}

Added: vendor/illumos/dist/cmd/zdb/zdb.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/illumos/dist/cmd/zdb/zdb.c	Sun Jul  1 07:57:18 2012	(r237895)
@@ -0,0 +1,3219 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/zfs_context.h>
+#include <sys/spa.h>
+#include <sys/spa_impl.h>
+#include <sys/dmu.h>
+#include <sys/zap.h>
+#include <sys/fs/zfs.h>
+#include <sys/zfs_znode.h>
+#include <sys/zfs_sa.h>
+#include <sys/sa.h>
+#include <sys/sa_impl.h>
+#include <sys/vdev.h>
+#include <sys/vdev_impl.h>
+#include <sys/metaslab_impl.h>
+#include <sys/dmu_objset.h>
+#include <sys/dsl_dir.h>
+#include <sys/dsl_dataset.h>
+#include <sys/dsl_pool.h>
+#include <sys/dbuf.h>
+#include <sys/zil.h>
+#include <sys/zil_impl.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <sys/dmu_traverse.h>
+#include <sys/zio_checksum.h>
+#include <sys/zio_compress.h>
+#include <sys/zfs_fuid.h>
+#include <sys/arc.h>
+#include <sys/ddt.h>
+#include <sys/zfeature.h>
+#undef ZFS_MAXNAMELEN
+#undef verify
+#include <libzfs.h>
+
+#define	ZDB_COMPRESS_NAME(idx) ((idx) < ZIO_COMPRESS_FUNCTIONS ? \
+    zio_compress_table[(idx)].ci_name : "UNKNOWN")
+#define	ZDB_CHECKSUM_NAME(idx) ((idx) < ZIO_CHECKSUM_FUNCTIONS ? \
+    zio_checksum_table[(idx)].ci_name : "UNKNOWN")
+#define	ZDB_OT_NAME(idx) ((idx) < DMU_OT_NUMTYPES ? \
+    dmu_ot[(idx)].ot_name : DMU_OT_IS_VALID(idx) ? \
+    dmu_ot_byteswap[DMU_OT_BYTESWAP(idx)].ob_name : "UNKNOWN")
+#define	ZDB_OT_TYPE(idx) ((idx) < DMU_OT_NUMTYPES ? (idx) : DMU_OT_NUMTYPES)
+
+#ifndef lint
+extern int zfs_recover;
+#else
+int zfs_recover;
+#endif
+
+const char cmdname[] = "zdb";
+uint8_t dump_opt[256];
+
+typedef void object_viewer_t(objset_t *, uint64_t, void *data, size_t size);
+
+extern void dump_intent_log(zilog_t *);
+uint64_t *zopt_object = NULL;
+int zopt_objects = 0;
+libzfs_handle_t *g_zfs;
+
+/*
+ * These libumem hooks provide a reasonable set of defaults for the allocator's
+ * debugging facilities.
+ */
+const char *
+_umem_debug_init()
+{
+	return ("default,verbose"); /* $UMEM_DEBUG setting */
+}
+
+const char *
+_umem_logging_init(void)
+{
+	return ("fail,contents"); /* $UMEM_LOGGING setting */
+}
+
+static void
+usage(void)
+{
+	(void) fprintf(stderr,
+	    "Usage: %s [-CumdibcsDvhLXFPA] [-t txg] [-e [-p path...]] "
+	    "poolname [object...]\n"
+	    "       %s [-divPA] [-e -p path...] dataset [object...]\n"
+	    "       %s -m [-LXFPA] [-t txg] [-e [-p path...]] "
+	    "poolname [vdev [metaslab...]]\n"
+	    "       %s -R [-A] [-e [-p path...]] poolname "
+	    "vdev:offset:size[:flags]\n"
+	    "       %s -S [-PA] [-e [-p path...]] poolname\n"
+	    "       %s -l [-uA] device\n"
+	    "       %s -C [-A] [-U config]\n\n",
+	    cmdname, cmdname, cmdname, cmdname, cmdname, cmdname, cmdname);
+
+	(void) fprintf(stderr, "    Dataset name must include at least one "
+	    "separator character '/' or '@'\n");
+	(void) fprintf(stderr, "    If dataset name is specified, only that "
+	    "dataset is dumped\n");
+	(void) fprintf(stderr, "    If object numbers are specified, only "
+	    "those objects are dumped\n\n");
+	(void) fprintf(stderr, "    Options to control amount of output:\n");
+	(void) fprintf(stderr, "        -u uberblock\n");
+	(void) fprintf(stderr, "        -d dataset(s)\n");
+	(void) fprintf(stderr, "        -i intent logs\n");
+	(void) fprintf(stderr, "        -C config (or cachefile if alone)\n");
+	(void) fprintf(stderr, "        -h pool history\n");
+	(void) fprintf(stderr, "        -b block statistics\n");
+	(void) fprintf(stderr, "        -m metaslabs\n");
+	(void) fprintf(stderr, "        -c checksum all metadata (twice for "
+	    "all data) blocks\n");
+	(void) fprintf(stderr, "        -s report stats on zdb's I/O\n");
+	(void) fprintf(stderr, "        -D dedup statistics\n");
+	(void) fprintf(stderr, "        -S simulate dedup to measure effect\n");
+	(void) fprintf(stderr, "        -v verbose (applies to all others)\n");
+	(void) fprintf(stderr, "        -l dump label contents\n");
+	(void) fprintf(stderr, "        -L disable leak tracking (do not "
+	    "load spacemaps)\n");
+	(void) fprintf(stderr, "        -R read and display block from a "
+	    "device\n\n");
+	(void) fprintf(stderr, "    Below options are intended for use "
+	    "with other options (except -l):\n");
+	(void) fprintf(stderr, "        -A ignore assertions (-A), enable "
+	    "panic recovery (-AA) or both (-AAA)\n");
+	(void) fprintf(stderr, "        -F attempt automatic rewind within "
+	    "safe range of transaction groups\n");
+	(void) fprintf(stderr, "        -U <cachefile_path> -- use alternate "
+	    "cachefile\n");
+	(void) fprintf(stderr, "        -X attempt extreme rewind (does not "
+	    "work with dataset)\n");
+	(void) fprintf(stderr, "        -e pool is exported/destroyed/"
+	    "has altroot/not in a cachefile\n");
+	(void) fprintf(stderr, "        -p <path> -- use one or more with "
+	    "-e to specify path to vdev dir\n");
+	(void) fprintf(stderr, "        -P print numbers in parseable form\n");
+	(void) fprintf(stderr, "        -t <txg> -- highest txg to use when "
+	    "searching for uberblocks\n");
+	(void) fprintf(stderr, "Specify an option more than once (e.g. -bb) "
+	    "to make only that option verbose\n");
+	(void) fprintf(stderr, "Default is to dump everything non-verbosely\n");
+	exit(1);
+}
+
+/*
+ * Called for usage errors that are discovered after a call to spa_open(),
+ * dmu_bonus_hold(), or pool_match().  abort() is called for other errors.
+ */
+
+static void
+fatal(const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	(void) fprintf(stderr, "%s: ", cmdname);
+	(void) vfprintf(stderr, fmt, ap);
+	va_end(ap);
+	(void) fprintf(stderr, "\n");
+
+	exit(1);
+}
+
+/* ARGSUSED */
+static void
+dump_packed_nvlist(objset_t *os, uint64_t object, void *data, size_t size)
+{
+	nvlist_t *nv;
+	size_t nvsize = *(uint64_t *)data;
+	char *packed = umem_alloc(nvsize, UMEM_NOFAIL);
+
+	VERIFY(0 == dmu_read(os, object, 0, nvsize, packed, DMU_READ_PREFETCH));
+
+	VERIFY(nvlist_unpack(packed, nvsize, &nv, 0) == 0);
+
+	umem_free(packed, nvsize);
+
+	dump_nvlist(nv, 8);
+
+	nvlist_free(nv);
+}
+
+static void
+zdb_nicenum(uint64_t num, char *buf)
+{
+	if (dump_opt['P'])
+		(void) sprintf(buf, "%llu", (longlong_t)num);
+	else
+		nicenum(num, buf);
+}
+
+const char dump_zap_stars[] = "****************************************";
+const int dump_zap_width = sizeof (dump_zap_stars) - 1;
+
+static void
+dump_zap_histogram(uint64_t histo[ZAP_HISTOGRAM_SIZE])
+{
+	int i;
+	int minidx = ZAP_HISTOGRAM_SIZE - 1;
+	int maxidx = 0;
+	uint64_t max = 0;
+
+	for (i = 0; i < ZAP_HISTOGRAM_SIZE; i++) {
+		if (histo[i] > max)
+			max = histo[i];
+		if (histo[i] > 0 && i > maxidx)
+			maxidx = i;
+		if (histo[i] > 0 && i < minidx)
+			minidx = i;
+	}
+
+	if (max < dump_zap_width)
+		max = dump_zap_width;
+
+	for (i = minidx; i <= maxidx; i++)
+		(void) printf("\t\t\t%u: %6llu %s\n", i, (u_longlong_t)histo[i],
+		    &dump_zap_stars[(max - histo[i]) * dump_zap_width / max]);
+}
+
+static void
+dump_zap_stats(objset_t *os, uint64_t object)
+{
+	int error;
+	zap_stats_t zs;
+
+	error = zap_get_stats(os, object, &zs);
+	if (error)
+		return;
+
+	if (zs.zs_ptrtbl_len == 0) {
+		ASSERT(zs.zs_num_blocks == 1);
+		(void) printf("\tmicrozap: %llu bytes, %llu entries\n",
+		    (u_longlong_t)zs.zs_blocksize,
+		    (u_longlong_t)zs.zs_num_entries);
+		return;
+	}
+
+	(void) printf("\tFat ZAP stats:\n");
+
+	(void) printf("\t\tPointer table:\n");
+	(void) printf("\t\t\t%llu elements\n",
+	    (u_longlong_t)zs.zs_ptrtbl_len);
+	(void) printf("\t\t\tzt_blk: %llu\n",
+	    (u_longlong_t)zs.zs_ptrtbl_zt_blk);
+	(void) printf("\t\t\tzt_numblks: %llu\n",
+	    (u_longlong_t)zs.zs_ptrtbl_zt_numblks);
+	(void) printf("\t\t\tzt_shift: %llu\n",
+	    (u_longlong_t)zs.zs_ptrtbl_zt_shift);
+	(void) printf("\t\t\tzt_blks_copied: %llu\n",
+	    (u_longlong_t)zs.zs_ptrtbl_blks_copied);
+	(void) printf("\t\t\tzt_nextblk: %llu\n",
+	    (u_longlong_t)zs.zs_ptrtbl_nextblk);
+
+	(void) printf("\t\tZAP entries: %llu\n",
+	    (u_longlong_t)zs.zs_num_entries);
+	(void) printf("\t\tLeaf blocks: %llu\n",
+	    (u_longlong_t)zs.zs_num_leafs);
+	(void) printf("\t\tTotal blocks: %llu\n",
+	    (u_longlong_t)zs.zs_num_blocks);
+	(void) printf("\t\tzap_block_type: 0x%llx\n",
+	    (u_longlong_t)zs.zs_block_type);
+	(void) printf("\t\tzap_magic: 0x%llx\n",
+	    (u_longlong_t)zs.zs_magic);
+	(void) printf("\t\tzap_salt: 0x%llx\n",
+	    (u_longlong_t)zs.zs_salt);
+
+	(void) printf("\t\tLeafs with 2^n pointers:\n");
+	dump_zap_histogram(zs.zs_leafs_with_2n_pointers);
+
+	(void) printf("\t\tBlocks with n*5 entries:\n");
+	dump_zap_histogram(zs.zs_blocks_with_n5_entries);
+
+	(void) printf("\t\tBlocks n/10 full:\n");
+	dump_zap_histogram(zs.zs_blocks_n_tenths_full);
+
+	(void) printf("\t\tEntries with n chunks:\n");
+	dump_zap_histogram(zs.zs_entries_using_n_chunks);
+
+	(void) printf("\t\tBuckets with n entries:\n");
+	dump_zap_histogram(zs.zs_buckets_with_n_entries);
+}
+
+/*ARGSUSED*/
+static void
+dump_none(objset_t *os, uint64_t object, void *data, size_t size)
+{
+}
+
+/*ARGSUSED*/
+static void
+dump_unknown(objset_t *os, uint64_t object, void *data, size_t size)
+{
+	(void) printf("\tUNKNOWN OBJECT TYPE\n");
+}
+
+/*ARGSUSED*/
+void
+dump_uint8(objset_t *os, uint64_t object, void *data, size_t size)
+{
+}
+
+/*ARGSUSED*/
+static void
+dump_uint64(objset_t *os, uint64_t object, void *data, size_t size)
+{
+}
+
+/*ARGSUSED*/
+static void
+dump_zap(objset_t *os, uint64_t object, void *data, size_t size)
+{
+	zap_cursor_t zc;
+	zap_attribute_t attr;
+	void *prop;
+	int i;
+
+	dump_zap_stats(os, object);
+	(void) printf("\n");
+
+	for (zap_cursor_init(&zc, os, object);
+	    zap_cursor_retrieve(&zc, &attr) == 0;
+	    zap_cursor_advance(&zc)) {
+		(void) printf("\t\t%s = ", attr.za_name);
+		if (attr.za_num_integers == 0) {
+			(void) printf("\n");
+			continue;
+		}
+		prop = umem_zalloc(attr.za_num_integers *
+		    attr.za_integer_length, UMEM_NOFAIL);
+		(void) zap_lookup(os, object, attr.za_name,
+		    attr.za_integer_length, attr.za_num_integers, prop);
+		if (attr.za_integer_length == 1) {
+			(void) printf("%s", (char *)prop);
+		} else {
+			for (i = 0; i < attr.za_num_integers; i++) {
+				switch (attr.za_integer_length) {
+				case 2:
+					(void) printf("%u ",
+					    ((uint16_t *)prop)[i]);
+					break;
+				case 4:
+					(void) printf("%u ",
+					    ((uint32_t *)prop)[i]);
+					break;
+				case 8:
+					(void) printf("%lld ",
+					    (u_longlong_t)((int64_t *)prop)[i]);
+					break;
+				}
+			}
+		}
+		(void) printf("\n");
+		umem_free(prop, attr.za_num_integers * attr.za_integer_length);
+	}
+	zap_cursor_fini(&zc);
+}
+
+/*ARGSUSED*/
+static void
+dump_ddt_zap(objset_t *os, uint64_t object, void *data, size_t size)
+{
+	dump_zap_stats(os, object);
+	/* contents are printed elsewhere, properly decoded */
+}
+
+/*ARGSUSED*/
+static void
+dump_sa_attrs(objset_t *os, uint64_t object, void *data, size_t size)
+{
+	zap_cursor_t zc;
+	zap_attribute_t attr;
+
+	dump_zap_stats(os, object);
+	(void) printf("\n");
+
+	for (zap_cursor_init(&zc, os, object);
+	    zap_cursor_retrieve(&zc, &attr) == 0;
+	    zap_cursor_advance(&zc)) {
+		(void) printf("\t\t%s = ", attr.za_name);
+		if (attr.za_num_integers == 0) {
+			(void) printf("\n");
+			continue;
+		}
+		(void) printf(" %llx : [%d:%d:%d]\n",
+		    (u_longlong_t)attr.za_first_integer,
+		    (int)ATTR_LENGTH(attr.za_first_integer),
+		    (int)ATTR_BSWAP(attr.za_first_integer),
+		    (int)ATTR_NUM(attr.za_first_integer));
+	}
+	zap_cursor_fini(&zc);
+}
+
+/*ARGSUSED*/
+static void
+dump_sa_layouts(objset_t *os, uint64_t object, void *data, size_t size)
+{
+	zap_cursor_t zc;
+	zap_attribute_t attr;
+	uint16_t *layout_attrs;
+	int i;
+
+	dump_zap_stats(os, object);
+	(void) printf("\n");
+
+	for (zap_cursor_init(&zc, os, object);
+	    zap_cursor_retrieve(&zc, &attr) == 0;
+	    zap_cursor_advance(&zc)) {
+		(void) printf("\t\t%s = [", attr.za_name);
+		if (attr.za_num_integers == 0) {
+			(void) printf("\n");
+			continue;
+		}
+
+		VERIFY(attr.za_integer_length == 2);
+		layout_attrs = umem_zalloc(attr.za_num_integers *
+		    attr.za_integer_length, UMEM_NOFAIL);
+
+		VERIFY(zap_lookup(os, object, attr.za_name,
+		    attr.za_integer_length,
+		    attr.za_num_integers, layout_attrs) == 0);
+
+		for (i = 0; i != attr.za_num_integers; i++)
+			(void) printf(" %d ", (int)layout_attrs[i]);
+		(void) printf("]\n");
+		umem_free(layout_attrs,
+		    attr.za_num_integers * attr.za_integer_length);
+	}
+	zap_cursor_fini(&zc);
+}
+
+/*ARGSUSED*/
+static void
+dump_zpldir(objset_t *os, uint64_t object, void *data, size_t size)
+{
+	zap_cursor_t zc;
+	zap_attribute_t attr;
+	const char *typenames[] = {
+		/* 0 */ "not specified",
+		/* 1 */ "FIFO",
+		/* 2 */ "Character Device",
+		/* 3 */ "3 (invalid)",
+		/* 4 */ "Directory",
+		/* 5 */ "5 (invalid)",
+		/* 6 */ "Block Device",
+		/* 7 */ "7 (invalid)",
+		/* 8 */ "Regular File",
+		/* 9 */ "9 (invalid)",
+		/* 10 */ "Symbolic Link",
+		/* 11 */ "11 (invalid)",
+		/* 12 */ "Socket",
+		/* 13 */ "Door",
+		/* 14 */ "Event Port",
+		/* 15 */ "15 (invalid)",
+	};
+
+	dump_zap_stats(os, object);
+	(void) printf("\n");
+
+	for (zap_cursor_init(&zc, os, object);
+	    zap_cursor_retrieve(&zc, &attr) == 0;
+	    zap_cursor_advance(&zc)) {
+		(void) printf("\t\t%s = %lld (type: %s)\n",
+		    attr.za_name, ZFS_DIRENT_OBJ(attr.za_first_integer),
+		    typenames[ZFS_DIRENT_TYPE(attr.za_first_integer)]);
+	}
+	zap_cursor_fini(&zc);
+}
+
+static void
+dump_spacemap(objset_t *os, space_map_obj_t *smo, space_map_t *sm)
+{
+	uint64_t alloc, offset, entry;
+	uint8_t mapshift = sm->sm_shift;
+	uint64_t mapstart = sm->sm_start;
+	char *ddata[] = { "ALLOC", "FREE", "CONDENSE", "INVALID",
+			    "INVALID", "INVALID", "INVALID", "INVALID" };
+
+	if (smo->smo_object == 0)
+		return;
+
+	/*
+	 * Print out the freelist entries in both encoded and decoded form.
+	 */
+	alloc = 0;
+	for (offset = 0; offset < smo->smo_objsize; offset += sizeof (entry)) {
+		VERIFY3U(0, ==, dmu_read(os, smo->smo_object, offset,
+		    sizeof (entry), &entry, DMU_READ_PREFETCH));
+		if (SM_DEBUG_DECODE(entry)) {
+			(void) printf("\t    [%6llu] %s: txg %llu, pass %llu\n",
+			    (u_longlong_t)(offset / sizeof (entry)),
+			    ddata[SM_DEBUG_ACTION_DECODE(entry)],
+			    (u_longlong_t)SM_DEBUG_TXG_DECODE(entry),
+			    (u_longlong_t)SM_DEBUG_SYNCPASS_DECODE(entry));
+		} else {
+			(void) printf("\t    [%6llu]    %c  range:"
+			    " %010llx-%010llx  size: %06llx\n",
+			    (u_longlong_t)(offset / sizeof (entry)),
+			    SM_TYPE_DECODE(entry) == SM_ALLOC ? 'A' : 'F',
+			    (u_longlong_t)((SM_OFFSET_DECODE(entry) <<
+			    mapshift) + mapstart),

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207010757.q617vIxa075119>