[lxc-devel] [lxd/master] Handle immutable/append-only files on removal

stgraber on Github lxc-bot at linuxcontainers.org
Tue Mar 17 22:48:00 UTC 2020


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200317/3e54862c/attachment-0001.bin>
-------------- next part --------------
From fa89288a986fad8f049f2ec81d1925f6ea8bd27e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 17 Mar 2020 18:37:31 -0400
Subject: [PATCH 1/3] lxd/storage/utils: Add missing comments
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage/drivers/utils.go | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go
index 430f9673b9..2fcbf98acb 100644
--- a/lxd/storage/drivers/utils.go
+++ b/lxd/storage/drivers/utils.go
@@ -43,6 +43,7 @@ func wipeDirectory(path string) error {
 	return nil
 }
 
+// forceUnmount unmounts stacked mounts until no mountpoint remains.
 func forceUnmount(path string) (bool, error) {
 	unmounted := false
 
@@ -66,6 +67,7 @@ func forceUnmount(path string) (bool, error) {
 	}
 }
 
+// mountReadOnly performs a read-only bind-mount.
 func mountReadOnly(srcPath string, dstPath string) (bool, error) {
 	// Check if already mounted.
 	if shared.IsMountPoint(dstPath) {
@@ -88,6 +90,7 @@ func mountReadOnly(srcPath string, dstPath string) (bool, error) {
 	return true, nil
 }
 
+// sameMount checks if two paths are on the same mountpoint.
 func sameMount(srcPath string, dstPath string) bool {
 	// Get the source vfs path information
 	var srcFsStat unix.Statfs_t
@@ -171,6 +174,7 @@ func TryUnmount(path string, flags int) error {
 	return nil
 }
 
+// tryExists waits up to 10s for a file to exist.
 func tryExists(path string) bool {
 	// Attempt 20 checks over 10s
 	for i := 0; i < 20; i++ {
@@ -184,10 +188,12 @@ func tryExists(path string) bool {
 	return false
 }
 
+// fsUUID returns the filesystem UUID for the given block path.
 func fsUUID(path string) (string, error) {
 	return shared.RunCommand("blkid", "-s", "UUID", "-o", "value", path)
 }
 
+// hasFilesystem checks if a given path is backed by a specified filesystem.
 func hasFilesystem(path string, fsType int64) bool {
 	fs := unix.Statfs_t{}
 
@@ -595,6 +601,7 @@ func UnshiftBtrfsRootfs(path string, diskIdmap *idmap.IdmapSet) error {
 	return shiftBtrfsRootfs(path, diskIdmap, false)
 }
 
+// shiftBtrfsRootfs shiftfs a filesystem that main include read-only subvolumes.
 func shiftBtrfsRootfs(path string, diskIdmap *idmap.IdmapSet, shift bool) error {
 	var err error
 	roSubvols := []string{}
@@ -660,6 +667,7 @@ func BTRFSSubVolumesGet(path string) ([]string, error) {
 	return result, nil
 }
 
+// btrfsIsSubvolume checks if a given path is a subvolume.
 func btrfsIsSubVolume(subvolPath string) bool {
 	fs := unix.Stat_t{}
 	err := unix.Lstat(subvolPath, &fs)

From 926d96d5f8ee41be2c2f14353a0effb81c3282c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 17 Mar 2020 18:46:38 -0400
Subject: [PATCH 2/3] lxd/storage/utils: Add forceRemoveAll
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage/drivers/utils.go | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go
index 2fcbf98acb..a0752f7416 100644
--- a/lxd/storage/drivers/utils.go
+++ b/lxd/storage/drivers/utils.go
@@ -43,6 +43,20 @@ func wipeDirectory(path string) error {
 	return nil
 }
 
+// forceRemoveAll wipes a path including any immutable/non-append files.
+func forceRemoveAll(path string) error {
+	err := os.RemoveAll(path)
+	if err != nil {
+		shared.RunCommand("chattr", "-ai", "-R", path)
+		err = os.RemoveAll(path)
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
 // forceUnmount unmounts stacked mounts until no mountpoint remains.
 func forceUnmount(path string) (bool, error) {
 	unmounted := false

From d2500dcb9f1e09478a44ad335d833a61df6a2b52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Tue, 17 Mar 2020 18:46:51 -0400
Subject: [PATCH 3/3] lxd/storage/dir: Use forceRemoveAll
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This clears the append-only and immutable flags on whatever is left
after a normal RemoveAll, then calls RemoveAll again.

Closes #6998

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/storage/drivers/driver_dir_volumes.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lxd/storage/drivers/driver_dir_volumes.go b/lxd/storage/drivers/driver_dir_volumes.go
index 5f00eb7a2c..5160ffe8bd 100644
--- a/lxd/storage/drivers/driver_dir_volumes.go
+++ b/lxd/storage/drivers/driver_dir_volumes.go
@@ -169,7 +169,7 @@ func (d *dir) DeleteVolume(vol Volume, op *operations.Operation) error {
 	}
 
 	// Remove the volume from the storage device.
-	err = os.RemoveAll(volPath)
+	err = forceRemoveAll(volPath)
 	if err != nil && !os.IsNotExist(err) {
 		return errors.Wrapf(err, "Failed to remove '%s'", volPath)
 	}
@@ -350,7 +350,7 @@ func (d *dir) DeleteVolumeSnapshot(snapVol Volume, op *operations.Operation) err
 	snapPath := snapVol.MountPath()
 
 	// Remove the snapshot from the storage device.
-	err := os.RemoveAll(snapPath)
+	err := forceRemoveAll(snapPath)
 	if err != nil && !os.IsNotExist(err) {
 		return errors.Wrapf(err, "Failed to remove '%s'", snapPath)
 	}


More information about the lxc-devel mailing list