Skip to content

Commit 167977d

Browse files
author
gitlab
committed
Merge branch 'zsv-ldap@@2' into 'feature-zsv-5.0.0-vm-support-vtpm-and-secuceboot'
<feature>[kvm]: periodic check and sync for VM host files See merge request zstackio/zstack!9555
2 parents 075028d + 195a8e0 commit 167977d

10 files changed

Lines changed: 213 additions & 18 deletions

File tree

conf/db/zsv/V5.0.0__schema.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ CREATE TABLE IF NOT EXISTS `zstack`.`VmHostFileVO` (
1616
`type` varchar(64) NOT NULL COMMENT 'NvRam, TpmState',
1717
`path` varchar(1024) NOT NULL COMMENT 'Absolute path of the file on the host',
1818
`lastSyncReason` varchar(255) DEFAULT NULL COMMENT 'The reason for the last sync operation',
19+
`changeDate` timestamp NULL DEFAULT NULL COMMENT 'Timestamp when file was reported changed, null after sync',
20+
`lastSyncDate` timestamp NULL DEFAULT NULL COMMENT 'Timestamp of the last successful sync',
1921
`lastOpDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
2022
`createDate` timestamp NOT NULL DEFAULT '1999-12-31 23:59:59',
2123
PRIMARY KEY (`uuid`),

header/src/main/java/org/zstack/header/vm/VmCanonicalEvents.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.zstack.header.message.NeedJsonSchema;
44
import org.zstack.header.errorcode.ErrorCode;
55
import java.util.Date;
6+
import java.util.List;
67
import java.time.LocalDateTime;
78

89
/**
@@ -19,6 +20,8 @@ public class VmCanonicalEvents {
1920
public static final String VM_NIC_INFO_CHANGED_PATH = "/vm/nicinfo/change";
2021
public static final String VM_NIC_INFO_DUPLICATE_PATH = "/vm/nicinfo/duplicate";
2122
public static final String VM_NIC_INFO_IPRANGE_CONFLICT_PATH = "/vm/nicinfo/iprangeConflict";
23+
public static final String VM_HOST_FILE_CHANGED_PATH = "/vm/hostfile/changed";
24+
public static final String KVM_REPORT_VM_HOST_FILE_CHANGED = "/kvm/reportvmhostfilechanged";
2225

2326
@NeedJsonSchema
2427
public static class VmCrashReportData {
@@ -317,4 +320,35 @@ public void setInternalIp(String internalIp) {
317320
this.internalIp = internalIp;
318321
}
319322
}
323+
324+
@NeedJsonSchema
325+
public static class VmHostFileChangedData {
326+
private String hostUuid;
327+
private String vmUuid;
328+
private List<String> types;
329+
330+
public String getHostUuid() {
331+
return hostUuid;
332+
}
333+
334+
public void setHostUuid(String hostUuid) {
335+
this.hostUuid = hostUuid;
336+
}
337+
338+
public String getVmUuid() {
339+
return vmUuid;
340+
}
341+
342+
public void setVmUuid(String vmUuid) {
343+
this.vmUuid = vmUuid;
344+
}
345+
346+
public List<String> getTypes() {
347+
return types;
348+
}
349+
350+
public void setTypes(List<String> types) {
351+
this.types = types;
352+
}
353+
}
320354
}

header/src/main/java/org/zstack/header/vm/additions/VmHostFileInventory.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ public class VmHostFileInventory {
1717
private String type;
1818
private String path;
1919
private String lastSyncReason;
20+
private Timestamp changeDate;
21+
private Timestamp lastSyncDate;
2022
private Timestamp createDate;
2123
private Timestamp lastOpDate;
2224

@@ -31,6 +33,8 @@ public static VmHostFileInventory valueOf(VmHostFileVO vo) {
3133
inv.setType(vo.getType().toString());
3234
inv.setPath(vo.getPath());
3335
inv.setLastSyncReason(vo.getLastSyncReason());
36+
inv.setChangeDate(vo.getChangeDate());
37+
inv.setLastSyncDate(vo.getLastSyncDate());
3438
inv.setCreateDate(vo.getCreateDate());
3539
inv.setLastOpDate(vo.getLastOpDate());
3640
return inv;
@@ -88,6 +92,22 @@ public void setLastSyncReason(String lastSyncReason) {
8892
this.lastSyncReason = lastSyncReason;
8993
}
9094

95+
public Timestamp getChangeDate() {
96+
return changeDate;
97+
}
98+
99+
public void setChangeDate(Timestamp changeDate) {
100+
this.changeDate = changeDate;
101+
}
102+
103+
public Timestamp getLastSyncDate() {
104+
return lastSyncDate;
105+
}
106+
107+
public void setLastSyncDate(Timestamp lastSyncDate) {
108+
this.lastSyncDate = lastSyncDate;
109+
}
110+
91111
public Timestamp getCreateDate() {
92112
return createDate;
93113
}

header/src/main/java/org/zstack/header/vm/additions/VmHostFileSyncReason.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public enum VmHostFileSyncReason {
1212
RevertSnapshot("revert snapshot"),
1313
VolumeBackup("volume backup"),
1414
BeforeHaStart("on before HA start (from last host)"),
15+
PeriodicDirtyCheck("on periodic dirty check"),
16+
PeriodicForceSync("on periodic force sync"),
1517
;
1618

1719
public final String detail;

header/src/main/java/org/zstack/header/vm/additions/VmHostFileVO.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ public class VmHostFileVO extends ResourceVO {
4242
@Column
4343
private String lastSyncReason;
4444
@Column
45+
private Timestamp changeDate;
46+
@Column
47+
private Timestamp lastSyncDate;
48+
@Column
4549
private Timestamp createDate;
4650
@Column
4751
private Timestamp lastOpDate;
@@ -86,6 +90,22 @@ public void setLastSyncReason(String lastSyncReason) {
8690
this.lastSyncReason = lastSyncReason;
8791
}
8892

93+
public Timestamp getChangeDate() {
94+
return changeDate;
95+
}
96+
97+
public void setChangeDate(Timestamp changeDate) {
98+
this.changeDate = changeDate;
99+
}
100+
101+
public Timestamp getLastSyncDate() {
102+
return lastSyncDate;
103+
}
104+
105+
public void setLastSyncDate(Timestamp lastSyncDate) {
106+
this.lastSyncDate = lastSyncDate;
107+
}
108+
89109
public Timestamp getCreateDate() {
90110
return createDate;
91111
}
@@ -111,6 +131,8 @@ public String toString() {
111131
", type=" + type +
112132
", path='" + path + '\'' +
113133
", lastSyncReason='" + lastSyncReason + '\'' +
134+
", changeDate=" + changeDate +
135+
", lastSyncDate=" + lastSyncDate +
114136
", createDate=" + createDate +
115137
", lastOpDate=" + lastOpDate +
116138
'}';

header/src/main/java/org/zstack/header/vm/additions/VmHostFileVO_.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public class VmHostFileVO_ extends ResourceVO_ {
1313
public static volatile SingularAttribute<VmHostFileVO, VmHostFileType> type;
1414
public static volatile SingularAttribute<VmHostFileVO, String> path;
1515
public static volatile SingularAttribute<VmHostFileVO, String> lastSyncReason;
16+
public static volatile SingularAttribute<VmHostFileVO, Timestamp> changeDate;
17+
public static volatile SingularAttribute<VmHostFileVO, Timestamp> lastSyncDate;
1618
public static volatile SingularAttribute<VmHostFileVO, Timestamp> createDate;
1719
public static volatile SingularAttribute<VmHostFileVO, Timestamp> lastOpDate;
1820
}

plugin/kvm/src/main/java/org/zstack/kvm/KVMGlobalConfig.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ public class KVMGlobalConfig {
168168
public static GlobalConfig VM_EDK_VERSION_CONFIG = new GlobalConfig(CATEGORY, "vm.edk.version");
169169

170170
@GlobalConfigValidation(numberGreaterThan = 1, numberLessThan = 86400)
171-
@GlobalConfigDef(defaultValue = "1800", type = Long.class,
172-
description = "Interval in seconds for syncing VM host files (NvRam, TpmState) from KVM hosts")
171+
@GlobalConfigDef(defaultValue = "15", type = Long.class,
172+
description = "Interval in seconds for checking VM host files (NvRam, TpmState) on KVM hosts")
173173
public static GlobalConfig VM_HOST_FILE_SYNC_INTERVAL = new GlobalConfig(CATEGORY, "vm.host.file.sync.interval");
174174

175175
@GlobalConfigValidation(numberGreaterThan = 1, numberLessThan = 30)

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

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.zstack.core.db.Q;
1313
import org.zstack.core.db.SQL;
1414
import org.zstack.core.db.SQLBatch;
15+
import org.zstack.core.timeout.TimeHelper;
1516
import org.zstack.core.workflow.SimpleFlowChain;
1617
import org.zstack.header.AbstractService;
1718
import org.zstack.header.core.ReturnValueCompletion;
@@ -101,6 +102,8 @@ public class KvmSecureBootManager extends AbstractService {
101102
private ResourceConfigFacade resourceConfigFacade;
102103
@Autowired
103104
private KvmVmHostFileFactory vmHostFileFactory;
105+
@Autowired
106+
private TimeHelper timeHelper;
104107

105108
@Override
106109
public boolean start() {
@@ -217,6 +220,7 @@ private void handle(SyncVmHostFilesFromHostMsg msg) {
217220
to.setType(VmHostFileType.NvRam.toString());
218221
cmd.getHostFiles().add(to);
219222
}
223+
long now = timeHelper.getCurrentTimeMillis();
220224

221225
SyncVmHostFilesFromHostReply reply = new SyncVmHostFilesFromHostReply();
222226
sender.send(cmd, READ_VM_HOST_FILE_PATH, wrapper -> {
@@ -237,7 +241,7 @@ public void success(KvmResponseWrapper wrapper) {
237241
if (msg.isSyncToBackup()) {
238242
error = syncToBackupFiles(msg, readRsp);
239243
} else {
240-
error = syncToHostFiles(msg, cmd, readRsp);
244+
error = syncToHostFiles(msg, cmd, readRsp, now);
241245
}
242246

243247
if (error != null) {
@@ -256,7 +260,8 @@ public void fail(ErrorCode errorCode) {
256260

257261
private ErrorCode syncToHostFiles(SyncVmHostFilesFromHostMsg msg,
258262
KVMAgentCommands.ReadVmHostFileContentCmd cmd,
259-
KVMAgentCommands.ReadVmHostFileContentResponse readRsp) {
263+
KVMAgentCommands.ReadVmHostFileContentResponse readRsp,
264+
long timeBeforeSync) {
260265
final List<VmHostFileVO> existsFiles = Q.New(VmHostFileVO.class)
261266
.eq(VmHostFileVO_.vmInstanceUuid, msg.getVmUuid())
262267
.eq(VmHostFileVO_.hostUuid, msg.getHostUuid())
@@ -272,6 +277,7 @@ private ErrorCode syncToHostFiles(SyncVmHostFilesFromHostMsg msg,
272277
existsContentUuid = Collections.emptyList();
273278
}
274279

280+
Timestamp syncTime = new Timestamp(timeBeforeSync);
275281
List<ErrorCode> errors = new ArrayList<>();
276282
for (String path : cmd.getPaths()) {
277283
KVMAgentCommands.VmHostFileTO to = findOneOrNull(readRsp.getHostFiles(), item -> item.getPath().equals(path));
@@ -291,13 +297,25 @@ private ErrorCode syncToHostFiles(SyncVmHostFilesFromHostMsg msg,
291297
VmHostFileVO file = findOneOrNull(existsFiles, item -> item.getPath().equals(path));
292298
boolean fileExists = file != null;
293299

294-
Timestamp now = Timestamp.from(Instant.now());
295300
if (fileExists) {
296-
SQL.New(VmHostFileVO.class)
297-
.eq(VmHostFileVO_.uuid, file.getUuid())
298-
.set(VmHostFileVO_.lastOpDate, now)
299-
.set(VmHostFileVO_.lastSyncReason, msg.getSyncReason())
300-
.update();
301+
String fileUuid = file.getUuid();
302+
new SQLBatch() {
303+
@Override
304+
protected void scripts() {
305+
sql(VmHostFileVO.class)
306+
.eq(VmHostFileVO_.uuid, fileUuid)
307+
.set(VmHostFileVO_.lastSyncReason, msg.getSyncReason())
308+
.set(VmHostFileVO_.lastSyncDate, syncTime)
309+
.set(VmHostFileVO_.lastOpDate, syncTime)
310+
.update();
311+
sql(VmHostFileVO.class)
312+
.eq(VmHostFileVO_.uuid, fileUuid)
313+
.lt(VmHostFileVO_.changeDate, syncTime)
314+
.set(VmHostFileVO_.changeDate, null) // CAS update
315+
.update();
316+
}
317+
}.execute();
318+
301319
} else {
302320
file = new VmHostFileVO();
303321
file.setUuid(Platform.getUuid());
@@ -306,8 +324,10 @@ private ErrorCode syncToHostFiles(SyncVmHostFilesFromHostMsg msg,
306324
file.setPath(path);
307325
file.setType(type);
308326
file.setLastSyncReason(msg.getSyncReason());
309-
file.setCreateDate(now);
310-
file.setLastOpDate(now);
327+
file.setLastSyncDate(syncTime);
328+
file.setChangeDate(null);
329+
file.setLastOpDate(syncTime);
330+
file.setCreateDate(syncTime);
311331
file.setResourceName(String.format("%s file for %s", type, msg.getVmUuid()));
312332
databaseFacade.persist(file);
313333
}
@@ -318,15 +338,15 @@ private ErrorCode syncToHostFiles(SyncVmHostFilesFromHostMsg msg,
318338
.eq(VmHostFileContentVO_.uuid, file.getUuid())
319339
.set(VmHostFileContentVO_.content, bytes)
320340
.set(VmHostFileContentVO_.format, VmHostFileContentFormat.valueOf(to.getFileFormat()))
321-
.set(VmHostFileContentVO_.lastOpDate, now)
341+
.set(VmHostFileContentVO_.lastOpDate, syncTime)
322342
.update();
323343
} else {
324344
VmHostFileContentVO content = new VmHostFileContentVO();
325345
content.setUuid(file.getUuid());
326346
content.setContent(bytes);
327347
content.setFormat(VmHostFileContentFormat.valueOf(to.getFileFormat()));
328-
content.setCreateDate(now);
329-
content.setLastOpDate(now);
348+
content.setCreateDate(syncTime);
349+
content.setLastOpDate(syncTime);
330350
databaseFacade.persist(content);
331351
}
332352

@@ -489,7 +509,7 @@ public void run(FlowTrigger trigger, Map data) {
489509
VmHostFileVO file = Q.New(VmHostFileVO.class)
490510
.eq(VmHostFileVO_.vmInstanceUuid, msg.getSrcVmUuid())
491511
.eq(VmHostFileVO_.type, type)
492-
.orderByDesc(VmHostFileVO_.lastOpDate)
512+
.orderByDesc(VmHostFileVO_.lastSyncDate)
493513
.limit(1)
494514
.find();
495515
if (file == null) {
@@ -884,6 +904,7 @@ public void fail(ErrorCode errorCode) {
884904
.eq(VmHostFileVO_.uuid, currentFile.getUuid())
885905
.set(VmHostFileVO_.lastSyncReason, Restore.reason(msg.getSyncReason()))
886906
.set(VmHostFileVO_.lastOpDate, now)
907+
.set(VmHostFileVO_.lastSyncDate, now)
887908
.update();
888909

889910
VmHostFileContentVO existingContent = contentMap.get(currentFile.getUuid());
@@ -913,6 +934,7 @@ public void fail(ErrorCode errorCode) {
913934
newFile.setType(type);
914935
newFile.setPath(buildPathForVmHostFileType(type, msg.getVmInstanceUuid()));
915936
newFile.setLastSyncReason(Restore.reason(msg.getSyncReason()));
937+
newFile.setLastSyncDate(now);
916938
newFile.setCreateDate(now);
917939
newFile.setLastOpDate(now);
918940
databaseFacade.persist(newFile);

0 commit comments

Comments
 (0)