}
 
 
+MDLog::~MDLog()
+{
+  if (reader) { delete reader; reader = 0; }
+  if (writer) { delete writer; writer = 0; }
+}
+
 
 int MDLog::submit_entry( LogEvent *e,
                                                 Context *c ) 
 
 #include "messages/MOSDReadReply.h"
 #include "messages/MOSDWriteReply.h"
 
-
 #include <list>
 
 #include <iostream>
   if (mdcache) { delete mdcache; mdcache = NULL; }
   if (mdstore) { delete mdstore; mdstore = NULL; }
   if (messenger) { delete messenger; messenger = NULL; }
+  if (mdlog) { delete mdlog; mdlog = NULL; }
 }
 
 
   messenger->init(this);
 }
 
-void MDS::shutdown()
+int MDS::shutdown()
 {
+  // shut down cache
+  mdcache->clear();
+  
+  // shut down messenger
   messenger->shutdown();
+
+  return 0;
 }
 
 void MDS::proc_message(Message *m) 
        if (((MPing*)m)->ttl > 0) {
          cout << nodeid << " responding to " << m->get_source() << endl;
          messenger->send_message(new MPing(((MPing*)m)->ttl-1), 
-                                                         m->get_source(), m->get_source_port());
+                                                         m->get_source(), m->get_source_port(),
+                                                         MDS_PORT_MAIN);
        }
        break;
 
        *p->bytesread = m->len;
 
        if (p->buf) { // user buffer
-         memcpy(p->buf, m->buf, m->len);
+         memcpy(p->buf, m->buf, m->len);  // copy
+         delete m->buf;                   // free message buf
        } else {      // new buffer
-         // steal message's buffer   (this is probably a bad idea?  :/ )
-         *p->bufptr = m->buf;   
-         m->buf = 0;
+         *p->bufptr = m->buf;     // steal message's buffer
        }
+       m->buf = 0;
   }
 
   delete p;
 int MDS::osd_write(int osd, object_t oid, size_t len, size_t offset, char *buf, int flags, Context *c)
 {
   osd_last_tid++;
+
+  char *nbuf = new char[len];
+  memcpy(nbuf, buf, len);
+
   MOSDWrite *m = new MOSDWrite(osd_last_tid,
                                                           oid,
                                                           len, offset,
-                                                          buf, flags);
+                                                          nbuf, flags);
   osd_writes[ osd_last_tid ] = c;
   cout << "mds: sending MOSDWrite " << m->get_type() << endl;
   messenger->send_message(m,
 
        // dentry
        string dname = buf+p;
        p += dname.length() + 1;
-       cout << "parse filename " << dname << endl;
+       //cout << "parse filename " << dname << endl;
 
        // just a hard link?
        if (*(buf+p) == 'L') {
          p++;
 
          // inode
-         inodeno_t ino = ((struct inode_t*)(buf+p+1))->ino;
-         if (mds->mdcache->have_inode(ino)) 
-               throw "inode already exists!  uh oh\n";
-
-         // new inode
          CInode *in = new CInode();
          memcpy(&in->inode, buf+p, sizeof(inode_t));
          p += sizeof(inode_t);
+         
+         cout << " got " << in->inode.ino << " " << dname << endl;
+         if (mds->mdcache->have_inode(in->inode.ino)) 
+               throw "inode already exists!  uh oh\n";
                
          // add and link
          mds->mdcache->add_inode( in );
 
   if (messenger) { delete messenger; messenger = 0; }
 }
 
-void OSD::init()
+int OSD::init()
 {
   messenger->set_dispatcher(this);
+  return 0;
+}
+
+int OSD::shutdown()
+{
+  messenger->shutdown();
+  return 0;
 }
 
 
 
   } else {
 
-       // read part of the object
-       lseek(fd, r->offset, SEEK_SET);
-       
        if (r->len == 0) {                    // read whole thing
          r->len = lseek(fd, 0, SEEK_END);  // get size
-       }
+         lseek(fd, 0, SEEK_SET);           // back to beginning
+       } else
+         lseek(fd, r->offset, SEEK_SET);   // seek     
+
        char *buf = new char[r->len];
        
        long got = ::read(fd, buf, r->len);
          lseek(fd, m->offset, SEEK_SET);
        long wrote = ::write(fd, m->buf, m->len);
        close(fd);
-       
+
        // reply
        reply = new MOSDWriteReply(m, wrote);
   }
 
+  // clean up
   cout << "sending reply" << endl;
   messenger->send_message(reply, m->get_source(), m->get_source_port());
+
+  delete m->buf;
   delete m;
 }
 
 
-
+#include <sys/types.h>
 #include "include/Clock.h"
 
+#ifndef NULL
+#define NULL 0
+#endif
+
 // public
 Clock g_clock;
 
 
   }
 
   int init();
-  void shutdown();
+  int shutdown();
 
   void proc_message(Message *m);
   virtual void dispatch(Message *m);
 
   OSD(int id, Messenger *m);
   ~OSD();
   
-  void init();
+  int init();
+  int shutdown();
 
   virtual void dispatch(Message *m);
 
 
 class MOSDReadReply : public MBuffer {
  public:
   long tid;
-  long len;
-  char *buf;
   off_t offset;
   object_t oid;
   MOSDReadReply(MOSDRead *r, char *buf, long len) :
 
 class MPing : public Message {
  public:
   int ttl;
-  MPing(int n) {
+  MPing(int n) : Message(MSG_PING) {
        ttl = n;
-       dest_port = MSG_SUBSYS_SERVER;
-       type = MSG_PING;
   }
 };
 
 
   void set_dispatcher(Dispatcher *d) {
        dispatcher = d;
   }
-  void remove_dispatcher() {
-       if (dispatcher) { delete dispatcher; dispatcher = 0; }
+  Dispatcher *remove_dispatcher() {
+       Dispatcher *t = dispatcher;
+       dispatcher = 0;
+       return t;
   }
 
   // ...
 
 #include <string>
 
 #include "include/MDS.h"
+#include "include/OSD.h"
 #include "include/MDCache.h"
 #include "include/MDStore.h"
 #include "include/FakeMessenger.h"
 
 
 // this parses find output
+int play();
 
-DentryCache *readfiles() {
-  DentryCache *dc = new DentryCache();
-
-  string fn;
-  int offs = -1;
-  while (getline(cin, fn)) {
-       string relfn;
-
-       CInode *in = new CInode();
-
-       if (offs < 0) {
-         if (fn == "/")
-               offs = 0;
-         else 
-               offs = fn.length();
-         //cout << "offs is " << offs << " from " << fn << endl;
-         relfn = "/";
-         in->inode.ino = 1;  // root
-       } else 
-         relfn = fn.substr(offs);
-       
-       // fill out inode
-       struct stat sb;
-       stat(fn.c_str(), &sb);
-
-       in->inode.ino = ino++; //sb.st_ino;
-       in->inode.mode = sb.st_mode;
-       in->inode.size = sb.st_size;
-       in->inode.uid = sb.st_uid;
-       in->inode.gid = sb.st_gid;
-       in->inode.atime = sb.st_atime;
-       in->inode.mtime = sb.st_mtime;
-       in->inode.ctime = sb.st_ctime;
-               
-       // add
-       dc->add_file(relfn, in);
-       cout << "added " << relfn << endl;
+int main(char **argv, int argc) {
+  cout << "hi there" << endl;
+
+  try {
+       play();
+  }
+  catch (char *s) {
+       cout << "exception: " << s << endl;
   }
-  
-  return dc;
 }
 
-int main(char **argv, int argc) {
-  cout << "hi there" << endl;
+int play() {
+  cout << "hello" << endl;
 
   // init
-  MDS *mds1 = new MDS(0, 2, new FakeMessenger(MSG_ADDR_MDS(0)));
-  mds1->open_root(NULL);
-  mds1->init();
+  // create mds
+  MDS *mds[10];
+  for (int i=0; i<10; i++) {
+       mds[i] = new MDS(0, 1, new FakeMessenger(MSG_ADDR_MDS(i)));
+       mds[i]->open_root(NULL);
+       mds[i]->init();
+  }
 
-  mds1->mdstore->fetch_dir( mds1->mdcache->get_root(), NULL );
+  // create osds
+  OSD *osd[10];
+  for (int i=0; i<10; i++) {
+       osd[i] = new OSD(i, new FakeMessenger(MSG_ADDR_OSD(i)));
+       osd[i]->init();
+  }
 
-  
-  MDS *mds2 = new MDS(1,2,new FakeMessenger(MSG_ADDR_MDS(1)));
-  mds2->init();
+  // fetch root on mds0
+  mds[0]->mdstore->fetch_dir( mds[0]->mdcache->get_root(), NULL );
 
   // send an initial message...?
-  mds1->messenger->send_message(new MPing(10), 1);
+  mds[0]->messenger->send_message(new MPing(10), 1, MDS_PORT_MAIN, MDS_PORT_MAIN);
 
   // loop
   fakemessenger_do_loop();
 
-
   // cleanup
-  if (mds1->mdcache->clear()) {
-       cout << "clean shutdown" << endl;
-       mds1->mdcache->dump();
-       delete mds1;
-  } else {
-       cout << "can't empty cache";
+  for (int i=0; i<10; i++) {
+       if (mds[i]->shutdown() == 0) {
+         //cout << "clean shutdown of mds " << i << endl;
+         delete mds[i];
+       } else {
+         cout << "problems shutting down mds " << i << endl;
+       }
+
+       if (osd[i]->shutdown() == 0) { 
+         //cout << "clean shutdown of osd " << i << endl;
+         delete osd[i];
+       } else {
+         cout << "problems shutting down osd " << i << endl;
+       }
   }
-
+  cout << "done." << endl;
   return 0;
 }