Skip to content

daemon/graphdriver/zfs: ignore non-existent dataset on removal#48520

Merged
thaJeztah merged 1 commit intomoby:masterfrom
arcenik:43080-zfs-destroy-missing-volume-fails
Nov 27, 2024
Merged

daemon/graphdriver/zfs: ignore non-existent dataset on removal#48520
thaJeztah merged 1 commit intomoby:masterfrom
arcenik:43080-zfs-destroy-missing-volume-fails

Conversation

@arcenik
Copy link
Copy Markdown
Contributor

@arcenik arcenik commented Sep 17, 2024

Fixes #43080

- What I did

I updated the Remove function to ignore the "dataset does not exist" error

- How I did it

Doing a strings.Contains of "dataset does not exist" in err

- How to verify it

- Description for the changelog

Ignores "dataset does not exist" error when removing dataset on ZFS (#43080)

image

@arcenik arcenik force-pushed the 43080-zfs-destroy-missing-volume-fails branch from ffaaae8 to 2189e47 Compare September 17, 2024 18:53
name := d.zfsPath(id)
dataset := zfs.Dataset{Name: name}
err := dataset.Destroy(zfs.DestroyRecursive)
if err != nil && strings.Contains(fmt.Sprint(err), "dataset does not exist") {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you may probably do a stricter check.

errZfs, ok := err.(zfs.Error)
if ok && errZfs.Stderr == "dataset does not exist" {
   ...
}

or go with err.Error() instead of fmt.Sprint(err), see https://pkg.go.dev/[email protected]#error

Happy Go hacking mate!

Copy link
Copy Markdown
Contributor Author

@arcenik arcenik Sep 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Unfortunately, the stderr field contains the whole output of the zfs command

Stderr: "cannot open 'rpool/zzztest/doesnotexist': dataset does not exist\n",

errZfs, isZfsError := err.(*zfs.Error)
if isZfsError && strings.HasSuffix(errZfs.Stderr, "dataset does not exist\n") {
logger := log.G(context.TODO()).WithField("storage-driver", "zfs")
logger.Warnf("Tried to destroy inexistant dataset %s", name)
Copy link
Copy Markdown
Member

@AkihiroSuda AkihiroSuda Sep 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
logger.Warnf("Tried to destroy inexistant dataset %s", name)
logger.WithError(err).Warnf("Tried to destroy inexistant dataset %q", name)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also please squash commits

@arcenik arcenik force-pushed the 43080-zfs-destroy-missing-volume-fails branch from b402bed to 12431a9 Compare September 19, 2024 08:10
@thaJeztah thaJeztah force-pushed the 43080-zfs-destroy-missing-volume-fails branch from 12431a9 to 446d648 Compare November 27, 2024 13:25
@thaJeztah thaJeztah changed the title (daemon/graphdriver/zfs) Fixes #43080 daemon/graphdriver/zfs: ignore non-existent dataset on removal Nov 27, 2024
@thaJeztah thaJeztah force-pushed the 43080-zfs-destroy-missing-volume-fails branch from 446d648 to 543aa2e Compare November 27, 2024 13:27
var errZfs *zfs.Error
isZfsError := errors.As(err, &errZfs)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a quick rebase, and changed this to use errors.As;

diff --git a/daemon/graphdriver/zfs/zfs.go b/daemon/graphdriver/zfs/zfs.go
index bd96463d60..63301629af 100644
--- a/daemon/graphdriver/zfs/zfs.go
+++ b/daemon/graphdriver/zfs/zfs.go
@@ -4,6 +4,7 @@ package zfs // import "github.com/docker/docker/daemon/graphdriver/zfs"

 import (
        "context"
+       "errors"
        "fmt"
        "os"
        "os/exec"
@@ -362,7 +363,8 @@ func (d *Driver) Remove(id string) error {
        dataset := zfs.Dataset{Name: name}
        err := dataset.Destroy(zfs.DestroyRecursive)
        if err != nil {
-               errZfs, isZfsError := err.(*zfs.Error)
+               var errZfs *zfs.Error
+               isZfsError := errors.As(err, &errZfs)
                if isZfsError && strings.HasSuffix(errZfs.Stderr, "dataset does not exist\n") {
                        logger := log.G(context.TODO()).WithField("storage-driver", "zfs")
                        logger.WithError(err).Warnf("Tried to destroy inexistant dataset %q", name)

Comment on lines +369 to +370
logger := log.G(context.TODO()).WithField("storage-driver", "zfs")
logger.WithError(err).Warnf("Tried to destroy inexistant dataset %q", name)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually; let me change this to WithFields instead of chaining WithField and WithError

Copy link
Copy Markdown
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

I'll ask for a second review as I made the last changes now 🙈 😂

@thaJeztah
Copy link
Copy Markdown
Member

oh! I messed up an import, probably my IDE tried to be helpful;

#23 49.72 daemon/graphdriver/zfs/zfs.go:27:2: errors redeclared in this block
#23 49.72 	daemon/graphdriver/zfs/zfs.go:7:2: other declaration of errors
#23 49.72 daemon/graphdriver/zfs/zfs.go:27:2: "github.com/pkg/errors" imported and not used
#23 49.72 daemon/graphdriver/zfs/zfs.go:416:21: undefined: errors.Wrap

@thaJeztah thaJeztah force-pushed the 43080-zfs-destroy-missing-volume-fails branch from e3fae0c to 2a9dc0d Compare November 27, 2024 13:37
@thaJeztah
Copy link
Copy Markdown
Member

Should be good now 😅 🤞

if err != nil {
var errZfs *zfs.Error
isZfsError := errors.As(err, &errZfs)
if isZfsError && strings.HasSuffix(errZfs.Stderr, "dataset does not exist\n") {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm slightly on the fence if we should consider stripping the newline from Stderr. Perhaps we should; I just had a quick peek at the zfs code and it already does some manipulation of the output it got, so it may be a bit brittle if we depend on the newline to be present.

Let me add a quick strings.TrimSpace here to prevent formatting changes from breaking this.

Ignore "dataset does not exist" error in Remove function

Signed-off-by: François Scala <[email protected]>
Signed-off-by: Sebastiaan van Stijn <[email protected]>
@thaJeztah thaJeztah force-pushed the 43080-zfs-destroy-missing-volume-fails branch from 2a9dc0d to e7d15d4 Compare November 27, 2024 13:44
Copy link
Copy Markdown
Contributor

@robmry robmry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Driver "zfs" failed to remove root filesystem: "cannot open '<dataset-path>': dataset does not exist"

5 participants