1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #include "include/compat.h"
21 #include "common/config.h"
22 #include "SyntheticClient.h"
23 #include "osdc/Objecter.h"
24 #include "osdc/Filer.h"
27 #include "include/filepath.h"
28 #include "common/perf_counters.h"
30 #include <sys/types.h>
35 #include <sys/statvfs.h>
37 #include "common/errno.h"
38 #include "include/ceph_assert.h"
39 #include "include/cephfs/ceph_statx.h"
41 #define dout_context g_ceph_context
42 #define dout_subsys ceph_subsys_client
44 #define dout_prefix *_dout << "client." << (whoami >= 0 ? whoami:client->get_nodeid()) << " "
47 //void trace_include(SyntheticClient *syn, Client *cl, string& prefix);
48 //void trace_openssh(SyntheticClient *syn, Client *cl, string& prefix);
53 list
<string
> syn_sargs
;
54 int syn_filer_flags
= 0;
56 void parse_syn_options(vector
<const char*>& args
)
58 vector
<const char*> nargs
;
60 for (unsigned i
=0; i
<args
.size(); i
++) {
61 if (strcmp(args
[i
],"--num-client") == 0) {
62 num_client
= atoi(args
[++i
]);
65 if (strcmp(args
[i
],"--syn") == 0) {
68 if (strcmp(args
[i
], "mksnap") == 0) {
69 syn_modes
.push_back(SYNCLIENT_MODE_MKSNAP
);
70 syn_sargs
.push_back(args
[++i
]); // path
71 syn_sargs
.push_back(args
[++i
]); // name
73 else if (strcmp(args
[i
], "rmsnap") == 0) {
74 syn_modes
.push_back(SYNCLIENT_MODE_RMSNAP
);
75 syn_sargs
.push_back(args
[++i
]); // path
76 syn_sargs
.push_back(args
[++i
]); // name
77 } else if (strcmp(args
[i
], "mksnapfile") == 0) {
78 syn_modes
.push_back(SYNCLIENT_MODE_MKSNAPFILE
);
79 syn_sargs
.push_back(args
[++i
]); // path
80 } else if (strcmp(args
[i
],"rmfile") == 0) {
81 syn_modes
.push_back( SYNCLIENT_MODE_RMFILE
);
82 } else if (strcmp(args
[i
],"writefile") == 0) {
83 syn_modes
.push_back( SYNCLIENT_MODE_WRITEFILE
);
84 syn_iargs
.push_back( atoi(args
[++i
]) );
85 syn_iargs
.push_back( atoi(args
[++i
]) );
86 } else if (strcmp(args
[i
],"wrshared") == 0) {
87 syn_modes
.push_back( SYNCLIENT_MODE_WRSHARED
);
88 syn_iargs
.push_back( atoi(args
[++i
]) );
89 syn_iargs
.push_back( atoi(args
[++i
]) );
90 } else if (strcmp(args
[i
],"writebatch") == 0) {
91 syn_modes
.push_back( SYNCLIENT_MODE_WRITEBATCH
);
92 syn_iargs
.push_back( atoi(args
[++i
]) );
93 syn_iargs
.push_back( atoi(args
[++i
]) );
94 syn_iargs
.push_back( atoi(args
[++i
]) );
95 } else if (strcmp(args
[i
],"readfile") == 0) {
96 syn_modes
.push_back( SYNCLIENT_MODE_READFILE
);
97 syn_iargs
.push_back( atoi(args
[++i
]) );
98 syn_iargs
.push_back( atoi(args
[++i
]) );
99 } else if (strcmp(args
[i
],"readwriterandom") == 0) {
100 syn_modes
.push_back( SYNCLIENT_MODE_RDWRRANDOM
);
101 syn_iargs
.push_back( atoi(args
[++i
]) );
102 syn_iargs
.push_back( atoi(args
[++i
]) );
103 } else if (strcmp(args
[i
],"readwriterandom_ex") == 0) {
104 syn_modes
.push_back( SYNCLIENT_MODE_RDWRRANDOM_EX
);
105 syn_iargs
.push_back( atoi(args
[++i
]) );
106 syn_iargs
.push_back( atoi(args
[++i
]) );
107 } else if (strcmp(args
[i
],"overloadosd0") == 0) {
108 syn_modes
.push_back( SYNCLIENT_MODE_OVERLOAD_OSD_0
);
109 syn_iargs
.push_back( atoi(args
[++i
]) );
110 syn_iargs
.push_back( atoi(args
[++i
]) );
111 syn_iargs
.push_back( atoi(args
[++i
]) );
112 } else if (strcmp(args
[i
],"readshared") == 0) {
113 syn_modes
.push_back( SYNCLIENT_MODE_READSHARED
);
114 syn_iargs
.push_back( atoi(args
[++i
]) );
115 syn_iargs
.push_back( atoi(args
[++i
]) );
116 } else if (strcmp(args
[i
],"rw") == 0) {
117 int a
= atoi(args
[++i
]);
118 int b
= atoi(args
[++i
]);
119 syn_modes
.push_back( SYNCLIENT_MODE_WRITEFILE
);
120 syn_iargs
.push_back( a
);
121 syn_iargs
.push_back( b
);
122 syn_modes
.push_back( SYNCLIENT_MODE_READFILE
);
123 syn_iargs
.push_back( a
);
124 syn_iargs
.push_back( b
);
125 } else if (strcmp(args
[i
],"dumpplacement") == 0) {
126 syn_modes
.push_back( SYNCLIENT_MODE_DUMP
);
127 syn_sargs
.push_back( args
[++i
] );
128 } else if (strcmp(args
[i
],"dropcache") == 0) {
129 syn_modes
.push_back( SYNCLIENT_MODE_DROPCACHE
);
130 } else if (strcmp(args
[i
],"makedirs") == 0) {
131 syn_modes
.push_back( SYNCLIENT_MODE_MAKEDIRS
);
132 syn_iargs
.push_back( atoi(args
[++i
]) );
133 syn_iargs
.push_back( atoi(args
[++i
]) );
134 syn_iargs
.push_back( atoi(args
[++i
]) );
135 } else if (strcmp(args
[i
],"makedirmess") == 0) {
136 syn_modes
.push_back( SYNCLIENT_MODE_MAKEDIRMESS
);
137 syn_iargs
.push_back( atoi(args
[++i
]) );
138 } else if (strcmp(args
[i
],"statdirs") == 0) {
139 syn_modes
.push_back( SYNCLIENT_MODE_STATDIRS
);
140 syn_iargs
.push_back( atoi(args
[++i
]) );
141 syn_iargs
.push_back( atoi(args
[++i
]) );
142 syn_iargs
.push_back( atoi(args
[++i
]) );
143 } else if (strcmp(args
[i
],"readdirs") == 0) {
144 syn_modes
.push_back( SYNCLIENT_MODE_READDIRS
);
145 syn_iargs
.push_back( atoi(args
[++i
]) );
146 syn_iargs
.push_back( atoi(args
[++i
]) );
147 syn_iargs
.push_back( atoi(args
[++i
]) );
148 } else if (strcmp(args
[i
],"makefiles") == 0) {
149 syn_modes
.push_back( SYNCLIENT_MODE_MAKEFILES
);
150 syn_iargs
.push_back( atoi(args
[++i
]) );
151 syn_iargs
.push_back( atoi(args
[++i
]) );
152 syn_iargs
.push_back( atoi(args
[++i
]) );
153 } else if (strcmp(args
[i
],"makefiles2") == 0) {
154 syn_modes
.push_back( SYNCLIENT_MODE_MAKEFILES2
);
155 syn_iargs
.push_back( atoi(args
[++i
]) );
156 syn_iargs
.push_back( atoi(args
[++i
]) );
157 syn_iargs
.push_back( atoi(args
[++i
]) );
158 } else if (strcmp(args
[i
],"linktest") == 0) {
159 syn_modes
.push_back( SYNCLIENT_MODE_LINKTEST
);
160 } else if (strcmp(args
[i
],"createshared") == 0) {
161 syn_modes
.push_back( SYNCLIENT_MODE_CREATESHARED
);
162 syn_iargs
.push_back( atoi(args
[++i
]) );
163 } else if (strcmp(args
[i
],"openshared") == 0) {
164 syn_modes
.push_back( SYNCLIENT_MODE_OPENSHARED
);
165 syn_iargs
.push_back( atoi(args
[++i
]) );
166 syn_iargs
.push_back( atoi(args
[++i
]) );
167 } else if (strcmp(args
[i
],"createobjects") == 0) {
168 syn_modes
.push_back( SYNCLIENT_MODE_CREATEOBJECTS
);
169 syn_iargs
.push_back( atoi(args
[++i
]) );
170 syn_iargs
.push_back( atoi(args
[++i
]) );
171 syn_iargs
.push_back( atoi(args
[++i
]) );
172 } else if (strcmp(args
[i
],"objectrw") == 0) {
173 syn_modes
.push_back( SYNCLIENT_MODE_OBJECTRW
);
174 syn_iargs
.push_back( atoi(args
[++i
]) );
175 syn_iargs
.push_back( atoi(args
[++i
]) );
176 syn_iargs
.push_back( atoi(args
[++i
]) );
177 syn_iargs
.push_back( atoi(args
[++i
]) );
178 syn_iargs
.push_back( atoi(args
[++i
]) );
179 syn_iargs
.push_back( atoi(args
[++i
]) );
180 } else if (strcmp(args
[i
],"walk") == 0) {
181 syn_modes
.push_back( SYNCLIENT_MODE_FULLWALK
);
182 //syn_sargs.push_back( atoi(args[++i]) );
183 } else if (strcmp(args
[i
],"randomwalk") == 0) {
184 syn_modes
.push_back( SYNCLIENT_MODE_RANDOMWALK
);
185 syn_iargs
.push_back( atoi(args
[++i
]) );
186 } else if (strcmp(args
[i
],"trace") == 0) {
187 syn_modes
.push_back( SYNCLIENT_MODE_TRACE
);
188 syn_sargs
.push_back( args
[++i
] );
189 syn_iargs
.push_back( atoi(args
[++i
]) );
190 syn_iargs
.push_back(1);// data
191 } else if (strcmp(args
[i
],"mtrace") == 0) {
192 syn_modes
.push_back( SYNCLIENT_MODE_TRACE
);
193 syn_sargs
.push_back( args
[++i
] );
194 syn_iargs
.push_back( atoi(args
[++i
]) );
195 syn_iargs
.push_back(0);// no data
196 } else if (strcmp(args
[i
],"thrashlinks") == 0) {
197 syn_modes
.push_back( SYNCLIENT_MODE_THRASHLINKS
);
198 syn_iargs
.push_back( atoi(args
[++i
]) );
199 syn_iargs
.push_back( atoi(args
[++i
]) );
200 syn_iargs
.push_back( atoi(args
[++i
]) );
201 syn_iargs
.push_back( atoi(args
[++i
]) );
202 } else if (strcmp(args
[i
],"foo") == 0) {
203 syn_modes
.push_back( SYNCLIENT_MODE_FOO
);
204 } else if (strcmp(args
[i
],"until") == 0) {
205 syn_modes
.push_back( SYNCLIENT_MODE_UNTIL
);
206 syn_iargs
.push_back( atoi(args
[++i
]) );
207 } else if (strcmp(args
[i
],"sleepuntil") == 0) {
208 syn_modes
.push_back( SYNCLIENT_MODE_SLEEPUNTIL
);
209 syn_iargs
.push_back( atoi(args
[++i
]) );
210 } else if (strcmp(args
[i
],"only") == 0) {
211 syn_modes
.push_back( SYNCLIENT_MODE_ONLY
);
212 syn_iargs
.push_back( atoi(args
[++i
]) );
213 } else if (strcmp(args
[i
],"onlyrange") == 0) {
214 syn_modes
.push_back( SYNCLIENT_MODE_ONLYRANGE
);
215 syn_iargs
.push_back( atoi(args
[++i
]) );
216 syn_iargs
.push_back( atoi(args
[++i
]) );
217 } else if (strcmp(args
[i
],"sleep") == 0) {
218 syn_modes
.push_back( SYNCLIENT_MODE_SLEEP
);
219 syn_iargs
.push_back( atoi(args
[++i
]) );
220 } else if (strcmp(args
[i
],"randomsleep") == 0) {
221 syn_modes
.push_back( SYNCLIENT_MODE_RANDOMSLEEP
);
222 syn_iargs
.push_back( atoi(args
[++i
]) );
223 } else if (strcmp(args
[i
],"opentest") == 0) {
224 syn_modes
.push_back( SYNCLIENT_MODE_OPENTEST
);
225 syn_iargs
.push_back( atoi(args
[++i
]) );
226 } else if (strcmp(args
[i
],"optest") == 0) {
227 syn_modes
.push_back( SYNCLIENT_MODE_OPTEST
);
228 syn_iargs
.push_back( atoi(args
[++i
]) );
229 } else if (strcmp(args
[i
],"truncate") == 0) {
230 syn_modes
.push_back( SYNCLIENT_MODE_TRUNCATE
);
231 syn_sargs
.push_back(args
[++i
]);
232 syn_iargs
.push_back(atoi(args
[++i
]));
233 } else if (strcmp(args
[i
],"importfind") == 0) {
234 syn_modes
.push_back(SYNCLIENT_MODE_IMPORTFIND
);
235 syn_sargs
.push_back(args
[++i
]);
236 syn_sargs
.push_back(args
[++i
]);
237 syn_iargs
.push_back(atoi(args
[++i
]));
238 } else if (strcmp(args
[i
], "lookuphash") == 0) {
239 syn_modes
.push_back(SYNCLIENT_MODE_LOOKUPHASH
);
240 syn_sargs
.push_back(args
[++i
]);
241 syn_sargs
.push_back(args
[++i
]);
242 syn_sargs
.push_back(args
[++i
]);
243 } else if (strcmp(args
[i
], "lookupino") == 0) {
244 syn_modes
.push_back(SYNCLIENT_MODE_LOOKUPINO
);
245 syn_sargs
.push_back(args
[++i
]);
246 } else if (strcmp(args
[i
], "chunkfile") == 0) {
247 syn_modes
.push_back(SYNCLIENT_MODE_CHUNK
);
248 syn_sargs
.push_back(args
[++i
]);
250 cerr
<< "unknown syn arg " << args
[i
] << std::endl
;
254 else if (strcmp(args
[i
], "localize_reads") == 0) {
255 cerr
<< "set CEPH_OSD_FLAG_LOCALIZE_READS" << std::endl
;
256 syn_filer_flags
|= CEPH_OSD_FLAG_LOCALIZE_READS
;
259 nargs
.push_back(args
[i
]);
267 SyntheticClient::SyntheticClient(StandaloneClient
*client
, int w
)
269 this->client
= client
;
278 this->modes
= syn_modes
;
279 this->iargs
= syn_iargs
;
280 this->sargs
= syn_sargs
;
282 run_start
= ceph_clock_now();
290 void *synthetic_client_thread_entry(void *ptr
)
292 SyntheticClient
*sc
= static_cast<SyntheticClient
*>(ptr
);
298 string
SyntheticClient::get_sarg(int seq
)
301 if (!sargs
.empty()) {
305 if (a
.length() == 0 || a
== "~") {
307 snprintf(s
, sizeof(s
), "syn.%lld.%d", (long long)client
->whoami
.v
, seq
);
313 int SyntheticClient::run()
315 UserPerm perms
= client
->pick_my_perms();
316 dout(15) << "initing" << dendl
;
317 int err
= client
->init();
319 dout(0) << "failed to initialize: " << cpp_strerror(err
) << dendl
;
323 dout(15) << "mounting" << dendl
;
324 err
= client
->mount("", perms
);
326 dout(0) << "failed to mount: " << cpp_strerror(err
) << dendl
;
331 //run_start = ceph_clock_now(client->cct);
332 run_until
= utime_t(0,0);
333 dout(5) << "run" << dendl
;
337 for (list
<int>::iterator it
= modes
.begin();
341 dout(3) << "mode " << mode
<< dendl
;
348 case SYNCLIENT_MODE_ONLY
:
350 run_only
= iargs
.front();
352 if (run_only
== client
->get_nodeid())
353 dout(2) << "only " << run_only
<< dendl
;
356 case SYNCLIENT_MODE_ONLYRANGE
:
358 int first
= iargs
.front();
360 int last
= iargs
.front();
362 if (first
<= client
->get_nodeid() &&
363 last
> client
->get_nodeid()) {
364 run_only
= client
->get_nodeid();
365 dout(2) << "onlyrange [" << first
<< ", " << last
<< ") includes me" << dendl
;
367 run_only
= client
->get_nodeid().v
+1; // not me
370 case SYNCLIENT_MODE_EXCLUDE
:
372 exclude
= iargs
.front();
374 if (exclude
== client
->get_nodeid()) {
375 run_only
= client
->get_nodeid().v
+ 1;
376 dout(2) << "not running " << exclude
<< dendl
;
384 case SYNCLIENT_MODE_UNTIL
:
386 int iarg1
= iargs
.front();
390 dout(2) << "until " << iarg1
<< dendl
;
391 utime_t
dur(iarg1
,0);
392 run_until
= run_start
+ dur
;
394 dout(2) << "until " << iarg1
<< " (no limit)" << dendl
;
395 run_until
= utime_t(0,0);
404 case SYNCLIENT_MODE_FOO
:
411 case SYNCLIENT_MODE_RANDOMSLEEP
:
413 int iarg1
= iargs
.front();
416 srand(time(0) + getpid() + client
->whoami
.v
);
417 sleep(rand() % iarg1
);
423 case SYNCLIENT_MODE_SLEEP
:
425 int iarg1
= iargs
.front();
428 dout(2) << "sleep " << iarg1
<< dendl
;
435 case SYNCLIENT_MODE_SLEEPUNTIL
:
437 int iarg1
= iargs
.front();
439 if (iarg1
&& run_me()) {
440 dout(2) << "sleepuntil " << iarg1
<< dendl
;
441 utime_t at
= ceph_clock_now() - run_start
;
442 if (at
.sec() < iarg1
)
443 sleep(iarg1
- at
.sec());
449 case SYNCLIENT_MODE_RANDOMWALK
:
451 int iarg1
= iargs
.front();
454 dout(2) << "randomwalk " << iarg1
<< dendl
;
462 case SYNCLIENT_MODE_DROPCACHE
:
465 client
->drop_caches();
469 case SYNCLIENT_MODE_DUMP
:
471 string sarg1
= get_sarg(0);
473 dout(2) << "placement dump " << sarg1
<< dendl
;
474 dump_placement(sarg1
);
481 case SYNCLIENT_MODE_MAKEDIRMESS
:
483 string sarg1
= get_sarg(0);
484 int iarg1
= iargs
.front(); iargs
.pop_front();
486 dout(2) << "makedirmess " << sarg1
<< " " << iarg1
<< dendl
;
487 make_dir_mess(sarg1
.c_str(), iarg1
);
492 case SYNCLIENT_MODE_MAKEDIRS
:
494 string sarg1
= get_sarg(seq
++);
495 int iarg1
= iargs
.front(); iargs
.pop_front();
496 int iarg2
= iargs
.front(); iargs
.pop_front();
497 int iarg3
= iargs
.front(); iargs
.pop_front();
499 dout(2) << "makedirs " << sarg1
<< " " << iarg1
<< " " << iarg2
<< " " << iarg3
<< dendl
;
500 make_dirs(sarg1
.c_str(), iarg1
, iarg2
, iarg3
);
505 case SYNCLIENT_MODE_STATDIRS
:
507 string sarg1
= get_sarg(0);
508 int iarg1
= iargs
.front(); iargs
.pop_front();
509 int iarg2
= iargs
.front(); iargs
.pop_front();
510 int iarg3
= iargs
.front(); iargs
.pop_front();
512 dout(2) << "statdirs " << sarg1
<< " " << iarg1
<< " " << iarg2
<< " " << iarg3
<< dendl
;
513 stat_dirs(sarg1
.c_str(), iarg1
, iarg2
, iarg3
);
518 case SYNCLIENT_MODE_READDIRS
:
520 string sarg1
= get_sarg(0);
521 int iarg1
= iargs
.front(); iargs
.pop_front();
522 int iarg2
= iargs
.front(); iargs
.pop_front();
523 int iarg3
= iargs
.front(); iargs
.pop_front();
525 dout(2) << "readdirs " << sarg1
<< " " << iarg1
<< " " << iarg2
<< " " << iarg3
<< dendl
;
526 read_dirs(sarg1
.c_str(), iarg1
, iarg2
, iarg3
);
533 case SYNCLIENT_MODE_THRASHLINKS
:
535 string sarg1
= get_sarg(0);
536 int iarg1
= iargs
.front(); iargs
.pop_front();
537 int iarg2
= iargs
.front(); iargs
.pop_front();
538 int iarg3
= iargs
.front(); iargs
.pop_front();
539 int iarg4
= iargs
.front(); iargs
.pop_front();
541 dout(2) << "thrashlinks " << sarg1
<< " " << iarg1
<< " " << iarg2
<< " " << iarg3
<< dendl
;
542 thrash_links(sarg1
.c_str(), iarg1
, iarg2
, iarg3
, iarg4
);
548 case SYNCLIENT_MODE_LINKTEST
:
558 case SYNCLIENT_MODE_MAKEFILES
:
560 int num
= iargs
.front(); iargs
.pop_front();
561 int count
= iargs
.front(); iargs
.pop_front();
562 int priv
= iargs
.front(); iargs
.pop_front();
564 dout(2) << "makefiles " << num
<< " " << count
<< " " << priv
<< dendl
;
565 make_files(num
, count
, priv
, false);
570 case SYNCLIENT_MODE_MAKEFILES2
:
572 int num
= iargs
.front(); iargs
.pop_front();
573 int count
= iargs
.front(); iargs
.pop_front();
574 int priv
= iargs
.front(); iargs
.pop_front();
576 dout(2) << "makefiles2 " << num
<< " " << count
<< " " << priv
<< dendl
;
577 make_files(num
, count
, priv
, true);
582 case SYNCLIENT_MODE_CREATESHARED
:
584 string sarg1
= get_sarg(0);
585 int num
= iargs
.front(); iargs
.pop_front();
587 dout(2) << "createshared " << num
<< dendl
;
593 case SYNCLIENT_MODE_OPENSHARED
:
595 string sarg1
= get_sarg(0);
596 int num
= iargs
.front(); iargs
.pop_front();
597 int count
= iargs
.front(); iargs
.pop_front();
599 dout(2) << "openshared " << num
<< dendl
;
600 open_shared(num
, count
);
606 case SYNCLIENT_MODE_CREATEOBJECTS
:
608 int count
= iargs
.front(); iargs
.pop_front();
609 int size
= iargs
.front(); iargs
.pop_front();
610 int inflight
= iargs
.front(); iargs
.pop_front();
612 dout(2) << "createobjects " << count
<< " of " << size
<< " bytes"
613 << ", " << inflight
<< " in flight" << dendl
;
614 create_objects(count
, size
, inflight
);
619 case SYNCLIENT_MODE_OBJECTRW
:
621 int count
= iargs
.front(); iargs
.pop_front();
622 int size
= iargs
.front(); iargs
.pop_front();
623 int wrpc
= iargs
.front(); iargs
.pop_front();
624 int overlap
= iargs
.front(); iargs
.pop_front();
625 int rskew
= iargs
.front(); iargs
.pop_front();
626 int wskew
= iargs
.front(); iargs
.pop_front();
628 dout(2) << "objectrw " << count
<< " " << size
<< " " << wrpc
629 << " " << overlap
<< " " << rskew
<< " " << wskew
<< dendl
;
630 object_rw(count
, size
, wrpc
, overlap
, rskew
, wskew
);
636 case SYNCLIENT_MODE_FULLWALK
:
638 string sarg1
;// = get_sarg(0);
640 dout(2) << "fullwalk" << sarg1
<< dendl
;
646 case SYNCLIENT_MODE_REPEATWALK
:
648 string sarg1
= get_sarg(0);
650 dout(2) << "repeatwalk " << sarg1
<< dendl
;
651 while (full_walk(sarg1
) == 0) ;
657 case SYNCLIENT_MODE_RMFILE
:
659 string sarg1
= get_sarg(0);
667 case SYNCLIENT_MODE_WRITEFILE
:
669 string sarg1
= get_sarg(0);
670 int iarg1
= iargs
.front(); iargs
.pop_front();
671 int iarg2
= iargs
.front(); iargs
.pop_front();
672 dout(1) << "WRITING SYN CLIENT" << dendl
;
674 write_file(sarg1
, iarg1
, iarg2
);
680 case SYNCLIENT_MODE_CHUNK
:
682 string sarg1
= get_sarg(0);
689 case SYNCLIENT_MODE_OVERLOAD_OSD_0
:
691 dout(1) << "OVERLOADING OSD 0" << dendl
;
692 int iarg1
= iargs
.front(); iargs
.pop_front();
693 int iarg2
= iargs
.front(); iargs
.pop_front();
694 int iarg3
= iargs
.front(); iargs
.pop_front();
696 overload_osd_0(iarg1
, iarg2
, iarg3
);
702 case SYNCLIENT_MODE_WRSHARED
:
704 string sarg1
= "shared";
705 int iarg1
= iargs
.front(); iargs
.pop_front();
706 int iarg2
= iargs
.front(); iargs
.pop_front();
708 write_file(sarg1
, iarg1
, iarg2
);
713 case SYNCLIENT_MODE_READSHARED
:
715 string sarg1
= "shared";
716 int iarg1
= iargs
.front(); iargs
.pop_front();
717 int iarg2
= iargs
.front(); iargs
.pop_front();
719 read_file(sarg1
, iarg1
, iarg2
, true);
724 case SYNCLIENT_MODE_WRITEBATCH
:
726 int iarg1
= iargs
.front(); iargs
.pop_front();
727 int iarg2
= iargs
.front(); iargs
.pop_front();
728 int iarg3
= iargs
.front(); iargs
.pop_front();
731 write_batch(iarg1
, iarg2
, iarg3
);
737 case SYNCLIENT_MODE_READFILE
:
739 string sarg1
= get_sarg(0);
740 int iarg1
= iargs
.front(); iargs
.pop_front();
741 int iarg2
= iargs
.front(); iargs
.pop_front();
743 dout(1) << "READING SYN CLIENT" << dendl
;
745 read_file(sarg1
, iarg1
, iarg2
);
751 case SYNCLIENT_MODE_RDWRRANDOM
:
753 string sarg1
= get_sarg(0);
754 int iarg1
= iargs
.front(); iargs
.pop_front();
755 int iarg2
= iargs
.front(); iargs
.pop_front();
757 dout(1) << "RANDOM READ WRITE SYN CLIENT" << dendl
;
759 read_random(sarg1
, iarg1
, iarg2
);
765 case SYNCLIENT_MODE_RDWRRANDOM_EX
:
767 string sarg1
= get_sarg(0);
768 int iarg1
= iargs
.front(); iargs
.pop_front();
769 int iarg2
= iargs
.front(); iargs
.pop_front();
771 dout(1) << "RANDOM READ WRITE SYN CLIENT" << dendl
;
773 read_random_ex(sarg1
, iarg1
, iarg2
);
778 case SYNCLIENT_MODE_TRACE
:
780 string tfile
= get_sarg(0);
781 sargs
.push_front(string("~"));
782 int iarg1
= iargs
.front(); iargs
.pop_front();
783 int playdata
= iargs
.front(); iargs
.pop_front();
784 string prefix
= get_sarg(0);
786 snprintf(realtfile
, sizeof(realtfile
), tfile
.c_str(), (int)client
->get_nodeid().v
);
789 dout(0) << "trace " << tfile
<< " prefix=" << prefix
<< " count=" << iarg1
<< " data=" << playdata
<< dendl
;
793 if (iarg1
== 0) iarg1
= 1; // play trace at least once!
795 for (int i
=0; i
<iarg1
; i
++) {
796 utime_t start
= ceph_clock_now();
798 if (time_to_stop()) break;
799 play_trace(t
, prefix
, !playdata
);
800 if (time_to_stop()) break;
801 if (iarg1
> 1) clean_dir(prefix
); // clean only if repeat
803 utime_t lat
= ceph_clock_now();
806 dout(0) << " trace " << tfile
<< " loop " << (i
+1) << "/" << iarg1
<< " done in " << (double)lat
<< " seconds" << dendl
;
811 //client->logger->finc("trsum", (double)lat);
812 //client->logger->inc("trnum");
815 dout(1) << "done " << dendl
;
822 case SYNCLIENT_MODE_OPENTEST
:
824 int count
= iargs
.front(); iargs
.pop_front();
826 for (int i
=0; i
<count
; i
++) {
827 int fd
= client
->open("test", (rand()%2) ?
828 (O_WRONLY
|O_CREAT
) : O_RDONLY
,
830 if (fd
> 0) client
->close(fd
);
837 case SYNCLIENT_MODE_OPTEST
:
839 int count
= iargs
.front(); iargs
.pop_front();
841 client
->mknod("test", 0777, perms
);
843 for (int i
=0; i
<count
; i
++) {
844 client
->lstat("test", &st
, perms
);
845 client
->chmod("test", 0777, perms
);
852 case SYNCLIENT_MODE_TRUNCATE
:
854 string file
= get_sarg(0);
855 sargs
.push_front(file
);
856 int iarg1
= iargs
.front(); iargs
.pop_front();
858 client
->truncate(file
.c_str(), iarg1
, perms
);
865 case SYNCLIENT_MODE_IMPORTFIND
:
867 string base
= get_sarg(0);
868 string find
= get_sarg(0);
869 int data
= get_iarg();
871 import_find(base
.c_str(), find
.c_str(), data
);
877 case SYNCLIENT_MODE_LOOKUPHASH
:
880 string iname
= get_sarg(0);
881 sscanf(iname
.c_str(), "%llx", (long long unsigned*)&ino
.val
);
883 string diname
= get_sarg(0);
884 sscanf(diname
.c_str(), "%llx", (long long unsigned*)&dirino
.val
);
885 string name
= get_sarg(0);
887 lookup_hash(ino
, dirino
, name
.c_str(), perms
);
891 case SYNCLIENT_MODE_LOOKUPINO
:
894 string iname
= get_sarg(0);
895 sscanf(iname
.c_str(), "%llx", (long long unsigned*)&ino
.val
);
897 lookup_ino(ino
, perms
);
902 case SYNCLIENT_MODE_MKSNAP
:
904 string base
= get_sarg(0);
905 string name
= get_sarg(0);
907 mksnap(base
.c_str(), name
.c_str(), perms
);
911 case SYNCLIENT_MODE_RMSNAP
:
913 string base
= get_sarg(0);
914 string name
= get_sarg(0);
916 rmsnap(base
.c_str(), name
.c_str(), perms
);
920 case SYNCLIENT_MODE_MKSNAPFILE
:
922 string base
= get_sarg(0);
924 mksnapfile(base
.c_str());
933 dout(1) << "syn done, unmounting " << dendl
;
941 int SyntheticClient::start_thread()
943 ceph_assert(!thread_id
);
945 pthread_create(&thread_id
, NULL
, synthetic_client_thread_entry
, this);
946 ceph_assert(thread_id
);
947 ceph_pthread_setname(thread_id
, "client");
951 int SyntheticClient::join_thread()
953 ceph_assert(thread_id
);
955 pthread_join(thread_id
, &rv
);
960 bool roll_die(float p
)
962 float r
= (float)(rand() % 100000) / 100000.0;
969 void SyntheticClient::init_op_dist()
973 op_dist
.add( CEPH_MDS_OP_STAT
, 610 );
974 op_dist
.add( CEPH_MDS_OP_UTIME
, 0 );
975 op_dist
.add( CEPH_MDS_OP_CHMOD
, 1 );
976 op_dist
.add( CEPH_MDS_OP_CHOWN
, 1 );
979 op_dist
.add( CEPH_MDS_OP_READDIR
, 2 );
980 op_dist
.add( CEPH_MDS_OP_MKNOD
, 30 );
981 op_dist
.add( CEPH_MDS_OP_LINK
, 0 );
982 op_dist
.add( CEPH_MDS_OP_UNLINK
, 20 );
983 op_dist
.add( CEPH_MDS_OP_RENAME
, 40 );
985 op_dist
.add( CEPH_MDS_OP_MKDIR
, 10 );
986 op_dist
.add( CEPH_MDS_OP_RMDIR
, 20 );
987 op_dist
.add( CEPH_MDS_OP_SYMLINK
, 20 );
989 op_dist
.add( CEPH_MDS_OP_OPEN
, 200 );
990 //op_dist.add( CEPH_MDS_OP_READ, 0 );
991 //op_dist.add( CEPH_MDS_OP_WRITE, 0 );
992 //op_dist.add( CEPH_MDS_OP_TRUNCATE, 0 );
993 //op_dist.add( CEPH_MDS_OP_FSYNC, 0 );
994 //op_dist.add( CEPH_MDS_OP_RELEASE, 200 );
998 void SyntheticClient::up()
1000 cwd
= cwd
.prefixpath(cwd
.depth()-1);
1001 dout(DBL
) << "cd .. -> " << cwd
<< dendl
;
1005 int SyntheticClient::play_trace(Trace
& t
, string
& prefix
, bool metadata_only
)
1007 dout(4) << "play trace prefix '" << prefix
<< "'" << dendl
;
1008 UserPerm perms
= client
->pick_my_perms();
1014 utime_t start
= ceph_clock_now();
1016 ceph::unordered_map
<int64_t, int64_t> open_files
;
1017 ceph::unordered_map
<int64_t, dir_result_t
*> open_dirs
;
1019 ceph::unordered_map
<int64_t, Fh
*> ll_files
;
1020 ceph::unordered_map
<int64_t, dir_result_t
*> ll_dirs
;
1021 ceph::unordered_map
<uint64_t, int64_t> ll_inos
;
1025 ll_inos
[1] = 1; // root inode is known.
1028 const char *p
= prefix
.c_str();
1029 if (prefix
.length()) {
1030 client
->mkdir(prefix
.c_str(), 0755, perms
);
1031 struct ceph_statx stx
;
1032 i1
= client
->ll_get_inode(vinodeno_t(1, CEPH_NOSNAP
));
1033 if (client
->ll_lookupx(i1
, prefix
.c_str(), &i2
, &stx
, CEPH_STATX_INO
, 0, perms
) == 0) {
1034 ll_inos
[1] = stx
.stx_ino
;
1035 dout(5) << "'root' ino is " << inodeno_t(stx
.stx_ino
) << dendl
;
1038 dout(0) << "warning: play_trace couldn't lookup up my per-client directory" << dendl
;
1041 (void) client
->ll_get_inode(vinodeno_t(1, CEPH_NOSNAP
));
1043 utime_t last_status
= start
;
1047 // for object traces
1048 Mutex
lock("synclient foo");
1056 utime_t now
= last_status
;
1057 if (now
- last_status
> 1.0) {
1059 dout(1) << "play_trace at line " << t
.get_line() << dendl
;
1063 if (time_to_stop()) break;
1066 const char *op
= t
.get_string(buf
, 0);
1067 dout(4) << (t
.get_line()-1) << ": trace op " << op
<< dendl
;
1070 // timestamp... ignore it!
1072 t
.get_int(); // usec
1073 op
= t
.get_string(buf
, 0);
1076 // high level ops ---------------------
1077 UserPerm perms
= client
->pick_my_perms();
1078 if (strcmp(op
, "link") == 0) {
1079 const char *a
= t
.get_string(buf
, p
);
1080 const char *b
= t
.get_string(buf2
, p
);
1081 client
->link(a
, b
, perms
);
1082 } else if (strcmp(op
, "unlink") == 0) {
1083 const char *a
= t
.get_string(buf
, p
);
1084 client
->unlink(a
, perms
);
1085 } else if (strcmp(op
, "rename") == 0) {
1086 const char *a
= t
.get_string(buf
, p
);
1087 const char *b
= t
.get_string(buf2
, p
);
1088 client
->rename(a
,b
, perms
);
1089 } else if (strcmp(op
, "mkdir") == 0) {
1090 const char *a
= t
.get_string(buf
, p
);
1091 int64_t b
= t
.get_int();
1092 client
->mkdir(a
, b
, perms
);
1093 } else if (strcmp(op
, "rmdir") == 0) {
1094 const char *a
= t
.get_string(buf
, p
);
1095 client
->rmdir(a
, perms
);
1096 } else if (strcmp(op
, "symlink") == 0) {
1097 const char *a
= t
.get_string(buf
, p
);
1098 const char *b
= t
.get_string(buf2
, p
);
1099 client
->symlink(a
, b
, perms
);
1100 } else if (strcmp(op
, "readlink") == 0) {
1101 const char *a
= t
.get_string(buf
, p
);
1103 client
->readlink(a
, buf
, 100, perms
);
1104 } else if (strcmp(op
, "lstat") == 0) {
1106 const char *a
= t
.get_string(buf
, p
);
1107 if (strcmp(a
, p
) != 0 &&
1108 strcmp(a
, "/") != 0 &&
1109 strcmp(a
, "/lib") != 0 && // or /lib.. that would be a lookup. hack.
1110 a
[0] != 0) // stop stating the root directory already
1111 client
->lstat(a
, &st
, perms
);
1112 } else if (strcmp(op
, "chmod") == 0) {
1113 const char *a
= t
.get_string(buf
, p
);
1114 int64_t b
= t
.get_int();
1115 client
->chmod(a
, b
, perms
);
1116 } else if (strcmp(op
, "chown") == 0) {
1117 const char *a
= t
.get_string(buf
, p
);
1118 int64_t b
= t
.get_int();
1119 int64_t c
= t
.get_int();
1120 client
->chown(a
, b
, c
, perms
);
1121 } else if (strcmp(op
, "utime") == 0) {
1122 const char *a
= t
.get_string(buf
, p
);
1123 int64_t b
= t
.get_int();
1124 int64_t c
= t
.get_int();
1128 client
->utime(a
, &u
, perms
);
1129 } else if (strcmp(op
, "mknod") == 0) {
1130 const char *a
= t
.get_string(buf
, p
);
1131 int64_t b
= t
.get_int();
1132 int64_t c
= t
.get_int();
1133 client
->mknod(a
, b
, perms
, c
);
1134 } else if (strcmp(op
, "oldmknod") == 0) {
1135 const char *a
= t
.get_string(buf
, p
);
1136 int64_t b
= t
.get_int();
1137 client
->mknod(a
, b
, perms
, 0);
1138 } else if (strcmp(op
, "getdir") == 0) {
1139 const char *a
= t
.get_string(buf
, p
);
1140 list
<string
> contents
;
1141 int r
= client
->getdir(a
, contents
, perms
);
1143 dout(1) << "getdir on " << a
<< " returns " << r
<< dendl
;
1145 } else if (strcmp(op
, "opendir") == 0) {
1146 const char *a
= t
.get_string(buf
, p
);
1147 int64_t b
= t
.get_int();
1149 client
->opendir(a
, &dirp
, perms
);
1150 if (dirp
) open_dirs
[b
] = dirp
;
1151 } else if (strcmp(op
, "closedir") == 0) {
1152 int64_t a
= t
.get_int();
1153 client
->closedir(open_dirs
[a
]);
1155 } else if (strcmp(op
, "open") == 0) {
1156 const char *a
= t
.get_string(buf
, p
);
1157 int64_t b
= t
.get_int();
1158 int64_t c
= t
.get_int();
1159 int64_t d
= t
.get_int();
1160 int64_t fd
= client
->open(a
, b
, perms
, c
);
1161 if (fd
> 0) open_files
[d
] = fd
;
1162 } else if (strcmp(op
, "oldopen") == 0) {
1163 const char *a
= t
.get_string(buf
, p
);
1164 int64_t b
= t
.get_int();
1165 int64_t d
= t
.get_int();
1166 int64_t fd
= client
->open(a
, b
, perms
, 0755);
1167 if (fd
> 0) open_files
[d
] = fd
;
1168 } else if (strcmp(op
, "close") == 0) {
1169 int64_t id
= t
.get_int();
1170 int64_t fh
= open_files
[id
];
1171 if (fh
> 0) client
->close(fh
);
1172 open_files
.erase(id
);
1173 } else if (strcmp(op
, "lseek") == 0) {
1174 int64_t f
= t
.get_int();
1175 int fd
= open_files
[f
];
1176 int64_t off
= t
.get_int();
1177 int64_t whence
= t
.get_int();
1178 client
->lseek(fd
, off
, whence
);
1179 } else if (strcmp(op
, "read") == 0) {
1180 int64_t f
= t
.get_int();
1181 int64_t size
= t
.get_int();
1182 int64_t off
= t
.get_int();
1183 int64_t fd
= open_files
[f
];
1184 if (!metadata_only
) {
1185 char *b
= new char[size
];
1186 client
->read(fd
, b
, size
, off
);
1189 } else if (strcmp(op
, "write") == 0) {
1190 int64_t f
= t
.get_int();
1191 int64_t fd
= open_files
[f
];
1192 int64_t size
= t
.get_int();
1193 int64_t off
= t
.get_int();
1194 if (!metadata_only
) {
1195 char *b
= new char[size
];
1196 memset(b
, 1, size
); // let's write 1's!
1197 client
->write(fd
, b
, size
, off
);
1200 client
->write(fd
, NULL
, 0, size
+off
);
1202 } else if (strcmp(op
, "truncate") == 0) {
1203 const char *a
= t
.get_string(buf
, p
);
1204 int64_t l
= t
.get_int();
1205 client
->truncate(a
, l
, perms
);
1206 } else if (strcmp(op
, "ftruncate") == 0) {
1207 int64_t f
= t
.get_int();
1208 int fd
= open_files
[f
];
1209 int64_t l
= t
.get_int();
1210 client
->ftruncate(fd
, l
, perms
);
1211 } else if (strcmp(op
, "fsync") == 0) {
1212 int64_t f
= t
.get_int();
1213 int64_t b
= t
.get_int();
1214 int fd
= open_files
[f
];
1215 client
->fsync(fd
, b
);
1216 } else if (strcmp(op
, "chdir") == 0) {
1217 const char *a
= t
.get_string(buf
, p
);
1218 // Client users should remember their path, but since this
1219 // is just a synthetic client we ignore it.
1221 client
->chdir(a
, ignore
, perms
);
1222 } else if (strcmp(op
, "statfs") == 0) {
1223 struct statvfs stbuf
;
1224 client
->statfs("/", &stbuf
, perms
);
1227 // low level ops ---------------------
1228 else if (strcmp(op
, "ll_lookup") == 0) {
1229 int64_t i
= t
.get_int();
1230 const char *name
= t
.get_string(buf
, p
);
1231 int64_t r
= t
.get_int();
1232 struct ceph_statx stx
;
1233 if (ll_inos
.count(i
)) {
1234 i1
= client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
));
1235 if (client
->ll_lookupx(i1
, name
, &i2
, &stx
, CEPH_STATX_INO
, 0, perms
) == 0)
1236 ll_inos
[r
] = stx
.stx_ino
;
1239 } else if (strcmp(op
, "ll_forget") == 0) {
1240 int64_t i
= t
.get_int();
1241 int64_t n
= t
.get_int();
1242 if (ll_inos
.count(i
) &&
1244 client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
)), n
))
1246 } else if (strcmp(op
, "ll_getattr") == 0) {
1247 int64_t i
= t
.get_int();
1249 if (ll_inos
.count(i
)) {
1250 i1
= client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
));
1251 client
->ll_getattr(i1
, &attr
, perms
);
1254 } else if (strcmp(op
, "ll_setattr") == 0) {
1255 int64_t i
= t
.get_int();
1257 memset(&attr
, 0, sizeof(attr
));
1258 attr
.st_mode
= t
.get_int();
1259 attr
.st_uid
= t
.get_int();
1260 attr
.st_gid
= t
.get_int();
1261 attr
.st_size
= t
.get_int();
1262 attr
.st_mtime
= t
.get_int();
1263 attr
.st_atime
= t
.get_int();
1264 int mask
= t
.get_int();
1265 if (ll_inos
.count(i
)) {
1266 i1
= client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
));
1267 client
->ll_setattr(i1
, &attr
, mask
, perms
);
1270 } else if (strcmp(op
, "ll_readlink") == 0) {
1271 int64_t i
= t
.get_int();
1272 if (ll_inos
.count(i
)) {
1274 i1
= client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
));
1275 client
->ll_readlink(i1
, buf
, sizeof(buf
), perms
);
1278 } else if (strcmp(op
, "ll_mknod") == 0) {
1279 int64_t i
= t
.get_int();
1280 const char *n
= t
.get_string(buf
, p
);
1281 int m
= t
.get_int();
1282 int r
= t
.get_int();
1283 int64_t ri
= t
.get_int();
1285 if (ll_inos
.count(i
)) {
1286 i1
= client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
));
1287 if (client
->ll_mknod(i1
, n
, m
, r
, &attr
, &i2
, perms
) == 0)
1288 ll_inos
[ri
] = attr
.st_ino
;
1291 } else if (strcmp(op
, "ll_mkdir") == 0) {
1292 int64_t i
= t
.get_int();
1293 const char *n
= t
.get_string(buf
, p
);
1294 int m
= t
.get_int();
1295 int64_t ri
= t
.get_int();
1297 if (ll_inos
.count(i
)) {
1298 i1
= client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
));
1299 if (client
->ll_mkdir(i1
, n
, m
, &attr
, &i2
, perms
) == 0)
1300 ll_inos
[ri
] = attr
.st_ino
;
1303 } else if (strcmp(op
, "ll_symlink") == 0) {
1304 int64_t i
= t
.get_int();
1305 const char *n
= t
.get_string(buf
, p
);
1306 const char *v
= t
.get_string(buf2
, p
);
1307 int64_t ri
= t
.get_int();
1309 if (ll_inos
.count(i
)) {
1310 i1
= client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
));
1311 if (client
->ll_symlink(i1
, n
, v
, &attr
, &i2
, perms
) == 0)
1312 ll_inos
[ri
] = attr
.st_ino
;
1315 } else if (strcmp(op
, "ll_unlink") == 0) {
1316 int64_t i
= t
.get_int();
1317 const char *n
= t
.get_string(buf
, p
);
1318 if (ll_inos
.count(i
)) {
1319 i1
= client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
));
1320 client
->ll_unlink(i1
, n
, perms
);
1323 } else if (strcmp(op
, "ll_rmdir") == 0) {
1324 int64_t i
= t
.get_int();
1325 const char *n
= t
.get_string(buf
, p
);
1326 if (ll_inos
.count(i
)) {
1327 i1
= client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
));
1328 client
->ll_rmdir(i1
, n
, perms
);
1331 } else if (strcmp(op
, "ll_rename") == 0) {
1332 int64_t i
= t
.get_int();
1333 const char *n
= t
.get_string(buf
, p
);
1334 int64_t ni
= t
.get_int();
1335 const char *nn
= t
.get_string(buf2
, p
);
1336 if (ll_inos
.count(i
) &&
1337 ll_inos
.count(ni
)) {
1338 i1
= client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
));
1339 i2
= client
->ll_get_inode(vinodeno_t(ll_inos
[ni
],CEPH_NOSNAP
));
1340 client
->ll_rename(i1
, n
, i2
, nn
, perms
);
1344 } else if (strcmp(op
, "ll_link") == 0) {
1345 int64_t i
= t
.get_int();
1346 int64_t ni
= t
.get_int();
1347 const char *nn
= t
.get_string(buf
, p
);
1348 if (ll_inos
.count(i
) &&
1349 ll_inos
.count(ni
)) {
1350 i1
= client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
));
1351 i2
= client
->ll_get_inode(vinodeno_t(ll_inos
[ni
],CEPH_NOSNAP
));
1352 client
->ll_link(i1
, i2
, nn
, perms
);
1356 } else if (strcmp(op
, "ll_opendir") == 0) {
1357 int64_t i
= t
.get_int();
1358 int64_t r
= t
.get_int();
1360 if (ll_inos
.count(i
)) {
1361 i1
= client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
));
1362 if (client
->ll_opendir(i1
, O_RDONLY
, &dirp
, perms
) == 0)
1366 } else if (strcmp(op
, "ll_releasedir") == 0) {
1367 int64_t f
= t
.get_int();
1368 if (ll_dirs
.count(f
)) {
1369 client
->ll_releasedir(ll_dirs
[f
]);
1372 } else if (strcmp(op
, "ll_open") == 0) {
1373 int64_t i
= t
.get_int();
1374 int64_t f
= t
.get_int();
1375 int64_t r
= t
.get_int();
1377 if (ll_inos
.count(i
)) {
1378 i1
= client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
));
1379 if (client
->ll_open(i1
, f
, &fhp
, perms
) == 0)
1383 } else if (strcmp(op
, "ll_create") == 0) {
1384 int64_t i
= t
.get_int();
1385 const char *n
= t
.get_string(buf
, p
);
1386 int64_t m
= t
.get_int();
1387 int64_t f
= t
.get_int();
1388 int64_t r
= t
.get_int();
1389 int64_t ri
= t
.get_int();
1391 if (ll_inos
.count(i
)) {
1393 i1
= client
->ll_get_inode(vinodeno_t(ll_inos
[i
],CEPH_NOSNAP
));
1394 if (client
->ll_create(i1
, n
, m
, f
, &attr
, NULL
, &fhp
, perms
) == 0) {
1395 ll_inos
[ri
] = attr
.st_ino
;
1400 } else if (strcmp(op
, "ll_read") == 0) {
1401 int64_t f
= t
.get_int();
1402 int64_t off
= t
.get_int();
1403 int64_t size
= t
.get_int();
1404 if (ll_files
.count(f
) &&
1407 client
->ll_read(ll_files
[f
], off
, size
, &bl
);
1409 } else if (strcmp(op
, "ll_write") == 0) {
1410 int64_t f
= t
.get_int();
1411 int64_t off
= t
.get_int();
1412 int64_t size
= t
.get_int();
1413 if (ll_files
.count(f
)) {
1414 if (!metadata_only
) {
1419 client
->ll_write(ll_files
[f
], off
, size
, bl
.c_str());
1421 client
->ll_write(ll_files
[f
], off
+size
, 0, NULL
);
1424 } else if (strcmp(op
, "ll_flush") == 0) {
1425 int64_t f
= t
.get_int();
1426 if (!metadata_only
&&
1428 client
->ll_flush(ll_files
[f
]);
1429 } else if (strcmp(op
, "ll_fsync") == 0) {
1430 int64_t f
= t
.get_int();
1431 if (!metadata_only
&&
1433 client
->ll_fsync(ll_files
[f
], false); // FIXME dataonly param
1434 } else if (strcmp(op
, "ll_release") == 0) {
1435 int64_t f
= t
.get_int();
1436 if (ll_files
.count(f
)) {
1437 client
->ll_release(ll_files
[f
]);
1440 } else if (strcmp(op
, "ll_statfs") == 0) {
1441 int64_t i
= t
.get_int();
1442 if (ll_inos
.count(i
))
1443 {} //client->ll_statfs(vinodeno_t(ll_inos[i],CEPH_NOSNAP), perms);
1447 // object-level traces
1449 else if (strcmp(op
, "o_stat") == 0) {
1450 int64_t oh
= t
.get_int();
1451 int64_t ol
= t
.get_int();
1452 object_t oid
= file_object_t(oh
, ol
);
1454 object_locator_t
oloc(SYNCLIENT_FIRST_POOL
);
1456 ceph::real_time mtime
;
1457 client
->objecter
->stat(oid
, oloc
, CEPH_NOSNAP
, &size
, &mtime
, 0,
1458 new C_SafeCond(&lock
, &cond
, &ack
));
1459 while (!ack
) cond
.Wait(lock
);
1462 else if (strcmp(op
, "o_read") == 0) {
1463 int64_t oh
= t
.get_int();
1464 int64_t ol
= t
.get_int();
1465 int64_t off
= t
.get_int();
1466 int64_t len
= t
.get_int();
1467 object_t oid
= file_object_t(oh
, ol
);
1468 object_locator_t
oloc(SYNCLIENT_FIRST_POOL
);
1471 client
->objecter
->read(oid
, oloc
, off
, len
, CEPH_NOSNAP
, &bl
, 0,
1472 new C_SafeCond(&lock
, &cond
, &ack
));
1473 while (!ack
) cond
.Wait(lock
);
1476 else if (strcmp(op
, "o_write") == 0) {
1477 int64_t oh
= t
.get_int();
1478 int64_t ol
= t
.get_int();
1479 int64_t off
= t
.get_int();
1480 int64_t len
= t
.get_int();
1481 object_t oid
= file_object_t(oh
, ol
);
1482 object_locator_t
oloc(SYNCLIENT_FIRST_POOL
);
1488 client
->objecter
->write(oid
, oloc
, off
, len
, snapc
, bl
,
1489 ceph::real_clock::now(), 0,
1490 new C_SafeCond(&lock
, &cond
, &ack
));
1491 while (!ack
) cond
.Wait(lock
);
1494 else if (strcmp(op
, "o_zero") == 0) {
1495 int64_t oh
= t
.get_int();
1496 int64_t ol
= t
.get_int();
1497 int64_t off
= t
.get_int();
1498 int64_t len
= t
.get_int();
1499 object_t oid
= file_object_t(oh
, ol
);
1500 object_locator_t
oloc(SYNCLIENT_FIRST_POOL
);
1503 client
->objecter
->zero(oid
, oloc
, off
, len
, snapc
,
1504 ceph::real_clock::now(), 0,
1505 new C_SafeCond(&lock
, &cond
, &ack
));
1506 while (!ack
) cond
.Wait(lock
);
1512 dout(0) << (t
.get_line()-1) << ": *** trace hit unrecognized symbol '" << op
<< "' " << dendl
;
1517 dout(10) << "trace finished on line " << t
.get_line() << dendl
;
1520 for (ceph::unordered_map
<int64_t, int64_t>::iterator fi
= open_files
.begin();
1521 fi
!= open_files
.end();
1523 dout(1) << "leftover close " << fi
->second
<< dendl
;
1524 if (fi
->second
> 0) client
->close(fi
->second
);
1526 for (ceph::unordered_map
<int64_t, dir_result_t
*>::iterator fi
= open_dirs
.begin();
1527 fi
!= open_dirs
.end();
1529 dout(1) << "leftover closedir " << fi
->second
<< dendl
;
1530 if (fi
->second
!= 0) client
->closedir(fi
->second
);
1532 for (ceph::unordered_map
<int64_t,Fh
*>::iterator fi
= ll_files
.begin();
1533 fi
!= ll_files
.end();
1535 dout(1) << "leftover ll_release " << fi
->second
<< dendl
;
1536 if (fi
->second
) client
->ll_release(fi
->second
);
1538 for (ceph::unordered_map
<int64_t,dir_result_t
*>::iterator fi
= ll_dirs
.begin();
1539 fi
!= ll_dirs
.end();
1541 dout(1) << "leftover ll_releasedir " << fi
->second
<< dendl
;
1542 if (fi
->second
) client
->ll_releasedir(fi
->second
);
1550 int SyntheticClient::clean_dir(string
& basedir
)
1553 list
<string
> contents
;
1554 UserPerm perms
= client
->pick_my_perms();
1555 int r
= client
->getdir(basedir
.c_str(), contents
, perms
);
1557 dout(1) << "getdir on " << basedir
<< " returns " << r
<< dendl
;
1561 for (list
<string
>::iterator it
= contents
.begin();
1562 it
!= contents
.end();
1564 if (*it
== ".") continue;
1565 if (*it
== "..") continue;
1566 string file
= basedir
+ "/" + *it
;
1568 if (time_to_stop()) break;
1571 int r
= client
->lstat(file
.c_str(), &st
, perms
);
1573 dout(1) << "stat error on " << file
<< " r=" << r
<< dendl
;
1577 if ((st
.st_mode
& S_IFMT
) == S_IFDIR
) {
1579 client
->rmdir(file
.c_str(), perms
);
1581 client
->unlink(file
.c_str(), perms
);
1590 int SyntheticClient::full_walk(string
& basedir
)
1592 if (time_to_stop()) return -1;
1595 list
<frag_info_t
> statq
;
1596 dirq
.push_back(basedir
);
1598 statq
.push_back(empty
);
1600 ceph::unordered_map
<inodeno_t
, int> nlink
;
1601 ceph::unordered_map
<inodeno_t
, int> nlink_seen
;
1603 UserPerm perms
= client
->pick_my_perms();
1604 while (!dirq
.empty()) {
1605 string dir
= dirq
.front();
1606 frag_info_t expect
= statq
.front();
1610 frag_info_t actual
= empty
;
1613 list
<string
> contents
;
1614 int r
= client
->getdir(dir
.c_str(), contents
, perms
);
1616 dout(1) << "getdir on " << dir
<< " returns " << r
<< dendl
;
1620 for (list
<string
>::iterator it
= contents
.begin();
1621 it
!= contents
.end();
1626 string file
= dir
+ "/" + *it
;
1629 frag_info_t dirstat
;
1630 int r
= client
->lstat(file
.c_str(), &st
, perms
, &dirstat
);
1632 dout(1) << "stat error on " << file
<< " r=" << r
<< dendl
;
1636 nlink_seen
[st
.st_ino
]++;
1637 nlink
[st
.st_ino
] = st
.st_nlink
;
1639 if (S_ISDIR(st
.st_mode
))
1645 char *tm
= ctime(&st
.st_mtime
);
1646 tm
[strlen(tm
)-1] = 0;
1647 printf("%llx %c%c%c%c%c%c%c%c%c%c %2d %5d %5d %8llu %12s %s\n",
1648 (long long)st
.st_ino
,
1649 S_ISDIR(st
.st_mode
) ? 'd':'-',
1650 (st
.st_mode
& 0400) ? 'r':'-',
1651 (st
.st_mode
& 0200) ? 'w':'-',
1652 (st
.st_mode
& 0100) ? 'x':'-',
1653 (st
.st_mode
& 040) ? 'r':'-',
1654 (st
.st_mode
& 020) ? 'w':'-',
1655 (st
.st_mode
& 010) ? 'x':'-',
1656 (st
.st_mode
& 04) ? 'r':'-',
1657 (st
.st_mode
& 02) ? 'w':'-',
1658 (st
.st_mode
& 01) ? 'x':'-',
1660 (int)st
.st_uid
, (int)st
.st_gid
,
1661 (long long unsigned)st
.st_size
,
1666 if ((st
.st_mode
& S_IFMT
) == S_IFDIR
) {
1667 dirq
.push_back(file
);
1668 statq
.push_back(dirstat
);
1673 (actual
.nsubdirs
!= expect
.nsubdirs
||
1674 actual
.nfiles
!= expect
.nfiles
)) {
1675 dout(0) << dir
<< ": expected " << expect
<< dendl
;
1676 dout(0) << dir
<< ": got " << actual
<< dendl
;
1680 for (ceph::unordered_map
<inodeno_t
,int>::iterator p
= nlink
.begin(); p
!= nlink
.end(); ++p
) {
1681 if (nlink_seen
[p
->first
] != p
->second
)
1682 dout(0) << p
->first
<< " nlink " << p
->second
<< " != " << nlink_seen
[p
->first
] << "seen" << dendl
;
1690 int SyntheticClient::dump_placement(string
& fn
) {
1692 UserPerm perms
= client
->pick_my_perms();
1695 int fd
= client
->open(fn
.c_str(), O_RDONLY
, perms
);
1696 dout(5) << "reading from " << fn
<< " fd " << fd
<< dendl
;
1697 if (fd
< 0) return fd
;
1702 int lstat_result
= client
->lstat(fn
.c_str(), &stbuf
, perms
);
1703 if (lstat_result
< 0) {
1704 dout(0) << "lstat error for file " << fn
<< dendl
;
1706 return lstat_result
;
1709 off_t filesize
= stbuf
.st_size
;
1711 // grab the placement info
1712 vector
<ObjectExtent
> extents
;
1714 client
->enumerate_layout(fd
, extents
, filesize
, offset
);
1718 // run through all the object extents
1719 dout(0) << "file size is " << filesize
<< dendl
;
1720 dout(0) << "(osd, start, length) tuples for file " << fn
<< dendl
;
1721 for (const auto& x
: extents
) {
1722 int osd
= client
->objecter
->with_osdmap([&](const OSDMap
& o
) {
1723 return o
.get_pg_acting_primary(o
.object_locator_to_pg(x
.oid
, x
.oloc
));
1726 // run through all the buffer extents
1727 for (const auto& be
: x
.buffer_extents
)
1728 dout(0) << "OSD " << osd
<< ", offset " << be
.first
1729 << ", length " << be
.second
<< dendl
;
1736 int SyntheticClient::make_dirs(const char *basedir
, int dirs
, int files
, int depth
)
1738 if (time_to_stop()) return 0;
1740 UserPerm perms
= client
->pick_my_perms();
1741 // make sure base dir exists
1742 int r
= client
->mkdir(basedir
, 0755, perms
);
1744 dout(1) << "can't make base dir? " << basedir
<< dendl
;
1750 dout(3) << "make_dirs " << basedir
<< " dirs " << dirs
<< " files " << files
<< " depth " << depth
<< dendl
;
1751 for (int i
=0; i
<files
; i
++) {
1752 snprintf(d
, sizeof(d
), "%s/file.%d", basedir
, i
);
1753 client
->mknod(d
, 0644, perms
);
1756 if (depth
== 0) return 0;
1758 for (int i
=0; i
<dirs
; i
++) {
1759 snprintf(d
, sizeof(d
), "%s/dir.%d", basedir
, i
);
1760 make_dirs(d
, dirs
, files
, depth
-1);
1766 int SyntheticClient::stat_dirs(const char *basedir
, int dirs
, int files
, int depth
)
1768 if (time_to_stop()) return 0;
1770 UserPerm perms
= client
->pick_my_perms();
1772 // make sure base dir exists
1774 int r
= client
->lstat(basedir
, &st
, perms
);
1776 dout(1) << "can't make base dir? " << basedir
<< dendl
;
1782 dout(3) << "stat_dirs " << basedir
<< " dirs " << dirs
<< " files " << files
<< " depth " << depth
<< dendl
;
1783 for (int i
=0; i
<files
; i
++) {
1784 snprintf(d
, sizeof(d
), "%s/file.%d", basedir
, i
);
1785 client
->lstat(d
, &st
, perms
);
1788 if (depth
== 0) return 0;
1790 for (int i
=0; i
<dirs
; i
++) {
1791 snprintf(d
, sizeof(d
), "%s/dir.%d", basedir
, i
);
1792 stat_dirs(d
, dirs
, files
, depth
-1);
1797 int SyntheticClient::read_dirs(const char *basedir
, int dirs
, int files
, int depth
)
1799 if (time_to_stop()) return 0;
1805 dout(3) << "read_dirs " << basedir
<< " dirs " << dirs
<< " files " << files
<< " depth " << depth
<< dendl
;
1807 list
<string
> contents
;
1808 UserPerm perms
= client
->pick_my_perms();
1809 utime_t s
= ceph_clock_now();
1810 int r
= client
->getdir(basedir
, contents
, perms
);
1811 utime_t e
= ceph_clock_now();
1814 dout(0) << "getdir couldn't readdir " << basedir
<< ", stopping" << dendl
;
1818 for (int i
=0; i
<files
; i
++) {
1819 snprintf(d
, sizeof(d
), "%s/file.%d", basedir
, i
);
1820 utime_t s
= ceph_clock_now();
1821 if (client
->lstat(d
, &st
, perms
) < 0) {
1822 dout(2) << "read_dirs failed stat on " << d
<< ", stopping" << dendl
;
1825 utime_t e
= ceph_clock_now();
1830 for (int i
=0; i
<dirs
; i
++) {
1831 snprintf(d
, sizeof(d
), "%s/dir.%d", basedir
, i
);
1832 if (read_dirs(d
, dirs
, files
, depth
-1) < 0) return -1;
1839 int SyntheticClient::make_files(int num
, int count
, int priv
, bool more
)
1841 int whoami
= client
->get_nodeid().v
;
1843 UserPerm perms
= client
->pick_my_perms();
1846 for (int c
=0; c
<count
; c
++) {
1847 snprintf(d
, sizeof(d
), "dir.%d.run%d", whoami
, c
);
1848 client
->mkdir(d
, 0755, perms
);
1852 if (true || whoami
== 0) {
1853 for (int c
=0; c
<count
; c
++) {
1854 snprintf(d
, sizeof(d
), "dir.%d.run%d", 0, c
);
1855 client
->mkdir(d
, 0755, perms
);
1864 utime_t start
= ceph_clock_now();
1865 for (int c
=0; c
<count
; c
++) {
1866 for (int n
=0; n
<num
; n
++) {
1867 snprintf(d
, sizeof(d
), "dir.%d.run%d/file.client%d.%d", priv
? whoami
:0, c
, whoami
, n
);
1869 client
->mknod(d
, 0644, perms
);
1872 client
->lstat(d
, &st
, perms
);
1873 int fd
= client
->open(d
, O_RDONLY
, perms
);
1874 client
->unlink(d
, perms
);
1878 if (time_to_stop()) return 0;
1881 utime_t end
= ceph_clock_now();
1883 dout(0) << "makefiles time is " << end
<< " or " << ((double)end
/ (double)num
) <<" per file" << dendl
;
1888 int SyntheticClient::link_test()
1893 UserPerm perms
= client
->pick_my_perms();
1898 client
->mkdir("orig", 0755, perms
);
1899 client
->mkdir("copy", 0755, perms
);
1901 utime_t start
= ceph_clock_now();
1902 for (int i
=0; i
<num
; i
++) {
1903 snprintf(d
, sizeof(d
), "orig/file.%d", i
);
1904 client
->mknod(d
, 0755, perms
);
1906 utime_t end
= ceph_clock_now();
1909 dout(0) << "orig " << end
<< dendl
;
1912 start
= ceph_clock_now();
1913 for (int i
=0; i
<num
; i
++) {
1914 snprintf(d
, sizeof(d
), "orig/file.%d", i
);
1915 snprintf(e
, sizeof(e
), "copy/file.%d", i
);
1916 client
->link(d
, e
, perms
);
1918 end
= ceph_clock_now();
1920 dout(0) << "copy " << end
<< dendl
;
1926 int SyntheticClient::create_shared(int num
)
1929 UserPerm perms
= client
->pick_my_perms();
1931 client
->mkdir("test", 0755, perms
);
1932 for (int n
=0; n
<num
; n
++) {
1933 snprintf(d
, sizeof(d
), "test/file.%d", n
);
1934 client
->mknod(d
, 0644, perms
);
1940 int SyntheticClient::open_shared(int num
, int count
)
1944 UserPerm perms
= client
->pick_my_perms();
1945 for (int c
=0; c
<count
; c
++) {
1948 for (int n
=0; n
<num
; n
++) {
1949 snprintf(d
, sizeof(d
), "test/file.%d", n
);
1950 int fd
= client
->open(d
, O_RDONLY
, perms
);
1951 if (fd
> 0) fds
.push_back(fd
);
1954 if (false && client
->get_nodeid() == 0)
1955 for (int n
=0; n
<num
; n
++) {
1956 snprintf(d
, sizeof(d
), "test/file.%d", n
);
1957 client
->unlink(d
, perms
);
1960 while (!fds
.empty()) {
1961 int fd
= fds
.front();
1971 // Hits OSD 0 with writes to various files with OSD 0 as the primary.
1972 int SyntheticClient::overload_osd_0(int n
, int size
, int wrsize
) {
1973 UserPerm perms
= client
->pick_my_perms();
1974 // collect a bunch of files starting on OSD 0
1981 dout(0) << "in OSD overload" << dendl
;
1982 string filename
= get_sarg(tried
);
1983 dout(1) << "OSD Overload workload: trying file " << filename
<< dendl
;
1984 int fd
= client
->open(filename
.c_str(), O_RDWR
|O_CREAT
, perms
);
1987 // only use the file if its first primary is OSD 0
1988 int primary_osd
= check_first_primary(fd
);
1989 if (primary_osd
!= 0) {
1991 dout(1) << "OSD Overload workload: SKIPPING file " << filename
<<
1992 " with OSD " << primary_osd
<< " as first primary. " << dendl
;
1995 dout(1) << "OSD Overload workload: USING file " << filename
<<
1996 " with OSD 0 as first primary. " << dendl
;
2000 // do whatever operation we want to do on the file. How about a write?
2001 write_fd(fd
, size
, wrsize
);
2007 // See what the primary is for the first object in this file.
2008 int SyntheticClient::check_first_primary(int fh
)
2010 vector
<ObjectExtent
> extents
;
2011 client
->enumerate_layout(fh
, extents
, 1, 0);
2012 return client
->objecter
->with_osdmap([&](const OSDMap
& o
) {
2013 return o
.get_pg_acting_primary(
2014 o
.object_locator_to_pg(extents
.begin()->oid
, extents
.begin()->oloc
));
2018 int SyntheticClient::rm_file(string
& fn
)
2020 UserPerm perms
= client
->pick_my_perms();
2021 return client
->unlink(fn
.c_str(), perms
);
2024 int SyntheticClient::write_file(string
& fn
, int size
, loff_t wrsize
) // size is in MB, wrsize in bytes
2026 //uint64_t wrsize = 1024*256;
2027 char *buf
= new char[wrsize
+100]; // 1 MB
2028 memset(buf
, 7, wrsize
);
2029 int64_t chunks
= (uint64_t)size
* (uint64_t)(1024*1024) / (uint64_t)wrsize
;
2030 UserPerm perms
= client
->pick_my_perms();
2032 int fd
= client
->open(fn
.c_str(), O_RDWR
|O_CREAT
, perms
);
2033 dout(5) << "writing to " << fn
<< " fd " << fd
<< dendl
;
2039 utime_t from
= ceph_clock_now();
2040 utime_t start
= from
;
2041 uint64_t bytes
= 0, total
= 0;
2044 for (loff_t i
=0; i
<chunks
; i
++) {
2045 if (time_to_stop()) {
2046 dout(0) << "stopping" << dendl
;
2049 dout(2) << "writing block " << i
<< "/" << chunks
<< dendl
;
2051 // fill buf with a 16 byte fingerprint
2052 // 64 bits : file offset
2053 // 64 bits : client id
2054 // = 128 bits (16 bytes)
2055 uint64_t *p
= (uint64_t*)buf
;
2056 while ((char*)p
< buf
+ wrsize
) {
2057 *p
= (uint64_t)i
*(uint64_t)wrsize
+ (uint64_t)((char*)p
- buf
);
2059 *p
= client
->get_nodeid().v
;
2063 client
->write(fd
, buf
, wrsize
, i
*wrsize
);
2067 utime_t now
= ceph_clock_now();
2068 if (now
- from
>= 1.0) {
2069 double el
= now
- from
;
2070 dout(0) << "write " << (bytes
/ el
/ 1048576.0) << " MB/sec" << dendl
;
2076 client
->fsync(fd
, true);
2078 utime_t stop
= ceph_clock_now();
2079 double el
= stop
- start
;
2080 dout(0) << "write total " << (total
/ el
/ 1048576.0) << " MB/sec ("
2081 << total
<< " bytes in " << el
<< " seconds)" << dendl
;
2089 int SyntheticClient::write_fd(int fd
, int size
, int wrsize
) // size is in MB, wrsize in bytes
2091 //uint64_t wrsize = 1024*256;
2092 char *buf
= new char[wrsize
+100]; // 1 MB
2093 memset(buf
, 7, wrsize
);
2094 uint64_t chunks
= (uint64_t)size
* (uint64_t)(1024*1024) / (uint64_t)wrsize
;
2096 //dout(5) << "SyntheticClient::write_fd: writing to fd " << fd << dendl;
2102 for (unsigned i
=0; i
<chunks
; i
++) {
2103 if (time_to_stop()) {
2104 dout(0) << "stopping" << dendl
;
2107 dout(2) << "writing block " << i
<< "/" << chunks
<< dendl
;
2109 // fill buf with a 16 byte fingerprint
2110 // 64 bits : file offset
2111 // 64 bits : client id
2112 // = 128 bits (16 bytes)
2113 uint64_t *p
= (uint64_t*)buf
;
2114 while ((char*)p
< buf
+ wrsize
) {
2115 *p
= (uint64_t)i
*(uint64_t)wrsize
+ (uint64_t)((char*)p
- buf
);
2117 *p
= client
->get_nodeid().v
;
2121 client
->write(fd
, buf
, wrsize
, i
*wrsize
);
2130 int SyntheticClient::write_batch(int nfile
, int size
, int wrsize
)
2132 for (int i
=0; i
<nfile
; i
++) {
2133 string sarg1
= get_sarg(i
);
2134 dout(0) << "Write file " << sarg1
<< dendl
;
2135 write_file(sarg1
, size
, wrsize
);
2140 // size is in MB, wrsize in bytes
2141 int SyntheticClient::read_file(const std::string
& fn
, int size
,
2142 int rdsize
, bool ignoreprint
)
2144 char *buf
= new char[rdsize
];
2145 memset(buf
, 1, rdsize
);
2146 uint64_t chunks
= (uint64_t)size
* (uint64_t)(1024*1024) / (uint64_t)rdsize
;
2147 UserPerm perms
= client
->pick_my_perms();
2149 int fd
= client
->open(fn
.c_str(), O_RDONLY
, perms
);
2150 dout(5) << "reading from " << fn
<< " fd " << fd
<< dendl
;
2156 utime_t from
= ceph_clock_now();
2157 utime_t start
= from
;
2158 uint64_t bytes
= 0, total
= 0;
2160 for (unsigned i
=0; i
<chunks
; i
++) {
2161 if (time_to_stop()) break;
2162 dout(2) << "reading block " << i
<< "/" << chunks
<< dendl
;
2163 int r
= client
->read(fd
, buf
, rdsize
, i
*rdsize
);
2165 dout(1) << "read_file got r = " << r
<< ", probably end of file" << dendl
;
2172 utime_t now
= ceph_clock_now();
2173 if (now
- from
>= 1.0) {
2174 double el
= now
- from
;
2175 dout(0) << "read " << (bytes
/ el
/ 1048576.0) << " MB/sec" << dendl
;
2180 // verify fingerprint
2182 uint64_t *p
= (uint64_t*)buf
;
2183 while ((char*)p
+ 32 < buf
+ rdsize
) {
2184 uint64_t readoff
= *p
;
2185 uint64_t wantoff
= (uint64_t)i
*(uint64_t)rdsize
+ (uint64_t)((char*)p
- buf
);
2187 int64_t readclient
= *p
;
2189 if (readoff
!= wantoff
||
2190 readclient
!= client
->get_nodeid()) {
2191 if (!bad
&& !ignoreprint
)
2192 dout(0) << "WARNING: wrong data from OSD, block says fileoffset=" << readoff
<< " client=" << readclient
2193 << ", should be offset " << wantoff
<< " client " << client
->get_nodeid()
2198 if (bad
&& !ignoreprint
)
2199 dout(0) << " + " << (bad
-1) << " other bad 16-byte bits in this block" << dendl
;
2202 utime_t stop
= ceph_clock_now();
2203 double el
= stop
- start
;
2204 dout(0) << "read total " << (total
/ el
/ 1048576.0) << " MB/sec ("
2205 << total
<< " bytes in " << el
<< " seconds)" << dendl
;
2216 class C_Ref
: public Context
{
2221 C_Ref(Mutex
&l
, Cond
&c
, int *r
) : lock(l
), cond(c
), ref(r
) {
2226 void finish(int) override
{
2234 int SyntheticClient::create_objects(int nobj
, int osize
, int inflight
)
2237 int numc
= num_client
? num_client
: 1;
2239 int start
, inc
, end
;
2243 start
= client
->get_nodeid().v
; //nobjs % numc;
2248 start
= nobj
* client
->get_nodeid().v
/ numc
;
2250 end
= nobj
* (client
->get_nodeid().v
+1) / numc
;
2253 dout(5) << "create_objects " << nobj
<< " size=" << osize
2254 << " .. doing [" << start
<< "," << end
<< ") inc " << inc
2257 bufferptr
bp(osize
);
2262 Mutex
lock("create_objects lock");
2267 list
<utime_t
> starts
;
2269 for (int i
=start
; i
<end
; i
+= inc
) {
2270 if (time_to_stop()) break;
2272 object_t oid
= file_object_t(999, i
);
2273 object_locator_t
oloc(SYNCLIENT_FIRST_POOL
);
2276 if (i
% inflight
== 0) {
2277 dout(6) << "create_objects " << i
<< "/" << (nobj
+1) << dendl
;
2279 dout(10) << "writing " << oid
<< dendl
;
2281 starts
.push_back(ceph_clock_now());
2282 client
->client_lock
.Lock();
2283 client
->objecter
->write(oid
, oloc
, 0, osize
, snapc
, bl
,
2284 ceph::real_clock::now(), 0,
2285 new C_Ref(lock
, cond
, &unsafe
));
2286 client
->client_lock
.Unlock();
2289 while (unsafe
> inflight
) {
2290 dout(20) << "waiting for " << unsafe
<< " unsafe" << dendl
;
2295 utime_t lat
= ceph_clock_now();
2296 lat
-= starts
.front();
2301 while (unsafe
> 0) {
2302 dout(10) << "waiting for " << unsafe
<< " unsafe" << dendl
;
2307 dout(5) << "create_objects done" << dendl
;
2311 int SyntheticClient::object_rw(int nobj
, int osize
, int wrpc
,
2313 double rskew
, double wskew
)
2315 dout(5) << "object_rw " << nobj
<< " size=" << osize
<< " with "
2316 << wrpc
<< "% writes"
2317 << ", " << overlappc
<< "% overlap"
2318 << ", rskew = " << rskew
2319 << ", wskew = " << wskew
2322 bufferptr
bp(osize
);
2327 // start with odd number > nobj
2329 unsigned prime
= nobj
+ 1; // this is the minimum!
2330 prime
+= h(nobj
) % (3*nobj
); // bump it up some
2331 prime
|= 1; // make it odd
2335 for (j
=2; j
*j
<=prime
; j
++)
2336 if (prime
% j
== 0) break;
2339 //cout << "prime " << prime << endl;
2350 if (time_to_stop()) break;
2353 bool write
= (rand() % 100) < wrpc
;
2356 double r
= drand48(); // [0..1)
2359 o
= (long)trunc(pow(r
, wskew
) * (double)nobj
); // exponentially skew towards 0
2360 int pnoremap
= (long)(r
* 100.0);
2361 if (pnoremap
>= overlappc
)
2362 o
= (o
*prime
) % nobj
; // remap
2364 o
= (long)trunc(pow(r
, rskew
) * (double)nobj
); // exponentially skew towards 0
2366 object_t oid
= file_object_t(999, o
);
2367 object_locator_t
oloc(SYNCLIENT_FIRST_POOL
);
2370 client
->client_lock
.Lock();
2371 utime_t start
= ceph_clock_now();
2373 dout(10) << "write to " << oid
<< dendl
;
2377 op
.op
.op
= CEPH_OSD_OP_WRITE
;
2378 op
.op
.extent
.offset
= 0;
2379 op
.op
.extent
.length
= osize
;
2381 m
.ops
.push_back(op
);
2382 client
->objecter
->mutate(oid
, oloc
, m
, snapc
,
2383 ceph::real_clock::now(), 0,
2384 new C_Ref(lock
, cond
, &unack
));
2386 dout(10) << "read from " << oid
<< dendl
;
2388 client
->objecter
->read(oid
, oloc
, 0, osize
, CEPH_NOSNAP
, &inbl
, 0,
2389 new C_Ref(lock
, cond
, &unack
));
2391 client
->client_lock
.Unlock();
2395 dout(20) << "waiting for " << unack
<< " unack" << dendl
;
2400 utime_t lat
= ceph_clock_now();
2411 int SyntheticClient::read_random(string
& fn
, int size
, int rdsize
) // size is in MB, wrsize in bytes
2413 UserPerm perms
= client
->pick_my_perms();
2414 uint64_t chunks
= (uint64_t)size
* (uint64_t)(1024*1024) / (uint64_t)rdsize
;
2415 int fd
= client
->open(fn
.c_str(), O_RDWR
, perms
);
2416 dout(5) << "reading from " << fn
<< " fd " << fd
<< dendl
;
2418 if (fd
< 0) return fd
;
2422 for (unsigned i
=0; i
<2000; i
++) {
2423 if (time_to_stop()) break;
2431 // use rand instead ??
2432 double x
= drand48();
2434 // cleanup before call 'new'
2440 buf
= new char[rdsize
];
2441 memset(buf
, 1, rdsize
);
2444 buf
= new char[rdsize
+100]; // 1 MB
2445 memset(buf
, 7, rdsize
);
2449 offset
=(rand())%(chunks
+1);
2450 dout(2) << "reading block " << offset
<< "/" << chunks
<< dendl
;
2452 int r
= client
->read(fd
, buf
, rdsize
, offset
*rdsize
);
2454 dout(1) << "read_file got r = " << r
<< ", probably end of file" << dendl
;
2457 dout(2) << "writing block " << offset
<< "/" << chunks
<< dendl
;
2459 // fill buf with a 16 byte fingerprint
2460 // 64 bits : file offset
2461 // 64 bits : client id
2462 // = 128 bits (16 bytes)
2464 offset
=(rand())%(chunks
+1);
2465 uint64_t *p
= (uint64_t*)buf
;
2466 while ((char*)p
< buf
+ rdsize
) {
2467 *p
= offset
*rdsize
+ (char*)p
- buf
;
2469 *p
= client
->get_nodeid().v
;
2473 client
->write(fd
, buf
, rdsize
,
2477 // verify fingerprint
2480 int64_t *p
= (int64_t*)buf
;
2481 while ((char*)p
+ 32 < buf
+ rdsize
) {
2482 int64_t readoff
= *p
;
2483 int64_t wantoff
= offset
*rdsize
+ (int64_t)((char*)p
- buf
);
2485 int64_t readclient
= *p
;
2487 if (readoff
!= wantoff
|| readclient
!= client
->get_nodeid()) {
2489 dout(0) << "WARNING: wrong data from OSD, block says fileoffset=" << readoff
<< " client=" << readclient
2490 << ", should be offset " << wantoff
<< " client " << client
->get_nodeid()
2496 dout(0) << " + " << (bad
-1) << " other bad 16-byte bits in this block" << dendl
;
2506 int normdist(int min
, int max
, int stdev
) /* specifies input values */
2508 /* min: Minimum value; max: Maximum value; stdev: degree of deviation */
2510 //int min, max, stdev; {
2515 int range
, iterate
, result
;
2516 /* declare range, iterate and result as integers, to avoid the need for
2517 floating point math*/
2520 /* ensure result is initialized to 0 */
2523 /* calculate range of possible values between the max and min values */
2525 iterate
= range
/ stdev
;
2526 /* this number of iterations ensures the proper shape of the resulting
2529 stdev
+= 1; /* compensation for integer vs. floating point math */
2530 for (int c
= iterate
; c
!= 0; c
--) /* loop through iterations */
2532 // result += (uniform (1, 100) * stdev) / 100; /* calculate and
2533 result
+= ( (rand()%100 + 1) * stdev
) / 100;
2534 // printf("result=%d\n", result );
2536 printf("\n final result=%d\n", result
);
2537 return result
+ min
; /* send final result back */
2540 int SyntheticClient::read_random_ex(string
& fn
, int size
, int rdsize
) // size is in MB, wrsize in bytes
2542 uint64_t chunks
= (uint64_t)size
* (uint64_t)(1024*1024) / (uint64_t)rdsize
;
2543 UserPerm perms
= client
->pick_my_perms();
2544 int fd
= client
->open(fn
.c_str(), O_RDWR
, perms
);
2545 dout(5) << "reading from " << fn
<< " fd " << fd
<< dendl
;
2547 if (fd
< 0) return fd
;
2551 for (unsigned i
=0; i
<2000; i
++) {
2552 if (time_to_stop()) break;
2560 // use rand instead ??
2561 double x
= drand48();
2563 // cleanup before call 'new'
2569 buf
= new char[rdsize
];
2570 memset(buf
, 1, rdsize
);
2573 buf
= new char[rdsize
+100]; // 1 MB
2574 memset(buf
, 7, rdsize
);
2578 dout(2) << "reading block " << offset
<< "/" << chunks
<< dendl
;
2580 int r
= client
->read(fd
, buf
, rdsize
,
2583 dout(1) << "read_file got r = " << r
<< ", probably end of file" << dendl
;
2586 dout(2) << "writing block " << offset
<< "/" << chunks
<< dendl
;
2588 // fill buf with a 16 byte fingerprint
2589 // 64 bits : file offset
2590 // 64 bits : client id
2591 // = 128 bits (16 bytes)
2593 int count
= rand()%10;
2595 for ( int j
=0;j
<count
; j
++ ) {
2596 offset
=(rand())%(chunks
+1);
2597 uint64_t *p
= (uint64_t*)buf
;
2598 while ((char*)p
< buf
+ rdsize
) {
2599 *p
= offset
*rdsize
+ (char*)p
- buf
;
2601 *p
= client
->get_nodeid().v
;
2605 client
->write(fd
, buf
, rdsize
, offset
*rdsize
);
2609 // verify fingerprint
2612 int64_t *p
= (int64_t*)buf
;
2613 while ((char*)p
+ 32 < buf
+ rdsize
) {
2614 int64_t readoff
= *p
;
2615 int64_t wantoff
= offset
*rdsize
+ (int64_t)((char*)p
- buf
);
2617 int64_t readclient
= *p
;
2619 if (readoff
!= wantoff
|| readclient
!= client
->get_nodeid()) {
2621 dout(0) << "WARNING: wrong data from OSD, block says fileoffset=" << readoff
<< " client=" << readclient
2622 << ", should be offset " << wantoff
<< " client " << client
->get_nodeid()
2628 dout(0) << " + " << (bad
-1) << " other bad 16-byte bits in this block" << dendl
;
2639 int SyntheticClient::random_walk(int num_req
)
2643 //dout(1) << "random_walk() will do " << left << " ops" << dendl;
2645 init_op_dist(); // set up metadata op distribution
2647 UserPerm perms
= client
->pick_my_perms();
2651 if (time_to_stop()) break;
2654 if (cwd
.depth() && !roll_die(::pow((double).9, (double)cwd
.depth()))) {
2655 dout(DBL
) << "die says up" << dendl
;
2661 if (roll_die(::pow((double).9,(double)cwd
.depth())) && !subdirs
.empty()) {
2662 string s
= get_random_subdir();
2663 cwd
.push_dentry( s
);
2664 dout(DBL
) << "cd " << s
<< " -> " << cwd
<< dendl
;
2672 if (contents
.empty() && roll_die(.3)) {
2674 dout(DBL
) << "empty dir, up" << dendl
;
2677 op
= CEPH_MDS_OP_READDIR
;
2679 op
= op_dist
.sample();
2681 //dout(DBL) << "op is " << op << dendl;
2686 if (op
== CEPH_MDS_OP_UNLINK
) {
2687 if (contents
.empty())
2688 op
= CEPH_MDS_OP_READDIR
;
2690 r
= client
->unlink(get_random_sub(), perms
); // will fail on dirs
2693 if (op
== CEPH_MDS_OP_RENAME
) {
2694 if (contents
.empty())
2695 op
= CEPH_MDS_OP_READDIR
;
2697 r
= client
->rename(get_random_sub(), make_sub("ren"), perms
);
2701 if (op
== CEPH_MDS_OP_MKDIR
) {
2702 r
= client
->mkdir(make_sub("mkdir"), 0755, perms
);
2705 if (op
== CEPH_MDS_OP_RMDIR
) {
2706 if (!subdirs
.empty())
2707 r
= client
->rmdir(get_random_subdir(), perms
);
2709 r
= client
->rmdir(cwd
.c_str(), perms
); // will pbly fail
2712 if (op
== CEPH_MDS_OP_SYMLINK
) {
2715 if (op == CEPH_MDS_OP_CHMOD) {
2716 if (contents.empty())
2717 op = CEPH_MDS_OP_READDIR;
2719 r = client->chmod(get_random_sub(), rand() & 0755, perms);
2722 if (op == CEPH_MDS_OP_CHOWN) {
2723 if (contents.empty()) r = client->chown(cwd.c_str(), rand(), rand(), perms);
2725 r = client->chown(get_random_sub(), rand(), rand(), perms);
2728 if (op == CEPH_MDS_OP_UTIME) {
2730 memset(&b, 1, sizeof(b));
2731 if (contents.empty())
2732 r = client->utime(cwd.c_str(), &b, perms);
2734 r = client->utime(get_random_sub(), &b, perms);
2737 if (op
== CEPH_MDS_OP_LINK
) {
2740 if (op
== CEPH_MDS_OP_MKNOD
) {
2741 r
= client
->mknod(make_sub("mknod"), 0644, perms
);
2744 if (op
== CEPH_MDS_OP_OPEN
) {
2745 if (contents
.empty())
2746 op
= CEPH_MDS_OP_READDIR
;
2748 r
= client
->open(get_random_sub(), O_RDONLY
, perms
);
2750 ceph_assert(open_files
.count(r
) == 0);
2751 open_files
.insert(r
);
2756 /*if (op == CEPH_MDS_OP_RELEASE) { // actually, close
2757 if (open_files.empty())
2758 op = CEPH_MDS_OP_STAT;
2760 int fh = get_random_fh();
2761 r = client->close( fh );
2762 if (r == 0) open_files.erase(fh);
2767 if (op
== CEPH_MDS_OP_GETATTR
) {
2769 if (contents
.empty()) {
2772 dout(DBL
) << "stat in empty dir, up" << dendl
;
2775 op
= CEPH_MDS_OP_MKNOD
;
2778 op
= CEPH_MDS_OP_READDIR
;
2780 r
= client
->lstat(get_random_sub(), &st
, perms
);
2783 if (op
== CEPH_MDS_OP_READDIR
) {
2787 r
= client
->getdir(cwd
.c_str(), c
, perms
);
2789 for (list
<string
>::iterator it
= c
.begin();
2792 //dout(DBL) << " got " << *it << dendl;
2794 /*contents[*it] = it->second;
2796 S_ISDIR(it->second->st_mode))
2797 subdirs.insert(*it);
2807 //while (cwd.depth()) {
2808 //if (client->lookup(cwd)) break; // it's in the cache
2810 //dout(DBL) << "r = " << r << ", client doesn't have " << cwd << ", cd .." << dendl;
2811 dout(DBL
) << "r = " << r
<< ", client may not have " << cwd
<< ", cd .." << dendl
;
2818 dout(DBL
) << "closing files" << dendl
;
2819 while (!open_files
.empty()) {
2820 int fh
= get_random_fh();
2821 int r
= client
->close( fh
);
2822 if (r
== 0) open_files
.erase(fh
);
2825 dout(DBL
) << "done" << dendl
;
2832 void SyntheticClient::make_dir_mess(const char *basedir
, int n
)
2834 UserPerm perms
= client
->pick_my_perms();
2835 vector
<string
> dirs
;
2837 dirs
.push_back(basedir
);
2838 dirs
.push_back(basedir
);
2840 client
->mkdir(basedir
, 0755, perms
);
2843 // P(dir) ~ subdirs_of(dir) + 2
2844 // from 5-year metadata workload paper in fast'07
2847 for (int i
=0; i
<n
; i
++) {
2849 int k
= rand() % dirs
.size();
2850 string parent
= dirs
[k
];
2853 std::stringstream ss
;
2854 ss
<< parent
<< "/" << i
;
2855 string dir
= ss
.str();
2858 dirs
.push_back(parent
);
2859 dirs
.push_back(dir
);
2860 dirs
.push_back(dir
);
2863 client
->mkdir(dir
.c_str(), 0755, perms
);
2871 void SyntheticClient::foo()
2873 UserPerm perms
= client
->pick_my_perms();
2876 // make 2 parallel dirs, link/unlink between them.
2877 char a
[100], b
[100];
2878 client
->mkdir("/a", 0755, perms
);
2879 client
->mkdir("/b", 0755, perms
);
2880 for (int i
=0; i
<10; i
++) {
2881 snprintf(a
, sizeof(a
), "/a/%d", i
);
2882 client
->mknod(a
, 0644, perms
);
2885 for (int i
=0; i
<10; i
++) {
2886 snprintf(a
, sizeof(a
), "/a/%d", i
);
2887 snprintf(b
, sizeof(b
), "/b/%d", i
);
2888 client
->link(a
, b
, perms
);
2890 for (int i
=0; i
<10; i
++) {
2891 snprintf(b
, sizeof(b
), "/b/%d", i
);
2892 client
->unlink(b
, perms
);
2899 const char *fn
= "blah";
2901 client
->unlink(fn
, perms
);
2902 int handle
= client
->open(fn
, O_CREAT
|O_RDWR
, perms
, S_IRWXU
);
2903 ceph_assert(handle
>=0);
2904 int r
=client
->write(handle
,buffer
,8192);
2906 r
=client
->close(handle
);
2909 handle
= client
->open(fn
, O_RDWR
, perms
); // open the same file, it must have some data already
2910 ceph_assert(handle
>=0);
2911 r
=client
->read(handle
,buffer
,8192);
2912 ceph_assert(r
==8192); // THIS ASSERTION FAILS with disabled cache
2913 r
=client
->close(handle
);
2919 dout(0) << "first" << dendl
;
2920 int fd
= client
->open("tester", O_WRONLY
|O_CREAT
, perms
);
2921 client
->write(fd
, "hi there", 0, 8);
2923 dout(0) << "sleep" << dendl
;
2925 dout(0) << "again" << dendl
;
2926 fd
= client
->open("tester", O_WRONLY
|O_CREAT
, perms
);
2927 client
->write(fd
, "hi there", 0, 8);
2934 for (int i
=0; i
<20; i
++) {
2940 snprintf(src
, sizeof(src
), "syn.0.0/dir.%d/dir.%d/file.%d", a
, b
, c
);
2942 client
->open(src
, O_RDONLY
, perms
);
2950 for (int i
=0; i
<100; i
++) {
2960 snprintf(src
, sizeof(src
), "syn.0.0/dir.%d/dir.%d/file.%d", a
, b
, c
);
2961 snprintf(dst
, sizeof(dst
), "syn.0.0/dir.%d/dir.%d/file.%d", d
, e
, f
);
2962 client
->rename(src
, dst
, perms
);
2970 for (int i
=0; i
<100; i
++) {
2980 snprintf(src
, sizeof(src
), "syn.0.0/dir.%d/dir.%d/file.%d", a
, b
, c
);
2981 snprintf(dst
, sizeof(dst
), "syn.0.0/dir.%d/dir.%d/newlink.%d", d
, e
, f
);
2982 client
->link(src
, dst
, perms
);
2985 for (int i
=0; i
<100; i
++) {
2995 snprintf(src
, sizeof(src
), "syn.0.0/dir.%d/dir.%d/file.%d", a
, b
, c
);
2996 snprintf(dst
, sizeof(dst
), "syn.0.0/dir.%d/dir.%d/newlink.%d", d
, e
, f
);
2997 client
->unlink(dst
, perms
);
3005 client
->mknod("one", 0755, perms
);
3006 client
->mknod("two", 0755, perms
);
3007 client
->link("one", "three", perms
);
3008 client
->mkdir("dir", 0755, perms
);
3009 client
->link("two", "/dir/twolink", perms
);
3010 client
->link("dir/twolink", "four", perms
);
3013 client
->mknod("a", 0644, perms
);
3014 client
->unlink("a", perms
);
3015 client
->mknod("b", 0644, perms
);
3016 client
->link("b", "c", perms
);
3017 client
->unlink("c", perms
);
3018 client
->mkdir("d", 0755, perms
);
3019 client
->unlink("d", perms
);
3020 client
->rmdir("d", perms
);
3023 client
->mknod("p1", 0644, perms
);
3024 client
->mknod("p2", 0644, perms
);
3025 client
->rename("p1","p2", perms
);
3026 client
->mknod("p3", 0644, perms
);
3027 client
->rename("p3","p4", perms
);
3029 // check dest dir ambiguity thing
3030 client
->mkdir("dir1", 0755, perms
);
3031 client
->mkdir("dir2", 0755, perms
);
3032 client
->rename("p2", "dir1/p2", perms
);
3033 client
->rename("dir1/p2", "dir2/p2", perms
);
3034 client
->rename("dir2/p2", "/p2", perms
);
3036 // check primary+remote link merging
3037 client
->link("p2","p2.l", perms
);
3038 client
->link("p4","p4.l", perms
);
3039 client
->rename("p2.l", "p2", perms
);
3040 client
->rename("p4", "p4.l", perms
);
3042 // check anchor updates
3043 client
->mknod("dir1/a", 0644, perms
);
3044 client
->link("dir1/a", "da1", perms
);
3045 client
->link("dir1/a", "da2", perms
);
3046 client
->link("da2","da3", perms
);
3047 client
->rename("dir1/a", "dir2/a", perms
);
3048 client
->rename("dir2/a", "da2", perms
);
3049 client
->rename("da1", "da2", perms
);
3050 client
->rename("da2", "da3", perms
);
3052 // check directory renames
3053 client
->mkdir("dir3", 0755, perms
);
3054 client
->mknod("dir3/asdf", 0644, perms
);
3055 client
->mkdir("dir4", 0755, perms
);
3056 client
->mkdir("dir5", 0755, perms
);
3057 client
->mknod("dir5/asdf", 0644, perms
);
3058 client
->rename("dir3", "dir4", perms
); // ok
3059 client
->rename("dir4", "dir5", perms
); // fail
3062 int SyntheticClient::thrash_links(const char *basedir
, int dirs
, int files
, int depth
, int n
)
3064 dout(1) << "thrash_links " << basedir
<< " " << dirs
<< " " << files
<< " " << depth
3068 if (time_to_stop()) return 0;
3070 UserPerm perms
= client
->pick_my_perms();
3074 bool renames
= true; // thrash renames too?
3075 for (int k
=0; k
<n
; k
++) {
3077 if (renames
&& rand() % 10 == 0) {
3078 // rename some directories. whee!
3079 int dep
= (rand() % depth
) + 1;
3080 string src
= basedir
;
3083 for (int d
=0; d
<dep
; d
++) {
3084 int a
= rand() % dirs
;
3085 snprintf(t
, sizeof(t
), "/dir.%d", a
);
3089 string dst
= basedir
;
3092 for (int d
=0; d
<dep
; d
++) {
3093 int a
= rand() % dirs
;
3094 snprintf(t
, sizeof(t
), "/dir.%d", a
);
3099 if (client
->rename(dst
.c_str(), "/tmp", perms
) == 0) {
3100 client
->rename(src
.c_str(), dst
.c_str(), perms
);
3101 client
->rename("/tmp", src
.c_str(), perms
);
3107 string src
= basedir
;
3110 for (int d
=0; d
<depth
; d
++) {
3111 int a
= rand() % dirs
;
3112 snprintf(t
, sizeof(t
), "/dir.%d", a
);
3115 int a
= rand() % files
;
3116 snprintf(t
, sizeof(t
), "/file.%d", a
);
3119 string dst
= basedir
;
3122 for (int d
=0; d
<depth
; d
++) {
3123 int a
= rand() % dirs
;
3124 snprintf(t
, sizeof(t
), "/dir.%d", a
);
3127 int a
= rand() % files
;
3128 snprintf(t
, sizeof(t
), "/file.%d", a
);
3135 client
->mknod(src
.c_str(), 0755, perms
);
3136 if (renames
) client
->rename(src
.c_str(), dst
.c_str(), perms
);
3139 client
->mknod(src
.c_str(), 0755, perms
);
3140 client
->unlink(dst
.c_str(), perms
);
3141 client
->link(src
.c_str(), dst
.c_str(), perms
);
3143 case 2: client
->unlink(src
.c_str(), perms
); break;
3144 case 3: client
->unlink(dst
.c_str(), perms
); break;
3145 //case 4: client->mknod(src.c_str(), 0755, perms); break;
3146 //case 5: client->mknod(dst.c_str(), 0755, perms); break;
3154 for (int i
=0; i
<n
; i
++) {
3155 if (time_to_stop()) return 0;
3160 string file
= basedir
;
3163 int d
= rand() % (depth
+1);
3164 for (int k
=0; k
<d
; k
++) {
3165 snprintf(f
, sizeof(f
), "/dir.%d", rand() % dirs
);
3169 snprintf(f
, sizeof(f
), "/file.%d", rand() % files
);
3172 // pick a dir for our link
3173 string ln
= basedir
;
3175 int d
= rand() % (depth
+1);
3176 for (int k
=0; k
<d
; k
++) {
3177 snprintf(f
, sizeof(f
), "/dir.%d", rand() % dirs
);
3181 snprintf(f
, sizeof(f
), "/ln.%d", i
);
3184 client
->link(file
.c_str(), ln
.c_str(), perms
);
3193 void SyntheticClient::import_find(const char *base
, const char *find
, bool data
)
3195 dout(1) << "import_find " << base
<< " from " << find
<< " data=" << data
<< dendl
;
3197 /* use this to gather the static trace:
3199 * find . -exec ls -dilsn --time-style=+%s \{\} \;
3201 * find . -path ./.snapshot -prune -o -exec ls -dilsn --time-style=+%s \{\} \;
3205 UserPerm process_perms
= client
->pick_my_perms();
3208 client
->mkdir(base
, 0755, process_perms
);
3211 ceph_assert(f
.is_open());
3232 f
.seekg(1, ios::cur
);
3233 getline(f
, filename
);
3234 UserPerm
perms(uid
, gid
);
3237 if (filename
== ".") continue;
3239 // remove leading ./
3240 ceph_assert(filename
[0] == '.' && filename
[1] == '/');
3241 filename
= filename
.substr(2);
3244 int sp
= filename
.find("/");
3245 if (sp
< 0) dirnum
++;
3247 //dout(0) << "leading dir " << filename << " " << dirnum << dendl;
3248 if (dirnum
% num_client
!= client
->get_nodeid()) {
3249 dout(20) << "skipping leading dir " << dirnum
<< " " << filename
<< dendl
;
3254 ceph_assert(modestring
.length() == 10);
3256 switch (modestring
[0]) {
3257 case 'd': mode
|= S_IFDIR
; break;
3258 case 'l': mode
|= S_IFLNK
; break;
3260 case '-': mode
|= S_IFREG
; break;
3262 if (modestring
[1] == 'r') mode
|= 0400;
3263 if (modestring
[2] == 'w') mode
|= 0200;
3264 if (modestring
[3] == 'x') mode
|= 0100;
3265 if (modestring
[4] == 'r') mode
|= 040;
3266 if (modestring
[5] == 'w') mode
|= 020;
3267 if (modestring
[6] == 'x') mode
|= 010;
3268 if (modestring
[7] == 'r') mode
|= 04;
3269 if (modestring
[8] == 'w') mode
|= 02;
3270 if (modestring
[9] == 'x') mode
|= 01;
3272 dout(20) << " mode " << modestring
<< " to " << oct
<< mode
<< dec
<< dendl
;
3274 if (S_ISLNK(mode
)) {
3275 // target vs destination
3276 int pos
= filename
.find(" -> ");
3277 ceph_assert(pos
> 0);
3279 if (base
[0] != '-') {
3283 link
+= filename
.substr(0, pos
);
3285 if (filename
[pos
+4] == '/') {
3288 target
+= filename
.substr(pos
+ 4);
3290 target
= filename
.substr(pos
+ 4);
3292 dout(10) << "symlink from '" << link
<< "' -> '" << target
<< "'" << dendl
;
3293 client
->symlink(target
.c_str(), link
.c_str(), perms
);
3296 if (base
[0] != '-') {
3301 if (S_ISDIR(mode
)) {
3302 client
->mkdir(f
.c_str(), mode
, perms
);
3304 int fd
= client
->open(f
.c_str(), O_WRONLY
|O_CREAT
, perms
, mode
& 0777);
3305 ceph_assert(fd
> 0);
3307 client
->write(fd
, "", 0, size
);
3309 client
->truncate(f
.c_str(), size
, perms
);
3313 //client->chmod(f.c_str(), mode & 0777, perms, process_perms);
3314 client
->chown(f
.c_str(), uid
, gid
, process_perms
);
3319 client
->utime(f
.c_str(), &ut
, perms
);
3328 int SyntheticClient::lookup_hash(inodeno_t ino
, inodeno_t dirino
,
3329 const char *name
, const UserPerm
& perms
)
3331 int r
= client
->lookup_hash(ino
, dirino
, name
, perms
);
3332 dout(0) << "lookup_hash(" << ino
<< ", #" << dirino
<< "/" << name
<< ") = " << r
<< dendl
;
3336 int SyntheticClient::lookup_ino(inodeno_t ino
, const UserPerm
& perms
)
3338 int r
= client
->lookup_ino(ino
, perms
);
3339 dout(0) << "lookup_ino(" << ino
<< ") = " << r
<< dendl
;
3343 int SyntheticClient::chunk_file(string
&filename
)
3345 UserPerm perms
= client
->pick_my_perms();
3346 int fd
= client
->open(filename
.c_str(), O_RDONLY
, perms
);
3351 int ret
= client
->fstat(fd
, &st
, perms
);
3356 uint64_t size
= st
.st_size
;
3357 dout(0) << "file " << filename
<< " size is " << size
<< dendl
;
3360 inode
.ino
= st
.st_ino
;
3361 ret
= client
->fdescribe_layout(fd
, &inode
.layout
);
3362 ceph_assert(ret
== 0); // otherwise fstat did a bad thing
3365 bufferlist from_before
;
3366 while (pos
< size
) {
3367 int get
= std::min
<int>(size
- pos
, 1048576);
3369 Mutex
flock("synclient chunk_file lock");
3375 Context
*onfinish
= new C_SafeCond(&flock
, &cond
, &done
);
3376 client
->filer
->read(inode
.ino
, &inode
.layout
, CEPH_NOSNAP
, pos
, get
, &bl
, 0,
3382 dout(0) << "got " << bl
.length() << " bytes at " << pos
<< dendl
;
3384 if (from_before
.length()) {
3385 dout(0) << " including bit from previous block" << dendl
;
3386 pos
-= from_before
.length();
3387 from_before
.claim_append(bl
);
3388 bl
.swap(from_before
);
3393 // keep last 32 bytes around
3394 from_before
.clear();
3395 from_before
.substr_of(bl
, bl
.length()-32, 32);
3406 void SyntheticClient::mksnap(const char *base
, const char *name
, const UserPerm
& perms
)
3408 client
->mksnap(base
, name
, perms
);
3411 void SyntheticClient::rmsnap(const char *base
, const char *name
, const UserPerm
& perms
)
3413 client
->rmsnap(base
, name
, perms
);
3416 void SyntheticClient::mksnapfile(const char *dir
)
3418 UserPerm perms
= client
->pick_my_perms();
3419 client
->mkdir(dir
, 0755, perms
);
3423 int fd
= client
->open(f
.c_str(), O_WRONLY
|O_CREAT
|O_TRUNC
, perms
);
3425 char buf
[1048576*4];
3426 client
->write(fd
, buf
, sizeof(buf
), 0);
3427 client
->fsync(fd
, true);
3432 client
->mkdir(s
.c_str(), 0755, perms
);
3434 fd
= client
->open(f
.c_str(), O_WRONLY
, perms
);
3435 client
->write(fd
, buf
, 1048576*2, 1048576);
3436 client
->fsync(fd
, true);