diff --git a/src/utils/ddb/ddb_commands.c b/src/utils/ddb/ddb_commands.c index 04cdd4e41ce..ddd1a581601 100644 --- a/src/utils/ddb/ddb_commands.c +++ b/src/utils/ddb/ddb_commands.c @@ -306,7 +306,7 @@ print_value_cb(void *cb_args, d_iov_t *value) return 0; } - ddb_iov_to_printable_buf(value, buf, ARRAY_SIZE(buf)); + ddb_iov_to_printable_buf(value, buf, ARRAY_SIZE(buf), NULL); ddb_printf(ctx, "Value (size: %lu):\n", value->iov_len); ddb_printf(ctx, "%s\n", buf); return 0; diff --git a/src/utils/ddb/ddb_parse.h b/src/utils/ddb/ddb_parse.h index 439791823a2..fad1a828fab 100644 --- a/src/utils/ddb/ddb_parse.h +++ b/src/utils/ddb/ddb_parse.h @@ -44,7 +44,7 @@ void ddb_str2argv_free(struct argv_parsed *parse_args); int ddb_parse_program_args(struct ddb_ctx *ctx, uint32_t argc, char **argv, struct program_args *pa); -/* See ddb_iov_to_printable_buf for how the keys will be printed */ +/* See ddb_key_to_printable_buf for how the keys will be printed */ int ddb_parse_key(const char *input, daos_key_t *key); /* Parse a string into the parts of a dtx_id. See DF_DTIF for how the format of the dtx_id is diff --git a/src/utils/ddb/ddb_printer.c b/src/utils/ddb/ddb_printer.c index dd78efbb481..60c4be27da4 100644 --- a/src/utils/ddb/ddb_printer.c +++ b/src/utils/ddb/ddb_printer.c @@ -24,69 +24,91 @@ ddb_can_print(d_iov_t *iov) uint32_t len = iov->iov_len; int i; - for (i = 0 ; i < len ; i++) { + for (i = 0; i < len; i++) { if (str[i] == '\0') return true; - if (!isprint(str[i]) && str[i] != '\n' && str[i] != '\r') + if (!isprint(str[i])) return false; } return true; } /* - * Converts contents of an iov to something that is more printable. + * Converts contents of an @iov to something that is more printable. * - * Returns number of characters that would have been written if buf_len was long - * enough, not including null terminator + * Returns number of characters that would have been written if @buf is large enough, + * not including the null terminator. */ -int -ddb_iov_to_printable_buf(d_iov_t *iov, char buf[], uint32_t buf_len) +uint32_t +ddb_iov_to_printable_buf(d_iov_t *iov, char buf[], uint32_t buf_len, const char *prefix) { + char tmp[32]; + uint32_t new_len; + uint32_t result = 0; + int i; + if (iov->iov_len == 0 || iov->iov_buf == NULL) return 0; if (ddb_can_print(iov)) return snprintf(buf, buf_len, "%.*s", (int)iov->iov_len, (char *)iov->iov_buf); - switch (iov->iov_len) { - case sizeof(uint8_t): - return snprintf(buf, buf_len, "uint8:0x%x", ((uint8_t *)iov->iov_buf)[0]); - case sizeof(uint16_t): - return snprintf(buf, buf_len, "uint16:0x%04hx", ((uint16_t *)iov->iov_buf)[0]); - case sizeof(uint32_t): - return snprintf(buf, buf_len, "uint32:0x%x", ((uint32_t *)iov->iov_buf)[0]); - case sizeof(uint64_t): - return snprintf(buf, buf_len, "uint64:0x%lx", ((uint64_t *)iov->iov_buf)[0]); - default: - { - char tmp_buf[32]; - uint32_t new_len; - uint32_t result = 0; - int i; - - result += snprintf(buf, buf_len, "bin(%lu):0x", iov->iov_len); - - for (i = 0; i < iov->iov_len; i++) { - new_len = snprintf(tmp_buf, ARRAY_SIZE(tmp_buf), "%02x", - ((uint8_t *)iov->iov_buf)[i]); - if (new_len + result > buf_len) { - /* Buffer not big enough */ - result += new_len; - } else { - result += sprintf(buf + result, "%s", tmp_buf); - } - } + if (prefix != NULL) + result = snprintf(buf, buf_len, "%s", prefix); - if (result > buf_len) { - buf[buf_len - 1] = '\0'; - buf[buf_len - 2] = '.'; - buf[buf_len - 3] = '.'; - buf[buf_len - 4] = '.'; + for (i = 0; i < iov->iov_len; i++) { + new_len = snprintf(tmp, ARRAY_SIZE(tmp), "%02x", ((uint8_t *)iov->iov_buf)[i]); + if (new_len + result > buf_len) + result += new_len; /* Buffer is not big enough. */ + else + result += sprintf(buf + result, "%s", tmp); + } - } - return result; + if (result > buf_len) { + buf[buf_len - 1] = '\0'; + for (i = 2; buf_len >= i && i <= 4; i++) + buf[buf_len - i] = '.'; } + + return result; +} + +/* + * Converts contents of an @key to something that is more printable. + * + * Returns number of characters that would have been written if @buf is long enough, + * not including the null terminator. + */ +uint32_t +ddb_key_to_printable_buf(daos_key_t *key, enum daos_otype_t otype, char buf[], uint32_t buf_len) +{ + char tmp[32]; + + if (key->iov_len == 0 || key->iov_buf == NULL) + return 0; + + if (ddb_key_is_lexical(otype)) + return snprintf(buf, buf_len, "%.*s", (int)key->iov_len, (char *)key->iov_buf); + + if (ddb_key_is_int(otype)) { + switch (key->iov_len) { + case sizeof(uint8_t): + return snprintf(buf, buf_len, "uint8:0x%x", ((uint8_t *)key->iov_buf)[0]); + case sizeof(uint16_t): + return snprintf(buf, buf_len, "uint16:0x%04hx", + ((uint16_t *)key->iov_buf)[0]); + case sizeof(uint32_t): + return snprintf(buf, buf_len, "uint32:0x%x", ((uint32_t *)key->iov_buf)[0]); + case sizeof(uint64_t): + return snprintf(buf, buf_len, "uint64:0x%lx", + ((uint64_t *)key->iov_buf)[0]); + /* Fall through. */ + } } + + snprintf(tmp, ARRAY_SIZE(tmp), "bin(%lu):0x", key->iov_len); + + return ddb_iov_to_printable_buf(key, buf, buf_len, tmp); } void @@ -115,22 +137,22 @@ ddb_print_key(struct ddb_ctx *ctx, struct ddb_key *key, uint32_t indent) memset(buf, 0, buf_len); - ddb_iov_to_printable_buf(&key->ddbk_key, buf, buf_len); + ddb_key_to_printable_buf(&key->ddbk_key, key->ddbk_otype, buf, buf_len); print_indent(ctx, indent); - if (ddb_can_print(&key->ddbk_key)) { - ddb_printf(ctx, DF_IDX" '%s' (%lu)%s\n", - DP_IDX(key->ddbk_idx), - buf, - key->ddbk_key.iov_len, - key->ddbk_child_type == VOS_ITER_SINGLE ? " (SV)" : - key->ddbk_child_type == VOS_ITER_RECX ? " (ARRAY)" : ""); - return; - } - ddb_printf(ctx, DF_IDX" {%s}%s\n", DP_IDX(key->ddbk_idx), buf, - key->ddbk_child_type == VOS_ITER_SINGLE ? " (SV)" : - key->ddbk_child_type == VOS_ITER_RECX ? " (ARRAY)" : ""); + if (ddb_key_is_lexical(key->ddbk_otype) || + (!ddb_key_is_int(key->ddbk_otype) && ddb_can_print(&key->ddbk_key))) + ddb_printf(ctx, DF_IDX " '%s' (%lu)%s\n", DP_IDX(key->ddbk_idx), buf, + key->ddbk_key.iov_len, + key->ddbk_child_type == VOS_ITER_SINGLE ? " (SV)" + : key->ddbk_child_type == VOS_ITER_RECX ? " (ARRAY)" + : ""); + else + ddb_printf(ctx, DF_IDX " {%s}%s\n", DP_IDX(key->ddbk_idx), buf, + key->ddbk_child_type == VOS_ITER_SINGLE ? " (SV)" + : key->ddbk_child_type == VOS_ITER_RECX ? " (ARRAY)" + : ""); } void diff --git a/src/utils/ddb/ddb_printer.h b/src/utils/ddb/ddb_printer.h index 5c6cc5a7332..642b1fcf156 100644 --- a/src/utils/ddb/ddb_printer.h +++ b/src/utils/ddb/ddb_printer.h @@ -1,5 +1,6 @@ /** * (C) Copyright 2022 Intel Corporation. + * (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -12,7 +13,10 @@ #define DF_IDX "[%d]" #define DP_IDX(idx) idx -int ddb_iov_to_printable_buf(d_iov_t *iov, char buf[], uint32_t buf_len); +uint32_t +ddb_iov_to_printable_buf(d_iov_t *iov, char buf[], uint32_t buf_len, const char *prefix); +uint32_t +ddb_key_to_printable_buf(daos_key_t *key, enum daos_otype_t otype, char buf[], uint32_t buf_len); void ddb_print_cont(struct ddb_ctx *ctx, struct ddb_cont *cont); void ddb_print_obj(struct ddb_ctx *ctx, struct ddb_obj *obj, uint32_t indent); void ddb_print_key(struct ddb_ctx *ctx, struct ddb_key *key, uint32_t indent); @@ -29,5 +33,16 @@ bool ddb_can_print(d_iov_t *iov); /* some utility functions helpful for printing */ void ddb_bytes_hr(uint64_t bytes, char *buf, uint32_t buf_len); +static inline bool +ddb_key_is_lexical(enum daos_otype_t otype) +{ + return daos_is_dkey_lexical_type(otype) || daos_is_akey_lexical_type(otype); +} + +static inline bool +ddb_key_is_int(enum daos_otype_t otype) +{ + return daos_is_dkey_uint64_type(otype) || daos_is_akey_uint64_type(otype); +} #endif /* DAOS_DDB_PRINTER_H */ diff --git a/src/utils/ddb/ddb_tree_path.c b/src/utils/ddb/ddb_tree_path.c index 3bfc104424e..6a45e025ff8 100644 --- a/src/utils/ddb/ddb_tree_path.c +++ b/src/utils/ddb/ddb_tree_path.c @@ -304,58 +304,55 @@ itp_parse(const char *path, struct dv_indexed_tree_path *itp) } bool -itp_part_set_cont(union itp_part_type *part, void *part_value) +itp_part_set_cont(struct indexed_tree_path_part *part, void *part_value) { const uint8_t *cont_uuid = part_value; if (cont_uuid == NULL || uuid_is_null(cont_uuid)) return false; - uuid_copy(part->itp_uuid, cont_uuid); + uuid_copy(part->itp_part_value.itp_uuid, cont_uuid); return true; } bool -itp_part_set_obj(union itp_part_type *part, void *part_value) +itp_part_set_obj(struct indexed_tree_path_part *part, void *part_value) { daos_unit_oid_t *oid = part_value; if (daos_unit_oid_is_null(*oid)) return false; - part->itp_oid = *oid; + part->itp_part_value.itp_oid = *oid; + part->itp_otype = daos_obj_id2type(oid->id_pub); return true; } bool -itp_part_set_key(union itp_part_type *part, void *part_value) +itp_part_set_key(struct indexed_tree_path_part *part, void *part_value) { daos_key_t *key = part_value; if (key->iov_len == 0) return false; - daos_iov_copy(&part->itp_key, key); + daos_iov_copy(&part->itp_part_value.itp_key, key); return true; } bool -itp_part_set_recx(union itp_part_type *part, void *part_value) +itp_part_set_recx(struct indexed_tree_path_part *part, void *part_value) { daos_recx_t *recx = part_value; if (recx->rx_nr == 0) return false; - part->itp_recx = *recx; + part->itp_part_value.itp_recx = *recx; return true; } -static bool (*part_set_fn[PATH_PART_END])(union itp_part_type *part, void *part_value) = { - itp_part_set_cont, - itp_part_set_obj, - itp_part_set_key, - itp_part_set_key, - itp_part_set_recx, +static bool (*part_set_fn[PATH_PART_END])(struct indexed_tree_path_part *part, void *part_value) = { + itp_part_set_cont, itp_part_set_obj, itp_part_set_key, itp_part_set_key, itp_part_set_recx, }; bool @@ -363,7 +360,7 @@ itp_part_value_set(struct dv_indexed_tree_path *itp, enum path_parts part_key, v { struct indexed_tree_path_part *p = &itp->itp_parts[part_key]; - if (part_set_fn[part_key](&p->itp_part_value, part_value)) { + if (part_set_fn[part_key](p, part_value)) { p->itp_has_part_value = true; return true; } @@ -779,15 +776,15 @@ dvp_is_empty(struct dv_tree_path *vtp) */ void -itp_print_part_cont(struct ddb_ctx *ctx, union itp_part_type *v) +itp_print_part_cont(struct ddb_ctx *ctx, struct indexed_tree_path_part *v) { - ddb_printf(ctx, DF_UUIDF, DP_UUID(v->itp_uuid)); + ddb_printf(ctx, DF_UUIDF, DP_UUID(v->itp_part_value.itp_uuid)); } void -itp_print_part_obj(struct ddb_ctx *ctx, union itp_part_type *v) +itp_print_part_obj(struct ddb_ctx *ctx, struct indexed_tree_path_part *v) { - ddb_printf(ctx, DF_UOID, DP_UOID(v->itp_oid)); + ddb_printf(ctx, DF_UOID, DP_UOID(v->itp_part_value.itp_oid)); } bool @@ -807,7 +804,8 @@ itp_key_safe_str(char *buf, size_t buf_len) bool escaped = false; if (tmp_idx + 1 >= tmp_end) { /* +1 for escape character if needed */ - D_ERROR("Buffer was too small to hold the escape characters"); + D_ERROR("Buffer (%ld) was too small to hold the escape characters\n", + buf_len); return false; } for (e = 0; e < ARRAY_SIZE(escape_chars) && !escaped; ++e) { @@ -828,20 +826,36 @@ itp_key_safe_str(char *buf, size_t buf_len) } void -itp_print_part_key(struct ddb_ctx *ctx, union itp_part_type *key_part) -{ - char buf[DDB_MAX_PRITABLE_KEY]; - d_iov_t *key_iov = &key_part->itp_key; +itp_print_part_key(struct ddb_ctx *ctx, struct indexed_tree_path_part *part) +{ + char buf[DDB_MAX_PRITABLE_KEY]; + d_iov_t *key_iov = &part->itp_part_value.itp_key; + char *ptr = buf; + uint32_t len; + + len = ddb_key_to_printable_buf(key_iov, part->itp_otype, buf, ARRAY_SIZE(buf)); + if (len > ARRAY_SIZE(buf)) { + len += 2; /* +2 for escape character if needed and null terminator. */ + D_ALLOC(ptr, len); + if (ptr == NULL) { + D_ERROR("NOT enough DRAM for print key: len = %u\n", len); + return; + } - ddb_iov_to_printable_buf(key_iov, buf, ARRAY_SIZE(buf)); - if (ddb_can_print(key_iov)) { + ddb_key_to_printable_buf(key_iov, part->itp_otype, ptr, len); + } else { + len = ARRAY_SIZE(buf); + } + + if (ddb_key_is_lexical(part->itp_otype) || + (!ddb_key_is_int(part->itp_otype) && ddb_can_print(key_iov))) { /* +1 to make sure there's room for a null terminator */ - char key_str[key_part->itp_key.iov_len + 1]; + char key_str[key_iov->iov_len + 1]; memcpy(key_str, key_iov->iov_buf, key_iov->iov_len); key_str[key_iov->iov_len] = '\0'; /* buffer should be plenty big, but just in case ... */ - if (!itp_key_safe_str(buf, ARRAY_SIZE(buf))) { + if (!itp_key_safe_str(ptr, len)) { ddb_print(ctx, "(ISSUE PRINTING KEY)"); return; } @@ -849,27 +863,27 @@ itp_print_part_key(struct ddb_ctx *ctx, union itp_part_type *key_part) * parsing the string into a valid key will work */ if (key_iov->iov_len != strlen(key_str)) - ddb_printf(ctx, "%s{%lu}", buf, key_iov->iov_len); + ddb_printf(ctx, "%s{%lu}", ptr, key_iov->iov_len); else - ddb_printf(ctx, "%s", buf); + ddb_printf(ctx, "%s", ptr); } else { - /* is an int or binary and already formatted in iov_to_pritable_buf */ - ddb_printf(ctx, "{%s}", buf); + /* is an int or binary and already formatted in ddb_key_to_printable_buf */ + ddb_printf(ctx, "{%s}", ptr); } + + if (ptr != buf) + D_FREE(ptr); } void -itp_print_part_recx(struct ddb_ctx *ctx, union itp_part_type *v) +itp_print_part_recx(struct ddb_ctx *ctx, struct indexed_tree_path_part *v) { - ddb_printf(ctx, DF_DDB_RECX, DP_DDB_RECX(v->itp_recx)); + ddb_printf(ctx, DF_DDB_RECX, DP_DDB_RECX(v->itp_part_value.itp_recx)); } -static void (*print_fn[PATH_PART_END])(struct ddb_ctx *ctx, union itp_part_type *v) = { - itp_print_part_cont, - itp_print_part_obj, - itp_print_part_key, - itp_print_part_key, - itp_print_part_recx, +static void (*print_fn[PATH_PART_END])(struct ddb_ctx *ctx, struct indexed_tree_path_part *v) = { + itp_print_part_cont, itp_print_part_obj, itp_print_part_key, + itp_print_part_key, itp_print_part_recx, }; void @@ -886,7 +900,7 @@ itp_print_parts(struct ddb_ctx *ctx, struct dv_indexed_tree_path *itp) if (!itp->itp_parts[i].itp_has_part_value) break; ddb_print(ctx, "/"); - print_fn[i](ctx, &itp->itp_parts[i].itp_part_value); + print_fn[i](ctx, &itp->itp_parts[i]); } } diff --git a/src/utils/ddb/ddb_tree_path.h b/src/utils/ddb/ddb_tree_path.h index af8c3d92dcf..9b5aced6184 100644 --- a/src/utils/ddb/ddb_tree_path.h +++ b/src/utils/ddb/ddb_tree_path.h @@ -1,5 +1,6 @@ /** * (C) Copyright 2023 Intel Corporation. + * (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -51,10 +52,11 @@ struct indexed_tree_path_part { daos_unit_oid_t itp_oid; daos_key_t itp_key; /* akey or dkey */ daos_recx_t itp_recx; - } itp_part_value; - uint32_t itp_part_idx; - bool itp_has_part_idx; - bool itp_has_part_value; + } itp_part_value; + uint32_t itp_part_idx; + enum daos_otype_t itp_otype; + bool itp_has_part_idx; + bool itp_has_part_value; }; struct dv_indexed_tree_path { @@ -93,10 +95,14 @@ bool itp_idx_set(struct dv_indexed_tree_path *itp, enum path_parts part_key, uint32_t idx); /* Functions for setting parts as a specific path part (i.e. container, object, ... */ -bool itp_part_set_cont(union itp_part_type *part, void *part_value); -bool itp_part_set_obj(union itp_part_type *part, void *part_value); -bool itp_part_set_key(union itp_part_type *part, void *part_value); -bool itp_part_set_recx(union itp_part_type *part, void *part_value); +bool +itp_part_set_cont(struct indexed_tree_path_part *part, void *part_value); +bool +itp_part_set_obj(struct indexed_tree_path_part *part, void *part_value); +bool +itp_part_set_key(struct indexed_tree_path_part *part, void *part_value); +bool + itp_part_set_recx(struct indexed_tree_path_part *part, void *part_value); /* Functions for setting the parts (cont, obj, ...) of a indexed tree path */ bool itp_set_cont(struct dv_indexed_tree_path *itp, uuid_t cont_uuid, uint32_t idx); @@ -171,7 +177,8 @@ int itp_recx_idx(struct dv_indexed_tree_path *itp); void itp_print_indexes(struct ddb_ctx *ctx, struct dv_indexed_tree_path *itp); void itp_print_parts(struct ddb_ctx *ctx, struct dv_indexed_tree_path *itp); void itp_print_full(struct ddb_ctx *ctx, struct dv_indexed_tree_path *itp); -void itp_print_part_key(struct ddb_ctx *ctx, union itp_part_type *key_part); +void + itp_print_part_key(struct ddb_ctx *ctx, struct indexed_tree_path_part *part); /* * This function is used when printing keys. It checks each character in the buffer and will diff --git a/src/utils/ddb/ddb_vos.c b/src/utils/ddb/ddb_vos.c index 7d4409a36c2..fe383e855d6 100644 --- a/src/utils/ddb/ddb_vos.c +++ b/src/utils/ddb/ddb_vos.c @@ -371,19 +371,19 @@ vos_vtp_compare(struct dv_indexed_tree_path *vtp, vos_iter_entry_t *entry, enum } static void -set_oid(vos_iter_entry_t *entry, union itp_part_type *part) +set_oid(vos_iter_entry_t *entry, struct indexed_tree_path_part *part) { itp_part_set_obj(part, &entry->ie_oid); } static void -set_key(vos_iter_entry_t *entry, union itp_part_type *part) +set_key(vos_iter_entry_t *entry, struct indexed_tree_path_part *part) { itp_part_set_key(part, &entry->ie_key); } static void -set_recx(vos_iter_entry_t *entry, union itp_part_type *part) +set_recx(vos_iter_entry_t *entry, struct indexed_tree_path_part *part) { itp_part_set_recx(part, &entry->ie_orig_recx); } @@ -391,18 +391,16 @@ set_recx(vos_iter_entry_t *entry, union itp_part_type *part) static void vos_itp_set(struct dv_indexed_tree_path *itp, vos_iter_entry_t *entry, enum path_parts part_key) { - void (*set_fn[PATH_PART_END])(vos_iter_entry_t *entry, union itp_part_type *part) = { + void (*set_fn[PATH_PART_END])(vos_iter_entry_t *entry, + struct indexed_tree_path_part *part) = { NULL, /* Won't set containers */ - set_oid, - set_key, - set_key, - set_recx, + set_oid, set_key, set_key, set_recx, }; D_ASSERT(part_key < PATH_PART_END); D_ASSERT(set_fn[part_key] != NULL); - set_fn[part_key](entry, &itp->itp_parts[part_key].itp_part_value); + set_fn[part_key](entry, &itp->itp_parts[part_key]); itp->itp_parts[part_key].itp_has_part_value = true; } @@ -702,8 +700,7 @@ dv_oid_to_obj(daos_obj_id_t oid, struct ddb_obj *obj) * obj_class_fini(); */ - obj->ddbo_otype = daos_obj_id2type(oid); - get_object_type(obj->ddbo_otype, obj->ddbo_otype_str); + get_object_type(daos_obj_id2type(oid), obj->ddbo_otype_str); } static int @@ -739,9 +736,10 @@ handle_dkey(struct ddb_iter_ctx *ctx, vos_iter_entry_t *entry) itp_unset_dkey(&ctx->itp); /* make sure dkey is freed from any previous handle */ itp_set_dkey(&ctx->itp, &entry->ie_key, ctx->dkey_seen); - dkey.ddbk_path = &ctx->itp; - dkey.ddbk_idx = ctx->dkey_seen++; - dkey.ddbk_key = entry->ie_key; + dkey.ddbk_path = &ctx->itp; + dkey.ddbk_idx = ctx->dkey_seen++; + dkey.ddbk_key = entry->ie_key; + dkey.ddbk_otype = daos_obj_id2type(ctx->current_obj.id_pub); dkey.ddbk_child_type = entry->ie_child_type; ctx->current_dkey = entry->ie_key; @@ -765,9 +763,10 @@ handle_akey(struct ddb_iter_ctx *ctx, vos_iter_entry_t *entry) itp_set_akey(&ctx->itp, &entry->ie_key, ctx->akey_seen); itp_unset_recx(&ctx->itp); - akey.ddbk_path = &ctx->itp; - akey.ddbk_idx = ctx->akey_seen++; - akey.ddbk_key = entry->ie_key; + akey.ddbk_path = &ctx->itp; + akey.ddbk_idx = ctx->akey_seen++; + akey.ddbk_key = entry->ie_key; + akey.ddbk_otype = daos_obj_id2type(ctx->current_obj.id_pub); akey.ddbk_child_type = entry->ie_child_type; ctx->current_akey = entry->ie_key; @@ -888,9 +887,10 @@ dv_iterate(daos_handle_t poh, struct dv_tree_path *path, bool recursive, vos_iter_type_t type; struct ddb_iter_ctx ctx = {0}; - ctx.handlers = handlers; + ctx.handlers = handlers; ctx.handler_args = handler_args; - ctx.poh = poh; + ctx.poh = poh; + ctx.current_obj = path->vtp_oid; itp_copy(&ctx.itp, itp); param.ip_epr.epr_hi = DAOS_EPOCH_MAX; diff --git a/src/utils/ddb/ddb_vos.h b/src/utils/ddb/ddb_vos.h index 7d1da8900fc..6edafa5f7c0 100644 --- a/src/utils/ddb/ddb_vos.h +++ b/src/utils/ddb/ddb_vos.h @@ -20,19 +20,19 @@ struct ddb_cont { }; struct ddb_obj { - daos_obj_id_t ddbo_oid; - uint32_t ddbo_idx; - enum daos_otype_t ddbo_otype; - char ddbo_otype_str[32]; - uint32_t ddbo_nr_grps; - struct dv_indexed_tree_path *ddbo_path; + daos_obj_id_t ddbo_oid; + uint32_t ddbo_idx; + uint32_t ddbo_nr_grps; + char ddbo_otype_str[32]; + struct dv_indexed_tree_path *ddbo_path; }; struct ddb_key { - daos_key_t ddbk_key; - uint32_t ddbk_idx; - vos_iter_type_t ddbk_child_type; - struct dv_indexed_tree_path *ddbk_path; + daos_key_t ddbk_key; + uint32_t ddbk_idx; + enum daos_otype_t ddbk_otype; + vos_iter_type_t ddbk_child_type; + struct dv_indexed_tree_path *ddbk_path; }; struct ddb_sv { diff --git a/src/utils/ddb/tests/ddb_commands_print_tests.c b/src/utils/ddb/tests/ddb_commands_print_tests.c index 9b60b070dd5..129568acbc9 100644 --- a/src/utils/ddb/tests/ddb_commands_print_tests.c +++ b/src/utils/ddb/tests/ddb_commands_print_tests.c @@ -1,6 +1,6 @@ /** * (C) Copyright 2022-2023 Intel Corporation. - * (C) Copyright 2025 Hewlett Packard Enterprise Development LP + * (C) Copyright 2025-2026 Hewlett Packard Enterprise Development LP * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -60,6 +60,7 @@ print_key_test(void **state) key.ddbk_idx = 4; d_iov_set(&key.ddbk_key, key_buf, ARRAY_SIZE(key_buf)); + key.ddbk_otype = DAOS_OT_MULTI_LEXICAL; ddb_print_key(&g_ctx, &key, 0); @@ -93,6 +94,7 @@ print_key_test(void **state) * If key length is a number type, then print as that. */ memset(key_buf, 0, ARRAY_SIZE(key_buf)); + key.ddbk_otype = DAOS_OT_MULTI_UINT64; /* char key */ key_buf[0] = 0xab; @@ -286,17 +288,17 @@ iov_to_printable_test(void **state) char buf[buf_len]; char input_buf[buf_len]; - assert_int_equal(0, ddb_iov_to_printable_buf(&iov, buf, buf_len)); + assert_int_equal(0, ddb_iov_to_printable_buf(&iov, buf, buf_len, NULL)); /* buf is plenty big */ sprintf(input_buf, "This is some text"); d_iov_set(&iov, input_buf, strlen(input_buf) + 1); - assert_int_equal(17, ddb_iov_to_printable_buf(&iov, buf, buf_len)); + assert_int_equal(17, ddb_iov_to_printable_buf(&iov, buf, buf_len, NULL)); assert_string_equal(input_buf, buf); /* buf is too small */ memset(buf, 0, buf_len); - assert_int_equal(17, ddb_iov_to_printable_buf(&iov, buf, 10)); + assert_int_equal(17, ddb_iov_to_printable_buf(&iov, buf, 10, NULL)); assert_string_equal("This is s", buf); /* Binary type - enough buffer*/ @@ -305,27 +307,27 @@ iov_to_printable_test(void **state) /* chars written to buffer is 30. For each byte, 2 are printed (10 bytes * 2) plus * the prefix of 'bin(10):' is 10 more chars. */ - assert_int_equal(30, ddb_iov_to_printable_buf(&iov, buf, buf_len)); + assert_int_equal(30, ddb_key_to_printable_buf(&iov, 0, buf, buf_len)); assert_string_equal("bin(10):0xabababababababababab", buf); /* Binary type - not enough buffer*/ - assert_int_equal(30, ddb_iov_to_printable_buf(&iov, buf, 20)); + assert_int_equal(30, ddb_key_to_printable_buf(&iov, 0, buf, 20)); assert_string_equal("bin(10):0xababab...", buf); /* Number types */ d_iov_set(&iov, input_buf, 8); /* uint64 */ - assert_int_equal(25, ddb_iov_to_printable_buf(&iov, buf, buf_len)); + assert_int_equal(25, ddb_key_to_printable_buf(&iov, DAOS_OT_MULTI_UINT64, buf, buf_len)); assert_string_equal("uint64:0xabababababababab", buf); - assert_int_equal(25, ddb_iov_to_printable_buf(&iov, buf, 10)); + assert_int_equal(25, ddb_key_to_printable_buf(&iov, DAOS_OT_MULTI_UINT64, buf, 10)); assert_string_equal("uint64:0x", buf); d_iov_set(&iov, input_buf, 4); /* uint32 */ - assert_int_equal(17, ddb_iov_to_printable_buf(&iov, buf, buf_len)); + assert_int_equal(17, ddb_key_to_printable_buf(&iov, DAOS_OT_ARRAY_BYTE, buf, buf_len)); assert_string_equal("uint32:0xabababab", buf); d_iov_set(&iov, input_buf, 1); /* uint8 */ - assert_int_equal(10, ddb_iov_to_printable_buf(&iov, buf, buf_len)); + assert_int_equal(10, ddb_key_to_printable_buf(&iov, DAOS_OT_ARRAY_BYTE, buf, buf_len)); assert_string_equal("uint8:0xab", buf); } diff --git a/src/utils/ddb/tests/ddb_path_tests.c b/src/utils/ddb/tests/ddb_path_tests.c index 7c0c7a3a421..5b8443d1b7d 100644 --- a/src/utils/ddb/tests/ddb_path_tests.c +++ b/src/utils/ddb/tests/ddb_path_tests.c @@ -1,5 +1,6 @@ /** * (C) Copyright 2023 Intel Corporation. + * (C) Copyright 2026 Hewlett Packard Enterprise Development LP * * SPDX-License-Identifier: BSD-2-Clause-Patent */ @@ -73,6 +74,7 @@ key_safe_str_tests(void **state) assert_string_equal(small_buf, "///////"); } +/* clang-format off */ static void key_printing_and_parsing_tests(void **state) { @@ -80,32 +82,36 @@ key_printing_and_parsing_tests(void **state) * These tests will parse the first argument, then print it. The printed * value will be compared to the second (expected) argument. */ -#define assert_key_parsed_printed(parsed, printed) do {\ - union itp_part_type __v = {0}; \ - assert_true(ddb_parse_key(parsed, &__v.itp_key) > 0); \ - itp_print_part_key(&g_ctx, &__v); \ - assert_printed_exact(printed); \ - dvt_fake_print_reset(); \ - daos_iov_free(&__v.itp_key); \ -} while (0) - - assert_key_parsed_printed("akey", "akey"); - assert_key_parsed_printed("akey{4}", "akey"); - assert_key_parsed_printed("akey{64}", "akey{64}"); +#define assert_key_parsed_printed(parsed, printed, int_key) \ + do { \ + struct indexed_tree_path_part __part = {0}; \ + assert_true(ddb_parse_key(parsed, &__part.itp_part_value.itp_key) > 0); \ + __part.itp_otype = int_key ? DAOS_OT_MULTI_UINT64 : 0; \ + itp_print_part_key(&g_ctx, &__part); \ + assert_printed_exact(printed); \ + dvt_fake_print_reset(); \ + daos_iov_free(&__part.itp_part_value.itp_key); \ + } while (0) + + assert_key_parsed_printed("akey", "akey", false); + assert_key_parsed_printed("akey{4}", "akey", false); + assert_key_parsed_printed("akey{64}", "akey{64}", false); /* binary should take size as input, but doesn't need it. It will always print it however */ - assert_key_parsed_printed("{bin:0xabcdef1234}", "{bin(5):0xabcdef1234}"); - assert_key_parsed_printed("{bin(5):0xabcdef1234}", "{bin(5):0xabcdef1234}"); + assert_key_parsed_printed("{bin:0xabcdef1234}", "{bin(5):0xabcdef1234}", false); + assert_key_parsed_printed("{bin(5):0xabcdef1234}", "{bin(5):0xabcdef1234}", false); /* Int types. Hex letters' case doesn't matter. Will always print as lower case */ - assert_key_parsed_printed("{uint64:0xABCDEF1234}", "{uint64:0xabcdef1234}"); - assert_key_parsed_printed("{uint32:0x12345678}", "{uint32:0x12345678}"); - assert_key_parsed_printed("{uint16:0x1234}", "{uint16:0x1234}"); - assert_key_parsed_printed("{uint8:0xAF}", "{uint8:0xaf}"); + assert_key_parsed_printed("{uint64:10}", "{uint64:0xa}", true); + assert_key_parsed_printed("{uint64:0xABCDEF1234}", "{uint64:0xabcdef1234}", true); + assert_key_parsed_printed("{uint32:0x12345678}", "{uint32:0x12345678}", true); + assert_key_parsed_printed("{uint16:0x1234}", "{uint16:0x1234}", true); + assert_key_parsed_printed("{uint8:0xAF}", "{uint8:0xaf}", true); /* Parsing doesn't handle too big of values yet, so will get truncated */ - assert_key_parsed_printed("{uint8:0xFFFAAA}", "{uint8:0xaa}"); - assert_key_parsed_printed("\\/", "\\/"); + assert_key_parsed_printed("{uint8:0xFFFAAA}", "{uint8:0xaa}", true); + assert_key_parsed_printed("\\/", "\\/", false); } +/* clang-format on */ /* Test setting and printing the full path given the path parts structure */ static void