2 Copyright (C) by Ronnie Sahlberg <sahlberg@samba.org> 2008
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>.
27 #define discard_const(ptr) ((void *)((intptr_t)(ptr)))
31 static char rw_buf[65536];
39 static void nfs3_deltree(struct dbench_op *op);
41 static void nfs3_cleanup(struct child_struct *child)
47 asprintf(&dname, "/clients/client%d", child->id);
54 static void nfs3_setup(struct child_struct *child)
56 const char *status = "0x00000000";
59 child->rate.last_time = timeval_current();
60 child->rate.last_bytes = 0;
63 srandom(getpid() ^ time(NULL));
64 child->private = nfsio_connect(options.server, options.export, options.protocol);
66 if (child->private == NULL) {
68 printf("nfsio_connect() failed\n");
72 /* create '/clients' */
73 res = nfsio_lookup(child->private, "/clients", NULL);
74 if (res == NFS3ERR_NOENT) {
75 res = nfsio_mkdir(child->private, "/clients");
76 if( (res != NFS3_OK) &&
77 (res != NFS3ERR_EXIST) ) {
78 printf("Failed to create '/clients' directory. res:%u\n", res);
85 static void dirent_cb(struct entryplus3 *e, void *private_data)
87 struct cb_data *cbd = private_data;
91 if (!strcmp(cbd->dirname,".")) {
94 if (!strcmp(cbd->dirname,"..")) {
98 asprintf(&objname, "%s/%s", cbd->dirname, e->name);
99 if (objname == NULL) {
100 printf("Failed to talloc ne object name in dirent_cb\n");
104 if (e->name_attributes.post_op_attr_u.attributes.type == NF3DIR) {
105 struct cb_data *new_cbd = malloc(sizeof(struct cb_data));
107 new_cbd->nfsio = cbd->nfsio;
108 new_cbd->dirname = strdup(objname);
110 nfsio_readdirplus(cbd->nfsio, objname, dirent_cb, new_cbd);
112 res = nfsio_rmdir(cbd->nfsio, objname);
113 if (res != NFS3_OK) {
114 printf("Failed to remove object : \"%s\" %s (%d)\n", objname, nfs_error(res), res);
116 free(new_cbd->dirname);
123 free(new_cbd->dirname);
128 res = nfsio_remove(cbd->nfsio, objname);
129 if (res != NFS3_OK) {
130 printf("Failed to remove object : \"%s\" %s %d\n", objname, nfs_error(res), res);
138 static void nfs3_deltree(struct dbench_op *op)
143 cbd = malloc(sizeof(struct cb_data));
145 cbd->nfsio = op->child->private;
146 cbd->dirname = discard_const(op->fname);
148 res = nfsio_lookup(cbd->nfsio, cbd->dirname, NULL);
149 if (res != NFS3ERR_NOENT) {
150 nfsio_readdirplus(cbd->nfsio, cbd->dirname, dirent_cb, cbd);
151 nfsio_rmdir(cbd->nfsio, cbd->dirname);
154 res = nfsio_lookup(cbd->nfsio, cbd->dirname, NULL);
155 if (res != NFS3ERR_NOENT) {
156 printf("Directory \"%s\" not empty. Aborting\n");
163 static int expected_status(const char *status)
165 if (strncmp(status, "0x", 2) == 0) {
166 return strtol(status, NULL, 16);
170 static void failed(struct child_struct *child)
173 printf("ERROR: child %d failed at line %d\n", child->id, child->line);
177 static void nfs3_getattr(struct dbench_op *op)
181 res = nfsio_getattr(op->child->private, op->fname, NULL);
182 if (res != expected_status(op->status)) {
183 printf("[%d] GETATTR \"%s\" failed (%x) - expected %x\n",
184 op->child->line, op->fname, res, expected_status(op->status));
190 static void nfs3_lookup(struct dbench_op *op)
194 res = nfsio_lookup(op->child->private, op->fname, NULL);
195 if (res != expected_status(op->status)) {
196 printf("[%d] LOOKUP \"%s\" failed (%x) - expected %x\n",
197 op->child->line, op->fname, res, expected_status(op->status));
202 static void nfs3_create(struct dbench_op *op)
206 res = nfsio_create(op->child->private, op->fname);
207 if (res != expected_status(op->status)) {
208 printf("[%d] CREATE \"%s\" failed (%x) - expected %x\n",
209 op->child->line, op->fname, res, expected_status(op->status));
214 static void nfs3_write(struct dbench_op *op)
216 int offset = op->params[0];
217 int len = op->params[1];
218 int stable = op->params[2];
221 res = nfsio_write(op->child->private, op->fname, rw_buf, offset, len, stable);
222 if (res != expected_status(op->status)) {
223 printf("[%d] WRITE \"%s\" failed (%x) - expected %x\n",
224 op->child->line, op->fname,
225 res, expected_status(op->status));
228 op->child->bytes += len;
231 static void nfs3_commit(struct dbench_op *op)
235 res = nfsio_commit(op->child->private, op->fname);
236 if (res != expected_status(op->status)) {
237 printf("[%d] COMMIT \"%s\" failed (%x) - expected %x\n",
238 op->child->line, op->fname, res, expected_status(op->status));
244 static void nfs3_read(struct dbench_op *op)
246 int offset = op->params[0];
247 int len = op->params[1];
250 res = nfsio_read(op->child->private, op->fname, rw_buf, offset, len, NULL, NULL);
251 if (res != expected_status(op->status)) {
252 printf("[%d] READ \"%s\" failed (%x) - expected %x\n",
253 op->child->line, op->fname,
254 res, expected_status(op->status));
257 op->child->bytes += len;
260 static void nfs3_access(struct dbench_op *op)
264 res = nfsio_access(op->child->private, op->fname, 0, NULL);
265 if (res != expected_status(op->status)) {
266 printf("[%d] ACCESS \"%s\" failed (%x) - expected %x\n",
267 op->child->line, op->fname, res, expected_status(op->status));
272 static void nfs3_mkdir(struct dbench_op *op)
276 res = nfsio_mkdir(op->child->private, op->fname);
277 if (res != expected_status(op->status)) {
278 printf("[%d] MKDIR \"%s\" failed (%x) - expected %x\n",
279 op->child->line, op->fname, res, expected_status(op->status));
284 static void nfs3_rmdir(struct dbench_op *op)
288 res = nfsio_rmdir(op->child->private, op->fname);
289 if (res != expected_status(op->status)) {
290 printf("[%d] RMDIR \"%s\" failed (%x) - expected %x\n",
291 op->child->line, op->fname, res, expected_status(op->status));
296 static void nfs3_fsstat(struct dbench_op *op)
300 res = nfsio_fsstat(op->child->private);
301 if (res != expected_status(op->status)) {
302 printf("[%d] FSSTAT failed (%x) - expected %x\n",
303 op->child->line, res, expected_status(op->status));
308 static void nfs3_fsinfo(struct dbench_op *op)
312 res = nfsio_fsinfo(op->child->private);
313 if (res != expected_status(op->status)) {
314 printf("[%d] FSINFO failed (%x) - expected %x\n",
315 op->child->line, res, expected_status(op->status));
320 static void nfs3_symlink(struct dbench_op *op)
324 res = nfsio_symlink(op->child->private, op->fname, op->fname2);
325 if (res != expected_status(op->status)) {
326 printf("[%d] SYMLINK \"%s\"->\"%s\" failed (%x) - expected %x\n",
327 op->child->line, op->fname, op->fname2,
328 res, expected_status(op->status));
333 static void nfs3_remove(struct dbench_op *op)
337 res = nfsio_remove(op->child->private, op->fname);
338 if (res != expected_status(op->status)) {
339 printf("[%d] REMOVE \"%s\" failed (%x) - expected %x\n",
340 op->child->line, op->fname, res, expected_status(op->status));
345 static void nfs3_readdirplus(struct dbench_op *op)
349 res = nfsio_readdirplus(op->child->private, op->fname, NULL, NULL);
350 if (res != expected_status(op->status)) {
351 printf("[%d] READDIRPLUS \"%s\" failed (%x) - expected %x\n",
352 op->child->line, op->fname, res, expected_status(op->status));
357 static void nfs3_link(struct dbench_op *op)
361 res = nfsio_link(op->child->private, op->fname, op->fname2);
362 if (res != expected_status(op->status)) {
363 printf("[%d] LINK \"%s\"->\"%s\" failed (%x) - expected %x\n",
364 op->child->line, op->fname, op->fname2,
365 res, expected_status(op->status));
370 static void nfs3_rename(struct dbench_op *op)
374 res = nfsio_rename(op->child->private, op->fname, op->fname2);
375 if (res != expected_status(op->status)) {
376 printf("[%d] RENAME \"%s\"->\"%s\" failed (%x) - expected %x\n",
377 op->child->line, op->fname, op->fname2,
378 res, expected_status(op->status));
383 static struct backend_op ops[] = {
384 { "Deltree", nfs3_deltree },
385 { "GETATTR3", nfs3_getattr },
386 { "LOOKUP3", nfs3_lookup },
387 { "CREATE3", nfs3_create },
388 { "WRITE3", nfs3_write },
389 { "COMMIT3", nfs3_commit },
390 { "READ3", nfs3_read },
391 { "ACCESS3", nfs3_access },
392 { "MKDIR3", nfs3_mkdir },
393 { "RMDIR3", nfs3_rmdir },
394 { "FSSTAT3", nfs3_fsstat },
395 { "FSINFO3", nfs3_fsinfo },
396 { "SYMLINK3", nfs3_symlink },
397 { "REMOVE3", nfs3_remove },
398 { "READDIRPLUS3", nfs3_readdirplus },
399 { "RENAME3", nfs3_rename },
400 { "LINK3", nfs3_link },
404 struct nb_operations nfs_ops = {
405 .backend_name = "nfsbench",
407 .cleanup = nfs3_cleanup,