dndEnv.c 8.4 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
Shengliang Guan 已提交
24
#include "sync.h"
S
Shengliang Guan 已提交
25
#include "tfs.h"
S
Shengliang Guan 已提交
26
#include "wal.h"
S
Shengliang Guan 已提交
27

S
Shengliang Guan 已提交
28 29
static SDnodeEnv dndEnv = {0};

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

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

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

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

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

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

  FileFd fd = taosOpenFileCreateWriteTrunc(filepath);
  if (fd < 0) {
    terrno = TAOS_SYSTEM_ERROR(errno);
69
    dError("failed to lock file:%s since %s, quit", filepath, terrstr());
S
Shengliang Guan 已提交
70 71 72 73 74 75
    return -1;
  }

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

S
Shengliang Guan 已提交
81
  return fd;
S
Shengliang Guan 已提交
82 83
}

S
Shengliang Guan 已提交
84 85
static int32_t dndCreateImp(SDnode *pDnode, SDnodeObjCfg *pCfg) {
  pDnode->lockFd = dndCheckRunning(pCfg->dataDir);
S
Shengliang Guan 已提交
86
  if (pDnode->lockFd < 0) {
S
Shengliang Guan 已提交
87 88 89 90
    return -1;
  }

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

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

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

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

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

S
Shengliang Guan 已提交
127 128 129 130 131 132 133 134 135 136 137 138
  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 已提交
139 140
  memcpy(&pDnode->cfg, pCfg, sizeof(SDnodeObjCfg));
  memcpy(&pDnode->env, &dndEnv.cfg, sizeof(SDnodeEnvCfg));
S
Shengliang Guan 已提交
141 142 143
  return 0;
}

S
Shengliang Guan 已提交
144
static void dndCloseImp(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

S
Shengliang Guan 已提交
151 152 153 154 155
  if (pDnode->lockFd >= 0) {
    taosUnLockFile(pDnode->lockFd);
    taosCloseFile(pDnode->lockFd);
    pDnode->lockFd = 0;
  }
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
Shengliang Guan 已提交
170 171 172
  if (dndCreateImp(pDnode, pCfg) != 0) {
    dError("failed to init dnode dir since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
173 174 175 176
    return NULL;
  }

  if (rpcInit() != 0) {
S
Shengliang Guan 已提交
177 178
    dError("failed to init rpc since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
179 180 181 182
    return NULL;
  }

  if (walInit() != 0) {
S
Shengliang Guan 已提交
183 184
    dError("failed to init wal since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
185 186 187
    return NULL;
  }

S
Shengliang Guan 已提交
188
  SDiskCfg dCfg;
S
Shengliang Guan 已提交
189
  strcpy(dCfg.dir, pDnode->cfg.dataDir);
S
Shengliang Guan 已提交
190 191 192
  dCfg.level = 0;
  dCfg.primary = 1;
  if (tfsInit(&dCfg, 1) != 0) {
S
Shengliang Guan 已提交
193 194
    dError("failed to init tfs since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
195 196 197
    return NULL;
  }

S
Shengliang Guan 已提交
198
  SVnodeOpt vnodeOpt = {
S
Shengliang Guan 已提交
199 200 201 202 203
      .sver = pDnode->env.sver,
      .timezone = pDnode->env.timezone,
      .locale = pDnode->env.locale,
      .charset = pDnode->env.charset,
      .nthreads = pDnode->cfg.numOfCommitThreads,
S
Shengliang Guan 已提交
204
      .putReqToVQueryQFp = dndPutReqToVQueryQ,
S
Shengliang Guan 已提交
205 206
  };
  if (vnodeInit(&vnodeOpt) != 0) {
S
Shengliang Guan 已提交
207 208
    dError("failed to init vnode since %s", terrstr());
    dndClose(pDnode);
209 210 211
    return NULL;
  }

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

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

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

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

  if (dndInitBnode(pDnode) != 0) {
S
Shengliang Guan 已提交
237 238
    dError("failed to init bnode since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
239 240 241
    return NULL;
  }

S
Shengliang Guan 已提交
242
  if (dndInitMnode(pDnode) != 0) {
S
Shengliang Guan 已提交
243 244
    dError("failed to init mnode since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
245 246 247
    return NULL;
  }

S
Shengliang Guan 已提交
248
  if (dndInitTrans(pDnode) != 0) {
S
Shengliang Guan 已提交
249 250
    dError("failed to init transport since %s", terrstr());
    dndClose(pDnode);
S
Shengliang Guan 已提交
251 252 253
    return NULL;
  }

S
Shengliang Guan 已提交
254
  dndSetStat(pDnode, DND_STAT_RUNNING);
S
Shengliang Guan 已提交
255
  dndSendStatusReq(pDnode);
S
Shengliang Guan 已提交
256
  dndReportStartup(pDnode, "TDengine", "initialized successfully");
S
Shengliang Guan 已提交
257
  dInfo("dnode object is created, data:%p", pDnode);
S
Shengliang Guan 已提交
258

259
  return pDnode;
S
Shengliang Guan 已提交
260 261
}

S
Shengliang Guan 已提交
262
void dndClose(SDnode *pDnode) {
S
Shengliang Guan 已提交
263 264
  if (pDnode == NULL) return;

S
Shengliang Guan 已提交
265
  if (dndGetStat(pDnode) == DND_STAT_STOPPED) {
S
Shengliang Guan 已提交
266
    dError("dnode is shutting down, data:%p", pDnode);
S
Shengliang Guan 已提交
267 268 269
    return;
  }

S
Shengliang Guan 已提交
270
  dInfo("start to close dnode, data:%p", pDnode);
S
Shengliang Guan 已提交
271 272
  dndSetStat(pDnode, DND_STAT_STOPPED);
  dndCleanupTrans(pDnode);
S
Shengliang Guan 已提交
273
  dndStopMgmt(pDnode);
S
Shengliang Guan 已提交
274
  dndCleanupMnode(pDnode);
S
Shengliang Guan 已提交
275 276 277
  dndCleanupBnode(pDnode);
  dndCleanupSnode(pDnode);
  dndCleanupQnode(pDnode);
S
Shengliang Guan 已提交
278
  dndCleanupVnodes(pDnode);
S
Shengliang Guan 已提交
279
  dndCleanupMgmt(pDnode);
280
  vnodeClear();
S
Shengliang Guan 已提交
281
  tfsDestroy();
S
Shengliang Guan 已提交
282 283
  walCleanUp();
  rpcCleanup();
284

S
Shengliang Guan 已提交
285
  dndCloseImp(pDnode);
S
Shengliang Guan 已提交
286
  free(pDnode);
S
Shengliang Guan 已提交
287
  dInfo("dnode object is closed, data:%p", pDnode);
S
Shengliang Guan 已提交
288
}
S
Shengliang Guan 已提交
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314

int32_t dndInit(const SDnodeEnvCfg *pCfg) {
  if (atomic_val_compare_exchange_8(&dndEnv.once, DND_ENV_INIT, DND_ENV_READY) != DND_ENV_INIT) {
    terrno = TSDB_CODE_REPEAT_INIT;
    dError("failed to init dnode env since %s", terrstr());
    return -1;
  }

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

  memcpy(&dndEnv.cfg, pCfg, sizeof(SDnodeEnvCfg));
  dInfo("dnode env is initialized");
  return 0;
}

void dndCleanup() {
  if (atomic_val_compare_exchange_8(&dndEnv.once, DND_ENV_READY, DND_ENV_CLEANUP) != DND_ENV_READY) {
    dError("dnode env is already cleaned up");
    return;
  }

  taosStopCacheRefreshWorker();
  dInfo("dnode env is cleaned up");
}