YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/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
25.7k
    server_(server) {
82
25.7k
}
83
84
182
GenericServiceImpl::~GenericServiceImpl() {
85
182
}
86
87
void GenericServiceImpl::SetFlag(const SetFlagRequestPB* req,
88
                                 SetFlagResponsePB* resp,
89
352
                                 rpc::RpcContext rpc) {
90
91
  // Validate that the flag exists and get the current value.
92
352
  string old_val;
93
352
  if (!google::GetCommandLineOption(req->flag().c_str(),
94
352
                                    &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
351
  unordered_set<string> tags;
102
351
  GetFlagTags(req->flag(), &tags);
103
351
  if (!ContainsKey(tags, "runtime")) {
104
152
    if (req->force()) {
105
151
      LOG(WARNING) << rpc.requestor_string() << " forcing change of "
106
151
                   << "non-runtime-safe flag " << req->flag();
107
151
    } 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
152
  }
114
115
350
  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
350
  ANNOTATE_IGNORE_WRITES_BEGIN();
120
  // Try to set the new value.
121
350
  string ret = google::SetCommandLineOption(
122
350
      req->flag().c_str(),
123
350
      req->value().c_str());
124
350
  ANNOTATE_IGNORE_WRITES_END();
125
126
350
  if (ret.empty()) {
127
1
    resp->set_result(SetFlagResponsePB::BAD_VALUE);
128
1
    resp->set_msg("Unable to set flag: bad value");
129
349
  } else {
130
349
    bool is_sensitive = ContainsKey(tags, "sensitive_info");
131
349
    LOG(INFO) << rpc.requestor_string() << " changed flags via RPC: "
132
349
              << req->flag() << " from '" << (is_sensitive ? 
"***"0
: old_val)
133
349
              << "' to '" << (is_sensitive ? 
"***"0
: req->value()) << "'";
134
349
    resp->set_result(SetFlagResponsePB::SUCCESS);
135
349
    resp->set_msg(ret);
136
349
  }
137
138
350
  rpc.RespondSuccess();
139
350
}
140
141
void GenericServiceImpl::RefreshFlags(const RefreshFlagsRequestPB* req,
142
                                      RefreshFlagsResponsePB* resp,
143
2
                                      rpc::RpcContext rpc) {
144
2
  if (yb::RefreshFlagsFile(FLAGS_flagfile)) {
145
2
    rpc.RespondSuccess();
146
2
  } else {
147
0
    rpc.RespondFailure(STATUS_SUBSTITUTE(InternalError,
148
0
                                         "Unable to refresh flagsfile: $0", FLAGS_flagfile));
149
0
  }
150
2
}
151
152
void GenericServiceImpl::GetFlag(const GetFlagRequestPB* req,
153
                                 GetFlagResponsePB* resp,
154
29
                                 rpc::RpcContext rpc) {
155
  // Validate that the flag exists and get the current value.
156
29
  string val;
157
29
  if (!google::GetCommandLineOption(req->flag().c_str(), &val)) {
158
0
    resp->set_valid(false);
159
0
    rpc.RespondSuccess();
160
0
    return;
161
0
  }
162
29
  resp->set_value(val);
163
29
  rpc.RespondSuccess();
164
29
}
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
7
                                   rpc::RpcContext rpc) {
192
7
  server_->GetStatusPB(resp->mutable_status());
193
7
  rpc.RespondSuccess();
194
7
}
195
196
void GenericServiceImpl::Ping(
197
380k
    const PingRequestPB* req, PingResponsePB* resp, rpc::RpcContext rpc) {
198
380k
  rpc.RespondSuccess();
199
380k
}
200
201
} // namespace server
202
} // namespace yb