Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ go 1.24.0

toolchain go1.25.4

replace github.com/longhorn/types => github.com/c3y1huang/types v0.0.0-20251121004827-d9950b3b42ed

replace github.com/longhorn/go-spdk-helper => github.com/c3y1huang/go-spdk-helper v0.0.0-20251120005748-74fdf9a77fef

replace github.com/longhorn/longhorn-spdk-engine => github.com/c3y1huang/longhorn-spdk-engine v0.0.0-20251121014657-b48539468a6e

require (
github.com/cockroachdb/errors v1.12.0
github.com/google/uuid v1.6.0
Expand All @@ -15,7 +21,6 @@ require (
github.com/longhorn/types v0.0.0-20251114033314-2b0f01ee4a71
github.com/sirupsen/logrus v1.9.3
github.com/urfave/cli v1.22.17
golang.org/x/net v0.47.0
golang.org/x/sync v0.18.0
google.golang.org/grpc v1.77.0
google.golang.org/protobuf v1.36.10
Expand Down Expand Up @@ -103,6 +108,7 @@ require (
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect
golang.org/x/net v0.47.0 // indirect
golang.org/x/oauth2 v0.32.0 // indirect
golang.org/x/sys v0.38.0 // indirect
golang.org/x/term v0.37.0 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/bits-and-blooms/bitset v1.16.0 h1:G3lirLlhFTcW/7ym/SLtYYLHQS0hBOcC8fPNJxbTYm4=
github.com/bits-and-blooms/bitset v1.16.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/c3y1huang/go-spdk-helper v0.0.0-20251120005748-74fdf9a77fef h1:HWk+ictJl81KgV2hxXXGczrRCzXJF0/7kkDc2z0kH5U=
github.com/c3y1huang/go-spdk-helper v0.0.0-20251120005748-74fdf9a77fef/go.mod h1:fpzNCDddFJMLAWjm2cNnpepuw0g4p+S5SzuxS57W0/4=
github.com/c3y1huang/longhorn-spdk-engine v0.0.0-20251121014657-b48539468a6e h1:g4ljh163wOD02BnOjfxb0kD1KTT18tP71qOakrYZ+74=
github.com/c3y1huang/longhorn-spdk-engine v0.0.0-20251121014657-b48539468a6e/go.mod h1:huqLNTOMMIEdPxqesH/rQQkO03cFYfVs5JJHblsRx50=
github.com/c3y1huang/types v0.0.0-20251121004827-d9950b3b42ed h1:cskDHVZ1dG8T/SrxByk+8KAYkybD9KdtzNj+elHxXPE=
github.com/c3y1huang/types v0.0.0-20251121004827-d9950b3b42ed/go.mod h1:qTXrHyxTIjNNhDgaTbxokUIU1tk6i/g1YOQCehzHDxw=
github.com/c9s/goprocinfo v0.0.0-20210130143923-c95fcf8c64a8 h1:SjZ2GvvOononHOpK84APFuMvxqsk3tEIaKH/z4Rpu3g=
github.com/c9s/goprocinfo v0.0.0-20210130143923-c95fcf8c64a8/go.mod h1:uEyr4WpAH4hio6LFriaPkL938XnrvLpNPmQHBdrmbIE=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
Expand Down Expand Up @@ -153,16 +159,10 @@ github.com/longhorn/go-common-libs v0.0.0-20251025140453-faa811992208 h1:yMQgxcN
github.com/longhorn/go-common-libs v0.0.0-20251025140453-faa811992208/go.mod h1:PRaMs6m409MbPGZ/v/Wlf6fePUEVcGa2leB14CxjL28=
github.com/longhorn/go-iscsi-helper v0.0.0-20251102142448-23eedefc2b60 h1:lwACMOh9nKBzWkLpmyJkpigmB9HHYV5FfiiZ3jFohDM=
github.com/longhorn/go-iscsi-helper v0.0.0-20251102142448-23eedefc2b60/go.mod h1:h8So5DelxtL605STgtfFsA3SYT3+4vnIO2OUrpRFwXo=
github.com/longhorn/go-spdk-helper v0.2.1-0.20251114033407-2b59bbd85cb8 h1:rwit+rQy35V4u2MM36WwAJ0OIMUqWhJPrp0fBN8J9bo=
github.com/longhorn/go-spdk-helper v0.2.1-0.20251114033407-2b59bbd85cb8/go.mod h1:fpzNCDddFJMLAWjm2cNnpepuw0g4p+S5SzuxS57W0/4=
github.com/longhorn/longhorn-engine v1.10.0-dev-20250824.0.20251103012748-950f695edced h1:y9bPkuEJTi4b8gAfW8aMEjPg39bsIkO6bj/Tbu3otYs=
github.com/longhorn/longhorn-engine v1.10.0-dev-20250824.0.20251103012748-950f695edced/go.mod h1:x6C4H+XbXF28mtQsqjUhM4MioQKzQEq8VMcds9xzrWI=
github.com/longhorn/longhorn-spdk-engine v0.0.0-20251118131515-34b2841b20b1 h1:K/D/QZxfPgoX+mMg2RY+XpjklaVsoAttj+CbVyJC0PU=
github.com/longhorn/longhorn-spdk-engine v0.0.0-20251118131515-34b2841b20b1/go.mod h1:vrWonA/J9Ykk8OpjFQU8Or17NCLOIHipVZJMNQWVdy4=
github.com/longhorn/sparse-tools v0.0.0-20251020055717-ae3aca526fd7 h1:t+ufkrgYbdzSjfGmsorKS7wjHR8nkOtzlOQOVKTrYDk=
github.com/longhorn/sparse-tools v0.0.0-20251020055717-ae3aca526fd7/go.mod h1:WfRkt5pFnDaULAjFtoGlWhwQwyIx/vgMnH+jXQNlnQ8=
github.com/longhorn/types v0.0.0-20251114033314-2b0f01ee4a71 h1:YsjkxOApeuQM+kbT41rCq1IDRE377q0WrrxMZph8KDQ=
github.com/longhorn/types v0.0.0-20251114033314-2b0f01ee4a71/go.mod h1:qTXrHyxTIjNNhDgaTbxokUIU1tk6i/g1YOQCehzHDxw=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
Expand Down
24 changes: 24 additions & 0 deletions pkg/api/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,27 @@ type DiskMetrics struct {
ReadIOPS uint64
WriteIOPS uint64
}

type DiskHealth struct {
ModelNumber string
SerialNumber string
FirmwareRevision string
Traddr string
CriticalWarning uint32
TemperatureCelsius float64
AvailableSparePercentage uint32
AvailableSpareThresholdPercentage uint32
PercentageUsed uint32
DataUnitsRead uint64
DataUnitsWritten uint64
HostReadCommands uint64
HostWriteCommands uint64
ControllerBusyTime uint64
PowerCycles uint64
PowerOnHours uint64
UnsafeShutdowns uint64
MediaErrors uint64
NumErrLogEntries uint64
WarningTemperatureTimeMinutes uint64
CriticalCompositeTemperatureTimeMinutes uint64
}
50 changes: 50 additions & 0 deletions pkg/client/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,56 @@ func (c *DiskServiceClient) DiskGet(diskType, diskName, diskPath, diskDriver str
}, nil
}

// DiskHealthGet returns the disk health info with the given name, path and driver.
func (c *DiskServiceClient) DiskHealthGet(diskType, diskName, diskPath, diskDriver string) (*api.DiskHealth, error) {
if diskName == "" {
return nil, fmt.Errorf("failed to get disk health info: missing required parameter diskName")
}

t, ok := rpc.DiskType_value[diskType]
if !ok {
return nil, fmt.Errorf("failed to get disk health info: invalid disk type %v", diskType)
}

client := c.getDiskServiceClient()
ctx, cancel := context.WithTimeout(context.Background(), types.GRPCServiceTimeout)
defer cancel()

resp, err := client.DiskHealthGet(ctx, &rpc.DiskHealthGetRequest{
DiskType: rpc.DiskType(t),
DiskName: diskName,
DiskPath: diskPath,
DiskDriver: diskDriver,
})
if err != nil {
return nil, err
}

return &api.DiskHealth{
ModelNumber: resp.GetModelNumber(),
SerialNumber: resp.GetSerialNumber(),
FirmwareRevision: resp.GetFirmwareRevision(),
Traddr: resp.GetTraddr(),
CriticalWarning: resp.GetCriticalWarning(),
TemperatureCelsius: resp.GetTemperatureCelsius(),
AvailableSparePercentage: resp.GetAvailableSparePercentage(),
AvailableSpareThresholdPercentage: resp.GetAvailableSpareThresholdPercentage(),
PercentageUsed: resp.GetPercentageUsed(),
DataUnitsRead: resp.GetDataUnitsRead(),
DataUnitsWritten: resp.GetDataUnitsWritten(),
HostReadCommands: resp.GetHostReadCommands(),
HostWriteCommands: resp.GetHostWriteCommands(),
ControllerBusyTime: resp.GetControllerBusyTime(),
PowerCycles: resp.GetPowerCycles(),
PowerOnHours: resp.GetPowerOnHours(),
UnsafeShutdowns: resp.GetUnsafeShutdowns(),
MediaErrors: resp.GetMediaErrors(),
NumErrLogEntries: resp.GetNumErrLogEntries(),
WarningTemperatureTimeMinutes: resp.GetWarningTemperatureTimeMinutes(),
CriticalCompositeTemperatureTimeMinutes: resp.GetCriticalCompositeTemperatureTimeMinutes(),
}, nil
}

// DiskDelete deletes the disk with the given name, disk name, disk UUID, disk path and disk driver.
func (c *DiskServiceClient) DiskDelete(diskType, diskName, diskUUID, diskPath, diskDriver string) error {
if diskName == "" {
Expand Down
48 changes: 48 additions & 0 deletions pkg/disk/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type DiskOps interface {
DiskCreate(context.Context, *rpc.DiskCreateRequest) (*rpc.Disk, error)
DiskDelete(*rpc.DiskDeleteRequest) (*emptypb.Empty, error)
DiskGet(req *rpc.DiskGetRequest) (*rpc.Disk, error)
DiskHealthGet(req *rpc.DiskHealthGetRequest) (*rpc.DiskHealthGetResponse, error)
DiskReplicaInstanceList(*rpc.DiskReplicaInstanceListRequest) (*rpc.DiskReplicaInstanceListResponse, error)
DiskReplicaInstanceDelete(*rpc.DiskReplicaInstanceDeleteRequest) (*emptypb.Empty, error)
MetricsGet(*rpc.DiskGetRequest) (*rpc.DiskMetricsGetReply, error)
Expand Down Expand Up @@ -202,6 +203,53 @@ func (ops BlockDiskOps) DiskGet(req *rpc.DiskGetRequest) (*rpc.Disk, error) {
return spdkDiskToDisk(ret), nil
}

func (s *Server) DiskHealthGet(ctx context.Context, req *rpc.DiskHealthGetRequest) (*rpc.DiskHealthGetResponse, error) {
if req.DiskName == "" {
return nil, grpcstatus.Error(grpccodes.InvalidArgument, "disk name is required")
}

ops, ok := s.ops[req.DiskType]
if !ok {
return nil, grpcstatus.Errorf(grpccodes.Unimplemented, "unsupported disk type %v", req.DiskType)
}
return ops.DiskHealthGet(req)
}

func (op FilesystemDiskOps) DiskHealthGet(req *rpc.DiskHealthGetRequest) (*rpc.DiskHealthGetResponse, error) {
return nil, grpcstatus.Errorf(grpccodes.Unimplemented, "unsupported disk type %v", req.DiskType)
}

func (op BlockDiskOps) DiskHealthGet(req *rpc.DiskHealthGetRequest) (*rpc.DiskHealthGetResponse, error) {
health, err := op.spdkClient.DiskHealthGet(req.DiskName, req.DiskPath, req.DiskDriver)
if err != nil {
return nil, grpcstatus.Error(grpccodes.Internal, err.Error())
}

return &rpc.DiskHealthGetResponse{
ModelNumber: health.ModelNumber,
SerialNumber: health.SerialNumber,
FirmwareRevision: health.FirmwareRevision,
Traddr: health.Traddr,
CriticalWarning: health.CriticalWarning,
TemperatureCelsius: health.TemperatureCelsius,
AvailableSparePercentage: health.AvailableSparePercentage,
AvailableSpareThresholdPercentage: health.AvailableSpareThresholdPercentage,
PercentageUsed: health.PercentageUsed,
DataUnitsRead: health.DataUnitsRead,
DataUnitsWritten: health.DataUnitsWritten,
HostReadCommands: health.HostReadCommands,
HostWriteCommands: health.HostWriteCommands,
ControllerBusyTime: health.ControllerBusyTime,
PowerCycles: health.PowerCycles,
PowerOnHours: health.PowerOnHours,
UnsafeShutdowns: health.UnsafeShutdowns,
MediaErrors: health.MediaErrors,
NumErrLogEntries: health.NumErrLogEntries,
WarningTemperatureTimeMinutes: health.WarningTemperatureTimeMinutes,
CriticalCompositeTemperatureTimeMinutes: health.CriticalCompositeTemperatureTimeMinutes,
}, nil
}

func (s *Server) DiskReplicaInstanceList(ctx context.Context, req *rpc.DiskReplicaInstanceListRequest) (*rpc.DiskReplicaInstanceListResponse, error) {
log := logrus.WithFields(logrus.Fields{
"diskType": req.DiskType,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading