dndEnv.c 8.7 KB
Newer Older
S
Shengliang Guan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * 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
S
Shengliang Guan 已提交
17
#include "dndBnode.h"
S
Shengliang Guan 已提交
18
#include "dndMgmt.h"
S
Shengliang Guan 已提交
19
#include "dndMnode.h"
S
Shengliang Guan 已提交
20 21
#include "dndQnode.h"
#include "dndSnode.h"
S
Shengliang Guan 已提交
22 23
#include "dndTransport.h"
#include "dndVnodes.h"
S
monitor  
Shengliang Guan 已提交
24
#include "monitor.h"
S
Shengliang Guan 已提交
25
#include "sync.h"
S
Shengliang Guan 已提交
26
#include "tfs.h"
S
Shengliang Guan 已提交
27
#include "wal.h"
S
Shengliang Guan 已提交
28

S
config  
Shengliang Guan 已提交
29
static int8_t once = DND_ENV_INIT;
S
Shengliang Guan 已提交
30

S
Shengliang Guan 已提交
31
EStat dndGetStat(SDnode *pDnode) { return pDnode->stat; }
S
Shengliang Guan 已提交
32

S
Shengliang Guan 已提交
33
void dndSetStat(SDnode *pDnode, EStat stat) {
S
Shengliang Guan 已提交
34
  dDebug("dnode status set from %s to %s", dndStatStr(pDnode->stat), dndStatStr(stat));
S
Shengliang Guan 已提交
35 36 37
  pDnode->stat = stat;
}

S
Shengliang Guan 已提交
38
const char *dndStatStr(EStat stat) {
S
Shengliang Guan 已提交
39
  switch (stat) {
S
Shengliang Guan 已提交
40
    case DND_STAT_INIT:
S
Shengliang Guan 已提交
41
      return "init";
S
Shengliang Guan 已提交
42
    case DND_STAT_RUNNING:
S
Shengliang Guan 已提交
43
      return "running";
S
Shengliang Guan 已提交
44
    case DND_STAT_STOPPED:
S
Shengliang Guan 已提交
45 46 47 48 49 50
      return "stopped";
    default:
      return "unknown";
  }
}

S
Shengliang Guan 已提交
51
void dndReportStartup(SDnode *pDnode, char *pName, char *pDesc) {
S
Shengliang Guan 已提交
52
  SStartupReq *pStartup = &pDnode->startup;
S
Shengliang Guan 已提交
53 54
  tstrncpy(pStartup->name, pName, TSDB_STEP_NAME_LEN);
  tstrncpy(pStartup->desc, pDesc, TSDB_STEP_DESC_LEN);
S
Shengliang Guan 已提交
55 56 57
  pStartup->finished = 0;
}

S
Shengliang Guan 已提交
58 59
void dndGetStartup(SDnode *pDnode, SStartupReq *pStartup) {
  memcpy(pStartup, &pDnode->startup, sizeof(SStartupReq));
S
Shengliang Guan 已提交
60
  pStartup->finished = (dndGetStat(pDnode) == DND_STAT_RUNNING);
S
Shengliang Guan 已提交
61 62
}

63
static TdFilePtr dndCheckRunning(char *dataDir) {
S
Shengliang Guan 已提交
64 65 66
  char filepath[PATH_MAX] = {0};
  snprintf(filepath, sizeof(filepath), "%s/.running", dataDir);

67 68
  TdFilePtr pFile = taosOpenFile(filepath, TD_FILE_CTEATE | TD_FILE_WRITE | TD_FILE_TRUNC);
  if (pFile == NULL) {
S
Shengliang Guan 已提交
69
    terrno = TAOS_SYSTEM_ERROR(errno);
70
    dError("failed to lock file:%s since %s, quit", filepath, terrstr());
71
    return NULL;
S
Shengliang Guan 已提交
72 73
  }

74
  int32_t ret = taosLockFile(pFile);
S
Shengliang Guan 已提交
75 76
  if (ret != 0) {
    terrno = TAOS_SYSTEM_ERROR(errno);
77
    dError("failed to lock file:%s since %s, quit", filepath, terrstr());
78 79
    taosCloseFile(&pFile);
    return NULL;
S
Shengliang Guan 已提交
80 81
  }

82
  return pFile;
S
Shengliang Guan 已提交
83 84
}

S
tfs cfg  
Shengliang Guan 已提交
85
static int32_t dndInitDir(SDnode *pDnode, SDnodeObjCfg *pCfg) {
86 87
  pDnode->pLockFile = dndCheckRunning(pCfg->dataDir);
  if (pDnode->pLockFile == NULL) {
S
Shengliang Guan 已提交
88 89 90 91
    return -1;
  }

  char path[PATH_MAX + 100];
S
Shengliang Guan 已提交
92
  snprintf(path, sizeof(path), "%s%smnode", pCfg->dataDir, TD_DIRSEP);
93
  pDnode->dir.mnode = tstrdup(path);
S
Shengliang Guan 已提交
94
  snprintf(path, sizeof(path), "%s%svnode", pCfg->dataDir, TD_DIRSEP);
95
  pDnode->dir.vnodes = tstrdup(path);
S
Shengliang Guan 已提交
96
  snprintf(path, sizeof(path), "%s%sdnode", pCfg->dataDir, TD_DIRSEP);
97
  pDnode->dir.dnode = tstrdup(path);
S
Shengliang Guan 已提交
98
  snprintf(path, sizeof(path), "%s%ssnode", pCfg->dataDir, TD_DIRSEP);
S
Shengliang Guan 已提交
99
  pDnode->dir.snode = tstrdup(path);
S
Shengliang Guan 已提交
100
  snprintf(path, sizeof(path), "%s%sbnode", pCfg->dataDir, TD_DIRSEP);
S
Shengliang Guan 已提交
101
  pDnode->dir.bnode = tstrdup(path);
S
Shengliang Guan 已提交
102

S
Shengliang Guan 已提交
103 104
  if (pDnode->dir.mnode == NULL || pDnode->dir.vnodes == NULL || pDnode->dir.dnode == NULL ||
      pDnode->dir.snode == NULL || pDnode->dir.bnode == NULL) {
S
Shengliang Guan 已提交
105 106 107 108 109
    dError("failed to malloc dir object");
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

110
  if (taosMkDir(pDnode->dir.dnode) != 0) {
S
Shengliang Guan 已提交
111 112 113 114 115
    dError("failed to create dir:%s since %s", pDnode->dir.dnode, strerror(errno));
    terrno = TAOS_SYSTEM_ERROR(errno);
    return -1;
  }

116
  if (taosMkDir(pDnode->dir.mnode) != 0) {
S
Shengliang Guan 已提交
117 118 119 120 121
    dError("failed to create dir:%s since %s", pDnode->dir.mnode, strerror(errno));
    terrno = TAOS_SYSTEM_ERROR(errno);
    return -1;
  }

122
  if (taosMkDir(pDnode->dir.vnodes) != 0) {
S
Shengliang Guan 已提交
123 124 125 126 127
    dError("failed to create dir:%s since %s", pDnode->dir.vnodes, strerror(errno));
    terrno = TAOS_SYSTEM_ERROR(errno);
    return -1;
  }

S
Shengliang Guan 已提交
128 129 130 131 132 133 134 135 136 137 138 139
  if (taosMkDir(pDnode->dir.snode) != 0) {
    dError("failed to create dir:%s since %s", pDnode->dir.snode, strerror(errno));
    terrno = TAOS_SYSTEM_ERROR(errno);
    return -1;
  }

  if (taosMkDir(pDnode->dir.bnode) != 0) {
    dError("failed to create dir:%s since %s", pDnode->dir.bnode, strerror(errno));
    terrno = TAOS_SYSTEM_ERROR(errno);
    return -1;
  }

S
Shengliang Guan 已提交
140
  memcpy(&pDnode->cfg, pCfg, sizeof(SDnodeObjCfg));
S
Shengliang Guan 已提交
141 142 143
  return 0;
}

S
monitor  
Shengliang Guan 已提交
144
static void dndCloseDir(SDnode *pDnode) {
S
Shengliang Guan 已提交
145 146 147 148 149
  tfree(pDnode->dir.mnode);
  tfree(pDnode->dir.vnodes);
  tfree(pDnode->dir.dnode);
  tfree(pDnode->dir.snode);
  tfree(pDnode->dir.bnode);
S
Shengliang Guan 已提交
150

151 152 153 154
  if (pDnode->pLockFile != NULL) {
    taosUnLockFile(pDnode->pLockFile);
    taosCloseFile(&pDnode->pLockFile);
    pDnode->pLockFile = NULL;
S
Shengliang Guan 已提交
155
  }
S
Shengliang Guan 已提交
156 157
}

S
Shengliang Guan 已提交
158 159
SDnode *dndCreate(SDnodeObjCfg *pCfg) {
  dInfo("start to create dnode object");
S
Shengliang Guan 已提交
160

161
  SDnode *pDnode = calloc(1, sizeof(SDnode));
S
Shengliang Guan 已提交
162 163
  if (pDnode == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
S
Shengliang Guan 已提交
164
    dError("failed to create dnode object since %s", terrstr());
S
Shengliang Guan 已提交
165 166 167
    return NULL;
  }

S
Shengliang Guan 已提交
168
  dndSetStat(pDnode, DND_STAT_INIT);
S
Shengliang Guan 已提交
169

S
tfs cfg  
Shengliang Guan 已提交
170
  if (dndInitDir(pDnode, pCfg) != 0) {
S
Shengliang Guan 已提交
171 172
    dError("failed to init dnode dir since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
173 174 175
    return NULL;
  }

S
Shengliang Guan 已提交
176 177
  SDiskCfg dCfg = {0};
  tstrncpy(dCfg.dir, pDnode->cfg.dataDir, TSDB_FILENAME_LEN);
S
Shengliang Guan 已提交
178 179
  dCfg.level = 0;
  dCfg.primary = 1;
S
tfs cfg  
Shengliang Guan 已提交
180 181 182 183 184 185 186 187
  SDiskCfg *pDisks = pDnode->cfg.pDisks;
  int32_t   numOfDisks = pDnode->cfg.numOfDisks;
  if (numOfDisks <= 0 || pDisks == NULL) {
    pDisks = &dCfg;
    numOfDisks = 1;
  }

  pDnode->pTfs = tfsOpen(pDisks, numOfDisks);
S
Shengliang Guan 已提交
188
  if (pDnode->pTfs == NULL) {
S
Shengliang Guan 已提交
189 190
    dError("failed to init tfs since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
191 192 193
    return NULL;
  }

S
Shengliang Guan 已提交
194
  if (dndInitMgmt(pDnode) != 0) {
S
Shengliang Guan 已提交
195 196
    dError("failed to init mgmt since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
197 198 199
    return NULL;
  }

S
Shengliang Guan 已提交
200
  if (dndInitVnodes(pDnode) != 0) {
S
Shengliang Guan 已提交
201 202
    dError("failed to init vnodes since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
203 204 205
    return NULL;
  }

S
Shengliang Guan 已提交
206
  if (dndInitQnode(pDnode) != 0) {
S
Shengliang Guan 已提交
207 208
    dError("failed to init qnode since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
209 210 211 212
    return NULL;
  }

  if (dndInitSnode(pDnode) != 0) {
S
Shengliang Guan 已提交
213 214
    dError("failed to init snode since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
215 216 217 218
    return NULL;
  }

  if (dndInitBnode(pDnode) != 0) {
S
Shengliang Guan 已提交
219 220
    dError("failed to init bnode since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
221 222 223
    return NULL;
  }

S
Shengliang Guan 已提交
224
  if (dndInitMnode(pDnode) != 0) {
S
Shengliang Guan 已提交
225 226
    dError("failed to init mnode since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
227 228 229
    return NULL;
  }

S
Shengliang Guan 已提交
230
  if (dndInitTrans(pDnode) != 0) {
S
Shengliang Guan 已提交
231 232
    dError("failed to init transport since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
233 234 235
    return NULL;
  }

S
Shengliang Guan 已提交
236
  dndSetStat(pDnode, DND_STAT_RUNNING);
S
Shengliang Guan 已提交
237
  dndSendStatusReq(pDnode);
S
Shengliang Guan 已提交
238
  dndReportStartup(pDnode, "TDengine", "initialized successfully");
S
Shengliang Guan 已提交
239
  dInfo("dnode object is created, data:%p", pDnode);
S
Shengliang Guan 已提交
240

241
  return pDnode;
S
Shengliang Guan 已提交
242 243
}

S
Shengliang Guan 已提交
244
void dndClose(SDnode *pDnode) {
S
Shengliang Guan 已提交
245 246
  if (pDnode == NULL) return;

S
Shengliang Guan 已提交
247
  if (dndGetStat(pDnode) == DND_STAT_STOPPED) {
S
Shengliang Guan 已提交
248
    dError("dnode is shutting down, data:%p", pDnode);
S
Shengliang Guan 已提交
249 250 251
    return;
  }

S
Shengliang Guan 已提交
252
  dInfo("start to close dnode, data:%p", pDnode);
S
Shengliang Guan 已提交
253 254
  dndSetStat(pDnode, DND_STAT_STOPPED);
  dndCleanupTrans(pDnode);
S
Shengliang Guan 已提交
255
  dndStopMgmt(pDnode);
S
Shengliang Guan 已提交
256
  dndCleanupMnode(pDnode);
S
Shengliang Guan 已提交
257 258 259
  dndCleanupBnode(pDnode);
  dndCleanupSnode(pDnode);
  dndCleanupQnode(pDnode);
S
Shengliang Guan 已提交
260
  dndCleanupVnodes(pDnode);
S
Shengliang Guan 已提交
261
  dndCleanupMgmt(pDnode);
S
Shengliang Guan 已提交
262
  tfsClose(pDnode->pTfs);
263

S
monitor  
Shengliang Guan 已提交
264
  dndCloseDir(pDnode);
S
Shengliang Guan 已提交
265
  free(pDnode);
S
Shengliang Guan 已提交
266
  dInfo("dnode object is closed, data:%p", pDnode);
S
Shengliang Guan 已提交
267
}
S
Shengliang Guan 已提交
268

S
config  
Shengliang Guan 已提交
269 270
int32_t dndInit() {
  if (atomic_val_compare_exchange_8(&once, DND_ENV_INIT, DND_ENV_READY) != DND_ENV_INIT) {
S
Shengliang Guan 已提交
271 272 273 274 275 276 277 278 279
    terrno = TSDB_CODE_REPEAT_INIT;
    dError("failed to init dnode env since %s", terrstr());
    return -1;
  }

  taosIgnSIGPIPE();
  taosBlockSIGPIPE();
  taosResolveCRC();

S
Shengliang Guan 已提交
280
  if (rpcInit() != 0) {
S
Shengliang Guan 已提交
281 282 283 284 285 286 287 288 289 290 291
    dError("failed to init rpc since %s", terrstr());
    dndCleanup();
    return -1;
  }

  if (walInit() != 0) {
    dError("failed to init wal since %s", terrstr());
    dndCleanup();
    return -1;
  }

S
monitor  
Shengliang Guan 已提交
292 293
  SVnodeOpt vnodeOpt = {
      .nthreads = tsNumOfCommitThreads, .putReqToVQueryQFp = dndPutReqToVQueryQ, .sendReqToDnodeFp = dndSendReqToDnode};
S
Shengliang Guan 已提交
294 295 296 297

  if (vnodeInit(&vnodeOpt) != 0) {
    dError("failed to init vnode since %s", terrstr());
    dndCleanup();
H
Hongze Cheng 已提交
298
    return -1;
S
Shengliang Guan 已提交
299 300
  }

S
monitor  
Shengliang Guan 已提交
301 302 303 304 305 306 307
  SMonCfg monCfg = {.maxLogs = tsMonitorMaxLogs, .port = tsMonitorPort, .server = tsMonitorFqdn};
  if (monInit(&monCfg) != 0) {
    dError("failed to init monitor since %s", terrstr());
    dndCleanup();
    return -1;
  }

S
Shengliang Guan 已提交
308 309 310 311 312
  dInfo("dnode env is initialized");
  return 0;
}

void dndCleanup() {
S
config  
Shengliang Guan 已提交
313
  if (atomic_val_compare_exchange_8(&once, DND_ENV_READY, DND_ENV_CLEANUP) != DND_ENV_READY) {
S
Shengliang Guan 已提交
314 315 316 317
    dError("dnode env is already cleaned up");
    return;
  }

S
Shengliang Guan 已提交
318
  walCleanUp();
S
Shengliang Guan 已提交
319
  vnodeCleanup();
S
Shengliang Guan 已提交
320
  rpcCleanup();
S
monitor  
Shengliang Guan 已提交
321
  monCleanup();
S
Shengliang Guan 已提交
322

S
Shengliang Guan 已提交
323 324
  taosStopCacheRefreshWorker();
  dInfo("dnode env is cleaned up");
S
Shengliang Guan 已提交
325
}