Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

broker: add FLUX_IPADDR_INTERFACE to select broker network interface #5707

Merged
merged 4 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions doc/man7/flux-environment.rst
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,11 @@ affect the broker's PMI client.
version 4 addresses. Setting this variable to any value in the broker's
environment causes it to prefer version 6 addresses.

.. envvar:: FLUX_IPADDR_HOSTNAME

Force PMI bootstrap to assign the broker an address associated with a
particular network interface, like ``eth0``.


CUSTOM OUTPUT FORMATS
=====================
Expand Down
2 changes: 1 addition & 1 deletion src/broker/boot_pmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ static int format_bind_uri (char *buf, int bufsz, attr_t *attrs, int rank)

if (ipaddr_getprimary (ipaddr, sizeof (ipaddr),
error, sizeof (error)) < 0) {
log_err ("%s", error);
log_msg ("%s", error);
return -1;
}
if (snprintf (buf, bufsz, "tcp://%s:*", ipaddr) >= bufsz)
Expand Down
47 changes: 38 additions & 9 deletions src/common/libutil/ipaddr.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,17 @@ static struct ifaddrs *find_ifaddr (struct ifaddrs *ifaddr,
return ifa;
}

static int getprimary_ifaddr (char *buf, int len, int prefer_family,
char *errstr, int errstrsz)
static int getnamed_ifaddr (char *buf,
int len,
const char *name,
int prefer_family,
char *errstr,
int errstrsz)
{
struct ifaddrs *ifaddr;
struct ifaddrs *ifa;
char name[64];
int error;

if (getprimary_iface4 (name, sizeof (name), errstr, errstrsz) < 0)
return -1;
if (getifaddrs (&ifaddr) < 0) {
esprintf (errstr, errstrsz, "getifaddrs: %s", strerror (errno));
return -1;
Expand Down Expand Up @@ -141,6 +142,18 @@ static int getprimary_ifaddr (char *buf, int len, int prefer_family,
return 0;
}

static int getprimary_ifaddr (char *buf,
int len,
int prefer_family,
char *errstr,
int errstrsz)
{
char name[64];
if (getprimary_iface4 (name, sizeof (name), errstr, errstrsz) < 0)
return -1;
return getnamed_ifaddr (buf, len, name, prefer_family, errstr, errstrsz);
}

static struct addrinfo *find_addrinfo (struct addrinfo *addrinfo, int family)
{
struct addrinfo *ai;
Expand Down Expand Up @@ -205,12 +218,28 @@ int ipaddr_getprimary (char *buf, int len,
char *errstr, int errstrsz)
{
int prefer_family = getenv ("FLUX_IPADDR_V6") ? AF_INET6 : AF_INET;
const char *iface_name;
int rc = -1;

if (getenv ("FLUX_IPADDR_HOSTNAME") == NULL)
rc = getprimary_ifaddr (buf, len, prefer_family, errstr, errstrsz);
if (rc < 0)
rc = getprimary_hostaddr (buf, len, prefer_family, errstr, errstrsz);
if ((iface_name = getenv ("FLUX_IPADDR_INTERFACE"))) {
rc = getnamed_ifaddr (buf,
len,
iface_name,
prefer_family,
errstr,
errstrsz);
}
else {
if (getenv ("FLUX_IPADDR_HOSTNAME") == NULL)
rc = getprimary_ifaddr (buf, len, prefer_family, errstr, errstrsz);
if (rc < 0) {
rc = getprimary_hostaddr (buf,
len,
prefer_family,
errstr,
errstrsz);
}
}
return rc;
}

Expand Down
3 changes: 3 additions & 0 deletions src/common/libutil/ipaddr.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* 1. Find the interface associated with the default route, then
* look up address of that interface.
* 2. Look up address associated with the hostname
* 3. Look up address associated with a specific interface.
*
* Main use case: determine bind address for a PMI-bootstrapped flux broker.
*
Expand All @@ -29,6 +30,8 @@
* FLUX_IPADDR_HOSTNAME
* if set, only method 2 is tried above
* if unset, first method 1 is tried, then if that fails, method 2 is tried
* FLUX_IPADDR_INTERFACE
* if set, only method 3 is tried above
*
* Return address as a string in buf (up to len bytes, always null terminated)
* Return 0 on success, -1 on error with error message written to errstr
Expand Down
11 changes: 11 additions & 0 deletions t/t0001-basic.t
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,17 @@ test_expect_success 'tbon.endpoint uses tcp:// if tbon.prefertcp is set' '
flux getattr tbon.endpoint >endpoint2.out &&
grep "^tcp" endpoint2.out
'
test_expect_success 'FLUX_IPADDR_INTERFACE=lo works' '
FLUX_IPADDR_INTERFACE=lo flux start \
${ARGS} -s2 -o,-Stbon.prefertcp=1 \
flux getattr tbon.endpoint >endpoint3.out &&
grep "127.0.0.1" endpoint3.out
'
test_expect_success 'FLUX_IPADDR_INTERFACE=badiface fails' '
(export FLUX_IPADDR_INTERFACE=badiface; \
test_expect_code 137 flux start \
${ARGS} --test-exit-timeout=1s -s2 -o,-Stbon.prefertcp=1 true)
'
test_expect_success 'tbon.endpoint cannot be set' '
test_must_fail flux start ${ARGS} -s2 \
-o,--setattr=tbon.endpoint=ipc:///tmp/customflux /bin/true
Expand Down
Loading