Whamcloud - gitweb
LU-1798 tests: add set_and_check to test-framework
[fs/lustre-release.git] / lustre / tests / sendfile.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.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  */
34
35 #include <stdio.h>
36 #include <unistd.h>
37 #include <fcntl.h>
38 #include <stdlib.h>
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <sys/sendfile.h>
42 #include <sys/stat.h>
43 #include <sys/socket.h>
44
45 #include <liblustre.h>
46 #include <lnet/lnetctl.h>
47 #include <obd.h>
48 #include <lustre_lib.h>
49 #include <obd_lov.h>
50 #include <lustre/liblustreapi.h>
51
52 #define syserr(str) { perror(str); exit(-1); }
53
54 int main(int argc, char *argv[])
55 {
56         char *sfile, *tfile;
57         struct stat stbuf;
58         int size;
59         unsigned long bufsize = 1024 * 1024;
60         int infd, outfd;
61         int sd[2];
62         int rc;
63         char *buf;
64         char cmd[1024];
65         loff_t pos;
66
67         if (argc < 3) {
68                 fprintf(stderr, "%s <source file> <dest file>\n", argv[0]);
69                 exit(-1);
70         }
71
72         sfile = argv[1];
73         tfile = argv[2];
74
75         if (stat(sfile, &stbuf) < 0) {
76                 if (errno == ENOENT) {
77                         /* assume doing non-object file testing */
78                         infd = open(sfile, O_LOV_DELAY_CREATE|O_CREAT|O_RDWR,
79                                     0644);
80                         if (infd < 0)
81                                 syserr("open source file:");
82
83                         size = random() % (1 * 1024 * 1024) + 1024;
84                         if (ftruncate(infd, (off_t)size) < 0)
85                                 syserr("truncate file error:");
86                 } else {
87                         syserr("stat file: ");
88                 }
89         } else if (S_ISREG(stbuf.st_mode)) {
90                 size = (int)stbuf.st_size;
91                 infd = open(sfile, O_RDONLY, 0644);
92                 if (infd < 0)
93                         syserr("Open an existing file error:");
94         } else {
95                 fprintf(stderr, "%s is not a regular file\n", sfile);
96                 exit(-1);
97         }
98
99         outfd = open(tfile, O_WRONLY|O_TRUNC|O_CREAT, 0666);
100         if (outfd < 0)
101                 syserr("open dest file:");
102
103         rc = socketpair(AF_LOCAL, SOCK_STREAM, 0, sd);
104         if (rc < 0)
105                 syserr("socketpair");
106
107         rc = fcntl(sd[0], F_SETFL, O_NONBLOCK);
108         if (rc < 0)
109                 syserr("fcntl");
110
111         rc = setsockopt(sd[0], SOL_SOCKET, SO_SNDBUF,
112                         &bufsize, sizeof(bufsize));
113         if (rc)
114                 syserr("setsockopt");
115
116         srandom(time(NULL));
117
118         pos = 0;
119         while (size > 0) {
120                 int rc2;
121                 size_t seg_size;
122
123                 seg_size = random() % bufsize + 1;
124                 if (seg_size > size)
125                         seg_size = size;
126
127                 while (seg_size) {
128                         rc = sendfile(sd[0], infd, &pos, seg_size);
129                         if (rc < 0)
130                                 syserr("sendfile:");
131
132                         seg_size -= rc;
133                         size -= rc;
134                         if (size == 0)
135                                 close(sd[0]);
136
137                         buf = malloc(rc);
138                         if (read(sd[1], buf, rc) < 0)
139                                 syserr("read from socket:");
140
141                         rc2 = write(outfd, buf, rc);
142                         if (rc2 != rc)
143                                 syserr("write dest file error:");
144                         free(buf);
145                 }
146         }
147         close(sd[1]), close(infd), close(outfd);
148
149         sprintf(cmd, "cmp %s %s\n", sfile, tfile);
150         return system(cmd);
151 }