Skip to content

Commit

Permalink
Fix deletion of data and kube root dirs
Browse files Browse the repository at this point in the history
Make sure that we don't have anything mounted under those directories so
we don't delete persistent data.

We do this py parsing /proc/mounts in reverse order as it is listed in
mount order, and then we unmount anything that is under our directories
before we delete them.

Don't umount datadir itself if it is on a separate partition/mount

Fixes #4318

Signed-off-by: Natanael Copa <[email protected]>
  • Loading branch information
ncopa committed Nov 8, 2024
1 parent 09ac812 commit 8599e88
Showing 1 changed file with 22 additions and 6 deletions.
28 changes: 22 additions & 6 deletions pkg/cleanup/directories.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
"k8s.io/mount-utils"
)

Expand All @@ -46,15 +48,23 @@ func (d *directories) Run() error {

var dataDirMounted bool

// search and unmount kubelet volume mounts
for _, v := range procMounts {
if v.Path == filepath.Join(d.Config.dataDir, "kubelet") {
// search and unmount anything under kubelet root or data dir
// in reverse order to handle nested mounts and over mounts
for i := len(procMounts) - 1; i >= 0; i-- {
v := procMounts[i]
// avoid unmount datadir if its mounted on separate partition
if v.Path == d.Config.k0sVars.DataDir {
dataDirMounted = true
continue
}
if isUnderPath(v.Path, filepath.Join(d.Config.dataDir, "kubelet")) || isUnderPath(v.Path, d.Config.k0sVars.DataDir) {
logrus.Debugf("%v is mounted! attempting to unmount...", v.Path)
if err = mounter.Unmount(v.Path); err != nil {
logrus.Warningf("failed to unmount %v", v.Path)
logrus.Warningf("lazy unmounting %v", v.Path)
if err = unix.Unmount(v.Path, unix.MNT_DETACH); err != nil {

Check failure on line 64 in pkg/cleanup/directories.go

View workflow job for this annotation

GitHub Actions / Unit tests :: windows-amd64

undefined: unix.Unmount

Check failure on line 64 in pkg/cleanup/directories.go

View workflow job for this annotation

GitHub Actions / Unit tests :: windows-amd64

undefined: unix.MNT_DETACH
return fmt.Errorf("failed unmount %v", v.Path)
}
}
} else if v.Path == d.Config.dataDir {
dataDirMounted = true
}
}

Expand All @@ -81,6 +91,12 @@ func (d *directories) Run() error {
return nil
}

// test if the path is a directory equal to or under base
func isUnderPath(path, base string) bool {
rel, err := filepath.Rel(base, path)
return err == nil && !strings.HasPrefix(rel, "..") && !filepath.IsAbs(rel)
}

// this is for checking if the error retrned by os.RemoveAll is due to
// it being a mount point. if it is, we can ignore the error. this way
// we can't rely on os.RemoveAll instead of recursively deleting the
Expand Down

0 comments on commit 8599e88

Please sign in to comment.