[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH -v2 03/22] virtio-9p: Implement P9_TATTACH
From: |
jvrao |
Subject: |
Re: [Qemu-devel] [PATCH -v2 03/22] virtio-9p: Implement P9_TATTACH |
Date: |
Fri, 26 Mar 2010 13:06:58 -0700 |
User-agent: |
Thunderbird 2.0.0.24 (Windows/20100228) |
Anthony Liguori wrote:
> On 03/16/2010 04:15 AM, Aneesh Kumar K.V wrote:
>> From: Anthony Liguori<address@hidden>
>>
>> address@hidden: Added qemu_vasprintf]
>>
>> Signed-off-by: Anthony Liguori<address@hidden>
>> Signed-off-by: Aneesh Kumar K.V<address@hidden>
>> ---
>> Makefile.target | 2 +-
>> hw/virtio-9p-local.c | 84 +++++++++++++++++++++++++++
>> hw/virtio-9p.c | 155
>> +++++++++++++++++++++++++++++++++++++++++++++++---
>> hw/virtio-9p.h | 33 +++++++++++
>> qemu-common.h | 1 +
>> qemu-malloc.c | 5 ++
>> 6 files changed, 270 insertions(+), 10 deletions(-)
>> create mode 100644 hw/virtio-9p-local.c
>>
>> diff --git a/Makefile.target b/Makefile.target
>> index 33f9fcb..97f32a9 100644
>> --- a/Makefile.target
>> +++ b/Makefile.target
>> @@ -172,7 +172,7 @@ obj-y = vl.o async.o monitor.o pci.o pci_host.o
>> pcie_host.o machine.o gdbstub.o
>> # virtio has to be here due to weird dependency between PCI and
>> virtio-net.
>> # need to fix this properly
>> obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-pci.o
>> virtio-serial-bus.o
>> -obj-y += virtio-9p.o virtio-9p-debug.o
>> +obj-y += virtio-9p.o virtio-9p-debug.o virtio-9p-local.o
>> obj-y += rwhandler.o
>> obj-$(CONFIG_KVM) += kvm.o kvm-all.o
>> obj-$(CONFIG_ISA_MMIO) += isa_mmio.o
>> diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c
>> new file mode 100644
>> index 0000000..1d2523b
>> --- /dev/null
>> +++ b/hw/virtio-9p-local.c
>>
>
> This should be a logically separate patch.
>
>> @@ -0,0 +1,84 @@
>> +/*
>> + * Virtio 9p Posix callback
>> + *
>> + * Copyright IBM, Corp. 2010
>> + *
>> + * Authors:
>> + * Anthony Liguori<address@hidden>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2. See
>> + * the COPYING file in the top-level directory.
>> + *
>> + */
>> +#include "virtio.h"
>> +#include "pc.h"
>> +#include "qemu_socket.h"
>> +#include "virtio-9p.h"
>> +#include<sys/uio.h>
>> +#include<arpa/inet.h>
>> +#include<assert.h>
>> +#include<pwd.h>
>> +#include<grp.h>
>> +#include<sys/socket.h>
>> +#include<sys/un.h>
>>
>
> These headers are almost certainly going to break the build on windows.
> Some care is needed here.
I don't think we are going to build this on Windows. Will it be OK if we
make changes to Makefile so that it is valid only on Linux?
Thanks,
JV
>
>> +
>> +static const char *base_path;
>> +
>> +static const char *rpath(const char *path)
>> +{
>> + /* FIXME: so wrong... */
>> + static char buffer[4096];
>> + snprintf(buffer, sizeof(buffer), "%s/%s", base_path, path);
>> + return buffer;
>> +}
>> +
>> +static int local_lstat(void *opaque, const char *path, struct stat
>> *stbuf)
>> +{
>> + return lstat(rpath(path), stbuf);
>> +}
>> +
>> +static int local_setuid(void *opaque, uid_t uid)
>> +{
>> + struct passwd *pw;
>> + gid_t groups[33];
>> + int ngroups;
>> + static uid_t cur_uid = -1;
>> +
>> + if (cur_uid == uid)
>> + return 0;
>> +
>> + if (setreuid(0, 0))
>> + return -1;
>> +
>> + pw = getpwuid(uid);
>> + if (pw == NULL)
>> + return -1;
>> +
>> + ngroups = 33;
>> + if (getgrouplist(pw->pw_name, pw->pw_gid, groups,&ngroups) == -1)
>> + return -1;
>> +
>> + if (setgroups(ngroups, groups))
>> + return -1;
>> +
>> + if (setregid(-1, pw->pw_gid))
>> + return -1;
>> +
>> + if (setreuid(-1, uid))
>> + return -1;
>> +
>> + cur_uid = uid;
>> +
>> + return 0;
>> +}
>> +
>> +static V9fsPosixFileOperations ops = {
>> + .lstat = local_lstat,
>> + .setuid = local_setuid,
>> +};
>> +
>> +V9fsPosixFileOperations *virtio_9p_init_local(const char *path)
>> +{
>> + base_path = path;
>> + return&ops;
>> +}
>> diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
>> index 53b3d78..fdff589 100644
>> --- a/hw/virtio-9p.c
>> +++ b/hw/virtio-9p.c
>> @@ -82,6 +82,7 @@ typedef struct V9fsState
>> V9fsPDU pdus[MAX_REQ];
>> V9fsPDU *free_pdu;
>> V9fsFidState *fid_list;
>> + V9fsPosixFileOperations *ops;
>> char *root;
>> uid_t uid;
>> } V9fsState;
>> @@ -91,6 +92,123 @@ int debug_9p_pdu = 1;
>>
>> 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);
>> +}
>> +
>> +static int posix_setuid(V9fsState *s, uid_t uid)
>> +{
>> + return s->ops->setuid(s->ops->opaque, uid);
>> +}
>> +
>> +static void v9fs_string_free(V9fsString *str)
>> +{
>> + qemu_free(str->data);
>> + str->data = NULL;
>> + str->size = 0;
>> +}
>> +
>> +static void v9fs_string_sprintf(V9fsString *str, const char *fmt, ...)
>> +{
>> + va_list ap;
>> + int err;
>> +
>> + v9fs_string_free(str);
>> +
>> + va_start(ap, fmt);
>> + err = qemu_vasprintf(&str->data, fmt, ap);
>> + BUG_ON(err == -1);
>> + va_end(ap);
>> +
>> + str->size = err;
>> +}
>> +
>> +static V9fsFidState *lookup_fid(V9fsState *s, int32_t fid)
>> +{
>> + V9fsFidState *f;
>> +
>> + for (f = s->fid_list; f; f = f->next) {
>> + if (f->fid == fid) {
>> + posix_setuid(s, f->uid);
>> + return f;
>> + }
>> + }
>> +
>> + return NULL;
>> +}
>> +
>> +static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid)
>> +{
>> + V9fsFidState *f;
>> +
>> + f = lookup_fid(s, fid);
>> + if (f)
>> + return NULL;
>> +
>> + f = qemu_mallocz(sizeof(V9fsFidState));
>> + BUG_ON(f == NULL);
>> +
>> + f->fid = fid;
>> + f->fd = -1;
>> + f->dir = NULL;
>> +
>> + f->next = s->fid_list;
>> + s->fid_list = f;
>> +
>> + return f;
>> +}
>> +
>> +#define P9_QID_TYPE_DIR 0x80
>> +#define P9_QID_TYPE_SYMLINK 0x02
>> +
>> +#define P9_STAT_MODE_DIR 0x80000000
>> +#define P9_STAT_MODE_APPEND 0x40000000
>> +#define P9_STAT_MODE_EXCL 0x20000000
>> +#define P9_STAT_MODE_MOUNT 0x10000000
>> +#define P9_STAT_MODE_AUTH 0x08000000
>> +#define P9_STAT_MODE_TMP 0x04000000
>> +#define P9_STAT_MODE_SYMLINK 0x02000000
>> +#define P9_STAT_MODE_LINK 0x01000000
>> +#define P9_STAT_MODE_DEVICE 0x00800000
>> +#define P9_STAT_MODE_NAMED_PIPE 0x00200000
>> +#define P9_STAT_MODE_SOCKET 0x00100000
>> +#define P9_STAT_MODE_SETUID 0x00080000
>> +#define P9_STAT_MODE_SETGID 0x00040000
>> +#define P9_STAT_MODE_SETVTX 0x00010000
>> +
>> +#define P9_STAT_MODE_SPECIAL (P9_STAT_MODE_NAMED_PIPE | \
>> + P9_STAT_MODE_SYMLINK | \
>> + P9_STAT_MODE_LINK | \
>> + P9_STAT_MODE_DEVICE)
>> +
>> +
>> +/* This is the algorithm from ufs in spfs */
>> +static void stat_to_qid(const struct stat *stbuf, V9fsQID *qidp)
>> +{
>> + size_t size;
>> +
>> + size = MIN(sizeof(stbuf->st_ino), sizeof(qidp->path));
>> + memcpy(&qidp->path,&stbuf->st_ino, size);
>> + qidp->version = stbuf->st_mtime ^ (stbuf->st_size<< 8);
>> + qidp->type = 0;
>> + if (S_ISDIR(stbuf->st_mode))
>> + qidp->type |= P9_QID_TYPE_DIR;
>> + if (S_ISLNK(stbuf->st_mode))
>> + qidp->type |= P9_QID_TYPE_SYMLINK;
>> +}
>> +
>> +static void fid_to_qid(V9fsState *s, V9fsFidState *fidp, V9fsQID *qidp)
>> +{
>> + struct stat stbuf;
>> + int err;
>> +
>> + err = posix_lstat(s,&fidp->path,&stbuf);
>> + BUG_ON(err == -1);
>> +
>> + stat_to_qid(&stbuf, qidp);
>> +}
>> +
>> static V9fsPDU *alloc_pdu(V9fsState *s)
>> {
>> V9fsPDU *pdu = NULL;
>> @@ -111,13 +229,6 @@ static void free_pdu(V9fsState *s, V9fsPDU *pdu)
>> }
>> }
>>
>> -static void v9fs_string_free(V9fsString *str)
>> -{
>> - free(str->data);
>> - str->data = NULL;
>> - str->size = 0;
>> -}
>> -
>> static size_t pdu_unpack(void *dst, V9fsPDU *pdu, size_t offset,
>> size_t size)
>> {
>> struct iovec *sg = pdu->elem.out_sg;
>> @@ -378,8 +489,33 @@ static void v9fs_version(V9fsState *s, V9fsPDU *pdu)
>>
>> static void v9fs_attach(V9fsState *s, V9fsPDU *pdu)
>> {
>> - if (debug_9p_pdu)
>> - pprint_pdu(pdu);
>> + int32_t fid, afid, n_uname;
>> + V9fsString uname, aname;
>> + V9fsFidState *fidp;
>> + V9fsQID qid;
>> + size_t offset = 7;
>> + ssize_t err;
>> +
>> + pdu_unmarshal(pdu, offset,
>> "ddssd",&fid,&afid,&uname,&aname,&n_uname);
>> +
>> + fidp = alloc_fid(s, fid);
>> + if (fidp == NULL) {
>> + err = -EINVAL;
>> + goto out;
>> + }
>> +
>> + fidp->uid = n_uname;
>> +
>> + v9fs_string_sprintf(&fidp->path, "%s", s->root);
>> + fid_to_qid(s, fidp,&qid);
>> +
>> + offset += pdu_marshal(pdu, offset, "Q",&qid);
>> +
>> + err = offset;
>> +out:
>> + complete_pdu(s, pdu, err);
>> + v9fs_string_free(&uname);
>> + v9fs_string_free(&aname);
>> }
>>
>> static void v9fs_stat(V9fsState *s, V9fsPDU *pdu)
>> @@ -528,6 +664,7 @@ VirtIODevice *virtio_9p_init(DeviceState *dev,
>> const char *path)
>> BUG_ON(s->root == NULL);
>> s->uid = -1;
>>
>> + s->ops = virtio_9p_init_local(path);
>> s->vdev.get_features = virtio_9p_get_features;
>>
>> return&s->vdev;
>> diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
>> index 2aa67d0..8e15bf0 100644
>> --- a/hw/virtio-9p.h
>> +++ b/hw/virtio-9p.h
>> @@ -66,5 +66,38 @@ struct V9fsPDU
>> V9fsPDU *next;
>> };
>>
>> +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);
>> + void *opaque;
>> +} V9fsPosixFileOperations;
>> +
>> +V9fsPosixFileOperations *virtio_9p_init_local(const char *path);
>>
>> #endif
>> diff --git a/qemu-common.h b/qemu-common.h
>> index 805be1a..ebe7088 100644
>> --- a/qemu-common.h
>> +++ b/qemu-common.h
>> @@ -159,6 +159,7 @@ void *qemu_mallocz(size_t size);
>> void qemu_free(void *ptr);
>> char *qemu_strdup(const char *str);
>> char *qemu_strndup(const char *str, size_t size);
>> +int qemu_vasprintf(char **strp, const char *fmt, va_list ap);
>>
>> void *get_mmap_addr(unsigned long size);
>>
>> diff --git a/qemu-malloc.c b/qemu-malloc.c
>> index 6cdc5de..d6de067 100644
>> --- a/qemu-malloc.c
>> +++ b/qemu-malloc.c
>> @@ -98,3 +98,8 @@ char *qemu_strndup(const char *str, size_t size)
>>
>> return memcpy(new, str, size);
>> }
>> +
>> +int qemu_vasprintf(char **strp, const char *fmt, va_list ap)
>> +{
>> + return vasprintf(strp, fmt, ap);
>> +}
>>
>
> asprintf() is not universally available so it cannot be wrapped this
> naively.
>
> Regards,
>
> Anthony Liguori
>
>
>
- [Qemu-devel] [PATCH -V2 00/22] virtio-9p: paravirtual file system passthrough, Aneesh Kumar K.V, 2010/03/16
- [Qemu-devel] [PATCH -v2 01/22] vitio-9p: Add a virtio 9p device to qemu, Aneesh Kumar K.V, 2010/03/16
- [Qemu-devel] [PATCH -v2 03/22] virtio-9p: Implement P9_TATTACH, Aneesh Kumar K.V, 2010/03/16
- [Qemu-devel] [PATCH -v2 04/22] virtio-9p: Implement P9_TSTAT, Aneesh Kumar K.V, 2010/03/16
- [Qemu-devel] [PATCH -v2 08/22] virtio-9p: Implement P9_TCLUNK, Aneesh Kumar K.V, 2010/03/16
- [Qemu-devel] [PATCH -v2 05/22] virtio-9p: Implement P9_TWALK, Aneesh Kumar K.V, 2010/03/16
- [Qemu-devel] [PATCH -v2 09/22] virtio-9p: Implement P9_TWRITE, Aneesh Kumar K.V, 2010/03/16
- [Qemu-devel] [PATCH -v2 06/22] virtio-9p: Implement P9_TOPEN, Aneesh Kumar K.V, 2010/03/16
- [Qemu-devel] [PATCH -v2 07/22] virtio-9p: Implement P9_TREAD, Aneesh Kumar K.V, 2010/03/16
- [Qemu-devel] [PATCH -v2 11/22] virtio-9p: Implement P9_TWSTAT, Aneesh Kumar K.V, 2010/03/16
- [Qemu-devel] [PATCH -v2 14/22] virtio-9p: Add multiple mount point support, Aneesh Kumar K.V, 2010/03/16
- [Qemu-devel] [PATCH -v2 18/22] virtio-9p: Fix sg usage in the code, Aneesh Kumar K.V, 2010/03/16
- [Qemu-devel] [PATCH -v2 12/22] virtio-9p: Implement P9_TREMOVE, Aneesh Kumar K.V, 2010/03/16