Whamcloud - gitweb
LU-10657 utils: fd leak in mirror_split()
[fs/lustre-release.git] / lustre / tests / small_write.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  */
26 /*
27  * This file is part of Lustre, http://www.lustre.org/
28  * Lustre is a trademark of Sun Microsystems, Inc.
29  */
30
31 #include <stdio.h>
32 #include <sys/stat.h>
33 #include <sys/types.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include <errno.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 #define GOTO(label, rc)   do { rc; goto label; } while (0)
41
42 int main (int argc, char **argv) {
43         int fd, i, rc = 0;
44         unsigned long bytes, lbytes;
45         struct stat st;
46         char *str, *str2, *readbuf;
47
48         if (argc != 3) {
49                 fprintf(stderr, "usage: %s <filename> <bytes>\n", argv[0]);
50                 GOTO(out, rc = 1);
51         }
52
53         bytes = strtoul(argv[2], NULL, 10);
54         if (!bytes) {
55                 printf("No bytes!\n");
56                 GOTO(out, rc = 2);
57         }
58         if (bytes % 2) {
59                 printf("Need an even number of bytes!\n");
60                 GOTO(out, rc = 3);
61         }
62         lbytes = 3*bytes/2;
63
64         str = malloc(bytes+1);
65         if (!str) {
66                 printf("No enough memory for %lu bytes.\n", bytes);
67                 GOTO(out, rc = 4);
68         }
69         str2 = malloc(lbytes+1);
70         if (!str2) {
71                 printf("No enough memory for %lu bytes.\n", lbytes);
72                 GOTO(out_str, rc = 5);
73         }
74         readbuf = malloc(bytes*2);
75         if (!readbuf) {
76                 printf("No enough memory for %lu bytes.\n", bytes*2);
77                 GOTO(out_str2, rc = 6);
78         }
79
80         for(i=0; i < bytes; i++)
81                 str[i] = 'a' + (i % 26);
82         str[i] = '\0';
83
84         memcpy(str2, str, bytes);
85         memcpy(str2+(bytes/2), str, bytes);
86         str2[lbytes] = '\0';
87
88         if (bytes < 320)
89                 printf("First  String: %s\nSecond String: %s\n", str, str2);
90
91         fd = open(argv[1], O_CREAT|O_RDWR|O_TRUNC, 0700);
92         if (fd == -1) {
93                 printf("Could not open file %s.\n", argv[1]);
94                 GOTO(out_readbuf, rc = 7);
95         }
96
97         rc = write(fd, str, bytes);
98         if (rc != bytes) {
99                 printf("Write failed!\n");
100                 GOTO(out_fd, rc = 8);
101         }
102
103         sleep(1);
104         rc = fstat(fd, &st);
105         if (rc < 0 || st.st_size != bytes) {
106                 printf("bad file %lu size first write %lu != %lu: rc %d\n",
107                        (unsigned long)st.st_ino, (unsigned long)st.st_size,
108                        bytes, rc);
109                 GOTO(out_fd, rc = 9);
110         }
111
112         rc = lseek(fd, bytes / 2, SEEK_SET);
113         if (rc != bytes / 2) {
114                 printf("Seek failed!\n");
115                 GOTO(out_fd, rc = 10);
116         }
117
118         rc = write(fd, str, bytes);
119         if (rc != bytes) {
120                 printf("Write failed!\n");
121                 GOTO(out_fd, rc = 11);
122         }
123
124         rc = fstat(fd, &st);
125         if (rc < 0 || st.st_size != bytes + bytes / 2) {
126                 printf("bad file %lu size second write %lu != %lu: rc %d\n",
127                        (unsigned long)st.st_ino, (unsigned long)st.st_size,
128                        bytes, rc);
129                 GOTO(out_fd, rc = 12);
130         }
131
132         rc = lseek(fd, 0, SEEK_SET);
133         if (rc != 0) {
134                 printf("Seek failed!\n");
135                 GOTO(out_fd, rc = 13);
136         }
137
138         rc = read(fd, readbuf, bytes * 2);
139         if (rc != lbytes) {
140                 printf("Read %d bytes instead of %lu.\n", rc, lbytes);
141                 if (rc == -1)
142                         perror("");
143                 else
144                         printf("%s\n%s\n", readbuf, str2);
145                 rc = fstat(fd, &st);
146                 if (rc < 0 || st.st_size != bytes + bytes / 2) {
147                         printf("bad file size after read %lu != %lu: rc %d\n",
148                                (unsigned long)st.st_size, bytes + bytes / 2,
149                                rc);
150                         GOTO(out_fd, rc = 14);
151                 }
152
153                 GOTO(out_fd, rc = 15);
154         }
155         rc = 0;
156
157         if (bytes < 320)
158                 printf("%s\n%s\n", readbuf, str2);
159         if (strcmp(readbuf, str2)) {
160                 printf("No match!\n");
161                 GOTO(out_fd, rc = 16);
162         }
163
164         printf("Pass!\n");
165 out_fd:
166         close(fd);
167 out_readbuf:
168         free(readbuf);
169 out_str2:
170         free(str2);
171 out_str:
172         free(str);
173 out:
174         return rc;
175 }