dnode.c 7.0 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 18 19 20
#include "dndDnode.h"
#include "dndMnode.h"
#include "dndTransport.h"
#include "dndVnodes.h"
S
Shengliang Guan 已提交
21
#include "sync.h"
S
Shengliang Guan 已提交
22
#include "wal.h"
S
Shengliang Guan 已提交
23

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

S
Shengliang Guan 已提交
26
void dndSetStat(SDnode *pDnode, EStat stat) {
S
Shengliang Guan 已提交
27
  dDebug("dnode status set from %s to %s", dndStatStr(pDnode->stat), dndStatStr(stat));
S
Shengliang Guan 已提交
28 29 30
  pDnode->stat = stat;
}

S
Shengliang Guan 已提交
31
char *dndStatStr(EStat stat) {
S
Shengliang Guan 已提交
32
  switch (stat) {
S
Shengliang Guan 已提交
33
    case DND_STAT_INIT:
S
Shengliang Guan 已提交
34
      return "init";
S
Shengliang Guan 已提交
35
    case DND_STAT_RUNNING:
S
Shengliang Guan 已提交
36
      return "running";
S
Shengliang Guan 已提交
37
    case DND_STAT_STOPPED:
S
Shengliang Guan 已提交
38 39 40 41 42 43
      return "stopped";
    default:
      return "unknown";
  }
}

S
Shengliang Guan 已提交
44
void dndReportStartup(SDnode *pDnode, char *pName, char *pDesc) {
S
Shengliang Guan 已提交
45
  SStartupMsg *pStartup = &pDnode->startup;
S
Shengliang Guan 已提交
46 47
  tstrncpy(pStartup->name, pName, TSDB_STEP_NAME_LEN);
  tstrncpy(pStartup->desc, pDesc, TSDB_STEP_DESC_LEN);
S
Shengliang Guan 已提交
48 49 50
  pStartup->finished = 0;
}

S
Shengliang Guan 已提交
51 52 53
void dndGetStartup(SDnode *pDnode, SStartupMsg *pStartup) {
  memcpy(pStartup, &pDnode->startup, sizeof(SStartupMsg));
  pStartup->finished = (dndGetStat(pDnode) == DND_STAT_RUNNING);
S
Shengliang Guan 已提交
54 55
}

S
Shengliang Guan 已提交
56
static FileFd dndCheckRunning(char *dataDir) {
S
Shengliang Guan 已提交
57 58 59 60 61 62
  char filepath[PATH_MAX] = {0};
  snprintf(filepath, sizeof(filepath), "%s/.running", dataDir);

  FileFd fd = taosOpenFileCreateWriteTrunc(filepath);
  if (fd < 0) {
    terrno = TAOS_SYSTEM_ERROR(errno);
63
    dError("failed to lock file:%s since %s, quit", filepath, terrstr());
S
Shengliang Guan 已提交
64 65 66 67 68 69
    return -1;
  }

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

S
Shengliang Guan 已提交
75
  return fd;
S
Shengliang Guan 已提交
76 77
}

S
Shengliang Guan 已提交
78
static int32_t dndInitEnv(SDnode *pDnode, SDnodeOpt *pOption) {
S
Shengliang Guan 已提交
79 80
  pDnode->lockFd = dndCheckRunning(pOption->dataDir);
  if (pDnode->lockFd < 0) {
S
Shengliang Guan 已提交
81 82 83 84
    return -1;
  }

  char path[PATH_MAX + 100];
S
Shengliang Guan 已提交
85
  snprintf(path, sizeof(path), "%s%smnode", pOption->dataDir, TD_DIRSEP);
86
  pDnode->dir.mnode = tstrdup(path);
S
Shengliang Guan 已提交
87

S
Shengliang Guan 已提交
88
  snprintf(path, sizeof(path), "%s%svnode", pOption->dataDir, TD_DIRSEP);
89
  pDnode->dir.vnodes = tstrdup(path);
S
Shengliang Guan 已提交
90

S
Shengliang Guan 已提交
91
  snprintf(path, sizeof(path), "%s%sdnode", pOption->dataDir, TD_DIRSEP);
92
  pDnode->dir.dnode = tstrdup(path);
S
Shengliang Guan 已提交
93

S
Shengliang Guan 已提交
94 95 96 97 98 99 100 101 102
  snprintf(path, sizeof(path), "%s%sqnode", pOption->dataDir, TD_DIRSEP);
  pDnode->dir.dnode = tstrdup(path);

  snprintf(path, sizeof(path), "%s%ssnode", pOption->dataDir, TD_DIRSEP);
  pDnode->dir.dnode = tstrdup(path);

  snprintf(path, sizeof(path), "%s%sbnode", pOption->dataDir, TD_DIRSEP);
  pDnode->dir.dnode = tstrdup(path);

S
Shengliang Guan 已提交
103 104 105 106 107 108
  if (pDnode->dir.mnode == NULL || pDnode->dir.vnodes == NULL || pDnode->dir.dnode == NULL) {
    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 139 140 141 142 143 144
  if (taosMkDir(pDnode->dir.qnode) != 0) {
    dError("failed to create dir:%s since %s", pDnode->dir.qnode, strerror(errno));
    terrno = TAOS_SYSTEM_ERROR(errno);
    return -1;
  }

  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 已提交
145
  memcpy(&pDnode->opt, pOption, sizeof(SDnodeOpt));
S
Shengliang Guan 已提交
146 147 148
  return 0;
}

S
Shengliang Guan 已提交
149
static void dndCleanupEnv(SDnode *pDnode) {
S
Shengliang Guan 已提交
150 151 152 153 154 155 156 157 158 159 160 161
  if (pDnode->dir.mnode != NULL) {
    tfree(pDnode->dir.mnode);
  }

  if (pDnode->dir.vnodes != NULL) {
    tfree(pDnode->dir.vnodes);
  }

  if (pDnode->dir.dnode != NULL) {
    tfree(pDnode->dir.dnode);
  }

S
Shengliang Guan 已提交
162 163 164 165 166 167 168 169 170 171 172 173
  if (pDnode->dir.qnode != NULL) {
    tfree(pDnode->dir.qnode);
  }

  if (pDnode->dir.bnode != NULL) {
    tfree(pDnode->dir.snode);
  }

  if (pDnode->dir.snode != NULL) {
    tfree(pDnode->dir.bnode);
  }

S
Shengliang Guan 已提交
174 175 176 177 178 179
  if (pDnode->lockFd >= 0) {
    taosUnLockFile(pDnode->lockFd);
    taosCloseFile(pDnode->lockFd);
    pDnode->lockFd = 0;
  }

S
Shengliang Guan 已提交
180 181 182
  taosStopCacheRefreshWorker();
}

S
Shengliang Guan 已提交
183
SDnode *dndInit(SDnodeOpt *pOption) {
S
Shengliang Guan 已提交
184 185 186 187
  taosIgnSIGPIPE();
  taosBlockSIGPIPE();
  taosResolveCRC();

188
  SDnode *pDnode = calloc(1, sizeof(SDnode));
S
Shengliang Guan 已提交
189 190 191 192 193 194 195
  if (pDnode == NULL) {
    dError("failed to create dnode object");
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return NULL;
  }

  dInfo("start to initialize TDengine");
S
Shengliang Guan 已提交
196
  dndSetStat(pDnode, DND_STAT_INIT);
S
Shengliang Guan 已提交
197

S
Shengliang Guan 已提交
198
  if (dndInitEnv(pDnode, pOption) != 0) {
S
Shengliang Guan 已提交
199
    dError("failed to init env");
S
Shengliang Guan 已提交
200
    dndCleanup(pDnode);
S
Shengliang Guan 已提交
201 202 203 204 205
    return NULL;
  }

  if (rpcInit() != 0) {
    dError("failed to init rpc env");
S
Shengliang Guan 已提交
206
    dndCleanup(pDnode);
S
Shengliang Guan 已提交
207 208 209 210 211
    return NULL;
  }

  if (walInit() != 0) {
    dError("failed to init wal env");
S
Shengliang Guan 已提交
212
    dndCleanup(pDnode);
S
Shengliang Guan 已提交
213 214 215
    return NULL;
  }

S
Shengliang Guan 已提交
216
  if (vnodeInit(pDnode->opt.numOfCommitThreads) != 0) {
217 218 219 220 221
    dError("failed to init vnode env");
    dndCleanup(pDnode);
    return NULL;
  }

S
Shengliang Guan 已提交
222
  if (dndInitDnode(pDnode) != 0) {
S
Shengliang Guan 已提交
223
    dError("failed to init dnode");
S
Shengliang Guan 已提交
224
    dndCleanup(pDnode);
S
Shengliang Guan 已提交
225 226 227
    return NULL;
  }

S
Shengliang Guan 已提交
228
  if (dndInitVnodes(pDnode) != 0) {
S
Shengliang Guan 已提交
229
    dError("failed to init vnodes");
S
Shengliang Guan 已提交
230
    dndCleanup(pDnode);
S
Shengliang Guan 已提交
231 232 233
    return NULL;
  }

S
Shengliang Guan 已提交
234
  if (dndInitMnode(pDnode) != 0) {
S
Shengliang Guan 已提交
235
    dError("failed to init mnode");
S
Shengliang Guan 已提交
236
    dndCleanup(pDnode);
S
Shengliang Guan 已提交
237 238 239
    return NULL;
  }

S
Shengliang Guan 已提交
240
  if (dndInitTrans(pDnode) != 0) {
S
Shengliang Guan 已提交
241
    dError("failed to init transport");
S
Shengliang Guan 已提交
242
    dndCleanup(pDnode);
S
Shengliang Guan 已提交
243 244 245
    return NULL;
  }

S
Shengliang Guan 已提交
246
  dndSetStat(pDnode, DND_STAT_RUNNING);
247
  dndSendStatusMsg(pDnode);
S
Shengliang Guan 已提交
248
  dndReportStartup(pDnode, "TDengine", "initialized successfully");
S
Shengliang Guan 已提交
249
  dInfo("TDengine is initialized successfully, pDnode:%p", pDnode);
S
Shengliang Guan 已提交
250

251
  return pDnode;
S
Shengliang Guan 已提交
252 253
}

S
Shengliang Guan 已提交
254
void dndCleanup(SDnode *pDnode) {
S
Shengliang Guan 已提交
255 256
  if (pDnode == NULL) return;

S
Shengliang Guan 已提交
257
  if (dndGetStat(pDnode) == DND_STAT_STOPPED) {
S
Shengliang Guan 已提交
258 259 260 261 262
    dError("dnode is shutting down");
    return;
  }

  dInfo("start to cleanup TDengine");
S
Shengliang Guan 已提交
263 264 265 266 267
  dndSetStat(pDnode, DND_STAT_STOPPED);
  dndCleanupTrans(pDnode);
  dndCleanupMnode(pDnode);
  dndCleanupVnodes(pDnode);
  dndCleanupDnode(pDnode);
268
  vnodeClear();
S
Shengliang Guan 已提交
269 270
  walCleanUp();
  rpcCleanup();
271

S
Shengliang Guan 已提交
272
  dndCleanupEnv(pDnode);
S
Shengliang Guan 已提交
273
  free(pDnode);
S
Shengliang Guan 已提交
274
  dInfo("TDengine is cleaned up successfully");
S
Shengliang Guan 已提交
275
}