• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #3559

18 Dec 2024 12:59AM UTC coverage: 59.805% (+0.03%) from 59.778%
#3559

push

travis-ci

web-flow
Merge pull request #29187 from taosdata/merge/mainto3.0

merge: main to 3.0 branch

132705 of 287544 branches covered (46.15%)

Branch coverage included in aggregate %.

87 of 95 new or added lines in 19 files covered. (91.58%)

1132 existing lines in 133 files now uncovered.

209591 of 284807 relevant lines covered (73.59%)

8125235.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

71.08
/source/os/src/osSysinfo.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#define _DEFAULT_SOURCE
17
#include "os.h"
18
#include "taoserror.h"
19

20
#if defined(CUS_NAME) || defined(CUS_PROMPT) || defined(CUS_EMAIL)
21
#include "cus_name.h"
22
#else
23
#ifndef CUS_PROMPT
24
#define CUS_PROMPT "taos"
25
#endif
26
#endif
27

28
#define PROCESS_ITEM 12
29
#define UUIDLEN37 37
30

31
typedef struct {
32
  uint64_t user;
33
  uint64_t nice;
34
  uint64_t system;
35
  uint64_t idle;
36
  uint64_t wa;
37
  uint64_t hi;
38
  uint64_t si;
39
  uint64_t st;
40
  uint64_t guest;
41
  uint64_t guest_nice;
42
} SysCpuInfo;
43

44
typedef struct {
45
  uint64_t utime;   // user time
46
  uint64_t stime;   // kernel time
47
  uint64_t cutime;  // all user time
48
  uint64_t cstime;  // all dead time
49
} ProcCpuInfo;
50

51
#ifdef WINDOWS
52

53
/*
54
 * windows implementation
55
 */
56

57
#if (_WIN64)
58
#include <iphlpapi.h>
59
#include <mswsock.h>
60
#include <psapi.h>
61
#include <stdio.h>
62
#include <windows.h>
63
#include <ws2tcpip.h>
64
#pragma comment(lib, "Mswsock.lib ")
65
#endif
66

67
#include <objbase.h>
68

69
#pragma warning(push)
70
#pragma warning(disable : 4091)
71
#include <DbgHelp.h>
72
#pragma warning(pop)
73

74
LONG WINAPI FlCrashDump(PEXCEPTION_POINTERS ep) {
75
  typedef BOOL(WINAPI * FxMiniDumpWriteDump)(IN HANDLE hProcess, IN DWORD ProcessId, IN HANDLE hFile,
76
                                             IN MINIDUMP_TYPE                           DumpType,
77
                                             IN CONST PMINIDUMP_EXCEPTION_INFORMATION   ExceptionParam,
78
                                             IN CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
79
                                             IN CONST PMINIDUMP_CALLBACK_INFORMATION    CallbackParam);
80

81
  HMODULE dll = LoadLibrary("dbghelp.dll");
82
  if (dll == NULL) return EXCEPTION_CONTINUE_SEARCH;
83
  FxMiniDumpWriteDump mdwd = (FxMiniDumpWriteDump)(GetProcAddress(dll, "MiniDumpWriteDump"));
84
  if (mdwd == NULL) {
85
    FreeLibrary(dll);
86
    return EXCEPTION_CONTINUE_SEARCH;
87
  }
88

89
  TCHAR path[MAX_PATH];
90
  DWORD len = GetModuleFileName(NULL, path, _countof(path));
91
  path[len - 3] = 'd';
92
  path[len - 2] = 'm';
93
  path[len - 1] = 'p';
94

95
  HANDLE file = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
96
  if (file == INVALID_HANDLE_VALUE) {
97
    FreeLibrary(dll);
98
    return EXCEPTION_CONTINUE_SEARCH;
99
  }
100

101
  MINIDUMP_EXCEPTION_INFORMATION mei;
102
  mei.ThreadId = GetCurrentThreadId();
103
  mei.ExceptionPointers = ep;
104
  mei.ClientPointers = FALSE;
105

106
  (*mdwd)(GetCurrentProcess(), GetCurrentProcessId(), file, MiniDumpWithHandleData, &mei, NULL, NULL);
107

108
  CloseHandle(file);
109
  FreeLibrary(dll);
110

111
  return EXCEPTION_CONTINUE_SEARCH;
112
}
113
LONG WINAPI exceptionHandler(LPEXCEPTION_POINTERS exception);
114

115
#elif defined(_TD_DARWIN_64)
116

117
#include <errno.h>
118
#include <libproc.h>
119
#include <sys/sysctl.h>
120
#include <SystemConfiguration/SCDynamicStoreCopySpecific.h>
121
#include <CoreFoundation/CFString.h>
122
#include <stdio.h>
123

124
#else
125

126
#include <argp.h>
127
#include <linux/sysctl.h>
128
#include <sys/file.h>
129
#include <sys/resource.h>
130
#include <sys/statvfs.h>
131
#include <sys/syscall.h>
132
#include <sys/utsname.h>
133
#include <unistd.h>
134

135
static pid_t tsProcId;
136
static char  tsSysNetFile[] = "/proc/net/dev";
137
static char  tsSysCpuFile[] = "/proc/stat";
138
static char  tsCpuPeriodFile[] = "/sys/fs/cgroup/cpu/cpu.cfs_period_us";
139
static char  tsCpuQuotaFile[] = "/sys/fs/cgroup/cpu/cpu.cfs_quota_us";
140
static char  tsProcCpuFile[25] = {0};
141
static char  tsProcMemFile[25] = {0};
142
static char  tsProcIOFile[25] = {0};
143

144
static void taosGetProcIOnfos() {
5,923✔
145
  tsPageSizeKB = sysconf(_SC_PAGESIZE) / 1024;
5,923✔
146
  tsOpenMax = sysconf(_SC_OPEN_MAX);
5,923✔
147
  tsStreamMax = TMAX(sysconf(_SC_STREAM_MAX), 0);
5,923✔
148
  tsProcId = (pid_t)syscall(SYS_gettid);
5,923✔
149

150
  (void)snprintf(tsProcMemFile, sizeof(tsProcMemFile), "/proc/%d/status", tsProcId);
5,923✔
151
  (void)snprintf(tsProcCpuFile, sizeof(tsProcCpuFile), "/proc/%d/stat", tsProcId);
5,923✔
152
  (void)snprintf(tsProcIOFile, sizeof(tsProcIOFile), "/proc/%d/io", tsProcId);
5,923✔
153
}
5,923✔
154
#endif
155

156
static int32_t taosGetSysCpuInfo(SysCpuInfo *cpuInfo) {
5,936✔
157
  OS_PARAM_CHECK(cpuInfo);
5,936!
158
  int32_t code = 0;
5,936✔
159
#ifdef WINDOWS
160
  FILETIME pre_idleTime = {0};
161
  FILETIME pre_kernelTime = {0};
162
  FILETIME pre_userTime = {0};
163
  FILETIME idleTime;
164
  FILETIME kernelTime;
165
  FILETIME userTime;
166
  bool     res = GetSystemTimes(&idleTime, &kernelTime, &userTime);
167
  if (res) {
168
    cpuInfo->idle = CompareFileTime(&pre_idleTime, &idleTime);
169
    cpuInfo->system = CompareFileTime(&pre_kernelTime, &kernelTime);
170
    cpuInfo->user = CompareFileTime(&pre_userTime, &userTime);
171
    cpuInfo->nice = 0;
172
  }
173
#elif defined(DARWIN)
174
  cpuInfo->idle = 0;
175
  cpuInfo->system = 0;
176
  cpuInfo->user = 0;
177
  cpuInfo->nice = 0;
178
#else
179
  TdFilePtr pFile = taosOpenFile(tsSysCpuFile, TD_FILE_READ | TD_FILE_STREAM);
5,936✔
180
  if (pFile == NULL) {
5,936!
181
    return terrno;
×
182
  }
183

184
  char    line[1024];
185
  ssize_t bytes = taosGetsFile(pFile, sizeof(line), line);
5,936✔
186
  if (bytes < 0) {
5,936!
187
    TAOS_SKIP_ERROR(taosCloseFile(&pFile));
×
188
    return terrno;
×
189
  }
190

191
  char cpu[10] = {0};
5,936✔
192
  code = sscanf(line,
5,936✔
193
         "%s %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64
194
         " %" PRIu64,
195
         cpu, &cpuInfo->user, &cpuInfo->nice, &cpuInfo->system, &cpuInfo->idle, &cpuInfo->wa, &cpuInfo->hi,
196
         &cpuInfo->si, &cpuInfo->st, &cpuInfo->guest, &cpuInfo->guest_nice);
197
  if (EOF == code) {
5,936!
198
    terrno = TAOS_SYSTEM_ERROR(errno);
×
199
    TAOS_SKIP_ERROR(taosCloseFile(&pFile));
×
200
    return terrno;
×
201
  }
202
  
203
  TAOS_SKIP_ERROR(taosCloseFile(&pFile));
5,936✔
204
#endif
205

206
  return 0;
5,936✔
207
}
208

209
static int32_t taosGetProcCpuInfo(ProcCpuInfo *cpuInfo) {
5,936✔
210
  OS_PARAM_CHECK(cpuInfo);
5,936!
211
  int32_t code = 0;
5,936✔
212

213
#ifdef WINDOWS
214
  FILETIME pre_krnlTm = {0};
215
  FILETIME pre_usrTm = {0};
216
  FILETIME creatTm, exitTm, krnlTm, usrTm;
217

218
  if (GetThreadTimes(GetCurrentThread(), &creatTm, &exitTm, &krnlTm, &usrTm)) {
219
    cpuInfo->stime = CompareFileTime(&pre_krnlTm, &krnlTm);
220
    cpuInfo->utime = CompareFileTime(&pre_usrTm, &usrTm);
221
    cpuInfo->cutime = 0;
222
    cpuInfo->cstime = 0;
223
  }
224
#elif defined(DARWIN)
225
  cpuInfo->stime = 0;
226
  cpuInfo->utime = 0;
227
  cpuInfo->cutime = 0;
228
  cpuInfo->cstime = 0;
229
#else
230
  TdFilePtr pFile = taosOpenFile(tsProcCpuFile, TD_FILE_READ | TD_FILE_STREAM);
5,936✔
231
  if (pFile == NULL) {
5,936✔
232
    return terrno;
1✔
233
  }
234

235
  char    line[1024] = {0};
5,935✔
236
  ssize_t bytes = taosGetsFile(pFile, sizeof(line), line);
5,935✔
237
  if (bytes < 0) {
5,935!
238
    TAOS_SKIP_ERROR(taosCloseFile(&pFile));
×
239
    return code;
×
240
  }
241

242
  for (int i = 0, blank = 0; line[i] != 0; ++i) {
403,629!
243
    if (line[i] == ' ') blank++;
403,629✔
244
    if (blank == PROCESS_ITEM) {
403,629✔
245
      code = sscanf(line + i + 1, "%" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, &cpuInfo->utime, &cpuInfo->stime,
5,935✔
246
             &cpuInfo->cutime, &cpuInfo->cstime);
247
      if (EOF == code) {
5,935!
248
        terrno = TAOS_SYSTEM_ERROR(errno);
×
249
        return terrno;
×
250
      }
251
             
252
      break;
5,935✔
253
    }
254
  }
255

256
  TAOS_SKIP_ERROR(taosCloseFile(&pFile));
5,935✔
257
#endif
258

259
  return 0;
5,935✔
260
}
261

262
bool taosCheckSystemIsLittleEnd() {
3,894✔
263
  union check {
264
    int16_t i;
265
    char    ch[2];
266
  } c;
267
  c.i = 1;
3,894✔
268
  return c.ch[0] == 1;
3,894✔
269
}
270

271
void taosGetSystemInfo() {
5,923✔
272
#ifdef WINDOWS
273
  TAOS_SKIP_ERROR(taosGetCpuCores(&tsNumOfCores, false));
274
  TAOS_SKIP_ERROR(taosGetTotalMemory(&tsTotalMemoryKB));
275
  TAOS_SKIP_ERROR(taosGetCpuUsage(NULL, NULL));
276
#elif defined(_TD_DARWIN_64)
277
  long physical_pages = sysconf(_SC_PHYS_PAGES);
278
  long page_size = sysconf(_SC_PAGESIZE);
279
  tsTotalMemoryKB = physical_pages * page_size / 1024;
280
  tsPageSizeKB = page_size / 1024;
281
  tsNumOfCores = sysconf(_SC_NPROCESSORS_ONLN);
282
#else
283
  taosGetProcIOnfos();
5,923✔
284
  TAOS_SKIP_ERROR(taosGetCpuCores(&tsNumOfCores, false));
5,923✔
285
  TAOS_SKIP_ERROR(taosGetTotalMemory(&tsTotalMemoryKB));
5,923✔
286
  TAOS_SKIP_ERROR(taosGetCpuUsage(NULL, NULL));
5,923✔
287
  TAOS_SKIP_ERROR(taosGetCpuInstructions(&tsSSE42Supported, &tsAVXSupported, &tsAVX2Supported, &tsFMASupported, &tsAVX512Supported));
5,923✔
288
#endif
289
}
5,923✔
290

291
int32_t taosGetEmail(char *email, int32_t maxLen) {
1,518✔
292
  OS_PARAM_CHECK(email);
1,518!
293
#ifdef WINDOWS
294
  return 0;
295
#elif defined(_TD_DARWIN_64)
296
#ifdef CUS_PROMPT
297
  const char *filepath = "/usr/local/"CUS_PROMPT"/email";
298
#else
299
  const char *filepath = "/usr/local/taos/email";
300
#endif  // CUS_PROMPT
301

302
  TdFilePtr pFile = taosOpenFile(filepath, TD_FILE_READ);
303
  if (pFile == NULL) return false;
304

305
  if (taosReadFile(pFile, (void *)email, maxLen) < 0) {
306
    taosCloseFile(&pFile);
307
    return terrno;
308
  }
309

310
  taosCloseFile(&pFile);
311
  return 0;
312
#else
313
#ifdef CUS_PROMPT
314
  const char *filepath = "/usr/local/"CUS_PROMPT"/email";
1,518✔
315
#else
316
  const char *filepath = "/usr/local/taos/email";
317
#endif  // CUS_PROMPT
318

319
  TdFilePtr pFile = taosOpenFile(filepath, TD_FILE_READ);
1,518✔
320
  if (pFile == NULL) return terrno;
1,518!
321

322
  if (taosReadFile(pFile, (void *)email, maxLen) < 0) {
×
323
    int32_t code = terrno;
×
324
    TAOS_SKIP_ERROR(taosCloseFile(&pFile));
×
325
    return code;
×
326
  }
327

328
  TAOS_SKIP_ERROR(taosCloseFile(&pFile));
×
329
  
330
  return 0;
×
331
#endif
332
}
333

334
#ifdef WINDOWS
335
bool getWinVersionReleaseName(char *releaseName, int32_t maxLen) {
336
  if(releaseName == NULL) return false;
337
  TCHAR          szFileName[MAX_PATH];
338
  DWORD             dwHandle;
339
  DWORD             dwLen;
340
  LPVOID            lpData;
341
  UINT              uLen;
342
  VS_FIXEDFILEINFO *pFileInfo;
343

344
  int ret = GetWindowsDirectory(szFileName, MAX_PATH);
345
  if (ret == 0) {
346
    return false;
347
  }
348
  wsprintf(szFileName, L"%s%s", szFileName, L"\\explorer.exe");
349
  dwLen = GetFileVersionInfoSize(szFileName, &dwHandle);
350
  if (dwLen == 0) {
351
    return false;
352
  }
353

354
  lpData = malloc(dwLen);
355
  if (lpData == NULL) return false;
356
  if (!GetFileVersionInfo(szFileName, dwHandle, dwLen, lpData)) {
357
    free(lpData);
358
    return false;
359
  }
360

361
  if (!VerQueryValue(lpData, L"\\", (LPVOID *)&pFileInfo, &uLen)) {
362
    free(lpData);
363
    return false;
364
  }
365

366
  snprintf(releaseName, maxLen, "Windows %d.%d", HIWORD(pFileInfo->dwProductVersionMS),
367
           LOWORD(pFileInfo->dwProductVersionMS));
368
  free(lpData);
369
  return true;
370
}
371
#endif
372

373
int32_t taosGetOsReleaseName(char *releaseName, char* sName, char* ver, int32_t maxLen) {
3✔
374
  OS_PARAM_CHECK(releaseName);
3!
375
#ifdef WINDOWS
376
  if (!getWinVersionReleaseName(releaseName, maxLen)) {
377
    snprintf(releaseName, maxLen, "Windows");
378
  }
379
  if(sName) snprintf(sName, maxLen, "Windows");
380
  return 0;
381
#elif defined(_TD_DARWIN_64)
382
  char osversion[32];
383
  size_t osversion_len = sizeof(osversion) - 1;
384
  int osversion_name[] = { CTL_KERN, KERN_OSRELEASE };
385

386
  if(sName) snprintf(sName, maxLen, "macOS");
387
  if (sysctl(osversion_name, 2, osversion, &osversion_len, NULL, 0) == -1) {
388
    return TAOS_SYSTEM_ERROR(errno);
389
  }
390

391
  uint32_t major, minor;
392
  if (sscanf(osversion, "%u.%u", &major, &minor) == EOF) {
393
      return TAOS_SYSTEM_ERROR(errno);
394
  }
395
  if (major >= 20) {
396
      major -= 9; // macOS 11 and newer
397
      snprintf(releaseName, maxLen, "macOS %u.%u", major, minor);
398
  } else {
399
      major -= 4; // macOS 10.1.1 and newer
400
      snprintf(releaseName, maxLen, "macOS 10.%d.%d", major, minor);
401
  }
402

403
  return 0;
404
#else
405
  char    line[1024];
406
  char   *dest = NULL;
3✔
407
  size_t  size = 0;
3✔
408
  int32_t code = 0;
3✔
409
  int32_t cnt = 0;
3✔
410

411
  TdFilePtr pFile = taosOpenFile("/etc/os-release", TD_FILE_READ | TD_FILE_STREAM);
3✔
412
  if (pFile == NULL) {
3!
413
    return terrno;
×
414
  }
415

416
  while ((size = taosGetsFile(pFile, sizeof(line), line)) > 0) {
39✔
417
    line[size - 1] = '\0';
36✔
418
    if (strncmp(line, "NAME", 4) == 0) {
36✔
419
      dest = sName;
3✔
420
    } else if (strncmp(line, "PRETTY_NAME", 11) == 0) {
33✔
421
      dest = releaseName;
3✔
422
      code = 0;
3✔
423
    } else if (strncmp(line, "VERSION_ID", 10) == 0) {
30✔
424
      dest = ver;
3✔
425
    } else {
426
      continue;
27✔
427
    }
428
    if (!dest) continue;
9✔
429
    const char *p = strchr(line, '=') + 1;
3✔
430
    if (*p == '"') {
3!
431
      p++;
3✔
432
      line[size - 2] = 0;
3✔
433
    }
434
    tstrncpy(dest, p, maxLen);
3✔
435

436
    if (++cnt >= 3) break;
3!
437
  }
438

439
  TAOS_SKIP_ERROR(taosCloseFile(&pFile));
3✔
440
  return code;
3✔
441
#endif
442
}
443

444
int32_t taosGetCpuInfo(char *cpuModel, int32_t maxLen, float *numOfCores) {
3✔
445
  OS_PARAM_CHECK(cpuModel);
3!
446
  OS_PARAM_CHECK(numOfCores);
3!
447
#ifdef WINDOWS
448
  char  value[100];
449
  DWORD bufferSize = sizeof(value);
450
  LSTATUS ret = RegGetValue(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", "ProcessorNameString",
451
              RRF_RT_ANY, NULL, (PVOID)&value, &bufferSize);
452
  if (ret != ERROR_SUCCESS) {
453
    return TAOS_SYSTEM_ERROR(ret);
454
  }
455
  tstrncpy(cpuModel, value, maxLen);
456
  SYSTEM_INFO si;
457
  memset(&si, 0, sizeof(SYSTEM_INFO));
458
  GetSystemInfo(&si);
459
  *numOfCores = si.dwNumberOfProcessors;
460
  return 0;
461
#elif defined(_TD_DARWIN_64)
462
  char    buf[16];
463
  int32_t done = 0;
464
  int32_t code = -1;
465

466
  TdCmdPtr pCmd = taosOpenCmd("sysctl -n machdep.cpu.brand_string");
467
  if (pCmd == NULL) return code;
468
  if (taosGetsCmd(pCmd, maxLen, cpuModel) > 0) {
469
    code = 0;
470
    done |= 1;
471
  }
472
  int endPos = strlen(cpuModel)-1;
473
  if (cpuModel[endPos] == '\n') {
474
    cpuModel[endPos] = '\0';
475
  }
476
  taosCloseCmd(&pCmd);
477

478
  pCmd = taosOpenCmd("sysctl -n machdep.cpu.core_count");
479
  if (pCmd == NULL) return code;
480
  memset(buf, 0, sizeof(buf));
481
  if (taosGetsCmd(pCmd, sizeof(buf) - 1, buf) > 0) {
482
    code = 0;
483
    done |= 2;
484
    *numOfCores = taosStr2Float(buf, NULL);
485
  }
486
  taosCloseCmd(&pCmd);
487

488
  return code;
489
#else
490
  char    line[1024] = {0};
3✔
491
  size_t  size = 0;
3✔
492
  int32_t done = 0;
3✔
493
  int32_t code = 0;
3✔
494
  float   coreCount = 0;
3✔
495

496
  TdFilePtr pFile = taosOpenFile("/proc/cpuinfo", TD_FILE_READ | TD_FILE_STREAM);
3✔
497
  if (pFile == NULL) return terrno;
3!
498

499
  while (done != 3 && (size = taosGetsFile(pFile, sizeof(line), line)) > 0) {
42!
500
    line[size - 1] = '\0';
39✔
501
    if (((done & 1) == 0) && strncmp(line, "model name", 10) == 0) {
39✔
502
      const char *v = strchr(line, ':') + 2;
3✔
503
      tstrncpy(cpuModel, v, maxLen);
3✔
504
      code = 0;
3✔
505
      done |= 1;
3✔
506
    } else if (((done & 2) == 0) && strncmp(line, "cpu cores", 9) == 0) {
36!
507
      const char *v = strchr(line, ':') + 2;
3✔
508
      *numOfCores = taosStr2Float(v, NULL);
3✔
509
      done |= 2;
3✔
510
    }
511
    if (strncmp(line, "processor", 9) == 0) coreCount += 1;
39✔
512
  }
513

514
  TAOS_SKIP_ERROR(taosCloseFile(&pFile));
3✔
515

516
  if (code != 0 && (done & 1) == 0) {
3!
517
    TdFilePtr pFile1 = taosOpenFile("/proc/device-tree/model", TD_FILE_READ | TD_FILE_STREAM);
×
518
    if (pFile1 != NULL) {
×
519
      ssize_t bytes = taosGetsFile(pFile1, maxLen, cpuModel);
×
520
      TAOS_SKIP_ERROR(taosCloseFile(&pFile));
×
521
      if (bytes > 0) {
×
522
        code = 0;
×
523
        done |= 1;
×
524
      }
525
    }
526
  }
527

528
  if (code != 0 && (done & 1) == 0) {
3!
529
    TdCmdPtr pCmd = taosOpenCmd("uname -a");
×
530
    if (pCmd == NULL) {
×
531
      return terrno;
×
532
    }
533
    if (taosGetsCmd(pCmd, maxLen, cpuModel) > 0) {
×
534
      code = 0;
×
535
      done |= 1;
×
536
    }
537
    taosCloseCmd(&pCmd);
×
538
  }
539

540
  if ((done & 2) == 0) {
3!
541
    *numOfCores = coreCount;
×
542
    done |= 2;
×
543
  }
544

545
  return code;
3✔
546
#endif
547
}
548

549
// Returns the container's CPU quota if successful, otherwise returns the physical CPU cores
550
static int32_t taosCntrGetCpuCores(float *numOfCores) {
7,840✔
551
  OS_PARAM_CHECK(numOfCores);
7,840!
552
#ifdef WINDOWS
553
  return TSDB_CODE_UNSUPPORT_OS;
554
#elif defined(_TD_DARWIN_64)
555
  return TSDB_CODE_UNSUPPORT_OS;
556
#else
557
  TdFilePtr pFile = NULL;
7,840✔
558
  if (!(pFile = taosOpenFile(tsCpuQuotaFile, TD_FILE_READ | TD_FILE_STREAM))) {
7,840!
559
    goto _sys;
×
560
  }
561
  char qline[32] = {0};
7,840✔
562
  if (taosGetsFile(pFile, sizeof(qline), qline) <= 0) {
7,840!
563
    TAOS_SKIP_ERROR(taosCloseFile(&pFile));
×
564
    goto _sys;
×
565
  }
566
  
567
  TAOS_SKIP_ERROR(taosCloseFile(&pFile));
7,840✔
568
  float quota = taosStr2Float(qline, NULL);
7,840✔
569
  if (quota < 0) {
7,840!
570
    goto _sys;
7,840✔
571
  }
572

573
  if (!(pFile = taosOpenFile(tsCpuPeriodFile, TD_FILE_READ | TD_FILE_STREAM))) {
×
574
    goto _sys;
×
575
  }
576
  
577
  char pline[32] = {0};
×
578
  if (taosGetsFile(pFile, sizeof(pline), pline) <= 0) {
×
579
    TAOS_SKIP_ERROR(taosCloseFile(&pFile));
×
580
    goto _sys;
×
581
  }
582
  
583
  TAOS_SKIP_ERROR(taosCloseFile(&pFile));
×
584

585
  float period = taosStr2Float(pline, NULL);
×
586
  float quotaCores = quota / period;
×
587
  float sysCores = sysconf(_SC_NPROCESSORS_ONLN);
×
588
  if (quotaCores < sysCores && quotaCores > 0) {
×
589
    *numOfCores = quotaCores;
×
590
  } else {
591
    *numOfCores = sysCores;
×
592
  }
593
  if(*numOfCores <= 0) {
×
594
    return TAOS_SYSTEM_ERROR(errno);
×
595
  }
596
  goto _end;
×
597
  
598
_sys:
7,840✔
599
  *numOfCores = sysconf(_SC_NPROCESSORS_ONLN);
7,840✔
600
  if(*numOfCores <= 0) {
7,840!
601
    return TAOS_SYSTEM_ERROR(errno);
×
602
  }
603
  
604
_end:
7,840✔
605
  return 0;
7,840✔
606
  
607
#endif
608
}
609

610
int32_t taosGetCpuCores(float *numOfCores, bool physical) {
10,853✔
611
  OS_PARAM_CHECK(numOfCores);
10,853!
612
#ifdef WINDOWS
613
  SYSTEM_INFO info;
614
  GetSystemInfo(&info);
615
  *numOfCores = info.dwNumberOfProcessors;
616
  return  0;
617
#elif defined(_TD_DARWIN_64)
618
  *numOfCores = sysconf(_SC_NPROCESSORS_ONLN);
619
  if(*numOfCores <= 0) {
620
    return TAOS_SYSTEM_ERROR(errno);
621
  }
622
  return 0;
623
#else
624
  if (physical) {
10,853✔
625
    *numOfCores = sysconf(_SC_NPROCESSORS_ONLN);
3,013✔
626
    if(*numOfCores <= 0) {
3,013!
627
      return TAOS_SYSTEM_ERROR(errno);
×
628
    }
629
  } else {
630
    int code= taosCntrGetCpuCores(numOfCores);
7,840✔
631
    if(code != 0) {
7,840!
632
      return code;
×
633
    }
634
  }
635
  return 0;
10,853✔
636
#endif
637
}
638

639
int32_t taosGetCpuUsage(double *cpu_system, double *cpu_engine) {
5,936✔
640
  static int64_t lastSysUsed = -1;
641
  static int64_t lastSysTotal = -1;
642
  static int64_t lastProcTotal = -1;
643
  static int64_t curSysUsed = 0;
644
  static int64_t curSysTotal = 0;
645
  static int64_t curProcTotal = 0;
646

647
  if (cpu_system != NULL) *cpu_system = 0;
5,936✔
648
  if (cpu_engine != NULL) *cpu_engine = 0;
5,936✔
649

650
  SysCpuInfo  sysCpu = {0};
5,936✔
651
  ProcCpuInfo procCpu = {0};
5,936✔
652
  if (taosGetSysCpuInfo(&sysCpu) == 0 && taosGetProcCpuInfo(&procCpu) == 0) {
5,936!
653
    curSysUsed = sysCpu.user + sysCpu.nice + sysCpu.system + sysCpu.wa + sysCpu.hi + sysCpu.si + sysCpu.st +
5,935✔
654
                 sysCpu.guest + sysCpu.guest_nice;
5,935✔
655
    curSysTotal = curSysUsed + sysCpu.idle;
5,935✔
656
    curProcTotal = procCpu.utime + procCpu.stime + procCpu.cutime + procCpu.cstime;
5,935✔
657

658
    if(lastSysUsed >= 0 && lastSysTotal >=0 && lastProcTotal >=0){
5,935!
659
      if (curSysTotal - lastSysTotal > 0 && curSysUsed >= lastSysUsed && curProcTotal >= lastProcTotal) {
21!
660
        if (cpu_system != NULL) {
21✔
661
          *cpu_system = (curSysUsed - lastSysUsed) / (double)(curSysTotal - lastSysTotal) * 100;
12✔
662
        }
663
        if (cpu_engine != NULL) {
21✔
664
          *cpu_engine = (curProcTotal - lastProcTotal) / (double)(curSysTotal - lastSysTotal) * 100;
12✔
665
        }
666
      }
667
    }
668

669
    lastSysUsed = curSysUsed;
5,935✔
670
    lastSysTotal = curSysTotal;
5,935✔
671
    lastProcTotal = curProcTotal;
5,935✔
672
  }
673
  return 0;
5,936✔
674
}
675

676
#define __cpuid_fix(level, a, b, c, d) \
677
              __asm__("xor %%ecx, %%ecx\n" \
678
                      "cpuid\n" \
679
                      : "=a"(a), "=b"(b), "=c"(c), "=d"(d) \
680
                      : "0"(level))
681

682
// todo add for windows and mac
683
int32_t taosGetCpuInstructions(char* sse42, char* avx, char* avx2, char* fma, char* avx512) {
5,923✔
684
#ifdef WINDOWS
685
#elif defined(_TD_DARWIN_64)
686
#else
687

688
#ifdef _TD_X86_
689
  // Since the compiler is not support avx/avx2 instructions, the global variables always need to be
690
  // set to be false
691
  uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
5,923✔
692

693
  int32_t ret = __get_cpuid(1, &eax, &ebx, &ecx, &edx);
5,923✔
694
  if (ret == 0) {
5,923!
695
    return -1;  // failed to get the cpuid info
×
696
  }
697

698
  *sse42 = (char) ((ecx & bit_SSE4_2) == bit_SSE4_2);
5,923✔
699
  *avx   = (char) ((ecx & bit_AVX) == bit_AVX);
5,923✔
700
  *fma   = (char) ((ecx & bit_FMA) == bit_FMA);
5,923✔
701

702
  // work around a bug in GCC.
703
  // Ref to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77756
704
  __cpuid_fix(7u, eax, ebx, ecx, edx);
5,923✔
705
  *avx2 = (char) ((ebx & bit_AVX2) == bit_AVX2);
5,923✔
706
  *avx512 = (char)((ebx & bit_AVX512F) == bit_AVX512F);
5,923✔
707
#endif   // _TD_X86_
708
#endif
709

710
  return 0;
5,923✔
711
}
712

713
int32_t taosGetTotalMemory(int64_t *totalKB) {
7,801✔
714
  OS_PARAM_CHECK(totalKB);
7,801!
715
#ifdef WINDOWS
716
  MEMORYSTATUSEX memsStat;
717
  memsStat.dwLength = sizeof(memsStat);
718
  if (!GlobalMemoryStatusEx(&memsStat)) {
719
    return TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
720
  }
721

722
  *totalKB = memsStat.ullTotalPhys / 1024;
723
  return 0;
724
#elif defined(_TD_DARWIN_64)
725
  return 0;
726
#else
727
  *totalKB = (int64_t)(sysconf(_SC_PHYS_PAGES) * tsPageSizeKB);
7,801✔
728
  if(*totalKB <= 0) {
7,801!
729
    return TAOS_SYSTEM_ERROR(errno);
×
730
  }
731
  return 0;
7,801✔
732
#endif
733
}
734

735
int32_t taosGetProcMemory(int64_t *usedKB) {
13✔
736
  OS_PARAM_CHECK(usedKB);
13!
737
#ifdef WINDOWS
738
  unsigned bytes_used = 0;
739

740
#if defined(_WIN64) && defined(_MSC_VER)
741
  PROCESS_MEMORY_COUNTERS pmc;
742
  HANDLE                  cur_proc = GetCurrentProcess();
743

744
  if (GetProcessMemoryInfo(cur_proc, &pmc, sizeof(pmc))) {
745
    bytes_used = (unsigned)(pmc.WorkingSetSize + pmc.PagefileUsage);
746
  }
747
#endif
748

749
  *usedKB = bytes_used / 1024;
750
  return 0;
751
#elif defined(_TD_DARWIN_64)
752
  *usedKB = 0;
753
  return 0;
754
#else
755
  TdFilePtr pFile = taosOpenFile(tsProcMemFile, TD_FILE_READ | TD_FILE_STREAM);
13✔
756
  if (pFile == NULL) {
13✔
757
    // printf("open file:%s failed", tsProcMemFile);
758
    return terrno;
1✔
759
  }
760

761
  ssize_t bytes = 0;
12✔
762
  char    line[1024] = {0};
12✔
763
  while (!taosEOFFile(pFile)) {
264!
764
    bytes = taosGetsFile(pFile, sizeof(line), line);
264✔
765
    if (bytes <= 0) {
264!
766
      break;
×
767
    }
768
    if (strstr(line, "VmRSS:") != NULL) {
264✔
769
      break;
12✔
770
    }
771
  }
772

773
  char tmp[10];
774
  (void)sscanf(line, "%s %" PRId64, tmp, usedKB);
12✔
775

776
  TAOS_SKIP_ERROR(taosCloseFile(&pFile));
12✔
777
  
778
  return 0;
12✔
779
#endif
780
}
781

782
int32_t taosGetSysAvailMemory(int64_t *availSize) {
8,809,422✔
783
#ifdef WINDOWS
784
  MEMORYSTATUSEX memsStat;
785
  memsStat.dwLength = sizeof(memsStat);
786
  if (!GlobalMemoryStatusEx(&memsStat)) {
787
    return -1;
788
  }
789

790
  int64_t nMemFree = memsStat.ullAvailPhys;
791
  int64_t nMemTotal = memsStat.ullTotalPhys;
792

793
  *availSize = nMemTotal - nMemFree;
794
  return 0;
795
#elif defined(_TD_DARWIN_64)
796
  *availSize = 0;
797
  return 0;
798
#else
799
  TdFilePtr pFile = taosOpenFile("/proc/meminfo", TD_FILE_READ | TD_FILE_STREAM);
8,809,422✔
800
  if (pFile == NULL) {
8,809,422!
801
    return terrno;
×
802
  }
803

804
  ssize_t bytes = 0;
8,809,422✔
805
  char    line[128] = {0};
8,809,422✔
806
  int32_t expectedSize = 13; //"MemAvailable:"
8,809,422✔
807
  while (!taosEOFFile(pFile)) {
26,428,266!
808
    bytes = taosGetsFile(pFile, sizeof(line), line);
26,428,266✔
809
    if (bytes < 0) {
26,428,266!
810
      break;
×
811
    }
812
    if (line[0] != 'M' && line[3] != 'A') {
26,428,266!
813
      line[0] = 0;
×
814
      continue;
×
815
    }
816
    if (0 == strncmp(line, "MemAvailable:", expectedSize)) {
26,428,266✔
817
      break;
8,809,422✔
818
    }
819
  }
820

821
  if (0 == line[0]) {
8,809,422!
822
    return TSDB_CODE_UNSUPPORT_OS;
×
823
  }
824
  
825
  char tmp[32];
826
  (void)sscanf(line, "%s %" PRId64, tmp, availSize);
8,809,422✔
827

828
  *availSize *= 1024;
8,809,422✔
829
  
830
  (void)taosCloseFile(&pFile);
8,809,422✔
831
  return 0;
8,809,422✔
832
#endif
833
}
834

835
int32_t taosGetSysMemory(int64_t *usedKB) {
13✔
836
  OS_PARAM_CHECK(usedKB);
13!
837
#ifdef WINDOWS
838
  MEMORYSTATUSEX memsStat;
839
  memsStat.dwLength = sizeof(memsStat);
840
  if (!GlobalMemoryStatusEx(&memsStat)) {
841
    return TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
842
  }
843

844
  int64_t nMemFree = memsStat.ullAvailPhys / 1024;
845
  int64_t nMemTotal = memsStat.ullTotalPhys / 1024.0;
846

847
  *usedKB = nMemTotal - nMemFree;
848
  return 0;
849
#elif defined(_TD_DARWIN_64)
850
  *usedKB = 0;
851
  return 0;
852
#else
853
  *usedKB = sysconf(_SC_AVPHYS_PAGES) * tsPageSizeKB;
13✔
854
  if(*usedKB <= 0) {
13✔
855
    return TAOS_SYSTEM_ERROR(errno);
1✔
856
  }
857
  return 0;
12✔
858
#endif
859
}
860

861
int32_t taosGetDiskSize(char *dataDir, SDiskSize *diskSize) {
1,019,634✔
862
  OS_PARAM_CHECK(dataDir);
1,019,634!
863
  OS_PARAM_CHECK(diskSize);
1,019,634!
864
#if defined(WINDOWS)
865
  unsigned _int64 i64FreeBytesToCaller;
866
  unsigned _int64 i64TotalBytes;
867
  unsigned _int64 i64FreeBytes;
868

869
  BOOL fResult = GetDiskFreeSpaceExA(dataDir, (PULARGE_INTEGER)&i64FreeBytesToCaller, (PULARGE_INTEGER)&i64TotalBytes,
870
                                     (PULARGE_INTEGER)&i64FreeBytes);
871
  if (fResult) {
872
    diskSize->total = (int64_t)(i64TotalBytes);
873
    diskSize->avail = (int64_t)(i64FreeBytesToCaller);
874
    diskSize->used = (int64_t)(i64TotalBytes - i64FreeBytes);
875
    return 0;
876
  } else {
877
    // printf("failed to get disk size, dataDir:%s errno:%s", tsDataDir, strerror(errno));
878
    terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
879
    return terrno;
880
  }
881
#elif defined(_TD_DARWIN_64)
882
  struct statvfs info;
883
  if (statvfs(dataDir, &info)) {
884
    // printf("failed to get disk size, dataDir:%s errno:%s", tsDataDir, strerror(errno));
885
    terrno = TAOS_SYSTEM_ERROR(errno);
886
    return terrno;
887
  } else {
888
    diskSize->total = info.f_blocks * info.f_frsize;
889
    diskSize->avail = info.f_bavail * info.f_frsize;
890
    diskSize->used = (info.f_blocks - info.f_bfree) * info.f_frsize;
891
    return 0;
892
  }
893
#else
894
  struct statvfs info;
895
  if (-1 == statvfs(dataDir, &info)) {
1,019,634!
UNCOV
896
    terrno = TAOS_SYSTEM_ERROR(errno);
×
897
    return terrno;
×
898
  } else {
899
    diskSize->total = info.f_blocks * info.f_frsize;
1,019,634✔
900
    diskSize->avail = info.f_bavail * info.f_frsize;
1,019,634✔
901
    diskSize->used = diskSize->total - diskSize->avail;
1,019,634✔
902
    
903
    return 0;
1,019,634✔
904
  }
905
#endif
906
}
907

908
int32_t taosGetProcIO(int64_t *rchars, int64_t *wchars, int64_t *read_bytes, int64_t *write_bytes) {
12✔
909
  OS_PARAM_CHECK(rchars);
12!
910
  OS_PARAM_CHECK(wchars);
12!
911
  OS_PARAM_CHECK(read_bytes);
12!
912
  OS_PARAM_CHECK(write_bytes);
12!
913
#ifdef WINDOWS
914
  IO_COUNTERS io_counter;
915
  if (GetProcessIoCounters(GetCurrentProcess(), &io_counter)) {
916
    *rchars = io_counter.ReadTransferCount;
917
    *wchars = io_counter.WriteTransferCount;
918
    *read_bytes = 0;
919
    *write_bytes = 0;
920
    return 0;
921
  }
922
  return TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
923
#elif defined(_TD_DARWIN_64)
924
  *rchars = 0;
925
  *wchars = 0;
926
  *read_bytes = 0;
927
  *write_bytes = 0;
928
  return 0;
929
#else
930
  TdFilePtr pFile = taosOpenFile(tsProcIOFile, TD_FILE_READ | TD_FILE_STREAM);
12✔
931
  if (pFile == NULL) {
12!
932
    return terrno;
×
933
  }
934

935
  ssize_t bytes = 0;
12✔
936
  char    line[1024] = {0};
12✔
937
  char    tmp[24];
938
  int     readIndex = 0;
12✔
939

940
  while (!taosEOFFile(pFile)) {
72!
941
    bytes = taosGetsFile(pFile, sizeof(line), line);
72✔
942
    if (bytes < 10) {
72!
943
      break;
×
944
    }
945
    if (strstr(line, "rchar:") != NULL) {
72✔
946
      (void)sscanf(line, "%s %" PRId64, tmp, rchars);
12✔
947
      readIndex++;
12✔
948
    } else if (strstr(line, "wchar:") != NULL) {
60✔
949
      (void)sscanf(line, "%s %" PRId64, tmp, wchars);
12✔
950
      readIndex++;
12✔
951
    } else if (strstr(line, "read_bytes:") != NULL) {  // read_bytes
48✔
952
      (void)sscanf(line, "%s %" PRId64, tmp, read_bytes);
12✔
953
      readIndex++;
12✔
954
    } else if (strstr(line, "write_bytes:") != NULL) {  // write_bytes
36✔
955
      (void)sscanf(line, "%s %" PRId64, tmp, write_bytes);
12✔
956
      readIndex++;
12✔
957
    } else {
958
    }
959

960
    if (readIndex >= 4) break;
72✔
961
  }
962

963
  TAOS_SKIP_ERROR(taosCloseFile(&pFile));
12✔
964

965
  if (readIndex < 4) {
12!
966
    return -1;
×
967
  }
968

969
  return 0;
12✔
970
#endif
971
}
972

973
int32_t taosGetProcIODelta(int64_t *rchars, int64_t *wchars, int64_t *read_bytes, int64_t *write_bytes) {
12✔
974
  if (rchars == NULL || wchars == NULL || read_bytes == NULL || write_bytes == NULL) {
12!
975
    return TSDB_CODE_INVALID_PARA;
×
976
  }
977
  static int64_t last_rchars = -1;
978
  static int64_t last_wchars = -1;
979
  static int64_t last_read_bytes = -1;
980
  static int64_t last_write_bytes = -1;
981
  static int64_t cur_rchars = 0;
982
  static int64_t cur_wchars = 0;
983
  static int64_t cur_read_bytes = 0;
984
  static int64_t cur_write_bytes = 0;
985
  int32_t code = taosGetProcIO(&cur_rchars, &cur_wchars, &cur_read_bytes, &cur_write_bytes);
12✔
986
  if (code == 0) {
12!
987
    if(last_rchars >=0 && last_wchars >=0 && last_read_bytes >=0 && last_write_bytes >= 0){
12!
988
      *rchars = cur_rchars - last_rchars;
10✔
989
      *wchars = cur_wchars - last_wchars;
10✔
990
      *read_bytes = cur_read_bytes - last_read_bytes;
10✔
991
      *write_bytes = cur_write_bytes - last_write_bytes;
10✔
992
    }
993
    else{
994
      *rchars = 0;
2✔
995
      *wchars = 0;
2✔
996
      *read_bytes = 0;
2✔
997
      *write_bytes = 0;
2✔
998
    }
999
    last_rchars = cur_rchars;
12✔
1000
    last_wchars = cur_wchars;
12✔
1001
    last_read_bytes = cur_read_bytes;
12✔
1002
    last_write_bytes = cur_write_bytes;
12✔
1003
  } else {
1004
    return code;
×
1005
  }
1006
  return 0;
12✔
1007
}
1008
void taosSetDefaultProcIODelta(int64_t *rchars, int64_t *wchars, int64_t *read_bytes, int64_t *write_bytes) {
×
1009
  if(rchars) *rchars = 0;
×
1010
  if(wchars) *wchars = 0;
×
1011
  if(read_bytes) *read_bytes = 0;
×
1012
  if(write_bytes) *write_bytes = 0;
×
1013
}
×
1014

1015
int32_t taosGetCardInfo(int64_t *receive_bytes, int64_t *transmit_bytes) {
12✔
1016
  OS_PARAM_CHECK(receive_bytes);
12!
1017
  OS_PARAM_CHECK(transmit_bytes);
12!
1018
  *receive_bytes = 0;
12✔
1019
  *transmit_bytes = 0;
12✔
1020

1021
#ifdef WINDOWS
1022
  return 0;
1023
#elif defined(_TD_DARWIN_64)
1024
  return 0;
1025
#else
1026
  TdFilePtr pFile = taosOpenFile(tsSysNetFile, TD_FILE_READ | TD_FILE_STREAM);
12✔
1027
  if (pFile == NULL) {
12!
1028
    return terrno;
×
1029
  }
1030

1031
  ssize_t _bytes = 0;
12✔
1032
  char    line[1024];
1033

1034
  while (!taosEOFFile(pFile)) {
60!
1035
    int64_t o_rbytes = 0;
60✔
1036
    int64_t rpackts = 0;
60✔
1037
    int64_t o_tbytes = 0;
60✔
1038
    int64_t tpackets = 0;
60✔
1039
    int64_t nouse1 = 0;
60✔
1040
    int64_t nouse2 = 0;
60✔
1041
    int64_t nouse3 = 0;
60✔
1042
    int64_t nouse4 = 0;
60✔
1043
    int64_t nouse5 = 0;
60✔
1044
    int64_t nouse6 = 0;
60✔
1045
    char    nouse0[200] = {0};
60✔
1046

1047
    _bytes = taosGetsFile(pFile, sizeof(line), line);
60✔
1048
    if (_bytes <= 0) {
60✔
1049
      break;
12✔
1050
    }
1051

1052
    line[_bytes - 1] = 0;
48✔
1053

1054
    if (strstr(line, "lo:") != NULL) {
48✔
1055
      continue;
12✔
1056
    }
1057

1058
    (void)sscanf(line,
36✔
1059
           "%s %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64 " %" PRId64
1060
           " %" PRId64,
1061
           nouse0, &o_rbytes, &rpackts, &nouse1, &nouse2, &nouse3, &nouse4, &nouse5, &nouse6, &o_tbytes, &tpackets);
1062
    *receive_bytes += o_rbytes;
36✔
1063
    *transmit_bytes += o_tbytes;
36✔
1064
  }
1065

1066
  TAOS_SKIP_ERROR(taosCloseFile(&pFile));
12✔
1067

1068
  return 0;
12✔
1069
#endif
1070
}
1071

1072
int32_t taosGetCardInfoDelta(int64_t *receive_bytes, int64_t *transmit_bytes) {
12✔
1073
  OS_PARAM_CHECK(receive_bytes);
12!
1074
  OS_PARAM_CHECK(transmit_bytes);
12!
1075
  static int64_t last_receive_bytes = -1;
1076
  static int64_t last_transmit_bytes = -1;
1077
  int64_t cur_receive_bytes = 0;
12✔
1078
  int64_t cur_transmit_bytes = 0;
12✔
1079
  int32_t code = taosGetCardInfo(&cur_receive_bytes, &cur_transmit_bytes);
12✔
1080
  if (code == 0) {
12!
1081
    if(last_receive_bytes >= 0 && last_transmit_bytes >= 0){
12!
1082
      *receive_bytes = cur_receive_bytes - last_receive_bytes;
10✔
1083
      *transmit_bytes = cur_transmit_bytes - last_transmit_bytes;
10✔
1084
    }
1085
    else{
1086
      *receive_bytes = 0;
2✔
1087
      *transmit_bytes = 0;
2✔
1088
    }
1089

1090
    last_receive_bytes = cur_receive_bytes;
12✔
1091
    last_transmit_bytes = cur_transmit_bytes;
12✔
1092
  } else {
1093
    return code;
×
1094
  }
1095
  return 0;
12✔
1096
}
1097
void taosSetDefaultCardInfoDelta(int64_t *receive_bytes, int64_t *transmit_bytes) {
×
1098
  if (receive_bytes) *receive_bytes = 0;
×
1099
  if (transmit_bytes) *transmit_bytes = 0;
×
1100
}
×
1101

1102
void taosKillSystem() {
×
1103
#ifdef WINDOWS
1104
  printf("function taosKillSystem, exit!");
1105
  exit(0);
1106
#elif defined(_TD_DARWIN_64)
1107
  printf("function taosKillSystem, exit!");
1108
  exit(0);
1109
#else
1110
  // SIGINT
1111
  (void)printf("%sd will shut down soon", CUS_PROMPT);
×
1112
  (void)kill(tsProcId, 2);
×
1113
#endif
1114
}
×
1115

1116
#define UUIDLEN (36)
1117
int32_t taosGetSystemUUIDLimit36(char *uid, int32_t uidlen) {
10,338✔
1118
  OS_PARAM_CHECK(uid);
10,338!
1119
#ifdef WINDOWS
1120
  GUID guid;
1121
  HRESULT h = CoCreateGuid(&guid);
1122
  if (h != S_OK) {
1123
    return TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
1124
  }
1125
  (void)snprintf(uid, uidlen, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", guid.Data1, guid.Data2, guid.Data3,
1126
           guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6],
1127
           guid.Data4[7]);
1128

1129
  return 0;
1130
#elif defined(_TD_DARWIN_64)
1131
  uuid_t uuid = {0};
1132
  char   buf[UUIDLEN37];
1133
  memset(buf, 0, UUIDLEN37);
1134
  uuid_generate(uuid);
1135
  // it's caller's responsibility to make enough space for `uid`, that's 36-char + 1-null
1136
  uuid_unparse_lower(uuid, buf);
1137
  (void)snprintf(uid, uidlen, "%.*s", (int)sizeof(buf), buf);
1138
  return 0;
1139
#else
1140
  int64_t len = 0;
10,338✔
1141

1142
  // fd = open("/proc/sys/kernel/random/uuid", 0);
1143
  TdFilePtr pFile = taosOpenFile("/proc/sys/kernel/random/uuid", TD_FILE_READ);
10,338✔
1144
  if (pFile == NULL) {
10,454!
1145
    return terrno;
×
1146
  } else {
1147
    len = taosReadFile(pFile, uid, uidlen);
10,454✔
1148
    TAOS_SKIP_ERROR(taosCloseFile(&pFile));
10,453✔
1149
    if (len < 0) {
10,452!
1150
      return terrno;
×
1151
    }
1152
  }
1153
  if (len >= UUIDLEN + 1) {
10,452✔
1154
    uid[len - 1] = 0;
9,310✔
1155
  } else {
1156
    uid[uidlen - 1] = 0;
1,142✔
1157
  }
1158

1159
  return 0;
10,452✔
1160
#endif
1161
}
1162

1163
int32_t taosGetSystemUUIDLen(char *uid, int32_t uidlen) {
1,137✔
1164
  if (uid == NULL || uidlen <= 0) {
1,137!
1165
    return TSDB_CODE_APP_ERROR;
×
1166
  }
1167
  int num = (uidlen % UUIDLEN == 0) ? (uidlen / UUIDLEN) : (uidlen / UUIDLEN + 1);
1,137✔
1168
  int left = uidlen;
1,137✔
1169
  for (int i = 0; i < num; ++i) {
3,407✔
1170
    int32_t code = taosGetSystemUUIDLimit36(uid + i * UUIDLEN, left);
2,270✔
1171
    if (code != 0) {
2,270!
1172
      return code;
×
1173
    }
1174
    left -= UUIDLEN;
2,270✔
1175
  }
1176
  return TSDB_CODE_SUCCESS;
1,137✔
1177
}
1178

1179
char *taosGetCmdlineByPID(int pid) {
1,874✔
1180
#ifdef WINDOWS
1181
  return "";
1182
#elif defined(_TD_DARWIN_64)
1183
  static char cmdline[1024];
1184
  errno = 0;
1185

1186
  if (proc_pidpath(pid, cmdline, sizeof(cmdline)) <= 0) {
1187
    fprintf(stderr, "PID is %d, %s", pid, strerror(errno));
1188
    return strerror(errno);
1189
  }
1190

1191
  return cmdline;
1192
#else
1193
  static char cmdline[1024];
1194
  (void)snprintf(cmdline, sizeof(cmdline), "/proc/%d/cmdline", pid);
1,874✔
1195

1196
  // int fd = open(cmdline, O_RDONLY);
1197
  TdFilePtr pFile = taosOpenFile(cmdline, TD_FILE_READ);
1,874✔
1198
  if (pFile != NULL) {
1,874✔
1199
    int n = taosReadFile(pFile, cmdline, sizeof(cmdline) - 1);
1,737✔
1200
    if (n < 0) n = 0;
1,737✔
1201

1202
    if (n > 0 && cmdline[n - 1] == '\n') --n;
1,737!
1203

1204
    cmdline[n] = 0;
1,737✔
1205

1206
    TAOS_SKIP_ERROR(taosCloseFile(&pFile));
1,737✔
1207
  } else {
1208
    cmdline[0] = 0;
137✔
1209
  }
1210

1211
  return cmdline;
1,874✔
1212
#endif
1213
}
1214

1215
int64_t taosGetOsUptime() {
3,501✔
1216
#ifdef WINDOWS
1217
#elif defined(_TD_DARWIN_64)
1218
#else
1219
  struct sysinfo info;
1220
  if (-1 == sysinfo(&info)) {
3,501!
1221
    terrno = TAOS_SYSTEM_ERROR(errno);
×
1222
    return terrno;
×
1223
  }
1224
  
1225
  return (int64_t)info.uptime * 1000;
3,501✔
1226
  
1227
#endif
1228
  return 0;
1229
}
1230

1231
void taosSetCoreDump(bool enable) {
7,404✔
1232
  if (!enable) return;
7,404!
1233
#ifdef WINDOWS
1234
  SetUnhandledExceptionFilter(exceptionHandler);
1235
  SetUnhandledExceptionFilter(&FlCrashDump);
1236
#elif defined(_TD_DARWIN_64)
1237
#else
1238
  // 1. set ulimit -c unlimited
1239
  struct rlimit rlim;
1240
  struct rlimit rlim_new;
1241
  if (getrlimit(RLIMIT_CORE, &rlim) == 0) {
7,404!
1242
#ifndef _ALPINE
1243
    // printf("the old unlimited para: rlim_cur=%" PRIu64 ", rlim_max=%" PRIu64, rlim.rlim_cur, rlim.rlim_max);
1244
#else
1245
    // printf("the old unlimited para: rlim_cur=%llu, rlim_max=%llu", rlim.rlim_cur, rlim.rlim_max);
1246
#endif
1247
    rlim_new.rlim_cur = RLIM_INFINITY;
7,404✔
1248
    rlim_new.rlim_max = RLIM_INFINITY;
7,404✔
1249
    if (setrlimit(RLIMIT_CORE, &rlim_new) != 0) {
7,404!
1250
      // printf("set unlimited fail, error: %s", strerror(errno));
1251
      rlim_new.rlim_cur = rlim.rlim_max;
×
1252
      rlim_new.rlim_max = rlim.rlim_max;
×
1253
      (void)setrlimit(RLIMIT_CORE, &rlim_new);
×
1254
    }
1255
  }
1256

1257
  if (getrlimit(RLIMIT_CORE, &rlim) == 0) {
7,404✔
1258
#ifndef _ALPINE
1259
    // printf("the new unlimited para: rlim_cur=%" PRIu64 ", rlim_max=%" PRIu64, rlim.rlim_cur, rlim.rlim_max);
1260
#else
1261
    // printf("the new unlimited para: rlim_cur=%llu, rlim_max=%llu", rlim.rlim_cur, rlim.rlim_max);
1262
#endif
1263
  }
1264

1265
#ifndef _TD_ARM_
1266
  // 2. set the path for saving core file
1267
  struct __sysctl_args args;
1268

1269
  int    old_usespid = 0;
7,404✔
1270
  size_t old_len = 0;
7,404✔
1271
  int    new_usespid = 1;
7,404✔
1272
  size_t new_len = sizeof(new_usespid);
7,404✔
1273

1274
  int name[] = {CTL_KERN, KERN_CORE_USES_PID};
7,404✔
1275

1276
  (void)memset(&args, 0, sizeof(struct __sysctl_args));
7,404✔
1277
  args.name = name;
7,404✔
1278
  args.nlen = sizeof(name) / sizeof(name[0]);
7,404✔
1279
  args.oldval = &old_usespid;
7,404✔
1280
  args.oldlenp = &old_len;
7,404✔
1281
  args.newval = &new_usespid;
7,404✔
1282
  args.newlen = new_len;
7,404✔
1283

1284
  old_len = sizeof(old_usespid);
7,404✔
1285

1286
#ifndef __loongarch64
1287
  if (syscall(SYS__sysctl, &args) == -1) {
7,404✔
1288
    // printf("_sysctl(kern_core_uses_pid) set fail: %s", strerror(errno));
1289
  }
1290
#endif
1291

1292
  // printf("The old core_uses_pid[%" PRIu64 "]: %d", old_len, old_usespid);
1293

1294
  old_usespid = 0;
7,404✔
1295
  old_len = 0;
7,404✔
1296
  (void)memset(&args, 0, sizeof(struct __sysctl_args));
7,404✔
1297
  args.name = name;
7,404✔
1298
  args.nlen = sizeof(name) / sizeof(name[0]);
7,404✔
1299
  args.oldval = &old_usespid;
7,404✔
1300
  args.oldlenp = &old_len;
7,404✔
1301

1302
  old_len = sizeof(old_usespid);
7,404✔
1303

1304
#ifndef __loongarch64
1305
  if (syscall(SYS__sysctl, &args) == -1) {
7,404✔
1306
    // printf("_sysctl(kern_core_uses_pid) get fail: %s", strerror(errno));
1307
  }
1308
#endif
1309

1310
  // printf("The new core_uses_pid[%" PRIu64 "]: %d", old_len, old_usespid);
1311
#endif
1312
#endif
1313
}
1314

1315
SysNameInfo taosGetSysNameInfo() {
5,900✔
1316
#ifdef WINDOWS
1317
  SysNameInfo info = {0};
1318
  DWORD       dwVersion = GetVersion();
1319

1320
  char *tmp = NULL;
1321
  tmp = getenv("OS");
1322
  if (tmp != NULL) tstrncpy(info.sysname, tmp, sizeof(info.sysname));
1323
  tmp = getenv("COMPUTERNAME");
1324
  if (tmp != NULL) tstrncpy(info.nodename, tmp, sizeof(info.nodename));
1325
  sprintf_s(info.release, sizeof(info.release), "%d", dwVersion & 0x0F);
1326
  sprintf_s(info.version, sizeof(info.release), "%d", (dwVersion >> 8) & 0x0F);
1327
  tmp = getenv("PROCESSOR_ARCHITECTURE");
1328
  if (tmp != NULL) tstrncpy(info.machine, tmp, sizeof(info.machine));
1329

1330
  return info;
1331
#elif defined(_TD_DARWIN_64)
1332
  SysNameInfo info = {0};
1333

1334
  struct utsname uts;
1335
  if (!uname(&uts)) {
1336
    tstrncpy(info.sysname, uts.sysname, sizeof(info.sysname));
1337
    tstrncpy(info.nodename, uts.nodename, sizeof(info.nodename));
1338
    tstrncpy(info.release, uts.release, sizeof(info.release));
1339
    tstrncpy(info.version, uts.version, sizeof(info.version));
1340
    tstrncpy(info.machine, uts.machine, sizeof(info.machine));
1341
  }
1342

1343
  char     localHostName[512];
1344
  TAOS_SKIP_ERROR(taosGetlocalhostname(localHostName, 512));
1345
  TdCmdPtr pCmd = taosOpenCmd("scutil --get LocalHostName");
1346
  tstrncpy(info.nodename, localHostName, sizeof(info.nodename));
1347

1348
  return info;
1349
#else
1350
  SysNameInfo info = {0};
5,900✔
1351
  struct utsname uts;
1352
  if (!uname(&uts)) {
5,900!
1353
    tstrncpy(info.sysname, uts.sysname, sizeof(info.sysname));
5,900✔
1354
    tstrncpy(info.nodename, uts.nodename, sizeof(info.nodename));
5,900✔
1355
    tstrncpy(info.release, uts.release, sizeof(info.release));
5,900✔
1356
    tstrncpy(info.version, uts.version, sizeof(info.version));
5,900✔
1357
    tstrncpy(info.machine, uts.machine, sizeof(info.machine));
5,900✔
1358
  } else {
1359
    terrno = TAOS_SYSTEM_ERROR(errno);
×
1360
  }
1361

1362
  return info;
5,900✔
1363
#endif
1364
}
1365

1366
bool taosCheckCurrentInDll() {
2,014✔
1367
#ifdef WINDOWS
1368
  MEMORY_BASIC_INFORMATION mbi;
1369
  char                     path[PATH_MAX] = {0};
1370
  GetModuleFileName(
1371
      ((VirtualQuery(taosCheckCurrentInDll, &mbi, sizeof(mbi)) != 0) ? (HMODULE)mbi.AllocationBase : NULL), path,
1372
      PATH_MAX);
1373
  int strLastIndex = strlen(path);
1374
  if ((path[strLastIndex - 3] == 'd' || path[strLastIndex - 3] == 'D') &&
1375
      (path[strLastIndex - 2] == 'l' || path[strLastIndex - 2] == 'L') &&
1376
      (path[strLastIndex - 1] == 'l' || path[strLastIndex - 1] == 'L')) {
1377
    return true;
1378
  }
1379
  return false;
1380
#else
1381
  return false;
2,014✔
1382
#endif
1383
}
1384

1385
#ifdef _TD_DARWIN_64
1386
int32_t taosGetMaclocalhostnameByCommand(char *hostname, size_t maxLen) {
1387
  TdCmdPtr pCmd = taosOpenCmd("scutil --get LocalHostName");
1388
  if (pCmd != NULL) {
1389
    if (taosGetsCmd(pCmd, maxLen - 1, hostname) > 0) {
1390
      int len = strlen(hostname);
1391
      if (hostname[len - 1] == '\n') {
1392
        hostname[len - 1] = '\0';
1393
      }
1394
      return 0;
1395
    }
1396
    taosCloseCmd(&pCmd);
1397
  }
1398
  return TAOS_SYSTEM_ERROR(errno);
1399
}
1400

1401
int32_t getMacLocalHostNameBySCD(char *hostname, size_t maxLen) {
1402
  SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR(""), NULL, NULL);
1403
  CFStringRef       hostname_cfstr = SCDynamicStoreCopyLocalHostName(store);
1404
  if (hostname_cfstr != NULL) {
1405
    CFStringGetCString(hostname_cfstr, hostname, maxLen - 1, kCFStringEncodingMacRoman);
1406
    CFRelease(hostname_cfstr);
1407
  } else {
1408
    return -1;
1409
  }
1410
  CFRelease(store);
1411
  return 0;
1412
}
1413
#endif
1414

1415
int32_t taosGetlocalhostname(char *hostname, size_t maxLen) {
35,299✔
1416
  OS_PARAM_CHECK(hostname);
35,299!
1417
#ifdef _TD_DARWIN_64
1418
  int res = getMacLocalHostNameBySCD(hostname, maxLen);
1419
  if (res != 0) {
1420
    return taosGetMaclocalhostnameByCommand(hostname, maxLen);
1421
  } else {
1422
    return 0;
1423
  }
1424
#else
1425
  int r = gethostname(hostname, maxLen);
35,299✔
1426
  if (-1 == r) {
35,299!
1427
    terrno = TAOS_SYSTEM_ERROR(errno);
×
1428
    return terrno;
×
1429
  }
1430
  return r;
35,300✔
1431
#endif
1432
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc