26 */
27
28 #include <ctype.h>
29 #include <errno.h>
30 #include <devid.h>
31 #include <fcntl.h>
32 #include <libintl.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <strings.h>
36 #include <unistd.h>
37 #include <sys/efi_partition.h>
38 #include <sys/vtoc.h>
39 #include <sys/zfs_ioctl.h>
40 #include <dlfcn.h>
41
42 #include "zfs_namecheck.h"
43 #include "zfs_prop.h"
44 #include "libzfs_impl.h"
45 #include "zfs_comutil.h"
46
47 static int read_efi_label(nvlist_t *config, diskaddr_t *sb);
48
49 #define DISK_ROOT "/dev/dsk"
50 #define RDISK_ROOT "/dev/rdsk"
51 #define BACKUP_SLICE "s2"
52
53 typedef struct prop_flags {
54 int create:1; /* Validate property on creation */
55 int import:1; /* Validate property on import */
56 } prop_flags_t;
57
58 /*
59 * ====================================================================
60 * zpool property functions
61 * ====================================================================
62 */
63
64 static int
65 zpool_get_all_props(zpool_handle_t *zhp)
256 return (0);
257 }
258
259 if (zhp->zpool_props == NULL && zpool_get_all_props(zhp) &&
260 prop != ZPOOL_PROP_NAME)
261 return (-1);
262
263 switch (zpool_prop_get_type(prop)) {
264 case PROP_TYPE_STRING:
265 (void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src),
266 len);
267 break;
268
269 case PROP_TYPE_NUMBER:
270 intval = zpool_get_prop_int(zhp, prop, &src);
271
272 switch (prop) {
273 case ZPOOL_PROP_SIZE:
274 case ZPOOL_PROP_ALLOCATED:
275 case ZPOOL_PROP_FREE:
276 case ZPOOL_PROP_EXPANDSZ:
277 (void) zfs_nicenum(intval, buf, len);
278 break;
279
280 case ZPOOL_PROP_CAPACITY:
281 (void) snprintf(buf, len, "%llu%%",
282 (u_longlong_t)intval);
283 break;
284
285 case ZPOOL_PROP_DEDUPRATIO:
286 (void) snprintf(buf, len, "%llu.%02llux",
287 (u_longlong_t)(intval / 100),
288 (u_longlong_t)(intval % 100));
289 break;
290
291 case ZPOOL_PROP_HEALTH:
292 verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
293 ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
294 verify(nvlist_lookup_uint64_array(nvroot,
295 ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &vsc)
296 == 0);
297
298 (void) strlcpy(buf, zpool_state_to_name(intval,
299 vs->vs_aux), len);
300 break;
301 default:
302 (void) snprintf(buf, len, "%llu", intval);
303 }
304 break;
305
306 case PROP_TYPE_INDEX:
307 intval = zpool_get_prop_int(zhp, prop, &src);
308 if (zpool_prop_index_to_string(prop, intval, &strval)
309 != 0)
310 return (-1);
311 (void) strlcpy(buf, strval, len);
312 break;
313
314 default:
315 abort();
316 }
317
318 if (srctype)
319 *srctype = src;
320
383 {
384 nvpair_t *elem;
385 nvlist_t *retprops;
386 zpool_prop_t prop;
387 char *strval;
388 uint64_t intval;
389 char *slash, *check;
390 struct stat64 statbuf;
391 zpool_handle_t *zhp;
392 nvlist_t *nvroot;
393
394 if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
395 (void) no_memory(hdl);
396 return (NULL);
397 }
398
399 elem = NULL;
400 while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
401 const char *propname = nvpair_name(elem);
402
403 /*
404 * Make sure this property is valid and applies to this type.
405 */
406 if ((prop = zpool_name_to_prop(propname)) == ZPROP_INVAL) {
407 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
408 "invalid property '%s'"), propname);
409 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
410 goto error;
411 }
412
413 if (zpool_prop_readonly(prop)) {
414 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
415 "is readonly"), propname);
416 (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
417 goto error;
418 }
419
420 if (zprop_parse_value(hdl, elem, prop, ZFS_TYPE_POOL, retprops,
421 &strval, &intval, errbuf) != 0)
422 goto error;
423
424 /*
425 * Perform additional checking for specific properties.
426 */
427 switch (prop) {
428 case ZPOOL_PROP_VERSION:
429 if (intval < version || intval > SPA_VERSION) {
430 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
431 "property '%s' number %d is invalid."),
432 propname, intval);
433 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
434 goto error;
435 }
436 break;
437
438 case ZPOOL_PROP_BOOTFS:
439 if (flags.create || flags.import) {
440 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
441 "property '%s' cannot be set at creation "
442 "or import time"), propname);
443 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
444 goto error;
445 }
446
447 if (version < SPA_VERSION_BOOTFS) {
448 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
449 "pool must be upgraded to support "
631
632 ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SET_PROPS, &zc);
633
634 zcmd_free_nvlists(&zc);
635 nvlist_free(nvl);
636
637 if (ret)
638 (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
639 else
640 (void) zpool_props_refresh(zhp);
641
642 return (ret);
643 }
644
645 int
646 zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp)
647 {
648 libzfs_handle_t *hdl = zhp->zpool_hdl;
649 zprop_list_t *entry;
650 char buf[ZFS_MAXPROPLEN];
651
652 if (zprop_expand_list(hdl, plp, ZFS_TYPE_POOL) != 0)
653 return (-1);
654
655 for (entry = *plp; entry != NULL; entry = entry->pl_next) {
656
657 if (entry->pl_fixed)
658 continue;
659
660 if (entry->pl_prop != ZPROP_INVAL &&
661 zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf),
662 NULL) == 0) {
663 if (strlen(buf) > entry->pl_width)
664 entry->pl_width = strlen(buf);
665 }
666 }
667
668 return (0);
669 }
670
671
672 /*
673 * Don't start the slice at the default block of 34; many storage
674 * devices will use a stripe width of 128k, so start there instead.
675 */
676 #define NEW_START_BLOCK 256
677
678 /*
679 * Validate the given pool name, optionally putting an extended error message in
680 * 'buf'.
681 */
682 boolean_t
683 zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
684 {
685 namecheck_err_t why;
686 char what;
687 int ret;
688
689 ret = pool_namecheck(pool, &why, &what);
690
691 /*
1237
1238 int
1239 zpool_export_force(zpool_handle_t *zhp)
1240 {
1241 return (zpool_export_common(zhp, B_TRUE, B_TRUE));
1242 }
1243
1244 static void
1245 zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun,
1246 nvlist_t *config)
1247 {
1248 nvlist_t *nv = NULL;
1249 uint64_t rewindto;
1250 int64_t loss = -1;
1251 struct tm t;
1252 char timestr[128];
1253
1254 if (!hdl->libzfs_printerr || config == NULL)
1255 return;
1256
1257 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0)
1258 return;
1259
1260 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
1261 return;
1262 (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
1263
1264 if (localtime_r((time_t *)&rewindto, &t) != NULL &&
1265 strftime(timestr, 128, 0, &t) != 0) {
1266 if (dryrun) {
1267 (void) printf(dgettext(TEXT_DOMAIN,
1268 "Would be able to return %s "
1269 "to its state as of %s.\n"),
1270 name, timestr);
1271 } else {
1272 (void) printf(dgettext(TEXT_DOMAIN,
1273 "Pool %s returned to its state as of %s.\n"),
1274 name, timestr);
1275 }
1276 if (loss > 120) {
1277 (void) printf(dgettext(TEXT_DOMAIN,
1278 "%s approximately %lld "),
1294 zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason,
1295 nvlist_t *config)
1296 {
1297 nvlist_t *nv = NULL;
1298 int64_t loss = -1;
1299 uint64_t edata = UINT64_MAX;
1300 uint64_t rewindto;
1301 struct tm t;
1302 char timestr[128];
1303
1304 if (!hdl->libzfs_printerr)
1305 return;
1306
1307 if (reason >= 0)
1308 (void) printf(dgettext(TEXT_DOMAIN, "action: "));
1309 else
1310 (void) printf(dgettext(TEXT_DOMAIN, "\t"));
1311
1312 /* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */
1313 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
1314 nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
1315 goto no_info;
1316
1317 (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
1318 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_DATA_ERRORS,
1319 &edata);
1320
1321 (void) printf(dgettext(TEXT_DOMAIN,
1322 "Recovery is possible, but will result in some data loss.\n"));
1323
1324 if (localtime_r((time_t *)&rewindto, &t) != NULL &&
1325 strftime(timestr, 128, 0, &t) != 0) {
1326 (void) printf(dgettext(TEXT_DOMAIN,
1327 "\tReturning the pool to its state as of %s\n"
1328 "\tshould correct the problem. "),
1329 timestr);
1330 } else {
1331 (void) printf(dgettext(TEXT_DOMAIN,
1332 "\tReverting the pool to an earlier state "
1333 "should correct the problem.\n\t"));
1416 uint64_t is_log = 0;
1417
1418 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG,
1419 &is_log);
1420
1421 if (name != NULL)
1422 (void) printf("\t%*s%s%s\n", indent, "", name,
1423 is_log ? " [log]" : "");
1424
1425 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1426 &child, &children) != 0)
1427 return;
1428
1429 for (c = 0; c < children; c++) {
1430 vname = zpool_vdev_name(hdl, NULL, child[c], B_TRUE);
1431 print_vdev_tree(hdl, vname, child[c], indent + 2);
1432 free(vname);
1433 }
1434 }
1435
1436 /*
1437 * Import the given pool using the known configuration and a list of
1438 * properties to be set. The configuration should have come from
1439 * zpool_find_import(). The 'newname' parameters control whether the pool
1440 * is imported with a different name.
1441 */
1442 int
1443 zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
1444 nvlist_t *props, int flags)
1445 {
1446 zfs_cmd_t zc = { 0 };
1447 zpool_rewind_policy_t policy;
1448 nvlist_t *nv = NULL;
1449 nvlist_t *nvinfo = NULL;
1450 nvlist_t *missing = NULL;
1451 char *thename;
1452 char *origname;
1453 int ret;
1454 int error = 0;
1455 char errbuf[1024];
1522 * looks like if we found a best txg
1523 */
1524 if (policy.zrp_request & ZPOOL_TRY_REWIND) {
1525 zpool_rewind_exclaim(hdl, newname ? origname : thename,
1526 B_TRUE, nv);
1527 nvlist_free(nv);
1528 return (-1);
1529 }
1530
1531 if (newname == NULL)
1532 (void) snprintf(desc, sizeof (desc),
1533 dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1534 thename);
1535 else
1536 (void) snprintf(desc, sizeof (desc),
1537 dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"),
1538 origname, thename);
1539
1540 switch (error) {
1541 case ENOTSUP:
1542 /*
1543 * Unsupported version.
1544 */
1545 (void) zfs_error(hdl, EZFS_BADVERSION, desc);
1546 break;
1547
1548 case EINVAL:
1549 (void) zfs_error(hdl, EZFS_INVALCONFIG, desc);
1550 break;
1551
1552 case EROFS:
1553 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1554 "one or more devices is read only"));
1555 (void) zfs_error(hdl, EZFS_BADDEV, desc);
1556 break;
1557
1558 case ENXIO:
1559 if (nv && nvlist_lookup_nvlist(nv,
1560 ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
1561 nvlist_lookup_nvlist(nvinfo,
|
26 */
27
28 #include <ctype.h>
29 #include <errno.h>
30 #include <devid.h>
31 #include <fcntl.h>
32 #include <libintl.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <strings.h>
36 #include <unistd.h>
37 #include <sys/efi_partition.h>
38 #include <sys/vtoc.h>
39 #include <sys/zfs_ioctl.h>
40 #include <dlfcn.h>
41
42 #include "zfs_namecheck.h"
43 #include "zfs_prop.h"
44 #include "libzfs_impl.h"
45 #include "zfs_comutil.h"
46 #include "zfeature_common.h"
47
48 static int read_efi_label(nvlist_t *config, diskaddr_t *sb);
49
50 #define DISK_ROOT "/dev/dsk"
51 #define RDISK_ROOT "/dev/rdsk"
52 #define BACKUP_SLICE "s2"
53
54 typedef struct prop_flags {
55 int create:1; /* Validate property on creation */
56 int import:1; /* Validate property on import */
57 } prop_flags_t;
58
59 /*
60 * ====================================================================
61 * zpool property functions
62 * ====================================================================
63 */
64
65 static int
66 zpool_get_all_props(zpool_handle_t *zhp)
257 return (0);
258 }
259
260 if (zhp->zpool_props == NULL && zpool_get_all_props(zhp) &&
261 prop != ZPOOL_PROP_NAME)
262 return (-1);
263
264 switch (zpool_prop_get_type(prop)) {
265 case PROP_TYPE_STRING:
266 (void) strlcpy(buf, zpool_get_prop_string(zhp, prop, &src),
267 len);
268 break;
269
270 case PROP_TYPE_NUMBER:
271 intval = zpool_get_prop_int(zhp, prop, &src);
272
273 switch (prop) {
274 case ZPOOL_PROP_SIZE:
275 case ZPOOL_PROP_ALLOCATED:
276 case ZPOOL_PROP_FREE:
277 case ZPOOL_PROP_FREEING:
278 case ZPOOL_PROP_EXPANDSZ:
279 (void) zfs_nicenum(intval, buf, len);
280 break;
281
282 case ZPOOL_PROP_CAPACITY:
283 (void) snprintf(buf, len, "%llu%%",
284 (u_longlong_t)intval);
285 break;
286
287 case ZPOOL_PROP_DEDUPRATIO:
288 (void) snprintf(buf, len, "%llu.%02llux",
289 (u_longlong_t)(intval / 100),
290 (u_longlong_t)(intval % 100));
291 break;
292
293 case ZPOOL_PROP_HEALTH:
294 verify(nvlist_lookup_nvlist(zpool_get_config(zhp, NULL),
295 ZPOOL_CONFIG_VDEV_TREE, &nvroot) == 0);
296 verify(nvlist_lookup_uint64_array(nvroot,
297 ZPOOL_CONFIG_VDEV_STATS, (uint64_t **)&vs, &vsc)
298 == 0);
299
300 (void) strlcpy(buf, zpool_state_to_name(intval,
301 vs->vs_aux), len);
302 break;
303 case ZPOOL_PROP_VERSION:
304 if (intval >= SPA_VERSION_FEATURES) {
305 (void) snprintf(buf, len, "-");
306 break;
307 }
308 /* FALLTHROUGH */
309 default:
310 (void) snprintf(buf, len, "%llu", intval);
311 }
312 break;
313
314 case PROP_TYPE_INDEX:
315 intval = zpool_get_prop_int(zhp, prop, &src);
316 if (zpool_prop_index_to_string(prop, intval, &strval)
317 != 0)
318 return (-1);
319 (void) strlcpy(buf, strval, len);
320 break;
321
322 default:
323 abort();
324 }
325
326 if (srctype)
327 *srctype = src;
328
391 {
392 nvpair_t *elem;
393 nvlist_t *retprops;
394 zpool_prop_t prop;
395 char *strval;
396 uint64_t intval;
397 char *slash, *check;
398 struct stat64 statbuf;
399 zpool_handle_t *zhp;
400 nvlist_t *nvroot;
401
402 if (nvlist_alloc(&retprops, NV_UNIQUE_NAME, 0) != 0) {
403 (void) no_memory(hdl);
404 return (NULL);
405 }
406
407 elem = NULL;
408 while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
409 const char *propname = nvpair_name(elem);
410
411 prop = zpool_name_to_prop(propname);
412 if (prop == ZPROP_INVAL && zpool_prop_feature(propname)) {
413 int err;
414 zfeature_info_t *feature;
415 char *fname = strchr(propname, '@') + 1;
416
417 err = zfeature_lookup_name(fname, &feature);
418 if (err != 0) {
419 ASSERT3U(err, ==, ENOENT);
420 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
421 "invalid feature '%s'"), fname);
422 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
423 goto error;
424 }
425
426 if (nvpair_type(elem) != DATA_TYPE_STRING) {
427 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
428 "'%s' must be a string"), propname);
429 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
430 goto error;
431 }
432
433 (void) nvpair_value_string(elem, &strval);
434 if (strcmp(strval, ZFS_FEATURE_ENABLED) != 0) {
435 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
436 "property '%s' can only be set to "
437 "'enabled'"), propname);
438 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
439 goto error;
440 }
441
442 if (nvlist_add_uint64(retprops, propname, 0) != 0) {
443 (void) no_memory(hdl);
444 goto error;
445 }
446 continue;
447 }
448
449 /*
450 * Make sure this property is valid and applies to this type.
451 */
452 if (prop == ZPROP_INVAL) {
453 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
454 "invalid property '%s'"), propname);
455 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
456 goto error;
457 }
458
459 if (zpool_prop_readonly(prop)) {
460 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "'%s' "
461 "is readonly"), propname);
462 (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
463 goto error;
464 }
465
466 if (zprop_parse_value(hdl, elem, prop, ZFS_TYPE_POOL, retprops,
467 &strval, &intval, errbuf) != 0)
468 goto error;
469
470 /*
471 * Perform additional checking for specific properties.
472 */
473 switch (prop) {
474 case ZPOOL_PROP_VERSION:
475 if (intval < version ||
476 !SPA_VERSION_IS_SUPPORTED(intval)) {
477 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
478 "property '%s' number %d is invalid."),
479 propname, intval);
480 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
481 goto error;
482 }
483 break;
484
485 case ZPOOL_PROP_BOOTFS:
486 if (flags.create || flags.import) {
487 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
488 "property '%s' cannot be set at creation "
489 "or import time"), propname);
490 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
491 goto error;
492 }
493
494 if (version < SPA_VERSION_BOOTFS) {
495 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
496 "pool must be upgraded to support "
678
679 ret = zfs_ioctl(zhp->zpool_hdl, ZFS_IOC_POOL_SET_PROPS, &zc);
680
681 zcmd_free_nvlists(&zc);
682 nvlist_free(nvl);
683
684 if (ret)
685 (void) zpool_standard_error(zhp->zpool_hdl, errno, errbuf);
686 else
687 (void) zpool_props_refresh(zhp);
688
689 return (ret);
690 }
691
692 int
693 zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp)
694 {
695 libzfs_handle_t *hdl = zhp->zpool_hdl;
696 zprop_list_t *entry;
697 char buf[ZFS_MAXPROPLEN];
698 nvlist_t *features = NULL;
699 zprop_list_t **last;
700 boolean_t firstexpand = (NULL == *plp);
701
702 if (zprop_expand_list(hdl, plp, ZFS_TYPE_POOL) != 0)
703 return (-1);
704
705 last = plp;
706 while (*last != NULL)
707 last = &(*last)->pl_next;
708
709 if ((*plp)->pl_all)
710 features = zpool_get_features(zhp);
711
712 if ((*plp)->pl_all && firstexpand) {
713 for (int i = 0; i < SPA_FEATURES; i++) {
714 zprop_list_t *entry = zfs_alloc(hdl,
715 sizeof (zprop_list_t));
716 entry->pl_prop = ZPROP_INVAL;
717 entry->pl_user_prop = zfs_asprintf(hdl, "feature@%s",
718 spa_feature_table[i].fi_uname);
719 entry->pl_width = strlen(entry->pl_user_prop);
720 entry->pl_all = B_TRUE;
721
722 *last = entry;
723 last = &entry->pl_next;
724 }
725 }
726
727 /* add any unsupported features */
728 for (nvpair_t *nvp = nvlist_next_nvpair(features, NULL);
729 nvp != NULL; nvp = nvlist_next_nvpair(features, nvp)) {
730 char *propname;
731 boolean_t found;
732 zprop_list_t *entry;
733
734 if (zfeature_is_supported(nvpair_name(nvp)))
735 continue;
736
737 propname = zfs_asprintf(hdl, "unsupported@%s",
738 nvpair_name(nvp));
739
740 /*
741 * Before adding the property to the list make sure that no
742 * other pool already added the same property.
743 */
744 found = B_FALSE;
745 entry = *plp;
746 while (entry != NULL) {
747 if (entry->pl_user_prop != NULL &&
748 strcmp(propname, entry->pl_user_prop) == 0) {
749 found = B_TRUE;
750 break;
751 }
752 entry = entry->pl_next;
753 }
754 if (found) {
755 free(propname);
756 continue;
757 }
758
759 entry = zfs_alloc(hdl, sizeof (zprop_list_t));
760 entry->pl_prop = ZPROP_INVAL;
761 entry->pl_user_prop = propname;
762 entry->pl_width = strlen(entry->pl_user_prop);
763 entry->pl_all = B_TRUE;
764
765 *last = entry;
766 last = &entry->pl_next;
767 }
768
769 for (entry = *plp; entry != NULL; entry = entry->pl_next) {
770
771 if (entry->pl_fixed)
772 continue;
773
774 if (entry->pl_prop != ZPROP_INVAL &&
775 zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf),
776 NULL) == 0) {
777 if (strlen(buf) > entry->pl_width)
778 entry->pl_width = strlen(buf);
779 }
780 }
781
782 return (0);
783 }
784
785 /*
786 * Get the state for the given feature on the given ZFS pool.
787 */
788 int
789 zpool_prop_get_feature(zpool_handle_t *zhp, const char *propname, char *buf,
790 size_t len)
791 {
792 uint64_t refcount;
793 boolean_t found = B_FALSE;
794 nvlist_t *features = zpool_get_features(zhp);
795 boolean_t supported;
796 const char *feature = strchr(propname, '@') + 1;
797
798 supported = zpool_prop_feature(propname);
799 ASSERT(supported || zfs_prop_unsupported(propname));
800
801 /*
802 * Convert from feature name to feature guid. This conversion is
803 * unecessary for unsupported@... properties because they already
804 * use guids.
805 */
806 if (supported) {
807 int ret;
808 zfeature_info_t *fi;
809
810 ret = zfeature_lookup_name(feature, &fi);
811 if (ret != 0) {
812 (void) strlcpy(buf, "-", len);
813 return (ENOTSUP);
814 }
815 feature = fi->fi_guid;
816 }
817
818 if (nvlist_lookup_uint64(features, feature, &refcount) == 0)
819 found = B_TRUE;
820
821 if (supported) {
822 if (!found) {
823 (void) strlcpy(buf, ZFS_FEATURE_DISABLED, len);
824 } else {
825 if (refcount == 0)
826 (void) strlcpy(buf, ZFS_FEATURE_ENABLED, len);
827 else
828 (void) strlcpy(buf, ZFS_FEATURE_ACTIVE, len);
829 }
830 } else {
831 if (found) {
832 if (refcount == 0) {
833 (void) strcpy(buf, ZFS_UNSUPPORTED_INACTIVE);
834 } else {
835 (void) strcpy(buf, ZFS_UNSUPPORTED_READONLY);
836 }
837 } else {
838 (void) strlcpy(buf, "-", len);
839 return (ENOTSUP);
840 }
841 }
842
843 return (0);
844 }
845
846 /*
847 * Don't start the slice at the default block of 34; many storage
848 * devices will use a stripe width of 128k, so start there instead.
849 */
850 #define NEW_START_BLOCK 256
851
852 /*
853 * Validate the given pool name, optionally putting an extended error message in
854 * 'buf'.
855 */
856 boolean_t
857 zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
858 {
859 namecheck_err_t why;
860 char what;
861 int ret;
862
863 ret = pool_namecheck(pool, &why, &what);
864
865 /*
1411
1412 int
1413 zpool_export_force(zpool_handle_t *zhp)
1414 {
1415 return (zpool_export_common(zhp, B_TRUE, B_TRUE));
1416 }
1417
1418 static void
1419 zpool_rewind_exclaim(libzfs_handle_t *hdl, const char *name, boolean_t dryrun,
1420 nvlist_t *config)
1421 {
1422 nvlist_t *nv = NULL;
1423 uint64_t rewindto;
1424 int64_t loss = -1;
1425 struct tm t;
1426 char timestr[128];
1427
1428 if (!hdl->libzfs_printerr || config == NULL)
1429 return;
1430
1431 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
1432 nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0) {
1433 return;
1434 }
1435
1436 if (nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
1437 return;
1438 (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
1439
1440 if (localtime_r((time_t *)&rewindto, &t) != NULL &&
1441 strftime(timestr, 128, 0, &t) != 0) {
1442 if (dryrun) {
1443 (void) printf(dgettext(TEXT_DOMAIN,
1444 "Would be able to return %s "
1445 "to its state as of %s.\n"),
1446 name, timestr);
1447 } else {
1448 (void) printf(dgettext(TEXT_DOMAIN,
1449 "Pool %s returned to its state as of %s.\n"),
1450 name, timestr);
1451 }
1452 if (loss > 120) {
1453 (void) printf(dgettext(TEXT_DOMAIN,
1454 "%s approximately %lld "),
1470 zpool_explain_recover(libzfs_handle_t *hdl, const char *name, int reason,
1471 nvlist_t *config)
1472 {
1473 nvlist_t *nv = NULL;
1474 int64_t loss = -1;
1475 uint64_t edata = UINT64_MAX;
1476 uint64_t rewindto;
1477 struct tm t;
1478 char timestr[128];
1479
1480 if (!hdl->libzfs_printerr)
1481 return;
1482
1483 if (reason >= 0)
1484 (void) printf(dgettext(TEXT_DOMAIN, "action: "));
1485 else
1486 (void) printf(dgettext(TEXT_DOMAIN, "\t"));
1487
1488 /* All attempted rewinds failed if ZPOOL_CONFIG_LOAD_TIME missing */
1489 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nv) != 0 ||
1490 nvlist_lookup_nvlist(nv, ZPOOL_CONFIG_REWIND_INFO, &nv) != 0 ||
1491 nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_TIME, &rewindto) != 0)
1492 goto no_info;
1493
1494 (void) nvlist_lookup_int64(nv, ZPOOL_CONFIG_REWIND_TIME, &loss);
1495 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_LOAD_DATA_ERRORS,
1496 &edata);
1497
1498 (void) printf(dgettext(TEXT_DOMAIN,
1499 "Recovery is possible, but will result in some data loss.\n"));
1500
1501 if (localtime_r((time_t *)&rewindto, &t) != NULL &&
1502 strftime(timestr, 128, 0, &t) != 0) {
1503 (void) printf(dgettext(TEXT_DOMAIN,
1504 "\tReturning the pool to its state as of %s\n"
1505 "\tshould correct the problem. "),
1506 timestr);
1507 } else {
1508 (void) printf(dgettext(TEXT_DOMAIN,
1509 "\tReverting the pool to an earlier state "
1510 "should correct the problem.\n\t"));
1593 uint64_t is_log = 0;
1594
1595 (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG,
1596 &is_log);
1597
1598 if (name != NULL)
1599 (void) printf("\t%*s%s%s\n", indent, "", name,
1600 is_log ? " [log]" : "");
1601
1602 if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
1603 &child, &children) != 0)
1604 return;
1605
1606 for (c = 0; c < children; c++) {
1607 vname = zpool_vdev_name(hdl, NULL, child[c], B_TRUE);
1608 print_vdev_tree(hdl, vname, child[c], indent + 2);
1609 free(vname);
1610 }
1611 }
1612
1613 void
1614 zpool_print_unsup_feat(nvlist_t *config)
1615 {
1616 nvlist_t *nvinfo, *unsup_feat;
1617
1618 verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO, &nvinfo) ==
1619 0);
1620 verify(nvlist_lookup_nvlist(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT,
1621 &unsup_feat) == 0);
1622
1623 for (nvpair_t *nvp = nvlist_next_nvpair(unsup_feat, NULL); nvp != NULL;
1624 nvp = nvlist_next_nvpair(unsup_feat, nvp)) {
1625 char *desc;
1626
1627 verify(nvpair_type(nvp) == DATA_TYPE_STRING);
1628 verify(nvpair_value_string(nvp, &desc) == 0);
1629
1630 if (strlen(desc) > 0)
1631 (void) printf("\t%s (%s)\n", nvpair_name(nvp), desc);
1632 else
1633 (void) printf("\t%s\n", nvpair_name(nvp));
1634 }
1635 }
1636
1637 /*
1638 * Import the given pool using the known configuration and a list of
1639 * properties to be set. The configuration should have come from
1640 * zpool_find_import(). The 'newname' parameters control whether the pool
1641 * is imported with a different name.
1642 */
1643 int
1644 zpool_import_props(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
1645 nvlist_t *props, int flags)
1646 {
1647 zfs_cmd_t zc = { 0 };
1648 zpool_rewind_policy_t policy;
1649 nvlist_t *nv = NULL;
1650 nvlist_t *nvinfo = NULL;
1651 nvlist_t *missing = NULL;
1652 char *thename;
1653 char *origname;
1654 int ret;
1655 int error = 0;
1656 char errbuf[1024];
1723 * looks like if we found a best txg
1724 */
1725 if (policy.zrp_request & ZPOOL_TRY_REWIND) {
1726 zpool_rewind_exclaim(hdl, newname ? origname : thename,
1727 B_TRUE, nv);
1728 nvlist_free(nv);
1729 return (-1);
1730 }
1731
1732 if (newname == NULL)
1733 (void) snprintf(desc, sizeof (desc),
1734 dgettext(TEXT_DOMAIN, "cannot import '%s'"),
1735 thename);
1736 else
1737 (void) snprintf(desc, sizeof (desc),
1738 dgettext(TEXT_DOMAIN, "cannot import '%s' as '%s'"),
1739 origname, thename);
1740
1741 switch (error) {
1742 case ENOTSUP:
1743 if (nv != NULL && nvlist_lookup_nvlist(nv,
1744 ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
1745 nvlist_exists(nvinfo, ZPOOL_CONFIG_UNSUP_FEAT)) {
1746 (void) printf(dgettext(TEXT_DOMAIN, "This "
1747 "pool uses the following feature(s) not "
1748 "supported by this system:\n"));
1749 zpool_print_unsup_feat(nv);
1750 if (nvlist_exists(nvinfo,
1751 ZPOOL_CONFIG_CAN_RDONLY)) {
1752 (void) printf(dgettext(TEXT_DOMAIN,
1753 "All unsupported features are only "
1754 "required for writing to the pool."
1755 "\nThe pool can be imported using "
1756 "'-o readonly=on'.\n"));
1757 }
1758 }
1759 /*
1760 * Unsupported version.
1761 */
1762 (void) zfs_error(hdl, EZFS_BADVERSION, desc);
1763 break;
1764
1765 case EINVAL:
1766 (void) zfs_error(hdl, EZFS_INVALCONFIG, desc);
1767 break;
1768
1769 case EROFS:
1770 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1771 "one or more devices is read only"));
1772 (void) zfs_error(hdl, EZFS_BADDEV, desc);
1773 break;
1774
1775 case ENXIO:
1776 if (nv && nvlist_lookup_nvlist(nv,
1777 ZPOOL_CONFIG_LOAD_INFO, &nvinfo) == 0 &&
1778 nvlist_lookup_nvlist(nvinfo,
|