You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by aw...@apache.org on 2020/01/18 08:46:35 UTC

[kudu] 02/02: mini-cluster: disallow restarting daemons from other threads

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

awong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git

commit 0cded868fd3d8ff088cd290dccdd9d90fdc0817c
Author: Andrew Wong <aw...@apache.org>
AuthorDate: Fri Jan 17 18:46:58 2020 -0800

    mini-cluster: disallow restarting daemons from other threads
    
    If we restart an external daemon from a separate thread, the daemon can be
    killed silently and without warning when the thread is reaped.
    
    For instance, the following would fail without logging any information about
    the tserver dying:
    
    TEST_F(ExternalMiniClusterITestBase, TestRestartFromThread) {
      ExternalMiniClusterOptions opts;
      opts.num_tablet_servers = 1;
      NO_FATALS(StartClusterWithOpts(std::move(opts)));
      thread t([&] {
        auto* ts = cluster_->tablet_server(0);
        ts->Shutdown();
        return ts->Restart();
      });
      t.join();
      SleepFor(MonoDelta::FromSeconds(1));
      ASSERT_TRUE(cluster_->tablet_server(0)->IsProcessAlive());
    }
    
    I didn't add a death test, since death tests themselves don't work well in
    multithreaded contexts.
    
    Change-Id: I184a01be3e1ac7f60a8b3aedab176dc9138033e0
    Reviewed-on: http://gerrit.cloudera.org:8080/15069
    Tested-by: Kudu Jenkins
    Reviewed-by: Alexey Serbin <as...@cloudera.com>
---
 src/kudu/mini-cluster/external_mini_cluster.cc | 9 +++++++--
 src/kudu/mini-cluster/external_mini_cluster.h  | 7 +++++++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/kudu/mini-cluster/external_mini_cluster.cc b/src/kudu/mini-cluster/external_mini_cluster.cc
index 0120dc9..54eae8f 100644
--- a/src/kudu/mini-cluster/external_mini_cluster.cc
+++ b/src/kudu/mini-cluster/external_mini_cluster.cc
@@ -25,11 +25,11 @@
 #include <iterator>
 #include <memory>
 #include <string>
+#include <thread>
 #include <unordered_set>
 #include <utility>
 
 #include <gflags/gflags.h>
-#include <gflags/gflags_declare.h>
 #include <gtest/gtest.h>
 
 #include "kudu/client/client.h"
@@ -939,7 +939,8 @@ string ExternalMiniCluster::UuidForTS(int ts_idx) const {
 //------------------------------------------------------------
 
 ExternalDaemon::ExternalDaemon(ExternalDaemonOptions opts)
-    : opts_(std::move(opts)) {
+    : opts_(std::move(opts)),
+      parent_tid_(std::this_thread::get_id()) {
   CHECK(rpc_bind_address().Initialized());
 }
 
@@ -968,6 +969,10 @@ Status ExternalDaemon::EnableKerberos(MiniKdc* kdc, const string& bind_host) {
 
 Status ExternalDaemon::StartProcess(const vector<string>& user_flags) {
   CHECK(!process_);
+  const auto this_tid = std::this_thread::get_id();
+  CHECK_EQ(parent_tid_, this_tid)
+    << "Process being started from thread " << this_tid << " which is different"
+    << " from the instantiating thread " << parent_tid_;
 
   vector<string> argv;
 
diff --git a/src/kudu/mini-cluster/external_mini_cluster.h b/src/kudu/mini-cluster/external_mini_cluster.h
index 428ec3a..5b7b81d 100644
--- a/src/kudu/mini-cluster/external_mini_cluster.h
+++ b/src/kudu/mini-cluster/external_mini_cluster.h
@@ -25,6 +25,8 @@
 #include <memory>
 #include <ostream>
 #include <string>
+#include <thread>
+#include <utility>
 #include <vector>
 
 #include <boost/optional/optional.hpp>
@@ -610,6 +612,11 @@ class ExternalDaemon : public RefCountedThreadSafe<ExternalDaemon> {
   HostPort bound_rpc_;
   HostPort bound_http_;
 
+  // ID of the thread that is spawning the child processes. This should not
+  // change across restarts of the daemon, as forking from different threads
+  // may yield behavior like daemons being killed when the new thread exits.
+  const std::thread::id parent_tid_;
+
   DISALLOW_COPY_AND_ASSIGN(ExternalDaemon);
 };