YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/util/ulimit_util.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/util/ulimit_util.h"
33
34
#include <sys/resource.h>
35
36
#include <map>
37
#include <string>
38
39
#include "yb/util/env.h"
40
#include "yb/util/result.h"
41
#include "yb/util/size_literals.h"
42
#include "yb/util/ulimit.h"
43
44
using std::string;
45
using std::stringstream;
46
using yb::operator"" _KB;
47
using yb::operator"" _MB;
48
49
// These flags allow operators to define process resource soft limits at runtime. Note that on some
50
// systems, RLIM_INFINITY is defined as -1, and setting these flags to that value will result in an
51
// attempt to set these resource limits to infinity. All other negative values are ignored.
52
DEFINE_int64(rlimit_data, RLIM_INFINITY, "Data file size limit: bytes.");
53
#if defined(__APPLE__)
54
// Note that we've chosen 10240 as the default value here since this is the default system limit
55
// for this resource on *macOS* as defined by OPEN_MAX in <sys/syslimits.h>
56
DEFINE_int64(rlimit_nofile, 10240, "Open files limit.");
57
#else
58
DEFINE_int64(rlimit_nofile, 1048576, "Open files limit.");
59
#endif
60
DEFINE_int64(rlimit_fsize, RLIM_INFINITY, "File size limit: blocks.");
61
DEFINE_int64(rlimit_memlock, 64_KB, "Locked memory limit: bytes.");
62
DEFINE_int64(rlimit_as, RLIM_INFINITY, "Memory size limit: bytes.");
63
DEFINE_int64(rlimit_stack, 8_MB, "Stack size limit: bytes.");
64
DEFINE_int64(rlimit_cpu, RLIM_INFINITY, "CPU time limit: seconds.");
65
DEFINE_int64(rlimit_nproc, 12000, "User process limit.");
66
67
// Note: we've observed it can take a while to dump full cores, esp. on systems like kubernetes or
68
// consumer laptops. In order to avoid causing more usability issues, we disable this flag for now
69
// and accept the system default rather than setting this to RLIM_INFINITY as suggested in our
70
// onboarding docs.
71
// DEFINE_int64(rlimit_core, RLIM_INFINITY, "Core file size limit: blocks.");
72
73
namespace {
74
75
const std::map<int, const int64_t&> kRlimitsToInit = {
76
  // {RLIMIT_CORE, FLAGS_rlimit_core},
77
  {RLIMIT_DATA, FLAGS_rlimit_data},
78
  {RLIMIT_NOFILE, FLAGS_rlimit_nofile},
79
  {RLIMIT_FSIZE, FLAGS_rlimit_fsize},
80
  {RLIMIT_MEMLOCK, FLAGS_rlimit_memlock},
81
  {RLIMIT_AS, FLAGS_rlimit_as},
82
  {RLIMIT_STACK, FLAGS_rlimit_stack},
83
  {RLIMIT_CPU, FLAGS_rlimit_cpu},
84
  {RLIMIT_NPROC, FLAGS_rlimit_nproc},
85
};
86
87
const std::map<int, std::string> kRdescriptions = {
88
  {RLIMIT_CORE, "core file size"},
89
  {RLIMIT_DATA, "data seg size"},
90
  {RLIMIT_NOFILE, "open files"},
91
  {RLIMIT_FSIZE, "file size"},
92
  {RLIMIT_MEMLOCK, "max locked memory"},
93
  {RLIMIT_AS, "max memory size"},
94
  {RLIMIT_STACK, "stack size"},
95
  {RLIMIT_CPU, "cpu time"},
96
  {RLIMIT_NPROC, "max user processes"},
97
};
98
99
} // namespace
100
101
namespace yb {
102
103
static stringstream& getLimit(
104
132k
    stringstream& ss, const std::string pfx, const std::string sfx, int resource, int rightshift) {
105
132k
  ss << "ulimit: " << pfx << " ";
106
132k
  const auto limits_or_status = Env::Default()->GetUlimit(resource);
107
132k
  if (limits_or_status.ok()) {
108
132k
    const ResourceLimit soft = limits_or_status->soft;
109
132k
    if (soft.IsUnlimited()) {
110
88.1k
      ss << "unlimited";
111
88.1k
    } else {
112
44.0k
      ss << (soft.RawValue() >> rightshift);
113
44.0k
    }
114
132k
    ss << "(";
115
132k
    const ResourceLimit hard = limits_or_status->hard;
116
132k
    if (hard.IsUnlimited()) {
117
102k
      ss << "unlimited";
118
102k
    } else {
119
29.3k
      ss << (hard.RawValue() >> rightshift);
120
29.3k
    }
121
132k
    ss << ")";
122
132k
  } else {
123
0
    ss << "-1";
124
0
  }
125
132k
  ss << (sfx[0] ? 
" "102k
:
""29.3k
) << sfx << "\n";
126
127
132k
  return ss;
128
132k
}
129
130
249k
static string getCommandLineDescription(int resource) {
131
249k
  if (resource == RLIMIT_CORE) {
132
14.6k
    return "core file size";
133
14.6k
  }
134
235k
  if (resource == RLIMIT_DATA) {
135
29.3k
    return "data seg size";
136
29.3k
  }
137
205k
  if (resource == RLIMIT_NOFILE) {
138
29.3k
    return "open files";
139
29.3k
  }
140
176k
  if (resource == RLIMIT_FSIZE) {
141
29.3k
    return "file size";
142
29.3k
  }
143
#if !defined(__APPLE__)
144
  if (resource == RLIMIT_SIGPENDING) {
145
    return "pending signals";
146
  }
147
  if (resource == RLIMIT_LOCKS) {
148
    return "file locks";
149
  }
150
#endif
151
146k
  if (resource == RLIMIT_MEMLOCK) {
152
29.3k
    return "max locked memory";
153
29.3k
  }
154
117k
  if (resource == RLIMIT_AS) {
155
29.3k
    return "max memory size";
156
29.3k
  }
157
88.1k
  if (resource == RLIMIT_STACK) {
158
29.3k
    return "stack size";
159
29.3k
  }
160
58.7k
  if (resource == RLIMIT_CPU) {
161
29.3k
    return "cpu time";
162
29.3k
  }
163
29.3k
  if (resource == RLIMIT_NPROC) {
164
29.3k
    return "max user processes";
165
29.3k
  }
166
0
  return "UNKNOWN";
167
29.3k
}
168
169
14.6k
string UlimitUtil::GetUlimitInfo() {
170
14.6k
  stringstream ss;
171
14.6k
  ss << "\n";
172
14.6k
  getLimit(ss, getCommandLineDescription(RLIMIT_CORE), "blks", RLIMIT_CORE, 0);
173
14.6k
  getLimit(ss, getCommandLineDescription(RLIMIT_DATA), "kb", RLIMIT_DATA, 10);
174
14.6k
  getLimit(ss, getCommandLineDescription(RLIMIT_NOFILE), "", RLIMIT_NOFILE, 0);
175
14.6k
  getLimit(ss, getCommandLineDescription(RLIMIT_FSIZE), "blks", RLIMIT_FSIZE, 0);
176
#if !defined(__APPLE__)
177
  getLimit(ss, getCommandLineDescription(RLIMIT_SIGPENDING), "", RLIMIT_SIGPENDING, 0);
178
  getLimit(ss, getCommandLineDescription(RLIMIT_LOCKS), "", RLIMIT_LOCKS, 0);
179
#endif
180
14.6k
  getLimit(ss, getCommandLineDescription(RLIMIT_MEMLOCK), "kb", RLIMIT_MEMLOCK, 10);
181
14.6k
  getLimit(ss, getCommandLineDescription(RLIMIT_AS), "kb", RLIMIT_AS, 10);
182
14.6k
  getLimit(ss, getCommandLineDescription(RLIMIT_STACK), "kb", RLIMIT_STACK, 10);
183
14.6k
  getLimit(ss, getCommandLineDescription(RLIMIT_CPU), "secs", RLIMIT_CPU, 0);
184
14.6k
  getLimit(ss, getCommandLineDescription(RLIMIT_NPROC), "", RLIMIT_NPROC, 0);
185
186
14.6k
  return ss.str();
187
14.6k
}
188
189
14.6k
void UlimitUtil::InitUlimits() {
190
117k
  for (const auto& kv : kRlimitsToInit) {
191
117k
    int resource_id = kv.first;
192
117k
    const ResourceLimit min_soft_limit(kv.second);
193
117k
    const string resource_name = getCommandLineDescription(resource_id);
194
195
117k
    if (min_soft_limit.IsNegative()) {
196
0
      LOG(INFO)
197
0
          << "Skipping setrlimit for " << resource_name
198
0
          << " with negative specified min value " << min_soft_limit.ToString();
199
0
      continue;
200
0
    }
201
202
117k
    const auto limits_or_status = Env::Default()->GetUlimit(resource_id);
203
117k
    if (!limits_or_status.ok()) {
204
0
      LOG(ERROR) << "Unable to fetch hard limit for resource " << resource_name
205
0
                 << " Skipping initialization.";
206
0
      continue;
207
0
    }
208
209
117k
    const ResourceLimit sys_soft_limit = limits_or_status->soft;
210
117k
    if (min_soft_limit <= sys_soft_limit) {
211
88.1k
      LOG(INFO)
212
88.1k
          << "Configured soft limit for " << resource_name
213
88.1k
          << " is already larger than specified min value (" << sys_soft_limit.ToString()
214
88.1k
          << " vs. " << min_soft_limit.ToString() << "). Skipping.";
215
88.1k
      continue;
216
88.1k
    }
217
218
29.3k
    const ResourceLimit sys_hard_limit = limits_or_status->hard;
219
29.3k
    const ResourceLimit new_soft_limit = std::min(sys_hard_limit, min_soft_limit);
220
221
29.3k
    Status set_ulim_status = Env::Default()->SetUlimit(resource_id, new_soft_limit, resource_name);
222
29.3k
    if (!set_ulim_status.ok()) {
223
0
      LOG(ERROR) << "Unable to set new soft limit for resource " << resource_name
224
0
                 << " error: " << set_ulim_status.ToString();
225
0
    }
226
29.3k
  }
227
14.6k
}
228
229
}  // namespace yb