• 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

83.93
/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 "tencrypt.h"
19
#include "tjson.h"
20

21
static int32_t mmDecodeOption(SJson *pJson, SMnodeOpt *pOption) {
615,291✔
22
  int32_t code = 0;
615,291✔
23

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

33
  SJson *replicas = tjsonGetObjectItem(pJson, "replicas");
615,291✔
34
  if (replicas == NULL) return 0;
615,291✔
35
  pOption->numOfTotalReplicas = tjsonGetArraySize(replicas);
27,388✔
36

37
  pOption->numOfReplicas = 0;
27,388✔
38

39
  for (int32_t i = 0; i < pOption->numOfTotalReplicas; ++i) {
95,548✔
40
    SJson *replica = tjsonGetArrayItem(replicas, i);
68,160✔
41
    if (replica == NULL) return TSDB_CODE_INVALID_JSON_FORMAT;
68,160✔
42

43
    SReplica *pReplica = pOption->replicas + i;
68,160✔
44
    tjsonGetInt32ValueFromDouble(replica, "id", pReplica->id, code);
68,160✔
45
    if (code < 0) return code;
68,160✔
46
    code = tjsonGetStringValue(replica, "fqdn", pReplica->fqdn);
68,160✔
47
    if (code < 0) return code;
68,160✔
48
    tjsonGetUInt16ValueFromDouble(replica, "port", pReplica->port, code);
68,160✔
49
    if (code < 0) return code;
68,160✔
50
    tjsonGetInt32ValueFromDouble(replica, "role", pOption->nodeRoles[i], code);
68,160✔
51
    if (code < 0) return code;
68,160✔
52
    if (pOption->nodeRoles[i] == TAOS_SYNC_ROLE_VOTER) {
68,160✔
53
      pOption->numOfReplicas++;
54,466✔
54
    }
55
  }
56

57
  for (int32_t i = 0; i < pOption->numOfTotalReplicas; ++i) {
95,548✔
58
  }
59

60
  return 0;
27,388✔
61
}
62

63
int32_t mmReadFile(const char *path, SMnodeOpt *pOption) {
1,385,957✔
64
  int32_t   code = -1;
1,385,957✔
65
  char     *pData = NULL;
1,385,957✔
66
  int32_t   dataLen = 0;
1,385,957✔
67
  SJson    *pJson = NULL;
1,385,957✔
68
  char      file[PATH_MAX] = {0};
1,385,957✔
69

70
  int32_t nBytes = snprintf(file, sizeof(file), "%s%smnode.json", path, TD_DIRSEP);
1,385,957✔
71
  if (nBytes <= 0 || nBytes >= sizeof(file)) {
1,385,957✔
72
    code = TSDB_CODE_OUT_OF_BUFFER;
×
73
    goto _OVER;
×
74
  }
75

76
  if (taosStatFile(file, NULL, NULL, NULL) < 0) {
1,385,957✔
77
    dInfo("mnode file:%s not exist, reason:%s", file, tstrerror(terrno));
770,666✔
78
    return 0;
770,666✔
79
  }
80

81
  // Use taosReadCfgFile for automatic decryption support (returns null-terminated string)
82
  code = taosReadCfgFile(file, &pData, &dataLen);
615,291✔
83
  if (code != 0) {
615,291✔
84
    dError("failed to read mnode file:%s since %s", file, tstrerror(code));
×
85
    goto _OVER;
×
86
  }
87

88
  pJson = tjsonParse(pData);
615,291✔
89
  if (pJson == NULL) {
615,291✔
90
    code = TSDB_CODE_INVALID_JSON_FORMAT;
×
91
    goto _OVER;
×
92
  }
93

94
  if ((code = mmDecodeOption(pJson, pOption)) < 0) {
615,291✔
95
    goto _OVER;
×
96
  }
97

98
  code = 0;
615,291✔
99
  dInfo("succceed to read mnode file %s", file);
615,291✔
100

101
_OVER:
615,046✔
102
  if (pData != NULL) taosMemoryFree(pData);
615,291✔
103
  if (pJson != NULL) cJSON_Delete(pJson);
615,291✔
104

105
  if (code != 0) {
615,291✔
106
    dError("failed to read mnode file:%s since %s", file, tstrerror(code));
×
107
  }
108
  return code;
615,291✔
109
}
110

111
static int32_t mmEncodeOption(SJson *pJson, const SMnodeOpt *pOption) {
661,025✔
112
  int32_t code = 0;
661,025✔
113
  if (pOption->deploy && pOption->numOfTotalReplicas > 0) {
661,025✔
114
    if ((code = tjsonAddDoubleToObject(pJson, "selfIndex", pOption->selfIndex)) < 0) return code;
27,388✔
115

116
    SJson *replicas = tjsonCreateArray();
27,388✔
117
    if (replicas == NULL) {
27,388✔
118
      return terrno;
×
119
    }
120
    if ((code = tjsonAddItemToObject(pJson, "replicas", replicas)) < 0) return code;
27,388✔
121

122
    for (int32_t i = 0; i < pOption->numOfTotalReplicas; ++i) {
95,548✔
123
      SJson *replica = tjsonCreateObject();
68,160✔
124
      if (replica == NULL) {
68,160✔
125
        return terrno;
×
126
      }
127

128
      const SReplica *pReplica = pOption->replicas + i;
68,160✔
129
      if ((code = tjsonAddDoubleToObject(replica, "id", pReplica->id)) < 0) return code;
68,160✔
130
      if ((code = tjsonAddStringToObject(replica, "fqdn", pReplica->fqdn)) < 0) return code;
68,160✔
131
      if ((code = tjsonAddDoubleToObject(replica, "port", pReplica->port)) < 0) return code;
68,160✔
132
      if ((code = tjsonAddDoubleToObject(replica, "role", pOption->nodeRoles[i])) < 0) return code;
68,160✔
133
      if ((code = tjsonAddItemToArray(replicas, replica)) < 0) return code;
68,160✔
134
    }
135
  }
136

137
  if ((code = tjsonAddDoubleToObject(pJson, "lastIndex", pOption->lastIndex)) < 0) return code;
661,025✔
138

139
  if ((code = tjsonAddDoubleToObject(pJson, "deployed", pOption->deploy)) < 0) return code;
661,025✔
140

141
  if ((code = tjsonAddDoubleToObject(pJson, "version", pOption->version)) < 0) return code;
661,025✔
142

143
  return code;
661,025✔
144
}
145

146
int32_t mmWriteFile(const char *path, const SMnodeOpt *pOption) {
661,025✔
147
  int32_t   code = -1;
661,025✔
148
  char     *buffer = NULL;
661,025✔
149
  SJson    *pJson = NULL;
661,025✔
150
  char      realfile[PATH_MAX] = {0};
661,025✔
151

152
  int32_t nBytes = snprintf(realfile, sizeof(realfile), "%s%smnode.json", path, TD_DIRSEP);
661,025✔
153
  if (nBytes <= 0 || nBytes >= sizeof(realfile)) {
661,025✔
154
    code = TSDB_CODE_OUT_OF_BUFFER;
×
155
    goto _OVER;
×
156
  }
157

158
  // terrno = TSDB_CODE_OUT_OF_MEMORY;
159
  pJson = tjsonCreateObject();
661,025✔
160
  if (pJson == NULL) {
661,025✔
161
    code = terrno;
×
162
    goto _OVER;
×
163
  }
164

165
  TAOS_CHECK_GOTO(mmEncodeOption(pJson, pOption), NULL, _OVER);
661,025✔
166

167
  buffer = tjsonToString(pJson);
661,025✔
168
  if (buffer == NULL) {
661,025✔
169
    code = TSDB_CODE_INVALID_JSON_FORMAT;
×
170
    goto _OVER;
×
171
  }
172

173
  int32_t len = strlen(buffer);
661,025✔
174
  
175
  // Use encrypted write if tsCfgKey is enabled
176
  code = taosWriteCfgFile(realfile, buffer, len);
661,025✔
177
  if (code != 0) {
661,025✔
UNCOV
178
    goto _OVER;
×
179
  }
180

181
  dInfo("succeed to write mnode file:%s, deloyed:%d", realfile, pOption->deploy);
661,025✔
182

183
_OVER:
660,793✔
184
  if (pJson != NULL) tjsonDelete(pJson);
661,025✔
185
  if (buffer != NULL) taosMemoryFree(buffer);
661,025✔
186

187
  if (code != 0) {
661,025✔
188
    dError("failed to write mnode file:%s since %s, deloyed:%d", realfile, tstrerror(code), pOption->deploy);
×
189
  }
190
  return code;
661,025✔
191
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc