summaryrefslogtreecommitdiff
path: root/ctdb
diff options
context:
space:
mode:
authorMartin Schwenke <martin@meltin.net>2022-07-05 12:31:57 +1000
committerAmitay Isaacs <amitay@samba.org>2022-07-22 16:09:31 +0000
commit00f1d6d94764ba1312500c72fd08e7df3fae064b (patch)
treea28ccf8b23a1b6b25c492d2554a796ab60ae5fe3 /ctdb
parentb686bbb4ac37296e23e74c1c10145f22b6d29d42 (diff)
downloadsamba-00f1d6d94764ba1312500c72fd08e7df3fae064b.tar.gz
ctdb-common: Use POSIX if_nameindex() to check interface existence
This works as an unprivileged user, so avoids unnecessary errors when running in test mode (and not as root): 2022-02-18T12:21:12.436491+11:00 node.0 ctdbd[6958]: ctdb_sys_check_iface_exists: Failed to open raw socket 2022-02-18T12:21:12.436534+11:00 node.0 ctdbd[6958]: ctdb_sys_check_iface_exists: Failed to open raw socket 2022-02-18T12:21:12.436557+11:00 node.0 ctdbd[6958]: ctdb_sys_check_iface_exists: Failed to open raw socket 2022-02-18T12:21:12.436577+11:00 node.0 ctdbd[6958]: ctdb_sys_check_iface_exists: Failed to open raw socket The corresponding porting test would now become pointless because it would just confirm that "fake" does not exist. Attempt to make it useful by using a less likely name than "fake" and attempting to detect the loopback interface. Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com>
Diffstat (limited to 'ctdb')
-rw-r--r--ctdb/common/system.c38
-rwxr-xr-xctdb/tests/UNIT/cunit/porting_tests_001.sh15
-rw-r--r--ctdb/tests/src/porting_tests.c18
3 files changed, 33 insertions, 38 deletions
diff --git a/ctdb/common/system.c b/ctdb/common/system.c
index 650b62bab16..08dc68284fd 100644
--- a/ctdb/common/system.c
+++ b/ctdb/common/system.c
@@ -148,32 +148,36 @@ void ctdb_wait_for_process_to_exit(pid_t pid)
}
}
-#ifdef HAVE_AF_PACKET
+#ifdef HAVE_IF_NAMEINDEX
bool ctdb_sys_check_iface_exists(const char *iface)
{
- int s;
- struct ifreq ifr;
+ struct if_nameindex *ifnis, *ifni;
+ bool found = false;
- s = socket(AF_PACKET, SOCK_RAW, 0);
- if (s == -1){
- /* We don't know if the interface exists, so assume yes */
- DBG_ERR("Failed to open raw socket\n");
- return true;
+ ifnis = if_nameindex();
+ if (ifnis == NULL) {
+ DBG_ERR("Failed to retrieve inteface list\n");
+ return false;
}
- strlcpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name));
- if (ioctl(s, SIOCGIFINDEX, &ifr) < 0 && errno == ENODEV) {
- DBG_ERR("Interface '%s' not found\n", iface);
- close(s);
- return false;
+ for (ifni = ifnis;
+ ifni->if_index != 0 || ifni->if_name != NULL;
+ ifni++) {
+ int cmp = strcmp(iface, ifni->if_name);
+ if (cmp == 0) {
+ found = true;
+ goto done;
+ }
}
- close(s);
- return true;
+done:
+ if_freenameindex(ifnis);
+
+ return found;
}
-#else /* HAVE_AF_PACKET */
+#else /* HAVE_IF_NAMEINDEX */
bool ctdb_sys_check_iface_exists(const char *iface)
{
@@ -181,7 +185,7 @@ bool ctdb_sys_check_iface_exists(const char *iface)
return true;
}
-#endif /* HAVE_AF_PACKET */
+#endif /* HAVE_IF_NAMEINDEX */
#ifdef HAVE_PEERCRED
diff --git a/ctdb/tests/UNIT/cunit/porting_tests_001.sh b/ctdb/tests/UNIT/cunit/porting_tests_001.sh
index 52291b20cc6..bdb7fc531d4 100755
--- a/ctdb/tests/UNIT/cunit/porting_tests_001.sh
+++ b/ctdb/tests/UNIT/cunit/porting_tests_001.sh
@@ -11,16 +11,5 @@ remove_socket ()
test_cleanup remove_socket
-os=$(uname)
-if [ "$os" = "Linux" ] ; then
- uid=$(id -u)
- if [ "$uid" -eq 0 ] ; then
- ok "ctdb_sys_check_iface_exists: Interface 'fake' not found"
- else
- ok "ctdb_sys_check_iface_exists: Failed to open raw socket"
- fi
-else
- ok_null
-fi
-
-unit_test porting_tests --socket=${socket}
+ok_null
+unit_test porting_tests --socket="$socket"
diff --git a/ctdb/tests/src/porting_tests.c b/ctdb/tests/src/porting_tests.c
index 8902c34dfc2..00618d2c4a7 100644
--- a/ctdb/tests/src/porting_tests.c
+++ b/ctdb/tests/src/porting_tests.c
@@ -171,15 +171,17 @@ static int fork_helper(void)
*/
static int test_ctdb_sys_check_iface_exists(void)
{
- const char *fakename = "fake";
- bool test;
+ bool test1, test2;
+
+ test1 = ctdb_sys_check_iface_exists("unlikely123xyz");
+ assert(!test1);
+
+ /* Linux and others */
+ test1 = ctdb_sys_check_iface_exists("lo");
+ /* FreeBSD */
+ test2 = ctdb_sys_check_iface_exists("lo0");
+ assert(test1 || test2);
- test = ctdb_sys_check_iface_exists(fakename);
- if (geteuid() == 0) {
- assert(test == false);
- } else {
- assert(test == true);
- }
return 0;
}