1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2003 4f08c3bdfSopenharmony_ci * 01/02/2003 Port to LTP avenkat@us.ibm.com 5f08c3bdfSopenharmony_ci * 06/30/2001 Port to Linux nsharoff@us.ibm.com 6f08c3bdfSopenharmony_ci * 10/03/2022 Refactor to LTP framework edliaw@google.com 7f08c3bdfSopenharmony_ci */ 8f08c3bdfSopenharmony_ci/*\ 9f08c3bdfSopenharmony_ci * [Description] 10f08c3bdfSopenharmony_ci * This test stresses mmaps, without dealing with fragments or anything! 11f08c3bdfSopenharmony_ci * It forks a specified number of children, 12f08c3bdfSopenharmony_ci * all of whom mmap the same file, make a given number of accesses 13f08c3bdfSopenharmony_ci * to random pages in the map (reading & writing and comparing data). 14f08c3bdfSopenharmony_ci * Then the child exits and the parent forks another to take its place. 15f08c3bdfSopenharmony_ci * Each time a child is forked, it stats the file and maps the full 16f08c3bdfSopenharmony_ci * length of the file. 17f08c3bdfSopenharmony_ci * 18f08c3bdfSopenharmony_ci * This program continues to run until it either receives a SIGINT, 19f08c3bdfSopenharmony_ci * or times out (if a timeout value is specified). When either of 20f08c3bdfSopenharmony_ci * these things happens, it cleans up its kids, then checks the 21f08c3bdfSopenharmony_ci * file to make sure it has the correct data. 22f08c3bdfSopenharmony_ci */ 23f08c3bdfSopenharmony_ci 24f08c3bdfSopenharmony_ci#define _GNU_SOURCE 1 25f08c3bdfSopenharmony_ci#include <stdio.h> 26f08c3bdfSopenharmony_ci#include <fcntl.h> 27f08c3bdfSopenharmony_ci#include <signal.h> 28f08c3bdfSopenharmony_ci#include <sys/mman.h> 29f08c3bdfSopenharmony_ci#include <sys/wait.h> 30f08c3bdfSopenharmony_ci#include <sys/stat.h> 31f08c3bdfSopenharmony_ci#include <unistd.h> 32f08c3bdfSopenharmony_ci#include <stdlib.h> 33f08c3bdfSopenharmony_ci#include <errno.h> 34f08c3bdfSopenharmony_ci#include <sys/types.h> 35f08c3bdfSopenharmony_ci#include <limits.h> 36f08c3bdfSopenharmony_ci#include <float.h> 37f08c3bdfSopenharmony_ci#include "tst_test.h" 38f08c3bdfSopenharmony_ci 39f08c3bdfSopenharmony_ci#if _FILE_OFFSET_BITS == 64 40f08c3bdfSopenharmony_ci# define FSIZE_MIN LONG_MIN 41f08c3bdfSopenharmony_ci# define FSIZE_MAX LONG_MAX 42f08c3bdfSopenharmony_ci#else 43f08c3bdfSopenharmony_ci# define FSIZE_MIN INT_MIN 44f08c3bdfSopenharmony_ci# define FSIZE_MAX INT_MAX 45f08c3bdfSopenharmony_ci#endif 46f08c3bdfSopenharmony_ci#define MAXLOOPS 500 /* max pages for map children to write */ 47f08c3bdfSopenharmony_ci#define TEST_FILE "mmapstress01.out" 48f08c3bdfSopenharmony_ci 49f08c3bdfSopenharmony_ci#ifdef roundup 50f08c3bdfSopenharmony_ci#undef roundup 51f08c3bdfSopenharmony_ci#endif 52f08c3bdfSopenharmony_ci#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) 53f08c3bdfSopenharmony_ci 54f08c3bdfSopenharmony_cistatic unsigned int initrand(void); 55f08c3bdfSopenharmony_cistatic void sighandler(int); 56f08c3bdfSopenharmony_ci 57f08c3bdfSopenharmony_cistatic char *debug; 58f08c3bdfSopenharmony_cistatic char *do_sync; 59f08c3bdfSopenharmony_cistatic char *do_offset; 60f08c3bdfSopenharmony_cistatic char *opt_filesize; 61f08c3bdfSopenharmony_cistatic char *opt_nprocs; 62f08c3bdfSopenharmony_cistatic char *opt_pattern; 63f08c3bdfSopenharmony_cistatic char *opt_sparseoffset; 64f08c3bdfSopenharmony_cistatic char *randloops; 65f08c3bdfSopenharmony_ci 66f08c3bdfSopenharmony_cistatic int fd; 67f08c3bdfSopenharmony_cistatic volatile int finished; 68f08c3bdfSopenharmony_cistatic int nprocs; 69f08c3bdfSopenharmony_cistatic long long filesize = 4096; 70f08c3bdfSopenharmony_cistatic long long sparseoffset; 71f08c3bdfSopenharmony_cistatic size_t pagesize; 72f08c3bdfSopenharmony_cistatic int pattern; 73f08c3bdfSopenharmony_ci 74f08c3bdfSopenharmony_cistatic void setup(void) 75f08c3bdfSopenharmony_ci{ 76f08c3bdfSopenharmony_ci struct sigaction sa; 77f08c3bdfSopenharmony_ci 78f08c3bdfSopenharmony_ci sa.sa_handler = sighandler; 79f08c3bdfSopenharmony_ci sa.sa_flags = 0; 80f08c3bdfSopenharmony_ci SAFE_SIGEMPTYSET(&sa.sa_mask); 81f08c3bdfSopenharmony_ci SAFE_SIGACTION(SIGINT, &sa, 0); 82f08c3bdfSopenharmony_ci SAFE_SIGACTION(SIGQUIT, &sa, 0); 83f08c3bdfSopenharmony_ci SAFE_SIGACTION(SIGTERM, &sa, 0); 84f08c3bdfSopenharmony_ci SAFE_SIGACTION(SIGALRM, &sa, 0); 85f08c3bdfSopenharmony_ci 86f08c3bdfSopenharmony_ci pagesize = sysconf(_SC_PAGE_SIZE); 87f08c3bdfSopenharmony_ci 88f08c3bdfSopenharmony_ci if (tst_parse_filesize(opt_filesize, &filesize, 0, FSIZE_MAX)) 89f08c3bdfSopenharmony_ci tst_brk(TBROK, "invalid initial filesize '%s'", opt_filesize); 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_ci if (tst_parse_filesize(opt_sparseoffset, &sparseoffset, FSIZE_MIN, FSIZE_MAX)) 92f08c3bdfSopenharmony_ci tst_brk(TBROK, "invalid sparse offset '%s'", opt_sparseoffset); 93f08c3bdfSopenharmony_ci if (sparseoffset % pagesize != 0) 94f08c3bdfSopenharmony_ci tst_brk(TBROK, "sparseoffset must be pagesize multiple"); 95f08c3bdfSopenharmony_ci 96f08c3bdfSopenharmony_ci if (tst_parse_int(opt_nprocs, &nprocs, 0, 255)) 97f08c3bdfSopenharmony_ci tst_brk(TBROK, "invalid number of mapping children '%s'", 98f08c3bdfSopenharmony_ci opt_nprocs); 99f08c3bdfSopenharmony_ci if (!opt_nprocs) 100f08c3bdfSopenharmony_ci nprocs = MAX(MIN(tst_ncpus() - 1L, 20L), 1L); 101f08c3bdfSopenharmony_ci 102f08c3bdfSopenharmony_ci if (tst_parse_int(opt_pattern, &pattern, 0, 255)) 103f08c3bdfSopenharmony_ci tst_brk(TBROK, "invalid pattern '%s'", opt_pattern); 104f08c3bdfSopenharmony_ci if (!opt_pattern) 105f08c3bdfSopenharmony_ci pattern = initrand() & 0xff; 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_ci tst_res(TINFO, "creating file <%s> with %lld bytes, pattern %d", 108f08c3bdfSopenharmony_ci TEST_FILE, filesize, pattern); 109f08c3bdfSopenharmony_ci} 110f08c3bdfSopenharmony_ci 111f08c3bdfSopenharmony_cistatic void cleanup(void) 112f08c3bdfSopenharmony_ci{ 113f08c3bdfSopenharmony_ci if (fd > 0) 114f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 115f08c3bdfSopenharmony_ci} 116f08c3bdfSopenharmony_ci 117f08c3bdfSopenharmony_ci/* 118f08c3bdfSopenharmony_ci * Child process that reads/writes map. The child stats the file 119f08c3bdfSopenharmony_ci * to determine the size, maps the size of the file, then reads/writes 120f08c3bdfSopenharmony_ci * its own locations on random pages of the map (its locations being 121f08c3bdfSopenharmony_ci * determined based on nprocs & procno). After a specific number of 122f08c3bdfSopenharmony_ci * iterations, it exits. 123f08c3bdfSopenharmony_ci */ 124f08c3bdfSopenharmony_cistatic void child_mapper(char *file, unsigned int procno, unsigned int nprocs) 125f08c3bdfSopenharmony_ci{ 126f08c3bdfSopenharmony_ci struct stat statbuf; 127f08c3bdfSopenharmony_ci off_t filesize; 128f08c3bdfSopenharmony_ci off_t offset; 129f08c3bdfSopenharmony_ci size_t validsize; 130f08c3bdfSopenharmony_ci size_t mapsize; 131f08c3bdfSopenharmony_ci char *maddr = NULL, *paddr; 132f08c3bdfSopenharmony_ci unsigned int randpage; 133f08c3bdfSopenharmony_ci unsigned int seed; 134f08c3bdfSopenharmony_ci unsigned int loopcnt; 135f08c3bdfSopenharmony_ci unsigned int nloops; 136f08c3bdfSopenharmony_ci unsigned int mappages; 137f08c3bdfSopenharmony_ci unsigned int i; 138f08c3bdfSopenharmony_ci 139f08c3bdfSopenharmony_ci seed = initrand(); 140f08c3bdfSopenharmony_ci 141f08c3bdfSopenharmony_ci SAFE_STAT(file, &statbuf); 142f08c3bdfSopenharmony_ci filesize = statbuf.st_size; 143f08c3bdfSopenharmony_ci 144f08c3bdfSopenharmony_ci fd = SAFE_OPEN(file, O_RDWR); 145f08c3bdfSopenharmony_ci 146f08c3bdfSopenharmony_ci if (statbuf.st_size - sparseoffset > UINT_MAX) 147f08c3bdfSopenharmony_ci tst_brk(TBROK, "size_t overflow when setting up map"); 148f08c3bdfSopenharmony_ci mapsize = (size_t) (statbuf.st_size - sparseoffset); 149f08c3bdfSopenharmony_ci mappages = roundup(mapsize, pagesize) / pagesize; 150f08c3bdfSopenharmony_ci offset = sparseoffset; 151f08c3bdfSopenharmony_ci if (do_offset) { 152f08c3bdfSopenharmony_ci int pageoffset = lrand48() % mappages; 153f08c3bdfSopenharmony_ci int byteoffset = pageoffset * pagesize; 154f08c3bdfSopenharmony_ci 155f08c3bdfSopenharmony_ci offset += byteoffset; 156f08c3bdfSopenharmony_ci mapsize -= byteoffset; 157f08c3bdfSopenharmony_ci mappages -= pageoffset; 158f08c3bdfSopenharmony_ci } 159f08c3bdfSopenharmony_ci nloops = (randloops) ? (lrand48() % MAXLOOPS) : MAXLOOPS; 160f08c3bdfSopenharmony_ci 161f08c3bdfSopenharmony_ci if (debug) 162f08c3bdfSopenharmony_ci tst_res(TINFO, "child %d (pid %d): seed %d, fsize %lld, mapsize %ld, off %lld, loop %d", 163f08c3bdfSopenharmony_ci procno, getpid(), seed, (long long)filesize, 164f08c3bdfSopenharmony_ci (long)mapsize, (long long)offset / pagesize, nloops); 165f08c3bdfSopenharmony_ci 166f08c3bdfSopenharmony_ci maddr = SAFE_MMAP(0, mapsize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 167f08c3bdfSopenharmony_ci offset); 168f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 169f08c3bdfSopenharmony_ci 170f08c3bdfSopenharmony_ci for (loopcnt = 0; loopcnt < nloops; loopcnt++) { 171f08c3bdfSopenharmony_ci randpage = lrand48() % mappages; 172f08c3bdfSopenharmony_ci paddr = maddr + (randpage * pagesize); /* page address */ 173f08c3bdfSopenharmony_ci 174f08c3bdfSopenharmony_ci if (randpage < mappages - 1 || !(mapsize % pagesize)) 175f08c3bdfSopenharmony_ci validsize = pagesize; 176f08c3bdfSopenharmony_ci else 177f08c3bdfSopenharmony_ci validsize = mapsize % pagesize; 178f08c3bdfSopenharmony_ci 179f08c3bdfSopenharmony_ci for (i = procno; i < validsize; i += nprocs) { 180f08c3bdfSopenharmony_ci if (*((unsigned char *)(paddr + i)) 181f08c3bdfSopenharmony_ci != ((procno + pattern) & 0xff)) 182f08c3bdfSopenharmony_ci tst_brk(TFAIL, "child %d: invalid data <x%x>\n" 183f08c3bdfSopenharmony_ci " at pg %d off %d, exp <x%x>", procno, 184f08c3bdfSopenharmony_ci *((unsigned char *)(paddr + i)), 185f08c3bdfSopenharmony_ci randpage, i, (procno + pattern) & 0xff); 186f08c3bdfSopenharmony_ci 187f08c3bdfSopenharmony_ci *(paddr + i) = (procno + pattern) & 0xff; 188f08c3bdfSopenharmony_ci } 189f08c3bdfSopenharmony_ci } 190f08c3bdfSopenharmony_ci if (do_sync) { 191f08c3bdfSopenharmony_ci randpage = lrand48() % mappages; 192f08c3bdfSopenharmony_ci paddr = maddr + (randpage * pagesize); /* page address */ 193f08c3bdfSopenharmony_ci if (msync(paddr, (mappages - randpage) * pagesize, 194f08c3bdfSopenharmony_ci MS_SYNC) == -1) 195f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, "msync failed"); 196f08c3bdfSopenharmony_ci } 197f08c3bdfSopenharmony_ci SAFE_MUNMAP(maddr, mapsize); 198f08c3bdfSopenharmony_ci exit(0); 199f08c3bdfSopenharmony_ci} 200f08c3bdfSopenharmony_ci 201f08c3bdfSopenharmony_ci/* Make sure file has all the correct data. */ 202f08c3bdfSopenharmony_cistatic void fileokay(char *file, unsigned char *expbuf) 203f08c3bdfSopenharmony_ci{ 204f08c3bdfSopenharmony_ci int cnt; 205f08c3bdfSopenharmony_ci size_t mapsize; 206f08c3bdfSopenharmony_ci struct stat statbuf; 207f08c3bdfSopenharmony_ci unsigned char readbuf[pagesize]; 208f08c3bdfSopenharmony_ci unsigned int i, j; 209f08c3bdfSopenharmony_ci unsigned int mappages; 210f08c3bdfSopenharmony_ci 211f08c3bdfSopenharmony_ci fd = SAFE_OPEN(file, O_RDONLY); 212f08c3bdfSopenharmony_ci 213f08c3bdfSopenharmony_ci SAFE_FSTAT(fd, &statbuf); 214f08c3bdfSopenharmony_ci SAFE_LSEEK(fd, sparseoffset, SEEK_SET); 215f08c3bdfSopenharmony_ci 216f08c3bdfSopenharmony_ci if (statbuf.st_size - sparseoffset > UINT_MAX) 217f08c3bdfSopenharmony_ci tst_brk(TBROK, "size_t overflow when setting up map"); 218f08c3bdfSopenharmony_ci mapsize = (size_t) (statbuf.st_size - sparseoffset); 219f08c3bdfSopenharmony_ci 220f08c3bdfSopenharmony_ci mappages = roundup(mapsize, pagesize) / pagesize; 221f08c3bdfSopenharmony_ci 222f08c3bdfSopenharmony_ci for (i = 0; i < mappages; i++) { 223f08c3bdfSopenharmony_ci cnt = SAFE_READ(0, fd, readbuf, pagesize); 224f08c3bdfSopenharmony_ci if ((unsigned int)cnt != pagesize) { 225f08c3bdfSopenharmony_ci /* Okay if at last page in file... */ 226f08c3bdfSopenharmony_ci if ((i * pagesize) + cnt != mapsize) 227f08c3bdfSopenharmony_ci tst_brk(TFAIL, "missing data: read %lu of %ld bytes", 228f08c3bdfSopenharmony_ci (i * pagesize) + cnt, (long)mapsize); 229f08c3bdfSopenharmony_ci } 230f08c3bdfSopenharmony_ci /* Compare read bytes of data. */ 231f08c3bdfSopenharmony_ci for (j = 0; j < (unsigned int)cnt; j++) { 232f08c3bdfSopenharmony_ci if (expbuf[j] != readbuf[j]) 233f08c3bdfSopenharmony_ci tst_brk(TFAIL, 234f08c3bdfSopenharmony_ci "read bad data: exp %c got %c, pg %d off %d, (fsize %lld)", 235f08c3bdfSopenharmony_ci expbuf[j], readbuf[j], i, j, 236f08c3bdfSopenharmony_ci (long long)statbuf.st_size); 237f08c3bdfSopenharmony_ci } 238f08c3bdfSopenharmony_ci } 239f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 240f08c3bdfSopenharmony_ci} 241f08c3bdfSopenharmony_ci 242f08c3bdfSopenharmony_cistatic void sighandler(int sig LTP_ATTRIBUTE_UNUSED) 243f08c3bdfSopenharmony_ci{ 244f08c3bdfSopenharmony_ci finished++; 245f08c3bdfSopenharmony_ci} 246f08c3bdfSopenharmony_ci 247f08c3bdfSopenharmony_cistatic unsigned int initrand(void) 248f08c3bdfSopenharmony_ci{ 249f08c3bdfSopenharmony_ci unsigned int seed; 250f08c3bdfSopenharmony_ci 251f08c3bdfSopenharmony_ci /* 252f08c3bdfSopenharmony_ci * Use srand/rand to diffuse the information from the 253f08c3bdfSopenharmony_ci * time and pid. If you start several processes, then 254f08c3bdfSopenharmony_ci * the time and pid information don't provide much 255f08c3bdfSopenharmony_ci * variation. 256f08c3bdfSopenharmony_ci */ 257f08c3bdfSopenharmony_ci srand((unsigned int)getpid()); 258f08c3bdfSopenharmony_ci seed = rand(); 259f08c3bdfSopenharmony_ci srand((unsigned int)time(NULL)); 260f08c3bdfSopenharmony_ci seed = (seed ^ rand()) % 100000; 261f08c3bdfSopenharmony_ci srand48((long)seed); 262f08c3bdfSopenharmony_ci return seed; 263f08c3bdfSopenharmony_ci} 264f08c3bdfSopenharmony_ci 265f08c3bdfSopenharmony_cistatic void run(void) 266f08c3bdfSopenharmony_ci{ 267f08c3bdfSopenharmony_ci int c; 268f08c3bdfSopenharmony_ci int i; 269f08c3bdfSopenharmony_ci int wait_stat; 270f08c3bdfSopenharmony_ci off_t bytes_left; 271f08c3bdfSopenharmony_ci pid_t pid; 272f08c3bdfSopenharmony_ci pid_t *pidarray; 273f08c3bdfSopenharmony_ci size_t write_cnt; 274f08c3bdfSopenharmony_ci unsigned char data; 275f08c3bdfSopenharmony_ci unsigned char *buf; 276f08c3bdfSopenharmony_ci 277f08c3bdfSopenharmony_ci alarm(tst_remaining_runtime()); 278f08c3bdfSopenharmony_ci 279f08c3bdfSopenharmony_ci finished = 0; 280f08c3bdfSopenharmony_ci fd = SAFE_OPEN(TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, 0664); 281f08c3bdfSopenharmony_ci buf = SAFE_MALLOC(pagesize); 282f08c3bdfSopenharmony_ci pidarray = SAFE_MALLOC(nprocs * sizeof(pid_t)); 283f08c3bdfSopenharmony_ci 284f08c3bdfSopenharmony_ci for (i = 0; i < nprocs; i++) 285f08c3bdfSopenharmony_ci *(pidarray + i) = 0; 286f08c3bdfSopenharmony_ci 287f08c3bdfSopenharmony_ci for (i = 0, data = 0; i < (int)pagesize; i++) { 288f08c3bdfSopenharmony_ci *(buf + i) = (data + pattern) & 0xff; 289f08c3bdfSopenharmony_ci if (++data == nprocs) 290f08c3bdfSopenharmony_ci data = 0; 291f08c3bdfSopenharmony_ci } 292f08c3bdfSopenharmony_ci SAFE_LSEEK(fd, (off_t)sparseoffset, SEEK_SET); 293f08c3bdfSopenharmony_ci for (bytes_left = filesize; bytes_left; bytes_left -= c) { 294f08c3bdfSopenharmony_ci write_cnt = MIN((long long)pagesize, (long long)bytes_left); 295f08c3bdfSopenharmony_ci c = SAFE_WRITE(1, fd, buf, write_cnt); 296f08c3bdfSopenharmony_ci } 297f08c3bdfSopenharmony_ci SAFE_CLOSE(fd); 298f08c3bdfSopenharmony_ci 299f08c3bdfSopenharmony_ci for (i = 0; i < nprocs; i++) { 300f08c3bdfSopenharmony_ci pid = SAFE_FORK(); 301f08c3bdfSopenharmony_ci 302f08c3bdfSopenharmony_ci if (pid == 0) { 303f08c3bdfSopenharmony_ci child_mapper(TEST_FILE, (unsigned int)i, (unsigned int)nprocs); 304f08c3bdfSopenharmony_ci exit(0); 305f08c3bdfSopenharmony_ci } else { 306f08c3bdfSopenharmony_ci pidarray[i] = pid; 307f08c3bdfSopenharmony_ci } 308f08c3bdfSopenharmony_ci } 309f08c3bdfSopenharmony_ci 310f08c3bdfSopenharmony_ci while (!finished) { 311f08c3bdfSopenharmony_ci pid = wait(&wait_stat); 312f08c3bdfSopenharmony_ci if (pid != -1) { 313f08c3bdfSopenharmony_ci if (!WIFEXITED(wait_stat) 314f08c3bdfSopenharmony_ci || WEXITSTATUS(wait_stat) != 0) 315f08c3bdfSopenharmony_ci tst_brk(TBROK, "child exit with err <x%x>", 316f08c3bdfSopenharmony_ci wait_stat); 317f08c3bdfSopenharmony_ci for (i = 0; i < nprocs; i++) 318f08c3bdfSopenharmony_ci if (pid == pidarray[i]) 319f08c3bdfSopenharmony_ci break; 320f08c3bdfSopenharmony_ci if (i == nprocs) 321f08c3bdfSopenharmony_ci tst_brk(TBROK, "unknown child pid %d, <x%x>", 322f08c3bdfSopenharmony_ci pid, wait_stat); 323f08c3bdfSopenharmony_ci 324f08c3bdfSopenharmony_ci pid = SAFE_FORK(); 325f08c3bdfSopenharmony_ci if (pid == 0) { 326f08c3bdfSopenharmony_ci child_mapper(TEST_FILE, (unsigned int)i, (unsigned int)nprocs); 327f08c3bdfSopenharmony_ci exit(0); 328f08c3bdfSopenharmony_ci } else { 329f08c3bdfSopenharmony_ci pidarray[i] = pid; 330f08c3bdfSopenharmony_ci } 331f08c3bdfSopenharmony_ci } else { 332f08c3bdfSopenharmony_ci if (errno != EINTR || !finished) 333f08c3bdfSopenharmony_ci tst_brk(TBROK | TERRNO, 334f08c3bdfSopenharmony_ci "unexpected wait error"); 335f08c3bdfSopenharmony_ci } 336f08c3bdfSopenharmony_ci } 337f08c3bdfSopenharmony_ci alarm(0); 338f08c3bdfSopenharmony_ci 339f08c3bdfSopenharmony_ci fileokay(TEST_FILE, buf); 340f08c3bdfSopenharmony_ci tst_res(TPASS, "file has expected data"); 341f08c3bdfSopenharmony_ci} 342f08c3bdfSopenharmony_ci 343f08c3bdfSopenharmony_cistatic struct tst_test test = { 344f08c3bdfSopenharmony_ci .test_all = run, 345f08c3bdfSopenharmony_ci .setup = setup, 346f08c3bdfSopenharmony_ci .options = (struct tst_option[]) { 347f08c3bdfSopenharmony_ci {"d", &debug, "Enable debug output"}, 348f08c3bdfSopenharmony_ci {"f:", &opt_filesize, "Initial filesize (default 4096)"}, 349f08c3bdfSopenharmony_ci {"m", &do_sync, "Do random msync/fsyncs as well"}, 350f08c3bdfSopenharmony_ci {"o", &do_offset, "Randomize the offset of file to map"}, 351f08c3bdfSopenharmony_ci {"p:", &opt_nprocs, 352f08c3bdfSopenharmony_ci "Number of mapping children to create (default 1 < ncpus < 20)"}, 353f08c3bdfSopenharmony_ci {"P:", &opt_pattern, 354f08c3bdfSopenharmony_ci "Use a fixed pattern (default random)"}, 355f08c3bdfSopenharmony_ci {"r", &randloops, 356f08c3bdfSopenharmony_ci "Randomize number of pages map children check (random % 500), " 357f08c3bdfSopenharmony_ci "otherwise each child checks 500 pages"}, 358f08c3bdfSopenharmony_ci {"S:", &opt_sparseoffset, 359f08c3bdfSopenharmony_ci "When non-zero, causes the sparse area to be left before the data, " 360f08c3bdfSopenharmony_ci "so that the actual initial filesize is sparseoffset + filesize " 361f08c3bdfSopenharmony_ci "(default 0)"}, 362f08c3bdfSopenharmony_ci {}, 363f08c3bdfSopenharmony_ci }, 364f08c3bdfSopenharmony_ci .cleanup = cleanup, 365f08c3bdfSopenharmony_ci .max_runtime = 12, 366f08c3bdfSopenharmony_ci .needs_tmpdir = 1, 367f08c3bdfSopenharmony_ci .forks_child = 1, 368f08c3bdfSopenharmony_ci}; 369