Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/cschoenebeck/tags/pull-9p-20220…
Browse files Browse the repository at this point in the history
…307' into staging

9pfs: introduce macOS host support and cleanup

* Add support for Darwin (a.k.a. macOS) hosts.

* Code cleanup (move qemu_dirent_dup() from osdep -> 9p-util).

* API doc cleanup (convert Doxygen -> kerneldoc format).

# gpg: Signature made Mon 07 Mar 2022 11:14:45 GMT
# gpg:                using RSA key 96D8D110CF7AF8084F88590134C2B58765A47395
# gpg:                issuer "qemu_oss@crudebyte.com"
# gpg: Good signature from "Christian Schoenebeck <qemu_oss@crudebyte.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: ECAB 1A45 4014 1413 BA38  4926 30DB 47C3 A012 D5F4
#      Subkey fingerprint: 96D8 D110 CF7A F808 4F88  5901 34C2 B587 65A4 7395

* remotes/cschoenebeck/tags/pull-9p-20220307:
  fsdev/p9array.h: convert Doxygen -> kerneldoc format
  9pfs/coth.h: drop Doxygen format on v9fs_co_run_in_worker()
  9pfs/9p-util.h: convert Doxygen -> kerneldoc format
  9pfs/9p.c: convert Doxygen -> kerneldoc format
  9pfs/codir.c: convert Doxygen -> kerneldoc format
  9pfs/9p.h: convert Doxygen -> kerneldoc format
  9pfs: drop Doxygen format from qemu_dirent_dup() API comment
  9pfs: move qemu_dirent_dup() from osdep -> 9p-util
  9p: darwin: meson: Allow VirtFS on Darwin
  9p: darwin: Adjust assumption on virtio-9p-test
  9p: darwin: Implement compatibility for mknodat
  9p: darwin: Compatibility for f/l*xattr
  9p: darwin: *xattr_nofollow implementations
  9p: darwin: Move XATTR_SIZE_MAX->P9_XATTR_SIZE_MAX
  9p: darwin: Ignore O_{NOATIME, DIRECT}
  9p: darwin: Handle struct dirent differences
  9p: darwin: Handle struct stat(fs) differences
  9p: Rename 9p-util -> 9p-util-linux
  9p: linux: Fix a couple Linux assumptions

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Mar 8, 2022
2 parents 99c4a9e + 35b6466 commit f45cc81
Show file tree
Hide file tree
Showing 19 changed files with 403 additions and 127 deletions.
9 changes: 8 additions & 1 deletion fsdev/file-op-9p.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,17 @@

#include <dirent.h>
#include <utime.h>
#include <sys/vfs.h>
#include "qemu-fsdev-throttle.h"
#include "p9array.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

Expand Down
1 change: 1 addition & 0 deletions fsdev/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ fsdev_ss.add(when: ['CONFIG_FSDEV_9P'], if_true: files(
'qemu-fsdev.c',
), if_false: files('qemu-fsdev-dummy.c'))
softmmu_ss.add_all(when: 'CONFIG_LINUX', if_true: fsdev_ss)
softmmu_ss.add_all(when: 'CONFIG_DARWIN', if_true: fsdev_ss)

if have_virtfs_proxy_helper
executable('virtfs-proxy-helper',
Expand Down
38 changes: 21 additions & 17 deletions fsdev/p9array.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@
*/

/**
* Declares an array type for the passed @a scalar_type.
* P9ARRAY_DECLARE_TYPE() - Declares an array type for the passed @scalar_type.
*
* This is typically used from a shared header file.
* @scalar_type: type of the individual array elements
*
* @param scalar_type - type of the individual array elements
* This is typically used from a shared header file.
*/
#define P9ARRAY_DECLARE_TYPE(scalar_type) \
typedef struct P9Array##scalar_type { \
Expand All @@ -97,14 +97,14 @@
void p9array_auto_free_##scalar_type(scalar_type **auto_var); \

/**
* Defines an array type for the passed @a scalar_type and appropriate
* @a scalar_cleanup_func.
* P9ARRAY_DEFINE_TYPE() - Defines an array type for the passed @scalar_type
* and appropriate @scalar_cleanup_func.
*
* This is typically used from a C unit file.
* @scalar_type: type of the individual array elements
* @scalar_cleanup_func: appropriate function to free memory dynamically
* allocated by individual array elements before
*
* @param scalar_type - type of the individual array elements
* @param scalar_cleanup_func - appropriate function to free memory dynamically
* allocated by individual array elements before
* This is typically used from a C unit file.
*/
#define P9ARRAY_DEFINE_TYPE(scalar_type, scalar_cleanup_func) \
void p9array_new_##scalar_type(scalar_type **auto_var, size_t len) \
Expand Down Expand Up @@ -132,23 +132,27 @@
} \

/**
* P9ARRAY_REF() - Declare a reference variable for an array.
*
* @scalar_type: type of the individual array elements
*
* Used to declare a reference variable (unique pointer) for an array. After
* leaving the scope of the reference variable, the associated array is
* automatically freed.
*
* @param scalar_type - type of the individual array elements
*/
#define P9ARRAY_REF(scalar_type) \
__attribute((__cleanup__(p9array_auto_free_##scalar_type))) scalar_type*

/**
* Allocates a new array of passed @a scalar_type with @a len number of array
* elements and assigns the created array to the reference variable
* @a auto_var.
* P9ARRAY_NEW() - Allocate a new array.
*
* @param scalar_type - type of the individual array elements
* @param auto_var - destination reference variable
* @param len - amount of array elements to be allocated immediately
* @scalar_type: type of the individual array elements
* @auto_var: destination reference variable
* @len: amount of array elements to be allocated immediately
*
* Allocates a new array of passed @scalar_type with @len number of array
* elements and assigns the created array to the reference variable
* @auto_var.
*/
#define P9ARRAY_NEW(scalar_type, auto_var, len) \
QEMU_BUILD_BUG_MSG( \
Expand Down
27 changes: 21 additions & 6 deletions hw/9pfs/9p-local.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@
#include "qemu/error-report.h"
#include "qemu/option.h"
#include <libgen.h>
#ifdef CONFIG_LINUX
#include <linux/fs.h>
#ifdef CONFIG_LINUX_MAGIC_H
#include <linux/magic.h>
#endif
#endif
#include <sys/ioctl.h>

#ifndef XFS_SUPER_MAGIC
Expand Down Expand Up @@ -560,6 +562,15 @@ static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs)
if (!entry) {
return NULL;
}
#ifdef CONFIG_DARWIN
int off;
off = telldir(fs->dir.stream);
/* If telldir fails, fail the entire readdir call */
if (off < 0) {
return NULL;
}
entry->d_seekoff = off;
#endif

if (ctx->export_flags & V9FS_SM_MAPPED) {
entry->d_type = DT_UNKNOWN;
Expand Down Expand Up @@ -671,7 +682,7 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,

if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
err = mknodat(dirfd, name, fs_ctx->fmode | S_IFREG, 0);
err = qemu_mknodat(dirfd, name, fs_ctx->fmode | S_IFREG, 0);
if (err == -1) {
goto out;
}
Expand All @@ -686,7 +697,7 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
}
} else if (fs_ctx->export_flags & V9FS_SM_PASSTHROUGH ||
fs_ctx->export_flags & V9FS_SM_NONE) {
err = mknodat(dirfd, name, credp->fc_mode, credp->fc_rdev);
err = qemu_mknodat(dirfd, name, credp->fc_mode, credp->fc_rdev);
if (err == -1) {
goto out;
}
Expand Down Expand Up @@ -779,16 +790,20 @@ static int local_fstat(FsContext *fs_ctx, int fid_type,
mode_t tmp_mode;
dev_t tmp_dev;

if (fgetxattr(fd, "user.virtfs.uid", &tmp_uid, sizeof(uid_t)) > 0) {
if (qemu_fgetxattr(fd, "user.virtfs.uid",
&tmp_uid, sizeof(uid_t)) > 0) {
stbuf->st_uid = le32_to_cpu(tmp_uid);
}
if (fgetxattr(fd, "user.virtfs.gid", &tmp_gid, sizeof(gid_t)) > 0) {
if (qemu_fgetxattr(fd, "user.virtfs.gid",
&tmp_gid, sizeof(gid_t)) > 0) {
stbuf->st_gid = le32_to_cpu(tmp_gid);
}
if (fgetxattr(fd, "user.virtfs.mode", &tmp_mode, sizeof(mode_t)) > 0) {
if (qemu_fgetxattr(fd, "user.virtfs.mode",
&tmp_mode, sizeof(mode_t)) > 0) {
stbuf->st_mode = le32_to_cpu(tmp_mode);
}
if (fgetxattr(fd, "user.virtfs.rdev", &tmp_dev, sizeof(dev_t)) > 0) {
if (qemu_fgetxattr(fd, "user.virtfs.rdev",
&tmp_dev, sizeof(dev_t)) > 0) {
stbuf->st_rdev = le64_to_cpu(tmp_dev);
}
} else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
Expand Down
38 changes: 35 additions & 3 deletions hw/9pfs/9p-proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,16 @@ static void prstatfs_to_statfs(struct statfs *stfs, ProxyStatFS *prstfs)
stfs->f_bavail = prstfs->f_bavail;
stfs->f_files = prstfs->f_files;
stfs->f_ffree = prstfs->f_ffree;
#ifdef CONFIG_DARWIN
/* f_namelen and f_frsize do not exist on Darwin */
stfs->f_fsid.val[0] = prstfs->f_fsid[0] & 0xFFFFFFFFU;
stfs->f_fsid.val[1] = prstfs->f_fsid[1] >> 32 & 0xFFFFFFFFU;
#else
stfs->f_fsid.__val[0] = prstfs->f_fsid[0] & 0xFFFFFFFFU;
stfs->f_fsid.__val[1] = prstfs->f_fsid[1] >> 32 & 0xFFFFFFFFU;
stfs->f_namelen = prstfs->f_namelen;
stfs->f_frsize = prstfs->f_frsize;
#endif
}

/* Converts proxy_stat structure to VFS stat structure */
Expand All @@ -143,12 +149,24 @@ static void prstat_to_stat(struct stat *stbuf, ProxyStat *prstat)
stbuf->st_size = prstat->st_size;
stbuf->st_blksize = prstat->st_blksize;
stbuf->st_blocks = prstat->st_blocks;
stbuf->st_atime = prstat->st_atim_sec;
stbuf->st_mtime = prstat->st_mtim_sec;
stbuf->st_ctime = prstat->st_ctim_sec;
#ifdef CONFIG_DARWIN
stbuf->st_atimespec.tv_sec = prstat->st_atim_sec;
stbuf->st_mtimespec.tv_sec = prstat->st_mtim_sec;
stbuf->st_ctimespec.tv_sec = prstat->st_ctim_sec;
stbuf->st_atimespec.tv_nsec = prstat->st_atim_nsec;
stbuf->st_mtimespec.tv_nsec = prstat->st_mtim_nsec;
stbuf->st_ctimespec.tv_nsec = prstat->st_ctim_nsec;
#else
stbuf->st_atim.tv_sec = prstat->st_atim_sec;
stbuf->st_mtim.tv_sec = prstat->st_mtim_sec;
stbuf->st_ctim.tv_sec = prstat->st_ctim_sec;
stbuf->st_atim.tv_nsec = prstat->st_atim_nsec;
stbuf->st_mtime = prstat->st_mtim_sec;
stbuf->st_mtim.tv_nsec = prstat->st_mtim_nsec;
stbuf->st_ctime = prstat->st_ctim_sec;
stbuf->st_ctim.tv_nsec = prstat->st_ctim_nsec;
#endif
}

/*
Expand Down Expand Up @@ -688,7 +706,21 @@ static off_t proxy_telldir(FsContext *ctx, V9fsFidOpenState *fs)

static struct dirent *proxy_readdir(FsContext *ctx, V9fsFidOpenState *fs)
{
return readdir(fs->dir.stream);
struct dirent *entry;
entry = readdir(fs->dir.stream);
#ifdef CONFIG_DARWIN
if (!entry) {
return NULL;
}
int td;
td = telldir(fs->dir.stream);
/* If telldir fails, fail the entire readdir call */
if (td < 0) {
return NULL;
}
entry->d_seekoff = td;
#endif
return entry;
}

static void proxy_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off)
Expand Down
6 changes: 6 additions & 0 deletions hw/9pfs/9p-synth.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,11 @@ static void synth_direntry(V9fsSynthNode *node,
offsetof(struct dirent, d_name) + sz);
memcpy(entry->d_name, node->name, sz);
entry->d_ino = node->attr->inode;
#ifdef CONFIG_DARWIN
entry->d_seekoff = off + 1;
#else
entry->d_off = off + 1;
#endif
}

static struct dirent *synth_get_dentry(V9fsSynthNode *dir,
Expand Down Expand Up @@ -439,7 +443,9 @@ static int synth_statfs(FsContext *s, V9fsPath *fs_path,
stbuf->f_bsize = 512;
stbuf->f_blocks = 0;
stbuf->f_files = synth_node_count;
#ifndef CONFIG_DARWIN
stbuf->f_namelen = NAME_MAX;
#endif
return 0;
}

Expand Down
97 changes: 97 additions & 0 deletions hw/9pfs/9p-util-darwin.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* 9p utilities (Darwin Implementation)
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/

#include "qemu/osdep.h"
#include "qemu/xattr.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "9p-util.h"

ssize_t fgetxattrat_nofollow(int dirfd, const char *filename, const char *name,
void *value, size_t size)
{
int ret;
int fd = openat_file(dirfd, filename,
O_RDONLY | O_PATH_9P_UTIL | O_NOFOLLOW, 0);
if (fd == -1) {
return -1;
}
ret = fgetxattr(fd, name, value, size, 0, 0);
close_preserve_errno(fd);
return ret;
}

ssize_t flistxattrat_nofollow(int dirfd, const char *filename,
char *list, size_t size)
{
int ret;
int fd = openat_file(dirfd, filename,
O_RDONLY | O_PATH_9P_UTIL | O_NOFOLLOW, 0);
if (fd == -1) {
return -1;
}
ret = flistxattr(fd, list, size, 0);
close_preserve_errno(fd);
return ret;
}

ssize_t fremovexattrat_nofollow(int dirfd, const char *filename,
const char *name)
{
int ret;
int fd = openat_file(dirfd, filename, O_PATH_9P_UTIL | O_NOFOLLOW, 0);
if (fd == -1) {
return -1;
}
ret = fremovexattr(fd, name, 0);
close_preserve_errno(fd);
return ret;
}

int fsetxattrat_nofollow(int dirfd, const char *filename, const char *name,
void *value, size_t size, int flags)
{
int ret;
int fd = openat_file(dirfd, filename, O_PATH_9P_UTIL | O_NOFOLLOW, 0);
if (fd == -1) {
return -1;
}
ret = fsetxattr(fd, name, value, size, 0, flags);
close_preserve_errno(fd);
return ret;
}

/*
* As long as mknodat is not available on macOS, this workaround
* using pthread_fchdir_np is needed.
*
* Radar filed with Apple for implementing mknodat:
* rdar://FB9862426 (https://openradar.appspot.com/FB9862426)
*/
#if defined CONFIG_PTHREAD_FCHDIR_NP

int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev)
{
int preserved_errno, err;
if (!pthread_fchdir_np) {
error_report_once("pthread_fchdir_np() not available on this version of macOS");
return -ENOTSUP;
}
if (pthread_fchdir_np(dirfd) < 0) {
return -1;
}
err = mknod(filename, mode, dev);
preserved_errno = errno;
/* Stop using the thread-local cwd */
pthread_fchdir_np(-1);
if (err < 0) {
errno = preserved_errno;
}
return err;
}

#endif
8 changes: 7 additions & 1 deletion hw/9pfs/9p-util.c → hw/9pfs/9p-util-linux.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* 9p utilities
* 9p utilities (Linux Implementation)
*
* Copyright IBM, Corp. 2017
*
Expand Down Expand Up @@ -61,4 +61,10 @@ int fsetxattrat_nofollow(int dirfd, const char *filename, const char *name,
ret = lsetxattr(proc_path, name, value, size, flags);
g_free(proc_path);
return ret;

}

int qemu_mknodat(int dirfd, const char *filename, mode_t mode, dev_t dev)
{
return mknodat(dirfd, filename, mode, dev);
}
Loading

0 comments on commit f45cc81

Please sign in to comment.