configure | 33 ++
fsdev/qemu-fsdev.c | 1 +
fsdev/qemu-fsdev.h | 3 +-
hw/9pfs/9p-cephfs.c | 836
++++++++++++++++++++++++++++++++++++++
hw/9pfs/Makefile.objs | 3 +
scripts/analyse-9p-simpletrace.py | 213 ----------
scripts/analyze-9p-simpletrace.py | 306 ++++++++++++++
trace-events | 33 ++
8 files changed, 1214 insertions(+), 214 deletions(-)
create mode 100644 hw/9pfs/9p-cephfs.c
delete mode 100755 scripts/analyse-9p-simpletrace.py
create mode 100755 scripts/analyze-9p-simpletrace.py
diff --git a/configure b/configure
index 0c0472a..c48f1af 100755
--- a/configure
+++ b/configure
@@ -275,6 +275,7 @@ trace_backends="log"
trace_file="trace"
spice=""
rbd=""
+cephfs=""
smartcard=""
libusb=""
usb_redir=""
@@ -1019,6 +1020,10 @@ for opt do
;;
--enable-rbd) rbd="yes"
;;
+ --disable-cephfs) cephfs="no"
+ ;;
+ --enable-cephfs) cephfs="yes"
+ ;;
--disable-xfsctl) xfs="no"
;;
--enable-xfsctl) xfs="yes"
@@ -1345,6 +1350,7 @@ disabled with --disable-FEATURE, default is
enabled if available:
vhost-net vhost-net acceleration support
spice spice
rbd rados block device (rbd)
+ cephfs Ceph File System
libiscsi iscsi support
libnfs nfs support
smartcard smartcard support (libcacard)
@@ -3087,6 +3093,28 @@ EOF
fi
##########################################
+# cephfs probe
+if test "$cephfs" != "no" ; then
+ cat > $TMPC <<EOF
+#include <stdio.h>
+#include <cephfs/libcephfs.h>
+int main(void) {
+ struct ceph_mount_info *cmount;
+ ceph_create(&cmount, NULL);
+ return 0;
+}
+EOF
+ cephfs_libs="-lcephfs"
+ if compile_prog "" "$cephfs_libs" ; then
+ cephfs=yes
+ else
+ if test "$cephfs" = "yes" ; then
+ feature_not_found "cephfs" "Install libcephfs/ceph devel"
+ fi
+ cephfs=no
+ fi
+fi
+##########################################
# libssh2 probe
min_libssh2_version=1.2.8
if test "$libssh2" != "no" ; then
@@ -4760,6 +4788,7 @@ else
echo "spice support $spice"
fi
echo "rbd support $rbd"
+echo "cephfs support $cephfs"
echo "xfsctl support $xfs"
echo "smartcard support $smartcard"
echo "libusb $libusb"
@@ -5224,6 +5253,10 @@ if test "$rbd" = "yes" ; then
echo "RBD_CFLAGS=$rbd_cflags" >> $config_host_mak
echo "RBD_LIBS=$rbd_libs" >> $config_host_mak
fi
+if test "$cephfs" = "yes" ; then
+ echo "CONFIG_CEPHFS=m" >> $config_host_mak
+ echo "CEPHFS_LIBS=$cephfs_libs" >> $config_host_mak
+fi
echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak
if test "$coroutine_pool" = "yes" ; then
diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c
index bf7f0b0..7f07a2a 100644
--- a/fsdev/qemu-fsdev.c
+++ b/fsdev/qemu-fsdev.c
@@ -27,6 +27,7 @@ static FsDriverTable FsDrivers[] = {
#endif
{ .name = "synth", .ops = &synth_ops},
{ .name = "proxy", .ops = &proxy_ops},
+ { .name = "cephfs", .ops = &cephfs_ops},
};
int qemu_fsdev_add(QemuOpts *opts)
diff --git a/fsdev/qemu-fsdev.h b/fsdev/qemu-fsdev.h
index 9fa45bf..86a17b8 100644
--- a/fsdev/qemu-fsdev.h
+++ b/fsdev/qemu-fsdev.h
@@ -22,7 +22,7 @@
* fstype | ops
* -----------------
* local | local_ops
- * . |
+ * cephfs| cephfs_ops
* . |
* . |
* . |
@@ -45,4 +45,5 @@ extern FileOperations local_ops;
extern FileOperations handle_ops;
extern FileOperations synth_ops;
extern FileOperations proxy_ops;
+extern FileOperations cephfs_ops;
#endif
diff --git a/hw/9pfs/9p-cephfs.c b/hw/9pfs/9p-cephfs.c
new file mode 100644
index 0000000..e2d659d
--- /dev/null
+++ b/hw/9pfs/9p-cephfs.c
@@ -0,0 +1,836 @@
+/*
+ * 9p cephfs callback
+ *
+ * Copyright UnitedStack, Corp. 2016
+ *
+ * Authors:
+ * Jevon Qiao <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version
2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/iov.h"
+#include "9p.h"
+#include "9p-xattr.h"
+#include "trace.h"
+#include <cephfs/libcephfs.h>
+#include "fsdev/qemu-fsdev.h" /* cephfs_ops */
+#include <arpa/inet.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include "qemu/xattr.h"
+#include "qemu/error-report.h"
+#include <libgen.h>
+#include <unistd.h>
+#include <linux/fs.h>
+#ifdef CONFIG_LINUX_MAGIC_H
+#include <linux/magic.h>
+#endif
+#include <sys/ioctl.h>
+
+#define CEPH_VER_LEN 32
+#define MON_NAME_LEN 32
+#define MON_SECRET_LEN 64
+
+#ifndef LIBCEPHFS_VERSION
+#define LIBCEPHFS_VERSION(maj, min, extra) ((maj << 16) + (min <<
8) + extra)
+#define LIBCEPHFS_VERSION_CODE LIBCEPHFS_VERSION(0, 0, 0)
+#endif
+
+#if defined(LIBCEPHFS_VERSION) && LIBCEPHFS_VERSION_CODE >= \
+LIBCEPHFS_VERSION(10, 0, 2)
+#define HAVE_CEPH_READV 1
+#endif
+
+struct cephfs_data {
+ int major, minor, patch;
+ char ceph_version[CEPH_VER_LEN];
+ struct ceph_mount_info *cmount;
+};
+
+static int cephfs_update_file_cred(struct ceph_mount_info *cmount,
+ const char *name, FsCred *credp)
+{
+ int fd, ret;
+ fd = ceph_open(cmount, name, O_NONBLOCK | O_NOFOLLOW,
credp->fc_mode);
+ if (fd < 0) {
+ return fd;
+ }
+ ret = ceph_fchown(cmount, fd, credp->fc_uid, credp->fc_gid);
+ if (ret < 0) {
+ goto err_out;
+ }
+ ret = ceph_fchmod(cmount, fd, credp->fc_mode & 07777);
+err_out:
+ close(fd);
+ return ret;
+}
+
+static int cephfs_lstat(FsContext *fs_ctx, V9fsPath *fs_path,
+ struct stat *stbuf)
+{
+ int ret;
+ char *path = fs_path->data;
+ struct cephfs_data *cfsdata = fs_ctx->private;
+
+ ret = ceph_lstat(cfsdata->cmount, path, stbuf);
+ trace_cephfs_lstat_return(path, stbuf->st_mode, stbuf->st_uid,
+ stbuf->st_gid, stbuf->st_size, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return 0;
+}
+
+static ssize_t cephfs_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
+ char *buf, size_t bufsz)
+{
+ int ret;
+ char *path = fs_path->data;
+ struct cephfs_data *cfsdata = fs_ctx->private;
+
+ ret = ceph_readlink(cfsdata->cmount, path, buf, bufsz);
+ trace_cephfs_readlink_return(path, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_close(FsContext *ctx, V9fsFidOpenState *fs)
+{
+ int ret;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ ret = ceph_close(cfsdata->cmount, fs->fd);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return 0;
+}
+
+static int cephfs_closedir(FsContext *ctx, V9fsFidOpenState *fs)
+{
+ int ret;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ ret = ceph_closedir(cfsdata->cmount, (struct ceph_dir_result
*)fs->dir);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return 0;
+}
+
+static int cephfs_open(FsContext *ctx, V9fsPath *fs_path,
+ int flags, V9fsFidOpenState *fs)
+{
+ int ret;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ ret = ceph_open(cfsdata->cmount, fs_path->data, flags, 0777);
+ trace_cephfs_open_return(fs_path->data, flags, 0777, fs->fd);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ fs->fd = ret;
+ return ret;
+}
+
+static int cephfs_opendir(FsContext *ctx,
+ V9fsPath *fs_path, V9fsFidOpenState *fs)
+{
+ int ret;
+ struct ceph_dir_result *result;
+ struct cephfs_data *cfsdata = ctx->private;
+ char *path = fs_path->data;
+
+ ret = ceph_opendir(cfsdata->cmount, path, &result);
+ trace_cephfs_opendir_return(path, ret);
+ if (ret < 0) {
+ errno = -ret;
+ error_report("failed to open %s, %s", path,
strerror(errno));
+ return -1;
+ }
+ fs->dir = (DIR *)result;
+ return 0;
+}
+
+static void cephfs_rewinddir(FsContext *ctx, V9fsFidOpenState *fs)
+{
+ struct cephfs_data *cfsdata = ctx->private;
+
+ trace_cephfs_rewinddir(fs->dir);
+ ceph_rewinddir(cfsdata->cmount, (struct ceph_dir_result
*)fs->dir);
+}
+
+static off_t cephfs_telldir(FsContext *ctx, V9fsFidOpenState *fs)
+{
+ off_t ret;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ trace_cephfs_telldir(fs->dir);
+ ret = ceph_telldir(cfsdata->cmount, (struct ceph_dir_result
*)fs->dir);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
+ struct dirent *entry,
+ struct dirent **result)
+{
+ int ret;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ ret = ceph_readdir_r(cfsdata->cmount, (struct ceph_dir_result
*)fs->dir,
+ entry);
+ if (ret > 0) {
+ *result = entry;
+ return 0;
+ } else if (ret == 0) {
+ *result = NULL;
+ return 0;
+ }
+ errno = -ret;
+ return -ret;
+}
+
+static void cephfs_seekdir(FsContext *ctx, V9fsFidOpenState *fs,
off_t off)
+{
+ struct cephfs_data *cfsdata = ctx->private;
+
+ trace_cephfs_seekdir(fs->dir, off);
+ ceph_seekdir(cfsdata->cmount, (struct ceph_dir_result
*)fs->dir, off);
+}
+
+#ifndef HAVE_CEPH_READV
+static ssize_t ceph_preadv(struct ceph_mount_info *cmount, int fd,
+ const struct iovec *iov, int iov_cnt,
+ off_t offset)
+{
+ ssize_t ret;
+ size_t i;
+ size_t len, tmp;
+ void *buf;
+ size_t bufoffset = 0;
+
+ len = iov_size(iov, iov_cnt);
+ buf = g_new0(uint8_t, len);
+ ret = ceph_read(cmount, fd, buf, len, offset);
+ if (ret < 0) {
+ return ret;
+ } else {
+ tmp = ret;
+ for (i = 0; (i < iov_cnt && tmp > 0); i++) {
+ if (tmp < iov[i].iov_len) {
+ memcpy(iov[i].iov_base, (buf + bufoffset), tmp);
+ } else {
+ memcpy(iov[i].iov_base, (buf + bufoffset),
iov[i].iov_len);
+ bufoffset += iov[i].iov_len;
+ }
+ tmp -= iov[i].iov_len;
+ }
+ }
+
+ free(buf);
+ return ret;
+}
+
+static ssize_t ceph_pwritev(struct ceph_mount_info *cmount, int fd,
+ const struct iovec *iov, int iov_cnt,
+ off_t offset)
+{
+ ssize_t ret;
+ size_t i;
+ size_t len;
+ void *buf;
+ size_t bufoffset = 0;
+
+ len = iov_size(iov, iov_cnt);
+ buf = g_new0(uint8_t, len);
+ for (i = 0; i < iov_cnt; i++) {
+ memcpy((buf + bufoffset), iov[i].iov_base, iov[i].iov_len);
+ bufoffset += iov[i].iov_len;
+ }
+ ret = ceph_write(cmount, fd, buf, len, offset);
+
+ free(buf);
+ return ret;
+}
+#endif
+
+static ssize_t cephfs_preadv(FsContext *ctx, V9fsFidOpenState *fs,
+ const struct iovec *iov,
+ int iovcnt, off_t offset)
+{
+ ssize_t ret = 0;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ trace_cephfs_preadv(iovcnt, iov_size(iov, iovcnt));
+ if (iovcnt < 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ ret = ceph_preadv(cfsdata->cmount, fs->fd, iov, iovcnt, offset);
+ trace_cephfs_preadv_return(iovcnt, iov_size(iov, iovcnt), ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static ssize_t cephfs_pwritev(FsContext *ctx, V9fsFidOpenState *fs,
+ const struct iovec *iov,
+ int iovcnt, off_t offset)
+{
+ ssize_t ret = 0;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ trace_cephfs_pwritev(iovcnt, iov_size(iov, iovcnt), offset);
+ if (iovcnt < 0) {
+ errno = EINVAL;
+ return -1;
+ }
+ ret = ceph_pwritev(cfsdata->cmount, fs->fd, iov, iovcnt,
offset);
+ trace_cephfs_pwritev_return(iovcnt, iov_size(iov, iovcnt),
offset, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+
+#ifdef CONFIG_SYNC_FILE_RANGE
+ if (ret > 0 && ctx->export_flags & V9FS_IMMEDIATE_WRITEOUT) {
+ /*
+ * Initiate a writeback. This is not a data integrity sync.
+ * We want to ensure that we don't leave dirty pages in
the cache
+ * after write when writeout=immediate is sepcified.
+ */
+ sync_file_range(fs->fd, offset, ret,
+ SYNC_FILE_RANGE_WAIT_BEFORE |
SYNC_FILE_RANGE_WRITE);
+ }
+#endif
+ return ret;
+}
+
+static int cephfs_chmod(FsContext *fs_ctx, V9fsPath *fs_path,
FsCred *credp)
+{
+ int ret;
+ struct cephfs_data *cfsdata = fs_ctx->private;
+
+ ret = ceph_chmod(cfsdata->cmount, fs_path->data,
credp->fc_mode);
+ trace_cephfs_chmod_return(fs_path->data, credp->fc_mode, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
+ const char *name, FsCred *credp)
+{
+ int ret;
+ V9fsString fullname;
+ struct cephfs_data *cfsdata = fs_ctx->private;
+
+ v9fs_string_init(&fullname);
+ v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
+ ret = ceph_mknod(cfsdata->cmount, fullname.data, credp->fc_mode,
+ credp->fc_rdev);
+ trace_cephfs_mknod_return(fullname.data, credp->fc_mode,
+ credp->fc_rdev, ret);
+ v9fs_string_free(&fullname);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
+ const char *name, FsCred *credp)
+{
+ int ret;
+ V9fsString fullname;
+ struct cephfs_data *cfsdata = fs_ctx->private;
+
+ v9fs_string_init(&fullname);
+ v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
+ ret = ceph_mkdir(cfsdata->cmount, fullname.data,
credp->fc_mode);
+ trace_cephfs_mkdir_return(fullname.data, credp->fc_mode, ret);
+ v9fs_string_free(&fullname);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_fstat(FsContext *fs_ctx, int fid_type,
+ V9fsFidOpenState *fs, struct stat *stbuf)
+{
+ int fd;
+ int ret;
+ struct cephfs_data *cfsdata = fs_ctx->private;
+
+ if (fid_type == P9_FID_DIR) {
+ fd = dirfd(fs->dir);
+ } else {
+ fd = fs->fd;
+ }
+ ret = ceph_fstat(cfsdata->cmount, fd, stbuf);
+ trace_cephfs_fstat_return(fid_type, fd, stbuf->st_uid,
stbuf->st_gid,
+ stbuf->st_size, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_open2(FsContext *fs_ctx, V9fsPath *dir_path,
const char *name,
+ int flags, FsCred *credp,
V9fsFidOpenState *fs)
+{
+ int fd, ret;
+ V9fsString fullname;
+ struct cephfs_data *cfsdata = fs_ctx->private;
+
+ v9fs_string_init(&fullname);
+ v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
+ fd = ceph_open(cfsdata->cmount, fullname.data, flags,
credp->fc_mode);
+ trace_cephfs_open2_return(fullname.data, flags, credp->fc_mode);
+ v9fs_string_free(&fullname);
+ if (fd >= 0) {
+ /* After creating the file, need to set the cred */
+ ret = cephfs_update_file_cred(cfsdata->cmount, name, credp);
+ if (ret < 0) {
+ ceph_close(cfsdata->cmount, fd);
+ errno = -ret;
+ fd = -1;
+ } else {
+ fs->fd = fd;
+ }
+ } else {
+ errno = -fd;
+ return -1;
+ }
+
+ return fd;
+}
+
+static int cephfs_symlink(FsContext *fs_ctx, const char *oldpath,
+ V9fsPath *dir_path, const char *name,
FsCred *credp)
+{
+ int ret;
+ V9fsString fullname;
+ struct cephfs_data *cfsdata = fs_ctx->private;
+
+ v9fs_string_init(&fullname);
+ v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
+ ret = ceph_symlink(cfsdata->cmount, oldpath, fullname.data);
+ trace_cephfs_symlink_return(oldpath, fullname.data, ret);
+ v9fs_string_free(&fullname);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_link(FsContext *ctx, V9fsPath *oldpath,
+ V9fsPath *dirpath, const char *name)
+{
+ int ret;
+ V9fsString newpath;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ v9fs_string_init(&newpath);
+ v9fs_string_sprintf(&newpath, "%s/%s", dirpath->data, name);
+ ret = ceph_link(cfsdata->cmount, oldpath->data, newpath.data);
+ trace_cephfs_link_return(oldpath->data, newpath.data, ret);
+ v9fs_string_free(&newpath);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_truncate(FsContext *ctx, V9fsPath *fs_path,
off_t size)
+{
+ int ret;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ ret = ceph_truncate(cfsdata->cmount, fs_path->data, size);
+ trace_cephfs_truncate_return(fs_path->data, size, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_rename(FsContext *ctx, const char *oldpath,
+ const char *newpath)
+{
+ int ret;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ ret = ceph_rename(cfsdata->cmount, oldpath, newpath);
+ trace_cephfs_rename_return(oldpath, newpath, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_chown(FsContext *fs_ctx, V9fsPath *fs_path,
FsCred *credp)
+{
+ int ret;
+ struct cephfs_data *cfsdata = fs_ctx->private;
+
+ ret = ceph_chown(cfsdata->cmount, fs_path->data, credp->fc_uid,
+ credp->fc_gid);
+ trace_cephfs_chown_return(fs_path->data, credp->fc_uid,
credp->fc_gid, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_utimensat(FsContext *ctx, V9fsPath *fs_path,
+ const struct timespec *buf)
+{
+ int ret;
+
+#ifdef CONFIG_UTIMENSAT
+ struct cephfs_data *cfsdata = ctx->private;
+
+ ret = ceph_utime(cfsdata->cmount, fs_path->data, (struct
utimbuf *)buf);
+ trace_cephfs_utimensat_return(fs_path->data, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+#else
+ ret = -1;
+ errno = ENOSYS;
+#endif
+
+ return ret;
+}
+
+static int cephfs_remove(FsContext *ctx, const char *path)
+{
+ errno = EOPNOTSUPP;
+ return -1;
+}
+
+static int cephfs_fsync(FsContext *ctx, int fid_type,
+ V9fsFidOpenState *fs, int datasync)
+{
+ int ret, fd;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ if (fid_type == P9_FID_DIR) {
+ fd = dirfd(fs->dir);
+ } else {
+ fd = fs->fd;
+ }
+ ret = ceph_fsync(cfsdata->cmount, fd, datasync);
+ trace_cephfs_fsync_return(fd, datasync, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_statfs(FsContext *ctx, V9fsPath *fs_path,
+ struct statfs *stbuf)
+{
+ int ret;
+ char *path = fs_path->data;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ ret = ceph_statfs(cfsdata->cmount, path, (struct statvfs
*)stbuf);
+ if (ret < 0) {
+ error_report("cephfs_statfs failed for %s, %s", path,
strerror(errno));
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+/*
+ * Get the extended attribute of normal file, if the path refer
to a symbolic
+ * link, just return the extended attributes of the syslink
rather than the
+ * attributes of the link itself.
+ */
+static ssize_t cephfs_lgetxattr(FsContext *ctx, V9fsPath *fs_path,
+ const char *name, void *value,
size_t size)
+{
+ int ret;
+ char *path = fs_path->data;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ ret = ceph_lgetxattr(cfsdata->cmount, path, name, value, size);
+ trace_cephfs_lgetxattr_return(path, name, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static ssize_t cephfs_llistxattr(FsContext *ctx, V9fsPath *fs_path,
+ void *value, size_t size)
+{
+ int ret;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ ret = ceph_llistxattr(cfsdata->cmount, fs_path->data, value,
size);
+ trace_cephfs_llistxattr_return(fs_path->data, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_lsetxattr(FsContext *ctx, V9fsPath *fs_path,
const char *name,
+ void *value, size_t size, int flags)
+{
+ int ret;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ ret = ceph_lsetxattr(cfsdata->cmount, fs_path->data, name,
value, size,
+ flags);
+ trace_cephfs_lsetxattr_return(fs_path->data, name, flags, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_lremovexattr(FsContext *ctx, V9fsPath *fs_path,
+ const char *name)
+{
+ int ret;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ ret = ceph_lremovexattr(cfsdata->cmount, fs_path->data, name);
+ trace_cephfs_lremovexattr_return(fs_path->data, name, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_name_to_path(FsContext *ctx, V9fsPath *dir_path,
+ const char *name, V9fsPath *target)
+{
+ if (dir_path) {
+ v9fs_string_sprintf((V9fsString *)target, "%s/%s",
+ dir_path->data, name);
+ } else {
+ /* if the path does not start from '/' */
+ v9fs_string_sprintf((V9fsString *)target, "%s", name);
+ }
+
+ /* Bump the size for including terminating NULL */
+ target->size++;
+ return 0;
+}
+
+static int cephfs_renameat(FsContext *ctx, V9fsPath *olddir,
+ const char *old_name, V9fsPath *newdir,
+ const char *new_name)
+{
+ int ret = -1;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ ret = ceph_rename(cfsdata->cmount, old_name, new_name);
+ trace_cephfs_renameat_return(old_name, new_name, ret);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+static int cephfs_unlinkat(FsContext *ctx, V9fsPath *dir,
+ const char *name, int flags)
+{
+ int ret = 0;
+ char *path = dir->data;
+ struct stat fstat;
+ V9fsString fullname;
+ struct cephfs_data *cfsdata = ctx->private;
+
+ v9fs_string_init(&fullname);
+ v9fs_string_sprintf(&fullname, "%s/%s", dir->data, name);
+ path = fullname.data;
+ /* determine which kind of file is being destroyed */
+ ret = ceph_lstat(cfsdata->cmount, path, &fstat);
+ if (!ret) {
+ switch (fstat.st_mode & S_IFMT) {
+ case S_IFDIR:
+ ret = ceph_rmdir(cfsdata->cmount, path);
+ break;
+
+ case S_IFBLK:
+ case S_IFCHR:
+ case S_IFIFO:
+ case S_IFLNK:
+ case S_IFREG:
+ case S_IFSOCK:
+ ret = ceph_unlink(cfsdata->cmount, path);
+ break;
+
+ default:
+ error_report("ceph_lstat unknown stmode %s, %s", path,
+ strerror(errno));
+ break;
+ }
+ if (ret < 0) {
+ errno = -ret;
+ ret = -1;
+ }
+ } else {
+ errno = -ret;
+ ret = -1;
+ }
+ trace_cephfs_unlinkat_return(path, fstat.st_mode, ret);
+
+ v9fs_string_free(&fullname);
+ return ret;
+}
+
+/*
+ * Do two things in the init function:
+ * 1) Create a mount handle used by all cephfs interfaces.
+ * 2) Invoke ceph_mount() to initialize a link between the client
and
+ * ceph monitor
+ */
+static int cephfs_init(FsContext *ctx)
+{
+ int ret;
+ const char *ver = NULL;
+ struct cephfs_data *data = g_malloc(sizeof(struct cephfs_data));
+
+ if (data == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ trace_cephfs_init(ctx->fs_root);
+ memset(data, 0, sizeof(struct cephfs_data));
+ ret = ceph_create(&data->cmount, NULL);
+ if (ret < 0) {
+ errno = -ret;
+ error_report("ceph_create failed %s", strerror(errno));
+ goto err_out;
+ }
+
+ ret = ceph_conf_read_file(data->cmount, NULL);
+ if (ret) {
+ errno = -ret;
+ error_report("ceph_conf_read_file failed %s",
strerror(errno));
+ goto err_out;
+ }
+
+ ret = ceph_mount(data->cmount, ctx->fs_root);
+ if (ret) {
+ errno = -ret;
+ error_report("ceph_mount failed %s", strerror(errno));
+ goto err_out;
+ } else {
+ ctx->private = data;
+ /* CephFS does not support FS_IOC_GETVERSION */
+ ctx->exops.get_st_gen = NULL;
+ goto out;
+ }
+
+ ver = ceph_version(&data->major, &data->minor, &data->patch);
+ memcpy(data->ceph_version, ver, strlen(ver) + 1);
+
+err_out:
+ g_free(data);
+out:
+ return ret;
+}
+
+static int cephfs_parse_opts(QemuOpts *opts, struct FsDriverEntry
*fse)
+{
+ const char *sec_model = qemu_opt_get(opts, "security_model");
+ const char *path = qemu_opt_get(opts, "path");
+
+ if (!sec_model) {
+ error_report("Invalid argument security_model specified "
+ "with cephfs fsdriver");
+ return -1;
+ }
+
+ if (!path) {
+ error_report("fsdev: No path specified.");
+ return -1;
+ }
+
+ fse->path = g_strdup(path);
+ return 0;
+}
+
+FileOperations cephfs_ops = {
+ .parse_opts = cephfs_parse_opts,
+ .init = cephfs_init,
+ .lstat = cephfs_lstat,
+ .readlink = cephfs_readlink,
+ .close = cephfs_close,
+ .closedir = cephfs_closedir,
+ .open = cephfs_open,
+ .opendir = cephfs_opendir,
+ .rewinddir = cephfs_rewinddir,
+ .telldir = cephfs_telldir,
+ .readdir_r = cephfs_readdir_r,
+ .seekdir = cephfs_seekdir,
+ .preadv = cephfs_preadv,
+ .pwritev = cephfs_pwritev,
+ .chmod = cephfs_chmod,
+ .mknod = cephfs_mknod,
+ .mkdir = cephfs_mkdir,
+ .fstat = cephfs_fstat,
+ .open2 = cephfs_open2,
+ .symlink = cephfs_symlink,
+ .link = cephfs_link,
+ .truncate = cephfs_truncate,
+ .rename = cephfs_rename,
+ .chown = cephfs_chown,
+ .utimensat = cephfs_utimensat,
+ .remove = cephfs_remove,
+ .fsync = cephfs_fsync,
+ .statfs = cephfs_statfs,
+ .lgetxattr = cephfs_lgetxattr,
+ .llistxattr = cephfs_llistxattr,
+ .lsetxattr = cephfs_lsetxattr,
+ .lremovexattr = cephfs_lremovexattr,
+ .name_to_path = cephfs_name_to_path,
+ .renameat = cephfs_renameat,
+ .unlinkat = cephfs_unlinkat,
+};
diff --git a/hw/9pfs/Makefile.objs b/hw/9pfs/Makefile.objs
index da0ae0c..a77a6f4 100644
--- a/hw/9pfs/Makefile.objs
+++ b/hw/9pfs/Makefile.objs
@@ -5,5 +5,8 @@ common-obj-y += coth.o cofs.o codir.o cofile.o
common-obj-y += coxattr.o 9p-synth.o
common-obj-$(CONFIG_OPEN_BY_HANDLE) += 9p-handle.o
common-obj-y += 9p-proxy.o
+common-obj-y += 9p-cephfs.o
obj-y += virtio-9p-device.o
+
+9p-cephfs.o-libs := $(CEPHFS_LIBS)
diff --git a/scripts/analyse-9p-simpletrace.py
b/scripts/analyse-9p-simpletrace.py
deleted file mode 100755
index 3c3dee4..0000000
--- a/scripts/analyse-9p-simpletrace.py
+++ /dev/null
@@ -1,213 +0,0 @@
-#!/usr/bin/env python
-# Pretty print 9p simpletrace log
-# Usage: ./analyse-9p-simpletrace <trace-events> <trace-pid>
-#
-# Author: Harsh Prateek Bora
-import os
-import simpletrace
-
-symbol_9p = {
- 6 : 'TLERROR',
- 7 : 'RLERROR',
- 8 : 'TSTATFS',
- 9 : 'RSTATFS',
- 12 : 'TLOPEN',
- 13 : 'RLOPEN',
- 14 : 'TLCREATE',
- 15 : 'RLCREATE',
- 16 : 'TSYMLINK',
- 17 : 'RSYMLINK',
- 18 : 'TMKNOD',
- 19 : 'RMKNOD',
- 20 : 'TRENAME',
- 21 : 'RRENAME',
- 22 : 'TREADLINK',
- 23 : 'RREADLINK',
- 24 : 'TGETATTR',
- 25 : 'RGETATTR',
- 26 : 'TSETATTR',
- 27 : 'RSETATTR',
- 30 : 'TXATTRWALK',
- 31 : 'RXATTRWALK',
- 32 : 'TXATTRCREATE',
- 33 : 'RXATTRCREATE',
- 40 : 'TREADDIR',
- 41 : 'RREADDIR',
- 50 : 'TFSYNC',
- 51 : 'RFSYNC',
- 52 : 'TLOCK',
- 53 : 'RLOCK',
- 54 : 'TGETLOCK',
- 55 : 'RGETLOCK',
- 70 : 'TLINK',
- 71 : 'RLINK',
- 72 : 'TMKDIR',
- 73 : 'RMKDIR',
- 74 : 'TRENAMEAT',
- 75 : 'RRENAMEAT',
- 76 : 'TUNLINKAT',
- 77 : 'RUNLINKAT',
- 100 : 'TVERSION',
- 101 : 'RVERSION',
- 102 : 'TAUTH',
- 103 : 'RAUTH',
- 104 : 'TATTACH',
- 105 : 'RATTACH',
- 106 : 'TERROR',
- 107 : 'RERROR',
- 108 : 'TFLUSH',
- 109 : 'RFLUSH',
- 110 : 'TWALK',
- 111 : 'RWALK',
- 112 : 'TOPEN',
- 113 : 'ROPEN',
- 114 : 'TCREATE',
- 115 : 'RCREATE',
- 116 : 'TREAD',
- 117 : 'RREAD',
- 118 : 'TWRITE',
- 119 : 'RWRITE',
- 120 : 'TCLUNK',
- 121 : 'RCLUNK',
- 122 : 'TREMOVE',
- 123 : 'RREMOVE',
- 124 : 'TSTAT',
- 125 : 'RSTAT',
- 126 : 'TWSTAT',
- 127 : 'RWSTAT'
-}
-
-class VirtFSRequestTracker(simpletrace.Analyzer):
- def begin(self):
- print "Pretty printing 9p simpletrace log ..."
-
- def v9fs_rerror(self, tag, id, err):
- print "RERROR (tag =", tag, ", id =",
symbol_9p[id], ", err = \"", os.strerror(err), "\")"
-
- def v9fs_version(self, tag, id, msize, version):
- print "TVERSION (tag =", tag, ", msize =", msize,
", version =", version, ")"
-
- def v9fs_version_return(self, tag, id, msize, version):
- print "RVERSION (tag =", tag, ", msize =", msize,
", version =", version, ")"
-
- def v9fs_attach(self, tag, id, fid, afid, uname, aname):
- print "TATTACH (tag =", tag, ", fid =", fid, ",
afid =", afid, ", uname =", uname, ", aname =", aname, ")"
-
- def v9fs_attach_return(self, tag, id, type, version, path):
- print "RATTACH (tag =", tag, ", qid={type =",
type, ", version =", version, ", path =", path, "})"
-
- def v9fs_stat(self, tag, id, fid):
- print "TSTAT (tag =", tag, ", fid =", fid, ")"
-
- def v9fs_stat_return(self, tag, id, mode, atime, mtime,
length):
- print "RSTAT (tag =", tag, ", mode =", mode, ",
atime =", atime, ", mtime =", mtime, ", length =", length, ")"
-
- def v9fs_getattr(self, tag, id, fid, request_mask):
- print "TGETATTR (tag =", tag, ", fid =", fid, ",
request_mask =", hex(request_mask), ")"
-
- def v9fs_getattr_return(self, tag, id, result_mask, mode,
uid, gid):
- print "RGETATTR (tag =", tag, ", result_mask =",
hex(result_mask), ", mode =", oct(mode), ", uid =", uid, ", gid
=", gid, ")"
-
- def v9fs_walk(self, tag, id, fid, newfid, nwnames):
- print "TWALK (tag =", tag, ", fid =", fid, ",
newfid =", newfid, ", nwnames =", nwnames, ")"
-
- def v9fs_walk_return(self, tag, id, nwnames, qids):
- print "RWALK (tag =", tag, ", nwnames =",
nwnames, ", qids =", hex(qids), ")"
-
- def v9fs_open(self, tag, id, fid, mode):
- print "TOPEN (tag =", tag, ", fid =", fid, ",
mode =", oct(mode), ")"
-
- def v9fs_open_return(self, tag, id, type, version, path,
iounit):
- print "ROPEN (tag =", tag, ", qid={type =",
type, ", version =", version, ", path =", path, "}, iounit =",
iounit, ")"
-
- def v9fs_lcreate(self, tag, id, dfid, flags, mode, gid):
- print "TLCREATE (tag =", tag, ", dfid =", dfid,
", flags =", oct(flags), ", mode =", oct(mode), ", gid =", gid, ")"
-
- def v9fs_lcreate_return(self, tag, id, type, version,
path, iounit):
- print "RLCREATE (tag =", tag, ", qid={type =",
type, ", version =", version, ", path =", path, "}, iounit =",
iounit, ")"
-
- def v9fs_fsync(self, tag, id, fid, datasync):
- print "TFSYNC (tag =", tag, ", fid =", fid, ",
datasync =", datasync, ")"
-
- def v9fs_clunk(self, tag, id, fid):
- print "TCLUNK (tag =", tag, ", fid =", fid, ")"
-
- def v9fs_read(self, tag, id, fid, off, max_count):
- print "TREAD (tag =", tag, ", fid =", fid, ", off
=", off, ", max_count =", max_count, ")"
-
- def v9fs_read_return(self, tag, id, count, err):
- print "RREAD (tag =", tag, ", count =", count, ",
err =", err, ")"
-
- def v9fs_readdir(self, tag, id, fid, offset, max_count):
- print "TREADDIR (tag =", tag, ", fid =", fid, ",
offset =", offset, ", max_count =", max_count, ")"
-
- def v9fs_readdir_return(self, tag, id, count, retval):
- print "RREADDIR (tag =", tag, ", count =", count,
", retval =", retval, ")"
-
- def v9fs_write(self, tag, id, fid, off, count, cnt):
- print "TWRITE (tag =", tag, ", fid =", fid, ",
off =", off, ", count =", count, ", cnt =", cnt, ")"
-
- def v9fs_write_return(self, tag, id, total, err):
- print "RWRITE (tag =", tag, ", total =", total,
", err =", err, ")"
-
- def v9fs_create(self, tag, id, fid, name, perm, mode):
- print "TCREATE (tag =", tag, ", fid =", fid, ",
perm =", oct(perm), ", name =", name, ", mode =", oct(mode), ")"
-
- def v9fs_create_return(self, tag, id, type, version,
path, iounit):
- print "RCREATE (tag =", tag, ", qid={type =",
type, ", version =", version, ", path =", path, "}, iounit =",
iounit, ")"
-
- def v9fs_symlink(self, tag, id, fid, name, symname, gid):
- print "TSYMLINK (tag =", tag, ", fid =", fid, ",
name =", name, ", symname =", symname, ", gid =", gid, ")"
-
- def v9fs_symlink_return(self, tag, id, type, version, path):
- print "RSYMLINK (tag =", tag, ", qid={type =",
type, ", version =", version, ", path =", path, "})"
-
- def v9fs_flush(self, tag, id, flush_tag):
- print "TFLUSH (tag =", tag, ", flush_tag =",
flush_tag, ")"
-
- def v9fs_link(self, tag, id, dfid, oldfid, name):
- print "TLINK (tag =", tag, ", dfid =", dfid, ",
oldfid =", oldfid, ", name =", name, ")"
-
- def v9fs_remove(self, tag, id, fid):
- print "TREMOVE (tag =", tag, ", fid =", fid, ")"
-
- def v9fs_wstat(self, tag, id, fid, mode, atime, mtime):
- print "TWSTAT (tag =", tag, ", fid =", fid, ",
mode =", oct(mode), ", atime =", atime, "mtime =", mtime, ")"
-
- def v9fs_mknod(self, tag, id, fid, mode, major, minor):
- print "TMKNOD (tag =", tag, ", fid =", fid, ",
mode =", oct(mode), ", major =", major, ", minor =", minor, ")"
-
- def v9fs_lock(self, tag, id, fid, type, start, length):
- print "TLOCK (tag =", tag, ", fid =", fid, "type
=", type, ", start =", start, ", length =", length, ")"
-
- def v9fs_lock_return(self, tag, id, status):
- print "RLOCK (tag =", tag, ", status =", status, ")"
-
- def v9fs_getlock(self, tag, id, fid, type, start, length):
- print "TGETLOCK (tag =", tag, ", fid =", fid,
"type =", type, ", start =", start, ", length =", length, ")"
-
- def v9fs_getlock_return(self, tag, id, type, start,
length, proc_id):
- print "RGETLOCK (tag =", tag, "type =", type, ",
start =", start, ", length =", length, ", proc_id =", proc_id, ")"
-
- def v9fs_mkdir(self, tag, id, fid, name, mode, gid):
- print "TMKDIR (tag =", tag, ", fid =", fid, ",
name =", name, ", mode =", mode, ", gid =", gid, ")"
-
- def v9fs_mkdir_return(self, tag, id, type, version, path,
err):
- print "RMKDIR (tag =", tag, ", qid={type =",
type, ", version =", version, ", path =", path, "}, err =", err, ")"
-
- def v9fs_xattrwalk(self, tag, id, fid, newfid, name):
- print "TXATTRWALK (tag =", tag, ", fid =", fid,
", newfid =", newfid, ", xattr name =", name, ")"
-
- def v9fs_xattrwalk_return(self, tag, id, size):
- print "RXATTRWALK (tag =", tag, ", xattrsize =",
size, ")"
-
- def v9fs_xattrcreate(self, tag, id, fid, name, size, flags):
- print "TXATTRCREATE (tag =", tag, ", fid =", fid,
", name =", name, ", xattrsize =", size, ", flags =", flags, ")"
-
- def v9fs_readlink(self, tag, id, fid):
- print "TREADLINK (tag =", tag, ", fid =", fid, ")"
-
- def v9fs_readlink_return(self, tag, id, target):
- print "RREADLINK (tag =", tag, ", target =",
target, ")"
-
-simpletrace.run(VirtFSRequestTracker())
diff --git a/scripts/analyze-9p-simpletrace.py
b/scripts/analyze-9p-simpletrace.py
new file mode 100755
index 0000000..e9c6737
--- /dev/null
+++ b/scripts/analyze-9p-simpletrace.py
@@ -0,0 +1,306 @@
+#!/usr/bin/env python
+# Pretty print 9p simpletrace log
+# Usage: ./analyse-9p-simpletrace <trace-events> <trace-pid>
+#
+# Author: Harsh Prateek Bora
+import os
+import simpletrace
+
+symbol_9p = {
+ 6 : 'TLERROR',
+ 7 : 'RLERROR',
+ 8 : 'TSTATFS',
+ 9 : 'RSTATFS',
+ 12 : 'TLOPEN',
+ 13 : 'RLOPEN',
+ 14 : 'TLCREATE',
+ 15 : 'RLCREATE',
+ 16 : 'TSYMLINK',
+ 17 : 'RSYMLINK',
+ 18 : 'TMKNOD',
+ 19 : 'RMKNOD',
+ 20 : 'TRENAME',
+ 21 : 'RRENAME',
+ 22 : 'TREADLINK',
+ 23 : 'RREADLINK',
+ 24 : 'TGETATTR',
+ 25 : 'RGETATTR',
+ 26 : 'TSETATTR',
+ 27 : 'RSETATTR',
+ 30 : 'TXATTRWALK',
+ 31 : 'RXATTRWALK',
+ 32 : 'TXATTRCREATE',
+ 33 : 'RXATTRCREATE',
+ 40 : 'TREADDIR',
+ 41 : 'RREADDIR',
+ 50 : 'TFSYNC',
+ 51 : 'RFSYNC',
+ 52 : 'TLOCK',
+ 53 : 'RLOCK',
+ 54 : 'TGETLOCK',
+ 55 : 'RGETLOCK',
+ 70 : 'TLINK',
+ 71 : 'RLINK',
+ 72 : 'TMKDIR',
+ 73 : 'RMKDIR',
+ 74 : 'TRENAMEAT',
+ 75 : 'RRENAMEAT',
+ 76 : 'TUNLINKAT',
+ 77 : 'RUNLINKAT',
+ 100 : 'TVERSION',
+ 101 : 'RVERSION',
+ 102 : 'TAUTH',
+ 103 : 'RAUTH',
+ 104 : 'TATTACH',
+ 105 : 'RATTACH',
+ 106 : 'TERROR',
+ 107 : 'RERROR',
+ 108 : 'TFLUSH',
+ 109 : 'RFLUSH',
+ 110 : 'TWALK',
+ 111 : 'RWALK',
+ 112 : 'TOPEN',
+ 113 : 'ROPEN',
+ 114 : 'TCREATE',
+ 115 : 'RCREATE',
+ 116 : 'TREAD',
+ 117 : 'RREAD',
+ 118 : 'TWRITE',
+ 119 : 'RWRITE',
+ 120 : 'TCLUNK',
+ 121 : 'RCLUNK',
+ 122 : 'TREMOVE',
+ 123 : 'RREMOVE',
+ 124 : 'TSTAT',
+ 125 : 'RSTAT',
+ 126 : 'TWSTAT',
+ 127 : 'RWSTAT'
+}
+
+class VirtFSRequestTracker(simpletrace.Analyzer):
+ def begin(self):
+ print "Pretty printing 9p simpletrace log ..."
+
+ def v9fs_rerror(self, tag, id, err):
+ print "RERROR (tag =", tag, ", id =",
symbol_9p[id], ", err = \"", os.strerror(err), "\")"
+
+ def v9fs_version(self, tag, id, msize, version):
+ print "TVERSION (tag =", tag, ", msize =", msize,
", version =", version, ")"
+
+ def v9fs_version_return(self, tag, id, msize, version):
+ print "RVERSION (tag =", tag, ", msize =", msize,
", version =", version, ")"
+
+ def v9fs_attach(self, tag, id, fid, afid, uname, aname):
+ print "TATTACH (tag =", tag, ", fid =", fid, ",
afid =", afid, ", uname =", uname, ", aname =", aname, ")"
+
+ def v9fs_attach_return(self, tag, id, type, version, path):
+ print "RATTACH (tag =", tag, ", qid={type =",
type, ", version =", version, ", path =", path, "})"
+
+ def v9fs_stat(self, tag, id, fid):
+ print "TSTAT (tag =", tag, ", fid =", fid, ")"
+
+ def v9fs_stat_return(self, tag, id, mode, atime, mtime,
length):
+ print "RSTAT (tag =", tag, ", mode =", mode, ",
atime =", atime, ", mtime =", mtime, ", length =", length, ")"
+
+ def v9fs_getattr(self, tag, id, fid, request_mask):
+ print "TGETATTR (tag =", tag, ", fid =", fid, ",
request_mask =", hex(request_mask), ")"
+
+ def v9fs_getattr_return(self, tag, id, result_mask, mode,
uid, gid):
+ print "RGETATTR (tag =", tag, ", result_mask =",
hex(result_mask), ", mode =", oct(mode), ", uid =", uid, ", gid
=", gid, ")"
+
+ def v9fs_walk(self, tag, id, fid, newfid, nwnames):
+ print "TWALK (tag =", tag, ", fid =", fid, ",
newfid =", newfid, ", nwnames =", nwnames, ")"
+
+ def v9fs_walk_return(self, tag, id, nwnames, qids):
+ print "RWALK (tag =", tag, ", nwnames =",
nwnames, ", qids =", hex(qids), ")"
+
+ def v9fs_open(self, tag, id, fid, mode):
+ print "TOPEN (tag =", tag, ", fid =", fid, ",
mode =", oct(mode), ")"
+
+ def v9fs_open_return(self, tag, id, type, version, path,
iounit):
+ print "ROPEN (tag =", tag, ", qid={type =",
type, ", version =", version, ", path =", path, "}, iounit =",
iounit, ")"
+
+ def v9fs_lcreate(self, tag, id, dfid, flags, mode, gid):
+ print "TLCREATE (tag =", tag, ", dfid =", dfid,
", flags =", oct(flags), ", mode =", oct(mode), ", gid =", gid, ")"
+
+ def v9fs_lcreate_return(self, tag, id, type, version,
path, iounit):
+ print "RLCREATE (tag =", tag, ", qid={type =",
type, ", version =", version, ", path =", path, "}, iounit =",
iounit, ")"
+
+ def v9fs_fsync(self, tag, id, fid, datasync):
+ print "TFSYNC (tag =", tag, ", fid =", fid, ",
datasync =", datasync, ")"
+
+ def v9fs_clunk(self, tag, id, fid):
+ print "TCLUNK (tag =", tag, ", fid =", fid, ")"
+
+ def v9fs_read(self, tag, id, fid, off, max_count):
+ print "TREAD (tag =", tag, ", fid =", fid, ", off
=", off, ", max_count =", max_count, ")"
+
+ def v9fs_read_return(self, tag, id, count, err):
+ print "RREAD (tag =", tag, ", count =", count, ",
err =", err, ")"
+
+ def v9fs_readdir(self, tag, id, fid, offset, max_count):
+ print "TREADDIR (tag =", tag, ", fid =", fid, ",
offset =", offset, ", max_count =", max_count, ")"
+
+ def v9fs_readdir_return(self, tag, id, count, retval):
+ print "RREADDIR (tag =", tag, ", count =", count,
", retval =", retval, ")"
+
+ def v9fs_write(self, tag, id, fid, off, count, cnt):
+ print "TWRITE (tag =", tag, ", fid =", fid, ",
off =", off, ", count =", count, ", cnt =", cnt, ")"
+
+ def v9fs_write_return(self, tag, id, total, err):
+ print "RWRITE (tag =", tag, ", total =", total,
", err =", err, ")"
+
+ def v9fs_create(self, tag, id, fid, name, perm, mode):
+ print "TCREATE (tag =", tag, ", fid =", fid, ",
perm =", oct(perm), ", name =", name, ", mode =", oct(mode), ")"
+
+ def v9fs_create_return(self, tag, id, type, version,
path, iounit):
+ print "RCREATE (tag =", tag, ", qid={type =",
type, ", version =", version, ", path =", path, "}, iounit =",
iounit, ")"
+
+ def v9fs_symlink(self, tag, id, fid, name, symname, gid):
+ print "TSYMLINK (tag =", tag, ", fid =", fid, ",
name =", name, ", symname =", symname, ", gid =", gid, ")"
+
+ def v9fs_symlink_return(self, tag, id, type, version, path):
+ print "RSYMLINK (tag =", tag, ", qid={type =",
type, ", version =", version, ", path =", path, "})"
+
+ def v9fs_flush(self, tag, id, flush_tag):
+ print "TFLUSH (tag =", tag, ", flush_tag =",
flush_tag, ")"
+
+ def v9fs_link(self, tag, id, dfid, oldfid, name):
+ print "TLINK (tag =", tag, ", dfid =", dfid, ",
oldfid =", oldfid, ", name =", name, ")"
+
+ def v9fs_remove(self, tag, id, fid):
+ print "TREMOVE (tag =", tag, ", fid =", fid, ")"
+
+ def v9fs_wstat(self, tag, id, fid, mode, atime, mtime):
+ print "TWSTAT (tag =", tag, ", fid =", fid, ",
mode =", oct(mode), ", atime =", atime, "mtime =", mtime, ")"
+
+ def v9fs_mknod(self, tag, id, fid, mode, major, minor):
+ print "TMKNOD (tag =", tag, ", fid =", fid, ",
mode =", oct(mode), ", major =", major, ", minor =", minor, ")"
+
+ def v9fs_lock(self, tag, id, fid, type, start, length):
+ print "TLOCK (tag =", tag, ", fid =", fid, "type
=", type, ", start =", start, ", length =", length, ")"
+
+ def v9fs_lock_return(self, tag, id, status):
+ print "RLOCK (tag =", tag, ", status =", status, ")"
+
+ def v9fs_getlock(self, tag, id, fid, type, start, length):
+ print "TGETLOCK (tag =", tag, ", fid =", fid,
"type =", type, ", start =", start, ", length =", length, ")"
+
+ def v9fs_getlock_return(self, tag, id, type, start,
length, proc_id):
+ print "RGETLOCK (tag =", tag, "type =", type, ",
start =", start, ", length =", length, ", proc_id =", proc_id, ")"
+
+ def v9fs_mkdir(self, tag, id, fid, name, mode, gid):
+ print "TMKDIR (tag =", tag, ", fid =", fid, ",
name =", name, ", mode =", mode, ", gid =", gid, ")"
+
+ def v9fs_mkdir_return(self, tag, id, type, version, path,
err):
+ print "RMKDIR (tag =", tag, ", qid={type =",
type, ", version =", version, ", path =", path, "}, err =", err, ")"
+
+ def v9fs_xattrwalk(self, tag, id, fid, newfid, name):
+ print "TXATTRWALK (tag =", tag, ", fid =", fid,
", newfid =", newfid, ", xattr name =", name, ")"
+
+ def v9fs_xattrwalk_return(self, tag, id, size):
+ print "RXATTRWALK (tag =", tag, ", xattrsize =",
size, ")"
+
+ def v9fs_xattrcreate(self, tag, id, fid, name, size, flags):
+ print "TXATTRCREATE (tag =", tag, ", fid =", fid,
", name =", name, ", xattrsize =", size, ", flags =", flags, ")"
+
+ def v9fs_readlink(self, tag, id, fid):
+ print "TREADLINK (tag =", tag, ", fid =", fid, ")"
+
+ def v9fs_readlink_return(self, tag, id, target):
+ print "RREADLINK (tag =", tag, ", target =",
target, ")"
+
+ def cephfs_lstat_return(self, path, stmode, stuid, stgid,
stsize, ret):
+ print "RCEPHFSLSTAT (path =", path, ", stmode =", stmode,
", stuid =", stuid, ", stgid =", stgid, ", stsize =", stsize, ",
ret =", ret, ")"
+
+ def cephfs_readlink_return(self, path, ret):
+ print "RCEPHFSREADLINK (path =", path, ", ret =", ret, ")"
+
+ def cephfs_open_return(self, path, flags, mode, fd):
+ print "RCEPHFSOPEN (path =", path, ", flags =", flags, ",
mode =", mode, ", fd =", fd, ")"
+
+ def cephfs_opendir_return(self, path, ret):
+ print "RCEPHFSOPENDIR (path =", path, ", ret =", ret,
")"Avoid duplicate copies of messages?