dmMgmt.c 9.3 KB
Newer Older
S
shm  
Shengliang Guan 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * 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/>.
 */

S
shm  
Shengliang Guan 已提交
16
#define _DEFAULT_SOURCE
S
Shengliang Guan 已提交
17
#include "dmMgmt.h"
S
Shengliang Guan 已提交
18
#include "dmNodes.h"
dengyihao's avatar
dengyihao 已提交
19
#include "index.h"
S
Shengliang Guan 已提交
20
#include "qworker.h"
S
Shengliang Guan 已提交
21

22
static bool dmRequireNode(SDnode *pDnode, SMgmtWrapper *pWrapper) {
S
Shengliang Guan 已提交
23
  SMgmtInputOpt input = dmBuildMgmtInputOpt(pWrapper);
S
Shengliang Guan 已提交
24 25

  bool    required = false;
S
Shengliang Guan 已提交
26
  int32_t code = (*pWrapper->func.requiredFp)(&input, &required);
S
Shengliang Guan 已提交
27 28 29 30
  if (!required) {
    dDebug("node:%s, does not require startup", pWrapper->name);
  }

31 32 33 34 35 36 37 38 39 40 41 42
  if (pWrapper->ntype == DNODE) {
    if (pDnode->rtype != DNODE && pDnode->rtype != NODE_END) {
      required = false;
      dDebug("node:%s, does not require startup in child process", pWrapper->name);
    }
  } else {
    if (OnlyInChildProc(pWrapper)) {
      if (pWrapper->ntype != pDnode->rtype) {
        dDebug("node:%s, does not require startup in child process", pWrapper->name);
        required = false;
      }
    }
S
Shengliang Guan 已提交
43 44
  }

S
Shengliang Guan 已提交
45 46 47 48
  if (required) {
    dDebug("node:%s, required to startup", pWrapper->name);
  }

S
Shengliang Guan 已提交
49 50
  return required;
}
S
Shengliang Guan 已提交
51

52 53
static int32_t dmInitVars(SDnode *pDnode, EDndNodeType rtype) {
  pDnode->rtype = rtype;
S
Shengliang Guan 已提交
54 55 56 57 58 59 60 61 62 63 64 65 66

  if (tsMultiProcess == 0) {
    pDnode->ptype = DND_PROC_SINGLE;
    dInfo("dnode will run in single-process mode");
  } else if (tsMultiProcess > 1) {
    pDnode->ptype = DND_PROC_TEST;
    dInfo("dnode will run in multi-process test mode");
  } else if (pDnode->rtype == DNODE || pDnode->rtype == NODE_END) {
    pDnode->ptype = DND_PROC_PARENT;
    dInfo("dnode will run in parent-process mode");
  } else {
    pDnode->ptype = DND_PROC_CHILD;
    SMgmtWrapper *pWrapper = &pDnode->wrappers[pDnode->rtype];
S
Shengliang Guan 已提交
67
    dInfo("dnode will run in child-process mode, node:%s", dmNodeName(pDnode->rtype));
S
Shengliang Guan 已提交
68 69
  }

S
Shengliang Guan 已提交
70 71 72 73 74 75 76 77
  SDnodeData *pData = &pDnode->data;
  pData->dnodeId = 0;
  pData->clusterId = 0;
  pData->dnodeVer = 0;
  pData->updateTime = 0;
  pData->rebootTime = taosGetTimestampMs();
  pData->dropped = 0;
  pData->stopped = 0;
S
shm  
Shengliang Guan 已提交
78

S
Shengliang Guan 已提交
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
  pData->dnodeHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
  if (pData->dnodeHash == NULL) {
    dError("failed to init dnode hash");
    terrno = TSDB_CODE_OUT_OF_MEMORY;
    return -1;
  }

  if (dmReadEps(pData) != 0) {
    dError("failed to read file since %s", terrstr());
    return -1;
  }

  if (pData->dropped) {
    dError("dnode will not start since its already dropped");
    return -1;
  }

96
  taosThreadRwlockInit(&pData->lock, NULL);
97
  taosThreadMutexInit(&pDnode->mutex, NULL);
S
shm  
Shengliang Guan 已提交
98 99 100
  return 0;
}

S
Shengliang Guan 已提交
101
static void dmClearVars(SDnode *pDnode) {
S
Shengliang Guan 已提交
102 103 104
  for (EDndNodeType ntype = DNODE; ntype < NODE_END; ++ntype) {
    SMgmtWrapper *pWrapper = &pDnode->wrappers[ntype];
    taosMemoryFreeClear(pWrapper->path);
105
    taosThreadRwlockDestroy(&pWrapper->lock);
S
Shengliang Guan 已提交
106 107 108 109 110 111 112
  }
  if (pDnode->lockfile != NULL) {
    taosUnLockFile(pDnode->lockfile);
    taosCloseFile(&pDnode->lockfile);
    pDnode->lockfile = NULL;
  }

S
Shengliang Guan 已提交
113
  SDnodeData *pData = &pDnode->data;
114
  taosThreadRwlockWrlock(&pData->lock);
S
Shengliang Guan 已提交
115 116 117 118 119 120 121 122
  if (pData->dnodeEps != NULL) {
    taosArrayDestroy(pData->dnodeEps);
    pData->dnodeEps = NULL;
  }
  if (pData->dnodeHash != NULL) {
    taosHashCleanup(pData->dnodeHash);
    pData->dnodeHash = NULL;
  }
123
  taosThreadRwlockUnlock(&pData->lock);
S
Shengliang Guan 已提交
124

125
  taosThreadRwlockDestroy(&pData->lock);
S
Shengliang Guan 已提交
126 127
  taosThreadMutexDestroy(&pDnode->mutex);
  memset(&pDnode->mutex, 0, sizeof(pDnode->mutex));
S
shm  
Shengliang Guan 已提交
128 129
}

130
int32_t dmInitDnode(SDnode *pDnode, EDndNodeType rtype) {
S
Shengliang Guan 已提交
131
  dInfo("start to create dnode");
S
shm  
Shengliang Guan 已提交
132
  int32_t code = -1;
S
Shengliang Guan 已提交
133
  char    path[PATH_MAX + 100] = {0};
S
shm  
Shengliang Guan 已提交
134

135
  if (dmInitVars(pDnode, rtype) != 0) {
S
Shengliang Guan 已提交
136 137 138
    goto _OVER;
  }

S
Shengliang Guan 已提交
139 140 141 142 143 144
  pDnode->wrappers[DNODE].func = dmGetMgmtFunc();
  pDnode->wrappers[MNODE].func = mmGetMgmtFunc();
  pDnode->wrappers[VNODE].func = vmGetMgmtFunc();
  pDnode->wrappers[QNODE].func = qmGetMgmtFunc();
  pDnode->wrappers[SNODE].func = smGetMgmtFunc();
  pDnode->wrappers[BNODE].func = bmGetMgmtFunc();
S
shm  
Shengliang Guan 已提交
145

S
Shengliang 已提交
146 147
  for (EDndNodeType ntype = DNODE; ntype < NODE_END; ++ntype) {
    SMgmtWrapper *pWrapper = &pDnode->wrappers[ntype];
148
    pWrapper->pDnode = pDnode;
S
Shengliang Guan 已提交
149
    pWrapper->name = dmNodeName(ntype);
S
Shengliang Guan 已提交
150 151 152 153 154 155 156 157
    pWrapper->ntype = ntype;
    pWrapper->proc.wrapper = pWrapper;
    pWrapper->proc.shm.id = -1;
    pWrapper->proc.pid = -1;
    pWrapper->proc.ptype = pDnode->ptype;
    if (ntype == DNODE) {
      pWrapper->proc.ptype = DND_PROC_SINGLE;
    }
158
    taosThreadRwlockInit(&pWrapper->lock, NULL);
S
Shengliang Guan 已提交
159

160
    snprintf(path, sizeof(path), "%s%s%s", tsDataDir, TD_DIRSEP, pWrapper->name);
S
Shengliang Guan 已提交
161
    pWrapper->path = strdup(path);
S
shm  
Shengliang Guan 已提交
162 163 164 165 166
    if (pWrapper->path == NULL) {
      terrno = TSDB_CODE_OUT_OF_MEMORY;
      goto _OVER;
    }

167
    pWrapper->required = dmRequireNode(pDnode, pWrapper);
S
Shengliang Guan 已提交
168

S
Shengliang Guan 已提交
169
    if (ntype != DNODE && dmReadShmFile(pWrapper->path, pWrapper->name, pDnode->rtype, &pWrapper->proc.shm) != 0) {
S
Shengliang Guan 已提交
170 171 172
      dError("node:%s, failed to read shm file since %s", pWrapper->name, terrstr());
      goto _OVER;
    }
S
shm  
Shengliang Guan 已提交
173 174
  }

S
Shengliang Guan 已提交
175
  if (dmInitMsgHandle(pDnode) != 0) {
S
Shengliang Guan 已提交
176
    dError("failed to init msg handles since %s", terrstr());
S
shm  
Shengliang Guan 已提交
177 178 179
    goto _OVER;
  }

180
  if (pDnode->ptype == SINGLE_PROC || (pDnode->ptype & PARENT_PROC)) {
181
    pDnode->lockfile = dmCheckRunning(tsDataDir);
S
Shengliang Guan 已提交
182 183 184 185 186 187 188 189 190 191
    if (pDnode->lockfile == NULL) {
      goto _OVER;
    }

    if (dmInitServer(pDnode) != 0) {
      dError("failed to init transport since %s", terrstr());
      goto _OVER;
    }
  }

S
Shengliang Guan 已提交
192 193 194 195
  if (dmInitClient(pDnode) != 0) {
    goto _OVER;
  }

196
  dmReportStartup("dnode-transport", "initialized");
S
Shengliang Guan 已提交
197
  dDebug("dnode is created, ptr:%p", pDnode);
S
shm  
Shengliang Guan 已提交
198 199 200
  code = 0;

_OVER:
S
Shengliang Guan 已提交
201
  if (code != 0 && pDnode != NULL) {
S
Shengliang Guan 已提交
202
    dmClearVars(pDnode);
203
    pDnode = NULL;
S
shm  
Shengliang Guan 已提交
204
    dError("failed to create dnode since %s", terrstr());
S
shm  
Shengliang Guan 已提交
205 206
  }

207
  return code;
S
shm  
Shengliang Guan 已提交
208 209
}

210
void dmCleanupDnode(SDnode *pDnode) {
S
shm  
Shengliang Guan 已提交
211
  if (pDnode == NULL) return;
S
Shengliang Guan 已提交
212 213 214

  dmCleanupClient(pDnode);
  dmCleanupServer(pDnode);
S
Shengliang Guan 已提交
215
  dmClearVars(pDnode);
dengyihao's avatar
dengyihao 已提交
216
  rpcCleanup();
dengyihao's avatar
dengyihao 已提交
217
  indexCleanup();
S
Shengliang Guan 已提交
218
  dDebug("dnode is closed, ptr:%p", pDnode);
S
shm  
Shengliang Guan 已提交
219
}
S
Shengliang Guan 已提交
220 221 222 223 224 225 226 227 228 229 230 231

void dmSetStatus(SDnode *pDnode, EDndRunStatus status) {
  if (pDnode->status != status) {
    dDebug("dnode status set from %s to %s", dmStatStr(pDnode->status), dmStatStr(status));
    pDnode->status = status;
  }
}

SMgmtWrapper *dmAcquireWrapper(SDnode *pDnode, EDndNodeType ntype) {
  SMgmtWrapper *pWrapper = &pDnode->wrappers[ntype];
  SMgmtWrapper *pRetWrapper = pWrapper;

232
  taosThreadRwlockRdlock(&pWrapper->lock);
S
Shengliang Guan 已提交
233 234
  if (pWrapper->deployed) {
    int32_t refCount = atomic_add_fetch_32(&pWrapper->refCount, 1);
S
Shengliang Guan 已提交
235
    // dTrace("node:%s, is acquired, ref:%d", pWrapper->name, refCount);
S
Shengliang Guan 已提交
236 237 238 239
  } else {
    terrno = TSDB_CODE_NODE_NOT_DEPLOYED;
    pRetWrapper = NULL;
  }
240
  taosThreadRwlockUnlock(&pWrapper->lock);
S
Shengliang Guan 已提交
241 242 243 244 245 246 247

  return pRetWrapper;
}

int32_t dmMarkWrapper(SMgmtWrapper *pWrapper) {
  int32_t code = 0;

248
  taosThreadRwlockRdlock(&pWrapper->lock);
249
  if (pWrapper->deployed || (InParentProc(pWrapper) && pWrapper->required)) {
S
Shengliang Guan 已提交
250
    int32_t refCount = atomic_add_fetch_32(&pWrapper->refCount, 1);
S
Shengliang Guan 已提交
251
    // dTrace("node:%s, is marked, ref:%d", pWrapper->name, refCount);
S
Shengliang Guan 已提交
252 253 254 255
  } else {
    terrno = TSDB_CODE_NODE_NOT_DEPLOYED;
    code = -1;
  }
256
  taosThreadRwlockUnlock(&pWrapper->lock);
S
Shengliang Guan 已提交
257 258 259 260 261 262 263

  return code;
}

void dmReleaseWrapper(SMgmtWrapper *pWrapper) {
  if (pWrapper == NULL) return;

264
  taosThreadRwlockRdlock(&pWrapper->lock);
S
Shengliang Guan 已提交
265
  int32_t refCount = atomic_sub_fetch_32(&pWrapper->refCount, 1);
266
  taosThreadRwlockUnlock(&pWrapper->lock);
S
Shengliang Guan 已提交
267
  // dTrace("node:%s, is released, ref:%d", pWrapper->name, refCount);
S
Shengliang Guan 已提交
268 269
}

270
static void dmGetServerStartupStatus(SDnode *pDnode, SServerStatusRsp *pStatus) {
S
Shengliang Guan 已提交
271
  SDnodeMgmt *pMgmt = pDnode->wrappers[DNODE].pMgmt;
S
Shengliang Guan 已提交
272 273 274 275 276
  pStatus->details[0] = 0;

  if (pDnode->status == DND_STAT_INIT) {
    pStatus->statusCode = TSDB_SRV_STATUS_NETWORK_OK;
    snprintf(pStatus->details, sizeof(pStatus->details), "%s: %s", pDnode->startup.name, pDnode->startup.desc);
277
  } else if (pDnode->status == DND_STAT_STOPPED) {
S
Shengliang Guan 已提交
278
    pStatus->statusCode = TSDB_SRV_STATUS_EXTING;
279 280
  } else {
    pStatus->statusCode = TSDB_SRV_STATUS_SERVICE_OK;
S
Shengliang Guan 已提交
281 282 283
  }
}

S
Shengliang Guan 已提交
284
void dmProcessNetTestReq(SDnode *pDnode, SRpcMsg *pMsg) {
S
Shengliang Guan 已提交
285
  dDebug("msg:%p, net test req will be processed", pMsg);
S
Shengliang Guan 已提交
286 287

  SRpcMsg rsp = {.info = pMsg->info};
S
Shengliang Guan 已提交
288
  rsp.pCont = rpcMallocCont(pMsg->contLen);
S
Shengliang Guan 已提交
289 290 291
  if (rsp.pCont == NULL) {
    rsp.code = TSDB_CODE_OUT_OF_MEMORY;
  } else {
S
Shengliang Guan 已提交
292
    rsp.contLen = pMsg->contLen;
S
Shengliang Guan 已提交
293
  }
S
Shengliang Guan 已提交
294

S
Shengliang Guan 已提交
295
  rpcSendResponse(&rsp);
S
Shengliang Guan 已提交
296
  rpcFreeCont(pMsg->pCont);
S
Shengliang Guan 已提交
297 298
}

S
Shengliang Guan 已提交
299
void dmProcessServerStartupStatus(SDnode *pDnode, SRpcMsg *pMsg) {
S
Shengliang Guan 已提交
300
  dDebug("msg:%p, server startup status req will be processed", pMsg);
S
Shengliang Guan 已提交
301

S
Shengliang Guan 已提交
302
  SServerStatusRsp statusRsp = {0};
303
  dmGetServerStartupStatus(pDnode, &statusRsp);
S
Shengliang Guan 已提交
304

S
Shengliang Guan 已提交
305 306 307 308 309 310 311 312 313 314
  SRpcMsg rsp = {.info = pMsg->info};
  int32_t contLen = tSerializeSServerStatusRsp(NULL, 0, &statusRsp);
  if (contLen < 0) {
    rsp.code = TSDB_CODE_OUT_OF_MEMORY;
  } else {
    rsp.pCont = rpcMallocCont(contLen);
    if (rsp.pCont != NULL) {
      tSerializeSServerStatusRsp(rsp.pCont, contLen, &statusRsp);
      rsp.contLen = contLen;
    }
S
Shengliang Guan 已提交
315 316
  }

S
Shengliang Guan 已提交
317 318
  rpcSendResponse(&rsp);
  rpcFreeCont(pMsg->pCont);
S
Shengliang Guan 已提交
319
}