new file mode 100644
@@ -0,0 +1,26 @@
+/*
+ * Virtio 9p
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_9P_H
+#define QEMU_9P_H
+
+#include <stdbool.h>
+
+typedef struct V9fsConf
+{
+ char *share_path;
+ /* tag name for the device */
+ char *tag;
+} V9fsConf;
+
+#endif
@@ -22,22 +22,20 @@
#include <sys/socket.h>
#include <sys/un.h>
-static const char *base_path;
-
-static const char *rpath(const char *path)
+static const char *rpath(V9fsState *s, const char *path)
{
/* FIXME: so wrong... */
static char buffer[4096];
- snprintf(buffer, sizeof(buffer), "%s/%s", base_path, path);
+ snprintf(buffer, sizeof(buffer), "%s/%s", s->fs_root, path);
return buffer;
}
-static int local_lstat(void *opaque, const char *path, struct stat *stbuf)
+static int local_lstat(V9fsState *s, const char *path, struct stat *stbuf)
{
- return lstat(rpath(path), stbuf);
+ return lstat(rpath(s, path), stbuf);
}
-static int local_setuid(void *opaque, uid_t uid)
+static int local_setuid(V9fsState *s, uid_t uid)
{
struct passwd *pw;
gid_t groups[33];
@@ -72,86 +70,86 @@ static int local_setuid(void *opaque, uid_t uid)
return 0;
}
-static ssize_t local_readlink(void *opaque, const char *path,
+static ssize_t local_readlink(V9fsState *s, const char *path,
char *buf, size_t bufsz)
{
- return readlink(rpath(path), buf, bufsz);
+ return readlink(rpath(s, path), buf, bufsz);
}
-static int local_close(void *opaque, int fd)
+static int local_close(V9fsState *s, int fd)
{
return close(fd);
}
-static int local_closedir(void *opaque, DIR *dir)
+static int local_closedir(V9fsState *s, DIR *dir)
{
return closedir(dir);
}
-static int local_open(void *opaque, const char *path, int flags)
+static int local_open(V9fsState *s, const char *path, int flags)
{
- return open(rpath(path), flags);
+ return open(rpath(s, path), flags);
}
-static DIR *local_opendir(void *opaque, const char *path)
+static DIR *local_opendir(V9fsState *s, const char *path)
{
- return opendir(rpath(path));
+ return opendir(rpath(s, path));
}
-static void local_rewinddir(void *opaque, DIR *dir)
+static void local_rewinddir(V9fsState *s, DIR *dir)
{
return rewinddir(dir);
}
-static off_t local_telldir(void *opaque, DIR *dir)
+static off_t local_telldir(V9fsState *s, DIR *dir)
{
return telldir(dir);
}
-static struct dirent *local_readdir(void *opaque, DIR *dir)
+static struct dirent *local_readdir(V9fsState *s, DIR *dir)
{
return readdir(dir);
}
-static void local_seekdir(void *opaque, DIR *dir, off_t off)
+static void local_seekdir(V9fsState *s, DIR *dir, off_t off)
{
return seekdir(dir, off);
}
-static ssize_t local_readv(void *opaque, int fd, const struct iovec *iov,
+static ssize_t local_readv(V9fsState *s, int fd, const struct iovec *iov,
int iovcnt)
{
return readv(fd, iov, iovcnt);
}
-static off_t local_lseek(void *opaque, int fd, off_t offset, int whence)
+static off_t local_lseek(V9fsState *s, int fd, off_t offset, int whence)
{
return lseek(fd, offset, whence);
}
-static ssize_t local_writev(void *opaque, int fd, const struct iovec *iov,
+static ssize_t local_writev(V9fsState *s, int fd, const struct iovec *iov,
int iovcnt)
{
return writev(fd, iov, iovcnt);
}
-static int local_chmod(void *opaque, const char *path, mode_t mode)
+static int local_chmod(V9fsState *s, const char *path, mode_t mode)
{
- return chmod(rpath(path), mode);
+ return chmod(rpath(s, path), mode);
}
-static int local_mknod(void *opaque, const char *path, mode_t mode, dev_t dev)
+static int local_mknod(V9fsState *s, const char *path, mode_t mode, dev_t dev)
{
- return mknod(rpath(path), mode, dev);
+ return mknod(rpath(s, path), mode, dev);
}
-static int local_mksock(void *opaque, const char *path)
+static int local_mksock(V9fsState *s2, const char *path)
{
struct sockaddr_un addr;
int s;
addr.sun_family = AF_UNIX;
- snprintf(addr.sun_path, 108, "%s", rpath(path));
+ snprintf(addr.sun_path, 108, "%s", rpath(s2, path));
s = socket(PF_UNIX, SOCK_STREAM, 0);
if (s == -1)
@@ -166,36 +164,36 @@ static int local_mksock(void *opaque, const char *path)
return 0;
}
-static int local_mkdir(void *opaque, const char *path, mode_t mode)
+static int local_mkdir(V9fsState *s, const char *path, mode_t mode)
{
- return mkdir(rpath(path), mode);
+ return mkdir(rpath(s, path), mode);
}
-static int local_fstat(void *opaque, int fd, struct stat *stbuf)
+static int local_fstat(V9fsState *s, int fd, struct stat *stbuf)
{
return fstat(fd, stbuf);
}
-static int local_open2(void *opaque, const char *path, int flags, mode_t mode)
+static int local_open2(V9fsState *s, const char *path, int flags, mode_t mode)
{
- return open(rpath(path), flags, mode);
+ return open(rpath(s, path), flags, mode);
}
-static int local_symlink(void *opaque, const char *oldpath,
+static int local_symlink(V9fsState *s, const char *oldpath,
const char *newpath)
{
- return symlink(oldpath, rpath(newpath));
+ return symlink(oldpath, rpath(s, newpath));
}
-static int local_link(void *opaque, const char *oldpath, const char *newpath)
+static int local_link(V9fsState *s, const char *oldpath, const char *newpath)
{
- char *tmp = strdup(rpath(oldpath));
+ char *tmp = strdup(rpath(s, oldpath));
int err, serrno = 0;
if (tmp == NULL)
return -ENOMEM;
- err = link(tmp, rpath(newpath));
+ err = link(tmp, rpath(s, newpath));
if (err == -1)
serrno = errno;
@@ -207,22 +205,22 @@ static int local_link(void *opaque, const char *oldpath, const char *newpath)
return err;
}
-static int local_truncate(void *opaque, const char *path, off_t size)
+static int local_truncate(V9fsState *s, const char *path, off_t size)
{
- return truncate(rpath(path), size);
+ return truncate(rpath(s, path), size);
}
-static int local_rename(void *opaque, const char *oldpath,
+static int local_rename(V9fsState *s, const char *oldpath,
const char *newpath)
{
char *tmp;
int err;
- tmp = strdup(rpath(oldpath));
+ tmp = strdup(rpath(s, oldpath));
if (tmp == NULL)
return -1;
- err = rename(tmp, rpath(newpath));
+ err = rename(tmp, rpath(s, newpath));
if (err == -1) {
int serrno = errno;
free(tmp);
@@ -234,20 +232,20 @@ static int local_rename(void *opaque, const char *oldpath,
}
-static int local_chown(void *opaque, const char *path, uid_t uid, gid_t gid)
+static int local_chown(V9fsState *s, const char *path, uid_t uid, gid_t gid)
{
- return chown(rpath(path), uid, gid);
+ return chown(rpath(s, path), uid, gid);
}
-static int local_utime(void *opaque, const char *path,
+static int local_utime(V9fsState *s, const char *path,
const struct utimbuf *buf)
{
- return utime(rpath(path), buf);
+ return utime(rpath(s, path), buf);
}
-static int local_remove(void *opaque, const char *path)
+static int local_remove(V9fsState *s, const char *path)
{
- return remove(rpath(path));
+ return remove(rpath(s, path));
}
@@ -283,6 +281,5 @@ static V9fsPosixFileOperations ops = {
V9fsPosixFileOperations *virtio_9p_init_local(const char *path)
{
- base_path = path;
return &ops;
}
@@ -15,78 +15,8 @@
#include "pc.h"
#include "qemu_socket.h"
#include "virtio-9p.h"
-
#include <assert.h>
-/* from Linux's linux/virtio_9p.h */
-
-/* The ID for virtio console */
-#define VIRTIO_ID_9P 9
-/* Maximum number of virtio channels per partition (1 for now) */
-#define MAX_9P_CHAN 1
-
-#define MAX_REQ 128
-
-#define BUG_ON(cond) assert(!(cond))
-
-typedef struct V9fsFidState V9fsFidState;
-
-typedef struct V9fsString
-{
- int16_t size;
- char *data;
-} V9fsString;
-
-typedef struct V9fsQID
-{
- int8_t type;
- int32_t version;
- int64_t path;
-} V9fsQID;
-
-typedef struct V9fsStat
-{
- int16_t size;
- int16_t type;
- int32_t dev;
- V9fsQID qid;
- int32_t mode;
- int32_t atime;
- int32_t mtime;
- int64_t length;
- V9fsString name;
- V9fsString uid;
- V9fsString gid;
- V9fsString muid;
- /* 9p2000.u */
- V9fsString extension;
- int32_t n_uid;
- int32_t n_gid;
- int32_t n_muid;
-} V9fsStat;
-
-struct V9fsFidState
-{
- int32_t fid;
- V9fsString path;
- int fd;
- DIR *dir;
- uid_t uid;
- V9fsFidState *next;
-};
-
-typedef struct V9fsState
-{
- VirtIODevice vdev;
- VirtQueue *vq;
- V9fsPDU pdus[MAX_REQ];
- V9fsPDU *free_pdu;
- V9fsFidState *fid_list;
- V9fsPosixFileOperations *ops;
- char *root;
- uid_t uid;
-} V9fsState;
-
int dotu = 1;
int debug_9p_pdu = 1;
@@ -94,12 +24,12 @@ extern void pprint_pdu(V9fsPDU *pdu);
static int posix_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf)
{
- return s->ops->lstat(s->ops->opaque, path->data, stbuf);
+ return s->ops->lstat(s, path->data, stbuf);
}
static int posix_setuid(V9fsState *s, uid_t uid)
{
- return s->ops->setuid(s->ops->opaque, uid);
+ return s->ops->setuid(s, uid);
}
static ssize_t posix_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
@@ -108,7 +38,7 @@ static ssize_t posix_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
buf->data = qemu_malloc(1024);
- len = s->ops->readlink(s->ops->opaque, path->data, buf->data, 1024 - 1);
+ len = s->ops->readlink(s, path->data, buf->data, 1024 - 1);
if (len > -1) {
buf->size = len;
buf->data[len] = 0;
@@ -119,127 +49,127 @@ static ssize_t posix_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
static int posix_close(V9fsState *s, int fd)
{
- return s->ops->close(s->ops->opaque, fd);
+ return s->ops->close(s, fd);
}
static int posix_closedir(V9fsState *s, DIR *dir)
{
- return s->ops->closedir(s->ops->opaque, dir);
+ return s->ops->closedir(s, dir);
}
static int posix_open(V9fsState *s, V9fsString *path, int flags)
{
- return s->ops->open(s->ops->opaque, path->data, flags);
+ return s->ops->open(s, path->data, flags);
}
static DIR *posix_opendir(V9fsState *s, V9fsString *path)
{
- return s->ops->opendir(s->ops->opaque, path->data);
+ return s->ops->opendir(s, path->data);
}
static void posix_rewinddir(V9fsState *s, DIR *dir)
{
- return s->ops->rewinddir(s->ops->opaque, dir);
+ return s->ops->rewinddir(s, dir);
}
static off_t posix_telldir(V9fsState *s, DIR *dir)
{
- return s->ops->telldir(s->ops->opaque, dir);
+ return s->ops->telldir(s, dir);
}
static struct dirent *posix_readdir(V9fsState *s, DIR *dir)
{
- return s->ops->readdir(s->ops->opaque, dir);
+ return s->ops->readdir(s, dir);
}
static void posix_seekdir(V9fsState *s, DIR *dir, off_t off)
{
- return s->ops->seekdir(s->ops->opaque, dir, off);
+ return s->ops->seekdir(s, dir, off);
}
static int posix_readv(V9fsState *s, int fd, const struct iovec *iov,
int iovcnt)
{
- return s->ops->readv(s->ops->opaque, fd, iov, iovcnt);
+ return s->ops->readv(s, fd, iov, iovcnt);
}
static off_t posix_lseek(V9fsState *s, int fd, off_t offset, int whence)
{
- return s->ops->lseek(s->ops->opaque, fd, offset, whence);
+ return s->ops->lseek(s, fd, offset, whence);
}
static int posix_writev(V9fsState *s, int fd, const struct iovec *iov,
int iovcnt)
{
- return s->ops->writev(s->ops->opaque, fd, iov, iovcnt);
+ return s->ops->writev(s, fd, iov, iovcnt);
}
static int posix_chmod(V9fsState *s, V9fsString *path, mode_t mode)
{
- return s->ops->chmod(s->ops->opaque, path->data, mode);
+ return s->ops->chmod(s, path->data, mode);
}
static int posix_mknod(V9fsState *s, V9fsString *path, mode_t mode, dev_t dev)
{
- return s->ops->mknod(s->ops->opaque, path->data, mode, dev);
+ return s->ops->mknod(s, path->data, mode, dev);
}
static int posix_mksock(V9fsState *s, V9fsString *path)
{
- return s->ops->mksock(s->ops->opaque, path->data);
+ return s->ops->mksock(s, path->data);
}
static int posix_mkdir(V9fsState *s, V9fsString *path, mode_t mode)
{
- return s->ops->mkdir(s->ops->opaque, path->data, mode);
+ return s->ops->mkdir(s, path->data, mode);
}
static int posix_fstat(V9fsState *s, int fd, struct stat *stbuf)
{
- return s->ops->fstat(s->ops->opaque, fd, stbuf);
+ return s->ops->fstat(s, fd, stbuf);
}
static int posix_open2(V9fsState *s, V9fsString *path, int flags, mode_t mode)
{
- return s->ops->open2(s->ops->opaque, path->data, flags, mode);
+ return s->ops->open2(s, path->data, flags, mode);
}
static int posix_symlink(V9fsState *s, V9fsString *oldpath,
V9fsString *newpath)
{
- return s->ops->symlink(s->ops->opaque, oldpath->data, newpath->data);
+ return s->ops->symlink(s, oldpath->data, newpath->data);
}
static int posix_link(V9fsState *s, V9fsString *oldpath, V9fsString *newpath)
{
- return s->ops->link(s->ops->opaque, oldpath->data, newpath->data);
+ return s->ops->link(s, oldpath->data, newpath->data);
}
static int posix_truncate(V9fsState *s, V9fsString *path, off_t size)
{
- return s->ops->truncate(s->ops->opaque, path->data, size);
+ return s->ops->truncate(s, path->data, size);
}
static int posix_rename(V9fsState *s, V9fsString *oldpath,
V9fsString *newpath)
{
- return s->ops->rename(s->ops->opaque, oldpath->data, newpath->data);
+ return s->ops->rename(s, oldpath->data, newpath->data);
}
static int posix_chown(V9fsState *s, V9fsString *path, uid_t uid, gid_t gid)
{
- return s->ops->chown(s->ops->opaque, path->data, uid, gid);
+ return s->ops->chown(s, path->data, uid, gid);
}
static int posix_utime(V9fsState *s, V9fsString *path,
const struct utimbuf *buf)
{
- return s->ops->utime(s->ops->opaque, path->data, buf);
+ return s->ops->utime(s, path->data, buf);
}
static int posix_remove(V9fsState *s, V9fsString *path)
{
- return s->ops->remove(s->ops->opaque, path->data);
+ return s->ops->remove(s, path->data);
}
static void v9fs_string_init(V9fsString *str)
@@ -787,7 +717,7 @@ static void v9fs_attach(V9fsState *s, V9fsPDU *pdu)
fidp->uid = n_uname;
- v9fs_string_sprintf(&fidp->path, "%s", s->root);
+ v9fs_string_sprintf(&fidp->path, "%s", "/");
fid_to_qid(s, fidp, &qid);
offset += pdu_marshal(pdu, offset, "Q", &qid);
@@ -2048,17 +1978,58 @@ static void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
{
+ features |= 1 << VIRTIO_9P_MOUNT_TAG;
return features;
}
-VirtIODevice *virtio_9p_init(DeviceState *dev, const char *path)
+static V9fsState *to_virtio_9p(VirtIODevice *vdev)
+{
+ return (V9fsState *)vdev;
+}
+
+static void virtio_9p_set_config(VirtIODevice *vdev, const uint8_t *config)
+{
+ uint16_t tag_len;
+ struct virtio_9p_config *cfg;
+ V9fsState *s = to_virtio_9p(vdev);
+
+ memcpy(&tag_len, config, sizeof(tag_len));
+ cfg = qemu_mallocz(sizeof(struct virtio_9p_config) + tag_len);
+
+ memcpy(cfg, config, s->config_size);
+ memcpy(&s->tag_len, &cfg->tag_len, sizeof(uint16_t));
+ /* free the old config details */
+ qemu_free(s->tag);
+ s->tag = qemu_malloc(tag_len);
+ memcpy(s->tag, cfg->tag, cfg->tag_len);
+ qemu_free(cfg);
+}
+
+static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
{
+ struct virtio_9p_config *cfg;
+ V9fsState *s = to_virtio_9p(vdev);
+
+ cfg = qemu_mallocz(sizeof(struct virtio_9p_config) +
+ s->tag_len);
+ memcpy(&cfg->tag_len, &s->tag_len, sizeof(uint16_t));
+ memcpy(cfg->tag, s->tag, s->tag_len);
+ memcpy(config, cfg, s->config_size);
+ qemu_free(cfg);
+}
+
+VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
+ {
V9fsState *s;
- int i;
+ int i, len;
+ struct stat stat;
+
s = (V9fsState *)virtio_common_init("virtio-9p",
VIRTIO_ID_9P,
- 0, sizeof(V9fsState));
+ sizeof(struct virtio_9p_config)+
+ MAX_TAG_LEN,
+ sizeof(V9fsState));
/* initialize pdu allocator */
s->free_pdu = &s->pdus[0];
@@ -2069,12 +2040,37 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, const char *path)
s->vq = virtio_add_queue(&s->vdev, MAX_REQ, handle_9p_output);
BUG_ON(s->vq == NULL);
- s->root = strdup("/");
- BUG_ON(s->root == NULL);
+ if (!conf->share_path || !conf->tag) {
+ /* we haven't specified a mount_tag */
+ fprintf(stderr, "Virtio-9p devices need share_path "
+ "and mount_tag arguments\n");
+ exit(1);
+ }
+ if (lstat(conf->share_path, &stat)) {
+ fprintf(stderr, "share path %s does not exist\n", conf->share_path);
+ exit(1);
+ } else if (!S_ISDIR(stat.st_mode)) {
+ fprintf(stderr, "share path %s is not a directory \n", conf->share_path);
+ exit(1);
+ }
+ s->fs_root = strdup(conf->share_path);
+ len = strlen(conf->tag);
+ if (len > MAX_TAG_LEN)
+ len = MAX_TAG_LEN;
+ /* s->tag is non-NULL terminated string */
+ s->tag = qemu_malloc(len);
+ memcpy(s->tag, conf->tag, len);
+ s->tag_len = len;
+ BUG_ON(s->fs_root == NULL);
s->uid = -1;
- s->ops = virtio_9p_init_local(path);
+ s->ops = virtio_9p_init_local(conf->share_path);
s->vdev.get_features = virtio_9p_get_features;
+ s->config_size = sizeof(struct virtio_9p_config) +
+ s->tag_len;
+ s->vdev.get_config = virtio_9p_get_config;
+ s->vdev.set_config = virtio_9p_set_config;
+
return &s->vdev;
}
@@ -6,6 +6,10 @@
#include <sys/time.h>
#include <utime.h>
+/* The feature bitmap for virtio 9P */
+/* The mount point is specified in a config variable */
+#define VIRTIO_9P_MOUNT_TAG 0
+
enum {
P9_TVERSION = 100,
P9_RVERSION,
@@ -66,35 +70,118 @@ struct V9fsPDU
V9fsPDU *next;
};
+/* FIXME
+ * 1) change user needs to set groups and stuff
+ */
+
+/* from Linux's linux/virtio_9p.h */
+
+/* The ID for virtio console */
+#define VIRTIO_ID_9P 9
+#define MAX_REQ 128
+#define MAX_TAG_LEN 32
+
+#define BUG_ON(cond) assert(!(cond))
+
+typedef struct V9fsFidState V9fsFidState;
+
+typedef struct V9fsString
+{
+ int16_t size;
+ char *data;
+} V9fsString;
+
+typedef struct V9fsQID
+{
+ int8_t type;
+ int32_t version;
+ int64_t path;
+} V9fsQID;
+
+typedef struct V9fsStat
+{
+ int16_t size;
+ int16_t type;
+ int32_t dev;
+ V9fsQID qid;
+ int32_t mode;
+ int32_t atime;
+ int32_t mtime;
+ int64_t length;
+ V9fsString name;
+ V9fsString uid;
+ V9fsString gid;
+ V9fsString muid;
+ /* 9p2000.u */
+ V9fsString extension;
+ int32_t n_uid;
+ int32_t n_gid;
+ int32_t n_muid;
+} V9fsStat;
+
+struct V9fsFidState
+{
+ int32_t fid;
+ V9fsString path;
+ int fd;
+ DIR *dir;
+ uid_t uid;
+ V9fsFidState *next;
+};
+
+struct V9fsPosixFileOpertions ;
+typedef struct V9fsState
+{
+ VirtIODevice vdev;
+ VirtQueue *vq;
+ V9fsPDU pdus[MAX_REQ];
+ V9fsPDU *free_pdu;
+ V9fsFidState *fid_list;
+ struct V9fsPosixFileOpertions *ops;
+ char *fs_root;
+ uid_t uid;
+ uint16_t tag_len;
+ uint8_t *tag;
+ size_t config_size;
+} V9fsState;
+
+struct virtio_9p_config
+{
+ /* number of characters in tag */
+ uint16_t tag_len;
+ /* Variable size tag name */
+ uint8_t tag[0];
+} __attribute__((packed));
+
typedef struct V9fsPosixFileOpertions
{
- int (*lstat)(void *, const char *, struct stat *);
- ssize_t (*readlink)(void *, const char *, char *, size_t);
- int (*chmod)(void *, const char *, mode_t);
- int (*chown)(void *, const char *, uid_t, gid_t);
- int (*mknod)(void *, const char *, mode_t, dev_t);
- int (*mksock)(void *, const char *);
- int (*utime)(void *, const char *, const struct utimbuf *);
- int (*remove)(void *, const char *);
- int (*symlink)(void *, const char *, const char *);
- int (*link)(void *, const char *, const char *);
- int (*setuid)(void *, uid_t);
- int (*close)(void *, int);
- int (*closedir)(void *, DIR *);
- DIR *(*opendir)(void *, const char *);
- int (*open)(void *, const char *, int);
- int (*open2)(void *, const char *, int, mode_t);
- void (*rewinddir)(void *, DIR *);
- off_t (*telldir)(void *, DIR *);
- struct dirent *(*readdir)(void *, DIR *);
- void (*seekdir)(void *, DIR *, off_t);
- ssize_t (*readv)(void *, int, const struct iovec *, int);
- ssize_t (*writev)(void *, int, const struct iovec *, int);
- off_t (*lseek)(void *, int, off_t, int);
- int (*mkdir)(void *, const char *, mode_t);
- int (*fstat)(void *, int, struct stat *);
- int (*rename)(void *, const char *, const char *);
- int (*truncate)(void *, const char *, off_t);
+ int (*lstat)(V9fsState *, const char *, struct stat *);
+ ssize_t (*readlink)(V9fsState *, const char *, char *, size_t);
+ int (*chmod)(V9fsState *, const char *, mode_t);
+ int (*chown)(V9fsState *, const char *, uid_t, gid_t);
+ int (*mknod)(V9fsState *, const char *, mode_t, dev_t);
+ int (*mksock)(V9fsState *, const char *);
+ int (*utime)(V9fsState *, const char *, const struct utimbuf *);
+ int (*remove)(V9fsState *, const char *);
+ int (*symlink)(V9fsState *, const char *, const char *);
+ int (*link)(V9fsState *, const char *, const char *);
+ int (*setuid)(V9fsState *, uid_t);
+ int (*close)(V9fsState *, int);
+ int (*closedir)(V9fsState *, DIR *);
+ DIR *(*opendir)(V9fsState *, const char *);
+ int (*open)(V9fsState *, const char *, int);
+ int (*open2)(V9fsState *, const char *, int, mode_t);
+ void (*rewinddir)(V9fsState *, DIR *);
+ off_t (*telldir)(V9fsState *, DIR *);
+ struct dirent *(*readdir)(V9fsState *, DIR *);
+ void (*seekdir)(V9fsState *, DIR *, off_t);
+ ssize_t (*readv)(V9fsState *, int, const struct iovec *, int);
+ ssize_t (*writev)(V9fsState *, int, const struct iovec *, int);
+ off_t (*lseek)(V9fsState *, int, off_t, int);
+ int (*mkdir)(V9fsState *, const char *, mode_t);
+ int (*fstat)(V9fsState *, int, struct stat *);
+ int (*rename)(V9fsState *, const char *, const char *);
+ int (*truncate)(V9fsState *, const char *, off_t);
void *opaque;
} V9fsPosixFileOperations;
@@ -86,7 +86,6 @@
#define wmb() do { } while (0)
/* PCI bindings. */
-
typedef struct {
PCIDevice pci_dev;
VirtIODevice *vdev;
@@ -96,7 +95,7 @@ typedef struct {
BlockConf block;
NICConf nic;
uint32_t host_features;
- char *share_path;
+ V9fsConf fsconf;
/* Max. number of ports we can have for a the virtio-serial device */
uint32_t max_virtserial_ports;
} VirtIOPCIProxy;
@@ -557,7 +556,7 @@ static int virtio_9p_init_pci(PCIDevice *pci_dev)
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
VirtIODevice *vdev;
- vdev = virtio_9p_init(&pci_dev->qdev, proxy->share_path);
+ vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf);
virtio_init_pci(proxy, vdev,
PCI_VENDOR_ID_REDHAT_QUMRANET,
0x1009,
@@ -625,7 +624,8 @@ static PCIDeviceInfo virtio_info[] = {
.init = virtio_9p_init_pci,
.qdev.props = (Property[]) {
DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
- DEFINE_PROP_STRING("share_path", VirtIOPCIProxy, share_path),
+ DEFINE_PROP_STRING("share_path", VirtIOPCIProxy, fsconf.share_path),
+ DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
DEFINE_PROP_END_OF_LIST(),
},
},{
@@ -19,6 +19,7 @@
#include "qdev.h"
#include "sysemu.h"
#include "block_int.h"
+#include "9p.h"
/* from Linux's linux/virtio_config.h */
@@ -174,7 +175,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf);
VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf);
VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports);
VirtIODevice *virtio_balloon_init(DeviceState *dev);
-VirtIODevice *virtio_9p_init(DeviceState *dev, const char *path);
+VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf);
void virtio_net_exit(VirtIODevice *vdev);