Repository: valkey-io/valkey
File: src/cluster_legacy.c (C)

Code before:
cleanup:
    if (fd != -1) {
        latencyStartMonitor(latency);
        close(fd);
        latencyEndMonitor(latency);
        latencyAddSampleIfNeeded("cluster-config-close", latency);
    }
    if (retval == C_ERR) {
        latencyStartMonitor(latency);
        unlink(tmpfilename);
        latencyEndMonitor(latency);
        latencyAddSampleIfNeeded("cluster-config-unlink", latency);
    }
    sdsfree(tmpfilename);
    sdsfree(ci);
    return retval;
}

void clusterSaveConfigOrDie(int do_fsync) {
    if (clusterSaveConfig(do_fsync) == C_ERR) {
        if (!server.cluster_ignore_disk_write_error) {
            serverLog(LL_WARNING, "Fatal: can't update cluster config file");
            exit(1);
        } else {
            static mstime_t last_log_time_ms = 0;
            const mstime_t log_interval_ms = 10000;
            if (server.mstime > last_log_time_ms + log_interval_ms) {
                last_log_time_ms = server.mstime;
                serverLog(LL_WARNING, "Cluster config file is applying a change even though "
                                      "it is unable to write to disk.");
            }
        }
    }
}

/* Lock the cluster config using flock(), and retain the file descriptor used to
 * acquire the lock so that the file will be locked as long as the process is up.
 *
 * This works because we always update nodes.conf with a new version
 * in-place, reopening the file, and writing to it in place (later adjusting
 * the length with ftruncate()).
 *
 * On success C_OK is returned, otherwise an error is logged and
 * the function returns C_ERR to signal a lock was not acquired. */
int clusterLockConfig(char *filename) {
/* flock() does not exist on Solaris
 * and a fcntl-based solution won't help, as we constantly re-open that file,
 * which will release _all_ locks anyway
 */
#if !defined(__sun)
    /* To lock it, we need to open the file in a way it is created if

Review comment (suggestion):
We may need a configuration item to control this in the future, currently this logic is copy from `replica-ignore-disk-write-errors`

Code after:

        /* Populate hash slots served by this instance. */
        for (j = 8; j < argc; j++) {
            int start, stop;

            if (argv[j][0] == '[') {
                /* Here we handle migrating / importing slots */
                int slot;
                char direction;
                clusterNode *cn;

                p = strchr(argv[j], '-');
                serverAssert(p != NULL);
                *p = '\0';
                direction = p[1]; /* Either '>' or '<' */
                slot = atoi(argv[j] + 1);
                if (slot < 0 || slot >= CLUSTER_SLOTS) {
                    sdsfreesplitres(argv, argc);
                    goto fmterr;
                }
                p += 3;

                char *pr = strchr(p, ']');
                size_t node_len = pr - p;
                if (pr == NULL || verifyClusterNodeId(p, node_len) == C_ERR) {
                    sdsfreesplitres(argv, argc);
                    goto fmterr;
                }
                cn = clusterLookupNode(p, CLUSTER_NAMELEN);
                if (!cn) {
                    cn = createClusterNode(p, 0);
                    clusterAddNode(cn);
                }
                if (direction == '>') {
                    setMigratingSlotDest(slot, cn);
                } else {
                    setImportingSlotSource(slot, cn);
                }
                continue;
            } else if ((p = strchr(argv[j], '-')) != NULL) {
                *p = '\0';
                start = atoi(argv[j]);
                stop = atoi(p + 1);
            } else {
                start = stop = atoi(argv[j]);
            }
            if (start < 0 || start >= CLUSTER_SLOTS || stop < 0 || stop >= CLUSTER_SLOTS) {
                sdsfreesplitres(argv, argc);
                goto fmterr;
            }
            while (start <= stop) clusterAddSlot(n, start++);