All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martin Wilck <martin.wilck@suse.com>
To: Christophe Varoqui <christophe.varoqui@opensvc.com>,
	Benjamin Marzinski <bmarzins@redhat.com>
Cc: dm-devel@lists.linux.dev
Subject: [PATCH v2 1/2] multipath-tools tests: fix CI failures on arm/v7 with glibc 2.37
Date: Tue, 16 Apr 2024 20:53:50 +0200	[thread overview]
Message-ID: <20240416185351.30670-2-mwilck@suse.com> (raw)
In-Reply-To: <20240416185351.30670-1-mwilck@suse.com>

glibc 2.37 has added several new wrappers around the ioctl and
io_getevents system calls on 32 bit systems, to deal with 64bit
time_t. These aren't resolved with cmocka's wrapping technique.

Fix this with C preprocessor trickery, similar to
7b217f8 ("multipath-tools: Makefile.inc: set _FILE_OFFSET_BITS=64").

Note: the directio test with DIO_TEST_DEV for fails under qemu-linux-user
with foreign-arch binfmt, because aio-related system calls are unsupported
by qemu-linux-user. See https://gitlab.com/qemu-project/qemu/-/issues/210.

Signed-off-by: Martin Wilck <mwilck@suse.com>
---
 tests/directio.c | 28 ++++++++++++++--------------
 tests/vpd.c      | 35 ++++++++++++++++++-----------------
 tests/wrap64.h   | 25 ++++++++++++++++++++++++-
 3 files changed, 56 insertions(+), 32 deletions(-)

diff --git a/tests/directio.c b/tests/directio.c
index cbedcc9..d5f84f1 100644
--- a/tests/directio.c
+++ b/tests/directio.c
@@ -41,13 +41,13 @@ struct timespec full_timeout = { .tv_sec = -1 };
 #define ioctl_request_t int
 #endif
 
-int __real_ioctl(int fd, ioctl_request_t request, void *argp);
+int REAL_IOCTL(int fd, ioctl_request_t request, void *argp);
 
-int __wrap_ioctl(int fd, ioctl_request_t request, void *argp)
+int WRAP_IOCTL(int fd, ioctl_request_t request, void *argp)
 {
 #ifdef DIO_TEST_DEV
 	mock_type(int);
-	return __real_ioctl(fd, request, argp);
+	return REAL_IOCTL(fd, request, argp);
 #else
 	int *blocksize = (int *)argp;
 
@@ -148,10 +148,10 @@ int __wrap_io_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt)
 #endif
 }
 
-int __real_io_getevents(io_context_t ctx, long min_nr, long nr,
+int REAL_IO_GETEVENTS(io_context_t ctx, long min_nr, long nr,
 			struct io_event *events, struct timespec *timeout);
 
-int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr,
+int WRAP_IO_GETEVENTS(io_context_t ctx, long min_nr, long nr,
 			struct io_event *events, struct timespec *timeout)
 {
 	int nr_evs;
@@ -169,8 +169,8 @@ int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr,
 #ifdef DIO_TEST_DEV
 	mock_ptr_type(struct timespec *);
 	mock_ptr_type(struct io_event *);
-	assert_int_equal(nr_evs, __real_io_getevents(ctx, min_nr, nr_evs,
-						     events, timeout));
+	assert_int_equal(nr_evs, REAL_IO_GETEVENTS(ctx, min_nr, nr_evs,
+						   events, timeout));
 #else
 	sleep_tmo = mock_ptr_type(struct timespec *);
 	if (sleep_tmo) {
@@ -193,7 +193,7 @@ int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr,
 
 static void return_io_getevents_none(void)
 {
-	will_return(__wrap_io_getevents, 0);
+	wrap_will_return(WRAP_IO_GETEVENTS, 0);
 }
 
 static void return_io_getevents_nr(struct timespec *ts, int nr,
@@ -207,15 +207,15 @@ static void return_io_getevents_nr(struct timespec *ts, int nr,
 			mock_events[i + ev_off].res = reqs[i]->blksize;
 	}
 	while (nr > 0) {
-		will_return(__wrap_io_getevents, (nr > 128)? 128 : nr);
-		will_return(__wrap_io_getevents, ts);
-		will_return(__wrap_io_getevents, &mock_events[off + ev_off]);
+		wrap_will_return(WRAP_IO_GETEVENTS, (nr > 128)? 128 : nr);
+		wrap_will_return(WRAP_IO_GETEVENTS, ts);
+		wrap_will_return(WRAP_IO_GETEVENTS, &mock_events[off + ev_off]);
 		ts = NULL;
 		off += 128;
 		nr -= 128;
 	}
 	if (nr == 0)
-		will_return(__wrap_io_getevents, 0);
+		wrap_will_return(WRAP_IO_GETEVENTS, 0);
 	ev_off += i;
 }
 
@@ -251,7 +251,7 @@ static void do_libcheck_init(struct checker *c, int blocksize,
 	struct directio_context * ct;
 
 	c->fd = test_fd;
-	will_return(__wrap_ioctl, blocksize);
+	wrap_will_return(WRAP_IOCTL, blocksize);
 	assert_int_equal(libcheck_init(c), 0);
 	ct = (struct directio_context *)c->context;
 	assert_non_null(ct);
@@ -762,7 +762,7 @@ int main(void)
 {
 	int ret = 0;
 
-	init_test_verbosity(2);
+	init_test_verbosity(5);
 	ret += test_directio();
 	return ret;
 }
diff --git a/tests/vpd.c b/tests/vpd.c
index 1b2d62d..e3212e6 100644
--- a/tests/vpd.c
+++ b/tests/vpd.c
@@ -20,6 +20,7 @@
 #include "vector.h"
 #include "structs.h"
 #include "discovery.h"
+#include "wrap64.h"
 #include "globals.c"
 
 #define VPD_BUFSIZ 4096
@@ -58,7 +59,7 @@ static const char vendor_id[] = "Linux";
 static const char test_id[] =
 	"A123456789AbcDefB123456789AbcDefC123456789AbcDefD123456789AbcDef";
 
-int __wrap_ioctl(int fd, unsigned long request, void *param)
+int WRAP_IOCTL(int fd, unsigned long request, void *param)
 {
 	int len;
 	struct sg_io_hdr *io_hdr;
@@ -428,8 +429,8 @@ static void test_vpd_vnd_ ## len ## _ ## wlen(void **state)             \
 	/* Replace spaces, like code under test */			\
 	exp_subst = subst_spaces(exp_wwid);				\
 	free(exp_wwid);							\
-	will_return(__wrap_ioctl, n);					\
-	will_return(__wrap_ioctl, vt->vpdbuf);				\
+	wrap_will_return(WRAP_IOCTL, n);				\
+	wrap_will_return(WRAP_IOCTL, vt->vpdbuf);			\
 	ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen);		\
 	assert_correct_wwid("test_vpd_vnd_" #len "_" #wlen,		\
 			    exp_len, ret, '1', 0, false,		\
@@ -458,8 +459,8 @@ static void test_vpd_str_ ## typ ## _ ## len ## _ ## wlen(void **state) \
 		exp_len--;						\
 	if (exp_len >= wlen)						\
 		exp_len = wlen - 1;					\
-	will_return(__wrap_ioctl, n);					\
-	will_return(__wrap_ioctl, vt->vpdbuf);				\
+	wrap_will_return(WRAP_IOCTL, n);				\
+	wrap_will_return(WRAP_IOCTL, vt->vpdbuf);			\
 	ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen);		\
 	assert_correct_wwid("test_vpd_str_" #typ "_" #len "_" #wlen,	\
 			    exp_len, ret, byte0[type], 0,		\
@@ -495,8 +496,8 @@ static void test_vpd_naa_ ## naa ## _ ## wlen(void **state)             \
 									\
 	n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id,	\
 			 3, naa, 0);					\
-	will_return(__wrap_ioctl, n);					\
-	will_return(__wrap_ioctl, vt->vpdbuf);				\
+	wrap_will_return(WRAP_IOCTL, n);				\
+	wrap_will_return(WRAP_IOCTL, vt->vpdbuf);			\
 	ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen);		\
 	assert_correct_wwid("test_vpd_naa_" #naa "_" #wlen,		\
 			    exp_len, ret, '3', '0' + naa, true,		\
@@ -518,8 +519,8 @@ static void test_vpd_naa_##NAA##_badlen_##BAD(void **state)	\
 	n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, 3, NAA, 0); \
 									\
 	vt->vpdbuf[7] = BAD;						\
-	will_return(__wrap_ioctl, n);					\
-	will_return(__wrap_ioctl, vt->vpdbuf);				\
+	wrap_will_return(WRAP_IOCTL, n);				\
+	wrap_will_return(WRAP_IOCTL, vt->vpdbuf);			\
 	ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, 40);			\
 	assert_int_equal(-ret, -ERR);					\
 }
@@ -545,11 +546,11 @@ static void test_vpd_eui_ ## len ## _ ## wlen ## _ ## sml(void **state)	\
 		/* overwrite the page size to DEFAULT_SGIO_LEN + 1 */	\
 		put_unaligned_be16(255, vt->vpdbuf + 2);		\
 		/* this causes get_vpd_sgio to do a second ioctl */	\
-		will_return(__wrap_ioctl, n);				\
-		will_return(__wrap_ioctl, vt->vpdbuf);			\
+		wrap_will_return(WRAP_IOCTL, n);			\
+		wrap_will_return(WRAP_IOCTL, vt->vpdbuf);		\
 	}								\
-	will_return(__wrap_ioctl, n);					\
-	will_return(__wrap_ioctl, vt->vpdbuf);				\
+	wrap_will_return(WRAP_IOCTL, n);				\
+	wrap_will_return(WRAP_IOCTL, vt->vpdbuf);			\
 	ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, wlen);		\
 	assert_correct_wwid("test_vpd_eui_" #len "_" #wlen "_" #sml,	\
 			    exp_len, ret, '2', 0, true,			\
@@ -571,8 +572,8 @@ static void test_vpd_eui_badlen_##LEN##_##BAD(void **state)	\
 	n = create_vpd83(vt->vpdbuf, sizeof(vt->vpdbuf), test_id, 2, 0, LEN); \
 									\
 	vt->vpdbuf[7] = BAD;						\
-	will_return(__wrap_ioctl, n);					\
-	will_return(__wrap_ioctl, vt->vpdbuf);				\
+	wrap_will_return(WRAP_IOCTL, n);				\
+	wrap_will_return(WRAP_IOCTL, vt->vpdbuf);			\
 	ret = get_vpd_sgio(10, 0x83, 0, vt->wwid, 40);			\
 	assert_int_equal(ret, ERR);					\
 	if (ERR >= 0)							\
@@ -600,8 +601,8 @@ static void test_vpd80_ ## size ## _ ## len ## _ ## wlen(void **state)  \
 		exp_len = wlen - 1;					\
 	n = create_vpd80(vt->vpdbuf, sizeof(vt->vpdbuf), input,		\
 			 size, len);					\
-	will_return(__wrap_ioctl, n);					\
-	will_return(__wrap_ioctl, vt->vpdbuf);				\
+	wrap_will_return(WRAP_IOCTL, n);				\
+	wrap_will_return(WRAP_IOCTL, vt->vpdbuf);			\
 	ret = get_vpd_sgio(10, 0x80, 0, vt->wwid, wlen);		\
 	assert_correct_wwid("test_vpd80_" #size "_" #len "_" #wlen,	\
 			    exp_len, ret, 0, 0, false,			\
diff --git a/tests/wrap64.h b/tests/wrap64.h
index 8c91d27..b0a4d83 100644
--- a/tests/wrap64.h
+++ b/tests/wrap64.h
@@ -1,5 +1,7 @@
 #ifndef _WRAP64_H
 #define _WRAP64_H 1
+#include <syscall.h>
+#include <linux/types.h>
 #include "util.h"
 
 /*
@@ -31,7 +33,9 @@
  * fcntl() needs special treatment; fcntl64() has been introduced in 2.28.
  * https://savannah.gnu.org/forum/forum.php?forum_id=9205
  */
-#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 28)
+#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 37) && defined(__arm__) && __ARM_ARCH == 7
+#define WRAP_FCNTL_NAME __fcntl_time64
+#elif defined(__GLIBC__) && __GLIBC_PREREQ(2, 28)
 #define WRAP_FCNTL_NAME WRAP_NAME(fcntl)
 #else
 #define WRAP_FCNTL_NAME fcntl
@@ -39,6 +43,25 @@
 #define WRAP_FCNTL CONCAT2(__wrap_, WRAP_FCNTL_NAME)
 #define REAL_FCNTL CONCAT2(__real_, WRAP_FCNTL_NAME)
 
+/*
+ * glibc 2.37 uses __ioctl_time64 for ioctl
+ */
+#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 37) && defined(__arm__) && __ARM_ARCH == 7
+#define WRAP_IOCTL_NAME __ioctl_time64
+#else
+#define WRAP_IOCTL_NAME ioctl
+#endif
+#define WRAP_IOCTL CONCAT2(__wrap_, WRAP_IOCTL_NAME)
+#define REAL_IOCTL CONCAT2(__real_, WRAP_IOCTL_NAME)
+
+#if defined(__NR_io_pgetevents) && __BITS_PER_LONG == 32 && defined(_TIME_BITS) && _TIME_BITS == 64
+#define WRAP_IO_GETEVENTS_NAME io_getevents_time64
+#else
+#define WRAP_IO_GETEVENTS_NAME io_getevents
+#endif
+#define WRAP_IO_GETEVENTS CONCAT2(__wrap_, WRAP_IO_GETEVENTS_NAME)
+#define REAL_IO_GETEVENTS CONCAT2(__real_, WRAP_IO_GETEVENTS_NAME)
+
 /*
  * will_return() is itself a macro that uses CPP "stringizing". We need a
  * macro indirection to make sure the *value* of WRAP_FUNC() is stringized
-- 
2.44.0


  reply	other threads:[~2024-04-16 18:54 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-16 18:53 [PATCH v2 0/2] multipath-tools: CI fixes for glibc symbol substitutions Martin Wilck
2024-04-16 18:53 ` Martin Wilck [this message]
2024-04-16 19:46   ` [PATCH v2 1/2] multipath-tools tests: fix CI failures on arm/v7 with glibc 2.37 Benjamin Marzinski
2024-04-16 18:53 ` [PATCH v2 2/2] multipath-tools tests: fix CI failures with clang on Fedora Rawhide Martin Wilck

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240416185351.30670-2-mwilck@suse.com \
    --to=martin.wilck@suse.com \
    --cc=bmarzins@redhat.com \
    --cc=christophe.varoqui@opensvc.com \
    --cc=dm-devel@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.