mirror of
https://github.com/taosdata/TDengine
synced 2026-05-24 10:09:01 +00:00
* fix: windows compile issue * test: add vtable cases (#31829) * fix: windows compile issues * test:add test cases * fix: windows compile issue * case: em-4 stream case submit * test: stream4_sub1 found bug2 * test: submit test_scene_meters_bug2.py * add stream parameters example * feat: [TS-6100] Do not translate const value as column. * Feat/ts 6100 3.0 zlv (#31747) * modify asan exampel * modify asan exampel * add example * add example * modify case example --------- Co-authored-by: zelv01 <1101510017@qq.com> * feat(stream): fix memory leak * modify sliding example * test: update test case. * feat(stream): fix conflicts * fix: add offset case 10a 10s 10m 10h 10d * feat(stream): fix conflicts * chore(stream): rename case name #TS-6100 * add case * modify example * fix: windows compile issues * fix: data null check * feat: [TS-6100] Forbid where when using %%trows (#31827) * feat: [TS-6100] Forbid where when using %%trows * test: update cases * feat: [TS-6100] Fix leaks. --------- Co-authored-by: Simon Guan <guanshengliang@qq.com> * test: reproduce bugs * test: update test case. * test: update test case. * feat: [TS-6100] Fix leaks. * test: add cases * Feat/ts 6100 3.0.pw10 (#31841) * enh: add operator reset func * fix: merge join reset issue * fix: memory issues * fix: add debug assert * fix: memory issues * fix: memory leak * fix: memory issues * fix taos log miss * fix: case issue * fix: case issue * fix: case issues * fix: drop dnode issue * fix: memory issues * fix: memory issues * fix: memory leak issues * fix: recalculate time range issue * fix: add debug log * fix: memory issues * fix: enable case asan * Update streamlist_for_ci.task * fix: case asan issue * fix: stream name issue * fix: external window compile issues * fix: deploy memory issue * fix: ahandle issue * fix: ahandle issue * fix: ahandle issue * fix: virtual table reader list issue * fix: log info * fix: msg error * fix: virtual table addr list issue * fix: memory issues * fix: memory leak issue * fix: memory issues * fix: memory free issues * fix: memory issues * fix: snode deploy issue * fix: mnode reader issue * fix: memory issues * fix: add debug test * enh: add ignore nodata trigger * fix: memory leaks * fix: configuration issue * fix: memory issue * fix: external window issue * fix: external window issues * fix: external window placeholder issue * fix: placeholder function init issues * fix: memory leak issue * fix: add debug log * fix: compile issues * fix: double free issue * fix: runner addr update issue * fix: msg rsp issue * fix: external window reset issue * fix: configuration issue * fix: deploy msg issue * fix: compile issue --------- Co-authored-by: huohong <sallyhuo@taosdata.com> * test: reproduce bugs * fix: add sliding interval combine case * test: add cases * test: add recalc test. * test: reproduce bugs * case : add vt ts is null check * modify case * bug: submit test_idmp_meters_bug3.py * test: add test for recalc. * test: add cases * fix: error code check * test: add cases * fix(stream): scan wal with schema in that version * add case * test: add cases * test: update test case. * fix: windows compile issues * add case * test: add cases (#31845) * modify case * fix: reset interpPrev * test: add test_idmp_meters bug4 and bug3 * add case * fix(stream): opti wal interface * fix: remove test_idmp_meters_bug5.py * test: add cases * fix(stream): fix ts data fetch for virtual tables * cancel asan case * test: update test case. * test: update test case. * add case * test: add cases * test: add cases * test: add case test_idmp_meters_bug5.py * test: update test case. * fix(stream): tmq error * test: add cases * feat: [TS-6100] Restore deleted code in mndSma.c since they are still in use. * fix(stream): optimize val scan logic * test: add test_recalc_expired_time.py to ci. * test: update test case. * test: update test case. * feat: [TS-6100] Fix fill range check * fix(stream): optimize val scan logic * add case * test: modify for partition by %%1 * test: add fun case stream4_sub7 * fix(stream): optimize val scan logic * add case * feat: [TS-6100] Rename OPTIONS to STREAM_OPTIONS. * test: add test for recalc. * test: use stream_options. * fix: some cases error. * test: remove recalc from ci. * fix: ci case issues (#31880) * enh: add operator reset func * fix: merge join reset issue * fix: memory issues * fix: add debug assert * fix: memory issues * fix: memory leak * fix: memory issues * fix taos log miss * fix: case issue * fix: case issue * fix: case issues * fix: drop dnode issue * fix: memory issues * fix: memory issues * fix: memory leak issues * fix: recalculate time range issue * fix: add debug log * fix: memory issues * fix: enable case asan * Update streamlist_for_ci.task * fix: case asan issue * fix: stream name issue * fix: external window compile issues * fix: deploy memory issue * fix: ahandle issue * fix: ahandle issue * fix: ahandle issue * fix: virtual table reader list issue * fix: log info * fix: msg error * fix: virtual table addr list issue * fix: memory issues * fix: memory leak issue * fix: memory issues * fix: memory free issues * fix: memory issues * fix: snode deploy issue * fix: mnode reader issue * fix: memory issues * fix: add debug test * enh: add ignore nodata trigger * fix: memory leaks * fix: configuration issue * fix: memory issue * fix: external window issue * fix: external window issues * fix: external window placeholder issue * fix: placeholder function init issues * fix: memory leak issue * fix: add debug log * fix: compile issues * fix: double free issue * fix: runner addr update issue * fix: msg rsp issue * fix: external window reset issue * fix: configuration issue * fix: deploy msg issue * fix: compile issue * fix: external window idx issue * fix: ci issues --------- Co-authored-by: huohong <sallyhuo@taosdata.com> * fix(stream): fix compilation error * fix(stream): optimize val scan logic * test:add test cases * test: modify case * fix: external agg error * test(stream): tobacco scene testing #TD-36514 * test: add stream cases (#31885) * fix: windows compile issue * fix: calc timerange * fix: windows compile issue * modify case * fix(stream): compile error * test: remove one debug test case file * test: modify * test: add test cases * test: reproduce bugs * test: reproduce bugs * feat: [TS-6100] Placeholder function should only appera in SELECT and… (#31868) * feat: [TS-6100] Placeholder function should only appera in SELECT and WHERE and FROM. * test: update case --------- Co-authored-by: Simon Guan <guanshengliang@qq.com> * add example * add example * modify case example * modify case * test:alter sql * test: add stream5 case * fix(stream): get schema error with version * test: add delete recalc test py. * test: remove bug cases * test: stream5 case test passed * test: add state cases (#31893) * fix(stream): compile error * test: modify case * test: add cases * test: add test. * test: update test case. * chore(test): fix case err * test: update test case. * fix: align data get * fix(stream): fix row index of datablock written into data cache * fix: put align data * test: update test case. * test: add test cases for virtual table * chore(test): fix case err #TD-36514 * add case * test: add test for water mark. * test: add meters bug6 for stream5 * test: add cases (#31903) * test: add test for recalc. * feat: [TS-6100] %%trows can only be used when event type is window close. * test: add precision of database for ms/us/ns * modify case * add case * add case * test: add test to ci. * modify case * fix: ci case issues (#31904) * enh: add operator reset func * fix: merge join reset issue * fix: memory issues * fix: add debug assert * fix: memory issues * fix: memory leak * fix: memory issues * fix taos log miss * fix: case issue * fix: case issue * fix: case issues * fix: drop dnode issue * fix: memory issues * fix: memory issues * fix: memory leak issues * fix: recalculate time range issue * fix: add debug log * fix: memory issues * fix: enable case asan * Update streamlist_for_ci.task * fix: case asan issue * fix: stream name issue * fix: external window compile issues * fix: deploy memory issue * fix: ahandle issue * fix: ahandle issue * fix: ahandle issue * fix: virtual table reader list issue * fix: log info * fix: msg error * fix: virtual table addr list issue * fix: memory issues * fix: memory leak issue * fix: memory issues * fix: memory free issues * fix: memory issues * fix: snode deploy issue * fix: mnode reader issue * fix: memory issues * fix: add debug test * enh: add ignore nodata trigger * fix: memory leaks * fix: configuration issue * fix: memory issue * fix: external window issue * fix: external window issues * fix: external window placeholder issue * fix: placeholder function init issues * fix: memory leak issue * fix: add debug log * fix: compile issues * fix: double free issue * fix: runner addr update issue * fix: msg rsp issue * fix: external window reset issue * fix: configuration issue * fix: deploy msg issue * fix: compile issue * fix: external window idx issue * fix: ci issues * fix: ci case issues * fix: drop dnode issue --------- Co-authored-by: huohong <sallyhuo@taosdata.com> * fix(stream): ci error * test: update test case. * feat: [TS-6100] Disable some failed UT. * feat: [TS-6100] Fix virtual table * test: add bug 5. * test: add test delete recalc to ci. * test: add bug 6. * test(stream): tobacco scene #TD-36514 * fix: reqCids,reqCols memory leak in SSTriggerRealtimeContext Co-authored-by: Tony Zhang <tonyzhang@taosdata.com> * test: add case stream6 * fix(stream): implement some pending features in trigger task * modify case * modify case * fix: case issues * modify case * test: add recalc for warter mark. * fix(stream): fix count window trigger of virtual tables * fix(stream): memory leak * test: fix run err. * test: add stream6 bug7 * fix: adjust format * test(stream): tobacco scene testing #TD-36514 * test: change bug7 with update window1 and 2 * test: add test bug 7. * case: restore write 3 window * fix: windows compile issue * fix: notify * test: add cases * modify case * test: update test case. * test(stream): toobacco scene testing #TD-36514 --------- Co-authored-by: Simon Guan <slguan@taosdata.com> Co-authored-by: plum-lihui <huili@taosdata.com> Co-authored-by: Alex Duan <417921451@qq.com> Co-authored-by: zelv01 <1101510017@qq.com> Co-authored-by: Jing Sima <simondominic9997@outlook.com> Co-authored-by: xiangyang guo <66111494+happyguoxy@users.noreply.github.com> Co-authored-by: wangmm0220 <wangmm0220@gmail.com> Co-authored-by: Haojun Liao <hjliao@taosdata.com> Co-authored-by: zyyang90 <zyyang@taosdata.com> Co-authored-by: Alex Duan <51781608+DuanKuanJun@users.noreply.github.com> Co-authored-by: facetosea <285808407@qq.com> Co-authored-by: Simon Guan <guanshengliang@qq.com> Co-authored-by: huohong <sallyhuo@taosdata.com> Co-authored-by: Li Hui <52318143+plum-lihui@users.noreply.github.com> Co-authored-by: Jinqing Kuang <kuangjinqingcn@gmail.com> Co-authored-by: xiao-77 <berylbao@taosdata.com> Co-authored-by: Zhixiao Bao <62235797+xiao-77@users.noreply.github.com> Co-authored-by: happyguoxy <happy_guoxy@163.com> Co-authored-by: Tony Zhang <34825804+Tony2h@users.noreply.github.com> Co-authored-by: Tony Zhang <tonyzhang@taosdata.com>
705 lines
18 KiB
C
705 lines
18 KiB
C
/*
|
|
* 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
|
|
#include "crypt.h"
|
|
#include "dmUtil.h"
|
|
#include "tchecksum.h"
|
|
#include "tgrant.h"
|
|
#include "tjson.h"
|
|
|
|
#define MAXLEN 1024
|
|
#define DM_KEY_INDICATOR "this indicator!"
|
|
#define DM_ENCRYPT_CODE_FILE "encryptCode.cfg"
|
|
#define DM_CHECK_CODE_FILE "checkCode.bin"
|
|
|
|
static int32_t dmDecodeFile(SJson *pJson, bool *deployed) {
|
|
int32_t code = 0;
|
|
int32_t value = 0;
|
|
|
|
tjsonGetInt32ValueFromDouble(pJson, "deployed", value, code);
|
|
if (code < 0) return code;
|
|
|
|
*deployed = (value != 0);
|
|
return code;
|
|
}
|
|
|
|
int32_t dmReadFile(const char *path, const char *name, bool *pDeployed) {
|
|
int32_t code = -1;
|
|
TdFilePtr pFile = NULL;
|
|
char *content = NULL;
|
|
SJson *pJson = NULL;
|
|
char file[PATH_MAX] = {0};
|
|
int32_t nBytes = snprintf(file, sizeof(file), "%s%s%s.json", path, TD_DIRSEP, name);
|
|
if (nBytes <= 0 || nBytes >= PATH_MAX) {
|
|
code = TSDB_CODE_OUT_OF_BUFFER;
|
|
goto _OVER;
|
|
}
|
|
|
|
if (taosStatFile(file, NULL, NULL, NULL) < 0) {
|
|
dInfo("file:%s not exist", file);
|
|
code = 0;
|
|
goto _OVER;
|
|
}
|
|
|
|
pFile = taosOpenFile(file, TD_FILE_READ);
|
|
if (pFile == NULL) {
|
|
code = terrno;
|
|
dError("failed to open file:%s since %s", file, tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
int64_t size = 0;
|
|
code = taosFStatFile(pFile, &size, NULL);
|
|
if (code != 0) {
|
|
dError("failed to fstat file:%s since %s", file, tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
content = taosMemoryMalloc(size + 1);
|
|
if (content == NULL) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
if (taosReadFile(pFile, content, size) != size) {
|
|
code = terrno;
|
|
dError("failed to read file:%s since %s", file, tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
content[size] = '\0';
|
|
|
|
pJson = tjsonParse(content);
|
|
if (pJson == NULL) {
|
|
code = TSDB_CODE_INVALID_JSON_FORMAT;
|
|
goto _OVER;
|
|
}
|
|
|
|
if (dmDecodeFile(pJson, pDeployed) < 0) {
|
|
code = TSDB_CODE_INVALID_JSON_FORMAT;
|
|
goto _OVER;
|
|
}
|
|
|
|
code = 0;
|
|
dInfo("succceed to read mnode file %s", file);
|
|
|
|
_OVER:
|
|
if (content != NULL) taosMemoryFree(content);
|
|
if (pJson != NULL) cJSON_Delete(pJson);
|
|
if (pFile != NULL) taosCloseFile(&pFile);
|
|
|
|
if (code != 0) {
|
|
dError("failed to read dnode file:%s since %s", file, tstrerror(code));
|
|
}
|
|
return code;
|
|
}
|
|
|
|
int32_t dmReadFileJson(const char *path, const char *name, SJson **ppJson, bool* deployed) {
|
|
int32_t code = -1;
|
|
TdFilePtr pFile = NULL;
|
|
char *content = NULL;
|
|
char file[PATH_MAX] = {0};
|
|
int32_t nBytes = snprintf(file, sizeof(file), "%s%s%s.json", path, TD_DIRSEP, name);
|
|
if (nBytes <= 0 || nBytes >= PATH_MAX) {
|
|
code = TSDB_CODE_OUT_OF_BUFFER;
|
|
goto _OVER;
|
|
}
|
|
|
|
if (taosStatFile(file, NULL, NULL, NULL) < 0) {
|
|
dInfo("file:%s not exist", file);
|
|
code = 0;
|
|
goto _OVER;
|
|
}
|
|
|
|
pFile = taosOpenFile(file, TD_FILE_READ);
|
|
if (pFile == NULL) {
|
|
code = terrno;
|
|
dError("failed to open file:%s since %s", file, tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
int64_t size = 0;
|
|
code = taosFStatFile(pFile, &size, NULL);
|
|
if (code != 0) {
|
|
dError("failed to fstat file:%s since %s", file, tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
content = taosMemoryMalloc(size + 1);
|
|
if (content == NULL) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
if (taosReadFile(pFile, content, size) != size) {
|
|
code = terrno;
|
|
dError("failed to read file:%s since %s", file, tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
content[size] = '\0';
|
|
|
|
*ppJson = tjsonParse(content);
|
|
if (*ppJson == NULL) {
|
|
code = TSDB_CODE_INVALID_JSON_FORMAT;
|
|
goto _OVER;
|
|
}
|
|
|
|
if (dmDecodeFile(*ppJson, deployed) < 0) {
|
|
code = TSDB_CODE_INVALID_JSON_FORMAT;
|
|
goto _OVER;
|
|
}
|
|
|
|
code = 0;
|
|
dInfo("succceed to read mnode file %s", file);
|
|
|
|
_OVER:
|
|
if (content != NULL) taosMemoryFree(content);
|
|
if (pFile != NULL) taosCloseFile(&pFile);
|
|
|
|
if (code != 0) {
|
|
if (*ppJson != NULL) cJSON_Delete(*ppJson);
|
|
dError("failed to read dnode file:%s since %s", file, tstrerror(code));
|
|
}
|
|
return code;
|
|
}
|
|
|
|
|
|
static int32_t dmEncodeFile(SJson *pJson, bool deployed) {
|
|
if (tjsonAddDoubleToObject(pJson, "deployed", deployed) < 0) return TSDB_CODE_INVALID_JSON_FORMAT;
|
|
return 0;
|
|
}
|
|
|
|
int32_t dmWriteFile(const char *path, const char *name, bool deployed) {
|
|
int32_t code = -1;
|
|
char *buffer = NULL;
|
|
SJson *pJson = NULL;
|
|
TdFilePtr pFile = NULL;
|
|
char file[PATH_MAX] = {0};
|
|
char realfile[PATH_MAX] = {0};
|
|
|
|
int32_t nBytes = snprintf(file, sizeof(file), "%s%s%s.json", path, TD_DIRSEP, name);
|
|
if (nBytes <= 0 || nBytes >= PATH_MAX) {
|
|
code = TSDB_CODE_OUT_OF_BUFFER;
|
|
goto _OVER;
|
|
}
|
|
|
|
nBytes = snprintf(realfile, sizeof(realfile), "%s%s%s.json", path, TD_DIRSEP, name);
|
|
if (nBytes <= 0 || nBytes >= PATH_MAX) {
|
|
code = TSDB_CODE_OUT_OF_BUFFER;
|
|
goto _OVER;
|
|
}
|
|
|
|
pJson = tjsonCreateObject();
|
|
if (pJson == NULL) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
if ((code = dmEncodeFile(pJson, deployed)) != 0) goto _OVER;
|
|
|
|
buffer = tjsonToString(pJson);
|
|
if (buffer == NULL) {
|
|
code = TSDB_CODE_INVALID_JSON_FORMAT;
|
|
goto _OVER;
|
|
}
|
|
|
|
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
|
if (pFile == NULL) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
int32_t len = strlen(buffer);
|
|
if (taosWriteFile(pFile, buffer, len) <= 0) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
if (taosFsyncFile(pFile) < 0) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
if (taosCloseFile(&pFile) != 0) {
|
|
code = TAOS_SYSTEM_ERROR(ERRNO);
|
|
goto _OVER;
|
|
}
|
|
TAOS_CHECK_GOTO(taosRenameFile(file, realfile), NULL, _OVER);
|
|
|
|
dInfo("succeed to write file:%s", realfile);
|
|
|
|
_OVER:
|
|
|
|
if (pJson != NULL) tjsonDelete(pJson);
|
|
if (buffer != NULL) taosMemoryFree(buffer);
|
|
if (pFile != NULL) taosCloseFile(&pFile);
|
|
|
|
if (code != 0) {
|
|
dError("failed to write file:%s since %s", realfile, tstrerror(code));
|
|
}
|
|
return code;
|
|
}
|
|
|
|
int32_t dmWriteFileJson(const char *path, const char *name, SJson *pJson) {
|
|
int32_t code = -1;
|
|
char *buffer = NULL;
|
|
TdFilePtr pFile = NULL;
|
|
char file[PATH_MAX] = {0};
|
|
char realfile[PATH_MAX] = {0};
|
|
|
|
int32_t nBytes = snprintf(file, sizeof(file), "%s%s%s.json", path, TD_DIRSEP, name);
|
|
if (nBytes <= 0 || nBytes >= PATH_MAX) {
|
|
code = TSDB_CODE_OUT_OF_BUFFER;
|
|
goto _OVER;
|
|
}
|
|
|
|
nBytes = snprintf(realfile, sizeof(realfile), "%s%s%s.json", path, TD_DIRSEP, name);
|
|
if (nBytes <= 0 || nBytes >= PATH_MAX) {
|
|
code = TSDB_CODE_OUT_OF_BUFFER;
|
|
goto _OVER;
|
|
}
|
|
|
|
buffer = tjsonToString(pJson);
|
|
if (buffer == NULL) {
|
|
code = TSDB_CODE_INVALID_JSON_FORMAT;
|
|
goto _OVER;
|
|
}
|
|
|
|
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
|
if (pFile == NULL) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
int32_t len = strlen(buffer);
|
|
if (taosWriteFile(pFile, buffer, len) <= 0) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
if (taosFsyncFile(pFile) < 0) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
if (taosCloseFile(&pFile) != 0) {
|
|
code = TAOS_SYSTEM_ERROR(ERRNO);
|
|
goto _OVER;
|
|
}
|
|
TAOS_CHECK_GOTO(taosRenameFile(file, realfile), NULL, _OVER);
|
|
|
|
dInfo("succeed to write file:%s", realfile);
|
|
|
|
_OVER:
|
|
|
|
if (pJson != NULL) tjsonDelete(pJson);
|
|
if (buffer != NULL) taosMemoryFree(buffer);
|
|
if (pFile != NULL) taosCloseFile(&pFile);
|
|
|
|
if (code != 0) {
|
|
dError("failed to write file:%s since %s", realfile, tstrerror(code));
|
|
}
|
|
return code;
|
|
}
|
|
|
|
|
|
int32_t dmCheckRunning(const char *dataDir, TdFilePtr *pFile) {
|
|
int32_t code = 0;
|
|
char filepath[PATH_MAX] = {0};
|
|
snprintf(filepath, sizeof(filepath), "%s%s.running", dataDir, TD_DIRSEP);
|
|
|
|
*pFile = taosOpenFile(filepath, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_CLOEXEC);
|
|
if (*pFile == NULL) {
|
|
code = terrno;
|
|
dError("failed to open file:%s since %s", filepath, tstrerror(code));
|
|
return code;
|
|
}
|
|
|
|
int32_t retryTimes = 0;
|
|
int32_t ret = 0;
|
|
do {
|
|
ret = taosLockFile(*pFile);
|
|
if (ret == 0) break;
|
|
|
|
code = terrno;
|
|
taosMsleep(1000);
|
|
retryTimes++;
|
|
dError("failed to lock file:%s since %s, retryTimes:%d", filepath, tstrerror(code), retryTimes);
|
|
} while (retryTimes < 12);
|
|
|
|
if (ret < 0) {
|
|
code = TAOS_SYSTEM_ERROR(ERRNO);
|
|
(void)taosCloseFile(pFile);
|
|
*pFile = NULL;
|
|
return code;
|
|
}
|
|
|
|
dDebug("lock file:%s to prevent repeated starts", filepath);
|
|
return code;
|
|
}
|
|
|
|
extern int32_t generateEncryptCode(const char *key, const char *machineId, char **encryptCode);
|
|
|
|
static int32_t dmWriteCheckCodeFile(char *file, char *realfile, char *key, bool toLogFile) {
|
|
TdFilePtr pFile = NULL;
|
|
char *result = NULL;
|
|
int32_t code = -1;
|
|
|
|
int32_t len = ENCRYPTED_LEN(sizeof(DM_KEY_INDICATOR));
|
|
result = taosMemoryMalloc(len);
|
|
if (result == NULL) {
|
|
return terrno;
|
|
}
|
|
|
|
SCryptOpts opts;
|
|
tstrncpy(opts.key, key, ENCRYPT_KEY_LEN + 1);
|
|
opts.len = len;
|
|
opts.source = DM_KEY_INDICATOR;
|
|
opts.result = result;
|
|
opts.unitLen = 16;
|
|
(void)CBC_Encrypt(&opts);
|
|
|
|
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
|
if (pFile == NULL) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
if (taosWriteFile(pFile, opts.result, len) <= 0) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
if (taosFsyncFile(pFile) < 0) {
|
|
code = TAOS_SYSTEM_ERROR(ERRNO);
|
|
goto _OVER;
|
|
}
|
|
|
|
if (taosCloseFile(&pFile) != 0) {
|
|
code = TAOS_SYSTEM_ERROR(ERRNO);
|
|
goto _OVER;
|
|
}
|
|
|
|
TAOS_CHECK_GOTO(taosRenameFile(file, realfile), NULL, _OVER);
|
|
|
|
encryptDebug("succeed to write checkCode file:%s", realfile);
|
|
|
|
code = 0;
|
|
_OVER:
|
|
if (pFile != NULL) taosCloseFile(&pFile);
|
|
if (result != NULL) taosMemoryFree(result);
|
|
|
|
return code;
|
|
}
|
|
|
|
static int32_t dmWriteEncryptCodeFile(char *file, char *realfile, char *encryptCode, bool toLogFile) {
|
|
TdFilePtr pFile = NULL;
|
|
int32_t code = -1;
|
|
|
|
pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC | TD_FILE_WRITE_THROUGH);
|
|
if (pFile == NULL) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
int32_t len = strlen(encryptCode);
|
|
if (taosWriteFile(pFile, encryptCode, len) <= 0) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
if (taosFsyncFile(pFile) < 0) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
if (taosCloseFile(&pFile) != 0) {
|
|
code = TAOS_SYSTEM_ERROR(ERRNO);
|
|
goto _OVER;
|
|
}
|
|
|
|
TAOS_CHECK_GOTO(taosRenameFile(file, realfile), NULL, _OVER);
|
|
|
|
encryptDebug("succeed to write encryptCode file:%s", realfile);
|
|
|
|
code = 0;
|
|
_OVER:
|
|
if (pFile != NULL) taosCloseFile(&pFile);
|
|
|
|
return code;
|
|
}
|
|
|
|
static int32_t dmCompareEncryptKey(char *file, char *key, bool toLogFile) {
|
|
char *content = NULL;
|
|
int64_t size = 0;
|
|
TdFilePtr pFile = NULL;
|
|
char *result = NULL;
|
|
int32_t code = -1;
|
|
|
|
pFile = taosOpenFile(file, TD_FILE_READ);
|
|
if (pFile == NULL) {
|
|
code = terrno;
|
|
encryptError("failed to open dnode file:%s since %s", file, tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
code = taosFStatFile(pFile, &size, NULL);
|
|
if (code != 0) {
|
|
encryptError("failed to fstat dnode file:%s since %s", file, tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
content = taosMemoryMalloc(size);
|
|
if (content == NULL) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
if (taosReadFile(pFile, content, size) != size) {
|
|
code = terrno;
|
|
encryptError("failed to read dnode file:%s since %s", file, tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
encryptDebug("succeed to read checkCode file:%s", file);
|
|
|
|
int len = ENCRYPTED_LEN(size);
|
|
result = taosMemoryMalloc(len);
|
|
if (result == NULL) {
|
|
code = terrno;
|
|
encryptError("failed to alloc memory file:%s since %s", file, tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
SCryptOpts opts = {0};
|
|
tstrncpy(opts.key, key, ENCRYPT_KEY_LEN + 1);
|
|
opts.len = len;
|
|
opts.source = content;
|
|
opts.result = result;
|
|
opts.unitLen = 16;
|
|
(void)CBC_Decrypt(&opts);
|
|
|
|
if (strcmp(opts.result, DM_KEY_INDICATOR) != 0) {
|
|
code = TSDB_CODE_DNODE_ENCRYPTKEY_CHANGED;
|
|
encryptError("failed to compare decrypted result");
|
|
goto _OVER;
|
|
}
|
|
|
|
encryptDebug("succeed to compare checkCode file:%s", file);
|
|
code = 0;
|
|
_OVER:
|
|
if (result != NULL) taosMemoryFree(result);
|
|
if (content != NULL) taosMemoryFree(content);
|
|
if (pFile != NULL) taosCloseFile(&pFile);
|
|
|
|
return code;
|
|
}
|
|
|
|
int32_t dmUpdateEncryptKey(char *key, bool toLogFile) {
|
|
#if defined(TD_ENTERPRISE) || defined(TD_ASTRA_TODO)
|
|
int32_t code = -1;
|
|
int32_t lino = 0;
|
|
char *machineId = NULL;
|
|
char *encryptCode = NULL;
|
|
|
|
char folder[PATH_MAX] = {0};
|
|
|
|
char encryptFile[PATH_MAX] = {0};
|
|
char realEncryptFile[PATH_MAX] = {0};
|
|
|
|
char checkFile[PATH_MAX] = {0};
|
|
char realCheckFile[PATH_MAX] = {0};
|
|
|
|
int32_t nBytes = snprintf(folder, sizeof(folder), "%s%sdnode", tsDataDir, TD_DIRSEP);
|
|
if (nBytes <= 0 || nBytes >= PATH_MAX) {
|
|
return TSDB_CODE_OUT_OF_BUFFER;
|
|
}
|
|
|
|
nBytes = snprintf(encryptFile, sizeof(realEncryptFile), "%s%s%s.bak", folder, TD_DIRSEP, DM_ENCRYPT_CODE_FILE);
|
|
if (nBytes <= 0 || nBytes >= PATH_MAX) {
|
|
return TSDB_CODE_OUT_OF_BUFFER;
|
|
}
|
|
|
|
nBytes = snprintf(realEncryptFile, sizeof(realEncryptFile), "%s%s%s", folder, TD_DIRSEP, DM_ENCRYPT_CODE_FILE);
|
|
if (nBytes <= 0 || nBytes >= PATH_MAX) {
|
|
return TSDB_CODE_OUT_OF_BUFFER;
|
|
}
|
|
|
|
nBytes = snprintf(checkFile, sizeof(checkFile), "%s%s%s.bak", folder, TD_DIRSEP, DM_CHECK_CODE_FILE);
|
|
if (nBytes <= 0 || nBytes >= PATH_MAX) {
|
|
return TSDB_CODE_OUT_OF_BUFFER;
|
|
}
|
|
|
|
snprintf(realCheckFile, sizeof(realCheckFile), "%s%s%s", folder, TD_DIRSEP, DM_CHECK_CODE_FILE);
|
|
if (nBytes <= 0 || nBytes >= PATH_MAX) {
|
|
return TSDB_CODE_OUT_OF_BUFFER;
|
|
}
|
|
|
|
if (taosMkDir(folder) != 0) {
|
|
code = terrno;
|
|
encryptError("failed to create dir:%s since %s", folder, tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
if (taosCheckExistFile(realCheckFile)) {
|
|
if ((code = dmCompareEncryptKey(realCheckFile, key, toLogFile)) != 0) {
|
|
goto _OVER;
|
|
}
|
|
}
|
|
|
|
TAOS_CHECK_GOTO(tGetMachineId(&machineId), &lino, _OVER);
|
|
|
|
TAOS_CHECK_GOTO(generateEncryptCode(key, machineId, &encryptCode), &lino, _OVER);
|
|
|
|
if ((code = dmWriteEncryptCodeFile(encryptFile, realEncryptFile, encryptCode, toLogFile)) != 0) {
|
|
goto _OVER;
|
|
}
|
|
|
|
if ((code = dmWriteCheckCodeFile(checkFile, realCheckFile, key, toLogFile)) != 0) {
|
|
goto _OVER;
|
|
}
|
|
|
|
encryptInfo("Succeed to update encrypt key\n");
|
|
|
|
code = 0;
|
|
_OVER:
|
|
taosMemoryFree(encryptCode);
|
|
taosMemoryFree(machineId);
|
|
if (code != 0) {
|
|
encryptError("failed to update encrypt key at line %d since %s", lino, tstrerror(code));
|
|
}
|
|
TAOS_RETURN(code);
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
extern int32_t checkAndGetCryptKey(const char *encryptCode, const char *machineId, char **key);
|
|
|
|
static int32_t dmReadEncryptCodeFile(char *file, char **output) {
|
|
TdFilePtr pFile = NULL;
|
|
int32_t code = -1;
|
|
char *content = NULL;
|
|
|
|
pFile = taosOpenFile(file, TD_FILE_READ);
|
|
if (pFile == NULL) {
|
|
code = terrno;
|
|
dError("failed to open dnode file:%s since %s", file, tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
int64_t size = 0;
|
|
code = taosFStatFile(pFile, &size, NULL);
|
|
if (code != 0) {
|
|
dError("failed to fstat dnode file:%s since %s", file, tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
content = taosMemoryMalloc(size + 1);
|
|
if (content == NULL) {
|
|
code = terrno;
|
|
goto _OVER;
|
|
}
|
|
|
|
if (taosReadFile(pFile, content, size) != size) {
|
|
code = terrno;
|
|
dError("failed to read dnode file:%s since %s", file, tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
content[size] = '\0';
|
|
|
|
*output = content;
|
|
content = NULL;
|
|
|
|
dInfo("succeed to read encryptCode file:%s", file);
|
|
code = 0;
|
|
_OVER:
|
|
if (pFile != NULL) taosCloseFile(&pFile);
|
|
taosMemoryFree(content);
|
|
|
|
return code;
|
|
}
|
|
|
|
int32_t dmGetEncryptKey() {
|
|
#if defined(TD_ENTERPRISE) || defined(TD_ASTRA_TODO)
|
|
int32_t code = -1;
|
|
char encryptFile[PATH_MAX] = {0};
|
|
char checkFile[PATH_MAX] = {0};
|
|
char *machineId = NULL;
|
|
char *encryptKey = NULL;
|
|
char *content = NULL;
|
|
|
|
int32_t nBytes = snprintf(encryptFile, sizeof(encryptFile), "%s%sdnode%s%s", tsDataDir, TD_DIRSEP, TD_DIRSEP,
|
|
DM_ENCRYPT_CODE_FILE);
|
|
if (nBytes <= 0 || nBytes >= sizeof(encryptFile)) {
|
|
code = TSDB_CODE_OUT_OF_BUFFER;
|
|
return code;
|
|
}
|
|
|
|
nBytes = snprintf(checkFile, sizeof(checkFile), "%s%sdnode%s%s", tsDataDir, TD_DIRSEP, TD_DIRSEP, DM_CHECK_CODE_FILE);
|
|
if (nBytes <= 0 || nBytes >= sizeof(checkFile)) {
|
|
code = TSDB_CODE_OUT_OF_BUFFER;
|
|
return code;
|
|
}
|
|
|
|
if (!taosCheckExistFile(encryptFile)) {
|
|
code = TSDB_CODE_DNODE_INVALID_ENCRYPT_CONFIG;
|
|
dInfo("no exist, checkCode file:%s", encryptFile);
|
|
return 0;
|
|
}
|
|
|
|
if ((code = dmReadEncryptCodeFile(encryptFile, &content)) != 0) {
|
|
goto _OVER;
|
|
}
|
|
|
|
if ((code = tGetMachineId(&machineId)) != 0) {
|
|
goto _OVER;
|
|
}
|
|
|
|
if ((code = checkAndGetCryptKey(content, machineId, &encryptKey)) != 0) {
|
|
goto _OVER;
|
|
}
|
|
|
|
taosMemoryFreeClear(machineId);
|
|
taosMemoryFreeClear(content);
|
|
|
|
if (encryptKey[0] == '\0') {
|
|
code = TSDB_CODE_DNODE_INVALID_ENCRYPTKEY;
|
|
dError("failed to read key since %s", tstrerror(code));
|
|
goto _OVER;
|
|
}
|
|
|
|
if ((code = dmCompareEncryptKey(checkFile, encryptKey, true)) != 0) {
|
|
goto _OVER;
|
|
}
|
|
|
|
tstrncpy(tsEncryptKey, encryptKey, ENCRYPT_KEY_LEN + 1);
|
|
taosMemoryFreeClear(encryptKey);
|
|
tsEncryptionKeyChksum = taosCalcChecksum(0, tsEncryptKey, strlen(tsEncryptKey));
|
|
tsEncryptionKeyStat = ENCRYPT_KEY_STAT_LOADED;
|
|
|
|
code = 0;
|
|
_OVER:
|
|
if (content != NULL) taosMemoryFree(content);
|
|
if (encryptKey != NULL) taosMemoryFree(encryptKey);
|
|
if (machineId != NULL) taosMemoryFree(machineId);
|
|
if (code != 0) {
|
|
dError("failed to get encrypt key since %s", tstrerror(code));
|
|
}
|
|
TAOS_RETURN(code);
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|