From owner-svn-src-stable-9@FreeBSD.ORG Fri Apr 19 09:19:12 2013 Return-Path: Delivered-To: svn-src-stable-9@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 0C11F866; Fri, 19 Apr 2013 09:19:12 +0000 (UTC) (envelope-from mm@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id ECE05697; Fri, 19 Apr 2013 09:19:11 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r3J9JBdp035892; Fri, 19 Apr 2013 09:19:11 GMT (envelope-from mm@svn.freebsd.org) Received: (from mm@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r3J9JA19035885; Fri, 19 Apr 2013 09:19:10 GMT (envelope-from mm@svn.freebsd.org) Message-Id: <201304190919.r3J9JA19035885@svn.freebsd.org> From: Martin Matuska Date: Fri, 19 Apr 2013 09:19:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r249643 - in stable/9: . cddl/contrib/opensolaris/cmd/zdb cddl/contrib/opensolaris/cmd/zfs cddl/contrib/opensolaris/cmd/zhack cddl/contrib/opensolaris/cmd/zpool cddl/contrib/opensolaris... X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 19 Apr 2013 09:19:12 -0000 Author: mm Date: Fri Apr 19 09:19:10 2013 New Revision: 249643 URL: http://svnweb.freebsd.org/changeset/base/249643 Log: MFC 248571,248976,249004,249042,249188,249195-249196,249206,249207,249319, 249326,249356-249357 Merge libzfs_core and other ZFS bugfixes and improvements. MFC r248571: MFV 238590, 238592: In the first zfs ioctl restructuring phase, the libzfs_core library was introduced. It is a new thin library that wraps around kernel ioctl's. The idea is to provide a forward-compatible way of dealing with new features. Arguments are passed in nvlists and not random zfs_cmd fields, new-style ioctls are logged to pool history using a new method of history logging. http://blog.delphix.com/matt/2012/01/17/the-future-of-libzfs/ MFV 247580 [1]: To address issues of several deadlocks and race conditions the locking code around dsl_dataset was rewritten and the interface to synctasks was changed. User-Visible Changes: "zfs snapshot" can create more arbitrary snapshots at once (atomically) "zfs destroy" destroys multiple snapshots at once "zfs recv" has improved performance Backward Compatibility: I have extended the compatibility layer to support full backward compatibility by remapping or rewriting the responsible ioctl arguments. Old utilities are fully supported by the new kernel module. Forward Compatibility: New utilities work with old kernels with the following restrictions: - creating, destroying, holding and releasing of multiple snapshots at once is not supported, this includes recursive (-r) commands Illumos ZFS issues: 2882 implement libzfs_core 2900 "zfs snapshot" should be able to create multiple, arbitrary snapshots at once 3464 zfs synctask code needs restructuring MFC r248976: Call dmu_snapshot_list_next() in zvol.c with dsl_pool_config lock held MFC r249004: Do not check against uninitialized rc and comment out vendor code MFC r249042: Fix possible pool hold leak in dmu_send_impl() Illumos ZFS issues: 3645 dmu_send_impl: possibilty of pool hold leak MFC r249188: Import vendor change to reduce diff, no effect on FreeBSD. Illumos ZFS issues: 3517 importing pool with autoreplace=on and "hole" vdevs crashes syseventd MFC r249195: Merge change from vendor to reduce diff only. ZFS dtrace probes are not supported on FreeBSD yet. Illumos ZFS issues: 3598 want to dtrace when errors are generated in zfs MFC r249196: Provide a fix for kernel panic if receiving recursive deduplicated streams. Problem reported to vendor. Illumos ZFS issues: 3692 Panic on zfs receive of a recursive deduplicated stream MFC r249206: Merge vendor change - modify time processing in deadman thread. Illumos ZFS issues: 3618 ::zio dcmd does not show timestamp data MFC r249207: Allow zdb to output a histogram of compressed block sizes. Illumos ZFS issues: 3641 want a histogram of compressed block sizes MFC r249319: ZFS expects a copyout of zfs_cmd_t on an ioctl error. Our sys_ioctl() doesn't copyout in this case. To solve this a new struct zfs_iocparm_t is introduced consisting of: - zfs_ioctl_version (future backwards compatibility purposes) - user space pointer to zfs_cmd_t (copyin and copyout) - size of zfs_cmd_t (verification purposes) The copyin and copyout of zfs_cmd_t is now done the illumos (vendor) way what makes porting of new changes easier and ensures correct behavior if returning an error. MFC r249326: Cast (void *)(uintptr_t) on copyout and copyin of zfs_iocparm_t.zfs_cmd MFC r249356: Merge bugfixes accepted and integrated by vendor. Underlying problems have been reported by us and fixed in r240942 and r249196. Illumos ZFS issues: 3645 dmu_send_impl: possibilty of pool hold leak 3692 Panic on zfs receive of a recursive deduplicated stream MFC r249357: Fix libzfs to report error instead of returning zero if trying to hold or release a non-existing snapshot of a existing dataset. In recursive case error is reported if no snapshots with the requested name have been found. Illumos ZFS issues: 3699 zfs hold or release of a non-existent snapshot does not output error Added: stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c - copied, changed from r248571, head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.c stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h - copied unchanged from r248571, head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_compat.h stable/9/cddl/contrib/opensolaris/lib/libzfs_core/ - copied from r248571, head/cddl/contrib/opensolaris/lib/libzfs_core/ stable/9/cddl/contrib/opensolaris/lib/libzpool/common/zfs.d - copied unchanged from r249195, head/cddl/contrib/opensolaris/lib/libzpool/common/zfs.d stable/9/cddl/lib/libzfs_core/ - copied from r248571, head/cddl/lib/libzfs_core/ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c - copied, changed from r248571, head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_userhold.c - copied, changed from r248571, head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_userhold.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_send.h - copied unchanged from r248571, head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_send.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_destroy.h - copied unchanged from r248571, head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_destroy.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_userhold.h - copied unchanged from r248571, head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_userhold.h Modified: stable/9/Makefile.inc1 (contents, props changed) stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb.c stable/9/cddl/contrib/opensolaris/cmd/zfs/zfs.8 stable/9/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c stable/9/cddl/contrib/opensolaris/cmd/zhack/zhack.c stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c stable/9/cddl/contrib/opensolaris/cmd/ztest/ztest.c stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_iter.c stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_util.c stable/9/cddl/contrib/opensolaris/lib/libzpool/common/kernel.c stable/9/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h stable/9/cddl/lib/Makefile stable/9/cddl/lib/libzfs/Makefile stable/9/cddl/sbin/zfs/Makefile stable/9/cddl/sbin/zpool/Makefile stable/9/cddl/usr.bin/zinject/Makefile stable/9/cddl/usr.bin/ztest/Makefile stable/9/cddl/usr.sbin/zdb/Makefile stable/9/cddl/usr.sbin/zhack/Makefile stable/9/rescue/rescue/Makefile stable/9/share/mk/bsd.libnames.mk stable/9/sys/cddl/compat/opensolaris/sys/cred.h stable/9/sys/cddl/compat/opensolaris/sys/sdt.h stable/9/sys/cddl/contrib/opensolaris/common/nvpair/fnvpair.c stable/9/sys/cddl/contrib/opensolaris/common/zfs/zfs_comutil.c stable/9/sys/cddl/contrib/opensolaris/common/zfs/zfs_comutil.h stable/9/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c stable/9/sys/cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.h stable/9/sys/cddl/contrib/opensolaris/common/zfs/zprop_common.c stable/9/sys/cddl/contrib/opensolaris/uts/common/Makefile.files stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bplist.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_diff.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deleg.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_synctask.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/rrwlock.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_errlog.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_history.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dbuf.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_tx.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_deleg.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dir.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_prop.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_synctask.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/metaslab.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/refcount.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/rrwlock.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/space_map.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/txg.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfeature.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_debug.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/uberblock.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_cache.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_root.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_leaf.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfeature.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_checksum.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_compress.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio_inject.c stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c stable/9/sys/cddl/contrib/opensolaris/uts/common/sys/feature_tests.h stable/9/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h stable/9/sys/cddl/contrib/opensolaris/uts/common/sys/nvpair.h Directory Properties: stable/9/cddl/ (props changed) stable/9/cddl/contrib/opensolaris/ (props changed) stable/9/cddl/contrib/opensolaris/cmd/zfs/ (props changed) stable/9/cddl/contrib/opensolaris/lib/libzfs/ (props changed) stable/9/cddl/lib/ (props changed) stable/9/rescue/rescue/ (props changed) stable/9/share/mk/ (props changed) stable/9/sys/ (props changed) stable/9/sys/cddl/contrib/opensolaris/ (props changed) stable/9/sys/conf/ (props changed) Modified: stable/9/Makefile.inc1 ============================================================================== --- stable/9/Makefile.inc1 Fri Apr 19 08:06:45 2013 (r249642) +++ stable/9/Makefile.inc1 Fri Apr 19 09:19:10 2013 (r249643) @@ -1321,6 +1321,7 @@ _prebuild_libs= ${_kerberos5_lib_libasn1 lib/libopie lib/libpam ${_lib_libthr} \ lib/libradius lib/libsbuf lib/libtacplus \ ${_cddl_lib_libumem} ${_cddl_lib_libnvpair} \ + ${_cddl_lib_libzfs_core} \ lib/libutil ${_lib_libypclnt} lib/libz lib/msun \ ${_secure_lib_libcrypto} ${_secure_lib_libssh} \ ${_secure_lib_libssl} @@ -1340,7 +1341,9 @@ lib/libopie__L lib/libtacplus__L: lib/li .if ${MK_CDDL} != "no" _cddl_lib_libumem= cddl/lib/libumem _cddl_lib_libnvpair= cddl/lib/libnvpair +_cddl_lib_libzfs_core= cddl/lib/libzfs_core _cddl_lib= cddl/lib +cddl/lib/libzfs_core__L: cddl/lib/libnvpair__L .endif .if ${MK_CRYPT} != "no" Modified: stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb.c ============================================================================== --- stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb.c Fri Apr 19 08:06:45 2013 (r249642) +++ stable/9/cddl/contrib/opensolaris/cmd/zdb/zdb.c Fri Apr 19 09:19:10 2013 (r249643) @@ -21,10 +21,11 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013 by Delphix. All rights reserved. */ #include +#include #include #include #include @@ -57,6 +58,7 @@ #include #include #include +#include #undef ZFS_MAXNAMELEN #undef verify #include @@ -206,6 +208,27 @@ dump_packed_nvlist(objset_t *os, uint64_ nvlist_free(nv); } +/* ARGSUSED */ +static void +dump_history_offsets(objset_t *os, uint64_t object, void *data, size_t size) +{ + spa_history_phys_t *shp = data; + + if (shp == NULL) + return; + + (void) printf("\t\tpool_create_len = %llu\n", + (u_longlong_t)shp->sh_pool_create_len); + (void) printf("\t\tphys_max_off = %llu\n", + (u_longlong_t)shp->sh_phys_max_off); + (void) printf("\t\tbof = %llu\n", + (u_longlong_t)shp->sh_bof); + (void) printf("\t\teof = %llu\n", + (u_longlong_t)shp->sh_eof); + (void) printf("\t\trecords_lost = %llu\n", + (u_longlong_t)shp->sh_records_lost); +} + static void zdb_nicenum(uint64_t num, char *buf) { @@ -215,18 +238,18 @@ zdb_nicenum(uint64_t num, char *buf) nicenum(num, buf); } -const char dump_zap_stars[] = "****************************************"; -const int dump_zap_width = sizeof (dump_zap_stars) - 1; +const char histo_stars[] = "****************************************"; +const int histo_width = sizeof (histo_stars) - 1; static void -dump_zap_histogram(uint64_t histo[ZAP_HISTOGRAM_SIZE]) +dump_histogram(const uint64_t *histo, int size) { int i; - int minidx = ZAP_HISTOGRAM_SIZE - 1; + int minidx = size - 1; int maxidx = 0; uint64_t max = 0; - for (i = 0; i < ZAP_HISTOGRAM_SIZE; i++) { + for (i = 0; i < size; i++) { if (histo[i] > max) max = histo[i]; if (histo[i] > 0 && i > maxidx) @@ -235,12 +258,14 @@ dump_zap_histogram(uint64_t histo[ZAP_HI minidx = i; } - if (max < dump_zap_width) - max = dump_zap_width; + if (max < histo_width) + max = histo_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]); + for (i = minidx; i <= maxidx; i++) { + (void) printf("\t\t\t%3u: %6llu %s\n", + i, (u_longlong_t)histo[i], + &histo_stars[(max - histo[i]) * histo_width / max]); + } } static void @@ -291,19 +316,19 @@ dump_zap_stats(objset_t *os, uint64_t ob (u_longlong_t)zs.zs_salt); (void) printf("\t\tLeafs with 2^n pointers:\n"); - dump_zap_histogram(zs.zs_leafs_with_2n_pointers); + dump_histogram(zs.zs_leafs_with_2n_pointers, ZAP_HISTOGRAM_SIZE); (void) printf("\t\tBlocks with n*5 entries:\n"); - dump_zap_histogram(zs.zs_blocks_with_n5_entries); + dump_histogram(zs.zs_blocks_with_n5_entries, ZAP_HISTOGRAM_SIZE); (void) printf("\t\tBlocks n/10 full:\n"); - dump_zap_histogram(zs.zs_blocks_n_tenths_full); + dump_histogram(zs.zs_blocks_n_tenths_full, ZAP_HISTOGRAM_SIZE); (void) printf("\t\tEntries with n chunks:\n"); - dump_zap_histogram(zs.zs_entries_using_n_chunks); + dump_histogram(zs.zs_entries_using_n_chunks, ZAP_HISTOGRAM_SIZE); (void) printf("\t\tBuckets with n entries:\n"); - dump_zap_histogram(zs.zs_buckets_with_n_entries); + dump_histogram(zs.zs_buckets_with_n_entries, ZAP_HISTOGRAM_SIZE); } /*ARGSUSED*/ @@ -857,21 +882,22 @@ dump_history(spa_t *spa) for (int i = 0; i < num; i++) { uint64_t time, txg, ievent; char *cmd, *intstr; + boolean_t printed = B_FALSE; if (nvlist_lookup_uint64(events[i], ZPOOL_HIST_TIME, &time) != 0) - continue; + goto next; if (nvlist_lookup_string(events[i], ZPOOL_HIST_CMD, &cmd) != 0) { if (nvlist_lookup_uint64(events[i], ZPOOL_HIST_INT_EVENT, &ievent) != 0) - continue; + goto next; verify(nvlist_lookup_uint64(events[i], ZPOOL_HIST_TXG, &txg) == 0); verify(nvlist_lookup_string(events[i], ZPOOL_HIST_INT_STR, &intstr) == 0); - if (ievent >= LOG_END) - continue; + if (ievent >= ZFS_NUM_LEGACY_HISTORY_EVENTS) + goto next; (void) snprintf(internalstr, sizeof (internalstr), @@ -884,6 +910,14 @@ dump_history(spa_t *spa) (void) localtime_r(&tsec, &t); (void) strftime(tbuf, sizeof (tbuf), "%F.%T", &t); (void) printf("%s %s\n", tbuf, cmd); + printed = B_TRUE; + +next: + if (dump_opt['h'] > 1) { + if (!printed) + (void) printf("unrecognized record:\n"); + dump_nvlist(events[i], 2); + } } } @@ -916,7 +950,7 @@ sprintf_blkptr_compact(char *blkbuf, con const dva_t *dva = bp->blk_dva; int ndvas = dump_opt['d'] > 5 ? BP_GET_NDVAS(bp) : 1; - if (dump_opt['b'] >= 5) { + if (dump_opt['b'] >= 6) { sprintf_blkptr(blkbuf, bp); return; } @@ -1496,7 +1530,7 @@ static object_viewer_t *object_viewer[DM dump_zap, /* other ZAP */ dump_zap, /* persistent error log */ dump_uint8, /* SPA history */ - dump_uint64, /* SPA history offsets */ + dump_history_offsets, /* SPA history offsets */ dump_zap, /* Pool properties */ dump_zap, /* DSL permissions */ dump_acl, /* ZFS ACL */ @@ -1661,7 +1695,9 @@ dump_dir(objset_t *os) int print_header = 1; int i, error; + dsl_pool_config_enter(dmu_objset_pool(os), FTAG); dmu_objset_fast_stat(os, &dds); + dsl_pool_config_exit(dmu_objset_pool(os), FTAG); if (dds.dds_type < DMU_OST_NUMTYPES) type = objset_types[dds.dds_type]; @@ -1953,11 +1989,13 @@ dump_one_dir(const char *dsname, void *a /* * Block statistics. */ +#define PSIZE_HISTO_SIZE (SPA_MAXBLOCKSIZE / SPA_MINBLOCKSIZE + 1) typedef struct zdb_blkstats { - uint64_t zb_asize; - uint64_t zb_lsize; - uint64_t zb_psize; - uint64_t zb_count; + uint64_t zb_asize; + uint64_t zb_lsize; + uint64_t zb_psize; + uint64_t zb_count; + uint64_t zb_psize_histogram[PSIZE_HISTO_SIZE]; } zdb_blkstats_t; /* @@ -1981,6 +2019,9 @@ typedef struct zdb_cb { zdb_blkstats_t zcb_type[ZB_TOTAL + 1][ZDB_OT_TOTAL + 1]; uint64_t zcb_dedup_asize; uint64_t zcb_dedup_blocks; + uint64_t zcb_start; + uint64_t zcb_lastprint; + uint64_t zcb_totalasize; uint64_t zcb_errors[256]; int zcb_readfails; int zcb_haderrors; @@ -2007,6 +2048,7 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t * zb->zb_lsize += BP_GET_LSIZE(bp); zb->zb_psize += BP_GET_PSIZE(bp); zb->zb_count++; + zb->zb_psize_histogram[BP_GET_PSIZE(bp) >> SPA_MINBLOCKSHIFT]++; } if (dump_opt['L']) @@ -2070,7 +2112,6 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog NULL, NULL, ZIO_PRIORITY_ASYNC_READ, flags, zb)); free(data); - if (ioerr && !(flags & ZIO_FLAG_SPECULATIVE)) { zcb->zcb_haderrors = 1; zcb->zcb_errors[ioerr]++; @@ -2094,7 +2135,7 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog zcb->zcb_readfails = 0; - if (dump_opt['b'] >= 4) { + if (dump_opt['b'] >= 5) { sprintf_blkptr(blkbuf, bp); (void) printf("objset %llu object %llu " "level %lld offset 0x%llx %s\n", @@ -2105,6 +2146,28 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog blkbuf); } + if (dump_opt['b'] < 5 && isatty(STDERR_FILENO) && + gethrtime() > zcb->zcb_lastprint + NANOSEC) { + uint64_t now = gethrtime(); + char buf[10]; + uint64_t bytes = zcb->zcb_type[ZB_TOTAL][ZDB_OT_TOTAL].zb_asize; + int kb_per_sec = + 1 + bytes / (1 + ((now - zcb->zcb_start) / 1000 / 1000)); + int sec_remaining = + (zcb->zcb_totalasize - bytes) / 1024 / kb_per_sec; + + zfs_nicenum(bytes, buf, sizeof (buf)); + (void) fprintf(stderr, + "\r%5s completed (%4dMB/s) " + "estimated time remaining: %uhr %02umin %02usec ", + buf, kb_per_sec / 1024, + sec_remaining / 60 / 60, + sec_remaining / 60 % 60, + sec_remaining % 60); + + zcb->zcb_lastprint = now; + } + return (0); } @@ -2236,7 +2299,7 @@ count_block_cb(void *arg, const blkptr_t { zdb_cb_t *zcb = arg; - if (dump_opt['b'] >= 4) { + if (dump_opt['b'] >= 5) { char blkbuf[BP_SPRINTF_LEN]; sprintf_blkptr(blkbuf, bp); (void) printf("[%s] %s\n", @@ -2255,7 +2318,7 @@ dump_block_stats(spa_t *spa) int flags = TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA | TRAVERSE_HARD; int leaks = 0; - (void) printf("\nTraversing all blocks %s%s%s%s%s...\n", + (void) printf("\nTraversing all blocks %s%s%s%s%s...\n\n", (dump_opt['c'] || !dump_opt['L']) ? "to verify " : "", (dump_opt['c'] == 1) ? "metadata " : "", dump_opt['c'] ? "checksums " : "", @@ -2291,6 +2354,8 @@ dump_block_stats(spa_t *spa) if (dump_opt['c'] > 1) flags |= TRAVERSE_PREFETCH_DATA; + zcb.zcb_totalasize = metaslab_class_get_alloc(spa_normal_class(spa)); + zcb.zcb_start = zcb.zcb_lastprint = gethrtime(); zcb.zcb_haderrors |= traverse_pool(spa, 0, flags, zdb_blkptr_cb, &zcb); if (zcb.zcb_haderrors) { @@ -2418,6 +2483,14 @@ dump_block_stats(spa_t *spa) else (void) printf(" L%d %s\n", level, typename); + + if (dump_opt['b'] >= 4) { + (void) printf("psize " + "(in 512-byte sectors): " + "number of blocks\n"); + dump_histogram(zb->zb_psize_histogram, + PSIZE_HISTO_SIZE); + } } } } Modified: stable/9/cddl/contrib/opensolaris/cmd/zfs/zfs.8 ============================================================================== --- stable/9/cddl/contrib/opensolaris/cmd/zfs/zfs.8 Fri Apr 19 08:06:45 2013 (r249642) +++ stable/9/cddl/contrib/opensolaris/cmd/zfs/zfs.8 Fri Apr 19 09:19:10 2013 (r249643) @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 1, 2013 +.Dd March 21, 2013 .Dt ZFS 8 .Os .Sh NAME @@ -65,6 +65,7 @@ .Op Fl r .Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... .Ar filesystem@snapname Ns | Ns Ar volume@snapname +.Ar filesystem@snapname Ns | Ns Ar volume@snapname Ns ... .Nm .Cm rollback .Op Fl rRf @@ -1609,7 +1610,11 @@ multiple snapshots. Destroy (or mark for deferred deletion) all snapshots with this name in descendent file systems. .It Fl R -Recursively destroy all dependents. +Recursively destroy all clones of these snapshots, including the clones, +snapshots, and children. +If this flag is specified, the +.Op fl d +flag will have no effect. .It Fl n Do a dry-run ("No-op") deletion. No data will be deleted. This is useful in conjunction with the @@ -1637,17 +1642,18 @@ behavior for mounted file systems in use .Op Fl r .Oo Fl o Ar property Ns = Ns Ar value Oc Ns ... .Ar filesystem@snapname Ns | Ns volume@snapname +.Ar filesystem@snapname Ns | Ns volume@snapname Ns ... .Xc .Pp -Creates a snapshot with the given name. All previous modifications by -successful system calls to the file system are part of the snapshot. See the +Creates snapshots with the given names. All previous modifications by +successful system calls to the file system are part of the snapshots. +Snapshots are taken atomically, so that all snapshots correspond to the same +moment in time. See the .Qq Sx Snapshots section for details. .Bl -tag -width indent .It Fl r -Recursively create snapshots of all descendent datasets. Snapshots are taken -atomically, so that all recursive snapshots correspond to the same moment in -time. +Recursively create snapshots of all descendent datasets .It Fl o Ar property Ns = Ns Ar value Sets the specified property; see .Qq Nm Cm create Modified: stable/9/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c ============================================================================== --- stable/9/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c Fri Apr 19 08:06:45 2013 (r249642) +++ stable/9/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c Fri Apr 19 09:19:10 2013 (r249643) @@ -58,6 +58,7 @@ #include #include +#include #include #include #include @@ -74,6 +75,7 @@ libzfs_handle_t *g_zfs; static FILE *mnttab_file; static char history_str[HIS_MAX_RECORD_LEN]; +static boolean_t log_history = B_TRUE; static int zfs_do_clone(int argc, char **argv); static int zfs_do_create(int argc, char **argv); @@ -276,7 +278,7 @@ get_usage(zfs_help_t idx) return (gettext("\tshare <-a | filesystem>\n")); case HELP_SNAPSHOT: return (gettext("\tsnapshot [-r] [-o property=value] ... " - "\n")); + " ...\n")); case HELP_UNMOUNT: return (gettext("\tunmount [-f] " "<-a | filesystem|mountpoint>\n")); @@ -903,11 +905,12 @@ typedef struct destroy_cbdata { boolean_t cb_parsable; boolean_t cb_dryrun; nvlist_t *cb_nvl; + nvlist_t *cb_batchedsnaps; /* first snap in contiguous run */ - zfs_handle_t *cb_firstsnap; + char *cb_firstsnap; /* previous snap in contiguous run */ - zfs_handle_t *cb_prevsnap; + char *cb_prevsnap; int64_t cb_snapused; char *cb_snapspec; } destroy_cbdata_t; @@ -999,9 +1002,27 @@ destroy_callback(zfs_handle_t *zhp, void zfs_close(zhp); return (0); } + if (cb->cb_dryrun) { + zfs_close(zhp); + return (0); + } + + /* + * We batch up all contiguous snapshots (even of different + * filesystems) and destroy them with one ioctl. We can't + * simply do all snap deletions and then all fs deletions, + * because we must delete a clone before its origin. + */ + if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) { + fnvlist_add_boolean(cb->cb_batchedsnaps, name); + } else { + int error = zfs_destroy_snaps_nvl(g_zfs, + cb->cb_batchedsnaps, B_FALSE); + fnvlist_free(cb->cb_batchedsnaps); + cb->cb_batchedsnaps = fnvlist_alloc(); - if (!cb->cb_dryrun) { - if (zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 || + if (error != 0 || + zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 || zfs_destroy(zhp, cb->cb_defer_destroy) != 0) { zfs_close(zhp); return (-1); @@ -1021,11 +1042,13 @@ destroy_print_cb(zfs_handle_t *zhp, void if (nvlist_exists(cb->cb_nvl, name)) { if (cb->cb_firstsnap == NULL) - cb->cb_firstsnap = zfs_handle_dup(zhp); + cb->cb_firstsnap = strdup(name); if (cb->cb_prevsnap != NULL) - zfs_close(cb->cb_prevsnap); + free(cb->cb_prevsnap); /* this snap continues the current range */ - cb->cb_prevsnap = zfs_handle_dup(zhp); + cb->cb_prevsnap = strdup(name); + if (cb->cb_firstsnap == NULL || cb->cb_prevsnap == NULL) + nomem(); if (cb->cb_verbose) { if (cb->cb_parsable) { (void) printf("destroy\t%s\n", name); @@ -1040,12 +1063,12 @@ destroy_print_cb(zfs_handle_t *zhp, void } else if (cb->cb_firstsnap != NULL) { /* end of this range */ uint64_t used = 0; - err = zfs_get_snapused_int(cb->cb_firstsnap, + err = lzc_snaprange_space(cb->cb_firstsnap, cb->cb_prevsnap, &used); cb->cb_snapused += used; - zfs_close(cb->cb_firstsnap); + free(cb->cb_firstsnap); cb->cb_firstsnap = NULL; - zfs_close(cb->cb_prevsnap); + free(cb->cb_prevsnap); cb->cb_prevsnap = NULL; } zfs_close(zhp); @@ -1062,13 +1085,13 @@ destroy_print_snapshots(zfs_handle_t *fs if (cb->cb_firstsnap != NULL) { uint64_t used = 0; if (err == 0) { - err = zfs_get_snapused_int(cb->cb_firstsnap, + err = lzc_snaprange_space(cb->cb_firstsnap, cb->cb_prevsnap, &used); } cb->cb_snapused += used; - zfs_close(cb->cb_firstsnap); + free(cb->cb_firstsnap); cb->cb_firstsnap = NULL; - zfs_close(cb->cb_prevsnap); + free(cb->cb_prevsnap); cb->cb_prevsnap = NULL; } return (err); @@ -1155,8 +1178,10 @@ static int zfs_do_destroy(int argc, char **argv) { destroy_cbdata_t cb = { 0 }; + int rv = 0; + int err = 0; int c; - zfs_handle_t *zhp; + zfs_handle_t *zhp = NULL; char *at; zfs_type_t type = ZFS_TYPE_DATASET; @@ -1210,11 +1235,9 @@ zfs_do_destroy(int argc, char **argv) at = strchr(argv[0], '@'); if (at != NULL) { - int err = 0; /* Build the list of snaps to destroy in cb_nvl. */ - if (nvlist_alloc(&cb.cb_nvl, NV_UNIQUE_NAME, 0) != 0) - nomem(); + cb.cb_nvl = fnvlist_alloc(); *at = '\0'; zhp = zfs_open(g_zfs, argv[0], @@ -1225,17 +1248,15 @@ zfs_do_destroy(int argc, char **argv) cb.cb_snapspec = at + 1; if (gather_snapshots(zfs_handle_dup(zhp), &cb) != 0 || cb.cb_error) { - zfs_close(zhp); - nvlist_free(cb.cb_nvl); - return (1); + rv = 1; + goto out; } if (nvlist_empty(cb.cb_nvl)) { (void) fprintf(stderr, gettext("could not find any " "snapshots to destroy; check snapshot names.\n")); - zfs_close(zhp); - nvlist_free(cb.cb_nvl); - return (1); + rv = 1; + goto out; } if (cb.cb_verbose) { @@ -1254,18 +1275,26 @@ zfs_do_destroy(int argc, char **argv) } if (!cb.cb_dryrun) { - if (cb.cb_doclones) + if (cb.cb_doclones) { + cb.cb_batchedsnaps = fnvlist_alloc(); err = destroy_clones(&cb); + if (err == 0) { + err = zfs_destroy_snaps_nvl(g_zfs, + cb.cb_batchedsnaps, B_FALSE); + } + if (err != 0) { + rv = 1; + goto out; + } + } if (err == 0) { - err = zfs_destroy_snaps_nvl(zhp, cb.cb_nvl, + err = zfs_destroy_snaps_nvl(g_zfs, cb.cb_nvl, cb.cb_defer_destroy); } } - zfs_close(zhp); - nvlist_free(cb.cb_nvl); if (err != 0) - return (1); + rv = 1; } else { /* Open the given dataset */ if ((zhp = zfs_open(g_zfs, argv[0], type)) == NULL) @@ -1286,8 +1315,8 @@ zfs_do_destroy(int argc, char **argv) zfs_get_name(zhp)); (void) fprintf(stderr, gettext("use 'zpool destroy %s' " "to destroy the pool itself\n"), zfs_get_name(zhp)); - zfs_close(zhp); - return (1); + rv = 1; + goto out; } /* @@ -1297,30 +1326,42 @@ zfs_do_destroy(int argc, char **argv) if (!cb.cb_doclones && zfs_iter_dependents(zhp, B_TRUE, destroy_check_dependent, &cb) != 0) { - zfs_close(zhp); - return (1); + rv = 1; + goto out; } if (cb.cb_error) { - zfs_close(zhp); - return (1); + rv = 1; + goto out; } + cb.cb_batchedsnaps = fnvlist_alloc(); if (zfs_iter_dependents(zhp, B_FALSE, destroy_callback, &cb) != 0) { - zfs_close(zhp); - return (1); + rv = 1; + goto out; } /* * Do the real thing. The callback will close the * handle regardless of whether it succeeds or not. */ - if (destroy_callback(zhp, &cb) != 0) - return (1); + err = destroy_callback(zhp, &cb); + zhp = NULL; + if (err == 0) { + err = zfs_destroy_snaps_nvl(g_zfs, + cb.cb_batchedsnaps, cb.cb_defer_destroy); + } + if (err != 0) + rv = 1; } - return (0); +out: + fnvlist_free(cb.cb_batchedsnaps); + fnvlist_free(cb.cb_nvl); + if (zhp != NULL) + zfs_close(zhp); + return (rv); } static boolean_t @@ -1921,9 +1962,11 @@ upgrade_set_callback(zfs_handle_t *zhp, /* * If they did "zfs upgrade -a", then we could * be doing ioctls to different pools. We need - * to log this history once to each pool. + * to log this history once to each pool, and bypass + * the normal history logging that happens in main(). */ - verify(zpool_stage_history(g_zfs, history_str) == 0); + (void) zpool_log_history(g_zfs, history_str); + log_history = B_FALSE; } if (zfs_prop_set(zhp, "version", verstr) == 0) cb->cb_numupgraded++; @@ -3461,6 +3504,32 @@ zfs_do_set(int argc, char **argv) return (ret); } +typedef struct snap_cbdata { + nvlist_t *sd_nvl; + boolean_t sd_recursive; + const char *sd_snapname; +} snap_cbdata_t; + +static int +zfs_snapshot_cb(zfs_handle_t *zhp, void *arg) +{ + snap_cbdata_t *sd = arg; + char *name; + int rv = 0; + int error; + + error = asprintf(&name, "%s@%s", zfs_get_name(zhp), sd->sd_snapname); + if (error == -1) + nomem(); + fnvlist_add_boolean(sd->sd_nvl, name); + free(name); + + if (sd->sd_recursive) + rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd); + zfs_close(zhp); + return (rv); +} + /* * zfs snapshot [-r] [-o prop=value] ... * @@ -3470,13 +3539,16 @@ zfs_do_set(int argc, char **argv) static int zfs_do_snapshot(int argc, char **argv) { - boolean_t recursive = B_FALSE; int ret = 0; char c; nvlist_t *props; + snap_cbdata_t sd = { 0 }; + boolean_t multiple_snaps = B_FALSE; if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) nomem(); + if (nvlist_alloc(&sd.sd_nvl, NV_UNIQUE_NAME, 0) != 0) + nomem(); /* check options */ while ((c = getopt(argc, argv, "ro:")) != -1) { @@ -3486,7 +3558,8 @@ zfs_do_snapshot(int argc, char **argv) return (1); break; case 'r': - recursive = B_TRUE; + sd.sd_recursive = B_TRUE; + multiple_snaps = B_TRUE; break; case '?': (void) fprintf(stderr, gettext("invalid option '%c'\n"), @@ -3503,18 +3576,35 @@ zfs_do_snapshot(int argc, char **argv) (void) fprintf(stderr, gettext("missing snapshot argument\n")); goto usage; } - if (argc > 1) { - (void) fprintf(stderr, gettext("too many arguments\n")); - goto usage; + + if (argc > 1) + multiple_snaps = B_TRUE; + for (; argc > 0; argc--, argv++) { + char *atp; + zfs_handle_t *zhp; + + atp = strchr(argv[0], '@'); + if (atp == NULL) + goto usage; + *atp = '\0'; + sd.sd_snapname = atp + 1; + zhp = zfs_open(g_zfs, argv[0], + ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME); + if (zhp == NULL) + goto usage; + if (zfs_snapshot_cb(zhp, &sd) != 0) + goto usage; } - ret = zfs_snapshot(g_zfs, argv[0], recursive, props); + ret = zfs_snapshot_nvl(g_zfs, sd.sd_nvl, props); + nvlist_free(sd.sd_nvl); nvlist_free(props); - if (ret && recursive) + if (ret != 0 && multiple_snaps) (void) fprintf(stderr, gettext("no snapshots were created\n")); return (ret != 0); usage: + nvlist_free(sd.sd_nvl); nvlist_free(props); usage(B_FALSE); return (-1); @@ -5057,28 +5147,12 @@ cleanup2: return (error); } -/* - * zfs allow [-r] [-t] ... - * - * -r Recursively hold - * -t Temporary hold (hidden option) - * - * Apply a user-hold with the given tag to the list of snapshots. - */ static int zfs_do_allow(int argc, char **argv) { return (zfs_do_allow_unallow_impl(argc, argv, B_FALSE)); } -/* - * zfs unallow [-r] [-t] ... - * - * -r Recursively hold - * -t Temporary hold (hidden option) - * - * Apply a user-hold with the given tag to the list of snapshots. - */ static int zfs_do_unallow(int argc, char **argv) { @@ -5092,7 +5166,6 @@ zfs_do_hold_rele_impl(int argc, char **a int i; const char *tag; boolean_t recursive = B_FALSE; - boolean_t temphold = B_FALSE; const char *opts = holding ? "rt" : "r"; int c; @@ -5102,9 +5175,6 @@ zfs_do_hold_rele_impl(int argc, char **a case 'r': recursive = B_TRUE; break; - case 't': - temphold = B_TRUE; - break; case '?': (void) fprintf(stderr, gettext("invalid option '%c'\n"), optopt); @@ -5153,7 +5223,7 @@ zfs_do_hold_rele_impl(int argc, char **a } if (holding) { if (zfs_hold(zhp, delim+1, tag, recursive, - temphold, B_FALSE, -1, 0, 0) != 0) + B_FALSE, -1) != 0) ++errors; } else { if (zfs_release(zhp, delim+1, tag, recursive) != 0) @@ -5169,7 +5239,6 @@ zfs_do_hold_rele_impl(int argc, char **a * zfs hold [-r] [-t] ... * * -r Recursively hold - * -t Temporary hold (hidden option) * * Apply a user-hold with the given tag to the list of snapshots. */ @@ -6591,8 +6660,7 @@ main(int argc, char **argv) return (1); } - zpool_set_history_str("zfs", argc, argv, history_str); - verify(zpool_stage_history(g_zfs, history_str) == 0); + zfs_save_arguments(argc, argv, history_str, sizeof (history_str)); libzfs_print_on_error(g_zfs, B_TRUE); @@ -6661,6 +6729,9 @@ main(int argc, char **argv) (void) fclose(mnttab_file); + if (ret == 0 && log_history) + (void) zpool_log_history(g_zfs, history_str); + libzfs_fini(g_zfs); /* Modified: stable/9/cddl/contrib/opensolaris/cmd/zhack/zhack.c ============================================================================== --- stable/9/cddl/contrib/opensolaris/cmd/zhack/zhack.c Fri Apr 19 08:06:45 2013 (r249642) +++ stable/9/cddl/contrib/opensolaris/cmd/zhack/zhack.c Fri Apr 19 09:19:10 2013 (r249643) @@ -46,6 +46,7 @@ #include #include #include +#include #undef ZFS_MAXNAMELEN #undef verify #include @@ -273,12 +274,15 @@ zhack_do_feature_stat(int argc, char **a } static void -feature_enable_sync(void *arg1, void *arg2, dmu_tx_t *tx) +feature_enable_sync(void *arg, dmu_tx_t *tx) { - spa_t *spa = arg1; - zfeature_info_t *feature = arg2; + spa_t *spa = dmu_tx_pool(tx)->dp_spa; + zfeature_info_t *feature = arg; spa_feature_enable(spa, feature, tx); + spa_history_log_internal(spa, "zhack enable feature", tx, + "name=%s can_readonly=%u", + feature->fi_guid, feature->fi_can_readonly); } static void @@ -341,8 +345,8 @@ zhack_do_feature_enable(int argc, char * if (0 == zap_contains(mos, spa->spa_feat_desc_obj, feature.fi_guid)) fatal("feature already enabled: %s", feature.fi_guid); - VERIFY3U(0, ==, dsl_sync_task_do(spa->spa_dsl_pool, NULL, - feature_enable_sync, spa, &feature, 5)); + VERIFY0(dsl_sync_task(spa_name(spa), NULL, + feature_enable_sync, &feature, 5)); spa_close(spa, FTAG); @@ -350,21 +354,25 @@ zhack_do_feature_enable(int argc, char * } static void -feature_incr_sync(void *arg1, void *arg2, dmu_tx_t *tx) +feature_incr_sync(void *arg, dmu_tx_t *tx) { - spa_t *spa = arg1; - zfeature_info_t *feature = arg2; + spa_t *spa = dmu_tx_pool(tx)->dp_spa; + zfeature_info_t *feature = arg; spa_feature_incr(spa, feature, tx); + spa_history_log_internal(spa, "zhack feature incr", tx, + "name=%s", feature->fi_guid); } static void -feature_decr_sync(void *arg1, void *arg2, dmu_tx_t *tx) +feature_decr_sync(void *arg, dmu_tx_t *tx) { - spa_t *spa = arg1; - zfeature_info_t *feature = arg2; + spa_t *spa = dmu_tx_pool(tx)->dp_spa; + zfeature_info_t *feature = arg; spa_feature_decr(spa, feature, tx); + spa_history_log_internal(spa, "zhack feature decr", tx, + "name=%s", feature->fi_guid); } static void @@ -435,8 +443,8 @@ zhack_do_feature_ref(int argc, char **ar if (decr && !spa_feature_is_active(spa, &feature)) fatal("feature refcount already 0: %s", feature.fi_guid); - VERIFY3U(0, ==, dsl_sync_task_do(spa->spa_dsl_pool, NULL, - decr ? feature_decr_sync : feature_incr_sync, spa, &feature, 5)); + VERIFY0(dsl_sync_task(spa_name(spa), NULL, + decr ? feature_decr_sync : feature_incr_sync, &feature, 5)); spa_close(spa, FTAG); } Modified: stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c ============================================================================== --- stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c Fri Apr 19 08:06:45 2013 (r249642) +++ stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c Fri Apr 19 09:19:10 2013 (r249643) @@ -192,9 +192,9 @@ static zpool_command_t command_table[] = #define NCOMMAND (sizeof (command_table) / sizeof (command_table[0])) -zpool_command_t *current_command; +static zpool_command_t *current_command; static char history_str[HIS_MAX_RECORD_LEN]; - +static boolean_t log_history = B_TRUE; static uint_t timestamp_fmt = NODATE; static const char * @@ -1092,7 +1092,10 @@ zpool_do_destroy(int argc, char **argv) return (1); } - ret = (zpool_destroy(zhp) != 0); + /* The history must be logged as part of the export */ + log_history = B_FALSE; + + ret = (zpool_destroy(zhp, history_str) != 0); zpool_close(zhp); @@ -1156,10 +1159,13 @@ zpool_do_export(int argc, char **argv) continue; } + /* The history must be logged as part of the export */ + log_history = B_FALSE; + if (hardforce) { - if (zpool_export_force(zhp) != 0) + if (zpool_export_force(zhp, history_str) != 0) ret = 1; - } else if (zpool_export(zhp, force) != 0) { + } else if (zpool_export(zhp, force, history_str) != 0) { ret = 1; } @@ -4562,6 +4568,14 @@ upgrade_cb(zpool_handle_t *zhp, void *ar if (count > 0) { cbp->cb_first = B_FALSE; printnl = B_TRUE; + /* + * If they did "zpool upgrade -a", then we could + * be doing ioctls to different pools. We need + * to log this history once to each pool, and bypass + * the normal history logging that happens in main(). + */ + (void) zpool_log_history(g_zfs, history_str); + log_history = B_FALSE; } } @@ -4923,8 +4937,8 @@ zpool_do_upgrade(int argc, char **argv) typedef struct hist_cbdata { boolean_t first; - int longfmt; - int internal; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***