* [PATCH][RFC] vmchannel a data channel between host and guest.
@ 2008-10-12 12:45 Gleb Natapov
2008-10-13 18:32 ` Anthony Liguori
0 siblings, 1 reply; 16+ messages in thread
From: Gleb Natapov @ 2008-10-12 12:45 UTC (permalink / raw)
To: kvm; +Cc: Anthony Liguori, Rusty Russell
[-- Attachment #1: Type: text/plain, Size: 621 bytes --]
Hello,
Sometimes there is a need to pass various bits of information between host
and guest (mostly for management purposes such as host screen resolution
changes or runtime statistics of a guest). To do that we need some way to
pass data between host and guest. Attached patch implements vmchannel that can
be used for this purpose. It is based on virtio infrastructure and
support more then one channel. The vmchannel presents itself as PCI
device to a guest so guest driver is also required. The one for linux is
attached. It uses netlink connector to communicate with userspace.
Comments are welcome.
--
Gleb.
[-- Attachment #2: vmchannel.diff --]
[-- Type: text/x-diff, Size: 11829 bytes --]
diff --git a/qemu/Makefile.target b/qemu/Makefile.target
index 5462092..6cf13f7 100644
--- a/qemu/Makefile.target
+++ b/qemu/Makefile.target
@@ -612,7 +612,7 @@ OBJS += rtl8139.o
OBJS += e1000.o
# virtio devices
-OBJS += virtio.o virtio-net.o virtio-blk.o virtio-balloon.o
+OBJS += virtio.o virtio-net.o virtio-blk.o virtio-balloon.o virtio-vmchannel.o
OBJS += device-hotplug.o
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index 1d42aa7..e8c5531 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -1141,6 +1141,7 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
drives_table[index].bdrv);
unit_id++;
}
+ virtio_vmchannel_init(pci_bus);
}
if (extboot_drive != -1) {
diff --git a/qemu/hw/virtio-vmchannel.c b/qemu/hw/virtio-vmchannel.c
new file mode 100644
index 0000000..1ce76ec
--- /dev/null
+++ b/qemu/hw/virtio-vmchannel.c
@@ -0,0 +1,239 @@
+/*
+ * Virtio VMChannel Device
+ *
+ * Copyright RedHat, inc. 2008
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "sysemu.h"
+#include "virtio.h"
+#include "pc.h"
+#include "qemu-kvm.h"
+#include "qemu-char.h"
+#include "virtio-vmchannel.h"
+
+#define DEBUG_VMCHANNEL
+
+#ifdef DEBUG_VMCHANNEL
+#define VMCHANNEL_DPRINTF(fmt, args...) \
+ do { printf("VMCHANNEL: " fmt , ##args); } while (0)
+#else
+#define VMCHANNEL_DPRINTF(fmt, args...)
+#endif
+
+typedef struct VirtIOVMChannel {
+ VirtIODevice vdev;
+ VirtQueue *sq;
+ VirtQueue *rq;
+} VirtIOVMChannel;
+
+typedef struct VMChannel {
+ CharDriverState *hd;
+ VirtQueueElement elem;
+ uint32_t id;
+ size_t len;
+} VMChannel;
+
+typedef struct VMChannelDesc {
+ uint32_t id;
+ uint32_t len;
+} VMChannelDesc;
+
+typedef struct VMChannelCfg {
+ uint32_t count;
+ uint32_t ids[MAX_VMCHANNEL_DEVICES];
+} VMChannelCfg;
+
+static VirtIOVMChannel *vmchannel;
+
+static VMChannel vmchannel_descs[MAX_VMCHANNEL_DEVICES];
+static int vmchannel_desc_idx;
+
+static int vmchannel_can_read(void *opaque)
+{
+ VMChannel *c = opaque;
+
+ /* device not yet configured */
+ if (vmchannel->rq->vring.avail == NULL)
+ return 0;
+
+ if (!c->len) {
+ int i;
+
+ if (virtqueue_pop(vmchannel->rq, &c->elem) == 0)
+ return 0;
+
+ if (c->elem.in_num < 1 ||
+ c->elem.in_sg[0].iov_len < sizeof(VMChannelDesc)) {
+ fprintf(stderr, "vmchannel: wrong receive descriptor\n");
+ return 0;
+ }
+
+ for (i = 0; i < c->elem.in_num; i++)
+ c->len += c->elem.in_sg[i].iov_len;
+
+ c->len -= sizeof(VMChannelDesc);
+ }
+
+ return (int)c->len;
+}
+
+static void vmchannel_read(void *opaque, const uint8_t *buf, int size)
+{
+ VMChannel *c = opaque;
+ VMChannelDesc *desc;
+ int i;
+
+ VMCHANNEL_DPRINTF("read %d bytes from channel %d\n", size, c->id);
+
+ if (!c->len) {
+ fprintf(stderr, "vmchannel: trying to receive into empty descriptor\n");
+ exit(1);
+ }
+
+ if (size <= 0 || size > c->len) {
+ fprintf(stderr, "vmchannel: read size is wrong\n");
+ exit(1);
+ }
+
+ desc = (VMChannelDesc*)c->elem.in_sg[0].iov_base;
+ desc->id = c->id;
+ desc->len = size;
+
+ c->elem.in_sg[0].iov_base = desc + 1;
+ c->elem.in_sg[0].iov_len -= sizeof(VMChannelDesc);
+
+ for (i = 0; i < c->elem.in_num && size; i++) {
+ struct iovec *iov = &c->elem.in_sg[i];
+ size_t len;
+
+ len = MIN(size, iov->iov_len);
+ memcpy(iov->iov_base, buf, len);
+ size -= len;
+ buf += len;
+ }
+
+ if (size) {
+ fprintf(stderr, "vmchannel: dropping %d bytes of data\n", size);
+ exit(1);
+ }
+
+ virtqueue_push(vmchannel->rq, &c->elem, desc->len);
+ c->len = 0;
+ virtio_notify(&vmchannel->vdev, vmchannel->rq);
+}
+
+static void virtio_vmchannel_handle_recv(VirtIODevice *vdev, VirtQueue *outputq)
+{
+ if (kvm_enabled())
+ qemu_kvm_notify_work();
+}
+
+static VMChannel *vmchannel_lookup(uint32_t id)
+{
+ int i;
+
+ for (i = 0; i < vmchannel_desc_idx; i++) {
+ if (vmchannel_descs[i].id == id)
+ return &vmchannel_descs[i];
+ }
+ return NULL;
+}
+
+static void virtio_vmchannel_handle_send(VirtIODevice *vdev, VirtQueue *outputq)
+{
+ VirtQueueElement elem;
+
+ VMCHANNEL_DPRINTF("send\n");
+ while (virtqueue_pop(vmchannel->sq, &elem)) {
+ VMChannelDesc *desc;
+ VMChannel *c;
+ unsigned int len = 0;
+ int i;
+
+ if (elem.out_num < 1 ||
+ elem.out_sg[0].iov_len < sizeof(VMChannelDesc)) {
+ fprintf(stderr, "vmchannel: incorrect send descriptor\n");
+ virtqueue_push(vmchannel->sq, &elem, 0);
+ return;
+ }
+
+ desc = (VMChannelDesc*)elem.out_sg[0].iov_base;
+ c = vmchannel_lookup(desc->id);
+
+ if(!c) {
+ fprintf(stderr, "vmchannel: guest sends to nonexistent channel\n");
+ virtqueue_push(vmchannel->sq, &elem, 0);
+ return;
+ }
+
+ VMCHANNEL_DPRINTF("send to channel %d %d bytes\n", c->id, desc->len);
+
+ elem.out_sg[0].iov_base = desc + 1;
+ elem.out_sg[0].iov_len -= sizeof(VMChannelDesc);
+
+ for (i = 0; i < elem.out_num; i++) {
+ struct iovec *iov = &elem.out_sg[i];
+
+ qemu_chr_write(c->hd, iov->iov_base, iov->iov_len);
+ len += iov->iov_len;
+ }
+
+ if (desc->len != len)
+ fprintf(stderr, "vmchannel: bad descriptor was sent by guest\n");
+
+ virtqueue_push(vmchannel->sq, &elem, len);
+ }
+
+ virtio_notify(&vmchannel->vdev, vmchannel->sq);
+}
+
+static uint32_t virtio_vmchannel_get_features(VirtIODevice *vdev)
+{
+ return 0;
+}
+
+static void virtio_vmchannel_update_config(VirtIODevice *vdev, uint8_t *config)
+{
+ VMChannelCfg *cfg = (VMChannelCfg *)config, *s = NULL;
+ int i;
+
+ printf("get_conf: %d %d\n", &s->count, &s->ids);
+ cfg->count = vmchannel_desc_idx;
+ for (i = 0; i < vmchannel_desc_idx; i++)
+ cfg->ids[i] = vmchannel_descs[i].id;
+}
+
+void virtio_vmchannel_init(PCIBus *bus)
+{
+
+ if (!vmchannel_desc_idx)
+ return;
+
+ vmchannel = (VirtIOVMChannel *)virtio_init_pci(bus, "virtio-vmchannel",
+ 0x1af4, 0x1003, 0, VIRTIO_ID_VMCHANNEL, 0x5, 0x0, 0x0,
+ sizeof(VMChannelCfg), sizeof(VirtIOVMChannel));
+
+ vmchannel->vdev.get_features = virtio_vmchannel_get_features;
+ vmchannel->vdev.get_config = virtio_vmchannel_update_config;
+
+ vmchannel->rq = virtio_add_queue(&vmchannel->vdev, 128,
+ virtio_vmchannel_handle_recv);
+ vmchannel->sq = virtio_add_queue(&vmchannel->vdev, 128,
+ virtio_vmchannel_handle_send);
+
+ return;
+}
+
+void vmchannel_init(CharDriverState *hd, uint32_t deviceid)
+{
+ VMChannel *c = &vmchannel_descs[vmchannel_desc_idx++];
+
+ c->hd = hd;
+ c->id = deviceid;
+ qemu_chr_add_handlers(hd, vmchannel_can_read, vmchannel_read, NULL, c);
+}
diff --git a/qemu/hw/virtio-vmchannel.h b/qemu/hw/virtio-vmchannel.h
new file mode 100644
index 0000000..bb9e6b6
--- /dev/null
+++ b/qemu/hw/virtio-vmchannel.h
@@ -0,0 +1,16 @@
+/*
+ * Virtio VMChannel Device
+ *
+ * Copyright RedHat, inc. 2008
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef VIRTIO_VMCHANNEL_H
+#define VIRTIO_VMCHANNEL_H
+
+#define VIRTIO_ID_VMCHANNEL 6
+
+#endif
diff --git a/qemu/sysemu.h b/qemu/sysemu.h
index b9abf99..192f8e1 100644
--- a/qemu/sysemu.h
+++ b/qemu/sysemu.h
@@ -189,6 +189,10 @@ extern CharDriverState *serial_hds[MAX_SERIAL_PORTS];
extern CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
+#define MAX_VMCHANNEL_DEVICES 4
+void virtio_vmchannel_init(PCIBus *bus);
+void vmchannel_init(CharDriverState *hd, uint32_t deviceid);
+
#ifdef NEED_CPU_H
/* loader.c */
int get_image_size(const char *filename);
diff --git a/qemu/vl.c b/qemu/vl.c
index 36e3bb7..b19fb88 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -210,6 +210,7 @@ int graphic_depth = 15;
static int full_screen = 0;
static int no_frame = 0;
int no_quit = 0;
+CharDriverState *vmchannel_hds[MAX_VMCHANNEL_DEVICES];
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
#ifdef TARGET_I386
@@ -8584,6 +8585,7 @@ static void help(int exitcode)
"-monitor dev redirect the monitor to char device 'dev'\n"
"-serial dev redirect the serial port to char device 'dev'\n"
"-parallel dev redirect the parallel port to char device 'dev'\n"
+ "-vmchannel di:DI,dev redirect the vmchannel device with device id DI, to char device 'dev'\n"
"-pidfile file Write PID to 'file'\n"
"-S freeze CPU at startup (use 'c' to start execution)\n"
"-s wait gdb connection to port\n"
@@ -8703,6 +8705,7 @@ enum {
QEMU_OPTION_monitor,
QEMU_OPTION_serial,
QEMU_OPTION_parallel,
+ QEMU_OPTION_vmchannel,
QEMU_OPTION_loadvm,
QEMU_OPTION_full_screen,
QEMU_OPTION_no_frame,
@@ -8820,6 +8823,7 @@ static const QEMUOption qemu_options[] = {
{ "monitor", HAS_ARG, QEMU_OPTION_monitor },
{ "serial", HAS_ARG, QEMU_OPTION_serial },
{ "parallel", HAS_ARG, QEMU_OPTION_parallel },
+ { "vmchannel", 1, QEMU_OPTION_vmchannel },
{ "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
{ "incoming", 1, QEMU_OPTION_incoming },
{ "full-screen", 0, QEMU_OPTION_full_screen },
@@ -9247,6 +9251,8 @@ int main(int argc, char **argv)
int serial_device_index;
const char *parallel_devices[MAX_PARALLEL_PORTS];
int parallel_device_index;
+ const char *vmchannel_devices[MAX_VMCHANNEL_DEVICES];
+ int vmchannel_device_index;
const char *loadvm = NULL;
QEMUMachine *machine;
const char *cpu_model;
@@ -9320,6 +9326,10 @@ int main(int argc, char **argv)
parallel_devices[i] = NULL;
parallel_device_index = 0;
+ for(i = 0; i < MAX_VMCHANNEL_DEVICES; i++)
+ vmchannel_devices[i] = NULL;
+ vmchannel_device_index = 0;
+
usb_devices_index = 0;
nb_net_clients = 0;
@@ -9706,6 +9716,12 @@ int main(int argc, char **argv)
parallel_devices[parallel_device_index] = optarg;
parallel_device_index++;
break;
+ case QEMU_OPTION_vmchannel:
+ if (vmchannel_device_index >= MAX_VMCHANNEL_DEVICES) {
+ fprintf(stderr, "qemu: too many vmchannel devices\n");
+ exit(1);
+ }
+ vmchannel_devices[vmchannel_device_index++] = optarg;
case QEMU_OPTION_loadvm:
loadvm = optarg;
break;
@@ -10232,6 +10248,29 @@ int main(int argc, char **argv)
if (kvm_enabled())
kvm_init_ap();
+ for(i = 0; i < vmchannel_device_index; i++) {
+ const char *devname = vmchannel_devices[i];
+ int devid;
+ char *di;
+ if (!devname)
+ continue;
+
+ if (strstart(devname, "di:", (const char**)&di)) {
+ devid = strtol(di, &di, 16);
+ di++;
+ } else {
+ fprintf(stderr, "qemu: could not find vmchannel device id in "
+ "'%s'\n", devname);
+ exit(1);
+ }
+ vmchannel_hds[i] = qemu_chr_open(di);
+ if (!vmchannel_hds[i]) {
+ fprintf(stderr, "qemu: could not open vmchannel device '%s'\n", di);
+ exit(1);
+ }
+ vmchannel_init(vmchannel_hds[i], devid);
+ }
+
machine->init(ram_size, vga_ram_size, boot_devices, ds,
kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
[-- Attachment #3: Makefile --]
[-- Type: text/plain, Size: 215 bytes --]
ifneq (${KERNELRELEASE},)
obj-m += vmchannel.o
else
KERNEL_SOURCE := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C ${KERNEL_SOURCE} SUBDIRS=$(PWD) modules
clean :
rm *.o *.ko
endif
[-- Attachment #4: vmchannel.c --]
[-- Type: text/x-csrc, Size: 6471 bytes --]
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/connector.h>
#include <linux/virtio.h>
#include <linux/scatterlist.h>
#include <linux/virtio_config.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include "vmchannel.h"
#define VMCHANNEL_DEBUG
#ifdef VMCHANNEL_DEBUG
#define vmc_print(A, B...) do { \
if(vmchannel.vdev) \
dev_printk(A, &vmchannel.vdev->dev, B); \
else \
printk(A "vmchannel: " B); \
}while (0)
#else
#define vmc_print() do {} while(0)
#endif
#define VMCHANNEL_CONNECTOR_IDX 10
#define MAX_PACKET_LEN 1024
struct vmchannel_info
{
struct virtio_device *vdev;
struct virtqueue *rq;
struct virtqueue *sq;
struct tasklet_struct tasklet;
__u16 channel_count;
__u32 *channel_ids;
__u32 seq;
};
struct vmchannel_desc
{
__u32 id;
__u32 len;
};
struct vmchannel_hdr
{
struct vmchannel_desc desc;
struct cn_msg msg;
};
static struct vmchannel_info vmchannel;
static int add_recq_buf(struct vmchannel_info *vmc, struct vmchannel_hdr *hdr)
{
struct scatterlist sg[2];
sg_init_table(sg, 2);
sg_init_one(&sg[0], hdr, sizeof(struct vmchannel_desc));
sg_init_one(&sg[1], hdr->msg.data, MAX_PACKET_LEN);
if (!vmc->rq->vq_ops->add_buf(vmc->rq, sg, 0, 2, hdr))
return 1;
kfree(hdr);
return 0;
}
static int try_fill_recvq(struct vmchannel_info *vmc)
{
int num = 0;
for (;;) {
struct vmchannel_hdr *hdr;
hdr = kmalloc(sizeof(*hdr) + MAX_PACKET_LEN, GFP_KERNEL);
if (unlikely(!hdr))
break;
if(!add_recq_buf(vmc, hdr))
break;
num++;
}
if (num)
vmc->rq->vq_ops->kick(vmc->rq);
return num;
}
static void vmchannel_recv(unsigned long data)
{
struct vmchannel_info *vmc = (struct vmchannel_info *)data;
struct vmchannel_hdr *hdr;
unsigned int len;
int posted = 0;
vmc_print(KERN_WARNING, "vmchannel_recv\n");
while ((hdr = vmc->rq->vq_ops->get_buf(vmc->rq, &len))) {
int rc;
if (hdr->desc.len == len) {
hdr->msg.id.idx = VMCHANNEL_CONNECTOR_IDX;
hdr->msg.id.val = hdr->desc.id;
hdr->msg.seq = vmc->seq++;
hdr->msg.len = len;
hdr->msg.ack = random32();
rc = cn_netlink_send(&hdr->msg, VMCHANNEL_CONNECTOR_IDX,
GFP_ATOMIC);
if (rc < 0)
vmc_print(KERN_ERR, "Failed to send netlink message\n");
} else
vmc_print(KERN_ERR, "wrong length in descriptor (%d instead of %d)\n", hdr->desc.len, len);
posted += add_recq_buf(vmc, hdr);
}
if (posted)
vmc->rq->vq_ops->kick(vmc->rq);
}
static void recvq_notify(struct virtqueue *recvq)
{
struct vmchannel_info *vmc = recvq->vdev->priv;
vmc_print(KERN_WARNING, "recvq_notify\n");
tasklet_schedule(&vmc->tasklet);
}
static void cleanup_sendq(struct vmchannel_info *vmc)
{
char *buf;
unsigned int len;
while ((buf = vmc->sq->vq_ops->get_buf(vmc->sq, &len)))
kfree(buf);
}
static void sendq_notify(struct virtqueue *sendq)
{
struct vmchannel_info *vmc = sendq->vdev->priv;
vmc_print(KERN_WARNING, "sendq_notify\n");
cleanup_sendq(vmc);
}
static void vmchannel_cn_callback(void *data)
{
struct vmchannel_desc *desc;
struct cn_msg *msg = data;
struct scatterlist sg;
char *buf;
int err;
vmc_print(KERN_WARNING, "cn_callback\n");
desc = kmalloc(msg->len + sizeof(*desc), GFP_KERNEL);
if (!desc)
return;
desc->id = msg->id.val;
desc->len = msg->len;
buf = (char*)(desc + 1);
memcpy(buf, msg->data, msg->len);
sg_init_one(&sg, desc, msg->len + sizeof(*desc));
err = vmchannel.sq->vq_ops->add_buf(vmchannel.sq, &sg, 1, 0, desc);
if (err) {
vmc_print(KERN_ERR, "No space in a send queue\n");
kfree(desc);
} else
vmchannel.sq->vq_ops->kick(vmchannel.sq);
}
static int vmchannel_probe(struct virtio_device *vdev)
{
struct vmchannel_info *vmc = &vmchannel;
struct cb_id cn_id;
int r, i;
__u32 count;
cn_id.idx = VMCHANNEL_CONNECTOR_IDX;
vdev->priv = vmc;
vmc->vdev = vdev;
vmc_print(KERN_WARNING, "probe\n");
vdev->config->get(vdev, 0, &count, sizeof(count));
if (count == 0) {
vmc_print(KERN_ERR, "no channels present\n");
return -ENODEV;
}
vmc_print(KERN_WARNING, "%d channel detected\n", count);
vmc->channel_count = count;
vmc->channel_ids = kmalloc(count * 4, GFP_KERNEL);
if (!vmc->channel_ids)
return -ENOMEM;
vdev->config->get(vdev, sizeof(count), vmc->channel_ids, count * 4);
vmc->rq = vdev->config->find_vq(vdev, 0, recvq_notify);
if (IS_ERR(vmc->rq)) {
r = PTR_ERR(vmc->rq);
goto out;
}
vmc->sq = vdev->config->find_vq(vdev, 1, sendq_notify);
if (IS_ERR(vmc->sq)) {
r = PTR_ERR(vmc->sq);
goto out;
}
for (i = 0; i < vmc->channel_count; i++) {
cn_id.val = vmc->channel_ids[i];
vmc_print(KERN_WARNING, "add callback for channel %d\n", cn_id.val);
r = cn_add_callback(&cn_id, "vmchannel", vmchannel_cn_callback);
if (r)
goto cn_unreg;
}
tasklet_init(&vmc->tasklet, vmchannel_recv, (unsigned long)vmc);
if(!try_fill_recvq(vmc)) {
r = -ENOMEM;
goto kill_task;
}
return 0;
kill_task:
tasklet_kill(&vmc->tasklet);
cn_unreg:
for (i = 0; i < vmc->channel_count; i++) {
cn_id.val = vmc->channel_ids[i];
cn_del_callback(&cn_id);
}
out:
if (vmc->sq) vdev->config->del_vq(vmc->sq);
if (vmc->rq) vdev->config->del_vq(vmc->rq);
if (vmc) kfree(vmc);
return r;
}
static void vmchannel_remove(struct virtio_device *vdev)
{
struct vmchannel_info *vmc = vdev->priv;
struct cb_id cn_id;
int i;
vmc_print(KERN_WARNING, "remove\n");
/* Stop all the virtqueues. */
vdev->config->reset(vdev);
tasklet_kill(&vmc->tasklet);
cn_id.idx = VMCHANNEL_CONNECTOR_IDX;
for (i = 0; i < vmc->channel_count; i++) {
cn_id.val = vmc->channel_ids[i];
cn_del_callback(&cn_id);
}
vdev->config->del_vq(vmc->rq);
vdev->config->del_vq(vmc->sq);
}
static struct virtio_device_id id_table[] = {
{ VIRTIO_ID_VMCHANNEL, VIRTIO_DEV_ANY_ID }, { 0 },
};
static struct virtio_driver virtio_vmchannel = {
.driver.name = "virtio-vmchannel",
.driver.owner = THIS_MODULE,
.id_table = id_table,
.probe = vmchannel_probe,
.remove = __devexit_p(vmchannel_remove),
};
static int __init init(void)
{
vmc_print(KERN_WARNING, "init\n");
return register_virtio_driver(&virtio_vmchannel);
}
static void __exit fini(void)
{
vmc_print(KERN_WARNING, "fini\n");
unregister_virtio_driver(&virtio_vmchannel);
}
module_init(init);
module_exit(fini);
MODULE_DEVICE_TABLE(virtio, id_table);
MODULE_DESCRIPTION("Virtio vmchannel driver");
MODULE_LICENSE("GPL");
[-- Attachment #5: vmchannel.h --]
[-- Type: text/x-chdr, Size: 110 bytes --]
#ifndef VMCHANNEL_H
#define VMCHANNEL_H
#define VIRTIO_ID_VMCHANNEL 6
#define VMCHANNEL_CHANNELS 32
#endif
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-12 12:45 [PATCH][RFC] vmchannel a data channel between host and guest Gleb Natapov
@ 2008-10-13 18:32 ` Anthony Liguori
2008-10-14 9:05 ` Gleb Natapov
0 siblings, 1 reply; 16+ messages in thread
From: Anthony Liguori @ 2008-10-13 18:32 UTC (permalink / raw)
To: Gleb Natapov; +Cc: kvm, Anthony Liguori, Rusty Russell
Gleb Natapov wrote:
> Hello,
>
> Sometimes there is a need to pass various bits of information between host
> and guest (mostly for management purposes such as host screen resolution
> changes or runtime statistics of a guest). To do that we need some way to
> pass data between host and guest. Attached patch implements vmchannel that can
> be used for this purpose. It is based on virtio infrastructure and
> support more then one channel. The vmchannel presents itself as PCI
> device to a guest so guest driver is also required. The one for linux is
> attached. It uses netlink connector to communicate with userspace.
>
Essentially, the transport itself ends up looking very much like a
network device so the only real design question is what the guest and
host interfaces look like. I don't know that a netlink interface is the
best interface to userspace. Why not a full blown socket? Perhaps a
virtual file system?
Having a limit of only 4 links seems like a problem to me too.
I think there needs to be a better articulation about why other
interfaces cannot be used (like a network device). Is it because of
ease of guest configuration? Is it performance?
Regards,
Anthony Liguori
> Comments are welcome.
>
> --
> Gleb.
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-13 18:32 ` Anthony Liguori
@ 2008-10-14 9:05 ` Gleb Natapov
2008-10-14 13:50 ` Anthony Liguori
0 siblings, 1 reply; 16+ messages in thread
From: Gleb Natapov @ 2008-10-14 9:05 UTC (permalink / raw)
To: Anthony Liguori; +Cc: kvm, Anthony Liguori, Rusty Russell
On Mon, Oct 13, 2008 at 01:32:35PM -0500, Anthony Liguori wrote:
> Gleb Natapov wrote:
>> Hello,
>>
>> Sometimes there is a need to pass various bits of information between host
>> and guest (mostly for management purposes such as host screen resolution
>> changes or runtime statistics of a guest). To do that we need some way to
>> pass data between host and guest. Attached patch implements vmchannel that can
>> be used for this purpose. It is based on virtio infrastructure and
>> support more then one channel. The vmchannel presents itself as PCI
>> device to a guest so guest driver is also required. The one for linux is
>> attached. It uses netlink connector to communicate with userspace.
>>
>
> Essentially, the transport itself ends up looking very much like a
> network device so the only real design question is what the guest and
> host interfaces look like. I don't know that a netlink interface is the
> best interface to userspace. Why not a full blown socket? Perhaps a
> virtual file system?
>
netlink was designed to be interface to userspace and is used like this
by different subsystems (not just network). What full blown socket (and
by that I presume you mean new address family) will give you over netlink?
File system? We need a simple stream semantics is this justify another
virtual file system? The choice was between char device and netlink.
Nelink was simpler and gives broadcast as a bonus.
> Having a limit of only 4 links seems like a problem to me too.
>
This can be easily extended.
> I think there needs to be a better articulation about why other
> interfaces cannot be used (like a network device). Is it because of
> ease of guest configuration? Is it performance?
Performance is not the reason. Actually vmchannel doesn't need
performance of a network device that is why its implementation is much
simpler. The main reasons to not use network is that we want to support
configurations where there is no network connectivity between host and
guest. We want to have communication channel available to us even if
guest network stack is misconfigured (actually we may use vmchannel to
configure guest networking). And if we will allocate separate network
device for guest <-> host communication this will be visible to various
guest components that may interfere with it (firewalls, antiviruses).
--
Gleb.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-14 9:05 ` Gleb Natapov
@ 2008-10-14 13:50 ` Anthony Liguori
2008-10-14 17:59 ` Gleb Natapov
0 siblings, 1 reply; 16+ messages in thread
From: Anthony Liguori @ 2008-10-14 13:50 UTC (permalink / raw)
To: Gleb Natapov; +Cc: Anthony Liguori, kvm, Rusty Russell
Gleb Natapov wrote:
> On Mon, Oct 13, 2008 at 01:32:35PM -0500, Anthony Liguori wrote:
>
>>
> netlink was designed to be interface to userspace and is used like this
> by different subsystems (not just network). What full blown socket (and
> by that I presume you mean new address family) will give you over netlink?
> File system? We need a simple stream semantics is this justify another
> virtual file system? The choice was between char device and netlink.
> Nelink was simpler and gives broadcast as a bonus.
>
The problem that you aren't solving, that IMHO is critical to solve, is
the namespace issue. How do you determine who gets to use what channel
in userspace and in the host? It's not a problem when you just have one
tool, but if you expect people to start using this interface,
arbitrating it quickly becomes a problem.
sockets have a concept of addressing and a vfs has a natural namespace.
That's what I was suggesting those interfaces.
>
>> Having a limit of only 4 links seems like a problem to me too.
>>
>>
> This can be easily extended.
>
There shouldn't be an inherent limit in the userspace interface.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-14 13:50 ` Anthony Liguori
@ 2008-10-14 17:59 ` Gleb Natapov
2008-10-14 18:16 ` Anthony Liguori
0 siblings, 1 reply; 16+ messages in thread
From: Gleb Natapov @ 2008-10-14 17:59 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Anthony Liguori, kvm, Rusty Russell
On Tue, Oct 14, 2008 at 08:50:48AM -0500, Anthony Liguori wrote:
> Gleb Natapov wrote:
>> On Mon, Oct 13, 2008 at 01:32:35PM -0500, Anthony Liguori wrote:
>>
>>>
>> netlink was designed to be interface to userspace and is used like this
>> by different subsystems (not just network). What full blown socket (and
>> by that I presume you mean new address family) will give you over netlink?
>> File system? We need a simple stream semantics is this justify another
>> virtual file system? The choice was between char device and netlink.
>> Nelink was simpler and gives broadcast as a bonus.
>>
>
> The problem that you aren't solving, that IMHO is critical to solve, is
> the namespace issue. How do you determine who gets to use what channel
> in userspace and in the host?
Management software determines this. You have an image that is managed
by particular software and management daemons on the guest knows what
channels to use to communicate with their counterparts on the host.
Is there a need to provide more then that?
> It's not a problem when you just have one
> tool, but if you expect people to start using this interface,
> arbitrating it quickly becomes a problem.
I expect that software on the host and on the guest will belong to the
same management solution.
>
> sockets have a concept of addressing and a vfs has a natural namespace.
> That's what I was suggesting those interfaces.
>
What address should look like if we will choose to use new address family?
An example will help me understand what problem you are trying to point out
easily.
>>
>>> Having a limit of only 4 links seems like a problem to me too.
>>>
>>>
>> This can be easily extended.
>>
>
> There shouldn't be an inherent limit in the userspace interface.
>
Well, qemu has those limits for all other interfaces (like number of
nics, serial ports, parallel ports), but if vmchannels are somehow
different in this regards there is no problem to dynamically grow their
number.
--
Gleb.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-14 17:59 ` Gleb Natapov
@ 2008-10-14 18:16 ` Anthony Liguori
2008-10-15 12:58 ` Gleb Natapov
0 siblings, 1 reply; 16+ messages in thread
From: Anthony Liguori @ 2008-10-14 18:16 UTC (permalink / raw)
To: Gleb Natapov
Cc: kvm, Rusty Russell, virtualization, Zachary Amsden, Anupam Chanda,
Andrew Biggadike
Gleb Natapov wrote:
> On Tue, Oct 14, 2008 at 08:50:48AM -0500, Anthony Liguori wrote:
>
>> Gleb Natapov wrote:
>>
>>> On Mon, Oct 13, 2008 at 01:32:35PM -0500, Anthony Liguori wrote:
>>>
>>>
>>> netlink was designed to be interface to userspace and is used like this
>>> by different subsystems (not just network). What full blown socket (and
>>> by that I presume you mean new address family) will give you over netlink?
>>> File system? We need a simple stream semantics is this justify another
>>> virtual file system? The choice was between char device and netlink.
>>> Nelink was simpler and gives broadcast as a bonus.
>>>
>>>
>> The problem that you aren't solving, that IMHO is critical to solve, is
>> the namespace issue. How do you determine who gets to use what channel
>> in userspace and in the host?
>>
> Management software determines this. You have an image that is managed
> by particular software and management daemons on the guest knows what
> channels to use to communicate with their counterparts on the host.
> Is there a need to provide more then that?
>
No, I don't think this is enough. I think we need to support multiple
independent management agents using these interfaces so we can't rely on
a single management too orchestrating who uses what channel.
For instance, we'll have something that's open that does copy/paste and
DnD, but then CIM people may want to have monitor agents that use the
interface for monitoring.
>> It's not a problem when you just have one
>> tool, but if you expect people to start using this interface,
>> arbitrating it quickly becomes a problem.
>>
> I expect that software on the host and on the guest will belong to the
> same management solution.
>
There won't always be one set of tools that use this functionality.
>> sockets have a concept of addressing and a vfs has a natural namespace.
>> That's what I was suggesting those interfaces.
>>
>>
> What address should look like if we will choose to use new address family?
> An example will help me understand what problem you are trying to point out
> easily.
>
One thing that's been discussed is to use something that looked much
like struct sockaddr_un. As long as the strings were unique, they could
be in whatever format people wanted.
Of course, you should also take a look at VMware's VMCI. If we're going
to have a socket interface, if we can have a compatible userspace
interface, that would probably be a good thing.
>>>
>>>
>>>> Having a limit of only 4 links seems like a problem to me too.
>>>>
>>>>
>>>>
>>> This can be easily extended.
>>>
>>>
>> There shouldn't be an inherent limit in the userspace interface.
>>
>>
> Well, qemu has those limits for all other interfaces (like number of
> nics, serial ports, parallel ports), but if vmchannels are somehow
> different in this regards there is no problem to dynamically grow their
> number.
>
Having a limit in QEMU is fine, we just don't want the limit to be in
the guest driver. It's relatively easy to increase the limit or make it
dynamic in QEMU but if it requires guest-visible changes, that's much
more difficult to fix.
Regards,
Anthony Liguori
>
> --
> Gleb.
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-14 18:16 ` Anthony Liguori
@ 2008-10-15 12:58 ` Gleb Natapov
2008-10-15 14:02 ` Anthony Liguori
2008-10-15 14:18 ` Andrew Biggadike
0 siblings, 2 replies; 16+ messages in thread
From: Gleb Natapov @ 2008-10-15 12:58 UTC (permalink / raw)
To: Anthony Liguori
Cc: kvm, Rusty Russell, virtualization, Zachary Amsden, Anupam Chanda,
Andrew Biggadike
On Tue, Oct 14, 2008 at 01:16:19PM -0500, Anthony Liguori wrote:
>>> sockets have a concept of addressing and a vfs has a natural
>>> namespace. That's what I was suggesting those interfaces.
>>>
>>>
>> What address should look like if we will choose to use new address family?
>> An example will help me understand what problem you are trying to point out
>> easily.
>>
>
> One thing that's been discussed is to use something that looked much
Where is has been discussed? Was it on a public mailing list with online
archive?
> like struct sockaddr_un. As long as the strings were unique, they could
> be in whatever format people wanted.
>
So basically what you are saying is that you want to use string IDs instead of
numerical IDs in a hope that the chance of colliding IDs will be smaller? (in the
current implementation ID length is 32 bit, so the chances for two services to
pick the same ID is small).
But why pick constant ID for a service at all? Management software can
assign unique IDs for each service during image preparation. So one
management software will use channel 42 for DnD and 22 for CIM and another
will use 13 for DnD and 42 for CIM. All is need is to not hard code
channel IDs into agents. You will not be able to move such images from one
management software to another easily of cause, but this task is not so easy
today too.
> Of course, you should also take a look at VMware's VMCI. If we're going
> to have a socket interface, if we can have a compatible userspace
> interface, that would probably be a good thing.
>
As good as VMware backdoor interface that we chose not to use because we
can't control it?
I looked at what I could find about VMCI (http://pubs.vmware.com/vmci-sdk/index.html).
Wow, it looks like somebody was assigned a task to design a cross
platform communication layer that should accommodate every past, present
and future requirement no matter how likely or weird it may be :)
But seriously if we drop all the cross platform craft from there and add
name resolution server to proposed vmchannel we will have something very
similar (sans shared memory of cause). If you like string IDs better
than numerical IDs and you are OK with "lookup by name" way of doing
things in VMCI I can easily add channel 0 (will be implemented by qemu
itself and thus always present) that will do name to ID mapping.
But why stop there. Lets run CORBA name service on channel 0 and run
CORBA objects on others (joke).
>>>>
>>>>> Having a limit of only 4 links seems like a problem to me too.
>>>>>
>>>>>
>>>> This can be easily extended.
>>>>
>>> There shouldn't be an inherent limit in the userspace interface.
>>>
>>>
>> Well, qemu has those limits for all other interfaces (like number of
>> nics, serial ports, parallel ports), but if vmchannels are somehow
>> different in this regards there is no problem to dynamically grow their
>> number.
>>
>
> Having a limit in QEMU is fine, we just don't want the limit to be in
> the guest driver. It's relatively easy to increase the limit or make it
> dynamic in QEMU but if it requires guest-visible changes, that's much
> more difficult to fix.
>
That's OK then. There is no any compile time limits on a number of
channels in the current Linux driver. The number is only limited by PCI
configuration space as I pass available channel IDs there.
--
Gleb.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-15 12:58 ` Gleb Natapov
@ 2008-10-15 14:02 ` Anthony Liguori
2008-10-16 8:41 ` Gleb Natapov
2008-10-15 14:18 ` Andrew Biggadike
1 sibling, 1 reply; 16+ messages in thread
From: Anthony Liguori @ 2008-10-15 14:02 UTC (permalink / raw)
To: Gleb Natapov
Cc: kvm, Rusty Russell, virtualization, Zachary Amsden, Anupam Chanda,
Andrew Biggadike
Gleb Natapov wrote:
> On Tue, Oct 14, 2008 at 01:16:19PM -0500, Anthony Liguori wrote:
>
>> One thing that's been discussed is to use something that looked much
>>
> Where is has been discussed? Was it on a public mailing list with online
> archive?
>
Probably? This subject has been discussed to death in various places
(including within the Xen community).
>> like struct sockaddr_un. As long as the strings were unique, they could
>> be in whatever format people wanted.
>>
>>
> So basically what you are saying is that you want to use string IDs instead of
> numerical IDs in a hope that the chance of colliding IDs will be smaller? (in the
> current implementation ID length is 32 bit, so the chances for two services to
> pick the same ID is small).
>
But people don't choose random 32-bit integers and since your
implementation only supports channels 0..4 obviously, the intention
isn't to choose random integers. When using integers, it would be
necessary to have some sort of authority that assigns out the integers
to avoid conflict. A protocol like this scales better if such an
authority isn't necessary.
> But why pick constant ID for a service at all? Management software can
> assign unique IDs for each service during image preparation.
First, not everyone has "management software". Even so, it's not the
center of the world. If I want to add a new feature to QEMU that makes
use of one of these channels (say Unity/Coherence), does that mean I now
have to tell every management tool (libvirt et al) about this interface
so they can assign an ID to it? How does the guest software know what
channel to use? You basically assume yet another host<=>guest
communication mechanism to tell the guest software what channel to use.
That seems to defeat the purpose.
> So one
> management software will use channel 42 for DnD and 22 for CIM and another
> will use 13 for DnD and 42 for CIM. All is need is to not hard code
> channel IDs into agents. You will not be able to move such images from one
> management software to another easily of cause, but this task is not so easy
> today too.
>
It's so much simpler to just use unique identifiers for each service.
Be it UUID, a string in the form of a reverse fqdn or URL, or whatever.
>> Of course, you should also take a look at VMware's VMCI. If we're going
>> to have a socket interface, if we can have a compatible userspace
>> interface, that would probably be a good thing.
>>
>>
> As good as VMware backdoor interface that we chose not to use because we
> can't control it?
>
I suggested you look at VMCI mainly to see the addressing mechanism.
AF_IUCV is something else to look at although there's a lot of legacy
there. I'm not suggesting we be binary compatible with VMCI, but if
their addressing mechanism is sufficiently general (like a string), then
I see no reason not to use the same addressing mechanism or something
similar to it.
> If you like string IDs better
> than numerical IDs and you are OK with "lookup by name" way of doing
> things in VMCI I can easily add channel 0 (will be implemented by qemu
> itself and thus always present) that will do name to ID mapping.
>
It's not a bad idea to have a bootstrap channel. Do channel exist
during the entirely life time of the guest? Can disconnects/reconnects
happen on a channel? Can a guest listen on a channel?
Certainly, sockets are a pretty well established model so it makes a
certain amount of sense to have these things behave like traditional
sockets.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-15 12:58 ` Gleb Natapov
2008-10-15 14:02 ` Anthony Liguori
@ 2008-10-15 14:18 ` Andrew Biggadike
2008-10-15 14:30 ` Gleb Natapov
2008-10-15 15:42 ` Gleb Natapov
1 sibling, 2 replies; 16+ messages in thread
From: Andrew Biggadike @ 2008-10-15 14:18 UTC (permalink / raw)
To: Gleb Natapov
Cc: Anthony Liguori, kvm@vger.kernel.org, Rusty Russell,
virtualization, Zach Amsden, Anupam Chanda
Gleb Natapov <gleb@redhat.com> wrote:
> > Of course, you should also take a look at VMware's VMCI. If we're going
> > to have a socket interface, if we can have a compatible userspace
> > interface, that would probably be a good thing.
>
> I looked at what I could find about VMCI (http://pubs.vmware.com/vmci-sdk/index.html).
I believe Anthony intended for you to look at the sockets interface to
VMCI: http://www.vmware.com/pdf/ws65_s2_vmci_sockets.pdf.
The link you referenced was experimental and is actually now
deprecated in favor of the sockets interface.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-15 14:18 ` Andrew Biggadike
@ 2008-10-15 14:30 ` Gleb Natapov
2008-10-15 15:00 ` Andrew Biggadike
2008-10-15 15:42 ` Gleb Natapov
1 sibling, 1 reply; 16+ messages in thread
From: Gleb Natapov @ 2008-10-15 14:30 UTC (permalink / raw)
To: Andrew Biggadike
Cc: Anthony Liguori, kvm@vger.kernel.org, Rusty Russell,
virtualization, Zach Amsden, Anupam Chanda
On Wed, Oct 15, 2008 at 07:18:52AM -0700, Andrew Biggadike wrote:
> Gleb Natapov <gleb@redhat.com> wrote:
> > > Of course, you should also take a look at VMware's VMCI. If we're going
> > > to have a socket interface, if we can have a compatible userspace
> > > interface, that would probably be a good thing.
> >
> > I looked at what I could find about VMCI (http://pubs.vmware.com/vmci-sdk/index.html).
>
> I believe Anthony intended for you to look at the sockets interface to
> VMCI: http://www.vmware.com/pdf/ws65_s2_vmci_sockets.pdf.
>
Thanks for the link! Are you going to push this interface into upstream kernel?
> The link you referenced was experimental and is actually now
> deprecated in favor of the sockets interface.
You should influence google somehow to drop old link. That the first
search result for "vmci vmware" ;)
--
Gleb.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-15 14:30 ` Gleb Natapov
@ 2008-10-15 15:00 ` Andrew Biggadike
0 siblings, 0 replies; 16+ messages in thread
From: Andrew Biggadike @ 2008-10-15 15:00 UTC (permalink / raw)
To: Gleb Natapov
Cc: Anupam Chanda, kvm@vger.kernel.org, virtualization,
Anthony Liguori
Gleb Natapov <gleb@redhat.com> wrote:
> On Wed, Oct 15, 2008 at 07:18:52AM -0700, Andrew Biggadike wrote:
> > Gleb Natapov <gleb@redhat.com> wrote:
> > > > Of course, you should also take a look at VMware's VMCI. If we're going
> > > > to have a socket interface, if we can have a compatible userspace
> > > > interface, that would probably be a good thing.
> > >
> > > I looked at what I could find about VMCI (http://pubs.vmware.com/vmci-sdk/index.html).
>
> > I believe Anthony intended for you to look at the sockets interface to
> > VMCI: http://www.vmware.com/pdf/ws65_s2_vmci_sockets.pdf.
> >
> Thanks for the link! Are you going to push this interface into upstream kernel?
Pushing it upstream is definitely something we want to do, since it
will make our development easier and allow us to clean up some
unnecessary code in the module. That said, before we can start that
effort we have some issues to resolve internally (for example, getting
our upgrade story straight in this model and ensuring our
infrastructure / installer can handle it) so we don't have an estimate
for when this will happen just yet. There are people here whose jobs
are to resolve these things and they are working on it, so I am
confident this will happen even if slower than we'd all like.
> > The link you referenced was experimental and is actually now
> > deprecated in favor of the sockets interface.
> You should influence google somehow to drop old link. That the first
> search result for "vmci vmware" ;)
You know, we talked a while ago about putting a notice at the top of
that page stating what I said and redirecting to the VMCI Sockets
programming guide, but somehow that seems to have not gotten done.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-15 14:18 ` Andrew Biggadike
2008-10-15 14:30 ` Gleb Natapov
@ 2008-10-15 15:42 ` Gleb Natapov
2008-10-15 15:56 ` Anthony Liguori
2008-10-15 16:59 ` Andrew Biggadike
1 sibling, 2 replies; 16+ messages in thread
From: Gleb Natapov @ 2008-10-15 15:42 UTC (permalink / raw)
To: Andrew Biggadike
Cc: Anthony Liguori, kvm@vger.kernel.org, Rusty Russell,
virtualization, Zach Amsden, Anupam Chanda
Andrew,
On Wed, Oct 15, 2008 at 07:18:52AM -0700, Andrew Biggadike wrote:
> Gleb Natapov <gleb@redhat.com> wrote:
> > > Of course, you should also take a look at VMware's VMCI. If we're going
> > > to have a socket interface, if we can have a compatible userspace
> > > interface, that would probably be a good thing.
> >
> > I looked at what I could find about VMCI (http://pubs.vmware.com/vmci-sdk/index.html).
>
> I believe Anthony intended for you to look at the sockets interface to
> VMCI: http://www.vmware.com/pdf/ws65_s2_vmci_sockets.pdf.
>
Using VMCI socket requires loading kernel module in a guest and in a host.
Is this correct?
--
Gleb.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-15 15:42 ` Gleb Natapov
@ 2008-10-15 15:56 ` Anthony Liguori
2008-10-16 8:54 ` Gleb Natapov
2008-10-15 16:59 ` Andrew Biggadike
1 sibling, 1 reply; 16+ messages in thread
From: Anthony Liguori @ 2008-10-15 15:56 UTC (permalink / raw)
To: Gleb Natapov
Cc: Andrew Biggadike, kvm@vger.kernel.org, Rusty Russell,
virtualization, Zach Amsden, Anupam Chanda
Gleb Natapov wrote:
> Andrew,
>
> On Wed, Oct 15, 2008 at 07:18:52AM -0700, Andrew Biggadike wrote:
>
>> Gleb Natapov <gleb@redhat.com> wrote:
>>
>>>> Of course, you should also take a look at VMware's VMCI. If we're going
>>>> to have a socket interface, if we can have a compatible userspace
>>>> interface, that would probably be a good thing.
>>>>
>>> I looked at what I could find about VMCI (http://pubs.vmware.com/vmci-sdk/index.html).
>>>
>> I believe Anthony intended for you to look at the sockets interface to
>> VMCI: http://www.vmware.com/pdf/ws65_s2_vmci_sockets.pdf.
>>
>>
> Using VMCI socket requires loading kernel module in a guest and in a host.
> Is this correct?
>
Note that their addressing scheme uses a CID/port pair. I think it's
interesting and somewhat safe because it basically mirrors an IP/port
pair. That makes it relatively safe because that addressing mechanism
is well known (with it's advantages and flaws). For instance, you need
some sort of authority to assign out ports. It doesn't really help with
discovery either.
Another possibility would be to have the address be like sockaddr_un.
You could actually have it be file paths. The effect would be that any
VMs that can communicate with each other could have a common namespace.
You could extend the analogy and actually create controllable
permissions that could be used to control who can talk to who. You
could even create a synthetic filesystem in the guest that could mount
this namespace allowing very sophisticated enumeration/permission
control. This is probably the complete opposite end in terms of having
a novel interface.
The best solution is probably somewhere between the two.
Regards,
Anthony Liguori
> --
> Gleb.
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-15 15:42 ` Gleb Natapov
2008-10-15 15:56 ` Anthony Liguori
@ 2008-10-15 16:59 ` Andrew Biggadike
1 sibling, 0 replies; 16+ messages in thread
From: Andrew Biggadike @ 2008-10-15 16:59 UTC (permalink / raw)
To: Gleb Natapov
Cc: Anthony Liguori, kvm@vger.kernel.org, Rusty Russell,
virtualization, Zach Amsden, Anupam Chanda
Gleb Natapov <gleb@redhat.com> wrote:
> On Wed, Oct 15, 2008 at 07:18:52AM -0700, Andrew Biggadike wrote:
> > Gleb Natapov <gleb@redhat.com> wrote:
> > > > Of course, you should also take a look at VMware's VMCI. If we're going
> > > > to have a socket interface, if we can have a compatible userspace
> > > > interface, that would probably be a good thing.
> > >
> > > I looked at what I could find about VMCI (http://pubs.vmware.com/vmci-sdk/index.html).
> >
> > I believe Anthony intended for you to look at the sockets interface to
> > VMCI: http://www.vmware.com/pdf/ws65_s2_vmci_sockets.pdf.
> >
> Using VMCI socket requires loading kernel module in a guest and in a host.
> Is this correct?
Yes, any context (in VMCI terms) that wants to allow for VMCI Socket
endpoints needs both the vmci and the vsock kernel modules loaded.
In case you're asking because you're going to try it out, note that
our currently released version of VMCI Sockets (with Workstation 6.5)
does not yet support SOCK_STREAM on the host, just guests. That gets
a lot of people at the moment.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-15 14:02 ` Anthony Liguori
@ 2008-10-16 8:41 ` Gleb Natapov
0 siblings, 0 replies; 16+ messages in thread
From: Gleb Natapov @ 2008-10-16 8:41 UTC (permalink / raw)
To: Anthony Liguori
Cc: kvm, Rusty Russell, virtualization, Zachary Amsden, Anupam Chanda,
Andrew Biggadike
On Wed, Oct 15, 2008 at 09:02:30AM -0500, Anthony Liguori wrote:
>>> like struct sockaddr_un. As long as the strings were unique, they
>>> could be in whatever format people wanted.
>>>
>>>
>> So basically what you are saying is that you want to use string IDs instead of
>> numerical IDs in a hope that the chance of colliding IDs will be smaller? (in the
>> current implementation ID length is 32 bit, so the chances for two services to
>> pick the same ID is small).
>>
>
> But people don't choose random 32-bit integers and since your
> implementation only supports channels 0..4 obviously, the intention
> isn't to choose random integers. When using integers, it would be
You can configure only four channels in qemu with my implementation, but
you can give arbitrary ID to each one of them. To configure vmchannel
with ID 42 you add "-vmchannel di:42,unix:/tmp/kvm-mouse,server"
to qemu command line ("di" means Device Id).
> necessary to have some sort of authority that assigns out the integers
> to avoid conflict. A protocol like this scales better if such an
> authority isn't necessary.
>
>> But why pick constant ID for a service at all? Management software can
>> assign unique IDs for each service during image preparation.
>
> First, not everyone has "management software". Even so, it's not the
If you run qemu without "management software" as most of us do, you
became "management software". If you want Linux console to be on a
serial port you have to configure qemu and Linux properly.
> center of the world. If I want to add a new feature to QEMU that makes
> use of one of these channels (say Unity/Coherence), does that mean I now
> have to tell every management tool (libvirt et al) about this interface
> so they can assign an ID to it? How does the guest software know what
With proposed solution yes, you have to tell it to a management tool.
Not only because of ID assigning issues, but also because you have no
direct control on a command line, so management tool should know how to
create a channel for you. Of cause management tool can have an option to
add channels on user request.
> channel to use? You basically assume yet another host<=>guest
> communication mechanism to tell the guest software what channel to use.
> That seems to defeat the purpose.
This happens when disk image is prepared and various agents are installed into
it. Just as if you want to redirect Linux console to serial port you
have to add kernel option once after installation.
>
>> So one
>> management software will use channel 42 for DnD and 22 for CIM and another
>> will use 13 for DnD and 42 for CIM. All is need is to not hard code
>> channel IDs into agents. You will not be able to move such images from one
>> management software to another easily of cause, but this task is not so easy
>> today too.
>>
>
> It's so much simpler to just use unique identifiers for each service.
> Be it UUID, a string in the form of a reverse fqdn or URL, or whatever.
>
It is easy to do with "name resolution" service on channel 0.
>> If you like string IDs better
>> than numerical IDs and you are OK with "lookup by name" way of doing
>> things in VMCI I can easily add channel 0 (will be implemented by qemu
>> itself and thus always present) that will do name to ID mapping.
>>
>
> It's not a bad idea to have a bootstrap channel. Do channel exist
> during the entirely life time of the guest?
Yes.
> Can disconnects/reconnects
> happen on a channel? Can a guest listen on a channel?
Netlink implements datagram semantic, so there is not
disconnects/reconnects or listen. Any process can send/receive data
to/from any channel.
>
> Certainly, sockets are a pretty well established model so it makes a
> certain amount of sense to have these things behave like traditional
> sockets.
>
I use socket! Existing one, not new one. I think there should be a very
good reason to add yet another address family. I thought about adding new
address family initially, but then I recalled that we already have one
that is used for kernel<->userspace communication.
--
Gleb.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH][RFC] vmchannel a data channel between host and guest.
2008-10-15 15:56 ` Anthony Liguori
@ 2008-10-16 8:54 ` Gleb Natapov
0 siblings, 0 replies; 16+ messages in thread
From: Gleb Natapov @ 2008-10-16 8:54 UTC (permalink / raw)
To: Anthony Liguori
Cc: Andrew Biggadike, kvm@vger.kernel.org, Rusty Russell,
virtualization, Zach Amsden, Anupam Chanda
On Wed, Oct 15, 2008 at 10:56:02AM -0500, Anthony Liguori wrote:
> Gleb Natapov wrote:
>> Andrew,
>>
>> On Wed, Oct 15, 2008 at 07:18:52AM -0700, Andrew Biggadike wrote:
>>
>>> Gleb Natapov <gleb@redhat.com> wrote:
>>>
>>>>> Of course, you should also take a look at VMware's VMCI. If we're going
>>>>> to have a socket interface, if we can have a compatible userspace
>>>>> interface, that would probably be a good thing.
>>>>>
>>>> I looked at what I could find about VMCI (http://pubs.vmware.com/vmci-sdk/index.html).
>>>>
>>> I believe Anthony intended for you to look at the sockets interface to
>>> VMCI: http://www.vmware.com/pdf/ws65_s2_vmci_sockets.pdf.
>>>
>>>
>> Using VMCI socket requires loading kernel module in a guest and in a host.
>> Is this correct?
>>
>
> Note that their addressing scheme uses a CID/port pair. I think it's
> interesting and somewhat safe because it basically mirrors an IP/port
> pair. That makes it relatively safe because that addressing mechanism
> is well known (with it's advantages and flaws). For instance, you need
> some sort of authority to assign out ports. It doesn't really help with
> discovery either.
>
I fails to see how this is more safe that what I propose. Same problem
exactly: which ID/port to use for my service? But I also don't want to
compare proposed vmchannel and VMCI socket. They try to solve different
problems as far as I can see. VMCI tries to address intra host communication
performance problem (what about migration of a guest using it BTW? Or
security? Firewalls know nothing about it). vmchannel goal is to provide
management tools a way to communicate with in guest agents.
--
Gleb.
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2008-10-16 8:54 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-12 12:45 [PATCH][RFC] vmchannel a data channel between host and guest Gleb Natapov
2008-10-13 18:32 ` Anthony Liguori
2008-10-14 9:05 ` Gleb Natapov
2008-10-14 13:50 ` Anthony Liguori
2008-10-14 17:59 ` Gleb Natapov
2008-10-14 18:16 ` Anthony Liguori
2008-10-15 12:58 ` Gleb Natapov
2008-10-15 14:02 ` Anthony Liguori
2008-10-16 8:41 ` Gleb Natapov
2008-10-15 14:18 ` Andrew Biggadike
2008-10-15 14:30 ` Gleb Natapov
2008-10-15 15:00 ` Andrew Biggadike
2008-10-15 15:42 ` Gleb Natapov
2008-10-15 15:56 ` Anthony Liguori
2008-10-16 8:54 ` Gleb Natapov
2008-10-15 16:59 ` Andrew Biggadike
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).