From 0e361d27e09e19b2fa5fcb41f113f9bccff0c734 Mon Sep 17 00:00:00 2001 From: Jamie Cui Date: Mon, 15 Dec 2025 14:45:11 +0800 Subject: [PATCH 1/2] refactor(domain): improve DomainStart logic and argument validation - Reorder null check for conn pointer Add file locking mechanism - Validate flags parameter Handle --only-tsb mode properly by - treating input as UUID Parallelize VRoot startup with guest - checking using std::async Improve error logging and code comments - Fix formatting in log statements --- virtrust/src/virtrust/api/domain.cpp | 76 ++++++++++++++++++---------- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/virtrust/src/virtrust/api/domain.cpp b/virtrust/src/virtrust/api/domain.cpp index b6c0574..199475f 100644 --- a/virtrust/src/virtrust/api/domain.cpp +++ b/virtrust/src/virtrust/api/domain.cpp @@ -310,7 +310,7 @@ VirtrustRc CheckCreateDomainName(const std::string &arg, std::string &domainName } // 处理--name=***或-n=***或-n***** bool isLongContainsName = arg.length() > 7 && arg.substr(0, 7) == "--name="; // 7是--name=的长度 - bool isShortContainsName = arg.length() > 3 && arg.substr(0, 2) == "-n"; // 这里大于3是处理-n并且紧跟字符的情况 + bool isShortContainsName = arg.length() > 3 && arg.substr(0, 2) == "-n"; // 这里大于3是处理-n并且紧跟字符的情况 if (isLongContainsName || isShortContainsName) { if (isLongContainsName || (isLongContainsName && arg.find('=') != std::string::npos)) { domainName = arg.substr(arg.find('=') + 1); @@ -638,7 +638,8 @@ VirtrustRc CheckCreateArgs(const std::vector &args) auto &arg = args[pos]; if (arg.empty() || arg.size() > CREATE_ARGS_MAX_STRING_LENGTH) { VIRTRUST_LOG_ERROR("|CheckCreateArgs|END|returnF||Arg with index {} not valid, " - "length needs to be between {} and {}.", pos, 1, CREATE_ARGS_MAX_STRING_LENGTH); + "length needs to be between {} and {}.", + pos, 1, CREATE_ARGS_MAX_STRING_LENGTH); return VirtrustRc::ERROR; } } @@ -933,50 +934,61 @@ VirtrustRc DomainStart(const std::unique_ptr &conn, const std::string & bool isOnlyTsb) { VIRTRUST_LOG_DEBUG("|DomainStart||START||start domainName: {}, isonlyTsb:{}", domainName, isOnlyTsb); + + // First, check conn is not null pointer if (conn == nullptr) { VIRTRUST_LOG_ERROR("|DomainStart|END|returnF|| ConnCtx is nullptr."); return VirtrustRc::ERROR; } + + // Perform file lock FileLock fileLock(LOCK_FILE); if (!fileLock.IsLocked()) { return VirtrustRc::ERROR; } - if (conn == nullptr) { - VIRTRUST_LOG_ERROR("|DomainStart|END|returnF||conn is nullptr"); + + // NOTE check for flags, currenty we only support: DOMAIN_START_NONE + // Libvirt does no checking and it is up to the hypervisor to refuse to start the domain if it cannot provide the + // requested CPU. With QEMU this means no checking is done at all since the default behavior of QEMU is to emit + // warnings, but start the domain anyway. + if (flags != DOMAIN_START_NONE) { + VIRTRUST_LOG_ERROR("flags only support: {}", static_cast(DOMAIN_START_NONE)); return VirtrustRc::ERROR; } - // 如果带--only-tsb仅更新tsb资源 + + std::string uuid; + if (isOnlyTsb) { - std::string uuidStr = domainName; - VIRTRUST_LOG_INFO("only update tsb resource"); - if (domainName.size() != 36) { // UUIDchang长度为36 - VIRTRUST_LOG_DEBUG("|DomainStart|END|returnF||invalid domain UUID: {}", domainName); + // HACK if --only-tsb enabled, the input domainName is actually the uuid (very hacky) + uuid = domainName; + VIRTRUST_LOG_INFO("only start tsb resource"); + // Check if the input uuid is valid + if (uuid.size() != 36) { // UUIDchang长度为36 + VIRTRUST_LOG_DEBUG("|DomainStart|END|returnF||invalid domain UUID: {}", uuid); return VirtrustRc::ERROR; } - if (StartVRoot(uuidStr.data()) != 0) { - VIRTRUST_LOG_DEBUG("|DomainStart|END|returnF||start vRoot failed,UUID: {}", domainName); + if (StartVRoot(uuid.data()) != 0) { + VIRTRUST_LOG_DEBUG("|DomainStart|END|returnF||start vRoot failed,UUID: {}", uuid); + return VirtrustRc::ERROR; + } + VIRTRUST_LOG_DEBUG("|DomainStart||END|returnS|start domainName (only-tsb mode): {} success", uuid); + return VirtrustRc::OK; // unconditionally exit + } else { + // Get domain instance + auto domain = std::make_unique(conn, domainName); + if (domain->Get() == nullptr) { + VIRTRUST_LOG_ERROR("failed to find domain: {}", domainName); return VirtrustRc::ERROR; } - VIRTRUST_LOG_DEBUG("|DomainStart||END|returnS|start domainName: {} success", domainName); - return VirtrustRc::OK; - } - if (flags != DOMAIN_START_NONE) { - VIRTRUST_LOG_ERROR("flags only support: {}", static_cast(DOMAIN_START_NONE)); - return VirtrustRc::ERROR; - } - auto domain = std::make_unique(conn, domainName); - if (domain->Get() == nullptr) { - VIRTRUST_LOG_ERROR("failed to find domain: {}", domainName); - return VirtrustRc::ERROR; - } - std::string uuid = GetUUIDStr(domain->Get()); - auto tsbRc = StartVRoot(uuid.data()); - if (tsbRc != 0) { - VIRTRUST_LOG_ERROR("start vRoot failed: {}", domainName); - return VirtrustRc::ERROR; + // Get actual UUID from + uuid = GetUUIDStr(domain->Get()); } + // Since Starting VRoot and check guest can run in parallel, use std::async + auto asyncStartVRoot = std::async(&StartVRoot, uuid.data()); + + // Secure Start Check (include mounting, hashing, and sending measures to tsb) VIRTRUST_LOG_INFO("Perform checking on: {} before start", domainName); if (!CheckGuestBeforeStart(domainName, uuid)) { VIRTRUST_LOG_ERROR("Check domain failed,domainName: {}", domainName); @@ -986,6 +998,14 @@ VirtrustRc DomainStart(const std::unique_ptr &conn, const std::string & return VirtrustRc::ERROR; } + // Make async join the main thread + auto startVRootRc = asyncStartVRoot.join(); + if (startVRootRc != 0) { + VIRTRUST_LOG_ERROR("Start vRoot failed: {}", uuid); + return VirtrustRc::ERROR; + } + + // Start Domain with libvirt api if (Libvirt::GetInstance().virDomainCreateWithFlags(domain->Get(), flags) < 0) { VIRTRUST_LOG_ERROR("failed to start domain: {}", domainName); if (StopVRoot(uuid.data()) != 0) { -- Gitee From c6ae3463ec694639ce013e59780c84a404af1dfb Mon Sep 17 00:00:00 2001 From: Jamie Cui Date: Mon, 15 Dec 2025 15:36:37 +0800 Subject: [PATCH 2/2] fix(domain): correct async handling and link secure_c library - Replace `std::async` `.join()` with `.get()` for proper future - handling Adjust conditional logic flow in DomainStart for better - readability Link `Deps::secure_c` instead of `boundscheck` in - CMakeLists.txt Include `` and `` headers where - needed --- virtrust/src/virtrust/CMakeLists.txt | 2 +- virtrust/src/virtrust/api/domain.cpp | 21 +++++++++++---------- virtrust/src/virtrust/base/str_utils.h | 1 + 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/virtrust/src/virtrust/CMakeLists.txt b/virtrust/src/virtrust/CMakeLists.txt index b57c331..ca78eae 100644 --- a/virtrust/src/virtrust/CMakeLists.txt +++ b/virtrust/src/virtrust/CMakeLists.txt @@ -77,7 +77,7 @@ target_include_directories( PRIVATE ${CMAKE_DEPS_INCLUDEDIR} ${CMAKE_CURRENT_BINARY_DIR}/src $) -target_link_libraries(virtrust-shared PRIVATE Deps::spdlog boundscheck) +target_link_libraries(virtrust-shared PRIVATE Deps::spdlog Deps::secure_c) target_link_libraries( virtrust-shared diff --git a/virtrust/src/virtrust/api/domain.cpp b/virtrust/src/virtrust/api/domain.cpp index 199475f..de5a953 100644 --- a/virtrust/src/virtrust/api/domain.cpp +++ b/virtrust/src/virtrust/api/domain.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include "spdlog/fmt/fmt.h" @@ -973,18 +974,18 @@ VirtrustRc DomainStart(const std::unique_ptr &conn, const std::string & } VIRTRUST_LOG_DEBUG("|DomainStart||END|returnS|start domainName (only-tsb mode): {} success", uuid); return VirtrustRc::OK; // unconditionally exit - } else { - // Get domain instance - auto domain = std::make_unique(conn, domainName); - if (domain->Get() == nullptr) { - VIRTRUST_LOG_ERROR("failed to find domain: {}", domainName); - return VirtrustRc::ERROR; - } + } - // Get actual UUID from - uuid = GetUUIDStr(domain->Get()); + // Get domain instance + auto domain = std::make_unique(conn, domainName); + if (domain->Get() == nullptr) { + VIRTRUST_LOG_ERROR("failed to find domain: {}", domainName); + return VirtrustRc::ERROR; } + // Get actual UUID from + uuid = GetUUIDStr(domain->Get()); + // Since Starting VRoot and check guest can run in parallel, use std::async auto asyncStartVRoot = std::async(&StartVRoot, uuid.data()); @@ -999,7 +1000,7 @@ VirtrustRc DomainStart(const std::unique_ptr &conn, const std::string & } // Make async join the main thread - auto startVRootRc = asyncStartVRoot.join(); + auto startVRootRc = asyncStartVRoot.get(); if (startVRootRc != 0) { VIRTRUST_LOG_ERROR("Start vRoot failed: {}", uuid); return VirtrustRc::ERROR; diff --git a/virtrust/src/virtrust/base/str_utils.h b/virtrust/src/virtrust/base/str_utils.h index 39cea02..cadd5ab 100644 --- a/virtrust/src/virtrust/base/str_utils.h +++ b/virtrust/src/virtrust/base/str_utils.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include -- Gitee