You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by ad...@apache.org on 2018/10/31 04:47:38 UTC
[1/2] kudu git commit: [location_awareness] Add location info in ksck
report
Repository: kudu
Updated Branches:
refs/heads/master 606488495 -> 0b2fef41d
[location_awareness] Add location info in ksck report
This patch adds additional tablet server location info
into the ksck report.
Before:
Tablet Server Summary
UUID | Address | Status
----------------------------------+-----------------+---------
21b1960d8b164c869a3e600ed8bad1ea | 127.0.0.1:63000 | HEALTHY
2c55bc50306a4463aa5a935aa97caff6 | 127.0.0.1:62973 | HEALTHY
a8dee6038c494b97b883d98292f7771f | 127.0.0.1:62983 | HEALTHY
d3664283918a434cbc5a8e067fa7c3b0 | 127.0.0.1:62978 | HEALTHY
...
After:
Tablet Server Summary
UUID | Address | Status | Location
----------------------------------+-----------------+---------+----------
21b1960d8b164c869a3e600ed8bad1ea | 127.0.0.1:63000 | HEALTHY | /foo
2c55bc50306a4463aa5a935aa97caff6 | 127.0.0.1:62973 | HEALTHY | <none>
a8dee6038c494b97b883d98292f7771f | 127.0.0.1:62983 | HEALTHY | <none>
d3664283918a434cbc5a8e067fa7c3b0 | 127.0.0.1:62978 | HEALTHY | <none>
Tablet Server Location Summary
Location | Count
----------+---------
<none> | 3
/foo | 1
...
Change-Id: Ideff2dd4975c99a1135002624debbbb2620fb95c
Reviewed-on: http://gerrit.cloudera.org:8080/11422
Tested-by: Kudu Jenkins
Reviewed-by: Alexey Serbin <as...@cloudera.com>
Reviewed-by: Will Berkeley <wd...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/973fc9a0
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/973fc9a0
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/973fc9a0
Branch: refs/heads/master
Commit: 973fc9a08596692fd9770959da5992b518fca5ec
Parents: 6064884
Author: fwang29 <fw...@cloudera.com>
Authored: Mon Oct 15 15:23:28 2018 -0700
Committer: Will Berkeley <wd...@gmail.com>
Committed: Tue Oct 30 23:34:45 2018 +0000
----------------------------------------------------------------------
src/kudu/tools/CMakeLists.txt | 4 ++-
src/kudu/tools/ksck-test.cc | 56 ++++++++++++++++++++++++---------
src/kudu/tools/ksck.cc | 1 +
src/kudu/tools/ksck.h | 15 +++++++--
src/kudu/tools/ksck_remote-test.cc | 54 +++++++++++++++++++++++++++++--
src/kudu/tools/ksck_remote.cc | 3 +-
src/kudu/tools/ksck_remote.h | 5 +--
src/kudu/tools/ksck_results.cc | 36 ++++++++++++++++++---
src/kudu/tools/tool.proto | 1 +
9 files changed, 147 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kudu/blob/973fc9a0/src/kudu/tools/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/tools/CMakeLists.txt b/src/kudu/tools/CMakeLists.txt
index c93439a..875657c 100644
--- a/src/kudu/tools/CMakeLists.txt
+++ b/src/kudu/tools/CMakeLists.txt
@@ -165,7 +165,9 @@ SET_KUDU_TEST_LINK_LIBS(
mini_cluster)
ADD_KUDU_TEST(diagnostics_log_parser-test)
ADD_KUDU_TEST(ksck-test)
-ADD_KUDU_TEST(ksck_remote-test PROCESSORS 3)
+ADD_KUDU_TEST(ksck_remote-test
+ PROCESSORS 3
+ DATA_FILES testdata/first_argument.sh)
ADD_KUDU_TEST(kudu-admin-test
NUM_SHARDS 8 PROCESSORS 3)
ADD_KUDU_TEST_DEPENDENCIES(kudu-admin-test
http://git-wip-us.apache.org/repos/asf/kudu/blob/973fc9a0/src/kudu/tools/ksck-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tools/ksck-test.cc b/src/kudu/tools/ksck-test.cc
index 558eff1..c781691 100644
--- a/src/kudu/tools/ksck-test.cc
+++ b/src/kudu/tools/ksck-test.cc
@@ -174,6 +174,7 @@ class MockKsckTabletServer : public KsckTabletServer {
// progress for this server.
int64_t checksum_progress_ = 10;
using KsckTabletServer::flags_;
+ using KsckTabletServer::location_;
using KsckTabletServer::version_;
private:
@@ -475,6 +476,9 @@ void CheckJsonVsServerHealthSummaries(const JsonReader& r,
EXPECT_JSON_STRING_FIELD(r, server, "address", summary.address);
EXPECT_JSON_STRING_FIELD(r, server, "health", ServerHealthToString(summary.health));
EXPECT_JSON_STRING_FIELD(r, server, "status", summary.status.ToString());
+ if (!summary.ts_location.empty()) {
+ EXPECT_JSON_STRING_FIELD(r, server, "location", summary.ts_location);
+ }
}
}
@@ -755,11 +759,11 @@ TEST_F(KsckTest, TestServersOk) {
// Tablet server health.
ASSERT_STR_CONTAINS(err_string,
"Tablet Server Summary\n"
- " UUID | Address | Status\n"
- "---------+---------+---------\n"
- " ts-id-0 | <mock> | HEALTHY\n"
- " ts-id-1 | <mock> | HEALTHY\n"
- " ts-id-2 | <mock> | HEALTHY\n");
+ " UUID | Address | Status | Location\n"
+ "---------+---------+---------+----------\n"
+ " ts-id-0 | <mock> | HEALTHY | <none>\n"
+ " ts-id-1 | <mock> | HEALTHY | <none>\n"
+ " ts-id-2 | <mock> | HEALTHY | <none>\n");
CheckJsonStringVsKsckResults(KsckResultsToJsonString(), ksck_->results());
}
@@ -946,11 +950,11 @@ TEST_F(KsckTest, TestWrongUUIDTabletServer) {
ASSERT_OK(ksck_->PrintResults());
ASSERT_STR_CONTAINS(err_stream_.str(),
"Tablet Server Summary\n"
- " UUID | Address | Status\n"
- "---------+---------+-------------------\n"
- " ts-id-0 | <mock> | HEALTHY\n"
- " ts-id-2 | <mock> | HEALTHY\n"
- " ts-id-1 | <mock> | WRONG_SERVER_UUID\n");
+ " UUID | Address | Status | Location\n"
+ "---------+---------+-------------------+----------\n"
+ " ts-id-0 | <mock> | HEALTHY | <none>\n"
+ " ts-id-2 | <mock> | HEALTHY | <none>\n"
+ " ts-id-1 | <mock> | WRONG_SERVER_UUID | <none>\n");
CheckJsonStringVsKsckResults(KsckResultsToJsonString(), ksck_->results());
}
@@ -976,11 +980,11 @@ TEST_F(KsckTest, TestBadTabletServer) {
ASSERT_STR_CONTAINS(
err_stream_.str(),
"Tablet Server Summary\n"
- " UUID | Address | Status\n"
- "---------+---------+-------------\n"
- " ts-id-0 | <mock> | HEALTHY\n"
- " ts-id-2 | <mock> | HEALTHY\n"
- " ts-id-1 | <mock> | UNAVAILABLE\n");
+ " UUID | Address | Status | Location\n"
+ "---------+---------+-------------+----------\n"
+ " ts-id-0 | <mock> | HEALTHY | <none>\n"
+ " ts-id-2 | <mock> | HEALTHY | <none>\n"
+ " ts-id-1 | <mock> | UNAVAILABLE | <none>\n");
ASSERT_STR_CONTAINS(
err_stream_.str(),
"Error from <mock>: Network error: Network failure (UNAVAILABLE)\n");
@@ -1596,5 +1600,27 @@ TEST_F(KsckTest, TestChecksumWithAllPeersUnhealthy) {
"T tablet-id-1 P ts-id-0 (<mock>): Error: Aborted: "
"no healthy peer was available to provide a timestamp");
}
+
+TEST_F(KsckTest, TestTabletServerLocation) {
+ CreateOneTableOneTablet();
+ shared_ptr<MockKsckTabletServer> ts =
+ static_pointer_cast<MockKsckTabletServer>(cluster_->tablet_servers_["ts-id-1"]);
+ ts->location_ = "/foo";
+
+ ASSERT_OK(ksck_->CheckClusterRunning());
+ ASSERT_OK(ksck_->FetchTableAndTabletInfo());
+ ASSERT_OK(ksck_->FetchInfoFromTabletServers());
+ ASSERT_OK(ksck_->PrintResults());
+
+ ASSERT_STR_CONTAINS(err_stream_.str(),
+ "Tablet Server Summary\n"
+ " UUID | Address | Status | Location\n"
+ "---------+---------+---------+----------\n"
+ " ts-id-0 | <mock> | HEALTHY | <none>\n"
+ " ts-id-1 | <mock> | HEALTHY | /foo\n"
+ " ts-id-2 | <mock> | HEALTHY | <none>\n");
+
+ NO_FATALS(CheckJsonStringVsKsckResults(KsckResultsToJsonString(), ksck_->results()));
+}
} // namespace tools
} // namespace kudu
http://git-wip-us.apache.org/repos/asf/kudu/blob/973fc9a0/src/kudu/tools/ksck.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tools/ksck.cc b/src/kudu/tools/ksck.cc
index 4597668..babaadc 100644
--- a/src/kudu/tools/ksck.cc
+++ b/src/kudu/tools/ksck.cc
@@ -336,6 +336,7 @@ Status Ksck::FetchInfoFromTabletServers() {
KsckServerHealthSummary summary;
summary.uuid = ts->uuid();
summary.address = ts->address();
+ summary.ts_location = ts->location();
summary.version = ts->version();
summary.status = s;
if (!s.ok()) {
http://git-wip-us.apache.org/repos/asf/kudu/blob/973fc9a0/src/kudu/tools/ksck.h
----------------------------------------------------------------------
diff --git a/src/kudu/tools/ksck.h b/src/kudu/tools/ksck.h
index 9a21736..85e6b49 100644
--- a/src/kudu/tools/ksck.h
+++ b/src/kudu/tools/ksck.h
@@ -38,7 +38,6 @@
#include "kudu/consensus/metadata.pb.h"
#include "kudu/gutil/macros.h"
#include "kudu/gutil/strings/substitute.h"
-#include "kudu/rpc/messenger.h"
#include "kudu/server/server_base.pb.h"
#include "kudu/tablet/metadata.pb.h"
#include "kudu/tablet/tablet.pb.h" // IWYU pragma: keep
@@ -48,6 +47,9 @@
namespace kudu {
class MonoDelta;
+namespace rpc {
+class Messenger;
+} // namespace rpc
namespace tools {
@@ -212,7 +214,6 @@ class KsckMaster {
return version_;
}
-
virtual const boost::optional<consensus::ConsensusStatePB> cstate() const {
CHECK_NE(KsckFetchState::UNINITIALIZED, state_);
return cstate_;
@@ -273,7 +274,10 @@ class KsckTabletServer {
typedef std::map
<std::pair<std::string, std::string>, consensus::ConsensusStatePB> TabletConsensusStateMap;
- explicit KsckTabletServer(std::string uuid) : uuid_(std::move(uuid)) {}
+ explicit KsckTabletServer(std::string uuid, std::string location = "")
+ : uuid_(std::move(uuid)),
+ location_(std::move(location)) {}
+
virtual ~KsckTabletServer() { }
// Connects to the configured tablet server and populates the fields of this class. 'health' must
@@ -310,6 +314,10 @@ class KsckTabletServer {
return uuid_;
}
+ virtual const std::string& location() const {
+ return location_;
+ }
+
std::string ToString() const {
return strings::Substitute("$0 ($1)", uuid(), address());
}
@@ -377,6 +385,7 @@ class KsckTabletServer {
boost::optional<server::GetFlagsResponsePB> flags_;
std::atomic<uint64_t> timestamp_;
const std::string uuid_;
+ std::string location_;
private:
DISALLOW_COPY_AND_ASSIGN(KsckTabletServer);
http://git-wip-us.apache.org/repos/asf/kudu/blob/973fc9a0/src/kudu/tools/ksck_remote-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tools/ksck_remote-test.cc b/src/kudu/tools/ksck_remote-test.cc
index d19aba7..694f212 100644
--- a/src/kudu/tools/ksck_remote-test.cc
+++ b/src/kudu/tools/ksck_remote-test.cc
@@ -51,6 +51,7 @@
#include "kudu/util/monotime.h"
#include "kudu/util/net/net_util.h"
#include "kudu/util/net/sockaddr.h"
+#include "kudu/util/path_util.h"
#include "kudu/util/promise.h"
#include "kudu/util/random.h"
#include "kudu/util/status.h"
@@ -63,6 +64,7 @@ DECLARE_int32(safe_time_max_lag_ms);
DECLARE_int32(tablet_history_max_age_sec);
DECLARE_int32(timestamp_update_period_ms);
DECLARE_int32(wait_before_setting_snapshot_timestamp_ms);
+DECLARE_string(location_mapping_cmd);
DEFINE_int32(experimental_flag_for_ksck_test, 0,
"A flag marked experimental so it can be used to test ksck's "
@@ -280,10 +282,12 @@ TEST_F(RemoteKsckTest, TestTabletServerMismatchedUUID) {
ASSERT_STR_CONTAINS(err_stream_.str(), strings::Substitute(match_string, address.ToString(),
new_uuid, old_uuid));
tserver::MiniTabletServer* ts = mini_cluster_->mini_tablet_server(1);
- ASSERT_STR_CONTAINS(err_stream_.str(), strings::Substitute("$0 | $1 | HEALTHY", ts->uuid(),
+ ASSERT_STR_CONTAINS(err_stream_.str(), strings::Substitute("$0 | $1 | HEALTHY | <none>",
+ ts->uuid(),
ts->bound_rpc_addr().ToString()));
ts = mini_cluster_->mini_tablet_server(2);
- ASSERT_STR_CONTAINS(err_stream_.str(), strings::Substitute("$0 | $1 | HEALTHY", ts->uuid(),
+ ASSERT_STR_CONTAINS(err_stream_.str(), strings::Substitute("$0 | $1 | HEALTHY | <none>",
+ ts->uuid(),
ts->bound_rpc_addr().ToString()));
}
@@ -502,5 +506,51 @@ TEST_F(RemoteKsckTest, TestLeaderMasterDown) {
ASSERT_OK(ksck_->FetchInfoFromTabletServers());
}
+TEST_F(RemoteKsckTest, TestClusterWithLocation) {
+ // There is no location assigned for the existing three tablet servers.
+ // With the flag set, the newly added server will be assiged with location '/foo'.
+ const string location_cmd_path = JoinPathSegments(GetTestExecutableDirectory(),
+ "testdata/first_argument.sh");
+ const string location = "/foo";
+ FLAGS_location_mapping_cmd = strings::Substitute("$0 $1", location_cmd_path, location);
+
+ ASSERT_OK(mini_cluster_->AddTabletServer());
+ ASSERT_EQ(4, mini_cluster_->num_tablet_servers());
+
+ ASSERT_OK(ksck_->CheckMasterHealth());
+ ASSERT_OK(ksck_->CheckMasterUnusualFlags());
+ ASSERT_OK(ksck_->CheckMasterConsensus());
+ ASSERT_OK(ksck_->CheckClusterRunning());
+ ASSERT_OK(ksck_->FetchTableAndTabletInfo());
+ ASSERT_OK(ksck_->FetchInfoFromTabletServers());
+
+ ASSERT_OK(ksck_->PrintResults());
+ string err_string = err_stream_.str();
+
+ // The existing tablet servers should have location '<none>' displayed.
+ for (int i = 0; i < 3; i++) {
+ auto *ts = mini_cluster_->mini_tablet_server(i);
+ ASSERT_STR_CONTAINS(err_string, strings::Substitute("$0 | $1 | HEALTHY | <none>",
+ ts->uuid(),
+ ts->bound_rpc_addr().ToString()));
+ }
+
+ // The newly added tablet server should have the assigned location displayed.
+ auto *ts = mini_cluster_->mini_tablet_server(3);
+ ASSERT_STR_CONTAINS(err_string, strings::Substitute("$0 | $1 | HEALTHY | $2",
+ ts->uuid(),
+ ts->bound_rpc_addr().ToString(),
+ location));
+
+ ASSERT_STR_CONTAINS(err_string,
+ "Tablet Server Location Summary\n"
+ " Location | Count\n"
+ "----------+---------\n");
+ ASSERT_STR_CONTAINS(err_string,
+ " <none> | 3\n");
+ ASSERT_STR_CONTAINS(err_string,
+ " /foo | 1\n");
+}
+
} // namespace tools
} // namespace kudu
http://git-wip-us.apache.org/repos/asf/kudu/blob/973fc9a0/src/kudu/tools/ksck_remote.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tools/ksck_remote.cc b/src/kudu/tools/ksck_remote.cc
index 8dd83af..3c69e75 100644
--- a/src/kudu/tools/ksck_remote.cc
+++ b/src/kudu/tools/ksck_remote.cc
@@ -483,7 +483,8 @@ Status RemoteKsckCluster::RetrieveTabletServers() {
auto ts = std::make_shared<RemoteKsckTabletServer>(
s->uuid(),
HostPort(s->hostname(), s->port()),
- messenger_);
+ messenger_,
+ s->location());
RETURN_NOT_OK(ts->Init());
InsertOrDie(&tablet_servers, ts->uuid(), ts);
}
http://git-wip-us.apache.org/repos/asf/kudu/blob/973fc9a0/src/kudu/tools/ksck_remote.h
----------------------------------------------------------------------
diff --git a/src/kudu/tools/ksck_remote.h b/src/kudu/tools/ksck_remote.h
index 2dac723..1872bc8 100644
--- a/src/kudu/tools/ksck_remote.h
+++ b/src/kudu/tools/ksck_remote.h
@@ -93,8 +93,9 @@ class RemoteKsckTabletServer : public KsckTabletServer,
public:
explicit RemoteKsckTabletServer(const std::string& id,
HostPort host_port,
- std::shared_ptr<rpc::Messenger> messenger)
- : KsckTabletServer(id),
+ std::shared_ptr<rpc::Messenger> messenger,
+ const std::string& location = "")
+ : KsckTabletServer(id, location),
host_port_(std::move(host_port)),
messenger_(std::move(messenger)) {
}
http://git-wip-us.apache.org/repos/asf/kudu/blob/973fc9a0/src/kudu/tools/ksck_results.cc
----------------------------------------------------------------------
diff --git a/src/kudu/tools/ksck_results.cc b/src/kudu/tools/ksck_results.cc
index ca42674..8fd5601 100644
--- a/src/kudu/tools/ksck_results.cc
+++ b/src/kudu/tools/ksck_results.cc
@@ -34,6 +34,7 @@
#include "kudu/gutil/map-util.h"
#include "kudu/gutil/strings/join.h"
+#include "kudu/gutil/strings/numbers.h"
#include "kudu/gutil/strings/substitute.h"
#include "kudu/tools/color.h"
#include "kudu/tools/tool.pb.h"
@@ -358,11 +359,35 @@ Status PrintServerHealthSummaries(KsckServerType type,
const vector<KsckServerHealthSummary>& summaries,
ostream& out) {
out << ServerTypeToString(type) << " Summary" << endl;
- DataTable table({ "UUID", "Address", "Status" });
- for (const auto& s : summaries) {
- table.AddRow({ s.uuid, s.address, ServerHealthToString(s.health) });
+ if (summaries.empty()) return Status::OK();
+
+ if (type == KsckServerType::TABLET_SERVER) {
+ DataTable table({ "UUID", "Address", "Status", "Location" });
+ unordered_map<string, int> location_counts;
+ for (const auto& s : summaries) {
+ string location = s.ts_location.empty() ? "<none>" : s.ts_location;
+ location_counts[location]++;
+ table.AddRow({ s.uuid, s.address, ServerHealthToString(s.health), std::move(location) });
+ }
+ RETURN_NOT_OK(table.PrintTo(out));
+
+ // Print location count table.
+ out << std::endl;
+ out << "Tablet Server Location Summary" << endl;
+ DataTable loc_stats_table({ "Location", "Count" });
+ for (const auto& loc_count : location_counts) {
+ loc_stats_table.AddRow({ loc_count.first, IntToString(loc_count.second) });
+ }
+ RETURN_NOT_OK(loc_stats_table.PrintTo(out));
+ } else {
+ DCHECK_EQ(ServerTypeToString(type), ServerTypeToString(KsckServerType::MASTER));
+ DataTable table({ "UUID", "Address", "Status" });
+ for (const auto& s : summaries) {
+ table.AddRow({ s.uuid, s.address, ServerHealthToString(s.health) });
+ }
+ RETURN_NOT_OK(table.PrintTo(out));
}
- RETURN_NOT_OK(table.PrintTo(out));
+
// Print out the status message from each server with bad health.
// This isn't done as part of the table because the messages can be quite long.
for (const auto& s : summaries) {
@@ -579,6 +604,9 @@ void KsckServerHealthSummaryToPb(const KsckServerHealthSummary& summary,
pb->set_version(*summary.version);
}
pb->set_status(summary.status.ToString());
+ if (!summary.ts_location.empty()) {
+ pb->set_location(summary.ts_location);
+ }
}
void KsckConsensusStateToPb(const KsckConsensusState& cstate,
http://git-wip-us.apache.org/repos/asf/kudu/blob/973fc9a0/src/kudu/tools/tool.proto
----------------------------------------------------------------------
diff --git a/src/kudu/tools/tool.proto b/src/kudu/tools/tool.proto
index 7d49cf1..f6dd937 100644
--- a/src/kudu/tools/tool.proto
+++ b/src/kudu/tools/tool.proto
@@ -228,6 +228,7 @@ message KsckServerHealthSummaryPB {
optional ServerHealth health = 3;
optional string status = 4;
optional string version = 5;
+ optional string location = 6;
}
message KsckConsensusStatePB {
[2/2] kudu git commit: thirdparty: work around an upstream LLVM build
race
Posted by ad...@apache.org.
thirdparty: work around an upstream LLVM build race
There is a long-standing race[1] in LLVM's build that seems to only manifest
when the compiler-rt LLVM project (used for sanitizers and the like) is
built via make with certain values of -j.
I spent some quality time with the compiler-rt build but was unable to find
its root cause, so instead let's work around it in our own build.
1. https://bugs.llvm.org/show_bug.cgi?id=26054
Change-Id: Ia3bf2a171b85d34326e187a4d14dbffe7326100d
Reviewed-on: http://gerrit.cloudera.org:8080/11834
Reviewed-by: Andrew Wong <aw...@cloudera.com>
Tested-by: Kudu Jenkins
Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/0b2fef41
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/0b2fef41
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/0b2fef41
Branch: refs/heads/master
Commit: 0b2fef41d8d0b4ffc1afe566597d764299620e72
Parents: 973fc9a
Author: Adar Dembo <ad...@cloudera.com>
Authored: Tue Oct 30 16:54:13 2018 -0700
Committer: Adar Dembo <ad...@cloudera.com>
Committed: Wed Oct 31 04:47:19 2018 +0000
----------------------------------------------------------------------
thirdparty/build-definitions.sh | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/kudu/blob/0b2fef41/thirdparty/build-definitions.sh
----------------------------------------------------------------------
diff --git a/thirdparty/build-definitions.sh b/thirdparty/build-definitions.sh
index 203d84d..d0c47ba 100644
--- a/thirdparty/build-definitions.sh
+++ b/thirdparty/build-definitions.sh
@@ -336,7 +336,27 @@ build_llvm() {
$EXTRA_CMAKE_FLAGS \
$LLVM_SOURCE
- ${NINJA:-make} -j$PARALLEL $EXTRA_MAKEFLAGS install
+ # Retry the build a few times. Thanks to an LLVM bug[1], the build can fail
+ # sporadically when using certain values of $PARALLEL.
+ #
+ # 1. https://bugs.llvm.org/show_bug.cgi?id=26054
+ set +e
+ attempt_number=1
+ max_attempts=3
+ while true; do
+ ${NINJA:-make} -j$PARALLEL $EXTRA_MAKEFLAGS install
+ exit_status=$?
+ if [[ $exit_status -eq 0 ]]; then
+ break
+ elif [[ $attempt_number -lt $max_attempts ]]; then
+ echo "LLVM build failed, retrying"
+ attempt_number=$((attempt_number + 1))
+ else
+ echo "LLVM build failed $max_attempts times, aborting"
+ exit $exit_status
+ fi
+ done
+ set -e
if [[ "$BUILD_TYPE" == "normal" ]]; then
# Create a link from Clang to thirdparty/clang-toolchain. This path is used