YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/server/generic_service.cc
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
//
18
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
//
32
#include "yb/server/generic_service.h"
33
34
#include <functional>
35
#include <map>
36
#include <mutex>
37
#include <set>
38
#include <string>
39
#include <unordered_map>
40
#include <unordered_set>
41
42
#include <boost/preprocessor/cat.hpp>
43
#include <boost/preprocessor/stringize.hpp>
44
#include <gflags/gflags.h>
45
#include <gflags/gflags_declare.h>
46
#include <glog/logging.h>
47
48
#include "yb/gutil/atomicops.h"
49
#include "yb/gutil/callback_forward.h"
50
#include "yb/gutil/dynamic_annotations.h"
51
#include "yb/gutil/macros.h"
52
#include "yb/gutil/map-util.h"
53
#include "yb/gutil/port.h"
54
#include "yb/rpc/rpc_context.h"
55
#include "yb/server/clock.h"
56
#include "yb/server/server_base.h"
57
#include "yb/util/flag_tags.h"
58
#include "yb/util/flags.h"
59
#include "yb/util/metrics_fwd.h"
60
#include "yb/util/monotime.h"
61
#include "yb/util/status.h"
62
#include "yb/util/status_format.h"
63
#include "yb/util/status_fwd.h"
64
65
using std::string;
66
using std::unordered_set;
67
68
DECLARE_string(flagfile);
69
70
#ifdef COVERAGE_BUILD
71
//extern "C" void __gcov_flush(void);
72
extern "C" int __llvm_profile_write_file(void);
73
#endif
74
75
76
namespace yb {
77
namespace server {
78
79
GenericServiceImpl::GenericServiceImpl(RpcServerBase* server)
80
  : GenericServiceIf(server->metric_entity()),
81
17.1k
    server_(server) {
82
17.1k
}
83
84
160
GenericServiceImpl::~GenericServiceImpl() {
85
160
}
86
87
void GenericServiceImpl::SetFlag(const SetFlagRequestPB* req,
88
                                 SetFlagResponsePB* resp,
89
244
                                 rpc::RpcContext rpc) {
90
91
  // Validate that the flag exists and get the current value.
92
244
  string old_val;
93
244
  if (!google::GetCommandLineOption(req->flag().c_str(),
94
1
                                    &old_val)) {
95
1
    resp->set_result(SetFlagResponsePB::NO_SUCH_FLAG);
96
1
    rpc.RespondSuccess();
97
1
    return;
98
1
  }
99
100
  // Validate that the flag is runtime-changeable.
101
243
  unordered_set<string> tags;
102
243
  GetFlagTags(req->flag(), &tags);
103
243
  if (!ContainsKey(tags, "runtime")) {
104
110
    if (req->force()) {
105
109
      LOG(WARNING) << rpc.requestor_string() << " forcing change of "
106
109
                   << "non-runtime-safe flag " << req->flag();
107
1
    } else {
108
1
      resp->set_result(SetFlagResponsePB::NOT_SAFE);
109
1
      resp->set_msg("Flag is not safe to change at runtime");
110
1
      rpc.RespondSuccess();
111
1
      return;
112
1
    }
113
242
  }
114
115
242
  resp->set_old_value(old_val);
116
117
  // The gflags library sets new values of flags without synchronization.
118
  // TODO: patch gflags to use proper synchronization.
119
242
  ANNOTATE_IGNORE_WRITES_BEGIN();
120
  // Try to set the new value.
121
242
  string ret = google::SetCommandLineOption(
122
242
      req->flag().c_str(),
123
242
      req->value().c_str());
124
242
  ANNOTATE_IGNORE_WRITES_END();
125
126
242
  if (ret.empty()) {
127
1
    resp->set_result(SetFlagResponsePB::BAD_VALUE);
128
1
    resp->set_msg("Unable to set flag: bad value");
129
241
  } else {
130
241
    bool is_sensitive = ContainsKey(tags, "sensitive_info");
131
241
    LOG(INFO) << rpc.requestor_string() << " changed flags via RPC: "
132
241
              << req->flag() << " from '" << (is_sensitive ? "***" : old_val)
133
241
              << "' to '" << (is_sensitive ? "***" : req->value()) << "'";
134
241
    resp->set_result(SetFlagResponsePB::SUCCESS);
135
241
    resp->set_msg(ret);
136
241
  }
137
138
242
  rpc.RespondSuccess();
139
242
}
140
141
void GenericServiceImpl::RefreshFlags(const RefreshFlagsRequestPB* req,
142
                                      RefreshFlagsResponsePB* resp,
143
0
                                      rpc::RpcContext rpc) {
144
0
  if (yb::RefreshFlagsFile(FLAGS_flagfile)) {
145
0
    rpc.RespondSuccess();
146
0
  } else {
147
0
    rpc.RespondFailure(STATUS_SUBSTITUTE(InternalError,
148
0
                                         "Unable to refresh flagsfile: $0", FLAGS_flagfile));
149
0
  }
150
0
}
151
152
void GenericServiceImpl::GetFlag(const GetFlagRequestPB* req,
153
                                 GetFlagResponsePB* resp,
154
25
                                 rpc::RpcContext rpc) {
155
  // Validate that the flag exists and get the current value.
156
25
  string val;
157
25
  if (!google::GetCommandLineOption(req->flag().c_str(), &val)) {
158
0
    resp->set_valid(false);
159
0
    rpc.RespondSuccess();
160
0
    return;
161
0
  }
162
25
  resp->set_value(val);
163
25
  rpc.RespondSuccess();
164
25
}
165
166
void GenericServiceImpl::FlushCoverage(const FlushCoverageRequestPB* req,
167
                                       FlushCoverageResponsePB* resp,
168
0
                                       rpc::RpcContext rpc) {
169
#ifdef COVERAGE_BUILD_
170
  //__gcov_flush();
171
  const int result = __llvm_profile_write_file();
172
  LOG(INFO) << "Flushed coverage info. (request from " << rpc.requestor_string() << ", result: " << result << ")";
173
  resp->set_success(result == 0);
174
#else
175
0
  LOG(WARNING) << "Non-coverage build cannot flush coverage (request from "
176
0
               << rpc.requestor_string() << ")";
177
0
  resp->set_success(false);
178
0
#endif
179
0
  rpc.RespondSuccess();
180
0
}
181
182
void GenericServiceImpl::ServerClock(const ServerClockRequestPB* req,
183
                                     ServerClockResponsePB* resp,
184
1
                                     rpc::RpcContext rpc) {
185
1
  resp->set_hybrid_time(server_->clock()->Now().ToUint64());
186
1
  rpc.RespondSuccess();
187
1
}
188
189
void GenericServiceImpl::GetStatus(const GetStatusRequestPB* req,
190
                                   GetStatusResponsePB* resp,
191
1
                                   rpc::RpcContext rpc) {
192
1
  server_->GetStatusPB(resp->mutable_status());
193
1
  rpc.RespondSuccess();
194
1
}
195
196
void GenericServiceImpl::Ping(
197
10.9k
    const PingRequestPB* req, PingResponsePB* resp, rpc::RpcContext rpc) {
198
10.9k
  rpc.RespondSuccess();
199
10.9k
}
200
201
} // namespace server
202
} // namespace yb