usr/src/lib/libzfs/common/libzfs_pool.c
changeset 2676 5cee47eddab6
parent 2468 b5038d012f66
child 2856 6f4d5ee1906a
equal deleted inserted replaced
2675:54d99ec6d12d 2676:5cee47eddab6
   342 {
   342 {
   343 	zfs_cmd_t zc = { 0 };
   343 	zfs_cmd_t zc = { 0 };
   344 
   344 
   345 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   345 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   346 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 ||
   346 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0 ||
   347 	    zc.zc_root[0] == '\0')
   347 	    zc.zc_value[0] == '\0')
   348 		return (-1);
   348 		return (-1);
   349 
   349 
   350 	(void) strlcpy(buf, zc.zc_root, buflen);
   350 	(void) strlcpy(buf, zc.zc_value, buflen);
   351 
   351 
   352 	return (0);
   352 	return (0);
   353 }
   353 }
   354 
   354 
   355 /*
   355 /*
   369 int
   369 int
   370 zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
   370 zpool_create(libzfs_handle_t *hdl, const char *pool, nvlist_t *nvroot,
   371     const char *altroot)
   371     const char *altroot)
   372 {
   372 {
   373 	zfs_cmd_t zc = { 0 };
   373 	zfs_cmd_t zc = { 0 };
   374 	char *packed;
       
   375 	size_t len;
       
   376 	char msg[1024];
   374 	char msg[1024];
   377 
   375 
   378 	(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
   376 	(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
   379 	    "cannot create '%s'"), pool);
   377 	    "cannot create '%s'"), pool);
   380 
   378 
   383 
   381 
   384 	if (altroot != NULL && altroot[0] != '/')
   382 	if (altroot != NULL && altroot[0] != '/')
   385 		return (zfs_error(hdl, EZFS_BADPATH,
   383 		return (zfs_error(hdl, EZFS_BADPATH,
   386 		    dgettext(TEXT_DOMAIN, "bad alternate root '%s'"), altroot));
   384 		    dgettext(TEXT_DOMAIN, "bad alternate root '%s'"), altroot));
   387 
   385 
   388 	if (nvlist_size(nvroot, &len, NV_ENCODE_NATIVE) != 0)
   386 	if (zcmd_write_src_nvlist(hdl, &zc, nvroot, NULL) != 0)
   389 		return (no_memory(hdl));
       
   390 
       
   391 	if ((packed = zfs_alloc(hdl, len)) == NULL)
       
   392 		return (-1);
   387 		return (-1);
   393 
   388 
   394 	if (nvlist_pack(nvroot, &packed, &len,
       
   395 	    NV_ENCODE_NATIVE, 0) != 0) {
       
   396 		free(packed);
       
   397 		return (no_memory(hdl));
       
   398 	}
       
   399 
       
   400 	(void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
   389 	(void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
   401 	zc.zc_config_src = (uint64_t)(uintptr_t)packed;
       
   402 	zc.zc_config_src_size = len;
       
   403 
   390 
   404 	if (altroot != NULL)
   391 	if (altroot != NULL)
   405 		(void) strlcpy(zc.zc_root, altroot, sizeof (zc.zc_root));
   392 		(void) strlcpy(zc.zc_value, altroot, sizeof (zc.zc_value));
   406 
   393 
   407 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_CREATE, &zc) != 0) {
   394 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_CREATE, &zc) != 0) {
   408 		free(packed);
   395 		zcmd_free_nvlists(&zc);
   409 
   396 
   410 		switch (errno) {
   397 		switch (errno) {
   411 		case EBUSY:
   398 		case EBUSY:
   412 			/*
   399 			/*
   413 			 * This can happen if the user has specified the same
   400 			 * This can happen if the user has specified the same
   445 		default:
   432 		default:
   446 			return (zpool_standard_error(hdl, errno, msg));
   433 			return (zpool_standard_error(hdl, errno, msg));
   447 		}
   434 		}
   448 	}
   435 	}
   449 
   436 
   450 	free(packed);
   437 	zcmd_free_nvlists(&zc);
   451 
   438 
   452 	/*
   439 	/*
   453 	 * If this is an alternate root pool, then we automatically set the
   440 	 * If this is an alternate root pool, then we automatically set the
   454 	 * moutnpoint of the root dataset to be '/'.
   441 	 * mountpoint of the root dataset to be '/'.
   455 	 */
   442 	 */
   456 	if (altroot != NULL) {
   443 	if (altroot != NULL) {
   457 		zfs_handle_t *zhp;
   444 		zfs_handle_t *zhp;
   458 
   445 
   459 		verify((zhp = zfs_open(hdl, pool, ZFS_TYPE_ANY)) != NULL);
   446 		verify((zhp = zfs_open(hdl, pool, ZFS_TYPE_ANY)) != NULL);
   460 		verify(zfs_prop_set(zhp, ZFS_PROP_MOUNTPOINT, "/") == 0);
   447 		verify(zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
       
   448 		    "/") == 0);
   461 
   449 
   462 		zfs_close(zhp);
   450 		zfs_close(zhp);
   463 	}
   451 	}
   464 
   452 
   465 	return (0);
   453 	return (0);
   517  * necessary verification to ensure that the vdev specification is well-formed.
   505  * necessary verification to ensure that the vdev specification is well-formed.
   518  */
   506  */
   519 int
   507 int
   520 zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
   508 zpool_add(zpool_handle_t *zhp, nvlist_t *nvroot)
   521 {
   509 {
   522 	char *packed;
   510 	zfs_cmd_t zc = { 0 };
   523 	size_t len;
       
   524 	zfs_cmd_t zc;
       
   525 	int ret;
   511 	int ret;
   526 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   512 	libzfs_handle_t *hdl = zhp->zpool_hdl;
   527 	char msg[1024];
   513 	char msg[1024];
   528 	nvlist_t **spares;
   514 	nvlist_t **spares;
   529 	uint_t nspares;
   515 	uint_t nspares;
   537 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
   523 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "pool must be "
   538 		    "upgraded to add hot spares"));
   524 		    "upgraded to add hot spares"));
   539 		return (zfs_error(hdl, EZFS_BADVERSION, msg));
   525 		return (zfs_error(hdl, EZFS_BADVERSION, msg));
   540 	}
   526 	}
   541 
   527 
   542 	verify(nvlist_size(nvroot, &len, NV_ENCODE_NATIVE) == 0);
   528 	if (zcmd_write_src_nvlist(hdl, &zc, nvroot, NULL) != 0)
   543 
       
   544 	if ((packed = zfs_alloc(zhp->zpool_hdl, len)) == NULL)
       
   545 		return (-1);
   529 		return (-1);
   546 
       
   547 	verify(nvlist_pack(nvroot, &packed, &len, NV_ENCODE_NATIVE, 0) == 0);
       
   548 
       
   549 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   530 	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
   550 	zc.zc_config_src = (uint64_t)(uintptr_t)packed;
       
   551 	zc.zc_config_src_size = len;
       
   552 
   531 
   553 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_ADD, &zc) != 0) {
   532 	if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_ADD, &zc) != 0) {
   554 		switch (errno) {
   533 		switch (errno) {
   555 		case EBUSY:
   534 		case EBUSY:
   556 			/*
   535 			/*
   596 		ret = -1;
   575 		ret = -1;
   597 	} else {
   576 	} else {
   598 		ret = 0;
   577 		ret = 0;
   599 	}
   578 	}
   600 
   579 
   601 	free(packed);
   580 	zcmd_free_nvlists(&zc);
   602 
   581 
   603 	return (ret);
   582 	return (ret);
   604 }
   583 }
   605 
   584 
   606 /*
   585 /*
   633  */
   612  */
   634 int
   613 int
   635 zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
   614 zpool_import(libzfs_handle_t *hdl, nvlist_t *config, const char *newname,
   636     const char *altroot)
   615     const char *altroot)
   637 {
   616 {
   638 	zfs_cmd_t zc;
   617 	zfs_cmd_t zc = { 0 };
   639 	char *packed;
       
   640 	size_t len;
       
   641 	char *thename;
   618 	char *thename;
   642 	char *origname;
   619 	char *origname;
   643 	int ret;
   620 	int ret;
   644 
   621 
   645 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
   622 	verify(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
   661 		    altroot));
   638 		    altroot));
   662 
   639 
   663 	(void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
   640 	(void) strlcpy(zc.zc_name, thename, sizeof (zc.zc_name));
   664 
   641 
   665 	if (altroot != NULL)
   642 	if (altroot != NULL)
   666 		(void) strlcpy(zc.zc_root, altroot, sizeof (zc.zc_root));
   643 		(void) strlcpy(zc.zc_value, altroot, sizeof (zc.zc_value));
   667 	else
   644 	else
   668 		zc.zc_root[0] = '\0';
   645 		zc.zc_value[0] = '\0';
   669 
   646 
   670 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
   647 	verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
   671 	    &zc.zc_guid) == 0);
   648 	    &zc.zc_guid) == 0);
   672 
   649 
   673 	verify(nvlist_size(config, &len, NV_ENCODE_NATIVE) == 0);
   650 	if (zcmd_write_src_nvlist(hdl, &zc, config, NULL) != 0)
   674 
       
   675 	if ((packed = zfs_alloc(hdl, len)) == NULL)
       
   676 		return (-1);
   651 		return (-1);
   677 
       
   678 	verify(nvlist_pack(config, &packed, &len, NV_ENCODE_NATIVE, 0) == 0);
       
   679 
       
   680 	zc.zc_config_src = (uint64_t)(uintptr_t)packed;
       
   681 	zc.zc_config_src_size = len;
       
   682 
   652 
   683 	ret = 0;
   653 	ret = 0;
   684 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_IMPORT, &zc) != 0) {
   654 	if (ioctl(hdl->libzfs_fd, ZFS_IOC_POOL_IMPORT, &zc) != 0) {
   685 		char desc[1024];
   655 		char desc[1024];
   686 		if (newname == NULL)
   656 		if (newname == NULL)
   720 			ret = zpool_create_zvol_links(zhp);
   690 			ret = zpool_create_zvol_links(zhp);
   721 			zpool_close(zhp);
   691 			zpool_close(zhp);
   722 		}
   692 		}
   723 	}
   693 	}
   724 
   694 
   725 	free(packed);
   695 	zcmd_free_nvlists(&zc);
   726 	return (ret);
   696 	return (ret);
   727 }
   697 }
   728 
   698 
   729 /*
   699 /*
   730  * Scrub the pool.
   700  * Scrub the pool.
   977 zpool_vdev_attach(zpool_handle_t *zhp,
   947 zpool_vdev_attach(zpool_handle_t *zhp,
   978     const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing)
   948     const char *old_disk, const char *new_disk, nvlist_t *nvroot, int replacing)
   979 {
   949 {
   980 	zfs_cmd_t zc = { 0 };
   950 	zfs_cmd_t zc = { 0 };
   981 	char msg[1024];
   951 	char msg[1024];
   982 	char *packed;
       
   983 	int ret;
   952 	int ret;
   984 	size_t len;
       
   985 	nvlist_t *tgt;
   953 	nvlist_t *tgt;
   986 	boolean_t avail_spare;
   954 	boolean_t avail_spare;
   987 	uint64_t val;
   955 	uint64_t val;
   988 	char *path;
   956 	char *path;
   989 	nvlist_t **child;
   957 	nvlist_t **child;
  1043 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
  1011 		zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
  1044 		    "device has already been replaced with a spare"));
  1012 		    "device has already been replaced with a spare"));
  1045 		return (zfs_error(hdl, EZFS_BADTARGET, msg));
  1013 		return (zfs_error(hdl, EZFS_BADTARGET, msg));
  1046 	}
  1014 	}
  1047 
  1015 
  1048 	verify(nvlist_size(nvroot, &len, NV_ENCODE_NATIVE) == 0);
  1016 	if (zcmd_write_src_nvlist(hdl, &zc, nvroot, NULL) != 0)
  1049 
       
  1050 	if ((packed = zfs_alloc(zhp->zpool_hdl, len)) == NULL)
       
  1051 		return (-1);
  1017 		return (-1);
  1052 
  1018 
  1053 	verify(nvlist_pack(nvroot, &packed, &len, NV_ENCODE_NATIVE, 0) == 0);
       
  1054 
       
  1055 	zc.zc_config_src = (uint64_t)(uintptr_t)packed;
       
  1056 	zc.zc_config_src_size = len;
       
  1057 
       
  1058 	ret = ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_ATTACH, &zc);
  1019 	ret = ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_ATTACH, &zc);
  1059 
  1020 
  1060 	free(packed);
  1021 	zcmd_free_nvlists(&zc);
  1061 
  1022 
  1062 	if (ret == 0)
  1023 	if (ret == 0)
  1063 		return (0);
  1024 		return (0);
  1064 
  1025 
  1065 	switch (errno) {
  1026 	switch (errno) {
  1222 	libzfs_handle_t *hdl = zhp->zpool_hdl;
  1183 	libzfs_handle_t *hdl = zhp->zpool_hdl;
  1223 
  1184 
  1224 	if (path)
  1185 	if (path)
  1225 		(void) snprintf(msg, sizeof (msg),
  1186 		(void) snprintf(msg, sizeof (msg),
  1226 		    dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
  1187 		    dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
  1227 		    zc.zc_prop_value);
  1188 		    path);
  1228 	else
  1189 	else
  1229 		(void) snprintf(msg, sizeof (msg),
  1190 		(void) snprintf(msg, sizeof (msg),
  1230 		    dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
  1191 		    dgettext(TEXT_DOMAIN, "cannot clear errors for %s"),
  1231 		    zhp->zpool_name);
  1192 		    zhp->zpool_name);
  1232 
  1193 
  1256 
  1217 
  1257 	/*
  1218 	/*
  1258 	 * We check for volblocksize intead of ZFS_TYPE_VOLUME so that we
  1219 	 * We check for volblocksize intead of ZFS_TYPE_VOLUME so that we
  1259 	 * correctly handle snapshots of volumes.
  1220 	 * correctly handle snapshots of volumes.
  1260 	 */
  1221 	 */
  1261 	if (zhp->zfs_volblocksize != 0) {
  1222 	if (ZFS_IS_VOLUME(zhp)) {
  1262 		if (linktype)
  1223 		if (linktype)
  1263 			ret = zvol_create_link(zhp->zfs_hdl, zhp->zfs_name);
  1224 			ret = zvol_create_link(zhp->zfs_hdl, zhp->zfs_name);
  1264 		else
  1225 		else
  1265 			ret = zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name);
  1226 			ret = zvol_remove_link(zhp->zfs_hdl, zhp->zfs_name);
  1266 	}
  1227 	}
  1382 set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path)
  1343 set_path(zpool_handle_t *zhp, nvlist_t *nv, const char *path)
  1383 {
  1344 {
  1384 	zfs_cmd_t zc = { 0 };
  1345 	zfs_cmd_t zc = { 0 };
  1385 
  1346 
  1386 	(void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
  1347 	(void) strncpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
  1387 	(void) strncpy(zc.zc_prop_value, path, sizeof (zc.zc_prop_value));
  1348 	(void) strncpy(zc.zc_value, path, sizeof (zc.zc_value));
  1388 	verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
  1349 	verify(nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID,
  1389 	    &zc.zc_guid) == 0);
  1350 	    &zc.zc_guid) == 0);
  1390 
  1351 
  1391 	(void) ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SETPATH, &zc);
  1352 	(void) ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_VDEV_SETPATH, &zc);
  1392 }
  1353 }
  1492 int
  1453 int
  1493 zpool_get_errlog(zpool_handle_t *zhp, nvlist_t ***list, size_t *nelem)
  1454 zpool_get_errlog(zpool_handle_t *zhp, nvlist_t ***list, size_t *nelem)
  1494 {
  1455 {
  1495 	zfs_cmd_t zc = { 0 };
  1456 	zfs_cmd_t zc = { 0 };
  1496 	uint64_t count;
  1457 	uint64_t count;
  1497 	zbookmark_t *zb;
  1458 	zbookmark_t *zb = NULL;
       
  1459 	libzfs_handle_t *hdl = zhp->zpool_hdl;
  1498 	int i, j;
  1460 	int i, j;
  1499 
  1461 
  1500 	if (zhp->zpool_error_log != NULL) {
  1462 	if (zhp->zpool_error_log != NULL) {
  1501 		*list = zhp->zpool_error_log;
  1463 		*list = zhp->zpool_error_log;
  1502 		*nelem = zhp->zpool_error_count;
  1464 		*nelem = zhp->zpool_error_count;
  1508 	 * has increased, allocate more space and continue until we get the
  1470 	 * has increased, allocate more space and continue until we get the
  1509 	 * entire list.
  1471 	 * entire list.
  1510 	 */
  1472 	 */
  1511 	verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT,
  1473 	verify(nvlist_lookup_uint64(zhp->zpool_config, ZPOOL_CONFIG_ERRCOUNT,
  1512 	    &count) == 0);
  1474 	    &count) == 0);
  1513 	if ((zc.zc_config_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl,
  1475 	if ((zc.zc_nvlist_dst = (uintptr_t)zfs_alloc(zhp->zpool_hdl,
  1514 	    count * sizeof (zbookmark_t))) == NULL)
  1476 	    count * sizeof (zbookmark_t))) == NULL)
  1515 		return (-1);
  1477 		return (-1);
  1516 	zc.zc_config_dst_size = count;
  1478 	zc.zc_nvlist_dst_size = count;
  1517 	(void) strcpy(zc.zc_name, zhp->zpool_name);
  1479 	(void) strcpy(zc.zc_name, zhp->zpool_name);
  1518 	for (;;) {
  1480 	for (;;) {
  1519 		if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_ERROR_LOG,
  1481 		if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_ERROR_LOG,
  1520 		    &zc) != 0) {
  1482 		    &zc) != 0) {
  1521 			free((void *)(uintptr_t)zc.zc_config_dst);
  1483 			free((void *)(uintptr_t)zc.zc_nvlist_dst);
  1522 			if (errno == ENOMEM) {
  1484 			if (errno == ENOMEM) {
  1523 				if ((zc.zc_config_dst = (uintptr_t)
  1485 				if ((zc.zc_nvlist_dst = (uintptr_t)
  1524 				    zfs_alloc(zhp->zpool_hdl,
  1486 				    zfs_alloc(zhp->zpool_hdl,
  1525 				    zc.zc_config_dst_size)) == NULL)
  1487 				    zc.zc_nvlist_dst_size)) == NULL)
  1526 					return (-1);
  1488 					return (-1);
  1527 			} else {
  1489 			} else {
  1528 				return (-1);
  1490 				return (-1);
  1529 			}
  1491 			}
  1530 		} else {
  1492 		} else {
  1533 	}
  1495 	}
  1534 
  1496 
  1535 	/*
  1497 	/*
  1536 	 * Sort the resulting bookmarks.  This is a little confusing due to the
  1498 	 * Sort the resulting bookmarks.  This is a little confusing due to the
  1537 	 * implementation of ZFS_IOC_ERROR_LOG.  The bookmarks are copied last
  1499 	 * implementation of ZFS_IOC_ERROR_LOG.  The bookmarks are copied last
  1538 	 * to first, and 'zc_config_dst_size' indicates the number of boomarks
  1500 	 * to first, and 'zc_nvlist_dst_size' indicates the number of boomarks
  1539 	 * _not_ copied as part of the process.  So we point the start of our
  1501 	 * _not_ copied as part of the process.  So we point the start of our
  1540 	 * array appropriate and decrement the total number of elements.
  1502 	 * array appropriate and decrement the total number of elements.
  1541 	 */
  1503 	 */
  1542 	zb = ((zbookmark_t *)(uintptr_t)zc.zc_config_dst) +
  1504 	zb = ((zbookmark_t *)(uintptr_t)zc.zc_nvlist_dst) +
  1543 	    zc.zc_config_dst_size;
  1505 	    zc.zc_nvlist_dst_size;
  1544 	count -= zc.zc_config_dst_size;
  1506 	count -= zc.zc_nvlist_dst_size;
       
  1507 	zc.zc_nvlist_dst = 0ULL;
  1545 
  1508 
  1546 	qsort(zb, count, sizeof (zbookmark_t), zbookmark_compare);
  1509 	qsort(zb, count, sizeof (zbookmark_t), zbookmark_compare);
  1547 
  1510 
  1548 	/*
  1511 	/*
  1549 	 * Count the number of unique elements
  1512 	 * Count the number of unique elements
  1560 	 * If the user has only requested the number of items, return it now
  1523 	 * If the user has only requested the number of items, return it now
  1561 	 * without bothering with the extra work.
  1524 	 * without bothering with the extra work.
  1562 	 */
  1525 	 */
  1563 	if (list == NULL) {
  1526 	if (list == NULL) {
  1564 		*nelem = j;
  1527 		*nelem = j;
  1565 		free((void *)(uintptr_t)zc.zc_config_dst);
  1528 		free((void *)(uintptr_t)zc.zc_nvlist_dst);
  1566 		return (0);
  1529 		return (0);
  1567 	}
  1530 	}
  1568 
  1531 
  1569 	zhp->zpool_error_count = j;
  1532 	zhp->zpool_error_count = j;
  1570 
  1533 
  1571 	/*
  1534 	/*
  1572 	 * Allocate an array of nvlists to hold the results
  1535 	 * Allocate an array of nvlists to hold the results
  1573 	 */
  1536 	 */
  1574 	if ((zhp->zpool_error_log = zfs_alloc(zhp->zpool_hdl,
  1537 	if ((zhp->zpool_error_log = zfs_alloc(zhp->zpool_hdl,
  1575 	    j * sizeof (nvlist_t *))) == NULL) {
  1538 	    j * sizeof (nvlist_t *))) == NULL) {
  1576 		free((void *)(uintptr_t)zc.zc_config_dst);
  1539 		free((void *)(uintptr_t)zc.zc_nvlist_dst);
  1577 		return (-1);
  1540 		return (-1);
  1578 	}
  1541 	}
  1579 
  1542 
  1580 	/*
  1543 	/*
  1581 	 * Fill in the results with names from the kernel.
  1544 	 * Fill in the results with names from the kernel.
  1587 
  1550 
  1588 		if (i > 0 && memcmp(&zb[i - 1], &zb[i],
  1551 		if (i > 0 && memcmp(&zb[i - 1], &zb[i],
  1589 		    sizeof (zbookmark_t)) == 0)
  1552 		    sizeof (zbookmark_t)) == 0)
  1590 			continue;
  1553 			continue;
  1591 
  1554 
  1592 		if (nvlist_alloc(&nv, NV_UNIQUE_NAME,
  1555 		if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
  1593 		    0) != 0)
       
  1594 			goto nomem;
  1556 			goto nomem;
  1595 		zhp->zpool_error_log[j] = nv;
       
  1596 
  1557 
  1597 		zc.zc_bookmark = zb[i];
  1558 		zc.zc_bookmark = zb[i];
  1598 		if (ioctl(zhp->zpool_hdl->libzfs_fd, ZFS_IOC_BOOKMARK_NAME,
  1559 		for (;;) {
  1599 		    &zc) == 0) {
  1560 			if (ioctl(zhp->zpool_hdl->libzfs_fd,
  1600 			if (nvlist_add_string(nv, ZPOOL_ERR_DATASET,
  1561 			    ZFS_IOC_BOOKMARK_NAME, &zc) != 0) {
  1601 			    zc.zc_prop_name) != 0 ||
  1562 				if (errno == ENOMEM) {
  1602 			    nvlist_add_string(nv, ZPOOL_ERR_OBJECT,
  1563 					if (zcmd_expand_dst_nvlist(hdl, &zc)
  1603 			    zc.zc_prop_value) != 0 ||
  1564 					    != 0) {
  1604 			    nvlist_add_string(nv, ZPOOL_ERR_RANGE,
  1565 						zcmd_free_nvlists(&zc);
  1605 			    zc.zc_filename) != 0)
  1566 						goto nomem;
  1606 				goto nomem;
  1567 					}
  1607 		} else {
  1568 
  1608 			(void) snprintf(buf, sizeof (buf), "%llx",
  1569 					continue;
  1609 			    zb[i].zb_objset);
  1570 				} else {
  1610 			if (nvlist_add_string(nv,
  1571 					if (nvlist_alloc(&nv, NV_UNIQUE_NAME,
  1611 			    ZPOOL_ERR_DATASET, buf) != 0)
  1572 					    0) != 0)
  1612 				goto nomem;
  1573 						goto nomem;
  1613 			(void) snprintf(buf, sizeof (buf), "%llx",
  1574 
  1614 			    zb[i].zb_object);
  1575 					zhp->zpool_error_log[j] = nv;
  1615 			if (nvlist_add_string(nv, ZPOOL_ERR_OBJECT,
  1576 					(void) snprintf(buf, sizeof (buf),
  1616 			    buf) != 0)
  1577 					    "%llx", zb[i].zb_objset);
  1617 				goto nomem;
  1578 					if (nvlist_add_string(nv,
  1618 			(void) snprintf(buf, sizeof (buf), "lvl=%u blkid=%llu",
  1579 					    ZPOOL_ERR_DATASET, buf) != 0)
  1619 			    (int)zb[i].zb_level, (long long)zb[i].zb_blkid);
  1580 						goto nomem;
  1620 			if (nvlist_add_string(nv, ZPOOL_ERR_RANGE,
  1581 					(void) snprintf(buf, sizeof (buf),
  1621 			    buf) != 0)
  1582 					    "%llx", zb[i].zb_object);
  1622 				goto nomem;
  1583 					if (nvlist_add_string(nv,
       
  1584 					    ZPOOL_ERR_OBJECT, buf) != 0)
       
  1585 						goto nomem;
       
  1586 					(void) snprintf(buf, sizeof (buf),
       
  1587 					    "lvl=%u blkid=%llu",
       
  1588 					    (int)zb[i].zb_level,
       
  1589 					    (long long)zb[i].zb_blkid);
       
  1590 					if (nvlist_add_string(nv,
       
  1591 					    ZPOOL_ERR_RANGE, buf) != 0)
       
  1592 						goto nomem;
       
  1593 				}
       
  1594 			} else {
       
  1595 				if (zcmd_read_dst_nvlist(hdl, &zc,
       
  1596 				    &zhp->zpool_error_log[j]) != 0) {
       
  1597 					zcmd_free_nvlists(&zc);
       
  1598 					goto nomem;
       
  1599 				}
       
  1600 			}
       
  1601 
       
  1602 			break;
  1623 		}
  1603 		}
       
  1604 
       
  1605 		zcmd_free_nvlists(&zc);
  1624 
  1606 
  1625 		j++;
  1607 		j++;
  1626 	}
  1608 	}
  1627 
  1609 
  1628 	*list = zhp->zpool_error_log;
  1610 	*list = zhp->zpool_error_log;
  1629 	*nelem = zhp->zpool_error_count;
  1611 	*nelem = zhp->zpool_error_count;
  1630 
  1612 	free(zb);
  1631 	free((void *)(uintptr_t)zc.zc_config_dst);
       
  1632 
  1613 
  1633 	return (0);
  1614 	return (0);
  1634 
  1615 
  1635 nomem:
  1616 nomem:
  1636 	free((void *)(uintptr_t)zc.zc_config_dst);
  1617 	free(zb);
  1637 	for (i = 0; i < zhp->zpool_error_count; i++) {
  1618 	free((void *)(uintptr_t)zc.zc_nvlist_dst);
  1638 		if (zhp->zpool_error_log[i])
  1619 	for (i = 0; i < zhp->zpool_error_count; i++)
  1639 			free(zhp->zpool_error_log[i]);
  1620 		nvlist_free(zhp->zpool_error_log[i]);
  1640 	}
       
  1641 	free(zhp->zpool_error_log);
  1621 	free(zhp->zpool_error_log);
  1642 	zhp->zpool_error_log = NULL;
  1622 	zhp->zpool_error_log = NULL;
  1643 	return (no_memory(zhp->zpool_hdl));
  1623 	return (no_memory(zhp->zpool_hdl));
  1644 }
  1624 }
  1645 
  1625