diff options
author | Adam Stevko <[email protected]> | 2016-05-09 14:03:18 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2016-05-11 11:49:37 -0700 |
commit | 2a8b84b747cb27a175aa3a45b8cdb293cde31886 (patch) | |
tree | 36698cee9684d649e0073c9d31efcdc6aef24e7d | |
parent | f00828e5d94d4ee386d362aee4e1b37900b1322c (diff) |
OpenZFS 3993, 4700
3993 zpool(1M) and zfs(1M) should support -p for "list" and "get"
4700 "zpool get" doesn't support -H or -o options
Reviewed by: Dan McDonald <[email protected]>
Reviewed by: Matthew Ahrens <[email protected]>
Approved by: Robert Mustacchi <[email protected]>
Ported by: Tony Hutter <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
OpenZFS-issue: https://www.illumos.org/issues/3993
OpenZFS-issue: https://www.illumos.org/issues/4700
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/c58b352
Porting notes:
I removed ZoL's zpool_get_prop_literal() in favor of
zpool_get_prop(..., boolean_t literal) since that's what OpenZFS
uses. The functionality is the same.
-rw-r--r-- | cmd/zpool/zpool_main.c | 111 | ||||
-rw-r--r-- | include/libzfs.h | 2 | ||||
-rw-r--r-- | lib/libzfs/libzfs_dataset.c | 4 | ||||
-rw-r--r-- | lib/libzfs/libzfs_pool.c | 29 | ||||
-rw-r--r-- | man/man8/zpool.8 | 43 |
5 files changed, 139 insertions, 50 deletions
diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index 50a332c6f..9c7e2a0c4 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -242,7 +242,7 @@ get_usage(zpool_help_t idx) { case HELP_LABELCLEAR: return (gettext("\tlabelclear [-f] <vdev>\n")); case HELP_LIST: - return (gettext("\tlist [-gHLPv] [-o property[,...]] " + return (gettext("\tlist [-gHLpPv] [-o property[,...]] " "[-T d|u] [pool] ... [interval [count]]\n")); case HELP_OFFLINE: return (gettext("\toffline [-t] <pool> <device> ...\n")); @@ -267,8 +267,8 @@ get_usage(zpool_help_t idx) { case HELP_EVENTS: return (gettext("\tevents [-vHfc]\n")); case HELP_GET: - return (gettext("\tget [-pH] <\"all\" | property[,...]> " - "<pool> ...\n")); + return (gettext("\tget [-Hp] [-o \"all\" | field[,...]] " + "<\"all\" | property[,...]> <pool> ...\n")); case HELP_SET: return (gettext("\tset <property=value> <pool> \n")); case HELP_SPLIT: @@ -3024,6 +3024,7 @@ typedef struct list_cbdata { int cb_namewidth; boolean_t cb_scripted; zprop_list_t *cb_proplist; + boolean_t cb_literal; } list_cbdata_t; /* @@ -3115,7 +3116,7 @@ print_pool(zpool_handle_t *zhp, list_cbdata_t *cb) right_justify = B_FALSE; if (pl->pl_prop != ZPROP_INVAL) { if (zpool_get_prop(zhp, pl->pl_prop, property, - sizeof (property), NULL) != 0) + sizeof (property), NULL, cb->cb_literal) != 0) propstr = "-"; else propstr = property; @@ -3325,7 +3326,7 @@ list_callback(zpool_handle_t *zhp, void *data) } /* - * zpool list [-gHLP] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]] + * zpool list [-gHLpP] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]] * * -g Display guid for individual vdev name. * -H Scripted mode. Don't display headers, and separate properties @@ -3334,6 +3335,7 @@ list_callback(zpool_handle_t *zhp, void *data) * -o List of properties to display. Defaults to * "name,size,allocated,free,expandsize,fragmentation,capacity," * "dedupratio,health,altroot" + * -p Display values in parsable (exact) format. * -P Display full path for vdev name. * -T Display a timestamp in date(1) or Unix format * @@ -3355,7 +3357,7 @@ zpool_do_list(int argc, char **argv) boolean_t first = B_TRUE; /* check options */ - while ((c = getopt(argc, argv, ":gHLo:PT:v")) != -1) { + while ((c = getopt(argc, argv, ":gHLo:pPT:v")) != -1) { switch (c) { case 'g': cb.cb_name_flags |= VDEV_NAME_GUID; @@ -3372,6 +3374,9 @@ zpool_do_list(int argc, char **argv) case 'P': cb.cb_name_flags |= VDEV_NAME_PATH; break; + case 'p': + cb.cb_literal = B_TRUE; + break; case 'T': get_timestamp_arg(*optarg); break; @@ -5886,7 +5891,7 @@ get_callback(zpool_handle_t *zhp, void *data) NULL, NULL); } } else { - if (zpool_get_prop_literal(zhp, pl->pl_prop, value, + if (zpool_get_prop(zhp, pl->pl_prop, value, sizeof (value), &srctype, cbp->cb_literal) != 0) continue; @@ -5898,24 +5903,99 @@ get_callback(zpool_handle_t *zhp, void *data) return (0); } +/* + * zpool get [-Hp] [-o "all" | field[,...]] <"all" | property[,...]> <pool> ... + * + * -H Scripted mode. Don't display headers, and separate properties + * by a single tab. + * -o List of columns to display. Defaults to + * "name,property,value,source". + * -p Diplay values in parsable (exact) format. + * + * Get properties of pools in the system. Output space statistics + * for each one as well as other attributes. + */ int zpool_do_get(int argc, char **argv) { zprop_get_cbdata_t cb = { 0 }; zprop_list_t fake_name = { 0 }; - int c, ret; + int ret; + int c, i; + char *value; + + cb.cb_first = B_TRUE; + + /* + * Set up default columns and sources. + */ + cb.cb_sources = ZPROP_SRC_ALL; + cb.cb_columns[0] = GET_COL_NAME; + cb.cb_columns[1] = GET_COL_PROPERTY; + cb.cb_columns[2] = GET_COL_VALUE; + cb.cb_columns[3] = GET_COL_SOURCE; + cb.cb_type = ZFS_TYPE_POOL; /* check options */ - while ((c = getopt(argc, argv, "pH")) != -1) { + while ((c = getopt(argc, argv, ":Hpo:")) != -1) { switch (c) { case 'p': cb.cb_literal = B_TRUE; break; - case 'H': cb.cb_scripted = B_TRUE; break; + case 'o': + bzero(&cb.cb_columns, sizeof (cb.cb_columns)); + i = 0; + while (*optarg != '\0') { + static char *col_subopts[] = + { "name", "property", "value", "source", + "all", NULL }; + + if (i == ZFS_GET_NCOLS) { + (void) fprintf(stderr, gettext("too " + "many fields given to -o " + "option\n")); + usage(B_FALSE); + } + switch (getsubopt(&optarg, col_subopts, + &value)) { + case 0: + cb.cb_columns[i++] = GET_COL_NAME; + break; + case 1: + cb.cb_columns[i++] = GET_COL_PROPERTY; + break; + case 2: + cb.cb_columns[i++] = GET_COL_VALUE; + break; + case 3: + cb.cb_columns[i++] = GET_COL_SOURCE; + break; + case 4: + if (i > 0) { + (void) fprintf(stderr, + gettext("\"all\" conflicts " + "with specific fields " + "given to -o option\n")); + usage(B_FALSE); + } + cb.cb_columns[0] = GET_COL_NAME; + cb.cb_columns[1] = GET_COL_PROPERTY; + cb.cb_columns[2] = GET_COL_VALUE; + cb.cb_columns[3] = GET_COL_SOURCE; + i = ZFS_GET_NCOLS; + break; + default: + (void) fprintf(stderr, + gettext("invalid column name " + "'%s'\n"), value); + usage(B_FALSE); + } + } + break; case '?': (void) fprintf(stderr, gettext("invalid option '%c'\n"), optopt); @@ -5932,15 +6012,8 @@ zpool_do_get(int argc, char **argv) usage(B_FALSE); } - cb.cb_first = B_TRUE; - cb.cb_sources = ZPROP_SRC_ALL; - cb.cb_columns[0] = GET_COL_NAME; - cb.cb_columns[1] = GET_COL_PROPERTY; - cb.cb_columns[2] = GET_COL_VALUE; - cb.cb_columns[3] = GET_COL_SOURCE; - cb.cb_type = ZFS_TYPE_POOL; - - if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist, ZFS_TYPE_POOL) != 0) + if (zprop_get_list(g_zfs, argv[0], &cb.cb_proplist, + ZFS_TYPE_POOL) != 0) usage(B_FALSE); argc--; diff --git a/include/libzfs.h b/include/libzfs.h index 4b3fab83f..3faee0add 100644 --- a/include/libzfs.h +++ b/include/libzfs.h @@ -287,8 +287,6 @@ extern int zpool_label_disk(libzfs_handle_t *, zpool_handle_t *, char *); */ extern int zpool_set_prop(zpool_handle_t *, const char *, const char *); extern int zpool_get_prop(zpool_handle_t *, zpool_prop_t, char *, - size_t proplen, zprop_source_t *); -extern int zpool_get_prop_literal(zpool_handle_t *, zpool_prop_t, char *, size_t proplen, zprop_source_t *, boolean_t literal); extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t, zprop_source_t *); diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index 3586c0e5e..cc26927eb 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -2372,8 +2372,8 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, } if ((zpool_get_prop(zhp->zpool_hdl, - ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL)) || - (strcmp(root, "-") == 0)) + ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL, + B_FALSE)) || (strcmp(root, "-") == 0)) root[0] = '\0'; /* * Special case an alternate root of '/'. This will diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c index 80ed010c1..8cacc01dd 100644 --- a/lib/libzfs/libzfs_pool.c +++ b/lib/libzfs/libzfs_pool.c @@ -236,21 +236,11 @@ zpool_pool_state_to_name(pool_state_t state) } /* - * API compatibility wrapper around zpool_get_prop_literal - */ -int -zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len, - zprop_source_t *srctype) -{ - return (zpool_get_prop_literal(zhp, prop, buf, len, srctype, B_FALSE)); -} - -/* * Get a zpool property value for 'prop' and return the value in * a pre-allocated buffer. */ int -zpool_get_prop_literal(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, +zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len, zprop_source_t *srctype, boolean_t literal) { uint64_t intval; @@ -283,9 +273,7 @@ zpool_get_prop_literal(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, (void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src), len); - if (srctype != NULL) - *srctype = src; - return (0); + break; } /* FALLTHROUGH */ default: @@ -337,8 +325,13 @@ zpool_get_prop_literal(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, break; case ZPOOL_PROP_CAPACITY: - (void) snprintf(buf, len, "%llu%%", - (u_longlong_t)intval); + if (literal) { + (void) snprintf(buf, len, "%llu", + (u_longlong_t)intval); + } else { + (void) snprintf(buf, len, "%llu%%", + (u_longlong_t)intval); + } break; case ZPOOL_PROP_FRAGMENTATION: @@ -443,7 +436,7 @@ zpool_is_bootable(zpool_handle_t *zhp) char bootfs[ZPOOL_MAXNAMELEN]; return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs, - sizeof (bootfs), NULL) == 0 && strncmp(bootfs, "-", + sizeof (bootfs), NULL, B_FALSE) == 0 && strncmp(bootfs, "-", sizeof (bootfs)) != 0); } @@ -873,7 +866,7 @@ zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp) if (entry->pl_prop != ZPROP_INVAL && zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf), - NULL) == 0) { + NULL, B_FALSE) == 0) { if (strlen(buf) > entry->pl_width) entry->pl_width = strlen(buf); } diff --git a/man/man8/zpool.8 b/man/man8/zpool.8 index 4a7a46bdd..bcbcaa249 100644 --- a/man/man8/zpool.8 +++ b/man/man8/zpool.8 @@ -67,7 +67,7 @@ zpool \- configures ZFS storage pools .LP .nf -\fBzpool get\fR [\fB-pH\fR] "\fIall\fR" | \fIproperty\fR[,...] \fIpool\fR ... +\fBzpool get\fR [\fB-Hp\fR] [\fB-o \fR\fIfield\fR[,...]] "\fIall\fR" | \fIproperty\fR[,...] \fIpool\fR ... .fi .LP @@ -105,7 +105,7 @@ zpool \- configures ZFS storage pools .LP .nf -\fBzpool list\fR [\fB-T\fR d | u ] [\fB-HgLPv\fR] [\fB-o\fR \fIproperty\fR[,...]] [\fIpool\fR] ... +\fBzpool list\fR [\fB-T\fR d | u ] [\fB-HgLpPv\fR] [\fB-o\fR \fIproperty\fR[,...]] [\fIpool\fR] ... [\fIinterval\fR[\fIcount\fR]] .fi @@ -1199,7 +1199,8 @@ This command will forcefully export the pool even if it has a shared spare that .ne 2 .mk .na -\fB\fBzpool get\fR [\fB-p\fR] "\fIall\fR" | \fIproperty\fR[,...] \fIpool\fR ...\fR +\fB\fBzpool get\fR [\fB-Hp\fR] [\fB-o \fR\fIfield\fR[,...]] "\fIall\fR" | \fIproperty\fR[,...] +\fIpool\fR ...\fR .ad .sp .6 .RS 4n @@ -1207,7 +1208,7 @@ Retrieves the given list of properties (or all properties if "\fBall\fR" is used .sp .in +2 .nf - name Name of storage pool + name Name of storage pool property Property name value Property value source Property source, either 'default' or 'local'. @@ -1216,28 +1217,40 @@ Retrieves the given list of properties (or all properties if "\fBall\fR" is used .sp See the "Properties" section for more information on the available pool properties. + .sp .ne 2 .mk .na -\fB\fB-p\fR\fR +\fB\fB-H\fR\fR .ad .RS 6n .rt -Display numbers in parseable (exact) values. +Scripted mode. Do not display headers, and separate fields by a single tab instead of arbitrary space. .RE .sp .ne 2 .mk .na -\fB\fB-H\fR\fR +\fB\fB-p\fR\fR .ad .RS 6n .rt -Scripted mode. Do not display headers, and separate fields by a single tab instead of arbitrary space. +Display numbers in parseable (exact) values. .RE +.sp +.ne 2 +.mk +.na +\fB\fB-o\fR \fIfield\fR\fR +.ad +.RS 12n +.rt +A comma-separated list of columns to display. \fBname,property,value,source\fR +is the default value. +.RE .RE .sp @@ -1765,7 +1778,7 @@ Treat exported or foreign devices as inactive. .ne 2 .mk .na -\fB\fBzpool list\fR [\fB-T\fR \fBd\fR | \fBu\fR] [\fB-HgLPv\fR] [\fB-o\fR \fIprops\fR[,...]] [\fIpool\fR] ... [\fIinterval\fR[\fIcount\fR]]\fR +\fB\fBzpool list\fR [\fB-T\fR \fBd\fR | \fBu\fR] [\fB-HgLpPv\fR] [\fB-o\fR \fIprops\fR[,...]] [\fIpool\fR] ... [\fIinterval\fR[\fIcount\fR]]\fR .ad .sp .6 .RS 4n @@ -1807,6 +1820,17 @@ Display real paths for vdevs resolving all symbolic links. This can be used to l .ne 2 .mk .na +\fB\fB-p\fR\fR +.ad +.RS 12n +.rt +Display numbers in parsable (exact) values. +.RE + +.sp +.ne 2 +.mk +.na \fB\fB-P\fR\fR .ad .RS 12n @@ -1814,6 +1838,7 @@ Display real paths for vdevs resolving all symbolic links. This can be used to l Display full paths for vdevs instead of only the last component of the path. This can be used in conjunction with the \fB-L\fR flag. .RE +.sp .ne 2 .mk .na |