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

taosdata / TDengine / #3748

27 Mar 2025 05:56PM UTC coverage: 30.662% (-0.6%) from 31.304%
#3748

push

travis-ci

GitHub
enh: update go.mod

132877 of 594593 branches covered (22.35%)

Branch coverage included in aggregate %.

198453 of 486010 relevant lines covered (40.83%)

971771.49 hits per line

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

47.25
/enterprise/src/plugins/dnode/src/dmodule.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

18
#include "dmMgmt.h"
19
#include "tchecksum.h"
20

21
#if defined(GRANTS_CFG) || defined(_TD_DARWIN_64)
22
#define _TD_DM_SKIP_CHECK
23
#endif
24

25
#if !defined(ASSERT_NOT_CORE) && !defined(WINDOWS)
26
#define _TD_DM_CHECK_OFFSET
27
#define DM_CHECK_OFFSET(p1, p2, offset, flag)             \
28
  do {                                                    \
29
    int32_t off = POINTER_DISTANCE((p1), (p2));           \
30
    if ((offset) != abs(off)) {                           \
31
      dError("%s offset: %d!=%d", (flag), off, (offset)); \
32
      return TSDB_CODE_INTERNAL_ERROR;                    \
33
    }                                                     \
34
  } while (0)
35
#endif
36

37
extern char tsVersionName[];
38

39
typedef enum {
40
  DM_ENG_FVER_1 = 1,
41
} DM_ENG_FVER;
42

43
typedef enum {
44
  DM_ETYPE_UN = 0,
45
  DM_ETYPE_OS = 1,
46
  DM_ETYPE_TR = 2,
47
  DM_ETYPE_EN = 3,
48
} DM_ENG_TYPE;
49

50
#define DM_ENG_FVER_MAX DM_ENG_FVER_1
51
#define DM_OS_ST_NAME_LEN 64
52

53
#define DM_ENGINE_FILE "dnode.info"
54
#define DM_ENGINE_FILE_T "dnode.info.t"
55
#define DNODE_CFG_FILE "dnode.json"
56

57
typedef struct {
58
  int8_t  type;  // 0 unknown 1 community 2 trial 3 official
59
  int32_t dnodeId;
60
  int32_t engineVer;  // tsVersion
61
  int64_t clusterId;
62
  int64_t createMs;
63
  int64_t updateMs;
64
} SEngineInfo;
65

66
// file operation (TODO: refactor to dmUtil.c)
67
#define DM_FILE_HEAD_SIZE 512
68
typedef struct {
69
  uint32_t version;
70
  uint32_t len;  // Encoded content len(checksum included)
71
} SDFHeader;
72

73
#define STR_CASE_CMP(s, d) (0 == strcasecmp((s), (d)))
74
#define STR_STR_CMP(s, d) (strstr((s), (d)))
75
#define STR_INT_CMP(s, d, c) (taosStr2Int32(s, 0, 10) c(d))
76
#define STR_STR_SIGN ("ia")
77
#define STR_STR_COMM ("unit")
78

79
#define STR_CASE_STR_CHECK(s, d)   \
80
  do {                             \
81
    TAOS_UNUSED(strtolower(s, s)); \
82
    TAOS_UNUSED(strtolower(d, d)); \
83
    if (STR_STR_CMP(s, d)) {       \
84
      DM_ERR_RTN(0);               \
85
    }                              \
86
  } while (0)
87

88
#define DM_ERR_RTN(c) \
89
  do {                \
90
    code = (c);       \
91
    goto _exit;       \
92
  } while (0)
93

94
static const char *dmOS[] = {"Ubuntu", "CentOS Linux", "Red Hat", "Debian GNU/Linux", "CoreOS", "FreeBSD", "openSUSE",
95
                             "SLES",   "Fedora",       "macOS",   "CentOS Stream"};
96

97
// declarations
98
static void    dmFetchEType(int8_t *type);
99
static void    dmGetFname(const char *fname, char *ofname);
100
static int32_t dmSyncEps(SDnodeData *pData);
101
static int32_t dmEncodeVars(void *buf, int32_t bufLen, SEngineInfo *pInfo);
102
static int32_t dmEncodeVars(void *buf, int32_t bufLen, SEngineInfo *pInfo);
103
static int32_t dmReadVars(SEngineInfo *pInfo);
104
static int32_t dmWriteVars(SEngineInfo *pInfo);
105

106
// implementations
107

108
#ifdef _TD_DM_CHECK_OFFSET
109
static int32_t dmCheckOffset(SDnode *pDnode) {
127✔
110
  SDnodeData     *pData = &pDnode->data;
127✔
111
  TdThreadRwlock *pLock = &pData->lock;
127✔
112
  int32_t        *pDnodeId = &pData->dnodeId;
127✔
113
  int32_t        *pEngineVer = &pData->engineVer;
127✔
114
  int64_t        *pClusterId = &pData->clusterId;
127✔
115

116
  DM_CHECK_OFFSET(pData, pDnode, 168, "dnode data");
127!
117
  DM_CHECK_OFFSET(pLock, pData, 720, "data lock");
127!
118
  DM_CHECK_OFFSET(pDnodeId, pData, 0, "data dnodeId");
127!
119
  DM_CHECK_OFFSET(pEngineVer, pData, 4, "data engineVer");
127!
120
  DM_CHECK_OFFSET(pClusterId, pData, 8, "data clusterId");
127!
121

122
  return TSDB_CODE_SUCCESS;
127✔
123
}
124
#endif
125

126
static int32_t dmInitPrerequisites() {
127✔
127
#ifndef _TD_DM_SKIP_CHECK
128
  int32_t code = 0;
127✔
129

130
  char reName[64] = {0};
127✔
131
  char stName[64] = {0};
127✔
132
  char ver[64] = {0};
127✔
133

134
  code = (int32_t)(2147483648 | 298);
127✔
135
  tstrncpy(stName, tsVersionName, 16);
127✔
136

137
  if (STR_STR_CMP(stName, STR_STR_SIGN)) {
127!
138
    DM_ERR_RTN(0);
127✔
139
  }
140
  if (taosGetOsReleaseName(reName, stName, ver, DM_OS_ST_NAME_LEN) != 0) {
×
141
    int32_t errCode = TAOS_SYSTEM_ERROR(errno);
×
142
    if (errCode != 0) code = errCode;
×
143
    TAOS_CHECK_GOTO(code, NULL, _exit);
×
144
  }
145
  if (STR_CASE_CMP(stName, dmOS[0])) {
×
146
    if (STR_INT_CMP(ver, 17, >)) {
×
147
      DM_ERR_RTN(0);
×
148
    }
149
  } else if (STR_CASE_CMP(stName, dmOS[1])) {
×
150
    if (STR_INT_CMP(ver, 6, >)) {
×
151
      DM_ERR_RTN(0);
×
152
    }
153
  } else {
154
    int32_t size = sizeof(dmOS) / sizeof(dmOS[0]);
×
155
    char    os[DM_OS_ST_NAME_LEN] = {0};
×
156
    for (int32_t i = 2; i < size; ++i) {
×
157
      tstrncpy(os, dmOS[i], DM_OS_ST_NAME_LEN);
×
158
      STR_CASE_STR_CHECK(stName, os);
×
159
    }
160
  }
161

162
_exit:
127✔
163
  TAOS_RETURN(code);
127✔
164
#else
165
  TAOS_RETURN(0);
166
#endif
167
}
168

169
static int dmEncodeDFHeader(void **buf, SDFHeader *pHeader) {
45✔
170
  int tlen = 0;
45✔
171

172
  tlen += taosEncodeFixedU32(buf, pHeader->version);
45!
173
  tlen += taosEncodeFixedU32(buf, pHeader->len);
45!
174

175
  return tlen;
45✔
176
}
177

178
static void *dmDecodeDFHeader(void *buf, SDFHeader *pHeader) {
18✔
179
  buf = taosDecodeFixedU32(buf, &(pHeader->version));
18!
180
  buf = taosDecodeFixedU32(buf, &(pHeader->len));
18!
181

182
  return buf;
18✔
183
}
184

185
static int32_t dmEncodeVars(void *buf, int32_t bufLen, SEngineInfo *pInfo) {
90✔
186
  SEncoder encoder = {0};
90✔
187
  tEncoderInit(&encoder, buf, bufLen);
90✔
188
  int32_t code = 0;
90✔
189

190
  TAOS_CHECK_GOTO(tStartEncode(&encoder), NULL, _exit);
90!
191
  TAOS_CHECK_GOTO(tEncodeI8(&encoder, pInfo->type), NULL, _exit);
180!
192
  TAOS_CHECK_GOTO(tEncodeI32v(&encoder, pInfo->dnodeId), NULL, _exit);
180!
193
  TAOS_CHECK_GOTO(tEncodeI32v(&encoder, pInfo->engineVer), NULL, _exit);
180!
194
  TAOS_CHECK_GOTO(tEncodeI64v(&encoder, pInfo->clusterId), NULL, _exit);
180!
195
  TAOS_CHECK_GOTO(tEncodeI64v(&encoder, pInfo->createMs), NULL, _exit);
180!
196
  TAOS_CHECK_GOTO(tEncodeI64v(&encoder, pInfo->updateMs), NULL, _exit);
180!
197

198
  tEndEncode(&encoder);
90✔
199
  code = encoder.pos;
90✔
200
_exit:
90✔
201
  tEncoderClear(&encoder);
90✔
202
  return code;
90✔
203
}
204

205
static int32_t dmDecodeVars(void *buf, int32_t bufLen, SEngineInfo *pInfo) {
18✔
206
  SDecoder decoder = {0};
18✔
207
  tDecoderInit(&decoder, buf, bufLen);
18✔
208
  int32_t code = 0;
18✔
209

210
  TAOS_CHECK_GOTO(tStartDecode(&decoder), NULL, _exit);
18!
211

212
  TAOS_CHECK_GOTO(tDecodeI8(&decoder, &pInfo->type), NULL, _exit);
36!
213
  TAOS_CHECK_GOTO(tDecodeI32v(&decoder, &pInfo->dnodeId), NULL, _exit);
36!
214
  TAOS_CHECK_GOTO(tDecodeI32v(&decoder, &pInfo->engineVer), NULL, _exit);
36!
215
  TAOS_CHECK_GOTO(tDecodeI64v(&decoder, &pInfo->clusterId), NULL, _exit);
36!
216
  TAOS_CHECK_GOTO(tDecodeI64v(&decoder, &pInfo->createMs), NULL, _exit);
36!
217
  TAOS_CHECK_GOTO(tDecodeI64v(&decoder, &pInfo->updateMs), NULL, _exit);
36!
218

219
  tEndDecode(&decoder);
18✔
220

221
_exit:
18✔
222
  tDecoderClear(&decoder);
18✔
223
  TAOS_RETURN(code);
18✔
224
}
225

226
static int32_t dmReadVars(SEngineInfo *pInfo) {
18✔
227
  int32_t   code = 0;
18✔
228
  int32_t   lino = 0;
18✔
229
  TdFilePtr pFile = NULL;
18✔
230
  void     *buffer = NULL;
18✔
231
  void     *ptr;
232
  SDFHeader dHeader;
233
  char      fname[FILENAME_MAX] = "\0";
18✔
234

235
  dmGetFname(DM_ENGINE_FILE, fname);
18✔
236

237
  errno = 0;  // clear errno
18✔
238

239
  if (!taosCheckExistFile(fname)) {
18!
240
    TAOS_CHECK_GOTO(TSDB_CODE_NOT_FOUND, &lino, _exit);
×
241
  }
242

243
  pFile = taosOpenFile(fname, TD_FILE_READ);
18✔
244
  if (!pFile) {
18!
245
    if (errno == ENOENT) {
×
246
      TAOS_CHECK_GOTO(TSDB_CODE_NOT_FOUND, &lino, _exit);
×
247
    } else {
248
      TAOS_CHECK_GOTO(TAOS_SYSTEM_ERROR(errno), &lino, _exit);
×
249
    }
250
  }
251

252
  if (!(buffer = taosMemoryMalloc(DM_FILE_HEAD_SIZE))) {
18!
253
    TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
254
  }
255

256
  int64_t nRead = taosReadFile(pFile, buffer, DM_FILE_HEAD_SIZE);
18✔
257
  if (nRead < 0) {
18!
258
    TAOS_CHECK_GOTO(TAOS_SYSTEM_ERROR(errno), &lino, _exit);
×
259
  }
260

261
  if (nRead != DM_FILE_HEAD_SIZE) {
18!
262
    code = TSDB_CODE_FILE_CORRUPTED;
×
263
    dTrace("failed to read %d bytes from vars head since %s", DM_FILE_HEAD_SIZE, tstrerror(code));
×
264
    TAOS_CHECK_GOTO(code, &lino, _exit);
×
265
  }
266

267
  if (!taosCheckChecksumWhole((uint8_t *)buffer, DM_FILE_HEAD_SIZE)) {
18!
268
    dTrace("failed to read vars head since wrong checksum");
×
269
    TAOS_CHECK_GOTO(TSDB_CODE_CHECKSUM_ERROR, &lino, _exit);
×
270
  }
271

272
  ptr = buffer;
18✔
273
  ptr = dmDecodeDFHeader(ptr, &dHeader);
18✔
274

275
  if (dHeader.version != DM_ENG_FVER_1) {
18✔
276
    // TODO
277
  }
278

279
  if (dHeader.len > 0) {
18!
280
    if (dHeader.len > DM_FILE_HEAD_SIZE) {
18!
281
      void *tmpBuf = NULL;
×
282
      if (!(tmpBuf = taosMemoryRealloc(buffer, dHeader.len))) {
×
283
        TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _exit);
×
284
      }
285
      buffer = tmpBuf;
×
286
    }
287

288
    nRead = (int)taosReadFile(pFile, buffer, dHeader.len);
18✔
289
    if (nRead < 0) {
18!
290
      code = TAOS_SYSTEM_ERROR(errno);
×
291
      TAOS_CHECK_GOTO(code, &lino, _exit);
×
292
    }
293

294
    if (nRead != dHeader.len) {
18!
295
      code = TSDB_CODE_FILE_CORRUPTED;
×
296
      dTrace("failed to read %d bytes from vars body since %s", dHeader.len, tstrerror(code));
×
297
      TAOS_CHECK_GOTO(code, &lino, _exit);
×
298
    }
299

300
    if (!taosCheckChecksumWhole((uint8_t *)buffer, dHeader.len)) {
36!
301
      dTrace("failed to read vars body since wrong checksum");
×
302
      TAOS_CHECK_GOTO(TSDB_CODE_FILE_CORRUPTED, &lino, _exit);
×
303
    }
304

305
    ptr = buffer;
18✔
306
    TAOS_CHECK_GOTO(dmDecodeVars(ptr, dHeader.len, pInfo), &lino, _exit);
18!
307
  }
308

309
_exit:
18✔
310
  if (code != 0) {
18!
311
    dError("failed to read vars at line %d since %s", lino, tstrerror(code));
×
312
  }
313
  taosMemoryFreeClear(buffer);
18!
314
  (void)taosCloseFile(&pFile);
18✔
315
  return code;
18✔
316
}
317

318
static void dmGetFname(const char *fname, char *ofname) {
470✔
319
  if (fname) {
470!
320
    snprintf(ofname, PATH_MAX, "%s%sdnode%s%s", tsDataDir, TD_DIRSEP, TD_DIRSEP, fname);
470✔
321
  } else {
322
    snprintf(ofname, PATH_MAX, "%s%sdnode", tsDataDir, TD_DIRSEP);
×
323
  }
324
}
470✔
325

326
int32_t dmInitDndInfo(SDnodeData *pData) {
191✔
327
#ifndef _TD_DM_SKIP_CHECK
328
  int32_t code = 0;
191✔
329
  char    cfname[PATH_MAX] = "\0";
191✔
330

331
  dmGetFname(DNODE_CFG_FILE, cfname);
191✔
332
  bool fileExist = !(taosStatFile(cfname, NULL, NULL, NULL) < 0);
191✔
333
  if (fileExist) {  // dnode.info must be created before dnode.json
191✔
334
    return code;
147✔
335
  }
336
  dmGetFname(DM_ENGINE_FILE, cfname);
44✔
337
  fileExist = !(taosStatFile(cfname, NULL, NULL, NULL) < 0);
44✔
338
  if (fileExist) {
44!
339
    return code;
×
340
  }
341

342
  int8_t      eType = 0;
44✔
343
  SEngineInfo eInfo = {0};
44✔
344
  dmFetchEType(&eType);
44✔
345
  eInfo.type = eType;
44✔
346
  eInfo.dnodeId = pData->dnodeId;
44✔
347
  eInfo.engineVer = tsVersion;
44✔
348
  eInfo.clusterId = pData->clusterId;
44✔
349
  eInfo.createMs = taosGetTimestampMs();
44✔
350
  eInfo.updateMs = eInfo.createMs;
44✔
351

352
  if ((code = dmWriteVars(&eInfo)) != 0) goto _exit;
44!
353

354
_exit:
44✔
355
  TAOS_RETURN(code);
44✔
356
#else
357
  TAOS_RETURN(0);
358
#endif
359
}
360

361
static int32_t dmWriteVars(SEngineInfo *pInfo) {
45✔
362
  SDFHeader fHeader;
363
  void     *pBuf = NULL;
45✔
364
  void     *ptr;
365
  char      hbuf[DM_FILE_HEAD_SIZE] = "\0";
45✔
366
  char      tfname[PATH_MAX] = "\0";
45✔
367
  char      cfname[PATH_MAX] = "\0";
45✔
368
  int32_t   code = 0;
45✔
369
  int32_t   lino = 0;
45✔
370

371
  dmGetFname(DM_ENGINE_FILE_T, tfname);
45✔
372
  dmGetFname(DM_ENGINE_FILE, cfname);
45✔
373

374
  errno = 0;  // clear errno
45✔
375

376
  TdFilePtr tFile = taosOpenFile(tfname, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
45✔
377
  if (!tFile) {
45!
378
    code = TAOS_SYSTEM_ERROR(errno);
×
379
    TAOS_CHECK_GOTO(code, &lino, _exit);
×
380
  }
381

382
  fHeader.version = DM_ENG_FVER_MAX;
45✔
383
  fHeader.len = dmEncodeVars(NULL, 0, pInfo) + sizeof(TSCKSUM);
45✔
384
  if (fHeader.len < 0) {
385
    TAOS_CHECK_GOTO(fHeader.len, &lino, _exit);
386
  }
387

388
  ptr = hbuf;
45✔
389
  TAOS_UNUSED(dmEncodeDFHeader(&ptr, &fHeader));
45✔
390
  TAOS_CHECK_EXIT(taosCalcChecksumAppend(0, (uint8_t *)hbuf, DM_FILE_HEAD_SIZE));
45!
391

392
  if (taosWriteFile(tFile, hbuf, DM_FILE_HEAD_SIZE) < DM_FILE_HEAD_SIZE) {
45!
393
    code = TAOS_SYSTEM_ERROR(errno);
×
394
    TAOS_CHECK_GOTO(code, &lino, _exit);
×
395
  }
396

397
  if (fHeader.len > 0) {
45!
398
    if (!(pBuf = taosMemoryMalloc(fHeader.len))) {
45!
399
      code = TSDB_CODE_OUT_OF_MEMORY;
×
400
      TAOS_CHECK_GOTO(code, &lino, _exit);
×
401
    }
402

403
    ptr = pBuf;
45✔
404
    int32_t len = dmEncodeVars(ptr, fHeader.len - sizeof(TSCKSUM), pInfo);
45✔
405
    if (len < 0) {
45!
406
      TAOS_CHECK_GOTO(len, &lino, _exit);
×
407
    }
408

409
    TAOS_CHECK_EXIT(taosCalcChecksumAppend(0, (uint8_t *)pBuf, fHeader.len));
90!
410

411
    if (taosWriteFile(tFile, pBuf, fHeader.len) < fHeader.len) {
45!
412
      code = TAOS_SYSTEM_ERROR(errno);
×
413
      TAOS_CHECK_GOTO(code, &lino, _exit);
×
414
    }
415
  }
416

417
  // fsync, close and rename
418
  if (taosFsyncFile(tFile) < 0) {
45!
419
    code = TAOS_SYSTEM_ERROR(errno);
×
420
    TAOS_CHECK_GOTO(code, &lino, _exit);
×
421
  }
422
  if (taosCloseFile(&tFile) < 0) {
45!
423
    code = TAOS_SYSTEM_ERROR(errno);
×
424
    TAOS_CHECK_GOTO(code, &lino, _exit);
×
425
  }
426
  if (taosRenameFile(tfname, cfname) < 0) {
45!
427
    code = TAOS_SYSTEM_ERROR(errno);
×
428
    TAOS_CHECK_GOTO(code, &lino, _exit);
×
429
  }
430

431
_exit:
45✔
432
  taosMemoryFreeClear(pBuf);
45!
433
  if (code != 0) {
45!
434
    dError("failed to write vars at line %d since %s", lino, tstrerror(code));
×
435
    TAOS_UNUSED(taosCloseFile(&tFile));
×
436
    TAOS_UNUSED(taosRemoveFile(tfname));
×
437
  }
438

439
  return code;
45✔
440
}
441

442
static void dmFetchEType(int8_t *type) {
171✔
443
  int8_t eType = DM_ETYPE_UN;
171✔
444
  if (STR_STR_CMP(tsVersionName, STR_STR_SIGN)) {
171!
445
    if (!strncmp(tsVersionName, "t", 1)) {
171!
446
      eType = DM_ETYPE_TR;
171✔
447
    } else {
448
      eType = DM_ETYPE_EN;
×
449
    }
450
  } else if (STR_STR_CMP(tsVersionName, STR_STR_COMM)) {
×
451
    eType = DM_ETYPE_OS;
×
452
  }
453
  if (type) *type = eType;
171!
454
}
171✔
455

456
static int32_t dmInitVersion(SDnode *pDnode) {
127✔
457
#ifndef _TD_DM_SKIP_CHECK
458
  int32_t     code = 0;
127✔
459
  int32_t     lino = 0;
127✔
460
  int8_t      eType = 0;
127✔
461
  SEngineInfo eInfo = {0};
127✔
462

463
  dmFetchEType(&eType);
127✔
464

465
  char cfgFile[PATH_MAX] = "\0";
127✔
466
  dmGetFname(DNODE_CFG_FILE, cfgFile);
127✔
467

468
  TAOS_UNUSED(taosThreadRwlockRdlock(&pDnode->data.lock));
127✔
469
  // dnode.json not exist, return directly
470
  if (taosStatFile(cfgFile, NULL, NULL, NULL) < 0) {
127✔
471
    TAOS_UNUSED(taosThreadRwlockUnlock(&pDnode->data.lock));
109✔
472
    goto _exit;
109✔
473
  }
474
  if (((code = dmReadVars(&eInfo)) != 0) && (code != TSDB_CODE_NOT_FOUND)) {
18!
475
    TAOS_UNUSED(taosThreadRwlockUnlock(&pDnode->data.lock));
×
476
    TAOS_CHECK_GOTO(code, &lino, _exit);
×
477
  }
478
  TAOS_UNUSED(taosThreadRwlockUnlock(&pDnode->data.lock));
18✔
479

480
  if (pDnode->data.engineVer == 0) {           // dnode.json history version
18!
481
    if ((eInfo.type & 0x0F) == DM_ETYPE_UN) {  // without DM_ENGINE_FILE, create(handle update from history version)
×
482
      eInfo.type = eType;
×
483
      eInfo.dnodeId = pDnode->data.dnodeId;
×
484
      eInfo.engineVer = tsVersion;
×
485
      eInfo.clusterId = pDnode->data.clusterId;
×
486
      eInfo.createMs = taosGetTimestampMs();
×
487
      eInfo.updateMs = eInfo.createMs;
×
488
      // save
489
      (void)taosThreadRwlockWrlock(&pDnode->data.lock);
×
490
      if ((code = dmWriteVars(&eInfo)) != 0) {
×
491
        TAOS_UNUSED(taosThreadRwlockUnlock(&pDnode->data.lock));
×
492
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
493
      }
494
      TAOS_UNUSED(taosThreadRwlockUnlock(&pDnode->data.lock));
×
495
      TAOS_CHECK_GOTO(dmSyncEps(&pDnode->data), &lino, _exit);
×
496
    }
497
  } else if ((eInfo.type & 0x0F) == DM_ETYPE_UN) {  // not history version, but without DM_ENGINE_FILE, fail
18!
498
    dError("failed to init since inconsistent ver");
×
499
    TAOS_CHECK_GOTO(TSDB_CODE_VERSION_NOT_COMPATIBLE, &lino, _exit);
×
500
  } else if (pDnode->data.clusterId !=
18✔
501
             eInfo.clusterId) {  // not history version, DM_ENGINE_FILE exists, check clusterId
18!
502
    if (eInfo.clusterId == 0) {
×
503
      eInfo.dnodeId = pDnode->data.dnodeId;
×
504
      eInfo.engineVer = tsVersion;
×
505
      eInfo.clusterId = pDnode->data.clusterId;
×
506
      eInfo.updateMs = taosGetTimestampMs();
×
507
      (void)taosThreadRwlockWrlock(&pDnode->data.lock);
×
508
      if ((code = dmWriteVars(&eInfo)) != 0) {
×
509
        TAOS_UNUSED(taosThreadRwlockUnlock(&pDnode->data.lock));
×
510
        TAOS_CHECK_GOTO(code, &lino, _exit);
×
511
      }
512
      TAOS_UNUSED(taosThreadRwlockUnlock(&pDnode->data.lock));
×
513
      dInfo("update clusterId from 0 to %" PRId64, pDnode->data.clusterId);
×
514
    } else {
515
      dError("failed to init since inconsistent cluster:%" PRIi64 ",%" PRIi64, eInfo.clusterId, pDnode->data.clusterId);
×
516
      TAOS_CHECK_GOTO(TSDB_CODE_VERSION_NOT_COMPATIBLE, &lino, _exit);
×
517
    }
518
  } else if (pDnode->data.engineVer != tsVersion) {  // update to latest engineVer
18!
519
    TAOS_CHECK_GOTO(dmSyncEps(&pDnode->data), &lino, _exit);
×
520
  }
521

522
  if (eType == DM_ETYPE_OS) {        // oss
18!
523
    if (eInfo.type > DM_ETYPE_OS) {  // enterprise to oss not allowed
×
524
      dError("failed to init since incompatible ver");
×
525
      TAOS_CHECK_GOTO(TSDB_CODE_VERSION_NOT_COMPATIBLE, &lino, _exit);
×
526
    }
527
  } else if (eInfo.type == DM_ETYPE_OS) {  // update oss to enterprise
18✔
528
    eInfo.type = eType;
1✔
529
    eInfo.engineVer = tsVersion;
1✔
530
    eInfo.updateMs = taosGetTimestampMs();
1✔
531
    (void)taosThreadRwlockWrlock(&pDnode->data.lock);
1✔
532
    if ((code = dmWriteVars(&eInfo)) != 0) {
1!
533
      TAOS_UNUSED(taosThreadRwlockUnlock(&pDnode->data.lock));
×
534
      TAOS_CHECK_GOTO(code, &lino, _exit);
×
535
    }
536
    TAOS_UNUSED(taosThreadRwlockUnlock(&pDnode->data.lock));
1✔
537
  }
538

539
_exit:
17✔
540
  if (code != 0) {
127!
541
    dError("failed to init version at line %d since %s", lino, tstrerror(code));
×
542
  }
543
  TAOS_RETURN(code);
127✔
544
#else
545
  TAOS_RETURN(0);
546
#endif
547
}
548

549
static int32_t dmSyncEps(SDnodeData *pData) {
×
550
  int32_t code = 0;
×
551
  char    file[PATH_MAX] = "\0";
×
552
  (void)snprintf(file, sizeof(file), "%s%sdnode%sdnode.json", tsDataDir, TD_DIRSEP, TD_DIRSEP);
×
553
  (void)taosThreadRwlockWrlock(&pData->lock);
×
554
  bool fileExist = !(taosStatFile(file, NULL, NULL, NULL) < 0);
×
555
  if (fileExist) {
×
556
    code = dmWriteEps(pData);
×
557
  }
558
  TAOS_UNUSED(taosThreadRwlockUnlock(&pData->lock));
×
559
  TAOS_RETURN(code);
×
560
}
561

562
// invoker
563
int32_t dmInitModule(SDnode *pDnode) {
127✔
564
  int32_t code = 0;
127✔
565
  int32_t lino = 0;
127✔
566

567
#ifdef _TD_DM_CHECK_OFFSET
568
  TAOS_CHECK_GOTO(dmCheckOffset(pDnode), &lino, _exit);
127!
569
#endif
570

571
  TAOS_CHECK_GOTO(dmInitPrerequisites(), &lino, _exit);
127!
572

573
  if (dmInitVersion(pDnode) != 0) {
127!
574
    TAOS_CHECK_GOTO(TSDB_CODE_VERSION_NOT_COMPATIBLE, &lino, _exit);
×
575
  }
576

577
  TAOS_CHECK_GOTO(dmInitMsgHandle(pDnode), &lino, _exit);
127!
578

579
  TAOS_CHECK_GOTO(dmInitServer(pDnode), &lino, _exit);
127!
580

581
  TAOS_CHECK_GOTO(dmInitClient(pDnode), &lino, _exit);
127!
582

583
_exit:
127✔
584
  if (code != 0) {
127!
585
    dError("failed to init module at line %d since %s", lino, tstrerror(code));
×
586
  }
587

588
  TAOS_RETURN(code);
127✔
589
}
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