Cluster node configuration is exactly the same as CLUSTER NODES output. * * This function writes the node config and returns 0, on error -1 * is returned. * * Note: we need to write the file in an atomic way from the point of view * of the POSIX filesystem semantics, so that if the server is stopped * or crashes during the write, we'll end with either the old file or the * new one. Since w
| 330 | * bigger we pad our payload with newlines that are anyway ignored and truncate |
| 331 | * the file afterward. */ |
| 332 | int clusterSaveConfig(int do_fsync) { |
| 333 | sds ci; |
| 334 | size_t content_size; |
| 335 | struct stat sb; |
| 336 | int fd; |
| 337 | |
| 338 | server.cluster->todo_before_sleep &= ~CLUSTER_TODO_SAVE_CONFIG; |
| 339 | |
| 340 | /* Get the nodes description and concatenate our "vars" directive to |
| 341 | * save currentEpoch and lastVoteEpoch. */ |
| 342 | ci = clusterGenNodesDescription(CLUSTER_NODE_HANDSHAKE, 0); |
| 343 | ci = sdscatprintf(ci,"vars currentEpoch %llu lastVoteEpoch %llu\n", |
| 344 | (unsigned long long) server.cluster->currentEpoch, |
| 345 | (unsigned long long) server.cluster->lastVoteEpoch); |
| 346 | content_size = sdslen(ci); |
| 347 | |
| 348 | if ((fd = open(server.cluster_configfile,O_WRONLY|O_CREAT,0644)) |
| 349 | == -1) goto err; |
| 350 | |
| 351 | /* Pad the new payload if the existing file length is greater. */ |
| 352 | if (fstat(fd,&sb) != -1) { |
| 353 | if (sb.st_size > (off_t)content_size) { |
| 354 | ci = sdsgrowzero(ci,sb.st_size); |
| 355 | memset(ci+content_size,'\n',sb.st_size-content_size); |
| 356 | } |
| 357 | } |
| 358 | if (write(fd,ci,sdslen(ci)) != (ssize_t)sdslen(ci)) goto err; |
| 359 | if (do_fsync) { |
| 360 | server.cluster->todo_before_sleep &= ~CLUSTER_TODO_FSYNC_CONFIG; |
| 361 | if (fsync(fd) == -1) goto err; |
| 362 | } |
| 363 | |
| 364 | /* Truncate the file if needed to remove the final \n padding that |
| 365 | * is just garbage. */ |
| 366 | if (content_size != sdslen(ci) && ftruncate(fd,content_size) == -1) { |
| 367 | /* ftruncate() failing is not a critical error. */ |
| 368 | } |
| 369 | close(fd); |
| 370 | sdsfree(ci); |
| 371 | return 0; |
| 372 | |
| 373 | err: |
| 374 | if (fd != -1) close(fd); |
| 375 | sdsfree(ci); |
| 376 | return -1; |
| 377 | } |
| 378 | |
| 379 | void clusterSaveConfigOrDie(int do_fsync) { |
| 380 | if (clusterSaveConfig(do_fsync) == -1) { |
no test coverage detected