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

taosdata / TDengine / #4932

19 Jan 2026 12:29PM UTC coverage: 66.646% (-0.1%) from 66.749%
#4932

push

travis-ci

web-flow
chore: upgrade taospy (#34272)

202981 of 304565 relevant lines covered (66.65%)

126831443.51 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,187,553✔
26
  int32_t code = 0;
1,187,553✔
27

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

35
  TAOS_RETURN(TSDB_CODE_SUCCESS);
1,187,823✔
36
}
37

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

45
  if (taosStatFile(file, NULL, NULL, NULL) < 0) {
4,238,281✔
46
    sInfo("vgId:%d, raft store file:%s not exist, use default value", pNode->vgId, file);
3,049,742✔
47
    pStore->currentTerm = 0;
3,050,458✔
48
    pStore->voteFor.addr = 0;
3,050,458✔
49
    pStore->voteFor.vgId = 0;
3,050,458✔
50
    return raftStoreWriteFile(pNode);
3,050,458✔
51
  }
52

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

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

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

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

73
_OVER:
1,187,672✔
74
  if (pData != NULL) taosMemoryFree(pData);
1,187,823✔
75
  if (pJson != NULL) cJSON_Delete(pJson);
1,187,823✔
76

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

81
  TAOS_RETURN(code);
1,187,823✔
82
}
83

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

89
  TAOS_RETURN(TSDB_CODE_SUCCESS);
10,198,148✔
90
}
91

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

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

103
  buffer = tjsonToString(pJson);
10,197,907✔
104
  if (buffer == NULL) TAOS_CHECK_GOTO(terrno, &lino, _OVER);
10,196,202✔
105

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

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

118
_OVER:
10,196,216✔
119
  if (pJson != NULL) tjsonDelete(pJson);
10,198,283✔
120
  if (buffer != NULL) taosMemoryFree(buffer);
10,198,283✔
121

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

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

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

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

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

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

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

172
void raftStoreSetTerm(SSyncNode *pNode, SyncTerm term) {
996,518✔
173
  (void)taosThreadMutexLock(&pNode->raftStore.mutex);
996,518✔
174
  if (pNode->raftStore.currentTerm < term) {
996,518✔
175
    pNode->raftStore.currentTerm = term;
996,518✔
176
    int32_t code = 0;
996,518✔
177
    if ((code = raftStoreWriteFile(pNode)) != 0) {
996,518✔
178
      sError("vgId:%d, failed to write raft store file since %s", pNode->vgId, tstrerror(code));
×
179
    }
180
  }
181
  (void)taosThreadMutexUnlock(&pNode->raftStore.mutex);
996,518✔
182
}
996,518✔
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,786,411✔
192
  SyncTerm term = 0;
1,786,411✔
193
  if (taosThreadMutexTryLock(&pNode->raftStore.mutex) == 0) {
1,786,411✔
194
    term = pNode->raftStore.currentTerm;
1,762,621✔
195
    (void)taosThreadMutexUnlock(&pNode->raftStore.mutex);
1,762,621✔
196
  }
197

198
  return term;
1,786,411✔
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