# behave just fine... change ${CC} back to mpicxx if you get paranoid.
CC = g++
MPICC = mpicxx
-CFLAGS = -g -I. -pg -D_FILE_OFFSET_BITS=64 -DMPICH_IGNORE_CXX_SEEK -D_REENTRANT -D_THREAD_SAFE
+CFLAGS = -g -I. -D_FILE_OFFSET_BITS=64 -DMPICH_IGNORE_CXX_SEEK -D_REENTRANT -D_THREAD_SAFE
LIBS = -lpthread
MDS_OBJS= \
${MPICC} ${CFLAGS} ${LIBS} -lfuse $^ -o $@
fakesyn: fakesyn.cc mds/allmds.o client/Client.o client/SyntheticClient.o osd/OSD.o msg/FakeMessenger.o msg/CheesySerializer.o ${COMMON_OBJS}
- ${CC} ${CFLAGS} ${LIBS} $^ -o $@
+ ${CC} -pg ${CFLAGS} ${LIBS} $^ -o $@
fakefuse: fakefuse.cc mds/allmds.o client/Client.o osd/OSD.o client/fuse.o msg/FakeMessenger.cc msg/CheesySerializer.o ${COMMON_OBJS}
- ${CC} ${CFLAGS} ${LIBS} -lfuse $^ -o $@
+ ${CC} -pg ${CFLAGS} ${LIBS} -lfuse $^ -o $@
clean:
rm -f *.o */*.o ${TARGETS} ${TEST_TARGETS}
- test mds scaling w/ makedirs, vs mds_log_on_request
- client needs to choose MDS intelligently
-- finish osd replication MOSDOp groundwork
+- fix up MDLog
big fast todo's:
- client buffer cache
- heartbeat protocol
- mds benchmarks
- - synthetic client stable,
- pseudo-mega-filesystem
- osd copy-on-write..
// -------
-MClientReply *Client::make_request(MClientRequest *req, int mds)
+MClientReply *Client::make_request(MClientRequest *req)
{
+ // send to what MDS? find deepest known prefix
+ int mds = 0;
+ Inode *cur = root;
+ for (int i=0; i<req->get_filepath().depth(); i++) {
+ if (cur && cur->inode.mode & INODE_MODE_DIR && cur->dir) {
+ Dir *dir = cur->dir;
+ Dentry *dn;
+ if (dir->dentries.count( req->get_filepath()[i] ) == 0)
+ break;
+
+ dout(7) << " have path seg " << i << " " << cur->inode.ino << " " << req->get_filepath()[i] << endl;
+ cur = dir->dentries[ req->get_filepath()[i] ]->inode;
+ assert(cur);
+ } else
+ break;
+ }
+
+ if (cur && cur->mds_contacts.size()) {
+ dout(7) << "contacting mds from deepest inode " << cur->inode.ino << " : " << cur->mds_contacts << endl;
+ set<int>::iterator it = cur->mds_contacts.begin();
+ if (cur->mds_contacts.size() == 1)
+ mds = *it;
+ else {
+ int r = rand() % cur->mds_contacts.size();
+ while (r--) it++;
+ mds = *it;
+ }
+ }
+
// drop mutex for duration of call
client_lock.Unlock();
MClientReply *reply = (MClientReply*)messenger->sendrecv(req,
req->set_caller_uid(getuid());
req->set_caller_gid(getgid());
- MClientReply *reply = make_request(req, 0);
+ MClientReply *reply = make_request(req);
int res = reply->get_result();
this->insert_trace(reply->get_trace());
//FIXME enforce caller uid rights?
- MClientReply *reply = make_request(req, 0);
+ MClientReply *reply = make_request(req);
int res = reply->get_result();
if (res == 0) {
//this crashes, haven't looked at why yet
//FIXME enforce caller uid rights?
- MClientReply *reply = make_request(req, 0);
+ MClientReply *reply = make_request(req);
int res = reply->get_result();
this->insert_trace(reply->get_trace());
delete reply;
//FIXME enforce caller uid rights?
- MClientReply *reply = make_request(req, 0);
+ MClientReply *reply = make_request(req);
int res = reply->get_result();
this->insert_trace(reply->get_trace());
delete reply;
//FIXME enforce caller uid rights?
- MClientReply *reply = make_request(req, 0);
+ MClientReply *reply = make_request(req);
int res = reply->get_result();
if (res == 0) {
// crashes, not sure why yet
//FIXME enforce caller uid rights?
- MClientReply *reply = make_request(req, 0);
+ MClientReply *reply = make_request(req);
int res = reply->get_result();
this->insert_trace(reply->get_trace()); //FIXME assuming trace of link, not of target
delete reply;
req->set_caller_uid(getuid());
req->set_caller_gid(getgid());
- MClientReply *reply = make_request(req, 0);
+ MClientReply *reply = make_request(req);
res = reply->get_result();
dout(10) << "lstat res is " << res << endl;
if (res == 0) {
req->set_caller_uid(getuid());
req->set_caller_gid(getgid());
- MClientReply *reply = make_request(req, 0);
+ MClientReply *reply = make_request(req);
int res = reply->get_result();
this->insert_trace(reply->get_trace());
delete reply;
//FIXME enforce caller uid rights?
- MClientReply *reply = make_request(req, 0);
+ MClientReply *reply = make_request(req);
int res = reply->get_result();
this->insert_trace(reply->get_trace());
delete reply;
//FIXME enforce caller uid rights?
- MClientReply *reply = make_request(req, 0);
+ MClientReply *reply = make_request(req);
int res = reply->get_result();
this->insert_trace(reply->get_trace());
delete reply;
//FIXME enforce caller uid rights?
- MClientReply *reply = make_request(req, 0);
+ MClientReply *reply = make_request(req);
int res = reply->get_result();
this->insert_trace(reply->get_trace());
//FIXME enforce caller uid rights?
- MClientReply *reply = make_request(req, 0);
+ MClientReply *reply = make_request(req);
int res = reply->get_result();
vector<c_inode_info*> trace = reply->get_trace();
this->insert_trace(trace);
req->set_caller_uid(getuid());
req->set_caller_gid(getgid());
- MClientReply *reply = make_request(req, 0);
+ MClientReply *reply = make_request(req);
assert(reply);
dout(3) << "open result = " << reply->get_result() << endl;
release_inode_buffers(in);
- MClientReply *reply = make_request(req, 0);
+ MClientReply *reply = make_request(req);
assert(reply);
int result = reply->get_result();
dout(3) << "close " << fh << " result = " << result << endl;
// blocking mds call
- MClientReply *make_request(MClientRequest *req, int mds);
+ MClientReply *make_request(MClientRequest *req);
// buffer cache
// profiling and debugging
log_messages: true,
- log_interval: 10,
+ log_interval: 1,
log_name: 0,
fake_clock: false,
char **nargv = new pchar[argc];
nargv[nargc++] = argv[0];
- int synthetic = 100;
+ string syn_sarg1;
+ int syn_mode = SYNCLIENT_MODE_WRITEFILE;
+ int syn_iarg1, syn_iarg2, syn_iarg3;
int mkfs = 0;
for (int i=1; i<argc; i++) {
if (strcmp(argv[i], "--fastmkfs") == 0) {
else if (strcmp(argv[i], "--fullmkfs") == 0) {
mkfs = MDS_MKFS_FULL;
}
- else if (strcmp(argv[i],"--synthetic") == 0) {
- synthetic = atoi(argv[++i]);
+
+ else if (strcmp(argv[i],"--synsarg1") == 0)
+ syn_sarg1 = argv[++i];
+ else if (strcmp(argv[i],"--syniarg1") == 0)
+ syn_iarg1 = atoi(argv[++i]);
+ else if (strcmp(argv[i],"--syniarg2") == 0)
+ syn_iarg2 = atoi(argv[++i]);
+ else if (strcmp(argv[i],"--syniarg3") == 0)
+ syn_iarg3 = atoi(argv[++i]);
+ else if (strcmp(argv[i],"--synmode") == 0) {
+ ++i;
+ if (strcmp(argv[i],"writefile") == 0)
+ syn_mode = SYNCLIENT_MODE_WRITEFILE;
+ else if (strcmp(argv[i],"makedirs") == 0)
+ syn_mode = SYNCLIENT_MODE_MAKEDIRS;
+ else if (strcmp(argv[i],"fullwalk") == 0)
+ syn_mode = SYNCLIENT_MODE_FULLWALK;
+ else if (strcmp(argv[i],"randomwalk") == 0)
+ syn_mode = SYNCLIENT_MODE_RANDOMWALK;
+ else {
+ cerr << "unknown syn mode " << argv[i] << endl;
+ return -1;
+ }
}
+
else {
// unknown arg, pass it on.
nargv[nargc++] = argv[i];
cout << "starting synthatic client " << endl;
syn[i] = new SyntheticClient(client[i]);
- syn[i]->mode = SYNCLIENT_MODE_MAKEDIRS;
char s[20];
sprintf(s,"syn.%d", i);
syn[i]->sarg1 = s;
- syn[i]->iarg1 = 5;
- syn[i]->iarg2 = 5;
- syn[i]->iarg3 = 2;
-
+
+ syn[i]->mode = syn_mode;
+ syn[i]->iarg1 = syn_iarg1;
+ syn[i]->iarg2 = syn_iarg2;
+ syn[i]->iarg3 = syn_iarg3;
+
syn[i]->start_thread();
}
for (int i=0; i<NUMCLIENT; i++) {
--- /dev/null
+/* gprof-helper.c -- preload library to profile pthread-enabled programs
+ *
+ * Authors: Sam Hocevar <sam at zoy dot org>
+ * Daniel Jönsson <danieljo at fagotten dot org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the Do What The Fuck You Want To
+ * Public License as published by Banlu Kemiyatorn. See
+ * http://sam.zoy.org/projects/COPYING.WTFPL for more details.
+ *
+ * Compilation example:
+ * gcc -shared -fPIC gprof-helper.c -o gprof-helper.so -lpthread -ldl
+ *
+ * Usage example:
+ * LD_PRELOAD=./gprof-helper.so your_program
+ */
+
+#define _GNU_SOURCE
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <pthread.h>
+
+static void * wrapper_routine(void *);
+
+/* Original pthread function */
+static int (*pthread_create_orig)(pthread_t *__restrict,
+ __const pthread_attr_t *__restrict,
+ void *(*)(void *),
+ void *__restrict) = NULL;
+
+/* Library initialization function */
+void wooinit(void) __attribute__((constructor));
+
+void wooinit(void)
+{
+ pthread_create_orig = dlsym(RTLD_NEXT, "pthread_create");
+ fprintf(stderr, "pthreads: using profiling hooks for gprof\n");
+ if(pthread_create_orig == NULL)
+ {
+ char *error = dlerror();
+ if(error == NULL)
+ {
+ error = "pthread_create is NULL";
+ }
+ fprintf(stderr, "%s\n", error);
+ exit(EXIT_FAILURE);
+ }
+}
+
+/* Our data structure passed to the wrapper */
+typedef struct wrapper_s
+{
+ void * (*start_routine)(void *);
+ void * arg;
+
+ pthread_mutex_t lock;
+ pthread_cond_t wait;
+
+ struct itimerval itimer;
+
+} wrapper_t;
+
+/* The wrapper function in charge for setting the itimer value */
+static void * wrapper_routine(void * data)
+{
+ /* Put user data in thread-local variables */
+ void * (*start_routine)(void *) = ((wrapper_t*)data)->start_routine;
+ void * arg = ((wrapper_t*)data)->arg;
+
+ /* Set the profile timer value */
+ setitimer(ITIMER_PROF, &((wrapper_t*)data)->itimer, NULL);
+
+ /* Tell the calling thread that we don't need its data anymore */
+ pthread_mutex_lock(&((wrapper_t*)data)->lock);
+ pthread_cond_signal(&((wrapper_t*)data)->wait);
+ pthread_mutex_unlock(&((wrapper_t*)data)->lock);
+
+ /* Call the real function */
+ return start_routine(arg);
+}
+
+/* Our wrapper function for the real pthread_create() */
+int pthread_create(pthread_t *__restrict thread,
+ __const pthread_attr_t *__restrict attr,
+ void * (*start_routine)(void *),
+ void *__restrict arg)
+{
+ wrapper_t wrapper_data;
+ int i_return;
+
+ /* Initialize the wrapper structure */
+ wrapper_data.start_routine = start_routine;
+ wrapper_data.arg = arg;
+ getitimer(ITIMER_PROF, &wrapper_data.itimer);
+ pthread_cond_init(&wrapper_data.wait, NULL);
+ pthread_mutex_init(&wrapper_data.lock, NULL);
+ pthread_mutex_lock(&wrapper_data.lock);
+
+ /* The real pthread_create call */
+ i_return = pthread_create_orig(thread,
+ attr,
+ &wrapper_routine,
+ &wrapper_data);
+
+ /* If the thread was successfully spawned, wait for the data
+ * to be released */
+ if(i_return == 0)
+ {
+ pthread_cond_wait(&wrapper_data.wait, &wrapper_data.lock);
+ }
+
+ pthread_mutex_unlock(&wrapper_data.lock);
+ pthread_mutex_destroy(&wrapper_data.lock);
+ pthread_cond_destroy(&wrapper_data.wait);
+
+ return i_return;
+}
+