fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
99653d4ee642c6528e88224f12409a5f23060994eschrock * Common Development and Distribution License (the "License").
99653d4ee642c6528e88224f12409a5f23060994eschrock * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
a8b6ddaf31808c845e00161dda0a3d1fe31ae281Mark J Musante * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
0d8fa8f8eba3ea46bc79d73445009505d1dd5d7dMartin Matuska * Copyright (c) 2012 Pawel Jakub Dawidek. All rights reserved.
43d68d68c1ce08fb35026bebfb141af422e7082eYuri Pankov * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens * Copyright (c) 2013 by Delphix. All rights reserved.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This is a private interface used to gather up all the datasets specified on
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the command line so that we can iterate over them in order.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * First, we iterate over all filesystems, gathering them together into an
b6825278356f1c9ddb8765d2f2b1d4fb62be1dbdsjelinek * AVL tree. We report errors for any explicitly specified datasets
fa9e4066f08beec538e775443c5be79dd423fcabahrens * that we couldn't open.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When finished, we have an AVL tree of ZFS handles. We go through and execute
fa9e4066f08beec538e775443c5be79dd423fcabahrens * the provided callback for each one, passing whatever data the user supplied.
d5b5bb256c576fe5ef26e0795bd40abe77f93246Rich Morris * Include snaps if they were requested or if this a zfs list where types
d5b5bb256c576fe5ef26e0795bd40abe77f93246Rich Morris * were not specified and the "listsnapshots" property is set on this pool.
d5b5bb256c576fe5ef26e0795bd40abe77f93246Rich Morriszfs_include_snapshots(zfs_handle_t *zhp, callback_data_t *cb)
d5b5bb256c576fe5ef26e0795bd40abe77f93246Rich Morris if ((cb->cb_flags & ZFS_ITER_PROP_LISTSNAPS) == 0)
d5b5bb256c576fe5ef26e0795bd40abe77f93246Rich Morris return (zpool_get_prop_int(zph, ZPOOL_PROP_LISTSNAPS, NULL));
d5b5bb256c576fe5ef26e0795bd40abe77f93246Rich Morris * Called for each dataset. If the object is of an appropriate type,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * add it to the avl tree and recurse over any children as necessary.
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens boolean_t include_snaps = zfs_include_snapshots(zhp, cb);
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens boolean_t include_bmarks = (cb->cb_types & ZFS_TYPE_BOOKMARK);
d5b5bb256c576fe5ef26e0795bd40abe77f93246Rich Morris ((zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) && include_snaps)) {
7f7322febbcfe774b7270abc3b191c094bfcc517eschrock * Recurse if necessary.
ae1726b6ae69a6882b0d520f4bc3433f501f2065Chris Gerhard ((cb->cb_flags & ZFS_ITER_DEPTH_LIMIT) == 0 ||
3cb34c601f3ef3016f638574f5982e80c3735c71ahrens (void) zfs_iter_filesystems(zhp, zfs_callback, data);
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
0d8fa8f8eba3ea46bc79d73445009505d1dd5d7dMartin Matuska (cb->cb_flags & ZFS_ITER_SIMPLE) != 0, zfs_callback,
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens if (((zfs_get_type(zhp) & (ZFS_TYPE_SNAPSHOT |
78f171005391b928aaf1642b3206c534ed644332Matthew Ahrens (void) zfs_iter_bookmarks(zhp, zfs_callback, data);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrockzfs_add_sort_column(zfs_sort_column_t **sc, const char *name,
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock return (-1);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock return (0);
0d8fa8f8eba3ea46bc79d73445009505d1dd5d7dMartin Matuskazfs_sort_only_by_name(const zfs_sort_column_t *sc)
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* ARGSUSED */
fa9e4066f08beec538e775443c5be79dd423fcabahrenszfs_compare(const void *larg, const void *rarg, void *unused)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (ret == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we're comparing a dataset to one of its snapshots, we
fa9e4066f08beec538e775443c5be79dd423fcabahrens * always make the full dataset first.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we have two snapshots from the same dataset, then
fa9e4066f08beec538e775443c5be79dd423fcabahrens * we want to sort them according to creation time. We
fa9e4066f08beec538e775443c5be79dd423fcabahrens * use the hidden CREATETXG property to get an absolute
fa9e4066f08beec538e775443c5be79dd423fcabahrens * ordering of snapshots.
0d8fa8f8eba3ea46bc79d73445009505d1dd5d7dMartin Matuska * Both lcreate and rcreate being 0 means we don't have
0d8fa8f8eba3ea46bc79d73445009505d1dd5d7dMartin Matuska * properties and we should compare full name.
b6825278356f1c9ddb8765d2f2b1d4fb62be1dbdsjelinek * Sort datasets by specified columns.
b6825278356f1c9ddb8765d2f2b1d4fb62be1dbdsjelinek * o Numeric types sort in ascending order.
b6825278356f1c9ddb8765d2f2b1d4fb62be1dbdsjelinek * o String types sort in alphabetical order.
b6825278356f1c9ddb8765d2f2b1d4fb62be1dbdsjelinek * o Types inappropriate for a row sort that row to the literal
b6825278356f1c9ddb8765d2f2b1d4fb62be1dbdsjelinek * bottom, regardless of the specified ordering.
b6825278356f1c9ddb8765d2f2b1d4fb62be1dbdsjelinek * If no sort columns are specified, or two datasets compare equally
b6825278356f1c9ddb8765d2f2b1d4fb62be1dbdsjelinek * across all specified columns, they are sorted alphabetically by name
b6825278356f1c9ddb8765d2f2b1d4fb62be1dbdsjelinek * with snapshots grouped under their parents.
b6825278356f1c9ddb8765d2f2b1d4fb62be1dbdsjelinekzfs_sort(const void *larg, const void *rarg, void *data)
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock * We group the checks below the generic code. If 'lstr' and
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock * 'rstr' are non-NULL, then we do a string based comparison.
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock * Otherwise, we compare 'lnum' and 'rnum'.
0d8fa8f8eba3ea46bc79d73445009505d1dd5d7dMartin Matuska (void) strlcpy(lbuf, zfs_get_name(l), sizeof (lbuf));
0d8fa8f8eba3ea46bc79d73445009505d1dd5d7dMartin Matuska (void) strlcpy(rbuf, zfs_get_name(r), sizeof (rbuf));
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock return (1);
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock return (-1);
b6825278356f1c9ddb8765d2f2b1d4fb62be1dbdsjelinek if (ret != 0) {
d5b5bb256c576fe5ef26e0795bd40abe77f93246Rich Morriszfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
ae1726b6ae69a6882b0d520f4bc3433f501f2065Chris Gerhard zfs_sort_column_t *sortcol, zprop_list_t **proplist, int limit,
fa9e4066f08beec538e775443c5be79dd423fcabahrens avl_pool = uu_avl_pool_create("zfs_pool", sizeof (zfs_node_t),
b6825278356f1c9ddb8765d2f2b1d4fb62be1dbdsjelinek offsetof(zfs_node_t, zn_avlnode), zfs_sort, UU_DEFAULT);
842727c2f41f01b380de4f5e787d905702870f23Chris Kirby * If cb_proplist is provided then in the zfs_handles created we
2e5e9e19867a0d75685f5beb2fe1b0e31491d49bSanjeev Bagewadi * retain only those properties listed in cb_proplist and sortcol.
2e5e9e19867a0d75685f5beb2fe1b0e31491d49bSanjeev Bagewadi * The rest are pruned. So, the caller should make sure that no other
2e5e9e19867a0d75685f5beb2fe1b0e31491d49bSanjeev Bagewadi * properties other than those listed in cb_proplist/sortcol are
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens * If cb_proplist is NULL then we retain all the properties. We
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens * always retain the zoned property, which some other properties
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens * need (userquota & friends), and the createtxg property, which
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens * we need to sort snapshots.
2e5e9e19867a0d75685f5beb2fe1b0e31491d49bSanjeev Bagewadi cb.cb_props_table[sortcol->sc_prop] = B_TRUE;
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens cb.cb_props_table[ZFS_PROP_CREATETXG] = B_TRUE;
a8b6ddaf31808c845e00161dda0a3d1fe31ae281Mark J Musante if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (argc == 0) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If given no arguments, iterate over all datasets.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If we're recursive, then we always allow filesystems as
fa9e4066f08beec538e775443c5be79dd423fcabahrens * arguments. If we also are interested in snapshots, then we
fa9e4066f08beec538e775443c5be79dd423fcabahrens * can take volumes as well.
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < argc; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * At this point we've got our AVL tree full of zfs handles, so iterate
fa9e4066f08beec538e775443c5be79dd423fcabahrens * over each one and execute the real user callback.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Finally, clean up the AVL tree.