Skip to content

Commit 09ec13e

Browse files
authored
Merge pull request #157 from jsafrane/clone-block
Add support for block volume cloning
2 parents 99036d4 + 65fda22 commit 09ec13e

File tree

2 files changed

+34
-9
lines changed

2 files changed

+34
-9
lines changed

pkg/hostpath/controllerserver.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
175175
}
176176
case *csi.VolumeContentSource_Volume:
177177
if srcVolume := volumeSource.GetVolume(); srcVolume != nil {
178-
err = loadFromVolume(capacity, srcVolume.GetVolumeId(), path)
178+
err = loadFromVolume(capacity, srcVolume.GetVolumeId(), path, requestedAccessType)
179179
vol.ParentVolID = srcVolume.GetVolumeId()
180180
}
181181
default:

pkg/hostpath/hostpath.go

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -299,20 +299,34 @@ func loadFromSnapshot(size int64, snapshotId, destPath string) error {
299299
return nil
300300
}
301301

302-
// loadfromVolume populates the given destPath with data from the srcVolumeID
303-
func loadFromVolume(size int64, srcVolumeId, destPath string) error {
302+
// loadFromVolume populates the given destPath with data from the srcVolumeID
303+
func loadFromVolume(size int64, srcVolumeId, destPath string, mode accessType) error {
304304
hostPathVolume, ok := hostPathVolumes[srcVolumeId]
305305
if !ok {
306306
return status.Error(codes.NotFound, "source volumeId does not exist, are source/destination in the same storage class?")
307307
}
308+
if hostPathVolume.VolSize > size {
309+
return status.Errorf(codes.InvalidArgument, "volume %v size %v is greater than requested volume size %v", srcVolumeId, hostPathVolume.VolSize, size)
310+
}
311+
if mode != hostPathVolume.VolAccessType {
312+
return status.Errorf(codes.InvalidArgument, "volume %v mode is not compatible with requested mode", srcVolumeId)
313+
}
314+
315+
switch mode {
316+
case mountAccess:
317+
return loadFromFilesystemVolume(hostPathVolume, destPath)
318+
case blockAccess:
319+
return loadFromBlockVolume(hostPathVolume, destPath)
320+
default:
321+
return status.Errorf(codes.InvalidArgument, "unknown accessType: %d", mode)
322+
}
323+
}
324+
325+
func loadFromFilesystemVolume(hostPathVolume hostPathVolume, destPath string) error {
308326
srcPath := hostPathVolume.VolPath
309327
isEmpty, err := hostPathIsEmpty(srcPath)
310328
if err != nil {
311-
return status.Errorf(codes.Internal, "failed verification check of source hostpath volume: %s: %v", srcVolumeId, err)
312-
}
313-
314-
if hostPathVolume.VolSize > size {
315-
return status.Errorf(codes.InvalidArgument, "volume %v size %v is greater than requested volume size %v", srcVolumeId, hostPathVolume.VolSize, size)
329+
return status.Errorf(codes.Internal, "failed verification check of source hostpath volume %v: %v", hostPathVolume.VolID, err)
316330
}
317331

318332
// If the source hostpath volume is empty it's a noop and we just move along, otherwise the cp call will fail with a a file stat error DNE
@@ -321,8 +335,19 @@ func loadFromVolume(size int64, srcVolumeId, destPath string) error {
321335
executor := utilexec.New()
322336
out, err := executor.Command("cp", args...).CombinedOutput()
323337
if err != nil {
324-
return status.Errorf(codes.Internal, "failed pre-populate data from volume %v: %v: %s", srcVolumeId, err, out)
338+
return status.Errorf(codes.Internal, "failed pre-populate data from volume %v: %v: %s", hostPathVolume.VolID, err, out)
325339
}
326340
}
327341
return nil
328342
}
343+
344+
func loadFromBlockVolume(hostPathVolume hostPathVolume, destPath string) error {
345+
srcPath := hostPathVolume.VolPath
346+
args := []string{"if=" + srcPath, "of=" + destPath}
347+
executor := utilexec.New()
348+
out, err := executor.Command("dd", args...).CombinedOutput()
349+
if err != nil {
350+
return status.Errorf(codes.Internal, "failed pre-populate data from volume %v: %v: %s", hostPathVolume.VolID, err, out)
351+
}
352+
return nil
353+
}

0 commit comments

Comments
 (0)