From 7e4528a0b921e6ff028c400b050ff45b617a10c3 Mon Sep 17 00:00:00 2001 From: Rongsong Shen Date: Fri, 8 May 2026 07:06:57 +0000 Subject: [PATCH] refactor: consolidate parse_peers into xce_parse_peers in libxce Three identical static copies (controller, worker, scheduler) replaced with a single xce_parse_peers() in src/lib/cluster.c. The libxce version is the canonical implementation: stores the logical name from 'name=host:port' syntax so daemons on the same dev host can identify themselves by name rather than IP address. --- src/controller/main.c | 40 +-------------------------------------- src/include/xce/cluster.h | 11 +++++++++++ src/lib/cluster.c | 40 +++++++++++++++++++++++++++++++++++++++ src/scheduler/src/main.c | 37 +----------------------------------- src/worker/src/main.c | 37 +----------------------------------- 5 files changed, 54 insertions(+), 111 deletions(-) diff --git a/src/controller/main.c b/src/controller/main.c index 8b63f2e..42c5fd7 100644 --- a/src/controller/main.c +++ b/src/controller/main.c @@ -38,44 +38,6 @@ static struct argp_option options[] = { { 0 } }; -/* parse_peers — split "host:port,host:port,..." into cfg->candidates[]. - * Accepts optional "name=host:port" prefix (name is ignored for controller). - * Returns 0 on success, -1 on empty input or parse error. */ -static int parse_peers(const char* peers_str, xce_cluster_config_t* cfg) -{ - cfg->candidates_count = 0; - if (!peers_str || peers_str[0] == '\0') - return -1; - - char buf[2048]; - strncpy(buf, peers_str, sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; - - char* saveptr; - char* tok = strtok_r(buf, ",", &saveptr); - while (tok && cfg->candidates_count < MAX_HA_CANDIDATES) { - char* eq = strchr(tok, '='); - char* addr = eq ? eq + 1 : tok; - char* colon = strrchr(addr, ':'); - if (!colon) - return -1; - *colon = '\0'; - 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); - } - return cfg->candidates_count > 0 ? 0 : -1; -} static error_t parse_opt(int key, char* arg, struct argp_state* state) { @@ -164,7 +126,7 @@ int main(int argc, char* argv[]) memset(&myconf.peers_cfg, 0, sizeof(myconf.peers_cfg)); if (arguments.peers_str) { - if (parse_peers(arguments.peers_str, &myconf.peers_cfg) != 0) { + if (xce_parse_peers(arguments.peers_str, &myconf.peers_cfg) != 0) { fprintf(stderr, "xce_controller: --peers parse error: expected " "host:port,... got: %s\n", diff --git a/src/include/xce/cluster.h b/src/include/xce/cluster.h index 5a33cbd..4e04e4c 100644 --- a/src/include/xce/cluster.h +++ b/src/include/xce/cluster.h @@ -109,6 +109,17 @@ int xce_reconnect_step(xce_reconnect_ctx_t* rctx); */ void xce_reconnect_fini(xce_reconnect_ctx_t* rctx); +/** + * xce_parse_peers() — parse "--peers name=host:port,..." into cfg->candidates[]. + * + * Each token may be "name=host:port" or bare "host:port". + * The name field is stored when present; it allows multiple daemons on the + * same host to identify themselves by logical name rather than IP address. + * + * Returns 0 on success, -1 on empty/NULL input or any parse error. + */ +int xce_parse_peers(const char* peers_str, xce_cluster_config_t* cfg); + /* Test seam: set to non-NULL to override the real connect (unit tests only) */ typedef void* (*xce_connect_fn_t)(const char* host, int port, const char* ca_cert); diff --git a/src/lib/cluster.c b/src/lib/cluster.c index a19b4a7..32544bb 100644 --- a/src/lib/cluster.c +++ b/src/lib/cluster.c @@ -14,11 +14,51 @@ #include #include #include +#include #include #include #include "xce/cluster.h" +/* ── Peer list parsing ─────────────────────────────────────────── */ + +int xce_parse_peers(const char* peers_str, xce_cluster_config_t* cfg) +{ + cfg->candidates_count = 0; + if (!peers_str || peers_str[0] == '\0') + return -1; + + char buf[2048]; + strncpy(buf, peers_str, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; + + char* saveptr; + char* tok = strtok_r(buf, ",", &saveptr); + while (tok && cfg->candidates_count < MAX_HA_CANDIDATES) { + /* Format: name=host:port OR host:port */ + char* eq = strchr(tok, '='); + char* addr = eq ? eq + 1 : tok; + char* colon = strrchr(addr, ':'); + if (!colon) + return -1; + *colon = '\0'; + 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); + } + return cfg->candidates_count > 0 ? 0 : -1; +} + /* ── Test seam ─────────────────────────────────────────────────── */ static xce_connect_fn_t s_connect_fn = NULL; diff --git a/src/scheduler/src/main.c b/src/scheduler/src/main.c index 2e07e30..5ea45dd 100644 --- a/src/scheduler/src/main.c +++ b/src/scheduler/src/main.c @@ -15,41 +15,6 @@ #include "resreq.h" #include "utils.h" -/* parse_peers — parse "--peers ctrl-1=10.0.1.1:7000,ctrl-2=10.0.1.2:7001" - * into cfg->candidates[]. Returns 0 on success, -1 on parse error. - * If peers_str is NULL or empty returns -1 (caller falls back to single-host - * path). */ -static int parse_peers(const char* peers_str, xce_cluster_config_t* cfg) -{ - cfg->candidates_count = 0; - if (!peers_str || peers_str[0] == '\0') - return -1; - - char buf[2048]; - strncpy(buf, peers_str, sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; - - char* saveptr; - char* tok = strtok_r(buf, ",", &saveptr); - - while (tok && cfg->candidates_count < MAX_HA_CANDIDATES) { - /* Format: name=host:port OR host:port */ - char* eq = strchr(tok, '='); - char* addr = eq ? eq + 1 : tok; - char* colon = strrchr(addr, ':'); - 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); - cfg->candidates_count++; - tok = strtok_r(NULL, ",", &saveptr); - } - return cfg->candidates_count > 0 ? 0 : -1; -} extern int scheduler_req_handler(xce_request_t*, void*); @@ -161,7 +126,7 @@ int main(int argc, char* argv[]) if (arguments.peers) { xce_cluster_config_t cluster_cfg = {0}; - if (parse_peers(arguments.peers, &cluster_cfg) != 0) { + if (xce_parse_peers(arguments.peers, &cluster_cfg) != 0) { fprintf(stderr, "xce_scheduler: --peers parse error: expected " "\"[name=]host:port,...\" got \"%s\"\n", diff --git a/src/worker/src/main.c b/src/worker/src/main.c index 18161c1..f4fa180 100644 --- a/src/worker/src/main.c +++ b/src/worker/src/main.c @@ -250,41 +250,6 @@ static void master_rusages_callback(xce_job_rusages_t* rusages) free_xce_job_rusages(rusages); } -/* parse_peers — parse "--peers ctrl-1=10.0.1.1:7000,ctrl-2=10.0.1.2:7001" - * into cfg->candidates[]. Returns 0 on success, -1 on parse error. - * If peers_str is NULL or empty, returns -1 (caller falls back to single-host - * path). */ -static int parse_peers(const char* peers_str, xce_cluster_config_t* cfg) -{ - cfg->candidates_count = 0; - if (!peers_str || peers_str[0] == '\0') - return -1; - - char buf[2048]; - strncpy(buf, peers_str, sizeof(buf) - 1); - buf[sizeof(buf) - 1] = '\0'; - - char* saveptr; - char* tok = strtok_r(buf, ",", &saveptr); - - while (tok && cfg->candidates_count < MAX_HA_CANDIDATES) { - /* Format: name=host:port OR host:port */ - char* eq = strchr(tok, '='); - char* addr = eq ? eq + 1 : tok; - char* colon = strrchr(addr, ':'); - 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); - cfg->candidates_count++; - tok = strtok_r(NULL, ",", &saveptr); - } - return cfg->candidates_count > 0 ? 0 : -1; -} static int check_xce_server_dir(char* myfile) { @@ -497,7 +462,7 @@ int main(int argc, char* argv[]) /* P2.5-5: populate and validate xce_cluster_config_t when --peers given */ if (peers_str) { - if (parse_peers(peers_str, &cluster_cfg) != 0) { + if (xce_parse_peers(peers_str, &cluster_cfg) != 0) { fprintf(stderr, "xcecd: --peers parse error: expected " "\"[name=]host:port,...\" got \"%s\"\n",