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 14, 2024
1 parent a065334 commit 7a9a5da
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(),

Check warning on line 26 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L24-L26

Added lines #L24 - L26 were not covered by tests
},
}
}
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,
},

Check warning on line 70 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L56-L70

Added lines #L56 - L70 were not covered by tests
},
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"))

Check warning on line 87 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L86-L87

Added lines #L86 - L87 were not covered by tests
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")
}

Check warning on line 223 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L216-L223

Added lines #L216 - L223 were not covered by tests
},
}
}

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

Check warning on line 232 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L228-L232

Added lines #L228 - L232 were not covered by tests

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

Check warning on line 237 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L234-L237

Added lines #L234 - L237 were not covered by tests

return util.PrintObject(deltaMap)

Check warning on line 239 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L239

Added line #L239 was not covered by tests
}

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")
}

Check warning on line 249 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L242-L249

Added lines #L242 - L249 were not covered by tests
},
}
}

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

Check warning on line 258 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L254-L258

Added lines #L254 - L258 were not covered by tests

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

Check warning on line 263 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L260-L263

Added lines #L260 - L263 were not covered by tests

return util.PrintObject(stopped)

Check warning on line 265 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L265

Added line #L265 was not covered by tests
}

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")
}

Check warning on line 275 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L268-L275

Added lines #L268 - L275 were not covered by tests
},
}
}

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

Check warning on line 284 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L280-L284

Added lines #L280 - L284 were not covered by tests

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

Check warning on line 289 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L286-L289

Added lines #L286 - L289 were not covered by tests

return util.PrintObject(cleared)

Check warning on line 291 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L291

Added line #L291 was not covered by tests
}
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
}

Check warning on line 710 in pkg/spdk/client/basic.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/client/basic.go#L702-L710

Added lines #L702 - L710 were not covered by tests

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

Check warning on line 712 in pkg/spdk/client/basic.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/client/basic.go#L712

Added line #L712 was not covered by tests
}

// 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
}

Check warning on line 726 in pkg/spdk/client/basic.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/client/basic.go#L718-L726

Added lines #L718 - L726 were not covered by tests

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

Check warning on line 728 in pkg/spdk/client/basic.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/client/basic.go#L728

Added line #L728 was not covered by tests
}

// 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
}

Check warning on line 742 in pkg/spdk/client/basic.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/client/basic.go#L734-L742

Added lines #L734 - L742 were not covered by tests

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

Check warning on line 744 in pkg/spdk/client/basic.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/client/basic.go#L744

Added line #L744 was not covered by tests
}

// 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 7a9a5da

Please sign in to comment.