#undef dout
#define dout(l) if (l<=g_conf.debug || l <= g_conf.debug_client) cout << g_clock.now() << " client" << whoami << "." << pthread_self() << " "
-#define tout if (g_conf.client_trace) cout << "trace: "
+#define tout if (g_conf.client_trace) traceout
// static logger
}
-void Client::init() {
+void Client::init()
+{
+
}
<< " and mdsmap " << mdsmap->get_epoch()
<< endl;
- // get+pin root inode
+ /*
+ // hack: get+pin root inode
Inode *root;
_do_lstat("/", STAT_MASK_ALL, &root);
_ll_get(root);
+ */
+
+ // trace?
+ if (g_conf.client_trace) {
+ traceout.open(g_conf.client_trace);
+ if (traceout.is_open()) {
+ dout(1) << "opened trace file '" << g_conf.client_trace << "'" << endl;
+ } else {
+ dout(1) << "FAILED to open trace file '" << g_conf.client_trace << "'" << endl;
+ }
+ }
client_lock.Unlock();
}
}
-
+ // stop tracing
+ if (g_conf.client_trace) {
+ dout(1) << "closing trace file '" << g_conf.client_trace << "'" << endl;
+ traceout.close();
+ }
+
// send session closes!
for (map<int,version_t>::iterator p = mds_sessions.begin();
}
+// ===============================================================
+// high level (POSIXy) interface
+
// namespace ops
int Client::link(const char *existing, const char *newname)
{
Mutex::Locker lock(client_lock);
+ tout << "link" << endl;
+ tout << existing << endl;
+ tout << newname << endl;
return _link(existing, newname);
}
int Client::_link(const char *existing, const char *newname)
{
- tout << "link" << endl;
- tout << existing << endl;
- tout << newname << endl;
-
-
// main path arg is new link name
// sarg is target (existing file)
-
MClientRequest *req = new MClientRequest(MDS_OP_LINK, messenger->get_myinst());
req->set_path(newname);
req->set_sarg(existing);
int Client::unlink(const char *relpath)
{
Mutex::Locker lock(client_lock);
+ tout << "unlink" << endl;
+ tout << relpath << endl;
+
string abspath;
mkabspath(relpath, abspath);
return _unlink(abspath.c_str());
int Client::_unlink(const char *path)
{
- tout << "unlink" << endl;
- tout << path << endl;
MClientRequest *req = new MClientRequest(MDS_OP_UNLINK, messenger->get_myinst());
req->set_path(path);
int Client::rename(const char *relfrom, const char *relto)
{
Mutex::Locker lock(client_lock);
+ tout << "rename" << endl;
+ tout << relfrom << endl;
+ tout << relto << endl;
+
string absfrom, absto;
mkabspath(relfrom, absfrom);
mkabspath(relto, absto);
int Client::_rename(const char *from, const char *to)
{
- tout << "rename" << endl;
- tout << from << endl;
- tout << to << endl;
-
MClientRequest *req = new MClientRequest(MDS_OP_RENAME, messenger->get_myinst());
req->set_path(from);
req->set_sarg(to);
int Client::mkdir(const char *relpath, mode_t mode)
{
Mutex::Locker lock(client_lock);
+ tout << "mkdir" << endl;
+ tout << relpath << endl;
+ tout << mode << endl;
+
string abspath;
mkabspath(relpath, abspath);
return _mkdir(abspath.c_str(), mode);
int Client::_mkdir(const char *path, mode_t mode)
{
- tout << "mkdir" << endl;
- tout << path << endl;
- tout << mode << endl;
-
MClientRequest *req = new MClientRequest(MDS_OP_MKDIR, messenger->get_myinst());
req->set_path(path);
req->args.mkdir.mode = mode;
int Client::rmdir(const char *relpath)
{
Mutex::Locker lock(client_lock);
+ tout << "rmdir" << endl;
+ tout << relpath << endl;
+
string abspath;
mkabspath(relpath, abspath);
return _rmdir(abspath.c_str());
int Client::_rmdir(const char *path)
{
- tout << "rmdir" << endl;
- tout << path << endl;
-
MClientRequest *req = new MClientRequest(MDS_OP_RMDIR, messenger->get_myinst());
req->set_path(path);
int Client::symlink(const char *reltarget, const char *rellink)
{
Mutex::Locker lock(client_lock);
+ tout << "symlink" << endl;
+ tout << reltarget << endl;
+ tout << rellink << endl;
+
string target, link;
mkabspath(reltarget, target);
mkabspath(rellink, link);
int Client::_symlink(const char *target, const char *link)
{
- tout << "symlink" << endl;
- tout << target << endl;
- tout << link << endl;
-
MClientRequest *req = new MClientRequest(MDS_OP_SYMLINK, messenger->get_myinst());
req->set_path(link);
req->set_sarg(target);
int Client::readlink(const char *path, char *buf, off_t size)
{
Mutex::Locker lock(client_lock);
+ tout << "readlink" << endl;
+ tout << path << endl;
+
string abspath;
mkabspath(path, abspath);
return _readlink(abspath.c_str(), buf, size);
int Client::_readlink(const char *path, char *buf, off_t size)
{
- tout << "readlink" << endl;
- tout << path << endl;
-
Inode *in;
int r = _do_lstat(path, STAT_MASK_BASE, &in);
if (r == 0 && !in->inode.is_symlink()) r = -EINVAL;
int Client::lstat(const char *relpath, struct stat *stbuf)
{
Mutex::Locker lock(client_lock);
+ tout << "lstat" << endl;
+ tout << relpath << endl;
+
string abspath;
mkabspath(relpath, abspath);
return _lstat(abspath.c_str(), stbuf);
int Client::_lstat(const char *path, struct stat *stbuf)
{
- tout << "lstat" << endl;
- tout << path << endl;
-
Inode *in = 0;
int res = _do_lstat(path, STAT_MASK_ALL, &in);
if (res == 0) {
int Client::chmod(const char *relpath, mode_t mode)
{
Mutex::Locker lock(client_lock);
+ tout << "chmod" << endl;
+ tout << relpath << endl;
+ tout << mode << endl;
+
string abspath;
mkabspath(relpath, abspath);
return _chmod(abspath.c_str(), mode);
int Client::_chmod(const char *path, mode_t mode)
{
dout(3) << "_chmod(" << path << ", 0" << oct << mode << dec << ")" << endl;
- tout << "chmod" << endl;
- tout << path << endl;
- tout << mode << endl;
-
MClientRequest *req = new MClientRequest(MDS_OP_CHMOD, messenger->get_myinst());
req->set_path(path);
req->args.chmod.mode = mode;
int res = reply->get_result();
insert_trace(reply);
delete reply;
- dout(10) << "chmod result is " << res << endl;
trim_cache();
- dout(3) << "chmod(\"" << path << "\", 0" << oct << mode << dec << ") = " << res << endl;
+ dout(3) << "_chmod(\"" << path << "\", 0" << oct << mode << dec << ") = " << res << endl;
return res;
}
int Client::chown(const char *relpath, uid_t uid, gid_t gid)
{
Mutex::Locker lock(client_lock);
+ tout << "chown" << endl;
+ tout << relpath << endl;
+ tout << uid << endl;
+ tout << gid << endl;
+
string abspath;
mkabspath(relpath, abspath);
return _chown(abspath.c_str(), uid, gid);
int Client::_chown(const char *path, uid_t uid, gid_t gid)
{
dout(3) << "_chown(" << path << ", " << uid << ", " << gid << ")" << endl;
- tout << "chown" << endl;
- tout << path << endl;
- tout << uid << endl;
- tout << gid << endl;
-
MClientRequest *req = new MClientRequest(MDS_OP_CHOWN, messenger->get_myinst());
req->set_path(path);
req->args.chown.uid = uid;
int Client::utime(const char *relpath, struct utimbuf *buf)
{
Mutex::Locker lock(client_lock);
+ tout << "utime" << endl;
+ tout << relpath << endl;
+ tout << buf->modtime << endl;
+ tout << buf->actime << endl;
+
string abspath;
mkabspath(relpath, abspath);
return _utimes(abspath.c_str(), utime_t(buf->modtime,0), utime_t(buf->actime,0));
int Client::_utimes(const char *path, utime_t mtime, utime_t atime)
{
dout(3) << "_utimes(" << path << ", " << mtime << ", " << atime << ")" << endl;
- tout << "utimes" << endl;
- tout << path << endl;
- tout << mtime.sec() << endl;
- tout << atime.sec() << endl;
-
MClientRequest *req = new MClientRequest(MDS_OP_UTIME, messenger->get_myinst());
req->set_path(path);
req->args.utime.mtime = mtime.tv_ref();
int Client::mknod(const char *relpath, mode_t mode, dev_t rdev)
{
Mutex::Locker lock(client_lock);
+ tout << "mknod" << endl;
+ tout << relpath << endl;
+ tout << mode << endl;
+ tout << rdev << endl;
+
string abspath;
mkabspath(relpath, abspath);
return _mknod(abspath.c_str(), mode, rdev);
int Client::_mknod(const char *path, mode_t mode, dev_t rdev)
{
dout(3) << "_mknod(" << path << ", 0" << oct << mode << dec << ", " << rdev << ")" << endl;
- tout << "mknod" << endl;
- tout << path << endl;
- tout << mode << endl;
MClientRequest *req = new MClientRequest(MDS_OP_MKNOD, messenger->get_myinst());
req->set_path(path);
int Client::getdir(const char *relpath, list<string>& contents)
{
dout(3) << "getdir(" << relpath << ")" << endl;
+ {
+ Mutex::Locker lock(client_lock);
+ tout << "getdir" << endl;
+ tout << relpath << endl;
+ }
DIR *d;
int r = opendir(relpath, &d);
int Client::opendir(const char *name, DIR **dirpp)
{
Mutex::Locker lock(client_lock);
+ tout << "opendir" << endl;
+ tout << name << endl;
- DirResult *dirp = new DirResult(name);
+ int r = _opendir(name, (DirResult**)dirpp);
+ tout << (unsigned long)*dirpp;
+ return r;
+}
+
+int Client::_opendir(const char *name, DirResult **dirpp)
+{
+ *dirpp = new DirResult(name);
// do we have the inode in our cache?
// if so, should be we ask for a different dirfrag?
filepath path(name);
Dentry *dn = lookup(path);
if (dn && dn->inode) {
- dirp->inode = dn->inode;
- dirp->inode->get();
+ (*dirpp)->inode = dn->inode;
+ (*dirpp)->inode->get();
dout(10) << "had inode " << dn->inode << " " << dn->inode->inode.ino << " ref now " << dn->inode->ref << endl;
- dirp->set_frag(dn->inode->dirfragtree[0]);
- dout(10) << "opendir " << name << ", our cache says the first dirfrag is " << dirp->frag() << endl;
+ (*dirpp)->set_frag(dn->inode->dirfragtree[0]);
+ dout(10) << "_opendir " << name << ", our cache says the first dirfrag is " << (*dirpp)->frag() << endl;
}
// get the first frag
- int r = _readdir_get_frag(dirp);
+ int r = _readdir_get_frag(*dirpp);
if (r < 0) {
- dout(3) << "opendir " << name << " err = " << r << endl;
- _closedir(dirp);
- } else {
- // yay!
- *((DirResult**)dirpp) = dirp;
- dout(3) << "opendir(" << name << ") = " << dirp << endl;
+ _closedir(*dirpp);
+ *dirpp = 0;
}
+ dout(3) << "_opendir(" << name << ") = " << r << " (" << *dirpp << ")" << endl;
+
return r;
}
int Client::closedir(DIR *dir)
{
Mutex::Locker lock(client_lock);
+ tout << "closedir" << endl;
+ tout << (unsigned long)dir << endl;
dout(3) << "closedir(" << dir << ") = 0" << endl;
_closedir((DirResult*)dir);
int Client::open(const char *relpath, int flags, mode_t mode)
{
Mutex::Locker lock(client_lock);
+ tout << "open" << endl;
+ tout << relpath << endl;
+ tout << flags << endl;
+
string abspath;
mkabspath(relpath, abspath);
r = get_fd();
assert(fd_map.count(r) == 0);
fd_map[r] = fh;
- }
+ }
+
+ tout << r << endl;
dout(3) << "open(" << relpath << ", " << flags << ") = " << r << endl;
return r;
}
int Client::_open(const char *path, int flags, mode_t mode, Fh **fhp)
{
- tout << "open" << endl;
- tout << path << endl;
- tout << flags << endl;
-
// go
MClientRequest *req = new MClientRequest(MDS_OP_OPEN, messenger->get_myinst());
req->set_path(path);
}
dout(5) << "open success, fh is " << f << " combined caps " << cap_string(f->inode->file_caps()) << endl;
- tout << (long)f << endl;
- } else {
- tout << 0 << endl;
}
delete reply;
int Client::close(int fd)
{
Mutex::Locker lock(client_lock);
+ tout << "close" << endl;
+ tout << fd << endl;
+
dout(3) << "close(" << fd << ")" << endl;
assert(fd_map.count(fd));
Fh *fh = fd_map[fd];
//dout(3) << "op: client->close(open_files[ " << fh << " ]);" << endl;
//dout(3) << "op: open_files.erase( " << fh << " );" << endl;
dout(5) << "_release " << f << endl;
- tout << "close" << endl;
- tout << (long)f << endl;
-
Inode *in = f->inode;
// update inode rd/wr counts
off_t Client::lseek(int fd, off_t offset, int whence)
{
Mutex::Locker lock(client_lock);
+ tout << "lseek" << endl;
+ tout << fd << endl;
+ tout << offset << endl;
+ tout << whence << endl;
assert(fd_map.count(fd));
Fh *f = fd_map[fd];
int Client::read(int fd, char *buf, off_t size, off_t offset)
{
Mutex::Locker lock(client_lock);
+ tout << "read" << endl;
+ tout << fd << endl;
+ tout << size << endl;
+ tout << offset << endl;
+
assert(fd_map.count(fd));
Fh *f = fd_map[fd];
bufferlist bl;
int Client::_read(Fh *f, off_t offset, off_t size, bufferlist *bl)
{
- tout << "read" << endl;
- tout << (long)f << endl;
- tout << size << endl;
- tout << offset << endl;
-
Inode *in = f->inode;
bool movepos = false;
int Client::write(int fd, const char *buf, off_t size, off_t offset)
{
Mutex::Locker lock(client_lock);
+ tout << "write" << endl;
+ tout << fd << endl;
+ tout << size << endl;
+ tout << offset << endl;
+
assert(fd_map.count(fd));
Fh *fh = fd_map[fd];
int r = _write(fh, offset, size, buf);
int Client::_write(Fh *f, off_t offset, off_t size, const char *buf)
{
//dout(7) << "write fh " << fh << " size " << size << " offset " << offset << endl;
- tout << "write" << endl;
- tout << f << endl;
- tout << size << endl;
- tout << offset << endl;
-
Inode *in = f->inode;
// use/adjust fd pos?
int Client::truncate(const char *relpath, off_t length)
{
Mutex::Locker lock(client_lock);
+ tout << "truncate" << endl;
+ tout << relpath << endl;
+ tout << length << endl;
+
string path;
mkabspath(relpath, path);
return _truncate(path.c_str(), length);
int Client::_truncate(const char *file, off_t length)
{
- tout << "truncate" << endl;
- tout << file << endl;
- tout << length << endl;
-
MClientRequest *req = new MClientRequest(MDS_OP_TRUNCATE, messenger->get_myinst());
req->set_path(file);
req->args.truncate.length = length;
int Client::ftruncate(int fd, off_t length)
{
Mutex::Locker lock(client_lock);
+ tout << "ftruncate" << endl;
+ tout << fd << endl;
+ tout << length << endl;
+
assert(fd_map.count(fd));
Fh *f = fd_map[fd];
return _ftruncate(f, length);
int Client::_ftruncate(Fh *fh, off_t length)
{
- tout << "ftruncate" << endl;
- tout << (long)fh << endl;
- tout << length << endl;
-
MClientRequest *req = new MClientRequest(MDS_OP_TRUNCATE, messenger->get_myinst());
req->args.truncate.ino = fh->inode->inode.ino;
req->args.truncate.length = length;
int Client::fsync(int fd, bool syncdataonly)
{
Mutex::Locker lock(client_lock);
+ tout << "fsync" << endl;
+ tout << fd << endl;
+ tout << syncdataonly << endl;
+
assert(fd_map.count(fd));
Fh *f = fd_map[fd];
int r = _fsync(f, syncdataonly);
int Client::_fsync(Fh *f, bool syncdataonly)
{
- tout << "fsync" << endl;
- tout << (long)f << endl;
- tout << syncdataonly << endl;
-
int r = 0;
Inode *in = f->inode;
int Client::chdir(const char *path)
{
+ Mutex::Locker lock(client_lock);
+ tout << "chdir" << endl;
+ tout << path << endl;
+
// fake it for now!
string abs;
mkabspath(path, abs);
int Client::statfs(const char *path, struct statvfs *stbuf)
{
+ Mutex::Locker lock(client_lock);
+ tout << "statfs" << endl;
+
bzero (stbuf, sizeof (struct statvfs));
// FIXME
stbuf->f_bsize = 1024;
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_lookup " << parent << " " << name << endl;
+ tout << "ll_lookup" << endl;
+ tout << parent.val << endl;
+ tout << name << endl;
- if (inode_map.count(parent) == 0) return -ENOENT;
+ if (inode_map.count(parent) == 0) {
+ tout << 0 << endl;
+ dout(1) << "ll_lookup " << parent << " " << name << " -> ENOENT (parent DNE... WTF)" << endl;
+ return -ENOENT;
+ }
Inode *diri = inode_map[parent];
- if (!diri->inode.is_dir()) return -ENOTDIR;
+ if (!diri->inode.is_dir()) {
+ tout << 0 << endl;
+ dout(1) << "ll_lookup " << parent << " " << name << " -> ENOTDIR (parent not a dir... WTF)" << endl;
+ return -ENOTDIR;
+ }
string dname = name;
Inode *in = diri->dir->dentries[dname]->inode;
fill_stat(in, attr);
_ll_get(in);
- dout(3) << "ll_lookup " << parent << " " << name << " -> " << in->inode.ino << endl;
+ dout(3) << "ll_lookup " << parent << " " << name << " -> " << in->inode.ino
+ << " (" << in << ")" << endl;
+ assert(inode_map[in->inode.ino] == in);
+ tout << in->inode.ino << endl;
return 0;
} else {
+ dout(3) << "ll_lookup " << parent << " " << name << " -> ENOENT" << endl;
+ tout << 0 << endl;
return -ENOENT;
}
}
dout(20) << "_ll_get " << in << " " << in->inode.ino << " -> " << in->ll_ref << endl;
}
-void Client::_ll_put(Inode *in, int num)
+int Client::_ll_put(Inode *in, int num)
{
in->ll_put(num);
dout(20) << "_ll_put " << in << " " << in->inode.ino << " " << num << " -> " << in->ll_ref << endl;
- if (in->ll_ref == 0)
+ if (in->ll_ref == 0) {
put_inode(in);
+ return 0;
+ } else {
+ return in->ll_ref;
+ }
}
void Client::_ll_drop_pins()
{
dout(10) << "_ll_drop_pins" << endl;
+ hash_map<inodeno_t, Inode*>::iterator next;
for (hash_map<inodeno_t, Inode*>::iterator it = inode_map.begin();
it != inode_map.end();
- it++) {
+ it = next) {
Inode *in = it->second;
+ next = it;
+ next++;
if (in->ll_ref)
_ll_put(in, in->ll_ref);
}
}
-void Client::ll_forget(inodeno_t ino, int num)
+bool Client::ll_forget(inodeno_t ino, int num)
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_forget " << ino << " " << num << endl;
+ tout << "ll_forget" << endl;
+ tout << ino.val << endl;
+ tout << num << endl;
- if (ino == 1) return; // ignore forget on root.
+ if (ino == 1) return true; // ignore forget on root.
+ bool last = false;
if (inode_map.count(ino) == 0) {
dout(1) << "WARNING: ll_forget on " << ino << " " << num
<< ", which I don't have" << endl;
} else {
Inode *in = inode_map[ino];
assert(in);
- _ll_put(in, num);
+ if (_ll_put(in, num) == 0)
+ last = true;
}
+ return last;
}
Inode *Client::_ll_get_inode(inodeno_t ino)
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_getattr " << ino << endl;
+ tout << "ll_getattr" << endl;
+ tout << ino.val << endl;
+
Inode *in = _ll_get_inode(ino);
fill_stat(in, attr);
return 0;
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_setattr " << ino << " mask " << hex << mask << dec << endl;
+ tout << "ll_setattr" << endl;
+ tout << ino.val << endl;
+ tout << attr->st_mode << endl;
+ tout << attr->st_uid << endl;
+ tout << attr->st_gid << endl;
+ tout << attr->st_size << endl;
+ tout << attr->st_mtime << endl;
+ tout << attr->st_atime << endl;
+ tout << mask << endl;
+
Inode *in = _ll_get_inode(ino);
string path;
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_readlink " << ino << endl;
+ tout << "ll_readlink" << endl;
+ tout << ino.val << endl;
+
Inode *in = _ll_get_inode(ino);
if (in->inode.is_symlink()) {
*value = in->symlink->c_str();
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_mknod " << parent << " " << name << endl;
+ tout << "ll_mknod" << endl;
+ tout << parent.val << endl;
+ tout << name << endl;
+ tout << mode << endl;
+ tout << rdev << endl;
+
Inode *diri = _ll_get_inode(parent);
string path;
string dname(name);
Inode *in = diri->dir->dentries[dname]->inode;
fill_stat(in, attr);
- //_ll_get(in);
+ _ll_get(in);
}
+ tout << attr->st_ino << endl;
dout(3) << "ll_mknod " << parent << " " << name << " = " << r << endl;
return r;
}
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_mkdir " << parent << " " << name << endl;
+ tout << "ll_mkdir" << endl;
+ tout << parent.val << endl;
+ tout << name << endl;
+ tout << mode << endl;
+
Inode *diri = _ll_get_inode(parent);
string path;
string dname(name);
Inode *in = diri->dir->dentries[dname]->inode;
fill_stat(in, attr);
- //_ll_get(in);
+ _ll_get(in);
}
+ tout << attr->st_ino << endl;
dout(3) << "ll_mkdir " << parent << " " << name << " = " << r << endl;
return r;
}
int Client::ll_symlink(inodeno_t parent, const char *name, const char *value, struct stat *attr)
{
Mutex::Locker lock(client_lock);
- dout(3) << "ll_mknod " << parent << " " << name << " -> " << value << endl;
+ dout(3) << "ll_symlink " << parent << " " << name << " -> " << value << endl;
+ tout << "ll_symlink" << endl;
+ tout << parent.val << endl;
+ tout << name << endl;
+ tout << value << endl;
+
Inode *diri = _ll_get_inode(parent);
string path;
string dname(name);
Inode *in = diri->dir->dentries[dname]->inode;
fill_stat(in, attr);
- //_ll_get(in);
+ _ll_get(in);
}
+ tout << attr->st_ino << endl;
return r;
}
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_unlink " << ino << " " << name << endl;
+ tout << "ll_unlink" << endl;
+ tout << ino.val << endl;
+ tout << name << endl;
+
Inode *diri = _ll_get_inode(ino);
string path;
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_rmdir " << ino << " " << name << endl;
+ tout << "ll_rmdir" << endl;
+ tout << ino.val << endl;
+ tout << name << endl;
+
Inode *diri = _ll_get_inode(ino);
string path;
Mutex::Locker lock(client_lock);
dout(3) << "ll_rename " << parent << " " << name << " to "
<< newparent << " " << newname << endl;
+ tout << "ll_rename" << endl;
+ tout << parent.val << endl;
+ tout << name << endl;
+ tout << newparent.val << endl;
+ tout << newname << endl;
Inode *diri = _ll_get_inode(parent);
string path;
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_link " << ino << " to " << newparent << " " << newname << endl;
+ tout << "ll_link" << endl;
+ tout << ino.val << endl;
+ tout << newparent << endl;
+ tout << newname << endl;
+
Inode *old = _ll_get_inode(ino);
Inode *diri = _ll_get_inode(newparent);
string dname(newname);
Inode *in = diri->dir->dentries[dname]->inode;
fill_stat(in, attr);
- //_ll_get(in);
+ _ll_get(in);
}
return r;
}
int Client::ll_opendir(inodeno_t ino, void **dirpp)
{
+ Mutex::Locker lock(client_lock);
+ dout(3) << "ll_opendir " << ino << endl;
+ tout << "ll_opendir" << endl;
+ tout << ino.val << endl;
+
+ Inode *diri = inode_map[ino];
+ assert(diri);
string path;
- {
- Mutex::Locker lock(client_lock);
- dout(3) << "ll_opendir " << ino << endl;
- Inode *diri = inode_map[ino];
- assert(diri);
- diri->make_path(path);
- }
- DIR *dir;
- int r = opendir(path.c_str(), &dir);
- dout(3) << "ll_opendir " << ino << " = " << r << endl;
- if (r < 0) return r;
- *dirpp = (void*)dir;
- return 0;
+ diri->make_path(path);
+
+ int r = _opendir(path.c_str(), (DirResult**)dirpp);
+
+ tout << (unsigned long)*dirpp << endl;
+
+ dout(3) << "ll_opendir " << ino << " = " << r << " (" << *dirpp << ")" << endl;
+ return r;
+}
+
+void Client::ll_releasedir(void *dirp)
+{
+ Mutex::Locker lock(client_lock);
+ dout(3) << "ll_releasedir " << dirp << endl;
+ tout << "ll_releasedir" << endl;
+ tout << (unsigned long)dirp << endl;
+ _closedir((DirResult*)dirp);
}
int Client::ll_open(inodeno_t ino, int flags, Fh **fhp)
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_open " << ino << " " << flags << endl;
+ tout << "ll_open" << endl;
+ tout << ino.val << endl;
+ tout << flags << endl;
Inode *in = _ll_get_inode(ino);
string path;
in->make_path(path);
int r = _open(path.c_str(), flags, 0, fhp);
- if (r < 0) return r;
+
+ tout << (unsigned long)*fhp << endl;
dout(3) << "ll_open " << ino << " " << flags << " = " << r << " (" << *fhp << ")" << endl;
- return 0;
+ return r;
}
int Client::ll_create(inodeno_t parent, const char *name, mode_t mode, int flags,
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_create " << parent << " " << name << " 0" << oct << mode << dec << " " << flags << endl;
+ tout << "ll_create" << endl;
+ tout << parent.val << endl;
+ tout << name << endl;
+ tout << mode << endl;
+ tout << flags << endl;
Inode *pin = _ll_get_inode(parent);
string path;
fill_stat(in, attr);
//_ll_get(in);
}
+ tout << (unsigned long)*fhp << endl;
+ tout << attr->st_ino << endl;
dout(3) << "ll_create " << parent << " " << name << " 0" << oct << mode << dec
<< " " << flags << " = " << r << " (" << *fhp << ")" << endl;
return 0;
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_read " << fh << " " << off << "~" << len << endl;
+ tout << "ll_read" << endl;
+ tout << (unsigned long)fh << endl;
+ tout << off << endl;
+ tout << len << endl;
+
return _read(fh, off, len, bl);
}
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_write " << fh << " " << off << "~" << len << endl;
+ tout << "ll_write" << endl;
+ tout << (unsigned long)fh << endl;
+ tout << off << endl;
+ tout << len << endl;
+
return _write(fh, off, len, data);
}
{
Mutex::Locker lock(client_lock);
dout(3) << "ll_release " << fh << endl;
+ tout << "ll_release" << endl;
+ tout << (unsigned long)fh << endl;
+
_release(fh);
return 0;
}
#include <sys/types.h>
#include <utime.h>
#include <math.h>
+#include <sys/statvfs.h>
#include "config.h"
#undef dout
dout(4) << "play trace" << endl;
t.start();
+ char buf[1024];
+
utime_t start = g_clock.now();
const char *p = prefix.c_str();
map<int64_t, int64_t> open_files;
+ map<int64_t, DIR*> open_dirs;
+
+ map<int64_t, Fh*> ll_files;
+ map<int64_t, void*> ll_dirs;
+ map<uint64_t, int64_t> ll_inos;
+
+ ll_inos[1] = 1; // root inode is known.
while (!t.end()) {
if (time_to_stop()) break;
// op
- const char *op = t.get_string();
- dout(4) << "trace op " << op << endl;
+ const char *op = t.get_string(buf, 0);
+ dout(4) << (t.get_line()-1) << ": trace op " << op << endl;
+
+ // high level ops ---------------------
if (strcmp(op, "link") == 0) {
- const char *a = t.get_string(p);
- const char *b = t.get_string(p);
+ const char *a = t.get_string(buf, p);
+ const char *b = t.get_string(buf, p);
client->link(a,b);
} else if (strcmp(op, "unlink") == 0) {
- const char *a = t.get_string(p);
+ const char *a = t.get_string(buf, p);
client->unlink(a);
} else if (strcmp(op, "rename") == 0) {
- const char *a = t.get_string(p);
- const char *b = t.get_string(p);
+ const char *a = t.get_string(buf, p);
+ const char *b = t.get_string(buf, p);
client->rename(a,b);
} else if (strcmp(op, "mkdir") == 0) {
- const char *a = t.get_string(p);
+ const char *a = t.get_string(buf, p);
int64_t b = t.get_int();
client->mkdir(a, b);
} else if (strcmp(op, "rmdir") == 0) {
- const char *a = t.get_string(p);
+ const char *a = t.get_string(buf, p);
client->rmdir(a);
} else if (strcmp(op, "symlink") == 0) {
- const char *a = t.get_string(p);
- const char *b = t.get_string(p);
+ const char *a = t.get_string(buf, p);
+ const char *b = t.get_string(buf, p);
client->symlink(a,b);
} else if (strcmp(op, "readlink") == 0) {
- const char *a = t.get_string(p);
+ const char *a = t.get_string(buf, 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);
+ const char *a = t.get_string(buf, p);
client->lstat(a, &st);
} else if (strcmp(op, "chmod") == 0) {
- const char *a = t.get_string(p);
+ const char *a = t.get_string(buf, p);
int64_t b = t.get_int();
client->chmod(a, b);
} else if (strcmp(op, "chown") == 0) {
- const char *a = t.get_string(p);
+ 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);
} else if (strcmp(op, "utime") == 0) {
- const char *a = t.get_string(p);
+ const char *a = t.get_string(buf, p);
int64_t b = t.get_int();
int64_t c = t.get_int();
struct utimbuf u;
u.modtime = c;
client->utime(a, &u);
} else if (strcmp(op, "mknod") == 0) {
- const char *a = t.get_string(p);
+ const char *a = t.get_string(buf, p);
int64_t b = t.get_int();
- client->mknod(a, b);
+ int64_t c = t.get_int();
+ client->mknod(a, b, c);
+ } else if (strcmp(op, "getdir") == 0) {
+ const char *a = t.get_string(buf, p);
+ list<string> contents;
+ client->getdir(a, contents);
} else if (strcmp(op, "getdir") == 0) {
- const char *a = t.get_string(p);
+ const char *a = t.get_string(buf, p);
list<string> contents;
client->getdir(a, contents);
+ } else if (strcmp(op, "opendir") == 0) {
+ const char *a = t.get_string(buf, p);
+ int64_t b = t.get_int();
+ DIR *dirp;
+ client->opendir(a, &dirp);
+ 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(p);
+ const char *a = t.get_string(buf, p);
int64_t b = t.get_int();
- int64_t id = t.get_int();
- int64_t fh = client->open(a, b);
- open_files[id] = fh;
+ int64_t c = t.get_int();
+ int64_t d = t.get_int();
+ int64_t fd = client->open(a, b, c);
+ 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, "truncate") == 0) {
- const char *a = t.get_string(p);
- int64_t b = t.get_int();
- client->truncate(a,b);
- } else if (strcmp(op, "read") == 0) {
- int64_t id = t.get_int();
- int64_t fh = open_files[id];
- int size = t.get_int();
- int off = t.get_int();
- char *buf = new char[size];
- client->read(fh, buf, size, off);
- delete[] buf;
} else if (strcmp(op, "lseek") == 0) {
- int64_t id = t.get_int();
- int64_t fh = open_files[id];
- int off = t.get_int();
- int whence = t.get_int();
- client->lseek(fh, off, whence);
+ 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];
+ char *b = new char[size];
+ client->read(fd, b, size, off);
+ delete[] b;
} else if (strcmp(op, "write") == 0) {
- int64_t id = t.get_int();
- int64_t fh = open_files[id];
- int size = t.get_int();
- int off = t.get_int();
- char *buf = new char[size];
- memset(buf, 1, size); // let's write 1's!
- client->write(fh, buf, size, off);
- delete[] buf;
+ int64_t f = t.get_int();
+ int64_t fd = open_files[f];
+ int64_t size = t.get_int();
+ int64_t off = t.get_int();
+ char *b = new char[size];
+ memset(b, 1, size); // let's write 1's!
+ client->write(fd, b, size, off);
+ delete[] b;
+ } else if (strcmp(op, "truncate") == 0) {
+ const char *a = t.get_string(buf, p);
+ int64_t l = t.get_int();
+ client->truncate(a, l);
+ } 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);
} 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->chdir(a);
+ } else if (strcmp(op, "statfs") == 0) {
+ struct statvfs stbuf;
+ client->statfs("/", &stbuf);
+ }
+
+ // 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 stat attr;
+ if (client->ll_lookup(i, name, &attr) == 0)
+ ll_inos[r] = attr.st_ino;
+ } else if (strcmp(op, "ll_forget") == 0) {
+ int64_t i = t.get_int();
+ int64_t n = t.get_int();
+ if (client->ll_forget(ll_inos[i], n))
+ ll_inos.erase(i);
+ } else if (strcmp(op, "ll_getattr") == 0) {
+ int64_t i = t.get_int();
+ struct stat attr;
+ client->ll_getattr(ll_inos[i], &attr);
+ } 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();
+ client->ll_setattr(ll_inos[i], &attr, mask);
+ } else if (strcmp(op, "ll_readlink") == 0) {
+ int64_t i = t.get_int();
+ const char *value;
+ client->ll_readlink(ll_inos[i], &value);
+ } 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 (client->ll_mknod(ll_inos[i], n, m, r, &attr) == 0)
+ ll_inos[ri] = attr.st_ino;
+ } 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 (client->ll_mkdir(ll_inos[i], n, m, &attr) == 0)
+ ll_inos[ri] = attr.st_ino;
+ } 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(buf, p);
+ int64_t ri = t.get_int();
+ struct stat attr;
+ if (client->ll_symlink(i, n, v, &attr) == 0)
+ ll_inos[ri] = attr.st_ino;
+ } else if (strcmp(op, "ll_unlink") == 0) {
+ int64_t i = t.get_int();
+ const char *n = t.get_string(buf, p);
+ client->ll_unlink(ll_inos[i], n);
+ } else if (strcmp(op, "ll_rmdir") == 0) {
+ int64_t i = t.get_int();
+ const char *n = t.get_string(buf, p);
+ client->ll_rmdir(ll_inos[i], n);
+ } 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(buf, p);
+ client->ll_rename(ll_inos[i], n, ll_inos[ni], nn);
+ } 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);
+ struct stat attr;
+ client->ll_link(ll_inos[i], ni, nn, &attr);
+ } else if (strcmp(op, "ll_opendir") == 0) {
+ int64_t i = t.get_int();
+ int64_t r = t.get_int();
+ void *dirp;
+ client->ll_opendir(ll_inos[i], &dirp);
+ ll_dirs[r] = dirp;
+ } else if (strcmp(op, "ll_releasedir") == 0) {
+ int64_t f = t.get_int();
+ void *dirp = ll_dirs[f];
+ client->ll_releasedir(dirp);
+ 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;
+ client->ll_open(ll_inos[i], f, &fhp);
+ ll_files[r] = fhp;
+ } 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();
+ Fh *fhp;
+ struct stat attr;
+ if (client->ll_create(ll_inos[i], n, m, f, &attr, &fhp) == 0) {
+ ll_inos[ri] = attr.st_ino;
+ ll_files[r] = fhp;
+ }
+ } 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();
+ Fh *fh = ll_files[f];
+ bufferlist bl;
+ client->ll_read(fh, 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();
+ Fh *fh = ll_files[f];
+ bufferlist bl;
+ bufferptr bp(size);
+ bl.push_back(bp);
+ bp.zero();
+ client->ll_write(fh, off, size, bl.c_str());
+ } else if (strcmp(op, "ll_release") == 0) {
+ int64_t f = t.get_int();
+ Fh *fh = ll_files[f];
+ client->ll_release(fh);
+ ll_files.erase(f);
+ }
+
+ else {
+ cout << (t.get_line()-1) << ": *** trace hit unrecognized symbol '" << op << "' " << endl;
assert(0);
- } else
- assert(0);
+ }
}
// close open files
}
+
int SyntheticClient::clean_dir(string& basedir)
{
// read dir
}
+