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

Code before:
        }
    }

    /* We are not able to find the replica to do the auto failover. */
    if (best_replica == NULL) {
        if (legacy_replica) {
            serverLog(LL_NOTICE, "Unable to perform auto failover on shutdown since there are legacy replicas.");
        } else {
            serverLog(LL_NOTICE, "Unable to find a replica to perform the auto failover on shutdown.");
        }
        return;
    }

    /* Send the CLUSTER FAILOVER FORCE REPLICAID node-id to all replicas since
     * it is a shared replication buffer, but only the replica with the matching
     * node-id will execute it. The caller will call flushReplicasOutputBuffers,
     * so in here it is a best effort. */
    char buf[128];
    size_t buflen = snprintf(buf, sizeof(buf),
                             "*5\r\n$7\r\nCLUSTER\r\n"
                             "$8\r\nFAILOVER\r\n"
                             "$5\r\nFORCE\r\n"
                             "$9\r\nREPLICAID\r\n"
                             "$%d\r\n%s\r\n",
                             CLUSTER_NAMELEN,
                             best_replica->repl_data->replica_nodeid);
    serverAssert(buflen <= 128);
    /* Must install write handler for all replicas first before feeding
     * replication stream. */
    prepareReplicasToWrite();
    feedReplicationBuffer(buf, buflen);
    serverLog(LL_NOTICE, "Perform auto failover to replica %s on shutdown.", best_replica->repl_data->replica_nodeid);
}

/* Called when a cluster node receives SHUTDOWN. */
void clusterHandleServerShutdown(void) {
    /* Check if we are able to do the auto failover on shutdown. */
    clusterAutoFailoverOnShutdown();

    /* The error logs have been logged in the save function if the save fails. */
    serverLog(LL_NOTICE, "Saving the cluster configuration file before exiting.");
    clusterSaveConfig(1);

#if !defined(__sun)
    /* Unlock the cluster config file before shutdown, see clusterLockConfig.
     *
     * This is needed if you shutdown a very large server process, it will take
     * a while for the OS to release resources and unlock the cluster configuration
     * file. Therefore, if we immediately try to restart the server process, it
     * may not be able to acquire the lock on the cluster configuration file and
     * fail to start. We explicitly releases the lock on the cluster configuration

Review comment (bug):
Safer to limit the node id

```suggestion
    size_t buflen = snprintf(buf, sizeof(buf),
                             "*5\r\n$7\r\nCLUSTER\r\n"
                             "$8\r\nFAILOVER\r\n"
                             "$5\r\nFORCE\r\n"
                             "$9\r\nREPLICAID\r\n"
                             "$%d\r\n%.40s\r\n",
                             CLUSTER_NAMELEN,
                             best_replica->repl_data->replica_nodeid);
```

Code after:
        if (replica->repl_data->repl_state == REPLICA_STATE_ONLINE &&
            replica->repl_data->repl_ack_off == server.primary_repl_offset &&
            replica->repl_data->replica_nodeid && sdslen(replica->repl_data->replica_nodeid) == CLUSTER_NAMELEN) {
            best_replica = replica;
        }
    }

    /* We are not able to find the replica to do the auto failover. */
    if (best_replica == NULL) {
        if (legacy_replica) {
            serverLog(LL_NOTICE, "Unable to perform auto failover on shutdown since there are legacy replicas.");
        } else {
            serverLog(LL_NOTICE, "Unable to find a replica to perform the auto failover on shutdown.");
        }
        return;
    }

    /* Send the CLUSTER FAILOVER FORCE REPLICAID node-id to all replicas since
     * it is a shared replication buffer, but only the replica with the matching
     * node-id will execute it. The caller will call flushReplicasOutputBuffers,
     * so in here it is a best effort. */
    char buf[128];
    size_t buflen = snprintf(buf, sizeof(buf),
                             "*5\r\n$7\r\nCLUSTER\r\n"
                             "$8\r\nFAILOVER\r\n"
                             "$5\r\nFORCE\r\n"
                             "$9\r\nREPLICAID\r\n"
                             "$%d\r\n%.*s\r\n",
                             CLUSTER_NAMELEN,
                             CLUSTER_NAMELEN,
                             best_replica->repl_data->replica_nodeid);
    serverAssert(buflen <= 128);
    /* Must install write handler for all replicas first before feeding
     * replication stream. */
    prepareReplicasToWrite();
    feedReplicationBuffer(buf, buflen);
    serverLog(LL_NOTICE, "Perform auto failover to replica %s on shutdown.", best_replica->repl_data->replica_nodeid);
}

/* Called when a cluster node receives SHUTDOWN. */
void clusterHandleServerShutdown(void) {
    /* Check if we are able to do the auto failover on shutdown. */
    clusterAutoFailoverOnShutdown();

    /* The error logs have been logged in the save function if the save fails. */
    serverLog(LL_NOTICE, "Saving the cluster configuration file before exiting.");
    clusterSaveConfig(1);

#if !defined(__sun)
    /* Unlock the cluster config file before shutdown, see clusterLockConfig.
     *