From 7af1bd9860eadf6443f4eeb71cd9f0deafefceae Mon Sep 17 00:00:00 2001 From: Kitae Kim Date: Tue, 29 Oct 2013 17:14:12 +0900 Subject: [PATCH] virtio-9p: enable virtfs on Mac OS X. Support virtio-9p local operation on Mac OS X to provide host directory sharing. Change-Id: Ic034673c6d3d4102ebe4fbaea7e186fffec34a2f Signed-off-by: Kitae Kim --- Makefile.objs | 5 +++- configure | 3 +++ fsdev/file-op-9p.h | 7 ++++++ hw/9pfs/Makefile.objs | 7 ++++-- hw/9pfs/virtio-9p-local.c | 57 ++++++++++++++++++++++++++++++++++++++++++ hw/9pfs/virtio-9p-posix-acl.c | 24 ++++++++++++++++++ hw/9pfs/virtio-9p-xattr-user.c | 12 +++++++++ hw/9pfs/virtio-9p-xattr.c | 8 ++++++ hw/9pfs/virtio-9p-xattr.h | 12 +++++++++ hw/9pfs/virtio-9p.c | 28 +++++++++++++++++++++ hw/9pfs/virtio-9p.h | 2 ++ include/qemu/xattr.h | 2 ++ 12 files changed, 164 insertions(+), 3 deletions(-) diff --git a/Makefile.objs b/Makefile.objs index 2b6c1fe..2f48c35 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -48,7 +48,10 @@ common-obj-y += qdev-monitor.o device-hotplug.o common-obj-$(CONFIG_WIN32) += os-win32.o common-obj-$(CONFIG_POSIX) += os-posix.o -common-obj-$(CONFIG_LINUX) += fsdev/ +#common-obj-$(CONFIG_LINUX) += fsdev/ +ifneq ($(CONFIG_WIN32),y) +common-obj-y += fsdev/ +endif common-obj-y += migration.o migration-tcp.o common-obj-$(CONFIG_RDMA) += migration-rdma.o diff --git a/configure b/configure index 0791234..5b9a298 100755 --- a/configure +++ b/configure @@ -3767,6 +3767,9 @@ if test "$softmmu" = yes ; then if test "$cap" = yes && test "$linux" = yes && test "$attr" = yes ; then virtfs=yes tools="$tools fsdev/virtfs-proxy-helper\$(EXESUF)" + elif test "$darwin" = yes ; then + echo "Enable VirtFS on Darwin" + virtfs=yes else if test "$virtfs" = yes; then error_exit "VirtFS is supported only on Linux and requires libcap-devel and libattr-devel" diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h index 956fda0..75ad11f 100644 --- a/fsdev/file-op-9p.h +++ b/fsdev/file-op-9p.h @@ -19,6 +19,13 @@ #include #include #include +#ifdef CONFIG_LINUX +#include +#endif +#ifdef CONFIG_DARWIN +#include +#include +#endif #define SM_LOCAL_MODE_BITS 0600 #define SM_LOCAL_DIR_MODE_BITS 0700 diff --git a/hw/9pfs/Makefile.objs b/hw/9pfs/Makefile.objs index 1e9b595..39fe14d 100644 --- a/hw/9pfs/Makefile.objs +++ b/hw/9pfs/Makefile.objs @@ -2,8 +2,11 @@ common-obj-y = virtio-9p.o common-obj-y += virtio-9p-local.o virtio-9p-xattr.o common-obj-y += virtio-9p-xattr-user.o virtio-9p-posix-acl.o common-obj-y += virtio-9p-coth.o cofs.o codir.o cofile.o -common-obj-y += coxattr.o virtio-9p-synth.o +#common-obj-y += coxattr.o virtio-9p-synth.o +common-obj-y += coxattr.o +common-obj-$(CONFIG_LINUX) += virtio-9p-synth.o common-obj-$(CONFIG_OPEN_BY_HANDLE) += virtio-9p-handle.o -common-obj-y += virtio-9p-proxy.o +#common-obj-y += virtio-9p-proxy.o +common-obj-$(CONFIG_LINUX) += virtio-9p-proxy.o obj-y += virtio-9p-device.o diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c index fc93e9e..24e2cda 100644 --- a/hw/9pfs/virtio-9p-local.c +++ b/hw/9pfs/virtio-9p-local.c @@ -21,7 +21,9 @@ #include #include "qemu/xattr.h" #include +#ifdef CONFIG_LINUX #include +#endif #ifdef CONFIG_LINUX_MAGIC_H #include #endif @@ -131,6 +133,7 @@ static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf) gid_t tmp_gid; mode_t tmp_mode; dev_t tmp_dev; +#ifdef CONFIG_LINUX if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.uid", &tmp_uid, sizeof(uid_t)) > 0) { stbuf->st_uid = tmp_uid; @@ -147,6 +150,24 @@ static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf) sizeof(dev_t)) > 0) { stbuf->st_rdev = tmp_dev; } +#else + if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.uid", &tmp_uid, + sizeof(uid_t), 0, 0) > 0) { + stbuf->st_uid = tmp_uid; + } + if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.gid", &tmp_gid, + sizeof(gid_t), 0, 0) > 0) { + stbuf->st_gid = tmp_gid; + } + if (getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.mode", + &tmp_mode, sizeof(mode_t), 0, 0) > 0) { + stbuf->st_mode = tmp_mode; + } + if(getxattr(rpath(fs_ctx, path, buffer), "user.virtfs.rdev", &tmp_dev, + sizeof(dev_t)) > 0) { + stbuf->st_rdev = tmp_dev; + } +#endif } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) { local_mapped_file_attr(fs_ctx, path, stbuf); } @@ -250,28 +271,44 @@ static int local_set_xattr(const char *path, FsCred *credp) if (credp->fc_uid != -1) { err = setxattr(path, "user.virtfs.uid", &credp->fc_uid, sizeof(uid_t), +#ifdef CONFIG_LINUX 0); +#else + 0, 0); +#endif if (err) { return err; } } if (credp->fc_gid != -1) { err = setxattr(path, "user.virtfs.gid", &credp->fc_gid, sizeof(gid_t), +#ifdef CONFIG_LINUX 0); +#else + 0, 0); +#endif if (err) { return err; } } if (credp->fc_mode != -1) { err = setxattr(path, "user.virtfs.mode", &credp->fc_mode, +#ifdef CONFIG_LINUX sizeof(mode_t), 0); +#else + sizeof(mode_t), 0, 0); +#endif if (err) { return err; } } if (credp->fc_rdev != -1) { err = setxattr(path, "user.virtfs.rdev", &credp->fc_rdev, +#ifdef CONFIG_LINUX sizeof(dev_t), 0); +#else + sizeof(dev_t), 0, 0); +#endif if (err) { return err; } @@ -595,6 +632,7 @@ static int local_fstat(FsContext *fs_ctx, int fid_type, mode_t tmp_mode; dev_t tmp_dev; +#ifdef CONFIG_LINUX if (fgetxattr(fd, "user.virtfs.uid", &tmp_uid, sizeof(uid_t)) > 0) { stbuf->st_uid = tmp_uid; @@ -611,6 +649,25 @@ static int local_fstat(FsContext *fs_ctx, int fid_type, &tmp_dev, sizeof(dev_t)) > 0) { stbuf->st_rdev = tmp_dev; } +#else + if (fgetxattr(fd, "user.virtfs.uid", + &tmp_uid, sizeof(uid_t), 0, 0) > 0) { + stbuf->st_uid = tmp_uid; + } + if (fgetxattr(fd, "user.virtfs.gid", + &tmp_gid, sizeof(gid_t), 0, 0) > 0) { + stbuf->st_gid = tmp_gid; + } + if (fgetxattr(fd, "user.virtfs.mode", + &tmp_mode, sizeof(mode_t), 0, 0) > 0) { + stbuf->st_mode = tmp_mode; + } + if (fgetxattr(fd, "user.virtfs.rdev", + &tmp_dev, sizeof(dev_t), 0, 0) > 0) { + stbuf->st_rdev = tmp_dev; + } + +#endif } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) { errno = EOPNOTSUPP; return -1; diff --git a/hw/9pfs/virtio-9p-posix-acl.c b/hw/9pfs/virtio-9p-posix-acl.c index 339c5ec..7b979b8 100644 --- a/hw/9pfs/virtio-9p-posix-acl.c +++ b/hw/9pfs/virtio-9p-posix-acl.c @@ -26,8 +26,12 @@ static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size) { +#ifdef CONFIG_LINUX char buffer[PATH_MAX]; return lgetxattr(rpath(ctx, path, buffer), MAP_ACL_ACCESS, value, size); +#else + return 0; +#endif } static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path, @@ -52,14 +56,19 @@ static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path, static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size, int flags) { +#ifdef CONFIG_LINUX char buffer[PATH_MAX]; return lsetxattr(rpath(ctx, path, buffer), MAP_ACL_ACCESS, value, size, flags); +#else + return 0; +#endif } static int mp_pacl_removexattr(FsContext *ctx, const char *path, const char *name) { +#ifdef CONFIG_LINUX int ret; char buffer[PATH_MAX]; ret = lremovexattr(rpath(ctx, path, buffer), MAP_ACL_ACCESS); @@ -73,13 +82,20 @@ static int mp_pacl_removexattr(FsContext *ctx, ret = 0; } return ret; +#else + return 0; +#endif } static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size) { +#ifdef CONFIG_LINUX char buffer[PATH_MAX]; return lgetxattr(rpath(ctx, path, buffer), MAP_ACL_DEFAULT, value, size); +#else + return 0; +#endif } static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path, @@ -104,14 +120,19 @@ static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path, static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size, int flags) { +#ifdef CONFIG_LINUX char buffer[PATH_MAX]; return lsetxattr(rpath(ctx, path, buffer), MAP_ACL_DEFAULT, value, size, flags); +#else + return 0; +#endif } static int mp_dacl_removexattr(FsContext *ctx, const char *path, const char *name) { +#ifdef CONFIG_LINUX int ret; char buffer[PATH_MAX]; ret = lremovexattr(rpath(ctx, path, buffer), MAP_ACL_DEFAULT); @@ -125,6 +146,9 @@ static int mp_dacl_removexattr(FsContext *ctx, ret = 0; } return ret; +#else + return 0; +#endif } diff --git a/hw/9pfs/virtio-9p-xattr-user.c b/hw/9pfs/virtio-9p-xattr-user.c index e0c92eb..c5d1f47 100644 --- a/hw/9pfs/virtio-9p-xattr-user.c +++ b/hw/9pfs/virtio-9p-xattr-user.c @@ -30,7 +30,11 @@ static ssize_t mp_user_getxattr(FsContext *ctx, const char *path, errno = ENOATTR; return -1; } +#ifdef CONFIG_LINUX return lgetxattr(rpath(ctx, path, buffer), name, value, size); +#else + return getxattr(rpath(ctx, path, buffer), name, value, size, 0, XATTR_NOFOLLOW); +#endif } static ssize_t mp_user_listxattr(FsContext *ctx, const char *path, @@ -78,7 +82,11 @@ static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name, errno = EACCES; return -1; } +#ifdef CONFIG_LINUX return lsetxattr(rpath(ctx, path, buffer), name, value, size, flags); +#else + return setxattr(rpath(ctx, path, buffer), name, value, size, 0, flags | XATTR_NOFOLLOW); +#endif } static int mp_user_removexattr(FsContext *ctx, @@ -93,7 +101,11 @@ static int mp_user_removexattr(FsContext *ctx, errno = EACCES; return -1; } +#ifdef CONFIG_LINUX return lremovexattr(rpath(ctx, path, buffer), name); +#else + return removexattr(rpath(ctx, path, buffer), name, XATTR_NOFOLLOW); +#endif } XattrOperations mapped_user_xattr = { diff --git a/hw/9pfs/virtio-9p-xattr.c b/hw/9pfs/virtio-9p-xattr.c index 3fae557..29e2288 100644 --- a/hw/9pfs/virtio-9p-xattr.c +++ b/hw/9pfs/virtio-9p-xattr.c @@ -74,14 +74,22 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path, ssize_t xattr_len, parsed_len = 0, attr_len; /* Get the actual len */ +#ifdef CONFIG_LINUX xattr_len = llistxattr(rpath(ctx, path, buffer), value, 0); +#else + xattr_len = listxattr(rpath(ctx, path, buffer), value, 0, XATTR_NOFOLLOW); +#endif if (xattr_len <= 0) { return xattr_len; } /* Now fetch the xattr and find the actual size */ orig_value = g_malloc(xattr_len); +#ifdef CONFIG_LINUX xattr_len = llistxattr(rpath(ctx, path, buffer), orig_value, xattr_len); +#else + xattr_len = listxattr(rpath(ctx, path, buffer), orig_value, xattr_len, XATTR_NOFOLLOW); +#endif /* store the orig pointer */ orig_value_start = orig_value; diff --git a/hw/9pfs/virtio-9p-xattr.h b/hw/9pfs/virtio-9p-xattr.h index 41cc6cb..202f139 100644 --- a/hw/9pfs/virtio-9p-xattr.h +++ b/hw/9pfs/virtio-9p-xattr.h @@ -55,7 +55,11 @@ static inline ssize_t pt_getxattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size) { char buffer[PATH_MAX]; +#ifdef CONFIG_LINUX return lgetxattr(rpath(ctx, path, buffer), name, value, size); +#else + return getxattr(rpath(ctx, path, buffer), name, value, size, 0, XATTR_NOFOLLOW); +#endif } static inline int pt_setxattr(FsContext *ctx, const char *path, @@ -63,14 +67,22 @@ static inline int pt_setxattr(FsContext *ctx, const char *path, size_t size, int flags) { char buffer[PATH_MAX]; +#ifdef CONFIG_LINUX return lsetxattr(rpath(ctx, path, buffer), name, value, size, flags); +#else + return setxattr(rpath(ctx, path, buffer), name, value, size, 0, flags | XATTR_NOFOLLOW); +#endif } static inline int pt_removexattr(FsContext *ctx, const char *path, const char *name) { char buffer[PATH_MAX]; +#ifdef CONFIG_LINUX return lremovexattr(rpath(ctx, path, buffer), name); +#else + return removexattr(rpath(ctx, path, buffer), name, XATTR_NOFOLLOW); +#endif } static inline ssize_t notsup_getxattr(FsContext *ctx, const char *path, diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c index 8cbb8ae..ba5a174 100644 --- a/hw/9pfs/virtio-9p.c +++ b/hw/9pfs/virtio-9p.c @@ -21,6 +21,11 @@ #include "trace.h" #include "migration/migration.h" +#ifdef CONFIG_DARWIN +#define O_DIRECT 040000 /* Direct disk access */ +#define O_NOATIME 01000000 /* Do not set atime */ +#endif + int open_fd_hw; int total_open_fd; static int open_fd_rc; @@ -854,12 +859,21 @@ static void stat_to_v9stat_dotl(V9fsState *s, const struct stat *stbuf, v9lstat->st_size = stbuf->st_size; v9lstat->st_blksize = stbuf->st_blksize; v9lstat->st_blocks = stbuf->st_blocks; +#ifdef CONFIG_LINUX v9lstat->st_atime_sec = stbuf->st_atime; v9lstat->st_atime_nsec = stbuf->st_atim.tv_nsec; v9lstat->st_mtime_sec = stbuf->st_mtime; v9lstat->st_mtime_nsec = stbuf->st_mtim.tv_nsec; v9lstat->st_ctime_sec = stbuf->st_ctime; v9lstat->st_ctime_nsec = stbuf->st_ctim.tv_nsec; +#else // darwin + v9lstat->st_atime_sec = stbuf->st_atimespec.tv_sec; + v9lstat->st_atime_nsec = stbuf->st_atimespec.tv_nsec; + v9lstat->st_mtime_sec = stbuf->st_mtimespec.tv_sec; + v9lstat->st_mtime_nsec = stbuf->st_mtimespec.tv_nsec; + v9lstat->st_ctime_sec = stbuf->st_ctimespec.tv_sec; + v9lstat->st_ctime_nsec = stbuf->st_ctimespec.tv_nsec; +#endif /* Currently we only support BASIC fields in stat */ v9lstat->st_result_mask = P9_STATS_BASIC; @@ -1788,6 +1802,12 @@ static int v9fs_do_readdir(V9fsPDU *pdu, if (err || !result) { break; } + +#ifdef CONFIG_DARWIN + uint64_t d_offset = 0; + d_offset = v9fs_co_telldir(pdu, fidp); +#endif + v9fs_string_init(&name); v9fs_string_sprintf(&name, "%s", dent->d_name); if ((count + v9fs_readdir_data_size(&name)) > max_count) { @@ -1810,7 +1830,11 @@ static int v9fs_do_readdir(V9fsPDU *pdu, /* 11 = 7 + 4 (7 = start offset, 4 = space for storing count) */ len = pdu_marshal(pdu, 11 + count, "Qqbs", +#ifdef CONFIG_LINUX &qid, dent->d_off, +#else + &qid, d_offset, +#endif dent->d_type, &name); if (len < 0) { v9fs_co_seekdir(pdu, fidp, saved_dir_pos); @@ -1820,7 +1844,11 @@ static int v9fs_do_readdir(V9fsPDU *pdu, } count += len; v9fs_string_free(&name); +#ifdef CONFIG_LINUX saved_dir_pos = dent->d_off; +#else + saved_dir_pos = d_offset; +#endif } g_free(dent); if (err < 0) { diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h index 1d6eedb..607334c 100644 --- a/hw/9pfs/virtio-9p.h +++ b/hw/9pfs/virtio-9p.h @@ -224,7 +224,9 @@ typedef struct V9fsState CoRwlock rename_lock; int32_t root_fid; Error *migration_blocker; +#ifdef CONFIG_LINUX V9fsConf fsconf; +#endif } V9fsState; typedef struct V9fsStatState { diff --git a/include/qemu/xattr.h b/include/qemu/xattr.h index f910d96..e5b485c 100644 --- a/include/qemu/xattr.h +++ b/include/qemu/xattr.h @@ -23,7 +23,9 @@ #ifdef CONFIG_LIBATTR # include #else +#ifndef ENOATTR # define ENOATTR ENODATA +#endif # include #endif -- 2.7.4