Merge pull request #18686 from cpuguy83/fix_btrfs_subvol_delete_panic

Fix btrfs recursive btrfs subvol delete
This commit is contained in:
Vincent Batts 2015-12-16 14:26:40 -05:00
commit f57d56350e
2 changed files with 43 additions and 2 deletions

View File

@ -188,20 +188,29 @@ func subvolDelete(dirpath, name string) error {
return err
}
defer closeDir(dir)
fullPath := path.Join(dirpath, name)
var args C.struct_btrfs_ioctl_vol_args
// walk the btrfs subvolumes
walkSubvolumes := func(p string, f os.FileInfo, err error) error {
if err != nil {
if os.IsNotExist(err) && p != fullPath {
// missing most likely because the path was a subvolume that got removed in the previous iteration
// since it's gone anyway, we don't care
return nil
}
return fmt.Errorf("error walking subvolumes: %v", err)
}
// we want to check children only so skip itself
// it will be removed after the filepath walk anyways
if f.IsDir() && p != path.Join(dirpath, name) {
if f.IsDir() && p != fullPath {
sv, err := isSubvolume(p)
if err != nil {
return fmt.Errorf("Failed to test if %s is a btrfs subvolume: %v", p, err)
}
if sv {
if err := subvolDelete(p, f.Name()); err != nil {
if err := subvolDelete(path.Dir(p), f.Name()); err != nil {
return fmt.Errorf("Failed to destroy btrfs child subvolume (%s) of parent (%s): %v", p, dirpath, err)
}
}

View File

@ -3,6 +3,8 @@
package btrfs
import (
"os"
"path"
"testing"
"github.com/docker/docker/daemon/graphdriver/graphtest"
@ -26,6 +28,36 @@ func TestBtrfsCreateSnap(t *testing.T) {
graphtest.DriverTestCreateSnap(t, "btrfs")
}
func TestBtrfsSubvolDelete(t *testing.T) {
d := graphtest.GetDriver(t, "btrfs")
if err := d.Create("test", "", ""); err != nil {
t.Fatal(err)
}
defer graphtest.PutDriver(t)
dir, err := d.Get("test", "")
if err != nil {
t.Fatal(err)
}
defer d.Put("test")
if err := subvolCreate(dir, "subvoltest"); err != nil {
t.Fatal(err)
}
if _, err := os.Stat(path.Join(dir, "subvoltest")); err != nil {
t.Fatal(err)
}
if err := d.Remove("test"); err != nil {
t.Fatal(err)
}
if _, err := os.Stat(path.Join(dir, "subvoltest")); !os.IsNotExist(err) {
t.Fatalf("expected not exist error on nested subvol, got: %v", err)
}
}
func TestBtrfsTeardown(t *testing.T) {
graphtest.PutDriver(t)
}