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

taosdata / TDengine / #4829

30 Oct 2025 09:25AM UTC coverage: 49.734% (-11.3%) from 61.071%
#4829

push

travis-ci

web-flow
Merge pull request #33435 from taosdata/3.0

merge 3.0

123072 of 323930 branches covered (37.99%)

Branch coverage included in aggregate %.

7 of 25 new or added lines in 3 files covered. (28.0%)

35232 existing lines in 327 files now uncovered.

172062 of 269495 relevant lines covered (63.85%)

70709785.06 hits per line

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

37.98
/source/dnode/mgmt/mgmt_vnode/src/vmFile.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 "tjson.h"
18
#include "vmInt.h"
19

20
#define MAX_CONTENT_LEN 2 * 1024 * 1024
21

22
int32_t vmGetAllVnodeListFromHash(SVnodeMgmt *pMgmt, int32_t *numOfVnodes, SVnodeObj ***ppVnodes) {
1,021,745✔
23
  int32_t num = 0;
1,021,745✔
24
  int32_t size = taosHashGetSize(pMgmt->runngingHash);
1,021,745✔
25
  int32_t closedSize = taosHashGetSize(pMgmt->closedHash);
1,021,745✔
26
  size += closedSize;
1,021,745✔
27
  SVnodeObj **pVnodes = taosMemoryCalloc(size, sizeof(SVnodeObj *));
1,021,745!
28
  if (pVnodes == NULL) {
1,021,745!
29
    return terrno;
×
30
  }
31

32
  void *pIter = taosHashIterate(pMgmt->runngingHash, NULL);
1,021,745✔
33
  while (pIter) {
5,322,400✔
34
    SVnodeObj **ppVnode = pIter;
4,300,655✔
35
    SVnodeObj  *pVnode = *ppVnode;
4,300,655✔
36
    if (pVnode && num < size) {
8,601,310!
37
      int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1);
4,300,655✔
38
      dTrace("vgId:%d,acquire vnode, vnode:%p, ref:%d", pVnode->vgId, pVnode, refCount);
4,300,655✔
39
      pVnodes[num++] = (*ppVnode);
4,300,655✔
40
      pIter = taosHashIterate(pMgmt->runngingHash, pIter);
4,300,655✔
41
    } else {
42
      taosHashCancelIterate(pMgmt->runngingHash, pIter);
×
43
    }
44
  }
45

46
  pIter = taosHashIterate(pMgmt->closedHash, NULL);
1,021,745✔
47
  while (pIter) {
1,043,843✔
48
    SVnodeObj **ppVnode = pIter;
22,098✔
49
    SVnodeObj  *pVnode = *ppVnode;
22,098✔
50
    if (pVnode && num < size) {
44,196!
51
      int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1);
22,098✔
52
      dTrace("vgId:%d, acquire vnode, vnode:%p, ref:%d", pVnode->vgId, pVnode, refCount);
22,098!
53
      pVnodes[num++] = (*ppVnode);
22,098✔
54
      pIter = taosHashIterate(pMgmt->closedHash, pIter);
22,098✔
55
    } else {
56
      taosHashCancelIterate(pMgmt->closedHash, pIter);
×
57
    }
58
  }
59

60
  *numOfVnodes = num;
1,021,745✔
61
  *ppVnodes = pVnodes;
1,021,745✔
62

63
  return 0;
1,021,745✔
64
}
65

66
int32_t vmGetAllVnodeListFromHashWithCreating(SVnodeMgmt *pMgmt, int32_t *numOfVnodes, SVnodeObj ***ppVnodes) {
560,183✔
67
  (void)taosThreadRwlockRdlock(&pMgmt->hashLock);
560,183✔
68

69
  int32_t num = 0;
560,183✔
70
  int32_t size = taosHashGetSize(pMgmt->runngingHash);
560,183✔
71
  int32_t creatingSize = taosHashGetSize(pMgmt->creatingHash);
560,183✔
72
  size += creatingSize;
560,183✔
73
  SVnodeObj **pVnodes = taosMemoryCalloc(size, sizeof(SVnodeObj *));
560,183!
74
  if (pVnodes == NULL) {
560,183!
75
    (void)taosThreadRwlockUnlock(&pMgmt->hashLock);
×
76
    return terrno;
×
77
  }
78

79
  void *pIter = taosHashIterate(pMgmt->runngingHash, NULL);
560,183✔
80
  while (pIter) {
1,703,446✔
81
    SVnodeObj **ppVnode = pIter;
1,143,263✔
82
    SVnodeObj  *pVnode = *ppVnode;
1,143,263✔
83
    if (pVnode && num < size) {
2,286,526!
84
      int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1);
1,143,263✔
85
      dTrace("vgId:%d,acquire vnode, vnode:%p, ref:%d", pVnode->vgId, pVnode, refCount);
1,143,263✔
86
      pVnodes[num++] = (*ppVnode);
1,143,263✔
87
      pIter = taosHashIterate(pMgmt->runngingHash, pIter);
1,143,263✔
88
    } else {
89
      taosHashCancelIterate(pMgmt->runngingHash, pIter);
×
90
    }
91
  }
92

93
  pIter = taosHashIterate(pMgmt->creatingHash, NULL);
560,183✔
94
  while (pIter) {
1,699,264✔
95
    SVnodeObj **ppVnode = pIter;
1,139,081✔
96
    SVnodeObj  *pVnode = *ppVnode;
1,139,081✔
97
    if (pVnode && num < size) {
2,278,162!
98
      int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1);
1,139,081✔
99
      dTrace("vgId:%d, acquire vnode, vnode:%p, ref:%d", pVnode->vgId, pVnode, refCount);
1,139,081✔
100
      pVnodes[num++] = (*ppVnode);
1,139,081✔
101
      pIter = taosHashIterate(pMgmt->creatingHash, pIter);
1,139,081✔
102
    } else {
103
      taosHashCancelIterate(pMgmt->creatingHash, pIter);
×
104
    }
105
  }
106
  (void)taosThreadRwlockUnlock(&pMgmt->hashLock);
560,183✔
107

108
  *numOfVnodes = num;
560,183✔
109
  *ppVnodes = pVnodes;
560,183✔
110

111
  return 0;
560,183✔
112
}
113

114
int32_t vmGetVnodeListFromHash(SVnodeMgmt *pMgmt, int32_t *numOfVnodes, SVnodeObj ***ppVnodes) {
504,475✔
115
  (void)taosThreadRwlockRdlock(&pMgmt->hashLock);
504,475✔
116

117
  int32_t     num = 0;
504,475✔
118
  int32_t     size = taosHashGetSize(pMgmt->runngingHash);
504,475✔
119
  SVnodeObj **pVnodes = taosMemoryCalloc(size, sizeof(SVnodeObj *));
504,475!
120
  if (pVnodes == NULL) {
504,475!
121
    (void)taosThreadRwlockUnlock(&pMgmt->hashLock);
×
122
    return terrno;
×
123
  }
124

125
  void *pIter = taosHashIterate(pMgmt->runngingHash, NULL);
504,475✔
126
  while (pIter) {
1,970,938✔
127
    SVnodeObj **ppVnode = pIter;
1,466,463✔
128
    SVnodeObj  *pVnode = *ppVnode;
1,466,463✔
129
    if (pVnode && num < size) {
2,932,926!
130
      int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1);
1,466,463✔
131
      dTrace("vgId:%d, acquire vnode, vnode:%p, ref:%d", pVnode->vgId, pVnode, refCount);
1,466,463✔
132
      pVnodes[num++] = (*ppVnode);
1,466,463✔
133
      pIter = taosHashIterate(pMgmt->runngingHash, pIter);
1,466,463✔
134
    } else {
135
      taosHashCancelIterate(pMgmt->runngingHash, pIter);
×
136
    }
137
  }
138

139
  (void)taosThreadRwlockUnlock(&pMgmt->hashLock);
504,475✔
140
  *numOfVnodes = num;
504,475✔
141
  *ppVnodes = pVnodes;
504,475✔
142

143
  return 0;
504,475✔
144
}
145

146
static int32_t vmDecodeVnodeList(SJson *pJson, SVnodeMgmt *pMgmt, SWrapperCfg **ppCfgs, int32_t *numOfVnodes) {
29,874✔
147
  int32_t      code = -1;
29,874✔
148
  SWrapperCfg *pCfgs = NULL;
29,874✔
149
  *ppCfgs = NULL;
29,874✔
150

151
  SJson *vnodes = tjsonGetObjectItem(pJson, "vnodes");
29,874✔
152
  if (vnodes == NULL) return TSDB_CODE_INVALID_JSON_FORMAT;
29,874!
153

154
  int32_t vnodesNum = cJSON_GetArraySize(vnodes);
29,874✔
155
  if (vnodesNum > 0) {
29,874!
156
    pCfgs = taosMemoryCalloc(vnodesNum, sizeof(SWrapperCfg));
29,874!
157
    if (pCfgs == NULL) return terrno;
29,874!
158
  }
159

160
  for (int32_t i = 0; i < vnodesNum; ++i) {
147,430✔
161
    SJson *vnode = tjsonGetArrayItem(vnodes, i);
117,556✔
162
    if (vnode == NULL) {
117,556!
163
      code = TSDB_CODE_INVALID_JSON_FORMAT;
×
164
      goto _OVER;
×
165
    }
166

167
    SWrapperCfg *pCfg = &pCfgs[i];
117,556✔
168
    tjsonGetInt32ValueFromDouble(vnode, "vgId", pCfg->vgId, code);
117,556!
169
    if (code != 0) goto _OVER;
117,556!
170
    tjsonGetInt32ValueFromDouble(vnode, "dropped", pCfg->dropped, code);
117,556!
171
    if (code != 0) goto _OVER;
117,556!
172
    tjsonGetInt32ValueFromDouble(vnode, "vgVersion", pCfg->vgVersion, code);
117,556!
173
    if (code != 0) goto _OVER;
117,556!
174
    tjsonGetInt32ValueFromDouble(vnode, "diskPrimary", pCfg->diskPrimary, code);
117,556!
175
    if (code != 0) goto _OVER;
117,556!
176
    tjsonGetInt32ValueFromDouble(vnode, "toVgId", pCfg->toVgId, code);
117,556!
177
    if (code != 0) goto _OVER;
117,556!
178
    if ((code = tjsonGetBigIntValue(vnode, "mountId", &pCfg->mountId)) != 0) goto _OVER;
117,556!
179

180
    snprintf(pCfg->path, sizeof(pCfg->path), "%s%svnode%d", pMgmt->path, TD_DIRSEP, pCfg->vgId);
117,556!
181
  }
182

183
  code = 0;
29,874✔
184
  *ppCfgs = pCfgs;
29,874✔
185
  *numOfVnodes = vnodesNum;
29,874✔
186

187
_OVER:
29,874✔
188
  if (*ppCfgs == NULL) taosMemoryFree(pCfgs);
29,874!
189
  return code;
29,874✔
190
}
191

192
int32_t vmGetVnodeListFromFile(SVnodeMgmt *pMgmt, SWrapperCfg **ppCfgs, int32_t *numOfVnodes) {
141,232✔
193
  int32_t      code = -1;
141,232✔
194
  TdFilePtr    pFile = NULL;
141,232✔
195
  char        *pData = NULL;
141,232✔
196
  SJson       *pJson = NULL;
141,232✔
197
  char         file[PATH_MAX] = {0};
141,232✔
198
  SWrapperCfg *pCfgs = NULL;
141,232✔
199
  snprintf(file, sizeof(file), "%s%svnodes.json", pMgmt->path, TD_DIRSEP);
141,232!
200

201
  if (taosStatFile(file, NULL, NULL, NULL) < 0) {
141,232✔
202
    code = terrno;
111,358✔
203
    dInfo("vnode file:%s not exist, reason:%s", file, tstrerror(code));
111,358!
204
    code = 0;
111,358✔
205
    return code;
111,358✔
206
  }
207

208
  pFile = taosOpenFile(file, TD_FILE_READ);
29,874✔
209
  if (pFile == NULL) {
29,874!
210
    code = terrno;
×
211
    dError("failed to open vnode file:%s since %s", file, tstrerror(code));
×
212
    goto _OVER;
×
213
  }
214

215
  int64_t size = 0;
29,874✔
216
  code = taosFStatFile(pFile, &size, NULL);
29,874✔
217
  if (code != 0) {
29,874!
218
    dError("failed to fstat vnode file:%s since %s", file, tstrerror(code));
×
219
    goto _OVER;
×
220
  }
221

222
  pData = taosMemoryMalloc(size + 1);
29,874!
223
  if (pData == NULL) {
29,874!
224
    code = terrno;
×
225
    goto _OVER;
×
226
  }
227

228
  if (taosReadFile(pFile, pData, size) != size) {
29,874!
229
    code = terrno;
×
230
    dError("failed to read vnode file:%s since %s", file, tstrerror(code));
×
231
    goto _OVER;
×
232
  }
233

234
  pData[size] = '\0';
29,874✔
235

236
  pJson = tjsonParse(pData);
29,874✔
237
  if (pJson == NULL) {
29,874!
238
    code = TSDB_CODE_INVALID_JSON_FORMAT;
×
239
    goto _OVER;
×
240
  }
241

242
  if (vmDecodeVnodeList(pJson, pMgmt, ppCfgs, numOfVnodes) < 0) {
29,874!
243
    code = TSDB_CODE_INVALID_JSON_FORMAT;
×
244
    goto _OVER;
×
245
  }
246

247
  code = 0;
29,874✔
248
  dInfo("succceed to read vnode file %s", file);
29,874!
249

250
_OVER:
29,874✔
251
  if (pData != NULL) taosMemoryFree(pData);
29,874!
252
  if (pJson != NULL) cJSON_Delete(pJson);
29,874!
253
  if (pFile != NULL) taosCloseFile(&pFile);
29,874!
254

255
  if (code != 0) {
29,874!
256
    dError("failed to read vnode file:%s since %s", file, tstrerror(code));
×
257
  }
258
  return code;
29,874✔
259
}
260

261
static int32_t vmEncodeVnodeList(SJson *pJson, SVnodeObj **ppVnodes, int32_t numOfVnodes) {
1,021,745✔
262
  int32_t code = 0;
1,021,745✔
263
  SJson  *vnodes = tjsonCreateArray();
1,021,745✔
264
  if (vnodes == NULL) {
1,021,745!
265
    return terrno;
×
266
  }
267
  if ((code = tjsonAddItemToObject(pJson, "vnodes", vnodes)) < 0) {
1,021,745!
268
    tjsonDelete(vnodes);
×
269
    return code;
×
270
  };
271

272
  for (int32_t i = 0; i < numOfVnodes; ++i) {
5,344,498✔
273
    SVnodeObj *pVnode = ppVnodes[i];
4,322,753✔
274
    if (pVnode == NULL) continue;
4,322,753!
275

276
    SJson *vnode = tjsonCreateObject();
4,322,753✔
277
    if (vnode == NULL) return terrno;
4,322,753!
278
    if ((code = tjsonAddDoubleToObject(vnode, "vgId", pVnode->vgId)) < 0) return code;
4,322,753!
279
    if ((code = tjsonAddDoubleToObject(vnode, "dropped", pVnode->dropped)) < 0) return code;
4,322,753!
280
    if ((code = tjsonAddDoubleToObject(vnode, "vgVersion", pVnode->vgVersion)) < 0) return code;
4,322,753!
281
    if ((code = tjsonAddDoubleToObject(vnode, "diskPrimary", pVnode->diskPrimary)) < 0) return code;
4,322,753!
282
    if (pVnode->toVgId) {
4,322,753✔
283
      if ((code = tjsonAddDoubleToObject(vnode, "toVgId", pVnode->toVgId)) < 0) return code;
536!
284
    }
285
    if (pVnode->mountId) {
4,322,753!
UNCOV
286
      if ((code = tjsonAddIntegerToObject(vnode, "mountId", pVnode->mountId)) < 0) return code;
×
287
    }
288
    if ((code = tjsonAddItemToArray(vnodes, vnode)) < 0) return code;
4,322,753!
289
  }
290

291
  return 0;
1,021,745✔
292
}
293

294
int32_t vmWriteVnodeListToFile(SVnodeMgmt *pMgmt) {
1,021,745✔
295
  int32_t     code = -1;
1,021,745✔
296
  char       *buffer = NULL;
1,021,745✔
297
  SJson      *pJson = NULL;
1,021,745✔
298
  TdFilePtr   pFile = NULL;
1,021,745✔
299
  SVnodeObj **ppVnodes = NULL;
1,021,745✔
300
  char        file[PATH_MAX] = {0};
1,021,745✔
301
  char        realfile[PATH_MAX] = {0};
1,021,345✔
302
  int32_t     lino = 0;
1,021,745✔
303
  int32_t     ret = -1;
1,021,745✔
304

305
  int32_t nBytes = snprintf(file, sizeof(file), "%s%svnodes_tmp.json", pMgmt->path, TD_DIRSEP);
1,021,745✔
306
  if (nBytes <= 0 || nBytes >= sizeof(file)) {
1,021,745!
307
    return TSDB_CODE_OUT_OF_RANGE;
×
308
  }
309

310
  nBytes = snprintf(realfile, sizeof(realfile), "%s%svnodes.json", pMgmt->path, TD_DIRSEP);
1,021,745✔
311
  if (nBytes <= 0 || nBytes >= sizeof(realfile)) {
1,021,745!
312
    return TSDB_CODE_OUT_OF_RANGE;
×
313
  }
314

315
  int32_t numOfVnodes = 0;
1,021,745✔
316
  (void)taosThreadRwlockWrlock(&pMgmt->hashLock);
1,021,745✔
317
  TAOS_CHECK_GOTO(vmGetAllVnodeListFromHash(pMgmt, &numOfVnodes, &ppVnodes), &lino, _OVER);
1,021,745!
318

319
  // terrno = TSDB_CODE_OUT_OF_MEMORY;
320
  pJson = tjsonCreateObject();
1,021,745✔
321
  if (pJson == NULL) {
1,021,745!
322
    code = terrno;
×
323
    goto _OVER;
×
324
  }
325
  TAOS_CHECK_GOTO(vmEncodeVnodeList(pJson, ppVnodes, numOfVnodes), &lino, _OVER);
1,021,745!
326

327
  buffer = tjsonToString(pJson);
1,021,745✔
328
  if (buffer == NULL) {
1,021,745!
329
    code = TSDB_CODE_INVALID_JSON_FORMAT;
×
330
    lino = __LINE__;
×
331
    goto _OVER;
×
332
  }
333

334

335
  pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
1,021,745✔
336
  if (pFile == NULL) {
1,021,745!
337
    code = terrno;
×
338
    lino = __LINE__;
×
339
    goto _OVER;
×
340
  }
341

342
  int32_t len = strlen(buffer);
1,021,745!
343
  if (taosWriteFile(pFile, buffer, len) <= 0) {
1,021,745!
344
    code = terrno;
×
345
    lino = __LINE__;
×
346
    goto _OVER;
×
347
  }
348
  if (taosFsyncFile(pFile) < 0) {
1,021,745!
349
    code = TAOS_SYSTEM_ERROR(ERRNO);
×
350
    lino = __LINE__;
×
351
    goto _OVER;
×
352
  }
353

354
  code = taosCloseFile(&pFile);
1,021,745✔
355
  if (code != 0) {
1,021,745!
356
    code = TAOS_SYSTEM_ERROR(ERRNO);
×
357
    lino = __LINE__;
×
358
    goto _OVER;
×
359
  }
360
  TAOS_CHECK_GOTO(taosRenameFile(file, realfile), &lino, _OVER);
1,021,745!
361

362
  dInfo("succeed to write vnodes file:%s, vnodes:%d", realfile, numOfVnodes);
1,021,745!
363

364
_OVER:
1,021,691✔
365
  (void)taosThreadRwlockUnlock(&pMgmt->hashLock);
1,021,745✔
366

367
  if (pJson != NULL) tjsonDelete(pJson);
1,021,745!
368
  if (buffer != NULL) taosMemoryFree(buffer);
1,021,745!
369
  if (pFile != NULL) taosCloseFile(&pFile);
1,021,745!
370
  if (ppVnodes != NULL) {
1,021,745!
371
    for (int32_t i = 0; i < numOfVnodes; ++i) {
5,344,498✔
372
      SVnodeObj *pVnode = ppVnodes[i];
4,322,753✔
373
      if (pVnode != NULL) {
4,322,753!
374
        vmReleaseVnode(pMgmt, pVnode);
4,322,753✔
375
      }
376
    }
377
    taosMemoryFree(ppVnodes);
1,021,745!
378
  }
379

380
  if (code != 0) {
1,021,745!
381
    dError("failed to write vnodes file:%s at line:%d since %s, vnodes:%d", realfile, lino, tstrerror(code),
×
382
           numOfVnodes);
383
  }
384
  return code;
1,021,745✔
385
}
386

387
#ifdef USE_MOUNT
UNCOV
388
static int32_t vmDecodeMountList(SJson *pJson, SVnodeMgmt *pMgmt, SMountCfg **ppCfgs, int32_t *numOfMounts) {
×
UNCOV
389
  int32_t    code = 0, lino = 0;
×
UNCOV
390
  int32_t    mountsNum = 0;
×
UNCOV
391
  SMountCfg *pCfgs = NULL;
×
UNCOV
392
  SJson     *mounts = NULL;
×
393

UNCOV
394
  if (!(mounts = tjsonGetObjectItem(pJson, "mounts"))) {
×
395
    goto _exit;
×
396
  }
UNCOV
397
  if ((mountsNum = cJSON_GetArraySize(mounts)) > 0) {
×
UNCOV
398
    TSDB_CHECK_NULL((pCfgs = taosMemoryMalloc(mountsNum * sizeof(SMountCfg))), code, lino, _exit, terrno);
×
399
  }
400

UNCOV
401
  for (int32_t i = 0; i < mountsNum; ++i) {
×
UNCOV
402
    SJson *mount = tjsonGetArrayItem(mounts, i);
×
UNCOV
403
    TSDB_CHECK_NULL(mount, code, lino, _exit, TSDB_CODE_INVALID_JSON_FORMAT);
×
UNCOV
404
    SMountCfg *pCfg = &pCfgs[i];
×
UNCOV
405
    TAOS_CHECK_EXIT(tjsonGetBigIntValue(mount, "mountId", &pCfg->mountId));
×
UNCOV
406
    TAOS_CHECK_EXIT(tjsonGetStringValue2(mount, "name", pCfg->name, sizeof(pCfg->name)));
×
UNCOV
407
    TAOS_CHECK_EXIT(tjsonGetStringValue2(mount, "path", pCfg->path, sizeof(pCfg->path)));
×
408
  }
UNCOV
409
_exit:
×
UNCOV
410
  if (code) {
×
411
    dError("failed to decode mount list at line %d since %s", lino, tstrerror(code));
×
412
    if (pCfgs) {
×
413
      taosMemoryFree(pCfgs);
×
414
      pCfgs = NULL;
×
415
    }
416
  }
UNCOV
417
  *numOfMounts = mountsNum;
×
UNCOV
418
  *ppCfgs = pCfgs;
×
UNCOV
419
  return code;
×
420
}
421

422
int32_t vmGetMountListFromFile(SVnodeMgmt *pMgmt, SMountCfg **ppCfgs, int32_t *numOfMounts) {
141,232✔
423
  int32_t    code = 0, lino = 0;
141,232✔
424
  int64_t    size = 0;
141,232✔
425
  TdFilePtr  pFile = NULL;
141,232✔
426
  char      *pData = NULL;
141,232✔
427
  SJson     *pJson = NULL;
141,232✔
428
  char       file[PATH_MAX] = {0};
141,232✔
429
  SMountCfg *pCfgs = NULL;
141,232✔
430
  snprintf(file, sizeof(file), "%s%smounts.json", pMgmt->path, TD_DIRSEP);
141,232✔
431

432
  if (!taosCheckExistFile(file)) goto _exit;
141,232!
UNCOV
433
  TAOS_CHECK_EXIT(taosStatFile(file, &size, NULL, NULL));
×
UNCOV
434
  TSDB_CHECK_NULL((pFile = taosOpenFile(file, TD_FILE_READ)), code, lino, _exit, terrno);
×
UNCOV
435
  TSDB_CHECK_NULL((pData = taosMemoryMalloc(size + 1)), code, lino, _exit, terrno);
×
UNCOV
436
  if (taosReadFile(pFile, pData, size) != size) {
×
437
    TAOS_CHECK_EXIT(terrno);
×
438
  }
UNCOV
439
  pData[size] = '\0';
×
UNCOV
440
  TSDB_CHECK_NULL((pJson = tjsonParse(pData)), code, lino, _exit, TSDB_CODE_INVALID_JSON_FORMAT);
×
UNCOV
441
  TAOS_CHECK_EXIT(vmDecodeMountList(pJson, pMgmt, ppCfgs, numOfMounts));
×
UNCOV
442
  dInfo("succceed to read mounts file %s", file);
×
443
_exit:
141,101✔
444
  if (pData != NULL) taosMemoryFree(pData);
141,232!
445
  if (pJson != NULL) cJSON_Delete(pJson);
141,232!
446
  if (pFile != NULL) taosCloseFile(&pFile);
141,232!
447
  if (code != 0) {
141,232!
448
    dError("failed to read mounts file:%s since %s", file, tstrerror(code));
×
449
  }
450
  return code;
141,232✔
451
}
452

UNCOV
453
static int32_t vmEncodeMountList(SVnodeMgmt *pMgmt, SJson *pJson) {
×
UNCOV
454
  int32_t    code = 0, lino = 0;
×
UNCOV
455
  SHashObj  *pTfsHash = pMgmt->mountTfsHash;
×
UNCOV
456
  int32_t    numOfMounts = 0;
×
UNCOV
457
  SJson     *mounts = NULL;
×
UNCOV
458
  SJson     *mount = NULL;
×
UNCOV
459
  SMountTfs *pTfs = NULL;
×
460

UNCOV
461
  if ((numOfMounts = taosHashGetSize(pTfsHash)) < 0) {
×
462
    goto _exit;
×
463
  }
UNCOV
464
  TSDB_CHECK_NULL((mounts = tjsonCreateArray()), code, lino, _exit, terrno);
×
UNCOV
465
  if ((code = tjsonAddItemToObject(pJson, "mounts", mounts))) {
×
466
    tjsonDelete(mounts);
×
467
    TAOS_CHECK_EXIT(code);
×
468
  }
UNCOV
469
  size_t keyLen = sizeof(int64_t);
×
UNCOV
470
  while ((pTfs = taosHashIterate(pTfsHash, pTfs))) {
×
UNCOV
471
    TSDB_CHECK_NULL((mount = tjsonCreateObject()), code, lino, _exit, terrno);
×
UNCOV
472
    if (!mount) TAOS_CHECK_EXIT(terrno);
×
UNCOV
473
    int64_t mountId = *(int64_t *)taosHashGetKey(pTfs, NULL);
×
UNCOV
474
    TAOS_CHECK_EXIT(tjsonAddIntegerToObject(mount, "mountId", mountId));
×
UNCOV
475
    TAOS_CHECK_EXIT(tjsonAddStringToObject(mount, "name", (*(SMountTfs **)pTfs)->name));
×
UNCOV
476
    TAOS_CHECK_EXIT(tjsonAddStringToObject(mount, "path", (*(SMountTfs **)pTfs)->path));
×
UNCOV
477
    TAOS_CHECK_EXIT(tjsonAddItemToArray(mounts, mount));
×
UNCOV
478
    mount = NULL;
×
479
  }
UNCOV
480
_exit:
×
UNCOV
481
  if (code != 0) {
×
482
    if (mount) tjsonDelete(mount);
×
483
    if (pTfs) taosHashCancelIterate(pTfsHash, pTfs);
×
484
    dError("failed to encode mount list at line %d since %s", lino, tstrerror(code));
×
485
  }
UNCOV
486
  TAOS_RETURN(code);
×
487
}
488
#endif
489

UNCOV
490
int32_t vmWriteMountListToFile(SVnodeMgmt *pMgmt) {
×
UNCOV
491
  int32_t     code = 0, lino = 0, ret = 0;
×
492
#ifdef USE_MOUNT
UNCOV
493
  char       *buffer = NULL;
×
UNCOV
494
  SJson      *pJson = NULL;
×
UNCOV
495
  TdFilePtr   pFile = NULL;
×
UNCOV
496
  SVnodeObj **ppVnodes = NULL;
×
UNCOV
497
  char        file[PATH_MAX] = {0};
×
UNCOV
498
  char        realfile[PATH_MAX] = {0};
×
UNCOV
499
  bool        unlock = false;
×
500

UNCOV
501
  int32_t nBytes = snprintf(file, sizeof(file), "%s%smounts_tmp.json", pMgmt->path, TD_DIRSEP);
×
UNCOV
502
  if (nBytes <= 0 || nBytes >= sizeof(file)) {
×
503
    TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_RANGE);
×
504
  }
UNCOV
505
  nBytes = snprintf(realfile, sizeof(realfile), "%s%smounts.json", pMgmt->path, TD_DIRSEP);
×
UNCOV
506
  if (nBytes <= 0 || nBytes >= sizeof(realfile)) {
×
507
    TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_RANGE);
×
508
  }
UNCOV
509
  TSDB_CHECK_NULL((pJson = tjsonCreateObject()), code, lino, _exit, terrno);
×
UNCOV
510
  TAOS_CHECK_EXIT(vmEncodeMountList(pMgmt, pJson));
×
UNCOV
511
  TSDB_CHECK_NULL((buffer = tjsonToString(pJson)), code, lino, _exit, terrno);
×
UNCOV
512
  TAOS_CHECK_EXIT(taosThreadMutexLock(&pMgmt->mutex));
×
UNCOV
513
  unlock = true;
×
UNCOV
514
  TSDB_CHECK_NULL((pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH)),
×
515
                  code, lino, _exit, terrno);
516

UNCOV
517
  int32_t len = strlen(buffer);
×
UNCOV
518
  if ((code = taosWriteFile(pFile, buffer, len)) <= 0) {
×
519
    TAOS_CHECK_EXIT(code);
×
520
  }
UNCOV
521
  TAOS_CHECK_EXIT(taosFsyncFile(pFile));
×
UNCOV
522
  TAOS_CHECK_EXIT(taosCloseFile(&pFile));
×
UNCOV
523
  TAOS_CHECK_EXIT(taosRenameFile(file, realfile));
×
UNCOV
524
  dInfo("succeed to write mounts file:%s", realfile);
×
UNCOV
525
_exit:
×
UNCOV
526
  if (unlock && (ret = taosThreadMutexUnlock(&pMgmt->mutex))) {
×
527
    dError("failed to unlock at line %d when write mounts file since %s", __LINE__, tstrerror(ret));
×
528
  }
UNCOV
529
  if (pJson) tjsonDelete(pJson);
×
UNCOV
530
  if (buffer) taosMemoryFree(buffer);
×
UNCOV
531
  if (pFile) taosCloseFile(&pFile);
×
UNCOV
532
  if (code != 0) {
×
533
    dError("failed to write mounts file:%s at line:%d since %s", realfile, lino, tstrerror(code));
×
534
  }
535
#endif
UNCOV
536
  TAOS_RETURN(code);
×
537
}
538
#ifdef USE_MOUNT
UNCOV
539
int32_t vmGetMountDisks(SVnodeMgmt *pMgmt, const char *mountPath, SArray **ppDisks) {
×
UNCOV
540
  int32_t   code = 0, lino = 0;
×
UNCOV
541
  SArray   *pDisks = NULL;
×
UNCOV
542
  TdFilePtr pFile = NULL;
×
UNCOV
543
  char     *content = NULL;
×
UNCOV
544
  SJson    *pJson = NULL;
×
UNCOV
545
  int64_t   size = 0;
×
UNCOV
546
  int64_t   clusterId = 0, dropped = 0, encryptScope = 0;
×
UNCOV
547
  char      file[TSDB_MOUNT_FPATH_LEN] = {0};
×
548

UNCOV
549
  (void)snprintf(file, sizeof(file), "%s%s%s%sconfig%s%s", mountPath, TD_DIRSEP, dmNodeName(DNODE), TD_DIRSEP,
×
550
                 TD_DIRSEP, "local.json");
UNCOV
551
  TAOS_CHECK_EXIT(taosStatFile(file, &size, NULL, NULL));
×
UNCOV
552
  TSDB_CHECK_NULL((pFile = taosOpenFile(file, TD_FILE_READ)), code, lino, _exit, terrno);
×
UNCOV
553
  TSDB_CHECK_NULL((content = taosMemoryMalloc(size + 1)), code, lino, _exit, terrno);
×
UNCOV
554
  if (taosReadFile(pFile, content, size) != size) {
×
555
    TAOS_CHECK_EXIT(terrno);
×
556
  }
UNCOV
557
  content[size] = '\0';
×
UNCOV
558
  pJson = tjsonParse(content);
×
UNCOV
559
  if (pJson == NULL) {
×
560
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_JSON_FORMAT);
×
561
  }
UNCOV
562
  SJson *pConfigs = tjsonGetObjectItem(pJson, "configs");
×
UNCOV
563
  if (pConfigs == NULL) {
×
564
    TAOS_CHECK_EXIT(TSDB_CODE_INVALID_JSON_FORMAT);
×
565
  }
UNCOV
566
  int32_t nDataDir = 0;
×
UNCOV
567
  SJson  *pDataDir = tjsonGetObjectItem(pConfigs, "dataDir");
×
UNCOV
568
  if (pDataDir) {
×
UNCOV
569
    nDataDir = tjsonGetArraySize(pDataDir);
×
570
  }
UNCOV
571
  if (!(pDisks = taosArrayInit_s(sizeof(SDiskCfg), nDataDir > 0 ? nDataDir : 1))) {
×
572
    TAOS_CHECK_EXIT(TSDB_CODE_OUT_OF_MEMORY);
×
573
  }
UNCOV
574
  for (int32_t i = 0; i < nDataDir; ++i) {
×
UNCOV
575
    char   dir[TSDB_MOUNT_PATH_LEN] = {0};
×
UNCOV
576
    SJson *pItem = tjsonGetArrayItem(pDataDir, i);
×
UNCOV
577
    if (pItem == NULL) {
×
578
      TAOS_CHECK_EXIT(TSDB_CODE_INVALID_JSON_FORMAT);
×
579
    }
UNCOV
580
    code = tjsonGetStringValue(pItem, "dir", dir);
×
UNCOV
581
    if (code < 0) {
×
582
      TAOS_CHECK_EXIT(TSDB_CODE_INVALID_JSON_FORMAT);
×
583
    }
UNCOV
584
    int32_t j = strlen(dir) - 1;
×
UNCOV
585
    while (j > 0 && (dir[j] == '/' || dir[j] == '\\')) {
×
586
      dir[j--] = '\0';  // remove trailing slashes
×
587
    }
UNCOV
588
    SJson *pLevel = tjsonGetObjectItem(pItem, "level");
×
UNCOV
589
    if (!pLevel) {
×
590
      TAOS_CHECK_EXIT(TSDB_CODE_INVALID_JSON_FORMAT);
×
591
    }
UNCOV
592
    int32_t level = (int32_t)cJSON_GetNumberValue(pLevel);
×
UNCOV
593
    if (level < 0 || level >= TFS_MAX_TIERS) {
×
594
      TAOS_CHECK_EXIT(TSDB_CODE_INVALID_JSON_FORMAT);
×
595
    }
UNCOV
596
    SJson *pPrimary = tjsonGetObjectItem(pItem, "primary");
×
UNCOV
597
    if (!pPrimary) {
×
598
      TAOS_CHECK_EXIT(TSDB_CODE_INVALID_JSON_FORMAT);
×
599
    }
UNCOV
600
    int32_t primary = (int32_t)cJSON_GetNumberValue(pPrimary);
×
UNCOV
601
    if ((primary < 0 || primary > 1) || (primary == 1 && level != 0)) {
×
602
      dError("mount:%s, invalid primary disk, primary:%d, level:%d", mountPath, primary, level);
×
603
      TAOS_CHECK_EXIT(TSDB_CODE_INVALID_JSON_FORMAT);
×
604
    }
UNCOV
605
    int8_t    disable = (int8_t)cJSON_GetNumberValue(pLevel);
×
UNCOV
606
    SDiskCfg *pDisk = taosArrayGet(pDisks, i);
×
UNCOV
607
    pDisk->level = level;
×
UNCOV
608
    pDisk->primary = primary;
×
UNCOV
609
    pDisk->disable = disable;
×
UNCOV
610
    if (primary == 1 && level == 0) {
×
UNCOV
611
      (void)snprintf(pDisk->dir, sizeof(pDisk->dir), "%s", mountPath);
×
612
    } else {
UNCOV
613
      (void)snprintf(pDisk->dir, sizeof(pDisk->dir), "%s", dir);
×
614
    }
615
  }
UNCOV
616
  if (nDataDir <= 0) {
×
617
    SDiskCfg *pDisk = taosArrayGet(pDisks, 0);
×
618
    pDisk->level = 0;
×
619
    pDisk->primary = 1;
×
620
    pDisk->disable = 0;
×
621
    (void)snprintf(pDisk->dir, sizeof(pDisk->dir), "%s", mountPath);
×
622
  }
UNCOV
623
_exit:
×
UNCOV
624
  if (content != NULL) taosMemoryFreeClear(content);
×
UNCOV
625
  if (pJson != NULL) cJSON_Delete(pJson);
×
UNCOV
626
  if (pFile != NULL) taosCloseFile(&pFile);
×
UNCOV
627
  if (code != 0) {
×
628
    dError("failed to get mount disks at line %d since %s, path:%s", lino, tstrerror(code), mountPath);
×
629
    taosArrayDestroy(pDisks);
×
630
    pDisks = NULL;
×
631
  }
UNCOV
632
  *ppDisks = pDisks;
×
UNCOV
633
  TAOS_RETURN(code);
×
634
}
635

636
#endif
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