vnodeMain.c 13.1 KB
Newer Older
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the GNU Affero General Public License, version 3
 * or later ("AGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#define _DEFAULT_SOURCE
#include "os.h"
#include "ihash.h"
#include "taoserror.h"
#include "taosmsg.h"
#include "tlog.h"
#include "trpc.h"
#include "tsdb.h"
#include "ttime.h"
#include "ttimer.h"
#include "twal.h"
J
Jeff Tao 已提交
27 28
#include "dnode.h"
#include "vnode.h"
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
29 30
#include "vnodeInt.h"

31
static int32_t  tsOpennedVnodes;
J
Jeff Tao 已提交
32 33 34 35 36 37 38 39 40 41 42
static void    *tsDnodeVnodesHash;
static void     vnodeCleanUp(SVnodeObj *pVnode);
static void     vnodeBuildVloadMsg(char *pNode, void * param);
static int      vnodeWalCallback(void *arg);
static int32_t  vnodeSaveCfg(SMDCreateVnodeMsg *pVnodeCfg);
static int32_t  vnodeReadCfg(SVnodeObj *pVnode);
static int      vnodeWalCallback(void *arg);
static uint32_t vnodeGetFileInfo(void *ahandle, char *name, uint32_t *index, int32_t *size);
static int      vnodeGetWalInfo(void *ahandle, char *name, uint32_t *index);
static void     vnodeNotifyRole(void *ahandle, int8_t role);

43
static pthread_once_t  vnodeModuleInit = PTHREAD_ONCE_INIT;
S
slguan 已提交
44 45 46 47 48 49

#ifndef _SYNC
tsync_h syncStart(const SSyncInfo *info) { return NULL; }
int     syncForwardToPeer(tsync_h shandle, void *pHead, void *mhandle) { return 0; }
#endif

50
static void vnodeInit() {
J
Jeff Tao 已提交
51
  vnodeInitWriteFp();
S
slguan 已提交
52
  vnodeInitReadFp();
J
Jeff Tao 已提交
53

54
  tsDnodeVnodesHash = taosInitIntHash(TSDB_MAX_VNODES, sizeof(SVnodeObj *), taosHashInt);
J
Jeff Tao 已提交
55 56 57 58
  if (tsDnodeVnodesHash == NULL) {
    dError("failed to init vnode list");
  }
}
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
59 60 61

int32_t vnodeCreate(SMDCreateVnodeMsg *pVnodeCfg) {
  int32_t code;
62
  pthread_once(&vnodeModuleInit, vnodeInit);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
63

64
  SVnodeObj *pTemp = (SVnodeObj *)taosGetIntHashData(tsDnodeVnodesHash, pVnodeCfg->cfg.vgId);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
65 66 67
  if (pTemp != NULL) {
    dPrint("vgId:%d, vnode already exist, pVnode:%p", pVnodeCfg->cfg.vgId, pTemp);
    return TSDB_CODE_SUCCESS;
68
  }
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
69 70 71 72 73 74 75 76 77 78 79 80 81 82

  char rootDir[TSDB_FILENAME_LEN] = {0};
  sprintf(rootDir, "%s/vnode%d", tsVnodeDir, pVnodeCfg->cfg.vgId);
  if (mkdir(rootDir, 0755) != 0) {
    if (errno == EACCES) {
      return TSDB_CODE_NO_DISK_PERMISSIONS;
    } else if (errno == ENOSPC) {
      return TSDB_CODE_SERV_NO_DISKSPACE;
    } else if (errno == EEXIST) {
    } else {
      return TSDB_CODE_VG_INIT_FAILED;
    }
  }

83 84 85 86 87 88
  code = vnodeSaveCfg(pVnodeCfg);
  if (code != TSDB_CODE_SUCCESS) {
    dError("vgId:%d, failed to save vnode cfg, reason:%s", pVnodeCfg->cfg.vgId, tstrerror(code));
    return code;
  }

S
slguan 已提交
89 90 91 92 93 94 95 96 97 98
  STsdbCfg tsdbCfg = {0};
  tsdbCfg.precision           = pVnodeCfg->cfg.precision;
  tsdbCfg.tsdbId              = pVnodeCfg->cfg.vgId;
  tsdbCfg.maxTables           = pVnodeCfg->cfg.maxSessions;
  tsdbCfg.daysPerFile         = pVnodeCfg->cfg.daysPerFile;
  tsdbCfg.minRowsPerFileBlock = -1;
  tsdbCfg.maxRowsPerFileBlock = -1;
  tsdbCfg.keep                = -1;
  tsdbCfg.maxCacheSize        = -1;

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
99 100 101
  char tsdbDir[TSDB_FILENAME_LEN] = {0};
  sprintf(tsdbDir, "%s/vnode%d/tsdb", tsVnodeDir, pVnodeCfg->cfg.vgId);
  code = tsdbCreateRepo(tsdbDir, &tsdbCfg, NULL);
102
  if (code != TSDB_CODE_SUCCESS) {
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
103
    dError("vgId:%d, failed to create tsdb in vnode, reason:%s", pVnodeCfg->cfg.vgId, tstrerror(terrno));
104
    return terrno;
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
105 106
  }

S
slguan 已提交
107
  dPrint("vgId:%d, vnode is created, clog:%d", pVnodeCfg->cfg.vgId, pVnodeCfg->cfg.commitLog);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
108 109 110 111 112 113
  code = vnodeOpen(pVnodeCfg->cfg.vgId, rootDir);

  return code;
}

int32_t vnodeDrop(int32_t vgId) {
114 115
  SVnodeObj **ppVnode = (SVnodeObj **)taosGetIntHashData(tsDnodeVnodesHash, vgId);
  if (ppVnode == NULL || *ppVnode == NULL) {
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
116 117 118 119
    dTrace("vgId:%d, failed to drop, vgId not exist", vgId);
    return TSDB_CODE_INVALID_VGROUP_ID;
  }

120
  SVnodeObj *pVnode = *ppVnode;
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
121
  dTrace("pVnode:%p vgId:%d, vnode will be dropped", pVnode, pVnode->vgId);
S
slguan 已提交
122
  pVnode->status = TAOS_VN_STATUS_DELETING;
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
123 124 125 126 127 128 129
  vnodeCleanUp(pVnode);
 
  return TSDB_CODE_SUCCESS;
}

int32_t vnodeOpen(int32_t vnode, char *rootDir) {
  char temp[TSDB_FILENAME_LEN];
130
  pthread_once(&vnodeModuleInit, vnodeInit);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
131

132 133
  SVnodeObj *pVnode = calloc(sizeof(SVnodeObj), 1);
  pVnode->vgId     = vnode;
S
slguan 已提交
134
  pVnode->status   = TAOS_VN_STATUS_INIT;
135 136 137
  pVnode->refCount = 1;
  pVnode->version  = 0;  
  taosAddIntHash(tsDnodeVnodesHash, pVnode->vgId, (char *)(&pVnode));
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
138

139 140 141 142 143 144 145
  int32_t code = vnodeReadCfg(pVnode);
  if (code != TSDB_CODE_SUCCESS) {
    dError("pVnode:%p vgId:%d, failed to read cfg file", pVnode, pVnode->vgId);
    taosDeleteIntHash(tsDnodeVnodesHash, pVnode->vgId);
    return code;
  }

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
146 147 148 149
  pVnode->wqueue = dnodeAllocateWqueue(pVnode);
  pVnode->rqueue = dnodeAllocateRqueue(pVnode);

  sprintf(temp, "%s/wal", rootDir);
J
Jeff Tao 已提交
150 151 152 153
  pVnode->wal      = walOpen(temp, &pVnode->walCfg);

  SSyncInfo syncInfo;
  syncInfo.vgId = pVnode->vgId;
J
Jeff Tao 已提交
154
  syncInfo.version = pVnode->version;
J
Jeff Tao 已提交
155 156 157 158 159 160 161 162
  syncInfo.syncCfg = pVnode->syncCfg;
  sprintf(syncInfo.path, "%s/tsdb/", rootDir);
  syncInfo.ahandle = pVnode;
  syncInfo.getWalInfo = vnodeGetWalInfo;
  syncInfo.getFileInfo = vnodeGetFileInfo;
  syncInfo.writeToCache = vnodeWriteToQueue;
  syncInfo.confirmForward = dnodeSendRpcWriteRsp; 
  syncInfo.notifyRole = vnodeNotifyRole;
S
slguan 已提交
163
  pVnode->sync     = syncStart(&syncInfo);
J
Jeff Tao 已提交
164

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
165 166 167
  pVnode->events   = NULL;
  pVnode->cq       = NULL;

H
hzcheng 已提交
168 169
  STsdbAppH appH = {0};
  appH.appH = (void *)pVnode;
J
Jeff Tao 已提交
170
  appH.walCallBack = vnodeWalCallback;
H
hzcheng 已提交
171 172 173 174 175 176 177 178 179 180 181

  sprintf(temp, "%s/tsdb", rootDir);
  void *pTsdb = tsdbOpenRepo(temp, &appH);
  if (pTsdb == NULL) {
    dError("pVnode:%p vgId:%d, failed to open tsdb at %s(%s)", pVnode, pVnode->vgId, temp, tstrerror(terrno));
    taosDeleteIntHash(tsDnodeVnodesHash, pVnode->vgId);
    return terrno;
  }

  pVnode->tsdb = pTsdb;

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
182 183
  walRestore(pVnode->wal, pVnode, vnodeWriteToQueue);

S
slguan 已提交
184
  pVnode->status = TAOS_VN_STATUS_READY;
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
185 186
  dTrace("pVnode:%p vgId:%d, vnode is opened in %s", pVnode, pVnode->vgId, rootDir);

J
Jeff Tao 已提交
187
  atomic_add_fetch_32(&tsOpennedVnodes, 1);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
188 189 190
  return TSDB_CODE_SUCCESS;
}

191
int32_t vnodeClose(int32_t vgId) {
192 193
  SVnodeObj **ppVnode = (SVnodeObj **)taosGetIntHashData(tsDnodeVnodesHash, vgId);
  if (ppVnode == NULL || *ppVnode == NULL) return 0;
194

195
  SVnodeObj *pVnode = *ppVnode;
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
196
  dTrace("pVnode:%p vgId:%d, vnode will be closed", pVnode, pVnode->vgId);
S
slguan 已提交
197
  pVnode->status = TAOS_VN_STATUS_CLOSING;
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
198 199 200 201 202 203 204
  vnodeCleanUp(pVnode);

  return 0;
}

void vnodeRelease(void *pVnodeRaw) {
  SVnodeObj *pVnode = pVnodeRaw;
205
  int32_t    vgId = pVnode->vgId;
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
206 207

  int32_t refCount = atomic_sub_fetch_32(&pVnode->refCount, 1);
208
  assert(refCount >= 0);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
209

J
Jeff Tao 已提交
210
  if (refCount > 0) {
211
    dTrace("pVnode:%p vgId:%d, release vnode, refCount:%d", pVnode, vgId, refCount);
J
Jeff Tao 已提交
212 213
    return;
  }
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
214 215 216 217 218 219 220 221 222

  // remove read queue
  dnodeFreeRqueue(pVnode->rqueue);
  pVnode->rqueue = NULL;

  // remove write queue
  dnodeFreeWqueue(pVnode->wqueue);
  pVnode->wqueue = NULL;

S
slguan 已提交
223
  if (pVnode->status == TAOS_VN_STATUS_DELETING) {
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
224 225 226
    // remove the whole directory
  }

227
  free(pVnode);
228

J
Jeff Tao 已提交
229
  int32_t count = atomic_sub_fetch_32(&tsOpennedVnodes, 1);
J
Jeff Tao 已提交
230 231
  dTrace("pVnode:%p vgId:%d, vnode is released, vnodes:%d", pVnode, vgId, count);

J
Jeff Tao 已提交
232
  if (count <= 0) {
233 234
    taosCleanUpIntHash(tsDnodeVnodesHash);
    vnodeModuleInit = PTHREAD_ONCE_INIT;
J
Jeff Tao 已提交
235
    tsDnodeVnodesHash = NULL;
236
  }
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
237 238 239
}

void *vnodeGetVnode(int32_t vgId) {
240 241
  SVnodeObj **ppVnode = (SVnodeObj **)taosGetIntHashData(tsDnodeVnodesHash, vgId);
  if (ppVnode == NULL || *ppVnode == NULL) {
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
242
    terrno = TSDB_CODE_INVALID_VGROUP_ID;
243
    assert(false);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
244 245
  }

246
  return *ppVnode;
S
slguan 已提交
247 248 249 250 251 252
}

void *vnodeAccquireVnode(int32_t vgId) {
  SVnodeObj *pVnode = vnodeGetVnode(vgId);
  if (pVnode == NULL) return pVnode;

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
253 254 255 256 257 258 259 260 261 262 263
  atomic_add_fetch_32(&pVnode->refCount, 1);
  dTrace("pVnode:%p vgId:%d, get vnode, refCount:%d", pVnode, pVnode->vgId, pVnode->refCount);

  return pVnode;
}

void *vnodeGetRqueue(void *pVnode) {
  return ((SVnodeObj *)pVnode)->rqueue; 
}

void *vnodeGetWqueue(int32_t vgId) {
S
slguan 已提交
264
  SVnodeObj *pVnode = vnodeAccquireVnode(vgId);
陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
265 266 267 268 269 270 271 272 273 274 275 276
  if (pVnode == NULL) return NULL;
  return pVnode->wqueue;
} 

void *vnodeGetWal(void *pVnode) {
  return ((SVnodeObj *)pVnode)->wal; 
}

void *vnodeGetTsdb(void *pVnode) {
  return ((SVnodeObj *)pVnode)->tsdb; 
}

J
Jeff Tao 已提交
277 278 279 280 281 282
void vnodeBuildStatusMsg(void *param) {
  SDMStatusMsg *pStatus = param;
  taosVisitIntHashWithFp(tsDnodeVnodesHash, vnodeBuildVloadMsg, pStatus);
}

static void vnodeBuildVloadMsg(char *pNode, void * param) {
283
  SVnodeObj *pVnode = *(SVnodeObj **) pNode;
S
slguan 已提交
284
  if (pVnode->status == TAOS_VN_STATUS_DELETING) return;
J
Jeff Tao 已提交
285 286 287 288 289 290 291

  SDMStatusMsg *pStatus = param;
  if (pStatus->openVnodes >= TSDB_MAX_VNODES) return;

  SVnodeLoad *pLoad = &pStatus->load[pStatus->openVnodes++];
  pLoad->vgId = htonl(pVnode->vgId);
  pLoad->status = pVnode->status;
S
slguan 已提交
292
  pLoad->role = pVnode->role;
J
Jeff Tao 已提交
293 294
}

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
295
static void vnodeCleanUp(SVnodeObj *pVnode) {
S
slguan 已提交
296
  
297 298
  taosDeleteIntHash(tsDnodeVnodesHash, pVnode->vgId);

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
299 300 301 302 303 304
  //syncStop(pVnode->sync);
  tsdbCloseRepo(pVnode->tsdb);
  walClose(pVnode->wal);

  vnodeRelease(pVnode);
}
H
hzcheng 已提交
305

306
// TODO: this is a simple implement
J
Jeff Tao 已提交
307
static int vnodeWalCallback(void *arg) {
H
hzcheng 已提交
308 309
  SVnodeObj *pVnode = arg;
  return walRenew(pVnode->wal);
310 311
}

J
Jeff Tao 已提交
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
static uint32_t vnodeGetFileInfo(void *ahandle, char *name, uint32_t *index, int32_t *size) {
  // SVnodeObj *pVnode = ahandle;
  //tsdbGetFileInfo(pVnode->tsdb, name, index, size);
  return 0;
}

static int vnodeGetWalInfo(void *ahandle, char *name, uint32_t *index) {
  SVnodeObj *pVnode = ahandle;
  return walGetWalFile(pVnode->wal, name, index);
}

static void vnodeNotifyRole(void *ahandle, int8_t role) {
  SVnodeObj *pVnode = ahandle;
  pVnode->role = role;
}

328 329 330 331 332 333 334
static int32_t vnodeSaveCfg(SMDCreateVnodeMsg *pVnodeCfg) {
  char cfgFile[TSDB_FILENAME_LEN * 2] = {0};
  sprintf(cfgFile, "%s/vnode%d/config", tsVnodeDir, pVnodeCfg->cfg.vgId);

  FILE *fp = fopen(cfgFile, "w");
  if (!fp) return errno;

S
slguan 已提交
335 336 337 338 339
  fprintf(fp, "commitLog %d\n", pVnodeCfg->cfg.commitLog);
  fprintf(fp, "wals %d\n", 3);
  fprintf(fp, "arbitratorIp %d\n", pVnodeCfg->vpeerDesc[0].ip);
  fprintf(fp, "quorum %d\n", 1);
  fprintf(fp, "replica %d\n", pVnodeCfg->cfg.replications);
340
  for (int32_t i = 0; i < pVnodeCfg->cfg.replications; i++) {
S
slguan 已提交
341
    fprintf(fp, "index%d nodeId %d nodeIp %u name n%d\n", i, pVnodeCfg->vpeerDesc[i].dnodeId, pVnodeCfg->vpeerDesc[i].ip, pVnodeCfg->vpeerDesc[i].dnodeId);
342 343 344
  }

  fclose(fp);
S
slguan 已提交
345
  dTrace("vgId:%d, save vnode cfg successed", pVnodeCfg->cfg.vgId);
346 347 348 349 350 351

  return TSDB_CODE_SUCCESS;
}

// TODO: this is a simple implement
static int32_t vnodeReadCfg(SVnodeObj *pVnode) {
S
slguan 已提交
352
  char option[5][16] = {0};
353 354 355 356 357 358
  char cfgFile[TSDB_FILENAME_LEN * 2] = {0};
  sprintf(cfgFile, "%s/vnode%d/config", tsVnodeDir, pVnode->vgId);

  FILE *fp = fopen(cfgFile, "r");
  if (!fp) return errno;

S
slguan 已提交
359
  int32_t commitLog = -1;
S
slguan 已提交
360 361 362
  int32_t num = fscanf(fp, "%s %d", option[0], &commitLog);
  if (num != 2) return TSDB_CODE_INVALID_FILE_FORMAT;
  if (strcmp(option[0], "commitLog") != 0) return TSDB_CODE_INVALID_FILE_FORMAT;
S
slguan 已提交
363
  if (commitLog == -1) return TSDB_CODE_INVALID_FILE_FORMAT;
S
slguan 已提交
364 365
  pVnode->walCfg.commitLog = (int8_t)commitLog;

S
slguan 已提交
366
  int32_t wals = -1;
S
slguan 已提交
367
  num = fscanf(fp, "%s %d", option[0], &wals);
368
  if (num != 2) return TSDB_CODE_INVALID_FILE_FORMAT;
S
slguan 已提交
369
  if (strcmp(option[0], "wals") != 0) return TSDB_CODE_INVALID_FILE_FORMAT;
S
slguan 已提交
370
  if (wals == -1) return TSDB_CODE_INVALID_FILE_FORMAT;
S
slguan 已提交
371
  pVnode->walCfg.wals = (int8_t)wals;
J
Jeff Tao 已提交
372
  pVnode->walCfg.keep = 0;
373

S
slguan 已提交
374
  int32_t arbitratorIp = -1;
S
slguan 已提交
375 376 377
  num = fscanf(fp, "%s %u", option[0], &arbitratorIp);
  if (num != 2) return TSDB_CODE_INVALID_FILE_FORMAT;
  if (strcmp(option[0], "arbitratorIp") != 0) return TSDB_CODE_INVALID_FILE_FORMAT;
S
slguan 已提交
378
  if (arbitratorIp == -1) return TSDB_CODE_INVALID_FILE_FORMAT;
J
Jeff Tao 已提交
379
  pVnode->syncCfg.arbitratorIp = arbitratorIp;
S
slguan 已提交
380

S
slguan 已提交
381
  int32_t quorum = -1;
S
slguan 已提交
382 383 384
  num = fscanf(fp, "%s %d", option[0], &quorum);
  if (num != 2) return TSDB_CODE_INVALID_FILE_FORMAT;
  if (strcmp(option[0], "quorum") != 0) return TSDB_CODE_INVALID_FILE_FORMAT;
S
slguan 已提交
385
  if (quorum == -1) return TSDB_CODE_INVALID_FILE_FORMAT;
S
slguan 已提交
386 387
  pVnode->syncCfg.quorum = (int8_t)quorum;

S
slguan 已提交
388
  int32_t replica = -1;
S
slguan 已提交
389 390 391
  num = fscanf(fp, "%s %d", option[0], &replica);
  if (num != 2) return TSDB_CODE_INVALID_FILE_FORMAT;
  if (strcmp(option[0], "replica") != 0) return TSDB_CODE_INVALID_FILE_FORMAT;
S
slguan 已提交
392
  if (replica == -1) return TSDB_CODE_INVALID_FILE_FORMAT;
S
slguan 已提交
393 394 395
  pVnode->syncCfg.replica = (int8_t)replica;

  for (int32_t i = 0; i < replica; ++i) {
S
slguan 已提交
396 397
    int32_t  dnodeId = -1;
    uint32_t dnodeIp = -1;
S
slguan 已提交
398 399 400 401 402
    num = fscanf(fp, "%s %s %d %s %u %s %s", option[0], option[1], &dnodeId, option[2], &dnodeIp, option[3], pVnode->syncCfg.nodeInfo[i].name);
    if (num != 7) return TSDB_CODE_INVALID_FILE_FORMAT;
    if (strcmp(option[1], "nodeId") != 0) return TSDB_CODE_INVALID_FILE_FORMAT;
    if (strcmp(option[2], "nodeIp") != 0) return TSDB_CODE_INVALID_FILE_FORMAT;
    if (strcmp(option[3], "name") != 0) return TSDB_CODE_INVALID_FILE_FORMAT;
S
slguan 已提交
403 404
    if (dnodeId == -1) return TSDB_CODE_INVALID_FILE_FORMAT;
    if (dnodeIp == -1) return TSDB_CODE_INVALID_FILE_FORMAT;
S
slguan 已提交
405 406
    pVnode->syncCfg.nodeInfo[i].nodeId = dnodeId;
    pVnode->syncCfg.nodeInfo[i].nodeIp = dnodeIp;
407 408 409 410 411 412
  }

  fclose(fp);
  dTrace("pVnode:%p vgId:%d, read vnode cfg successed", pVnode, pVnode->vgId);

  return TSDB_CODE_SUCCESS;
S
slguan 已提交
413
}