static int net_init(struct XenDevice *xendev) { struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev); /* read xenstore entries */ if (netdev->mac == NULL) { netdev->mac = xenstore_read_be_str(&netdev->xendev, "mac"); } /* do we have all we need? */ if (netdev->mac == NULL) { return -1; } if (net_parse_macaddr(netdev->conf.macaddr.a, netdev->mac) < 0) { return -1; } netdev->conf.vlan = qemu_find_vlan(netdev->xendev.dev, 1); netdev->conf.peer = NULL; netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf, "xen", NULL, netdev); snprintf(netdev->nic->nc.info_str, sizeof(netdev->nic->nc.info_str), "nic: xenbus vif macaddr=%s", netdev->mac); /* fill info */ xenstore_write_be_int(&netdev->xendev, "feature-rx-copy", 1); xenstore_write_be_int(&netdev->xendev, "feature-rx-flip", 0); return 0; }
/* * Initial xendev setup. Read frontend path, register watch for it. * Should succeed once xend finished setting up the backend device. * * Also sets initial state (-> Initializing) when done. Which * only affects the xendev->be_state variable as xenbus should * already be put into that state by xend. */ static int xen_be_try_setup(struct XenDevice *xendev) { char token[XEN_BUFSIZE]; int be_state; if (xenstore_read_be_int(xendev, "state", &be_state) == -1) { xen_be_printf(xendev, 0, "reading backend state failed\n"); return -1; } if (be_state != XenbusStateInitialising) { xen_be_printf(xendev, 0, "initial backend state is wrong (%s)\n", xenbus_strstate(be_state)); return -1; } xendev->fe = xenstore_read_be_str(xendev, "frontend"); if (xendev->fe == NULL) { xen_be_printf(xendev, 0, "reading frontend path failed\n"); return -1; } /* setup frontend watch */ snprintf(token, sizeof(token), "fe:%p", xendev); if (!xs_watch(xenstore, xendev->fe, token)) { xen_be_printf(xendev, 0, "watching frontend path (%s) failed\n", xendev->fe); return -1; } xen_be_set_state(xendev, XenbusStateInitialising); xen_be_backend_changed(xendev, NULL); xen_be_frontend_changed(xendev, NULL); return 0; }
static int net_init(struct XenDevice *xendev) { struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev); VLANState *vlan; /* read xenstore entries */ if (netdev->mac == NULL) netdev->mac = xenstore_read_be_str(&netdev->xendev, "mac"); /* do we have all we need? */ if (netdev->mac == NULL) return -1; vlan = qemu_find_vlan(netdev->xendev.dev, 1); netdev->vs = qemu_new_vlan_client(vlan, "xen", NULL, net_rx_ok, net_rx_packet, NULL, NULL, netdev); snprintf(netdev->vs->info_str, sizeof(netdev->vs->info_str), "nic: xenbus vif macaddr=%s", netdev->mac); /* fill info */ xenstore_write_be_int(&netdev->xendev, "feature-rx-copy", 1); xenstore_write_be_int(&netdev->xendev, "feature-rx-flip", 0); return 0; }
static int blk_init(struct XenDevice *xendev) { struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev); int index, qflags, have_barriers, info = 0; char *h; /* read xenstore entries */ if (blkdev->params == NULL) { blkdev->params = xenstore_read_be_str(&blkdev->xendev, "params"); h = strchr(blkdev->params, ':'); if (h != NULL) { blkdev->fileproto = blkdev->params; blkdev->filename = h+1; *h = 0; } else { blkdev->fileproto = "<unset>"; blkdev->filename = blkdev->params; } } if (blkdev->mode == NULL) blkdev->mode = xenstore_read_be_str(&blkdev->xendev, "mode"); if (blkdev->type == NULL) blkdev->type = xenstore_read_be_str(&blkdev->xendev, "type"); if (blkdev->dev == NULL) blkdev->dev = xenstore_read_be_str(&blkdev->xendev, "dev"); if (blkdev->devtype == NULL) blkdev->devtype = xenstore_read_be_str(&blkdev->xendev, "device-type"); /* do we have all we need? */ if (blkdev->params == NULL || blkdev->mode == NULL || blkdev->type == NULL || blkdev->dev == NULL) return -1; /* read-only ? */ if (strcmp(blkdev->mode, "w") == 0) { qflags = BDRV_O_RDWR; } else { qflags = 0; info |= VDISK_READONLY; } /* cdrom ? */ if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom")) info |= VDISK_CDROM; /* init qemu block driver */ index = (blkdev->xendev.dev - 202 * 256) / 16; blkdev->dinfo = drive_get(IF_XEN, 0, index); if (!blkdev->dinfo) { /* setup via xenbus -> create new block driver instance */ xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n"); blkdev->bs = bdrv_new(blkdev->dev); if (bdrv_open(blkdev->bs, blkdev->filename, qflags, bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) { bdrv_delete(blkdev->bs); return -1; } } else { /* setup via qemu cmdline -> already setup for us */ xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n"); blkdev->bs = blkdev->dinfo->bdrv; } blkdev->file_blk = BLOCK_SIZE; blkdev->file_size = bdrv_getlength(blkdev->bs); if (blkdev->file_size < 0) { xen_be_printf(&blkdev->xendev, 1, "bdrv_getlength: %d (%s) | drv %s\n", (int)blkdev->file_size, strerror(-blkdev->file_size), blkdev->bs->drv ? blkdev->bs->drv->format_name : "-"); blkdev->file_size = 0; } have_barriers = blkdev->bs->drv && blkdev->bs->drv->bdrv_flush ? 1 : 0; xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\"," " size %" PRId64 " (%" PRId64 " MB)\n", blkdev->type, blkdev->fileproto, blkdev->filename, blkdev->file_size, blkdev->file_size >> 20); /* fill info */ xenstore_write_be_int(&blkdev->xendev, "feature-barrier", have_barriers); xenstore_write_be_int(&blkdev->xendev, "info", info); xenstore_write_be_int(&blkdev->xendev, "sector-size", blkdev->file_blk); xenstore_write_be_int(&blkdev->xendev, "sectors", blkdev->file_size / blkdev->file_blk); return 0; }
static int blk_init(struct XenDevice *xendev) { struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev); int info = 0; char *directiosafe = NULL; trace_xen_disk_init(xendev->name); /* read xenstore entries */ if (blkdev->params == NULL) { char *h = NULL; blkdev->params = xenstore_read_be_str(xendev, "params"); if (blkdev->params != NULL) { h = strchr(blkdev->params, ':'); } if (h != NULL) { blkdev->fileproto = blkdev->params; blkdev->filename = h+1; *h = 0; } else { blkdev->fileproto = "<unset>"; blkdev->filename = blkdev->params; } } if (!strcmp("aio", blkdev->fileproto)) { blkdev->fileproto = "raw"; } if (!strcmp("vhd", blkdev->fileproto)) { blkdev->fileproto = "vpc"; } if (blkdev->mode == NULL) { blkdev->mode = xenstore_read_be_str(xendev, "mode"); } if (blkdev->type == NULL) { blkdev->type = xenstore_read_be_str(xendev, "type"); } if (blkdev->dev == NULL) { blkdev->dev = xenstore_read_be_str(xendev, "dev"); } if (blkdev->devtype == NULL) { blkdev->devtype = xenstore_read_be_str(xendev, "device-type"); } directiosafe = xenstore_read_be_str(xendev, "direct-io-safe"); blkdev->directiosafe = (directiosafe && atoi(directiosafe)); /* do we have all we need? */ if (blkdev->params == NULL || blkdev->mode == NULL || blkdev->type == NULL || blkdev->dev == NULL) { goto out_error; } /* read-only ? */ if (strcmp(blkdev->mode, "w")) { info |= VDISK_READONLY; } /* cdrom ? */ if (blkdev->devtype && !strcmp(blkdev->devtype, "cdrom")) { info |= VDISK_CDROM; } blkdev->file_blk = BLOCK_SIZE; /* fill info * blk_connect supplies sector-size and sectors */ xenstore_write_be_int(xendev, "feature-flush-cache", 1); xenstore_write_be_int(xendev, "info", info); xenstore_write_be_int(xendev, "max-ring-page-order", MAX_RING_PAGE_ORDER); blk_parse_discard(blkdev); g_free(directiosafe); return 0; out_error: g_free(blkdev->params); blkdev->params = NULL; g_free(blkdev->mode); blkdev->mode = NULL; g_free(blkdev->type); blkdev->type = NULL; g_free(blkdev->dev); blkdev->dev = NULL; g_free(blkdev->devtype); blkdev->devtype = NULL; g_free(directiosafe); blkdev->directiosafe = false; return -1; }
static int xen_9pfs_connect(struct XenLegacyDevice *xendev) { Error *err = NULL; int i; Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev); V9fsState *s = &xen_9pdev->state; QemuOpts *fsdev; if (xenstore_read_fe_int(&xen_9pdev->xendev, "num-rings", &xen_9pdev->num_rings) == -1 || xen_9pdev->num_rings > MAX_RINGS || xen_9pdev->num_rings < 1) { return -1; } xen_9pdev->rings = g_new0(Xen9pfsRing, xen_9pdev->num_rings); for (i = 0; i < xen_9pdev->num_rings; i++) { char *str; int ring_order; xen_9pdev->rings[i].priv = xen_9pdev; xen_9pdev->rings[i].evtchn = -1; xen_9pdev->rings[i].local_port = -1; str = g_strdup_printf("ring-ref%u", i); if (xenstore_read_fe_int(&xen_9pdev->xendev, str, &xen_9pdev->rings[i].ref) == -1) { g_free(str); goto out; } g_free(str); str = g_strdup_printf("event-channel-%u", i); if (xenstore_read_fe_int(&xen_9pdev->xendev, str, &xen_9pdev->rings[i].evtchn) == -1) { g_free(str); goto out; } g_free(str); xen_9pdev->rings[i].intf = xen_be_map_grant_ref(&xen_9pdev->xendev, xen_9pdev->rings[i].ref, PROT_READ | PROT_WRITE); if (!xen_9pdev->rings[i].intf) { goto out; } ring_order = xen_9pdev->rings[i].intf->ring_order; if (ring_order > MAX_RING_ORDER) { goto out; } xen_9pdev->rings[i].ring_order = ring_order; xen_9pdev->rings[i].data = xen_be_map_grant_refs(&xen_9pdev->xendev, xen_9pdev->rings[i].intf->ref, (1 << ring_order), PROT_READ | PROT_WRITE); if (!xen_9pdev->rings[i].data) { goto out; } xen_9pdev->rings[i].ring.in = xen_9pdev->rings[i].data; xen_9pdev->rings[i].ring.out = xen_9pdev->rings[i].data + XEN_FLEX_RING_SIZE(ring_order); xen_9pdev->rings[i].bh = qemu_bh_new(xen_9pfs_bh, &xen_9pdev->rings[i]); xen_9pdev->rings[i].out_cons = 0; xen_9pdev->rings[i].out_size = 0; xen_9pdev->rings[i].inprogress = false; xen_9pdev->rings[i].evtchndev = xenevtchn_open(NULL, 0); if (xen_9pdev->rings[i].evtchndev == NULL) { goto out; } qemu_set_cloexec(xenevtchn_fd(xen_9pdev->rings[i].evtchndev)); xen_9pdev->rings[i].local_port = xenevtchn_bind_interdomain (xen_9pdev->rings[i].evtchndev, xendev->dom, xen_9pdev->rings[i].evtchn); if (xen_9pdev->rings[i].local_port == -1) { xen_pv_printf(xendev, 0, "xenevtchn_bind_interdomain failed port=%d\n", xen_9pdev->rings[i].evtchn); goto out; } xen_pv_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port); qemu_set_fd_handler(xenevtchn_fd(xen_9pdev->rings[i].evtchndev), xen_9pfs_evtchn_event, NULL, &xen_9pdev->rings[i]); } xen_9pdev->security_model = xenstore_read_be_str(xendev, "security_model"); xen_9pdev->path = xenstore_read_be_str(xendev, "path"); xen_9pdev->id = s->fsconf.fsdev_id = g_strdup_printf("xen9p%d", xendev->dev); xen_9pdev->tag = s->fsconf.tag = xenstore_read_fe_str(xendev, "tag"); fsdev = qemu_opts_create(qemu_find_opts("fsdev"), s->fsconf.tag, 1, NULL); qemu_opt_set(fsdev, "fsdriver", "local", NULL); qemu_opt_set(fsdev, "path", xen_9pdev->path, NULL); qemu_opt_set(fsdev, "security_model", xen_9pdev->security_model, NULL); qemu_opts_set_id(fsdev, s->fsconf.fsdev_id); qemu_fsdev_add(fsdev, &err); if (err) { error_report_err(err); } v9fs_device_realize_common(s, &xen_9p_transport, NULL); return 0; out: xen_9pfs_free(xendev); return -1; }