Skip to content

Commit

Permalink
feat(raid): add delta bitmap APIs
Browse files Browse the repository at this point in the history
Longhorn 9766

Signed-off-by: Damiano Cipriani <[email protected]>
  • Loading branch information
DamiaSan committed Nov 15, 2024
1 parent a878ed0 commit 7ed33af
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 4 deletions.
99 changes: 98 additions & 1 deletion app/cmd/basic/bdev_raid.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ func BdevRaidCmd() cli.Command {
BdevRaidGetCmd(),
BdevRaidRemoveBaseBdevCmd(),
BdevRaidGrowBaseBdevCmd(),
BdevRaidGetBaseBdevDeltaMapCmd(),
BdevRaidStopBaseBdevDeltaMapCmd(),
BdevRaidClearBaseBdevFaultyStateCmd(),
},
}
}
Expand Down Expand Up @@ -50,6 +53,21 @@ func BdevRaidCreateCmd() cli.Command {
Usage: "Names of Nvme bdevs, the input is like \"--base-devs Nvme0n1 --base-devs Nvme1n1\"",
Required: true,
},
cli.StringFlag{
Name: "UUID",
Usage: "UUID for this raid bdev",
Required: false,
},
cli.BoolFlag{
Name: "superblock",
Usage: "Raid bdev info will be stored in superblock on each base bdev",
Required: false,
},
cli.BoolFlag{
Name: "delta-bitmap",
Usage: "A delta bitmap for faulty base bdevs will be recorded",
Required: false,
},
},
Action: func(c *cli.Context) {
if err := bdevRaidCreate(c); err != nil {
Expand All @@ -65,7 +83,8 @@ func bdevRaidCreate(c *cli.Context) error {
return err
}

created, err := spdkCli.BdevRaidCreate(c.String("name"), spdktypes.BdevRaidLevel(c.String("level")), uint32(c.Uint64("strip-size-kb")), c.StringSlice("base-bdevs"))
created, err := spdkCli.BdevRaidCreate(c.String("name"), spdktypes.BdevRaidLevel(c.String("level")), uint32(c.Uint64("strip-size-kb")), c.StringSlice("base-bdevs"),
c.String("UUID"), c.Bool("superblock"), c.Bool("delta-bitmap"))
if err != nil {
return err
}
Expand Down Expand Up @@ -193,3 +212,81 @@ func bdevRaidGrowBaseBdev(c *cli.Context) error {

return util.PrintObject(growed)
}

func BdevRaidGetBaseBdevDeltaMapCmd() cli.Command {
return cli.Command{
Name: "get-base-bdev-delta-map",
Usage: "get the delta bitmap of a faulty base bdev: get-base-bdev-delta-map <BASE BDEV NAME>",
Action: func(c *cli.Context) {
if err := bdevRaidGetBaseBdevDeltaMap(c); err != nil {
logrus.WithError(err).Fatalf("Failed to run get base bdev delta map to raid command")
}
},
}
}

func bdevRaidGetBaseBdevDeltaMap(c *cli.Context) error {
spdkCli, err := client.NewClient(context.Background())
if err != nil {
return err
}

deltaMap, err := spdkCli.BdevRaidGetBaseBdevDeltaMap(c.Args().First())
if err != nil {
return err
}

return util.PrintObject(deltaMap)
}

func BdevRaidStopBaseBdevDeltaMapCmd() cli.Command {
return cli.Command{
Name: "stop-base-bdev-delta-map",
Usage: "stop the updating of the delta bitmap of a faulty base bdev: stop-base-bdev-delta-map <BASE BDEV NAME>",
Action: func(c *cli.Context) {
if err := bdevRaidStopBaseBdevDeltaMap(c); err != nil {
logrus.WithError(err).Fatalf("Failed to run stop base bdev delta map to raid command")
}
},
}
}

func bdevRaidStopBaseBdevDeltaMap(c *cli.Context) error {
spdkCli, err := client.NewClient(context.Background())
if err != nil {
return err
}

stopped, err := spdkCli.BdevRaidStopBaseBdevDeltaMap(c.Args().First())
if err != nil {
return err
}

return util.PrintObject(stopped)
}

func BdevRaidClearBaseBdevFaultyStateCmd() cli.Command {
return cli.Command{
Name: "clear-base-bdev-faulty-state",
Usage: "clear the faulty state of a base bdev: clear-base-bdev-faulty-state <BASE BDEV NAME>",
Action: func(c *cli.Context) {
if err := bdevRaidClearBaseBdevFaultyState(c); err != nil {
logrus.WithError(err).Fatalf("Failed to run clear base bdev faulty state to raid command")
}
},
}
}

func bdevRaidClearBaseBdevFaultyState(c *cli.Context) error {
spdkCli, err := client.NewClient(context.Background())
if err != nil {
return err
}

cleared, err := spdkCli.BdevRaidClearBaseBdevFaultyState(c.Args().First())
if err != nil {
return err
}

return util.PrintObject(cleared)
}
60 changes: 59 additions & 1 deletion pkg/spdk/client/basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,14 @@ func (c *Client) BdevLvolRename(oldName, newName string) (renamed bool, err erro
// "stripSizeKb": Required. Strip size in KB. It's valid for raid0 and raid5f only. For other raid levels, this would be modified to 0.
//
// "baseBdevs": Required. The bdev list used as the underlying disk of the RAID.
func (c *Client) BdevRaidCreate(name string, raidLevel spdktypes.BdevRaidLevel, stripSizeKb uint32, baseBdevs []string) (created bool, err error) {
//
// "uuid": Optional. UUID for this raid bdev. Empty value will be ignored.
//
// "superblock": Optional. Raid bdev info will be stored in superblock on each base bdev. Default false.
//
// "delta_bitmap": Optional. A delta bitmap for faulty base bdevs will be recorded. Default false.
func (c *Client) BdevRaidCreate(name string, raidLevel spdktypes.BdevRaidLevel, stripSizeKb uint32, baseBdevs []string,
uuid string, superblock bool, delta_bitmap bool) (created bool, err error) {
if raidLevel != spdktypes.BdevRaidLevel0 && raidLevel != spdktypes.BdevRaidLevelRaid0 && raidLevel != spdktypes.BdevRaidLevel5f && raidLevel != spdktypes.BdevRaidLevelRaid5f {
stripSizeKb = 0
}
Expand All @@ -540,6 +547,9 @@ func (c *Client) BdevRaidCreate(name string, raidLevel spdktypes.BdevRaidLevel,
RaidLevel: raidLevel,
StripSizeKb: stripSizeKb,
BaseBdevs: baseBdevs,
UUID: uuid,
SuperBlock: superblock,
DeltaBitmap: delta_bitmap,
}

cmdOutput, err := c.jsonCli.SendCommand("bdev_raid_create", req)
Expand Down Expand Up @@ -686,6 +696,54 @@ func (c *Client) BdevRaidGrowBaseBdev(raidName, baseBdevName string) (growed boo
return growed, json.Unmarshal(cmdOutput, &growed)
}

// BdevRaidGetBaseBdevDeltaMap get the delta bitmap of a faulty base bdev
//
// "baseBdevName": Required. The faulty base bdev name to get the delta bitmap of.
func (c *Client) BdevRaidGetBaseBdevDeltaMap(baseBdevName string) (deltaMap *spdktypes.BdevRaidBaseBdevDeltaMap, err error) {
req := spdktypes.BdevRaidGetBaseBdevDeltaMapRequest{
BaseName: baseBdevName,
}

cmdOutput, err := c.jsonCli.SendCommand("bdev_raid_get_base_bdev_delta_bitmap", req)
if err != nil {
return nil, err
}

return deltaMap, json.Unmarshal(cmdOutput, &deltaMap)
}

// BdevRaidStopBaseBdevDeltaMap stop the updating of the delta bitmap of a faulty base bdev
//
// "baseBdevName": Required. The faulty base bdev name to stop the delta bitmap of.
func (c *Client) BdevRaidStopBaseBdevDeltaMap(baseBdevName string) (stopped bool, err error) {
req := spdktypes.BdevRaidStopBaseBdevDeltaMapRequest{
BaseName: baseBdevName,
}

cmdOutput, err := c.jsonCli.SendCommand("bdev_raid_stop_base_bdev_delta_bitmap", req)
if err != nil {
return false, err
}

return stopped, json.Unmarshal(cmdOutput, &stopped)
}

// BdevRaidClearBaseBdevFaultyState clear the faulty state of a base bdev
//
// "baseBdevName": Required. The faulty base bdev name to clear the faulty state of.
func (c *Client) BdevRaidClearBaseBdevFaultyState(baseBdevName string) (cleared bool, err error) {
req := spdktypes.BdevRaidClearBaseBdevFaultyStateRequest{
BaseName: baseBdevName,
}

cmdOutput, err := c.jsonCli.SendCommand("bdev_raid_clear_base_bdev_faulty_state", req)
if err != nil {
return false, err
}

return cleared, json.Unmarshal(cmdOutput, &cleared)
}

// BdevNvmeAttachController constructs NVMe bdev.
//
// "name": Name of the NVMe controller. And the corresponding bdev nvme name are same as the nvme namespace name, which is `{ControllerName}n1`
Expand Down
6 changes: 4 additions & 2 deletions pkg/spdk/spdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,8 @@ func (s *TestSuite) TestSPDKBasic(c *C) {
c.Assert(time.Since(start) < time.Minute, Equals, true)

raidName := "test-raid"
created, err := spdkCli.BdevRaidCreate(raidName, spdktypes.BdevRaidLevelRaid1, 0, []string{lvolUUID1, lvolUUID2})
created, err := spdkCli.BdevRaidCreate(raidName, spdktypes.BdevRaidLevelRaid1, 0, []string{lvolUUID1, lvolUUID2},
"", false, false)
c.Assert(err, IsNil)
c.Assert(created, Equals, true)
defer func() {
Expand Down Expand Up @@ -562,7 +563,8 @@ func (s *TestSuite) TestSPDKEngineSuspend(c *C) {
c.Assert(len(lvolList), Equals, 2)

raidName := "test-raid"
created, err := spdkCli.BdevRaidCreate(raidName, spdktypes.BdevRaidLevelRaid1, 0, []string{lvolUUID1, lvolUUID2})
created, err := spdkCli.BdevRaidCreate(raidName, spdktypes.BdevRaidLevelRaid1, 0, []string{lvolUUID1, lvolUUID2},
"", false, false)
c.Assert(err, IsNil)
c.Assert(created, Equals, true)
defer func() {
Expand Down
20 changes: 20 additions & 0 deletions pkg/spdk/types/raid.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ type BdevRaidCreateRequest struct {
RaidLevel BdevRaidLevel `json:"raid_level"`
StripSizeKb uint32 `json:"strip_size_kb"`
BaseBdevs []string `json:"base_bdevs"`
UUID string `json:"uuid,omitempty"`
SuperBlock bool `json:"superblock"`
DeltaBitmap bool `json:"delta_bitmap"`
}

type BdevRaidDeleteRequest struct {
Expand Down Expand Up @@ -64,3 +67,20 @@ type BdevRaidGrowBaseBdevRequest struct {
RaidName string `json:"raid_name"`
BaseName string `json:"base_name"`
}

type BdevRaidGetBaseBdevDeltaMapRequest struct {
BaseName string `json:"base_bdev_name"`
}

type BdevRaidBaseBdevDeltaMap struct {
RegionSize uint64 `json:"region_size"`
DeltaBitmap string `json:"delta_bitmap"`
}

type BdevRaidStopBaseBdevDeltaMapRequest struct {
BaseName string `json:"base_bdev_name"`
}

type BdevRaidClearBaseBdevFaultyStateRequest struct {
BaseName string `json:"base_bdev_name"`
}

0 comments on commit 7ed33af

Please sign in to comment.