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

taosdata / TDengine / #4488

12 Jul 2025 07:47AM UTC coverage: 62.207% (-0.7%) from 62.948%
#4488

push

travis-ci

web-flow
docs: update stream docs (#31822)

157961 of 324087 branches covered (48.74%)

Branch coverage included in aggregate %.

244465 of 322830 relevant lines covered (75.73%)

6561668.76 hits per line

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

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

32
  void *pIter = taosHashIterate(pMgmt->runngingHash, NULL);
20,545✔
33
  while (pIter) {
94,388✔
34
    SVnodeObj **ppVnode = pIter;
73,843✔
35
    SVnodeObj  *pVnode = *ppVnode;
73,843✔
36
    if (pVnode && num < size) {
147,686!
37
      int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1);
73,843✔
38
      dTrace("vgId:%d,acquire vnode, vnode:%p, ref:%d", pVnode->vgId, pVnode, refCount);
73,843✔
39
      pVnodes[num++] = (*ppVnode);
73,843✔
40
      pIter = taosHashIterate(pMgmt->runngingHash, pIter);
73,843✔
41
    } else {
42
      taosHashCancelIterate(pMgmt->runngingHash, pIter);
×
43
    }
44
  }
45

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

60
  *numOfVnodes = num;
20,545✔
61
  *ppVnodes = pVnodes;
20,545✔
62

63
  return 0;
20,545✔
64
}
65

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

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

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

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

108
  *numOfVnodes = num;
11,249✔
109
  *ppVnodes = pVnodes;
11,249✔
110

111
  return 0;
11,249✔
112
}
113

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

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

125
  void *pIter = taosHashIterate(pMgmt->runngingHash, NULL);
8,684✔
126
  while (pIter) {
24,448✔
127
    SVnodeObj **ppVnode = pIter;
15,764✔
128
    SVnodeObj  *pVnode = *ppVnode;
15,764✔
129
    if (pVnode && num < size) {
31,528!
130
      int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1);
15,764✔
131
      dTrace("vgId:%d, acquire vnode, vnode:%p, ref:%d", pVnode->vgId, pVnode, refCount);
15,764✔
132
      pVnodes[num++] = (*ppVnode);
15,764✔
133
      pIter = taosHashIterate(pMgmt->runngingHash, pIter);
15,764✔
134
    } else {
135
      taosHashCancelIterate(pMgmt->runngingHash, pIter);
×
136
    }
137
  }
138

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

143
  return 0;
8,684✔
144
}
145

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

272
  for (int32_t i = 0; i < numOfVnodes; ++i) {
94,391✔
273
    SVnodeObj *pVnode = ppVnodes[i];
73,846✔
274
    if (pVnode == NULL) continue;
73,846!
275

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

291
  return 0;
20,545✔
292
}
293

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

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

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

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

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

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

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

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

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

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

367
  if (pJson != NULL) tjsonDelete(pJson);
20,545!
368
  if (buffer != NULL) taosMemoryFree(buffer);
20,545!
369
  if (pFile != NULL) taosCloseFile(&pFile);
20,545!
370
  if (ppVnodes != NULL) {
20,545!
371
    for (int32_t i = 0; i < numOfVnodes; ++i) {
94,391✔
372
      SVnodeObj *pVnode = ppVnodes[i];
73,846✔
373
      if (pVnode != NULL) {
73,846!
374
        vmReleaseVnode(pMgmt, pVnode);
73,846✔
375
      }
376
    }
377
    taosMemoryFree(ppVnodes);
20,545!
378
  }
379

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

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

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

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

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

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

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

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

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

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

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

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

629
#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