Message ID | 20241210-convert_mmap01-v4-1-c2338a2ca071@suse.com |
---|---|
State | Changes Requested |
Headers | show |
Series | [v4] mmap01: Convert to new API | expand |
Hi Ricardo, ... > +static void run(void) > { > + pid_t pid; > + > + addr = SAFE_MMAP(NULL, page_sz, PROT_READ | PROT_WRITE, > + MAP_FILE | MAP_SHARED, fildes, 0); > + > + /* > + * Check if mapped memory area beyond EOF are zeros and changes beyond > + * EOF are not written to file. > + */ > + if (memcmp(&addr[file_sz], dummy, page_sz - file_sz)) > + tst_brk(TFAIL, "mapped memory area contains invalid data"); FYI test fails when run more iterations (e.g. -i2) Kind regards, Petr
Hi Petr! On 11 Dec 24 02:47, Petr Vorel wrote: > Hi Ricardo, > > ... > > +static void run(void) > > { > > + pid_t pid; > > + > > + addr = SAFE_MMAP(NULL, page_sz, PROT_READ | PROT_WRITE, > > + MAP_FILE | MAP_SHARED, fildes, 0); > > + > > + /* > > + * Check if mapped memory area beyond EOF are zeros and changes beyond > > + * EOF are not written to file. > > + */ > > + if (memcmp(&addr[file_sz], dummy, page_sz - file_sz)) > > + tst_brk(TFAIL, "mapped memory area contains invalid data"); > FYI test fails when run more iterations (e.g. -i2) > Thanks for taking a look, but I don't see the issue here: # /opt/ltp/testcases/bin/mmap01 -i4 tst_tmpdir.c:316: TINFO: Using /tmp/LTP_mmaiVJsAq as tmpdir (fuse filesystem) tst_test.c:1890: TINFO: LTP version: 20240930-73-g865be36ffce8 tst_test.c:1894: TINFO: Tested kernel: 6.11.0-virtme #1 SMP PREEMPT_DYNAMIC Fri Oct 4 13:39:48 -03 2024 x86_64 tst_test.c:1725: TINFO: Timeout per run is 0h 00m 30s mmap01.c:49: TPASS: Functionality of mmap() successful YES mmap01.c:49: TPASS: Functionality of mmap() successful YES mmap01.c:49: TPASS: Functionality of mmap() successful YES mmap01.c:49: TPASS: Functionality of mmap() successful YES Summary: passed 4 failed 0 broken 0 skipped 0 warnings 0 I appended the "YES" just to make sure I wasn't running some outdated code, can you please provide more details? Thanks! - Ricardo. > Kind regards, > Petr
> Hi Petr! > On 11 Dec 24 02:47, Petr Vorel wrote: > > Hi Ricardo, > > ... > > > +static void run(void) > > > { > > > + pid_t pid; > > > + > > > + addr = SAFE_MMAP(NULL, page_sz, PROT_READ | PROT_WRITE, > > > + MAP_FILE | MAP_SHARED, fildes, 0); > > > + > > > + /* > > > + * Check if mapped memory area beyond EOF are zeros and changes beyond > > > + * EOF are not written to file. > > > + */ > > > + if (memcmp(&addr[file_sz], dummy, page_sz - file_sz)) > > > + tst_brk(TFAIL, "mapped memory area contains invalid data"); > > FYI test fails when run more iterations (e.g. -i2) > Thanks for taking a look, but I don't see the issue here: > # /opt/ltp/testcases/bin/mmap01 -i4 > tst_tmpdir.c:316: TINFO: Using /tmp/LTP_mmaiVJsAq as tmpdir (fuse filesystem) > tst_test.c:1890: TINFO: LTP version: 20240930-73-g865be36ffce8 > tst_test.c:1894: TINFO: Tested kernel: 6.11.0-virtme #1 SMP PREEMPT_DYNAMIC Fri Oct 4 13:39:48 -03 2024 x86_64 > tst_test.c:1725: TINFO: Timeout per run is 0h 00m 30s > mmap01.c:49: TPASS: Functionality of mmap() successful YES > mmap01.c:49: TPASS: Functionality of mmap() successful YES > mmap01.c:49: TPASS: Functionality of mmap() successful YES > mmap01.c:49: TPASS: Functionality of mmap() successful YES > Summary: > passed 4 > failed 0 > broken 0 > skipped 0 > warnings 0 > I appended the "YES" just to make sure I wasn't running some outdated > code, can you please provide more details? I have no idea myself. I verified if I'm using v4 [1] and I really do. Can you please push the code you're using? Your code I'm testing is in my fork [2]. Tested on more systems: # ./mmap01 -i4 tst_tmpdir.c:316: TINFO: Using /tmp/LTP_mmabiOth0 as tmpdir (tmpfs filesystem) tst_test.c:1890: TINFO: LTP version: 20240930-116-g23f5a4447 tst_test.c:1894: TINFO: Tested kernel: 6.13.0-rc1-1.g492f944-default #1 SMP PREEMPT_DYNAMIC Mon Dec 2 08:55:00 UTC 2024 (492f944) x86_64 tst_test.c:1725: TINFO: Timeout per run is 0h 00m 30s mmap01.c:49: TPASS: Functionality of mmap() successful mmap01.c:68: TFAIL: mapped memory area contains invalid data Summary: passed 1 failed 1 broken 0 skipped 0 warnings 0 $ ./mmap01 -i4 tst_tmpdir.c:316: TINFO: Using /tmp/LTP_mmakqgzvS as tmpdir (tmpfs filesystem) tst_test.c:1890: TINFO: LTP version: 20240930-115-g786b808eda tst_test.c:1894: TINFO: Tested kernel: 6.11-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.11 (2024-11-23) x86_64 tst_test.c:1725: TINFO: Timeout per run is 0h 00m 30s mmap01.c:49: TPASS: Functionality of mmap() successful mmap01.c:68: TFAIL: mapped memory area contains invalid data Summary: passed 1 failed 1 broken 0 skipped 0 warnings 0 [1] https://patchwork.ozlabs.org/project/ltp/patch/20241210-convert_mmap01-v4-1-c2338a2ca071@suse.com/ [2] https://github.com/pevik/ltp/commit/a3c07097784088a679e77a4486bb10adfe03eea0
Hello! On 11 Dec 24 20:00, Petr Vorel wrote: > > Hi Petr! > > > On 11 Dec 24 02:47, Petr Vorel wrote: > > > Hi Ricardo, > > > > ... > > > > +static void run(void) > > > > { > > > > + pid_t pid; > > > > + > > > > + addr = SAFE_MMAP(NULL, page_sz, PROT_READ | PROT_WRITE, > > > > + MAP_FILE | MAP_SHARED, fildes, 0); > > > > + > > > > + /* > > > > + * Check if mapped memory area beyond EOF are zeros and changes beyond > > > > + * EOF are not written to file. > > > > + */ > > > > + if (memcmp(&addr[file_sz], dummy, page_sz - file_sz)) > > > > + tst_brk(TFAIL, "mapped memory area contains invalid data"); > > > FYI test fails when run more iterations (e.g. -i2) > > > > Thanks for taking a look, but I don't see the issue here: > > > # /opt/ltp/testcases/bin/mmap01 -i4 > > tst_tmpdir.c:316: TINFO: Using /tmp/LTP_mmaiVJsAq as tmpdir (fuse filesystem) > > tst_test.c:1890: TINFO: LTP version: 20240930-73-g865be36ffce8 > > tst_test.c:1894: TINFO: Tested kernel: 6.11.0-virtme #1 SMP PREEMPT_DYNAMIC Fri Oct 4 13:39:48 -03 2024 x86_64 > > tst_test.c:1725: TINFO: Timeout per run is 0h 00m 30s > > mmap01.c:49: TPASS: Functionality of mmap() successful YES > > mmap01.c:49: TPASS: Functionality of mmap() successful YES > > mmap01.c:49: TPASS: Functionality of mmap() successful YES > > mmap01.c:49: TPASS: Functionality of mmap() successful YES > > > Summary: > > passed 4 > > failed 0 > > broken 0 > > skipped 0 > > warnings 0 > > > I appended the "YES" just to make sure I wasn't running some outdated > > code, can you please provide more details? > > I have no idea myself. I verified if I'm using v4 [1] and I really do. > Can you please push the code you're using? > Your code I'm testing is in my fork [2]. > > Tested on more systems: Many thanks! After a fresh build I started seeing those, too. The issue is that run() changes the file and the second run uses this updated file. I pushed a new revision with a new set_file to put it in a known state before each run. FWIW I pushed it here: https://github.com/rbmarliere/ltp/tree/b4/convert_mmap01 Thanks, - Ricardo. > > # ./mmap01 -i4 > tst_tmpdir.c:316: TINFO: Using /tmp/LTP_mmabiOth0 as tmpdir (tmpfs filesystem) > tst_test.c:1890: TINFO: LTP version: 20240930-116-g23f5a4447 > tst_test.c:1894: TINFO: Tested kernel: 6.13.0-rc1-1.g492f944-default #1 SMP PREEMPT_DYNAMIC Mon Dec 2 08:55:00 UTC 2024 (492f944) x86_64 > tst_test.c:1725: TINFO: Timeout per run is 0h 00m 30s > mmap01.c:49: TPASS: Functionality of mmap() successful > mmap01.c:68: TFAIL: mapped memory area contains invalid data > > Summary: > passed 1 > failed 1 > broken 0 > skipped 0 > warnings 0 > > $ ./mmap01 -i4 > tst_tmpdir.c:316: TINFO: Using /tmp/LTP_mmakqgzvS as tmpdir (tmpfs filesystem) > tst_test.c:1890: TINFO: LTP version: 20240930-115-g786b808eda > tst_test.c:1894: TINFO: Tested kernel: 6.11-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.11 (2024-11-23) x86_64 > tst_test.c:1725: TINFO: Timeout per run is 0h 00m 30s > mmap01.c:49: TPASS: Functionality of mmap() successful > mmap01.c:68: TFAIL: mapped memory area contains invalid data > > Summary: > passed 1 > failed 1 > broken 0 > skipped 0 > warnings 0 > > [1] https://patchwork.ozlabs.org/project/ltp/patch/20241210-convert_mmap01-v4-1-c2338a2ca071@suse.com/ > [2] https://github.com/pevik/ltp/commit/a3c07097784088a679e77a4486bb10adfe03eea0
diff --git a/testcases/kernel/syscalls/mmap/mmap01.c b/testcases/kernel/syscalls/mmap/mmap01.c index 99266b57ffc16e6c3a0e31a2c87d0f8106f429e5..fff39d0ff6e1c271616d1391904f7011fbb2675e 100644 --- a/testcases/kernel/syscalls/mmap/mmap01.c +++ b/testcases/kernel/syscalls/mmap/mmap01.c @@ -1,194 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) International Business Machines Corp., 2001 + * Copyright (c) 2024 Ricardo B. Marliere <rbm@suse.com> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * HISTORY + * 07/2001 Ported by Wayne Boyer */ -/* - * Test Description: - * Verify that, mmap() succeeds when used to map a file where size of the - * file is not a multiple of the page size, the memory area beyond the end - * of the file to the end of the page is accessible. Also, verify that - * this area is all zeroed and the modifications done to this area are - * not written to the file. +/*\ + * [Description] * - * Expected Result: - * mmap() should succeed returning the address of the mapped region. - * The memory area beyond the end of file to the end of page should be - * filled with zero. - * The changes beyond the end of file should not get written to the file. + * Verify that mmap() succeeds when used to map a file where size of the + * file is not a multiple of the page size, the memory area beyond the end + * of the file to the end of the page is accessible. Also, verify that + * this area is all zeroed and the modifications done to this area are + * not written to the file. * - * HISTORY - * 07/2001 Ported by Wayne Boyer + * mmap() should succeed returning the address of the mapped region. + * The memory area beyond the end of file to the end of page should be + * filled with zero. + * The changes beyond the end of file should not get written to the file. */ -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <signal.h> -#include <stdint.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <sys/shm.h> - -#include "test.h" - -#define TEMPFILE "mmapfile" - -char *TCID = "mmap01"; -int TST_TOTAL = 1; + +#include "tst_test.h" + +#define TEMPFILE "mmapfile" +#define STRING "hello world" static char *addr; static char *dummy; static size_t page_sz; static size_t file_sz; static int fildes; -static char cmd_buffer[BUFSIZ]; -static void setup(void); -static void cleanup(void); - -int main(int ac, char **av) +static void check_file(void) { - int lc; - - tst_parse_opts(ac, av, NULL, NULL); - - setup(); - - for (lc = 0; TEST_LOOPING(lc); lc++) { - - tst_count = 0; - - /* - * Call mmap to map the temporary file beyond EOF - * with write access. - */ - errno = 0; - addr = mmap(NULL, page_sz, PROT_READ | PROT_WRITE, - MAP_FILE | MAP_SHARED, fildes, 0); - - /* Check for the return value of mmap() */ - if (addr == MAP_FAILED) { - tst_resm(TFAIL | TERRNO, "mmap of %s failed", TEMPFILE); - continue; - } - - /* - * Check if mapped memory area beyond EOF are - * zeros and changes beyond EOF are not written - * to file. - */ - if (memcmp(&addr[file_sz], dummy, page_sz - file_sz)) { - tst_brkm(TFAIL, cleanup, - "mapped memory area contains invalid " - "data"); - } - - /* - * Initialize memory beyond file size - */ - addr[file_sz] = 'X'; - addr[file_sz + 1] = 'Y'; - addr[file_sz + 2] = 'Z'; - - /* - * Synchronize the mapped memory region - * with the file. - */ - if (msync(addr, page_sz, MS_SYNC) != 0) { - tst_brkm(TFAIL | TERRNO, cleanup, - "failed to synchronize mapped file"); - } - - /* - * Now, Search for the pattern 'XYZ' in the - * temporary file. The pattern should not be - * found and the return value should be 1. - */ - if (system(cmd_buffer) != 0) { - tst_resm(TPASS, - "Functionality of mmap() successful"); - } else { - tst_resm(TFAIL, - "Specified pattern found in file"); - } - - /* Clean up things in case we are looping */ - /* Unmap the mapped memory */ - if (munmap(addr, page_sz) != 0) { - tst_brkm(TFAIL | TERRNO, NULL, "munmap failed"); - } - } + int i, fildes, buf_len = sizeof(STRING) + 3; + char buf[buf_len]; + + fildes = SAFE_OPEN(TEMPFILE, O_RDONLY); + SAFE_READ(0, fildes, buf, sizeof(buf)); + + for (i = 0; i < buf_len; i++) + if (buf[i] == 'X' || buf[i] == 'Y' || buf[i] == 'Z') + break; - cleanup(); - tst_exit(); + if (i == buf_len) + tst_res(TPASS, "Functionality of mmap() successful"); + else + tst_res(TFAIL, "Specified pattern found in file"); + + SAFE_CLOSE(fildes); } -static void setup(void) +static void run(void) { - struct stat stat_buf; - char Path_name[PATH_MAX]; - char write_buf[] = "hello world\n"; + pid_t pid; + + addr = SAFE_MMAP(NULL, page_sz, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, fildes, 0); + + /* + * Check if mapped memory area beyond EOF are zeros and changes beyond + * EOF are not written to file. + */ + if (memcmp(&addr[file_sz], dummy, page_sz - file_sz)) + tst_brk(TFAIL, "mapped memory area contains invalid data"); + + /* + * Initialize memory beyond file size + */ + addr[file_sz] = 'X'; + addr[file_sz + 1] = 'Y'; + addr[file_sz + 2] = 'Z'; + + /* + * Synchronize the mapped memory region with the file. + */ + if (msync(addr, page_sz, MS_SYNC) != 0) { + tst_res(TFAIL | TERRNO, "failed to synchronize mapped file"); + return; + } - tst_sig(FORK, DEF_HANDLER, cleanup); + /* + * Now, search for the pattern 'XYZ' in the temporary file. + * The pattern should not be found and the return value should be 1. + */ + pid = SAFE_FORK(); + if (!pid) { + check_file(); + exit(0); + } - TEST_PAUSE; + SAFE_MUNMAP(addr, page_sz); +} - tst_tmpdir(); +static void cleanup(void) +{ + if (dummy) + free(dummy); + if (fildes > 0) + SAFE_CLOSE(fildes); +} - /* Get the path of temporary file to be created */ - if (getcwd(Path_name, sizeof(Path_name)) == NULL) { - tst_brkm(TFAIL | TERRNO, cleanup, - "getcwd failed to get current working directory"); - } +static void setup(void) +{ + char *write_buf = STRING; + struct stat stat_buf; - /* Creat a temporary file used for mapping */ - if ((fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0) { - tst_brkm(TFAIL, cleanup, "opening %s failed", TEMPFILE); - } + /* Create a temporary file used for mapping */ + fildes = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666); /* Write some data into temporary file */ - if (write(fildes, write_buf, strlen(write_buf)) != (long)strlen(write_buf)) { - tst_brkm(TFAIL, cleanup, "writing to %s", TEMPFILE); - } + SAFE_WRITE(SAFE_WRITE_ALL, fildes, write_buf, strlen(write_buf)); /* Get the size of temporary file */ - if (stat(TEMPFILE, &stat_buf) < 0) { - tst_brkm(TFAIL | TERRNO, cleanup, "stat of %s failed", - TEMPFILE); - } + SAFE_STAT(TEMPFILE, &stat_buf); file_sz = stat_buf.st_size; page_sz = getpagesize(); /* Allocate and initialize dummy string of system page size bytes */ - if ((dummy = calloc(page_sz, sizeof(char))) == NULL) { - tst_brkm(TFAIL, cleanup, "calloc failed (dummy)"); - } - - /* Create the command which will be executed in the test */ - sprintf(cmd_buffer, "grep XYZ %s/%s > /dev/null", Path_name, TEMPFILE); + dummy = SAFE_CALLOC(page_sz, sizeof(char)); } -static void cleanup(void) -{ - close(fildes); - free(dummy); - tst_rmdir(); -} +static struct tst_test test = { + .setup = setup, + .cleanup = cleanup, + .needs_tmpdir = 1, + .test_all = run, + .forks_child = 1, +};