提交 5dc2a671 编写于 作者: Y Yifan Hao

Fix DFile name parsing bug

When parsing DFile name, we expect the file name to follow the
format of v<vid>f<fid>.<type>-ver<version>. When parsing type
in tsdbParseDFilename(), it uses a glibc modifier "m" to allocate
string. However, type string ("p" variable in the original code)
could be NULL for various reasons, and the following code doesn't
check NULL, while would lead to crash.

This patch fixes this bug by using a stack allocated string to
parse type.

* Testing

I have a local vnode repository like following:
.
├── vnode145
│   ├── config.json
│   ├── tsdb
│   │   ├── data
│   │   │   ├── v145f1736.data
│   │   │   ├── v145f1736.head-ver14
│   │   │   ├── v145f1736.last
│   │   │   ├── v145f1736.smad
│   │   │   └── v145f1736.smal
│   │   └── meta
│   ├── version.json
│   └── wal

"vnode145" is lacking "current" for the FS status, but this is fine
since it can be recovered from the "data" folder. However, the above
repository will lead to taosd crashing while restoring "current",
because type for DFile can sometimes be not parsed by the sscanf
format before this patch.

After this patch, the above repository can work OK and "current" can
be restored.

Also run taosdemo for sanity check.

Spent 81.9563 seconds to insert rows: 100000000, affected rows: 100000000 with 8 thread(s) into test.meters. 1220162.42 records/second

insert delay, avg:      65.13ms, max:     252.73ms, min:      24.77ms
上级 38c0244e
......@@ -683,19 +683,20 @@ int tsdbScanAndTryFixDFileSet(STsdbRepo *pRepo, SDFileSet *pSet) {
}
int tsdbParseDFilename(const char *fname, int *vid, int *fid, TSDB_FILE_T *ftype, uint32_t *_version) {
char *p = NULL;
static const int MAX_SUFFIX_LEN = 10;
char suffix[MAX_SUFFIX_LEN] = {0};
*_version = 0;
*ftype = TSDB_FILE_MAX;
sscanf(fname, "v%df%d.%m[a-z]-ver%" PRIu32, vid, fid, &p, _version);
// "suffix" needs to be constrained by 1 less MAX_SUFFIX_LEN
sscanf(fname, "v%df%d.%9[a-z]-ver%" PRIu32, vid, fid, suffix, _version);
for (TSDB_FILE_T i = 0; i < TSDB_FILE_MAX; i++) {
if (strcmp(p, TSDB_FNAME_SUFFIX[i]) == 0) {
if (strcmp(suffix, TSDB_FNAME_SUFFIX[i]) == 0) {
*ftype = i;
break;
}
}
tfree(p);
return 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册