Skip to content

Commit

Permalink
fix(zfspv): fixing data loss in case of pod deletion
Browse files Browse the repository at this point in the history
looks like a bug in ZFS as when you change the mountpoint property to none,
ZFS automatically umounts the file system. When we delete the pod, we get the
unmount request for the old pod and mount request for the new pod. Unmount
is done by the driver by setting mountpoint to none and the driver assumes that
unmount has done and proceeded to delete the mountpath, but here zfs has not unmounted
the dataset

```
$ sudo zfs get all zfspv-pool/pvc-3fe69b0e-9f91-4c6e-8e5c-eb4218468765 | grep mount
zfspv-pool/pvc-3fe69b0e-9f91-4c6e-8e5c-eb4218468765  mounted               yes                                                                                                -
zfspv-pool/pvc-3fe69b0e-9f91-4c6e-8e5c-eb4218468765  mountpoint            none                                                                                               local
zfspv-pool/pvc-3fe69b0e-9f91-4c6e-8e5c-eb4218468765  canmount              on
```

here, the driver will assume that dataset has been unmouted and proceed to delete the
mountpath and it will delete the data as part of cleaning up for the NodeUnPublish request.

Shifting to use zfs umount instead of doing zfs set mountpoint=none for umounting the dataset.
Also the driver is using os.RemoveAll which is very risky as it will clean
child also, since the mountpoint is not supposed to have anything,
just os.Remove is sufficient and it will fail if there is anything there.

Signed-off-by: Pawan <[email protected]>
  • Loading branch information
pawanpraka1 authored and kmova committed Apr 22, 2020
1 parent 11e15e5 commit 920e9fa
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
3 changes: 1 addition & 2 deletions pkg/zfs/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,8 @@ func UmountVolume(vol *apis.ZFSVolume, targetPath string,
}
}

if err := os.RemoveAll(targetPath); err != nil {
if err := os.Remove(targetPath); err != nil {
logrus.Errorf("zfspv: failed to remove mount path Error: %v", err)
return err
}

logrus.Infof("umount done path %v", targetPath)
Expand Down
16 changes: 15 additions & 1 deletion pkg/zfs/zfs_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,22 @@ func MountZFSDataset(vol *apis.ZFSVolume, mountpath string) error {
// UmountZFSDataset umounts the dataset
func UmountZFSDataset(vol *apis.ZFSVolume) error {
volume := vol.Spec.PoolName + "/" + vol.Name
var MountVolArg []string
MountVolArg = append(MountVolArg, "umount", volume)
cmd := exec.Command(ZFSVolCmd, MountVolArg...)
out, err := cmd.CombinedOutput()
if err != nil {
logrus.Errorf("zfs: could not umount the dataset %v cmd %v error: %s",
volume, MountVolArg, string(out))
return err
}
// ignoring the failure of setting the mountpoint to none
// as the dataset has already been umounted, now the new pod
// can mount it and it will change that to desired mountpath
// and try to mount it if not mounted
SetDatasetMountProp(volume, "none")

return SetDatasetMountProp(volume, "none")
return nil
}

// GetVolumeProperty gets zfs properties for the volume
Expand Down

0 comments on commit 920e9fa

Please sign in to comment.