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 25, 2024
1 parent c396ae7 commit 534bba6
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 4 deletions.
111 changes: 110 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,93 @@ 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",
ArgsUsage: "<BASE BDEV NAME>",
Action: func(c *cli.Context) {
if c.NArg() != 1 {
logrus.Fatal("BASE BDEV NAME argument required")
}
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 227 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

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

Added lines #L216 - L227 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 236 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

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

Added lines #L232 - L236 were not covered by tests

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

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

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L238-L241

Added lines #L238 - L241 were not covered by tests

return util.PrintObject(deltaMap)

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

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L243

Added line #L243 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",
ArgsUsage: "<BASE BDEV NAME>",
Action: func(c *cli.Context) {
if c.NArg() != 1 {
logrus.Fatal("BASE BDEV NAME argument required")
}
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 257 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L246-L257

Added lines #L246 - L257 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 266 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L262-L266

Added lines #L262 - L266 were not covered by tests

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

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

View check run for this annotation

Codecov / codecov/patch

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

Added lines #L268 - L271 were not covered by tests

return util.PrintObject(stopped)

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

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L273

Added line #L273 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",
ArgsUsage: "<BASE BDEV NAME>",
Action: func(c *cli.Context) {
if c.NArg() != 1 {
logrus.Fatal("BASE BDEV NAME argument required")
}
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 287 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L276-L287

Added lines #L276 - L287 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 296 in app/cmd/basic/bdev_raid.go

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L292-L296

Added lines #L292 - L296 were not covered by tests

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

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

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L298-L301

Added lines #L298 - L301 were not covered by tests

return util.PrintObject(cleared)

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

View check run for this annotation

Codecov / codecov/patch

app/cmd/basic/bdev_raid.go#L303

Added line #L303 was not covered by tests
}
66 changes: 65 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, deltaBitmap 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: deltaBitmap,
}

cmdOutput, err := c.jsonCli.SendCommand("bdev_raid_create", req)
Expand Down Expand Up @@ -686,6 +696,60 @@ 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

deltaMap = &spdktypes.BdevRaidBaseBdevDeltaMap{}
err = json.Unmarshal(cmdOutput, deltaMap)
if err != nil {
return nil, err
}

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

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/client/basic.go#L712-L716

Added lines #L712 - L716 were not covered by tests

return deltaMap, nil

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

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/client/basic.go#L718

Added line #L718 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 732 in pkg/spdk/client/basic.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/client/basic.go#L724-L732

Added lines #L724 - L732 were not covered by tests

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

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

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/client/basic.go#L734

Added line #L734 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 748 in pkg/spdk/client/basic.go

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/client/basic.go#L740-L748

Added lines #L740 - L748 were not covered by tests

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

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

View check run for this annotation

Codecov / codecov/patch

pkg/spdk/client/basic.go#L750

Added line #L750 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,omitempty"`
DeltaBitmap bool `json:"delta_bitmap,omitempty"`
}

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 534bba6

Please sign in to comment.