summaryrefslogtreecommitdiff
path: root/usr/src/cmd/zfs/zfs_iter.c
diff options
context:
space:
mode:
authoreschrock <none@none>2006-09-05 11:37:36 -0700
committereschrock <none@none>2006-09-05 11:37:36 -0700
commite9dbad6f263d5570ed7ff5443ec5b958af8c24d7 (patch)
tree7bd6d85273a4462fc4699aa9ed69e33bd69e2613 /usr/src/cmd/zfs/zfs_iter.c
parentf724721be86f2d808bc08cd6be299acc214e3dc5 (diff)
downloadillumos-joyent-e9dbad6f263d5570ed7ff5443ec5b958af8c24d7.tar.gz
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
Diffstat (limited to 'usr/src/cmd/zfs/zfs_iter.c')
-rw-r--r--usr/src/cmd/zfs/zfs_iter.c113
1 files changed, 78 insertions, 35 deletions
diff --git a/usr/src/cmd/zfs/zfs_iter.c b/usr/src/cmd/zfs/zfs_iter.c
index 814a165393..c2d4260d8f 100644
--- a/usr/src/cmd/zfs/zfs_iter.c
+++ b/usr/src/cmd/zfs/zfs_iter.c
@@ -59,6 +59,7 @@ typedef struct callback_data {
int cb_recurse;
zfs_type_t cb_types;
zfs_sort_column_t *cb_sortcol;
+ zfs_proplist_t **cb_proplist;
} callback_data_t;
uu_avl_pool_t *avl_pool;
@@ -84,6 +85,11 @@ zfs_callback(zfs_handle_t *zhp, void *data)
uu_avl_node_init(node, &node->zn_avlnode, avl_pool);
if (uu_avl_find(cb->cb_avl, node, cb->cb_sortcol,
&idx) == NULL) {
+ if (cb->cb_proplist &&
+ zfs_expand_proplist(zhp, cb->cb_proplist) != 0) {
+ free(node);
+ return (-1);
+ }
uu_avl_insert(cb->cb_avl, node, idx);
dontclose = 1;
} else {
@@ -105,17 +111,25 @@ zfs_callback(zfs_handle_t *zhp, void *data)
return (0);
}
-void
-zfs_add_sort_column(zfs_sort_column_t **sc, zfs_prop_t prop,
+int
+zfs_add_sort_column(zfs_sort_column_t **sc, const char *name,
boolean_t reverse)
{
zfs_sort_column_t *col;
+ zfs_prop_t prop;
+
+ if ((prop = zfs_name_to_prop(name)) == ZFS_PROP_INVAL &&
+ !zfs_prop_user(name))
+ return (-1);
col = safe_malloc(sizeof (zfs_sort_column_t));
col->sc_prop = prop;
col->sc_reverse = reverse;
- col->sc_next = NULL;
+ if (prop == ZFS_PROP_INVAL) {
+ col->sc_user_prop = safe_malloc(strlen(name) + 1);
+ (void) strcpy(col->sc_user_prop, name);
+ }
if (*sc == NULL) {
col->sc_last = col;
@@ -124,6 +138,8 @@ zfs_add_sort_column(zfs_sort_column_t **sc, zfs_prop_t prop,
(*sc)->sc_last->sc_next = col;
(*sc)->sc_last = col;
}
+
+ return (0);
}
void
@@ -133,6 +149,7 @@ zfs_free_sort_columns(zfs_sort_column_t *sc)
while (sc != NULL) {
col = sc->sc_next;
+ free(sc->sc_user_prop);
free(sc);
sc = col;
}
@@ -214,48 +231,72 @@ zfs_sort(const void *larg, const void *rarg, void *data)
zfs_sort_column_t *psc;
for (psc = sc; psc != NULL; psc = psc->sc_next) {
- char lstr[ZFS_MAXPROPLEN], rstr[ZFS_MAXPROPLEN];
+ char lbuf[ZFS_MAXPROPLEN], rbuf[ZFS_MAXPROPLEN];
+ char *lstr, *rstr;
uint64_t lnum, rnum;
- int lvalid, rvalid;
+ boolean_t lvalid, rvalid;
int ret = 0;
- if (zfs_prop_is_string(psc->sc_prop)) {
- lvalid = zfs_prop_get(l, psc->sc_prop, lstr,
- sizeof (lstr), NULL, NULL, 0, B_TRUE);
- rvalid = zfs_prop_get(r, psc->sc_prop, rstr,
- sizeof (rstr), NULL, NULL, 0, B_TRUE);
-
- if ((lvalid == -1) && (rvalid == -1))
- continue;
- if (lvalid == -1)
- return (1);
- else if (rvalid == -1)
- return (-1);
-
- ret = strcmp(lstr, rstr);
+ /*
+ * We group the checks below the generic code. If 'lstr' and
+ * 'rstr' are non-NULL, then we do a string based comparison.
+ * Otherwise, we compare 'lnum' and 'rnum'.
+ */
+ lstr = rstr = NULL;
+ if (psc->sc_prop == ZFS_PROP_INVAL) {
+ nvlist_t *luser, *ruser;
+ nvlist_t *lval, *rval;
+
+ luser = zfs_get_user_props(l);
+ ruser = zfs_get_user_props(r);
+
+ lvalid = (nvlist_lookup_nvlist(luser,
+ psc->sc_user_prop, &lval) == 0);
+ rvalid = (nvlist_lookup_nvlist(ruser,
+ psc->sc_user_prop, &rval) == 0);
+
+ if (lvalid)
+ verify(nvlist_lookup_string(lval,
+ ZFS_PROP_VALUE, &lstr) == 0);
+ if (rvalid)
+ verify(nvlist_lookup_string(rval,
+ ZFS_PROP_VALUE, &rstr) == 0);
+
+ } else if (zfs_prop_is_string(psc->sc_prop)) {
+ lvalid = (zfs_prop_get(l, psc->sc_prop, lbuf,
+ sizeof (lbuf), NULL, NULL, 0, B_TRUE) == 0);
+ rvalid = (zfs_prop_get(r, psc->sc_prop, rbuf,
+ sizeof (rbuf), NULL, NULL, 0, B_TRUE) == 0);
+
+ lstr = lbuf;
+ rstr = rbuf;
} else {
lvalid = zfs_prop_valid_for_type(psc->sc_prop,
zfs_get_type(l));
rvalid = zfs_prop_valid_for_type(psc->sc_prop,
zfs_get_type(r));
- if (!lvalid && !rvalid)
- continue;
- else if (!lvalid)
- return (1);
- else if (!rvalid)
- return (-1);
+ if (lvalid)
+ (void) zfs_prop_get_numeric(l, psc->sc_prop,
+ &lnum, NULL, NULL, 0);
+ if (rvalid)
+ (void) zfs_prop_get_numeric(r, psc->sc_prop,
+ &rnum, NULL, NULL, 0);
+ }
- (void) zfs_prop_get_numeric(l, psc->sc_prop, &lnum,
- NULL, NULL, 0);
- (void) zfs_prop_get_numeric(r, psc->sc_prop, &rnum,
- NULL, NULL, 0);
+ if (!lvalid && !rvalid)
+ continue;
+ else if (!lvalid)
+ return (1);
+ else if (!rvalid)
+ return (-1);
- if (lnum < rnum)
- ret = -1;
- else if (lnum > rnum)
- ret = 1;
- }
+ if (lstr)
+ ret = strcmp(lstr, rstr);
+ if (lnum < rnum)
+ ret = -1;
+ else if (lnum > rnum)
+ ret = 1;
if (ret != 0) {
if (psc->sc_reverse == B_TRUE)
@@ -269,7 +310,8 @@ zfs_sort(const void *larg, const void *rarg, void *data)
int
zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
- zfs_sort_column_t *sortcol, zfs_iter_f callback, void *data)
+ zfs_sort_column_t *sortcol, zfs_proplist_t **proplist, zfs_iter_f callback,
+ void *data)
{
callback_data_t cb;
int ret = 0;
@@ -287,6 +329,7 @@ zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
cb.cb_sortcol = sortcol;
cb.cb_recurse = recurse;
+ cb.cb_proplist = proplist;
cb.cb_types = types;
if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL) {
(void) fprintf(stderr,