This is an automated email from the ASF dual-hosted git repository.

Yukang-Lian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new c54083d0a92 [fix](cloud) Validate server config before starting 
services (#66947)
c54083d0a92 is described below

commit c54083d0a922bb6e2634e11fe70f2d08b6e58747
Author: Jamie <[email protected]>
AuthorDate: Fri Aug 21 15:26:30 2026 +0800

    [fix](cloud) Validate server config before starting services (#66947)
    
    ## Proposed changes
    
    - Validate Cloud server configuration before initializing TxnKv,
    MetaService, Recycler, or background threads.
    - Keep start-time validation as a defensive check.
    - Add OSS starter unit coverage for plaintext, unsupported TLS, and
    null-server configurations.
    
    ## Problem
    
    Cloud server validation currently runs after MetaService, Recycler, and
    the Recycler logging thread have started. If validation rejects the
    configuration, `main` returns through partially initialized resources,
    and the joinable Recycler thread can terminate the process during stack
    unwinding.
---
 cloud/src/main.cpp                                 | 12 ++--
 cloud/src/server/cloud_server_starter_factory.h    |  1 +
 .../server/oss/cloud_server_starter_factory.cpp    |  9 ++-
 cloud/test/CMakeLists.txt                          |  4 ++
 cloud/test/cloud_server_starter_factory_test.cpp   | 64 ++++++++++++++++++++++
 5 files changed, 85 insertions(+), 5 deletions(-)

diff --git a/cloud/src/main.cpp b/cloud/src/main.cpp
index be8b347fdc9..bbaa7953a5a 100644
--- a/cloud/src/main.cpp
+++ b/cloud/src/main.cpp
@@ -252,6 +252,13 @@ int main(int argc, char** argv) {
     brpc::FLAGS_max_body_size = config::brpc_max_body_size;
     brpc::FLAGS_socket_max_unwritten_bytes = 
config::brpc_socket_max_unwritten_bytes;
 
+    std::unique_ptr<ICloudServerStarter> meta_brpc_starter;
+    int port = config::brpc_listen_port;
+    if (!create_meta_brpc_starter(&server, port, &meta_brpc_starter) ||
+        !meta_brpc_starter->validate_config()) {
+        return -1;
+    }
+
     std::shared_ptr<TxnKv> txn_kv;
     if (config::use_mem_kv) {
         // MUST NOT be used in production environment
@@ -326,10 +333,7 @@ int main(int argc, char** argv) {
         pthread_setname_np(periodiccally_log_thread.native_handle(), 
"recycler_periodically_log");
     }
 
-    std::unique_ptr<ICloudServerStarter> meta_brpc_starter;
-    int port = config::brpc_listen_port;
-    if (!create_meta_brpc_starter(&server, port, &meta_brpc_starter) ||
-        !meta_brpc_starter->start()) {
+    if (!meta_brpc_starter->start()) {
         return -1;
     }
     end = steady_clock::now();
diff --git a/cloud/src/server/cloud_server_starter_factory.h 
b/cloud/src/server/cloud_server_starter_factory.h
index 28419842c58..5dc5ca0da2f 100644
--- a/cloud/src/server/cloud_server_starter_factory.h
+++ b/cloud/src/server/cloud_server_starter_factory.h
@@ -30,6 +30,7 @@ namespace doris::cloud {
 class ICloudServerStarter {
 public:
     virtual ~ICloudServerStarter() = default;
+    virtual bool validate_config() = 0;
     virtual bool start() = 0;
     virtual void stop() = 0;
     virtual void join() = 0;
diff --git a/cloud/src/server/oss/cloud_server_starter_factory.cpp 
b/cloud/src/server/oss/cloud_server_starter_factory.cpp
index 85d12bb8988..bf898c046da 100644
--- a/cloud/src/server/oss/cloud_server_starter_factory.cpp
+++ b/cloud/src/server/oss/cloud_server_starter_factory.cpp
@@ -34,7 +34,7 @@ class OssMetaBrpcServerStarter final : public 
ICloudServerStarter {
 public:
     OssMetaBrpcServerStarter(brpc::Server* server, int port) : 
_server(server), _port(port) {}
 
-    bool start() override {
+    bool validate_config() override {
         if (_server == nullptr) {
             LOG(ERROR) << "meta brpc server is null";
             return false;
@@ -43,6 +43,13 @@ public:
             LOG(ERROR) << "Cloud TLS requires TLS module";
             return false;
         }
+        return true;
+    }
+
+    bool start() override {
+        if (!validate_config()) {
+            return false;
+        }
 
         brpc::ServerOptions options;
         if (config::brpc_idle_timeout_sec != -1) {
diff --git a/cloud/test/CMakeLists.txt b/cloud/test/CMakeLists.txt
index 6f0189acbf8..e8fefae321f 100644
--- a/cloud/test/CMakeLists.txt
+++ b/cloud/test/CMakeLists.txt
@@ -104,6 +104,8 @@ add_executable(util_test util_test.cpp)
 
 add_executable(network_util_test network_util_test.cpp)
 
+add_executable(cloud_server_starter_factory_test 
cloud_server_starter_factory_test.cpp)
+
 set(TLS_UT_TARGETS)
 if (ENABLE_TLS)
     file(GLOB_RECURSE TLS_UT_FILES CONFIGURE_DEPENDS
@@ -184,6 +186,8 @@ target_link_libraries(util_test ${TEST_LINK_LIBS})
 
 target_link_libraries(network_util_test ${TEST_LINK_LIBS})
 
+target_link_libraries(cloud_server_starter_factory_test ${TEST_LINK_LIBS})
+
 foreach(TLS_UT_TARGET ${TLS_UT_TARGETS})
     target_link_libraries(${TLS_UT_TARGET} ${TEST_LINK_LIBS})
 endforeach()
diff --git a/cloud/test/cloud_server_starter_factory_test.cpp 
b/cloud/test/cloud_server_starter_factory_test.cpp
new file mode 100644
index 00000000000..6105ea53348
--- /dev/null
+++ b/cloud/test/cloud_server_starter_factory_test.cpp
@@ -0,0 +1,64 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "server/cloud_server_starter_factory.h"
+
+#include <brpc/server.h>
+#include <gtest/gtest.h>
+
+#include <memory>
+
+#include "common/config.h"
+
+namespace doris::cloud {
+
+class CloudServerStarterFactoryTest : public testing::Test {
+protected:
+    void SetUp() override { original_enable_tls = config::enable_tls; }
+
+    void TearDown() override { config::enable_tls = original_enable_tls; }
+
+    bool original_enable_tls = false;
+};
+
+TEST_F(CloudServerStarterFactoryTest, PlaintextConfigIsValid) {
+    brpc::Server server;
+    std::unique_ptr<ICloudServerStarter> starter;
+    ASSERT_TRUE(create_meta_brpc_starter(&server, 0, &starter));
+
+    config::enable_tls = false;
+    EXPECT_TRUE(starter->validate_config());
+}
+
+TEST_F(CloudServerStarterFactoryTest, TlsConfigIsRejected) {
+    brpc::Server server;
+    std::unique_ptr<ICloudServerStarter> starter;
+    ASSERT_TRUE(create_meta_brpc_starter(&server, 0, &starter));
+
+    config::enable_tls = true;
+    EXPECT_FALSE(starter->validate_config());
+}
+
+TEST_F(CloudServerStarterFactoryTest, NullServerIsRejected) {
+    std::unique_ptr<ICloudServerStarter> starter;
+    ASSERT_TRUE(create_meta_brpc_starter(nullptr, 0, &starter));
+
+    config::enable_tls = false;
+    EXPECT_FALSE(starter->validate_config());
+}
+
+} // namespace doris::cloud


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to