From 1d772cd518aecc21d37552cb460bc1a7f47eae5a Mon Sep 17 00:00:00 2001 From: waynehao Date: Wed, 14 Oct 2026 15:28:36 +0800 Subject: [PATCH] Let the F-Stack tools find a stack started with a vdev or file_prefix by itself (issue #419): every DPDK primary records its EAL runtime directory in /var/run/ff_primary.conf (pid, start time, runtime_dir), and ff_ipc_init() falls back to that record after FF_FILE_PREFIX and the resident slim primary's record, before the EAL default. Before this, a [vdevN] config ran the stack under --file-prefix=container while the tools attached to rte and failed with "mp_socket ... Connection refused". The record is checked like the slim one (live pid with the same start time, a direct child of /var/run/dpdk/); the file_prefix naming is unchanged. --- lib/ff_dpdk_if.c | 56 +++++++++++++++++++++++++++++++++++++++++++ tools/README.md | 3 ++- tools/compat/ff_ipc.c | 15 ++++++++---- 3 files changed, 69 insertions(+), 5 deletions(-) diff --git a/lib/ff_dpdk_if.c b/lib/ff_dpdk_if.c index 1cdd51640..63083c3d0 100644 --- a/lib/ff_dpdk_if.c +++ b/lib/ff_dpdk_if.c @@ -24,9 +24,13 @@ * */ #include +#include +#include +#include #include #include #include +#include #include #include @@ -103,6 +107,9 @@ typedef char ff_reload_ring_name_fit_check[ + 2 + 1 /* "_g" + generation */ <= (size_t)(RTE_RING_NAMESIZE - 1)) ? 1 : -1]; +/* also read by tools/compat/ff_ipc.c */ +#define FF_PRIMARY_RECORD "/var/run/ff_primary.conf" + #ifdef FF_KNI #define KNI_MBUF_MAX 2048 #define KNI_QUEUE_SIZE KNI_MBUF_MAX @@ -2001,6 +2008,51 @@ fdir_add_tcp_flow(uint16_t port_id, uint16_t queue, uint16_t dir, #endif +/* lets the F-Stack tools find this primary's EAL file prefix + * (tools/compat/ff_ipc.c reads it back). Best effort: a missing record + * only means the tools fall back to FF_FILE_PREFIX or the default. */ +static void +ff_primary_record_write(void) +{ + char path[64], buf[1024], tmp[sizeof(FF_PRIMARY_RECORD) + 24], *p; + unsigned long long start; + int fd, i, rc; + ssize_t n; + + snprintf(path, sizeof(path), "/proc/%d/stat", (int)getpid()); + fd = open(path, O_RDONLY); + if (fd < 0) + return; + n = read(fd, buf, sizeof(buf) - 1); + close(fd); + if (n <= 0) + return; + buf[n] = '\0'; + + /* field 22 (starttime), counted after the ")" that ends comm */ + p = strrchr(buf, ')'); + if (p == NULL || p[1] != ' ') + return; + p += 2; + for (i = 0; i < 19; i++) { + p = strchr(p, ' '); + if (p == NULL) + return; + p++; + } + start = strtoull(p, NULL, 10); + + snprintf(tmp, sizeof(tmp), FF_PRIMARY_RECORD ".%d.tmp", (int)getpid()); + fd = open(tmp, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0644); + if (fd < 0) + return; + rc = dprintf(fd, "pid=%d\nstart_time=%llu\nruntime_dir=%s\n", + (int)getpid(), start, rte_eal_get_runtime_dir()); + close(fd); + if (rc <= 0 || rename(tmp, FF_PRIMARY_RECORD) != 0) + unlink(tmp); +} + int ff_dpdk_init(int argc, char **argv) { @@ -2019,6 +2071,10 @@ ff_dpdk_init(int argc, char **argv) rte_exit(EXIT_FAILURE, "Error with EAL initialization\n"); } + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + ff_primary_record_write(); + } + if (ff_global_cfg.log.level) { ff_log_open_set(); } diff --git a/tools/README.md b/tools/README.md index 497be2890..c6c87dd86 100644 --- a/tools/README.md +++ b/tools/README.md @@ -31,8 +31,9 @@ Each tool add an option `-p`(Which F-Stack process to communicate with, default The tools attach to the stack as DPDK secondary processes, so they must use the stack's EAL file prefix (the directory name under `/var/run/dpdk/`): - with `graceful_reload=1` the prefix is read from the resident slim primary's record `/var/run/ff_slim_primary.conf` (only while that primary is alive); +- otherwise from the record every F-Stack primary writes, `/var/run/ff_primary.conf` (only while that primary is alive; with several stacks on one host it names the one started last); - otherwise the DPDK default `rte` is used; -- `FF_FILE_PREFIX=` overrides both. Note that `[dpdk] file_prefix=` in config.ini gives the directory `container-`, and a config with `[vdevN]` but no file_prefix gives `container`, e.g. `FF_FILE_PREFIX=container- ff_top`. +- `FF_FILE_PREFIX=` overrides all of them, e.g. to pick one of several stacks. Note that `[dpdk] file_prefix=` in config.ini gives the directory `container-`, and a config with `[vdevN]` but no file_prefix gives `container`, e.g. `FF_FILE_PREFIX=container- ff_top`. The tools do not probe PCI devices (`--no-pci`). `ff_top` and `ff_traffic` follow graceful reloads while sampling: a sample taken right after the target switched generations is not printed, because the new generation's counters start from zero. diff --git a/tools/compat/ff_ipc.c b/tools/compat/ff_ipc.c index 094d442ba..625caccc5 100644 --- a/tools/compat/ff_ipc.c +++ b/tools/compat/ff_ipc.c @@ -49,6 +49,8 @@ static int ff_ipc_exited; /* EAL file prefix override, the directory name under /var/run/dpdk */ #define FF_IPC_PREFIX_ENV "FF_FILE_PREFIX" #define FF_IPC_PRIMARY_RECORD "/var/run/ff_slim_primary.conf" +/* written by every F-Stack primary (lib/ff_dpdk_if.c) */ +#define FF_IPC_FSTACK_RECORD "/var/run/ff_primary.conf" #define FF_IPC_RUNTIME_BASE "/var/run/dpdk/" static struct rte_mempool *message_pool; @@ -408,8 +410,9 @@ ff_ipc_proc_start(long pid, unsigned long long *start) return 0; } -/* EAL file prefix of the runtime directory recorded by a live resident - * slim primary (graceful_reload=1). No heap use: the EAL is not up yet. */ +/* EAL file prefix of the runtime directory recorded by a live primary: + * the resident slim primary (graceful_reload=1) or any F-Stack primary. + * No heap use: the EAL is not up yet. */ static int ff_ipc_record_prefix(const char *record, char *prefix, size_t len) { @@ -450,8 +453,9 @@ ff_ipc_record_prefix(const char *record, char *prefix, size_t len) return 0; } -/* FF_FILE_PREFIX wins, then the resident primary's record; otherwise - * the EAL default prefix is used. */ +/* FF_FILE_PREFIX wins, then the resident primary's record; ff_ipc_init() + * then tries the F-Stack primary's record, otherwise the EAL default + * prefix is used. */ static const char * ff_ipc_file_prefix(const char *record, char *prefix, size_t len) { @@ -500,6 +504,9 @@ ff_ipc_init(void) argc = (int)(sizeof(dpdk_argv) / sizeof(dpdk_argv[0])) - 2; p = ff_ipc_file_prefix(FF_IPC_PRIMARY_RECORD, prefix, sizeof(prefix)); + if (p == NULL && ff_ipc_record_prefix(FF_IPC_FSTACK_RECORD, prefix, + sizeof(prefix)) == 0) + p = prefix; if (p != NULL) { snprintf(prefix_arg, sizeof(prefix_arg), "--file-prefix=%s", p); dpdk_argv[argc++] = prefix_arg;