refactor
This commit is contained in:
parent
adc8e4e815
commit
7ba953bab5
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* 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
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* 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
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,196 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
Loading…
Reference in New Issue