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

taosdata / TDengine / #3903

24 Apr 2025 11:36AM UTC coverage: 55.307% (+0.09%) from 55.213%
#3903

push

travis-ci

happyguoxy
Sync branches at 2025-04-24 19:35

175024 of 316459 relevant lines covered (55.31%)

1151858.11 hits per line

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

76.97
/source/util/src/tconfig.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 "cJSON.h"
18
#include "taoserror.h"
19
#include "tconfig.h"
20
#include "tconv.h"
21
#include "tenv.h"
22
#include "tglobal.h"
23
#include "tgrant.h"
24
#include "tjson.h"
25
#include "tlog.h"
26
#include "tunit.h"
27
#include "tutil.h"
28

29
#define CFG_NAME_PRINT_LEN 32
30
#define CFG_SRC_PRINT_LEN  12
31

32
struct SConfig {
33
  ECfgSrcType   stype;
34
  SArray       *localArray;
35
  SArray       *globalArray;
36
  TdThreadMutex lock;
37
};
38

39
int32_t cfgLoadFromCfgFile(SConfig *pConfig, const char *filepath);
40
int32_t cfgLoadFromEnvFile(SConfig *pConfig, const char *envFile);
41
int32_t cfgLoadFromEnvVar(SConfig *pConfig);
42
int32_t cfgLoadFromEnvCmd(SConfig *pConfig, const char **envCmd);
43
int32_t cfgLoadFromApollUrl(SConfig *pConfig, const char *url);
44
int32_t cfgSetItemVal(SConfigItem *pItem, const char *name, const char *value, ECfgSrcType stype);
45

46
extern char **environ;
47

48
int32_t cfgInit(SConfig **ppCfg) {
1,158✔
49
  int32_t  code = 0;
1,158✔
50
  int32_t  lino = 0;
1,158✔
51
  SConfig *pCfg = NULL;
1,158✔
52

53
  pCfg = taosMemoryCalloc(1, sizeof(SConfig));
1,158✔
54
  if (pCfg == NULL) return terrno;
1,158✔
55

56
  pCfg->localArray = NULL, pCfg->globalArray = NULL;
1,158✔
57
  pCfg->localArray = taosArrayInit(64, sizeof(SConfigItem));
1,158✔
58
  TSDB_CHECK_NULL(pCfg->localArray, code, lino, _exit, terrno);
1,158✔
59

60
  pCfg->globalArray = taosArrayInit(64, sizeof(SConfigItem));
1,158✔
61
  TSDB_CHECK_NULL(pCfg->globalArray, code, lino, _exit, terrno);
1,158✔
62

63
  TAOS_CHECK_RETURN(taosThreadMutexInit(&pCfg->lock, NULL));
1,158✔
64
  *ppCfg = pCfg;
1,158✔
65

66
_exit:
1,158✔
67
  if (code != 0) {
1,158✔
68
    uError("failed to init config, since %s ,at line %d", tstrerror(code), lino);
×
69
    cfgCleanup(pCfg);
×
70
  }
71

72
  TAOS_RETURN(TSDB_CODE_SUCCESS);
1,158✔
73
}
74

75
int32_t cfgLoad(SConfig *pCfg, ECfgSrcType cfgType, const void *sourceStr) {
5,708✔
76
  switch (cfgType) {
5,708✔
77
    case CFG_STYPE_CFG_FILE:
1,141✔
78
      return cfgLoadFromCfgFile(pCfg, sourceStr);
1,141✔
79
    case CFG_STYPE_ENV_FILE:
1,142✔
80
      return cfgLoadFromEnvFile(pCfg, sourceStr);
1,142✔
81
    case CFG_STYPE_ENV_VAR:
1,141✔
82
      return cfgLoadFromEnvVar(pCfg);
1,141✔
83
    case CFG_STYPE_APOLLO_URL:
1,143✔
84
      return cfgLoadFromApollUrl(pCfg, sourceStr);
1,143✔
85
    case CFG_STYPE_ENV_CMD:
1,141✔
86
      return cfgLoadFromEnvCmd(pCfg, (const char **)sourceStr);
1,141✔
87
    default:
×
88
      return TSDB_CODE_INVALID_PARA;
×
89
  }
90
}
91

92
int32_t cfgLoadFromArray(SConfig *pCfg, SArray *pArgs) {
1,141✔
93
  int32_t size = taosArrayGetSize(pArgs);
1,141✔
94
  for (int32_t i = 0; i < size; ++i) {
1,147✔
95
    SConfigPair *pPair = taosArrayGet(pArgs, i);
6✔
96
    if (cfgSetItem(pCfg, pPair->name, pPair->value, CFG_STYPE_ARG_LIST, true) != 0) {
6✔
97
      return TSDB_CODE_INVALID_PARA;
×
98
    }
99
  }
100

101
  return TSDB_CODE_SUCCESS;
1,141✔
102
}
103

104
int32_t cfgUpdateFromArray(SConfig *pCfg, SArray *pArgs) {
61✔
105
  int32_t code = TSDB_CODE_SUCCESS;
61✔
106
  int32_t size = taosArrayGetSize(pArgs);
61✔
107
  for (int32_t i = 0; i < size; ++i) {
4,778✔
108
    SConfigItem *pItemNew = taosArrayGet(pArgs, i);
4,717✔
109

110
    (void)taosThreadMutexLock(&pCfg->lock);
4,717✔
111

112
    SConfigItem *pItemOld = cfgGetItem(pCfg, pItemNew->name);
4,717✔
113
    if (pItemOld == NULL) {
4,717✔
114
      (void)taosThreadMutexUnlock(&pCfg->lock);
×
115
      TAOS_RETURN(TSDB_CODE_CFG_NOT_FOUND);
×
116
    }
117
    switch (pItemNew->dtype) {
4,717✔
118
      case CFG_DTYPE_BOOL:
1,007✔
119
        pItemOld->bval = pItemNew->bval;
1,007✔
120
        break;
1,007✔
121
      case CFG_DTYPE_INT32:
2,438✔
122
        pItemOld->i32 = pItemNew->i32;
2,438✔
123
        break;
2,438✔
124
      case CFG_DTYPE_INT64:
424✔
125
        pItemOld->i64 = pItemNew->i64;
424✔
126
        break;
424✔
127
      case CFG_DTYPE_FLOAT:
159✔
128
      case CFG_DTYPE_DOUBLE:
129
        pItemOld->fval = pItemNew->fval;
159✔
130
        break;
159✔
131
      case CFG_DTYPE_STRING:
530✔
132
      case CFG_DTYPE_DIR:
133
        taosMemoryFree(pItemOld->str);
530✔
134
        pItemOld->str = taosStrdup(pItemNew->str);
530✔
135
        if (pItemOld->str == NULL) {
530✔
136
          (void)taosThreadMutexUnlock(&pCfg->lock);
×
137
          TAOS_RETURN(terrno);
×
138
        }
139
        break;
530✔
140
      case CFG_DTYPE_LOCALE:
106✔
141
      case CFG_DTYPE_CHARSET:
142
        code = cfgSetItemVal(pItemOld, pItemNew->name, pItemNew->str, pItemNew->stype);
106✔
143
        if (code != TSDB_CODE_SUCCESS) {
106✔
144
          (void)taosThreadMutexUnlock(&pCfg->lock);
×
145
          TAOS_RETURN(code);
×
146
        }
147
        break;
106✔
148
      case CFG_DTYPE_TIMEZONE:
53✔
149
        truncateTimezoneString(pItemNew->str);
53✔
150
        code = cfgSetItemVal(pItemOld, pItemNew->name, pItemNew->str, pItemNew->stype);
53✔
151
        if (code != TSDB_CODE_SUCCESS) {
53✔
152
          (void)taosThreadMutexUnlock(&pCfg->lock);
×
153
          TAOS_RETURN(code);
×
154
        }
155
        break;
53✔
156
      default:
×
157
        break;
×
158
    }
159

160
    (void)taosThreadMutexUnlock(&pCfg->lock);
4,717✔
161
  }
162

163
  return TSDB_CODE_SUCCESS;
61✔
164
}
165

166
void cfgItemFreeVal(SConfigItem *pItem) {
82,109✔
167
  if (pItem->dtype == CFG_DTYPE_STRING || pItem->dtype == CFG_DTYPE_DIR || pItem->dtype == CFG_DTYPE_LOCALE ||
82,109✔
168
      pItem->dtype == CFG_DTYPE_CHARSET || pItem->dtype == CFG_DTYPE_TIMEZONE) {
65,162✔
169
    taosMemoryFreeClear(pItem->str);
19,522✔
170
  }
171

172
  if (pItem->array) {
82,109✔
173
    taosArrayDestroy(pItem->array);
206✔
174
    pItem->array = NULL;
206✔
175
  }
176
}
82,109✔
177

178
void cfgCleanup(SConfig *pCfg) {
1,147✔
179
  if (pCfg == NULL) {
1,147✔
180
    return;
×
181
  }
182

183
  int32_t size = taosArrayGetSize(pCfg->localArray);
1,147✔
184
  for (int32_t i = 0; i < size; ++i) {
61,176✔
185
    SConfigItem *pItem = taosArrayGet(pCfg->localArray, i);
60,029✔
186
    cfgItemFreeVal(pItem);
60,029✔
187
    taosMemoryFreeClear(pItem->name);
60,029✔
188
  }
189

190
  size = taosArrayGetSize(pCfg->globalArray);
1,147✔
191
  for (int32_t i = 0; i < size; ++i) {
20,940✔
192
    SConfigItem *pItem = taosArrayGet(pCfg->globalArray, i);
19,793✔
193
    cfgItemFreeVal(pItem);
19,793✔
194
    taosMemoryFreeClear(pItem->name);
19,793✔
195
  }
196

197
  taosArrayDestroy(pCfg->localArray);
1,147✔
198
  taosArrayDestroy(pCfg->globalArray);
1,147✔
199
  (void)taosThreadMutexDestroy(&pCfg->lock);
1,147✔
200
  taosMemoryFree(pCfg);
1,147✔
201
}
202

203
int32_t cfgGetSize(SConfig *pCfg) { return taosArrayGetSize(pCfg->localArray) + taosArrayGetSize(pCfg->globalArray); }
19✔
204
int32_t cfgGetLocalSize(SConfig *pCfg) { return taosArrayGetSize(pCfg->localArray); }
1,196✔
205
int32_t cfgGetGlobalSize(SConfig *pCfg) { return taosArrayGetSize(pCfg->globalArray); }
3,906✔
206

207
static int32_t cfgCheckAndSetConf(SConfigItem *pItem, const char *conf) {
2,287✔
208
  cfgItemFreeVal(pItem);
2,287✔
209
  if (!(pItem->str == NULL)) return TSDB_CODE_INVALID_PARA;
2,287✔
210

211
  pItem->str = taosStrdup(conf);
2,287✔
212

213
  if (pItem->str == NULL) return terrno;
2,287✔
214

215
  TAOS_RETURN(TSDB_CODE_SUCCESS);
2,287✔
216
}
217

218
static int32_t cfgCheckAndSetDir(SConfigItem *pItem, const char *inputDir) {
4,808✔
219
  char fullDir[PATH_MAX] = {0};
4,808✔
220
  if (taosExpandDir(inputDir, fullDir, PATH_MAX) != 0) {
4,808✔
221
    int32_t code = terrno;
×
222
    uError("failed to expand dir:%s since %s", inputDir, tstrerror(code));
×
223
    TAOS_RETURN(code);
×
224
  }
225

226
  taosMemoryFreeClear(pItem->str);
4,808✔
227
  pItem->str = taosStrdup(fullDir);
4,808✔
228

229
  if (pItem->str == NULL) return terrno;
4,808✔
230

231
  TAOS_RETURN(TSDB_CODE_SUCCESS);
4,808✔
232
}
233

234
static int32_t cfgSetBool(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
910✔
235
  int32_t code = 0;
910✔
236
  bool    tmp = false;
910✔
237
  if (strcasecmp(value, "true") == 0) tmp = true;
910✔
238

239
  int32_t val = 0;
910✔
240
  if ((code = taosStr2int32(value, &val)) == 0 && val > 0) {
910✔
241
    tmp = true;
202✔
242
  }
243

244
  pItem->bval = tmp;
910✔
245
  pItem->stype = stype;
910✔
246
  return 0;
910✔
247
}
248

249
static int32_t cfgSetInt32(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
6,653✔
250
  int32_t ival;
251
  TAOS_CHECK_RETURN(taosStrHumanToInt32(value, &ival));
6,653✔
252
  if (ival < pItem->imin || ival > pItem->imax) {
6,653✔
253
    uError("cfg:%s, type:%s src:%s value:%d out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
10✔
254
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), ival, pItem->imin, pItem->imax);
255
    TAOS_RETURN(TSDB_CODE_OUT_OF_RANGE);
10✔
256
  }
257

258
  pItem->i32 = ival;
6,643✔
259
  pItem->stype = stype;
6,643✔
260
  TAOS_RETURN(TSDB_CODE_SUCCESS);
6,643✔
261
}
262

263
static int32_t cfgSetInt64(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
23✔
264
  int64_t ival;
265
  TAOS_CHECK_RETURN(taosStrHumanToInt64(value, &ival));
23✔
266
  if (ival < pItem->imin || ival > pItem->imax) {
23✔
267
    uError("cfg:%s, type:%s src:%s value:%" PRId64 " out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
1✔
268
           cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), ival, pItem->imin, pItem->imax);
269
    TAOS_RETURN(TSDB_CODE_OUT_OF_RANGE);
1✔
270
  }
271

272
  pItem->i64 = ival;
22✔
273
  pItem->stype = stype;
22✔
274
  TAOS_RETURN(TSDB_CODE_SUCCESS);
22✔
275
}
276

277
static int32_t cfgSetFloat(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
4✔
278
  float dval = 0;
4✔
279
  TAOS_CHECK_RETURN(parseCfgReal(value, &dval));
4✔
280
  if (dval < pItem->fmin || dval > pItem->fmax) {
4✔
281
    uError("cfg:%s, type:%s src:%s value:%g out of range[%g, %g]", pItem->name, cfgDtypeStr(pItem->dtype),
×
282
           cfgStypeStr(stype), dval, pItem->fmin, pItem->fmax);
283
    TAOS_RETURN(TSDB_CODE_OUT_OF_RANGE);
×
284
  }
285

286
  pItem->fval = dval;
4✔
287
  pItem->stype = stype;
4✔
288
  TAOS_RETURN(TSDB_CODE_SUCCESS);
4✔
289
}
290

291
static int32_t cfgSetString(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
1,642✔
292
  char *tmp = taosStrdup(value);
1,642✔
293
  if (tmp == NULL) {
1,642✔
294
    uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s", pItem->name, cfgDtypeStr(pItem->dtype),
×
295
           cfgStypeStr(stype), value, tstrerror(TSDB_CODE_OUT_OF_MEMORY));
296
    TAOS_RETURN(terrno);
×
297
  }
298

299
  taosMemoryFreeClear(pItem->str);
1,642✔
300
  pItem->str = tmp;
1,642✔
301
  pItem->stype = stype;
1,642✔
302
  TAOS_RETURN(TSDB_CODE_SUCCESS);
1,642✔
303
}
304

305
static int32_t cfgSetDir(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
658✔
306
  int32_t code = cfgCheckAndSetDir(pItem, value);
658✔
307
  if (TSDB_CODE_SUCCESS != code) {
658✔
308
    uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s", pItem->name, cfgDtypeStr(pItem->dtype),
×
309
           cfgStypeStr(stype), value, tstrerror(code));
310
    TAOS_RETURN(code);
×
311
  }
312

313
  pItem->stype = stype;
658✔
314
  TAOS_RETURN(TSDB_CODE_SUCCESS);
658✔
315
}
316

317
static int32_t doSetConf(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
577✔
318
  int32_t code = cfgCheckAndSetConf(pItem, value);
577✔
319
  if (TSDB_CODE_SUCCESS != code) {
577✔
320
    uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s", pItem->name, cfgDtypeStr(pItem->dtype),
×
321
           cfgStypeStr(stype), value, tstrerror(TSDB_CODE_OUT_OF_MEMORY));
322
    TAOS_RETURN(TSDB_CODE_OUT_OF_MEMORY);
×
323
  }
324

325
  pItem->stype = stype;
577✔
326
  TAOS_RETURN(TSDB_CODE_SUCCESS);
577✔
327
}
328

329
static int32_t cfgSetTimezone(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
65✔
330
  if (value == NULL) {
65✔
331
    uError("cfg:%s, type:%s src:%s, value is null, skip to set timezone", pItem->name, cfgDtypeStr(pItem->dtype),
×
332
           cfgStypeStr(stype));
333
    TAOS_RETURN(TSDB_CODE_INVALID_CFG);
×
334
  }
335
  TAOS_CHECK_RETURN(osSetTimezone(value));
65✔
336

337
  TAOS_CHECK_RETURN(doSetConf(pItem, tsTimezoneStr, stype));
65✔
338

339
  TAOS_RETURN(TSDB_CODE_SUCCESS);
65✔
340
}
341

342
static int32_t cfgSetCharset(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
238✔
343
  if (stype == CFG_STYPE_ALTER_SERVER_CMD || stype == CFG_STYPE_ALTER_CLIENT_CMD) {
238✔
344
    uError("failed to config charset, not support");
×
345
    TAOS_RETURN(TSDB_CODE_INVALID_CFG);
×
346
  }
347

348
  if (value == NULL || strlen(value) == 0) {
238✔
349
    uError("cfg:%s, type:%s src:%s, value:%s, skip to set charset", pItem->name, cfgDtypeStr(pItem->dtype),
×
350
           cfgStypeStr(stype), value);
351
    TAOS_RETURN(TSDB_CODE_INVALID_CFG);
×
352
  }
353
#ifndef DISALLOW_NCHAR_WITHOUT_ICONV
354
  if (!taosValidateEncodec(value)) {
238✔
355
    uError("invalid charset:%s", value);
×
356
    TAOS_RETURN(terrno);
×
357
  }
358

359
  if ((tsCharsetCxt = taosConvInit(value)) == NULL) {
238✔
360
    TAOS_RETURN(terrno);
×
361
  }
362
  (void)memcpy(tsCharset, value, strlen(value) + 1);
238✔
363
  TAOS_CHECK_RETURN(doSetConf(pItem, value, stype));
238✔
364
#endif
365
  TAOS_RETURN(TSDB_CODE_SUCCESS);
238✔
366
}
367

368
static int32_t cfgSetLocale(SConfigItem *pItem, const char *value, ECfgSrcType stype) {
274✔
369
  if (stype == CFG_STYPE_ALTER_SERVER_CMD || (pItem->dynScope & CFG_DYN_CLIENT) == 0) {
274✔
370
    uError("failed to config locale, not support");
×
371
    TAOS_RETURN(TSDB_CODE_INVALID_CFG);
×
372
  }
373

374
  if (value == NULL || strlen(value) == 0 || taosSetSystemLocale(value) != 0) {
274✔
375
    uError("cfg:%s, type:%s src:%s, value:%s, skip to set locale", pItem->name, cfgDtypeStr(pItem->dtype),
×
376
           cfgStypeStr(stype), value);
377
    TAOS_RETURN(TSDB_CODE_INVALID_CFG);
×
378
  }
379

380
  TAOS_CHECK_RETURN(doSetConf(pItem, value, stype));
274✔
381

382
  TAOS_RETURN(TSDB_CODE_SUCCESS);
274✔
383
}
384

385
static int32_t cfgSetTfsItem(SConfig *pCfg, const char *name, const char *value, const char *level, const char *primary,
331✔
386
                             const char *disable, ECfgSrcType stype) {
387
  int32_t code = 0;
331✔
388
  (void)taosThreadMutexLock(&pCfg->lock);
331✔
389

390
  SConfigItem *pItem = cfgGetItem(pCfg, name);
331✔
391
  if (pItem == NULL) {
331✔
392
    (void)taosThreadMutexUnlock(&pCfg->lock);
185✔
393

394
    TAOS_RETURN(TSDB_CODE_CFG_NOT_FOUND);
185✔
395
  }
396

397
  if (pItem->array == NULL) {
146✔
398
    pItem->array = taosArrayInit(16, sizeof(SDiskCfg));
146✔
399
    if (pItem->array == NULL) {
146✔
400
      (void)taosThreadMutexUnlock(&pCfg->lock);
×
401

402
      TAOS_RETURN(terrno);
×
403
    }
404
  }
405

406
  SDiskCfg cfg = {0};
146✔
407
  tstrncpy(cfg.dir, pItem->str, sizeof(cfg.dir));
146✔
408

409
  if (level == NULL || strlen(level) == 0) {
146✔
410
    cfg.level = 0;
146✔
411
  } else {
412
    code = taosStr2int32(level, &cfg.level);
×
413
    TAOS_CHECK_GOTO(code, NULL, _err);
×
414
  }
415

416
  if (primary == NULL || strlen(primary) == 0) {
146✔
417
    cfg.primary = 1;
146✔
418
  } else {
419
    code = taosStr2int32(primary, &cfg.primary);
×
420
    TAOS_CHECK_GOTO(code, NULL, _err);
×
421
  }
422

423
  if (disable == NULL || strlen(disable) == 0) {
146✔
424
    cfg.disable = 0;
146✔
425
  } else {
426
    code = taosStr2int8(disable, &cfg.disable);
×
427
    TAOS_CHECK_GOTO(code, NULL, _err);
×
428
  }
429
  void *ret = taosArrayPush(pItem->array, &cfg);
146✔
430
  if (ret == NULL) {
146✔
431
    code = terrno;
×
432
    TAOS_CHECK_GOTO(code, NULL, _err);
×
433
  }
434

435
  pItem->stype = stype;
146✔
436
  (void)taosThreadMutexUnlock(&pCfg->lock);
146✔
437

438
  TAOS_RETURN(TSDB_CODE_SUCCESS);
146✔
439
_err:
×
440
  (void)taosThreadMutexUnlock(&pCfg->lock);
×
441
  TAOS_RETURN(code);
×
442
}
443

444
static int32_t cfgUpdateDebugFlagItem(SConfig *pCfg, const char *name, bool resetArray) {
5,870✔
445
  SConfigItem *pDebugFlagItem = cfgGetItem(pCfg, "debugFlag");
5,870✔
446
  if (resetArray) {
5,870✔
447
    // reset
448
    if (pDebugFlagItem == NULL) TAOS_RETURN(TSDB_CODE_CFG_NOT_FOUND);
62✔
449

450
    // logflag names that should 'not' be set by 'debugFlag'
451
    if (pDebugFlagItem->array == NULL) {
62✔
452
      pDebugFlagItem->array = taosArrayInit(16, sizeof(SLogVar));
62✔
453
      if (pDebugFlagItem->array == NULL) return terrno;
62✔
454
    }
455
    taosArrayClear(pDebugFlagItem->array);
62✔
456
    TAOS_RETURN(TSDB_CODE_SUCCESS);
62✔
457
  }
458

459
  // update
460
  if (pDebugFlagItem == NULL) return -1;
5,808✔
461
  if (pDebugFlagItem->array != NULL) {
5,808✔
462
    SLogVar logVar = {0};
8✔
463
    tstrncpy(logVar.name, name, TSDB_LOG_VAR_LEN);
8✔
464
    if (NULL == taosArrayPush(pDebugFlagItem->array, &logVar)) return terrno;
16✔
465
  }
466
  TAOS_RETURN(TSDB_CODE_SUCCESS);
5,808✔
467
}
468

469
int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype, bool lock) {
13,212✔
470
  // GRANT_CFG_SET;
471
  int32_t code = TSDB_CODE_SUCCESS;
13,212✔
472

473
  if (lock) {
13,212✔
474
    (void)taosThreadMutexLock(&pCfg->lock);
13,208✔
475
  }
476

477
  SConfigItem *pItem = cfgGetItem(pCfg, name);
13,212✔
478
  if (pItem == NULL) {
13,212✔
479
    (void)taosThreadMutexUnlock(&pCfg->lock);
2,907✔
480
    TAOS_RETURN(TSDB_CODE_CFG_NOT_FOUND);
2,907✔
481
  }
482

483
  code = cfgSetItemVal(pItem, name, value, stype);
10,305✔
484
  if (code != TSDB_CODE_SUCCESS) {
10,305✔
485
    if (lock) {
11✔
486
      (void)taosThreadMutexUnlock(&pCfg->lock);
11✔
487
    }
488
    TAOS_RETURN(code);
11✔
489
  }
490

491
  if (lock) {
10,294✔
492
    (void)taosThreadMutexUnlock(&pCfg->lock);
10,290✔
493
  }
494

495
  TAOS_RETURN(code);
10,294✔
496
}
497

498
int32_t cfgGetAndSetItem(SConfig *pCfg, SConfigItem **pItem, const char *name, const char *value, ECfgSrcType stype,
4✔
499
                         bool lock) {
500
  // GRANT_CFG_SET;
501
  int32_t code = TSDB_CODE_SUCCESS;
4✔
502

503
  if (lock) {
4✔
504
    (void)taosThreadMutexLock(&pCfg->lock);
4✔
505
  }
506

507
  *pItem = cfgGetItem(pCfg, name);
4✔
508
  if (*pItem == NULL) {
4✔
509
    code = TSDB_CODE_CFG_NOT_FOUND;
1✔
510
    goto _exit;
1✔
511
  }
512

513
  TAOS_CHECK_GOTO(cfgSetItemVal(*pItem, name, value, stype), NULL, _exit);
3✔
514

515
_exit:
3✔
516
  if (lock) {
4✔
517
    (void)taosThreadMutexUnlock(&pCfg->lock);
4✔
518
  }
519

520
  TAOS_RETURN(code);
4✔
521
}
522

523
int32_t cfgSetItemVal(SConfigItem *pItem, const char *name, const char *value, ECfgSrcType stype) {
10,467✔
524
  int32_t code = TSDB_CODE_SUCCESS;
10,467✔
525

526
  if (pItem == NULL) return TSDB_CODE_CFG_NOT_FOUND;
10,467✔
527

528
  switch (pItem->dtype) {
10,467✔
529
    case CFG_DTYPE_BOOL: {
910✔
530
      code = cfgSetBool(pItem, value, stype);
910✔
531
      break;
910✔
532
    }
533
    case CFG_DTYPE_INT32: {
6,653✔
534
      code = cfgSetInt32(pItem, value, stype);
6,653✔
535
      break;
6,653✔
536
    }
537
    case CFG_DTYPE_INT64: {
23✔
538
      code = cfgSetInt64(pItem, value, stype);
23✔
539
      break;
23✔
540
    }
541
    case CFG_DTYPE_FLOAT:
4✔
542
    case CFG_DTYPE_DOUBLE: {
543
      code = cfgSetFloat(pItem, value, stype);
4✔
544
      break;
4✔
545
    }
546
    case CFG_DTYPE_STRING: {
1,642✔
547
      code = cfgSetString(pItem, value, stype);
1,642✔
548
      break;
1,642✔
549
    }
550
    case CFG_DTYPE_DIR: {
658✔
551
      code = cfgSetDir(pItem, value, stype);
658✔
552
      break;
658✔
553
    }
554
    case CFG_DTYPE_TIMEZONE: {
65✔
555
      code = cfgSetTimezone(pItem, value, stype);
65✔
556
      break;
65✔
557
    }
558
    case CFG_DTYPE_CHARSET: {
238✔
559
      code = cfgSetCharset(pItem, value, stype);
238✔
560
      break;
238✔
561
    }
562
    case CFG_DTYPE_LOCALE: {
274✔
563
      code = cfgSetLocale(pItem, value, stype);
274✔
564
      break;
274✔
565
    }
566
    case CFG_DTYPE_NONE:
×
567
    default:
568
      code = TSDB_CODE_INVALID_CFG;
×
569
      break;
×
570
  }
571

572
  TAOS_RETURN(code);
10,467✔
573
}
574

575
SConfigItem *cfgGetItem(SConfig *pCfg, const char *pName) {
102,716✔
576
  if (pCfg == NULL) return NULL;
102,716✔
577
  int32_t size = taosArrayGetSize(pCfg->localArray);
102,036✔
578
  for (int32_t i = 0; i < size; ++i) {
6,128,214✔
579
    SConfigItem *pItem = taosArrayGet(pCfg->localArray, i);
6,094,895✔
580
    if (taosStrcasecmp(pItem->name, pName) == 0) {
6,094,895✔
581
      return pItem;
68,717✔
582
    }
583
  }
584
  size = taosArrayGetSize(pCfg->globalArray);
33,319✔
585
  for (int32_t i = 0; i < size; ++i) {
1,062,648✔
586
    SConfigItem *pItem = taosArrayGet(pCfg->globalArray, i);
1,059,434✔
587
    if (taosStrcasecmp(pItem->name, pName) == 0) {
1,059,434✔
588
      return pItem;
30,105✔
589
    }
590
  }
591

592
  return NULL;
3,214✔
593
}
594

595
void cfgLock(SConfig *pCfg) {
72✔
596
  if (pCfg == NULL) return;
72✔
597
  (void)taosThreadMutexLock(&pCfg->lock);
72✔
598
}
599

600
void cfgUnLock(SConfig *pCfg) { (void)taosThreadMutexUnlock(&pCfg->lock); }
72✔
601

602
int32_t checkItemDyn(SConfigItem *pItem, bool isServer) {
31✔
603
  if (pItem->dynScope == CFG_DYN_NONE) {
31✔
604
    return TSDB_CODE_INVALID_CFG;
×
605
  }
606
  if (isServer) {
31✔
607
    if (pItem->dynScope == CFG_DYN_CLIENT || pItem->dynScope == CFG_DYN_CLIENT_LAZY) {
5✔
608
      return TSDB_CODE_INVALID_CFG;
1✔
609
    }
610
  } else {
611
    if (pItem->dynScope == CFG_DYN_SERVER || pItem->dynScope == CFG_DYN_SERVER_LAZY) {
26✔
612
      return TSDB_CODE_INVALID_CFG;
1✔
613
    }
614
  }
615

616
  return TSDB_CODE_SUCCESS;
29✔
617
}
618

619
int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *pVal, bool isServer,
33✔
620
                                  CfgAlterType alterType) {
621
  int32_t code = TSDB_CODE_SUCCESS;
33✔
622
  int32_t lino = 0;
33✔
623
  cfgLock(pCfg);
33✔
624

625
  SConfigItem *pItem = cfgGetItem(pCfg, name);
33✔
626
  TSDB_CHECK_NULL(pItem, code, lino, _exit, TSDB_CODE_CFG_NOT_FOUND);
33✔
627

628
  TAOS_CHECK_EXIT(checkItemDyn(pItem, isServer));
31✔
629

630
  if ((pItem->category == CFG_CATEGORY_GLOBAL) && alterType == CFG_ALTER_DNODE) {
29✔
631
    uError("failed to config:%s, not support update global config on only one dnode", name);
×
632
    code = TSDB_CODE_INVALID_CFG;
×
633
    goto _exit;
×
634
  }
635
  switch (pItem->dtype) {
29✔
636
    case CFG_DTYPE_STRING: {
7✔
637
      if (strcasecmp(name, "slowLogScope") == 0) {
7✔
638
        char *tmp = taosStrdup(pVal);
×
639
        if (!tmp) {
×
640
          code = terrno;
×
641
          goto _exit;
×
642
        }
643
        int32_t scope = 0;
×
644
        code = taosSetSlowLogScope(tmp, &scope);
×
645
        if (TSDB_CODE_SUCCESS != code) {
×
646
          taosMemoryFree(tmp);
×
647
          goto _exit;
×
648
        }
649
        taosMemoryFree(tmp);
×
650
      }
651
    } break;
7✔
652
    case CFG_DTYPE_BOOL: {
1✔
653
      int32_t ival = 0;
1✔
654
      code = taosStr2int32(pVal, &ival);
1✔
655
      if (code != 0 || (ival != 0 && ival != 1)) {
1✔
656
        uError("cfg:%s, type:%s value:%d out of range[0, 1]", pItem->name, cfgDtypeStr(pItem->dtype), ival);
1✔
657
        code = TSDB_CODE_OUT_OF_RANGE;
1✔
658
        goto _exit;
1✔
659
      }
660
    } break;
×
661
    case CFG_DTYPE_INT32: {
15✔
662
      int32_t ival;
663
      code = (int32_t)taosStrHumanToInt32(pVal, &ival);
15✔
664
      if (code != TSDB_CODE_SUCCESS) {
15✔
665
        cfgUnLock(pCfg);
×
666
        return code;
×
667
      }
668
      if (ival < pItem->imin || ival > pItem->imax) {
15✔
669
        uError("cfg:%s, type:%s value:%d out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
1✔
670
               cfgDtypeStr(pItem->dtype), ival, pItem->imin, pItem->imax);
671
        code = TSDB_CODE_OUT_OF_RANGE;
1✔
672
        goto _exit;
1✔
673
      }
674
    } break;
14✔
675
    case CFG_DTYPE_INT64: {
1✔
676
      int64_t ival;
677
      code = taosStrHumanToInt64(pVal, &ival);
1✔
678
      if (code != TSDB_CODE_SUCCESS) {
1✔
679
        cfgUnLock(pCfg);
×
680
        TAOS_RETURN(code);
×
681
      }
682
      if (ival < pItem->imin || ival > pItem->imax) {
1✔
683
        uError("cfg:%s, type:%s value:%" PRId64 " out of range[%" PRId64 ", %" PRId64 "]", pItem->name,
1✔
684
               cfgDtypeStr(pItem->dtype), ival, pItem->imin, pItem->imax);
685
        code = TSDB_CODE_OUT_OF_RANGE;
1✔
686
        goto _exit;
1✔
687
      }
688
    } break;
×
689
    case CFG_DTYPE_FLOAT:
3✔
690
    case CFG_DTYPE_DOUBLE: {
691
      float dval = 0;
3✔
692
      TAOS_CHECK_EXIT(parseCfgReal(pVal, &dval));
4✔
693

694
      if (dval < pItem->fmin || dval > pItem->fmax) {
3✔
695
        uError("cfg:%s, type:%s value:%g out of range[%g, %g]", pItem->name, cfgDtypeStr(pItem->dtype), dval,
1✔
696
               pItem->fmin, pItem->fmax);
697
        code = TSDB_CODE_OUT_OF_RANGE;
1✔
698
        goto _exit;
1✔
699
      }
700
    } break;
2✔
701
    default:
2✔
702
      break;
2✔
703
  }
704

705
_exit:
33✔
706
  if (code != TSDB_CODE_SUCCESS) {
33✔
707
    uError("failed to check range for cfg:%s, value:%s, since %s at line:%d", name, pVal, tstrerror(code), __LINE__);
8✔
708
  }
709
  cfgUnLock(pCfg);
33✔
710
  TAOS_RETURN(code);
33✔
711
}
712

713
static int32_t cfgAddItem(SConfig *pCfg, SConfigItem *pItem, const char *name) {
80,598✔
714
  SArray *array = pCfg->globalArray;
80,598✔
715
  if (pItem->category == CFG_CATEGORY_LOCAL) array = pCfg->localArray;
80,598✔
716

717
  pItem->stype = CFG_STYPE_DEFAULT;
80,598✔
718
  pItem->name = taosStrdup(name);
80,598✔
719
  if (pItem->name == NULL) return terrno;
80,598✔
720

721
  int32_t size = taosArrayGetSize(array);
80,598✔
722
  for (int32_t i = 0; i < size; ++i) {
3,101,850✔
723
    SConfigItem *existItem = taosArrayGet(array, i);
3,021,252✔
724
    if (existItem != NULL && strcmp(existItem->name, pItem->name) == 0) {
3,021,252✔
725
      taosMemoryFree(pItem->name);
×
726
      TAOS_RETURN(TSDB_CODE_INVALID_CFG);
×
727
    }
728
  }
729

730
  int32_t len = strlen(name);
80,598✔
731
  char    lowcaseName[CFG_NAME_MAX_LEN + 1] = {0};
80,598✔
732
  (void)strntolower(lowcaseName, name, TMIN(CFG_NAME_MAX_LEN, len));
80,598✔
733

734
  if (taosArrayPush(array, pItem) == NULL) {
80,598✔
735
    if (pItem->dtype == CFG_DTYPE_STRING) {
×
736
      taosMemoryFree(pItem->str);
×
737
    }
738

739
    taosMemoryFree(pItem->name);
×
740
    TAOS_RETURN(terrno);
×
741
  }
742

743
  TAOS_RETURN(TSDB_CODE_SUCCESS);
80,598✔
744
}
745

746
int32_t cfgAddBool(SConfig *pCfg, const char *name, bool defaultVal, int8_t scope, int8_t dynScope, int8_t category) {
14,410✔
747
  SConfigItem item = {
14,410✔
748
      .dtype = CFG_DTYPE_BOOL, .bval = defaultVal, .scope = scope, .dynScope = dynScope, .category = category};
749
  return cfgAddItem(pCfg, &item, name);
14,410✔
750
}
751

752
int32_t cfgAddInt32Ex(SConfig *pCfg, const char *name, int32_t defaultVal, int64_t minval, int64_t maxval, int8_t scope,
150✔
753
                      int8_t dynScope, int8_t category) {
754
  SConfigItem item = {.dtype = CFG_DTYPE_INT32,
150✔
755
                      .i32 = defaultVal,
756
                      .imin = minval,
757
                      .imax = maxval,
758
                      .scope = scope,
759
                      .dynScope = dynScope,
760
                      .category = category};
761
  return cfgAddItem(pCfg, &item, name);
150✔
762
}
763

764
int32_t cfgAddInt32(SConfig *pCfg, const char *name, int32_t defaultVal, int64_t minval, int64_t maxval, int8_t scope,
40,838✔
765
                    int8_t dynScope, int8_t category) {
766
  if (defaultVal < minval || defaultVal > maxval) {
40,838✔
767
    TAOS_RETURN(TSDB_CODE_OUT_OF_RANGE);
3✔
768
  }
769

770
  SConfigItem item = {.dtype = CFG_DTYPE_INT32,
40,835✔
771
                      .i32 = defaultVal,
772
                      .imin = minval,
773
                      .imax = maxval,
774
                      .scope = scope,
775
                      .dynScope = dynScope,
776
                      .category = category};
777
  return cfgAddItem(pCfg, &item, name);
40,835✔
778
}
779

780
int32_t cfgAddInt64(SConfig *pCfg, const char *name, int64_t defaultVal, int64_t minval, int64_t maxval, int8_t scope,
4,779✔
781
                    int8_t dynScope, int8_t category) {
782
  if (defaultVal < minval || defaultVal > maxval) {
4,779✔
783
    TAOS_RETURN(TSDB_CODE_OUT_OF_RANGE);
3✔
784
  }
785

786
  SConfigItem item = {.dtype = CFG_DTYPE_INT64,
4,776✔
787
                      .i64 = defaultVal,
788
                      .imin = minval,
789
                      .imax = maxval,
790
                      .scope = scope,
791
                      .dynScope = dynScope,
792
                      .category = category};
793
  return cfgAddItem(pCfg, &item, name);
4,776✔
794
}
795

796
int32_t cfgAddFloat(SConfig *pCfg, const char *name, float defaultVal, float minval, float maxval, int8_t scope,
3,041✔
797
                    int8_t dynScope, int8_t category) {
798
  if (defaultVal < minval || defaultVal > maxval) {
3,041✔
799
    TAOS_RETURN(TSDB_CODE_OUT_OF_RANGE);
3✔
800
  }
801

802
  SConfigItem item = {.dtype = CFG_DTYPE_FLOAT,
3,038✔
803
                      .fval = defaultVal,
804
                      .fmin = minval,
805
                      .fmax = maxval,
806
                      .scope = scope,
807
                      .dynScope = dynScope,
808
                      .category = category};
809
  return cfgAddItem(pCfg, &item, name);
3,038✔
810
}
811

812
int32_t cfgAddString(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope,
11,529✔
813
                     int8_t category) {
814
  SConfigItem item = {.dtype = CFG_DTYPE_STRING, .scope = scope, .dynScope = dynScope, .category = category};
11,529✔
815
  item.str = taosStrdup(defaultVal);
11,529✔
816
  if (item.str == NULL) return terrno;
11,529✔
817

818
  return cfgAddItem(pCfg, &item, name);
11,529✔
819
}
820

821
int32_t cfgAddDir(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope,
4,150✔
822
                  int8_t category) {
823
  SConfigItem item = {.dtype = CFG_DTYPE_DIR, .scope = scope, .dynScope = dynScope, .category = category};
4,150✔
824
  TAOS_CHECK_RETURN(cfgCheckAndSetDir(&item, defaultVal));
4,150✔
825
  return cfgAddItem(pCfg, &item, name);
4,150✔
826
}
827

828
int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope,
570✔
829
                     int8_t category) {
830
  SConfigItem item = {.dtype = CFG_DTYPE_LOCALE, .scope = scope, .dynScope = dynScope, .category = category};
570✔
831
  TAOS_CHECK_RETURN(cfgCheckAndSetConf(&item, defaultVal));
570✔
832
  return cfgAddItem(pCfg, &item, name);
570✔
833
}
834

835
int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope,
570✔
836
                      int8_t category) {
837
  SConfigItem item = {.dtype = CFG_DTYPE_CHARSET, .scope = scope, .dynScope = dynScope, .category = category};
570✔
838
  TAOS_CHECK_RETURN(cfgCheckAndSetConf(&item, defaultVal));
570✔
839
  return cfgAddItem(pCfg, &item, name);
570✔
840
}
841

842
int32_t cfgAddTimezone(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope,
570✔
843
                       int8_t category) {
844
  SConfigItem item = {.dtype = CFG_DTYPE_TIMEZONE, .scope = scope, .dynScope = dynScope, .category = category};
570✔
845
  TAOS_CHECK_RETURN(cfgCheckAndSetConf(&item, defaultVal));
570✔
846
  return cfgAddItem(pCfg, &item, name);
570✔
847
}
848

849
const char *cfgStypeStr(ECfgSrcType type) {
48,278✔
850
  switch (type) {
48,278✔
851
    case CFG_STYPE_DEFAULT:
40,735✔
852
      return "default";
40,735✔
853
    case CFG_STYPE_CFG_FILE:
7,523✔
854
      return "cfg_file";
7,523✔
855
    case CFG_STYPE_ENV_FILE:
1✔
856
      return "env_file";
1✔
857
    case CFG_STYPE_ENV_VAR:
1✔
858
      return "env_var";
1✔
859
    case CFG_STYPE_APOLLO_URL:
3✔
860
      return "apollo_url";
3✔
861
    case CFG_STYPE_ARG_LIST:
1✔
862
      return "arg_list";
1✔
863
    case CFG_STYPE_TAOS_OPTIONS:
10✔
864
      return "taos_options";
10✔
865
    case CFG_STYPE_ENV_CMD:
1✔
866
      return "env_cmd";
1✔
867
    case CFG_STYPE_ALTER_CLIENT_CMD:
1✔
868
      return "alter_client_cmd";
1✔
869
    case CFG_STYPE_ALTER_SERVER_CMD:
1✔
870
      return "alter_server_cmd";
1✔
871
    default:
1✔
872
      return "invalid";
1✔
873
  }
874
}
875

876
const char *cfgDtypeStr(ECfgDataType type) {
30✔
877
  switch (type) {
30✔
878
    case CFG_DTYPE_NONE:
1✔
879
      return "none";
1✔
880
    case CFG_DTYPE_BOOL:
2✔
881
      return "bool";
2✔
882
    case CFG_DTYPE_INT32:
12✔
883
      return "int32";
12✔
884
    case CFG_DTYPE_INT64:
3✔
885
      return "int64";
3✔
886
    case CFG_DTYPE_FLOAT:
2✔
887
      return "float";
2✔
888
    case CFG_DTYPE_DOUBLE:
1✔
889
      return "double";
1✔
890
    case CFG_DTYPE_STRING:
1✔
891
      return "string";
1✔
892
    case CFG_DTYPE_DIR:
4✔
893
      return "dir";
4✔
894
    case CFG_DTYPE_LOCALE:
1✔
895
      return "locale";
1✔
896
    case CFG_DTYPE_CHARSET:
1✔
897
      return "charset";
1✔
898
    case CFG_DTYPE_TIMEZONE:
1✔
899
      return "timezone";
1✔
900
    default:
1✔
901
      return "invalid";
1✔
902
  }
903
}
904

905
int32_t cfgDumpItemValue(SConfigItem *pItem, char *buf, int32_t bufSize, int32_t *pLen) {
1,508✔
906
  int32_t len = 0;
1,508✔
907
  switch (pItem->dtype) {
1,508✔
908
    case CFG_DTYPE_BOOL:
324✔
909
      len = tsnprintf(buf, bufSize, "%u", pItem->bval);
324✔
910
      break;
324✔
911
    case CFG_DTYPE_INT32:
641✔
912
      len = tsnprintf(buf, bufSize, "%d", pItem->i32);
641✔
913
      break;
641✔
914
    case CFG_DTYPE_INT64:
105✔
915
      len = tsnprintf(buf, bufSize, "%" PRId64, pItem->i64);
105✔
916
      break;
105✔
917
    case CFG_DTYPE_FLOAT:
53✔
918
    case CFG_DTYPE_DOUBLE:
919
      len = tsnprintf(buf, bufSize, "%f", pItem->fval);
53✔
920
      break;
53✔
921
    case CFG_DTYPE_TIMEZONE: {
385✔
922
      //      char str1[TD_TIMEZONE_LEN] = {0};
923
      //      time_t    tx1 = taosGetTimestampSec();
924
      //      if (taosFormatTimezoneStr(tx1, buf, NULL, str1) != 0) {
925
      //        tstrncpy(str1, "tz error", sizeof(str1));
926
      //      }
927
      //      len = tsnprintf(buf, bufSize, "%s", str1);
928
      //      break;
929
    }
930
    case CFG_DTYPE_STRING:
931
    case CFG_DTYPE_DIR:
932
    case CFG_DTYPE_LOCALE:
933
    case CFG_DTYPE_CHARSET:
934
    case CFG_DTYPE_NONE:
935
      len = tsnprintf(buf, bufSize, "%s", pItem->str);
385✔
936
      break;
385✔
937
  }
938

939
  if (len < 0) return terrno;
1,508✔
940

941
  if (len > bufSize) len = bufSize;
1,508✔
942

943
  *pLen = len;
1,508✔
944
  TAOS_RETURN(TSDB_CODE_SUCCESS);
1,508✔
945
}
946

947
int32_t cfgDumpItemScope(SConfigItem *pItem, char *buf, int32_t bufSize, int32_t *pLen) {
1,508✔
948
  int32_t len = 0;
1,508✔
949
  switch (pItem->scope) {
1,508✔
950
    case CFG_SCOPE_SERVER:
180✔
951
      len = tsnprintf(buf, bufSize, "server");
180✔
952
      break;
180✔
953
    case CFG_SCOPE_CLIENT:
448✔
954
      len = tsnprintf(buf, bufSize, "client");
448✔
955
      break;
448✔
956
    case CFG_SCOPE_BOTH:
880✔
957
      len = tsnprintf(buf, bufSize, "both");
880✔
958
      break;
880✔
959
  }
960

961
  if (len < 0) {
1,508✔
962
    TAOS_RETURN(TAOS_SYSTEM_ERROR(ERRNO));
×
963
  }
964

965
  if (len > bufSize) {
1,508✔
966
    len = bufSize;
×
967
  }
968

969
  *pLen = len;
1,508✔
970
  TAOS_RETURN(TSDB_CODE_SUCCESS);
1,508✔
971
}
972

973
int32_t cfgDumpItemCategory(SConfigItem *pItem, char *buf, int32_t bufSize, int32_t *pLen) {
1,509✔
974
  int32_t len = 0;
1,509✔
975
  switch (pItem->category) {
1,509✔
976
    case CFG_CATEGORY_LOCAL:
1,179✔
977
      len = tsnprintf(buf, bufSize, "local");
1,179✔
978
      break;
1,179✔
979
    case CFG_CATEGORY_GLOBAL:
329✔
980
      len = tsnprintf(buf, bufSize, "global");
329✔
981
      break;
329✔
982
    default:
1✔
983
      uError("invalid category:%d", pItem->category);
1✔
984
      TAOS_RETURN(TSDB_CODE_INVALID_CFG);
1✔
985
  }
986

987
  if (len < 0) {
1,508✔
988
    TAOS_RETURN(TAOS_SYSTEM_ERROR(ERRNO));
×
989
  }
990

991
  if (len > bufSize) {
1,508✔
992
    len = bufSize;
×
993
  }
994

995
  *pLen = len;
1,508✔
996
  TAOS_RETURN(TSDB_CODE_SUCCESS);
1,508✔
997
}
998

999
void cfgDumpCfgArrayS3(SArray *array, bool tsc, bool dump) {
10✔
1000
  char    src[CFG_SRC_PRINT_LEN + 1] = {0};
10✔
1001
  char    name[CFG_NAME_PRINT_LEN + 1] = {0};
10✔
1002
  int32_t size = taosArrayGetSize(array);
10✔
1003
  for (int32_t i = 0; i < size; ++i) {
260✔
1004
    SConfigItem *pItem = taosArrayGet(array, i);
250✔
1005
    if (tsc && pItem->scope == CFG_SCOPE_SERVER) continue;
250✔
1006
    if (dump && strcmp(pItem->name, "scriptDir") == 0) continue;
236✔
1007
    if (dump && strncmp(pItem->name, "s3", 2) != 0) continue;
233✔
1008
    tstrncpy(src, cfgStypeStr(pItem->stype), CFG_SRC_PRINT_LEN);
23✔
1009
    for (int32_t j = 0; j < CFG_SRC_PRINT_LEN; ++j) {
299✔
1010
      if (src[j] == 0) src[j] = ' ';
276✔
1011
    }
1012

1013
    tstrncpy(name, pItem->name, CFG_NAME_PRINT_LEN);
23✔
1014
    for (int32_t j = 0; j < CFG_NAME_PRINT_LEN; ++j) {
759✔
1015
      if (name[j] == 0) name[j] = ' ';
736✔
1016
    }
1017

1018
    switch (pItem->dtype) {
23✔
1019
      case CFG_DTYPE_BOOL:
3✔
1020
        if (dump) {
3✔
1021
          (void)printf("%s %s %u\n", src, name, pItem->bval);
2✔
1022
        } else {
1023
          uInfo("%s %s %u", src, name, pItem->bval);
1✔
1024
        }
1025

1026
        break;
3✔
1027
      case CFG_DTYPE_INT32:
9✔
1028
        if (dump) {
9✔
1029
          (void)printf("%s %s %d\n", src, name, pItem->i32);
6✔
1030
        } else {
1031
          uInfo("%s %s %d", src, name, pItem->i32);
3✔
1032
        }
1033
        break;
9✔
1034
      case CFG_DTYPE_INT64:
×
1035
        if (dump) {
×
1036
          (void)printf("%s %s %" PRId64 "\n", src, name, pItem->i64);
×
1037
        } else {
1038
          uInfo("%s %s %" PRId64, src, name, pItem->i64);
×
1039
        }
1040
        break;
×
1041
      case CFG_DTYPE_DOUBLE:
×
1042
      case CFG_DTYPE_FLOAT:
1043
        if (dump) {
×
1044
          (void)printf("%s %s %.2f\n", src, name, pItem->fval);
×
1045
        } else {
1046
          uInfo("%s %s %.2f", src, name, pItem->fval);
×
1047
        }
1048
        break;
×
1049
      case CFG_DTYPE_STRING:
11✔
1050
      case CFG_DTYPE_DIR:
1051
      case CFG_DTYPE_LOCALE:
1052
      case CFG_DTYPE_CHARSET:
1053
      case CFG_DTYPE_TIMEZONE:
1054
      case CFG_DTYPE_NONE:
1055
        if (dump) {
11✔
1056
          (void)printf("%s %s %s\n", src, name, pItem->str);
6✔
1057
        } else {
1058
          uInfo("%s %s %s", src, name, pItem->str);
5✔
1059
        }
1060
        break;
11✔
1061
    }
1062
  }
250✔
1063
}
10✔
1064

1065
void cfgDumpCfgS3(SConfig *pCfg, bool tsc, bool dump) {
5✔
1066
  if (dump) {
5✔
1067
    (void)printf("                     s3 config");
3✔
1068
    (void)printf("\n");
3✔
1069
    (void)printf("=================================================================");
3✔
1070
    (void)printf("\n");
3✔
1071
  } else {
1072
    uInfo("                     s3 config");
2✔
1073
    uInfo("=================================================================");
2✔
1074
  }
1075
  cfgDumpCfgArrayS3(pCfg->localArray, tsc, dump);
5✔
1076
  cfgDumpCfgArrayS3(pCfg->globalArray, tsc, dump);
5✔
1077
  if (dump) {
5✔
1078
    (void)printf("=================================================================\n");
3✔
1079
  } else {
1080
    uInfo("=================================================================");
2✔
1081
  }
1082
}
5✔
1083

1084
void cfgDumpCfg(SConfig *pCfg, bool tsc, bool dump) {
573✔
1085
  if (dump) {
573✔
1086
    (void)printf("                     global config");
3✔
1087
    (void)printf("\n");
3✔
1088
    (void)printf("=================================================================");
3✔
1089
    (void)printf("\n");
3✔
1090
  } else {
1091
    uInfo("                     global config");
570✔
1092
    uInfo("=================================================================");
570✔
1093
  }
1094

1095
  char src[CFG_SRC_PRINT_LEN + 1] = {0};
573✔
1096
  char name[CFG_NAME_PRINT_LEN + 1] = {0};
573✔
1097

1098
  int32_t size = taosArrayGetSize(pCfg->localArray);
573✔
1099
  for (int32_t i = 0; i < size; ++i) {
49,651✔
1100
    SConfigItem *pItem = taosArrayGet(pCfg->localArray, i);
49,078✔
1101
    if (tsc && pItem->scope == CFG_SCOPE_SERVER) continue;
49,078✔
1102
    if (dump && strcmp(pItem->name, "scriptDir") == 0) continue;
48,236✔
1103
    tstrncpy(src, cfgStypeStr(pItem->stype), CFG_SRC_PRINT_LEN);
48,233✔
1104
    for (int32_t j = 0; j < CFG_SRC_PRINT_LEN; ++j) {
627,029✔
1105
      if (src[j] == 0) src[j] = ' ';
578,796✔
1106
    }
1107

1108
    tstrncpy(name, pItem->name, CFG_NAME_PRINT_LEN);
48,233✔
1109
    for (int32_t j = 0; j < CFG_NAME_PRINT_LEN; ++j) {
1,591,689✔
1110
      if (name[j] == 0) name[j] = ' ';
1,543,456✔
1111
    }
1112

1113
    switch (pItem->dtype) {
48,233✔
1114
      case CFG_DTYPE_BOOL:
9,776✔
1115
        if (dump) {
9,776✔
1116
          (void)printf("%s %s %u\n", src, name, pItem->bval);
56✔
1117
        } else {
1118
          uInfo("%s %s %u", src, name, pItem->bval);
9,720✔
1119
        }
1120

1121
        break;
9,776✔
1122
      case CFG_DTYPE_INT32:
21,586✔
1123
        if (dump) {
21,586✔
1124
          (void)printf("%s %s %d\n", src, name, pItem->i32);
166✔
1125
        } else {
1126
          uInfo("%s %s %d", src, name, pItem->i32);
21,420✔
1127
        }
1128
        break;
21,586✔
1129
      case CFG_DTYPE_INT64:
2,748✔
1130
        if (dump) {
2,748✔
1131
          (void)printf("%s %s %" PRId64 "\n", src, name, pItem->i64);
18✔
1132
        } else {
1133
          uInfo("%s %s %" PRId64, src, name, pItem->i64);
2,730✔
1134
        }
1135
        break;
2,748✔
1136
      case CFG_DTYPE_DOUBLE:
2,023✔
1137
      case CFG_DTYPE_FLOAT:
1138
        if (dump) {
2,023✔
1139
          (void)printf("%s %s %.2f\n", src, name, pItem->fval);
13✔
1140
        } else {
1141
          uInfo("%s %s %.2f", src, name, pItem->fval);
2,010✔
1142
        }
1143
        break;
2,023✔
1144
      case CFG_DTYPE_STRING:
12,100✔
1145
      case CFG_DTYPE_DIR:
1146
      case CFG_DTYPE_LOCALE:
1147
      case CFG_DTYPE_CHARSET:
1148
      case CFG_DTYPE_TIMEZONE:
1149
      case CFG_DTYPE_NONE:
1150
        if (strcasecmp(pItem->name, "dataDir") == 0) {
12,100✔
1151
          size_t sz = taosArrayGetSize(pItem->array);
152✔
1152
          if (sz > 1) {
152✔
1153
            for (size_t j = 0; j < sz; ++j) {
×
1154
              SDiskCfg *pCfg = taosArrayGet(pItem->array, j);
×
1155
              if (dump) {
×
1156
                (void)printf("%s %s %s l:%d p:%d d:%" PRIi8 "\n", src, name, pCfg->dir, pCfg->level, pCfg->primary,
×
1157
                             pCfg->disable);
×
1158
              } else {
1159
                uInfo("%s %s %s l:%d p:%d d:%" PRIi8, src, name, pCfg->dir, pCfg->level, pCfg->primary, pCfg->disable);
×
1160
              }
1161
            }
1162
            break;
×
1163
          }
1164
        }
1165
        if (dump) {
12,100✔
1166
          (void)printf("%s %s %s\n", src, name, pItem->str);
70✔
1167
        } else {
1168
          uInfo("%s %s %s", src, name, pItem->str);
12,030✔
1169
        }
1170

1171
        break;
12,100✔
1172
    }
1173
  }
49,078✔
1174

1175
  if (dump) {
573✔
1176
    (void)printf("=================================================================\n");
3✔
1177
  } else {
1178
    uInfo("=================================================================");
570✔
1179
  }
1180
}
573✔
1181

1182
int32_t cfgLoadFromEnvVar(SConfig *pConfig) {
1,141✔
1183
  char    line[1024], *name, *value, *value2, *value3, *value4;
1184
  int32_t olen, vlen, vlen2, vlen3, vlen4;
1185
  int32_t code = 0;
1,141✔
1186
  char  **pEnv = environ;
1,141✔
1187
  line[1023] = 0;
1,141✔
1188

1189
  if (pEnv == NULL) TAOS_RETURN(TSDB_CODE_SUCCESS);
1,141✔
1190
  while (*pEnv != NULL) {
25,902✔
1191
    name = value = value2 = value3 = value4 = NULL;
24,761✔
1192
    olen = vlen = vlen2 = vlen3 = vlen4 = 0;
24,761✔
1193

1194
    tstrncpy(line, *pEnv, sizeof(line));
24,761✔
1195
    pEnv++;
24,761✔
1196
    if (taosEnvToCfg(line, line, 1024) < 0) {
24,761✔
1197
      uTrace("failed to convert env to cfg:%s", line);
24,761✔
1198
    }
1199

1200
    (void)paGetToken(line, &name, &olen);
24,761✔
1201
    if (olen == 0) continue;
24,761✔
1202
    name[olen] = 0;
×
1203

1204
    (void)paGetToken(name + olen + 1, &value, &vlen);
×
1205
    if (vlen == 0) continue;
×
1206
    value[vlen] = 0;
×
1207

1208
    (void)paGetToken(value + vlen + 1, &value2, &vlen2);
×
1209
    if (vlen2 != 0) {
×
1210
      value2[vlen2] = 0;
×
1211
      (void)paGetToken(value2 + vlen2 + 1, &value3, &vlen3);
×
1212
      if (vlen3 != 0) {
×
1213
        value3[vlen3] = 0;
×
1214
        (void)paGetToken(value3 + vlen3 + 1, &value4, &vlen4);
×
1215
        if (vlen4 != 0) value4[vlen4] = 0;
×
1216
      }
1217
    }
1218

1219
    code = cfgSetItem(pConfig, name, value, CFG_STYPE_ENV_VAR, true);
×
1220
    if (TSDB_CODE_SUCCESS != code && TSDB_CODE_CFG_NOT_FOUND != code) break;
×
1221

1222
    if (strcasecmp(name, "dataDir") == 0) {
×
1223
      code = cfgSetTfsItem(pConfig, name, value, value2, value3, value4, CFG_STYPE_ENV_VAR);
×
1224
      if (TSDB_CODE_SUCCESS != code && TSDB_CODE_CFG_NOT_FOUND != code) break;
×
1225
    }
1226
  }
1227

1228
  uInfo("load from env variables cfg success");
1,141✔
1229
  TAOS_RETURN(TSDB_CODE_SUCCESS);
1,141✔
1230
}
1231

1232
int32_t cfgLoadFromEnvCmd(SConfig *pConfig, const char **envCmd) {
1,141✔
1233
  char    buf[1024], *name, *value, *value2, *value3, *value4;
1234
  int32_t olen, vlen, vlen2, vlen3, vlen4;
1235
  int32_t code = 0;
1,141✔
1236
  int32_t index = 0;
1,141✔
1237
  if (envCmd == NULL) TAOS_RETURN(TSDB_CODE_SUCCESS);
1,141✔
1238
  while (envCmd[index] != NULL) {
150✔
1239
    tstrncpy(buf, envCmd[index], sizeof(buf));
7✔
1240
    buf[sizeof(buf) - 1] = 0;
7✔
1241
    if (taosEnvToCfg(buf, buf, 1024) < 0) {
7✔
1242
      uTrace("failed to convert env to cfg:%s", buf);
5✔
1243
    }
1244
    index++;
7✔
1245

1246
    name = value = value2 = value3 = value4 = NULL;
7✔
1247
    olen = vlen = vlen2 = vlen3 = vlen4 = 0;
7✔
1248

1249
    (void)paGetToken(buf, &name, &olen);
7✔
1250
    if (olen == 0) continue;
7✔
1251
    name[olen] = 0;
2✔
1252

1253
    (void)paGetToken(name + olen + 1, &value, &vlen);
2✔
1254
    if (vlen == 0) continue;
2✔
1255
    value[vlen] = 0;
×
1256

1257
    (void)paGetToken(value + vlen + 1, &value2, &vlen2);
×
1258
    if (vlen2 != 0) {
×
1259
      value2[vlen2] = 0;
×
1260
      (void)paGetToken(value2 + vlen2 + 1, &value3, &vlen3);
×
1261
      if (vlen3 != 0) {
×
1262
        value3[vlen3] = 0;
×
1263
        (void)paGetToken(value3 + vlen3 + 1, &value4, &vlen4);
×
1264
        if (vlen4 != 0) value4[vlen4] = 0;
×
1265
      }
1266
    }
1267

1268
    code = cfgSetItem(pConfig, name, value, CFG_STYPE_ENV_CMD, true);
×
1269
    if (TSDB_CODE_SUCCESS != code && TSDB_CODE_CFG_NOT_FOUND != code) break;
×
1270

1271
    if (strcasecmp(name, "dataDir") == 0) {
×
1272
      code = cfgSetTfsItem(pConfig, name, value, value2, value3, value4, CFG_STYPE_ENV_CMD);
×
1273
      if (TSDB_CODE_SUCCESS != code && TSDB_CODE_CFG_NOT_FOUND != code) break;
×
1274
    }
1275
  }
1276

1277
  uInfo("load from env cmd cfg success");
143✔
1278
  TAOS_RETURN(TSDB_CODE_SUCCESS);
143✔
1279
}
1280

1281
int32_t cfgLoadFromEnvFile(SConfig *pConfig, const char *envFile) {
1,142✔
1282
  char    line[1024], *name, *value, *value2, *value3, *value4;
1283
  int32_t olen, vlen, vlen2, vlen3, vlen4;
1284
  int32_t code = 0;
1,142✔
1285
  ssize_t _bytes = 0;
1,142✔
1286

1287
  const char *filepath = ".env";
1,142✔
1288
  if (envFile != NULL && strlen(envFile) > 0) {
1,142✔
1289
    if (!taosCheckExistFile(envFile)) {
2✔
1290
      (void)printf("failed to load env file:%s\n", envFile);
1✔
1291
      TAOS_RETURN(TSDB_CODE_NOT_FOUND);
1✔
1292
    }
1293
    filepath = envFile;
1✔
1294
  } else {
1295
    if (!taosCheckExistFile(filepath)) {
1,140✔
1296
      uInfo("env file:%s not load", filepath);
1,140✔
1297
      TAOS_RETURN(TSDB_CODE_SUCCESS);
1,140✔
1298
    }
1299
  }
1300

1301
  TdFilePtr pFile = taosOpenFile(filepath, TD_FILE_READ | TD_FILE_STREAM);
1✔
1302
  if (pFile == NULL) return terrno;
1✔
1303

1304
  while (!taosEOFFile(pFile)) {
6✔
1305
    name = value = value2 = value3 = value4 = NULL;
6✔
1306
    olen = vlen = vlen2 = vlen3 = vlen4 = 0;
6✔
1307

1308
    _bytes = taosGetsFile(pFile, sizeof(line), line);
6✔
1309
    if (_bytes <= 0) {
6✔
1310
      break;
1✔
1311
    }
1312
    if (line[_bytes - 1] == '\n') line[_bytes - 1] = 0;
5✔
1313
    if (taosEnvToCfg(line, line, 1024) < 0) {
5✔
1314
      uTrace("failed to convert env to cfg:%s", line);
5✔
1315
    }
1316

1317
    (void)paGetToken(line, &name, &olen);
5✔
1318
    if (olen == 0) continue;
5✔
1319
    name[olen] = 0;
×
1320

1321
    (void)paGetToken(name + olen + 1, &value, &vlen);
×
1322
    if (vlen == 0) continue;
×
1323
    value[vlen] = 0;
×
1324

1325
    (void)paGetToken(value + vlen + 1, &value2, &vlen2);
×
1326
    if (vlen2 != 0) {
×
1327
      value2[vlen2] = 0;
×
1328
      (void)paGetToken(value2 + vlen2 + 1, &value3, &vlen3);
×
1329
      if (vlen3 != 0) {
×
1330
        value3[vlen3] = 0;
×
1331
        (void)paGetToken(value3 + vlen3 + 1, &value4, &vlen4);
×
1332
        if (vlen4 != 0) value4[vlen4] = 0;
×
1333
      }
1334
    }
1335

1336
    code = cfgSetItem(pConfig, name, value, CFG_STYPE_ENV_FILE, true);
×
1337
    if (TSDB_CODE_SUCCESS != code && TSDB_CODE_CFG_NOT_FOUND != code) break;
×
1338

1339
    if (strcasecmp(name, "dataDir") == 0) {
×
1340
      code = cfgSetTfsItem(pConfig, name, value, value2, value3, value4, CFG_STYPE_ENV_FILE);
×
1341
      if (TSDB_CODE_SUCCESS != code && TSDB_CODE_CFG_NOT_FOUND != code) break;
×
1342
    }
1343
  }
1344

1345
  (void)taosCloseFile(&pFile);
1✔
1346

1347
  uInfo("load from env cfg file %s success", filepath);
1✔
1348
  TAOS_RETURN(TSDB_CODE_SUCCESS);
1✔
1349
}
1350

1351
int32_t cfgLoadFromCfgFile(SConfig *pConfig, const char *filepath) {
1,141✔
1352
  char    line[1024], *name, *value, *value2, *value3, *value4;
1353
  int32_t olen, vlen, vlen2, vlen3, vlen4;
1354
  ssize_t _bytes = 0;
1,141✔
1355
  int32_t code = 0;
1,141✔
1356

1357
  TdFilePtr pFile = taosOpenFile(filepath, TD_FILE_READ | TD_FILE_STREAM);
1,141✔
1358
  if (pFile == NULL) {
1,141✔
1359
    // success when the file does not exist
1360
    code = terrno;
656✔
1361
    if (ERRNO == ENOENT) {
656✔
1362
      uInfo("failed to load from cfg file %s since %s, use default parameters", filepath, tstrerror(code));
656✔
1363
      TAOS_RETURN(TSDB_CODE_SUCCESS);
656✔
1364
    } else {
1365
      (void)printf("failed to load from cfg file %s since %s\n", filepath, tstrerror(code));
×
1366
      TAOS_RETURN(code);
×
1367
    }
1368
  }
1369

1370
  while (!taosEOFFile(pFile)) {
13,641✔
1371
    name = value = value2 = value3 = value4 = NULL;
13,641✔
1372
    olen = vlen = vlen2 = vlen3 = vlen4 = 0;
13,641✔
1373

1374
    _bytes = taosGetsFile(pFile, sizeof(line), line);
13,641✔
1375
    if (_bytes <= 0) {
13,641✔
1376
      break;
485✔
1377
    }
1378

1379
    if (line[_bytes - 1] == '\n') line[_bytes - 1] = 0;
13,156✔
1380

1381
    (void)paGetToken(line, &name, &olen);
13,156✔
1382
    if (olen == 0) continue;
13,156✔
1383
    name[olen] = 0;
11,894✔
1384

1385
    (void)paGetToken(name + olen + 1, &value, &vlen);
11,894✔
1386
    if (vlen == 0) continue;
11,894✔
1387
    value[vlen] = 0;
11,894✔
1388

1389
    if (strcasecmp(name, "encryptScope") == 0) {
11,894✔
1390
      char   *tmp = NULL;
×
1391
      int32_t len = 0;
×
1392
      char    newValue[1024] = {0};
×
1393

1394
      tstrncpy(newValue, value, sizeof(newValue));
×
1395

1396
      int32_t count = 1;
×
1397
      while (vlen < 1024) {
×
1398
        (void)paGetToken(value + vlen + 1 * count, &tmp, &len);
×
1399
        if (len == 0) break;
×
1400
        tmp[len] = 0;
×
1401
        tstrncpy(newValue + vlen, tmp, sizeof(newValue) - vlen);
×
1402
        vlen += len;
×
1403
        count++;
×
1404
      }
1405

1406
      code = cfgSetItem(pConfig, name, newValue, CFG_STYPE_CFG_FILE, true);
×
1407
      if (TSDB_CODE_SUCCESS != code && TSDB_CODE_CFG_NOT_FOUND != code) {
×
1408
        (void)printf("cfg:%s, value:%s failed since %s\n", name, newValue, tstrerror(code));
×
1409
        break;
×
1410
      }
1411
    } else {
1412
      (void)paGetToken(value + vlen + 1, &value2, &vlen2);
11,894✔
1413
      if (vlen2 != 0) {
11,894✔
1414
        value2[vlen2] = 0;
×
1415
        (void)paGetToken(value2 + vlen2 + 1, &value3, &vlen3);
×
1416
        if (vlen3 != 0) {
×
1417
          value3[vlen3] = 0;
×
1418
          (void)paGetToken(value3 + vlen3 + 1, &value4, &vlen4);
×
1419
          if (vlen4 != 0) value4[vlen4] = 0;
×
1420
        }
1421
      }
1422

1423
      code = cfgSetItem(pConfig, name, value, CFG_STYPE_CFG_FILE, true);
11,894✔
1424
      if (TSDB_CODE_SUCCESS != code && TSDB_CODE_CFG_NOT_FOUND != code) {
11,894✔
1425
        (void)printf("cfg:%s, value:%s failed since %s\n", name, value, tstrerror(code));
×
1426
        break;
×
1427
      }
1428
    }
1429

1430
    if (strcasecmp(name, "dataDir") == 0) {
11,894✔
1431
      code = cfgSetTfsItem(pConfig, name, value, value2, value3, value4, CFG_STYPE_CFG_FILE);
331✔
1432
      if (TSDB_CODE_SUCCESS != code && TSDB_CODE_CFG_NOT_FOUND != code) break;
331✔
1433
    }
1434

1435
    size_t       len = strlen(name);
11,894✔
1436
    const char  *debugFlagStr = "debugFlag";
11,894✔
1437
    const size_t debugFlagLen = strlen(debugFlagStr);
11,894✔
1438
    if (len >= debugFlagLen && taosStrcasecmp(name + len - debugFlagLen, debugFlagStr) == 0) {
11,894✔
1439
      code = cfgUpdateDebugFlagItem(pConfig, name, len == debugFlagLen);
5,870✔
1440
      if (TSDB_CODE_SUCCESS != code && TSDB_CODE_CFG_NOT_FOUND != code) break;
5,870✔
1441
    }
1442
  }
1443

1444
  (void)taosCloseFile(&pFile);
485✔
1445

1446
  if (TSDB_CODE_SUCCESS == code || TSDB_CODE_CFG_NOT_FOUND == code) {
485✔
1447
    uInfo("load from cfg file %s success", filepath);
485✔
1448
    TAOS_RETURN(TSDB_CODE_SUCCESS);
485✔
1449
  } else {
1450
    (void)printf("failed to load from cfg file %s since %s\n", filepath, tstrerror(code));
×
1451
    TAOS_RETURN(code);
×
1452
  }
1453
}
1454

1455
int32_t cfgLoadFromApollUrl(SConfig *pConfig, const char *url) {
1,143✔
1456
  char     *cfgLineBuf = NULL, *buf = NULL, *name, *value, *value2, *value3, *value4;
1,143✔
1457
  SJson    *pJson = NULL;
1,143✔
1458
  TdFilePtr pFile = NULL;
1,143✔
1459

1460
  int32_t olen, vlen, vlen2, vlen3, vlen4;
1461
  int32_t code = 0, lino = 0;
1,143✔
1462
  if (url == NULL || strlen(url) == 0) {
1,143✔
1463
    uTrace("apoll url not load");
1,139✔
1464
    TAOS_RETURN(TSDB_CODE_SUCCESS);
1,139✔
1465
  }
1466

1467
  char *p = strchr(url, ':');
4✔
1468
  if (p == NULL) {
4✔
1469
    (void)printf("fail to load apoll url: %s, unknown format\n", url);
×
1470
    TAOS_RETURN(TSDB_CODE_INVALID_PARA);
×
1471
  }
1472
  p++;
4✔
1473

1474
  if (strncmp(url, "jsonFile", 8) == 0) {
4✔
1475
    char *filepath = p;
3✔
1476
    if (!taosCheckExistFile(filepath)) {
3✔
1477
      (void)printf("failed to load json file:%s\n", filepath);
×
1478
      TAOS_RETURN(TSDB_CODE_NOT_FOUND);
×
1479
    }
1480

1481
    TdFilePtr pFile = taosOpenFile(filepath, TD_FILE_READ);
3✔
1482
    TSDB_CHECK_NULL(pFile, code, lino, _exit, terrno);
3✔
1483

1484
    size_t fileSize = taosLSeekFile(pFile, 0, SEEK_END);
3✔
1485
    if (fileSize <= 0) {
3✔
1486
      code = terrno;
×
1487
      goto _exit;
×
1488
    }
1489

1490
    buf = taosMemoryMalloc(fileSize + 1);
3✔
1491
    TSDB_CHECK_NULL(buf, code, lino, _exit, terrno);
3✔
1492

1493
    buf[fileSize] = 0;
3✔
1494
    if (taosLSeekFile(pFile, 0, SEEK_SET) < 0) {
3✔
1495
      code = terrno;
×
1496
      goto _exit;
×
1497
    }
1498

1499
    if (taosReadFile(pFile, buf, fileSize) <= 0) {
3✔
1500
      code = TSDB_CODE_INVALID_DATA_FMT;
×
1501
      goto _exit;
×
1502
    }
1503

1504
    pJson = tjsonParse(buf);
3✔
1505
    if (NULL == pJson) {
3✔
1506
      const char *jsonParseError = tjsonGetError();
×
1507
      if (jsonParseError != NULL) {
×
1508
        (void)printf("load json file parse error: %s\n", jsonParseError);
×
1509
      }
1510
      taosMemoryFreeClear(buf);
×
1511
      TAOS_CHECK_EXIT(TSDB_CODE_INVALID_DATA_FMT);
×
1512
    }
1513

1514
    int32_t jsonArraySize = tjsonGetArraySize(pJson);
3✔
1515
    for (int32_t i = 0; i < jsonArraySize; i++) {
10✔
1516
      cJSON *item = tjsonGetArrayItem(pJson, i);
7✔
1517
      if (item == NULL) break;
7✔
1518
      char *itemName = NULL, *itemValueString = NULL;
7✔
1519
      if (tjsonGetObjectName(item, &itemName) != 0) {
7✔
1520
        TAOS_CHECK_EXIT(TSDB_CODE_INVALID_DATA_FMT);
×
1521
      }
1522
      if (tjsonGetObjectValueString(item, &itemValueString) != 0) {
7✔
1523
        TAOS_CHECK_EXIT(TSDB_CODE_INVALID_DATA_FMT);
×
1524
      }
1525

1526
      if (itemValueString != NULL && itemName != NULL) {
7✔
1527
        size_t itemNameLen = strlen(itemName);
7✔
1528
        size_t itemValueStringLen = strlen(itemValueString);
7✔
1529
        void  *px = taosMemoryRealloc(cfgLineBuf, itemNameLen + itemValueStringLen + 3);
7✔
1530
        if (NULL == px) {
7✔
1531
          TAOS_CHECK_EXIT(terrno);
×
1532
        }
1533

1534
        cfgLineBuf = px;
7✔
1535
        (void)memset(cfgLineBuf, 0, itemNameLen + itemValueStringLen + 3);
7✔
1536

1537
        (void)memcpy(cfgLineBuf, itemName, itemNameLen);
7✔
1538
        cfgLineBuf[itemNameLen] = ' ';
7✔
1539
        (void)memcpy(&cfgLineBuf[itemNameLen + 1], itemValueString, itemValueStringLen);
7✔
1540

1541
        (void)paGetToken(cfgLineBuf, &name, &olen);
7✔
1542
        if (olen == 0) continue;
7✔
1543
        name[olen] = 0;
7✔
1544

1545
        (void)paGetToken(name + olen + 1, &value, &vlen);
7✔
1546
        if (vlen == 0) continue;
7✔
1547
        value[vlen] = 0;
7✔
1548

1549
        (void)paGetToken(value + vlen + 1, &value2, &vlen2);
7✔
1550
        if (vlen2 != 0) {
7✔
1551
          value2[vlen2] = 0;
×
1552
          (void)paGetToken(value2 + vlen2 + 1, &value3, &vlen3);
×
1553
          if (vlen3 != 0) {
×
1554
            value3[vlen3] = 0;
×
1555
            (void)paGetToken(value3 + vlen3 + 1, &value4, &vlen4);
×
1556
            if (vlen4 != 0) value4[vlen4] = 0;
×
1557
          }
1558
        }
1559

1560
        code = cfgSetItem(pConfig, name, value, CFG_STYPE_APOLLO_URL, true);
7✔
1561
        if (TSDB_CODE_SUCCESS != code && TSDB_CODE_CFG_NOT_FOUND != code) break;
7✔
1562

1563
        if (strcasecmp(name, "dataDir") == 0) {
7✔
1564
          code = cfgSetTfsItem(pConfig, name, value, value2, value3, value4, CFG_STYPE_APOLLO_URL);
×
1565
          if (TSDB_CODE_SUCCESS != code && TSDB_CODE_CFG_NOT_FOUND != code) break;
×
1566
        }
1567
      }
1568
    }
1569
    tjsonDelete(pJson);
3✔
1570
    pJson = NULL;
3✔
1571

1572
    // } else if (strncmp(url, "jsonUrl", 7) == 0) {
1573
    // } else if (strncmp(url, "etcdUrl", 7) == 0) {
1574
  } else {
1575
    (void)printf("Unsupported url: %s\n", url);
1✔
1576
    TAOS_RETURN(TSDB_CODE_INVALID_PARA);
1✔
1577
  }
1578

1579
  uInfo("load from apoll url not implemented yet");
3✔
1580

1581
_exit:
×
1582
  taosMemoryFree(cfgLineBuf);
3✔
1583
  taosMemoryFree(buf);
3✔
1584
  (void)taosCloseFile(&pFile);
3✔
1585
  tjsonDelete(pJson);
3✔
1586
  if (code == TSDB_CODE_CFG_NOT_FOUND) {
3✔
1587
    uTrace("load from apoll url success");
1✔
1588
    TAOS_RETURN(TSDB_CODE_SUCCESS);
1✔
1589
  } else {
1590
    (void)printf("failed to load from apoll url:%s at line %d since %s\n", url, lino, tstrerror(code));
2✔
1591
    TAOS_RETURN(code);
2✔
1592
  }
1593
}
1594

1595
int32_t cfgGetApollUrl(const char **envCmd, const char *envFile, char *apolloUrl) {
141✔
1596
  int32_t index = 0;
141✔
1597
  if (envCmd == NULL) TAOS_RETURN(TSDB_CODE_SUCCESS);
141✔
1598
  while (envCmd[index] != NULL) {
143✔
1599
    if (strncmp(envCmd[index], "TAOS_APOLLO_URL", 14) == 0) {
2✔
1600
      char *p = strchr(envCmd[index], '=');
×
1601
      if (p != NULL) {
×
1602
        p++;
×
1603
        if (*p == '\'') {
×
1604
          p++;
×
1605
          p[strlen(p) - 1] = '\0';
×
1606
        }
1607
        (void)memcpy(apolloUrl, p, TMIN(strlen(p) + 1, PATH_MAX));
×
1608
        uInfo("get apollo url from env cmd success");
×
1609
        TAOS_RETURN(TSDB_CODE_SUCCESS);
×
1610
      }
1611
    }
1612
    index++;
2✔
1613
  }
1614

1615
  char   line[1024];
1616
  char **pEnv = environ;
141✔
1617
  line[1023] = 0;
141✔
1618
  while (*pEnv != NULL) {
3,158✔
1619
    tstrncpy(line, *pEnv, sizeof(line));
3,017✔
1620
    pEnv++;
3,017✔
1621
    if (strncmp(line, "TAOS_APOLLO_URL", 14) == 0) {
3,017✔
1622
      char *p = strchr(line, '=');
×
1623
      if (p != NULL) {
×
1624
        p++;
×
1625
        if (*p == '\'') {
×
1626
          p++;
×
1627
          p[strlen(p) - 1] = '\0';
×
1628
        }
1629
        (void)memcpy(apolloUrl, p, TMIN(strlen(p) + 1, PATH_MAX));
×
1630
        uInfo("get apollo url from env variables success, apolloUrl=%s", apolloUrl);
×
1631
        TAOS_RETURN(TSDB_CODE_SUCCESS);
×
1632
      }
1633
    }
1634
  }
1635

1636
  const char *filepath = ".env";
141✔
1637
  if (envFile != NULL && strlen(envFile) > 0) {
141✔
1638
    if (!taosCheckExistFile(envFile)) {
1✔
1639
      uError("failed to load env file:%s", envFile);
1✔
1640
      TAOS_RETURN(TSDB_CODE_NOT_FOUND);
1✔
1641
    }
1642
    filepath = envFile;
×
1643
  } else {
1644
    if (!taosCheckExistFile(filepath)) {
140✔
1645
      uInfo("env file:%s not load", filepath);
140✔
1646
      TAOS_RETURN(TSDB_CODE_SUCCESS);
140✔
1647
    }
1648
  }
1649
  int64_t   _bytes;
1650
  TdFilePtr pFile = taosOpenFile(filepath, TD_FILE_READ | TD_FILE_STREAM);
×
1651
  if (pFile != NULL) {
×
1652
    while (!taosEOFFile(pFile)) {
×
1653
      _bytes = taosGetsFile(pFile, sizeof(line) - 1, line);
×
1654
      if (_bytes <= 0) {
×
1655
        break;
×
1656
      }
1657
      if (line[_bytes - 1] == '\n') line[_bytes - 1] = 0;
×
1658
      if (strncmp(line, "TAOS_APOLLO_URL", 14) == 0) {
×
1659
        char *p = strchr(line, '=');
×
1660
        if (p != NULL) {
×
1661
          p++;
×
1662
          if (*p == '\'') {
×
1663
            p++;
×
1664
            p[strlen(p) - 1] = '\0';
×
1665
          }
1666
          (void)memcpy(apolloUrl, p, TMIN(strlen(p) + 1, PATH_MAX));
×
1667
          (void)taosCloseFile(&pFile);
×
1668
          uInfo("get apollo url from env file success");
×
1669
          TAOS_RETURN(TSDB_CODE_SUCCESS);
×
1670
        }
1671
      }
1672
    }
1673
    (void)taosCloseFile(&pFile);
×
1674
  }
1675

1676
  uInfo("fail get apollo url from cmd env file");
×
1677
  TAOS_RETURN(TSDB_CODE_NOT_FOUND);
×
1678
}
1679

1680
struct SConfigIter {
1681
  int32_t  index;
1682
  SConfig *pConf;
1683
};
1684

1685
int32_t cfgCreateIter(SConfig *pConf, SConfigIter **ppIter) {
17✔
1686
  SConfigIter *pIter = taosMemoryCalloc(1, sizeof(SConfigIter));
17✔
1687
  if (pIter == NULL) return terrno;
17✔
1688

1689
  pIter->pConf = pConf;
17✔
1690

1691
  *ppIter = pIter;
17✔
1692
  TAOS_RETURN(TSDB_CODE_SUCCESS);
17✔
1693
}
1694

1695
SConfigItem *cfgNextIter(SConfigIter *pIter) {
1,531✔
1696
  if (pIter->index < cfgGetGlobalSize(pIter->pConf)) {
1,531✔
1697
    return taosArrayGet(pIter->pConf->globalArray, pIter->index++);
335✔
1698
  } else if (pIter->index < cfgGetGlobalSize(pIter->pConf) + cfgGetLocalSize(pIter->pConf)) {
1,196✔
1699
    return taosArrayGet(pIter->pConf->localArray, pIter->index++ - cfgGetGlobalSize(pIter->pConf));
1,179✔
1700
  }
1701
  return NULL;
17✔
1702
}
1703

1704
void cfgDestroyIter(SConfigIter *pIter) {
17✔
1705
  if (pIter == NULL) return;
17✔
1706

1707
  taosMemoryFree(pIter);
17✔
1708
}
1709

1710
SArray *taosGetLocalCfg(SConfig *pCfg) { return pCfg->localArray; }
215✔
1711
SArray *taosGetGlobalCfg(SConfig *pCfg) { return pCfg->globalArray; }
5,565✔
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