Skip to content

Commit 0a5630d

Browse files
author
Zhang Wenhao
committed
<fix>[kvm]: mark TPM VM host files changed on start/shutdown
When a VM with TPM starts or shuts down, NvRam/TpmState data must have changed. Preemptively set changeDate on the corresponding VmHostFileVO so the periodic tracker knows to sync them, even if the direct sync fails. Also add ResourceDestinationMaker check to all VM canonical event handlers in KvmSecureBootManager to ensure only the owning management node processes each event. Resolves: ZSV-11779 Related: ZSV-11310 Change-Id: I6e6d6c6c647175716669756b75756a6f72657277
1 parent 449ef01 commit 0a5630d

2 files changed

Lines changed: 91 additions & 0 deletions

File tree

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

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.zstack.core.cloudbus.EventCallback;
99
import org.zstack.core.cloudbus.EventFacadeImpl;
1010
import org.zstack.core.cloudbus.MessageSafe;
11+
import org.zstack.core.cloudbus.ResourceDestinationMaker;
1112
import org.zstack.core.db.DatabaseFacade;
1213
import org.zstack.core.db.Q;
1314
import org.zstack.core.db.SQL;
@@ -104,6 +105,8 @@ public class KvmSecureBootManager extends AbstractService {
104105
private KvmVmHostFileFactory vmHostFileFactory;
105106
@Autowired
106107
private TimeHelper timeHelper;
108+
@Autowired
109+
private ResourceDestinationMaker resourceDestinationMaker;
107110

108111
@Override
109112
public boolean start() {
@@ -118,10 +121,28 @@ public boolean stop() {
118121

119122
@SuppressWarnings("rawtypes")
120123
private void setupCanonicalEvents() {
124+
eventFacade.on(VmCanonicalEvents.VM_LIBVIRT_REPORT_START, new EventCallback<Object>() {
125+
@Override
126+
protected void run(Map tokens, Object data) {
127+
String vmUuid = (String) data;
128+
boolean managedByMe = resourceDestinationMaker.isManagedByUs(vmUuid);
129+
if (!managedByMe) {
130+
return;
131+
}
132+
markVmHostFilesChanged(vmUuid);
133+
}
134+
});
135+
121136
eventFacade.on(VmCanonicalEvents.VM_LIBVIRT_REPORT_SHUTDOWN, new EventCallback<Object>() {
122137
@Override
123138
protected void run(Map tokens, Object data) {
124139
String vmUuid = (String) data;
140+
boolean managedByMe = resourceDestinationMaker.isManagedByUs(vmUuid);
141+
if (!managedByMe) {
142+
return;
143+
}
144+
markVmHostFilesChanged(vmUuid);
145+
125146
Tuple tuple = Q.New(VmInstanceVO.class)
126147
.select(VmInstanceVO_.hostUuid, VmInstanceVO_.lastHostUuid)
127148
.eq(VmInstanceVO_.uuid, vmUuid)
@@ -173,6 +194,47 @@ public void run(MessageReply reply) {
173194
});
174195
}
175196

197+
/**
198+
* Preemptive judgment: when a VM with TPM (or enabled secure boot) starts or shuts down,
199+
* the NvRam/TpmState data must have changed, so mark the corresponding
200+
* VmHostFileVO.changeDate to current time.
201+
*/
202+
private void markVmHostFilesChanged(String vmUuid) {
203+
final Set<VmHostFileType> types = vmHostFileFactory.vmHostFileTypeNeedRegisterForVm(vmUuid);
204+
if (types.isEmpty()) {
205+
return;
206+
}
207+
208+
Tuple tuple = Q.New(VmInstanceVO.class)
209+
.select(VmInstanceVO_.hostUuid, VmInstanceVO_.lastHostUuid)
210+
.eq(VmInstanceVO_.uuid, vmUuid)
211+
.findTuple();
212+
if (tuple == null) {
213+
return;
214+
}
215+
216+
String hostUuid = (String) tuple.get(0);
217+
if (hostUuid == null) {
218+
hostUuid = (String) tuple.get(1);
219+
}
220+
if (hostUuid == null) {
221+
return;
222+
}
223+
224+
Timestamp now = new Timestamp(timeHelper.getCurrentTimeMillis());
225+
long updated = SQL.New(VmHostFileVO.class)
226+
.eq(VmHostFileVO_.vmInstanceUuid, vmUuid)
227+
.eq(VmHostFileVO_.hostUuid, hostUuid)
228+
.in(VmHostFileVO_.type, types)
229+
.set(VmHostFileVO_.changeDate, now)
230+
.update();
231+
232+
if (updated > 0) {
233+
logger.debug(String.format("preemptively marked VmHostFiles as changed for TPM vm[uuid:%s] on host[uuid:%s], %d records updated",
234+
vmUuid, hostUuid, updated));
235+
}
236+
}
237+
176238
@Override
177239
public String getId() {
178240
return bus.makeLocalServiceId(VmInstanceConstant.SECURE_BOOT_SERVICE_ID);

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,32 @@
11
package org.zstack.kvm.efi;
22

3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.zstack.core.db.Q;
5+
import org.zstack.header.tpm.entity.TpmVO;
6+
import org.zstack.header.tpm.entity.TpmVO_;
37
import org.zstack.header.vm.additions.VmHostBackupFileVO;
8+
import org.zstack.header.vm.additions.VmHostFileType;
49
import org.zstack.header.vm.additions.VmHostFileVO;
510
import org.zstack.kvm.tpm.TpmStateVmHostBackupFileBase;
611
import org.zstack.kvm.tpm.TpmStateVmHostFileBase;
712
import org.zstack.kvm.vmfiles.AbstractVmHostBackupFileBase;
813
import org.zstack.kvm.vmfiles.AbstractVmHostFileBase;
14+
import org.zstack.resourceconfig.ResourceConfig;
15+
import org.zstack.resourceconfig.ResourceConfigFacade;
916

17+
import java.util.Collections;
18+
import java.util.HashSet;
19+
import java.util.Set;
20+
21+
import static org.zstack.compute.vm.VmGlobalConfig.ENABLE_UEFI_SECURE_BOOT;
1022
import static org.zstack.core.Platform.operr;
23+
import static org.zstack.header.vm.additions.VmHostFileType.*;
24+
import static org.zstack.utils.CollectionDSL.list;
1125

1226
public class KvmVmHostFileFactory {
27+
@Autowired
28+
private ResourceConfigFacade resourceConfigFacade;
29+
1330
public AbstractVmHostFileBase createBase(VmHostFileVO file) {
1431
switch (file.getType()) {
1532
case NvRam: return new NvRamVmHostFileBase(file);
@@ -25,4 +42,16 @@ public AbstractVmHostBackupFileBase createBackupBase(VmHostBackupFileVO backupFi
2542
default: throw operr("invalid VM host file type: " + backupFile.getType()).toException();
2643
}
2744
}
45+
46+
public Set<VmHostFileType> vmHostFileTypeNeedRegisterForVm(String vmUuid) {
47+
boolean hasTpm = Q.New(TpmVO.class)
48+
.eq(TpmVO_.vmInstanceUuid, vmUuid)
49+
.isExists();
50+
if (hasTpm) {
51+
return new HashSet<>(list(NvRam, TpmState));
52+
}
53+
ResourceConfig resourceConfig = resourceConfigFacade.getResourceConfig(ENABLE_UEFI_SECURE_BOOT.getIdentity());
54+
return resourceConfig.getResourceConfigValue(vmUuid, Boolean.class) ?
55+
new HashSet<>(list(NvRam)) : Collections.emptySet();
56+
}
2857
}

0 commit comments

Comments
 (0)