converted all backends to new common format
[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 static void sio_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 static void sio_unlink(struct dbench_op *op)
86 {
87         do_packets(op->child, 39+2+strlen(op->fname)*2+2, 39);
88 }
89
90 static void sio_mkdir(struct dbench_op *op)
91 {
92         do_packets(op->child, 39+2+strlen(op->fname)*2+2, 39);
93 }
94
95 static void sio_rmdir(struct dbench_op *op)
96 {
97         do_packets(op->child, 39+2+strlen(op->fname)*2+2, 39);
98 }
99
100 static void sio_createx(struct dbench_op *op)
101 {
102         do_packets(op->child, 70+2+strlen(op->fname)*2+2, 39+12*4);
103 }
104
105 static void sio_writex(struct dbench_op *op)
106 {
107         int size = op->params[2];
108         do_packets(op->child, 39+20+size, 39+16);
109         op->child->bytes += size;
110 }
111
112 static void sio_readx(struct dbench_op *op)
113 {
114         int ret_size = op->params[3];
115         do_packets(op->child, 39+20, 39+20+ret_size);
116         op->child->bytes += ret_size;
117 }
118
119 static void sio_close(struct dbench_op *op)
120 {
121         do_packets(op->child, 39+8, 39);
122 }
123
124 static void sio_rename(struct dbench_op *op)
125 {
126         const char *old = op->fname;
127         const char *new = op->fname2;
128         do_packets(op->child, 39+8+2*strlen(old)+2*strlen(new), 39);
129 }
130
131 static void sio_flush(struct dbench_op *op)
132 {
133         do_packets(op->child, 39+2, 39);
134 }
135
136 static void sio_qpathinfo(struct dbench_op *op)
137 {
138         do_packets(op->child, 39+16+2*strlen(op->fname), 39+32);
139 }
140
141 static void sio_qfileinfo(struct dbench_op *op)
142 {
143         do_packets(op->child, 39+20, 39+32);
144 }
145
146 static void sio_qfsinfo(struct dbench_op *op)
147 {
148         do_packets(op->child, 39+20, 39+32);
149 }
150
151 static void sio_findfirst(struct dbench_op *op)
152 {
153         int count = op->params[2];
154         do_packets(op->child, 39+20+strlen(op->fname)*2, 39+90*count);
155 }
156
157 static void sio_cleanup(struct child_struct *child)
158 {
159         (void)child;
160 }
161
162 static void sio_deltree(struct dbench_op *op)
163 {
164         (void)op;
165 }
166
167 static void sio_sfileinfo(struct dbench_op *op)
168 {
169         do_packets(op->child, 39+32, 39+8);
170 }
171
172 static void sio_lockx(struct dbench_op *op)
173 {
174         do_packets(op->child, 39+12, 39);
175 }
176
177 static void sio_unlockx(struct dbench_op *op)
178 {
179         do_packets(op->child, 39+12, 39);
180 }
181
182 static struct backend_op ops[] = {
183         { "Deltree", sio_deltree },
184         { "Flush", sio_flush },
185         { "Close", sio_close },
186         { "LockX", sio_lockx },
187         { "Rmdir", sio_rmdir },
188         { "Mkdir", sio_mkdir },
189         { "Rename", sio_rename },
190         { "ReadX", sio_readx },
191         { "WriteX", sio_writex },
192         { "Unlink", sio_unlink },
193         { "UnlockX", sio_unlockx },
194         { "FIND_FIRST", sio_findfirst },
195         { "SET_FILE_INFORMATION", sio_sfileinfo },
196         { "QUERY_FILE_INFORMATION", sio_qfileinfo },
197         { "QUERY_PATH_INFORMATION", sio_qpathinfo },
198         { "QUERY_FS_INFORMATION", sio_qfsinfo },
199         { "NTCreateX", sio_createx },
200         { NULL, NULL}
201 };
202
203 struct nb_operations nb_ops = {
204         .backend_name = "tbench",
205         .setup        = sio_setup,
206         .cleanup      = sio_cleanup,
207         .ops          = ops
208 };