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>
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
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"
#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
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
#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
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;
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);
}
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;
}
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;
&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;
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,
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);
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,
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);
ret = 0;
}
return ret;
+#else
+ return 0;
+#endif
}
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,
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,
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 = {
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;
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,
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,
#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;
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;
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) {
/* 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);
}
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) {
CoRwlock rename_lock;
int32_t root_fid;
Error *migration_blocker;
+#ifdef CONFIG_LINUX
V9fsConf fsconf;
+#endif
} V9fsState;
typedef struct V9fsStatState {
#ifdef CONFIG_LIBATTR
# include <attr/xattr.h>
#else
+#ifndef ENOATTR
# define ENOATTR ENODATA
+#endif
# include <sys/xattr.h>
#endif