[LTP] [PATCH v3 5/7] mremap05: Convert to new API
Andrea Cervesato
andrea.cervesato@suse.de
Fri Aug 7 14:17:14 CEST 2026
From: Andrea Cervesato <andrea.cervesato@suse.com>
Convert the mremap05 test case from the legacy LTP API to the new
tst_test API.
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mremap/mremap05.c | 278 ++++++++--------------------
1 file changed, 75 insertions(+), 203 deletions(-)
diff --git a/testcases/kernel/syscalls/mremap/mremap05.c b/testcases/kernel/syscalls/mremap/mremap05.c
index 971cc8e5e..4e906a044 100644
--- a/testcases/kernel/syscalls/mremap/mremap05.c
+++ b/testcases/kernel/syscalls/mremap/mremap05.c
@@ -1,239 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2012 Linux Test Project, Inc.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it
- * is free of the rightful claim of any third person regarding
- * infringement or the like. Any license provided herein, whether
- * implied or otherwise, applies only to this software file. Patent
- * licenses, if any, provided herein do not apply to combinations of
- * this program with other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
+ * Copyright (c) 2026 Linux Test Project
*/
-/*
- * Test Name: mremap05
+
+/*\
+ * Verify the behavior of the ``MREMAP_FIXED`` flag of :manpage:`mremap(2)`
+ * when invalid arguments are provided:
*
- * Test Description:
- * Verify that MREMAP_FIXED fails without MREMAP_MAYMOVE.
- * Verify that MREMAP_FIXED|MREMAP_MAYMOVE fails if target address
- * is not page aligned.
- * Verify that MREMAP_FIXED|MREMAP_MAYMOVE fails if old range
- * overlaps with new range.
- * Verify that MREMAP_FIXED|MREMAP_MAYMOVE can move mapping to new address.
- * Verify that MREMAP_FIXED|MREMAP_MAYMOVE unmaps previous mapping
- * at the address range specified by new_address and new_size.
+ * - ``MREMAP_FIXED`` fails with ``EINVAL`` without ``MREMAP_MAYMOVE``.
+ * - ``MREMAP_FIXED | MREMAP_MAYMOVE`` fails with ``EINVAL`` if the target
+ * address is not page aligned.
+ * - ``MREMAP_FIXED | MREMAP_MAYMOVE`` fails with ``EINVAL`` if the old range
+ * overlaps with the new range.
*/
#define _GNU_SOURCE
-#include "config.h"
#include <sys/mman.h>
-#include <errno.h>
-#include <unistd.h>
-#include "test.h"
-#include "tso_safe_macros.h"
+#include "tst_test.h"
-char *TCID = "mremap05";
+static int pagesize;
-struct test_case_t {
- char *old_address;
- char *new_address;
- size_t old_size; /* in pages */
- size_t new_size; /* in pages */
+static struct tcase {
+ size_t old_pages;
+ size_t new_pages;
int flags;
- const char *msg;
- void *exp_ret;
+ int align_offset;
+ int overlap;
+ int free_dst;
int exp_errno;
- char *ret;
- void (*setup) (struct test_case_t *);
- void (*cleanup) (struct test_case_t *);
-};
-
-static void setup(void);
-static void cleanup(void);
-static void setup0(struct test_case_t *);
-static void setup1(struct test_case_t *);
-static void setup2(struct test_case_t *);
-static void setup3(struct test_case_t *);
-static void setup4(struct test_case_t *);
-static void cleanup0(struct test_case_t *);
-static void cleanup1(struct test_case_t *);
-
-struct test_case_t tdat[] = {
- {
- .old_size = 1,
- .new_size = 1,
- .flags = MREMAP_FIXED,
- .msg = "MREMAP_FIXED requires MREMAP_MAYMOVE",
- .exp_ret = MAP_FAILED,
- .exp_errno = EINVAL,
- .setup = setup0,
- .cleanup = cleanup0},
- {
- .old_size = 1,
- .new_size = 1,
- .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
- .msg = "new_addr has to be page aligned",
- .exp_ret = MAP_FAILED,
- .exp_errno = EINVAL,
- .setup = setup1,
- .cleanup = cleanup0},
+ const char *msg;
+} tcases[] = {
{
- .old_size = 2,
- .new_size = 1,
- .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
- .msg = "old/new area must not overlap",
- .exp_ret = MAP_FAILED,
- .exp_errno = EINVAL,
- .setup = setup2,
- .cleanup = cleanup0},
+ .old_pages = 1,
+ .new_pages = 1,
+ .flags = MREMAP_FIXED,
+ .free_dst = 1,
+ .exp_errno = EINVAL,
+ .msg = "MREMAP_FIXED requires MREMAP_MAYMOVE",
+ },
{
- .old_size = 1,
- .new_size = 1,
- .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
- .msg = "mremap #1",
- .setup = setup3,
- .cleanup = cleanup0},
+ .old_pages = 1,
+ .new_pages = 1,
+ .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
+ .align_offset = 1,
+ .exp_errno = EINVAL,
+ .msg = "new_addr has to be page aligned",
+ },
{
- .old_size = 1,
- .new_size = 1,
- .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
- .msg = "mremap #2",
- .setup = setup4,
- .cleanup = cleanup1},
+ .old_pages = 2,
+ .new_pages = 1,
+ .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
+ .overlap = 1,
+ .exp_errno = EINVAL,
+ .msg = "old/new area must not overlap",
+ },
};
-static int pagesize;
-static int TST_TOTAL = sizeof(tdat) / sizeof(tdat[0]);
-
-static void free_test_area(void *p, int size)
-{
- SAFE_MUNMAP(cleanup, p, size);
-}
-
-static void *get_test_area(int size, int free_area)
+static void *get_test_area(size_t size, int free_area)
{
void *p;
- p = mmap(NULL, size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
- if (p == MAP_FAILED)
- tst_brkm(TBROK | TERRNO, cleanup, "get_test_area mmap");
- if (free_area)
- free_test_area(p, size);
- return p;
-}
-static void test_mremap(struct test_case_t *t)
-{
- t->ret = mremap(t->old_address, t->old_size, t->new_size, t->flags,
- t->new_address);
+ p = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (t->ret == t->exp_ret) {
- if (t->ret != MAP_FAILED) {
- tst_resm(TPASS, "%s", t->msg);
- if (*(t->ret) == 0x1)
- tst_resm(TPASS, "%s value OK", t->msg);
- else
- tst_resm(TPASS, "%s value failed", t->msg);
- } else {
- if (errno == t->exp_errno)
- tst_resm(TPASS, "%s", t->msg);
- else
- tst_resm(TFAIL | TERRNO, "%s", t->msg);
- }
- } else {
- tst_resm(TFAIL, "%s ret: %p, expected: %p", t->msg,
- t->ret, t->exp_ret);
- }
-}
-
-static void setup0(struct test_case_t *t)
-{
- t->old_address = get_test_area(t->old_size * pagesize, 0);
- t->new_address = get_test_area(t->new_size * pagesize, 1);
-}
-
-static void setup1(struct test_case_t *t)
-{
- t->old_address = get_test_area(t->old_size * pagesize, 0);
- t->new_address = get_test_area((t->new_size + 1) * pagesize, 1) + 1;
-}
+ if (free_area)
+ SAFE_MUNMAP(p, size);
-static void setup2(struct test_case_t *t)
-{
- t->old_address = get_test_area(t->old_size * pagesize, 0);
- t->new_address = t->old_address;
+ return p;
}
-static void setup3(struct test_case_t *t)
+static void setup(void)
{
- t->old_address = get_test_area(t->old_size * pagesize, 0);
- t->new_address = get_test_area(t->new_size * pagesize, 1);
- t->exp_ret = t->new_address;
- *(t->old_address) = 0x1;
+ pagesize = getpagesize();
}
-static void setup4(struct test_case_t *t)
+static void run(unsigned int n)
{
- t->old_address = get_test_area(t->old_size * pagesize, 0);
- t->new_address = get_test_area(t->new_size * pagesize, 0);
- t->exp_ret = t->new_address;
- *(t->old_address) = 0x1;
- *(t->new_address) = 0x2;
-}
+ struct tcase *tc = &tcases[n];
+ char *old_address;
+ char *new_address;
+ size_t old_size = tc->old_pages * pagesize;
+ size_t new_size = tc->new_pages * pagesize;
-static void cleanup0(struct test_case_t *t)
-{
- if (t->ret == MAP_FAILED)
- free_test_area(t->old_address, t->old_size * pagesize);
- else
- free_test_area(t->ret, t->new_size * pagesize);
-}
+ old_address = get_test_area(old_size, 0);
-static void cleanup1(struct test_case_t *t)
-{
- if (t->ret == MAP_FAILED) {
- free_test_area(t->old_address, t->old_size * pagesize);
- free_test_area(t->new_address, t->new_size * pagesize);
+ if (tc->overlap) {
+ new_address = old_address;
+ } else if (tc->align_offset) {
+ new_address = get_test_area(new_size + pagesize, 1) +
+ tc->align_offset;
} else {
- free_test_area(t->ret, t->new_size * pagesize);
+ new_address = get_test_area(new_size, tc->free_dst);
}
-}
-
-int main(int ac, char **av)
-{
- int lc, testno;
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
- for (testno = 0; testno < TST_TOTAL; testno++) {
- tdat[testno].setup(&tdat[testno]);
- test_mremap(&tdat[testno]);
- tdat[testno].cleanup(&tdat[testno]);
- }
- }
- cleanup();
- tst_exit();
-}
+ TST_EXP_FAIL_PTR_VOID(mremap(old_address, old_size, new_size,
+ tc->flags, new_address),
+ tc->exp_errno, "%s", tc->msg);
-static void setup(void)
-{
- pagesize = getpagesize();
+ if (TST_RET_PTR == MAP_FAILED)
+ SAFE_MUNMAP(old_address, old_size);
+ else
+ SAFE_MUNMAP(TST_RET_PTR, new_size);
}
-static void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .setup = setup,
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+};
--
2.51.0
More information about the ltp
mailing list