X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fclient%2FSyntheticClient.cc;fp=src%2Fceph%2Fsrc%2Fclient%2FSyntheticClient.cc;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=88574e07a202cdf0fd4b3f5fc0a38d391bd9bec4;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/client/SyntheticClient.cc b/src/ceph/src/client/SyntheticClient.cc deleted file mode 100644 index 88574e0..0000000 --- a/src/ceph/src/client/SyntheticClient.cc +++ /dev/null @@ -1,3441 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2004-2006 Sage Weil - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software - * Foundation. See file COPYING. - * - */ - -#include "include/compat.h" - -#include -#include -using namespace std; - - -#include "common/config.h" -#include "SyntheticClient.h" -#include "osdc/Objecter.h" -#include "osdc/Filer.h" - - -#include "include/filepath.h" -#include "common/perf_counters.h" - -#include -#include -#include -#include -#include -#include - -#include "common/errno.h" -#include "include/assert.h" -#include "include/cephfs/ceph_statx.h" - -#define dout_context g_ceph_context -#define dout_subsys ceph_subsys_client -#undef dout_prefix -#define dout_prefix *_dout << "client." << (whoami >= 0 ? whoami:client->get_nodeid()) << " " - -// traces -//void trace_include(SyntheticClient *syn, Client *cl, string& prefix); -//void trace_openssh(SyntheticClient *syn, Client *cl, string& prefix); - -int num_client = 1; -list syn_modes; -list syn_iargs; -list syn_sargs; -int syn_filer_flags = 0; - -void parse_syn_options(vector& args) -{ - vector nargs; - - for (unsigned i=0; iclient = client; - whoami = w; - thread_id = 0; - - did_readdir = false; - - run_only = -1; - exclude = -1; - - this->modes = syn_modes; - this->iargs = syn_iargs; - this->sargs = syn_sargs; - - run_start = ceph_clock_now(); -} - - - - -#define DBL 2 - -void *synthetic_client_thread_entry(void *ptr) -{ - SyntheticClient *sc = static_cast(ptr); - //int r = - sc->run(); - return 0;//(void*)r; -} - -string SyntheticClient::get_sarg(int seq) -{ - string a; - if (!sargs.empty()) { - a = sargs.front(); - sargs.pop_front(); - } - if (a.length() == 0 || a == "~") { - char s[30]; - snprintf(s, sizeof(s), "syn.%lld.%d", (long long)client->whoami.v, seq); - a = s; - } - return a; -} - -int SyntheticClient::run() -{ - UserPerm perms = client->pick_my_perms(); - dout(15) << "initing" << dendl; - int err = client->init(); - if (err < 0) { - dout(0) << "failed to initialize: " << cpp_strerror(err) << dendl; - return -1; - } - - dout(15) << "mounting" << dendl; - err = client->mount("", perms); - if (err < 0) { - dout(0) << "failed to mount: " << cpp_strerror(err) << dendl; - client->shutdown(); - return -1; - } - - //run_start = ceph_clock_now(client->cct); - run_until = utime_t(0,0); - dout(5) << "run" << dendl; - - int seq = 0; - - for (list::iterator it = modes.begin(); - it != modes.end(); - ++it) { - int mode = *it; - dout(3) << "mode " << mode << dendl; - - switch (mode) { - - - // WHO? - - case SYNCLIENT_MODE_ONLY: - { - run_only = iargs.front(); - iargs.pop_front(); - if (run_only == client->get_nodeid()) - dout(2) << "only " << run_only << dendl; - } - break; - case SYNCLIENT_MODE_ONLYRANGE: - { - int first = iargs.front(); - iargs.pop_front(); - int last = iargs.front(); - iargs.pop_front(); - if (first <= client->get_nodeid() && - last > client->get_nodeid()) { - run_only = client->get_nodeid(); - dout(2) << "onlyrange [" << first << ", " << last << ") includes me" << dendl; - } else - run_only = client->get_nodeid().v+1; // not me - } - break; - case SYNCLIENT_MODE_EXCLUDE: - { - exclude = iargs.front(); - iargs.pop_front(); - if (exclude == client->get_nodeid()) { - run_only = client->get_nodeid().v + 1; - dout(2) << "not running " << exclude << dendl; - } else - run_only = -1; - } - break; - - // HOW LONG? - - case SYNCLIENT_MODE_UNTIL: - { - int iarg1 = iargs.front(); - iargs.pop_front(); - if (run_me()) { - if (iarg1) { - dout(2) << "until " << iarg1 << dendl; - utime_t dur(iarg1,0); - run_until = run_start + dur; - } else { - dout(2) << "until " << iarg1 << " (no limit)" << dendl; - run_until = utime_t(0,0); - } - } - } - break; - - - // ... - - case SYNCLIENT_MODE_FOO: - if (run_me()) { - foo(); - } - did_run_me(); - break; - - case SYNCLIENT_MODE_RANDOMSLEEP: - { - int iarg1 = iargs.front(); - iargs.pop_front(); - if (run_me()) { - srand(time(0) + getpid() + client->whoami.v); - sleep(rand() % iarg1); - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_SLEEP: - { - int iarg1 = iargs.front(); - iargs.pop_front(); - if (run_me()) { - dout(2) << "sleep " << iarg1 << dendl; - sleep(iarg1); - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_SLEEPUNTIL: - { - int iarg1 = iargs.front(); - iargs.pop_front(); - if (iarg1 && run_me()) { - dout(2) << "sleepuntil " << iarg1 << dendl; - utime_t at = ceph_clock_now() - run_start; - if (at.sec() < iarg1) - sleep(iarg1 - at.sec()); - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_RANDOMWALK: - { - int iarg1 = iargs.front(); - iargs.pop_front(); - if (run_me()) { - dout(2) << "randomwalk " << iarg1 << dendl; - random_walk(iarg1); - } - did_run_me(); - } - break; - - - case SYNCLIENT_MODE_DROPCACHE: - { - client->sync_fs(); - client->drop_caches(); - } - break; - - case SYNCLIENT_MODE_DUMP: - { - string sarg1 = get_sarg(0); - if (run_me()) { - dout(2) << "placement dump " << sarg1 << dendl; - dump_placement(sarg1); - } - did_run_me(); - } - break; - - - case SYNCLIENT_MODE_MAKEDIRMESS: - { - string sarg1 = get_sarg(0); - int iarg1 = iargs.front(); iargs.pop_front(); - if (run_me()) { - dout(2) << "makedirmess " << sarg1 << " " << iarg1 << dendl; - make_dir_mess(sarg1.c_str(), iarg1); - } - did_run_me(); - } - break; - case SYNCLIENT_MODE_MAKEDIRS: - { - string sarg1 = get_sarg(seq++); - int iarg1 = iargs.front(); iargs.pop_front(); - int iarg2 = iargs.front(); iargs.pop_front(); - int iarg3 = iargs.front(); iargs.pop_front(); - if (run_me()) { - dout(2) << "makedirs " << sarg1 << " " << iarg1 << " " << iarg2 << " " << iarg3 << dendl; - make_dirs(sarg1.c_str(), iarg1, iarg2, iarg3); - } - did_run_me(); - } - break; - case SYNCLIENT_MODE_STATDIRS: - { - string sarg1 = get_sarg(0); - int iarg1 = iargs.front(); iargs.pop_front(); - int iarg2 = iargs.front(); iargs.pop_front(); - int iarg3 = iargs.front(); iargs.pop_front(); - if (run_me()) { - dout(2) << "statdirs " << sarg1 << " " << iarg1 << " " << iarg2 << " " << iarg3 << dendl; - stat_dirs(sarg1.c_str(), iarg1, iarg2, iarg3); - } - did_run_me(); - } - break; - case SYNCLIENT_MODE_READDIRS: - { - string sarg1 = get_sarg(0); - int iarg1 = iargs.front(); iargs.pop_front(); - int iarg2 = iargs.front(); iargs.pop_front(); - int iarg3 = iargs.front(); iargs.pop_front(); - if (run_me()) { - dout(2) << "readdirs " << sarg1 << " " << iarg1 << " " << iarg2 << " " << iarg3 << dendl; - read_dirs(sarg1.c_str(), iarg1, iarg2, iarg3); - } - did_run_me(); - } - break; - - - case SYNCLIENT_MODE_THRASHLINKS: - { - string sarg1 = get_sarg(0); - int iarg1 = iargs.front(); iargs.pop_front(); - int iarg2 = iargs.front(); iargs.pop_front(); - int iarg3 = iargs.front(); iargs.pop_front(); - int iarg4 = iargs.front(); iargs.pop_front(); - if (run_me()) { - dout(2) << "thrashlinks " << sarg1 << " " << iarg1 << " " << iarg2 << " " << iarg3 << dendl; - thrash_links(sarg1.c_str(), iarg1, iarg2, iarg3, iarg4); - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_LINKTEST: - { - if (run_me()) { - link_test(); - } - did_run_me(); - } - break; - - - case SYNCLIENT_MODE_MAKEFILES: - { - int num = iargs.front(); iargs.pop_front(); - int count = iargs.front(); iargs.pop_front(); - int priv = iargs.front(); iargs.pop_front(); - if (run_me()) { - dout(2) << "makefiles " << num << " " << count << " " << priv << dendl; - make_files(num, count, priv, false); - } - did_run_me(); - } - break; - case SYNCLIENT_MODE_MAKEFILES2: - { - int num = iargs.front(); iargs.pop_front(); - int count = iargs.front(); iargs.pop_front(); - int priv = iargs.front(); iargs.pop_front(); - if (run_me()) { - dout(2) << "makefiles2 " << num << " " << count << " " << priv << dendl; - make_files(num, count, priv, true); - } - did_run_me(); - } - break; - case SYNCLIENT_MODE_CREATESHARED: - { - string sarg1 = get_sarg(0); - int num = iargs.front(); iargs.pop_front(); - if (run_me()) { - dout(2) << "createshared " << num << dendl; - create_shared(num); - } - did_run_me(); - } - break; - case SYNCLIENT_MODE_OPENSHARED: - { - string sarg1 = get_sarg(0); - int num = iargs.front(); iargs.pop_front(); - int count = iargs.front(); iargs.pop_front(); - if (run_me()) { - dout(2) << "openshared " << num << dendl; - open_shared(num, count); - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_CREATEOBJECTS: - { - int count = iargs.front(); iargs.pop_front(); - int size = iargs.front(); iargs.pop_front(); - int inflight = iargs.front(); iargs.pop_front(); - if (run_me()) { - dout(2) << "createobjects " << count << " of " << size << " bytes" - << ", " << inflight << " in flight" << dendl; - create_objects(count, size, inflight); - } - did_run_me(); - } - break; - case SYNCLIENT_MODE_OBJECTRW: - { - int count = iargs.front(); iargs.pop_front(); - int size = iargs.front(); iargs.pop_front(); - int wrpc = iargs.front(); iargs.pop_front(); - int overlap = iargs.front(); iargs.pop_front(); - int rskew = iargs.front(); iargs.pop_front(); - int wskew = iargs.front(); iargs.pop_front(); - if (run_me()) { - dout(2) << "objectrw " << count << " " << size << " " << wrpc - << " " << overlap << " " << rskew << " " << wskew << dendl; - object_rw(count, size, wrpc, overlap, rskew, wskew); - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_FULLWALK: - { - string sarg1;// = get_sarg(0); - if (run_me()) { - dout(2) << "fullwalk" << sarg1 << dendl; - full_walk(sarg1); - } - did_run_me(); - } - break; - case SYNCLIENT_MODE_REPEATWALK: - { - string sarg1 = get_sarg(0); - if (run_me()) { - dout(2) << "repeatwalk " << sarg1 << dendl; - while (full_walk(sarg1) == 0) ; - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_RMFILE: - { - string sarg1 = get_sarg(0); - if (run_me()) { - rm_file(sarg1); - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_WRITEFILE: - { - string sarg1 = get_sarg(0); - int iarg1 = iargs.front(); iargs.pop_front(); - int iarg2 = iargs.front(); iargs.pop_front(); - dout(1) << "WRITING SYN CLIENT" << dendl; - if (run_me()) { - write_file(sarg1, iarg1, iarg2); - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_CHUNK: - if (run_me()) { - string sarg1 = get_sarg(0); - chunk_file(sarg1); - } - did_run_me(); - break; - - - case SYNCLIENT_MODE_OVERLOAD_OSD_0: - { - dout(1) << "OVERLOADING OSD 0" << dendl; - int iarg1 = iargs.front(); iargs.pop_front(); - int iarg2 = iargs.front(); iargs.pop_front(); - int iarg3 = iargs.front(); iargs.pop_front(); - if (run_me()) { - overload_osd_0(iarg1, iarg2, iarg3); - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_WRSHARED: - { - string sarg1 = "shared"; - int iarg1 = iargs.front(); iargs.pop_front(); - int iarg2 = iargs.front(); iargs.pop_front(); - if (run_me()) { - write_file(sarg1, iarg1, iarg2); - } - did_run_me(); - } - break; - case SYNCLIENT_MODE_READSHARED: - { - string sarg1 = "shared"; - int iarg1 = iargs.front(); iargs.pop_front(); - int iarg2 = iargs.front(); iargs.pop_front(); - if (run_me()) { - read_file(sarg1, iarg1, iarg2, true); - } - did_run_me(); - } - break; - case SYNCLIENT_MODE_WRITEBATCH: - { - int iarg1 = iargs.front(); iargs.pop_front(); - int iarg2 = iargs.front(); iargs.pop_front(); - int iarg3 = iargs.front(); iargs.pop_front(); - - if (run_me()) { - write_batch(iarg1, iarg2, iarg3); - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_READFILE: - { - string sarg1 = get_sarg(0); - int iarg1 = iargs.front(); iargs.pop_front(); - int iarg2 = iargs.front(); iargs.pop_front(); - - dout(1) << "READING SYN CLIENT" << dendl; - if (run_me()) { - read_file(sarg1, iarg1, iarg2); - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_RDWRRANDOM: - { - string sarg1 = get_sarg(0); - int iarg1 = iargs.front(); iargs.pop_front(); - int iarg2 = iargs.front(); iargs.pop_front(); - - dout(1) << "RANDOM READ WRITE SYN CLIENT" << dendl; - if (run_me()) { - read_random(sarg1, iarg1, iarg2); - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_RDWRRANDOM_EX: - { - string sarg1 = get_sarg(0); - int iarg1 = iargs.front(); iargs.pop_front(); - int iarg2 = iargs.front(); iargs.pop_front(); - - dout(1) << "RANDOM READ WRITE SYN CLIENT" << dendl; - if (run_me()) { - read_random_ex(sarg1, iarg1, iarg2); - } - did_run_me(); - } - break; - case SYNCLIENT_MODE_TRACE: - { - string tfile = get_sarg(0); - sargs.push_front(string("~")); - int iarg1 = iargs.front(); iargs.pop_front(); - int playdata = iargs.front(); iargs.pop_front(); - string prefix = get_sarg(0); - char realtfile[100]; - snprintf(realtfile, sizeof(realtfile), tfile.c_str(), (int)client->get_nodeid().v); - - if (run_me()) { - dout(0) << "trace " << tfile << " prefix=" << prefix << " count=" << iarg1 << " data=" << playdata << dendl; - - Trace t(realtfile); - - if (iarg1 == 0) iarg1 = 1; // play trace at least once! - - for (int i=0; i 1) clean_dir(prefix); // clean only if repeat - - utime_t lat = ceph_clock_now(); - lat -= start; - - dout(0) << " trace " << tfile << " loop " << (i+1) << "/" << iarg1 << " done in " << (double)lat << " seconds" << dendl; - if (client->logger - && i > 0 - && i < iarg1-1 - ) { - //client->logger->finc("trsum", (double)lat); - //client->logger->inc("trnum"); - } - } - dout(1) << "done " << dendl; - } - did_run_me(); - } - break; - - - case SYNCLIENT_MODE_OPENTEST: - { - int count = iargs.front(); iargs.pop_front(); - if (run_me()) { - for (int i=0; iopen("test", (rand()%2) ? - (O_WRONLY|O_CREAT) : O_RDONLY, - perms); - if (fd > 0) client->close(fd); - } - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_OPTEST: - { - int count = iargs.front(); iargs.pop_front(); - if (run_me()) { - client->mknod("test", 0777, perms); - struct stat st; - for (int i=0; ilstat("test", &st, perms); - client->chmod("test", 0777, perms); - } - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_TRUNCATE: - { - string file = get_sarg(0); - sargs.push_front(file); - int iarg1 = iargs.front(); iargs.pop_front(); - if (run_me()) { - client->truncate(file.c_str(), iarg1, perms); - } - did_run_me(); - } - break; - - - case SYNCLIENT_MODE_IMPORTFIND: - { - string base = get_sarg(0); - string find = get_sarg(0); - int data = get_iarg(); - if (run_me()) { - import_find(base.c_str(), find.c_str(), data); - } - did_run_me(); - } - break; - - case SYNCLIENT_MODE_LOOKUPHASH: - { - inodeno_t ino; - string iname = get_sarg(0); - sscanf(iname.c_str(), "%llx", (long long unsigned*)&ino.val); - inodeno_t dirino; - string diname = get_sarg(0); - sscanf(diname.c_str(), "%llx", (long long unsigned*)&dirino.val); - string name = get_sarg(0); - if (run_me()) { - lookup_hash(ino, dirino, name.c_str(), perms); - } - } - break; - case SYNCLIENT_MODE_LOOKUPINO: - { - inodeno_t ino; - string iname = get_sarg(0); - sscanf(iname.c_str(), "%llx", (long long unsigned*)&ino.val); - if (run_me()) { - lookup_ino(ino, perms); - } - } - break; - - case SYNCLIENT_MODE_MKSNAP: - { - string base = get_sarg(0); - string name = get_sarg(0); - if (run_me()) - mksnap(base.c_str(), name.c_str(), perms); - did_run_me(); - } - break; - case SYNCLIENT_MODE_RMSNAP: - { - string base = get_sarg(0); - string name = get_sarg(0); - if (run_me()) - rmsnap(base.c_str(), name.c_str(), perms); - did_run_me(); - } - break; - case SYNCLIENT_MODE_MKSNAPFILE: - { - string base = get_sarg(0); - if (run_me()) - mksnapfile(base.c_str()); - did_run_me(); - } - break; - - default: - ceph_abort(); - } - } - dout(1) << "syn done, unmounting " << dendl; - - client->unmount(); - client->shutdown(); - return 0; -} - - -int SyntheticClient::start_thread() -{ - assert(!thread_id); - - pthread_create(&thread_id, NULL, synthetic_client_thread_entry, this); - assert(thread_id); - ceph_pthread_setname(thread_id, "client"); - return 0; -} - -int SyntheticClient::join_thread() -{ - assert(thread_id); - void *rv; - pthread_join(thread_id, &rv); - return 0; -} - - -bool roll_die(float p) -{ - float r = (float)(rand() % 100000) / 100000.0; - if (r < p) - return true; - else - return false; -} - -void SyntheticClient::init_op_dist() -{ - op_dist.clear(); -#if 0 - op_dist.add( CEPH_MDS_OP_STAT, 610 ); - op_dist.add( CEPH_MDS_OP_UTIME, 0 ); - op_dist.add( CEPH_MDS_OP_CHMOD, 1 ); - op_dist.add( CEPH_MDS_OP_CHOWN, 1 ); -#endif - - op_dist.add( CEPH_MDS_OP_READDIR, 2 ); - op_dist.add( CEPH_MDS_OP_MKNOD, 30 ); - op_dist.add( CEPH_MDS_OP_LINK, 0 ); - op_dist.add( CEPH_MDS_OP_UNLINK, 20 ); - op_dist.add( CEPH_MDS_OP_RENAME, 40 ); - - op_dist.add( CEPH_MDS_OP_MKDIR, 10 ); - op_dist.add( CEPH_MDS_OP_RMDIR, 20 ); - op_dist.add( CEPH_MDS_OP_SYMLINK, 20 ); - - op_dist.add( CEPH_MDS_OP_OPEN, 200 ); - //op_dist.add( CEPH_MDS_OP_READ, 0 ); - //op_dist.add( CEPH_MDS_OP_WRITE, 0 ); - //op_dist.add( CEPH_MDS_OP_TRUNCATE, 0 ); - //op_dist.add( CEPH_MDS_OP_FSYNC, 0 ); - //op_dist.add( CEPH_MDS_OP_RELEASE, 200 ); - op_dist.normalize(); -} - -void SyntheticClient::up() -{ - cwd = cwd.prefixpath(cwd.depth()-1); - dout(DBL) << "cd .. -> " << cwd << dendl; - clear_dir(); -} - -int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only) -{ - dout(4) << "play trace prefix '" << prefix << "'" << dendl; - UserPerm perms = client->pick_my_perms(); - t.start(); - - string buf; - string buf2; - - utime_t start = ceph_clock_now(); - - ceph::unordered_map open_files; - ceph::unordered_map open_dirs; - - ceph::unordered_map ll_files; - ceph::unordered_map ll_dirs; - ceph::unordered_map ll_inos; - - Inode *i1, *i2; - - ll_inos[1] = 1; // root inode is known. - - // prefix? - const char *p = prefix.c_str(); - if (prefix.length()) { - client->mkdir(prefix.c_str(), 0755, perms); - struct ceph_statx stx; - i1 = client->ll_get_inode(vinodeno_t(1, CEPH_NOSNAP)); - if (client->ll_lookupx(i1, prefix.c_str(), &i2, &stx, CEPH_STATX_INO, 0, perms) == 0) { - ll_inos[1] = stx.stx_ino; - dout(5) << "'root' ino is " << inodeno_t(stx.stx_ino) << dendl; - client->ll_put(i1); - } else { - dout(0) << "warning: play_trace couldn't lookup up my per-client directory" << dendl; - } - } else - (void) client->ll_get_inode(vinodeno_t(1, CEPH_NOSNAP)); - - utime_t last_status = start; - - int n = 0; - - // for object traces - Mutex lock("synclient foo"); - Cond cond; - bool ack; - - while (!t.end()) { - - if (++n == 100) { - n = 00; - utime_t now = last_status; - if (now - last_status > 1.0) { - last_status = now; - dout(1) << "play_trace at line " << t.get_line() << dendl; - } - } - - if (time_to_stop()) break; - - // op - const char *op = t.get_string(buf, 0); - dout(4) << (t.get_line()-1) << ": trace op " << op << dendl; - - if (op[0] == '@') { - // timestamp... ignore it! - t.get_int(); // sec - t.get_int(); // usec - op = t.get_string(buf, 0); - } - - // high level ops --------------------- - UserPerm perms = client->pick_my_perms(); - if (strcmp(op, "link") == 0) { - const char *a = t.get_string(buf, p); - const char *b = t.get_string(buf2, p); - client->link(a, b, perms); - } else if (strcmp(op, "unlink") == 0) { - const char *a = t.get_string(buf, p); - client->unlink(a, perms); - } else if (strcmp(op, "rename") == 0) { - const char *a = t.get_string(buf, p); - const char *b = t.get_string(buf2, p); - client->rename(a,b, perms); - } else if (strcmp(op, "mkdir") == 0) { - const char *a = t.get_string(buf, p); - int64_t b = t.get_int(); - client->mkdir(a, b, perms); - } else if (strcmp(op, "rmdir") == 0) { - const char *a = t.get_string(buf, p); - client->rmdir(a, perms); - } else if (strcmp(op, "symlink") == 0) { - const char *a = t.get_string(buf, p); - const char *b = t.get_string(buf2, p); - client->symlink(a, b, perms); - } else if (strcmp(op, "readlink") == 0) { - const char *a = t.get_string(buf, p); - char buf[100]; - client->readlink(a, buf, 100, perms); - } else if (strcmp(op, "lstat") == 0) { - struct stat st; - const char *a = t.get_string(buf, p); - if (strcmp(a, p) != 0 && - strcmp(a, "/") != 0 && - strcmp(a, "/lib") != 0 && // or /lib.. that would be a lookup. hack. - a[0] != 0) // stop stating the root directory already - client->lstat(a, &st, perms); - } else if (strcmp(op, "chmod") == 0) { - const char *a = t.get_string(buf, p); - int64_t b = t.get_int(); - client->chmod(a, b, perms); - } else if (strcmp(op, "chown") == 0) { - const char *a = t.get_string(buf, p); - int64_t b = t.get_int(); - int64_t c = t.get_int(); - client->chown(a, b, c, perms); - } else if (strcmp(op, "utime") == 0) { - const char *a = t.get_string(buf, p); - int64_t b = t.get_int(); - int64_t c = t.get_int(); - struct utimbuf u; - u.actime = b; - u.modtime = c; - client->utime(a, &u, perms); - } else if (strcmp(op, "mknod") == 0) { - const char *a = t.get_string(buf, p); - int64_t b = t.get_int(); - int64_t c = t.get_int(); - client->mknod(a, b, perms, c); - } else if (strcmp(op, "oldmknod") == 0) { - const char *a = t.get_string(buf, p); - int64_t b = t.get_int(); - client->mknod(a, b, perms, 0); - } else if (strcmp(op, "getdir") == 0) { - const char *a = t.get_string(buf, p); - list contents; - int r = client->getdir(a, contents, perms); - if (r < 0) { - dout(1) << "getdir on " << a << " returns " << r << dendl; - } - } else if (strcmp(op, "opendir") == 0) { - const char *a = t.get_string(buf, p); - int64_t b = t.get_int(); - dir_result_t *dirp; - client->opendir(a, &dirp, perms); - if (dirp) open_dirs[b] = dirp; - } else if (strcmp(op, "closedir") == 0) { - int64_t a = t.get_int(); - client->closedir(open_dirs[a]); - open_dirs.erase(a); - } else if (strcmp(op, "open") == 0) { - const char *a = t.get_string(buf, p); - int64_t b = t.get_int(); - int64_t c = t.get_int(); - int64_t d = t.get_int(); - int64_t fd = client->open(a, b, perms, c); - if (fd > 0) open_files[d] = fd; - } else if (strcmp(op, "oldopen") == 0) { - const char *a = t.get_string(buf, p); - int64_t b = t.get_int(); - int64_t d = t.get_int(); - int64_t fd = client->open(a, b, perms, 0755); - if (fd > 0) open_files[d] = fd; - } else if (strcmp(op, "close") == 0) { - int64_t id = t.get_int(); - int64_t fh = open_files[id]; - if (fh > 0) client->close(fh); - open_files.erase(id); - } else if (strcmp(op, "lseek") == 0) { - int64_t f = t.get_int(); - int fd = open_files[f]; - int64_t off = t.get_int(); - int64_t whence = t.get_int(); - client->lseek(fd, off, whence); - } else if (strcmp(op, "read") == 0) { - int64_t f = t.get_int(); - int64_t size = t.get_int(); - int64_t off = t.get_int(); - int64_t fd = open_files[f]; - if (!metadata_only) { - char *b = new char[size]; - client->read(fd, b, size, off); - delete[] b; - } - } else if (strcmp(op, "write") == 0) { - int64_t f = t.get_int(); - int64_t fd = open_files[f]; - int64_t size = t.get_int(); - int64_t off = t.get_int(); - if (!metadata_only) { - char *b = new char[size]; - memset(b, 1, size); // let's write 1's! - client->write(fd, b, size, off); - delete[] b; - } else { - client->write(fd, NULL, 0, size+off); - } - } else if (strcmp(op, "truncate") == 0) { - const char *a = t.get_string(buf, p); - int64_t l = t.get_int(); - client->truncate(a, l, perms); - } else if (strcmp(op, "ftruncate") == 0) { - int64_t f = t.get_int(); - int fd = open_files[f]; - int64_t l = t.get_int(); - client->ftruncate(fd, l, perms); - } else if (strcmp(op, "fsync") == 0) { - int64_t f = t.get_int(); - int64_t b = t.get_int(); - int fd = open_files[f]; - client->fsync(fd, b); - } else if (strcmp(op, "chdir") == 0) { - const char *a = t.get_string(buf, p); - // Client users should remember their path, but since this - // is just a synthetic client we ignore it. - std::string ignore; - client->chdir(a, ignore, perms); - } else if (strcmp(op, "statfs") == 0) { - struct statvfs stbuf; - client->statfs("/", &stbuf, perms); - } - - // low level ops --------------------- - else if (strcmp(op, "ll_lookup") == 0) { - int64_t i = t.get_int(); - const char *name = t.get_string(buf, p); - int64_t r = t.get_int(); - struct ceph_statx stx; - if (ll_inos.count(i)) { - i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - if (client->ll_lookupx(i1, name, &i2, &stx, CEPH_STATX_INO, 0, perms) == 0) - ll_inos[r] = stx.stx_ino; - client->ll_put(i1); - } - } else if (strcmp(op, "ll_forget") == 0) { - int64_t i = t.get_int(); - int64_t n = t.get_int(); - if (ll_inos.count(i) && - client->ll_forget( - client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)), n)) - ll_inos.erase(i); - } else if (strcmp(op, "ll_getattr") == 0) { - int64_t i = t.get_int(); - struct stat attr; - if (ll_inos.count(i)) { - i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - client->ll_getattr(i1, &attr, perms); - client->ll_put(i1); - } - } else if (strcmp(op, "ll_setattr") == 0) { - int64_t i = t.get_int(); - struct stat attr; - memset(&attr, 0, sizeof(attr)); - attr.st_mode = t.get_int(); - attr.st_uid = t.get_int(); - attr.st_gid = t.get_int(); - attr.st_size = t.get_int(); - attr.st_mtime = t.get_int(); - attr.st_atime = t.get_int(); - int mask = t.get_int(); - if (ll_inos.count(i)) { - i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - client->ll_setattr(i1, &attr, mask, perms); - client->ll_put(i1); - } - } else if (strcmp(op, "ll_readlink") == 0) { - int64_t i = t.get_int(); - if (ll_inos.count(i)) { - char buf[PATH_MAX]; - i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - client->ll_readlink(i1, buf, sizeof(buf), perms); - client->ll_put(i1); - } - } else if (strcmp(op, "ll_mknod") == 0) { - int64_t i = t.get_int(); - const char *n = t.get_string(buf, p); - int m = t.get_int(); - int r = t.get_int(); - int64_t ri = t.get_int(); - struct stat attr; - if (ll_inos.count(i)) { - i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - if (client->ll_mknod(i1, n, m, r, &attr, &i2, perms) == 0) - ll_inos[ri] = attr.st_ino; - client->ll_put(i1); - } - } else if (strcmp(op, "ll_mkdir") == 0) { - int64_t i = t.get_int(); - const char *n = t.get_string(buf, p); - int m = t.get_int(); - int64_t ri = t.get_int(); - struct stat attr; - if (ll_inos.count(i)) { - i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - if (client->ll_mkdir(i1, n, m, &attr, &i2, perms) == 0) - ll_inos[ri] = attr.st_ino; - client->ll_put(i1); - } - } else if (strcmp(op, "ll_symlink") == 0) { - int64_t i = t.get_int(); - const char *n = t.get_string(buf, p); - const char *v = t.get_string(buf2, p); - int64_t ri = t.get_int(); - struct stat attr; - if (ll_inos.count(i)) { - i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - if (client->ll_symlink(i1, n, v, &attr, &i2, perms) == 0) - ll_inos[ri] = attr.st_ino; - client->ll_put(i1); - } - } else if (strcmp(op, "ll_unlink") == 0) { - int64_t i = t.get_int(); - const char *n = t.get_string(buf, p); - if (ll_inos.count(i)) { - i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - client->ll_unlink(i1, n, perms); - client->ll_put(i1); - } - } else if (strcmp(op, "ll_rmdir") == 0) { - int64_t i = t.get_int(); - const char *n = t.get_string(buf, p); - if (ll_inos.count(i)) { - i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - client->ll_rmdir(i1, n, perms); - client->ll_put(i1); - } - } else if (strcmp(op, "ll_rename") == 0) { - int64_t i = t.get_int(); - const char *n = t.get_string(buf, p); - int64_t ni = t.get_int(); - const char *nn = t.get_string(buf2, p); - if (ll_inos.count(i) && - ll_inos.count(ni)) { - i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - i2 = client->ll_get_inode(vinodeno_t(ll_inos[ni],CEPH_NOSNAP)); - client->ll_rename(i1, n, i2, nn, perms); - client->ll_put(i1); - client->ll_put(i2); - } - } else if (strcmp(op, "ll_link") == 0) { - int64_t i = t.get_int(); - int64_t ni = t.get_int(); - const char *nn = t.get_string(buf, p); - if (ll_inos.count(i) && - ll_inos.count(ni)) { - i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - i2 = client->ll_get_inode(vinodeno_t(ll_inos[ni],CEPH_NOSNAP)); - client->ll_link(i1, i2, nn, perms); - client->ll_put(i1); - client->ll_put(i2); - } - } else if (strcmp(op, "ll_opendir") == 0) { - int64_t i = t.get_int(); - int64_t r = t.get_int(); - dir_result_t *dirp; - if (ll_inos.count(i)) { - i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - if (client->ll_opendir(i1, O_RDONLY, &dirp, perms) == 0) - ll_dirs[r] = dirp; - client->ll_put(i1); - } - } else if (strcmp(op, "ll_releasedir") == 0) { - int64_t f = t.get_int(); - if (ll_dirs.count(f)) { - client->ll_releasedir(ll_dirs[f]); - ll_dirs.erase(f); - } - } else if (strcmp(op, "ll_open") == 0) { - int64_t i = t.get_int(); - int64_t f = t.get_int(); - int64_t r = t.get_int(); - Fh *fhp; - if (ll_inos.count(i)) { - i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - if (client->ll_open(i1, f, &fhp, perms) == 0) - ll_files[r] = fhp; - client->ll_put(i1); - } - } else if (strcmp(op, "ll_create") == 0) { - int64_t i = t.get_int(); - const char *n = t.get_string(buf, p); - int64_t m = t.get_int(); - int64_t f = t.get_int(); - int64_t r = t.get_int(); - int64_t ri = t.get_int(); - struct stat attr; - if (ll_inos.count(i)) { - Fh *fhp; - i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP)); - if (client->ll_create(i1, n, m, f, &attr, NULL, &fhp, perms) == 0) { - ll_inos[ri] = attr.st_ino; - ll_files[r] = fhp; - } - client->ll_put(i1); - } - } else if (strcmp(op, "ll_read") == 0) { - int64_t f = t.get_int(); - int64_t off = t.get_int(); - int64_t size = t.get_int(); - if (ll_files.count(f) && - !metadata_only) { - bufferlist bl; - client->ll_read(ll_files[f], off, size, &bl); - } - } else if (strcmp(op, "ll_write") == 0) { - int64_t f = t.get_int(); - int64_t off = t.get_int(); - int64_t size = t.get_int(); - if (ll_files.count(f)) { - if (!metadata_only) { - bufferlist bl; - bufferptr bp(size); - bl.push_back(bp); - bp.zero(); - client->ll_write(ll_files[f], off, size, bl.c_str()); - } else { - client->ll_write(ll_files[f], off+size, 0, NULL); - } - } - } else if (strcmp(op, "ll_flush") == 0) { - int64_t f = t.get_int(); - if (!metadata_only && - ll_files.count(f)) - client->ll_flush(ll_files[f]); - } else if (strcmp(op, "ll_fsync") == 0) { - int64_t f = t.get_int(); - if (!metadata_only && - ll_files.count(f)) - client->ll_fsync(ll_files[f], false); // FIXME dataonly param - } else if (strcmp(op, "ll_release") == 0) { - int64_t f = t.get_int(); - if (ll_files.count(f)) { - client->ll_release(ll_files[f]); - ll_files.erase(f); - } - } else if (strcmp(op, "ll_statfs") == 0) { - int64_t i = t.get_int(); - if (ll_inos.count(i)) - {} //client->ll_statfs(vinodeno_t(ll_inos[i],CEPH_NOSNAP), perms); - } - - - // object-level traces - - else if (strcmp(op, "o_stat") == 0) { - int64_t oh = t.get_int(); - int64_t ol = t.get_int(); - object_t oid = file_object_t(oh, ol); - lock.Lock(); - object_locator_t oloc(SYNCLIENT_FIRST_POOL); - uint64_t size; - ceph::real_time mtime; - client->objecter->stat(oid, oloc, CEPH_NOSNAP, &size, &mtime, 0, - new C_SafeCond(&lock, &cond, &ack)); - while (!ack) cond.Wait(lock); - lock.Unlock(); - } - else if (strcmp(op, "o_read") == 0) { - int64_t oh = t.get_int(); - int64_t ol = t.get_int(); - int64_t off = t.get_int(); - int64_t len = t.get_int(); - object_t oid = file_object_t(oh, ol); - object_locator_t oloc(SYNCLIENT_FIRST_POOL); - lock.Lock(); - bufferlist bl; - client->objecter->read(oid, oloc, off, len, CEPH_NOSNAP, &bl, 0, - new C_SafeCond(&lock, &cond, &ack)); - while (!ack) cond.Wait(lock); - lock.Unlock(); - } - else if (strcmp(op, "o_write") == 0) { - int64_t oh = t.get_int(); - int64_t ol = t.get_int(); - int64_t off = t.get_int(); - int64_t len = t.get_int(); - object_t oid = file_object_t(oh, ol); - object_locator_t oloc(SYNCLIENT_FIRST_POOL); - lock.Lock(); - bufferptr bp(len); - bufferlist bl; - bl.push_back(bp); - SnapContext snapc; - client->objecter->write(oid, oloc, off, len, snapc, bl, - ceph::real_clock::now(), 0, - new C_SafeCond(&lock, &cond, &ack)); - while (!ack) cond.Wait(lock); - lock.Unlock(); - } - else if (strcmp(op, "o_zero") == 0) { - int64_t oh = t.get_int(); - int64_t ol = t.get_int(); - int64_t off = t.get_int(); - int64_t len = t.get_int(); - object_t oid = file_object_t(oh, ol); - object_locator_t oloc(SYNCLIENT_FIRST_POOL); - lock.Lock(); - SnapContext snapc; - client->objecter->zero(oid, oloc, off, len, snapc, - ceph::real_clock::now(), 0, - new C_SafeCond(&lock, &cond, &ack)); - while (!ack) cond.Wait(lock); - lock.Unlock(); - } - - - else { - dout(0) << (t.get_line()-1) << ": *** trace hit unrecognized symbol '" << op << "' " << dendl; - ceph_abort(); - } - } - - dout(10) << "trace finished on line " << t.get_line() << dendl; - - // close open files - for (ceph::unordered_map::iterator fi = open_files.begin(); - fi != open_files.end(); - ++fi) { - dout(1) << "leftover close " << fi->second << dendl; - if (fi->second > 0) client->close(fi->second); - } - for (ceph::unordered_map::iterator fi = open_dirs.begin(); - fi != open_dirs.end(); - ++fi) { - dout(1) << "leftover closedir " << fi->second << dendl; - if (fi->second != 0) client->closedir(fi->second); - } - for (ceph::unordered_map::iterator fi = ll_files.begin(); - fi != ll_files.end(); - ++fi) { - dout(1) << "leftover ll_release " << fi->second << dendl; - if (fi->second) client->ll_release(fi->second); - } - for (ceph::unordered_map::iterator fi = ll_dirs.begin(); - fi != ll_dirs.end(); - ++fi) { - dout(1) << "leftover ll_releasedir " << fi->second << dendl; - if (fi->second) client->ll_releasedir(fi->second); - } - - return 0; -} - - - -int SyntheticClient::clean_dir(string& basedir) -{ - // read dir - list contents; - UserPerm perms = client->pick_my_perms(); - int r = client->getdir(basedir.c_str(), contents, perms); - if (r < 0) { - dout(1) << "getdir on " << basedir << " returns " << r << dendl; - return r; - } - - for (list::iterator it = contents.begin(); - it != contents.end(); - ++it) { - if (*it == ".") continue; - if (*it == "..") continue; - string file = basedir + "/" + *it; - - if (time_to_stop()) break; - - struct stat st; - int r = client->lstat(file.c_str(), &st, perms); - if (r < 0) { - dout(1) << "stat error on " << file << " r=" << r << dendl; - continue; - } - - if ((st.st_mode & S_IFMT) == S_IFDIR) { - clean_dir(file); - client->rmdir(file.c_str(), perms); - } else { - client->unlink(file.c_str(), perms); - } - } - - return 0; - -} - - -int SyntheticClient::full_walk(string& basedir) -{ - if (time_to_stop()) return -1; - - list dirq; - list statq; - dirq.push_back(basedir); - frag_info_t empty; - memset(&empty, 0, sizeof(empty)); - statq.push_back(empty); - - ceph::unordered_map nlink; - ceph::unordered_map nlink_seen; - - UserPerm perms = client->pick_my_perms(); - while (!dirq.empty()) { - string dir = dirq.front(); - frag_info_t expect = statq.front(); - dirq.pop_front(); - statq.pop_front(); - - frag_info_t actual = empty; - - // read dir - list contents; - int r = client->getdir(dir.c_str(), contents, perms); - if (r < 0) { - dout(1) << "getdir on " << dir << " returns " << r << dendl; - continue; - } - - for (list::iterator it = contents.begin(); - it != contents.end(); - ++it) { - if (*it == "." || - *it == "..") - continue; - string file = dir + "/" + *it; - - struct stat st; - frag_info_t dirstat; - int r = client->lstat(file.c_str(), &st, perms, &dirstat); - if (r < 0) { - dout(1) << "stat error on " << file << " r=" << r << dendl; - continue; - } - - nlink_seen[st.st_ino]++; - nlink[st.st_ino] = st.st_nlink; - - if (S_ISDIR(st.st_mode)) - actual.nsubdirs++; - else - actual.nfiles++; - - // print - char *tm = ctime(&st.st_mtime); - tm[strlen(tm)-1] = 0; - printf("%llx %c%c%c%c%c%c%c%c%c%c %2d %5d %5d %8llu %12s %s\n", - (long long)st.st_ino, - S_ISDIR(st.st_mode) ? 'd':'-', - (st.st_mode & 0400) ? 'r':'-', - (st.st_mode & 0200) ? 'w':'-', - (st.st_mode & 0100) ? 'x':'-', - (st.st_mode & 040) ? 'r':'-', - (st.st_mode & 020) ? 'w':'-', - (st.st_mode & 010) ? 'x':'-', - (st.st_mode & 04) ? 'r':'-', - (st.st_mode & 02) ? 'w':'-', - (st.st_mode & 01) ? 'x':'-', - (int)st.st_nlink, - (int)st.st_uid, (int)st.st_gid, - (long long unsigned)st.st_size, - tm, - file.c_str()); - - - if ((st.st_mode & S_IFMT) == S_IFDIR) { - dirq.push_back(file); - statq.push_back(dirstat); - } - } - - if (dir != "" && - (actual.nsubdirs != expect.nsubdirs || - actual.nfiles != expect.nfiles)) { - dout(0) << dir << ": expected " << expect << dendl; - dout(0) << dir << ": got " << actual << dendl; - } - } - - for (ceph::unordered_map::iterator p = nlink.begin(); p != nlink.end(); ++p) { - if (nlink_seen[p->first] != p->second) - dout(0) << p->first << " nlink " << p->second << " != " << nlink_seen[p->first] << "seen" << dendl; - } - - return 0; -} - - - -int SyntheticClient::dump_placement(string& fn) { - - UserPerm perms = client->pick_my_perms(); - - // open file - int fd = client->open(fn.c_str(), O_RDONLY, perms); - dout(5) << "reading from " << fn << " fd " << fd << dendl; - if (fd < 0) return fd; - - - // How big is it? - struct stat stbuf; - int lstat_result = client->lstat(fn.c_str(), &stbuf, perms); - if (lstat_result < 0) { - dout(0) << "lstat error for file " << fn << dendl; - client->close(fd); - return lstat_result; - } - - off_t filesize = stbuf.st_size; - - // grab the placement info - vector extents; - off_t offset = 0; - client->enumerate_layout(fd, extents, filesize, offset); - client->close(fd); - - - // run through all the object extents - dout(0) << "file size is " << filesize << dendl; - dout(0) << "(osd, start, length) tuples for file " << fn << dendl; - for (const auto& x : extents) { - int osd = client->objecter->with_osdmap([&](const OSDMap& o) { - return o.get_pg_acting_primary(o.object_locator_to_pg(x.oid, x.oloc)); - }); - - // run through all the buffer extents - for (const auto& be : x.buffer_extents) - dout(0) << "OSD " << osd << ", offset " << be.first - << ", length " << be.second << dendl; - } - return 0; -} - - - -int SyntheticClient::make_dirs(const char *basedir, int dirs, int files, int depth) -{ - if (time_to_stop()) return 0; - - UserPerm perms = client->pick_my_perms(); - // make sure base dir exists - int r = client->mkdir(basedir, 0755, perms); - if (r != 0) { - dout(1) << "can't make base dir? " << basedir << dendl; - //return -1; - } - - // children - char d[500]; - dout(3) << "make_dirs " << basedir << " dirs " << dirs << " files " << files << " depth " << depth << dendl; - for (int i=0; imknod(d, 0644, perms); - } - - if (depth == 0) return 0; - - for (int i=0; ipick_my_perms(); - - // make sure base dir exists - struct stat st; - int r = client->lstat(basedir, &st, perms); - if (r != 0) { - dout(1) << "can't make base dir? " << basedir << dendl; - return -1; - } - - // children - char d[500]; - dout(3) << "stat_dirs " << basedir << " dirs " << dirs << " files " << files << " depth " << depth << dendl; - for (int i=0; ilstat(d, &st, perms); - } - - if (depth == 0) return 0; - - for (int i=0; i contents; - UserPerm perms = client->pick_my_perms(); - utime_t s = ceph_clock_now(); - int r = client->getdir(basedir, contents, perms); - utime_t e = ceph_clock_now(); - e -= s; - if (r < 0) { - dout(0) << "getdir couldn't readdir " << basedir << ", stopping" << dendl; - return -1; - } - - for (int i=0; ilstat(d, &st, perms) < 0) { - dout(2) << "read_dirs failed stat on " << d << ", stopping" << dendl; - return -1; - } - utime_t e = ceph_clock_now(); - e -= s; - } - - if (depth > 0) - for (int i=0; iget_nodeid().v; - char d[255]; - UserPerm perms = client->pick_my_perms(); - - if (priv) { - for (int c=0; cmkdir(d, 0755, perms); - } - } else { - // shared - if (true || whoami == 0) { - for (int c=0; cmkdir(d, 0755, perms); - } - } else { - sleep(2); - } - } - - // files - struct stat st; - utime_t start = ceph_clock_now(); - for (int c=0; cmknod(d, 0644, perms); - - if (more) { - client->lstat(d, &st, perms); - int fd = client->open(d, O_RDONLY, perms); - client->unlink(d, perms); - client->close(fd); - } - - if (time_to_stop()) return 0; - } - } - utime_t end = ceph_clock_now(); - end -= start; - dout(0) << "makefiles time is " << end << " or " << ((double)end / (double)num) <<" per file" << dendl; - - return 0; -} - -int SyntheticClient::link_test() -{ - char d[255]; - char e[255]; - - UserPerm perms = client->pick_my_perms(); - - // create files - int num = 200; - - client->mkdir("orig", 0755, perms); - client->mkdir("copy", 0755, perms); - - utime_t start = ceph_clock_now(); - for (int i=0; imknod(d, 0755, perms); - } - utime_t end = ceph_clock_now(); - end -= start; - - dout(0) << "orig " << end << dendl; - - // link - start = ceph_clock_now(); - for (int i=0; ilink(d, e, perms); - } - end = ceph_clock_now(); - end -= start; - dout(0) << "copy " << end << dendl; - - return 0; -} - - -int SyntheticClient::create_shared(int num) -{ - // files - UserPerm perms = client->pick_my_perms(); - char d[255]; - client->mkdir("test", 0755, perms); - for (int n=0; nmknod(d, 0644, perms); - } - - return 0; -} - -int SyntheticClient::open_shared(int num, int count) -{ - // files - char d[255]; - UserPerm perms = client->pick_my_perms(); - for (int c=0; c fds; - for (int n=0; nopen(d, O_RDONLY, perms); - if (fd > 0) fds.push_back(fd); - } - - if (false && client->get_nodeid() == 0) - for (int n=0; nunlink(d, perms); - } - - while (!fds.empty()) { - int fd = fds.front(); - fds.pop_front(); - client->close(fd); - } - } - - return 0; -} - - -// Hits OSD 0 with writes to various files with OSD 0 as the primary. -int SyntheticClient::overload_osd_0(int n, int size, int wrsize) { - UserPerm perms = client->pick_my_perms(); - // collect a bunch of files starting on OSD 0 - int left = n; - int tried = 0; - while (left < 0) { - - - // pull open a file - dout(0) << "in OSD overload" << dendl; - string filename = get_sarg(tried); - dout(1) << "OSD Overload workload: trying file " << filename << dendl; - int fd = client->open(filename.c_str(), O_RDWR|O_CREAT, perms); - ++tried; - - // only use the file if its first primary is OSD 0 - int primary_osd = check_first_primary(fd); - if (primary_osd != 0) { - client->close(fd); - dout(1) << "OSD Overload workload: SKIPPING file " << filename << - " with OSD " << primary_osd << " as first primary. " << dendl; - continue; - } - dout(1) << "OSD Overload workload: USING file " << filename << - " with OSD 0 as first primary. " << dendl; - - - --left; - // do whatever operation we want to do on the file. How about a write? - write_fd(fd, size, wrsize); - } - return 0; -} - - -// See what the primary is for the first object in this file. -int SyntheticClient::check_first_primary(int fh) -{ - vector extents; - client->enumerate_layout(fh, extents, 1, 0); - return client->objecter->with_osdmap([&](const OSDMap& o) { - return o.get_pg_acting_primary( - o.object_locator_to_pg(extents.begin()->oid, extents.begin()->oloc)); - }); -} - -int SyntheticClient::rm_file(string& fn) -{ - UserPerm perms = client->pick_my_perms(); - return client->unlink(fn.c_str(), perms); -} - -int SyntheticClient::write_file(string& fn, int size, loff_t wrsize) // size is in MB, wrsize in bytes -{ - //uint64_t wrsize = 1024*256; - char *buf = new char[wrsize+100]; // 1 MB - memset(buf, 7, wrsize); - int64_t chunks = (uint64_t)size * (uint64_t)(1024*1024) / (uint64_t)wrsize; - UserPerm perms = client->pick_my_perms(); - - int fd = client->open(fn.c_str(), O_RDWR|O_CREAT, perms); - dout(5) << "writing to " << fn << " fd " << fd << dendl; - if (fd < 0) { - delete[] buf; - return fd; - } - - utime_t from = ceph_clock_now(); - utime_t start = from; - uint64_t bytes = 0, total = 0; - - - for (loff_t i=0; iget_nodeid().v; - p++; - } - - client->write(fd, buf, wrsize, i*wrsize); - bytes += wrsize; - total += wrsize; - - utime_t now = ceph_clock_now(); - if (now - from >= 1.0) { - double el = now - from; - dout(0) << "write " << (bytes / el / 1048576.0) << " MB/sec" << dendl; - from = now; - bytes = 0; - } - } - - client->fsync(fd, true); - - utime_t stop = ceph_clock_now(); - double el = stop - start; - dout(0) << "write total " << (total / el / 1048576.0) << " MB/sec (" - << total << " bytes in " << el << " seconds)" << dendl; - - client->close(fd); - delete[] buf; - - return 0; -} - -int SyntheticClient::write_fd(int fd, int size, int wrsize) // size is in MB, wrsize in bytes -{ - //uint64_t wrsize = 1024*256; - char *buf = new char[wrsize+100]; // 1 MB - memset(buf, 7, wrsize); - uint64_t chunks = (uint64_t)size * (uint64_t)(1024*1024) / (uint64_t)wrsize; - - //dout(5) << "SyntheticClient::write_fd: writing to fd " << fd << dendl; - if (fd < 0) { - delete[] buf; - return fd; - } - - for (unsigned i=0; iget_nodeid().v; - p++; - } - - client->write(fd, buf, wrsize, i*wrsize); - } - client->close(fd); - delete[] buf; - - return 0; -} - - -int SyntheticClient::write_batch(int nfile, int size, int wrsize) -{ - for (int i=0; ipick_my_perms(); - - int fd = client->open(fn.c_str(), O_RDONLY, perms); - dout(5) << "reading from " << fn << " fd " << fd << dendl; - if (fd < 0) { - delete[] buf; - return fd; - } - - utime_t from = ceph_clock_now(); - utime_t start = from; - uint64_t bytes = 0, total = 0; - - for (unsigned i=0; iread(fd, buf, rdsize, i*rdsize); - if (r < rdsize) { - dout(1) << "read_file got r = " << r << ", probably end of file" << dendl; - break; - } - - bytes += rdsize; - total += rdsize; - - utime_t now = ceph_clock_now(); - if (now - from >= 1.0) { - double el = now - from; - dout(0) << "read " << (bytes / el / 1048576.0) << " MB/sec" << dendl; - from = now; - bytes = 0; - } - - // verify fingerprint - int bad = 0; - uint64_t *p = (uint64_t*)buf; - while ((char*)p + 32 < buf + rdsize) { - uint64_t readoff = *p; - uint64_t wantoff = (uint64_t)i*(uint64_t)rdsize + (uint64_t)((char*)p - buf); - p++; - int64_t readclient = *p; - p++; - if (readoff != wantoff || - readclient != client->get_nodeid()) { - if (!bad && !ignoreprint) - dout(0) << "WARNING: wrong data from OSD, block says fileoffset=" << readoff << " client=" << readclient - << ", should be offset " << wantoff << " client " << client->get_nodeid() - << dendl; - bad++; - } - } - if (bad && !ignoreprint) - dout(0) << " + " << (bad-1) << " other bad 16-byte bits in this block" << dendl; - } - - utime_t stop = ceph_clock_now(); - double el = stop - start; - dout(0) << "read total " << (total / el / 1048576.0) << " MB/sec (" - << total << " bytes in " << el << " seconds)" << dendl; - - client->close(fd); - delete[] buf; - - return 0; -} - - - - -class C_Ref : public Context { - Mutex& lock; - Cond& cond; - int *ref; -public: - C_Ref(Mutex &l, Cond &c, int *r) : lock(l), cond(c), ref(r) { - lock.Lock(); - (*ref)++; - lock.Unlock(); - } - void finish(int) override { - lock.Lock(); - (*ref)--; - cond.Signal(); - lock.Unlock(); - } -}; - -int SyntheticClient::create_objects(int nobj, int osize, int inflight) -{ - // divy up - int numc = num_client ? num_client : 1; - - int start, inc, end; - - if (1) { - // strided - start = client->get_nodeid().v; //nobjs % numc; - inc = numc; - end = start + nobj; - } else { - // segments - start = nobj * client->get_nodeid().v / numc; - inc = 1; - end = nobj * (client->get_nodeid().v+1) / numc; - } - - dout(5) << "create_objects " << nobj << " size=" << osize - << " .. doing [" << start << "," << end << ") inc " << inc - << dendl; - - bufferptr bp(osize); - bp.zero(); - bufferlist bl; - bl.push_back(bp); - - Mutex lock("create_objects lock"); - Cond cond; - - int unsafe = 0; - - list starts; - - for (int i=start; iclient_lock.Lock(); - client->objecter->write(oid, oloc, 0, osize, snapc, bl, - ceph::real_clock::now(), 0, - new C_Ref(lock, cond, &unsafe)); - client->client_lock.Unlock(); - - lock.Lock(); - while (unsafe > inflight) { - dout(20) << "waiting for " << unsafe << " unsafe" << dendl; - cond.Wait(lock); - } - lock.Unlock(); - - utime_t lat = ceph_clock_now(); - lat -= starts.front(); - starts.pop_front(); - } - - lock.Lock(); - while (unsafe > 0) { - dout(10) << "waiting for " << unsafe << " unsafe" << dendl; - cond.Wait(lock); - } - lock.Unlock(); - - dout(5) << "create_objects done" << dendl; - return 0; -} - -int SyntheticClient::object_rw(int nobj, int osize, int wrpc, - int overlappc, - double rskew, double wskew) -{ - dout(5) << "object_rw " << nobj << " size=" << osize << " with " - << wrpc << "% writes" - << ", " << overlappc << "% overlap" - << ", rskew = " << rskew - << ", wskew = " << wskew - << dendl; - - bufferptr bp(osize); - bp.zero(); - bufferlist bl; - bl.push_back(bp); - - // start with odd number > nobj - rjhash h; - unsigned prime = nobj + 1; // this is the minimum! - prime += h(nobj) % (3*nobj); // bump it up some - prime |= 1; // make it odd - - while (true) { - unsigned j; - for (j=2; j*j<=prime; j++) - if (prime % j == 0) break; - if (j*j > prime) { - break; - //cout << "prime " << prime << endl; - } - prime += 2; - } - - Mutex lock("lock"); - Cond cond; - - int unack = 0; - - while (1) { - if (time_to_stop()) break; - - // read or write? - bool write = (rand() % 100) < wrpc; - - // choose object - double r = drand48(); // [0..1) - long o; - if (write) { - o = (long)trunc(pow(r, wskew) * (double)nobj); // exponentially skew towards 0 - int pnoremap = (long)(r * 100.0); - if (pnoremap >= overlappc) - o = (o*prime) % nobj; // remap - } else { - o = (long)trunc(pow(r, rskew) * (double)nobj); // exponentially skew towards 0 - } - object_t oid = file_object_t(999, o); - object_locator_t oloc(SYNCLIENT_FIRST_POOL); - SnapContext snapc; - - client->client_lock.Lock(); - utime_t start = ceph_clock_now(); - if (write) { - dout(10) << "write to " << oid << dendl; - - ObjectOperation m; - OSDOp op; - op.op.op = CEPH_OSD_OP_WRITE; - op.op.extent.offset = 0; - op.op.extent.length = osize; - op.indata = bl; - m.ops.push_back(op); - client->objecter->mutate(oid, oloc, m, snapc, - ceph::real_clock::now(), 0, - new C_Ref(lock, cond, &unack)); - } else { - dout(10) << "read from " << oid << dendl; - bufferlist inbl; - client->objecter->read(oid, oloc, 0, osize, CEPH_NOSNAP, &inbl, 0, - new C_Ref(lock, cond, &unack)); - } - client->client_lock.Unlock(); - - lock.Lock(); - while (unack > 0) { - dout(20) << "waiting for " << unack << " unack" << dendl; - cond.Wait(lock); - } - lock.Unlock(); - - utime_t lat = ceph_clock_now(); - lat -= start; - } - - return 0; -} - - - - - -int SyntheticClient::read_random(string& fn, int size, int rdsize) // size is in MB, wrsize in bytes -{ - UserPerm perms = client->pick_my_perms(); - uint64_t chunks = (uint64_t)size * (uint64_t)(1024*1024) / (uint64_t)rdsize; - int fd = client->open(fn.c_str(), O_RDWR, perms); - dout(5) << "reading from " << fn << " fd " << fd << dendl; - - if (fd < 0) return fd; - int offset = 0; - char * buf = NULL; - - for (unsigned i=0; i<2000; i++) { - if (time_to_stop()) break; - - bool read=false; - - time_t seconds; - time( &seconds); - srand(seconds); - - // use rand instead ?? - double x = drand48(); - - // cleanup before call 'new' - if (buf != NULL) { - delete[] buf; - buf = NULL; - } - if (x < 0.5) { - buf = new char[rdsize]; - memset(buf, 1, rdsize); - read=true; - } else { - buf = new char[rdsize+100]; // 1 MB - memset(buf, 7, rdsize); - } - - if (read) { - offset=(rand())%(chunks+1); - dout(2) << "reading block " << offset << "/" << chunks << dendl; - - int r = client->read(fd, buf, rdsize, offset*rdsize); - if (r < rdsize) { - dout(1) << "read_file got r = " << r << ", probably end of file" << dendl; - } - } else { - dout(2) << "writing block " << offset << "/" << chunks << dendl; - - // fill buf with a 16 byte fingerprint - // 64 bits : file offset - // 64 bits : client id - // = 128 bits (16 bytes) - - offset=(rand())%(chunks+1); - uint64_t *p = (uint64_t*)buf; - while ((char*)p < buf + rdsize) { - *p = offset*rdsize + (char*)p - buf; - p++; - *p = client->get_nodeid().v; - p++; - } - - client->write(fd, buf, rdsize, - offset*rdsize); - } - - // verify fingerprint - if (read) { - int bad = 0; - int64_t *p = (int64_t*)buf; - while ((char*)p + 32 < buf + rdsize) { - int64_t readoff = *p; - int64_t wantoff = offset*rdsize + (int64_t)((char*)p - buf); - p++; - int64_t readclient = *p; - p++; - if (readoff != wantoff || readclient != client->get_nodeid()) { - if (!bad) - dout(0) << "WARNING: wrong data from OSD, block says fileoffset=" << readoff << " client=" << readclient - << ", should be offset " << wantoff << " client " << client->get_nodeid() - << dendl; - bad++; - } - } - if (bad) - dout(0) << " + " << (bad-1) << " other bad 16-byte bits in this block" << dendl; - } - } - - client->close(fd); - delete[] buf; - - return 0; -} - -int normdist(int min, int max, int stdev) /* specifies input values */ -{ - /* min: Minimum value; max: Maximum value; stdev: degree of deviation */ - - //int min, max, stdev; { - time_t seconds; - time( &seconds); - srand(seconds); - - int range, iterate, result; - /* declare range, iterate and result as integers, to avoid the need for - floating point math*/ - - result = 0; - /* ensure result is initialized to 0 */ - - range = max -min; - /* calculate range of possible values between the max and min values */ - - iterate = range / stdev; - /* this number of iterations ensures the proper shape of the resulting - curve */ - - stdev += 1; /* compensation for integer vs. floating point math */ - for (int c = iterate; c != 0; c--) /* loop through iterations */ - { - // result += (uniform (1, 100) * stdev) / 100; /* calculate and - result += ( (rand()%100 + 1) * stdev) / 100; - // printf("result=%d\n", result ); - } - printf("\n final result=%d\n", result ); - return result + min; /* send final result back */ -} - -int SyntheticClient::read_random_ex(string& fn, int size, int rdsize) // size is in MB, wrsize in bytes -{ - uint64_t chunks = (uint64_t)size * (uint64_t)(1024*1024) / (uint64_t)rdsize; - UserPerm perms = client->pick_my_perms(); - int fd = client->open(fn.c_str(), O_RDWR, perms); - dout(5) << "reading from " << fn << " fd " << fd << dendl; - - if (fd < 0) return fd; - int offset = 0; - char * buf = NULL; - - for (unsigned i=0; i<2000; i++) { - if (time_to_stop()) break; - - bool read=false; - - time_t seconds; - time( &seconds); - srand(seconds); - - // use rand instead ?? - double x = drand48(); - - // cleanup before call 'new' - if (buf != NULL) { - delete[] buf; - buf = NULL; - } - if (x < 0.5) { - buf = new char[rdsize]; - memset(buf, 1, rdsize); - read=true; - } else { - buf = new char[rdsize+100]; // 1 MB - memset(buf, 7, rdsize); - } - - if (read) { - dout(2) << "reading block " << offset << "/" << chunks << dendl; - - int r = client->read(fd, buf, rdsize, - offset*rdsize); - if (r < rdsize) { - dout(1) << "read_file got r = " << r << ", probably end of file" << dendl; - } - } else { - dout(2) << "writing block " << offset << "/" << chunks << dendl; - - // fill buf with a 16 byte fingerprint - // 64 bits : file offset - // 64 bits : client id - // = 128 bits (16 bytes) - - int count = rand()%10; - - for ( int j=0;jget_nodeid().v; - p++; - } - - client->write(fd, buf, rdsize, offset*rdsize); - } - } - - // verify fingerprint - if (read) { - int bad = 0; - int64_t *p = (int64_t*)buf; - while ((char*)p + 32 < buf + rdsize) { - int64_t readoff = *p; - int64_t wantoff = offset*rdsize + (int64_t)((char*)p - buf); - p++; - int64_t readclient = *p; - p++; - if (readoff != wantoff || readclient != client->get_nodeid()) { - if (!bad) - dout(0) << "WARNING: wrong data from OSD, block says fileoffset=" << readoff << " client=" << readclient - << ", should be offset " << wantoff << " client " << client->get_nodeid() - << dendl; - bad++; - } - } - if (bad) - dout(0) << " + " << (bad-1) << " other bad 16-byte bits in this block" << dendl; - } - } - - client->close(fd); - delete[] buf; - - return 0; -} - - -int SyntheticClient::random_walk(int num_req) -{ - int left = num_req; - - //dout(1) << "random_walk() will do " << left << " ops" << dendl; - - init_op_dist(); // set up metadata op distribution - - UserPerm perms = client->pick_my_perms(); - while (left > 0) { - left--; - - if (time_to_stop()) break; - - // ascend? - if (cwd.depth() && !roll_die(::pow((double).9, (double)cwd.depth()))) { - dout(DBL) << "die says up" << dendl; - up(); - continue; - } - - // descend? - if (roll_die(::pow((double).9,(double)cwd.depth())) && !subdirs.empty()) { - string s = get_random_subdir(); - cwd.push_dentry( s ); - dout(DBL) << "cd " << s << " -> " << cwd << dendl; - clear_dir(); - continue; - } - - int op = 0; - filepath path; - - if (contents.empty() && roll_die(.3)) { - if (did_readdir) { - dout(DBL) << "empty dir, up" << dendl; - up(); - } else - op = CEPH_MDS_OP_READDIR; - } else { - op = op_dist.sample(); - } - //dout(DBL) << "op is " << op << dendl; - - int r = 0; - - // do op - if (op == CEPH_MDS_OP_UNLINK) { - if (contents.empty()) - op = CEPH_MDS_OP_READDIR; - else - r = client->unlink(get_random_sub(), perms); // will fail on dirs - } - - if (op == CEPH_MDS_OP_RENAME) { - if (contents.empty()) - op = CEPH_MDS_OP_READDIR; - else { - r = client->rename(get_random_sub(), make_sub("ren"), perms); - } - } - - if (op == CEPH_MDS_OP_MKDIR) { - r = client->mkdir(make_sub("mkdir"), 0755, perms); - } - - if (op == CEPH_MDS_OP_RMDIR) { - if (!subdirs.empty()) - r = client->rmdir(get_random_subdir(), perms); - else - r = client->rmdir(cwd.c_str(), perms); // will pbly fail - } - - if (op == CEPH_MDS_OP_SYMLINK) { - } - /* - if (op == CEPH_MDS_OP_CHMOD) { - if (contents.empty()) - op = CEPH_MDS_OP_READDIR; - else - r = client->chmod(get_random_sub(), rand() & 0755, perms); - } - - if (op == CEPH_MDS_OP_CHOWN) { - if (contents.empty()) r = client->chown(cwd.c_str(), rand(), rand(), perms); - else - r = client->chown(get_random_sub(), rand(), rand(), perms); - } - - if (op == CEPH_MDS_OP_UTIME) { - struct utimbuf b; - memset(&b, 1, sizeof(b)); - if (contents.empty()) - r = client->utime(cwd.c_str(), &b, perms); - else - r = client->utime(get_random_sub(), &b, perms); - } - */ - if (op == CEPH_MDS_OP_LINK) { - } - - if (op == CEPH_MDS_OP_MKNOD) { - r = client->mknod(make_sub("mknod"), 0644, perms); - } - - if (op == CEPH_MDS_OP_OPEN) { - if (contents.empty()) - op = CEPH_MDS_OP_READDIR; - else { - r = client->open(get_random_sub(), O_RDONLY, perms); - if (r > 0) { - assert(open_files.count(r) == 0); - open_files.insert(r); - } - } - } - - /*if (op == CEPH_MDS_OP_RELEASE) { // actually, close - if (open_files.empty()) - op = CEPH_MDS_OP_STAT; - else { - int fh = get_random_fh(); - r = client->close( fh ); - if (r == 0) open_files.erase(fh); - } - } - */ - - if (op == CEPH_MDS_OP_GETATTR) { - struct stat st; - if (contents.empty()) { - if (did_readdir) { - if (roll_die(.1)) { - dout(DBL) << "stat in empty dir, up" << dendl; - up(); - } else { - op = CEPH_MDS_OP_MKNOD; - } - } else - op = CEPH_MDS_OP_READDIR; - } else - r = client->lstat(get_random_sub(), &st, perms); - } - - if (op == CEPH_MDS_OP_READDIR) { - clear_dir(); - - list c; - r = client->getdir(cwd.c_str(), c, perms); - - for (list::iterator it = c.begin(); - it != c.end(); - ++it) { - //dout(DBL) << " got " << *it << dendl; - ceph_abort(); - /*contents[*it] = it->second; - if (it->second && - S_ISDIR(it->second->st_mode)) - subdirs.insert(*it); - */ - } - - did_readdir = true; - } - - // errors? - if (r < 0) { - // reevaluate cwd. - //while (cwd.depth()) { - //if (client->lookup(cwd)) break; // it's in the cache - - //dout(DBL) << "r = " << r << ", client doesn't have " << cwd << ", cd .." << dendl; - dout(DBL) << "r = " << r << ", client may not have " << cwd << ", cd .." << dendl; - up(); - //} - } - } - - // close files - dout(DBL) << "closing files" << dendl; - while (!open_files.empty()) { - int fh = get_random_fh(); - int r = client->close( fh ); - if (r == 0) open_files.erase(fh); - } - - dout(DBL) << "done" << dendl; - return 0; -} - - - - -void SyntheticClient::make_dir_mess(const char *basedir, int n) -{ - UserPerm perms = client->pick_my_perms(); - vector dirs; - - dirs.push_back(basedir); - dirs.push_back(basedir); - - client->mkdir(basedir, 0755, perms); - - // motivation: - // P(dir) ~ subdirs_of(dir) + 2 - // from 5-year metadata workload paper in fast'07 - - // create dirs - for (int i=0; imkdir(dir.c_str(), 0755, perms); - } - - -} - - - -void SyntheticClient::foo() -{ - UserPerm perms = client->pick_my_perms(); - - if (1) { - // make 2 parallel dirs, link/unlink between them. - char a[100], b[100]; - client->mkdir("/a", 0755, perms); - client->mkdir("/b", 0755, perms); - for (int i=0; i<10; i++) { - snprintf(a, sizeof(a), "/a/%d", i); - client->mknod(a, 0644, perms); - } - while (1) { - for (int i=0; i<10; i++) { - snprintf(a, sizeof(a), "/a/%d", i); - snprintf(b, sizeof(b), "/b/%d", i); - client->link(a, b, perms); - } - for (int i=0; i<10; i++) { - snprintf(b, sizeof(b), "/b/%d", i); - client->unlink(b, perms); - } - } - return; - } - if (1) { - // bug1.cpp - const char *fn = "blah"; - char buffer[8192]; - client->unlink(fn, perms); - int handle = client->open(fn, O_CREAT|O_RDWR, perms, S_IRWXU); - assert(handle>=0); - int r=client->write(handle,buffer,8192); - assert(r>=0); - r=client->close(handle); - assert(r>=0); - - handle = client->open(fn, O_RDWR, perms); // open the same file, it must have some data already - assert(handle>=0); - r=client->read(handle,buffer,8192); - assert(r==8192); // THIS ASSERTION FAILS with disabled cache - r=client->close(handle); - assert(r>=0); - - return; - } - if (1) { - dout(0) << "first" << dendl; - int fd = client->open("tester", O_WRONLY|O_CREAT, perms); - client->write(fd, "hi there", 0, 8); - client->close(fd); - dout(0) << "sleep" << dendl; - sleep(10); - dout(0) << "again" << dendl; - fd = client->open("tester", O_WRONLY|O_CREAT, perms); - client->write(fd, "hi there", 0, 8); - client->close(fd); - return; - } - if (1) { - // open some files - srand(0); - for (int i=0; i<20; i++) { - int s = 5; - int a = rand() % s; - int b = rand() % s; - int c = rand() % s; - char src[80]; - snprintf(src, sizeof(src), "syn.0.0/dir.%d/dir.%d/file.%d", a, b, c); - //int fd = - client->open(src, O_RDONLY, perms); - } - - return; - } - - if (0) { - // rename fun - for (int i=0; i<100; i++) { - int s = 5; - int a = rand() % s; - int b = rand() % s; - int c = rand() % s; - int d = rand() % s; - int e = rand() % s; - int f = rand() % s; - char src[80]; - char dst[80]; - snprintf(src, sizeof(src), "syn.0.0/dir.%d/dir.%d/file.%d", a, b, c); - snprintf(dst, sizeof(dst), "syn.0.0/dir.%d/dir.%d/file.%d", d, e, f); - client->rename(src, dst, perms); - } - return; - } - - if (1) { - // link fun - srand(0); - for (int i=0; i<100; i++) { - int s = 5; - int a = rand() % s; - int b = rand() % s; - int c = rand() % s; - int d = rand() % s; - int e = rand() % s; - int f = rand() % s; - char src[80]; - char dst[80]; - snprintf(src, sizeof(src), "syn.0.0/dir.%d/dir.%d/file.%d", a, b, c); - snprintf(dst, sizeof(dst), "syn.0.0/dir.%d/dir.%d/newlink.%d", d, e, f); - client->link(src, dst, perms); - } - srand(0); - for (int i=0; i<100; i++) { - int s = 5; - int a = rand() % s; - int b = rand() % s; - int c = rand() % s; - int d = rand() % s; - int e = rand() % s; - int f = rand() % s; - char src[80]; - char dst[80]; - snprintf(src, sizeof(src), "syn.0.0/dir.%d/dir.%d/file.%d", a, b, c); - snprintf(dst, sizeof(dst), "syn.0.0/dir.%d/dir.%d/newlink.%d", d, e, f); - client->unlink(dst, perms); - } - - - return; - } - - // link fun - client->mknod("one", 0755, perms); - client->mknod("two", 0755, perms); - client->link("one", "three", perms); - client->mkdir("dir", 0755, perms); - client->link("two", "/dir/twolink", perms); - client->link("dir/twolink", "four", perms); - - // unlink fun - client->mknod("a", 0644, perms); - client->unlink("a", perms); - client->mknod("b", 0644, perms); - client->link("b", "c", perms); - client->unlink("c", perms); - client->mkdir("d", 0755, perms); - client->unlink("d", perms); - client->rmdir("d", perms); - - // rename fun - client->mknod("p1", 0644, perms); - client->mknod("p2", 0644, perms); - client->rename("p1","p2", perms); - client->mknod("p3", 0644, perms); - client->rename("p3","p4", perms); - - // check dest dir ambiguity thing - client->mkdir("dir1", 0755, perms); - client->mkdir("dir2", 0755, perms); - client->rename("p2", "dir1/p2", perms); - client->rename("dir1/p2", "dir2/p2", perms); - client->rename("dir2/p2", "/p2", perms); - - // check primary+remote link merging - client->link("p2","p2.l", perms); - client->link("p4","p4.l", perms); - client->rename("p2.l", "p2", perms); - client->rename("p4", "p4.l", perms); - - // check anchor updates - client->mknod("dir1/a", 0644, perms); - client->link("dir1/a", "da1", perms); - client->link("dir1/a", "da2", perms); - client->link("da2","da3", perms); - client->rename("dir1/a", "dir2/a", perms); - client->rename("dir2/a", "da2", perms); - client->rename("da1", "da2", perms); - client->rename("da2", "da3", perms); - - // check directory renames - client->mkdir("dir3", 0755, perms); - client->mknod("dir3/asdf", 0644, perms); - client->mkdir("dir4", 0755, perms); - client->mkdir("dir5", 0755, perms); - client->mknod("dir5/asdf", 0644, perms); - client->rename("dir3", "dir4", perms); // ok - client->rename("dir4", "dir5", perms); // fail -} - -int SyntheticClient::thrash_links(const char *basedir, int dirs, int files, int depth, int n) -{ - dout(1) << "thrash_links " << basedir << " " << dirs << " " << files << " " << depth - << " links " << n - << dendl; - - if (time_to_stop()) return 0; - - UserPerm perms = client->pick_my_perms(); - - srand(0); - if (1) { - bool renames = true; // thrash renames too? - for (int k=0; krename(dst.c_str(), "/tmp", perms) == 0) { - client->rename(src.c_str(), dst.c_str(), perms); - client->rename("/tmp", src.c_str(), perms); - } - continue; - } - - // pick a dest dir - string src = basedir; - { - char t[80]; - for (int d=0; dmknod(src.c_str(), 0755, perms); - if (renames) client->rename(src.c_str(), dst.c_str(), perms); - break; - case 1: - client->mknod(src.c_str(), 0755, perms); - client->unlink(dst.c_str(), perms); - client->link(src.c_str(), dst.c_str(), perms); - break; - case 2: client->unlink(src.c_str(), perms); break; - case 3: client->unlink(dst.c_str(), perms); break; - //case 4: client->mknod(src.c_str(), 0755, perms); break; - //case 5: client->mknod(dst.c_str(), 0755, perms); break; - } - } - return 0; - } - - if (1) { - // now link shit up - for (int i=0; ilink(file.c_str(), ln.c_str(), perms); - } - } - return 0; -} - - - - -void SyntheticClient::import_find(const char *base, const char *find, bool data) -{ - dout(1) << "import_find " << base << " from " << find << " data=" << data << dendl; - - /* use this to gather the static trace: - * - * find . -exec ls -dilsn --time-style=+%s \{\} \; - * or if it's wafl, - * find . -path ./.snapshot -prune -o -exec ls -dilsn --time-style=+%s \{\} \; - * - */ - - UserPerm process_perms = client->pick_my_perms(); - - if (base[0] != '-') - client->mkdir(base, 0755, process_perms); - - ifstream f(find); - assert(f.is_open()); - - int dirnum = 0; - - while (!f.eof()) { - uint64_t ino; - int dunno, nlink; - string modestring; - int uid, gid; - off_t size; - time_t mtime; - string filename; - f >> ino; - if (f.eof()) break; - f >> dunno; - f >> modestring; - f >> nlink; - f >> uid; - f >> gid; - f >> size; - f >> mtime; - f.seekg(1, ios::cur); - getline(f, filename); - UserPerm perms(uid, gid); - - // ignore "." - if (filename == ".") continue; - - // remove leading ./ - assert(filename[0] == '.' && filename[1] == '/'); - filename = filename.substr(2); - - // new leading dir? - int sp = filename.find("/"); - if (sp < 0) dirnum++; - - //dout(0) << "leading dir " << filename << " " << dirnum << dendl; - if (dirnum % num_client != client->get_nodeid()) { - dout(20) << "skipping leading dir " << dirnum << " " << filename << dendl; - continue; - } - - // parse the mode - assert(modestring.length() == 10); - mode_t mode = 0; - switch (modestring[0]) { - case 'd': mode |= S_IFDIR; break; - case 'l': mode |= S_IFLNK; break; - default: - case '-': mode |= S_IFREG; break; - } - if (modestring[1] == 'r') mode |= 0400; - if (modestring[2] == 'w') mode |= 0200; - if (modestring[3] == 'x') mode |= 0100; - if (modestring[4] == 'r') mode |= 040; - if (modestring[5] == 'w') mode |= 020; - if (modestring[6] == 'x') mode |= 010; - if (modestring[7] == 'r') mode |= 04; - if (modestring[8] == 'w') mode |= 02; - if (modestring[9] == 'x') mode |= 01; - - dout(20) << " mode " << modestring << " to " << oct << mode << dec << dendl; - - if (S_ISLNK(mode)) { - // target vs destination - int pos = filename.find(" -> "); - assert(pos > 0); - string link; - if (base[0] != '-') { - link = base; - link += "/"; - } - link += filename.substr(0, pos); - string target; - if (filename[pos+4] == '/') { - if (base[0] != '-') - target = base; - target += filename.substr(pos + 4); - } else { - target = filename.substr(pos + 4); - } - dout(10) << "symlink from '" << link << "' -> '" << target << "'" << dendl; - client->symlink(target.c_str(), link.c_str(), perms); - } else { - string f; - if (base[0] != '-') { - f = base; - f += "/"; - } - f += filename; - if (S_ISDIR(mode)) { - client->mkdir(f.c_str(), mode, perms); - } else { - int fd = client->open(f.c_str(), O_WRONLY|O_CREAT, perms, mode & 0777); - assert(fd > 0); - if (data) { - client->write(fd, "", 0, size); - } else { - client->truncate(f.c_str(), size, perms); - } - client->close(fd); - - //client->chmod(f.c_str(), mode & 0777, perms, process_perms); - client->chown(f.c_str(), uid, gid, process_perms); - - struct utimbuf ut; - ut.modtime = mtime; - ut.actime = mtime; - client->utime(f.c_str(), &ut, perms); - } - } - } - - -} - - -int SyntheticClient::lookup_hash(inodeno_t ino, inodeno_t dirino, - const char *name, const UserPerm& perms) -{ - int r = client->lookup_hash(ino, dirino, name, perms); - dout(0) << "lookup_hash(" << ino << ", #" << dirino << "/" << name << ") = " << r << dendl; - return r; -} - -int SyntheticClient::lookup_ino(inodeno_t ino, const UserPerm& perms) -{ - int r = client->lookup_ino(ino, perms); - dout(0) << "lookup_ino(" << ino << ") = " << r << dendl; - return r; -} - -int SyntheticClient::chunk_file(string &filename) -{ - UserPerm perms = client->pick_my_perms(); - int fd = client->open(filename.c_str(), O_RDONLY, perms); - if (fd < 0) - return fd; - - struct stat st; - int ret = client->fstat(fd, &st, perms); - if (ret < 0) { - client->close(fd); - return ret; - } - uint64_t size = st.st_size; - dout(0) << "file " << filename << " size is " << size << dendl; - - inode_t inode; - memset(&inode, 0, sizeof(inode)); - inode.ino = st.st_ino; - ret = client->fdescribe_layout(fd, &inode.layout); - assert(ret == 0); // otherwise fstat did a bad thing - - uint64_t pos = 0; - bufferlist from_before; - while (pos < size) { - int get = MIN(size-pos, 1048576); - - Mutex flock("synclient chunk_file lock"); - Cond cond; - bool done; - bufferlist bl; - - flock.Lock(); - Context *onfinish = new C_SafeCond(&flock, &cond, &done); - client->filer->read(inode.ino, &inode.layout, CEPH_NOSNAP, pos, get, &bl, 0, - onfinish); - while (!done) - cond.Wait(flock); - flock.Unlock(); - - dout(0) << "got " << bl.length() << " bytes at " << pos << dendl; - - if (from_before.length()) { - dout(0) << " including bit from previous block" << dendl; - pos -= from_before.length(); - from_before.claim_append(bl); - bl.swap(from_before); - } - - // .... - - // keep last 32 bytes around - from_before.clear(); - from_before.substr_of(bl, bl.length()-32, 32); - - pos += bl.length(); - } - - client->close(fd); - return 0; -} - - - -void SyntheticClient::mksnap(const char *base, const char *name, const UserPerm& perms) -{ - client->mksnap(base, name, perms); -} - -void SyntheticClient::rmsnap(const char *base, const char *name, const UserPerm& perms) -{ - client->rmsnap(base, name, perms); -} - -void SyntheticClient::mksnapfile(const char *dir) -{ - UserPerm perms = client->pick_my_perms(); - client->mkdir(dir, 0755, perms); - - string f = dir; - f += "/foo"; - int fd = client->open(f.c_str(), O_WRONLY|O_CREAT|O_TRUNC, perms); - - char buf[1048576*4]; - client->write(fd, buf, sizeof(buf), 0); - client->fsync(fd, true); - client->close(fd); - - string s = dir; - s += "/.snap/1"; - client->mkdir(s.c_str(), 0755, perms); - - fd = client->open(f.c_str(), O_WRONLY, perms); - client->write(fd, buf, 1048576*2, 1048576); - client->fsync(fd, true); - client->close(fd); -}