Whamcloud - gitweb
b=20500
[fs/lustre-release.git] / lustre / tests / sendfile.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #include <stdio.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <stdlib.h>
41 #include <sys/types.h>
42 #include <sys/socket.h>
43 #include <sys/sendfile.h>
44 #include <sys/stat.h>
45 #include <sys/socket.h>
46
47 #include <liblustre.h>
48 #include <lnet/lnetctl.h>
49 #include <obd.h>
50 #include <lustre_lib.h>
51 #include <obd_lov.h>
52 #include <lustre/liblustreapi.h>
53
54 #define syserr(str) { perror(str); exit(-1); }
55
56 int main(int argc, char *argv[])
57 {
58         char *sfile, *tfile;
59         struct stat stbuf;
60         int size;
61         unsigned long bufsize = 1024 * 1024;
62         int infd, outfd;
63         int sd[2];
64         int rc;
65         char *buf;
66         char cmd[1024];
67         loff_t pos;
68
69         if (argc < 3) {
70                 fprintf(stderr, "%s <source file> <dest file>\n", argv[0]);
71                 exit(-1);
72         }
73
74         sfile = argv[1];
75         tfile = argv[2];
76
77         if (stat(sfile, &stbuf) < 0) {
78                 if (errno == ENOENT) {
79                         /* assume doing non-object file testing */
80                         infd = open(sfile, O_LOV_DELAY_CREATE|O_CREAT|O_RDWR,
81                                     0644);
82                         if (infd < 0)
83                                 syserr("open source file:");
84
85                         size = random() % (1 * 1024 * 1024) + 1024;
86                         if (ftruncate(infd, (off_t)size) < 0)
87                                 syserr("truncate file error:");
88                 } else {
89                         syserr("stat file: ");
90                 }
91         } else if (S_ISREG(stbuf.st_mode)) {
92                 size = (int)stbuf.st_size;
93                 infd = open(sfile, O_RDONLY, 0644);
94                 if (infd < 0)
95                         syserr("Open an existing file error:");
96         } else {
97                 fprintf(stderr, "%s is not a regular file\n", sfile);
98                 exit(-1);
99         }
100
101         outfd = open(tfile, O_WRONLY|O_TRUNC|O_CREAT, 0666);
102         if (outfd < 0)
103                 syserr("open dest file:");
104
105         rc = socketpair(AF_LOCAL, SOCK_STREAM, 0, sd);
106         if (rc < 0)
107                 syserr("socketpair");
108
109         rc = fcntl(sd[0], F_SETFL, O_NONBLOCK);
110         if (rc < 0)
111                 syserr("fcntl");
112
113         rc = setsockopt(sd[0], SOL_SOCKET, SO_SNDBUF,
114                         &bufsize, sizeof(bufsize));
115         if (rc)
116                 syserr("setsockopt");
117
118         srandom(time(NULL));
119
120         pos = 0;
121         while (size > 0) {
122                 int rc2;
123                 size_t seg_size;
124
125                 seg_size = random() % bufsize + 1;
126                 if (seg_size > size)
127                         seg_size = size;
128
129                 while (seg_size) {
130                         rc = sendfile(sd[0], infd, &pos, seg_size);
131                         if (rc < 0)
132                                 syserr("sendfile:");
133
134                         seg_size -= rc;
135                         size -= rc;
136                         if (size == 0)
137                                 close(sd[0]);
138
139                         buf = malloc(rc);
140                         if (read(sd[1], buf, rc) < 0)
141                                 syserr("read from socket:");
142
143                         rc2 = write(outfd, buf, rc);
144                         if (rc2 != rc)
145                                 syserr("write dest file error:");
146                         free(buf);
147                 }
148         }
149         close(sd[1]), close(infd), close(outfd);
150
151         sprintf(cmd, "cmp %s %s\n", sfile, tfile);
152         return system(cmd);
153 }