usr/src/cmd/zfs/zfs_iter.c
author eschrock
Tue, 05 Sep 2006 11:37:36 -0700
changeset 2676 5cee47eddab6
parent 2379 0ff8239b1e93
child 3635 63e2169c1249
permissions -rw-r--r--
PSARC 2006/486 ZFS canmount property PSARC 2006/497 ZFS create time properties PSARC 2006/502 ZFS get all datasets PSARC 2006/504 ZFS user properties 6269805 properties should be set via an nvlist. 6281585 user defined properties 6349494 'zfs list' output annoying for even moderately long dataset names 6366244 'canmount' option for container-like functionality 6367103 create-time properties 6416639 RFE: provide zfs get -a 6437808 ZFS module version should match on-disk version 6454551 'zfs create -b blocksize filesystem' should fail. 6457478 unrecognized character in error message with 'zpool create -R' command 6457865 missing device name in the error message of 'zpool clear' command 6458571 zfs_ioc_set_prop() doesn't validate input 6458614 zfs ACL #defines should use prefix 6458638 get_configs() accesses bogus memory 6458678 zvol functions should be moved out of zfs_ioctl.h 6458683 zfs_cmd_t could use more cleanup 6458691 common routines to manage zfs_cmd_t nvlists 6460398 zpool import cores on zfs_prop_get 6461029 zpool status -x noexisting-pool has incorrect error message. 6461223 index translations should live with property definitions 6461424 zpool_unmount_datasets() has some busted logic 6461427 zfs_realloc() would be useful 6461757 'zpool status' can report the wrong number of persistent errors 6461784 recursive zfs_snapshot() leaks memory
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1356
diff changeset
     5
 * Common Development and Distribution License (the "License").
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1356
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
/*
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 789
diff changeset
    22
 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
#include <libintl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <libuutil.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <stddef.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <stdio.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <stdlib.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <strings.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#include <libzfs.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
#include "zfs_util.h"
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
    38
#include "zfs_iter.h"
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
 * This is a private interface used to gather up all the datasets specified on
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
 * the command line so that we can iterate over them in order.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
 * First, we iterate over all filesystems, gathering them together into an
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
    45
 * AVL tree.  We report errors for any explicitly specified datasets
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
 * that we couldn't open.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
 * When finished, we have an AVL tree of ZFS handles.  We go through and execute
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
 * the provided callback for each one, passing whatever data the user supplied.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
typedef struct zfs_node {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
	zfs_handle_t	*zn_handle;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
	uu_avl_node_t	zn_avlnode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
} zfs_node_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
typedef struct callback_data {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
	uu_avl_t	*cb_avl;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
	int		cb_recurse;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
	zfs_type_t	cb_types;
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
    61
	zfs_sort_column_t *cb_sortcol;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
    62
	zfs_proplist_t	**cb_proplist;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
} callback_data_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
uu_avl_pool_t *avl_pool;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
 * Called for each dataset.  If the object the object is of an appropriate type,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
 * add it to the avl tree and recurse over any children as necessary.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
zfs_callback(zfs_handle_t *zhp, void *data)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
	callback_data_t *cb = data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
	int dontclose = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
	 * If this object is of the appropriate type, add it to the AVL tree.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
	if (zfs_get_type(zhp) & cb->cb_types) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
		uu_avl_index_t idx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
		zfs_node_t *node = safe_malloc(sizeof (zfs_node_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
		node->zn_handle = zhp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
		uu_avl_node_init(node, &node->zn_avlnode, avl_pool);
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
    86
		if (uu_avl_find(cb->cb_avl, node, cb->cb_sortcol,
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
    87
		    &idx) == NULL) {
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
    88
			if (cb->cb_proplist &&
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
    89
			    zfs_expand_proplist(zhp, cb->cb_proplist) != 0) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
    90
				free(node);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
    91
				return (-1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
    92
			}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
			uu_avl_insert(cb->cb_avl, node, idx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
			dontclose = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
			free(node);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
	/*
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 789
diff changeset
   101
	 * Recurse if necessary.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
	if (cb->cb_recurse && (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM ||
1356
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 789
diff changeset
   104
	    (zfs_get_type(zhp) == ZFS_TYPE_VOLUME && (cb->cb_types &
e021b5e4aa0e 6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents: 789
diff changeset
   105
	    ZFS_TYPE_SNAPSHOT))))
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
		(void) zfs_iter_children(zhp, zfs_callback, data);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
	if (!dontclose)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
		zfs_close(zhp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   114
int
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   115
zfs_add_sort_column(zfs_sort_column_t **sc, const char *name,
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   116
    boolean_t reverse)
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   117
{
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   118
	zfs_sort_column_t *col;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   119
	zfs_prop_t prop;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   120
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   121
	if ((prop = zfs_name_to_prop(name)) == ZFS_PROP_INVAL &&
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   122
	    !zfs_prop_user(name))
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   123
		return (-1);
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   124
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   125
	col = safe_malloc(sizeof (zfs_sort_column_t));
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   126
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   127
	col->sc_prop = prop;
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   128
	col->sc_reverse = reverse;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   129
	if (prop == ZFS_PROP_INVAL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   130
		col->sc_user_prop = safe_malloc(strlen(name) + 1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   131
		(void) strcpy(col->sc_user_prop, name);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   132
	}
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   133
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   134
	if (*sc == NULL) {
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   135
		col->sc_last = col;
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   136
		*sc = col;
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   137
	} else {
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   138
		(*sc)->sc_last->sc_next = col;
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   139
		(*sc)->sc_last = col;
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   140
	}
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   141
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   142
	return (0);
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   143
}
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   144
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   145
void
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   146
zfs_free_sort_columns(zfs_sort_column_t *sc)
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   147
{
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   148
	zfs_sort_column_t *col;
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   149
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   150
	while (sc != NULL) {
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   151
		col = sc->sc_next;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   152
		free(sc->sc_user_prop);
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   153
		free(sc);
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   154
		sc = col;
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   155
	}
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   156
}
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   157
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
zfs_compare(const void *larg, const void *rarg, void *unused)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
	zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
	zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
	const char *lname = zfs_get_name(l);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
	const char *rname = zfs_get_name(r);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
	char *lat, *rat;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
	uint64_t lcreate, rcreate;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
	int ret;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
	lat = (char *)strchr(lname, '@');
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   171
	rat = (char *)strchr(rname, '@');
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
	if (lat != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
		*lat = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
	if (rat != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
		*rat = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
	ret = strcmp(lname, rname);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
	if (ret == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
		 * If we're comparing a dataset to one of its snapshots, we
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
		 * always make the full dataset first.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
		if (lat == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
			ret = -1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
		} else if (rat == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
			ret = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
		} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
			 * If we have two snapshots from the same dataset, then
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
			 * we want to sort them according to creation time.  We
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
			 * use the hidden CREATETXG property to get an absolute
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
			 * ordering of snapshots.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
			lcreate = zfs_prop_get_int(l, ZFS_PROP_CREATETXG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
			rcreate = zfs_prop_get_int(r, ZFS_PROP_CREATETXG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
			if (lcreate < rcreate)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
				ret = -1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
			else if (lcreate > rcreate)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
				ret = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
	if (lat != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
		*lat = '@';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
	if (rat != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
		*rat = '@';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
	return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   213
/*
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   214
 * Sort datasets by specified columns.
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   215
 *
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   216
 * o  Numeric types sort in ascending order.
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   217
 * o  String types sort in alphabetical order.
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   218
 * o  Types inappropriate for a row sort that row to the literal
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   219
 *    bottom, regardless of the specified ordering.
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   220
 *
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   221
 * If no sort columns are specified, or two datasets compare equally
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   222
 * across all specified columns, they are sorted alphabetically by name
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   223
 * with snapshots grouped under their parents.
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   224
 */
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   225
static int
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   226
zfs_sort(const void *larg, const void *rarg, void *data)
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   227
{
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   228
	zfs_handle_t *l = ((zfs_node_t *)larg)->zn_handle;
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   229
	zfs_handle_t *r = ((zfs_node_t *)rarg)->zn_handle;
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   230
	zfs_sort_column_t *sc = (zfs_sort_column_t *)data;
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   231
	zfs_sort_column_t *psc;
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   232
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   233
	for (psc = sc; psc != NULL; psc = psc->sc_next) {
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   234
		char lbuf[ZFS_MAXPROPLEN], rbuf[ZFS_MAXPROPLEN];
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   235
		char *lstr, *rstr;
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   236
		uint64_t lnum, rnum;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   237
		boolean_t lvalid, rvalid;
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   238
		int ret = 0;
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   239
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   240
		/*
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   241
		 * We group the checks below the generic code.  If 'lstr' and
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   242
		 * 'rstr' are non-NULL, then we do a string based comparison.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   243
		 * Otherwise, we compare 'lnum' and 'rnum'.
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   244
		 */
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   245
		lstr = rstr = NULL;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   246
		if (psc->sc_prop == ZFS_PROP_INVAL) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   247
			nvlist_t *luser, *ruser;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   248
			nvlist_t *lval, *rval;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   249
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   250
			luser = zfs_get_user_props(l);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   251
			ruser = zfs_get_user_props(r);
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   252
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   253
			lvalid = (nvlist_lookup_nvlist(luser,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   254
			    psc->sc_user_prop, &lval) == 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   255
			rvalid = (nvlist_lookup_nvlist(ruser,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   256
			    psc->sc_user_prop, &rval) == 0);
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   257
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   258
			if (lvalid)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   259
				verify(nvlist_lookup_string(lval,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   260
				    ZFS_PROP_VALUE, &lstr) == 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   261
			if (rvalid)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   262
				verify(nvlist_lookup_string(rval,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   263
				    ZFS_PROP_VALUE, &rstr) == 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   264
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   265
		} else if (zfs_prop_is_string(psc->sc_prop)) {
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   266
			lvalid = (zfs_prop_get(l, psc->sc_prop, lbuf,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   267
			    sizeof (lbuf), NULL, NULL, 0, B_TRUE) == 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   268
			rvalid = (zfs_prop_get(r, psc->sc_prop, rbuf,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   269
			    sizeof (rbuf), NULL, NULL, 0, B_TRUE) == 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   270
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   271
			lstr = lbuf;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   272
			rstr = rbuf;
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   273
		} else {
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   274
			lvalid = zfs_prop_valid_for_type(psc->sc_prop,
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   275
			    zfs_get_type(l));
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   276
			rvalid = zfs_prop_valid_for_type(psc->sc_prop,
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   277
			    zfs_get_type(r));
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   278
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   279
			if (lvalid)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   280
				(void) zfs_prop_get_numeric(l, psc->sc_prop,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   281
				    &lnum, NULL, NULL, 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   282
			if (rvalid)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   283
				(void) zfs_prop_get_numeric(r, psc->sc_prop,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   284
				    &rnum, NULL, NULL, 0);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   285
		}
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   286
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   287
		if (!lvalid && !rvalid)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   288
			continue;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   289
		else if (!lvalid)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   290
			return (1);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   291
		else if (!rvalid)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   292
			return (-1);
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   293
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   294
		if (lstr)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   295
			ret = strcmp(lstr, rstr);
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   296
		if (lnum < rnum)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   297
			ret = -1;
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   298
		else if (lnum > rnum)
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   299
			ret = 1;
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   300
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   301
		if (ret != 0) {
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   302
			if (psc->sc_reverse == B_TRUE)
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   303
				ret = (ret < 0) ? 1 : -1;
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   304
			return (ret);
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   305
		}
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   306
	}
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   307
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   308
	return (zfs_compare(larg, rarg, NULL));
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   309
}
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   310
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
int
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1356
diff changeset
   312
zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   313
    zfs_sort_column_t *sortcol, zfs_proplist_t **proplist, zfs_iter_f callback,
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   314
    void *data)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
	callback_data_t cb;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
	int ret = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
	zfs_node_t *node;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
	uu_avl_walk_t *walk;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
	avl_pool = uu_avl_pool_create("zfs_pool", sizeof (zfs_node_t),
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   322
	    offsetof(zfs_node_t, zn_avlnode), zfs_sort, UU_DEFAULT);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
	if (avl_pool == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
		(void) fprintf(stderr,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
		    gettext("internal error: out of memory\n"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
		exit(1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
2379
0ff8239b1e93 PSARC 2006/308 zfs list sort option
sjelinek
parents: 2082
diff changeset
   330
	cb.cb_sortcol = sortcol;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
	cb.cb_recurse = recurse;
2676
5cee47eddab6 PSARC 2006/486 ZFS canmount property
eschrock
parents: 2379
diff changeset
   332
	cb.cb_proplist = proplist;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
	cb.cb_types = types;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
	if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
		(void) fprintf(stderr,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
		    gettext("internal error: out of memory\n"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
		exit(1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
	if (argc == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
		 * If given no arguments, iterate over all datasets.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
		cb.cb_recurse = 1;
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1356
diff changeset
   345
		ret = zfs_iter_root(g_zfs, zfs_callback, &cb);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
		int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
		zfs_handle_t *zhp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
		zfs_type_t argtype;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
		 * If we're recursive, then we always allow filesystems as
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
		 * arguments.  If we also are interested in snapshots, then we
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
		 * can take volumes as well.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
		argtype = types;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
		if (recurse) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
			argtype |= ZFS_TYPE_FILESYSTEM;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
			if (types & ZFS_TYPE_SNAPSHOT)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
				argtype |= ZFS_TYPE_VOLUME;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   363
		for (i = 0; i < argc; i++) {
2082
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1356
diff changeset
   364
			if ((zhp = zfs_open(g_zfs, argv[i], argtype)) != NULL)
76b439ec3ac1 PSARC 2006/223 ZFS Hot Spares
eschrock
parents: 1356
diff changeset
   365
				ret |= zfs_callback(zhp, &cb);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   366
			else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   367
				ret = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   368
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   369
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
	 * At this point we've got our AVL tree full of zfs handles, so iterate
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
	 * over each one and execute the real user callback.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
	for (node = uu_avl_first(cb.cb_avl); node != NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   376
	    node = uu_avl_next(cb.cb_avl, node))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
		ret |= callback(node->zn_handle, data);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   379
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
	 * Finally, clean up the AVL tree.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   382
	if ((walk = uu_avl_walk_start(cb.cb_avl, UU_WALK_ROBUST)) == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
		(void) fprintf(stderr,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   384
		    gettext("internal error: out of memory"));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
		exit(1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   386
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   387
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   388
	while ((node = uu_avl_walk_next(walk)) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   389
		uu_avl_remove(cb.cb_avl, node);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   390
		zfs_close(node->zn_handle);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
		free(node);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   392
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
	uu_avl_walk_end(walk);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
	uu_avl_destroy(cb.cb_avl);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
	uu_avl_pool_destroy(avl_pool);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
	return (ret);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
}