MCPcopy
hub / github.com/lxc/incus / BackupVolume

Function BackupVolume

internal/server/storage/drivers/utils.go:1055–1181  ·  view source on GitHub ↗

BackupVolume copy a volume into the backup target location.

(d Driver, v Volume, writer instancewriter.InstanceWriter, mountPath string, blockPath string, prefix string)

Source from the content-addressed store, hash-verified

1053
1054// BackupVolume copy a volume into the backup target location.
1055func BackupVolume(d Driver, v Volume, writer instancewriter.InstanceWriter, mountPath string, blockPath string, prefix string) error {
1056 // Reset hard link cache as we are copying a new volume (instance or snapshot).
1057 writer.ResetHardLinkMap()
1058
1059 if v.contentType == ContentTypeBlock || v.contentType == ContentTypeISO {
1060 // Get size of disk block device for tarball header.
1061 blockDiskSize, err := BlockDiskSizeBytes(blockPath)
1062 if err != nil {
1063 return fmt.Errorf("Error getting block device size %q: %w", blockPath, err)
1064 }
1065
1066 var exclude []string // Files to exclude from filesystem volume backup.
1067 if !linux.IsBlockdevPath(blockPath) {
1068 // Exclude the volume root disk file from the filesystem volume backup.
1069 // We will read it as a block device later instead.
1070 exclude = append(exclude, blockPath)
1071 }
1072
1073 if v.IsVMBlock() {
1074 logMsg := "Copying virtual machine config volume"
1075
1076 d.Logger().Debug(logMsg, logger.Ctx{"sourcePath": mountPath, "prefix": prefix})
1077 err = filepath.Walk(mountPath, func(srcPath string, fi os.FileInfo, err error) error {
1078 if err != nil {
1079 return err
1080 }
1081
1082 // Skip any excluded files.
1083 if util.StringHasPrefix(srcPath, exclude...) {
1084 return nil
1085 }
1086
1087 name := filepath.Join(prefix, strings.TrimPrefix(srcPath, mountPath))
1088 err = writer.WriteFile(name, srcPath, fi, false)
1089 if err != nil {
1090 return fmt.Errorf("Error adding %q as %q to tarball: %w", srcPath, name, err)
1091 }
1092
1093 return nil
1094 })
1095 if err != nil {
1096 return err
1097 }
1098 }
1099
1100 name := fmt.Sprintf("%s.%s", prefix, genericVolumeBlockExtension)
1101
1102 logMsg := "Copying virtual machine block volume"
1103 if v.volType == VolumeTypeCustom {
1104 logMsg = "Copying custom block volume"
1105 }
1106
1107 d.Logger().Debug(logMsg, logger.Ctx{"sourcePath": blockPath, "file": name, "size": blockDiskSize})
1108 from, err := os.Open(blockPath)
1109 if err != nil {
1110 return fmt.Errorf("Error opening file for reading %q: %w", blockPath, err)
1111 }
1112

Callers 2

qcow2BackupVolumeMethod · 0.92
genericVFSBackupVolumeFunction · 0.85

Calls 14

IsBlockdevPathFunction · 0.92
StringHasPrefixFunction · 0.92
WarnOnErrorFunction · 0.92
WarnfFunction · 0.92
BlockDiskSizeBytesFunction · 0.85
ErrorfMethod · 0.80
IsVMBlockMethod · 0.80
ResetHardLinkMapMethod · 0.65
DebugMethod · 0.65
LoggerMethod · 0.65
WriteFileMethod · 0.65
WriteFileFromReaderMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…