diff --git a/include/os/osFile.h b/include/os/osFile.h index 1c397f3042..7bd99644d3 100644 --- a/include/os/osFile.h +++ b/include/os/osFile.h @@ -83,6 +83,8 @@ int32_t taosUnLockFile(TdFilePtr pFile); int32_t taosUmaskFile(int32_t maskVal); int32_t taosStatFile(const char *path, int64_t *size, int64_t *mtime, int64_t *atime); +int32_t taosGetFileDiskID(const char *path, int64_t *diskid); +bool taosCheckFileDiskID(const char *path, int64_t *actDiskID, int64_t expDiskID); int32_t taosDevInoFile(TdFilePtr pFile, int64_t *stDev, int64_t *stIno); int32_t taosFStatFile(TdFilePtr pFile, int64_t *size, int64_t *mtime); bool taosCheckExistFile(const char *pathname); diff --git a/include/util/tdef.h b/include/util/tdef.h index 246d1a293d..b46f472673 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -580,6 +580,7 @@ enum { ENCRYPT_KEY_STAT_UNKNOWN = 0, ENCRYPT_KEY_STAT_UNSET, ENCRYPT_KEY_STAT_SE typedef struct { char dir[TSDB_FILENAME_LEN]; int32_t level; + int64_t diskId; int32_t primary; int8_t disable; // disable create new file } SDiskCfg; diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index a6bb249bc3..548b561d42 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -1964,39 +1964,55 @@ int32_t cfgDeserialize(SArray *array, char *buf, bool isGlobal) { return TSDB_CODE_OUT_OF_MEMORY; } for (int i = 0; i < sz; i++) { - SConfigItem *item = (SConfigItem *)taosArrayGet(array, i); - cJSON *pItem = cJSON_GetObjectItem(configs, item->name); - if (pItem == NULL) { + SConfigItem *pItem = (SConfigItem *)taosArrayGet(array, i); + cJSON *pJson = cJSON_GetObjectItem(configs, pItem->name); + if (pJson == NULL) { continue; } - if (strstr(item->name, "syncLogBufferMemoryAllowed")) { - uDebug("syncLogBufferMemoryAllowed:%f", pItem->valuedouble); + if (strcasecmp(pItem->name, "dataDir") == 0) { + int sz = cJSON_GetArraySize(pJson); + cJSON *filed = NULL; + // check disk id for each dir + for (int j = 0; j < sz; j++) { + cJSON *diskCfgJson = cJSON_GetArrayItem(pJson, j); + filed = cJSON_GetObjectItem(diskCfgJson, "dir"); + char *dir = cJSON_GetStringValue(filed); + filed = cJSON_GetObjectItem(diskCfgJson, "disk_id"); + int64_t actDiskID = 0; + int64_t expDiskID = atoll(cJSON_GetStringValue(filed)); + if (!taosCheckFileDiskID(dir, &actDiskID, expDiskID)) { + uError("failed to check disk id for dir:%s, actDiskID:" PRId64 ", expDiskID:" PRId64, dir, actDiskID, + expDiskID); + return TSDB_CODE_FAILED; + } + } + continue; } - item->stype = CFG_STYPE_CFG_FILE; - switch (item->dtype) { + pItem->stype = CFG_STYPE_CFG_FILE; + switch (pItem->dtype) { { case CFG_DTYPE_NONE: break; case CFG_DTYPE_BOOL: - item->bval = cJSON_IsTrue(pItem); + pItem->bval = cJSON_IsTrue(pJson); break; case CFG_DTYPE_INT32: - item->i32 = pItem->valueint; + pItem->i32 = pJson->valueint; break; case CFG_DTYPE_INT64: - item->i64 = atoll(cJSON_GetStringValue(pItem)); + pItem->i64 = atoll(cJSON_GetStringValue(pJson)); break; case CFG_DTYPE_FLOAT: case CFG_DTYPE_DOUBLE: - item->fval = atoll(cJSON_GetStringValue(pItem)); + pItem->fval = atoll(cJSON_GetStringValue(pJson)); break; case CFG_DTYPE_STRING: case CFG_DTYPE_DIR: case CFG_DTYPE_LOCALE: case CFG_DTYPE_CHARSET: case CFG_DTYPE_TIMEZONE: - taosMemoryFree(item->str); - item->str = taosStrdup(pItem->valuestring); + taosMemoryFree(pItem->str); + pItem->str = taosStrdup(pJson->valuestring); break; } } @@ -2127,7 +2143,6 @@ int32_t taosInitCfg(const char *cfgDir, const char **envCmd, const char *envFile TAOS_CHECK_GOTO(taosUpdateServerCfg(tsCfg), &lino, _exit); TAOS_CHECK_GOTO(taosSetServerCfg(tsCfg), &lino, _exit); TAOS_CHECK_GOTO(taosSetReleaseCfg(tsCfg), &lino, _exit); - TAOS_CHECK_GOTO(taosSetTfsCfg(tsCfg), &lino, _exit); TAOS_CHECK_GOTO(taosSetS3Cfg(tsCfg), &lino, _exit); } @@ -2820,6 +2835,34 @@ int32_t localConfigSerialize(SArray *array, char **serialized) { // string are used to prohibit the loss of precision for (int i = 0; i < sz; i++) { SConfigItem *item = (SConfigItem *)taosArrayGet(array, i); + if (strcasecmp(item->name, "dataDir") == 0) { + int32_t sz = taosArrayGetSize(item->array); + cJSON *dataDirs = cJSON_CreateArray(); + if (!cJSON_AddItemToObject(cField, item->name, dataDirs)) { + uError("failed to serialize global config since %s", tstrerror(terrno)); + } + for (int j = 0; j < sz; j++) { + SDiskCfg *disk = (SDiskCfg *)taosArrayGet(item->array, j); + cJSON *dataDir = cJSON_CreateObject(); + if (dataDir == NULL) goto _exit; + if (!cJSON_AddItemToArray(dataDirs, dataDir)) { + uError("failed to serialize global config since %s", tstrerror(terrno)); + } + if (cJSON_AddStringToObject(dataDir, "dir", disk->dir) == NULL) goto _exit; + if (cJSON_AddNumberToObject(dataDir, "level", disk->level) == NULL) goto _exit; + if (disk->diskId == 0) { + if (taosGetFileDiskID(disk->dir, &disk->diskId) != 0) { + uError("failed to get disk id for %s", disk->dir); + goto _exit; + } + } + (void)sprintf(buf, "%" PRId64, disk->diskId); + if (cJSON_AddStringToObject(dataDir, "disk_id", buf) == NULL) goto _exit; + if (cJSON_AddNumberToObject(dataDir, "primary", disk->primary) == NULL) goto _exit; + if (cJSON_AddNumberToObject(dataDir, "disable", disk->disable) == NULL) goto _exit; + } + continue; + } switch (item->dtype) { { case CFG_DTYPE_NONE: diff --git a/source/os/src/osFile.c b/source/os/src/osFile.c index 5030eb1f67..27450b810f 100644 --- a/source/os/src/osFile.c +++ b/source/os/src/osFile.c @@ -198,7 +198,7 @@ _err: } TdFilePtr taosCreateFile(const char *path, int32_t tdFileOptions) { - if(path == NULL) { + if (path == NULL) { terrno = TSDB_CODE_INVALID_PARA; return NULL; } @@ -301,6 +301,48 @@ int32_t taosStatFile(const char *path, int64_t *size, int64_t *mtime, int64_t *a return 0; } + +int32_t taosGetFileDiskID(const char *path, int64_t *diskid) { + OS_PARAM_CHECK(path); +#ifdef WINDOWS + struct _stati64 fileStat; + int32_t code = _stati64(path, &fileStat); +#else + struct stat fileStat; + int32_t code = stat(path, &fileStat); +#endif + if (-1 == code) { + terrno = TAOS_SYSTEM_ERROR(errno); + return terrno; + } + + if (diskid != NULL) { + *diskid = fileStat.st_dev; + } + + return 0; +} + +bool taosCheckFileDiskID(const char *path, int64_t *actDiskID, int64_t expDiskID) { + OS_PARAM_CHECK(path); +#ifdef WINDOWS + struct _stati64 fileStat; + int32_t code = _stati64(path, &fileStat); +#else + struct stat fileStat; + int32_t code = stat(path, &fileStat); +#endif + if (-1 == code) { + terrno = TAOS_SYSTEM_ERROR(errno); + return terrno; + } + + if (actDiskID != NULL) { + *actDiskID = fileStat.st_dev; + } + return fileStat.st_dev == expDiskID; +} + int32_t taosDevInoFile(TdFilePtr pFile, int64_t *stDev, int64_t *stIno) { #ifdef WINDOWS if (pFile == NULL || pFile->hFile == NULL) { @@ -429,7 +471,7 @@ HANDLE taosOpenFileNotStream(const char *path, int32_t tdFileOptions) { } int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count) { - if (pFile == NULL || buf == NULL) { + if (pFile == NULL || buf == NULL) { terrno = TSDB_CODE_INVALID_PARA; return terrno; } @@ -1572,7 +1614,7 @@ FILE *taosOpenCFile(const char *filename, const char *mode) { } int taosSeekCFile(FILE *file, int64_t offset, int whence) { - if(NULL == file) { + if (NULL == file) { terrno = TSDB_CODE_INVALID_PARA; return terrno; }