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