dio_append.c revision 4548c6cf9bcdd96d8303caa4130ab638b61f8a30
1 2/* 3 * Copyright (c) 2004 Daniel McNeil <daniel@osdl.org> 4 * 2004 Open Source Development Lab 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 * 19 * Module: .c 20 */ 21 22/* 23 * Change History: 24 * 25 * 2/2004 Marty Ridgeway (mridge@us.ibm.com) Changes to adapt to LTP 26 * 27 */ 28/* 29 * dio_append - append zeroed data to a file using O_DIRECT while 30 * a 2nd process is doing buffered reads and check if the buffer 31 * reads always see zero. 32 */ 33#define _GNU_SOURCE 34 35#include <stdlib.h> 36#include <sys/types.h> 37#include <signal.h> 38#include <fcntl.h> 39#include <stdio.h> 40#include <unistd.h> 41#include <memory.h> 42#include <limits.h> 43#define NUM_CHILDREN 8 44 45char *check_zero(unsigned char *buf, int size) 46{ 47 unsigned char *p; 48 49 p = buf; 50 51 while (size > 0) { 52 if (*buf != 0) { 53 fprintf(stderr, "non zero buffer at buf[%d] => 0x%02x,%02x,%02x,%02x\n", 54 buf - p, (unsigned int)buf[0], 55 size > 1 ? (unsigned int)buf[1] : 0, 56 size > 2 ? (unsigned int)buf[2] : 0, 57 size > 3 ? (unsigned int)buf[3] : 0); 58 fprintf(stderr, "buf %p, p %p\n", buf, p); 59 return buf; 60 } 61 buf++; 62 size--; 63 } 64 return 0; /* all zeros */ 65} 66 67int read_eof(char *filename) 68{ 69 int fd; 70 int i; 71 int r; 72 char buf[4096]; 73 74 while ((fd = open(filename, O_RDONLY)) < 0) { 75 sleep(1); /* wait for file to be created */ 76 } 77 78 for (i = 0 ; i < 1000000; i++) { 79 off_t offset; 80 char *bufoff; 81 82 offset = lseek(fd, SEEK_END, 0); 83 r = read(fd, buf, 4096); 84 if (r > 0) { 85 if ((bufoff = check_zero(buf, r))) { 86 fprintf(stderr, "non-zero read at offset %p\n", 87 offset + bufoff); 88 exit(1); 89 } 90 } 91 } 92 return 0; 93} 94 95void dio_append(char *filename) 96{ 97 int fd; 98 void *bufptr; 99 int i; 100 int w; 101 102 fd = open(filename, O_DIRECT|O_WRONLY|O_CREAT, 0666); 103 104 if (fd < 0) { 105 perror("cannot create file"); 106 return; 107 } 108 109 if (posix_memalign(&bufptr, 4096, 64*1024)) { 110 perror("cannot malloc aligned memory"); 111 return; 112 } 113 114 memset(bufptr, 0, 64*1024); 115 for (i = 0; i < 1000; i++) { 116 if ((w = write(fd, bufptr, 64*1024)) != 64*1024) { 117 fprintf(stderr, "write %d returned %d\n", i, w); 118 } 119 } 120} 121 122int main(int argc, char **argv) 123{ 124 char filename[PATH_MAX]; 125 int pid[NUM_CHILDREN]; 126 int num_children = 1; 127 int i; 128 129 snprintf(filename, sizeof(filename), "%s/aiodio/file", 130 getenv("TMP") ? getenv("TMP") : "/tmp"); 131 132 printf("Begin dio_append test...\n"); 133 134 for (i = 0; i < num_children; i++) { 135 if ((pid[i] = fork()) == 0) { 136 /* child */ 137 return read_eof(filename); 138 } else if (pid[i] < 0) { 139 /* error */ 140 perror("fork error"); 141 break; 142 } else { 143 /* Parent */ 144 continue; 145 } 146 } 147 148 /* 149 * Parent appends to end of file using direct i/o 150 */ 151 152 dio_append(filename); 153 154 for (i = 0; i < num_children; i++) { 155 kill(pid[i], SIGTERM); 156 } 157 return 0; 158} 159