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 ceph::mutex lock
= ceph::make_mutex("synclient foo");
1049 ceph::condition_variable cond
;
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
);
1453 std::unique_lock locker
{lock
};
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 cond
.wait(locker
, [&ack
] { return ack
; });
1461 else if (strcmp(op
, "o_read") == 0) {
1462 int64_t oh
= t
.get_int();
1463 int64_t ol
= t
.get_int();
1464 int64_t off
= t
.get_int();
1465 int64_t len
= t
.get_int();
1466 object_t oid
= file_object_t(oh
, ol
);
1467 object_locator_t
oloc(SYNCLIENT_FIRST_POOL
);
1468 std::unique_lock locker
{lock
};
1470 client
->objecter
->read(oid
, oloc
, off
, len
, CEPH_NOSNAP
, &bl
, 0,
1471 new C_SafeCond(lock
, cond
, &ack
));
1472 cond
.wait(locker
, [&ack
] { return ack
; });
1474 else if (strcmp(op
, "o_write") == 0) {
1475 int64_t oh
= t
.get_int();
1476 int64_t ol
= t
.get_int();
1477 int64_t off
= t
.get_int();
1478 int64_t len
= t
.get_int();
1479 object_t oid
= file_object_t(oh
, ol
);
1480 object_locator_t
oloc(SYNCLIENT_FIRST_POOL
);
1481 std::unique_lock locker
{lock
};
1486 client
->objecter
->write(oid
, oloc
, off
, len
, snapc
, bl
,
1487 ceph::real_clock::now(), 0,
1488 new C_SafeCond(lock
, cond
, &ack
));
1489 cond
.wait(locker
, [&ack
] { return ack
; });
1491 else if (strcmp(op
, "o_zero") == 0) {
1492 int64_t oh
= t
.get_int();
1493 int64_t ol
= t
.get_int();
1494 int64_t off
= t
.get_int();
1495 int64_t len
= t
.get_int();
1496 object_t oid
= file_object_t(oh
, ol
);
1497 object_locator_t
oloc(SYNCLIENT_FIRST_POOL
);
1498 std::unique_lock locker
{lock
};
1500 client
->objecter
->zero(oid
, oloc
, off
, len
, snapc
,
1501 ceph::real_clock::now(), 0,
1502 new C_SafeCond(lock
, cond
, &ack
));
1503 cond
.wait(locker
, [&ack
] { return ack
; });
1508 dout(0) << (t
.get_line()-1) << ": *** trace hit unrecognized symbol '" << op
<< "' " << dendl
;
1513 dout(10) << "trace finished on line " << t
.get_line() << dendl
;
1516 for (ceph::unordered_map
<int64_t, int64_t>::iterator fi
= open_files
.begin();
1517 fi
!= open_files
.end();
1519 dout(1) << "leftover close " << fi
->second
<< dendl
;
1520 if (fi
->second
> 0) client
->close(fi
->second
);
1522 for (ceph::unordered_map
<int64_t, dir_result_t
*>::iterator fi
= open_dirs
.begin();
1523 fi
!= open_dirs
.end();
1525 dout(1) << "leftover closedir " << fi
->second
<< dendl
;
1526 if (fi
->second
!= 0) client
->closedir(fi
->second
);
1528 for (ceph::unordered_map
<int64_t,Fh
*>::iterator fi
= ll_files
.begin();
1529 fi
!= ll_files
.end();
1531 dout(1) << "leftover ll_release " << fi
->second
<< dendl
;
1532 if (fi
->second
) client
->ll_release(fi
->second
);
1534 for (ceph::unordered_map
<int64_t,dir_result_t
*>::iterator fi
= ll_dirs
.begin();
1535 fi
!= ll_dirs
.end();
1537 dout(1) << "leftover ll_releasedir " << fi
->second
<< dendl
;
1538 if (fi
->second
) client
->ll_releasedir(fi
->second
);
1546 int SyntheticClient::clean_dir(string
& basedir
)
1549 list
<string
> contents
;
1550 UserPerm perms
= client
->pick_my_perms();
1551 int r
= client
->getdir(basedir
.c_str(), contents
, perms
);
1553 dout(1) << "getdir on " << basedir
<< " returns " << r
<< dendl
;
1557 for (list
<string
>::iterator it
= contents
.begin();
1558 it
!= contents
.end();
1560 if (*it
== ".") continue;
1561 if (*it
== "..") continue;
1562 string file
= basedir
+ "/" + *it
;
1564 if (time_to_stop()) break;
1567 int r
= client
->lstat(file
.c_str(), &st
, perms
);
1569 dout(1) << "stat error on " << file
<< " r=" << r
<< dendl
;
1573 if ((st
.st_mode
& S_IFMT
) == S_IFDIR
) {
1575 client
->rmdir(file
.c_str(), perms
);
1577 client
->unlink(file
.c_str(), perms
);
1586 int SyntheticClient::full_walk(string
& basedir
)
1588 if (time_to_stop()) return -1;
1591 list
<frag_info_t
> statq
;
1592 dirq
.push_back(basedir
);
1594 statq
.push_back(empty
);
1596 ceph::unordered_map
<inodeno_t
, int> nlink
;
1597 ceph::unordered_map
<inodeno_t
, int> nlink_seen
;
1599 UserPerm perms
= client
->pick_my_perms();
1600 while (!dirq
.empty()) {
1601 string dir
= dirq
.front();
1602 frag_info_t expect
= statq
.front();
1606 frag_info_t actual
= empty
;
1609 list
<string
> contents
;
1610 int r
= client
->getdir(dir
.c_str(), contents
, perms
);
1612 dout(1) << "getdir on " << dir
<< " returns " << r
<< dendl
;
1616 for (list
<string
>::iterator it
= contents
.begin();
1617 it
!= contents
.end();
1622 string file
= dir
+ "/" + *it
;
1625 frag_info_t dirstat
;
1626 int r
= client
->lstat(file
.c_str(), &st
, perms
, &dirstat
);
1628 dout(1) << "stat error on " << file
<< " r=" << r
<< dendl
;
1632 nlink_seen
[st
.st_ino
]++;
1633 nlink
[st
.st_ino
] = st
.st_nlink
;
1635 if (S_ISDIR(st
.st_mode
))
1641 char *tm
= ctime(&st
.st_mtime
);
1642 tm
[strlen(tm
)-1] = 0;
1643 printf("%llx %c%c%c%c%c%c%c%c%c%c %2d %5d %5d %8llu %12s %s\n",
1644 (long long)st
.st_ino
,
1645 S_ISDIR(st
.st_mode
) ? 'd':'-',
1646 (st
.st_mode
& 0400) ? 'r':'-',
1647 (st
.st_mode
& 0200) ? 'w':'-',
1648 (st
.st_mode
& 0100) ? 'x':'-',
1649 (st
.st_mode
& 040) ? 'r':'-',
1650 (st
.st_mode
& 020) ? 'w':'-',
1651 (st
.st_mode
& 010) ? 'x':'-',
1652 (st
.st_mode
& 04) ? 'r':'-',
1653 (st
.st_mode
& 02) ? 'w':'-',
1654 (st
.st_mode
& 01) ? 'x':'-',
1656 (int)st
.st_uid
, (int)st
.st_gid
,
1657 (long long unsigned)st
.st_size
,
1662 if ((st
.st_mode
& S_IFMT
) == S_IFDIR
) {
1663 dirq
.push_back(file
);
1664 statq
.push_back(dirstat
);
1669 (actual
.nsubdirs
!= expect
.nsubdirs
||
1670 actual
.nfiles
!= expect
.nfiles
)) {
1671 dout(0) << dir
<< ": expected " << expect
<< dendl
;
1672 dout(0) << dir
<< ": got " << actual
<< dendl
;
1676 for (ceph::unordered_map
<inodeno_t
,int>::iterator p
= nlink
.begin(); p
!= nlink
.end(); ++p
) {
1677 if (nlink_seen
[p
->first
] != p
->second
)
1678 dout(0) << p
->first
<< " nlink " << p
->second
<< " != " << nlink_seen
[p
->first
] << "seen" << dendl
;
1686 int SyntheticClient::dump_placement(string
& fn
) {
1688 UserPerm perms
= client
->pick_my_perms();
1691 int fd
= client
->open(fn
.c_str(), O_RDONLY
, perms
);
1692 dout(5) << "reading from " << fn
<< " fd " << fd
<< dendl
;
1693 if (fd
< 0) return fd
;
1698 int lstat_result
= client
->lstat(fn
.c_str(), &stbuf
, perms
);
1699 if (lstat_result
< 0) {
1700 dout(0) << "lstat error for file " << fn
<< dendl
;
1702 return lstat_result
;
1705 off_t filesize
= stbuf
.st_size
;
1707 // grab the placement info
1708 vector
<ObjectExtent
> extents
;
1710 client
->enumerate_layout(fd
, extents
, filesize
, offset
);
1714 // run through all the object extents
1715 dout(0) << "file size is " << filesize
<< dendl
;
1716 dout(0) << "(osd, start, length) tuples for file " << fn
<< dendl
;
1717 for (const auto& x
: extents
) {
1718 int osd
= client
->objecter
->with_osdmap([&](const OSDMap
& o
) {
1719 return o
.get_pg_acting_primary(o
.object_locator_to_pg(x
.oid
, x
.oloc
));
1722 // run through all the buffer extents
1723 for (const auto& be
: x
.buffer_extents
)
1724 dout(0) << "OSD " << osd
<< ", offset " << be
.first
1725 << ", length " << be
.second
<< dendl
;
1732 int SyntheticClient::make_dirs(const char *basedir
, int dirs
, int files
, int depth
)
1734 if (time_to_stop()) return 0;
1736 UserPerm perms
= client
->pick_my_perms();
1737 // make sure base dir exists
1738 int r
= client
->mkdir(basedir
, 0755, perms
);
1740 dout(1) << "can't make base dir? " << basedir
<< dendl
;
1746 dout(3) << "make_dirs " << basedir
<< " dirs " << dirs
<< " files " << files
<< " depth " << depth
<< dendl
;
1747 for (int i
=0; i
<files
; i
++) {
1748 snprintf(d
, sizeof(d
), "%s/file.%d", basedir
, i
);
1749 client
->mknod(d
, 0644, perms
);
1752 if (depth
== 0) return 0;
1754 for (int i
=0; i
<dirs
; i
++) {
1755 snprintf(d
, sizeof(d
), "%s/dir.%d", basedir
, i
);
1756 make_dirs(d
, dirs
, files
, depth
-1);
1762 int SyntheticClient::stat_dirs(const char *basedir
, int dirs
, int files
, int depth
)
1764 if (time_to_stop()) return 0;
1766 UserPerm perms
= client
->pick_my_perms();
1768 // make sure base dir exists
1770 int r
= client
->lstat(basedir
, &st
, perms
);
1772 dout(1) << "can't make base dir? " << basedir
<< dendl
;
1778 dout(3) << "stat_dirs " << basedir
<< " dirs " << dirs
<< " files " << files
<< " depth " << depth
<< dendl
;
1779 for (int i
=0; i
<files
; i
++) {
1780 snprintf(d
, sizeof(d
), "%s/file.%d", basedir
, i
);
1781 client
->lstat(d
, &st
, perms
);
1784 if (depth
== 0) return 0;
1786 for (int i
=0; i
<dirs
; i
++) {
1787 snprintf(d
, sizeof(d
), "%s/dir.%d", basedir
, i
);
1788 stat_dirs(d
, dirs
, files
, depth
-1);
1793 int SyntheticClient::read_dirs(const char *basedir
, int dirs
, int files
, int depth
)
1795 if (time_to_stop()) return 0;
1801 dout(3) << "read_dirs " << basedir
<< " dirs " << dirs
<< " files " << files
<< " depth " << depth
<< dendl
;
1803 list
<string
> contents
;
1804 UserPerm perms
= client
->pick_my_perms();
1805 utime_t s
= ceph_clock_now();
1806 int r
= client
->getdir(basedir
, contents
, perms
);
1807 utime_t e
= ceph_clock_now();
1810 dout(0) << "getdir couldn't readdir " << basedir
<< ", stopping" << dendl
;
1814 for (int i
=0; i
<files
; i
++) {
1815 snprintf(d
, sizeof(d
), "%s/file.%d", basedir
, i
);
1816 utime_t s
= ceph_clock_now();
1817 if (client
->lstat(d
, &st
, perms
) < 0) {
1818 dout(2) << "read_dirs failed stat on " << d
<< ", stopping" << dendl
;
1821 utime_t e
= ceph_clock_now();
1826 for (int i
=0; i
<dirs
; i
++) {
1827 snprintf(d
, sizeof(d
), "%s/dir.%d", basedir
, i
);
1828 if (read_dirs(d
, dirs
, files
, depth
-1) < 0) return -1;
1835 int SyntheticClient::make_files(int num
, int count
, int priv
, bool more
)
1837 int whoami
= client
->get_nodeid().v
;
1839 UserPerm perms
= client
->pick_my_perms();
1842 for (int c
=0; c
<count
; c
++) {
1843 snprintf(d
, sizeof(d
), "dir.%d.run%d", whoami
, c
);
1844 client
->mkdir(d
, 0755, perms
);
1848 if (true || whoami
== 0) {
1849 for (int c
=0; c
<count
; c
++) {
1850 snprintf(d
, sizeof(d
), "dir.%d.run%d", 0, c
);
1851 client
->mkdir(d
, 0755, perms
);
1860 utime_t start
= ceph_clock_now();
1861 for (int c
=0; c
<count
; c
++) {
1862 for (int n
=0; n
<num
; n
++) {
1863 snprintf(d
, sizeof(d
), "dir.%d.run%d/file.client%d.%d", priv
? whoami
:0, c
, whoami
, n
);
1865 client
->mknod(d
, 0644, perms
);
1868 client
->lstat(d
, &st
, perms
);
1869 int fd
= client
->open(d
, O_RDONLY
, perms
);
1870 client
->unlink(d
, perms
);
1874 if (time_to_stop()) return 0;
1877 utime_t end
= ceph_clock_now();
1879 dout(0) << "makefiles time is " << end
<< " or " << ((double)end
/ (double)num
) <<" per file" << dendl
;
1884 int SyntheticClient::link_test()
1889 UserPerm perms
= client
->pick_my_perms();
1894 client
->mkdir("orig", 0755, perms
);
1895 client
->mkdir("copy", 0755, perms
);
1897 utime_t start
= ceph_clock_now();
1898 for (int i
=0; i
<num
; i
++) {
1899 snprintf(d
, sizeof(d
), "orig/file.%d", i
);
1900 client
->mknod(d
, 0755, perms
);
1902 utime_t end
= ceph_clock_now();
1905 dout(0) << "orig " << end
<< dendl
;
1908 start
= ceph_clock_now();
1909 for (int i
=0; i
<num
; i
++) {
1910 snprintf(d
, sizeof(d
), "orig/file.%d", i
);
1911 snprintf(e
, sizeof(e
), "copy/file.%d", i
);
1912 client
->link(d
, e
, perms
);
1914 end
= ceph_clock_now();
1916 dout(0) << "copy " << end
<< dendl
;
1922 int SyntheticClient::create_shared(int num
)
1925 UserPerm perms
= client
->pick_my_perms();
1927 client
->mkdir("test", 0755, perms
);
1928 for (int n
=0; n
<num
; n
++) {
1929 snprintf(d
, sizeof(d
), "test/file.%d", n
);
1930 client
->mknod(d
, 0644, perms
);
1936 int SyntheticClient::open_shared(int num
, int count
)
1940 UserPerm perms
= client
->pick_my_perms();
1941 for (int c
=0; c
<count
; c
++) {
1944 for (int n
=0; n
<num
; n
++) {
1945 snprintf(d
, sizeof(d
), "test/file.%d", n
);
1946 int fd
= client
->open(d
, O_RDONLY
, perms
);
1947 if (fd
> 0) fds
.push_back(fd
);
1950 if (false && client
->get_nodeid() == 0)
1951 for (int n
=0; n
<num
; n
++) {
1952 snprintf(d
, sizeof(d
), "test/file.%d", n
);
1953 client
->unlink(d
, perms
);
1956 while (!fds
.empty()) {
1957 int fd
= fds
.front();
1967 // Hits OSD 0 with writes to various files with OSD 0 as the primary.
1968 int SyntheticClient::overload_osd_0(int n
, int size
, int wrsize
) {
1969 UserPerm perms
= client
->pick_my_perms();
1970 // collect a bunch of files starting on OSD 0
1977 dout(0) << "in OSD overload" << dendl
;
1978 string filename
= get_sarg(tried
);
1979 dout(1) << "OSD Overload workload: trying file " << filename
<< dendl
;
1980 int fd
= client
->open(filename
.c_str(), O_RDWR
|O_CREAT
, perms
);
1983 // only use the file if its first primary is OSD 0
1984 int primary_osd
= check_first_primary(fd
);
1985 if (primary_osd
!= 0) {
1987 dout(1) << "OSD Overload workload: SKIPPING file " << filename
<<
1988 " with OSD " << primary_osd
<< " as first primary. " << dendl
;
1991 dout(1) << "OSD Overload workload: USING file " << filename
<<
1992 " with OSD 0 as first primary. " << dendl
;
1996 // do whatever operation we want to do on the file. How about a write?
1997 write_fd(fd
, size
, wrsize
);
2003 // See what the primary is for the first object in this file.
2004 int SyntheticClient::check_first_primary(int fh
)
2006 vector
<ObjectExtent
> extents
;
2007 client
->enumerate_layout(fh
, extents
, 1, 0);
2008 return client
->objecter
->with_osdmap([&](const OSDMap
& o
) {
2009 return o
.get_pg_acting_primary(
2010 o
.object_locator_to_pg(extents
.begin()->oid
, extents
.begin()->oloc
));
2014 int SyntheticClient::rm_file(string
& fn
)
2016 UserPerm perms
= client
->pick_my_perms();
2017 return client
->unlink(fn
.c_str(), perms
);
2020 int SyntheticClient::write_file(string
& fn
, int size
, loff_t wrsize
) // size is in MB, wrsize in bytes
2022 //uint64_t wrsize = 1024*256;
2023 char *buf
= new char[wrsize
+100]; // 1 MB
2024 memset(buf
, 7, wrsize
);
2025 int64_t chunks
= (uint64_t)size
* (uint64_t)(1024*1024) / (uint64_t)wrsize
;
2026 UserPerm perms
= client
->pick_my_perms();
2028 int fd
= client
->open(fn
.c_str(), O_RDWR
|O_CREAT
, perms
);
2029 dout(5) << "writing to " << fn
<< " fd " << fd
<< dendl
;
2035 utime_t from
= ceph_clock_now();
2036 utime_t start
= from
;
2037 uint64_t bytes
= 0, total
= 0;
2040 for (loff_t i
=0; i
<chunks
; i
++) {
2041 if (time_to_stop()) {
2042 dout(0) << "stopping" << dendl
;
2045 dout(2) << "writing block " << i
<< "/" << chunks
<< dendl
;
2047 // fill buf with a 16 byte fingerprint
2048 // 64 bits : file offset
2049 // 64 bits : client id
2050 // = 128 bits (16 bytes)
2051 uint64_t *p
= (uint64_t*)buf
;
2052 while ((char*)p
< buf
+ wrsize
) {
2053 *p
= (uint64_t)i
*(uint64_t)wrsize
+ (uint64_t)((char*)p
- buf
);
2055 *p
= client
->get_nodeid().v
;
2059 client
->write(fd
, buf
, wrsize
, i
*wrsize
);
2063 utime_t now
= ceph_clock_now();
2064 if (now
- from
>= 1.0) {
2065 double el
= now
- from
;
2066 dout(0) << "write " << (bytes
/ el
/ 1048576.0) << " MB/sec" << dendl
;
2072 client
->fsync(fd
, true);
2074 utime_t stop
= ceph_clock_now();
2075 double el
= stop
- start
;
2076 dout(0) << "write total " << (total
/ el
/ 1048576.0) << " MB/sec ("
2077 << total
<< " bytes in " << el
<< " seconds)" << dendl
;
2085 int SyntheticClient::write_fd(int fd
, int size
, int wrsize
) // size is in MB, wrsize in bytes
2087 //uint64_t wrsize = 1024*256;
2088 char *buf
= new char[wrsize
+100]; // 1 MB
2089 memset(buf
, 7, wrsize
);
2090 uint64_t chunks
= (uint64_t)size
* (uint64_t)(1024*1024) / (uint64_t)wrsize
;
2092 //dout(5) << "SyntheticClient::write_fd: writing to fd " << fd << dendl;
2098 for (unsigned i
=0; i
<chunks
; i
++) {
2099 if (time_to_stop()) {
2100 dout(0) << "stopping" << dendl
;
2103 dout(2) << "writing block " << i
<< "/" << chunks
<< dendl
;
2105 // fill buf with a 16 byte fingerprint
2106 // 64 bits : file offset
2107 // 64 bits : client id
2108 // = 128 bits (16 bytes)
2109 uint64_t *p
= (uint64_t*)buf
;
2110 while ((char*)p
< buf
+ wrsize
) {
2111 *p
= (uint64_t)i
*(uint64_t)wrsize
+ (uint64_t)((char*)p
- buf
);
2113 *p
= client
->get_nodeid().v
;
2117 client
->write(fd
, buf
, wrsize
, i
*wrsize
);
2126 int SyntheticClient::write_batch(int nfile
, int size
, int wrsize
)
2128 for (int i
=0; i
<nfile
; i
++) {
2129 string sarg1
= get_sarg(i
);
2130 dout(0) << "Write file " << sarg1
<< dendl
;
2131 write_file(sarg1
, size
, wrsize
);
2136 // size is in MB, wrsize in bytes
2137 int SyntheticClient::read_file(const std::string
& fn
, int size
,
2138 int rdsize
, bool ignoreprint
)
2140 char *buf
= new char[rdsize
];
2141 memset(buf
, 1, rdsize
);
2142 uint64_t chunks
= (uint64_t)size
* (uint64_t)(1024*1024) / (uint64_t)rdsize
;
2143 UserPerm perms
= client
->pick_my_perms();
2145 int fd
= client
->open(fn
.c_str(), O_RDONLY
, perms
);
2146 dout(5) << "reading from " << fn
<< " fd " << fd
<< dendl
;
2152 utime_t from
= ceph_clock_now();
2153 utime_t start
= from
;
2154 uint64_t bytes
= 0, total
= 0;
2156 for (unsigned i
=0; i
<chunks
; i
++) {
2157 if (time_to_stop()) break;
2158 dout(2) << "reading block " << i
<< "/" << chunks
<< dendl
;
2159 int r
= client
->read(fd
, buf
, rdsize
, i
*rdsize
);
2161 dout(1) << "read_file got r = " << r
<< ", probably end of file" << dendl
;
2168 utime_t now
= ceph_clock_now();
2169 if (now
- from
>= 1.0) {
2170 double el
= now
- from
;
2171 dout(0) << "read " << (bytes
/ el
/ 1048576.0) << " MB/sec" << dendl
;
2176 // verify fingerprint
2178 uint64_t *p
= (uint64_t*)buf
;
2179 while ((char*)p
+ 32 < buf
+ rdsize
) {
2180 uint64_t readoff
= *p
;
2181 uint64_t wantoff
= (uint64_t)i
*(uint64_t)rdsize
+ (uint64_t)((char*)p
- buf
);
2183 int64_t readclient
= *p
;
2185 if (readoff
!= wantoff
||
2186 readclient
!= client
->get_nodeid()) {
2187 if (!bad
&& !ignoreprint
)
2188 dout(0) << "WARNING: wrong data from OSD, block says fileoffset=" << readoff
<< " client=" << readclient
2189 << ", should be offset " << wantoff
<< " client " << client
->get_nodeid()
2194 if (bad
&& !ignoreprint
)
2195 dout(0) << " + " << (bad
-1) << " other bad 16-byte bits in this block" << dendl
;
2198 utime_t stop
= ceph_clock_now();
2199 double el
= stop
- start
;
2200 dout(0) << "read total " << (total
/ el
/ 1048576.0) << " MB/sec ("
2201 << total
<< " bytes in " << el
<< " seconds)" << dendl
;
2212 class C_Ref
: public Context
{
2214 ceph::condition_variable
& cond
;
2217 C_Ref(ceph::mutex
&l
, ceph::condition_variable
&c
, int *r
)
2218 : lock(l
), cond(c
), ref(r
) {
2219 lock_guard locker
{lock
};
2222 void finish(int) override
{
2223 lock_guard locker
{lock
};
2229 int SyntheticClient::create_objects(int nobj
, int osize
, int inflight
)
2232 int numc
= num_client
? num_client
: 1;
2234 int start
, inc
, end
;
2238 start
= client
->get_nodeid().v
; //nobjs % numc;
2243 start
= nobj
* client
->get_nodeid().v
/ numc
;
2245 end
= nobj
* (client
->get_nodeid().v
+1) / numc
;
2248 dout(5) << "create_objects " << nobj
<< " size=" << osize
2249 << " .. doing [" << start
<< "," << end
<< ") inc " << inc
2252 bufferptr
bp(osize
);
2257 ceph::mutex lock
= ceph::make_mutex("create_objects lock");
2258 ceph::condition_variable cond
;
2262 list
<utime_t
> starts
;
2264 for (int i
=start
; i
<end
; i
+= inc
) {
2265 if (time_to_stop()) break;
2267 object_t oid
= file_object_t(999, i
);
2268 object_locator_t
oloc(SYNCLIENT_FIRST_POOL
);
2271 if (i
% inflight
== 0) {
2272 dout(6) << "create_objects " << i
<< "/" << (nobj
+1) << dendl
;
2274 dout(10) << "writing " << oid
<< dendl
;
2276 starts
.push_back(ceph_clock_now());
2278 std::lock_guard locker
{client
->client_lock
};
2279 client
->objecter
->write(oid
, oloc
, 0, osize
, snapc
, bl
,
2280 ceph::real_clock::now(), 0,
2281 new C_Ref(lock
, cond
, &unsafe
));
2284 std::unique_lock locker
{lock
};
2285 cond
.wait(locker
, [&unsafe
, inflight
, this] {
2286 if (unsafe
> inflight
) {
2287 dout(20) << "waiting for " << unsafe
<< " unsafe" << dendl
;
2289 return unsafe
<= inflight
;
2292 utime_t lat
= ceph_clock_now();
2293 lat
-= starts
.front();
2297 std::unique_lock locker
{lock
};
2298 cond
.wait(locker
, [&unsafe
, this] {
2300 dout(10) << "waiting for " << unsafe
<< " unsafe" << dendl
;
2305 dout(5) << "create_objects done" << dendl
;
2309 int SyntheticClient::object_rw(int nobj
, int osize
, int wrpc
,
2311 double rskew
, double wskew
)
2313 dout(5) << "object_rw " << nobj
<< " size=" << osize
<< " with "
2314 << wrpc
<< "% writes"
2315 << ", " << overlappc
<< "% overlap"
2316 << ", rskew = " << rskew
2317 << ", wskew = " << wskew
2320 bufferptr
bp(osize
);
2325 // start with odd number > nobj
2327 unsigned prime
= nobj
+ 1; // this is the minimum!
2328 prime
+= h(nobj
) % (3*nobj
); // bump it up some
2329 prime
|= 1; // make it odd
2333 for (j
=2; j
*j
<=prime
; j
++)
2334 if (prime
% j
== 0) break;
2337 //cout << "prime " << prime << endl;
2342 ceph::mutex lock
= ceph::make_mutex("lock");
2343 ceph::condition_variable cond
;
2348 if (time_to_stop()) break;
2351 bool write
= (rand() % 100) < wrpc
;
2354 double r
= drand48(); // [0..1)
2357 o
= (long)trunc(pow(r
, wskew
) * (double)nobj
); // exponentially skew towards 0
2358 int pnoremap
= (long)(r
* 100.0);
2359 if (pnoremap
>= overlappc
)
2360 o
= (o
*prime
) % nobj
; // remap
2362 o
= (long)trunc(pow(r
, rskew
) * (double)nobj
); // exponentially skew towards 0
2364 object_t oid
= file_object_t(999, o
);
2365 object_locator_t
oloc(SYNCLIENT_FIRST_POOL
);
2368 client
->client_lock
.lock();
2369 utime_t start
= ceph_clock_now();
2371 dout(10) << "write to " << oid
<< dendl
;
2375 op
.op
.op
= CEPH_OSD_OP_WRITE
;
2376 op
.op
.extent
.offset
= 0;
2377 op
.op
.extent
.length
= osize
;
2379 m
.ops
.push_back(op
);
2380 client
->objecter
->mutate(oid
, oloc
, m
, snapc
,
2381 ceph::real_clock::now(), 0,
2382 new C_Ref(lock
, cond
, &unack
));
2384 dout(10) << "read from " << oid
<< dendl
;
2386 client
->objecter
->read(oid
, oloc
, 0, osize
, CEPH_NOSNAP
, &inbl
, 0,
2387 new C_Ref(lock
, cond
, &unack
));
2389 client
->client_lock
.unlock();
2392 std::unique_lock locker
{lock
};
2393 cond
.wait(locker
, [&unack
, this] {
2395 dout(20) << "waiting for " << unack
<< " unack" << dendl
;
2401 utime_t lat
= ceph_clock_now();
2412 int SyntheticClient::read_random(string
& fn
, int size
, int rdsize
) // size is in MB, wrsize in bytes
2414 UserPerm perms
= client
->pick_my_perms();
2415 uint64_t chunks
= (uint64_t)size
* (uint64_t)(1024*1024) / (uint64_t)rdsize
;
2416 int fd
= client
->open(fn
.c_str(), O_RDWR
, perms
);
2417 dout(5) << "reading from " << fn
<< " fd " << fd
<< dendl
;
2419 if (fd
< 0) return fd
;
2423 for (unsigned i
=0; i
<2000; i
++) {
2424 if (time_to_stop()) break;
2432 // use rand instead ??
2433 double x
= drand48();
2435 // cleanup before call 'new'
2441 buf
= new char[rdsize
];
2442 memset(buf
, 1, rdsize
);
2445 buf
= new char[rdsize
+100]; // 1 MB
2446 memset(buf
, 7, rdsize
);
2450 offset
=(rand())%(chunks
+1);
2451 dout(2) << "reading block " << offset
<< "/" << chunks
<< dendl
;
2453 int r
= client
->read(fd
, buf
, rdsize
, offset
*rdsize
);
2455 dout(1) << "read_file got r = " << r
<< ", probably end of file" << dendl
;
2458 dout(2) << "writing block " << offset
<< "/" << chunks
<< dendl
;
2460 // fill buf with a 16 byte fingerprint
2461 // 64 bits : file offset
2462 // 64 bits : client id
2463 // = 128 bits (16 bytes)
2465 offset
=(rand())%(chunks
+1);
2466 uint64_t *p
= (uint64_t*)buf
;
2467 while ((char*)p
< buf
+ rdsize
) {
2468 *p
= offset
*rdsize
+ (char*)p
- buf
;
2470 *p
= client
->get_nodeid().v
;
2474 client
->write(fd
, buf
, rdsize
,
2478 // verify fingerprint
2481 int64_t *p
= (int64_t*)buf
;
2482 while ((char*)p
+ 32 < buf
+ rdsize
) {
2483 int64_t readoff
= *p
;
2484 int64_t wantoff
= offset
*rdsize
+ (int64_t)((char*)p
- buf
);
2486 int64_t readclient
= *p
;
2488 if (readoff
!= wantoff
|| readclient
!= client
->get_nodeid()) {
2490 dout(0) << "WARNING: wrong data from OSD, block says fileoffset=" << readoff
<< " client=" << readclient
2491 << ", should be offset " << wantoff
<< " client " << client
->get_nodeid()
2497 dout(0) << " + " << (bad
-1) << " other bad 16-byte bits in this block" << dendl
;
2507 int normdist(int min
, int max
, int stdev
) /* specifies input values */
2509 /* min: Minimum value; max: Maximum value; stdev: degree of deviation */
2511 //int min, max, stdev; {
2516 int range
, iterate
, result
;
2517 /* declare range, iterate and result as integers, to avoid the need for
2518 floating point math*/
2521 /* ensure result is initialized to 0 */
2524 /* calculate range of possible values between the max and min values */
2526 iterate
= range
/ stdev
;
2527 /* this number of iterations ensures the proper shape of the resulting
2530 stdev
+= 1; /* compensation for integer vs. floating point math */
2531 for (int c
= iterate
; c
!= 0; c
--) /* loop through iterations */
2533 // result += (uniform (1, 100) * stdev) / 100; /* calculate and
2534 result
+= ( (rand()%100 + 1) * stdev
) / 100;
2535 // printf("result=%d\n", result );
2537 printf("\n final result=%d\n", result
);
2538 return result
+ min
; /* send final result back */
2541 int SyntheticClient::read_random_ex(string
& fn
, int size
, int rdsize
) // size is in MB, wrsize in bytes
2543 uint64_t chunks
= (uint64_t)size
* (uint64_t)(1024*1024) / (uint64_t)rdsize
;
2544 UserPerm perms
= client
->pick_my_perms();
2545 int fd
= client
->open(fn
.c_str(), O_RDWR
, perms
);
2546 dout(5) << "reading from " << fn
<< " fd " << fd
<< dendl
;
2548 if (fd
< 0) return fd
;
2552 for (unsigned i
=0; i
<2000; i
++) {
2553 if (time_to_stop()) break;
2561 // use rand instead ??
2562 double x
= drand48();
2564 // cleanup before call 'new'
2570 buf
= new char[rdsize
];
2571 memset(buf
, 1, rdsize
);
2574 buf
= new char[rdsize
+100]; // 1 MB
2575 memset(buf
, 7, rdsize
);
2579 dout(2) << "reading block " << offset
<< "/" << chunks
<< dendl
;
2581 int r
= client
->read(fd
, buf
, rdsize
,
2584 dout(1) << "read_file got r = " << r
<< ", probably end of file" << dendl
;
2587 dout(2) << "writing block " << offset
<< "/" << chunks
<< dendl
;
2589 // fill buf with a 16 byte fingerprint
2590 // 64 bits : file offset
2591 // 64 bits : client id
2592 // = 128 bits (16 bytes)
2594 int count
= rand()%10;
2596 for ( int j
=0;j
<count
; j
++ ) {
2597 offset
=(rand())%(chunks
+1);
2598 uint64_t *p
= (uint64_t*)buf
;
2599 while ((char*)p
< buf
+ rdsize
) {
2600 *p
= offset
*rdsize
+ (char*)p
- buf
;
2602 *p
= client
->get_nodeid().v
;
2606 client
->write(fd
, buf
, rdsize
, offset
*rdsize
);
2610 // verify fingerprint
2613 int64_t *p
= (int64_t*)buf
;
2614 while ((char*)p
+ 32 < buf
+ rdsize
) {
2615 int64_t readoff
= *p
;
2616 int64_t wantoff
= offset
*rdsize
+ (int64_t)((char*)p
- buf
);
2618 int64_t readclient
= *p
;
2620 if (readoff
!= wantoff
|| readclient
!= client
->get_nodeid()) {
2622 dout(0) << "WARNING: wrong data from OSD, block says fileoffset=" << readoff
<< " client=" << readclient
2623 << ", should be offset " << wantoff
<< " client " << client
->get_nodeid()
2629 dout(0) << " + " << (bad
-1) << " other bad 16-byte bits in this block" << dendl
;
2640 int SyntheticClient::random_walk(int num_req
)
2644 //dout(1) << "random_walk() will do " << left << " ops" << dendl;
2646 init_op_dist(); // set up metadata op distribution
2648 UserPerm perms
= client
->pick_my_perms();
2652 if (time_to_stop()) break;
2655 if (cwd
.depth() && !roll_die(::pow((double).9, (double)cwd
.depth()))) {
2656 dout(DBL
) << "die says up" << dendl
;
2662 if (roll_die(::pow((double).9,(double)cwd
.depth())) && !subdirs
.empty()) {
2663 string s
= get_random_subdir();
2664 cwd
.push_dentry( s
);
2665 dout(DBL
) << "cd " << s
<< " -> " << cwd
<< dendl
;
2673 if (contents
.empty() && roll_die(.3)) {
2675 dout(DBL
) << "empty dir, up" << dendl
;
2678 op
= CEPH_MDS_OP_READDIR
;
2680 op
= op_dist
.sample();
2682 //dout(DBL) << "op is " << op << dendl;
2687 if (op
== CEPH_MDS_OP_UNLINK
) {
2688 if (contents
.empty())
2689 op
= CEPH_MDS_OP_READDIR
;
2691 r
= client
->unlink(get_random_sub(), perms
); // will fail on dirs
2694 if (op
== CEPH_MDS_OP_RENAME
) {
2695 if (contents
.empty())
2696 op
= CEPH_MDS_OP_READDIR
;
2698 r
= client
->rename(get_random_sub(), make_sub("ren"), perms
);
2702 if (op
== CEPH_MDS_OP_MKDIR
) {
2703 r
= client
->mkdir(make_sub("mkdir"), 0755, perms
);
2706 if (op
== CEPH_MDS_OP_RMDIR
) {
2707 if (!subdirs
.empty())
2708 r
= client
->rmdir(get_random_subdir(), perms
);
2710 r
= client
->rmdir(cwd
.c_str(), perms
); // will pbly fail
2713 if (op
== CEPH_MDS_OP_SYMLINK
) {
2716 if (op == CEPH_MDS_OP_CHMOD) {
2717 if (contents.empty())
2718 op = CEPH_MDS_OP_READDIR;
2720 r = client->chmod(get_random_sub(), rand() & 0755, perms);
2723 if (op == CEPH_MDS_OP_CHOWN) {
2724 if (contents.empty()) r = client->chown(cwd.c_str(), rand(), rand(), perms);
2726 r = client->chown(get_random_sub(), rand(), rand(), perms);
2729 if (op == CEPH_MDS_OP_UTIME) {
2731 memset(&b, 1, sizeof(b));
2732 if (contents.empty())
2733 r = client->utime(cwd.c_str(), &b, perms);
2735 r = client->utime(get_random_sub(), &b, perms);
2738 if (op
== CEPH_MDS_OP_LINK
) {
2741 if (op
== CEPH_MDS_OP_MKNOD
) {
2742 r
= client
->mknod(make_sub("mknod"), 0644, perms
);
2745 if (op
== CEPH_MDS_OP_OPEN
) {
2746 if (contents
.empty())
2747 op
= CEPH_MDS_OP_READDIR
;
2749 r
= client
->open(get_random_sub(), O_RDONLY
, perms
);
2751 ceph_assert(open_files
.count(r
) == 0);
2752 open_files
.insert(r
);
2757 /*if (op == CEPH_MDS_OP_RELEASE) { // actually, close
2758 if (open_files.empty())
2759 op = CEPH_MDS_OP_STAT;
2761 int fh = get_random_fh();
2762 r = client->close( fh );
2763 if (r == 0) open_files.erase(fh);
2768 if (op
== CEPH_MDS_OP_GETATTR
) {
2770 if (contents
.empty()) {
2773 dout(DBL
) << "stat in empty dir, up" << dendl
;
2776 op
= CEPH_MDS_OP_MKNOD
;
2779 op
= CEPH_MDS_OP_READDIR
;
2781 r
= client
->lstat(get_random_sub(), &st
, perms
);
2784 if (op
== CEPH_MDS_OP_READDIR
) {
2788 r
= client
->getdir(cwd
.c_str(), c
, perms
);
2790 for (list
<string
>::iterator it
= c
.begin();
2793 //dout(DBL) << " got " << *it << dendl;
2795 /*contents[*it] = it->second;
2797 S_ISDIR(it->second->st_mode))
2798 subdirs.insert(*it);
2808 //while (cwd.depth()) {
2809 //if (client->lookup(cwd)) break; // it's in the cache
2811 //dout(DBL) << "r = " << r << ", client doesn't have " << cwd << ", cd .." << dendl;
2812 dout(DBL
) << "r = " << r
<< ", client may not have " << cwd
<< ", cd .." << dendl
;
2819 dout(DBL
) << "closing files" << dendl
;
2820 while (!open_files
.empty()) {
2821 int fh
= get_random_fh();
2822 int r
= client
->close( fh
);
2823 if (r
== 0) open_files
.erase(fh
);
2826 dout(DBL
) << "done" << dendl
;
2833 void SyntheticClient::make_dir_mess(const char *basedir
, int n
)
2835 UserPerm perms
= client
->pick_my_perms();
2836 vector
<string
> dirs
;
2838 dirs
.push_back(basedir
);
2839 dirs
.push_back(basedir
);
2841 client
->mkdir(basedir
, 0755, perms
);
2844 // P(dir) ~ subdirs_of(dir) + 2
2845 // from 5-year metadata workload paper in fast'07
2848 for (int i
=0; i
<n
; i
++) {
2850 int k
= rand() % dirs
.size();
2851 string parent
= dirs
[k
];
2854 std::stringstream ss
;
2855 ss
<< parent
<< "/" << i
;
2856 string dir
= ss
.str();
2859 dirs
.push_back(parent
);
2860 dirs
.push_back(dir
);
2861 dirs
.push_back(dir
);
2864 client
->mkdir(dir
.c_str(), 0755, perms
);
2872 void SyntheticClient::foo()
2874 UserPerm perms
= client
->pick_my_perms();
2877 // make 2 parallel dirs, link/unlink between them.
2878 char a
[100], b
[100];
2879 client
->mkdir("/a", 0755, perms
);
2880 client
->mkdir("/b", 0755, perms
);
2881 for (int i
=0; i
<10; i
++) {
2882 snprintf(a
, sizeof(a
), "/a/%d", i
);
2883 client
->mknod(a
, 0644, perms
);
2886 for (int i
=0; i
<10; i
++) {
2887 snprintf(a
, sizeof(a
), "/a/%d", i
);
2888 snprintf(b
, sizeof(b
), "/b/%d", i
);
2889 client
->link(a
, b
, perms
);
2891 for (int i
=0; i
<10; i
++) {
2892 snprintf(b
, sizeof(b
), "/b/%d", i
);
2893 client
->unlink(b
, perms
);
2900 const char *fn
= "blah";
2902 client
->unlink(fn
, perms
);
2903 int handle
= client
->open(fn
, O_CREAT
|O_RDWR
, perms
, S_IRWXU
);
2904 ceph_assert(handle
>=0);
2905 int r
=client
->write(handle
,buffer
,8192);
2907 r
=client
->close(handle
);
2910 handle
= client
->open(fn
, O_RDWR
, perms
); // open the same file, it must have some data already
2911 ceph_assert(handle
>=0);
2912 r
=client
->read(handle
,buffer
,8192);
2913 ceph_assert(r
==8192); // THIS ASSERTION FAILS with disabled cache
2914 r
=client
->close(handle
);
2920 dout(0) << "first" << dendl
;
2921 int fd
= client
->open("tester", O_WRONLY
|O_CREAT
, perms
);
2922 client
->write(fd
, "hi there", 0, 8);
2924 dout(0) << "sleep" << dendl
;
2926 dout(0) << "again" << dendl
;
2927 fd
= client
->open("tester", O_WRONLY
|O_CREAT
, perms
);
2928 client
->write(fd
, "hi there", 0, 8);
2935 for (int i
=0; i
<20; i
++) {
2941 snprintf(src
, sizeof(src
), "syn.0.0/dir.%d/dir.%d/file.%d", a
, b
, c
);
2943 client
->open(src
, O_RDONLY
, perms
);
2951 for (int i
=0; i
<100; i
++) {
2961 snprintf(src
, sizeof(src
), "syn.0.0/dir.%d/dir.%d/file.%d", a
, b
, c
);
2962 snprintf(dst
, sizeof(dst
), "syn.0.0/dir.%d/dir.%d/file.%d", d
, e
, f
);
2963 client
->rename(src
, dst
, perms
);
2971 for (int i
=0; i
<100; i
++) {
2981 snprintf(src
, sizeof(src
), "syn.0.0/dir.%d/dir.%d/file.%d", a
, b
, c
);
2982 snprintf(dst
, sizeof(dst
), "syn.0.0/dir.%d/dir.%d/newlink.%d", d
, e
, f
);
2983 client
->link(src
, dst
, perms
);
2986 for (int i
=0; i
<100; i
++) {
2996 snprintf(src
, sizeof(src
), "syn.0.0/dir.%d/dir.%d/file.%d", a
, b
, c
);
2997 snprintf(dst
, sizeof(dst
), "syn.0.0/dir.%d/dir.%d/newlink.%d", d
, e
, f
);
2998 client
->unlink(dst
, perms
);
3006 client
->mknod("one", 0755, perms
);
3007 client
->mknod("two", 0755, perms
);
3008 client
->link("one", "three", perms
);
3009 client
->mkdir("dir", 0755, perms
);
3010 client
->link("two", "/dir/twolink", perms
);
3011 client
->link("dir/twolink", "four", perms
);
3014 client
->mknod("a", 0644, perms
);
3015 client
->unlink("a", perms
);
3016 client
->mknod("b", 0644, perms
);
3017 client
->link("b", "c", perms
);
3018 client
->unlink("c", perms
);
3019 client
->mkdir("d", 0755, perms
);
3020 client
->unlink("d", perms
);
3021 client
->rmdir("d", perms
);
3024 client
->mknod("p1", 0644, perms
);
3025 client
->mknod("p2", 0644, perms
);
3026 client
->rename("p1","p2", perms
);
3027 client
->mknod("p3", 0644, perms
);
3028 client
->rename("p3","p4", perms
);
3030 // check dest dir ambiguity thing
3031 client
->mkdir("dir1", 0755, perms
);
3032 client
->mkdir("dir2", 0755, perms
);
3033 client
->rename("p2", "dir1/p2", perms
);
3034 client
->rename("dir1/p2", "dir2/p2", perms
);
3035 client
->rename("dir2/p2", "/p2", perms
);
3037 // check primary+remote link merging
3038 client
->link("p2","p2.l", perms
);
3039 client
->link("p4","p4.l", perms
);
3040 client
->rename("p2.l", "p2", perms
);
3041 client
->rename("p4", "p4.l", perms
);
3043 // check anchor updates
3044 client
->mknod("dir1/a", 0644, perms
);
3045 client
->link("dir1/a", "da1", perms
);
3046 client
->link("dir1/a", "da2", perms
);
3047 client
->link("da2","da3", perms
);
3048 client
->rename("dir1/a", "dir2/a", perms
);
3049 client
->rename("dir2/a", "da2", perms
);
3050 client
->rename("da1", "da2", perms
);
3051 client
->rename("da2", "da3", perms
);
3053 // check directory renames
3054 client
->mkdir("dir3", 0755, perms
);
3055 client
->mknod("dir3/asdf", 0644, perms
);
3056 client
->mkdir("dir4", 0755, perms
);
3057 client
->mkdir("dir5", 0755, perms
);
3058 client
->mknod("dir5/asdf", 0644, perms
);
3059 client
->rename("dir3", "dir4", perms
); // ok
3060 client
->rename("dir4", "dir5", perms
); // fail
3063 int SyntheticClient::thrash_links(const char *basedir
, int dirs
, int files
, int depth
, int n
)
3065 dout(1) << "thrash_links " << basedir
<< " " << dirs
<< " " << files
<< " " << depth
3069 if (time_to_stop()) return 0;
3071 UserPerm perms
= client
->pick_my_perms();
3075 bool renames
= true; // thrash renames too?
3076 for (int k
=0; k
<n
; k
++) {
3078 if (renames
&& rand() % 10 == 0) {
3079 // rename some directories. whee!
3080 int dep
= (rand() % depth
) + 1;
3081 string src
= basedir
;
3084 for (int d
=0; d
<dep
; d
++) {
3085 int a
= rand() % dirs
;
3086 snprintf(t
, sizeof(t
), "/dir.%d", a
);
3090 string dst
= basedir
;
3093 for (int d
=0; d
<dep
; d
++) {
3094 int a
= rand() % dirs
;
3095 snprintf(t
, sizeof(t
), "/dir.%d", a
);
3100 if (client
->rename(dst
.c_str(), "/tmp", perms
) == 0) {
3101 client
->rename(src
.c_str(), dst
.c_str(), perms
);
3102 client
->rename("/tmp", src
.c_str(), perms
);
3108 string src
= basedir
;
3111 for (int d
=0; d
<depth
; d
++) {
3112 int a
= rand() % dirs
;
3113 snprintf(t
, sizeof(t
), "/dir.%d", a
);
3116 int a
= rand() % files
;
3117 snprintf(t
, sizeof(t
), "/file.%d", a
);
3120 string dst
= basedir
;
3123 for (int d
=0; d
<depth
; d
++) {
3124 int a
= rand() % dirs
;
3125 snprintf(t
, sizeof(t
), "/dir.%d", a
);
3128 int a
= rand() % files
;
3129 snprintf(t
, sizeof(t
), "/file.%d", a
);
3136 client
->mknod(src
.c_str(), 0755, perms
);
3137 if (renames
) client
->rename(src
.c_str(), dst
.c_str(), perms
);
3140 client
->mknod(src
.c_str(), 0755, perms
);
3141 client
->unlink(dst
.c_str(), perms
);
3142 client
->link(src
.c_str(), dst
.c_str(), perms
);
3144 case 2: client
->unlink(src
.c_str(), perms
); break;
3145 case 3: client
->unlink(dst
.c_str(), perms
); break;
3146 //case 4: client->mknod(src.c_str(), 0755, perms); break;
3147 //case 5: client->mknod(dst.c_str(), 0755, perms); break;
3155 for (int i
=0; i
<n
; i
++) {
3156 if (time_to_stop()) return 0;
3161 string file
= basedir
;
3164 int d
= rand() % (depth
+1);
3165 for (int k
=0; k
<d
; k
++) {
3166 snprintf(f
, sizeof(f
), "/dir.%d", rand() % dirs
);
3170 snprintf(f
, sizeof(f
), "/file.%d", rand() % files
);
3173 // pick a dir for our link
3174 string ln
= basedir
;
3176 int d
= rand() % (depth
+1);
3177 for (int k
=0; k
<d
; k
++) {
3178 snprintf(f
, sizeof(f
), "/dir.%d", rand() % dirs
);
3182 snprintf(f
, sizeof(f
), "/ln.%d", i
);
3185 client
->link(file
.c_str(), ln
.c_str(), perms
);
3194 void SyntheticClient::import_find(const char *base
, const char *find
, bool data
)
3196 dout(1) << "import_find " << base
<< " from " << find
<< " data=" << data
<< dendl
;
3198 /* use this to gather the static trace:
3200 * find . -exec ls -dilsn --time-style=+%s \{\} \;
3202 * find . -path ./.snapshot -prune -o -exec ls -dilsn --time-style=+%s \{\} \;
3206 UserPerm process_perms
= client
->pick_my_perms();
3209 client
->mkdir(base
, 0755, process_perms
);
3212 ceph_assert(f
.is_open());
3233 f
.seekg(1, ios::cur
);
3234 getline(f
, filename
);
3235 UserPerm
perms(uid
, gid
);
3238 if (filename
== ".") continue;
3240 // remove leading ./
3241 ceph_assert(filename
[0] == '.' && filename
[1] == '/');
3242 filename
= filename
.substr(2);
3245 int sp
= filename
.find("/");
3246 if (sp
< 0) dirnum
++;
3248 //dout(0) << "leading dir " << filename << " " << dirnum << dendl;
3249 if (dirnum
% num_client
!= client
->get_nodeid()) {
3250 dout(20) << "skipping leading dir " << dirnum
<< " " << filename
<< dendl
;
3255 ceph_assert(modestring
.length() == 10);
3257 switch (modestring
[0]) {
3258 case 'd': mode
|= S_IFDIR
; break;
3259 case 'l': mode
|= S_IFLNK
; break;
3261 case '-': mode
|= S_IFREG
; break;
3263 if (modestring
[1] == 'r') mode
|= 0400;
3264 if (modestring
[2] == 'w') mode
|= 0200;
3265 if (modestring
[3] == 'x') mode
|= 0100;
3266 if (modestring
[4] == 'r') mode
|= 040;
3267 if (modestring
[5] == 'w') mode
|= 020;
3268 if (modestring
[6] == 'x') mode
|= 010;
3269 if (modestring
[7] == 'r') mode
|= 04;
3270 if (modestring
[8] == 'w') mode
|= 02;
3271 if (modestring
[9] == 'x') mode
|= 01;
3273 dout(20) << " mode " << modestring
<< " to " << oct
<< mode
<< dec
<< dendl
;
3275 if (S_ISLNK(mode
)) {
3276 // target vs destination
3277 int pos
= filename
.find(" -> ");
3278 ceph_assert(pos
> 0);
3280 if (base
[0] != '-') {
3284 link
+= filename
.substr(0, pos
);
3286 if (filename
[pos
+4] == '/') {
3289 target
+= filename
.substr(pos
+ 4);
3291 target
= filename
.substr(pos
+ 4);
3293 dout(10) << "symlink from '" << link
<< "' -> '" << target
<< "'" << dendl
;
3294 client
->symlink(target
.c_str(), link
.c_str(), perms
);
3297 if (base
[0] != '-') {
3302 if (S_ISDIR(mode
)) {
3303 client
->mkdir(f
.c_str(), mode
, perms
);
3305 int fd
= client
->open(f
.c_str(), O_WRONLY
|O_CREAT
, perms
, mode
& 0777);
3306 ceph_assert(fd
> 0);
3308 client
->write(fd
, "", 0, size
);
3310 client
->truncate(f
.c_str(), size
, perms
);
3314 //client->chmod(f.c_str(), mode & 0777, perms, process_perms);
3315 client
->chown(f
.c_str(), uid
, gid
, process_perms
);
3320 client
->utime(f
.c_str(), &ut
, perms
);
3329 int SyntheticClient::lookup_hash(inodeno_t ino
, inodeno_t dirino
,
3330 const char *name
, const UserPerm
& perms
)
3332 int r
= client
->lookup_hash(ino
, dirino
, name
, perms
);
3333 dout(0) << "lookup_hash(" << ino
<< ", #" << dirino
<< "/" << name
<< ") = " << r
<< dendl
;
3337 int SyntheticClient::lookup_ino(inodeno_t ino
, const UserPerm
& perms
)
3339 int r
= client
->lookup_ino(ino
, perms
);
3340 dout(0) << "lookup_ino(" << ino
<< ") = " << r
<< dendl
;
3344 int SyntheticClient::chunk_file(string
&filename
)
3346 UserPerm perms
= client
->pick_my_perms();
3347 int fd
= client
->open(filename
.c_str(), O_RDONLY
, perms
);
3352 int ret
= client
->fstat(fd
, &st
, perms
);
3357 uint64_t size
= st
.st_size
;
3358 dout(0) << "file " << filename
<< " size is " << size
<< dendl
;
3361 inode
.ino
= st
.st_ino
;
3362 ret
= client
->fdescribe_layout(fd
, &inode
.layout
);
3363 ceph_assert(ret
== 0); // otherwise fstat did a bad thing
3366 bufferlist from_before
;
3367 while (pos
< size
) {
3368 int get
= std::min
<int>(size
- pos
, 1048576);
3370 ceph::mutex flock
= ceph::make_mutex("synclient chunk_file lock");
3371 ceph::condition_variable cond
;
3375 std::unique_lock locker
{flock
};
3376 Context
*onfinish
= new C_SafeCond(flock
, cond
, &done
);
3377 client
->filer
->read(inode
.ino
, &inode
.layout
, CEPH_NOSNAP
, pos
, get
, &bl
, 0,
3379 cond
.wait(locker
, [&done
] { return done
; });
3381 dout(0) << "got " << bl
.length() << " bytes at " << pos
<< dendl
;
3383 if (from_before
.length()) {
3384 dout(0) << " including bit from previous block" << dendl
;
3385 pos
-= from_before
.length();
3386 from_before
.claim_append(bl
);
3387 bl
.swap(from_before
);
3392 // keep last 32 bytes around
3393 from_before
.clear();
3394 from_before
.substr_of(bl
, bl
.length()-32, 32);
3405 void SyntheticClient::mksnap(const char *base
, const char *name
, const UserPerm
& perms
)
3407 client
->mksnap(base
, name
, perms
);
3410 void SyntheticClient::rmsnap(const char *base
, const char *name
, const UserPerm
& perms
)
3412 client
->rmsnap(base
, name
, perms
);
3415 void SyntheticClient::mksnapfile(const char *dir
)
3417 UserPerm perms
= client
->pick_my_perms();
3418 client
->mkdir(dir
, 0755, perms
);
3422 int fd
= client
->open(f
.c_str(), O_WRONLY
|O_CREAT
|O_TRUNC
, perms
);
3424 char buf
[1048576*4];
3425 client
->write(fd
, buf
, sizeof(buf
), 0);
3426 client
->fsync(fd
, true);
3431 client
->mkdir(s
.c_str(), 0755, perms
);
3433 fd
= client
->open(f
.c_str(), O_WRONLY
, perms
);
3434 client
->write(fd
, buf
, 1048576*2, 1048576);
3435 client
->fsync(fd
, true);