qemu/hw/xen/xen_devconfig.c
<<
>>
Prefs
   1#include "qemu/osdep.h"
   2#include "hw/xen/xen_backend.h"
   3#include "sysemu/block-backend.h"
   4#include "sysemu/blockdev.h"
   5
   6/* ------------------------------------------------------------- */
   7
   8struct xs_dirs {
   9    char *xs_dir;
  10    QTAILQ_ENTRY(xs_dirs) list;
  11};
  12static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup = QTAILQ_HEAD_INITIALIZER(xs_cleanup);
  13
  14static void xen_config_cleanup_dir(char *dir)
  15{
  16    struct xs_dirs *d;
  17
  18    d = g_malloc(sizeof(*d));
  19    d->xs_dir = dir;
  20    QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
  21}
  22
  23void xen_config_cleanup(void)
  24{
  25    struct xs_dirs *d;
  26
  27    QTAILQ_FOREACH(d, &xs_cleanup, list) {
  28        xs_rm(xenstore, 0, d->xs_dir);
  29    }
  30}
  31
  32/* ------------------------------------------------------------- */
  33
  34static int xen_config_dev_mkdir(char *dev, int p)
  35{
  36    struct xs_permissions perms[2] = {{
  37            .id    = 0, /* set owner: dom0 */
  38        },{
  39            .id    = xen_domid,
  40            .perms = p,
  41        }};
  42
  43    if (!xs_mkdir(xenstore, 0, dev)) {
  44        xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", dev);
  45        return -1;
  46    }
  47    xen_config_cleanup_dir(g_strdup(dev));
  48
  49    if (!xs_set_permissions(xenstore, 0, dev, perms, 2)) {
  50        xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", dev);
  51        return -1;
  52    }
  53    return 0;
  54}
  55
  56static int xen_config_dev_dirs(const char *ftype, const char *btype, int vdev,
  57                               char *fe, char *be, int len)
  58{
  59    char *dom;
  60
  61    dom = xs_get_domain_path(xenstore, xen_domid);
  62    snprintf(fe, len, "%s/device/%s/%d", dom, ftype, vdev);
  63    free(dom);
  64
  65    dom = xs_get_domain_path(xenstore, 0);
  66    snprintf(be, len, "%s/backend/%s/%d/%d", dom, btype, xen_domid, vdev);
  67    free(dom);
  68
  69    xen_config_dev_mkdir(fe, XS_PERM_READ | XS_PERM_WRITE);
  70    xen_config_dev_mkdir(be, XS_PERM_READ);
  71    return 0;
  72}
  73
  74static int xen_config_dev_all(char *fe, char *be)
  75{
  76    /* frontend */
  77    if (xen_protocol)
  78        xenstore_write_str(fe, "protocol", xen_protocol);
  79
  80    xenstore_write_int(fe, "state",           XenbusStateInitialising);
  81    xenstore_write_int(fe, "backend-id",      0);
  82    xenstore_write_str(fe, "backend",         be);
  83
  84    /* backend */
  85    xenstore_write_str(be, "domain",          qemu_name ? qemu_name : "no-name");
  86    xenstore_write_int(be, "online",          1);
  87    xenstore_write_int(be, "state",           XenbusStateInitialising);
  88    xenstore_write_int(be, "frontend-id",     xen_domid);
  89    xenstore_write_str(be, "frontend",        fe);
  90
  91    return 0;
  92}
  93
  94/* ------------------------------------------------------------- */
  95
  96int xen_config_dev_blk(DriveInfo *disk)
  97{
  98    char fe[256], be[256], device_name[32];
  99    int vdev = 202 * 256 + 16 * disk->unit;
 100    int cdrom = disk->media_cd;
 101    const char *devtype = cdrom ? "cdrom" : "disk";
 102    const char *mode    = cdrom ? "r"     : "w";
 103    const char *filename = qemu_opt_get(disk->opts, "file");
 104
 105    snprintf(device_name, sizeof(device_name), "xvd%c", 'a' + disk->unit);
 106    xen_be_printf(NULL, 1, "config disk %d [%s]: %s\n",
 107                  disk->unit, device_name, filename);
 108    xen_config_dev_dirs("vbd", "qdisk", vdev, fe, be, sizeof(fe));
 109
 110    /* frontend */
 111    xenstore_write_int(fe, "virtual-device",  vdev);
 112    xenstore_write_str(fe, "device-type",     devtype);
 113
 114    /* backend */
 115    xenstore_write_str(be, "dev",             device_name);
 116    xenstore_write_str(be, "type",            "file");
 117    xenstore_write_str(be, "params",          filename);
 118    xenstore_write_str(be, "mode",            mode);
 119
 120    /* common stuff */
 121    return xen_config_dev_all(fe, be);
 122}
 123
 124int xen_config_dev_nic(NICInfo *nic)
 125{
 126    char fe[256], be[256];
 127    char mac[20];
 128    int vlan_id = -1;
 129
 130    net_hub_id_for_client(nic->netdev, &vlan_id);
 131    snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
 132             nic->macaddr.a[0], nic->macaddr.a[1], nic->macaddr.a[2],
 133             nic->macaddr.a[3], nic->macaddr.a[4], nic->macaddr.a[5]);
 134    xen_be_printf(NULL, 1, "config nic %d: mac=\"%s\"\n", vlan_id, mac);
 135    xen_config_dev_dirs("vif", "qnic", vlan_id, fe, be, sizeof(fe));
 136
 137    /* frontend */
 138    xenstore_write_int(fe, "handle",     vlan_id);
 139    xenstore_write_str(fe, "mac",        mac);
 140
 141    /* backend */
 142    xenstore_write_int(be, "handle",     vlan_id);
 143    xenstore_write_str(be, "mac",        mac);
 144
 145    /* common stuff */
 146    return xen_config_dev_all(fe, be);
 147}
 148
 149int xen_config_dev_vfb(int vdev, const char *type)
 150{
 151    char fe[256], be[256];
 152
 153    xen_config_dev_dirs("vfb", "vfb", vdev, fe, be, sizeof(fe));
 154
 155    /* backend */
 156    xenstore_write_str(be, "type",  type);
 157
 158    /* common stuff */
 159    return xen_config_dev_all(fe, be);
 160}
 161
 162int xen_config_dev_vkbd(int vdev)
 163{
 164    char fe[256], be[256];
 165
 166    xen_config_dev_dirs("vkbd", "vkbd", vdev, fe, be, sizeof(fe));
 167    return xen_config_dev_all(fe, be);
 168}
 169
 170int xen_config_dev_console(int vdev)
 171{
 172    char fe[256], be[256];
 173
 174    xen_config_dev_dirs("console", "console", vdev, fe, be, sizeof(fe));
 175    return xen_config_dev_all(fe, be);
 176}
 177