usr/src/cmd/zpool/zpool_main.c
changeset 12296 7cf402a7f374
parent 11935 538c866aaac6
child 12321 c2943f5c6eb9
equal deleted inserted replaced
12295:e16f396f04a1 12296:7cf402a7f374
    18  *
    18  *
    19  * CDDL HEADER END
    19  * CDDL HEADER END
    20  */
    20  */
    21 
    21 
    22 /*
    22 /*
    23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
    23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
    24  * Use is subject to license terms.
       
    25  */
    24  */
    26 
    25 
    27 #include <assert.h>
    26 #include <assert.h>
    28 #include <ctype.h>
    27 #include <ctype.h>
    29 #include <dirent.h>
    28 #include <dirent.h>
    40 #include <unistd.h>
    39 #include <unistd.h>
    41 #include <priv.h>
    40 #include <priv.h>
    42 #include <pwd.h>
    41 #include <pwd.h>
    43 #include <zone.h>
    42 #include <zone.h>
    44 #include <sys/fs/zfs.h>
    43 #include <sys/fs/zfs.h>
    45 
       
    46 #include <sys/stat.h>
    44 #include <sys/stat.h>
    47 
    45 
    48 #include <libzfs.h>
    46 #include <libzfs.h>
    49 
    47 
    50 #include "zpool_util.h"
    48 #include "zpool_util.h"
   213 	case HELP_IOSTAT:
   211 	case HELP_IOSTAT:
   214 		return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval "
   212 		return (gettext("\tiostat [-v] [-T d|u] [pool] ... [interval "
   215 		    "[count]]\n"));
   213 		    "[count]]\n"));
   216 	case HELP_LIST:
   214 	case HELP_LIST:
   217 		return (gettext("\tlist [-H] [-o property[,...]] "
   215 		return (gettext("\tlist [-H] [-o property[,...]] "
   218 		    "[pool] ...\n"));
   216 		    "[-T d|u] [pool] ... [interval [count]]\n"));
   219 	case HELP_OFFLINE:
   217 	case HELP_OFFLINE:
   220 		return (gettext("\toffline [-t] <pool> <device> ...\n"));
   218 		return (gettext("\toffline [-t] <pool> <device> ...\n"));
   221 	case HELP_ONLINE:
   219 	case HELP_ONLINE:
   222 		return (gettext("\tonline <pool> <device> ...\n"));
   220 		return (gettext("\tonline <pool> <device> ...\n"));
   223 	case HELP_REPLACE:
   221 	case HELP_REPLACE:
   226 	case HELP_REMOVE:
   224 	case HELP_REMOVE:
   227 		return (gettext("\tremove <pool> <device> ...\n"));
   225 		return (gettext("\tremove <pool> <device> ...\n"));
   228 	case HELP_SCRUB:
   226 	case HELP_SCRUB:
   229 		return (gettext("\tscrub [-s] <pool> ...\n"));
   227 		return (gettext("\tscrub [-s] <pool> ...\n"));
   230 	case HELP_STATUS:
   228 	case HELP_STATUS:
   231 		return (gettext("\tstatus [-vx] [pool] ...\n"));
   229 		return (gettext("\tstatus [-vx] [-T d|u] [pool] ... [interval "
       
   230 		    "[count]]\n"));
   232 	case HELP_UPGRADE:
   231 	case HELP_UPGRADE:
   233 		return (gettext("\tupgrade\n"
   232 		return (gettext("\tupgrade\n"
   234 		    "\tupgrade -v\n"
   233 		    "\tupgrade -v\n"
   235 		    "\tupgrade [-V version] <-a | pool ...>\n"));
   234 		    "\tupgrade [-V version] <-a | pool ...>\n"));
   236 	case HELP_GET:
   235 	case HELP_GET:
   517 
   516 
   518 	return (ret);
   517 	return (ret);
   519 }
   518 }
   520 
   519 
   521 /*
   520 /*
   522  * zpool remove <pool> <vdev> ...
   521  * zpool remove  <pool> <vdev> ...
   523  *
   522  *
   524  * Removes the given vdev from the pool.  Currently, this only supports removing
   523  * Removes the given vdev from the pool.  Currently, this supports removing
   525  * spares and cache devices from the pool.  Eventually, we'll want to support
   524  * spares, cache, and log devices from the pool.
   526  * removing leaf vdevs (as an alias for 'detach') as well as toplevel vdevs.
       
   527  */
   525  */
   528 int
   526 int
   529 zpool_do_remove(int argc, char **argv)
   527 zpool_do_remove(int argc, char **argv)
   530 {
   528 {
   531 	char *poolname;
   529 	char *poolname;
  1042 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
  1040 print_status_config(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
  1043     int namewidth, int depth, boolean_t isspare)
  1041     int namewidth, int depth, boolean_t isspare)
  1044 {
  1042 {
  1045 	nvlist_t **child;
  1043 	nvlist_t **child;
  1046 	uint_t c, children;
  1044 	uint_t c, children;
       
  1045 	pool_scan_stat_t *ps = NULL;
  1047 	vdev_stat_t *vs;
  1046 	vdev_stat_t *vs;
  1048 	char rbuf[6], wbuf[6], cbuf[6], repaired[7];
  1047 	char rbuf[6], wbuf[6], cbuf[6];
  1049 	char *vname;
  1048 	char *vname;
  1050 	uint64_t notpresent;
  1049 	uint64_t notpresent;
  1051 	spare_cbdata_t cb;
  1050 	spare_cbdata_t cb;
  1052 	char *state;
  1051 	char *state;
  1053 
  1052 
  1054 	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
       
  1055 	    (uint64_t **)&vs, &c) == 0);
       
  1056 
       
  1057 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
  1053 	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
  1058 	    &child, &children) != 0)
  1054 	    &child, &children) != 0)
  1059 		children = 0;
  1055 		children = 0;
       
  1056 
       
  1057 	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
       
  1058 	    (uint64_t **)&vs, &c) == 0);
  1060 
  1059 
  1061 	state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
  1060 	state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
  1062 	if (isspare) {
  1061 	if (isspare) {
  1063 		/*
  1062 		/*
  1064 		 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
  1063 		 * For hot spares, we use the terms 'INUSE' and 'AVAILABLE' for
  1145 
  1144 
  1146 		default:
  1145 		default:
  1147 			(void) printf(gettext("corrupted data"));
  1146 			(void) printf(gettext("corrupted data"));
  1148 			break;
  1147 			break;
  1149 		}
  1148 		}
  1150 	} else if (vs->vs_scrub_repaired != 0 && children == 0) {
  1149 	}
  1151 		/*
  1150 
  1152 		 * Report bytes resilvered/repaired on leaf devices.
  1151 	(void) nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_SCAN_STATS,
  1153 		 */
  1152 	    (uint64_t **)&ps, &c);
  1154 		zfs_nicenum(vs->vs_scrub_repaired, repaired, sizeof (repaired));
  1153 
  1155 		(void) printf(gettext("  %s %s"), repaired,
  1154 	if (ps && ps->pss_state == DSS_SCANNING &&
  1156 		    (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
  1155 	    vs->vs_scan_processed != 0 && children == 0) {
  1157 		    "resilvered" : "repaired");
  1156 		(void) printf(gettext("  (%s)"),
       
  1157 		    (ps->pss_func == POOL_SCAN_RESILVER) ?
       
  1158 		    "resilvering" : "repairing");
  1158 	}
  1159 	}
  1159 
  1160 
  1160 	(void) printf("\n");
  1161 	(void) printf("\n");
  1161 
  1162 
  1162 	for (c = 0; c < children; c++) {
  1163 	for (c = 0; c < children; c++) {
  1192 	verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
  1193 	verify(nvlist_lookup_string(nv, ZPOOL_CONFIG_TYPE, &type) == 0);
  1193 	if (strcmp(type, VDEV_TYPE_MISSING) == 0 ||
  1194 	if (strcmp(type, VDEV_TYPE_MISSING) == 0 ||
  1194 	    strcmp(type, VDEV_TYPE_HOLE) == 0)
  1195 	    strcmp(type, VDEV_TYPE_HOLE) == 0)
  1195 		return;
  1196 		return;
  1196 
  1197 
  1197 	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_STATS,
  1198 	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
  1198 	    (uint64_t **)&vs, &c) == 0);
  1199 	    (uint64_t **)&vs, &c) == 0);
  1199 
  1200 
  1200 	(void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
  1201 	(void) printf("\t%*s%-*s", depth, "", namewidth - depth, name);
  1201 	(void) printf("  %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
  1202 	(void) printf("  %s", zpool_state_to_name(vs->vs_state, vs->vs_aux));
  1202 
  1203 
  1331 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
  1332 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
  1332 	    &pool_state) == 0);
  1333 	    &pool_state) == 0);
  1333 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
  1334 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
  1334 	    &nvroot) == 0);
  1335 	    &nvroot) == 0);
  1335 
  1336 
  1336 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
  1337 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
  1337 	    (uint64_t **)&vs, &vsc) == 0);
  1338 	    (uint64_t **)&vs, &vsc) == 0);
  1338 	health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
  1339 	health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
  1339 
  1340 
  1340 	reason = zpool_import_status(config, &msgid);
  1341 	reason = zpool_import_status(config, &msgid);
  1341 
  1342 
  1396 		break;
  1397 		break;
  1397 
  1398 
  1398 	case ZPOOL_STATUS_BAD_LOG:
  1399 	case ZPOOL_STATUS_BAD_LOG:
  1399 		(void) printf(gettext("status: An intent log record cannot be "
  1400 		(void) printf(gettext("status: An intent log record cannot be "
  1400 		    "read.\n"));
  1401 		    "read.\n"));
       
  1402 		break;
       
  1403 
       
  1404 	case ZPOOL_STATUS_RESILVERING:
       
  1405 		(void) printf(gettext("status: One or more devices were being "
       
  1406 		    "resilvered.\n"));
  1401 		break;
  1407 		break;
  1402 
  1408 
  1403 	default:
  1409 	default:
  1404 		/*
  1410 		/*
  1405 		 * No other status can be seen when importing pools.
  1411 		 * No other status can be seen when importing pools.
  1988 	uint64_t tdelta;
  1994 	uint64_t tdelta;
  1989 	double scale;
  1995 	double scale;
  1990 	char *vname;
  1996 	char *vname;
  1991 
  1997 
  1992 	if (oldnv != NULL) {
  1998 	if (oldnv != NULL) {
  1993 		verify(nvlist_lookup_uint64_array(oldnv, ZPOOL_CONFIG_STATS,
  1999 		verify(nvlist_lookup_uint64_array(oldnv,
  1994 		    (uint64_t **)&oldvs, &c) == 0);
  2000 		    ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&oldvs, &c) == 0);
  1995 	} else {
  2001 	} else {
  1996 		oldvs = &zerovs;
  2002 		oldvs = &zerovs;
  1997 	}
  2003 	}
  1998 
  2004 
  1999 	verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_STATS,
  2005 	verify(nvlist_lookup_uint64_array(newnv, ZPOOL_CONFIG_VDEV_STATS,
  2000 	    (uint64_t **)&newvs, &c) == 0);
  2006 	    (uint64_t **)&newvs, &c) == 0);
  2001 
  2007 
  2002 	if (strlen(name) + depth > cb->cb_namewidth)
  2008 	if (strlen(name) + depth > cb->cb_namewidth)
  2003 		(void) printf("%*s%s", depth, "", name);
  2009 		(void) printf("%*s%s", depth, "", name);
  2004 	else
  2010 	else
  2044 	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
  2050 	if (oldnv && nvlist_lookup_nvlist_array(oldnv, ZPOOL_CONFIG_CHILDREN,
  2045 	    &oldchild, &c) != 0)
  2051 	    &oldchild, &c) != 0)
  2046 		return;
  2052 		return;
  2047 
  2053 
  2048 	for (c = 0; c < children; c++) {
  2054 	for (c = 0; c < children; c++) {
       
  2055 		uint64_t ishole = B_FALSE;
       
  2056 
       
  2057 		if (nvlist_lookup_uint64(newchild[c],
       
  2058 		    ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
       
  2059 			continue;
       
  2060 
  2049 		vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE);
  2061 		vname = zpool_vdev_name(g_zfs, zhp, newchild[c], B_FALSE);
  2050 		print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
  2062 		print_vdev_stats(zhp, vname, oldnv ? oldchild[c] : NULL,
  2051 		    newchild[c], cb, depth + 2);
  2063 		    newchild[c], cb, depth + 2);
  2052 		free(vname);
  2064 		free(vname);
  2053 	}
  2065 	}
  2155 
  2167 
  2156 	return (0);
  2168 	return (0);
  2157 }
  2169 }
  2158 
  2170 
  2159 /*
  2171 /*
  2160  * zpool iostat [-T d|u] [-v] [pool] ... [interval [count]]
  2172  * Parse the input string, get the 'interval' and 'count' value if there is one.
  2161  *
       
  2162  *	-T	Display a timestamp in date(1) or Unix format
       
  2163  *	-v	Display statistics for individual vdevs
       
  2164  *
       
  2165  * This command can be tricky because we want to be able to deal with pool
       
  2166  * creation/destruction as well as vdev configuration changes.  The bulk of this
       
  2167  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
       
  2168  * on pool_list_update() to detect the addition of new pools.  Configuration
       
  2169  * changes are all handled within libzfs.
       
  2170  */
  2173  */
  2171 int
  2174 static void
  2172 zpool_do_iostat(int argc, char **argv)
  2175 get_interval_count(int *argcp, char **argv, unsigned long *iv,
  2173 {
  2176     unsigned long *cnt)
  2174 	int c;
  2177 {
  2175 	int ret;
       
  2176 	int npools;
       
  2177 	unsigned long interval = 0, count = 0;
  2178 	unsigned long interval = 0, count = 0;
  2178 	zpool_list_t *list;
  2179 	int argc = *argcp, errno;
  2179 	boolean_t verbose = B_FALSE;
       
  2180 	iostat_cbdata_t cb;
       
  2181 
       
  2182 	/* check options */
       
  2183 	while ((c = getopt(argc, argv, "T:v")) != -1) {
       
  2184 		switch (c) {
       
  2185 		case 'T':
       
  2186 			if (optarg) {
       
  2187 				if (*optarg == 'u')
       
  2188 					timestamp_fmt = UDATE;
       
  2189 				else if (*optarg == 'd')
       
  2190 					timestamp_fmt = DDATE;
       
  2191 				else
       
  2192 					usage(B_FALSE);
       
  2193 			} else {
       
  2194 				usage(B_FALSE);
       
  2195 			}
       
  2196 			break;
       
  2197 		case 'v':
       
  2198 			verbose = B_TRUE;
       
  2199 			break;
       
  2200 		case '?':
       
  2201 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
       
  2202 			    optopt);
       
  2203 			usage(B_FALSE);
       
  2204 		}
       
  2205 	}
       
  2206 
       
  2207 	argc -= optind;
       
  2208 	argv += optind;
       
  2209 
  2180 
  2210 	/*
  2181 	/*
  2211 	 * Determine if the last argument is an integer or a pool name
  2182 	 * Determine if the last argument is an integer or a pool name
  2212 	 */
  2183 	 */
  2213 	if (argc > 0 && isdigit(argv[argc - 1][0])) {
  2184 	if (argc > 0 && isdigit(argv[argc - 1][0])) {
  2220 			if (interval == 0) {
  2191 			if (interval == 0) {
  2221 				(void) fprintf(stderr, gettext("interval "
  2192 				(void) fprintf(stderr, gettext("interval "
  2222 				    "cannot be zero\n"));
  2193 				    "cannot be zero\n"));
  2223 				usage(B_FALSE);
  2194 				usage(B_FALSE);
  2224 			}
  2195 			}
  2225 
       
  2226 			/*
  2196 			/*
  2227 			 * Ignore the last parameter
  2197 			 * Ignore the last parameter
  2228 			 */
  2198 			 */
  2229 			argc--;
  2199 			argc--;
  2230 		} else {
  2200 		} else {
  2237 		}
  2207 		}
  2238 	}
  2208 	}
  2239 
  2209 
  2240 	/*
  2210 	/*
  2241 	 * If the last argument is also an integer, then we have both a count
  2211 	 * If the last argument is also an integer, then we have both a count
  2242 	 * and an integer.
  2212 	 * and an interval.
  2243 	 */
  2213 	 */
  2244 	if (argc > 0 && isdigit(argv[argc - 1][0])) {
  2214 	if (argc > 0 && isdigit(argv[argc - 1][0])) {
  2245 		char *end;
  2215 		char *end;
  2246 
  2216 
  2247 		errno = 0;
  2217 		errno = 0;
  2261 			argc--;
  2231 			argc--;
  2262 		} else {
  2232 		} else {
  2263 			interval = 0;
  2233 			interval = 0;
  2264 		}
  2234 		}
  2265 	}
  2235 	}
       
  2236 
       
  2237 	*iv = interval;
       
  2238 	*cnt = count;
       
  2239 	*argcp = argc;
       
  2240 }
       
  2241 
       
  2242 static void
       
  2243 get_timestamp_arg(char c)
       
  2244 {
       
  2245 	if (c == 'u')
       
  2246 		timestamp_fmt = UDATE;
       
  2247 	else if (c == 'd')
       
  2248 		timestamp_fmt = DDATE;
       
  2249 	else
       
  2250 		usage(B_FALSE);
       
  2251 }
       
  2252 
       
  2253 /*
       
  2254  * zpool iostat [-v] [-T d|u] [pool] ... [interval [count]]
       
  2255  *
       
  2256  *	-v	Display statistics for individual vdevs
       
  2257  *	-T	Display a timestamp in date(1) or Unix format
       
  2258  *
       
  2259  * This command can be tricky because we want to be able to deal with pool
       
  2260  * creation/destruction as well as vdev configuration changes.  The bulk of this
       
  2261  * processing is handled by the pool_list_* routines in zpool_iter.c.  We rely
       
  2262  * on pool_list_update() to detect the addition of new pools.  Configuration
       
  2263  * changes are all handled within libzfs.
       
  2264  */
       
  2265 int
       
  2266 zpool_do_iostat(int argc, char **argv)
       
  2267 {
       
  2268 	int c;
       
  2269 	int ret;
       
  2270 	int npools;
       
  2271 	unsigned long interval = 0, count = 0;
       
  2272 	zpool_list_t *list;
       
  2273 	boolean_t verbose = B_FALSE;
       
  2274 	iostat_cbdata_t cb;
       
  2275 
       
  2276 	/* check options */
       
  2277 	while ((c = getopt(argc, argv, "T:v")) != -1) {
       
  2278 		switch (c) {
       
  2279 		case 'T':
       
  2280 			get_timestamp_arg(*optarg);
       
  2281 			break;
       
  2282 		case 'v':
       
  2283 			verbose = B_TRUE;
       
  2284 			break;
       
  2285 		case '?':
       
  2286 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
       
  2287 			    optopt);
       
  2288 			usage(B_FALSE);
       
  2289 		}
       
  2290 	}
       
  2291 
       
  2292 	argc -= optind;
       
  2293 	argv += optind;
       
  2294 
       
  2295 	get_interval_count(&argc, argv, &interval, &count);
  2266 
  2296 
  2267 	/*
  2297 	/*
  2268 	 * Construct the list of all interesting pools.
  2298 	 * Construct the list of all interesting pools.
  2269 	 */
  2299 	 */
  2270 	ret = 0;
  2300 	ret = 0;
  2462 
  2492 
  2463 	return (0);
  2493 	return (0);
  2464 }
  2494 }
  2465 
  2495 
  2466 /*
  2496 /*
  2467  * zpool list [-H] [-o prop[,prop]*] [pool] ...
  2497  * zpool list [-H] [-o prop[,prop]*] [-T d|u] [pool] ... [interval [count]]
  2468  *
  2498  *
  2469  *	-H	Scripted mode.  Don't display headers, and separate properties
  2499  *	-H	Scripted mode.  Don't display headers, and separate properties
  2470  *		by a single tab.
  2500  *		by a single tab.
  2471  *	-o	List of properties to display.  Defaults to
  2501  *	-o	List of properties to display.  Defaults to
  2472  *		"name,size,allocated,free,capacity,health,altroot"
  2502  *		"name,size,allocated,free,capacity,health,altroot"
       
  2503  *	-T	Display a timestamp in date(1) or Unix format
  2473  *
  2504  *
  2474  * List all pools in the system, whether or not they're healthy.  Output space
  2505  * List all pools in the system, whether or not they're healthy.  Output space
  2475  * statistics for each one, as well as health status summary.
  2506  * statistics for each one, as well as health status summary.
  2476  */
  2507  */
  2477 int
  2508 int
  2481 	int ret;
  2512 	int ret;
  2482 	list_cbdata_t cb = { 0 };
  2513 	list_cbdata_t cb = { 0 };
  2483 	static char default_props[] =
  2514 	static char default_props[] =
  2484 	    "name,size,allocated,free,capacity,dedupratio,health,altroot";
  2515 	    "name,size,allocated,free,capacity,dedupratio,health,altroot";
  2485 	char *props = default_props;
  2516 	char *props = default_props;
       
  2517 	unsigned long interval = 0, count = 0;
  2486 
  2518 
  2487 	/* check options */
  2519 	/* check options */
  2488 	while ((c = getopt(argc, argv, ":Ho:")) != -1) {
  2520 	while ((c = getopt(argc, argv, ":Ho:T:")) != -1) {
  2489 		switch (c) {
  2521 		switch (c) {
  2490 		case 'H':
  2522 		case 'H':
  2491 			cb.cb_scripted = B_TRUE;
  2523 			cb.cb_scripted = B_TRUE;
  2492 			break;
  2524 			break;
  2493 		case 'o':
  2525 		case 'o':
  2494 			props = optarg;
  2526 			props = optarg;
       
  2527 			break;
       
  2528 		case 'T':
       
  2529 			get_timestamp_arg(*optarg);
  2495 			break;
  2530 			break;
  2496 		case ':':
  2531 		case ':':
  2497 			(void) fprintf(stderr, gettext("missing argument for "
  2532 			(void) fprintf(stderr, gettext("missing argument for "
  2498 			    "'%c' option\n"), optopt);
  2533 			    "'%c' option\n"), optopt);
  2499 			usage(B_FALSE);
  2534 			usage(B_FALSE);
  2506 	}
  2541 	}
  2507 
  2542 
  2508 	argc -= optind;
  2543 	argc -= optind;
  2509 	argv += optind;
  2544 	argv += optind;
  2510 
  2545 
       
  2546 	get_interval_count(&argc, argv, &interval, &count);
       
  2547 
  2511 	if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
  2548 	if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
  2512 		usage(B_FALSE);
  2549 		usage(B_FALSE);
  2513 
  2550 
  2514 	cb.cb_first = B_TRUE;
  2551 	cb.cb_first = B_TRUE;
  2515 
  2552 
  2516 	ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
  2553 	for (;;) {
  2517 	    list_callback, &cb);
  2554 
       
  2555 		if (timestamp_fmt != NODATE)
       
  2556 			print_timestamp(timestamp_fmt);
       
  2557 
       
  2558 		ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
       
  2559 		    list_callback, &cb);
       
  2560 
       
  2561 		if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
       
  2562 			(void) printf(gettext("no pools available\n"));
       
  2563 			zprop_free_list(cb.cb_proplist);
       
  2564 			return (0);
       
  2565 		}
       
  2566 
       
  2567 		if (interval == 0)
       
  2568 			break;
       
  2569 
       
  2570 		if (count != 0 && --count == 0)
       
  2571 			break;
       
  2572 
       
  2573 		(void) sleep(interval);
       
  2574 	}
  2518 
  2575 
  2519 	zprop_free_list(cb.cb_proplist);
  2576 	zprop_free_list(cb.cb_proplist);
  2520 
       
  2521 	if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
       
  2522 		(void) printf(gettext("no pools available\n"));
       
  2523 		return (0);
       
  2524 	}
       
  2525 
       
  2526 	return (ret);
  2577 	return (ret);
  2527 }
  2578 }
  2528 
  2579 
  2529 static nvlist_t *
  2580 static nvlist_t *
  2530 zpool_get_vdev_by_name(nvlist_t *nv, char *name)
  2581 zpool_get_vdev_by_name(nvlist_t *nv, char *name)
  3104 		(void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
  3155 		(void) fprintf(stderr, gettext("cannot scrub '%s': pool is "
  3105 		    "currently unavailable\n"), zpool_get_name(zhp));
  3156 		    "currently unavailable\n"), zpool_get_name(zhp));
  3106 		return (1);
  3157 		return (1);
  3107 	}
  3158 	}
  3108 
  3159 
  3109 	err = zpool_scrub(zhp, cb->cb_type);
  3160 	err = zpool_scan(zhp, cb->cb_type);
  3110 
  3161 
  3111 	return (err != 0);
  3162 	return (err != 0);
  3112 }
  3163 }
  3113 
  3164 
  3114 /*
  3165 /*
  3120 zpool_do_scrub(int argc, char **argv)
  3171 zpool_do_scrub(int argc, char **argv)
  3121 {
  3172 {
  3122 	int c;
  3173 	int c;
  3123 	scrub_cbdata_t cb;
  3174 	scrub_cbdata_t cb;
  3124 
  3175 
  3125 	cb.cb_type = POOL_SCRUB_EVERYTHING;
  3176 	cb.cb_type = POOL_SCAN_SCRUB;
  3126 
  3177 
  3127 	/* check options */
  3178 	/* check options */
  3128 	while ((c = getopt(argc, argv, "s")) != -1) {
  3179 	while ((c = getopt(argc, argv, "s")) != -1) {
  3129 		switch (c) {
  3180 		switch (c) {
  3130 		case 's':
  3181 		case 's':
  3131 			cb.cb_type = POOL_SCRUB_NONE;
  3182 			cb.cb_type = POOL_SCAN_NONE;
  3132 			break;
  3183 			break;
  3133 		case '?':
  3184 		case '?':
  3134 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
  3185 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
  3135 			    optopt);
  3186 			    optopt);
  3136 			usage(B_FALSE);
  3187 			usage(B_FALSE);
  3161 
  3212 
  3162 /*
  3213 /*
  3163  * Print out detailed scrub status.
  3214  * Print out detailed scrub status.
  3164  */
  3215  */
  3165 void
  3216 void
  3166 print_scrub_status(nvlist_t *nvroot)
  3217 print_scan_status(pool_scan_stat_t *ps)
  3167 {
  3218 {
  3168 	vdev_stat_t *vs;
  3219 	time_t start, end;
  3169 	uint_t vsc;
  3220 	uint64_t elapsed, mins_left;
  3170 	time_t start, end, now;
  3221 	uint64_t pass_exam, examined, total;
       
  3222 	uint_t rate;
  3171 	double fraction_done;
  3223 	double fraction_done;
  3172 	uint64_t examined, total, minutes_left, minutes_taken;
  3224 	char processed_buf[7], examined_buf[7], total_buf[7], rate_buf[7];
  3173 	char *scrub_type;
  3225 
  3174 
  3226 	(void) printf(gettext(" scan: "));
  3175 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
  3227 
  3176 	    (uint64_t **)&vs, &vsc) == 0);
  3228 	/* If there's never been a scan, there's not much to say. */
  3177 
  3229 	if (ps == NULL || ps->pss_func == POOL_SCAN_NONE ||
  3178 	/*
  3230 	    ps->pss_func >= POOL_SCAN_FUNCS) {
  3179 	 * If there's never been a scrub, there's not much to say.
       
  3180 	 */
       
  3181 	if (vs->vs_scrub_end == 0 && vs->vs_scrub_type == POOL_SCRUB_NONE) {
       
  3182 		(void) printf(gettext("none requested\n"));
  3231 		(void) printf(gettext("none requested\n"));
  3183 		return;
  3232 		return;
  3184 	}
  3233 	}
  3185 
  3234 
  3186 	scrub_type = (vs->vs_scrub_type == POOL_SCRUB_RESILVER) ?
  3235 	start = ps->pss_start_time;
  3187 	    "resilver" : "scrub";
  3236 	end = ps->pss_end_time;
  3188 
  3237 	zfs_nicenum(ps->pss_processed, processed_buf, sizeof (processed_buf));
  3189 	start = vs->vs_scrub_start;
  3238 
  3190 	end = vs->vs_scrub_end;
  3239 	assert(ps->pss_func == POOL_SCAN_SCRUB ||
  3191 	now = time(NULL);
  3240 	    ps->pss_func == POOL_SCAN_RESILVER);
  3192 	examined = vs->vs_scrub_examined;
  3241 	/*
  3193 	total = vs->vs_alloc;
  3242 	 * Scan is finished or canceled.
  3194 
  3243 	 */
  3195 	if (end != 0) {
  3244 	if (ps->pss_state == DSS_FINISHED) {
  3196 		minutes_taken = (uint64_t)((end - start) / 60);
  3245 		uint64_t minutes_taken = (end - start) / 60;
  3197 
  3246 		char *fmt;
  3198 		(void) printf(gettext("%s %s after %lluh%um with %llu errors "
  3247 
  3199 		    "on %s"),
  3248 		if (ps->pss_func == POOL_SCAN_SCRUB) {
  3200 		    scrub_type, vs->vs_scrub_complete ? "completed" : "stopped",
  3249 			fmt = gettext("scrub repaired %s in %lluh%um with "
       
  3250 			    "%llu errors on %s");
       
  3251 		} else if (ps->pss_func == POOL_SCAN_RESILVER) {
       
  3252 			fmt = gettext("resilvered %s in %lluh%um with "
       
  3253 			    "%llu errors on %s");
       
  3254 		}
       
  3255 		/* LINTED */
       
  3256 		(void) printf(fmt, processed_buf,
  3201 		    (u_longlong_t)(minutes_taken / 60),
  3257 		    (u_longlong_t)(minutes_taken / 60),
  3202 		    (uint_t)(minutes_taken % 60),
  3258 		    (uint_t)(minutes_taken % 60),
  3203 		    (u_longlong_t)vs->vs_scrub_errors, ctime(&end));
  3259 		    (u_longlong_t)ps->pss_errors,
       
  3260 		    ctime((time_t *)&end));
  3204 		return;
  3261 		return;
  3205 	}
  3262 	} else if (ps->pss_state == DSS_CANCELED) {
  3206 
  3263 		if (ps->pss_func == POOL_SCAN_SCRUB) {
  3207 	if (examined == 0)
  3264 			(void) printf(gettext("scrub canceled on %s"),
  3208 		examined = 1;
  3265 			    ctime(&end));
  3209 	if (examined > total)
  3266 		} else if (ps->pss_func == POOL_SCAN_RESILVER) {
  3210 		total = examined;
  3267 			(void) printf(gettext("resilver canceled on %s"),
  3211 
  3268 			    ctime(&end));
       
  3269 		}
       
  3270 		return;
       
  3271 	}
       
  3272 
       
  3273 	assert(ps->pss_state == DSS_SCANNING);
       
  3274 
       
  3275 	/*
       
  3276 	 * Scan is in progress.
       
  3277 	 */
       
  3278 	if (ps->pss_func == POOL_SCAN_SCRUB) {
       
  3279 		(void) printf(gettext("scrub in progress since %s"),
       
  3280 		    ctime(&start));
       
  3281 	} else if (ps->pss_func == POOL_SCAN_RESILVER) {
       
  3282 		(void) printf(gettext("resilver in progress since %s"),
       
  3283 		    ctime(&start));
       
  3284 	}
       
  3285 
       
  3286 	examined = ps->pss_examined ? ps->pss_examined : 1;
       
  3287 	total = ps->pss_to_examine;
  3212 	fraction_done = (double)examined / total;
  3288 	fraction_done = (double)examined / total;
  3213 	minutes_left = (uint64_t)((now - start) *
  3289 
  3214 	    (1 - fraction_done) / fraction_done / 60);
  3290 	/* elapsed time for this pass */
  3215 	minutes_taken = (uint64_t)((now - start) / 60);
  3291 	elapsed = time(NULL) - ps->pss_pass_start;
  3216 
  3292 	elapsed = elapsed ? elapsed : 1;
  3217 	(void) printf(gettext("%s in progress for %lluh%um, %.2f%% done, "
  3293 	pass_exam = ps->pss_pass_exam ? ps->pss_pass_exam : 1;
  3218 	    "%lluh%um to go\n"),
  3294 	rate = pass_exam / elapsed;
  3219 	    scrub_type, (u_longlong_t)(minutes_taken / 60),
  3295 	rate = rate ? rate : 1;
  3220 	    (uint_t)(minutes_taken % 60), 100 * fraction_done,
  3296 	mins_left = ((total - examined) / rate) / 60;
  3221 	    (u_longlong_t)(minutes_left / 60), (uint_t)(minutes_left % 60));
  3297 
       
  3298 	zfs_nicenum(examined, examined_buf, sizeof (examined_buf));
       
  3299 	zfs_nicenum(total, total_buf, sizeof (total_buf));
       
  3300 	zfs_nicenum(rate, rate_buf, sizeof (rate_buf));
       
  3301 
       
  3302 	(void) printf(gettext("    %s scanned out of %s at "
       
  3303 	    "%s/s, %lluh%um to go\n"), examined_buf, total_buf, rate_buf,
       
  3304 	    (u_longlong_t)(mins_left / 60),
       
  3305 	    (uint_t)(mins_left % 60));
       
  3306 
       
  3307 	if (ps->pss_func == POOL_SCAN_RESILVER) {
       
  3308 		(void) printf(gettext("    %s resilvered, %.2f%% done\n"),
       
  3309 		    processed_buf, 100 * fraction_done);
       
  3310 	} else if (ps->pss_func == POOL_SCAN_SCRUB) {
       
  3311 		(void) printf(gettext("    %s repaired, %.2f%% done\n"),
       
  3312 		    processed_buf, 100 * fraction_done);
       
  3313 	}
  3222 }
  3314 }
  3223 
  3315 
  3224 static void
  3316 static void
  3225 print_error_log(zpool_handle_t *zhp)
  3317 print_error_log(zpool_handle_t *zhp)
  3226 {
  3318 {
  3376 	else
  3468 	else
  3377 		(void) printf("\n");
  3469 		(void) printf("\n");
  3378 
  3470 
  3379 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
  3471 	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
  3380 	    &nvroot) == 0);
  3472 	    &nvroot) == 0);
  3381 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_STATS,
  3473 	verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
  3382 	    (uint64_t **)&vs, &c) == 0);
  3474 	    (uint64_t **)&vs, &c) == 0);
  3383 	health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
  3475 	health = zpool_state_to_name(vs->vs_state, vs->vs_aux);
  3384 
  3476 
  3385 	(void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
  3477 	(void) printf(gettext("  pool: %s\n"), zpool_get_name(zhp));
  3386 	(void) printf(gettext(" state: %s\n"), health);
  3478 	(void) printf(gettext(" state: %s\n"), health);
  3449 		(void) printf(gettext("action: Online the device using "
  3541 		(void) printf(gettext("action: Online the device using "
  3450 		    "'zpool online' or replace the device with\n\t'zpool "
  3542 		    "'zpool online' or replace the device with\n\t'zpool "
  3451 		    "replace'.\n"));
  3543 		    "replace'.\n"));
  3452 		break;
  3544 		break;
  3453 
  3545 
  3454 
       
  3455 	case ZPOOL_STATUS_RESILVERING:
  3546 	case ZPOOL_STATUS_RESILVERING:
  3456 		(void) printf(gettext("status: One or more devices is "
  3547 		(void) printf(gettext("status: One or more devices is "
  3457 		    "currently being resilvered.  The pool will\n\tcontinue "
  3548 		    "currently being resilvered.  The pool will\n\tcontinue "
  3458 		    "to function, possibly in a degraded state.\n"));
  3549 		    "to function, possibly in a degraded state.\n"));
  3459 		(void) printf(gettext("action: Wait for the resilver to "
  3550 		(void) printf(gettext("action: Wait for the resilver to "
  3547 	if (config != NULL) {
  3638 	if (config != NULL) {
  3548 		int namewidth;
  3639 		int namewidth;
  3549 		uint64_t nerr;
  3640 		uint64_t nerr;
  3550 		nvlist_t **spares, **l2cache;
  3641 		nvlist_t **spares, **l2cache;
  3551 		uint_t nspares, nl2cache;
  3642 		uint_t nspares, nl2cache;
  3552 
  3643 		pool_scan_stat_t *ps = NULL;
  3553 
  3644 
  3554 		(void) printf(gettext(" scrub: "));
  3645 		(void) nvlist_lookup_uint64_array(nvroot,
  3555 		print_scrub_status(nvroot);
  3646 		    ZPOOL_CONFIG_SCAN_STATS, (uint64_t **)&ps, &c);
       
  3647 		print_scan_status(ps);
  3556 
  3648 
  3557 		namewidth = max_width(zhp, nvroot, 0, 0);
  3649 		namewidth = max_width(zhp, nvroot, 0, 0);
  3558 		if (namewidth < 10)
  3650 		if (namewidth < 10)
  3559 			namewidth = 10;
  3651 			namewidth = 10;
  3560 
  3652 
  3618 
  3710 
  3619 	return (0);
  3711 	return (0);
  3620 }
  3712 }
  3621 
  3713 
  3622 /*
  3714 /*
  3623  * zpool status [-vx] [pool] ...
  3715  * zpool status [-vx] [-T d|u] [pool] ... [interval [count]]
  3624  *
  3716  *
  3625  *	-v	Display complete error logs
  3717  *	-v	Display complete error logs
  3626  *	-x	Display only pools with potential problems
  3718  *	-x	Display only pools with potential problems
  3627  *	-D	Display dedup status (undocumented)
  3719  *	-D	Display dedup status (undocumented)
       
  3720  *	-T	Display a timestamp in date(1) or Unix format
  3628  *
  3721  *
  3629  * Describes the health status of all pools or some subset.
  3722  * Describes the health status of all pools or some subset.
  3630  */
  3723  */
  3631 int
  3724 int
  3632 zpool_do_status(int argc, char **argv)
  3725 zpool_do_status(int argc, char **argv)
  3633 {
  3726 {
  3634 	int c;
  3727 	int c;
  3635 	int ret;
  3728 	int ret;
       
  3729 	unsigned long interval = 0, count = 0;
  3636 	status_cbdata_t cb = { 0 };
  3730 	status_cbdata_t cb = { 0 };
  3637 
  3731 
  3638 	/* check options */
  3732 	/* check options */
  3639 	while ((c = getopt(argc, argv, "vxD")) != -1) {
  3733 	while ((c = getopt(argc, argv, "vxDT:")) != -1) {
  3640 		switch (c) {
  3734 		switch (c) {
  3641 		case 'v':
  3735 		case 'v':
  3642 			cb.cb_verbose = B_TRUE;
  3736 			cb.cb_verbose = B_TRUE;
  3643 			break;
  3737 			break;
  3644 		case 'x':
  3738 		case 'x':
  3645 			cb.cb_explain = B_TRUE;
  3739 			cb.cb_explain = B_TRUE;
  3646 			break;
  3740 			break;
  3647 		case 'D':
  3741 		case 'D':
  3648 			cb.cb_dedup_stats = B_TRUE;
  3742 			cb.cb_dedup_stats = B_TRUE;
       
  3743 			break;
       
  3744 		case 'T':
       
  3745 			get_timestamp_arg(*optarg);
  3649 			break;
  3746 			break;
  3650 		case '?':
  3747 		case '?':
  3651 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
  3748 			(void) fprintf(stderr, gettext("invalid option '%c'\n"),
  3652 			    optopt);
  3749 			    optopt);
  3653 			usage(B_FALSE);
  3750 			usage(B_FALSE);
  3655 	}
  3752 	}
  3656 
  3753 
  3657 	argc -= optind;
  3754 	argc -= optind;
  3658 	argv += optind;
  3755 	argv += optind;
  3659 
  3756 
  3660 	cb.cb_first = B_TRUE;
  3757 	get_interval_count(&argc, argv, &interval, &count);
  3661 
  3758 
  3662 	if (argc == 0)
  3759 	if (argc == 0)
  3663 		cb.cb_allpools = B_TRUE;
  3760 		cb.cb_allpools = B_TRUE;
  3664 
  3761 
  3665 	ret = for_each_pool(argc, argv, B_TRUE, NULL, status_callback, &cb);
  3762 	cb.cb_first = B_TRUE;
  3666 
  3763 
  3667 	if (argc == 0 && cb.cb_count == 0)
  3764 	for (;;) {
  3668 		(void) printf(gettext("no pools available\n"));
  3765 		if (timestamp_fmt != NODATE)
  3669 	else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
  3766 			print_timestamp(timestamp_fmt);
  3670 		(void) printf(gettext("all pools are healthy\n"));
  3767 
  3671 
  3768 		ret = for_each_pool(argc, argv, B_TRUE, NULL,
  3672 	return (ret);
  3769 		    status_callback, &cb);
       
  3770 
       
  3771 		if (argc == 0 && cb.cb_count == 0)
       
  3772 			(void) printf(gettext("no pools available\n"));
       
  3773 		else if (cb.cb_explain && cb.cb_first && cb.cb_allpools)
       
  3774 			(void) printf(gettext("all pools are healthy\n"));
       
  3775 
       
  3776 		if (ret != 0)
       
  3777 			return (ret);
       
  3778 
       
  3779 		if (interval == 0)
       
  3780 			break;
       
  3781 
       
  3782 		if (count != 0 && --count == 0)
       
  3783 			break;
       
  3784 
       
  3785 		(void) sleep(interval);
       
  3786 	}
       
  3787 
       
  3788 	return (0);
  3673 }
  3789 }
  3674 
  3790 
  3675 typedef struct upgrade_cbdata {
  3791 typedef struct upgrade_cbdata {
  3676 	int	cb_all;
  3792 	int	cb_all;
  3677 	int	cb_first;
  3793 	int	cb_first;
  3888 		    "(zero-length encoding)\n"));
  4004 		    "(zero-length encoding)\n"));
  3889 		(void) printf(gettext(" 21  Deduplication\n"));
  4005 		(void) printf(gettext(" 21  Deduplication\n"));
  3890 		(void) printf(gettext(" 22  Received properties\n"));
  4006 		(void) printf(gettext(" 22  Received properties\n"));
  3891 		(void) printf(gettext(" 23  Slim ZIL\n"));
  4007 		(void) printf(gettext(" 23  Slim ZIL\n"));
  3892 		(void) printf(gettext(" 24  System attributes\n"));
  4008 		(void) printf(gettext(" 24  System attributes\n"));
       
  4009 		(void) printf(gettext(" 25  Improved scrub stats\n"));
  3893 		(void) printf(gettext("\nFor more information on a particular "
  4010 		(void) printf(gettext("\nFor more information on a particular "
  3894 		    "version, including supported releases, see:\n\n"));
  4011 		    "version, including supported releases, see:\n\n"));
  3895 		(void) printf("http://www.opensolaris.org/os/community/zfs/"
  4012 		(void) printf("http://www.opensolaris.org/os/community/zfs/"
  3896 		    "version/N\n\n");
  4013 		    "version/N\n\n");
  3897 		(void) printf(gettext("Where 'N' is the version number.\n"));
  4014 		(void) printf(gettext("Where 'N' is the version number.\n"));
  3991 			if (ievent >= LOG_END)
  4108 			if (ievent >= LOG_END)
  3992 				continue;
  4109 				continue;
  3993 			(void) snprintf(internalstr,
  4110 			(void) snprintf(internalstr,
  3994 			    sizeof (internalstr),
  4111 			    sizeof (internalstr),
  3995 			    "[internal %s txg:%lld] %s",
  4112 			    "[internal %s txg:%lld] %s",
  3996 			    hist_event_table[ievent], txg,
  4113 			    zfs_history_event_names[ievent], txg,
  3997 			    pathstr);
  4114 			    pathstr);
  3998 			cmdstr = internalstr;
  4115 			cmdstr = internalstr;
  3999 		}
  4116 		}
  4000 		tsec = dst_time;
  4117 		tsec = dst_time;
  4001 		(void) localtime_r(&tsec, &t);
  4118 		(void) localtime_r(&tsec, &t);