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

#define _DEFAULT_SOURCE
S
shm  
Shengliang Guan 已提交
17
#include "mmInt.h"
18
#include "tjson.h"
S
shm  
Shengliang Guan 已提交
19

S
Shengliang Guan 已提交
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
static int32_t mmDecodeOption(SJson *pJson, SMnodeOpt *pOption) {
  int32_t code = 0;

  tjsonGetInt32ValueFromDouble(pJson, "deployed", pOption->deploy, code);
  if (code < 0) return -1;
  tjsonGetInt32ValueFromDouble(pJson, "selfIndex", pOption->selfIndex, code);
  if (code < 0) return 0;

  SJson *replicas = tjsonGetObjectItem(pJson, "replicas");
  if (replicas == NULL) return 0;
  pOption->numOfReplicas = tjsonGetArraySize(replicas);

  for (int32_t i = 0; i < pOption->numOfReplicas; ++i) {
    SJson *replica = tjsonGetArrayItem(replicas, i);
    if (replica == NULL) return -1;

    SReplica *pReplica = pOption->replicas + i;
    tjsonGetInt32ValueFromDouble(replica, "id", pReplica->id, code);
    if (code < 0) return -1;
    code = tjsonGetStringValue(replica, "fqdn", pReplica->fqdn);
    if (code < 0) return -1;
    tjsonGetUInt16ValueFromDouble(replica, "port", pReplica->port, code);
    if (code < 0) return -1;
  }

  return 0;
}

48
int32_t mmReadFile(const char *path, SMnodeOpt *pOption) {
S
Shengliang Guan 已提交
49
  int32_t   code = -1;
S
shm  
Shengliang Guan 已提交
50
  TdFilePtr pFile = NULL;
S
Shengliang Guan 已提交
51 52 53
  char     *pData = NULL;
  SJson    *pJson = NULL;
  char      file[PATH_MAX] = {0};
54
  snprintf(file, sizeof(file), "%s%smnode.json", path, TD_DIRSEP);
S
Shengliang Guan 已提交
55 56 57 58 59 60

  if (taosStatFile(file, NULL, NULL) < 0) {
    dInfo("mnode file:%s not exist", file);
    return 0;
  }

S
shm  
Shengliang Guan 已提交
61
  pFile = taosOpenFile(file, TD_FILE_READ);
S
shm  
Shengliang Guan 已提交
62
  if (pFile == NULL) {
S
Shengliang Guan 已提交
63 64
    terrno = TAOS_SYSTEM_ERROR(errno);
    dError("failed to open mnode file:%s since %s", file, terrstr());
S
Shengliang Guan 已提交
65
    goto _OVER;
S
shm  
Shengliang Guan 已提交
66 67
  }

S
Shengliang Guan 已提交
68 69 70 71
  int64_t size = 0;
  if (taosFStatFile(pFile, &size, NULL) < 0) {
    terrno = TAOS_SYSTEM_ERROR(errno);
    dError("failed to fstat mnode file:%s since %s", file, terrstr());
S
Shengliang Guan 已提交
72
    goto _OVER;
S
shm  
Shengliang Guan 已提交
73 74
  }

S
Shengliang Guan 已提交
75 76 77
  pData = taosMemoryMalloc(size + 1);
  if (pData == NULL) {
    terrno = TSDB_CODE_OUT_OF_MEMORY;
S
Shengliang Guan 已提交
78
    goto _OVER;
S
shm  
Shengliang Guan 已提交
79 80
  }

S
Shengliang Guan 已提交
81 82 83
  if (taosReadFile(pFile, pData, size) != size) {
    terrno = TAOS_SYSTEM_ERROR(errno);
    dError("failed to read mnode file:%s since %s", file, terrstr());
S
Shengliang Guan 已提交
84
    goto _OVER;
S
shm  
Shengliang Guan 已提交
85
  }
S
Shengliang Guan 已提交
86 87 88 89 90 91 92

  pData[size] = '\0';

  pJson = tjsonParse(pData);
  if (pJson == NULL) {
    terrno = TSDB_CODE_INVALID_JSON_FORMAT;
    goto _OVER;
S
Shengliang Guan 已提交
93
  }
S
shm  
Shengliang Guan 已提交
94

S
Shengliang Guan 已提交
95 96 97
  if (mmDecodeOption(pJson, pOption) < 0) {
    terrno = TSDB_CODE_INVALID_JSON_FORMAT;
    goto _OVER;
S
shm  
Shengliang Guan 已提交
98 99 100
  }

  code = 0;
S
Shengliang Guan 已提交
101
  dInfo("succceed to read mnode file %s", file);
S
shm  
Shengliang Guan 已提交
102

S
Shengliang Guan 已提交
103
_OVER:
S
Shengliang Guan 已提交
104 105
  if (pData != NULL) taosMemoryFree(pData);
  if (pJson != NULL) cJSON_Delete(pJson);
S
shm  
Shengliang Guan 已提交
106 107
  if (pFile != NULL) taosCloseFile(&pFile);

S
Shengliang Guan 已提交
108 109 110
  if (code != 0) {
    dError("failed to read mnode file:%s since %s", file, terrstr());
  }
S
shm  
Shengliang Guan 已提交
111 112 113
  return code;
}

114
static int32_t mmEncodeOption(SJson *pJson, const SMnodeOpt *pOption) {
115
  if (pOption->deploy && pOption->numOfReplicas > 0) {
116 117 118 119 120
    if (tjsonAddDoubleToObject(pJson, "selfIndex", pOption->selfIndex) < 0) return -1;

    SJson *replicas = tjsonCreateArray();
    if (replicas == NULL) return -1;
    if (tjsonAddItemToObject(pJson, "replicas", replicas) < 0) return -1;
121 122

    for (int32_t i = 0; i < pOption->numOfReplicas; ++i) {
123 124 125
      SJson *replica = tjsonCreateObject();
      if (replica == NULL) return -1;

126
      const SReplica *pReplica = pOption->replicas + i;
127 128 129 130
      if (tjsonAddDoubleToObject(replica, "id", pReplica->id) < 0) return -1;
      if (tjsonAddStringToObject(replica, "fqdn", pReplica->fqdn) < 0) return -1;
      if (tjsonAddDoubleToObject(replica, "port", pReplica->port) < 0) return -1;
      if (tjsonAddItemToArray(replicas, replica) < 0) return -1;
131
    }
S
shm  
Shengliang Guan 已提交
132 133
  }

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
  if (tjsonAddDoubleToObject(pJson, "deployed", pOption->deploy) < 0) return -1;

  return 0;
}

int32_t mmWriteFile(const char *path, const SMnodeOpt *pOption) {
  int32_t   code = -1;
  char     *buffer = NULL;
  SJson    *pJson = NULL;
  TdFilePtr pFile = NULL;
  char      file[PATH_MAX] = {0};
  char      realfile[PATH_MAX] = {0};
  snprintf(file, sizeof(file), "%s%smnode.json.bak", path, TD_DIRSEP);
  snprintf(realfile, sizeof(realfile), "%s%smnode.json", path, TD_DIRSEP);

  terrno = TSDB_CODE_OUT_OF_MEMORY;
  pJson = tjsonCreateObject();
  if (pJson == NULL) goto _OVER;
  if (mmEncodeOption(pJson, pOption) != 0) goto _OVER;
  buffer = tjsonToString(pJson);
  if (buffer == NULL) goto _OVER;
155 156 157 158
  terrno = 0;

  pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
  if (pFile == NULL) goto _OVER;
159 160 161 162

  int32_t len = strlen(buffer);
  if (taosWriteFile(pFile, buffer, len) <= 0) goto _OVER;
  if (taosFsyncFile(pFile) < 0) goto _OVER;
S
shm  
Shengliang Guan 已提交
163

164
  taosCloseFile(&pFile);
165
  if (taosRenameFile(file, realfile) != 0) goto _OVER;
S
shm  
Shengliang Guan 已提交
166

167 168 169 170 171 172 173 174 175
  code = 0;
  dInfo("succeed to write mnode file:%s, deloyed:%d", realfile, pOption->deploy);

_OVER:
  if (pJson != NULL) tjsonDelete(pJson);
  if (buffer != NULL) taosMemoryFree(buffer);
  if (pFile != NULL) taosCloseFile(&pFile);

  if (code != 0) {
176
    if (terrno == 0) terrno = TAOS_SYSTEM_ERROR(errno);
177 178 179
    dError("failed to write mnode file:%s since %s, deloyed:%d", realfile, terrstr(), pOption->deploy);
  }
  return code;
S
shm  
Shengliang Guan 已提交
180
}