Home | History | Annotate | Download | only in ltp-aiodio
      1 /*
      2  * Copyright (c) 2011 Cyril Hrubis <chrubis (at) suse.cz>
      3  *
      4  *   This program is free software;  you can redistribute it and/or modify
      5  *   it under the terms of the GNU General Public License as published by
      6  *   the Free Software Foundation; either version 2 of the License, or
      7  *   (at your option) any later version.
      8  *
      9  *   This program is distributed in the hope that it will be useful,
     10  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
     11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
     12  *   the GNU General Public License for more details.
     13  *
     14  *   You should have received a copy of the GNU General Public License
     15  *   along with this program;  if not, write to the Free Software
     16  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     17  */
     18 
     19 #ifndef LTP_AIODIO_COMMON_SPARSE
     20 #define LTP_AIODIO_COMMON_SPARSE
     21 
     22 /*
     23  * This code tries to create dirty free blocks on
     24  * the HDD so there is a chance that blocks to be allocated
     25  * for a file are filled with something else than zeroes.
     26  *
     27  * The usefulness of this is IMHO questionable.
     28  */
     29 static void dirty_freeblocks(int size)
     30 {
     31 	int fd;
     32 	void *p;
     33 	int pg;
     34 	char *filename = "dirty_freeblocks";
     35 
     36 	pg = getpagesize();
     37 	size = ((size + pg - 1) / pg) * pg;
     38 
     39 	fd = open(filename, O_CREAT|O_RDWR|O_EXCL, 0600);
     40 
     41 	if (fd < 0)
     42 		tst_brkm(TBROK|TERRNO, cleanup, "failed to open '%s'", filename);
     43 
     44 	SAFE_FTRUNCATE(cleanup, fd, size);
     45 
     46 	p = SAFE_MMAP(cleanup, NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED|MAP_FILE, fd, 0);
     47 
     48 	memset(p, 0xaa, size);
     49 	msync(p, size, MS_SYNC);
     50 	munmap(p, size);
     51 	close(fd);
     52 	unlink(filename);
     53 }
     54 
     55 /*
     56  * Scale value by kilo, mega, or giga.
     57  */
     58 long long scale_by_kmg(long long value, char scale)
     59 {
     60 	switch (scale) {
     61 	case 'g':
     62 	case 'G':
     63 		value *= 1024;
     64 	case 'm':
     65 	case 'M':
     66 		value *= 1024;
     67 	case 'k':
     68 	case 'K':
     69 		value *= 1024;
     70 		break;
     71 	case '\0':
     72 		break;
     73 	default:
     74 		usage();
     75 		break;
     76 	}
     77 	return value;
     78 }
     79 
     80 char *check_zero(char *buf, int size)
     81 {
     82 	char *p;
     83 
     84 	p = buf;
     85 
     86 	while (size > 0) {
     87 		if (*buf != 0) {
     88 			fprintf(stderr, "non zero buffer at buf[%d] => 0x%02x,%02x,%02x,%02x\n",
     89 				buf - p, (unsigned int)buf[0],
     90 				size > 1 ? (unsigned int)buf[1] : 0,
     91 				size > 2 ? (unsigned int)buf[2] : 0,
     92 				size > 3 ? (unsigned int)buf[3] : 0);
     93 			return buf;
     94 		}
     95 		buf++;
     96 		size--;
     97 	}
     98 
     99 	return NULL;
    100 }
    101 
    102 /*
    103  * Make sure we read only zeroes,
    104  * either there is a hole in the file,
    105  * or zeroes were actually written by parent.
    106  */
    107 static void read_sparse(char *filename, int filesize)
    108 {
    109 	int fd;
    110 	int  i, j, r;
    111 	char buf[4096];
    112 
    113 	/*
    114 	 * Wait for the file to appear.
    115 	 */
    116 	for (i = 0; i < 10000; i++) {
    117 		fd = open(filename, O_RDONLY);
    118 
    119 		if (fd != -1)
    120 			break;
    121 
    122 		if (debug)
    123 			fprintf(stderr, "Child %i waits for '%s' to appear\n",
    124 			        getpid(), filename);
    125 
    126 		usleep(100000);
    127 	}
    128 
    129 	if (fd == -1) {
    130 		if (debug)
    131 			fprintf(stderr, "Child %i failed to open '%s'\n",
    132 			        getpid(), filename);
    133 		exit(10);
    134 	}
    135 
    136 	if (debug)
    137 		fprintf(stderr, "Child %i has opened '%s' for reading\n",
    138 		        getpid(), filename);
    139 
    140 	for (i = 0; i < 100000000; i++) {
    141 		off_t offset = 0;
    142 		char *badbuf;
    143 
    144 		if (debug)
    145 			fprintf(stderr, "Child %i loop %i\n", getpid(), i);
    146 
    147 		lseek(fd, SEEK_SET, 0);
    148 		for (j = 0; j < filesize+1; j += sizeof(buf)) {
    149 			r = read(fd, buf, sizeof(buf));
    150 			if (r > 0) {
    151 				if ((badbuf = check_zero(buf, r))) {
    152 					fprintf(stderr, "non-zero read at offset %d\n",
    153 						offset + badbuf - buf);
    154 					exit(10);
    155 				}
    156 			}
    157 			offset += r;
    158 		}
    159 	}
    160 
    161 	exit(0);
    162 }
    163 
    164 #endif /* LTP_AIODIO_COMMON_SPARSE */
    165