@@ -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