virtio-9p: enable virtfs on Mac OS X. 76/20176/1
authorKitae Kim <kt920.kim@samsung.com>
Tue, 29 Oct 2013 08:14:12 +0000 (17:14 +0900)
committerSooyoung Ha <yoosah.ha@samsung.com>
Tue, 29 Apr 2014 05:52:07 +0000 (14:52 +0900)
Support virtio-9p local operation on Mac OS X to provide host directory sharing.

Change-Id: Ic034673c6d3d4102ebe4fbaea7e186fffec34a2f
Signed-off-by: Kitae Kim <kt920.kim@samsung.com>
12 files changed:
Makefile.objs
configure
fsdev/file-op-9p.h
hw/9pfs/Makefile.objs
hw/9pfs/virtio-9p-local.c
hw/9pfs/virtio-9p-posix-acl.c
hw/9pfs/virtio-9p-xattr-user.c
hw/9pfs/virtio-9p-xattr.c
hw/9pfs/virtio-9p-xattr.h
hw/9pfs/virtio-9p.c
hw/9pfs/virtio-9p.h
include/qemu/xattr.h

index 2b6c1fe..2f48c35 100644 (file)
@@ -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
index 0791234..5b9a298 100755 (executable)
--- 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"
index 956fda0..75ad11f 100644 (file)
 #include <sys/stat.h>
 #include <sys/uio.h>
 #include <sys/vfs.h>
+#ifdef CONFIG_LINUX
+#include <sys/vfs.h>
+#endif
+#ifdef CONFIG_DARWIN
+#include <sys/param.h>
+#include <sys/mount.h>
+#endif
 
 #define SM_LOCAL_MODE_BITS    0600
 #define SM_LOCAL_DIR_MODE_BITS    0700
index 1e9b595..39fe14d 100644 (file)
@@ -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
index fc93e9e..24e2cda 100644 (file)
@@ -21,7 +21,9 @@
 #include <sys/un.h>
 #include "qemu/xattr.h"
 #include <libgen.h>
+#ifdef CONFIG_LINUX
 #include <linux/fs.h>
+#endif
 #ifdef CONFIG_LINUX_MAGIC_H
 #include <linux/magic.h>
 #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;
index 339c5ec..7b979b8 100644 (file)
 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
 }
 
 
index e0c92eb..c5d1f47 100644 (file)
@@ -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 = {
index 3fae557..29e2288 100644 (file)
@@ -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;
index 41cc6cb..202f139 100644 (file)
@@ -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,
index 8cbb8ae..ba5a174 100644 (file)
 #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) {
index 1d6eedb..607334c 100644 (file)
@@ -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 {
index f910d96..e5b485c 100644 (file)
@@ -23,7 +23,9 @@
 #ifdef CONFIG_LIBATTR
 #  include <attr/xattr.h>
 #else
+#ifndef ENOATTR
 #  define ENOATTR ENODATA
+#endif
 #  include <sys/xattr.h>
 #endif