diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c index 66ccf4a..62ea18f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c @@ -3755,6 +3755,165 @@ out: #else +#ifdef DEBUG +static void +print_nvlist_sbuf(nvlist_t *nvl, struct sbuf *sb, uint_t depth) +{ + nvpair_t *elem = NULL; + + while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) { + uint_t j; + + for (j = 0; j < depth; j++) + sbuf_printf(sb, "\t"); + sbuf_printf(sb, "%s:", nvpair_name(elem)); + + switch (nvpair_type(elem)) { + case DATA_TYPE_BOOLEAN: + { + boolean_t value; + + (void) nvpair_value_boolean_value(elem, &value); + sbuf_printf(sb, " %s", + value ? "true" : "false"); + break; + } + case DATA_TYPE_UINT8: + { + uint8_t value; + + (void) nvpair_value_uint8(elem, &value); + sbuf_printf(sb, " %hhu", value); + break; + } + case DATA_TYPE_INT32: + { + int32_t value; + + (void) nvpair_value_int32(elem, &value); + sbuf_printf(sb, " %jd", + (intmax_t)value); + break; + } + case DATA_TYPE_UINT32: + { + uint32_t value; + + (void) nvpair_value_uint32(elem, &value); + sbuf_printf(sb, " %ju", + (uintmax_t)value); + break; + } + case DATA_TYPE_INT64: + { + int64_t value; + + (void) nvpair_value_int64(elem, &value); + sbuf_printf(sb, " %jd", + (intmax_t)value); + break; + } + case DATA_TYPE_UINT64: + { + uint64_t value; + + (void) nvpair_value_uint64(elem, &value); + sbuf_printf(sb, " %ju", + (uintmax_t)value); + break; + } + case DATA_TYPE_STRING: + { + char *value; + + (void) nvpair_value_string(elem, &value); + sbuf_printf(sb, " %s", value); + break; + } + case DATA_TYPE_NVLIST: + { + nvlist_t *value; + + (void) nvpair_value_nvlist(elem, &value); + sbuf_printf(sb, "\n"); + print_nvlist_sbuf(value, sb, depth + 1); + break; + } + case DATA_TYPE_UINT8_ARRAY: + { + uint8_t *value; + uint_t ii, nelem; + + (void) nvpair_value_uint8_array(elem, &value, &nelem); + for (ii = 0; ii < nelem; ii++) + sbuf_printf(sb, "%02hhx,", value[ii]); + break; + } + case DATA_TYPE_UINT16_ARRAY: + { + uint16_t *value; + uint_t ii, nelem; + + (void) nvpair_value_uint16_array(elem, &value, &nelem); + for (ii = 0; ii < nelem; ii++) + sbuf_printf(sb, "%04hx,", value[ii]); + break; + } + case DATA_TYPE_UINT32_ARRAY: + { + uint32_t *value; + uint_t ii, nelem; + + (void) nvpair_value_uint32_array(elem, &value, &nelem); + for (ii = 0; ii < nelem; ii++) + sbuf_printf(sb, "%08jx,", (uintmax_t)value[ii]); + break; + } + case DATA_TYPE_UINT64_ARRAY: + { + uint64_t *value; + uint_t ii, nelem; + + (void) nvpair_value_uint64_array(elem, &value, &nelem); + for (ii = 0; ii < nelem; ii++) + sbuf_printf(sb, "%016jx,", (uintmax_t)value[ii]); + break; + } + case DATA_TYPE_STRING_ARRAY: + { + char **value; + uint_t ii, nelem; + + (void) nvpair_value_string_array(elem, &value, &nelem); + for (ii = 0; ii < nelem; ii++) + sbuf_printf(sb, "'%s',", value[ii]); + break; + } + case DATA_TYPE_NVLIST_ARRAY: + { + nvlist_t **value; + uint_t ii, nelem; + + (void) nvpair_value_nvlist_array(elem, &value, &nelem); + sbuf_printf(sb, "\n"); + for (ii = 0; ii < nelem; ii++) { + for (j = 0; j < depth; j++) + sbuf_printf(sb, "\t"); + sbuf_printf(sb, "%s[%u]:\n", nvpair_name(elem), ii); + print_nvlist_sbuf(value[ii], sb, depth + 1); + } + break; + } + default: + sbuf_printf(sb, " ", + nvpair_type(elem)); + break; + } + sbuf_printf(sb, "\n"); + } +} +#endif + extern int vdev_geom_read_pool_label(const char *name, nvlist_t ***configs, uint64_t *count); @@ -3857,6 +4016,12 @@ spa_generate_rootconf(const char *name) */ VERIFY(nvlist_add_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, nvroot) == 0); + /* + * Drop vdev config elements that can not be present at pool level. + */ + nvlist_remove(config, ZPOOL_CONFIG_GUID, DATA_TYPE_UINT64); + nvlist_remove(config, ZPOOL_CONFIG_TOP_GUID, DATA_TYPE_UINT64); + for (i = 0; i < count; i++) nvlist_free(configs[i]); kmem_free(configs, count * sizeof(void *)); @@ -3864,6 +4029,25 @@ spa_generate_rootconf(const char *name) nvlist_free(tops[i]); kmem_free(tops, nchildren * sizeof(void *)); nvlist_free(nvroot); +#ifdef DEBUG + do { + struct sbuf *sb; + + sb = sbuf_new_auto(); + if (sb == NULL) + break; + + print_nvlist_sbuf(config, sb, 0); + + if (sbuf_finish(sb) != 0) { + sbuf_delete(sb); + break; + } + + printf("Reconstructed root pool config:\n%s\n", sbuf_data(sb)); + sbuf_delete(sb); + } while (0); +#endif return (config); }