Skip to content

Commit

Permalink
Address review feedback
Browse files Browse the repository at this point in the history
Move PoolQueryTarget and related types into lib/daos.

Features: pool
Required-githooks: true
Change-Id: Ibb90c44d681402b699e023cc78adb4b7f21b0910
Signed-off-by: Michael MacDonald <[email protected]>
  • Loading branch information
mjmac committed Apr 17, 2024
1 parent d73d0dd commit 33f1d61
Show file tree
Hide file tree
Showing 8 changed files with 387 additions and 419 deletions.
106 changes: 44 additions & 62 deletions src/control/cmd/daos/pool.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// (C) Copyright 2021-2023 Intel Corporation.
// (C) Copyright 2021-2024 Intel Corporation.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
Expand All @@ -16,11 +16,8 @@ import (
"github.com/pkg/errors"

"github.com/daos-stack/daos/src/control/build"
"github.com/daos-stack/daos/src/control/cmd/dmg/pretty"
"github.com/daos-stack/daos/src/control/cmd/daos/pretty"
"github.com/daos-stack/daos/src/control/common"
"github.com/daos-stack/daos/src/control/common/proto/convert"
mgmtpb "github.com/daos-stack/daos/src/control/common/proto/mgmt"
"github.com/daos-stack/daos/src/control/lib/control"
"github.com/daos-stack/daos/src/control/lib/daos"
"github.com/daos-stack/daos/src/control/lib/ranklist"
"github.com/daos-stack/daos/src/control/lib/ui"
Expand Down Expand Up @@ -201,74 +198,63 @@ type poolQueryCmd struct {
ShowDisabledRanks bool `short:"b" long:"show-disabled" description:"Show engine unique identifiers (ranks) which are disabled"`
}

func convertPoolSpaceInfo(in *C.struct_daos_pool_space, mt C.uint) *mgmtpb.StorageUsageStats {
func convertPoolSpaceInfo(in *C.struct_daos_pool_space, mt C.uint) *daos.StorageUsageStats {
if in == nil {
return nil
}

return &mgmtpb.StorageUsageStats{
return &daos.StorageUsageStats{
Total: uint64(in.ps_space.s_total[mt]),
Free: uint64(in.ps_space.s_free[mt]),
Min: uint64(in.ps_free_min[mt]),
Max: uint64(in.ps_free_max[mt]),
Mean: uint64(in.ps_free_mean[mt]),
MediaType: mgmtpb.StorageMediaType(mt),
MediaType: daos.StorageMediaType(mt),
}
}

func convertPoolRebuildStatus(in *C.struct_daos_rebuild_status) *mgmtpb.PoolRebuildStatus {
func convertPoolRebuildStatus(in *C.struct_daos_rebuild_status) *daos.PoolRebuildStatus {
if in == nil {
return nil
}

out := &mgmtpb.PoolRebuildStatus{
out := &daos.PoolRebuildStatus{
Status: int32(in.rs_errno),
}
if out.Status == 0 {
out.Objects = uint64(in.rs_obj_nr)
out.Records = uint64(in.rs_rec_nr)
switch {
case in.rs_version == 0:
out.State = mgmtpb.PoolRebuildStatus_IDLE
out.State = daos.PoolRebuildStateIdle
case C.get_rebuild_state(in) == C.DRS_COMPLETED:
out.State = mgmtpb.PoolRebuildStatus_DONE
out.State = daos.PoolRebuildStateDone
default:
out.State = mgmtpb.PoolRebuildStatus_BUSY
out.State = daos.PoolRebuildStateBusy
}
}

return out
}

// This is not great... But it allows us to leverage the existing
// pretty printer that dmg uses for this info. Better to find some
// way to unify all of this and remove redundancy/manual conversion.
//
// We're basically doing the same thing as ds_mgmt_drpc_pool_query()
// to stuff the info into a protobuf message and then using the
// automatic conversion from proto to control. Kind of ugly but
// gets the job done. We could potentially create some function
// that's shared between this code and the drpc handlers to deal
// with stuffing the protobuf message but it's probably overkill.
func convertPoolInfo(pinfo *C.daos_pool_info_t) (*control.PoolQueryResp, error) {
pqp := new(mgmtpb.PoolQueryResp)

pqp.Uuid = uuid.Must(uuidFromC(pinfo.pi_uuid)).String()
pqp.TotalTargets = uint32(pinfo.pi_ntargets)
pqp.DisabledTargets = uint32(pinfo.pi_ndisabled)
pqp.ActiveTargets = uint32(pinfo.pi_space.ps_ntargets)
pqp.TotalEngines = uint32(pinfo.pi_nnodes)
pqp.Leader = uint32(pinfo.pi_leader)
pqp.Version = uint32(pinfo.pi_map_ver)

pqp.TierStats = []*mgmtpb.StorageUsageStats{
func convertPoolInfo(pinfo *C.daos_pool_info_t) (*daos.PoolInfo, error) {
poolInfo := new(daos.PoolInfo)

poolInfo.UUID = uuid.Must(uuidFromC(pinfo.pi_uuid))
poolInfo.TotalTargets = uint32(pinfo.pi_ntargets)
poolInfo.DisabledTargets = uint32(pinfo.pi_ndisabled)
poolInfo.ActiveTargets = uint32(pinfo.pi_space.ps_ntargets)
poolInfo.TotalEngines = uint32(pinfo.pi_nnodes)
poolInfo.Leader = uint32(pinfo.pi_leader)
poolInfo.Version = uint32(pinfo.pi_map_ver)

poolInfo.TierStats = []*daos.StorageUsageStats{
convertPoolSpaceInfo(&pinfo.pi_space, C.DAOS_MEDIA_SCM),
convertPoolSpaceInfo(&pinfo.pi_space, C.DAOS_MEDIA_NVME),
}
pqp.Rebuild = convertPoolRebuildStatus(&pinfo.pi_rebuild_st)
poolInfo.Rebuild = convertPoolRebuildStatus(&pinfo.pi_rebuild_st)

pqr := new(control.PoolQueryResp)
return pqr, convert.Types(pqp, pqr)
return poolInfo, nil
}

const (
Expand Down Expand Up @@ -311,46 +297,40 @@ func (cmd *poolQueryCmd) Execute(_ []string) error {
}
defer cleanup()

pinfo := C.daos_pool_info_t{
cPoolInfo := C.daos_pool_info_t{
pi_bits: dpiQueryAll,
}
if cmd.ShowDisabledRanks {
pinfo.pi_bits &= C.uint64_t(^(uint64(C.DPI_ENGINES_ENABLED)))
cPoolInfo.pi_bits &= C.uint64_t(^(uint64(C.DPI_ENGINES_ENABLED)))
}

rc := C.daos_pool_query(cmd.cPoolHandle, rlPtr, &pinfo, nil, nil)
rc := C.daos_pool_query(cmd.cPoolHandle, rlPtr, &cPoolInfo, nil, nil)
defer C.d_rank_list_free(rl)
if err := daosError(rc); err != nil {
return errors.Wrapf(err,
"failed to query pool %s", cmd.poolUUID)
}

pqr, err := convertPoolInfo(&pinfo)
poolInfo, err := convertPoolInfo(&cPoolInfo)
if err != nil {
return err
}

if rlPtr != nil {
if cmd.ShowEnabledRanks {
pqr.EnabledRanks = ranklist.MustCreateRankSet(generateRankSet(rl))
poolInfo.EnabledRanks = ranklist.MustCreateRankSet(generateRankSet(rl))
}
if cmd.ShowDisabledRanks {
pqr.DisabledRanks = ranklist.MustCreateRankSet(generateRankSet(rl))
poolInfo.DisabledRanks = ranklist.MustCreateRankSet(generateRankSet(rl))
}
}

// Update the Pool Query State based on response
err = pqr.UpdateState()
if err != nil {
return err
}

if cmd.JSONOutputEnabled() {
return cmd.OutputJSON(pqr, nil)
return cmd.OutputJSON(poolInfo, nil)
}

var bld strings.Builder
if err := pretty.PrintPoolQueryResponse(pqr, &bld); err != nil {
if err := pretty.PrintPoolInfo(poolInfo, &bld); err != nil {
return err
}

Expand All @@ -367,11 +347,11 @@ type poolQueryTargetsCmd struct {
}

// For using the pretty printer that dmg uses for this target info.
func convertPoolTargetInfo(ptinfo *C.daos_target_info_t) (*control.PoolQueryTargetInfo, error) {
pqti := new(control.PoolQueryTargetInfo)
pqti.Type = control.PoolQueryTargetType(ptinfo.ta_type)
pqti.State = control.PoolQueryTargetState(ptinfo.ta_state)
pqti.Space = []*daos.StorageTargetUsage{
func convertPoolTargetInfo(ptinfo *C.daos_target_info_t) (*daos.PoolQueryTargetInfo, error) {
pqti := new(daos.PoolQueryTargetInfo)
pqti.Type = daos.PoolQueryTargetType(ptinfo.ta_type)
pqti.State = daos.PoolQueryTargetState(ptinfo.ta_state)
pqti.Space = []*daos.StorageUsageStats{
{
Total: uint64(ptinfo.ta_space.s_total[C.DAOS_MEDIA_SCM]),
Free: uint64(ptinfo.ta_space.s_free[C.DAOS_MEDIA_SCM]),
Expand Down Expand Up @@ -399,10 +379,10 @@ func (cmd *poolQueryTargetsCmd) Execute(_ []string) error {
return errors.WithMessage(err, "parsing target list")
}

infoResp := new(control.PoolQueryTargetResp)
ptInfo := new(C.daos_target_info_t)
var rc C.int

infos := make([]*daos.PoolQueryTargetInfo, 0, len(idxList))
for tgt := 0; tgt < len(idxList); tgt++ {
rc = C.daos_pool_query_target(cmd.cPoolHandle, C.uint32_t(idxList[tgt]), C.uint32_t(cmd.Rank), ptInfo, nil)
if err := daosError(rc); err != nil {
Expand All @@ -411,19 +391,21 @@ func (cmd *poolQueryTargetsCmd) Execute(_ []string) error {
}

tgtInfo, err := convertPoolTargetInfo(ptInfo)
infoResp.Infos = append(infoResp.Infos, tgtInfo)
if err != nil {
return err
}
infos = append(infos, tgtInfo)
}

if cmd.JSONOutputEnabled() {
return cmd.OutputJSON(infoResp, nil)
return cmd.OutputJSON(infos, nil)
}

var bld strings.Builder
if err := pretty.PrintPoolQueryTargetResponse(infoResp, &bld); err != nil {
return err
for _, info := range infos {
if err := pretty.PrintPoolQueryTargetInfo(info, &bld); err != nil {
return err
}
}

cmd.Info(bld.String())
Expand Down
23 changes: 22 additions & 1 deletion src/control/cmd/daos/pretty/pool.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// (C) Copyright 2020-2023 Intel Corporation.
// (C) Copyright 2020-2024 Intel Corporation.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
Expand Down Expand Up @@ -74,3 +74,24 @@ func PrintPoolInfo(pi *daos.PoolInfo, out io.Writer) error {

return w.Err
}

// PrintPoolQueryTargetInfo generates a human-readable representation of the supplied
// PoolQueryTargetResp struct and writes it to the supplied io.Writer.
func PrintPoolQueryTargetInfo(pqti *daos.PoolQueryTargetInfo, out io.Writer) error {
if pqti == nil {
return errors.Errorf("nil %T", pqti)
}
w := txtfmt.NewErrWriter(out)

// Maintain output compatibility with the `daos pool query-targets` output.
fmt.Fprintf(w, "Target: type %s, state %s\n", pqti.Type, pqti.State)
if pqti.Space != nil {
for tierIdx, tierUsage := range pqti.Space {
fmt.Fprintln(w, getTierNameText(tierIdx))
fmt.Fprintf(w, " Total size: %s\n", humanize.Bytes(tierUsage.Total))
fmt.Fprintf(w, " Free: %s\n", humanize.Bytes(tierUsage.Free))
}
}

return w.Err
}
Loading

0 comments on commit 33f1d61

Please sign in to comment.