1f08c3bdfSopenharmony_ci/* IBM Corporation */ 2f08c3bdfSopenharmony_ci/* 01/02/2003 Port to LTP avenkat@us.ibm.com */ 3f08c3bdfSopenharmony_ci/* 06/30/2001 Port to Linux nsharoff@us.ibm.com */ 4f08c3bdfSopenharmony_ci/* 5f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify 6f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by 7f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 8f08c3bdfSopenharmony_ci * (at your option) any later version. 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful, 11f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 12f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13f08c3bdfSopenharmony_ci * the GNU General Public License for more details. 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 16f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software 17f08c3bdfSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18f08c3bdfSopenharmony_ci */ 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci#define _GNU_SOURCE 1 21f08c3bdfSopenharmony_ci#include <stdio.h> 22f08c3bdfSopenharmony_ci#include <fcntl.h> 23f08c3bdfSopenharmony_ci#include <signal.h> 24f08c3bdfSopenharmony_ci#include <sys/mman.h> 25f08c3bdfSopenharmony_ci#include <sys/wait.h> 26f08c3bdfSopenharmony_ci#include <sys/stat.h> 27f08c3bdfSopenharmony_ci#include <unistd.h> 28f08c3bdfSopenharmony_ci#include <stdlib.h> 29f08c3bdfSopenharmony_ci#include <errno.h> 30f08c3bdfSopenharmony_ci#include <sys/types.h> 31f08c3bdfSopenharmony_ci#include <limits.h> 32f08c3bdfSopenharmony_ci/***** LTP Port *****/ 33f08c3bdfSopenharmony_ci#include "test.h" 34f08c3bdfSopenharmony_ci#define FAILED 0 35f08c3bdfSopenharmony_ci#define PASSED 1 36f08c3bdfSopenharmony_ci 37f08c3bdfSopenharmony_ciint local_flag = PASSED; 38f08c3bdfSopenharmony_cichar *TCID = "mmapstress10"; 39f08c3bdfSopenharmony_ciFILE *temp; 40f08c3bdfSopenharmony_ciint TST_TOTAL = 1; 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_ciint anyfail(); 43f08c3bdfSopenharmony_civoid ok_exit(); 44f08c3bdfSopenharmony_ci/***** ** ** *****/ 45f08c3bdfSopenharmony_ci 46f08c3bdfSopenharmony_ci/* 47f08c3bdfSopenharmony_ci * This test stresses mmaps, specifically the code dealing with 48f08c3bdfSopenharmony_ci * mapping of fragments. It forks a specified number of children, 49f08c3bdfSopenharmony_ci * all of whom mmap the same file, make a given number of accesses 50f08c3bdfSopenharmony_ci * to random pages in the map (reading & writing and comparing data). 51f08c3bdfSopenharmony_ci * Then the child exits and the parent forks another to take its place. 52f08c3bdfSopenharmony_ci * Each time a child is forked, it stats the file and maps the full 53f08c3bdfSopenharmony_ci * length of the file. Meanwhile, another child is forked which 54f08c3bdfSopenharmony_ci * continually writes to the file. It loops writing some bytes (default 55f08c3bdfSopenharmony_ci * 20), then sleeps some seconds (default 1). This causes the file 56f08c3bdfSopenharmony_ci * to gradually grow, crossing fragment boundaries, etc. 57f08c3bdfSopenharmony_ci * Then it forks yet *another* child who maps the file in extend 58f08c3bdfSopenharmony_ci * mode, just to check out interaction. (Because this will cause 59f08c3bdfSopenharmony_ci * 0 padding at end of file, children can't test as exactly as in tmmap - 60f08c3bdfSopenharmony_ci * have to check for zero or pattern...) 61f08c3bdfSopenharmony_ci * 62f08c3bdfSopenharmony_ci * This program continues to run until it either receives a SIGINT, 63f08c3bdfSopenharmony_ci * or times out (if a timeout value is specified). When either of 64f08c3bdfSopenharmony_ci * these things happens, it cleans up its kids, then checks the 65f08c3bdfSopenharmony_ci * file to make sure it has the correct data. 66f08c3bdfSopenharmony_ci * 67f08c3bdfSopenharmony_ci * usage: 68f08c3bdfSopenharmony_ci * mmapstress10 -p nprocs [-t minutes -w nbytes -s secs -f filesize 69f08c3bdfSopenharmony_ci * -S sparseoffset -r -o -m -l -d] 70f08c3bdfSopenharmony_ci * where: 71f08c3bdfSopenharmony_ci * -p nprocs - specifies the number of mapping children 72f08c3bdfSopenharmony_ci * to create. (nprocs + 1 children actually 73f08c3bdfSopenharmony_ci * get created, since one is the writer child) 74f08c3bdfSopenharmony_ci * -t minutes - specifies minutes to run. If not specified, 75f08c3bdfSopenharmony_ci * default is to run forever until a SIGINT 76f08c3bdfSopenharmony_ci * is received. 77f08c3bdfSopenharmony_ci * -w nbytes - specifies number of bytes for writer process 78f08c3bdfSopenharmony_ci * to write at a time (i.e. between sleeps). 79f08c3bdfSopenharmony_ci * defaults to GROWSIZE bytes. 80f08c3bdfSopenharmony_ci * -s secs - specifies number of seconds for writer process 81f08c3bdfSopenharmony_ci * to sleep between writes. Defaults to 82f08c3bdfSopenharmony_ci * SLEEPTIME seconds. 83f08c3bdfSopenharmony_ci * -f filesize - initial filesize (defaults to FILESIZE) 84f08c3bdfSopenharmony_ci * -S sparseoffset - when non-zero, causes a sparse area to 85f08c3bdfSopenharmony_ci * be left before the data, meaning that the 86f08c3bdfSopenharmony_ci * actual initial file size is sparseoffset + 87f08c3bdfSopenharmony_ci * filesize. Useful for testing large files. 88f08c3bdfSopenharmony_ci * (default is 0). 89f08c3bdfSopenharmony_ci * -r - randomize number of pages map children check. 90f08c3bdfSopenharmony_ci * (random % MAXLOOPS). If not specified, each 91f08c3bdfSopenharmony_ci * child checks MAXLOOPS pages. 92f08c3bdfSopenharmony_ci * -o - randomize offset of file to map. (default is 0) 93f08c3bdfSopenharmony_ci * -m - do random msync/fsyncs as well 94f08c3bdfSopenharmony_ci * -l - if set, the output file is not removed on 95f08c3bdfSopenharmony_ci * program exit. 96f08c3bdfSopenharmony_ci * -d - enable debug outputd 97f08c3bdfSopenharmony_ci * 98f08c3bdfSopenharmony_ci * Compile with -DLARGE_FILE to enable file sizes > 2 GB. 99f08c3bdfSopenharmony_ci */ 100f08c3bdfSopenharmony_ci 101f08c3bdfSopenharmony_ci#define MAXLOOPS 500 /* max pages for map children to write */ 102f08c3bdfSopenharmony_ci#define GROWSIZE 20 /* # bytes to write per write call */ 103f08c3bdfSopenharmony_ci#define SLEEPTIME 1 /* # secs to sleep between writes */ 104f08c3bdfSopenharmony_ci#define FILESIZE 4096 /* initial filesize set up by parent */ 105f08c3bdfSopenharmony_ci#ifdef roundup 106f08c3bdfSopenharmony_ci#undef roundup 107f08c3bdfSopenharmony_ci#endif 108f08c3bdfSopenharmony_ci#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) 109f08c3bdfSopenharmony_ci 110f08c3bdfSopenharmony_ci#define SIZE_MAX UINT_MAX 111f08c3bdfSopenharmony_ci 112f08c3bdfSopenharmony_ciextern time_t time(time_t *); 113f08c3bdfSopenharmony_ciextern char *ctime(const time_t *); 114f08c3bdfSopenharmony_ciextern void *malloc(size_t); 115f08c3bdfSopenharmony_ciextern void exit(int); 116f08c3bdfSopenharmony_ciextern long lrand48(void); 117f08c3bdfSopenharmony_ciextern void srand(unsigned); 118f08c3bdfSopenharmony_ciextern void srand48(long); 119f08c3bdfSopenharmony_ciextern int rand(void); 120f08c3bdfSopenharmony_ciextern int atoi(const char *); 121f08c3bdfSopenharmony_ci 122f08c3bdfSopenharmony_cichar *usage = 123f08c3bdfSopenharmony_ci "-p nprocs [-t minutes -w nbytes -s secs -f fsize -S sparseoffset -r -o -m -l -d]"; 124f08c3bdfSopenharmony_ci 125f08c3bdfSopenharmony_citypedef unsigned char uchar_t; //Ananda 12/17/02 126f08c3bdfSopenharmony_ci 127f08c3bdfSopenharmony_civoid child_mapper(char *file, unsigned procno, unsigned nprocs); 128f08c3bdfSopenharmony_civoid child_writer(char *file, uchar_t * buf); 129f08c3bdfSopenharmony_ciint fileokay(char *file, uchar_t * expbuf); 130f08c3bdfSopenharmony_ciunsigned int initrand(void); 131f08c3bdfSopenharmony_civoid finish(int sig); 132f08c3bdfSopenharmony_civoid clean_up_file(int sig); 133f08c3bdfSopenharmony_ciint finished = 0; 134f08c3bdfSopenharmony_ciint leavefile = 0; 135f08c3bdfSopenharmony_ci 136f08c3bdfSopenharmony_ciint debug = 0; 137f08c3bdfSopenharmony_ciint growsize = GROWSIZE; 138f08c3bdfSopenharmony_ciint sleeptime = SLEEPTIME; 139f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 140f08c3bdfSopenharmony_cioff64_t filesize = FILESIZE; 141f08c3bdfSopenharmony_cioff64_t sparseoffset = 0; 142f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 143f08c3bdfSopenharmony_cioff_t filesize = FILESIZE; 144f08c3bdfSopenharmony_cioff_t sparseoffset = 0; 145f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 146f08c3bdfSopenharmony_ciunsigned randloops = 0; 147f08c3bdfSopenharmony_ciunsigned dosync = 0; 148f08c3bdfSopenharmony_ciunsigned do_offset = 0; 149f08c3bdfSopenharmony_ciunsigned pattern = 0; 150f08c3bdfSopenharmony_cistatic const char *filename = "mmapstress10.out"; 151f08c3bdfSopenharmony_ci 152f08c3bdfSopenharmony_civoid clean_mapper(int sig); 153f08c3bdfSopenharmony_civoid clean_writer(int sig); 154f08c3bdfSopenharmony_ci 155f08c3bdfSopenharmony_ciint fd_mapper = 0; 156f08c3bdfSopenharmony_cicaddr_t maddr_mapper; 157f08c3bdfSopenharmony_cisize_t mapsize_mapper; 158f08c3bdfSopenharmony_ci 159f08c3bdfSopenharmony_ciint fd_writer = 0; 160f08c3bdfSopenharmony_ci 161f08c3bdfSopenharmony_ciint main(int argc, char *argv[]) 162f08c3bdfSopenharmony_ci{ 163f08c3bdfSopenharmony_ci char *progname; 164f08c3bdfSopenharmony_ci int fd; 165f08c3bdfSopenharmony_ci int c; 166f08c3bdfSopenharmony_ci extern char *optarg; 167f08c3bdfSopenharmony_ci unsigned nprocs = 0; 168f08c3bdfSopenharmony_ci unsigned procno; 169f08c3bdfSopenharmony_ci pid_t *pidarray = NULL; 170f08c3bdfSopenharmony_ci pid_t pid; 171f08c3bdfSopenharmony_ci pid_t wr_pid = 0; 172f08c3bdfSopenharmony_ci uchar_t *buf = NULL; 173f08c3bdfSopenharmony_ci unsigned int seed; 174f08c3bdfSopenharmony_ci int pagesize = sysconf(_SC_PAGE_SIZE); 175f08c3bdfSopenharmony_ci float alarmtime = 0; 176f08c3bdfSopenharmony_ci struct sigaction sa; 177f08c3bdfSopenharmony_ci unsigned i; 178f08c3bdfSopenharmony_ci int write_cnt; 179f08c3bdfSopenharmony_ci uchar_t data; 180f08c3bdfSopenharmony_ci int no_prob = 0; 181f08c3bdfSopenharmony_ci int wait_stat; 182f08c3bdfSopenharmony_ci time_t t; 183f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 184f08c3bdfSopenharmony_ci off64_t bytes_left; 185f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 186f08c3bdfSopenharmony_ci off_t bytes_left; 187f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 188f08c3bdfSopenharmony_ci 189f08c3bdfSopenharmony_ci progname = *argv; 190f08c3bdfSopenharmony_ci tst_tmpdir(); 191f08c3bdfSopenharmony_ci if (argc < 2) { 192f08c3bdfSopenharmony_ci (void)fprintf(stderr, "usage: %s %s\n", progname, usage); 193f08c3bdfSopenharmony_ci exit(1); 194f08c3bdfSopenharmony_ci } 195f08c3bdfSopenharmony_ci 196f08c3bdfSopenharmony_ci while ((c = getopt(argc, argv, "S:omdlrf:p:t:w:s:")) != -1) { 197f08c3bdfSopenharmony_ci switch (c) { 198f08c3bdfSopenharmony_ci case 'd': 199f08c3bdfSopenharmony_ci debug = 1; 200f08c3bdfSopenharmony_ci break; 201f08c3bdfSopenharmony_ci case 't': 202f08c3bdfSopenharmony_ci alarmtime = atof(optarg) * 60; 203f08c3bdfSopenharmony_ci break; 204f08c3bdfSopenharmony_ci case 'p': 205f08c3bdfSopenharmony_ci nprocs = atoi(optarg); 206f08c3bdfSopenharmony_ci break; 207f08c3bdfSopenharmony_ci case 'l': 208f08c3bdfSopenharmony_ci leavefile = 1; 209f08c3bdfSopenharmony_ci break; 210f08c3bdfSopenharmony_ci case 's': 211f08c3bdfSopenharmony_ci sleeptime = atoi(optarg); 212f08c3bdfSopenharmony_ci if (sleeptime < 0) { 213f08c3bdfSopenharmony_ci (void)fprintf(stderr, "error: negative " 214f08c3bdfSopenharmony_ci "sleeptime\n"); 215f08c3bdfSopenharmony_ci anyfail(); 216f08c3bdfSopenharmony_ci } 217f08c3bdfSopenharmony_ci break; 218f08c3bdfSopenharmony_ci case 'w': 219f08c3bdfSopenharmony_ci growsize = atoi(optarg); 220f08c3bdfSopenharmony_ci if (growsize < 0) { 221f08c3bdfSopenharmony_ci (void)fprintf(stderr, "error: negative write " 222f08c3bdfSopenharmony_ci "size\n"); 223f08c3bdfSopenharmony_ci anyfail(); 224f08c3bdfSopenharmony_ci } 225f08c3bdfSopenharmony_ci break; 226f08c3bdfSopenharmony_ci case 'f': 227f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 228f08c3bdfSopenharmony_ci filesize = atoll(optarg); 229f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 230f08c3bdfSopenharmony_ci filesize = atoi(optarg); 231f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 232f08c3bdfSopenharmony_ci if (filesize < 0) { 233f08c3bdfSopenharmony_ci (void)fprintf(stderr, "error: negative " 234f08c3bdfSopenharmony_ci "filesize\n"); 235f08c3bdfSopenharmony_ci anyfail(); 236f08c3bdfSopenharmony_ci } 237f08c3bdfSopenharmony_ci break; 238f08c3bdfSopenharmony_ci case 'r': 239f08c3bdfSopenharmony_ci randloops = 1; 240f08c3bdfSopenharmony_ci break; 241f08c3bdfSopenharmony_ci case 'm': 242f08c3bdfSopenharmony_ci dosync = 1; 243f08c3bdfSopenharmony_ci break; 244f08c3bdfSopenharmony_ci case 'o': 245f08c3bdfSopenharmony_ci do_offset = 1; 246f08c3bdfSopenharmony_ci break; 247f08c3bdfSopenharmony_ci case 'S': 248f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 249f08c3bdfSopenharmony_ci sparseoffset = atoll(optarg); 250f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 251f08c3bdfSopenharmony_ci sparseoffset = atoi(optarg); 252f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 253f08c3bdfSopenharmony_ci if (sparseoffset % pagesize != 0) { 254f08c3bdfSopenharmony_ci fprintf(stderr, 255f08c3bdfSopenharmony_ci "sparseoffset must be pagesize multiple\n"); 256f08c3bdfSopenharmony_ci anyfail(); 257f08c3bdfSopenharmony_ci } 258f08c3bdfSopenharmony_ci break; 259f08c3bdfSopenharmony_ci default: 260f08c3bdfSopenharmony_ci (void)fprintf(stderr, "usage: %s %s\n", progname, 261f08c3bdfSopenharmony_ci usage); 262f08c3bdfSopenharmony_ci anyfail(); 263f08c3bdfSopenharmony_ci } 264f08c3bdfSopenharmony_ci } 265f08c3bdfSopenharmony_ci 266f08c3bdfSopenharmony_ci if (nprocs > 255) { 267f08c3bdfSopenharmony_ci (void)fprintf(stderr, "invalid nprocs %d - (range 0-255)\n", 268f08c3bdfSopenharmony_ci nprocs); 269f08c3bdfSopenharmony_ci anyfail(); 270f08c3bdfSopenharmony_ci } 271f08c3bdfSopenharmony_ci (void)time(&t); 272f08c3bdfSopenharmony_ci 273f08c3bdfSopenharmony_ci seed = initrand(); 274f08c3bdfSopenharmony_ci pattern = seed & 0xff; 275f08c3bdfSopenharmony_ci 276f08c3bdfSopenharmony_ci if (debug) { 277f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 278f08c3bdfSopenharmony_ci (void)printf("creating file <%s> with %Ld bytes, pattern %d\n", 279f08c3bdfSopenharmony_ci filename, filesize, pattern); 280f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 281f08c3bdfSopenharmony_ci (void)printf("creating file <%s> with %ld bytes, pattern %d\n", 282f08c3bdfSopenharmony_ci filename, filesize, pattern); 283f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 284f08c3bdfSopenharmony_ci if (alarmtime) 285f08c3bdfSopenharmony_ci (void)printf("running for %f minutes\n", 286f08c3bdfSopenharmony_ci alarmtime / 60); 287f08c3bdfSopenharmony_ci else 288f08c3bdfSopenharmony_ci (void)printf("running with no time limit\n"); 289f08c3bdfSopenharmony_ci } 290f08c3bdfSopenharmony_ci 291f08c3bdfSopenharmony_ci /* 292f08c3bdfSopenharmony_ci * Plan for death by signal. User may have specified 293f08c3bdfSopenharmony_ci * a time limit, in which case set an alarm and catch SIGALRM. 294f08c3bdfSopenharmony_ci * Also catch and cleanup with SIGINT, SIGQUIT, and SIGTERM. 295f08c3bdfSopenharmony_ci */ 296f08c3bdfSopenharmony_ci sa.sa_handler = finish; 297f08c3bdfSopenharmony_ci sa.sa_flags = 0; 298f08c3bdfSopenharmony_ci if (sigemptyset(&sa.sa_mask)) { 299f08c3bdfSopenharmony_ci perror("sigempty error"); 300f08c3bdfSopenharmony_ci goto cleanup; 301f08c3bdfSopenharmony_ci } 302f08c3bdfSopenharmony_ci 303f08c3bdfSopenharmony_ci if (sigaction(SIGINT, &sa, 0) == -1) { 304f08c3bdfSopenharmony_ci perror("sigaction error SIGINT"); 305f08c3bdfSopenharmony_ci goto cleanup; 306f08c3bdfSopenharmony_ci } 307f08c3bdfSopenharmony_ci if (alarmtime) { 308f08c3bdfSopenharmony_ci if (sigaction(SIGALRM, &sa, 0) == -1) { 309f08c3bdfSopenharmony_ci perror("sigaction error"); 310f08c3bdfSopenharmony_ci goto cleanup; 311f08c3bdfSopenharmony_ci } 312f08c3bdfSopenharmony_ci (void)alarm(alarmtime); 313f08c3bdfSopenharmony_ci } 314f08c3bdfSopenharmony_ci /* If we get a SIGQUIT or SIGTERM, clean up and exit immediately. */ 315f08c3bdfSopenharmony_ci sa.sa_handler = clean_up_file; 316f08c3bdfSopenharmony_ci if (sigaction(SIGQUIT, &sa, 0) == -1) { 317f08c3bdfSopenharmony_ci perror("sigaction error SIGQUIT"); 318f08c3bdfSopenharmony_ci goto cleanup; 319f08c3bdfSopenharmony_ci } 320f08c3bdfSopenharmony_ci if (sigaction(SIGTERM, &sa, 0) == -1) { 321f08c3bdfSopenharmony_ci perror("sigaction error SIGTERM"); 322f08c3bdfSopenharmony_ci goto cleanup; 323f08c3bdfSopenharmony_ci } 324f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 325f08c3bdfSopenharmony_ci if ((fd = open64(filename, O_CREAT | O_TRUNC | O_RDWR, 0664)) == -1) { 326f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 327f08c3bdfSopenharmony_ci if ((fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, 0664)) == -1) { 328f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 329f08c3bdfSopenharmony_ci perror("open error"); 330f08c3bdfSopenharmony_ci anyfail(); 331f08c3bdfSopenharmony_ci } 332f08c3bdfSopenharmony_ci 333f08c3bdfSopenharmony_ci if ((buf = malloc(pagesize + growsize)) == NULL 334f08c3bdfSopenharmony_ci || (pidarray = malloc(nprocs * sizeof(pid_t))) == NULL) { 335f08c3bdfSopenharmony_ci perror("malloc error"); 336f08c3bdfSopenharmony_ci anyfail(); 337f08c3bdfSopenharmony_ci } 338f08c3bdfSopenharmony_ci 339f08c3bdfSopenharmony_ci for (i = 0; i < nprocs; i++) 340f08c3bdfSopenharmony_ci *(pidarray + i) = 0; 341f08c3bdfSopenharmony_ci 342f08c3bdfSopenharmony_ci for (i = 0, data = 0; i < pagesize; i++) { 343f08c3bdfSopenharmony_ci *(buf + i) = (data + pattern) & 0xff; 344f08c3bdfSopenharmony_ci if (++data == nprocs) 345f08c3bdfSopenharmony_ci data = 0; 346f08c3bdfSopenharmony_ci } 347f08c3bdfSopenharmony_ci for (data = 0; i < pagesize + growsize; i++) { 348f08c3bdfSopenharmony_ci *(buf + i) = (data + pattern) & 0xff; 349f08c3bdfSopenharmony_ci if (++data == nprocs) 350f08c3bdfSopenharmony_ci data = 0; 351f08c3bdfSopenharmony_ci } 352f08c3bdfSopenharmony_ci 353f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 354f08c3bdfSopenharmony_ci if (lseek64(fd, sparseoffset, SEEK_SET) < 0) { 355f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 356f08c3bdfSopenharmony_ci if (lseek(fd, sparseoffset, SEEK_SET) < 0) { 357f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 358f08c3bdfSopenharmony_ci perror("lseek"); 359f08c3bdfSopenharmony_ci anyfail(); 360f08c3bdfSopenharmony_ci } 361f08c3bdfSopenharmony_ci 362f08c3bdfSopenharmony_ci for (bytes_left = filesize; bytes_left; bytes_left -= c) { 363f08c3bdfSopenharmony_ci write_cnt = MIN(pagesize, (int)bytes_left); 364f08c3bdfSopenharmony_ci if ((c = write(fd, (char *)buf, write_cnt)) != write_cnt) { 365f08c3bdfSopenharmony_ci if (c == -1) { 366f08c3bdfSopenharmony_ci perror("write error"); 367f08c3bdfSopenharmony_ci } else { 368f08c3bdfSopenharmony_ci (void)fprintf(stderr, "write: wrote %d of %d " 369f08c3bdfSopenharmony_ci "bytes\n", c, write_cnt); 370f08c3bdfSopenharmony_ci } 371f08c3bdfSopenharmony_ci (void)close(fd); 372f08c3bdfSopenharmony_ci (void)unlink(filename); 373f08c3bdfSopenharmony_ci anyfail(); 374f08c3bdfSopenharmony_ci } 375f08c3bdfSopenharmony_ci } 376f08c3bdfSopenharmony_ci 377f08c3bdfSopenharmony_ci (void)close(fd); 378f08c3bdfSopenharmony_ci 379f08c3bdfSopenharmony_ci /* 380f08c3bdfSopenharmony_ci * Fork off mmap children. 381f08c3bdfSopenharmony_ci */ 382f08c3bdfSopenharmony_ci for (procno = 0; procno < nprocs; procno++) { 383f08c3bdfSopenharmony_ci switch (pid = fork()) { 384f08c3bdfSopenharmony_ci 385f08c3bdfSopenharmony_ci case -1: 386f08c3bdfSopenharmony_ci perror("fork error"); 387f08c3bdfSopenharmony_ci goto cleanup; 388f08c3bdfSopenharmony_ci 389f08c3bdfSopenharmony_ci case 0: 390f08c3bdfSopenharmony_ci child_mapper(filename, procno, nprocs); 391f08c3bdfSopenharmony_ci exit(0); 392f08c3bdfSopenharmony_ci 393f08c3bdfSopenharmony_ci default: 394f08c3bdfSopenharmony_ci pidarray[procno] = pid; 395f08c3bdfSopenharmony_ci } 396f08c3bdfSopenharmony_ci } 397f08c3bdfSopenharmony_ci 398f08c3bdfSopenharmony_ci /* 399f08c3bdfSopenharmony_ci * Now fork off an additional process to continually 400f08c3bdfSopenharmony_ci * write to (and grow) the file. 401f08c3bdfSopenharmony_ci */ 402f08c3bdfSopenharmony_ci if ((wr_pid = fork()) == -1) { 403f08c3bdfSopenharmony_ci perror("fork error"); 404f08c3bdfSopenharmony_ci goto cleanup; 405f08c3bdfSopenharmony_ci } else if (wr_pid == 0) { /* child */ 406f08c3bdfSopenharmony_ci child_writer(filename, buf); 407f08c3bdfSopenharmony_ci exit(0); 408f08c3bdfSopenharmony_ci } 409f08c3bdfSopenharmony_ci 410f08c3bdfSopenharmony_ci /* 411f08c3bdfSopenharmony_ci * Now wait for children and refork them as needed. 412f08c3bdfSopenharmony_ci */ 413f08c3bdfSopenharmony_ci 414f08c3bdfSopenharmony_ci while (!finished) { 415f08c3bdfSopenharmony_ci pid = wait(&wait_stat); 416f08c3bdfSopenharmony_ci /* 417f08c3bdfSopenharmony_ci * Block signals while processing child exit. 418f08c3bdfSopenharmony_ci */ 419f08c3bdfSopenharmony_ci 420f08c3bdfSopenharmony_ci if (sighold(SIGALRM) || sighold(SIGINT)) { 421f08c3bdfSopenharmony_ci perror("sighold error"); 422f08c3bdfSopenharmony_ci goto cleanup; 423f08c3bdfSopenharmony_ci } 424f08c3bdfSopenharmony_ci 425f08c3bdfSopenharmony_ci if (pid != -1) { 426f08c3bdfSopenharmony_ci /* 427f08c3bdfSopenharmony_ci * Check exit status, then refork with the 428f08c3bdfSopenharmony_ci * appropriate procno. 429f08c3bdfSopenharmony_ci */ 430f08c3bdfSopenharmony_ci if (!WIFEXITED(wait_stat) 431f08c3bdfSopenharmony_ci || WEXITSTATUS(wait_stat) != 0) { 432f08c3bdfSopenharmony_ci (void)fprintf(stderr, "child exit with err " 433f08c3bdfSopenharmony_ci "<x%x>\n", wait_stat); 434f08c3bdfSopenharmony_ci goto cleanup; 435f08c3bdfSopenharmony_ci } 436f08c3bdfSopenharmony_ci for (i = 0; i < nprocs; i++) 437f08c3bdfSopenharmony_ci if (pid == pidarray[i]) 438f08c3bdfSopenharmony_ci break; 439f08c3bdfSopenharmony_ci if (i == nprocs) { 440f08c3bdfSopenharmony_ci if (pid == wr_pid) { 441f08c3bdfSopenharmony_ci (void)fprintf(stderr, 442f08c3bdfSopenharmony_ci "writer child unexpected exit <x%x>\n", 443f08c3bdfSopenharmony_ci wait_stat); 444f08c3bdfSopenharmony_ci wr_pid = 0; 445f08c3bdfSopenharmony_ci } else 446f08c3bdfSopenharmony_ci (void)fprintf(stderr, "unknown child " 447f08c3bdfSopenharmony_ci "pid %d, <x%x>\n", 448f08c3bdfSopenharmony_ci pid, wait_stat); 449f08c3bdfSopenharmony_ci goto cleanup; 450f08c3bdfSopenharmony_ci } 451f08c3bdfSopenharmony_ci 452f08c3bdfSopenharmony_ci if ((pid = fork()) == -1) { 453f08c3bdfSopenharmony_ci perror("fork error"); 454f08c3bdfSopenharmony_ci pidarray[i] = 0; 455f08c3bdfSopenharmony_ci goto cleanup; 456f08c3bdfSopenharmony_ci } else if (pid == 0) { /* child */ 457f08c3bdfSopenharmony_ci child_mapper(filename, i, nprocs); 458f08c3bdfSopenharmony_ci exit(0); 459f08c3bdfSopenharmony_ci } else 460f08c3bdfSopenharmony_ci pidarray[i] = pid; 461f08c3bdfSopenharmony_ci } else { 462f08c3bdfSopenharmony_ci /* 463f08c3bdfSopenharmony_ci * wait returned an error. If EINTR, then 464f08c3bdfSopenharmony_ci * normal finish, else it's an unexpected 465f08c3bdfSopenharmony_ci * error... 466f08c3bdfSopenharmony_ci */ 467f08c3bdfSopenharmony_ci if (errno != EINTR || !finished) { 468f08c3bdfSopenharmony_ci perror("unexpected wait error"); 469f08c3bdfSopenharmony_ci goto cleanup; 470f08c3bdfSopenharmony_ci } 471f08c3bdfSopenharmony_ci } 472f08c3bdfSopenharmony_ci if (sigrelse(SIGALRM) || sigrelse(SIGINT)) { 473f08c3bdfSopenharmony_ci perror("sigrelse error"); 474f08c3bdfSopenharmony_ci goto cleanup; 475f08c3bdfSopenharmony_ci } 476f08c3bdfSopenharmony_ci } 477f08c3bdfSopenharmony_ci 478f08c3bdfSopenharmony_ci /* 479f08c3bdfSopenharmony_ci * Finished! Check the file for sanity, then kill all 480f08c3bdfSopenharmony_ci * the children and done!. 481f08c3bdfSopenharmony_ci */ 482f08c3bdfSopenharmony_ci 483f08c3bdfSopenharmony_ci (void)alarm(0); 484f08c3bdfSopenharmony_ci no_prob = 1; 485f08c3bdfSopenharmony_ci 486f08c3bdfSopenharmony_cicleanup: 487f08c3bdfSopenharmony_ci for (i = 0; i < nprocs; i++) 488f08c3bdfSopenharmony_ci (void)kill(pidarray[i], SIGUSR1); 489f08c3bdfSopenharmony_ci (void)kill(wr_pid, SIGUSR1); 490f08c3bdfSopenharmony_ci 491f08c3bdfSopenharmony_ci while (wait(&wait_stat) != -1 || errno != ECHILD) 492f08c3bdfSopenharmony_ci continue; 493f08c3bdfSopenharmony_ci 494f08c3bdfSopenharmony_ci if (no_prob) { /* only check file if no errors */ 495f08c3bdfSopenharmony_ci if (!fileokay(filename, buf)) { 496f08c3bdfSopenharmony_ci (void)fprintf(stderr, "file data incorrect!\n"); 497f08c3bdfSopenharmony_ci (void)printf(" leaving file <%s>\n", filename); 498f08c3bdfSopenharmony_ci anyfail(); 499f08c3bdfSopenharmony_ci 500f08c3bdfSopenharmony_ci } else { 501f08c3bdfSopenharmony_ci (void)printf("file data okay\n"); 502f08c3bdfSopenharmony_ci if (!leavefile) 503f08c3bdfSopenharmony_ci (void)unlink(filename); 504f08c3bdfSopenharmony_ci } 505f08c3bdfSopenharmony_ci } else 506f08c3bdfSopenharmony_ci (void)printf(" leaving file <%s>\n", filename); 507f08c3bdfSopenharmony_ci 508f08c3bdfSopenharmony_ci (void)time(&t); 509f08c3bdfSopenharmony_ci// (void)printf("%s: Finished %s", argv[0], ctime(&t)); LTP Port 510f08c3bdfSopenharmony_ci ok_exit(); 511f08c3bdfSopenharmony_ci tst_exit(); 512f08c3bdfSopenharmony_ci} 513f08c3bdfSopenharmony_ci 514f08c3bdfSopenharmony_ci/* 515f08c3bdfSopenharmony_ci * Child process that reads/writes map. The child stats the file 516f08c3bdfSopenharmony_ci * to determine the size, maps the size of the file, then reads/writes 517f08c3bdfSopenharmony_ci * its own locations on random pages of the map (its locations being 518f08c3bdfSopenharmony_ci * determined based on nprocs & procno). After a specific number of 519f08c3bdfSopenharmony_ci * iterations, it exits. 520f08c3bdfSopenharmony_ci */ 521f08c3bdfSopenharmony_civoid child_mapper(char *file, unsigned procno, unsigned nprocs) 522f08c3bdfSopenharmony_ci{ 523f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 524f08c3bdfSopenharmony_ci struct stat64 statbuf; 525f08c3bdfSopenharmony_ci off64_t filesize; 526f08c3bdfSopenharmony_ci off64_t offset; 527f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 528f08c3bdfSopenharmony_ci struct stat statbuf; 529f08c3bdfSopenharmony_ci off_t filesize; 530f08c3bdfSopenharmony_ci off_t offset; 531f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 532f08c3bdfSopenharmony_ci size_t validsize; 533f08c3bdfSopenharmony_ci caddr_t paddr; 534f08c3bdfSopenharmony_ci int pagesize = sysconf(_SC_PAGE_SIZE); 535f08c3bdfSopenharmony_ci unsigned randpage; 536f08c3bdfSopenharmony_ci unsigned int seed; 537f08c3bdfSopenharmony_ci unsigned loopcnt; 538f08c3bdfSopenharmony_ci unsigned nloops; 539f08c3bdfSopenharmony_ci unsigned mappages; 540f08c3bdfSopenharmony_ci unsigned mapflags; 541f08c3bdfSopenharmony_ci unsigned i; 542f08c3bdfSopenharmony_ci struct sigaction sa_mapper; 543f08c3bdfSopenharmony_ci 544f08c3bdfSopenharmony_ci mapflags = MAP_SHARED; 545f08c3bdfSopenharmony_ci 546f08c3bdfSopenharmony_ci seed = initrand(); /* initialize random seed */ 547f08c3bdfSopenharmony_ci 548f08c3bdfSopenharmony_ci sa_mapper.sa_handler = clean_mapper; 549f08c3bdfSopenharmony_ci sa_mapper.sa_flags = 0; 550f08c3bdfSopenharmony_ci if (sigemptyset(&sa_mapper.sa_mask)) { 551f08c3bdfSopenharmony_ci perror("sigempty error"); 552f08c3bdfSopenharmony_ci anyfail(); 553f08c3bdfSopenharmony_ci } 554f08c3bdfSopenharmony_ci 555f08c3bdfSopenharmony_ci if (sigaction(SIGUSR1, &sa_mapper, 0) == -1) { 556f08c3bdfSopenharmony_ci perror("sigaction error SIGUSR1"); 557f08c3bdfSopenharmony_ci anyfail(); 558f08c3bdfSopenharmony_ci } 559f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 560f08c3bdfSopenharmony_ci if ((fd_mapper = open64(file, O_RDWR)) == -1) { 561f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 562f08c3bdfSopenharmony_ci if ((fd_mapper = open(file, O_RDWR)) == -1) { 563f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 564f08c3bdfSopenharmony_ci perror("open error"); 565f08c3bdfSopenharmony_ci anyfail(); 566f08c3bdfSopenharmony_ci } 567f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 568f08c3bdfSopenharmony_ci if (fstat64(fd_mapper, &statbuf) == -1) { 569f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 570f08c3bdfSopenharmony_ci if (fstat(fd_mapper, &statbuf) == -1) { 571f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 572f08c3bdfSopenharmony_ci perror("stat error"); 573f08c3bdfSopenharmony_ci anyfail(); 574f08c3bdfSopenharmony_ci } 575f08c3bdfSopenharmony_ci filesize = statbuf.st_size; 576f08c3bdfSopenharmony_ci 577f08c3bdfSopenharmony_ci if (statbuf.st_size - sparseoffset > SIZE_MAX) { 578f08c3bdfSopenharmony_ci fprintf(stderr, "size_t overflow when setting up map\n"); 579f08c3bdfSopenharmony_ci anyfail(); 580f08c3bdfSopenharmony_ci } 581f08c3bdfSopenharmony_ci mapsize_mapper = (size_t) (statbuf.st_size - sparseoffset); 582f08c3bdfSopenharmony_ci mappages = roundup(mapsize_mapper, pagesize) / pagesize; 583f08c3bdfSopenharmony_ci offset = sparseoffset; 584f08c3bdfSopenharmony_ci if (do_offset) { 585f08c3bdfSopenharmony_ci int pageoffset = lrand48() % mappages; 586f08c3bdfSopenharmony_ci int byteoffset = pageoffset * pagesize; 587f08c3bdfSopenharmony_ci offset += byteoffset; 588f08c3bdfSopenharmony_ci mapsize_mapper -= byteoffset; 589f08c3bdfSopenharmony_ci mappages -= pageoffset; 590f08c3bdfSopenharmony_ci } 591f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 592f08c3bdfSopenharmony_ci if ((maddr_mapper = mmap64(0, mapsize_mapper, PROT_READ | PROT_WRITE, 593f08c3bdfSopenharmony_ci mapflags, fd_mapper, 594f08c3bdfSopenharmony_ci offset)) == (caddr_t) - 1) { 595f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 596f08c3bdfSopenharmony_ci if ((maddr_mapper = mmap(0, mapsize_mapper, PROT_READ | PROT_WRITE, 597f08c3bdfSopenharmony_ci mapflags, fd_mapper, 598f08c3bdfSopenharmony_ci offset)) == (caddr_t) - 1) { 599f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 600f08c3bdfSopenharmony_ci perror("mmap error"); 601f08c3bdfSopenharmony_ci anyfail(); 602f08c3bdfSopenharmony_ci } 603f08c3bdfSopenharmony_ci 604f08c3bdfSopenharmony_ci (void)close(fd_mapper); 605f08c3bdfSopenharmony_ci 606f08c3bdfSopenharmony_ci nloops = (randloops) ? (lrand48() % MAXLOOPS) : MAXLOOPS; 607f08c3bdfSopenharmony_ci 608f08c3bdfSopenharmony_ci if (debug) { 609f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 610f08c3bdfSopenharmony_ci (void)printf("child %d (pid %ld): seed %d, fsize %Ld, " 611f08c3bdfSopenharmony_ci "mapsize %d, off %Ld, loop %d\n", 612f08c3bdfSopenharmony_ci procno, getpid(), seed, filesize, mapsize_mapper, 613f08c3bdfSopenharmony_ci offset / pagesize, nloops); 614f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 615f08c3bdfSopenharmony_ci (void)printf("child %d (pid %d): seed %d, fsize %ld, " 616f08c3bdfSopenharmony_ci "mapsize %ld, off %ld, loop %d\n", 617f08c3bdfSopenharmony_ci procno, getpid(), seed, filesize, 618f08c3bdfSopenharmony_ci (long)mapsize_mapper, offset / pagesize, nloops); 619f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 620f08c3bdfSopenharmony_ci } 621f08c3bdfSopenharmony_ci 622f08c3bdfSopenharmony_ci /* 623f08c3bdfSopenharmony_ci * Now loop read/writing random pages. 624f08c3bdfSopenharmony_ci */ 625f08c3bdfSopenharmony_ci for (loopcnt = 0; loopcnt < nloops; loopcnt++) { 626f08c3bdfSopenharmony_ci randpage = lrand48() % mappages; 627f08c3bdfSopenharmony_ci paddr = maddr_mapper + (randpage * pagesize); /* page address */ 628f08c3bdfSopenharmony_ci 629f08c3bdfSopenharmony_ci if (randpage < mappages - 1 || !(mapsize_mapper % pagesize)) 630f08c3bdfSopenharmony_ci validsize = pagesize; 631f08c3bdfSopenharmony_ci else 632f08c3bdfSopenharmony_ci validsize = mapsize_mapper % pagesize; 633f08c3bdfSopenharmony_ci 634f08c3bdfSopenharmony_ci /* 635f08c3bdfSopenharmony_ci * Because one child is mapping file in extend mode, 636f08c3bdfSopenharmony_ci * it may be padded with zeros at end. So we can't 637f08c3bdfSopenharmony_ci * do an exact check -- accept known pattern OR zeros. 638f08c3bdfSopenharmony_ci */ 639f08c3bdfSopenharmony_ci for (i = procno; i < validsize; i += nprocs) { 640f08c3bdfSopenharmony_ci if (*((unsigned char *)(paddr + i)) 641f08c3bdfSopenharmony_ci != ((procno + pattern) & 0xff) 642f08c3bdfSopenharmony_ci && *((unsigned char *)(paddr + i)) != 0) { 643f08c3bdfSopenharmony_ci (void)fprintf(stderr, "child %d: invalid data " 644f08c3bdfSopenharmony_ci "<x%x>", procno, 645f08c3bdfSopenharmony_ci *((unsigned char *)(paddr + i))); 646f08c3bdfSopenharmony_ci (void)fprintf(stderr, 647f08c3bdfSopenharmony_ci " at pg %d off %d, exp " 648f08c3bdfSopenharmony_ci "<x%x>\n", randpage, i, 649f08c3bdfSopenharmony_ci (procno + pattern) & 0xff); 650f08c3bdfSopenharmony_ci anyfail(); 651f08c3bdfSopenharmony_ci } 652f08c3bdfSopenharmony_ci /* 653f08c3bdfSopenharmony_ci * Now write it. 654f08c3bdfSopenharmony_ci */ 655f08c3bdfSopenharmony_ci 656f08c3bdfSopenharmony_ci *(paddr + i) = (procno + pattern) & 0xff; 657f08c3bdfSopenharmony_ci } 658f08c3bdfSopenharmony_ci } 659f08c3bdfSopenharmony_ci if (dosync) { 660f08c3bdfSopenharmony_ci /* 661f08c3bdfSopenharmony_ci * Exercise msync() as well! 662f08c3bdfSopenharmony_ci */ 663f08c3bdfSopenharmony_ci randpage = lrand48() % mappages; 664f08c3bdfSopenharmony_ci paddr = maddr_mapper + (randpage * pagesize); /* page address */ 665f08c3bdfSopenharmony_ci if (msync(paddr, (mappages - randpage) * pagesize, 666f08c3bdfSopenharmony_ci MS_SYNC) == -1) { 667f08c3bdfSopenharmony_ci perror("msync error"); 668f08c3bdfSopenharmony_ci anyfail(); 669f08c3bdfSopenharmony_ci } 670f08c3bdfSopenharmony_ci } 671f08c3bdfSopenharmony_ci if (munmap(maddr_mapper, mapsize_mapper) == -1) { 672f08c3bdfSopenharmony_ci perror("munmap failed"); 673f08c3bdfSopenharmony_ci anyfail(); 674f08c3bdfSopenharmony_ci } 675f08c3bdfSopenharmony_ci exit(0); 676f08c3bdfSopenharmony_ci} 677f08c3bdfSopenharmony_ci 678f08c3bdfSopenharmony_ci/* 679f08c3bdfSopenharmony_ci * child_writer 680f08c3bdfSopenharmony_ci * The child process that continually (and slowly!!) grows 681f08c3bdfSopenharmony_ci * the file. The purpose of this is to exercise the code 682f08c3bdfSopenharmony_ci * supporting mapping of fragments. The map children are 683f08c3bdfSopenharmony_ci * constantly reforking and will pick up the map changes, etc. 684f08c3bdfSopenharmony_ci * This process executes until signalled (i.e. has no exit!) 685f08c3bdfSopenharmony_ci * unless error. 686f08c3bdfSopenharmony_ci */ 687f08c3bdfSopenharmony_civoid child_writer(char *file, uchar_t * buf) 688f08c3bdfSopenharmony_ci{ /* buf already set up in main */ 689f08c3bdfSopenharmony_ci struct sigaction sa_writer; 690f08c3bdfSopenharmony_ci 691f08c3bdfSopenharmony_ci sa_writer.sa_handler = clean_writer; 692f08c3bdfSopenharmony_ci sa_writer.sa_flags = 0; 693f08c3bdfSopenharmony_ci if (sigemptyset(&sa_writer.sa_mask)) { 694f08c3bdfSopenharmony_ci perror("sigempty error"); 695f08c3bdfSopenharmony_ci anyfail(); 696f08c3bdfSopenharmony_ci } 697f08c3bdfSopenharmony_ci 698f08c3bdfSopenharmony_ci if (sigaction(SIGUSR1, &sa_writer, 0) == -1) { 699f08c3bdfSopenharmony_ci perror("sigaction error SIGUSR1"); 700f08c3bdfSopenharmony_ci anyfail(); 701f08c3bdfSopenharmony_ci } 702f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 703f08c3bdfSopenharmony_ci struct stat64 statbuf; 704f08c3bdfSopenharmony_ci off64_t off; 705f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 706f08c3bdfSopenharmony_ci struct stat statbuf; 707f08c3bdfSopenharmony_ci off_t off; 708f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 709f08c3bdfSopenharmony_ci int pagesize = sysconf(_SC_PAGE_SIZE); 710f08c3bdfSopenharmony_ci uchar_t *p; 711f08c3bdfSopenharmony_ci int cnt; 712f08c3bdfSopenharmony_ci 713f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 714f08c3bdfSopenharmony_ci if ((fd_writer = open64(file, O_RDWR)) == -1) { 715f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 716f08c3bdfSopenharmony_ci if ((fd_writer = open(file, O_RDWR)) == -1) { 717f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 718f08c3bdfSopenharmony_ci perror("open error"); 719f08c3bdfSopenharmony_ci anyfail(); 720f08c3bdfSopenharmony_ci } 721f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 722f08c3bdfSopenharmony_ci if ((off = lseek64(fd_writer, 0, SEEK_END)) == -1) { 723f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 724f08c3bdfSopenharmony_ci if ((off = lseek(fd_writer, 0, SEEK_END)) == -1) { 725f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 726f08c3bdfSopenharmony_ci perror("lseek error"); 727f08c3bdfSopenharmony_ci anyfail(); 728f08c3bdfSopenharmony_ci } 729f08c3bdfSopenharmony_ci 730f08c3bdfSopenharmony_ci for (;;) { 731f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 732f08c3bdfSopenharmony_ci if (fstat64(fd_writer, &statbuf) == -1) { 733f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 734f08c3bdfSopenharmony_ci if (fstat(fd_writer, &statbuf) == -1) { 735f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 736f08c3bdfSopenharmony_ci perror("fstat error"); 737f08c3bdfSopenharmony_ci anyfail(); 738f08c3bdfSopenharmony_ci } 739f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 740f08c3bdfSopenharmony_ci if (debug) 741f08c3bdfSopenharmony_ci (void)printf("writer %d bytes at off %Ld, size %Ld\n", 742f08c3bdfSopenharmony_ci growsize, off, statbuf.st_size); 743f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 744f08c3bdfSopenharmony_ci if (debug) 745f08c3bdfSopenharmony_ci (void)printf("writer %d bytes at off %ld, size %ld\n", 746f08c3bdfSopenharmony_ci growsize, off, statbuf.st_size); 747f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 748f08c3bdfSopenharmony_ci 749f08c3bdfSopenharmony_ci /* 750f08c3bdfSopenharmony_ci * Write some number of bytes, then sleep some 751f08c3bdfSopenharmony_ci * number of seconds... 752f08c3bdfSopenharmony_ci * Need to keep track of our offset so write the 753f08c3bdfSopenharmony_ci * right bytes. 754f08c3bdfSopenharmony_ci */ 755f08c3bdfSopenharmony_ci 756f08c3bdfSopenharmony_ci p = buf + (off % pagesize); 757f08c3bdfSopenharmony_ci 758f08c3bdfSopenharmony_ci if ((cnt = write(fd_writer, p, growsize)) != growsize) { 759f08c3bdfSopenharmony_ci if (cnt == -1) 760f08c3bdfSopenharmony_ci perror("write error"); 761f08c3bdfSopenharmony_ci else 762f08c3bdfSopenharmony_ci (void)fprintf(stderr, "wrote %d of %d bytes\n", 763f08c3bdfSopenharmony_ci cnt, growsize); 764f08c3bdfSopenharmony_ci anyfail(); 765f08c3bdfSopenharmony_ci } 766f08c3bdfSopenharmony_ci 767f08c3bdfSopenharmony_ci off += growsize; 768f08c3bdfSopenharmony_ci 769f08c3bdfSopenharmony_ci (void)sleep(sleeptime); 770f08c3bdfSopenharmony_ci if (dosync) { 771f08c3bdfSopenharmony_ci if (fsync(fd_writer) == -1) { 772f08c3bdfSopenharmony_ci perror("fsync error"); 773f08c3bdfSopenharmony_ci anyfail(); 774f08c3bdfSopenharmony_ci } 775f08c3bdfSopenharmony_ci } 776f08c3bdfSopenharmony_ci } 777f08c3bdfSopenharmony_ci close(fd_writer); 778f08c3bdfSopenharmony_ci} 779f08c3bdfSopenharmony_ci 780f08c3bdfSopenharmony_ci/* 781f08c3bdfSopenharmony_ci * Make sure file has all the correct data. 782f08c3bdfSopenharmony_ci 783f08c3bdfSopenharmony_ci */ 784f08c3bdfSopenharmony_ciint fileokay(char *file, uchar_t * expbuf) 785f08c3bdfSopenharmony_ci{ 786f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 787f08c3bdfSopenharmony_ci struct stat64 statbuf; 788f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 789f08c3bdfSopenharmony_ci struct stat statbuf; 790f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 791f08c3bdfSopenharmony_ci size_t mapsize; 792f08c3bdfSopenharmony_ci uchar_t *readbuf; 793f08c3bdfSopenharmony_ci unsigned mappages; 794f08c3bdfSopenharmony_ci unsigned pagesize = sysconf(_SC_PAGE_SIZE); 795f08c3bdfSopenharmony_ci int fd; 796f08c3bdfSopenharmony_ci int cnt; 797f08c3bdfSopenharmony_ci unsigned i, j; 798f08c3bdfSopenharmony_ci 799f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 800f08c3bdfSopenharmony_ci if ((fd = open64(file, O_RDONLY)) == -1) { 801f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 802f08c3bdfSopenharmony_ci if ((fd = open(file, O_RDONLY)) == -1) { 803f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 804f08c3bdfSopenharmony_ci perror("open error"); 805f08c3bdfSopenharmony_ci anyfail(); 806f08c3bdfSopenharmony_ci } 807f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 808f08c3bdfSopenharmony_ci if (fstat64(fd, &statbuf) == -1) { 809f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 810f08c3bdfSopenharmony_ci if (fstat(fd, &statbuf) == -1) { 811f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 812f08c3bdfSopenharmony_ci perror("stat error"); 813f08c3bdfSopenharmony_ci anyfail(); 814f08c3bdfSopenharmony_ci } 815f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 816f08c3bdfSopenharmony_ci if (lseek64(fd, sparseoffset, SEEK_SET) < 0) { 817f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 818f08c3bdfSopenharmony_ci if (lseek(fd, sparseoffset, SEEK_SET) < 0) { 819f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 820f08c3bdfSopenharmony_ci perror("lseek"); 821f08c3bdfSopenharmony_ci exit(1); 822f08c3bdfSopenharmony_ci } 823f08c3bdfSopenharmony_ci 824f08c3bdfSopenharmony_ci readbuf = malloc(pagesize); 825f08c3bdfSopenharmony_ci 826f08c3bdfSopenharmony_ci if (statbuf.st_size - sparseoffset > SIZE_MAX) { 827f08c3bdfSopenharmony_ci fprintf(stderr, "size_t overflow when setting up map\n"); 828f08c3bdfSopenharmony_ci exit(1); 829f08c3bdfSopenharmony_ci } 830f08c3bdfSopenharmony_ci mapsize = (size_t) (statbuf.st_size - sparseoffset); 831f08c3bdfSopenharmony_ci mappages = roundup(mapsize, pagesize) / pagesize; 832f08c3bdfSopenharmony_ci 833f08c3bdfSopenharmony_ci for (i = 0; i < mappages; i++) { 834f08c3bdfSopenharmony_ci cnt = read(fd, (char *)readbuf, pagesize); 835f08c3bdfSopenharmony_ci if (cnt == -1) { 836f08c3bdfSopenharmony_ci perror("read error"); 837f08c3bdfSopenharmony_ci close(fd); 838f08c3bdfSopenharmony_ci return 0; 839f08c3bdfSopenharmony_ci } else if (cnt != pagesize) { 840f08c3bdfSopenharmony_ci /* 841f08c3bdfSopenharmony_ci * Okay if at last page in file... 842f08c3bdfSopenharmony_ci */ 843f08c3bdfSopenharmony_ci if ((i * pagesize) + cnt != mapsize) { 844f08c3bdfSopenharmony_ci (void)fprintf(stderr, "read %d of %ld bytes\n", 845f08c3bdfSopenharmony_ci (i * pagesize) + cnt, 846f08c3bdfSopenharmony_ci (long)mapsize); 847f08c3bdfSopenharmony_ci close(fd); 848f08c3bdfSopenharmony_ci return 0; 849f08c3bdfSopenharmony_ci } 850f08c3bdfSopenharmony_ci } 851f08c3bdfSopenharmony_ci /* 852f08c3bdfSopenharmony_ci * Compare read bytes of data. 853f08c3bdfSopenharmony_ci * May have zeros from map extend... 854f08c3bdfSopenharmony_ci */ 855f08c3bdfSopenharmony_ci for (j = 0; j < cnt; j++) { 856f08c3bdfSopenharmony_ci if (expbuf[j] != readbuf[j] && readbuf[j] != 0) { 857f08c3bdfSopenharmony_ci (void)fprintf(stderr, 858f08c3bdfSopenharmony_ci "read bad data: exp %c got %c", 859f08c3bdfSopenharmony_ci expbuf[j], readbuf[j]); 860f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 861f08c3bdfSopenharmony_ci (void)fprintf(stderr, ", pg %d off %d, " 862f08c3bdfSopenharmony_ci "(fsize %Ld)\n", i, j, 863f08c3bdfSopenharmony_ci statbuf.st_size); 864f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 865f08c3bdfSopenharmony_ci (void)fprintf(stderr, ", pg %d off %d, " 866f08c3bdfSopenharmony_ci "(fsize %ld)\n", i, j, 867f08c3bdfSopenharmony_ci statbuf.st_size); 868f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 869f08c3bdfSopenharmony_ci close(fd); 870f08c3bdfSopenharmony_ci return 0; 871f08c3bdfSopenharmony_ci } 872f08c3bdfSopenharmony_ci } 873f08c3bdfSopenharmony_ci } 874f08c3bdfSopenharmony_ci 875f08c3bdfSopenharmony_ci close(fd); 876f08c3bdfSopenharmony_ci return 1; 877f08c3bdfSopenharmony_ci} 878f08c3bdfSopenharmony_ci 879f08c3bdfSopenharmony_ci /*ARGSUSED*/ void finish(int sig) 880f08c3bdfSopenharmony_ci{ 881f08c3bdfSopenharmony_ci finished++; 882f08c3bdfSopenharmony_ci /* finish nicely and check the file contents */ 883f08c3bdfSopenharmony_ci} 884f08c3bdfSopenharmony_ci 885f08c3bdfSopenharmony_ci /*ARGSUSED*/ void clean_up_file(int sig) 886f08c3bdfSopenharmony_ci{ 887f08c3bdfSopenharmony_ci if (!leavefile) 888f08c3bdfSopenharmony_ci (void)unlink(filename); 889f08c3bdfSopenharmony_ci _exit(1); 890f08c3bdfSopenharmony_ci} 891f08c3bdfSopenharmony_ci 892f08c3bdfSopenharmony_civoid clean_mapper(int sig) 893f08c3bdfSopenharmony_ci{ 894f08c3bdfSopenharmony_ci if (fd_mapper) 895f08c3bdfSopenharmony_ci close(fd_mapper); 896f08c3bdfSopenharmony_ci munmap(maddr_mapper, mapsize_mapper); 897f08c3bdfSopenharmony_ci _exit(0); 898f08c3bdfSopenharmony_ci} 899f08c3bdfSopenharmony_ci 900f08c3bdfSopenharmony_civoid clean_writer(int sig) 901f08c3bdfSopenharmony_ci{ 902f08c3bdfSopenharmony_ci if (fd_writer) 903f08c3bdfSopenharmony_ci close(fd_writer); 904f08c3bdfSopenharmony_ci _exit(0); 905f08c3bdfSopenharmony_ci} 906f08c3bdfSopenharmony_ci 907f08c3bdfSopenharmony_ciunsigned int initrand(void) 908f08c3bdfSopenharmony_ci{ 909f08c3bdfSopenharmony_ci unsigned int seed; 910f08c3bdfSopenharmony_ci 911f08c3bdfSopenharmony_ci /* 912f08c3bdfSopenharmony_ci * Initialize random seed... Got this from a test written 913f08c3bdfSopenharmony_ci * by scooter: 914f08c3bdfSopenharmony_ci * Use srand/rand to diffuse the information from the 915f08c3bdfSopenharmony_ci * time and pid. If you start several processes, then 916f08c3bdfSopenharmony_ci * the time and pid information don't provide much 917f08c3bdfSopenharmony_ci * variation. 918f08c3bdfSopenharmony_ci */ 919f08c3bdfSopenharmony_ci srand((unsigned int)getpid()); 920f08c3bdfSopenharmony_ci seed = rand(); 921f08c3bdfSopenharmony_ci srand((unsigned int)time(NULL)); 922f08c3bdfSopenharmony_ci seed = (seed ^ rand()) % 100000; 923f08c3bdfSopenharmony_ci srand48((long int)seed); 924f08c3bdfSopenharmony_ci return (seed); 925f08c3bdfSopenharmony_ci} 926f08c3bdfSopenharmony_ci 927f08c3bdfSopenharmony_ci/***** LTP Port *****/ 928f08c3bdfSopenharmony_civoid ok_exit(void) 929f08c3bdfSopenharmony_ci{ 930f08c3bdfSopenharmony_ci tst_resm(TPASS, "Test passed"); 931f08c3bdfSopenharmony_ci tst_rmdir(); 932f08c3bdfSopenharmony_ci tst_exit(); 933f08c3bdfSopenharmony_ci} 934f08c3bdfSopenharmony_ci 935f08c3bdfSopenharmony_ciint anyfail(void) 936f08c3bdfSopenharmony_ci{ 937f08c3bdfSopenharmony_ci tst_brkm(TFAIL, tst_rmdir, "Test failed"); 938f08c3bdfSopenharmony_ci} 939f08c3bdfSopenharmony_ci 940f08c3bdfSopenharmony_ci/***** ** ** *****/ 941