Skip to content

Commit 32bb845

Browse files
author
Zhang Wenhao
committed
<feature>[kvm]: support TPM key provider restore from snapshot group
Add findKeyProviderUuidByName and defaultKeyProviderUuid methods to TpmEncryptedResourceKeyBackend interface for key provider lookup. Implement these methods in DummyTpmEncryptedResourceKeyBackend. Add backupUuid field to KvmSecureBootExtensions to support restoring from specific backup files instead of default latest backup. Update SnapshotGroupRevertTpmHelper to restore TPM key provider information from system tags on backup files, with fallback to default provider. Related: ZSV-11310 Resolves: ZSV-11441 Change-Id: I6d75766b6a6c616e73737a6d77626d6870706574
1 parent 98a926f commit 32bb845

4 files changed

Lines changed: 75 additions & 18 deletions

File tree

compute/src/main/java/org/zstack/compute/vm/devices/DummyTpmEncryptedResourceKeyBackend.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,21 @@ public String findKeyProviderUuidByTpm(String tpmUuid) {
2323
return null;
2424
}
2525

26+
@Override
27+
public String findKeyProviderUuidByName(String providerName) {
28+
return null;
29+
}
30+
2631
@Override
2732
public String findKeyProviderNameByTpm(String tpmUuid) {
2833
return null;
2934
}
3035

36+
@Override
37+
public String defaultKeyProviderUuid() {
38+
return null;
39+
}
40+
3141
@Override
3242
public void cloneEncryptedResourceKey(CloneEncryptedResourceKeyContext context, Completion completion) {
3343
// do nothing

compute/src/main/java/org/zstack/compute/vm/devices/TpmEncryptedResourceKeyBackend.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,21 @@ public interface TpmEncryptedResourceKeyBackend {
2525
*/
2626
String findKeyProviderUuidByTpm(String tpmUuid);
2727

28+
/**
29+
* maybe null (when crypto module is not installed)
30+
*/
31+
String findKeyProviderUuidByName(String providerName);
32+
2833
/**
2934
* maybe null (when crypto module is not installed)
3035
*/
3136
String findKeyProviderNameByTpm(String tpmUuid);
3237

38+
/**
39+
* maybe null (when crypto module is not installed)
40+
*/
41+
String defaultKeyProviderUuid();
42+
3343
static class CloneEncryptedResourceKeyContext {
3444
public String srcTpmUuid;
3545
public String dstTpmUuid;

plugin/kvm/src/main/java/org/zstack/kvm/efi/KvmSecureBootExtensions.java

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.zstack.kvm.efi;
22

3+
import org.apache.commons.lang.StringUtils;
34
import org.springframework.beans.factory.annotation.Autowired;
45
import org.zstack.compute.legacy.ComputeLegacyGlobalProperty;
56
import org.zstack.compute.vm.VmGlobalConfig;
@@ -33,7 +34,6 @@
3334
import org.zstack.header.vm.PreVmInstantiateResourceExtensionPoint;
3435
import org.zstack.header.vm.VmInstanceConstant;
3536
import org.zstack.header.vm.AfterReimageVmInstanceExtensionPoint;
36-
import org.zstack.header.vm.VmInstanceDestroyExtensionPoint;
3737
import org.zstack.header.vm.VmInstanceInventory;
3838
import org.zstack.header.vm.VmInstanceMigrateExtensionPoint;
3939
import org.zstack.header.vm.VmInstanceSpec;
@@ -364,6 +364,7 @@ public static class PrepareHostFileContext {
364364
public String hostUuid;
365365
public String vmUuid;
366366
public VmHostFileType type;
367+
public String backupUuid;
367368
public String syncReason;
368369

369370
public String path;
@@ -373,8 +374,10 @@ public static class PrepareHostFileContext {
373374
private VmHostFileVO vmHostFile;
374375
private VmHostBackupFileVO vmBackupFileVO;
375376

376-
// property: VmHostFileVO (read success) > VmHostFileVO (read fail) > VmHostBackupFileVO
377-
// Note: read VmHostBackupFileVO only if VmHostFileVO is not exist
377+
// property: VmHostBackupFileVO (when "backupUuid" is set)
378+
// > VmHostFileVO (read success)
379+
// > VmHostFileVO (read fail)
380+
// > VmHostBackupFileVO (vmInstanceUuid matched) <- read this only if VmHostFileVO is not exist
378381
}
379382

380383
@SuppressWarnings("rawtypes")
@@ -384,6 +387,11 @@ public void prepareHostFileOnHost(PrepareHostFileContext context, Completion com
384387
chain.then(new NoRollbackFlow() {
385388
String __name__ = "read-vm-host-file-from-origin-host";
386389

390+
@Override
391+
public boolean skip(Map data) {
392+
return StringUtils.isNotBlank(context.backupUuid);
393+
}
394+
387395
@Override
388396
public void run(FlowTrigger trigger, Map data) {
389397
VmHostFileVO vmHostFile = Q.New(VmHostFileVO.class)
@@ -439,12 +447,23 @@ public boolean skip(Map data) {
439447

440448
@Override
441449
public void run(FlowTrigger trigger, Map data) {
442-
context.vmBackupFileVO = Q.New(VmHostBackupFileVO.class)
443-
.eq(VmHostBackupFileVO_.type, context.type)
444-
.eq(VmHostBackupFileVO_.resourceUuid, context.vmUuid)
445-
.orderByDesc(VmHostBackupFileVO_.lastOpDate)
446-
.limit(1)
447-
.find();
450+
if (context.backupUuid == null) {
451+
context.vmBackupFileVO = Q.New(VmHostBackupFileVO.class)
452+
.eq(VmHostBackupFileVO_.type, context.type)
453+
.eq(VmHostBackupFileVO_.resourceUuid, context.vmUuid)
454+
.orderByDesc(VmHostBackupFileVO_.lastOpDate)
455+
.limit(1)
456+
.find();
457+
} else {
458+
context.vmBackupFileVO = Q.New(VmHostBackupFileVO.class)
459+
.eq(VmHostBackupFileVO_.uuid, context.backupUuid)
460+
.find();
461+
if (context.vmBackupFileVO == null) {
462+
trigger.fail(operr("cannot find matched vm-host backup file[backupUuid:%s]",
463+
context.backupUuid));
464+
return;
465+
}
466+
}
448467
if (context.vmBackupFileVO != null) {
449468
logger.debug(String.format("use %s[type=%s] VM-host backup file for VM[uuid=%s]",
450469
context.vmBackupFileVO.getUuid(), context.type, context.vmUuid));

plugin/kvm/src/main/java/org/zstack/kvm/tpm/SnapshotGroupRevertTpmHelper.java

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.springframework.beans.factory.annotation.Autowired;
55
import org.springframework.beans.factory.annotation.Configurable;
66
import org.zstack.compute.vm.VmGlobalConfig;
7+
import org.zstack.compute.vm.devices.TpmEncryptedResourceKeyBackend;
78
import org.zstack.core.db.Q;
89
import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupVO;
910
import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupVO_;
@@ -15,6 +16,7 @@
1516
import org.zstack.header.vm.additions.VmHostFileType;
1617
import org.zstack.header.vm.devices.NvRamSpec;
1718
import org.zstack.header.vm.devices.VmDevicesSpec;
19+
import org.zstack.kvm.KVMSystemTags;
1820
import org.zstack.resourceconfig.ResourceConfigFacade;
1921
import org.zstack.utils.Utils;
2022
import org.zstack.utils.logging.CLogger;
@@ -26,7 +28,9 @@ public class SnapshotGroupRevertTpmHelper {
2628
private static final CLogger logger = Utils.getLogger(SnapshotGroupRevertTpmHelper.class);
2729

2830
@Autowired
29-
ResourceConfigFacade resourceConfigFacade;
31+
private ResourceConfigFacade resourceConfigFacade;
32+
@Autowired
33+
private TpmEncryptedResourceKeyBackend tpmKeyBackend;
3034

3135
public void setupFromApi(APICreateVmInstanceFromVolumeSnapshotGroupMsg apiMsg, CreateVmInstanceMsg cmsg) {
3236
String snapshotGroupUuid = apiMsg.getVolumeSnapshotGroupUuid();
@@ -87,17 +91,31 @@ public void setupFromApi(APICreateVmInstanceFromVolumeSnapshotGroupMsg apiMsg, C
8791
tpmSpec.setEnable(true);
8892

8993
if (resetTpm) {
90-
// resetTpm=true: reset secretUuid, generate a new one during VM creation
94+
// resetTpm=true: reset generate a new one during VM creation
9195
logger.debug(String.format("resetTpm is true for volume snapshot group[uuid:%s], " +
92-
"will reset secretUuid, tpmBackupFileUuid:%s", snapshotGroupUuid, tpmBackupFile.getUuid()));
96+
"will reset tpmBackupFileUuid:%s", snapshotGroupUuid, tpmBackupFile.getUuid()));
9397
} else {
9498
tpmSpec.setBackupFileUuid(tpmBackupFile.getUuid());
95-
// resetTpm=false: should reuse secretUuid + keyProviderUuid recorded in VolumeSnapshotGroup,
96-
// but the recording step is not yet implemented, leave them empty for now
97-
// TODO: retrieve secretUuid and keyProviderUuid from VolumeSnapshotGroup and set them here
98-
logger.warn(String.format("resetTpm is false for volume snapshot group[uuid:%s], " +
99-
"should restore secretUuid and keyProviderUuid but they are not yet recorded in snapshot group, " +
100-
"leaving empty. tpmBackupFileUuid:%s", snapshotGroupUuid, tpmBackupFile.getUuid()));
99+
}
100+
101+
String keyProviderName = KVMSystemTags.TPM_KEY_PROVIDER_NAME
102+
.getTokenByResourceUuid(tpmBackupFile.getUuid(), KVMSystemTags.TPM_KEY_PROVIDER_NAME_TOKEN);
103+
if (keyProviderName == null) {
104+
logger.warn(String.format(
105+
"failed to find keyProvider from snapshotGroup[uuid:%s] by tpmBackupFile[uuid:%s]",
106+
snapshotGroupUuid, tpmBackupFile.getUuid()));
107+
if (tpmSpec.getKeyProviderUuid() == null) {
108+
tpmSpec.setKeyProviderUuid(tpmKeyBackend.defaultKeyProviderUuid()); // maybe null
109+
}
110+
} else {
111+
String keyProviderUuid = tpmKeyBackend.findKeyProviderUuidByName(keyProviderName);
112+
if (keyProviderUuid == null) {
113+
logger.warn(String.format(
114+
"failed to resolve keyProvider[name:%s] from snapshotGroup[uuid:%s] by tpmBackupFile[uuid:%s], keep keyProviderUuid unset",
115+
keyProviderName, snapshotGroupUuid, tpmBackupFile.getUuid()));
116+
} else {
117+
tpmSpec.setKeyProviderUuid(keyProviderUuid);
118+
}
101119
}
102120
}
103121

0 commit comments

Comments
 (0)