dmEnv.c 6.7 KB
Newer Older
S
shm  
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
17
#include "dmMgmt.h"
S
shm  
Shengliang Guan 已提交
18

19 20 21
static SDnode global = {0};

SDnode *dmInstance() { return &global; }
22 23 24

static int32_t dmCheckRepeatInit(SDnode *pDnode) {
  if (atomic_val_compare_exchange_8(&pDnode->once, DND_ENV_INIT, DND_ENV_READY) != DND_ENV_INIT) {
S
Shengliang Guan 已提交
25
    dError("env is already initialized");
S
shm  
Shengliang Guan 已提交
26 27 28
    terrno = TSDB_CODE_REPEAT_INIT;
    return -1;
  }
29 30
  return 0;
}
S
shm  
Shengliang Guan 已提交
31

32
static int32_t dmInitSystem() {
S
shm  
Shengliang Guan 已提交
33 34 35
  taosIgnSIGPIPE();
  taosBlockSIGPIPE();
  taosResolveCRC();
36 37
  return 0;
}
S
shm  
Shengliang Guan 已提交
38

39
static int32_t dmInitMonitor() {
S
Shengliang 已提交
40 41 42 43 44 45 46 47 48
  SMonCfg monCfg = {0};
  monCfg.maxLogs = tsMonitorMaxLogs;
  monCfg.port = tsMonitorPort;
  monCfg.server = tsMonitorFqdn;
  monCfg.comp = tsMonitorComp;
  if (monInit(&monCfg) != 0) {
    dError("failed to init monitor since %s", terrstr());
    return -1;
  }
49 50 51
  return 0;
}

wafwerar's avatar
wafwerar 已提交
52 53
static bool dmCheckDiskSpace() {
  osUpdate();
wafwerar's avatar
wafwerar 已提交
54 55
  if (!osDataSpaceAvailable()) {
    dError("free disk size: %f GB, too little, require %f GB at least at least , quit", (double)tsDataSpace.size.avail / 1024.0 / 1024.0 / 1024.0, (double)tsDataSpace.reserved / 1024.0 / 1024.0 / 1024.0);
wafwerar's avatar
wafwerar 已提交
56
    terrno = TSDB_CODE_NO_AVAIL_DISK;
wafwerar's avatar
wafwerar 已提交
57 58
    return false;
  }
wafwerar's avatar
wafwerar 已提交
59 60
  if (!osLogSpaceAvailable()) {
    dError("free disk size: %f GB, too little, require %f GB at least at least, quit", (double)tsLogSpace.size.avail / 1024.0 / 1024.0 / 1024.0, (double)tsLogSpace.reserved / 1024.0 / 1024.0 / 1024.0);
wafwerar's avatar
wafwerar 已提交
61
    terrno = TSDB_CODE_NO_AVAIL_DISK;
wafwerar's avatar
wafwerar 已提交
62 63
    return false;
  }
wafwerar's avatar
wafwerar 已提交
64 65
  if (!osTempSpaceAvailable()) {
    dError("free disk size: %f GB, too little, require %f GB at least at least, quit", (double)tsTempSpace.size.avail / 1024.0 / 1024.0 / 1024.0, (double)tsTempSpace.reserved / 1024.0 / 1024.0 / 1024.0);
wafwerar's avatar
wafwerar 已提交
66 67 68 69 70 71 72 73 74 75 76
    terrno = TSDB_CODE_NO_AVAIL_DISK;
    return false;
  }
  return true;
}

static bool dmCheckDataDirVersion() {
  char checkDataDirJsonFileName[PATH_MAX];
  snprintf(checkDataDirJsonFileName, PATH_MAX, "%s/dnode/dnodeCfg.json", tsDataDir);
  if (taosCheckExistFile(checkDataDirJsonFileName)) {
    dError("The default data directory %s contains old data of tdengine 2.x, please clear it before running!", tsDataDir);
wafwerar's avatar
wafwerar 已提交
77 78 79 80 81
    return false;
  }
  return true;
}

82
int32_t dmInit(int8_t rtype) {
S
Shengliang Guan 已提交
83
  dInfo("start to init dnode env");
wafwerar's avatar
wafwerar 已提交
84
  if (!dmCheckDataDirVersion()) return -1;
wafwerar's avatar
wafwerar 已提交
85
  if (!dmCheckDiskSpace()) return -1;
86
  if (dmCheckRepeatInit(dmInstance()) != 0) return -1;
87 88
  if (dmInitSystem() != 0) return -1;
  if (dmInitMonitor() != 0) return -1;
89
  if (dmInitDnode(dmInstance(), rtype) != 0) return -1;
S
Shengliang 已提交
90

S
Shengliang Guan 已提交
91
  dInfo("dnode env is initialized");
S
shm  
Shengliang Guan 已提交
92 93 94
  return 0;
}

95 96
static int32_t dmCheckRepeatCleanup(SDnode *pDnode) {
  if (atomic_val_compare_exchange_8(&pDnode->once, DND_ENV_READY, DND_ENV_CLEANUP) != DND_ENV_READY) {
S
Shengliang Guan 已提交
97
    dError("dnode env is already cleaned up");
98
    return -1;
S
shm  
Shengliang Guan 已提交
99
  }
100 101 102 103
  return 0;
}

void dmCleanup() {
S
Shengliang Guan 已提交
104
  dDebug("start to cleanup dnode env");
105 106 107
  SDnode *pDnode = dmInstance();
  if (dmCheckRepeatCleanup(pDnode) != 0) return;
  dmCleanupDnode(pDnode);
S
shm  
Shengliang Guan 已提交
108
  monCleanup();
S
Shengliang Guan 已提交
109
  syncCleanUp();
S
shm  
Shengliang Guan 已提交
110
  walCleanUp();
S
Shengliang Guan 已提交
111
  udfcClose();
S
Shengliang 已提交
112
  udfStopUdfd();
S
shm  
Shengliang Guan 已提交
113
  taosStopCacheRefreshWorker();
S
Shengliang Guan 已提交
114
  dInfo("dnode env is cleaned up");
115 116 117 118 119 120

  taosCloseLog();
  taosCleanupCfg();
}

void dmStop() {
121
  SDnode *pDnode = dmInstance();
122 123 124 125
  pDnode->stop = true;
}

int32_t dmRun() {
126
  SDnode *pDnode = dmInstance();
127 128 129 130
  return dmRunDnode(pDnode);
}

static int32_t dmProcessCreateNodeReq(EDndNodeType ntype, SRpcMsg *pMsg) {
131
  SDnode *pDnode = dmInstance();
132 133 134 135 136 137 138 139 140 141 142

  SMgmtWrapper *pWrapper = dmAcquireWrapper(pDnode, ntype);
  if (pWrapper != NULL) {
    dmReleaseWrapper(pWrapper);
    terrno = TSDB_CODE_NODE_ALREADY_DEPLOYED;
    dError("failed to create node since %s", terrstr());
    return -1;
  }

  pWrapper = &pDnode->wrappers[ntype];
  if (taosMkDir(pWrapper->path) != 0) {
143
    dmReleaseWrapper(pWrapper);
144 145 146 147 148
    terrno = TAOS_SYSTEM_ERROR(errno);
    dError("failed to create dir:%s since %s", pWrapper->path, terrstr());
    return -1;
  }

149
  taosThreadMutexLock(&pDnode->mutex);
150 151
  SMgmtInputOpt input = dmBuildMgmtInputOpt(pWrapper);

152
  dInfo("node:%s, start to create", pWrapper->name);
153 154 155 156
  int32_t code = (*pWrapper->func.createFp)(&input, pMsg);
  if (code != 0) {
    dError("node:%s, failed to create since %s", pWrapper->name, terrstr());
  } else {
157
    dInfo("node:%s, has been created", pWrapper->name);
S
Shengliang Guan 已提交
158
    code = dmOpenNode(pWrapper);
S
Shengliang Guan 已提交
159
    if (code == 0) {
S
Shengliang Guan 已提交
160 161
      code = dmStartNode(pWrapper);
    }
162
    pWrapper->deployed = true;
S
Shengliang Guan 已提交
163
    pWrapper->required = true;
164 165 166 167 168 169 170 171
    pWrapper->proc.ptype = pDnode->ptype;
  }

  taosThreadMutexUnlock(&pDnode->mutex);
  return code;
}

static int32_t dmProcessDropNodeReq(EDndNodeType ntype, SRpcMsg *pMsg) {
172
  SDnode *pDnode = dmInstance();
173 174 175 176 177 178 179 180 181

  SMgmtWrapper *pWrapper = dmAcquireWrapper(pDnode, ntype);
  if (pWrapper == NULL) {
    terrno = TSDB_CODE_NODE_NOT_DEPLOYED;
    dError("failed to drop node since %s", terrstr());
    return -1;
  }

  taosThreadMutexLock(&pDnode->mutex);
182
  SMgmtInputOpt input = dmBuildMgmtInputOpt(pWrapper);
183

184 185
  dInfo("node:%s, start to drop", pWrapper->name);
  int32_t code = (*pWrapper->func.dropFp)(&input, pMsg);
186 187 188
  if (code != 0) {
    dError("node:%s, failed to drop since %s", pWrapper->name, terrstr());
  } else {
189
    dInfo("node:%s, has been dropped", pWrapper->name);
190 191 192 193 194 195 196
    pWrapper->required = false;
    pWrapper->deployed = false;
  }

  dmReleaseWrapper(pWrapper);

  if (code == 0) {
197
    dmStopNode(pWrapper);
198 199 200 201 202 203 204 205 206 207 208
    dmCloseNode(pWrapper);
    taosRemoveDir(pWrapper->path);
  }
  taosThreadMutexUnlock(&pDnode->mutex);
  return code;
}

SMgmtInputOpt dmBuildMgmtInputOpt(SMgmtWrapper *pWrapper) {
  SMgmtInputOpt opt = {
      .path = pWrapper->path,
      .name = pWrapper->name,
209
      .pData = &pWrapper->pDnode->data,
210 211
      .processCreateNodeFp = dmProcessCreateNodeReq,
      .processDropNodeFp = dmProcessDropNodeReq,
S
Shengliang Guan 已提交
212 213 214
      .sendMonitorReportFp = dmSendMonitorReport,
      .getVnodeLoadsFp = dmGetVnodeLoads,
      .getMnodeLoadsFp = dmGetMnodeLoads,
D
dapan1121 已提交
215
      .getQnodeLoadsFp = dmGetQnodeLoads,
216 217
  };

218
  opt.msgCb = dmGetMsgcb(pWrapper->pDnode);
219 220 221 222
  return opt;
}

void dmReportStartup(const char *pName, const char *pDesc) {
223
  SStartupInfo *pStartup = &(dmInstance()->startup);
224 225 226
  tstrncpy(pStartup->name, pName, TSDB_STEP_NAME_LEN);
  tstrncpy(pStartup->desc, pDesc, TSDB_STEP_DESC_LEN);
  dDebug("step:%s, %s", pStartup->name, pStartup->desc);
S
shm  
Shengliang Guan 已提交
227
}