[dbench @ tridge@samba.org-20070717123945-34sbk2w6rhc3wdm9]
[tridge/dbench.git] / sockio.c
1 /* 
2    dbench version 2
3    Copyright (C) Andrew Tridgell 1999
4    
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 3 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 the
13    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, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "dbench.h"
20
21 #define MAX_FILES 1000
22
23 struct sockio {
24         char buf[70000];
25         int sock;
26 };
27
28 /* emulate a single SMB packet exchange */
29 static void do_packets(struct child_struct *child, int send_size, int recv_size)
30 {
31         struct sockio *sockio = (struct sockio *)child->private;
32         uint32 *ubuf = (uint32 *)sockio->buf;
33
34         ubuf[0] = htonl(send_size-4);
35         ubuf[1] = htonl(recv_size-4);
36
37         if (write_sock(sockio->sock, sockio->buf, send_size) != send_size) {
38                 printf("error writing %d bytes\n", (int)send_size);
39                 exit(1);
40         }
41
42         if (read_sock(sockio->sock, sockio->buf, 4) != 4) {
43                 printf("error reading header\n");
44                 exit(1);
45         }
46
47         if (ntohl(ubuf[0]) != (unsigned)(recv_size-4)) {
48                 printf("lost sync (%d %d)\n", 
49                        (int)recv_size-4, (int)ntohl(ubuf[0]));
50                 exit(1);
51         }
52
53         if (recv(sockio->sock, sockio->buf, recv_size-4, MSG_WAITALL|MSG_TRUNC) != 
54             recv_size-4) {
55                 printf("error reading %d bytes\n", (int)recv_size-4);
56                 exit(1);
57         }
58
59         if (ntohl(ubuf[0]) != (unsigned)(recv_size-4)) {
60                 printf("lost sync (%d %d)\n", 
61                        (int)recv_size-4, (int)ntohl(ubuf[0]));
62         }
63 }
64
65
66 void nb_setup(struct child_struct *child)
67 {
68         struct sockio *sockio;
69         sockio = calloc(1, sizeof(struct sockio));
70         child->private = sockio;
71         child->rate.last_time = timeval_current();
72         child->rate.last_bytes = 0;
73         
74         sockio->sock = open_socket_out(options.server, TCP_PORT);
75         if (sockio->sock == -1) {
76                 printf("client %d failed to start\n", child->id);
77                 exit(1);
78         }
79         set_socket_options(sockio->sock, options.tcp_options);
80
81         do_packets(child, 8, 8);
82 }
83
84
85 void nb_unlink(struct child_struct *child, const char *fname, int attr, const char *status)
86 {
87         (void)child;
88         (void)attr;
89         (void)status;
90         do_packets(child, 39+2+strlen(fname)*2+2, 39);
91 }
92
93 void nb_mkdir(struct child_struct *child, const char *dname, const char *status)
94 {
95         (void)child;
96         (void)status;
97         do_packets(child, 39+2+strlen(dname)*2+2, 39);
98 }
99
100 void nb_rmdir(struct child_struct *child, const char *fname, const char *status)
101 {
102         (void)child;
103         (void)status;
104         do_packets(child, 39+2+strlen(fname)*2+2, 39);
105 }
106
107 void nb_createx(struct child_struct *child, const char *fname, 
108                 uint32_t create_options, uint32_t create_disposition, int fnum,
109                 const char *status)
110 {
111         (void)child;
112         (void)create_options;
113         (void)create_disposition;
114         (void)fnum;
115         (void)status;
116         do_packets(child, 70+2+strlen(fname)*2+2, 39+12*4);
117 }
118
119 void nb_writex(struct child_struct *child, int handle, int offset, 
120                int size, int ret_size, const char *status)
121 {
122         (void)child;
123         (void)handle;
124         (void)offset;
125         (void)ret_size;
126         (void)status;
127         do_packets(child, 39+20+size, 39+16);
128         child->bytes += size;
129 }
130
131 void nb_readx(struct child_struct *child, int handle, int offset, 
132               int size, int ret_size, const char *status)
133 {
134         (void)child;
135         (void)handle;
136         (void)offset;
137         (void)size;
138         (void)status;
139         do_packets(child, 39+20, 39+20+ret_size);
140         child->bytes += ret_size;
141 }
142
143 void nb_close(struct child_struct *child, int handle, const char *status)
144 {
145         (void)child;
146         (void)handle;
147         (void)status;
148         do_packets(child, 39+8, 39);
149 }
150
151 void nb_rename(struct child_struct *child, const char *old, const char *new, const char *status)
152 {
153         (void)child;
154         (void)status;
155         do_packets(child, 39+8+2*strlen(old)+2*strlen(new), 39);
156 }
157
158 void nb_flush(struct child_struct *child, int handle, const char *status)
159 {
160         (void)child;
161         (void)handle;
162         (void)status;
163         do_packets(child, 39+2, 39);
164 }
165
166 void nb_qpathinfo(struct child_struct *child, const char *fname, int level, 
167                   const char *status)
168 {
169         (void)child;
170         (void)level;
171         (void)status;
172         do_packets(child, 39+16+2*strlen(fname), 39+32);
173 }
174
175 void nb_qfileinfo(struct child_struct *child, int handle, int level, const char *status)
176 {
177         (void)child;
178         (void)level;
179         (void)handle;
180         (void)status;
181         do_packets(child, 39+20, 39+32);
182 }
183
184 void nb_qfsinfo(struct child_struct *child, int level, const char *status)
185 {
186         (void)child;
187         (void)level;
188         (void)status;
189         do_packets(child, 39+20, 39+32);
190 }
191
192 void nb_findfirst(struct child_struct *child, const char *fname, int level, int maxcnt, 
193                   int count, const char *status)
194 {
195         (void)child;
196         (void)level;
197         (void)maxcnt;
198         (void)status;
199         do_packets(child, 39+20+strlen(fname)*2, 39+90*count);
200 }
201
202 void nb_cleanup(struct child_struct *child)
203 {
204         (void)child;
205 }
206
207 void nb_deltree(struct child_struct *child, const char *dname)
208 {
209         (void)child;
210         (void)dname;
211 }
212
213 void nb_sfileinfo(struct child_struct *child, int handle, int level, const char *status)
214 {
215         (void)child;
216         (void)handle;
217         (void)level;
218         (void)status;
219         do_packets(child, 39+32, 39+8);
220 }
221
222 void nb_lockx(struct child_struct *child, int handle, uint32_t offset, int size, 
223               const char *status)
224 {
225         (void)child;
226         (void)handle;
227         (void)offset;
228         (void)size;
229         (void)status;
230         do_packets(child, 39+12, 39);
231 }
232
233 void nb_unlockx(struct child_struct *child,
234                 int handle, uint32_t offset, int size, const char *status)
235 {
236         (void)child;
237         (void)handle;
238         (void)offset;
239         (void)size;
240         (void)status;
241         do_packets(child, 39+12, 39);
242 }
243
244 void nb_sleep(struct child_struct *child, int usec, const char *status)
245 {
246         (void)child;
247         (void)usec;
248         (void)status;
249         usleep(usec);
250 }