From 72cacd14c67099faf179cce2eda04150289bcbd8 Mon Sep 17 00:00:00 2001 From: Damiano Cipriani Date: Mon, 16 Dec 2024 13:37:08 +0100 Subject: [PATCH] feat(lvol): add lvol detach parent API Longhorn 9922 Signed-off-by: Damiano Cipriani --- app/cmd/basic/bdev_lvol.go | 42 ++++++++++++++++++++++++++++++++++++++ pkg/spdk/client/basic.go | 18 ++++++++++++++++ pkg/spdk/types/lvol.go | 4 ++++ 3 files changed, 64 insertions(+) diff --git a/app/cmd/basic/bdev_lvol.go b/app/cmd/basic/bdev_lvol.go index 150c149..6e8217c 100644 --- a/app/cmd/basic/bdev_lvol.go +++ b/app/cmd/basic/bdev_lvol.go @@ -27,6 +27,7 @@ func BdevLvolCmd() cli.Command { BdevLvolCloneBdevCmd(), BdevLvolSetParentCmd(), BdevLvolDecoupleParentCmd(), + BdevLvolDetachParentCmd(), BdevLvolResizeCmd(), BdevLvolStartShallowCopyCmd(), BdevLvolCheckShallowCopyCmd(), @@ -345,6 +346,47 @@ func bdevLvolDecoupleParent(c *cli.Context) error { return util.PrintObject(decoupled) } +func BdevLvolDetachParentCmd() cli.Command { + return cli.Command{ + Name: "detach", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "alias", + Usage: "The alias of a lvol is /. Specify this or uuid", + }, + cli.StringFlag{ + Name: "uuid", + Usage: "Specify this or alias", + }, + }, + Usage: "detach a lvol from its parent lvol: \"detach --alias /\", or \"detach --uuid \"", + Action: func(c *cli.Context) { + if err := bdevLvolDetachParent(c); err != nil { + logrus.WithError(err).Fatalf("Failed to run detach parent bdev lvol command") + } + }, + } +} + +func bdevLvolDetachParent(c *cli.Context) error { + spdkCli, err := client.NewClient(context.Background()) + if err != nil { + return err + } + + name := c.String("alias") + if name == "" { + name = c.String("uuid") + } + + decoupled, err := spdkCli.BdevLvolDetachParent(name) + if err != nil { + return err + } + + return util.PrintObject(decoupled) +} + func BdevLvolSetParentCmd() cli.Command { return cli.Command{ Name: "set-parent", diff --git a/pkg/spdk/client/basic.go b/pkg/spdk/client/basic.go index bbd5bae..a87198b 100644 --- a/pkg/spdk/client/basic.go +++ b/pkg/spdk/client/basic.go @@ -387,6 +387,24 @@ func (c *Client) BdevLvolDecoupleParent(name string) (decoupled bool, err error) return decoupled, json.Unmarshal(cmdOutput, &decoupled) } +// BdevLvolDetachParent detach the parent of a logical volume. +// No new clusters are allocated to the child blob, no data are copied from the parent to the child, so lvol's data are not modified. +// The parent must be a standard snapshot, not an external snapshot. All dependencies on the parent are removed +// +// "name": Required. UUID or alias of the logical volume to detach the parent of it. The alias of a lvol is /. +func (c *Client) BdevLvolDetachParent(name string) (decoupled bool, err error) { + req := spdktypes.BdevLvolDetachParentRequest{ + Name: name, + } + + cmdOutput, err := c.jsonCli.SendCommandWithLongTimeout("bdev_lvol_detach_parent", req) + if err != nil { + return false, err + } + + return decoupled, json.Unmarshal(cmdOutput, &decoupled) +} + // BdevLvolSetParent sets a snapshot as the parent of a lvol, making the lvol a clone/child of this snapshot. // The previous parent of the lvol can be another snapshot or an external snapshot, if the lvol is not a clone must be thin-provisioned. // Lvol and parent snapshot must have the same size and must belong to the same lvol store. diff --git a/pkg/spdk/types/lvol.go b/pkg/spdk/types/lvol.go index 6f36b4e..246a65b 100644 --- a/pkg/spdk/types/lvol.go +++ b/pkg/spdk/types/lvol.go @@ -124,6 +124,10 @@ type BdevLvolDecoupleParentRequest struct { Name string `json:"name"` } +type BdevLvolDetachParentRequest struct { + Name string `json:"name"` +} + type BdevLvolSetParentRequest struct { LvolName string `json:"lvol_name"` ParentName string `json:"parent_name"`