• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #4898

26 Dec 2025 09:58AM UTC coverage: 65.061% (-0.7%) from 65.717%
#4898

push

travis-ci

web-flow
feat: support encryption of configuration files, data files and metadata files (#33801)

350 of 1333 new or added lines in 31 files covered. (26.26%)

2796 existing lines in 159 files now uncovered.

184024 of 282850 relevant lines covered (65.06%)

113940470.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.08
/source/libs/sync/src/syncRaftStore.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15

16
#define _DEFAULT_SOURCE
17
#include "syncRaftStore.h"
18
#include "syncUtil.h"
19
#include "tencrypt.h"
20
#include "tjson.h"
21

22
int32_t raftStoreReadFile(SSyncNode *pNode);
23
int32_t raftStoreWriteFile(SSyncNode *pNode);
24

25
static int32_t raftStoreDecode(const SJson *pJson, SRaftStore *pStore) {
1,138,476✔
26
  int32_t code = 0;
1,138,476✔
27

28
  tjsonGetNumberValue(pJson, "current_term", pStore->currentTerm, code);
1,138,476✔
29
  if (code < 0) TAOS_RETURN(TSDB_CODE_FAILED);
1,138,476✔
30
  tjsonGetNumberValue(pJson, "vote_for_addr", pStore->voteFor.addr, code);
1,138,476✔
31
  if (code < 0) TAOS_RETURN(TSDB_CODE_FAILED);
1,138,476✔
32
  tjsonGetInt32ValueFromDouble(pJson, "vote_for_vgid", pStore->voteFor.vgId, code);
1,138,476✔
33
  if (code < 0) TAOS_RETURN(TSDB_CODE_FAILED);
1,138,476✔
34

35
  TAOS_RETURN(TSDB_CODE_SUCCESS);
1,138,476✔
36
}
37

38
int32_t raftStoreReadFile(SSyncNode *pNode) {
4,069,659✔
39
  int32_t     code = -1, lino = 0;
4,069,659✔
40
  char       *pData = NULL;
4,070,515✔
41
  SJson      *pJson = NULL;
4,070,515✔
42
  const char *file = pNode->raftStorePath;
4,070,515✔
43
  SRaftStore *pStore = &pNode->raftStore;
4,070,515✔
44

45
  if (taosStatFile(file, NULL, NULL, NULL) < 0) {
4,070,515✔
46
    sInfo("vgId:%d, raft store file:%s not exist, use default value", pNode->vgId, file);
2,932,039✔
47
    pStore->currentTerm = 0;
2,932,039✔
48
    pStore->voteFor.addr = 0;
2,932,039✔
49
    pStore->voteFor.vgId = 0;
2,932,039✔
50
    return raftStoreWriteFile(pNode);
2,932,039✔
51
  }
52

53
  // Use taosReadCfgFile for automatic decryption support (returns null-terminated string)
54
  int32_t dataLen = 0;
1,138,476✔
55
  code = taosReadCfgFile(file, &pData, &dataLen);
1,138,476✔
56
  if (code != 0) {
1,138,476✔
57
    sError("vgId:%d, failed to read raft store file:%s since %s", pNode->vgId, file, terrstr());
×
NEW
58
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
59
  }
60

61
  pJson = tjsonParse(pData);
1,138,476✔
62
  if (pJson == NULL) {
1,138,476✔
63
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_JSON_FORMAT, &lino, _OVER);
×
64
  }
65

66
  if (raftStoreDecode(pJson, pStore) < 0) {
1,138,476✔
67
    TAOS_CHECK_GOTO(TSDB_CODE_INVALID_JSON_FORMAT, &lino, _OVER);
×
68
  }
69

70
  code = 0;
1,138,476✔
71
  sInfo("vgId:%d, succceed to read raft store file %s", pNode->vgId, file);
1,138,476✔
72

73
_OVER:
1,139,003✔
74
  if (pData != NULL) taosMemoryFree(pData);
1,138,476✔
75
  if (pJson != NULL) cJSON_Delete(pJson);
1,138,476✔
76

77
  if (code != 0) {
1,138,476✔
78
    sError("vgId:%d, failed to read raft store file:%s since %s", pNode->vgId, file, terrstr());
×
79
  }
80

81
  TAOS_RETURN(code);
1,138,476✔
82
}
83

84
static int32_t raftStoreEncode(SJson *pJson, SRaftStore *pStore) {
9,565,639✔
85
  if (tjsonAddIntegerToObject(pJson, "current_term", pStore->currentTerm) < 0) TAOS_RETURN(TSDB_CODE_FAILED);
9,565,639✔
86
  if (tjsonAddIntegerToObject(pJson, "vote_for_addr", pStore->voteFor.addr) < 0) TAOS_RETURN(TSDB_CODE_FAILED);
9,565,151✔
87
  if (tjsonAddDoubleToObject(pJson, "vote_for_vgid", pStore->voteFor.vgId) < 0) TAOS_RETURN(TSDB_CODE_FAILED);
9,565,639✔
88

89
  TAOS_RETURN(TSDB_CODE_SUCCESS);
9,565,134✔
90
}
91

92
int32_t raftStoreWriteFile(SSyncNode *pNode) {
9,565,639✔
93
  int32_t     code = -1, lino = 0;
9,565,639✔
94
  char       *buffer = NULL;
9,565,639✔
95
  SJson      *pJson = NULL;
9,565,639✔
96
  const char *realfile = pNode->raftStorePath;
9,565,639✔
97
  SRaftStore *pStore = &pNode->raftStore;
9,565,639✔
98

99
  pJson = tjsonCreateObject();
9,565,639✔
100
  if (pJson == NULL) TAOS_CHECK_GOTO(terrno, &lino, _OVER);
9,565,639✔
101
  if (raftStoreEncode(pJson, pStore) != 0) TAOS_CHECK_GOTO(TSDB_CODE_OUT_OF_MEMORY, &lino, _OVER);
9,565,639✔
102

103
  buffer = tjsonToString(pJson);
9,564,931✔
104
  if (buffer == NULL) TAOS_CHECK_GOTO(terrno, &lino, _OVER);
9,564,834✔
105

106
  int32_t len = strlen(buffer);
9,564,834✔
107
  
108
  // Use encrypted write if tsCfgKey is enabled
109
  code = taosWriteCfgFile(realfile, buffer, len);
9,564,834✔
110
  if (code != 0) {
9,564,450✔
NEW
111
    lino = __LINE__;
×
NEW
112
    TAOS_CHECK_GOTO(code, &lino, _OVER);
×
113
  }
114

115
  code = 0;
9,564,450✔
116
  sInfo("vgId:%d, succeed to write raft store file:%s, term:%" PRId64, pNode->vgId, realfile, pStore->currentTerm);
9,564,450✔
117

118
_OVER:
9,565,575✔
119
  if (pJson != NULL) tjsonDelete(pJson);
9,565,639✔
120
  if (buffer != NULL) taosMemoryFree(buffer);
9,565,639✔
121

122
  if (code != 0) {
9,565,639✔
123
    sError("vgId:%d, failed to write raft store file:%s since %s", pNode->vgId, realfile, terrstr());
×
124
  }
125
  return code;
9,565,639✔
126
}
127

128
int32_t raftStoreOpen(SSyncNode *pNode) {
4,070,436✔
129
  (void)taosThreadMutexInit(&pNode->raftStore.mutex, NULL);
4,070,436✔
130
  return raftStoreReadFile(pNode);
4,070,515✔
131
}
132

133
void raftStoreClose(SSyncNode *pNode) { (void)taosThreadMutexDestroy(&pNode->raftStore.mutex); }
4,058,668✔
134

135
bool raftStoreHasVoted(SSyncNode *pNode) {
1,210,132✔
136
  (void)taosThreadMutexLock(&pNode->raftStore.mutex);
1,210,132✔
137
  bool b = syncUtilEmptyId(&pNode->raftStore.voteFor);
1,210,132✔
138
  (void)taosThreadMutexUnlock(&pNode->raftStore.mutex);
1,210,132✔
139
  return (!b);
1,210,132✔
140
}
141

142
void raftStoreVote(SSyncNode *pNode, SRaftId *pRaftId) {
1,201,788✔
143
  (void)taosThreadMutexLock(&pNode->raftStore.mutex);
1,201,788✔
144
  pNode->raftStore.voteFor = *pRaftId;
1,201,788✔
145
  int32_t code = 0;
1,201,788✔
146
  if ((code = raftStoreWriteFile(pNode)) != 0) {
1,201,788✔
147
    sError("vgId:%d, failed to write raft store file since %s", pNode->vgId, tstrerror(code));
×
148
  }
149
  (void)taosThreadMutexUnlock(&pNode->raftStore.mutex);
1,201,788✔
150
}
1,201,788✔
151

152
void raftStoreClearVote(SSyncNode *pNode) {
1,261,049✔
153
  (void)taosThreadMutexLock(&pNode->raftStore.mutex);
1,261,049✔
154
  pNode->raftStore.voteFor = EMPTY_RAFT_ID;
1,261,049✔
155
  int32_t code = 0;
1,261,049✔
156
  if ((code = raftStoreWriteFile(pNode)) != 0) {
1,261,049✔
157
    sError("vgId:%d, failed to write raft store file since %s", pNode->vgId, tstrerror(code));
×
158
  }
159
  (void)taosThreadMutexUnlock(&pNode->raftStore.mutex);
1,261,049✔
160
}
1,261,049✔
161

162
void raftStoreNextTerm(SSyncNode *pNode) {
3,265,197✔
163
  (void)taosThreadMutexLock(&pNode->raftStore.mutex);
3,265,197✔
164
  pNode->raftStore.currentTerm++;
3,265,197✔
165
  int32_t code = 0;
3,265,197✔
166
  if ((code = raftStoreWriteFile(pNode)) != 0) {
3,265,197✔
167
    sError("vgId:%d, failed to write raft store file since %s", pNode->vgId, tstrerror(code));
×
168
  }
169
  (void)taosThreadMutexUnlock(&pNode->raftStore.mutex);
3,265,197✔
170
}
3,265,197✔
171

172
void raftStoreSetTerm(SSyncNode *pNode, SyncTerm term) {
905,566✔
173
  (void)taosThreadMutexLock(&pNode->raftStore.mutex);
905,566✔
174
  if (pNode->raftStore.currentTerm < term) {
905,566✔
175
    pNode->raftStore.currentTerm = term;
905,566✔
176
    int32_t code = 0;
905,566✔
177
    if ((code = raftStoreWriteFile(pNode)) != 0) {
905,566✔
178
      sError("vgId:%d, failed to write raft store file since %s", pNode->vgId, tstrerror(code));
×
179
    }
180
  }
181
  (void)taosThreadMutexUnlock(&pNode->raftStore.mutex);
905,566✔
182
}
905,566✔
183

184
SyncTerm raftStoreGetTerm(SSyncNode *pNode) {
2,147,483,647✔
185
  (void)taosThreadMutexLock(&pNode->raftStore.mutex);
2,147,483,647✔
186
  SyncTerm term = pNode->raftStore.currentTerm;
2,147,483,647✔
187
  (void)taosThreadMutexUnlock(&pNode->raftStore.mutex);
2,147,483,647✔
188
  return term;
2,147,483,647✔
189
}
190

191
SyncTerm raftStoreTryGetTerm(SSyncNode *pNode) {
1,681,898✔
192
  SyncTerm term = 0;
1,681,898✔
193
  if (taosThreadMutexTryLock(&pNode->raftStore.mutex) == 0) {
1,681,898✔
194
    term = pNode->raftStore.currentTerm;
1,648,674✔
195
    (void)taosThreadMutexUnlock(&pNode->raftStore.mutex);
1,648,674✔
196
  }
197

198
  return term;
1,681,898✔
199
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc