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

taosdata / TDengine / #4822

27 Oct 2025 05:42AM UTC coverage: 59.732% (+1.0%) from 58.728%
#4822

push

travis-ci

web-flow
Merge pull request #33377 from taosdata/fix/main/rename-udf-path

fix: update UDF example links to correct file paths

121214 of 258518 branches covered (46.89%)

Branch coverage included in aggregate %.

193636 of 268583 relevant lines covered (72.1%)

4002399.5 hits per line

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

63.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) {
13,192✔
23
  int32_t num = 0;
13,192✔
24
  int32_t size = taosHashGetSize(pMgmt->runngingHash);
13,192✔
25
  int32_t closedSize = taosHashGetSize(pMgmt->closedHash);
13,192✔
26
  size += closedSize;
13,192✔
27
  SVnodeObj **pVnodes = taosMemoryCalloc(size, sizeof(SVnodeObj *));
13,192!
28
  if (pVnodes == NULL) {
13,192!
29
    return terrno;
×
30
  }
31

32
  void *pIter = taosHashIterate(pMgmt->runngingHash, NULL);
13,192✔
33
  while (pIter) {
64,023✔
34
    SVnodeObj **ppVnode = pIter;
50,831✔
35
    SVnodeObj  *pVnode = *ppVnode;
50,831✔
36
    if (pVnode && num < size) {
101,662!
37
      int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1);
50,831✔
38
      dTrace("vgId:%d,acquire vnode, vnode:%p, ref:%d", pVnode->vgId, pVnode, refCount);
50,831✔
39
      pVnodes[num++] = (*ppVnode);
50,831✔
40
      pIter = taosHashIterate(pMgmt->runngingHash, pIter);
50,831✔
41
    } else {
42
      taosHashCancelIterate(pMgmt->runngingHash, pIter);
×
43
    }
44
  }
45

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

60
  *numOfVnodes = num;
13,192✔
61
  *ppVnodes = pVnodes;
13,192✔
62

63
  return 0;
13,192✔
64
}
65

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

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

79
  void *pIter = taosHashIterate(pMgmt->runngingHash, NULL);
6,896✔
80
  while (pIter) {
20,098✔
81
    SVnodeObj **ppVnode = pIter;
13,202✔
82
    SVnodeObj  *pVnode = *ppVnode;
13,202✔
83
    if (pVnode && num < size) {
26,404!
84
      int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1);
13,202✔
85
      dTrace("vgId:%d,acquire vnode, vnode:%p, ref:%d", pVnode->vgId, pVnode, refCount);
13,202✔
86
      pVnodes[num++] = (*ppVnode);
13,202✔
87
      pIter = taosHashIterate(pMgmt->runngingHash, pIter);
13,202✔
88
    } else {
89
      taosHashCancelIterate(pMgmt->runngingHash, pIter);
×
90
    }
91
  }
92

93
  pIter = taosHashIterate(pMgmt->creatingHash, NULL);
6,896✔
94
  while (pIter) {
16,830✔
95
    SVnodeObj **ppVnode = pIter;
9,934✔
96
    SVnodeObj  *pVnode = *ppVnode;
9,934✔
97
    if (pVnode && num < size) {
19,868!
98
      int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1);
9,934✔
99
      dTrace("vgId:%d, acquire vnode, vnode:%p, ref:%d", pVnode->vgId, pVnode, refCount);
9,934✔
100
      pVnodes[num++] = (*ppVnode);
9,934✔
101
      pIter = taosHashIterate(pMgmt->creatingHash, pIter);
9,934✔
102
    } else {
103
      taosHashCancelIterate(pMgmt->creatingHash, pIter);
×
104
    }
105
  }
106
  (void)taosThreadRwlockUnlock(&pMgmt->hashLock);
6,896✔
107

108
  *numOfVnodes = num;
6,896✔
109
  *ppVnodes = pVnodes;
6,896✔
110

111
  return 0;
6,896✔
112
}
113

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

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

125
  void *pIter = taosHashIterate(pMgmt->runngingHash, NULL);
5,840✔
126
  while (pIter) {
19,477✔
127
    SVnodeObj **ppVnode = pIter;
13,637✔
128
    SVnodeObj  *pVnode = *ppVnode;
13,637✔
129
    if (pVnode && num < size) {
27,274!
130
      int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1);
13,637✔
131
      dTrace("vgId:%d, acquire vnode, vnode:%p, ref:%d", pVnode->vgId, pVnode, refCount);
13,637✔
132
      pVnodes[num++] = (*ppVnode);
13,637✔
133
      pIter = taosHashIterate(pMgmt->runngingHash, pIter);
13,637✔
134
    } else {
135
      taosHashCancelIterate(pMgmt->runngingHash, pIter);
×
136
    }
137
  }
138

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

143
  return 0;
5,840✔
144
}
145

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

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

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

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

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

180
    snprintf(pCfg->path, sizeof(pCfg->path), "%s%svnode%d", pMgmt->path, TD_DIRSEP, pCfg->vgId);
1,153✔
181
  }
182

183
  code = 0;
319✔
184
  *ppCfgs = pCfgs;
319✔
185
  *numOfVnodes = vnodesNum;
319✔
186

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

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

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

208
  pFile = taosOpenFile(file, TD_FILE_READ);
319✔
209
  if (pFile == NULL) {
319!
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;
319✔
216
  code = taosFStatFile(pFile, &size, NULL);
319✔
217
  if (code != 0) {
319!
218
    dError("failed to fstat vnode file:%s since %s", file, tstrerror(code));
×
219
    goto _OVER;
×
220
  }
221

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

228
  if (taosReadFile(pFile, pData, size) != size) {
319!
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';
319✔
235

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

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

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

250
_OVER:
×
251
  if (pData != NULL) taosMemoryFree(pData);
319!
252
  if (pJson != NULL) cJSON_Delete(pJson);
319!
253
  if (pFile != NULL) taosCloseFile(&pFile);
319!
254

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

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

272
  for (int32_t i = 0; i < numOfVnodes; ++i) {
64,128✔
273
    SVnodeObj *pVnode = ppVnodes[i];
50,936✔
274
    if (pVnode == NULL) continue;
50,936!
275

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

291
  return 0;
13,192✔
292
}
293

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

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

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

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

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

327
  buffer = tjsonToString(pJson);
13,192✔
328
  if (buffer == NULL) {
13,192!
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);
13,192✔
336
  if (pFile == NULL) {
13,192!
337
    code = terrno;
×
338
    lino = __LINE__;
×
339
    goto _OVER;
×
340
  }
341

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

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

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

364
_OVER:
×
365
  (void)taosThreadRwlockUnlock(&pMgmt->hashLock);
13,192✔
366

367
  if (pJson != NULL) tjsonDelete(pJson);
13,192!
368
  if (buffer != NULL) taosMemoryFree(buffer);
13,192!
369
  if (pFile != NULL) taosCloseFile(&pFile);
13,192!
370
  if (ppVnodes != NULL) {
13,192!
371
    for (int32_t i = 0; i < numOfVnodes; ++i) {
64,128✔
372
      SVnodeObj *pVnode = ppVnodes[i];
50,936✔
373
      if (pVnode != NULL) {
50,936!
374
        vmReleaseVnode(pMgmt, pVnode);
50,936✔
375
      }
376
    }
377
    taosMemoryFree(ppVnodes);
13,192!
378
  }
379

380
  if (code != 0) {
13,192!
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;
13,192✔
385
}
386

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

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

401
  for (int32_t i = 0; i < mountsNum; ++i) {
5✔
402
    SJson *mount = tjsonGetArrayItem(mounts, i);
2✔
403
    TSDB_CHECK_NULL(mount, code, lino, _exit, TSDB_CODE_INVALID_JSON_FORMAT);
2!
404
    SMountCfg *pCfg = &pCfgs[i];
2✔
405
    TAOS_CHECK_EXIT(tjsonGetBigIntValue(mount, "mountId", &pCfg->mountId));
2!
406
    TAOS_CHECK_EXIT(tjsonGetStringValue2(mount, "name", pCfg->name, sizeof(pCfg->name)));
2!
407
    TAOS_CHECK_EXIT(tjsonGetStringValue2(mount, "path", pCfg->path, sizeof(pCfg->path)));
2!
408
  }
409
_exit:
3✔
410
  if (code) {
3!
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
  }
417
  *numOfMounts = mountsNum;
3✔
418
  *ppCfgs = pCfgs;
3✔
419
  return code;
3✔
420
}
421

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

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

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

461
  if ((numOfMounts = taosHashGetSize(pTfsHash)) < 0) {
10!
462
    goto _exit;
×
463
  }
464
  TSDB_CHECK_NULL((mounts = tjsonCreateArray()), code, lino, _exit, terrno);
10!
465
  if ((code = tjsonAddItemToObject(pJson, "mounts", mounts))) {
10!
466
    tjsonDelete(mounts);
×
467
    TAOS_CHECK_EXIT(code);
×
468
  }
469
  size_t keyLen = sizeof(int64_t);
10✔
470
  while ((pTfs = taosHashIterate(pTfsHash, pTfs))) {
18✔
471
    TSDB_CHECK_NULL((mount = tjsonCreateObject()), code, lino, _exit, terrno);
8!
472
    if (!mount) TAOS_CHECK_EXIT(terrno);
8!
473
    int64_t mountId = *(int64_t *)taosHashGetKey(pTfs, NULL);
8✔
474
    TAOS_CHECK_EXIT(tjsonAddIntegerToObject(mount, "mountId", mountId));
8!
475
    TAOS_CHECK_EXIT(tjsonAddStringToObject(mount, "name", (*(SMountTfs **)pTfs)->name));
8!
476
    TAOS_CHECK_EXIT(tjsonAddStringToObject(mount, "path", (*(SMountTfs **)pTfs)->path));
8!
477
    TAOS_CHECK_EXIT(tjsonAddItemToArray(mounts, mount));
8!
478
    mount = NULL;
8✔
479
  }
480
_exit:
10✔
481
  if (code != 0) {
10!
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
  }
486
  TAOS_RETURN(code);
10✔
487
}
488
#endif
489

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

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

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

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