Skip to content

Commit f5882d5

Browse files
committed
feat(raid): add delta bitmap APIs
Longhorn 9766 Signed-off-by: Damiano Cipriani <[email protected]>
1 parent af0134e commit f5882d5

File tree

4 files changed

+199
-4
lines changed

4 files changed

+199
-4
lines changed

app/cmd/basic/bdev_raid.go

+110-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ func BdevRaidCmd() cli.Command {
2121
BdevRaidGetCmd(),
2222
BdevRaidRemoveBaseBdevCmd(),
2323
BdevRaidGrowBaseBdevCmd(),
24+
BdevRaidGetBaseBdevDeltaMapCmd(),
25+
BdevRaidStopBaseBdevDeltaMapCmd(),
26+
BdevRaidClearBaseBdevFaultyStateCmd(),
2427
},
2528
}
2629
}
@@ -50,6 +53,21 @@ func BdevRaidCreateCmd() cli.Command {
5053
Usage: "Names of Nvme bdevs, the input is like \"--base-devs Nvme0n1 --base-devs Nvme1n1\"",
5154
Required: true,
5255
},
56+
cli.StringFlag{
57+
Name: "UUID",
58+
Usage: "UUID for this raid bdev",
59+
Required: false,
60+
},
61+
cli.BoolFlag{
62+
Name: "superblock",
63+
Usage: "Raid bdev info will be stored in superblock on each base bdev",
64+
Required: false,
65+
},
66+
cli.BoolFlag{
67+
Name: "delta-bitmap",
68+
Usage: "A delta bitmap for faulty base bdevs will be recorded",
69+
Required: false,
70+
},
5371
},
5472
Action: func(c *cli.Context) {
5573
if err := bdevRaidCreate(c); err != nil {
@@ -65,7 +83,8 @@ func bdevRaidCreate(c *cli.Context) error {
6583
return err
6684
}
6785

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

194213
return util.PrintObject(growed)
195214
}
215+
216+
func BdevRaidGetBaseBdevDeltaMapCmd() cli.Command {
217+
return cli.Command{
218+
Name: "get-base-bdev-delta-map",
219+
Usage: "get the delta bitmap of a faulty base bdev",
220+
ArgsUsage: "<BASE BDEV NAME>",
221+
Action: func(c *cli.Context) {
222+
if c.NArg() != 1 {
223+
logrus.Fatal("BASE BDEV NAME argument required")
224+
}
225+
if err := bdevRaidGetBaseBdevDeltaMap(c); err != nil {
226+
logrus.WithError(err).Fatalf("Failed to run get base bdev delta map to raid command")
227+
}
228+
},
229+
}
230+
}
231+
232+
func bdevRaidGetBaseBdevDeltaMap(c *cli.Context) error {
233+
spdkCli, err := client.NewClient(context.Background())
234+
if err != nil {
235+
return err
236+
}
237+
238+
deltaMap, err := spdkCli.BdevRaidGetBaseBdevDeltaMap(c.Args().First())
239+
if err != nil {
240+
return err
241+
}
242+
243+
return util.PrintObject(deltaMap)
244+
}
245+
246+
func BdevRaidStopBaseBdevDeltaMapCmd() cli.Command {
247+
return cli.Command{
248+
Name: "stop-base-bdev-delta-map",
249+
Usage: "stop the updating of the delta bitmap of a faulty base bdev",
250+
ArgsUsage: "<BASE BDEV NAME>",
251+
Action: func(c *cli.Context) {
252+
if c.NArg() != 1 {
253+
logrus.Fatal("BASE BDEV NAME argument required")
254+
}
255+
if err := bdevRaidStopBaseBdevDeltaMap(c); err != nil {
256+
logrus.WithError(err).Fatalf("Failed to run stop base bdev delta map to raid command")
257+
}
258+
},
259+
}
260+
}
261+
262+
func bdevRaidStopBaseBdevDeltaMap(c *cli.Context) error {
263+
spdkCli, err := client.NewClient(context.Background())
264+
if err != nil {
265+
return err
266+
}
267+
268+
stopped, err := spdkCli.BdevRaidStopBaseBdevDeltaMap(c.Args().First())
269+
if err != nil {
270+
return err
271+
}
272+
273+
return util.PrintObject(stopped)
274+
}
275+
276+
func BdevRaidClearBaseBdevFaultyStateCmd() cli.Command {
277+
return cli.Command{
278+
Name: "clear-base-bdev-faulty-state",
279+
Usage: "clear the faulty state of a base bdev",
280+
ArgsUsage: "<BASE BDEV NAME>",
281+
Action: func(c *cli.Context) {
282+
if c.NArg() != 1 {
283+
logrus.Fatal("BASE BDEV NAME argument required")
284+
}
285+
if err := bdevRaidClearBaseBdevFaultyState(c); err != nil {
286+
logrus.WithError(err).Fatalf("Failed to run clear base bdev faulty state to raid command")
287+
}
288+
},
289+
}
290+
}
291+
292+
func bdevRaidClearBaseBdevFaultyState(c *cli.Context) error {
293+
spdkCli, err := client.NewClient(context.Background())
294+
if err != nil {
295+
return err
296+
}
297+
298+
cleared, err := spdkCli.BdevRaidClearBaseBdevFaultyState(c.Args().First())
299+
if err != nil {
300+
return err
301+
}
302+
303+
return util.PrintObject(cleared)
304+
}

pkg/spdk/client/basic.go

+65-1
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,14 @@ func (c *Client) BdevLvolRename(oldName, newName string) (renamed bool, err erro
531531
// "stripSizeKb": Required. Strip size in KB. It's valid for raid0 and raid5f only. For other raid levels, this would be modified to 0.
532532
//
533533
// "baseBdevs": Required. The bdev list used as the underlying disk of the RAID.
534-
func (c *Client) BdevRaidCreate(name string, raidLevel spdktypes.BdevRaidLevel, stripSizeKb uint32, baseBdevs []string) (created bool, err error) {
534+
//
535+
// "uuid": Optional. UUID for this raid bdev. Empty value will be ignored.
536+
//
537+
// "superblock": Optional. Raid bdev info will be stored in superblock on each base bdev. Default false.
538+
//
539+
// "delta_bitmap": Optional. A delta bitmap for faulty base bdevs will be recorded. Default false.
540+
func (c *Client) BdevRaidCreate(name string, raidLevel spdktypes.BdevRaidLevel, stripSizeKb uint32, baseBdevs []string,
541+
uuid string, superBlock bool, deltaBitmap bool) (created bool, err error) {
535542
if raidLevel != spdktypes.BdevRaidLevel0 && raidLevel != spdktypes.BdevRaidLevelRaid0 && raidLevel != spdktypes.BdevRaidLevel5f && raidLevel != spdktypes.BdevRaidLevelRaid5f {
536543
stripSizeKb = 0
537544
}
@@ -540,6 +547,9 @@ func (c *Client) BdevRaidCreate(name string, raidLevel spdktypes.BdevRaidLevel,
540547
RaidLevel: raidLevel,
541548
StripSizeKb: stripSizeKb,
542549
BaseBdevs: baseBdevs,
550+
UUID: uuid,
551+
SuperBlock: superBlock,
552+
DeltaBitmap: deltaBitmap,
543553
}
544554

545555
cmdOutput, err := c.jsonCli.SendCommand("bdev_raid_create", req)
@@ -686,6 +696,60 @@ func (c *Client) BdevRaidGrowBaseBdev(raidName, baseBdevName string) (growed boo
686696
return growed, json.Unmarshal(cmdOutput, &growed)
687697
}
688698

699+
// BdevRaidGetBaseBdevDeltaMap get the delta bitmap of a faulty base bdev
700+
//
701+
// "baseBdevName": Required. The faulty base bdev name to get the delta bitmap of.
702+
func (c *Client) BdevRaidGetBaseBdevDeltaMap(baseBdevName string) (deltaMap *spdktypes.BdevRaidBaseBdevDeltaMap, err error) {
703+
req := spdktypes.BdevRaidGetBaseBdevDeltaMapRequest{
704+
BaseName: baseBdevName,
705+
}
706+
707+
cmdOutput, err := c.jsonCli.SendCommand("bdev_raid_get_base_bdev_delta_bitmap", req)
708+
if err != nil {
709+
return nil, err
710+
}
711+
712+
deltaMap = &spdktypes.BdevRaidBaseBdevDeltaMap{}
713+
err = json.Unmarshal(cmdOutput, deltaMap)
714+
if err != nil {
715+
return nil, err
716+
}
717+
718+
return deltaMap, nil
719+
}
720+
721+
// BdevRaidStopBaseBdevDeltaMap stop the updating of the delta bitmap of a faulty base bdev
722+
//
723+
// "baseBdevName": Required. The faulty base bdev name to stop the delta bitmap of.
724+
func (c *Client) BdevRaidStopBaseBdevDeltaMap(baseBdevName string) (stopped bool, err error) {
725+
req := spdktypes.BdevRaidStopBaseBdevDeltaMapRequest{
726+
BaseName: baseBdevName,
727+
}
728+
729+
cmdOutput, err := c.jsonCli.SendCommand("bdev_raid_stop_base_bdev_delta_bitmap", req)
730+
if err != nil {
731+
return false, err
732+
}
733+
734+
return stopped, json.Unmarshal(cmdOutput, &stopped)
735+
}
736+
737+
// BdevRaidClearBaseBdevFaultyState clear the faulty state of a base bdev
738+
//
739+
// "baseBdevName": Required. The faulty base bdev name to clear the faulty state of.
740+
func (c *Client) BdevRaidClearBaseBdevFaultyState(baseBdevName string) (cleared bool, err error) {
741+
req := spdktypes.BdevRaidClearBaseBdevFaultyStateRequest{
742+
BaseName: baseBdevName,
743+
}
744+
745+
cmdOutput, err := c.jsonCli.SendCommand("bdev_raid_clear_base_bdev_faulty_state", req)
746+
if err != nil {
747+
return false, err
748+
}
749+
750+
return cleared, json.Unmarshal(cmdOutput, &cleared)
751+
}
752+
689753
// BdevNvmeAttachController constructs NVMe bdev.
690754
//
691755
// "name": Name of the NVMe controller. And the corresponding bdev nvme name are same as the nvme namespace name, which is `{ControllerName}n1`

pkg/spdk/spdk_test.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,8 @@ func (s *TestSuite) TestSPDKBasic(c *C) {
302302
c.Assert(time.Since(start) < time.Minute, Equals, true)
303303

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

564565
raidName := "test-raid"
565-
created, err := spdkCli.BdevRaidCreate(raidName, spdktypes.BdevRaidLevelRaid1, 0, []string{lvolUUID1, lvolUUID2})
566+
created, err := spdkCli.BdevRaidCreate(raidName, spdktypes.BdevRaidLevelRaid1, 0, []string{lvolUUID1, lvolUUID2},
567+
"", false, false)
566568
c.Assert(err, IsNil)
567569
c.Assert(created, Equals, true)
568570
defer func() {

pkg/spdk/types/raid.go

+20
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ type BdevRaidCreateRequest struct {
3737
RaidLevel BdevRaidLevel `json:"raid_level"`
3838
StripSizeKb uint32 `json:"strip_size_kb"`
3939
BaseBdevs []string `json:"base_bdevs"`
40+
UUID string `json:"uuid,omitempty"`
41+
SuperBlock bool `json:"superblock,omitempty"`
42+
DeltaBitmap bool `json:"delta_bitmap,omitempty"`
4043
}
4144

4245
type BdevRaidDeleteRequest struct {
@@ -64,3 +67,20 @@ type BdevRaidGrowBaseBdevRequest struct {
6467
RaidName string `json:"raid_name"`
6568
BaseName string `json:"base_name"`
6669
}
70+
71+
type BdevRaidGetBaseBdevDeltaMapRequest struct {
72+
BaseName string `json:"base_bdev_name"`
73+
}
74+
75+
type BdevRaidBaseBdevDeltaMap struct {
76+
RegionSize uint64 `json:"region_size"`
77+
DeltaBitmap string `json:"delta_bitmap"`
78+
}
79+
80+
type BdevRaidStopBaseBdevDeltaMapRequest struct {
81+
BaseName string `json:"base_bdev_name"`
82+
}
83+
84+
type BdevRaidClearBaseBdevFaultyStateRequest struct {
85+
BaseName string `json:"base_bdev_name"`
86+
}

0 commit comments

Comments
 (0)