18
18
#include " cgroupconfigurator.h"
19
19
#include " configcpp.h"
20
20
#include " logger.h"
21
+ #include < charconv>
21
22
#include < fstream>
22
23
#include < iostream>
24
+ #include < limits>
23
25
#include < sys/sysinfo.h>
24
26
25
27
using namespace boost ;
@@ -77,9 +79,8 @@ CGroupConfigurator::CGroupConfigurator()
77
79
else
78
80
cGroupDefined = true ;
79
81
80
- totalMemory = 0 ;
81
- totalSwap = 0 ;
82
- printedWarning = false ;
82
+ ifstream v2Check (" /sys/fs/cgroup/cgroup.controllers" );
83
+ cGroupVersion_ = (v2Check) ? v2 : v1;
83
84
}
84
85
85
86
CGroupConfigurator::~CGroupConfigurator ()
@@ -88,9 +89,16 @@ CGroupConfigurator::~CGroupConfigurator()
88
89
89
90
uint32_t CGroupConfigurator::getNumCoresFromCGroup ()
90
91
{
91
- ostringstream filename_os;
92
- filename_os << " /sys/fs/cgroup/cpuset/" << cGroupName << " /cpus" ;
93
- string filename = filename_os.str ();
92
+ ostringstream filenameOs;
93
+ if (cGroupVersion_ == v1)
94
+ {
95
+ filenameOs << " /sys/fs/cgroup/cpuset/" << cGroupName << " /cpuset.cpus" ;
96
+ }
97
+ else
98
+ {
99
+ filenameOs << " /sys/fs/cgroup/" << cGroupName << " /cpuset.cpus" ;
100
+ }
101
+ string filename = filenameOs.str ();
94
102
95
103
ifstream in (filename.c_str ());
96
104
string cpusString;
@@ -141,7 +149,7 @@ uint32_t CGroupConfigurator::getNumCoresFromCGroup()
141
149
first = last + 1 ;
142
150
}
143
151
144
- // cout << "found " << cpus << " CPUS in the string " << cpusString << endl;
152
+ cout << " found " << cpus << " CPUS in the string " << cpusString << endl;
145
153
return cpus;
146
154
}
147
155
@@ -155,7 +163,7 @@ uint32_t CGroupConfigurator::getNumCoresFromProc()
155
163
uint32_t CGroupConfigurator::getNumCores ()
156
164
{
157
165
/*
158
- Detect if InfiniDB is in a C-Group
166
+ Detect if MCS is in a C-Group
159
167
- get the group ID
160
168
If not, get the number of cores from /proc
161
169
*/
@@ -171,7 +179,7 @@ uint32_t CGroupConfigurator::getNumCores()
171
179
ret = getNumCoresFromProc ();
172
180
}
173
181
174
- // cout << "There are " << ret << " cores available" << endl;
182
+ cout << " There are " << ret << " cores available" << endl;
175
183
return ret;
176
184
}
177
185
@@ -188,11 +196,11 @@ uint64_t CGroupConfigurator::getTotalMemory()
188
196
{
189
197
ret = getTotalMemoryFromCGroup ();
190
198
191
- if (ret == 0 )
199
+ if (ret == 0 || ret == std::numeric_limits< uint64_t >:: max () )
192
200
ret = getTotalMemoryFromProc ();
193
201
}
194
202
195
- // cout << "Total mem available is " << ret << endl;
203
+ cout << " Total mem available is " << ret << endl;
196
204
totalMemory = ret;
197
205
return totalMemory;
198
206
}
@@ -201,23 +209,11 @@ uint64_t CGroupConfigurator::getTotalMemoryFromProc()
201
209
{
202
210
size_t memTot;
203
211
204
- #if defined(__FreeBSD__)
205
- string cmd (" sysctl -a | awk '/realmem/ {print int(($2+1023)/1024);}'" );
206
- FILE* cmdPipe;
207
- char input[80 ];
208
- cmdPipe = popen (cmd.c_str (), " r" );
209
- input[0 ] = ' \0 ' ;
210
- fgets (input, 80 , cmdPipe);
211
- input[79 ] = ' \0 ' ;
212
- pclose (cmdPipe);
213
- memTot = atoi (input);
214
- #else
215
212
ifstream in (" /proc/meminfo" );
216
213
string x;
217
214
218
215
in >> x;
219
216
in >> memTot;
220
- #endif
221
217
222
218
// memTot is now in KB, convert to bytes
223
219
memTot *= 1024 ;
@@ -227,61 +223,88 @@ uint64_t CGroupConfigurator::getTotalMemoryFromProc()
227
223
228
224
uint64_t CGroupConfigurator::getTotalMemoryFromCGroup ()
229
225
{
230
- ifstream in ;
231
- uint64_t ret ;
226
+ std::string memLimitStr ;
227
+ uint64_t memLimit = std::numeric_limits< uint64_t >:: max () ;
232
228
ostringstream os;
233
- string filename;
234
229
235
- os << " /sys/fs/cgroup/memory/" << cGroupName << " /memory.limit_in_bytes" ;
236
- filename = os.str ();
230
+ if (cGroupVersion_ == v1)
231
+ {
232
+ os << " /sys/fs/cgroup/memory/" << cGroupName << " /memory.limit_in_bytes" ;
233
+ }
234
+ else
235
+ {
236
+ os << " /sys/fs/cgroup/" << cGroupName << " /memory.max" ;
237
+ }
238
+ string filename = os.str ();
237
239
238
- in. open (filename.c_str ());
240
+ ifstream in (filename.c_str ());
239
241
240
242
if (!in)
241
243
RETURN_NO_GROUP (0 );
242
244
243
245
try
244
246
{
245
- in >> ret ;
247
+ in >> memLimitStr ;
246
248
}
247
249
catch (...)
248
250
{
249
251
RETURN_READ_ERROR (0 );
250
252
}
251
253
252
- return ret;
254
+ if (cGroupVersion_ == v2 && memLimitStr == " max" )
255
+ {
256
+ return std::numeric_limits<uint64_t >::max ();
257
+ }
258
+
259
+ auto [ch, ec] = std::from_chars (memLimitStr.c_str (), memLimitStr.c_str () + memLimitStr.size (), memLimit);
260
+ if (ec != std::errc ())
261
+ {
262
+ return std::numeric_limits<uint64_t >::max ();
263
+ }
264
+
265
+ if (cGroupVersion_ == v1)
266
+ {
267
+ return std::min (getTotalMemoryFromProc (), memLimit);
268
+ }
269
+ return memLimit;
253
270
}
254
271
255
272
uint64_t CGroupConfigurator::getFreeMemory ()
256
273
{
257
274
uint64_t ret;
258
-
259
275
if (!cGroupDefined)
260
276
ret = getFreeMemoryFromProc ();
261
277
else
262
278
{
263
279
uint64_t usage = getMemUsageFromCGroup ();
280
+ cout << " usage " << usage << endl;
264
281
265
282
if (usage == 0 )
266
283
ret = getFreeMemoryFromProc ();
267
284
else
268
285
ret = getTotalMemory () - usage;
269
286
}
270
287
271
- // cout << "free memory = " << ret << endl;
288
+ cout << " free memory = " << ret << endl;
272
289
return ret;
273
290
}
274
291
275
292
uint64_t CGroupConfigurator::getMemUsageFromCGroup ()
276
293
{
277
- uint64_t ret = 0 ;
278
- bool found = false ;
279
294
char oneline[80 ];
280
-
281
295
if (memUsageFilename.empty ())
282
296
{
283
297
ostringstream filename;
284
- filename << " /sys/fs/cgroup/memory/" << cGroupName << " /memory.stat" ;
298
+ if (cGroupVersion_ == v1)
299
+ {
300
+ memStatePrefix = " rss " ;
301
+ filename << " /sys/fs/cgroup/memory/" << cGroupName << " /memory.stat" ;
302
+ }
303
+ else
304
+ {
305
+ memStatePrefix = " anon " ;
306
+ filename << " /sys/fs/cgroup/" << cGroupName << " /memory.stat" ;
307
+ }
285
308
memUsageFilename = filename.str ();
286
309
}
287
310
@@ -293,14 +316,13 @@ uint64_t CGroupConfigurator::getMemUsageFromCGroup()
293
316
294
317
try
295
318
{
296
- while (in && !found )
319
+ while (in)
297
320
{
298
321
in.getline (oneline, 80 );
299
322
300
- if (strncmp (oneline, " rss " , 2 ) == 0 )
323
+ if (strncmp (oneline, memStatePrefix. c_str (), memStatePrefix. size () - 1 ) == 0 )
301
324
{
302
- ret = atoll (&oneline[3 ]);
303
- found = true ;
325
+ return atoll (&oneline[memStatePrefix.size ()]);
304
326
}
305
327
}
306
328
}
@@ -309,7 +331,7 @@ uint64_t CGroupConfigurator::getMemUsageFromCGroup()
309
331
RETURN_READ_ERROR (0 );
310
332
}
311
333
312
- return ret ;
334
+ return 0 ;
313
335
}
314
336
315
337
uint64_t CGroupConfigurator::getFreeMemoryFromProc ()
@@ -320,10 +342,6 @@ uint64_t CGroupConfigurator::getFreeMemoryFromProc()
320
342
uint64_t memTotal = 0 ;
321
343
uint64_t memAvailable = 0 ;
322
344
323
- #if defined(__FreeBSD__)
324
- // FreeBSD is not supported, no optimization.
325
- memAvailable = 0 ;
326
- #else
327
345
ifstream in (" /proc/meminfo" );
328
346
string x;
329
347
@@ -354,137 +372,9 @@ uint64_t CGroupConfigurator::getFreeMemoryFromProc()
354
372
memAvailable = memFree + buffers + cached;
355
373
}
356
374
357
- #endif
358
-
359
375
// amount available for application
360
376
memAvailable *= 1024 ;
361
377
return memAvailable;
362
378
}
363
379
364
- uint64_t CGroupConfigurator::getTotalSwapSpace ()
365
- {
366
- int64_t ret;
367
-
368
- if (totalSwap != 0 )
369
- return totalSwap;
370
-
371
- if (!cGroupDefined)
372
- ret = getTotalSwapFromSysinfo ();
373
- else
374
- {
375
- ret = getTotalMemAndSwapFromCGroup ();
376
-
377
- // if no limit is set in the cgroup, the file contains maxint64. Use sysinfo in that case.
378
- if (ret == -1 || ret == numeric_limits<int64_t >::max ())
379
- ret = getTotalSwapFromSysinfo ();
380
- else
381
- ret -= getTotalMemory ();
382
- }
383
-
384
- // cout << "total swap=" << ret << endl;
385
- totalSwap = ret;
386
- return ret;
387
- }
388
-
389
- uint64_t CGroupConfigurator::getTotalSwapFromSysinfo ()
390
- {
391
- struct sysinfo si;
392
-
393
- sysinfo (&si);
394
- return si.totalswap ;
395
- }
396
-
397
- int64_t CGroupConfigurator::getTotalMemAndSwapFromCGroup ()
398
- {
399
- int64_t ret;
400
- ifstream in;
401
- string filename;
402
- ostringstream os;
403
-
404
- os << " /sys/fs/cgroup/memory/" << cGroupName << " /memory.memsw.limit_in_bytes" ;
405
- filename = os.str ();
406
- in.open (filename.c_str ());
407
-
408
- if (!in)
409
- RETURN_NO_GROUP (-1 );
410
-
411
- try
412
- {
413
- in >> ret;
414
- }
415
- catch (...)
416
- {
417
- RETURN_READ_ERROR (-1 );
418
- }
419
-
420
- return ret;
421
- }
422
-
423
- uint64_t CGroupConfigurator::getSwapInUse ()
424
- {
425
- int64_t ret;
426
-
427
- if (!cGroupDefined)
428
- ret = getSwapInUseFromSysinfo ();
429
- else
430
- {
431
- ret = getSwapInUseFromCGroup ();
432
-
433
- if (ret == -1 )
434
- ret = getSwapInUseFromSysinfo ();
435
- }
436
-
437
- // cout << "current swap in use=" << ret << endl;
438
- return ret;
439
- }
440
-
441
- int64_t CGroupConfigurator::getSwapInUseFromCGroup ()
442
- {
443
- int64_t ret = -1 ;
444
- ifstream in;
445
- bool found = false ;
446
- char oneline[80 ];
447
-
448
- if (usedSwapFilename.empty ())
449
- {
450
- ostringstream os;
451
- os << " /sys/fs/cgroup/memory/" << cGroupName << " /memory.stat" ;
452
- usedSwapFilename = os.str ();
453
- }
454
-
455
- string& filename = usedSwapFilename;
456
- in.open (filename.c_str ());
457
-
458
- if (!in)
459
- RETURN_NO_GROUP (-1 );
460
-
461
- try
462
- {
463
- while (in && !found)
464
- {
465
- in.getline (oneline, 80 );
466
-
467
- if (strncmp (oneline, " swap" , 4 ) == 0 )
468
- {
469
- ret = atoll (&oneline[5 ]);
470
- found = true ;
471
- }
472
- }
473
- }
474
- catch (...)
475
- {
476
- RETURN_READ_ERROR (-1 );
477
- }
478
-
479
- return ret;
480
- }
481
-
482
- uint64_t CGroupConfigurator::getSwapInUseFromSysinfo ()
483
- {
484
- struct sysinfo si;
485
-
486
- sysinfo (&si);
487
- return si.totalswap - si.freeswap ;
488
- }
489
-
490
380
} // namespace utils
0 commit comments