This patch makes qemu create backend and frontend device entries in
xenstore for devices configured on the command line. It will use
qdisk and qnic backend names, so the qemu internal backends will
be used.
Disks can be created using -drive if=xen,file=...
Nics can be created using -net nic,macaddr=...
Signed-off-by: Gerd Hoffmann <kraxel@xxxxxxxxxx>
---
Makefile.target | 2 +-
hw/xen-backend.h | 7 +++
hw/xen-config.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/xen-machine.c | 19 +++++++-
4 files changed, 165 insertions(+), 2 deletions(-)
create mode 100644 hw/xen-config.c
diff --git a/Makefile.target b/Makefile.target
index 85f938c..a3f8d24 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -516,7 +516,7 @@ LIBS += $(CONFIG_VNC_TLS_LIBS)
endif
# xen backend driver support
-XEN_OBJS := xen-machine.o xen-backend.o
+XEN_OBJS := xen-machine.o xen-backend.o xen-config.o
XEN_OBJS += xen-console.o xen-framebuffer.o xen-disk.o xen-nic.o
ifeq ($(CONFIG_XEN), yes)
OBJS += $(XEN_OBJS)
diff --git a/hw/xen-backend.h b/hw/xen-backend.h
index b484752..c1da2ca 100644
--- a/hw/xen-backend.h
+++ b/hw/xen-backend.h
@@ -3,6 +3,8 @@
#include "xen-common.h"
#include "sysemu.h"
+#include "net.h"
+#include "block_int.h"
/* ------------------------------------------------------------- */
@@ -94,4 +96,9 @@ struct XenDevOps xen_netdev_ops; /* xen_nic.c */
void xen_set_display(int domid, DisplayState *ds);
+/* configuration (aka xenbus setup) */
+void xen_config_cleanup(void);
+int xen_config_dev_blk(DriveInfo *disk);
+int xen_config_dev_nic(NICInfo *nic);
+
#endif /* QEMU_XEN_BACKEND_H */
diff --git a/hw/xen-config.c b/hw/xen-config.c
new file mode 100644
index 0000000..4156f82
--- /dev/null
+++ b/hw/xen-config.c
@@ -0,0 +1,139 @@
+#include "xen-backend.h"
+
+/* ------------------------------------------------------------- */
+
+struct xs_dirs {
+ char *xs_dir;
+ TAILQ_ENTRY(xs_dirs) list;
+};
+static TAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup =
TAILQ_HEAD_INITIALIZER(xs_cleanup);
+
+static void xen_config_cleanup_dir(char *dir)
+{
+ struct xs_dirs *d;
+
+ d = qemu_malloc(sizeof(*d));
+ if (!d)
+ return;
+ d->xs_dir = dir;
+ TAILQ_INSERT_TAIL(&xs_cleanup, d, list);
+}
+
+void xen_config_cleanup(void)
+{
+ struct xs_dirs *d;
+
+ fprintf(stderr, "xen be: %s\n", __FUNCTION__);
+ TAILQ_FOREACH(d, &xs_cleanup, list) {
+ xs_rm(xenstore, 0, d->xs_dir);
+ }
+}
+
+/* ------------------------------------------------------------- */
+
+static int xen_config_dev_mkdir(char *dev, int p)
+{
+ struct xs_permissions perms = {
+ .id = xen_domid,
+ .perms = p,
+ };
+
+ if (!xs_mkdir(xenstore, 0, dev)) {
+ fprintf(stderr, "xs_mkdir %s: failed\n", dev);
+ return -1;
+ }
+ xen_config_cleanup_dir(qemu_strdup(dev));
+
+ if (!xs_set_permissions(xenstore, 0, dev, &perms, 1)) {
+ fprintf(stderr, "%s: xs_set_permissions failed\n", __FUNCTION__);
+ return -1;
+ }
+ return 0;
+}
+
+static int xen_config_dev_dirs(char *ftype, char *btype, int vdev,
+ char *fe, char *be, int len)
+{
+ snprintf(fe, len, "/local/domain/%d/device/%s/%d",
+ xen_domid, ftype, vdev);
+ snprintf(be, len, "/local/domain/0/backend/%s/%d/%d",
+ btype, xen_domid, vdev);
+
+ xen_config_dev_mkdir(fe, XS_PERM_WRITE);
+ xen_config_dev_mkdir(be, XS_PERM_READ);
+ return 0;
+}
+
+static int xen_config_dev_all(char *fe, char *be)
+{
+ /* frontend */
+#if 0
+ xenstore_write_str(fe, "protocol",
+ xen_config_dev_protocol(xen));
+#endif
+ xenstore_write_int(fe, "state", XenbusStateInitialising);
+ xenstore_write_int(fe, "backend-id", 0);
+ xenstore_write_str(fe, "backend", be);
+
+ /* backend */
+ xenstore_write_str(be, "domain", qemu_name ? qemu_name :
"no-name");
+ xenstore_write_int(be, "online", 1);
+ xenstore_write_int(be, "state", XenbusStateInitialising);
+ xenstore_write_int(be, "frontend-id", xen_domid);
+ xenstore_write_str(be, "frontend", fe);
+
+ return 0;
+}
+
+/* ------------------------------------------------------------- */
+
+int xen_config_dev_blk(DriveInfo *disk)
+{
+ char fe[256], be[256];
+ int vdev = 202 * 256 + 16 * disk->unit;
+ int cdrom = disk->bdrv->type == BDRV_TYPE_CDROM;
+ char *devtype = cdrom ? "cdrom" : "disk";
+ char *mode = cdrom ? "r" : "w";
+
+ snprintf(disk->bdrv->device_name, sizeof(disk->bdrv->device_name),
+ "xvd%c", 'a' + disk->unit);
+ fprintf(stderr, "xen be: config disk %d [%s]: %s\n",
+ disk->unit, disk->bdrv->device_name, disk->bdrv->filename);
+ xen_config_dev_dirs("vbd", "qdisk", vdev, fe, be, sizeof(fe));
+
+ /* frontend */
+ xenstore_write_int(fe, "virtual-device", vdev);
+ xenstore_write_str(fe, "device-type", devtype);
+
+ /* backend */
+ xenstore_write_str(be, "dev", disk->bdrv->device_name);
+ xenstore_write_str(be, "type", "file");
+ xenstore_write_str(be, "params", disk->bdrv->filename);
+ xenstore_write_str(be, "mode", mode);
+
+ /* common stuff */
+ return xen_config_dev_all(fe, be);
+}
+
+int xen_config_dev_nic(NICInfo *nic)
+{
+ char fe[256], be[256];
+ char mac[20];
+
+ snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
+ nic->macaddr[0], nic->macaddr[1], nic->macaddr[2],
+ nic->macaddr[3], nic->macaddr[4], nic->macaddr[5]);
+ fprintf(stderr, "xen be: config nic %d: mac=\"%s\"\n", nic->vlan->id, mac);
+ xen_config_dev_dirs("vif", "qnic", nic->vlan->id, fe, be, sizeof(fe));
+
+ /* frontend */
+ xenstore_write_int(fe, "handle", nic->vlan->id);
+ xenstore_write_str(fe, "mac", mac);
+
+ /* backend */
+ xenstore_write_int(be, "handle", nic->vlan->id);
+ xenstore_write_str(be, "mac", mac);
+
+ /* common stuff */
+ return xen_config_dev_all(fe, be);
+}
diff --git a/hw/xen-machine.c b/hw/xen-machine.c
index c8fb256..4e4d893 100644
--- a/hw/xen-machine.c
+++ b/hw/xen-machine.c
@@ -121,7 +121,7 @@ static void xenpv_init(ram_addr_t ram_size, int
vga_ram_size,
const char *cpu_model)
{
CPUState *env;
- int rc;
+ int index,i,rc;
rc = xen_init_pv(ds);
if (-1 == rc)
@@ -147,6 +147,23 @@ static void xenpv_init(ram_addr_t ram_size, int
vga_ram_size,
env = cpu_init(cpu_model);
env->halted = 1;
+ /* configure disks */
+ for (i = 0; i < 16; i++) {
+ index = drive_get_index(IF_XEN, 0, i);
+ if (index == -1)
+ continue;
+ xen_config_dev_blk(drives_table + index);
+ }
+
+ /* configure nics */
+ for (i = 0; i < nb_nics; i++) {
+ if (nd_table[i].model && 0 != strcmp(nd_table[i].model, "xen"))
+ continue;
+ xen_config_dev_nic(nd_table + i);
+ }
+
+ /* config cleanup hook */
+ atexit(xen_config_cleanup);
return;
err:
--
1.5.5.1
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|