|
27 | 27 | import org.zstack.header.tpm.entity.TpmVO_; |
28 | 28 | import org.zstack.header.vm.DiskAO; |
29 | 29 | import org.zstack.header.vm.PreVmInstantiateResourceExtensionPoint; |
| 30 | +import org.zstack.header.vm.VmInstanceVO; |
| 31 | +import org.zstack.header.vm.VmInstanceVO_; |
30 | 32 | import org.zstack.header.vm.VmInstanceConstant; |
31 | 33 | import org.zstack.header.vm.AfterReimageVmInstanceExtensionPoint; |
32 | 34 | import org.zstack.header.vm.VmInstanceInventory; |
|
45 | 47 | import org.zstack.header.vm.additions.VmHostFileType; |
46 | 48 | import org.zstack.header.vm.additions.VmHostFileVO; |
47 | 49 | import org.zstack.header.vm.additions.VmHostFileVO_; |
| 50 | +import org.zstack.header.storage.snapshot.ConsistentType; |
| 51 | +import org.zstack.header.storage.snapshot.CreateVolumesSnapshotOverlayInnerMsg; |
| 52 | +import org.zstack.header.storage.snapshot.TakeVolumesSnapshotOnKvmReply; |
| 53 | +import org.zstack.header.storage.snapshot.VolumeSnapshotCreationExtensionPoint; |
| 54 | +import org.zstack.header.storage.snapshot.VolumeSnapshotInventory; |
| 55 | +import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupInventory; |
48 | 56 | import org.zstack.header.volume.VolumeInventory; |
49 | 57 | import org.zstack.kvm.KVMAgentCommands; |
50 | 58 | import org.zstack.kvm.KVMAgentCommands.*; |
@@ -83,7 +91,8 @@ public class KvmSecureBootExtensions implements KVMStartVmExtensionPoint, |
83 | 91 | VmPreMigrationExtensionPoint, |
84 | 92 | AfterReimageVmInstanceExtensionPoint, |
85 | 93 | VmReleaseResourceExtensionPoint, |
86 | | - VmInstanceMigrateExtensionPoint { |
| 94 | + VmInstanceMigrateExtensionPoint, |
| 95 | + VolumeSnapshotCreationExtensionPoint { |
87 | 96 | private static final CLogger logger = Utils.getLogger(KvmSecureBootExtensions.class); |
88 | 97 |
|
89 | 98 | @Autowired |
@@ -634,4 +643,86 @@ public void run(MessageReply reply) { |
634 | 643 | } |
635 | 644 | }); |
636 | 645 | } |
| 646 | + |
| 647 | + @Override |
| 648 | + public void afterVolumeLiveSnapshotGroupCreatedOnBackend(CreateVolumesSnapshotOverlayInnerMsg msg, |
| 649 | + TakeVolumesSnapshotOnKvmReply treply, |
| 650 | + Completion completion) { |
| 651 | + if (treply == null || !treply.isSuccess()) { |
| 652 | + completion.success(); |
| 653 | + return; |
| 654 | + } |
| 655 | + |
| 656 | + if (!msg.isBackupHostFileIfNeeded()) { |
| 657 | + completion.success(); |
| 658 | + return; |
| 659 | + } |
| 660 | + |
| 661 | + String vmUuid = msg.getLockedVmInstanceUuids().get(0); |
| 662 | + String hostUuid = Q.New(VmInstanceVO.class) |
| 663 | + .select(VmInstanceVO_.hostUuid) |
| 664 | + .eq(VmInstanceVO_.uuid, vmUuid) |
| 665 | + .findValue(); |
| 666 | + |
| 667 | + List<VmHostFileVO> hostFiles = Q.New(VmHostFileVO.class) |
| 668 | + .eq(VmHostFileVO_.vmInstanceUuid, vmUuid) |
| 669 | + .eq(VmHostFileVO_.hostUuid, hostUuid) |
| 670 | + .list(); |
| 671 | + |
| 672 | + if (hostFiles.isEmpty()) { |
| 673 | + completion.success(); |
| 674 | + return; |
| 675 | + } |
| 676 | + |
| 677 | + String tempResourceUuid = Platform.getUuid(); |
| 678 | + |
| 679 | + SyncVmHostFilesFromHostMsg syncMsg = new SyncVmHostFilesFromHostMsg(); |
| 680 | + syncMsg.setVmUuid(vmUuid); |
| 681 | + syncMsg.setHostUuid(hostUuid); |
| 682 | + |
| 683 | + for (VmHostFileVO file : hostFiles) { |
| 684 | + if (file.getType() == VmHostFileType.NvRam) { |
| 685 | + syncMsg.setNvRamPath(buildNvramSnapshotBackupFilePath(vmUuid)); |
| 686 | + } else if (file.getType() == VmHostFileType.TpmState) { |
| 687 | + syncMsg.setTpmStateFolder(buildTpmStateSnapshotBackupFilePath(vmUuid)); |
| 688 | + } |
| 689 | + } |
| 690 | + |
| 691 | + syncMsg.setSyncReason("snapshot-group-online-backup"); |
| 692 | + syncMsg.setSyncToBackup(true); |
| 693 | + syncMsg.setBackupResourceUuid(tempResourceUuid); |
| 694 | + bus.makeLocalServiceId(syncMsg, VmInstanceConstant.SECURE_BOOT_SERVICE_ID); |
| 695 | + bus.send(syncMsg, new CloudBusCallBack(completion) { |
| 696 | + @Override |
| 697 | + public void run(MessageReply reply) { |
| 698 | + if (reply.isSuccess()) { |
| 699 | + treply.setHostBackupTempResourceUuid(tempResourceUuid); |
| 700 | + logger.debug(String.format("synced backup host files for vm[uuid:%s] to VmHostBackupFileVO[resourceUuid:%s]", |
| 701 | + vmUuid, tempResourceUuid)); |
| 702 | + } else { |
| 703 | + logger.warn(String.format("failed to sync backup host files for vm[uuid:%s] during online snapshot, " + |
| 704 | + "but tolerated: %s", vmUuid, reply.getError().getReadableDetails())); |
| 705 | + } |
| 706 | + completion.success(); |
| 707 | + } |
| 708 | + }); |
| 709 | + } |
| 710 | + |
| 711 | + @Override |
| 712 | + public void afterVolumeLiveSnapshotGroupCreationFailsOnBackend(CreateVolumesSnapshotOverlayInnerMsg msg, |
| 713 | + TakeVolumesSnapshotOnKvmReply treply) { |
| 714 | + // No cleanup needed — backup files on agent side are ephemeral |
| 715 | + } |
| 716 | + |
| 717 | + @Override |
| 718 | + public void afterVolumeSnapshotGroupCreated(VolumeSnapshotGroupInventory snapshotGroup, |
| 719 | + ConsistentType consistentType, |
| 720 | + Completion completion) { |
| 721 | + completion.success(); |
| 722 | + } |
| 723 | + |
| 724 | + @Override |
| 725 | + public void afterVolumeSnapshotCreated(VolumeSnapshotInventory snapshot, Completion completion) { |
| 726 | + completion.success(); |
| 727 | + } |
637 | 728 | } |
0 commit comments