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 #include "common_checkzero.h"
     23 
     24 /*
     25  * This code tries to create dirty free blocks on
     26  * the HDD so there is a chance that blocks to be allocated
     27  * for a file are filled with something else than zeroes.
     28  *
     29  * The usefulness of this is IMHO questionable.
     30  */
     31 static void dirty_freeblocks(int size)
     32 {
     33 	int fd;
     34 	void *p;
     35 	int pg;
     36 	char *filename = "dirty_freeblocks";
     37 
     38 	pg = getpagesize();
     39 	size = ((size + pg - 1) / pg) * pg;
     40 
     41 	fd = open(filename, O_CREAT|O_RDWR|O_EXCL, 0600);
     42 
     43 	if (fd < 0)
     44 		tst_brkm(TBROK|TERRNO, cleanup, "failed to open '%s'", filename);
     45 
     46 	SAFE_FTRUNCATE(cleanup, fd, size);
     47 
     48 	p = SAFE_MMAP(cleanup, NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED|MAP_FILE, fd, 0);
     49 
     50 	memset(p, 0xaa, size);
     51 	msync(p, size, MS_SYNC);
     52 	munmap(p, size);
     53 	close(fd);
     54 	unlink(filename);
     55 }
     56 
     57 /*
     58  * Scale value by kilo, mega, or giga.
     59  */
     60 long long scale_by_kmg(long long value, char scale)
     61 {
     62 	switch (scale) {
     63 	case 'g':
     64 	case 'G':
     65 		value *= 1024;
     66 	case 'm':
     67 	case 'M':
     68 		value *= 1024;
     69 	case 'k':
     70 	case 'K':
     71 		value *= 1024;
     72 		break;
     73 	case '\0':
     74 		break;
     75 	default:
     76 		usage();
     77 		break;
     78 	}
     79 	return value;
     80 }
     81 
     82 /*
     83  * Make sure we read only zeroes,
     84  * either there is a hole in the file,
     85  * or zeroes were actually written by parent.
     86  */
     87 static void read_sparse(char *filename, int filesize)
     88 {
     89 	int fd;
     90 	int  i, j, r;
     91 	char buf[4096];
     92 
     93 	fd = open(filename, O_RDONLY);
     94 	if (fd == -1) {
     95 		if (debug)
     96 			fprintf(stderr, "Child %i failed to open '%s'\n",
     97 			        getpid(), filename);
     98 		exit(10);
     99 	}
    100 
    101 	if (debug)
    102 		fprintf(stderr, "Child %i has opened '%s' for reading\n",
    103 		        getpid(), filename);
    104 
    105 	for (i = 0; i < 100000000; i++) {
    106 		off_t offset = 0;
    107 		char *badbuf;
    108 
    109 		if (debug)
    110 			fprintf(stderr, "Child %i loop %i\n", getpid(), i);
    111 
    112 		lseek(fd, SEEK_SET, 0);
    113 		for (j = 0; j < filesize+1; j += sizeof(buf)) {
    114 			r = read(fd, buf, sizeof(buf));
    115 			if (r > 0) {
    116 				if ((badbuf = check_zero(buf, r))) {
    117 					fprintf(stderr, "non-zero read at offset %u\n",
    118 						(unsigned int)(offset + badbuf - buf));
    119 					exit(10);
    120 				}
    121 			}
    122 			offset += r;
    123 		}
    124 	}
    125 
    126 	exit(0);
    127 }
    128 
    129 #endif /* LTP_AIODIO_COMMON_SPARSE */
    130