Skip to content

Commit 595d7ba

Browse files
committed
incusd/storage: Adjust code for VolumeTargetArgs Snapshots type change
Signed-off-by: Piotr Resztak <[email protected]>
1 parent 32eb66d commit 595d7ba

File tree

8 files changed

+150
-44
lines changed

8 files changed

+150
-44
lines changed

internal/server/storage/backend.go

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,14 @@ func (b *backend) CreateInstanceFromCopy(inst instance.Instance, src instance.In
11651165
}
11661166
}
11671167

1168+
var migrationSnapshots []*migration.Snapshot
1169+
if snapshots {
1170+
migrationSnapshots, err = VolumeSnapshotsToMigrationSnapshots(srcConfig.VolumeSnapshots, inst.Project().Name, srcPool, contentType, volType, src.Name())
1171+
if err != nil {
1172+
return err
1173+
}
1174+
}
1175+
11681176
ctx, cancel := context.WithCancel(context.Background())
11691177
defer cancel()
11701178

@@ -1193,7 +1201,7 @@ func (b *backend) CreateInstanceFromCopy(inst instance.Instance, src instance.In
11931201
return b.CreateInstanceFromMigration(inst, bEnd, localMigration.VolumeTargetArgs{
11941202
IndexHeaderVersion: localMigration.IndexHeaderVersion,
11951203
Name: inst.Name(),
1196-
Snapshots: snapshotNames,
1204+
Snapshots: migrationSnapshots,
11971205
MigrationType: migrationTypes[0],
11981206
VolumeSize: srcVolumeSize, // Block size setting override.
11991207
TrackProgress: false, // Do not use a progress tracker on receiver.
@@ -1421,6 +1429,14 @@ func (b *backend) RefreshCustomVolume(projectName string, srcProjectName string,
14211429
}
14221430
}
14231431

1432+
var migrationSnapshots []*migration.Snapshot
1433+
if snapshots {
1434+
migrationSnapshots, err = VolumeSnapshotsToMigrationSnapshots(srcConfig.VolumeSnapshots, projectName, srcPool, contentType, drivers.VolumeTypeCustom, srcVolName)
1435+
if err != nil {
1436+
return err
1437+
}
1438+
}
1439+
14241440
ctx, cancel := context.WithCancel(context.Background())
14251441

14261442
// Use in-memory pipe pair to simulate a connection between the sender and receiver.
@@ -1453,7 +1469,7 @@ func (b *backend) RefreshCustomVolume(projectName string, srcProjectName string,
14531469
Name: volName,
14541470
Description: desc,
14551471
Config: config,
1456-
Snapshots: snapshotNames,
1472+
Snapshots: migrationSnapshots,
14571473
MigrationType: migrationTypes[0],
14581474
TrackProgress: false, // Do not use a progress tracker on receiver.
14591475
ContentType: string(contentType),
@@ -1634,6 +1650,20 @@ func (b *backend) RefreshInstance(inst instance.Instance, src instance.Instance,
16341650
return fmt.Errorf("Failed to negotiate copy migration type: %w", err)
16351651
}
16361652

1653+
var srcVolumeSize int64
1654+
// For VMs, get source volume size so that target can create the volume the same size.
1655+
if src.Type() == instancetype.VM {
1656+
srcVolumeSize, err = InstanceDiskBlockSize(srcPool, src, op)
1657+
if err != nil {
1658+
return fmt.Errorf("Failed getting source disk size: %w", err)
1659+
}
1660+
}
1661+
1662+
migrationSnapshots, err := VolumeSnapshotsToMigrationSnapshots(srcConfig.VolumeSnapshots, src.Project().Name, srcPool, contentType, volType, src.Name())
1663+
if err != nil {
1664+
return err
1665+
}
1666+
16371667
ctx, cancel := context.WithCancel(context.Background())
16381668
defer cancel()
16391669

@@ -1663,9 +1693,10 @@ func (b *backend) RefreshInstance(inst instance.Instance, src instance.Instance,
16631693
return b.CreateInstanceFromMigration(inst, bEnd, localMigration.VolumeTargetArgs{
16641694
IndexHeaderVersion: localMigration.IndexHeaderVersion,
16651695
Name: inst.Name(),
1666-
Snapshots: snapshotNames,
1696+
Snapshots: migrationSnapshots,
16671697
MigrationType: migrationTypes[0],
1668-
Refresh: true, // Indicate to receiver volume should exist.
1698+
Refresh: true, // Indicate to receiver volume should exist.
1699+
VolumeSize: srcVolumeSize,
16691700
TrackProgress: false, // Do not use a progress tracker on receiver.
16701701
VolumeOnly: !snapshots,
16711702
}, op)
@@ -1994,7 +2025,8 @@ func (b *backend) CreateInstanceFromMigration(inst instance.Instance, conn io.Re
19942025
// Create new volume database records when the storage pool is changed or
19952026
// when it is not a remote cluster move.
19962027
if !isRemoteClusterMove || args.StoragePool != "" {
1997-
for i, snapName := range args.Snapshots {
2028+
for i, snapshot := range args.Snapshots {
2029+
snapName := snapshot.GetName()
19982030
newSnapshotName := drivers.GetSnapshotVolumeName(inst.Name(), snapName)
19992031
snapConfig := vol.Config() // Use parent volume config by default.
20002032
snapDescription := volumeDescription // Use parent volume description by default.
@@ -4815,6 +4847,14 @@ func (b *backend) CreateCustomVolumeFromCopy(projectName string, srcProjectName
48154847
}
48164848
}
48174849

4850+
var migrationSnapshots []*migration.Snapshot
4851+
if snapshots {
4852+
migrationSnapshots, err = VolumeSnapshotsToMigrationSnapshots(srcConfig.VolumeSnapshots, srcProjectName, srcPool, contentType, drivers.VolumeTypeCustom, srcVolName)
4853+
if err != nil {
4854+
return err
4855+
}
4856+
}
4857+
48184858
ctx, cancel := context.WithCancel(context.Background())
48194859

48204860
// Use in-memory pipe pair to simulate a connection between the sender and receiver.
@@ -4848,7 +4888,7 @@ func (b *backend) CreateCustomVolumeFromCopy(projectName string, srcProjectName
48484888
Name: volName,
48494889
Description: desc,
48504890
Config: config,
4851-
Snapshots: snapshotNames,
4891+
Snapshots: migrationSnapshots,
48524892
MigrationType: migrationTypes[0],
48534893
TrackProgress: false, // Do not use a progress tracker on receiver.
48544894
ContentType: string(contentType),
@@ -5117,7 +5157,8 @@ func (b *backend) CreateCustomVolumeFromMigration(projectName string, conn io.Re
51175157

51185158
if len(args.Snapshots) > 0 {
51195159
// Create database entries for new storage volume snapshots.
5120-
for _, snapName := range args.Snapshots {
5160+
for _, snapshot := range args.Snapshots {
5161+
snapName := snapshot.GetName()
51215162
newSnapshotName := drivers.GetSnapshotVolumeName(args.Name, snapName)
51225163

51235164
snapConfig := vol.Config() // Use parent volume config by default.

internal/server/storage/drivers/driver_btrfs_volumes.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -532,9 +532,9 @@ func (d *btrfs) CreateVolumeFromMigration(vol Volume, conn io.ReadWriteCloser, v
532532
d.logger.Debug("Received BTRFS migration meta data header", logger.Ctx{"name": vol.name})
533533
} else {
534534
// Populate the migrationHeader subvolumes with root volumes only to support older sources.
535-
for _, snapName := range volTargetArgs.Snapshots {
535+
for _, snapshot := range volTargetArgs.Snapshots {
536536
migrationHeader.Subvolumes = append(migrationHeader.Subvolumes, BTRFSSubVolume{
537-
Snapshot: snapName,
537+
Snapshot: snapshot.GetName(),
538538
Path: string(filepath.Separator),
539539
Readonly: true, // Snapshots are made readonly.
540540
})
@@ -554,7 +554,7 @@ func (d *btrfs) CreateVolumeFromMigration(vol Volume, conn io.ReadWriteCloser, v
554554
}
555555

556556
// Reset list of snapshots which are to be received.
557-
volTargetArgs.Snapshots = []string{}
557+
volTargetArgs.Snapshots = []*migration.Snapshot{}
558558

559559
// Map of local subvolumes with their received UUID.
560560
localSubvolumes := make(map[string]string)
@@ -579,7 +579,7 @@ func (d *btrfs) CreateVolumeFromMigration(vol Volume, conn io.ReadWriteCloser, v
579579
}
580580

581581
if migrationSnap.Path == "/" && migrationSnap.Snapshot != "" {
582-
volTargetArgs.Snapshots = append(volTargetArgs.Snapshots, migrationSnap.Snapshot)
582+
volTargetArgs.Snapshots = append(volTargetArgs.Snapshots, &migration.Snapshot{Name: &migrationSnap.Snapshot})
583583
}
584584

585585
syncSubvolumes = append(syncSubvolumes, BTRFSSubVolume{Path: migrationSnap.Path, Snapshot: migrationSnap.Snapshot, UUID: migrationSnap.UUID})
@@ -702,8 +702,8 @@ func (d *btrfs) createVolumeFromMigrationOptimized(vol Volume, conn io.ReadWrite
702702
revert.Add(func() { _ = deleteParentSnapshotDirIfEmpty(d.name, vol.volType, vol.name) })
703703

704704
// Transfer the snapshots.
705-
for _, snapName := range volTargetArgs.Snapshots {
706-
snapVol, _ := vol.NewSnapshot(snapName)
705+
for _, snapshot := range volTargetArgs.Snapshots {
706+
snapVol, _ := vol.NewSnapshot(snapshot.GetName())
707707
err = receiveVolume(snapVol, tmpVolumesMountPoint)
708708
if err != nil {
709709
return err

internal/server/storage/drivers/driver_ceph_volumes.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -584,16 +584,16 @@ func (d *ceph) CreateVolumeFromMigration(vol Volume, conn io.ReadWriteCloser, vo
584584
}
585585

586586
// Transfer the snapshots.
587-
for _, snapName := range volTargetArgs.Snapshots {
588-
fullSnapshotName := d.getRBDVolumeName(vol, snapName, true)
587+
for _, snapshot := range volTargetArgs.Snapshots {
588+
fullSnapshotName := d.getRBDVolumeName(vol, snapshot.GetName(), true)
589589
wrapper := localMigration.ProgressWriter(op, "fs_progress", fullSnapshotName)
590590

591591
err = d.receiveVolume(recvName, conn, wrapper)
592592
if err != nil {
593593
return err
594594
}
595595

596-
snapVol, err := vol.NewSnapshot(snapName)
596+
snapVol, err := vol.NewSnapshot(snapshot.GetName())
597597
if err != nil {
598598
return err
599599
}

internal/server/storage/drivers/driver_cephfs_volumes.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,19 +194,19 @@ func (d *cephfs) CreateVolumeFromMigration(vol Volume, conn io.ReadWriteCloser,
194194
path := internalUtil.AddSlash(mountPath)
195195

196196
// Snapshots are sent first by the sender, so create these first.
197-
for _, snapName := range volTargetArgs.Snapshots {
197+
for _, snapshot := range volTargetArgs.Snapshots {
198198
// Receive the snapshot.
199199
var wrapper *ioprogress.ProgressTracker
200200
if volTargetArgs.TrackProgress {
201-
wrapper = localMigration.ProgressTracker(op, "fs_progress", snapName)
201+
wrapper = localMigration.ProgressTracker(op, "fs_progress", snapshot.GetName())
202202
}
203203

204204
err = rsync.Recv(path, conn, wrapper, volTargetArgs.MigrationType.Features)
205205
if err != nil {
206206
return err
207207
}
208208

209-
fullSnapName := GetSnapshotVolumeName(vol.name, snapName)
209+
fullSnapName := GetSnapshotVolumeName(vol.name, snapshot.GetName())
210210
snapVol := NewVolume(d, d.name, vol.volType, vol.contentType, fullSnapName, vol.config, vol.poolConfig)
211211

212212
// Create the snapshot itself.
@@ -216,7 +216,7 @@ func (d *cephfs) CreateVolumeFromMigration(vol Volume, conn io.ReadWriteCloser,
216216
}
217217

218218
// Setup the revert.
219-
revertSnaps = append(revertSnaps, snapName)
219+
revertSnaps = append(revertSnaps, snapshot.GetName())
220220
}
221221

222222
if vol.contentType == ContentTypeFS {

internal/server/storage/drivers/driver_zfs_volumes.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,7 @@ func (d *zfs) CreateVolumeFromMigration(vol Volume, conn io.ReadWriteCloser, vol
939939
}
940940

941941
var respSnapshots []ZFSDataset
942-
var syncSnapshotNames []string
942+
var syncSnapshots []*migration.Snapshot
943943

944944
// Get the GUIDs of all target snapshots.
945945
for _, snapVol := range snapshots {
@@ -965,7 +965,7 @@ func (d *zfs) CreateVolumeFromMigration(vol Volume, conn io.ReadWriteCloser, vol
965965
}
966966

967967
if !found {
968-
syncSnapshotNames = append(syncSnapshotNames, srcSnapshot.Name)
968+
syncSnapshots = append(syncSnapshots, &migration.Snapshot{Name: &srcSnapshot.Name})
969969
}
970970
}
971971

@@ -992,10 +992,10 @@ func (d *zfs) CreateVolumeFromMigration(vol Volume, conn io.ReadWriteCloser, vol
992992
respSnapshots = []ZFSDataset{}
993993

994994
// Let the source know that we need all snapshots.
995-
syncSnapshotNames = []string{}
995+
syncSnapshots = []*migration.Snapshot{}
996996

997997
for _, dataset := range migrationHeader.SnapshotDatasets {
998-
syncSnapshotNames = append(syncSnapshotNames, dataset.Name)
998+
syncSnapshots = append(syncSnapshots, &migration.Snapshot{Name: &dataset.Name})
999999
}
10001000
} else {
10011001
// Delete local snapshots which exist on the target but not on the source.
@@ -1041,7 +1041,7 @@ func (d *zfs) CreateVolumeFromMigration(vol Volume, conn io.ReadWriteCloser, vol
10411041

10421042
// Don't pass the snapshots if it's volume only.
10431043
if !volumeOnly {
1044-
volTargetArgs.Snapshots = syncSnapshotNames
1044+
volTargetArgs.Snapshots = syncSnapshots
10451045
}
10461046
}
10471047

@@ -1090,8 +1090,8 @@ func (d *zfs) createVolumeFromMigrationOptimized(vol Volume, conn io.ReadWriteCl
10901090
}
10911091

10921092
// Transfer the snapshots.
1093-
for _, snapName := range volTargetArgs.Snapshots {
1094-
snapVol, err := vol.NewSnapshot(snapName)
1093+
for _, snapshot := range volTargetArgs.Snapshots {
1094+
snapVol, err := vol.NewSnapshot(snapshot.GetName())
10951095
if err != nil {
10961096
return err
10971097
}
@@ -1151,8 +1151,8 @@ func (d *zfs) createVolumeFromMigrationOptimized(vol Volume, conn io.ReadWriteCl
11511151
// Check if snapshot data set matches one of the requested snapshots in volTargetArgs.Snapshots.
11521152
// If so, then keep it, otherwise request it be removed.
11531153
entrySnapName := strings.TrimPrefix(dataSetName, dataSetSnapshotPrefix)
1154-
for _, snapName := range volTargetArgs.Snapshots {
1155-
if entrySnapName == snapName {
1154+
for _, snapshot := range volTargetArgs.Snapshots {
1155+
if entrySnapName == snapshot.GetName() {
11561156
return true // Keep snapshot data set if present in the requested snapshots list.
11571157
}
11581158
}

internal/server/storage/drivers/generic_vfs.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/lxc/incus/v6/shared/ioprogress"
2626
"github.com/lxc/incus/v6/shared/logger"
2727
"github.com/lxc/incus/v6/shared/revert"
28+
"github.com/lxc/incus/v6/shared/units"
2829
"github.com/lxc/incus/v6/shared/util"
2930
)
3031

@@ -375,8 +376,9 @@ func genericVFSCreateVolumeFromMigration(d Driver, initVolume func(vol Volume) (
375376
}
376377

377378
// Snapshots are sent first by the sender, so create these first.
378-
for _, snapName := range volTargetArgs.Snapshots {
379-
fullSnapshotName := GetSnapshotVolumeName(vol.name, snapName)
379+
for _, snapshot := range volTargetArgs.Snapshots {
380+
fullSnapshotName := GetSnapshotVolumeName(vol.name, snapshot.GetName())
381+
380382
snapVol := NewVolume(d, d.Name(), vol.volType, vol.contentType, fullSnapshotName, vol.config, vol.poolConfig)
381383

382384
if snapVol.contentType != ContentTypeBlock || snapVol.volType != VolumeTypeCustom { // Receive the filesystem snapshot first (as it is sent first).
@@ -393,12 +395,19 @@ func genericVFSCreateVolumeFromMigration(d Driver, initVolume func(vol Volume) (
393395
return err
394396
}
395397

398+
volSize, err := units.ParseByteSizeString(migration.GetSnapshotConfigValue(snapshot, "size"))
399+
if err != nil {
400+
return err
401+
}
402+
396403
// During migration (e.g., LVM → dir), the block file may be smaller because
397404
// recvBlockVol uses SparseFileWrapper, which omits trailing zero bytes and does not truncate.
398405
// enlargeVolumeBlockFile ensures the block file matches the source volume size by applying truncation.
399-
err = enlargeVolumeBlockFile(snapVol, pathBlock)
400-
if err != nil {
401-
return err
406+
if volSize > 0 {
407+
err = enlargeVolumeBlockFile(pathBlock, volSize)
408+
if err != nil {
409+
return err
410+
}
402411
}
403412
}
404413

@@ -457,9 +466,11 @@ func genericVFSCreateVolumeFromMigration(d Driver, initVolume func(vol Volume) (
457466
// During migration (e.g., LVM → dir), the block file may be smaller because
458467
// recvBlockVol uses SparseFileWrapper, which omits trailing zero bytes and does not truncate.
459468
// enlargeVolumeBlockFile ensures the block file matches the source volume size by applying truncation.
460-
err = enlargeVolumeBlockFile(vol, pathBlock)
461-
if err != nil {
462-
return err
469+
if volTargetArgs.VolumeSize > 0 {
470+
err = enlargeVolumeBlockFile(pathBlock, volTargetArgs.VolumeSize)
471+
if err != nil {
472+
return err
473+
}
463474
}
464475
}
465476

internal/server/storage/drivers/utils.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import (
2424
"github.com/lxc/incus/v6/shared/idmap"
2525
"github.com/lxc/incus/v6/shared/logger"
2626
"github.com/lxc/incus/v6/shared/subprocess"
27-
"github.com/lxc/incus/v6/shared/units"
2827
"github.com/lxc/incus/v6/shared/util"
2928
)
3029

@@ -391,16 +390,11 @@ func ensureVolumeBlockFile(vol Volume, path string, sizeBytes int64, allowUnsafe
391390
}
392391

393392
// enlargeVolumeBlockFile enlarges the raw block file for a volume to the specified size.
394-
func enlargeVolumeBlockFile(vol Volume, path string) error {
393+
func enlargeVolumeBlockFile(path string, volSize int64) error {
395394
if linux.IsBlockdevPath(path) {
396395
return nil
397396
}
398397

399-
volSize, err := units.ParseByteSizeString(vol.ConfigSize())
400-
if err != nil {
401-
return err
402-
}
403-
404398
actualSize, err := BlockDiskSizeBytes(path)
405399
if err != nil {
406400
return err

0 commit comments

Comments
 (0)