aboutsummaryrefslogtreecommitdiffstats
path: root/hw/xen_devconfig.c
diff options
context:
space:
mode:
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2009-04-22 15:19:39 +0000
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2009-04-22 15:19:39 +0000
commit2c8b24a3914361de941e959e38e3c163a5adeea7 (patch)
tree411b956f4fbe8f95bb971f4241ff90087bee7bd7 /hw/xen_devconfig.c
parente613b064a88a94b2e887f2cb7a5a3a9082e67d9b (diff)
xen: blk & nic configuration via cmd line. (Gerd Hoffmann)
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@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7225 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/xen_devconfig.c')
-rw-r--r--hw/xen_devconfig.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/hw/xen_devconfig.c b/hw/xen_devconfig.c
new file mode 100644
index 000000000..4420561c8
--- /dev/null
+++ b/hw/xen_devconfig.c
@@ -0,0 +1,142 @@
+#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));
+ d->xs_dir = dir;
+ TAILQ_INSERT_TAIL(&xs_cleanup, d, list);
+}
+
+void xen_config_cleanup(void)
+{
+ struct xs_dirs *d;
+
+ 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[2] = {{
+ .id = 0, /* set owner: dom0 */
+ },{
+ .id = xen_domid,
+ .perms = p,
+ }};
+
+ if (!xs_mkdir(xenstore, 0, dev)) {
+ xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", dev);
+ return -1;
+ }
+ xen_config_cleanup_dir(qemu_strdup(dev));
+
+ if (!xs_set_permissions(xenstore, 0, dev, perms, 2)) {
+ xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", dev);
+ return -1;
+ }
+ return 0;
+}
+
+static int xen_config_dev_dirs(const char *ftype, const char *btype, int vdev,
+ char *fe, char *be, int len)
+{
+ char *dom;
+
+ dom = xs_get_domain_path(xenstore, xen_domid);
+ snprintf(fe, len, "%s/device/%s/%d", dom, ftype, vdev);
+ free(dom);
+
+ dom = xs_get_domain_path(xenstore, 0);
+ snprintf(be, len, "%s/backend/%s/%d/%d", dom, btype, xen_domid, vdev);
+ free(dom);
+
+ xen_config_dev_mkdir(fe, XS_PERM_READ | 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 (xen_protocol)
+ xenstore_write_str(fe, "protocol", xen_protocol);
+
+ 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;
+ const char *devtype = cdrom ? "cdrom" : "disk";
+ const char *mode = cdrom ? "r" : "w";
+
+ snprintf(disk->bdrv->device_name, sizeof(disk->bdrv->device_name),
+ "xvd%c", 'a' + disk->unit);
+ xen_be_printf(NULL, 1, "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]);
+ xen_be_printf(NULL, 1, "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);
+}