common/Timer.o\
config.o
+SYN_OBJS = \
+ client/Trace.o
+
TEST_TARGETS = fakemds mpitest
TARGETS = import singleclient mpifuse fakefuse mpisyn fakesyn tcpsyn
gprof-helper.so: test/gprof-helper.c
gcc -shared -fPIC test/gprof-helper.c -o gprof-helper.so -lpthread -ldl
+
+# old test crap
import: mds/allmds.o osd/OSD.o msg/FakeMessenger.o import.cc ${COMMON_OBJS}
${CC} ${CFLAGS} ${LIBS} $^ -o $@
mttest: test/mttest.cc msg/MTMessenger.cc ${COMMON_OBJS}
${MPICC} ${CFLAGS} ${LIBS} $^ -o $@
-mpifuse: mpifuse.cc mds/allmds.o client/Client.o client/Buffercache.o client/SyntheticClient.o osd/OSD.o client/fuse.o msg/MPIMessenger.cc ${COMMON_OBJS}
- ${MPICC} ${CFLAGS} ${LIBS} -lfuse $^ -o $@
+
+# fuse
+fakefuse: fakefuse.cc mds/allmds.o client/Client.o client/Buffercache.o osd/OSD.o client/fuse.o msg/FakeMessenger.cc ${COMMON_OBJS}
+ ${CC} -pg ${CFLAGS} ${LIBS} -lfuse $^ -o $@
tcpfuse: tcpfuse.cc mds/allmds.o client/Client.o client/Buffercache.o client/SyntheticClient.o osd/OSD.o client/fuse.o msg/TCPMessenger.cc ${COMMON_OBJS}
${MPICC} ${CFLAGS} ${LIBS} -lfuse $^ -o $@
-mpisyn: mpisyn.cc mds/allmds.o client/Client.o client/Buffercache.o client/SyntheticClient.o osd/OSD.o msg/MPIMessenger.cc ${COMMON_OBJS}
+mpifuse: mpifuse.cc mds/allmds.o client/Client.o client/Buffercache.o client/SyntheticClient.o osd/OSD.o client/fuse.o msg/MPIMessenger.cc ${COMMON_OBJS}
+ ${MPICC} ${CFLAGS} ${LIBS} -lfuse $^ -o $@
+
+# synthetic workload
+fakesyn: fakesyn.cc mds/allmds.o client/Client.o client/Buffercache.o client/SyntheticClient.o osd/OSD.o msg/FakeMessenger.o ${COMMON_OBJS} ${SYN_OBJS}
+ ${CC} -pg ${CFLAGS} ${LIBS} $^ -o $@
+
+mpisyn: mpisyn.cc mds/allmds.o client/Client.o client/Buffercache.o client/SyntheticClient.o osd/OSD.o msg/MPIMessenger.cc ${COMMON_OBJS} ${SYN_OBJS}
${MPICC} ${MPICFLAGS} ${MPILIBS} $^ -o $@
-tcpsyn: tcpsyn.cc mds/allmds.o client/Client.o client/Buffercache.o client/SyntheticClient.o osd/OSD.o msg/TCPMessenger.cc ${COMMON_OBJS}
+tcpsyn: tcpsyn.cc mds/allmds.o client/Client.o client/Buffercache.o client/SyntheticClient.o osd/OSD.o msg/TCPMessenger.cc ${COMMON_OBJS} ${SYN_OBJS}
${MPICC} ${MPICFLAGS} ${MPILIBS} $^ -o $@
+# obfs + synthetic
obfstest: tcpsyn.cc mds/allmds.o client/Client.o client/Buffercache.o client/SyntheticClient.o osd/OSD.cc osd/OBFSStore.o msg/TCPMessenger.cc ${COMMON_OBJS}
${MPICC} -DUSE_OBFS ${MPICFLAGS} ${MPILIBS} $^ -o $@ ../uofs/uofs.a
-fakesyn: fakesyn.cc mds/allmds.o client/Client.o client/Buffercache.o client/SyntheticClient.o osd/OSD.o msg/FakeMessenger.o ${COMMON_OBJS}
- ${CC} -pg ${CFLAGS} ${LIBS} $^ -o $@
-fakefuse: fakefuse.cc mds/allmds.o client/Client.o client/Buffercache.o osd/OSD.o client/fuse.o msg/FakeMessenger.cc ${COMMON_OBJS}
- ${CC} -pg ${CFLAGS} ${LIBS} -lfuse $^ -o $@
testmpi: test/testmpi.cc msg/MPIMessenger.cc config.o common/Timer.o common/clock.o msg/Messenger.o msg/Dispatcher.o msg/error.o
${MPICC} ${CFLAGS} ${LIBS} $^ -o $@
+known bugs to fix after fast
+- RDWR on synthetic client results in
+fakesyn: mds/MDS.cc:2334: void MDS::handle_client_close(MClientRequest*, CInode*): Assertion `cur->softlock.can_write(true)' failed.
+- caps needs to be rewritten
+ - MDS currently not reclaiming fh's (otherwise a client assertion eventually fails)
+- hard links!
+
+
!!!
- test mds scaling w/ makedirs, vs mds_log_on_request
#include "include/config.h"
#undef dout
-#define dout(l) if (l<=g_conf.debug || l<=g_conf.debug_client) cout << "client" << "." << pthread_self() << " "
-
+#define dout(l) if (l<=g_conf.debug || l<=g_conf.debug_client) cout << "client" << whoami << "." << pthread_self() << " "
+#define tout if (g_conf.client_trace) cout << "trace: "
delete reply;
client_lock.Unlock();
+
+ dout(3) << "op: // client trace data structs" << endl;
+ dout(3) << "op: struct stat st;" << endl;
+ dout(3) << "op: struct utimbuf utim;" << endl;
+ dout(3) << "op: int readlinkbuf_len = 1000;" << endl;
+ dout(3) << "op: char readlinkbuf[readlinkbuf_len];" << endl;
+ dout(3) << "op: map<string, inode_t*> dir_contents;" << endl;
+ dout(3) << "op: map<fileh_t, fileh_t> open_files;" << endl;
+ dout(3) << "op: fileh_t fh;" << endl;
}
int Client::unmount()
int Client::link(const char *existing, const char *newname)
{
client_lock.Lock();
+ dout(3) << "op: client->link(\"" << existing << "\", \"" << newname << "\");" << endl;
+ tout << "link" << endl;
+ tout << existing << endl;
+ tout << newname << endl;
+
// main path arg is new link name
// sarg is target (existing file)
- dout(3) << "link " << existing << " " << newname << endl;
MClientRequest *req = new MClientRequest(MDS_OP_LINK, whoami);
req->set_path(newname);
int Client::unlink(const char *path)
{
client_lock.Lock();
+ dout(3) << "op: client->unlink\(\"" << path << "\");" << endl;
+ tout << "unlink" << endl;
+ tout << path << endl;
+
- dout(3) << "unlink " << path << endl;
MClientRequest *req = new MClientRequest(MDS_OP_UNLINK, whoami);
req->set_path(path);
MClientReply *reply = make_request(req);
int res = reply->get_result();
if (res == 0) {
- //this crashes, haven't looked at why yet
- //Dentry *dn = lookup(req->get_filepath());
- //if (dn) unlink(dn);
+ // remove from local cache
+ filepath fp(path);
+ Dentry *dn = lookup(fp);
+ if (dn) unlink(dn);
}
this->insert_trace(reply->get_trace());
delete reply;
int Client::rename(const char *from, const char *to)
{
client_lock.Lock();
+ dout(3) << "op: client->rename(\"" << from << "\", \"" << to << "\");" << endl;
+ tout << "rename" << endl;
+ tout << from << endl;
+ tout << to << endl;
+
- dout(3) << "rename " << from << " " << to << endl;
MClientRequest *req = new MClientRequest(MDS_OP_RENAME, whoami);
req->set_path(from);
req->set_sarg(to);
int Client::mkdir(const char *path, mode_t mode)
{
client_lock.Lock();
+ dout(3) << "op: client->mkdir(\"" << path << "\", " << mode << ");" << endl;
+ tout << "mkdir" << endl;
+ tout << path << endl;
+ tout << mode << endl;
+
- dout(3) << "mkdir " << path << " mode " << mode << endl;
MClientRequest *req = new MClientRequest(MDS_OP_MKDIR, whoami);
req->set_path(path);
req->set_iarg( (int)mode );
int Client::rmdir(const char *path)
{
client_lock.Lock();
+ dout(3) << "op: client->rmdir(\"" << path << "\");" << endl;
+ tout << "rmdir" << endl;
+ tout << path << endl;
+
- dout(3) << "rmdir " << path << endl;
MClientRequest *req = new MClientRequest(MDS_OP_RMDIR, whoami);
req->set_path(path);
MClientReply *reply = make_request(req);
int res = reply->get_result();
if (res == 0) {
- // crashes, not sure why yet
- //unlink(lookup(req->get_filepath()));
+ // remove from local cache
+ filepath fp(path);
+ Dentry *dn = lookup(fp);
+ if (dn) {
+ if (dn->inode->dir && dn->inode->dir->is_empty())
+ close_dir(dn->inode->dir); // FIXME: maybe i shoudl proactively hose the whole subtree from cache?
+ unlink(dn);
+ }
}
this->insert_trace(reply->get_trace());
delete reply;
int Client::symlink(const char *target, const char *link)
{
client_lock.Lock();
+ dout(3) << "op: client->symlink(\"" << target << "\", \"" << link << "\");" << endl;
+ tout << "symlink" << endl;
+ tout << target << endl;
+ tout << link << endl;
+
- dout(3) << "symlink target " << target << " link " << link << endl;
MClientRequest *req = new MClientRequest(MDS_OP_SYMLINK, whoami);
req->set_path(link);
req->set_sarg(target);
int Client::readlink(const char *path, char *buf, size_t size)
{
- dout(3) << "readlink " << path << endl;
+ client_lock.Lock();
+ dout(3) << "op: client->readlink(\"" << path << "\", readlinkbuf, readlinkbuf_len);" << endl;
+ tout << "readlink" << endl;
+ tout << path << endl;
+ client_lock.Unlock();
+
// stat first (FIXME, PERF access cache directly) ****
struct stat stbuf;
int r = this->lstat(path, &stbuf);
int Client::lstat(const char *path, struct stat *stbuf)
{
client_lock.Lock();
+ dout(3) << "op: client->lstat(\"" << path << "\", &st);" << endl;
+ tout << "lstat" << endl;
+ tout << path << endl;
+
- dout(3) << "lstat " << path << endl;
// FIXME, PERF request allocation convenient but not necessary for cache hit
MClientRequest *req = new MClientRequest(MDS_OP_STAT, whoami);
req->set_path(path);
int Client::chmod(const char *path, mode_t mode)
{
client_lock.Lock();
+ dout(3) << "op: client->chmod(\"" << path << "\", " << mode << ");" << endl;
+ tout << "chmod" << endl;
+ tout << path << endl;
+ tout << mode << endl;
+
- dout(3) << "chmod " << path << " mode " << mode << endl;
MClientRequest *req = new MClientRequest(MDS_OP_CHMOD, whoami);
req->set_path(path);
req->set_iarg( (int)mode );
int Client::chown(const char *path, uid_t uid, gid_t gid)
{
client_lock.Lock();
+ dout(3) << "op: client->chown(\"" << path << "\", " << uid << ", " << gid << ");" << endl;
+ tout << "chown" << endl;
+ tout << path << endl;
+ tout << uid << endl;
+ tout << gid << endl;
+
- dout(3) << "chown " << path << " " << uid << "." << gid << endl;
MClientRequest *req = new MClientRequest(MDS_OP_CHOWN, whoami);
req->set_path(path);
req->set_iarg( (int)uid );
int Client::utime(const char *path, struct utimbuf *buf)
{
client_lock.Lock();
+ dout(3) << "op: utim.actime = " << buf->actime << "; utim.modtime = " << buf->modtime << ";" << endl;
+ dout(3) << "op: client->utime(\"" << path << "\", &utim);" << endl;
+ tout << "utime" << endl;
+ tout << path << endl;
+ tout << buf->actime << endl;
+ tout << buf->modtime << endl;
+
- dout(3) << "utime " << path << endl;
MClientRequest *req = new MClientRequest(MDS_OP_UTIME, whoami);
req->set_path(path);
req->set_targ( buf->modtime );
int Client::mknod(const char *path, mode_t mode)
{
client_lock.Lock();
+ dout(3) << "op: client->mknod(\"" << path << "\", " << mode << ");" << endl;
+ tout << "mknod" << endl;
+ tout << path << endl;
+ tout << mode << endl;
+
- dout(3) << "mknod " << path << " mode " << mode << endl;
MClientRequest *req = new MClientRequest(MDS_OP_MKNOD, whoami);
req->set_path(path);
req->set_iarg( mode );
int Client::getdir(const char *path, map<string,inode_t*>& contents)
{
client_lock.Lock();
+ dout(3) << "op: client->getdir(\"" << path << "\", dir_contents);" << endl;
+ tout << "getdir" << endl;
+ tout << path << endl;
+
- dout(3) << "getdir " << path << endl;
MClientRequest *req = new MClientRequest(MDS_OP_READDIR, whoami);
req->set_path(path);
int Client::open(const char *path, int mode)
{
client_lock.Lock();
+ dout(3) << "op: fh = client->open(\"" << path << "\", " << mode << ");" << endl;
+ tout << "open" << endl;
+ tout << path << endl;
+ tout << mode << endl;
+
- dout(3) << "open " << path << " mode " << mode << endl;
-
MClientRequest *req = new MClientRequest(MDS_OP_OPEN, whoami);
req->set_path(path);
req->set_iarg(mode);
MClientReply *reply = make_request(req);
assert(reply);
- dout(3) << "open result = " << reply->get_result() << endl;
+ dout(3) << "op: open_files[" << reply->get_result() << "] = fh; // fh = " << reply->get_result() << endl;
+ tout << reply->get_result() << endl;
vector<c_inode_info*> trace = reply->get_trace();
this->insert_trace(trace);
int Client::close(fileh_t fh)
{
client_lock.Lock();
+ dout(3) << "op: client->close(open_files[ " << fh << " ]);" << endl;
+ dout(3) << "op: open_files.erase( " << fh << " );" << endl;
+ tout << "close" << endl;
+ tout << fh << endl;
+
- dout(3) << "close " << fh << endl;
assert(fh_map.count(fh));
Fh *f = fh_map[fh];
Inode *in = f->inode;
cond.Wait(client_lock);
}
+#if 0
+ }
+#endif
// assume success for now. FIXME.
}
+int Client::truncate(const char *file, off_t size)
+{
+ client_lock.Lock();
+ dout(3) << "op: client->truncate(\"" << file << "\", " << size << ");" << endl;
+ tout << "truncate" << endl;
+ tout << file << endl;
+ tout << size << endl;
+
+
+ MClientRequest *req = new MClientRequest(MDS_OP_TRUNCATE, whoami);
+ req->set_path(file);
+ req->set_sizearg( size );
+
+ // FIXME where does FUSE maintain user information
+ req->set_caller_uid(getuid());
+ req->set_caller_gid(getgid());
+
+ MClientReply *reply = make_request(req);
+ int res = reply->get_result();
+ this->insert_trace(reply->get_trace());
+ delete reply;
+
+ dout(10) << " truncate result is " << res << endl;
+
+ client_lock.Unlock();
+ return res;
+}
+
+
int Client::fsync(fileh_t fh, bool syncdataonly)
{
client_lock.Lock();
+ dout(3) << "op: client->fsync(open_files[ " << fh << " ], " << syncdataonly << ");" << endl;
+ tout << "fsync" << endl;
+ tout << fh << endl;
+ tout << syncdataonly << endl;
+
int r = 0;
assert(fh_map.count(fh));
in->put();
if (in->ref == 0) {
inode_map.erase(in->inode.ino);
+ if (in == root) root = 0;
delete in;
}
}
int close(fileh_t fh);
int read(fileh_t fh, char *buf, size_t size, off_t offset);
int write(fileh_t fh, const char *buf, size_t size, off_t offset);
- int truncate(fileh_t fh, off_t size);
+ int truncate(const char *file, off_t size);
+ //int truncate(fileh_t fh, off_t size);
int fsync(fileh_t fh, bool syncdataonly);
};
#include "include/filepath.h"
#include "mds/MDS.h"
+
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#undef dout
#define dout(l) if (l<=g_conf.debug || l<=g_conf.debug_client) cout << "synthetic" << client->get_nodeid() << " "
+// traces
+//void trace_include(SyntheticClient *syn, Client *cl, string& prefix);
+//void trace_openssh(SyntheticClient *syn, Client *cl, string& prefix);
+
#define DBL 2
read_file(sarg1, iarg1, iarg2);
}
break;
+
+
+ case SYNCLIENT_MODE_TRACEINCLUDE:
+ {
+ int iarg1 = iargs.front(); iargs.pop_front();
+ string prefix;
+ if (client->whoami == 0) {
+ Trace t("client/traces/trace.include");
+ play_trace(t, prefix);
+ } else {
+ sleep(iarg1);
+ }
+ }
+ break;
+ case SYNCLIENT_MODE_TRACEOPENSSH:
+ {
+ string prefix = get_sarg();
+ int iarg1 = iargs.front(); iargs.pop_front();
+
+ Trace t("client/traces/trace.openssh");
+
+ client->mkdir(prefix.c_str(), 0755);
+
+ for (int i=0; i<iarg1; i++) {
+ if (time_to_stop()) break;
+ play_trace(t, prefix);
+ if (time_to_stop()) break;
+ clean_dir(prefix);
+ }
+ }
+ break;
+
default:
assert(0);
}
}
+int SyntheticClient::play_trace(Trace& t, string& prefix)
+{
+ dout(4) << "play trace" << endl;
+ t.start();
+
+ const char *p = prefix.c_str();
+
+ map<__int64_t, int> open_files;
+
+ while (!t.end()) {
+
+ if (time_to_stop()) break;
+
+ // op
+ const char *op = t.get_string();
+ dout(4) << "trace op " << op << endl;
+ if (strcmp(op, "link") == 0) {
+ const char *a = t.get_string(p);
+ const char *b = t.get_string(p);
+ client->link(a,b);
+ } else if (strcmp(op, "unlink") == 0) {
+ const char *a = t.get_string(p);
+ client->unlink(a);
+ } else if (strcmp(op, "rename") == 0) {
+ const char *a = t.get_string(p);
+ const char *b = t.get_string(p);
+ client->rename(a,b);
+ } else if (strcmp(op, "mkdir") == 0) {
+ const char *a = t.get_string(p);
+ __int64_t b = t.get_int();
+ client->mkdir(a, b);
+ } else if (strcmp(op, "rmdir") == 0) {
+ const char *a = t.get_string(p);
+ client->rmdir(a);
+ } else if (strcmp(op, "symlink") == 0) {
+ const char *a = t.get_string(p);
+ const char *b = t.get_string(p);
+ client->symlink(a,b);
+ } else if (strcmp(op, "readlink") == 0) {
+ const char *a = t.get_string(p);
+ char buf[100];
+ client->readlink(a, buf, 100);
+ } else if (strcmp(op, "lstat") == 0) {
+ struct stat st;
+ const char *a = t.get_string(p);
+ client->lstat(a, &st);
+ } else if (strcmp(op, "chmod") == 0) {
+ const char *a = t.get_string(p);
+ __int64_t b = t.get_int();
+ client->chmod(a, b);
+ } else if (strcmp(op, "chown") == 0) {
+ const char *a = t.get_string(p);
+ __int64_t b = t.get_int();
+ __int64_t c = t.get_int();
+ client->chown(a, b, c);
+ } else if (strcmp(op, "utime") == 0) {
+ const char *a = t.get_string(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);
+ } else if (strcmp(op, "mknod") == 0) {
+ const char *a = t.get_string(p);
+ __int64_t b = t.get_int();
+ client->mknod(a, b);
+ } else if (strcmp(op, "getdir") == 0) {
+ const char *a = t.get_string(p);
+ map<string,inode_t*> contents;
+ client->getdir(a, contents);
+ } else if (strcmp(op, "open") == 0) {
+ const char *a = t.get_string(p);
+ __int64_t b = t.get_int();
+ __int64_t id = t.get_int();
+ __int64_t fh = client->open(a, b);
+ open_files[id] = fh;
+ } 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, "truncate") == 0) {
+ const char *a = t.get_string(p);
+ __int64_t b = t.get_int();
+ client->truncate(a,b);
+ } else if (strcmp(op, "fsync") == 0) {
+ assert(0);
+ } else
+ assert(0);
+ }
+
+ // close open files
+ for (map<__int64_t, __int64_t>::iterator fi = open_files.begin();
+ fi != open_files.end();
+ fi++) {
+ client->close(fi->second);
+ }
+
+}
+
+
+int SyntheticClient::clean_dir(string& basedir)
+{
+ // read dir
+ map<string, inode_t*> contents;
+ int r = client->getdir(basedir.c_str(), contents);
+ if (r < 0) {
+ dout(1) << "readdir on " << basedir << " returns " << r << endl;
+ return r;
+ }
+
+ for (map<string, inode_t*>::iterator it = contents.begin();
+ it != contents.end();
+ it++) {
+ string file = basedir + "/" + it->first;
+
+ if (time_to_stop()) break;
+
+ struct stat st;
+ int r = client->lstat(file.c_str(), &st);
+ if (r < 0) {
+ dout(1) << "stat error on " << file << " r=" << r << endl;
+ continue;
+ }
+
+ if (st.st_mode & INODE_MODE_DIR) {
+ clean_dir(file);
+ client->rmdir(file.c_str());
+ } else {
+ client->unlink(file.c_str());
+ }
+ }
+
+ return 0;
+
+}
int SyntheticClient::full_walk(string& basedir)
{
- if (run_until.first && g_clock.gettimepair() > run_until) return -1;
+ if (time_to_stop()) return -1;
// read dir
map<string, inode_t*> contents;
int SyntheticClient::make_dirs(const char *basedir, int dirs, int files, int depth)
{
- if (run_until.first && g_clock.gettimepair() > run_until) return 0;
+ if (time_to_stop()) return 0;
// make sure base dir exists
int r = client->mkdir(basedir, 0755);
if (fd < 0) return fd;
for (int i=0; i<chunks; i++) {
- if (run_until.first && g_clock.gettimepair() > run_until) break;
+ if (time_to_stop()) break;
dout(2) << "writing block " << i << "/" << chunks << endl;
client->write(fd, buf, wrsize, i*wrsize);
}
if (fd < 0) return fd;
for (int i=0; i<chunks; i++) {
- if (run_until.first && g_clock.gettimepair() > run_until) break;
+ if (time_to_stop()) break;
dout(2) << "reading block " << i << "/" << chunks << endl;
client->read(fd, buf, rdsize, i*rdsize);
}
while (left > 0) {
left--;
- if (run_until.first && g_clock.gettimepair() > run_until) break;
+ if (time_to_stop()) break;
// ascend?
if (cwd.depth() && !roll_die(pow(.9, cwd.depth()))) {
dout(DBL) << "done" << endl;
return 0;
}
+
+
#include "Client.h"
#include "include/Distribution.h"
+#include "Trace.h"
+
#define SYNCLIENT_MODE_RANDOMWALK 1
#define SYNCLIENT_MODE_FULLWALK 2
#define SYNCLIENT_MODE_MAKEDIRS 3
#define SYNCLIENT_MODE_UNTIL 6
#define SYNCLIENT_MODE_REPEATWALK 7
+#define SYNCLIENT_MODE_TRACEOPENSSH 8
+#define SYNCLIENT_MODE_TRACEINCLUDE 9
+
class SyntheticClient {
Client *client;
timepair_t run_until;
string get_sarg();
-
+
+ bool time_to_stop() {
+ if (run_until.first && g_clock.gettimepair() > run_until)
+ return true;
+ else
+ return false;
+ }
+
+ string compose_path(string& prefix, char *rest) {
+ return prefix + rest;
+ }
+
int full_walk(string& fromdir);
int random_walk(int n);
int make_dirs(const char *basedir, int dirs, int files, int depth);
int write_file(string& fn, int mb, int chunk);
int read_file(string& fn, int mb, int chunk);
+ int clean_dir(string& basedir);
+
+ int play_trace(Trace& t, string& prefix);
};
--- /dev/null
+
+#include "Trace.h"
+
+#include <cassert>
+#include <map>
+#include <ext/rope>
+using namespace __gnu_cxx;
+
+#include "common/Mutex.h"
+
+#include "include/config.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+Mutex trace_lock;
+
+class TokenList {
+public:
+ string filename;
+ char *data;
+ int len;
+ list<const char *> tokens;
+
+ int ref;
+};
+
+map<string, TokenList*> traces;
+
+
+//
+Trace::Trace(const char* f)
+{
+ string filename = f;
+
+ trace_lock.Lock();
+
+ if (traces.count(filename))
+ tl = traces[filename];
+ else {
+ tl = new TokenList;
+ tl->ref = 0;
+ tl->filename = filename;
+
+ // open file
+ crope cr;
+ int fd = open(filename.c_str(), O_RDONLY);
+ assert(fd > 0);
+ char buf[100];
+ while (1) {
+ int r = read(fd, buf, 100);
+ if (r == 0) break;
+ assert(r > 0);
+ cr.append(buf, r);
+ }
+ close(fd);
+
+ // copy
+ tl->len = cr.length()+1;
+ tl->data = new char[cr.length()];
+ memcpy(tl->data, cr.c_str(), cr.length());
+ tl->data[tl->len-1] = '\n';
+
+ // index!
+ int o = 0;
+ while (o < tl->len) {
+ char *n = tl->data + o;
+
+ // find newline
+ while (tl->data[o] != '\n') o++;
+ assert(tl->data[o] == '\n');
+ tl->data[o] = 0;
+
+ if (tl->data + o > n) tl->tokens.push_back(n);
+ o++;
+ }
+
+ dout(1) << "trace " << filename << " loaded with " << tl->tokens.size() << " tokens" << endl;
+ traces[filename] = tl;
+ }
+ tl->ref++;
+
+ trace_lock.Unlock();
+}
+
+Trace::~Trace()
+{
+ trace_lock.Lock();
+
+ tl->ref--;
+ if (tl->ref == 0) {
+ traces.erase(tl->filename);
+ delete tl;
+ }
+
+ trace_lock.Unlock();
+}
+
+
+list<const char*>& Trace::get_list()
+{
+ return tl->tokens;
+}
--- /dev/null
+#ifndef __CLIENT_TRACE_H
+#define __CLIENT_TRACE_H
+
+#include <list>
+#include <string>
+using namespace std;
+
+/*
+
+ this class is more like an iterator over a constant tokenlist (which
+ is protected by a mutex, see Trace.cc)
+
+ */
+
+class Trace {
+ class TokenList *tl;
+
+ public:
+ Trace(const char* filename);
+ ~Trace();
+
+ list<const char*>& get_list();
+
+ list<const char*>::iterator _cur;
+ list<const char*>::iterator _end;
+
+ void start() {
+ _cur = get_list().begin();
+ _end = get_list().end();
+ ns = 0;
+ }
+
+ char strings[10][200];
+ int ns;
+ const char *get_string(const char *prefix = 0) {
+ const char *s = *_cur;
+ _cur++;
+ if (prefix) {
+ if (strstr(s, "/prefix") == s ||
+ strstr(s, "/prefix") == s+1) {
+ strcpy(strings[ns], prefix);
+ strcpy(strings[ns] + strlen(prefix),
+ s + strlen("/prefix"));
+ s = (const char*)strings[ns];
+ ns++;
+ if (ns == 10) ns = 0;
+ }
+ }
+ return s;
+ }
+ __int64_t get_int() {
+ return atoll(get_string());
+ }
+ bool end() {
+ return _cur == _end;
+ }
+};
+
+#endif
#include "Client.h"
+#include "include/config.h"
+
// stl
#include <map>
using namespace std;
static int ceph_truncate(const char *path, off_t size)
{
- return truncate(path, size);
+ return client->truncate(path, size);
}
static int ceph_utime(const char *path, struct utimbuf *buf)
// large reads, direct_io (no kernel cachine)
//newargv[newargc++] = "-o";
//newargv[newargc++] = "large_read";
- newargv[newargc++] = "-o";
- newargv[newargc++] = "direct_io";
+ if (g_conf.fuse_direct_io) {
+ newargv[newargc++] = "-o";
+ newargv[newargc++] = "direct_io";
+ }
// disable stupid fuse unlink hiding thing
newargv[newargc++] = "-o";
client_bcache_alloc_minsize: 1024,
client_bcache_alloc_maxsize: 262144,
client_bcache_ttl: 30, // seconds until dirty buffers are written to disk
+ client_trace: 0,
+ fuse_direct_io: 1,
// --- mds ---
mds_cache_size: MDS_CACHE_SIZE,
g_conf.client_cache_size = atoi(argv[++i]);
else if (strcmp(argv[i], "--client_cache_stat_ttl") == 0)
g_conf.client_cache_stat_ttl = atoi(argv[++i]);
+ else if (strcmp(argv[i], "--client_trace") == 0)
+ g_conf.client_trace = atoi(argv[++i]);
+ else if (strcmp(argv[i], "--fuse_direct_io") == 0)
+ g_conf.fuse_direct_io = atoi(argv[++i]);
else if (strcmp(argv[i], "--osd_fsync") == 0)
g_conf.osd_fsync = atoi(argv[++i]);
int client_bcache_alloc_minsize;
int client_bcache_alloc_maxsize;
int client_bcache_ttl;
+ int client_trace;
+ int fuse_direct_io;
// mds
int mds_cache_size;
//syn_sargs.push_back( atoi(argv[++i]) );
} else if (strcmp(argv[i],"randomwalk") == 0) {
syn_modes.push_back( SYNCLIENT_MODE_RANDOMWALK );
+ syn_iargs.push_back( atoi(argv[++i]) );
+ } else if (strcmp(argv[i],"trace_include") == 0) {
+ syn_modes.push_back( SYNCLIENT_MODE_TRACEINCLUDE );
+ syn_iargs.push_back( atoi(argv[++i]) );
+ } else if (strcmp(argv[i],"trace_openssh") == 0) {
+ syn_modes.push_back( SYNCLIENT_MODE_TRACEOPENSSH );
syn_iargs.push_back( atoi(argv[++i]) );
} else if (strcmp(argv[i],"until") == 0) {
syn_modes.push_back( SYNCLIENT_MODE_UNTIL );
// shut down?
if (shutting_down && !shut_down) {
if (mdcache->shutdown_pass()) {
+ dout(7) << "shutdown_pass=true, finished w/ shutdown" << endl;
shutting_down = false;
shut_down = true;
if (whoami) shutdown_final();
*/
case MDS_OP_TRUNCATE:
- if (!req->get_iarg()) break; // can be called w/ either fh OR path
+ if (!req->get_ino()) break; // can be called w/ either fh OR path
case MDS_OP_CLOSE:
case MDS_OP_FSYNC:
case MDS_OP_MKNOD:
case MDS_OP_MKDIR:
case MDS_OP_SYMLINK:
- case MDS_OP_TRUNCATE:
case MDS_OP_LINK:
case MDS_OP_UNLINK: // also wrt parent dir, NOT the unlinked inode!!
case MDS_OP_RMDIR:
else
handle_client_open(req, ref);
break;
- /*
case MDS_OP_TRUNCATE:
handle_client_truncate(req, ref);
break;
+ /*
case MDS_OP_FSYNC:
handle_client_fsync(req, ref);
break;
+// ===================================
+// TRUNCATE, FSYNC
+
+/*
+ * FIXME: this truncate implemention is WRONG WRONG WRONG
+ */
+
+void MDS::handle_client_truncate(MClientRequest *req, CInode *cur)
+{
+ // write
+ if (!mdcache->inode_hard_write_start(cur, req))
+ return; // fw or (wait for) lock
+
+ // check permissions
+
+ // do update
+ cur->inode.size = req->get_sizearg();
+ cur->mark_dirty();
+
+ mdcache->inode_hard_write_finish(cur);
+
+ balancer->hit_inode(cur);
+
+ // start reply
+ MClientReply *reply = new MClientReply(req, 0);
+
+ // commit
+ commit_request(req, reply, cur,
+ new EInodeUpdate(cur));
+}
FakeMessenger::FakeMessenger(long me) : Messenger(me)
{
whoami = me;
+ lock.Lock();
directory[ whoami ] = this;
-
+ lock.Unlock();
cout << "fakemessenger " << whoami << " messenger is " << this << endl;
int FakeMessenger::shutdown()
{
//cout << "shutdown on messenger " << this << " has " << num_incoming() << " queued" << endl;
+ lock.Lock();
directory.erase(whoami);
if (directory.empty()) {
::shutdown = true;
cond.Signal(); // why not
- }
+ }
+ lock.Unlock();
}
/*
--- /dev/null
+#!/usr/bin/perl
+
+my $n = 0;
+while (<>) {
+ next unless /trace: /;
+ my $l = $'; $';
+ print $l;
+}
} else if (strcmp(argv[i],"randomwalk") == 0) {
syn_modes.push_back( SYNCLIENT_MODE_RANDOMWALK );
syn_iargs.push_back( atoi(argv[++i]) );
+ } else if (strcmp(argv[i],"trace_include") == 0) {
+ syn_modes.push_back( SYNCLIENT_MODE_TRACEINCLUDE );
+ syn_iargs.push_back( atoi(argv[++i]) );
+ } else if (strcmp(argv[i],"trace_openssh") == 0) {
+ syn_modes.push_back( SYNCLIENT_MODE_TRACEOPENSSH );
+ syn_iargs.push_back( atoi(argv[++i]) );
} else if (strcmp(argv[i],"until") == 0) {
syn_modes.push_back( SYNCLIENT_MODE_UNTIL );
syn_iargs.push_back( atoi(argv[++i]) );