1f08c3bdfSopenharmony_ci/* IBM Corporation */ 2f08c3bdfSopenharmony_ci/* 01/03/2003 Port to LTP avenkat@us.ibm.com */ 3f08c3bdfSopenharmony_ci/* 06/30/2001 Port to Linux nsharoff@us.ibm.com */ 4f08c3bdfSopenharmony_ci 5f08c3bdfSopenharmony_ci/* 6f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2003 7f08c3bdfSopenharmony_ci * 8f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify 9f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by 10f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 11f08c3bdfSopenharmony_ci * (at your option) any later version. 12f08c3bdfSopenharmony_ci * 13f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful, 14f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 16f08c3bdfSopenharmony_ci * the GNU General Public License for more details. 17f08c3bdfSopenharmony_ci * 18f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 19f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software 20f08c3bdfSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21f08c3bdfSopenharmony_ci */ 22f08c3bdfSopenharmony_ci 23f08c3bdfSopenharmony_ci/* 24f08c3bdfSopenharmony_ci * Mmap a sparse file and then fiddle with the hole in the middle. 25f08c3bdfSopenharmony_ci * Then check the file contents. 26f08c3bdfSopenharmony_ci * 27f08c3bdfSopenharmony_ci * Usage: mmapstress07 filename holesize e_pageskip sparseoff 28f08c3bdfSopenharmony_ci * EXAMPLE: mmapstress07 myfile 4096 1 4096 29f08c3bdfSopenharmony_ci */ 30f08c3bdfSopenharmony_ci#include <stdio.h> 31f08c3bdfSopenharmony_ci#include <sys/types.h> 32f08c3bdfSopenharmony_ci#include <sys/mman.h> 33f08c3bdfSopenharmony_ci#include <stdlib.h> 34f08c3bdfSopenharmony_ci#include <unistd.h> 35f08c3bdfSopenharmony_ci#include <fcntl.h> 36f08c3bdfSopenharmony_ci#include <signal.h> 37f08c3bdfSopenharmony_ci#include <errno.h> 38f08c3bdfSopenharmony_ci#include <sys/wait.h> 39f08c3bdfSopenharmony_ci#include "test.h" 40f08c3bdfSopenharmony_ci#define FAILED 0 41f08c3bdfSopenharmony_ci#define PASSED 1 42f08c3bdfSopenharmony_ci 43f08c3bdfSopenharmony_cistatic char *tmpname; 44f08c3bdfSopenharmony_ci 45f08c3bdfSopenharmony_ci#define ERROR(M) (void)fprintf(stderr, "%s: errno = %d: " M "\n", \ 46f08c3bdfSopenharmony_ci argv[0], errno) 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_ci#define CLEANERROR(M) (void)close(rofd); \ 49f08c3bdfSopenharmony_ci (void)close(rwfd); \ 50f08c3bdfSopenharmony_ci (void)unlink(tmpname); \ 51f08c3bdfSopenharmony_ci ERROR(M) 52f08c3bdfSopenharmony_ci 53f08c3bdfSopenharmony_ci#define CATCH_SIG(SIG) \ 54f08c3bdfSopenharmony_ci if (sigaction(SIG, &sa, 0) == -1) { \ 55f08c3bdfSopenharmony_ci ERROR("couldn't catch signal " #SIG); \ 56f08c3bdfSopenharmony_ci exit(1); \ 57f08c3bdfSopenharmony_ci } 58f08c3bdfSopenharmony_ci 59f08c3bdfSopenharmony_ciextern time_t time(time_t *); 60f08c3bdfSopenharmony_ciextern char *ctime(const time_t *); 61f08c3bdfSopenharmony_ciextern void exit(int); 62f08c3bdfSopenharmony_cistatic int checkchars(int fd, char val, int n); 63f08c3bdfSopenharmony_ci 64f08c3bdfSopenharmony_cichar *TCID = "mmapstress07"; 65f08c3bdfSopenharmony_ci 66f08c3bdfSopenharmony_ciint local_flag = PASSED; 67f08c3bdfSopenharmony_ciint block_number; 68f08c3bdfSopenharmony_ciFILE *temp; 69f08c3bdfSopenharmony_ciint TST_TOTAL = 1; 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ciint anyfail(); 72f08c3bdfSopenharmony_civoid ok_exit(); 73f08c3bdfSopenharmony_ci 74f08c3bdfSopenharmony_ci /*ARGSUSED*/ static 75f08c3bdfSopenharmony_civoid cleanup(int sig) 76f08c3bdfSopenharmony_ci{ 77f08c3bdfSopenharmony_ci /* 78f08c3bdfSopenharmony_ci * Don't check error codes - we could be signaled before the file is 79f08c3bdfSopenharmony_ci * created. 80f08c3bdfSopenharmony_ci */ 81f08c3bdfSopenharmony_ci (void)unlink(tmpname); 82f08c3bdfSopenharmony_ci exit(1); 83f08c3bdfSopenharmony_ci} 84f08c3bdfSopenharmony_ci 85f08c3bdfSopenharmony_ciint main(int argc, char **argv) 86f08c3bdfSopenharmony_ci{ 87f08c3bdfSopenharmony_ci size_t pagesize = (size_t) sysconf(_SC_PAGE_SIZE); 88f08c3bdfSopenharmony_ci caddr_t mapaddr; 89f08c3bdfSopenharmony_ci time_t t; 90f08c3bdfSopenharmony_ci int rofd, rwfd, i; 91f08c3bdfSopenharmony_ci struct sigaction sa; 92f08c3bdfSopenharmony_ci int e_pageskip; 93f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 94f08c3bdfSopenharmony_ci off64_t holesize; 95f08c3bdfSopenharmony_ci off64_t sparseoff; 96f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 97f08c3bdfSopenharmony_ci off_t holesize; 98f08c3bdfSopenharmony_ci off_t sparseoff; 99f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 100f08c3bdfSopenharmony_ci 101f08c3bdfSopenharmony_ci (void)time(&t); 102f08c3bdfSopenharmony_ci// (void)printf("%s: Started %s", argv[0], ctime(&t)); 103f08c3bdfSopenharmony_ci /* Test fsync & mmap over a hole in a sparse file & extend fragment */ 104f08c3bdfSopenharmony_ci if (argc < 2 || argc > 5) { 105f08c3bdfSopenharmony_ci fprintf(stderr, 106f08c3bdfSopenharmony_ci "Usage: mmapstress07 filename holesize e_pageskip sparseoff\n"); 107f08c3bdfSopenharmony_ci /***** ** LTP Port 02/01/03 ** **** */ 108f08c3bdfSopenharmony_ci fprintf(stderr, 109f08c3bdfSopenharmony_ci "\t*holesize should be a multiple of pagesize\n"); 110f08c3bdfSopenharmony_ci fprintf(stderr, "\t*e_pageskip should be 1 always \n"); 111f08c3bdfSopenharmony_ci fprintf(stderr, 112f08c3bdfSopenharmony_ci "\t*sparseoff should be a multiple of pagesize\n"); 113f08c3bdfSopenharmony_ci fprintf(stderr, "Example: mmapstress07 myfile 4096 1 8192\n"); 114f08c3bdfSopenharmony_ci /***** ** ****** ***** ***** ** 02/01/03 */ 115f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 116f08c3bdfSopenharmony_ci } 117f08c3bdfSopenharmony_ci tst_tmpdir(); 118f08c3bdfSopenharmony_ci tmpname = argv[1]; 119f08c3bdfSopenharmony_ci 120f08c3bdfSopenharmony_ci if (argc >= 3) { 121f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 122f08c3bdfSopenharmony_ci holesize = atoll(argv[2]); 123f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 124f08c3bdfSopenharmony_ci holesize = atoi(argv[2]); 125f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 126f08c3bdfSopenharmony_ci } else 127f08c3bdfSopenharmony_ci holesize = pagesize; 128f08c3bdfSopenharmony_ci 129f08c3bdfSopenharmony_ci if (argc >= 4) 130f08c3bdfSopenharmony_ci e_pageskip = atoi(argv[3]); 131f08c3bdfSopenharmony_ci else 132f08c3bdfSopenharmony_ci e_pageskip = 1; 133f08c3bdfSopenharmony_ci 134f08c3bdfSopenharmony_ci if (argc >= 5) { 135f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 136f08c3bdfSopenharmony_ci sparseoff = atoll(argv[4]); 137f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 138f08c3bdfSopenharmony_ci sparseoff = atoi(argv[4]); 139f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 140f08c3bdfSopenharmony_ci } else 141f08c3bdfSopenharmony_ci sparseoff = pagesize * 2; 142f08c3bdfSopenharmony_ci 143f08c3bdfSopenharmony_ci sa.sa_handler = cleanup; 144f08c3bdfSopenharmony_ci sa.sa_flags = 0; 145f08c3bdfSopenharmony_ci if (sigemptyset(&sa.sa_mask)) { 146f08c3bdfSopenharmony_ci ERROR("sigemptyset failed"); 147f08c3bdfSopenharmony_ci return 1; 148f08c3bdfSopenharmony_ci } 149f08c3bdfSopenharmony_ci CATCH_SIG(SIGINT); 150f08c3bdfSopenharmony_ci CATCH_SIG(SIGQUIT); 151f08c3bdfSopenharmony_ci CATCH_SIG(SIGTERM); 152f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 153f08c3bdfSopenharmony_ci if ((rofd = open64(tmpname, O_RDONLY | O_CREAT, 0777)) == -1) { 154f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 155f08c3bdfSopenharmony_ci if ((rofd = open(tmpname, O_RDONLY | O_CREAT, 0777)) == -1) { 156f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 157f08c3bdfSopenharmony_ci ERROR("couldn't reopen rofd for reading"); 158f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 159f08c3bdfSopenharmony_ci } 160f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 161f08c3bdfSopenharmony_ci if ((rwfd = open64(tmpname, O_RDWR)) == -1) { 162f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 163f08c3bdfSopenharmony_ci if ((rwfd = open(tmpname, O_RDWR)) == -1) { 164f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 165f08c3bdfSopenharmony_ci CLEANERROR("couldn't reopen rwfd for read/write"); 166f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 167f08c3bdfSopenharmony_ci } 168f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 169f08c3bdfSopenharmony_ci if (lseek64(rwfd, sparseoff, SEEK_SET) < 0) { 170f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 171f08c3bdfSopenharmony_ci if (lseek(rwfd, sparseoff, SEEK_SET) < 0) { 172f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 173f08c3bdfSopenharmony_ci perror("lseek"); 174f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 175f08c3bdfSopenharmony_ci } 176f08c3bdfSopenharmony_ci /* fill file with junk. */ 177f08c3bdfSopenharmony_ci i = 0; 178f08c3bdfSopenharmony_ci while (i < pagesize && write(rwfd, "a", 1) == 1) 179f08c3bdfSopenharmony_ci i++; 180f08c3bdfSopenharmony_ci if (i != pagesize) { 181f08c3bdfSopenharmony_ci CLEANERROR("couldn't fill first part of file with junk"); 182f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 183f08c3bdfSopenharmony_ci } 184f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 185f08c3bdfSopenharmony_ci if (lseek64(rwfd, holesize, SEEK_CUR) == -1) { 186f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 187f08c3bdfSopenharmony_ci if (lseek(rwfd, holesize, SEEK_CUR) == -1) { 188f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 189f08c3bdfSopenharmony_ci CLEANERROR("couldn't create hole in file"); 190f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 191f08c3bdfSopenharmony_ci } 192f08c3bdfSopenharmony_ci /* create fragment */ 193f08c3bdfSopenharmony_ci i = 0; 194f08c3bdfSopenharmony_ci while (i < (pagesize >> 1) && write(rwfd, "b", 1) == 1) 195f08c3bdfSopenharmony_ci i++; 196f08c3bdfSopenharmony_ci if (i != (pagesize >> 1)) { 197f08c3bdfSopenharmony_ci CLEANERROR("couldn't fill second part of file with junk"); 198f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 199f08c3bdfSopenharmony_ci } 200f08c3bdfSopenharmony_ci /* At this point fd contains 1 page of a's, holesize bytes skipped, 201f08c3bdfSopenharmony_ci * 1/2 page of b's. 202f08c3bdfSopenharmony_ci */ 203f08c3bdfSopenharmony_ci 204f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 205f08c3bdfSopenharmony_ci if ((mapaddr = mmap64((caddr_t) 0, pagesize * 2 + holesize, PROT_READ, 206f08c3bdfSopenharmony_ci MAP_SHARED | MAP_FILE, rofd, 207f08c3bdfSopenharmony_ci sparseoff)) == (caddr_t) - 1) { 208f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 209f08c3bdfSopenharmony_ci if ((mapaddr = mmap((caddr_t) 0, pagesize * 2 + holesize, PROT_READ, 210f08c3bdfSopenharmony_ci MAP_SHARED | MAP_FILE, rofd, 211f08c3bdfSopenharmony_ci sparseoff)) == (caddr_t) - 1) { 212f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 213f08c3bdfSopenharmony_ci CLEANERROR("mmap tmp file failed"); 214f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 215f08c3bdfSopenharmony_ci } 216f08c3bdfSopenharmony_ci /* fill out remainder of page + one more page to extend mmapped flag */ 217f08c3bdfSopenharmony_ci while (i < 2 * pagesize && write(rwfd, "c", 1) == 1) 218f08c3bdfSopenharmony_ci i++; 219f08c3bdfSopenharmony_ci if (i != 2 * pagesize) { 220f08c3bdfSopenharmony_ci CLEANERROR("couldn't fill second part of file with junk"); 221f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 222f08c3bdfSopenharmony_ci } 223f08c3bdfSopenharmony_ci /* fiddle with mmapped hole */ 224f08c3bdfSopenharmony_ci if (*(mapaddr + pagesize + (holesize >> 1)) != 0) { 225f08c3bdfSopenharmony_ci CLEANERROR("hole not filled with 0's"); 226f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 227f08c3bdfSopenharmony_ci } 228f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 229f08c3bdfSopenharmony_ci if (lseek64(rwfd, sparseoff + e_pageskip * pagesize, SEEK_SET) == -1) { 230f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 231f08c3bdfSopenharmony_ci if (lseek(rwfd, sparseoff + e_pageskip * pagesize, SEEK_SET) == -1) { 232f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 233f08c3bdfSopenharmony_ci CLEANERROR("couldn't lseek back to put e's in hole"); 234f08c3bdfSopenharmony_ci anyfail(); /*LTP Port */ 235f08c3bdfSopenharmony_ci } 236f08c3bdfSopenharmony_ci i = 0; 237f08c3bdfSopenharmony_ci while (i < pagesize && write(rwfd, "e", 1) == 1) 238f08c3bdfSopenharmony_ci i++; 239f08c3bdfSopenharmony_ci if (i != pagesize) { 240f08c3bdfSopenharmony_ci CLEANERROR("couldn't part of hole with e's"); 241f08c3bdfSopenharmony_ci anyfail(); /*LTP Port */ 242f08c3bdfSopenharmony_ci } 243f08c3bdfSopenharmony_ci if (fsync(rwfd) == -1) { 244f08c3bdfSopenharmony_ci CLEANERROR("fsync failed"); 245f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 246f08c3bdfSopenharmony_ci } 247f08c3bdfSopenharmony_ci#ifdef LARGE_FILE 248f08c3bdfSopenharmony_ci if (lseek64(rofd, sparseoff, SEEK_SET) == -1) { 249f08c3bdfSopenharmony_ci#else /* LARGE_FILE */ 250f08c3bdfSopenharmony_ci if (lseek(rofd, sparseoff, SEEK_SET) == -1) { 251f08c3bdfSopenharmony_ci#endif /* LARGE_FILE */ 252f08c3bdfSopenharmony_ci CLEANERROR("couldn't lseek to begining to verify contents"); 253f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 254f08c3bdfSopenharmony_ci } 255f08c3bdfSopenharmony_ci if (munmap(mapaddr, holesize + 2 * pagesize) == -1) { 256f08c3bdfSopenharmony_ci CLEANERROR("munmap of tmp file failed"); 257f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 258f08c3bdfSopenharmony_ci } 259f08c3bdfSopenharmony_ci /* check file's contents */ 260f08c3bdfSopenharmony_ci if (checkchars(rofd, 'a', pagesize)) { 261f08c3bdfSopenharmony_ci CLEANERROR("first page not filled with a's"); 262f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 263f08c3bdfSopenharmony_ci } 264f08c3bdfSopenharmony_ci if (checkchars(rofd, '\0', (e_pageskip - 1) * pagesize)) { 265f08c3bdfSopenharmony_ci CLEANERROR("e_skip not filled with 0's"); 266f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 267f08c3bdfSopenharmony_ci } 268f08c3bdfSopenharmony_ci if (checkchars(rofd, 'e', pagesize)) { 269f08c3bdfSopenharmony_ci CLEANERROR("part after first 0's not filled with e's"); 270f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 271f08c3bdfSopenharmony_ci } 272f08c3bdfSopenharmony_ci if (checkchars(rofd, '\0', holesize - e_pageskip * pagesize)) { 273f08c3bdfSopenharmony_ci CLEANERROR("second hole section not filled with 0's"); 274f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 275f08c3bdfSopenharmony_ci } 276f08c3bdfSopenharmony_ci if (checkchars(rofd, 'b', (pagesize >> 1))) { 277f08c3bdfSopenharmony_ci CLEANERROR("next to last half page not filled with b's"); 278f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 279f08c3bdfSopenharmony_ci } 280f08c3bdfSopenharmony_ci if (checkchars(rofd, 'c', pagesize + (pagesize >> 1))) { 281f08c3bdfSopenharmony_ci CLEANERROR("extended fragment not filled with c's"); 282f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 283f08c3bdfSopenharmony_ci } 284f08c3bdfSopenharmony_ci if (close(rofd) == -1) { 285f08c3bdfSopenharmony_ci CLEANERROR("second close of rofd failed"); 286f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 287f08c3bdfSopenharmony_ci } 288f08c3bdfSopenharmony_ci if (unlink(tmpname) == -1) { 289f08c3bdfSopenharmony_ci CLEANERROR("unlink failed"); 290f08c3bdfSopenharmony_ci anyfail(); /* LTP Port */ 291f08c3bdfSopenharmony_ci } 292f08c3bdfSopenharmony_ci (void)time(&t); 293f08c3bdfSopenharmony_ci// (void)printf("%s: Finished %s", argv[0], ctime(&t)); 294f08c3bdfSopenharmony_ci ok_exit(); 295f08c3bdfSopenharmony_ci tst_exit(); 296f08c3bdfSopenharmony_ci} 297f08c3bdfSopenharmony_ci 298f08c3bdfSopenharmony_ci/* checkchars 299f08c3bdfSopenharmony_ci * verrify that the next n characters of file fd are of value val. 300f08c3bdfSopenharmony_ci * 0 = success; -1 = failure 301f08c3bdfSopenharmony_ci */ 302f08c3bdfSopenharmony_cistatic int checkchars(int fd, char val, int n) 303f08c3bdfSopenharmony_ci{ 304f08c3bdfSopenharmony_ci int i; 305f08c3bdfSopenharmony_ci char buf; 306f08c3bdfSopenharmony_ci 307f08c3bdfSopenharmony_ci for (i = 0; i < n && read(fd, &buf, 1) == 1; i++) 308f08c3bdfSopenharmony_ci if (buf != val) 309f08c3bdfSopenharmony_ci return -1; 310f08c3bdfSopenharmony_ci return 0; 311f08c3bdfSopenharmony_ci} 312f08c3bdfSopenharmony_ci 313f08c3bdfSopenharmony_ci/***** ** LTP Port ** *****/ 314f08c3bdfSopenharmony_ciint anyfail(void) 315f08c3bdfSopenharmony_ci{ 316f08c3bdfSopenharmony_ci tst_brkm(TFAIL, tst_rmdir, "Test failed"); 317f08c3bdfSopenharmony_ci} 318f08c3bdfSopenharmony_ci 319f08c3bdfSopenharmony_civoid ok_exit(void) 320f08c3bdfSopenharmony_ci{ 321f08c3bdfSopenharmony_ci tst_resm(TPASS, "Test passed"); 322f08c3bdfSopenharmony_ci tst_rmdir(); 323f08c3bdfSopenharmony_ci tst_exit(); 324f08c3bdfSopenharmony_ci} 325f08c3bdfSopenharmony_ci 326f08c3bdfSopenharmony_ci/***** ** ****** ** *****/ 327