Skip to content
Open
111 changes: 111 additions & 0 deletions src/utils/ddb/ddb_vos.c
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,117 @@ dv_dump_value(daos_handle_t poh, struct dv_tree_path *path, dv_dump_value_cb dum
return rc;
}

static int
dump_csum_sv(daos_handle_t coh, daos_key_t *dkey, daos_unit_oid_t *oid, daos_iod_t *iod,
daos_epoch_t epoch, dv_dump_csum_cb dump_cb, void *cb_arg)
{
daos_handle_t ioh;
struct dcs_ci_list *cil;
int cb_rc = 0;
int rc;

rc = vos_fetch_begin(coh, *oid, epoch, dkey, 1, iod, VOS_OF_FETCH_CSUM, NULL, &ioh, NULL);
if (!SUCCESS(rc)) {
D_ERROR("vos_fetch_begin for csum dump of " DF_UOID " failed: " DF_RC "\n",
DP_UOID(*oid), DP_RC(rc));
goto out;
}

cil = vos_ioh2ci(ioh);

cb_rc = dump_cb(cb_arg, NULL, cil);
if (!SUCCESS(cb_rc))
D_DEBUG(DB_IO, "Csum dump callback for " DF_UOID " returned: " DF_RC "\n",
DP_UOID(*oid), DP_RC(cb_rc));

rc = vos_fetch_end(ioh, NULL, cb_rc);
if (!SUCCESS(rc) && rc != cb_rc)
D_ERROR("vos_fetch_end for csum dump of " DF_UOID " failed: " DF_RC "\n",
DP_UOID(*oid), DP_RC(rc));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to repeatedly report error if failed during dump_cb()?

@knard38 knard38 Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to repeatedly report error if failed during dump_cb()?

  • Avoid double error logging on callback failure in csum dump

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed with commit 89aef6b


out:
if (!SUCCESS(cb_rc))
rc = cb_rc;
return rc;
}

static int
dump_csum_recx(daos_handle_t coh, daos_key_t *dkey, daos_unit_oid_t *oid, daos_iod_t *iod,
daos_epoch_t epoch, dv_dump_csum_cb dump_cb, void *cb_arg)
{
daos_handle_t ioh;
struct dcs_ci_list *cil;
struct daos_recx_ep_list *rel;
int cb_rc = 0;
int rc;

rc = vos_fetch_begin(coh, *oid, epoch, dkey, 1, iod, VOS_OF_FETCH_CSUM, NULL, &ioh, NULL);
if (!SUCCESS(rc)) {
D_ERROR("vos_fetch_begin for csum dump of " DF_UOID " failed: " DF_RC "\n",
DP_UOID(*oid), DP_RC(rc));
goto out;
}

cil = vos_ioh2ci(ioh);
rel = vos_ioh2recx_list(ioh);

cb_rc = dump_cb(cb_arg, rel, cil);
if (!SUCCESS(cb_rc))
D_DEBUG(DB_IO, "Csum dump callback for " DF_UOID " returned: " DF_RC "\n",
DP_UOID(*oid), DP_RC(cb_rc));

/* rel ownership is transferred by vos_ioh2recx_list(); free before vos_fetch_end. */
daos_recx_ep_list_free(rel, iod->iod_nr);
rc = vos_fetch_end(ioh, NULL, cb_rc);
if (!SUCCESS(rc) && rc != cb_rc)
D_ERROR("vos_fetch_end for csum dump of " DF_UOID " failed: " DF_RC "\n",
DP_UOID(*oid), DP_RC(rc));

out:
if (!SUCCESS(cb_rc))
rc = cb_rc;
return rc;
}

int
dv_dump_csum(daos_handle_t poh, struct dv_tree_path *path, daos_epoch_t epoch,
dv_dump_csum_cb dump_cb, void *cb_arg)
{
daos_handle_t coh;
daos_iod_t iod = {0};
int rc = 0;

/* No-op when no callback is provided; the caller controls whether to consume results. */
if (dump_cb == NULL)
goto out;

rc = vos_cont_open(poh, path->vtp_cont, &coh);
if (!SUCCESS(rc)) {
D_ERROR("Opening container for csum dump of " DF_UOID " failed: " DF_RC "\n",
DP_UOID(path->vtp_oid), DP_RC(rc));
goto out;
}

iod.iod_name = path->vtp_akey;
iod.iod_recxs = &path->vtp_recx;
iod.iod_nr = 1;
iod.iod_size = 0;
if (path->vtp_is_recx) {
iod.iod_type = DAOS_IOD_ARRAY;
rc = dump_csum_recx(coh, &path->vtp_dkey, &path->vtp_oid, &iod, epoch, dump_cb,
cb_arg);
} else {
iod.iod_type = DAOS_IOD_SINGLE;
rc = dump_csum_sv(coh, &path->vtp_dkey, &path->vtp_oid, &iod, epoch, dump_cb,
cb_arg);
}

vos_cont_close(coh);

out:
return rc;
}

static void
ilog_entry_status(enum ilog_status status, char *status_str, uint32_t status_str_len)
{
Expand Down
31 changes: 31 additions & 0 deletions src/utils/ddb/ddb_vos.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,37 @@ typedef int (*dv_dump_value_cb)(void *cb_arg, d_iov_t *value);
int dv_dump_value(daos_handle_t poh, struct dv_tree_path *path, dv_dump_value_cb dump_cb,
void *cb_arg);

/**
* Callback invoked by dv_dump_csum() with the fetched checksum information.
*
* @param cb_arg User-provided argument passed through from dv_dump_csum().
* @param rel Recx/epoch list describing the stored extents. NULL for single-value akeys;
* non-NULL for array akeys. The caller must not free this pointer.
* @param cil Checksum info list. Valid only for the duration of the callback.
* @return 0 on success; a negative error code is propagated back to the caller of
* dv_dump_csum().
*/
typedef int (*dv_dump_csum_cb)(void *cb_arg, struct daos_recx_ep_list *rel,
struct dcs_ci_list *cil);

/**
* Fetch and dump the checksum information for the akey identified by \a path.
*
* @param poh Open pool handle.
* @param path VOS tree path identifying the container, object, dkey, and akey.
* For array akeys, path->vtp_recx selects the extent to inspect.
* @param epoch Epoch for the fetch. For single-value akeys, controls which version is
* returned — pass DAOS_EPOCH_MAX to get the latest, or a snapshot epoch to
* access an earlier version. For array akeys, selects the visible extent set.
* @param dump_cb Callback invoked with the result. If NULL, the function returns 0
* without opening the container or calling VOS.
* @param cb_arg Opaque argument forwarded to \a dump_cb.
* @return 0 on success, or a negative error code.
*/
int
dv_dump_csum(daos_handle_t poh, struct dv_tree_path *path, daos_epoch_t epoch,
dv_dump_csum_cb dump_cb, void *cb_arg);

struct ddb_ilog_entry {
uint32_t die_idx;
int32_t die_status;
Expand Down
Loading
Loading