diff --git a/pkg/zfs/zfs_util.go b/pkg/zfs/zfs_util.go index 4e6942ac4..541ae33b0 100644 --- a/pkg/zfs/zfs_util.go +++ b/pkg/zfs/zfs_util.go @@ -46,6 +46,7 @@ const ( ZFSSnapshotArg = "snapshot" ZFSSendArg = "send" ZFSRecvArg = "recv" + ZFSPromoteArg = "promote" ) // constants to define volume type @@ -186,6 +187,18 @@ func buildZFSSnapCreateArgs(snap *apis.ZFSSnapshot) []string { return ZFSSnapArg } +// buildZFSPromoteArgs returns zfs promote command for zfs clone +// zfs clone / +func buildZFSPromoteArgs(vol *apis.ZFSVolume) []string { + var ZFSVolArg []string + + volume := vol.Spec.PoolName + "/" + vol.Name + + ZFSVolArg = append(ZFSVolArg, ZFSPromoteArg, volume) + + return ZFSVolArg +} + // builldZFSSnapDestroyArgs returns zfs destroy command for zfs snapshot // zfs destroy /@ func buildZFSSnapDestroyArgs(snap *apis.ZFSSnapshot) []string { @@ -399,6 +412,7 @@ func CreateVolume(vol *apis.ZFSVolume) error { // CreateClone creates clone for the zvol/dataset as per // info provided in ZFSVolume object func CreateClone(vol *apis.ZFSVolume) error { + var err error volume := vol.Spec.PoolName + "/" + vol.Name if srcVol, ok := vol.Labels[ZFSSrcVolKey]; ok { @@ -439,11 +453,31 @@ func CreateClone(vol *apis.ZFSVolume) error { } if vol.Spec.FsType == "xfs" { - return xfsGenerateUUID(volume) + err = xfsGenerateUUID(volume) + } else if vol.Spec.FsType == "btrfs" { + err = btrfsGenerateUUID(volume) } - if vol.Spec.FsType == "btrfs" { - return btrfsGenerateUUID(volume) + + if err != nil { + return err } + + // promote the cloned volume so that we can delete the original volume + if _, ok := vol.Labels[ZFSSrcVolKey]; ok { + var args []string + args = buildZFSPromoteArgs(vol) + cmd := exec.Command(ZFSVolCmd, args...) + out, err := cmd.CombinedOutput() + + if err != nil { + klog.Errorf( + "zfs: could not promote the volume %v cmd %v error: %s", volume, args, string(out), + ) + return err + } + klog.Infof("promoted the clone %s", volume) + } + return nil } @@ -601,26 +635,6 @@ func DestroyVolume(vol *apis.ZFSVolume) error { return err } - if srcVol, ok := vol.Labels[ZFSSrcVolKey]; ok { - // datasource is volume, delete the dependent snapshot - snap := &apis.ZFSSnapshot{} - snap.Name = vol.Name // snapname is same as volname - snap.Spec = vol.Spec - // add src vol name - snap.Labels = map[string]string{ZFSVolKey: srcVol} - - klog.Infof("destroying snapshot %s@%s for the clone %s", srcVol, snap.Name, volume) - - err := DestroySnapshot(snap) - - if err != nil { - // no need to reconcile as volume has already been deleted - klog.Errorf( - "zfs: could not destroy snapshot for the clone vol %s snap %s err %v", volume, snap.Name, err, - ) - } - } - klog.Infof("destroyed volume %s", volume) return nil