1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

cleanup and fix btrfs subvolume recursion deletion

Signed-off-by: Jessica Frazelle <acidburn@docker.com>
This commit is contained in:
Jessica Frazelle 2015-08-24 16:18:01 -07:00
parent dea78fc2ce
commit bd06432ba3
4 changed files with 41 additions and 38 deletions

View file

@ -4,7 +4,7 @@
FROM debian:wheezy-backports
RUN apt-get update && apt-get install -y bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y bash-completion btrfs-tools/wheezy-backports build-essential curl ca-certificates debhelper dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
ENV GO_VERSION 1.4.2
RUN curl -fSL "https://storage.googleapis.com/golang/go${GO_VERSION}.linux-amd64.tar.gz" | tar xzC /usr/local

View file

@ -73,6 +73,12 @@ for version in "${versions[@]}"; do
extraBuildTags+=' exclude_graphdriver_btrfs'
fi
if [ "$suite" = 'wheezy' ]; then
# pull btrfs-toold from backports
backports="/$suite-backports"
packages=( "${packages[@]/btrfs-tools/btrfs-tools$backports}" )
fi
echo "RUN apt-get update && apt-get install -y ${packages[*]} --no-install-recommends && rm -rf /var/lib/apt/lists/*" >> "$version/Dockerfile"
echo >> "$version/Dockerfile"

View file

@ -26,21 +26,6 @@ func init() {
graphdriver.Register("btrfs", Init)
}
func is_subvolume(dirpath string) (bool, error) {
rootdir := path.Dir(dirpath)
var bufStat syscall.Stat_t
if err := syscall.Lstat(rootdir, &bufStat); err != nil {
return false, err
}
if bufStat.Ino != C.BTRFS_FIRST_FREE_OBJECTID {
return false, nil
}
return true, nil
}
// Init returns a new BTRFS driver.
// An error is returned if BTRFS is not supported.
func Init(home string, options []string) (graphdriver.Driver, error) {
@ -177,6 +162,16 @@ func subvolSnapshot(src, dest, name string) error {
return nil
}
func isSubvolume(p string) (bool, error) {
var bufStat syscall.Stat_t
if err := syscall.Lstat(p, &bufStat); err != nil {
return false, err
}
// return true if it is a btrfs subvolume
return bufStat.Ino == C.BTRFS_FIRST_FREE_OBJECTID, nil
}
func subvolDelete(dirpath, name string) error {
dir, err := openDir(dirpath)
if err != nil {
@ -186,35 +181,36 @@ func subvolDelete(dirpath, name string) error {
var args C.struct_btrfs_ioctl_vol_args
filepath.Walk(dirpath,
func(dirpath string, f os.FileInfo, err error) error {
if f.IsDir() {
isSubvolumes, err := is_subvolume(path.Join(dirpath, f.Name()))
// walk the btrfs subvolumes
walkSubvolumes := func(p string, f os.FileInfo, err error) error {
// 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) {
sv, err := isSubvolume(p)
if err != nil {
return err
return fmt.Errorf("Failed to test if %s is a btrfs subvolume: %v", p, err)
}
if isSubvolumes {
for i, c := range []byte(f.Name()) {
args.name[i] = C.char(c)
if sv {
if err := subvolDelete(p, f.Name()); err != nil {
return fmt.Errorf("Failed to destroy btrfs child subvolume (%s) of parent (%s): %v", p, dirpath, err)
}
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, getDirFd(dir), C.BTRFS_IOC_SNAP_DESTROY,
uintptr(unsafe.Pointer(&args)))
if errno != 0 {
return fmt.Errorf("Failed to destroy btrfs snapshot: %v", errno.Error())
}
}
return nil
}
return nil
})
if err := filepath.Walk(path.Join(dirpath, name), walkSubvolumes); err != nil {
return fmt.Errorf("Recursively walking subvolumes for %s failed: %v", dirpath, err)
}
// all subvolumes have been removed
// now remove the one originally passed in
for i, c := range []byte(name) {
args.name[i] = C.char(c)
}
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, getDirFd(dir), C.BTRFS_IOC_SNAP_DESTROY,
uintptr(unsafe.Pointer(&args)))
if errno != 0 {
return fmt.Errorf("Failed to destroy btrfs snapshot: %v", errno.Error())
return fmt.Errorf("Failed to destroy btrfs snapshot %s for %s: %v", dirpath, name, errno.Error())
}
return nil
}

View file

@ -3,8 +3,9 @@
package btrfs
import (
"github.com/docker/docker/daemon/graphdriver/graphtest"
"testing"
"github.com/docker/docker/daemon/graphdriver/graphtest"
)
// This avoids creating a new driver for each test if all tests are run