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
| 347 | * bigger we pad our payload with newlines that are anyway ignored and truncate |
| 348 | * the file afterward. */ |
| 349 | int clusterSaveConfig(int do_fsync) { |
| 350 | sds ci; |
| 351 | size_t content_size; |
| 352 | struct stat sb; |
| 353 | int fd; |
| 354 | |
| 355 | g_pserver->cluster->todo_before_sleep &= ~CLUSTER_TODO_SAVE_CONFIG; |
| 356 | |
| 357 | /* Get the nodes description and concatenate our "vars" directive to |
| 358 | * save currentEpoch and lastVoteEpoch. */ |
| 359 | ci = clusterGenNodesDescription(CLUSTER_NODE_HANDSHAKE, 0); |
| 360 | ci = sdscatprintf(ci,"vars currentEpoch %llu lastVoteEpoch %llu\n", |
| 361 | (unsigned long long) g_pserver->cluster->currentEpoch, |
| 362 | (unsigned long long) g_pserver->cluster->lastVoteEpoch); |
| 363 | content_size = sdslen(ci); |
| 364 | |
| 365 | if ((fd = open(g_pserver->cluster_configfile,O_WRONLY|O_CREAT,0644)) |
| 366 | == -1) goto err; |
| 367 | |
| 368 | /* Pad the new payload if the existing file length is greater. */ |
| 369 | if (fstat(fd,&sb) != -1) { |
| 370 | if (sb.st_size > (off_t)content_size) { |
| 371 | ci = sdsgrowzero(ci,sb.st_size); |
| 372 | memset(ci+content_size,'\n',sb.st_size-content_size); |
| 373 | } |
| 374 | } |
| 375 | if (write(fd,ci,sdslen(ci)) != (ssize_t)sdslen(ci)) goto err; |
| 376 | if (do_fsync) { |
| 377 | g_pserver->cluster->todo_before_sleep &= ~CLUSTER_TODO_FSYNC_CONFIG; |
| 378 | if (fsync(fd) == -1) goto err; |
| 379 | } |
| 380 | |
| 381 | /* Truncate the file if needed to remove the final \n padding that |
| 382 | * is just garbage. */ |
| 383 | if (content_size != sdslen(ci) && ftruncate(fd,content_size) == -1) { |
| 384 | /* ftruncate() failing is not a critical error. */ |
| 385 | } |
| 386 | close(fd); |
| 387 | sdsfree(ci); |
| 388 | return 0; |
| 389 | |
| 390 | err: |
| 391 | if (fd != -1) close(fd); |
| 392 | sdsfree(ci); |
| 393 | return -1; |
| 394 | } |
| 395 | |
| 396 | void clusterSaveConfigOrDie(int do_fsync) { |
| 397 | if (clusterSaveConfig(do_fsync) == -1) { |
no test coverage detected