From a05c9bd3447902f50be1ddbaab43798ea8664bf4 Mon Sep 17 00:00:00 2001 From: Rongsong Shen Date: Fri, 8 May 2026 06:51:54 +0000 Subject: [PATCH] feat: support name=host:port format in controller --peers - xce_candidate_t gains name[] field for logical peer identity - parse_peers stores name prefix before '=' (empty when omitted) - cluster_init matches own identity by name first, hostname as fallback enabling multiple controllers on the same dev host via --peers ctrl-1=10.0.1.1:7000,ctrl-2=10.0.1.2:7001 --- src/controller/cluster.c | 10 +++++++--- src/controller/main.c | 15 +++++++++++---- src/include/xce/cluster.h | 6 +++++- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/controller/cluster.c b/src/controller/cluster.c index 5a914a89..931b48ee 100644 --- a/src/controller/cluster.c +++ b/src/controller/cluster.c @@ -650,9 +650,13 @@ int cluster_init(cluster_t* c) if (pcfg->candidates_count > 0) { my_priority = pcfg->candidates_count - 1; /* default: last = lowest */ for (int i = 0; i < pcfg->candidates_count; i++) { - if (strncmp(pcfg->candidates[i].hostname, - c->myconf->name, - XCE_MAXHOSTNAME_LEN - 1) == 0) { + /* Match by logical name first (supports multiple controllers + * on the same dev host via name=host:port syntax). Fall back + * to hostname match when no name was specified. */ + const char* key = pcfg->candidates[i].name[0] + ? pcfg->candidates[i].name + : pcfg->candidates[i].hostname; + if (strncmp(key, c->myconf->name, XCE_MAXNAME_LEN - 1) == 0) { my_priority = i; break; } diff --git a/src/controller/main.c b/src/controller/main.c index 156e6c73..8b63f2eb 100644 --- a/src/controller/main.c +++ b/src/controller/main.c @@ -60,10 +60,17 @@ static int parse_peers(const char* peers_str, xce_cluster_config_t* cfg) if (!colon) return -1; *colon = '\0'; - strncpy(cfg->candidates[cfg->candidates_count].hostname, addr, - XCE_MAXHOSTNAME_LEN - 1); - cfg->candidates[cfg->candidates_count].hostname[XCE_MAXHOSTNAME_LEN - 1] = '\0'; - cfg->candidates[cfg->candidates_count].port = atoi(colon + 1); + xce_candidate_t* cand = &cfg->candidates[cfg->candidates_count]; + if (eq) { + *eq = '\0'; + strncpy(cand->name, tok, XCE_MAXNAME_LEN - 1); + cand->name[XCE_MAXNAME_LEN - 1] = '\0'; + } else { + cand->name[0] = '\0'; + } + strncpy(cand->hostname, addr, XCE_MAXHOSTNAME_LEN - 1); + cand->hostname[XCE_MAXHOSTNAME_LEN - 1] = '\0'; + cand->port = atoi(colon + 1); cfg->candidates_count++; tok = strtok_r(NULL, ",", &saveptr); } diff --git a/src/include/xce/cluster.h b/src/include/xce/cluster.h index 3bd4bdb5..5a33cbdb 100644 --- a/src/include/xce/cluster.h +++ b/src/include/xce/cluster.h @@ -10,9 +10,13 @@ #include "config.h" /* MAX_HA_CANDIDATES, XCE_MAXHOSTNAME_LEN */ /** - * A single controller candidate (host + port). + * A single controller candidate. + * name: logical name from "name=host:port" syntax (empty if omitted). + * Matching against myconf->name allows multiple controllers on the same + * dev host to distinguish themselves by name rather than IP address. */ typedef struct { + char name[XCE_MAXNAME_LEN]; char hostname[XCE_MAXHOSTNAME_LEN]; int port; } xce_candidate_t;