Skip to content

Commit 4db6aab

Browse files
author
gitlab
committed
Merge branch 'zsv-ldap-4' into 'feature-zsv-5.0.0-vm-support-vtpm-and-secuceboot'
<refactor>[kvm]: improve TPM removal by cleaning host files before DB deletion See merge request zstackio/zstack!9527
2 parents 93a9b91 + efc4fc2 commit 4db6aab

1 file changed

Lines changed: 69 additions & 14 deletions

File tree

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

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@
5353
import org.zstack.header.vm.additions.VmHostFileType;
5454
import org.zstack.header.vm.additions.VmHostFileVO;
5555
import org.zstack.header.vm.additions.VmHostFileVO_;
56+
import org.zstack.header.vm.additions.VmHostFileOperation;
57+
import org.zstack.header.core.ReturnValueCompletion;
58+
import org.zstack.kvm.KVMConstant;
59+
import org.zstack.kvm.KVMAgentCommands;
60+
import org.zstack.kvm.KvmCommandSender;
61+
import org.zstack.kvm.KvmResponseWrapper;
5662
import org.zstack.kvm.tpm.message.CloneVmTpmMsg;
5763
import org.zstack.kvm.tpm.message.CloneVmTpmReply;
5864
import org.zstack.resourceconfig.ResourceConfig;
@@ -62,10 +68,9 @@
6268
import org.zstack.utils.logging.CLogger;
6369

6470
import java.util.ArrayList;
65-
import java.util.HashSet;
71+
import java.util.HashMap;
6672
import java.util.List;
6773
import java.util.Map;
68-
import java.util.Set;
6974

7075
import static org.zstack.compute.vm.VmGlobalConfig.RESET_TPM_AFTER_VM_CLONE;
7176
import static org.zstack.core.Platform.err;
@@ -294,6 +299,7 @@ public String getName() {
294299
static class RemoveTpmFromVmContext {
295300
String vmInstanceUuid;
296301
String tpmUuid;
302+
List<VmHostFileVO> hostFiles;
297303

298304
static RemoveTpmFromVmContext valueOf(RemoveTpmMsg msg) {
299305
RemoveTpmFromVmContext context = new RemoveTpmFromVmContext();
@@ -320,36 +326,85 @@ private void removeTpmFromVm(RemoveTpmFromVmContext context, Completion completi
320326
trigger.next();
321327
})
322328
.build())
329+
.then(Flow.of("collect-vm-host-files")
330+
.handle(trigger -> {
331+
// DO NOT delete NvRam type VmHostFile: Maybe secure boot or other component related.
332+
context.hostFiles = Q.New(VmHostFileVO.class)
333+
.eq(VmHostFileVO_.vmInstanceUuid, context.vmInstanceUuid)
334+
.eq(VmHostFileVO_.type, VmHostFileType.TpmState)
335+
.list();
336+
trigger.next();
337+
})
338+
.build())
339+
.then(Flow.of("send-delete-commands-to-hosts")
340+
.skipIf(data -> context.hostFiles.isEmpty())
341+
.handle(trigger -> {
342+
Map<String, List<VmHostFileVO>> filesByHost = new HashMap<>();
343+
for (VmHostFileVO file : context.hostFiles) {
344+
filesByHost.computeIfAbsent(file.getHostUuid(), k -> new ArrayList<>()).add(file);
345+
}
346+
347+
new While<>(filesByHost.entrySet()).each((entry, whileCompletion) -> {
348+
String hostUuid = entry.getKey();
349+
List<VmHostFileVO> files = entry.getValue();
350+
351+
KVMAgentCommands.WriteVmHostFileContentCmd cmd = new KVMAgentCommands.WriteVmHostFileContentCmd();
352+
List<KVMAgentCommands.VmHostFileTO> fileTOs = new ArrayList<>();
353+
for (VmHostFileVO file : files) {
354+
KVMAgentCommands.VmHostFileTO to = new KVMAgentCommands.VmHostFileTO();
355+
to.setPath(file.getPath());
356+
to.setType(file.getType().toString());
357+
to.setOperation(VmHostFileOperation.Delete.toString());
358+
fileTOs.add(to);
359+
}
360+
cmd.setHostFiles(fileTOs);
361+
362+
new KvmCommandSender(hostUuid).send(cmd, KVMConstant.WRITE_VM_HOST_FILE_PATH, wrapper -> {
363+
KVMAgentCommands.WriteVmHostFileContentResponse rsp =
364+
wrapper.getResponse(KVMAgentCommands.WriteVmHostFileContentResponse.class);
365+
return rsp.isSuccess() ? null : operr("failed to delete host files on host[uuid=%s]", hostUuid);
366+
}, new ReturnValueCompletion<KvmResponseWrapper>(whileCompletion) {
367+
@Override
368+
public void success(KvmResponseWrapper wrapper) {
369+
whileCompletion.done();
370+
}
371+
372+
@Override
373+
public void fail(ErrorCode errorCode) {
374+
logger.warn(String.format("failed to delete host files on host[uuid=%s], but continuing with DB cleanup: %s",
375+
hostUuid, errorCode.getDetails()));
376+
whileCompletion.done();
377+
}
378+
});
379+
}).run(new WhileDoneCompletion(trigger) {
380+
@Override
381+
public void done(ErrorCodeList errorCodeList) {
382+
trigger.next();
383+
}
384+
});
385+
})
386+
.build())
323387
.then(Flow.of("detach-resource-key")
324388
.handle(trigger -> {
325389
tpmKeyBackend.detachKeyProviderFromTpm(context.tpmUuid);
326390
trigger.next();
327391
})
328392
.build())
329-
.then(Flow.of("remove-tpm-db-records")
393+
.then(Flow.of("remove-db-records")
330394
.handle(trigger -> {
331395
new SQLBatch() {
332396
@Override
333397
protected void scripts() {
334-
Set<VmHostFileType> types = new HashSet<>();
335-
types.add(VmHostFileType.TpmState);
336-
337398
sql(TpmVO.class)
338399
.eq(TpmVO_.uuid, context.tpmUuid)
339400
.delete();
340-
341-
boolean needRegisterNvRam = vmTpmManager.needRegisterNvRam(context.vmInstanceUuid);
342-
if (!needRegisterNvRam) {
343-
types.add(VmHostFileType.NvRam);
344-
}
345-
346401
sql(VmHostFileVO.class)
347402
.eq(VmHostFileVO_.vmInstanceUuid, context.vmInstanceUuid)
348-
.in(VmHostFileVO_.type, types)
403+
.eq(VmHostFileVO_.type, VmHostFileType.TpmState)
349404
.delete();
350405
sql(VmHostBackupFileVO.class)
351406
.eq(VmHostBackupFileVO_.resourceUuid, context.vmInstanceUuid)
352-
.in(VmHostBackupFileVO_.type, types)
407+
.eq(VmHostBackupFileVO_.type, VmHostFileType.TpmState)
353408
.delete();
354409
}
355410
}.execute();

0 commit comments

Comments
 (0)