diff --git a/app/cmd/basic/bdev_raid.go b/app/cmd/basic/bdev_raid.go
index 7ac8d60..a2efdc5 100644
--- a/app/cmd/basic/bdev_raid.go
+++ b/app/cmd/basic/bdev_raid.go
@@ -21,6 +21,9 @@ func BdevRaidCmd() cli.Command {
BdevRaidGetCmd(),
BdevRaidRemoveBaseBdevCmd(),
BdevRaidGrowBaseBdevCmd(),
+ BdevRaidGetBaseBdevDeltaMapCmd(),
+ BdevRaidStopBaseBdevDeltaMapCmd(),
+ BdevRaidClearBaseBdevFaultyStateCmd(),
},
}
}
@@ -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 {
@@ -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
}
@@ -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: "",
+ 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")
+ }
+ },
+ }
+}
+
+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",
+ ArgsUsage: "",
+ 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")
+ }
+ },
+ }
+}
+
+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",
+ ArgsUsage: "",
+ 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")
+ }
+ },
+ }
+}
+
+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)
+}
diff --git a/pkg/spdk/client/basic.go b/pkg/spdk/client/basic.go
index e257dab..12b139d 100644
--- a/pkg/spdk/client/basic.go
+++ b/pkg/spdk/client/basic.go
@@ -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
}
@@ -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)
@@ -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
+ }
+
+ deltaMap = &spdktypes.BdevRaidBaseBdevDeltaMap{}
+ err = json.Unmarshal(cmdOutput, deltaMap)
+ if err != nil {
+ return nil, err
+ }
+
+ return deltaMap, nil
+}
+
+// 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`
diff --git a/pkg/spdk/spdk_test.go b/pkg/spdk/spdk_test.go
index 9a43349..5cebc83 100644
--- a/pkg/spdk/spdk_test.go
+++ b/pkg/spdk/spdk_test.go
@@ -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() {
@@ -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() {
diff --git a/pkg/spdk/types/raid.go b/pkg/spdk/types/raid.go
index 2645929..def446a 100644
--- a/pkg/spdk/types/raid.go
+++ b/pkg/spdk/types/raid.go
@@ -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 {
@@ -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"`
+}