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

taosdata / TDengine / #4945

30 Jan 2026 06:19AM UTC coverage: 66.87% (+0.02%) from 66.849%
#4945

push

travis-ci

web-flow
merge: from main to 3.0 #34453

1126 of 2018 new or added lines in 72 files covered. (55.8%)

13708 existing lines in 159 files now uncovered.

205277 of 306978 relevant lines covered (66.87%)

126353544.65 hits per line

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

72.39
/source/dnode/mgmt/mgmt_mnode/src/mmFile.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 "mmInt.h"
18
#include "sdb.h"
19
#include "tencrypt.h"
20
#include "tjson.h"
21

22
static int32_t mmDecodeOption(SJson *pJson, SMnodeOpt *pOption) {
600,216✔
23
  int32_t code = 0;
600,216✔
24

25
  tjsonGetInt32ValueFromDouble(pJson, "deployed", pOption->deploy, code);
600,216✔
26
  if (code < 0) return code;
600,216✔
27
  tjsonGetInt32ValueFromDouble(pJson, "version", pOption->version, code);
600,216✔
28
  if (code < 0) return code;
600,216✔
29
  tjsonGetInt32ValueFromDouble(pJson, "selfIndex", pOption->selfIndex, code);
600,216✔
30
  if (code < 0) return code;
600,216✔
31
  tjsonGetInt32ValueFromDouble(pJson, "lastIndex", pOption->lastIndex, code);
600,216✔
32
  if (code < 0) return code;
600,216✔
33

34
  tjsonGetInt32ValueFromDouble(pJson, "encrypted", pOption->encrypted, code);
600,216✔
35
  if (code < 0) return code;
600,216✔
36

37
  SJson *replicas = tjsonGetObjectItem(pJson, "replicas");
600,216✔
38
  if (replicas == NULL) return 0;
600,216✔
39
  pOption->numOfTotalReplicas = tjsonGetArraySize(replicas);
27,992✔
40

41
  pOption->numOfReplicas = 0;
27,992✔
42

43
  for (int32_t i = 0; i < pOption->numOfTotalReplicas; ++i) {
97,662✔
44
    SJson *replica = tjsonGetArrayItem(replicas, i);
69,670✔
45
    if (replica == NULL) return TSDB_CODE_INVALID_JSON_FORMAT;
69,670✔
46

47
    SReplica *pReplica = pOption->replicas + i;
69,670✔
48
    tjsonGetInt32ValueFromDouble(replica, "id", pReplica->id, code);
69,670✔
49
    if (code < 0) return code;
69,670✔
50
    code = tjsonGetStringValue(replica, "fqdn", pReplica->fqdn);
69,670✔
51
    if (code < 0) return code;
69,670✔
52
    tjsonGetUInt16ValueFromDouble(replica, "port", pReplica->port, code);
69,670✔
53
    if (code < 0) return code;
69,670✔
54
    tjsonGetInt32ValueFromDouble(replica, "role", pOption->nodeRoles[i], code);
69,670✔
55
    if (code < 0) return code;
69,670✔
56
    if (pOption->nodeRoles[i] == TAOS_SYNC_ROLE_VOTER) {
69,670✔
57
      pOption->numOfReplicas++;
55,674✔
58
    }
59
  }
60

61
  for (int32_t i = 0; i < pOption->numOfTotalReplicas; ++i) {
97,662✔
62
  }
63

64
  return 0;
27,992✔
65
}
66

67
int32_t mmReadFile(const char *path, SMnodeOpt *pOption) {
1,356,677✔
68
  int32_t   code = -1;
1,356,677✔
69
  char     *pData = NULL;
1,356,677✔
70
  int32_t   dataLen = 0;
1,356,677✔
71
  SJson    *pJson = NULL;
1,356,677✔
72
  char      file[PATH_MAX] = {0};
1,356,677✔
73

74
  int32_t nBytes = snprintf(file, sizeof(file), "%s%smnode.json", path, TD_DIRSEP);
1,356,677✔
75
  if (nBytes <= 0 || nBytes >= sizeof(file)) {
1,356,677✔
UNCOV
76
    code = TSDB_CODE_OUT_OF_BUFFER;
×
UNCOV
77
    goto _OVER;
×
78
  }
79

80
  if (taosStatFile(file, NULL, NULL, NULL) < 0) {
1,356,677✔
81
    dInfo("mnode file:%s not exist, reason:%s", file, tstrerror(terrno));
756,461✔
82
    return 0;
756,461✔
83
  }
84

85
  // Read file with potential decryption
86
  // First try to read with taosReadCfgFile (supports encrypted files)
87
  code = taosReadCfgFile(file, &pData, &dataLen);
600,216✔
88
  if (code != 0) {
600,216✔
UNCOV
89
    dError("failed to read mnode file:%s since %s", file, tstrerror(code));
×
UNCOV
90
    goto _OVER;
×
91
  }
92

93
  pJson = tjsonParse(pData);
600,216✔
94
  if (pJson == NULL) {
600,216✔
UNCOV
95
    code = TSDB_CODE_INVALID_JSON_FORMAT;
×
96
    goto _OVER;
×
97
  }
98

99
  if ((code = mmDecodeOption(pJson, pOption)) < 0) {
600,216✔
UNCOV
100
    goto _OVER;
×
101
  }
102

103
  code = 0;
600,216✔
104
  dInfo("succeed to read mnode file %s, sdb.data encrypted flag:%d", file, pOption->encrypted);
600,216✔
105

106
_OVER:
600,017✔
107
  if (pData != NULL) taosMemoryFree(pData);
600,216✔
108
  if (pJson != NULL) cJSON_Delete(pJson);
600,216✔
109

110
  if (code != 0) {
600,216✔
UNCOV
111
    dError("failed to read mnode file:%s since %s", file, tstrerror(code));
×
112
  }
113
  return code;
600,216✔
114
}
115

116
static int32_t mmEncodeOption(SJson *pJson, const SMnodeOpt *pOption) {
658,648✔
117
  int32_t code = 0;
658,648✔
118
  if (pOption->deploy && pOption->numOfTotalReplicas > 0) {
658,648✔
119
    if ((code = tjsonAddDoubleToObject(pJson, "selfIndex", pOption->selfIndex)) < 0) return code;
27,992✔
120

121
    SJson *replicas = tjsonCreateArray();
27,992✔
122
    if (replicas == NULL) {
27,992✔
UNCOV
123
      return terrno;
×
124
    }
125
    if ((code = tjsonAddItemToObject(pJson, "replicas", replicas)) < 0) return code;
27,992✔
126

127
    for (int32_t i = 0; i < pOption->numOfTotalReplicas; ++i) {
97,662✔
128
      SJson *replica = tjsonCreateObject();
69,670✔
129
      if (replica == NULL) {
69,670✔
UNCOV
130
        return terrno;
×
131
      }
132

133
      const SReplica *pReplica = pOption->replicas + i;
69,670✔
134
      if ((code = tjsonAddDoubleToObject(replica, "id", pReplica->id)) < 0) return code;
69,670✔
135
      if ((code = tjsonAddStringToObject(replica, "fqdn", pReplica->fqdn)) < 0) return code;
69,670✔
136
      if ((code = tjsonAddDoubleToObject(replica, "port", pReplica->port)) < 0) return code;
69,670✔
137
      if ((code = tjsonAddDoubleToObject(replica, "role", pOption->nodeRoles[i])) < 0) return code;
69,670✔
138
      if ((code = tjsonAddItemToArray(replicas, replica)) < 0) return code;
69,670✔
139
    }
140
  }
141

142
  if ((code = tjsonAddDoubleToObject(pJson, "lastIndex", pOption->lastIndex)) < 0) return code;
658,648✔
143

144
  if ((code = tjsonAddDoubleToObject(pJson, "deployed", pOption->deploy)) < 0) return code;
658,648✔
145

146
  if ((code = tjsonAddDoubleToObject(pJson, "version", pOption->version)) < 0) return code;
658,648✔
147

148
  // Add encrypted flag
149
  if ((code = tjsonAddDoubleToObject(pJson, "encrypted", pOption->encrypted ? 1 : 0)) < 0) return code;
658,648✔
150

151
  return code;
658,648✔
152
}
153

154
int32_t mmWriteFile(const char *path, const SMnodeOpt *pOption) {
658,648✔
155
  int32_t   code = -1;
658,648✔
156
  char     *buffer = NULL;
658,648✔
157
  SJson    *pJson = NULL;
658,648✔
158
  char      realfile[PATH_MAX] = {0};
658,648✔
159

160
  int32_t nBytes = snprintf(realfile, sizeof(realfile), "%s%smnode.json", path, TD_DIRSEP);
658,648✔
161
  if (nBytes <= 0 || nBytes >= sizeof(realfile)) {
658,648✔
UNCOV
162
    code = TSDB_CODE_OUT_OF_BUFFER;
×
UNCOV
163
    goto _OVER;
×
164
  }
165

166
  // terrno = TSDB_CODE_OUT_OF_MEMORY;
167
  pJson = tjsonCreateObject();
658,648✔
168
  if (pJson == NULL) {
658,648✔
UNCOV
169
    code = terrno;
×
UNCOV
170
    goto _OVER;
×
171
  }
172

173
  TAOS_CHECK_GOTO(mmEncodeOption(pJson, pOption), NULL, _OVER);
658,648✔
174

175
  buffer = tjsonToString(pJson);
658,648✔
176
  if (buffer == NULL) {
658,648✔
UNCOV
177
    code = TSDB_CODE_INVALID_JSON_FORMAT;
×
UNCOV
178
    goto _OVER;
×
179
  }
180

181
  int32_t len = strlen(buffer);
658,648✔
182

183
  // mnode.json itself is not encrypted, just write as plain JSON
184
  // The encrypted flag indicates whether sdb.data is encrypted
185
  code = taosWriteCfgFile(realfile, buffer, len);
658,648✔
186
  if (code != 0) {
658,648✔
UNCOV
187
    goto _OVER;
×
188
  }
189

190
  dInfo("succeed to write mnode file:%s, deployed:%d, sdb.data encrypted:%d", realfile, pOption->deploy,
658,648✔
191
        pOption->encrypted);
192

193
_OVER:
658,440✔
194
  if (pJson != NULL) tjsonDelete(pJson);
658,648✔
195
  if (buffer != NULL) taosMemoryFree(buffer);
658,648✔
196

197
  if (code != 0) {
658,648✔
UNCOV
198
    dError("failed to write mnode file:%s since %s, deloyed:%d", realfile, tstrerror(code), pOption->deploy);
×
199
  }
200
  return code;
658,648✔
201
}
202

203
// Update and persist encrypted flag (exposed via mnode.h for sdb module)
204
int32_t mndSetEncryptedFlag(SSdb *pSdb) {
×
205
  int32_t   code = 0;
×
206
  SMnodeOpt option = {0};
×
207

UNCOV
208
  if (pSdb == NULL || pSdb->mnodePath[0] == '\0') {
×
UNCOV
209
    dError("invalid parameters, pSdb:%p", pSdb);
×
210
    return TSDB_CODE_INVALID_PARA;
×
211
  }
212

213
  // Read current mnode.json
UNCOV
214
  code = mmReadFile(pSdb->mnodePath, &option);
×
UNCOV
215
  if (code != 0) {
×
UNCOV
216
    dError("failed to read mnode.json for setting encrypted flag since %s", tstrerror(code));
×
217
    return code;
×
218
  }
219

220
  // Update encrypted flag
221
  option.encrypted = true;
×
222
  pSdb->encrypted = true;
×
223

224
  // Write back to mnode.json
225
  code = mmWriteFile(pSdb->mnodePath, &option);
×
226
  if (code != 0) {
×
UNCOV
227
    dError("failed to persist encrypted flag to mnode.json since %s", tstrerror(code));
×
228
    // Rollback in-memory flag
229
    pSdb->encrypted = false;
×
230
    return code;
×
231
  }
232

UNCOV
233
  dInfo("successfully set and persisted encrypted flag in mnode.json");
×
UNCOV
234
  return 0;
×
235
}
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