tscSystem.c 12.3 KB
Newer Older
H
hzcheng 已提交
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
slguan 已提交
16
#include "os.h"
H
hzcheng 已提交
17
#include "taosmsg.h"
18
#include "tref.h"
H
hzcheng 已提交
19
#include "trpc.h"
S
TD-2371  
Shengliang Guan 已提交
20
#include "tnote.h"
H
hzcheng 已提交
21 22
#include "ttimer.h"
#include "tutil.h"
S
slguan 已提交
23
#include "tsched.h"
S
slguan 已提交
24
#include "tscLog.h"
25
#include "tscUtil.h"
H
hzcheng 已提交
26
#include "tsclient.h"
S
slguan 已提交
27 28 29 30
#include "tglobal.h"
#include "tconfig.h"
#include "ttimezone.h"
#include "tlocale.h"
S
slguan 已提交
31

H
hzcheng 已提交
32
// global, not configurable
33 34
#define TSC_VAR_NOT_RELEASE 1
#define TSC_VAR_RELEASED    0
H
hzcheng 已提交
35

36 37 38 39 40 41 42 43 44 45
int32_t    sentinel = TSC_VAR_NOT_RELEASE;

SHashObj  *tscVgroupMap;         // hash map to keep the global vgroup info
SHashObj  *tscTableMetaInfo;     // table meta info
int32_t    tscObjRef = -1;
void      *tscTmr;
void      *tscQhandle;
int32_t    tscRefId = -1;
int32_t    tscNumOfObj = 0;         // number of sqlObj in current process.
static void  *tscCheckDiskUsageTmr;
Y
yihaoDeng 已提交
46 47 48
void      *tscRpcCache;            // cache to keep rpc obj
int32_t   tscNumOfThreads = 1;     // num of rpc threads  
static    pthread_mutex_t rpcObjMutex; // mutex to protect open the rpc obj concurrently 
49
static pthread_once_t tscinit = PTHREAD_ONCE_INIT;
D
fix bug  
dapan1121 已提交
50
static volatile int tscInitRes = 0;
L
lihui 已提交
51

S
TD-1413  
Shengliang Guan 已提交
52
void tscCheckDiskUsage(void *UNUSED_PARAM(para), void *UNUSED_PARAM(param)) {
S
slguan 已提交
53
  taosGetDisk();
Y
TD-2957  
yihaoDeng 已提交
54
  taosTmrReset(tscCheckDiskUsage, 20 * 1000, NULL, tscTmr, &tscCheckDiskUsageTmr);
S
slguan 已提交
55
}
Y
yihaoDeng 已提交
56 57 58
void tscFreeRpcObj(void *param) {
  assert(param);
  SRpcObj *pRpcObj = (SRpcObj *)(param);
Y
yihaoDeng 已提交
59
  tscDebug("free rpcObj:%p and free pDnodeConn: %p", pRpcObj, pRpcObj->pDnodeConn);
Y
yihaoDeng 已提交
60 61
  rpcClose(pRpcObj->pDnodeConn);
}
S
slguan 已提交
62

Y
yihaoDeng 已提交
63 64 65
void tscReleaseRpc(void *param)  {
  if (param == NULL) {
    return;
S
slguan 已提交
66
  }
Y
yihaoDeng 已提交
67
  pthread_mutex_lock(&rpcObjMutex);
Y
yihaoDeng 已提交
68
  taosCacheRelease(tscRpcCache, (void *)&param, false); 
Y
yihaoDeng 已提交
69 70
  pthread_mutex_unlock(&rpcObjMutex);
} 
S
slguan 已提交
71

Y
yihaoDeng 已提交
72
int32_t tscAcquireRpc(const char *key, const char *user, const char *secretEncrypt, void **ppRpcObj) {
Y
yihaoDeng 已提交
73 74
  pthread_mutex_lock(&rpcObjMutex);

Y
yihaoDeng 已提交
75
  SRpcObj *pRpcObj = (SRpcObj *)taosCacheAcquireByKey(tscRpcCache, key, strlen(key));
Y
yihaoDeng 已提交
76 77 78 79 80
  if (pRpcObj != NULL) {
    *ppRpcObj = pRpcObj;   
    pthread_mutex_unlock(&rpcObjMutex);
    return 0;
  } 
S
slguan 已提交
81

Y
yihaoDeng 已提交
82 83 84 85
  SRpcInit rpcInit;
  memset(&rpcInit, 0, sizeof(rpcInit));
  rpcInit.localPort = 0;
  rpcInit.label = "TSC";
Y
yihaoDeng 已提交
86
  rpcInit.numOfThreads = tscNumOfThreads * 2;    
Y
yihaoDeng 已提交
87 88 89 90
  rpcInit.cfp = tscProcessMsgFromServer;
  rpcInit.sessions = tsMaxConnections;
  rpcInit.connType = TAOS_CONN_CLIENT;
  rpcInit.user = (char *)user;
Y
yihaoDeng 已提交
91
  rpcInit.idleTime = tsShellActivityTimer * 1000; 
Y
yihaoDeng 已提交
92 93 94 95 96 97 98 99 100 101 102 103 104
  rpcInit.ckey = "key"; 
  rpcInit.spi = 1; 
  rpcInit.secret = (char *)secretEncrypt;

  SRpcObj rpcObj;
  memset(&rpcObj, 0, sizeof(rpcObj));
  strncpy(rpcObj.key, key, strlen(key));
  rpcObj.pDnodeConn = rpcOpen(&rpcInit);
  if (rpcObj.pDnodeConn == NULL) {
    pthread_mutex_unlock(&rpcObjMutex);
    tscError("failed to init connection to TDengine");
    return -1;
  } 
Y
fix bug  
yihaoDeng 已提交
105
  pRpcObj = taosCachePut(tscRpcCache, rpcObj.key, strlen(rpcObj.key), &rpcObj, sizeof(rpcObj), 1000*5);   
Y
yihaoDeng 已提交
106 107 108 109 110 111 112 113
  if (pRpcObj == NULL) {
    rpcClose(rpcObj.pDnodeConn);
    pthread_mutex_unlock(&rpcObjMutex);
    return -1;
  } 

  *ppRpcObj  = pRpcObj;
  pthread_mutex_unlock(&rpcObjMutex);
S
slguan 已提交
114 115 116
  return 0;
}

S
Shengliang Guan 已提交
117
void taos_init_imp(void) {
H
Haojun Liao 已提交
118
  char temp[128]  = {0};
119
  
120
  errno = TSDB_CODE_SUCCESS;
H
hzcheng 已提交
121
  srand(taosGetTimestampSec());
L
lihui 已提交
122
  deltaToUtcInitOnce();
H
hzcheng 已提交
123 124 125 126

  if (tscEmbedded == 0) {

    // Read global configuration.
S
slguan 已提交
127 128
    taosInitGlobalCfg();
    taosReadGlobalLogCfg();
H
hzcheng 已提交
129 130

    // For log directory
131 132 133
    if (mkdir(tsLogDir, 0755) != 0 && errno != EEXIST) {
      printf("failed to create log dir:%s\n", tsLogDir);
    }
H
hzcheng 已提交
134

S
slguan 已提交
135
    sprintf(temp, "%s/taoslog", tsLogDir);
H
hzcheng 已提交
136
    if (taosInitLog(temp, tsNumOfLogLines, 10) < 0) {
S
slguan 已提交
137
      printf("failed to open log file in directory:%s\n", tsLogDir);
H
hzcheng 已提交
138 139
    }

S
slguan 已提交
140
    taosReadGlobalCfg();
D
fix bug  
dapan1121 已提交
141 142 143 144 145
    if (taosCheckGlobalCfg()) {
      tscInitRes = -1;
      return;
    }
    
S
TD-2371  
Shengliang Guan 已提交
146
    taosInitNotes();
H
hzcheng 已提交
147

148
    rpcInit();
149 150
    tscDebug("starting to initialize TAOS client ...");
    tscDebug("Local End Point is:%s", tsLocalEp);
H
hzcheng 已提交
151 152
  }

L
lihui 已提交
153
  taosSetCoreDump();
154
  tscInitMsgsFp();
155
  int queueSize = tsMaxConnections*2;
H
hzcheng 已提交
156

157
  double factor = (tscEmbedded == 0)? 2.0:4.0;
Y
yihaoDeng 已提交
158
  tscNumOfThreads = (int)(tsNumOfCores * tsNumOfThreadsPerCore / factor);
H
Haojun Liao 已提交
159 160 161
  if (tscNumOfThreads < 2) {
    tscNumOfThreads = 2;
  }
Y
patch  
yihaoDeng 已提交
162
  taosTmrThreads = tscNumOfThreads;
H
hzcheng 已提交
163 164

  tscQhandle = taosInitScheduler(queueSize, tscNumOfThreads, "tsc");
S
slguan 已提交
165 166
  if (NULL == tscQhandle) {
    tscError("failed to init scheduler");
D
fix bug  
dapan1121 已提交
167
    tscInitRes = -1;
S
slguan 已提交
168 169
    return;
  }
H
hzcheng 已提交
170

171
  tscTmr = taosTmrInit(tsMaxConnections * 2, 200, 60000, "TSC");
H
Hongze Cheng 已提交
172
  if(0 == tscEmbedded){
Y
TD-2957  
yihaoDeng 已提交
173
    taosTmrReset(tscCheckDiskUsage, 20 * 1000, NULL, tscTmr, &tscCheckDiskUsageTmr);      
S
slguan 已提交
174
  }
H
hzcheng 已提交
175

176
  if (tscTableMetaInfo == NULL) {
H
Haojun Liao 已提交
177
    tscObjRef  = taosOpenRef(40960, tscFreeRegisteredSqlObj);
178
    tscVgroupMap = taosHashInit(256, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
179 180
    tscTableMetaInfo = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
    tscDebug("TableMeta:%p", tscTableMetaInfo);
181
  }
Y
yihaoDeng 已提交
182 183
   
  int refreshTime = 5;
Y
yihaoDeng 已提交
184 185
  tscRpcCache = taosCacheInit(TSDB_DATA_TYPE_BINARY, refreshTime, true, tscFreeRpcObj, "rpcObj");
  pthread_mutex_init(&rpcObjMutex, NULL);
H
hzcheng 已提交
186

陶建辉(Jeff)'s avatar
陶建辉(Jeff) 已提交
187 188
  tscRefId = taosOpenRef(200, tscCloseTscObj);

H
Haojun Liao 已提交
189 190 191 192
  // in other language APIs, taos_cleanup is not available yet.
  // So, to make sure taos_cleanup will be invoked to clean up the allocated
  // resource to suppress the valgrind warning.
  atexit(taos_cleanup);
193
  tscDebug("client is initialized successfully");
H
hzcheng 已提交
194 195
}

D
fix bug  
dapan1121 已提交
196
int taos_init() {     pthread_once(&tscinit, taos_init_imp);  return tscInitRes;}
H
hzcheng 已提交
197

H
Haojun Liao 已提交
198
// this function may be called by user or system, or by both simultaneously.
S
Shengliang Guan 已提交
199
void taos_cleanup(void) {
H
Haojun Liao 已提交
200
  tscDebug("start to cleanup client environment");
H
Haojun Liao 已提交
201

202 203
  if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
    return;
204
  }
H
Haojun Liao 已提交
205

206 207
  taosHashCleanup(tscTableMetaInfo);
  tscTableMetaInfo = NULL;
H
Haojun Liao 已提交
208

209 210 211 212 213 214 215 216 217 218 219 220 221 222
  taosHashCleanup(tscVgroupMap);
  tscVgroupMap = NULL;

  int32_t id = tscObjRef;
  tscObjRef = -1;
  taosCloseRef(id);

  void* p = tscQhandle;
  tscQhandle = NULL;
  taosCleanUpScheduler(p);

  id = tscRefId;
  tscRefId = -1;
  taosCloseRef(id);
H
Haojun Liao 已提交
223 224

  taosCleanupKeywordsTable();
H
Haojun Liao 已提交
225

Y
yihaoDeng 已提交
226 227 228 229 230
  p = tscRpcCache; 
  tscRpcCache = NULL;
  
  if (p != NULL) {
    taosCacheCleanup(p); 
Y
yihaoDeng 已提交
231
    pthread_mutex_destroy(&rpcObjMutex);
H
Haojun Liao 已提交
232
  }
233

Y
TD-2884  
yihaoDeng 已提交
234 235 236 237
  if (tscEmbedded == 0) {
    rpcCleanup();
    taosCloseLog();
  };
H
Haojun Liao 已提交
238

239 240 241
  p = tscTmr;
  tscTmr = NULL;
  taosTmrCleanUp(p);
242 243
}

weixin_48148422's avatar
weixin_48148422 已提交
244
static int taos_options_imp(TSDB_OPTION option, const char *pStr) {
S
slguan 已提交
245
  SGlobalCfg *cfg = NULL;
H
hzcheng 已提交
246 247 248

  switch (option) {
    case TSDB_OPTION_CONFIGDIR:
S
slguan 已提交
249
      cfg = taosGetConfigOption("configDir");
H
hjxilinx 已提交
250 251
      assert(cfg != NULL);
    
S
slguan 已提交
252
      if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
B
Bomin Zhang 已提交
253
        tstrncpy(configDir, pStr, TSDB_FILENAME_LEN);
S
slguan 已提交
254
        cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
255
        tscInfo("set config file directory:%s", pStr);
H
hzcheng 已提交
256
      } else {
weixin_48148422's avatar
weixin_48148422 已提交
257 258
        tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
                tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
H
hzcheng 已提交
259 260
      }
      break;
S
slguan 已提交
261

H
hzcheng 已提交
262
    case TSDB_OPTION_SHELL_ACTIVITY_TIMER:
S
slguan 已提交
263
      cfg = taosGetConfigOption("shellActivityTimer");
H
hjxilinx 已提交
264 265
      assert(cfg != NULL);
    
S
slguan 已提交
266
      if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
weixin_48148422's avatar
weixin_48148422 已提交
267
        tsShellActivityTimer = atoi(pStr);
H
hzcheng 已提交
268 269
        if (tsShellActivityTimer < 1) tsShellActivityTimer = 1;
        if (tsShellActivityTimer > 3600) tsShellActivityTimer = 3600;
S
slguan 已提交
270
        cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
271
        tscInfo("set shellActivityTimer:%d", tsShellActivityTimer);
H
hzcheng 已提交
272
      } else {
weixin_48148422's avatar
weixin_48148422 已提交
273
        tscWarn("config option:%s, input value:%s, is configured by %s, use %d", cfg->option, pStr,
274
                tsCfgStatusStr[cfg->cfgStatus], *(int32_t *)cfg->ptr);
H
hzcheng 已提交
275 276
      }
      break;
S
slguan 已提交
277

H
hzcheng 已提交
278
    case TSDB_OPTION_LOCALE: {  // set locale
S
slguan 已提交
279
      cfg = taosGetConfigOption("locale");
H
hjxilinx 已提交
280 281
      assert(cfg != NULL);
  
H
hzcheng 已提交
282 283
      size_t len = strlen(pStr);
      if (len == 0 || len > TSDB_LOCALE_LEN) {
284
        tscInfo("Invalid locale:%s, use default", pStr);
H
hzcheng 已提交
285 286 287
        return -1;
      }

S
slguan 已提交
288
      if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
H
hzcheng 已提交
289 290
        char sep = '.';

S
slguan 已提交
291 292
        if (strlen(tsLocale) == 0) { // locale does not set yet
          char* defaultLocale = setlocale(LC_CTYPE, "");
S
Shengliang Guan 已提交
293
          tstrncpy(tsLocale, defaultLocale, TSDB_LOCALE_LEN);
S
slguan 已提交
294 295 296
        }

        // set the user specified locale
H
hzcheng 已提交
297 298 299
        char *locale = setlocale(LC_CTYPE, pStr);

        if (locale != NULL) {
300
          tscInfo("locale set, prev locale:%s, new locale:%s", tsLocale, locale);
S
slguan 已提交
301
          cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
S
slguan 已提交
302
        } else { // set the user-specified localed failed, use default LC_CTYPE as current locale
S
slguan 已提交
303
          locale = setlocale(LC_CTYPE, tsLocale);
304
          tscInfo("failed to set locale:%s, current locale:%s", pStr, tsLocale);
H
hzcheng 已提交
305 306
        }

S
Shengliang Guan 已提交
307
        tstrncpy(tsLocale, locale, TSDB_LOCALE_LEN);
H
hzcheng 已提交
308 309 310 311 312 313 314 315

        char *charset = strrchr(tsLocale, sep);
        if (charset != NULL) {
          charset += 1;

          charset = taosCharsetReplace(charset);

          if (taosValidateEncodec(charset)) {
S
slguan 已提交
316
            if (strlen(tsCharset) == 0) {
317
              tscInfo("charset set:%s", charset);
S
slguan 已提交
318
            } else {
319
              tscInfo("charset changed from %s to %s", tsCharset, charset);
S
slguan 已提交
320 321
            }

S
Shengliang Guan 已提交
322
            tstrncpy(tsCharset, charset, TSDB_LOCALE_LEN);
S
slguan 已提交
323
            cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
S
slguan 已提交
324

H
hzcheng 已提交
325
          } else {
326
            tscInfo("charset:%s is not valid in locale, charset remains:%s", charset, tsCharset);
H
hzcheng 已提交
327
          }
S
slguan 已提交
328

H
hzcheng 已提交
329
          free(charset);
S
slguan 已提交
330
        } else { // it may be windows system
331
          tscInfo("charset remains:%s", tsCharset);
H
hzcheng 已提交
332 333
        }
      } else {
weixin_48148422's avatar
weixin_48148422 已提交
334 335
        tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
                tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
H
hzcheng 已提交
336 337 338 339 340 341
      }
      break;
    }

    case TSDB_OPTION_CHARSET: {
      /* set charset will override the value of charset, assigned during system locale changed */
S
slguan 已提交
342
      cfg = taosGetConfigOption("charset");
H
hjxilinx 已提交
343 344
      assert(cfg != NULL);
      
H
hzcheng 已提交
345 346
      size_t len = strlen(pStr);
      if (len == 0 || len > TSDB_LOCALE_LEN) {
347
        tscInfo("failed to set charset:%s", pStr);
H
hzcheng 已提交
348 349 350
        return -1;
      }

S
slguan 已提交
351
      if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
H
hzcheng 已提交
352
        if (taosValidateEncodec(pStr)) {
S
slguan 已提交
353
          if (strlen(tsCharset) == 0) {
354
            tscInfo("charset is set:%s", pStr);
S
slguan 已提交
355
          } else {
356
            tscInfo("charset changed from %s to %s", tsCharset, pStr);
S
slguan 已提交
357 358
          }

S
Shengliang Guan 已提交
359
          tstrncpy(tsCharset, pStr, TSDB_LOCALE_LEN);
S
slguan 已提交
360
          cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
H
hzcheng 已提交
361
        } else {
362
          tscInfo("charset:%s not valid", pStr);
H
hzcheng 已提交
363 364
        }
      } else {
weixin_48148422's avatar
weixin_48148422 已提交
365 366
        tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
                tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
H
hzcheng 已提交
367 368 369 370 371 372
      }

      break;
    }

    case TSDB_OPTION_TIMEZONE:
S
slguan 已提交
373
      cfg = taosGetConfigOption("timezone");
H
hjxilinx 已提交
374 375
      assert(cfg != NULL);
    
S
slguan 已提交
376
      if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
S
Shengliang Guan 已提交
377
        tstrncpy(tsTimezone, pStr, TSDB_TIMEZONE_LEN);
H
hzcheng 已提交
378
        tsSetTimeZone();
S
slguan 已提交
379
        cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
380
        tscDebug("timezone set:%s, input:%s by taos_options", tsTimezone, pStr);
H
hzcheng 已提交
381
      } else {
weixin_48148422's avatar
weixin_48148422 已提交
382 383
        tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
                tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
H
hzcheng 已提交
384 385
      }
      break;
386

H
hzcheng 已提交
387
    default:
H
hjxilinx 已提交
388
      // TODO return the correct error code to client in the format for taos_errstr()
H
hzcheng 已提交
389 390 391 392 393 394
      tscError("Invalid option %d", option);
      return -1;
  }

  return 0;
}
weixin_48148422's avatar
weixin_48148422 已提交
395 396 397 398 399 400

int taos_options(TSDB_OPTION option, const void *arg, ...) {
  static int32_t lock = 0;

  for (int i = 1; atomic_val_compare_exchange_32(&lock, 0, 1) != 0; ++i) {
    if (i % 1000 == 0) {
401
      tscInfo("haven't acquire lock after spin %d times.", i);
weixin_48148422's avatar
weixin_48148422 已提交
402 403 404 405 406 407 408 409
      sched_yield();
    }
  }

  int ret = taos_options_imp(option, (const char*)arg);

  atomic_store_32(&lock, 0);
  return ret;
L
lihui 已提交
410
}