提交 7ba953ba 编写于 作者: H Hongze Cheng

refactor

上级 adc8e4e8
/*
* 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/>.
*/
#ifndef TD_TDISK_H
#define TD_TDISK_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int level;
int id;
} SDiskID;
typedef struct {
uint64_t size;
uint64_t free;
uint64_t nfiles;
} SDiskMeta;
typedef struct {
int level;
int id;
char dir[TSDB_FILENAME_LEN];
SDiskMeta dmeta;
} SDisk;
SDisk *tdNewDisk(SDiskID did, char *dir);
void tdFreeDisk(SDisk *pDisk);
#ifdef __cplusplus
}
#endif
#endif
\ No newline at end of file
/*
* 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/>.
*/
#ifndef TD_TFS_H
#define TD_TFS_H
#include "tglobal.h"
#ifdef __cplusplus
extern "C" {
#endif
int tfsInit(SDiskCfg *pDiskCfg, int ndisk);
void tfsDestroy();
#ifdef __cplusplus
}
#endif
#endif
\ No newline at end of file
/*
* 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/>.
*/
#ifndef TD_TTIER_H
#define TD_TTIER_H
#include "tdisk.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TSDB_MAX_DISK_PER_TIER 16
typedef struct {
int level;
int ndisk;
SDisk *disks[TSDB_MAX_DISK_PER_TIER];
} STier;
void tdInitTier(STier *pTier, int level);
void tdDestroyTier(STier *pTier);
SDisk *tdAddDiskToTier(STier *pTier, SDiskCfg *pCfg);
#ifdef __cplusplus
}
#endif
#endif
\ No newline at end of file
/*
* 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/>.
*/
#include "tdisk.h"
SDisk *tdNewDisk(SDiskID did, char *dir) {
SDisk *pDisk = (SDisk *)calloc(1, sizeof(*pDisk));
if (pDisk == NULL) {
terrno = TSDB_CODE_FS_OUT_OF_MEMORY;
return NULL;
}
pDisk->level = did.level;
pDisk->id = did.id;
strncpy(pDisk->dir, dir, TSDB_FILENAME_LEN);
return pDisk;
}
void tdFreeDisk(SDisk *pDisk) {
if (pDisk) {
free(pDisk)
}
}
\ No newline at end of file
/*
* 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/>.
*/
#include "os.h"
#include "hash.h"
#include "ttier.h"
#include "tglobal.h"
#include "taoserror.h"
#define fFatal(...) { if (fsDebugFlag & DEBUG_FATAL) { taosPrintLog("FS FATAL ", 255, __VA_ARGS__); }}
#define fError(...) { if (fsDebugFlag & DEBUG_ERROR) { taosPrintLog("FS ERROR ", 255, __VA_ARGS__); }}
#define fWarn(...) { if (fsDebugFlag & DEBUG_WARN) { taosPrintLog("FS WARN ", 255, __VA_ARGS__); }}
#define fInfo(...) { if (fsDebugFlag & DEBUG_INFO) { taosPrintLog("FS ", 255, __VA_ARGS__); }}
#define fDebug(...) { if (fsDebugFlag & DEBUG_DEBUG) { taosPrintLog("FS ", cqDebugFlag, __VA_ARGS__); }}
#define fTrace(...) { if (fsDebugFlag & DEBUG_TRACE) { taosPrintLog("FS ", cqDebugFlag, __VA_ARGS__); }}
#define TSDB_MAX_TIER 3
typedef struct {
uint64_t tsize;
uint64_t avail;
} SFSMeta;
typedef struct {
pthread_mutex_t lock;
SFSMeta meta;
int nlevel;
STier tiers[TSDB_MAX_TIER];
SHashObj * map; // name to did map
} SFS;
static SFS tdFileSystem = {0};
static SFS *pfs = &tdFileSystem;
#define TIER_AT(level) (pfs->tiers + (level))
int tfsInit(SDiskCfg *pDiskCfg, int ndisk) {
ASSERT(ndisk > 0);
for (int level = 0; level < TSDB_MAX_TIER; level++) {
tdInitTier(TIER_AT(level), level);
}
int ret = pthread_mutex_init(&(pfs->lock), NULL);
if (ret != 0) {
terrno = TAOS_SYSTEM_ERROR(ret);
return -1;
}
pfs->map = taosHashInit(TSDB_MAX_TIER * TSDB_MAX_DISKS_PER_TIER * 2,
taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
if (pfs->map == NULL) {
terrno = TSDB_CODE_FS_OUT_OF_MEMORY;
tfsDestroy();
return -1;
}
for (int idisk = 0; idisk < ndisk; idisk++) {
if (tdAddDiskToFS(pDiskCfg + idisk) < 0) {
tfsDestroy();
return -1;
}
}
if (tdCheckFS() < 0) {
tfsDestroy();
return -1;
}
return 0;
}
void tfsDestroy() {
taosHashCleanup(pfs->map);
pfs->map = NULL;
pthread_mutex_destroy(&(pfs->lock));
for (int level = 0; level < TSDB_MAX_TIER; level++) {
tdDestroyTier(TIER_AT(level));
}
}
static int tdAddDiskToFS(SDiskCfg *pCfg) {
if (tdCheckAndFormatCfg(pCfg) < 0) return -1;
if (tdAddDiskToTier(pCfg, TIER_AT(pCfg->level)) < 0) {
fError("failed to add disk %s to FS since %s", pCfg->dir, tstrerror(terrno));
}
taosHashPut(pTiers->map, (void *)dirName, strnlen(dirName, TSDB_FILENAME_LEN), (void *)(&diskid), sizeof(diskid));
if (pfs->nlevel < pCfg->level + 1) pfs->nlevel = pCfg->level + 1;
return 0;
}
static int tdCheckAndFormatCfg(SDiskCfg *pCfg) {
char dirName[TSDB_FILENAME_LEN] = "\0";
struct stat pstat;
if (pCfg->level < 0 || pCfg->level >= TSDB_MAX_TIER) {
fError("failed to add disk %s to FS since invalid level %d", pCfg->dir, pCfg->level);
terrno = TSDB_CODE_FS_INVLD_CFG;
return -1;
}
if (pCfg->primary && pCfg->level != 0) {
fError("failed to add disk %s to FS since disk is primary but level %d not 0", pCfg->dir, pCfg->level);
terrno = TSDB_CODE_FS_INVLD_CFG;
return -1;
}
if (tdFormatDir(pCfg->dir, dirName) < 0) {
fError("failed to add disk %s to FS since invalid dir format", pCfg->dir);
terrno = TSDB_CODE_FS_INVLD_CFG;
return -1;
}
if (tdGetDiskByName(dirName)) {
fError("failed to add disk %s to FS since duplicate add", pCfg->dir);
terrno = TSDB_CODE_FS_INVLD_CFG;
return -1;
}
if (access(dirName, W_OK | R_OK | F_OK) != 0) {
fError("failed to add disk %s to FS since no enough access rights", pCfg->dir);
terrno = TSDB_CODE_FS_INVLD_CFG;
return -1;
}
if (stat(dirName, &pstat) < 0) {
fError("failed to add disk %s to FS since %s", pCfg->dir, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
if (!S_ISDIR(pstat.st_mode)) {
fError("failed to add disk %s to FS since not a directory", pCfg->dir);
terrno = TSDB_CODE_FS_INVLD_CFG;
return -1;
}
strncpy(pCfg->dir, dirName, TSDB_FILENAME_LEN);
return 0;
}
static int tdFormatDir(char *idir, char *odir) {
wordexp_t wep = {0};
int code = wordexp(idir, &wep, 0);
if (code != 0) {
terrno = TAOS_SYSTEM_ERROR(code);
return -1;
}
if (realpath(wep.we_wordv[0], odir) == NULL) {
terrno = TAOS_SYSTEM_ERROR(errno);
wordfree(&wep);
return -1;
}
wordfree(&wep);
return 0;
}
static int tdCheckFS() {
if (DISK_AT(0, 0) == NULL) {
fError("no primary disk is set");
terrno = TSDB_CODE_FS_NO_PRIMARY_DISK;
return -1;
}
for (int level = 0; level < pfs->nlevel; level++) {
if (TIER_AT(level)->ndisk == 0) {
fError("no disk at level %d", level);
terrno = TSDB_CODE_FS_NO_DISK_AT_TIER;
return -1;
}
}
return 0;
}
\ No newline at end of file
/*
* 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/>.
*/
#include "ttier.h"
#include "tglobal.h"
#define DISK_AT_TIER(pTier, id) ((pTier)->disks + (id))
void tdInitTier(STier *pTier, int level) {
pTier->level = level;
}
void tdDestroyTier(STier *pTier) {
for (int id = 0; id < TSDB_MAX_DISK_PER_TIER; id++) {
tdFreeDisk(DISK_AT_TIER(pTier, id));
DISK_AT_TIER(pTier, id) = NULL;
}
}
SDisk *tdAddDiskToTier(STier *pTier, SDiskCfg *pCfg) {
ASSERT(pTier->level == pCfg->level);
int id = 0;
if (pTier->ndisk >= TSDB_MAX_DISK_PER_TIER) {
terrno = TSDB_CODE_FS_TOO_MANY_DISKS;
return -1;
}
if (pCfg->primary) {
if (DISK_AT(0, 0) != NULL) {
terrno = TSDB_CODE_FS_DUP_PRIMARY;
return -1;
}
} else {
if (pTier->level == 0) {
if (DISK_AT_TIER(pTier, 0) != NULL) {
id = pTier->ndisk;
} else {
id = pTier->ndisk + 1;
if (id >= TSDB_MAX_DISK_PER_TIER) {
terrno = TSDB_CODE_FS_TOO_MANY_DISKS;
return -1;
}
}
} else {
id = pTier->ndisk;
}
}
pTier->disks[id] = tdNewDisk({pCfg->level, id}, pCfg->dir);
if (pTier->disks[id] == NULL) return -1;
return 0;
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册