Load the cluster config from 'filename'. * * If the file does not exist or is zero-length (this may happen because * when we lock the nodes.conf file, we create a zero-length one for the * sake of locking if it does not already exist), C_ERR is returned. * If the configuration was loaded from the file, C_OK is returned. */
| 91 | * sake of locking if it does not already exist), C_ERR is returned. |
| 92 | * If the configuration was loaded from the file, C_OK is returned. */ |
| 93 | int clusterLoadConfig(char *filename) { |
| 94 | FILE *fp = fopen(filename,"r"); |
| 95 | struct stat sb; |
| 96 | char *line; |
| 97 | int maxline, j; |
| 98 | |
| 99 | if (fp == NULL) { |
| 100 | if (errno == ENOENT) { |
| 101 | return C_ERR; |
| 102 | } else { |
| 103 | serverLog(LL_WARNING, |
| 104 | "Loading the cluster node config from %s: %s", |
| 105 | filename, strerror(errno)); |
| 106 | exit(1); |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | /* Check if the file is zero-length: if so return C_ERR to signal |
| 111 | * we have to write the config. */ |
| 112 | if (fstat(fileno(fp),&sb) != -1 && sb.st_size == 0) { |
| 113 | fclose(fp); |
| 114 | return C_ERR; |
| 115 | } |
| 116 | |
| 117 | /* Parse the file. Note that single lines of the cluster config file can |
| 118 | * be really long as they include all the hash slots of the node. |
| 119 | * This means in the worst possible case, half of the Redis slots will be |
| 120 | * present in a single line, possibly in importing or migrating state, so |
| 121 | * together with the node ID of the sender/receiver. |
| 122 | * |
| 123 | * To simplify we allocate 1024+CLUSTER_SLOTS*128 bytes per line. */ |
| 124 | maxline = 1024+CLUSTER_SLOTS*128; |
| 125 | line = zmalloc(maxline); |
| 126 | while(fgets(line,maxline,fp) != NULL) { |
| 127 | int argc; |
| 128 | sds *argv; |
| 129 | clusterNode *n, *master; |
| 130 | char *p, *s; |
| 131 | |
| 132 | /* Skip blank lines, they can be created either by users manually |
| 133 | * editing nodes.conf or by the config writing process if stopped |
| 134 | * before the truncate() call. */ |
| 135 | if (line[0] == '\n' || line[0] == '\0') continue; |
| 136 | |
| 137 | /* Split the line into arguments for processing. */ |
| 138 | argv = sdssplitargs(line,&argc); |
| 139 | if (argv == NULL) goto fmterr; |
| 140 | |
| 141 | /* Handle the special "vars" line. Don't pretend it is the last |
| 142 | * line even if it actually is when generated by Redis. */ |
| 143 | if (strcasecmp(argv[0],"vars") == 0) { |
| 144 | if (!(argc % 2)) goto fmterr; |
| 145 | for (j = 1; j < argc; j += 2) { |
| 146 | if (strcasecmp(argv[j],"currentEpoch") == 0) { |
| 147 | server.cluster->currentEpoch = |
| 148 | strtoull(argv[j+1],NULL,10); |
| 149 | } else if (strcasecmp(argv[j],"lastVoteEpoch") == 0) { |
| 150 | server.cluster->lastVoteEpoch = |
no test coverage detected