dnode.c 5.6 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 22
#include "sync.h"
#include "tcache.h"
S
Shengliang Guan 已提交
23
#include "tcrc32c.h"
S
Shengliang Guan 已提交
24
#include "wal.h"
S
Shengliang Guan 已提交
25

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

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

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

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

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

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

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

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

  return 0;
}

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

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

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

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

  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;
  }

101
  if (taosMkDir(pDnode->dir.dnode) != 0) {
S
Shengliang Guan 已提交
102 103 104 105 106
    dError("failed to create dir:%s since %s", pDnode->dir.dnode, strerror(errno));
    terrno = TAOS_SYSTEM_ERROR(errno);
    return -1;
  }

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

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

S
Shengliang Guan 已提交
119
  memcpy(&pDnode->opt, pOption, sizeof(SDnodeOpt));
S
Shengliang Guan 已提交
120 121 122
  return 0;
}

S
Shengliang Guan 已提交
123
static void dndCleanupEnv(SDnode *pDnode) {
S
Shengliang Guan 已提交
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
  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);
  }

  taosStopCacheRefreshWorker();
}

S
Shengliang Guan 已提交
139
SDnode *dndInit(SDnodeOpt *pOption) {
S
Shengliang Guan 已提交
140 141 142 143
  taosIgnSIGPIPE();
  taosBlockSIGPIPE();
  taosResolveCRC();

144
  SDnode *pDnode = calloc(1, sizeof(SDnode));
S
Shengliang Guan 已提交
145 146 147 148 149 150 151
  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 已提交
152
  dndSetStat(pDnode, DND_STAT_INIT);
S
Shengliang Guan 已提交
153

S
Shengliang Guan 已提交
154
  if (dndInitEnv(pDnode, pOption) != 0) {
S
Shengliang Guan 已提交
155
    dError("failed to init env");
S
Shengliang Guan 已提交
156
    dndCleanup(pDnode);
S
Shengliang Guan 已提交
157 158 159 160 161
    return NULL;
  }

  if (rpcInit() != 0) {
    dError("failed to init rpc env");
S
Shengliang Guan 已提交
162
    dndCleanup(pDnode);
S
Shengliang Guan 已提交
163 164 165 166 167
    return NULL;
  }

  if (walInit() != 0) {
    dError("failed to init wal env");
S
Shengliang Guan 已提交
168
    dndCleanup(pDnode);
S
Shengliang Guan 已提交
169 170 171
    return NULL;
  }

S
Shengliang Guan 已提交
172
  if (dndInitDnode(pDnode) != 0) {
S
Shengliang Guan 已提交
173
    dError("failed to init dnode");
S
Shengliang Guan 已提交
174
    dndCleanup(pDnode);
S
Shengliang Guan 已提交
175 176 177
    return NULL;
  }

S
Shengliang Guan 已提交
178
  if (dndInitVnodes(pDnode) != 0) {
S
Shengliang Guan 已提交
179
    dError("failed to init vnodes");
S
Shengliang Guan 已提交
180
    dndCleanup(pDnode);
S
Shengliang Guan 已提交
181 182 183
    return NULL;
  }

S
Shengliang Guan 已提交
184
  if (dndInitMnode(pDnode) != 0) {
S
Shengliang Guan 已提交
185
    dError("failed to init mnode");
S
Shengliang Guan 已提交
186
    dndCleanup(pDnode);
S
Shengliang Guan 已提交
187 188 189
    return NULL;
  }

S
Shengliang Guan 已提交
190
  if (dndInitTrans(pDnode) != 0) {
S
Shengliang Guan 已提交
191
    dError("failed to init transport");
S
Shengliang Guan 已提交
192
    dndCleanup(pDnode);
S
Shengliang Guan 已提交
193 194 195
    return NULL;
  }

S
Shengliang Guan 已提交
196 197
  dndSetStat(pDnode, DND_STAT_RUNNING);
  dndReportStartup(pDnode, "TDengine", "initialized successfully");
S
Shengliang Guan 已提交
198 199
  dInfo("TDengine is initialized successfully");

200
  return pDnode;
S
Shengliang Guan 已提交
201 202
}

S
Shengliang Guan 已提交
203 204
void dndCleanup(SDnode *pDnode) {
  if (dndGetStat(pDnode) == DND_STAT_STOPPED) {
S
Shengliang Guan 已提交
205 206 207 208 209
    dError("dnode is shutting down");
    return;
  }

  dInfo("start to cleanup TDengine");
S
Shengliang Guan 已提交
210 211 212 213 214
  dndSetStat(pDnode, DND_STAT_STOPPED);
  dndCleanupTrans(pDnode);
  dndCleanupMnode(pDnode);
  dndCleanupVnodes(pDnode);
  dndCleanupDnode(pDnode);
S
Shengliang Guan 已提交
215 216
  walCleanUp();
  rpcCleanup();
S
Shengliang Guan 已提交
217
  dndCleanupEnv(pDnode);
S
Shengliang Guan 已提交
218
  free(pDnode);
S
Shengliang Guan 已提交
219
  dInfo("TDengine is cleaned up successfully");
S
Shengliang Guan 已提交
220
}