Drop the open-coded MAC assignment from net_init_nic and replace it with standard qemu_macaddr_default_if_unset which is also used by qdev. That avoid creating colliding MACs when instantiating NICs via different mechanisms. This change requires to store the MAC as MACAddr in NICInfo, and the remaining nd_table users need to be updated. Based on suggestion by Peter Maydell. CC: Markus Armbruster <armbru@redhat.com> CC: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
174 lines
4.8 KiB
C
174 lines
4.8 KiB
C
#include "xen_backend.h"
|
|
#include "blockdev.h"
|
|
#include "block_int.h" /* XXX */
|
|
|
|
/* ------------------------------------------------------------- */
|
|
|
|
struct xs_dirs {
|
|
char *xs_dir;
|
|
QTAILQ_ENTRY(xs_dirs) list;
|
|
};
|
|
static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup = QTAILQ_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;
|
|
QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
|
|
}
|
|
|
|
void xen_config_cleanup(void)
|
|
{
|
|
struct xs_dirs *d;
|
|
|
|
QTAILQ_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->media_cd;
|
|
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.a[0], nic->macaddr.a[1], nic->macaddr.a[2],
|
|
nic->macaddr.a[3], nic->macaddr.a[4], nic->macaddr.a[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);
|
|
}
|
|
|
|
int xen_config_dev_vfb(int vdev, const char *type)
|
|
{
|
|
char fe[256], be[256];
|
|
|
|
xen_config_dev_dirs("vfb", "vfb", vdev, fe, be, sizeof(fe));
|
|
|
|
/* backend */
|
|
xenstore_write_str(be, "type", type);
|
|
|
|
/* common stuff */
|
|
return xen_config_dev_all(fe, be);
|
|
}
|
|
|
|
int xen_config_dev_vkbd(int vdev)
|
|
{
|
|
char fe[256], be[256];
|
|
|
|
xen_config_dev_dirs("vkbd", "vkbd", vdev, fe, be, sizeof(fe));
|
|
return xen_config_dev_all(fe, be);
|
|
}
|
|
|
|
int xen_config_dev_console(int vdev)
|
|
{
|
|
char fe[256], be[256];
|
|
|
|
xen_config_dev_dirs("console", "console", vdev, fe, be, sizeof(fe));
|
|
return xen_config_dev_all(fe, be);
|
|
}
|