if (STREQ(format, XEN_CONFIG_FORMAT_XM)) {
int len = MAX_CONFIG_SIZE;
- conf = xenXMDomainConfigFormat(conn, def);
+ conf = xenXMDomainConfigFormat(conn, def, priv->xendConfigVersion);
if (!conf)
goto cleanup;
to sched.h, so we'll match that for now */
#define XEN_MAX_PHYSICAL_CPU 1024
-static int xenXMConfigSetString(virConfPtr conf, const char *setting,
- const char *str);
char * xenXMAutoAssignMac(void);
static int xenXMDomainAttachDeviceFlags(virDomainPtr domain, const char *xml,
unsigned int flags);
static int
xenXMConfigSaveFile(virConnectPtr conn, const char *filename, virDomainDefPtr def) {
virConfPtr conf;
+ xenUnifiedPrivatePtr priv = conn->privateData;
int ret;
- if (!(conf = xenXMDomainConfigFormat(conn, def)))
+ if (!(conf = xenXMDomainConfigFormat(conn, def, priv->xendConfigVersion)))
return -1;
ret = virConfWriteFile(filename, conf);
return (-1);
}
-
-static
-int xenXMConfigSetInt(virConfPtr conf, const char *setting, long l) {
- virConfValuePtr value = NULL;
-
- if (VIR_ALLOC(value) < 0) {
- virReportOOMError();
- return -1;
- }
-
- value->type = VIR_CONF_LONG;
- value->next = NULL;
- value->l = l;
-
- return virConfSetValue(conf, setting, value);
-}
-
-
-static
-int xenXMConfigSetString(virConfPtr conf, const char *setting, const char *str) {
- virConfValuePtr value = NULL;
-
- if (VIR_ALLOC(value) < 0) {
- virReportOOMError();
- return -1;
- }
-
- value->type = VIR_CONF_STRING;
- value->next = NULL;
- if (!(value->str = strdup(str))) {
- VIR_FREE(value);
- virReportOOMError();
- return -1;
- }
-
- return virConfSetValue(conf, setting, value);
-}
-
-
-static int xenXMDomainConfigFormatDisk(virConfValuePtr list,
- virDomainDiskDefPtr disk,
- int hvm,
- int xendConfigVersion)
-{
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- virConfValuePtr val, tmp;
-
- if(disk->src) {
- if (disk->driverName) {
- virBufferVSprintf(&buf, "%s:", disk->driverName);
- if (STREQ(disk->driverName, "tap"))
- virBufferVSprintf(&buf, "%s:", disk->driverType ? disk->driverType : "aio");
- } else {
- switch (disk->type) {
- case VIR_DOMAIN_DISK_TYPE_FILE:
- virBufferAddLit(&buf, "file:");
- break;
- case VIR_DOMAIN_DISK_TYPE_BLOCK:
- virBufferAddLit(&buf, "phy:");
- break;
- default:
- xenXMError(VIR_ERR_INTERNAL_ERROR,
- _("unsupported disk type %s"),
- virDomainDiskTypeToString(disk->type));
- goto cleanup;
- }
- }
- virBufferVSprintf(&buf, "%s", disk->src);
- }
- virBufferAddLit(&buf, ",");
- if (hvm && xendConfigVersion == 1)
- virBufferAddLit(&buf, "ioemu:");
-
- virBufferVSprintf(&buf, "%s", disk->dst);
- if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
- virBufferAddLit(&buf, ":cdrom");
-
- if (disk->readonly)
- virBufferAddLit(&buf, ",r");
- else if (disk->shared)
- virBufferAddLit(&buf, ",!");
- else
- virBufferAddLit(&buf, ",w");
-
- if (virBufferError(&buf)) {
- virReportOOMError();
- goto cleanup;
- }
-
- if (VIR_ALLOC(val) < 0) {
- virReportOOMError();
- goto cleanup;
- }
-
- val->type = VIR_CONF_STRING;
- val->str = virBufferContentAndReset(&buf);
- tmp = list->list;
- while (tmp && tmp->next)
- tmp = tmp->next;
- if (tmp)
- tmp->next = val;
- else
- list->list = val;
-
- return 0;
-
-cleanup:
- virBufferFreeAndReset(&buf);
- return -1;
-}
-
-static int xenXMDomainConfigFormatNet(virConnectPtr conn,
- virConfValuePtr list,
- virDomainNetDefPtr net,
- int hvm)
-{
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- virConfValuePtr val, tmp;
- xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
-
- virBufferVSprintf(&buf, "mac=%02x:%02x:%02x:%02x:%02x:%02x",
- net->mac[0], net->mac[1],
- net->mac[2], net->mac[3],
- net->mac[4], net->mac[5]);
-
- switch (net->type) {
- case VIR_DOMAIN_NET_TYPE_BRIDGE:
- virBufferVSprintf(&buf, ",bridge=%s", net->data.bridge.brname);
- if (net->data.bridge.ipaddr)
- virBufferVSprintf(&buf, ",ip=%s", net->data.bridge.ipaddr);
- virBufferVSprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
- break;
-
- case VIR_DOMAIN_NET_TYPE_ETHERNET:
- if (net->data.ethernet.script)
- virBufferVSprintf(&buf, ",script=%s", net->data.ethernet.script);
- if (net->data.ethernet.ipaddr)
- virBufferVSprintf(&buf, ",ip=%s", net->data.ethernet.ipaddr);
- break;
-
- case VIR_DOMAIN_NET_TYPE_NETWORK:
- {
- virNetworkPtr network = virNetworkLookupByName(conn, net->data.network.name);
- char *bridge;
- if (!network) {
- xenXMError(VIR_ERR_NO_NETWORK, "%s",
- net->data.network.name);
- return -1;
- }
- bridge = virNetworkGetBridgeName(network);
- virNetworkFree(network);
- if (!bridge) {
- xenXMError(VIR_ERR_INTERNAL_ERROR,
- _("network %s is not active"),
- net->data.network.name);
- return -1;
- }
-
- virBufferVSprintf(&buf, ",bridge=%s", bridge);
- virBufferVSprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
- }
- break;
-
- default:
- xenXMError(VIR_ERR_INTERNAL_ERROR,
- _("unsupported network type %d"),
- net->type);
- goto cleanup;
- }
-
- if (!hvm) {
- if (net->model != NULL)
- virBufferVSprintf(&buf, ",model=%s", net->model);
- }
- else if (net->model == NULL) {
- /*
- * apparently type ioemu breaks paravirt drivers on HVM so skip this
- * from XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU
- */
- if (priv->xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
- virBufferAddLit(&buf, ",type=ioemu");
- }
- else if (STREQ(net->model, "netfront")) {
- virBufferAddLit(&buf, ",type=netfront");
- }
- else {
- virBufferVSprintf(&buf, ",model=%s", net->model);
- virBufferAddLit(&buf, ",type=ioemu");
- }
-
- if (net->ifname)
- virBufferVSprintf(&buf, ",vifname=%s",
- net->ifname);
-
- if (virBufferError(&buf)) {
- virReportOOMError();
- goto cleanup;
- }
-
- if (VIR_ALLOC(val) < 0) {
- virReportOOMError();
- goto cleanup;
- }
-
- val->type = VIR_CONF_STRING;
- val->str = virBufferContentAndReset(&buf);
- tmp = list->list;
- while (tmp && tmp->next)
- tmp = tmp->next;
- if (tmp)
- tmp->next = val;
- else
- list->list = val;
-
- return 0;
-
-cleanup:
- virBufferFreeAndReset(&buf);
- return -1;
-}
-
-
-
-static int
-xenXMDomainConfigFormatPCI(virConfPtr conf,
- virDomainDefPtr def)
-{
-
- virConfValuePtr pciVal = NULL;
- int hasPCI = 0;
- int i;
-
- for (i = 0 ; i < def->nhostdevs ; i++)
- if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
- def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
- hasPCI = 1;
-
- if (!hasPCI)
- return 0;
-
- if (VIR_ALLOC(pciVal) < 0) {
- virReportOOMError();
- return -1;
- }
-
- pciVal->type = VIR_CONF_LIST;
- pciVal->list = NULL;
-
- for (i = 0 ; i < def->nhostdevs ; i++) {
- if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
- def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
- virConfValuePtr val, tmp;
- char *buf;
-
- if (virAsprintf(&buf, "%04x:%02x:%02x.%x",
- def->hostdevs[i]->source.subsys.u.pci.domain,
- def->hostdevs[i]->source.subsys.u.pci.bus,
- def->hostdevs[i]->source.subsys.u.pci.slot,
- def->hostdevs[i]->source.subsys.u.pci.function) < 0) {
- virReportOOMError();
- goto error;
- }
-
- if (VIR_ALLOC(val) < 0) {
- VIR_FREE(buf);
- virReportOOMError();
- goto error;
- }
- val->type = VIR_CONF_STRING;
- val->str = buf;
- tmp = pciVal->list;
- while (tmp && tmp->next)
- tmp = tmp->next;
- if (tmp)
- tmp->next = val;
- else
- pciVal->list = val;
- }
- }
-
- if (pciVal->list != NULL) {
- int ret = virConfSetValue(conf, "pci", pciVal);
- pciVal = NULL;
- if (ret < 0)
- return -1;
- }
- VIR_FREE(pciVal);
-
- return 0;
-
-error:
- virConfFreeValue(pciVal);
- return -1;
-}
-
-
-/* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is
- either 32, or 64 on a platform where long is big enough. */
-verify(MAX_VIRT_CPUS <= sizeof(1UL) * CHAR_BIT);
-
-virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
- virDomainDefPtr def) {
- virConfPtr conf = NULL;
- int hvm = 0, i;
- xenUnifiedPrivatePtr priv;
- char *cpus = NULL;
- const char *lifecycle;
- char uuid[VIR_UUID_STRING_BUFLEN];
- virConfValuePtr diskVal = NULL;
- virConfValuePtr netVal = NULL;
-
- priv = (xenUnifiedPrivatePtr) conn->privateData;
-
- if (!(conf = virConfNew()))
- goto cleanup;
-
-
- if (xenXMConfigSetString(conf, "name", def->name) < 0)
- goto no_memory;
-
- virUUIDFormat(def->uuid, uuid);
- if (xenXMConfigSetString(conf, "uuid", uuid) < 0)
- goto no_memory;
-
- if (xenXMConfigSetInt(conf, "maxmem", VIR_DIV_UP(def->mem.max_balloon, 1024)) < 0)
- goto no_memory;
-
- if (xenXMConfigSetInt(conf, "memory", VIR_DIV_UP(def->mem.cur_balloon, 1024)) < 0)
- goto no_memory;
-
- if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
- goto no_memory;
- /* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is
- either 32, or 64 on a platform where long is big enough. */
- if (def->vcpus < def->maxvcpus &&
- xenXMConfigSetInt(conf, "vcpu_avail", (1UL << def->vcpus) - 1) < 0)
- goto no_memory;
-
- if ((def->cpumask != NULL) &&
- ((cpus = virDomainCpuSetFormat(def->cpumask,
- def->cpumasklen)) == NULL))
- goto cleanup;
-
- if (cpus &&
- xenXMConfigSetString(conf, "cpus", cpus) < 0)
- goto no_memory;
- VIR_FREE(cpus);
-
- hvm = STREQ(def->os.type, "hvm") ? 1 : 0;
-
- if (hvm) {
- char boot[VIR_DOMAIN_BOOT_LAST+1];
- if (xenXMConfigSetString(conf, "builder", "hvm") < 0)
- goto no_memory;
-
- if (def->os.loader &&
- xenXMConfigSetString(conf, "kernel", def->os.loader) < 0)
- goto no_memory;
-
- for (i = 0 ; i < def->os.nBootDevs ; i++) {
- switch (def->os.bootDevs[i]) {
- case VIR_DOMAIN_BOOT_FLOPPY:
- boot[i] = 'a';
- break;
- case VIR_DOMAIN_BOOT_CDROM:
- boot[i] = 'd';
- break;
- case VIR_DOMAIN_BOOT_NET:
- boot[i] = 'n';
- break;
- case VIR_DOMAIN_BOOT_DISK:
- default:
- boot[i] = 'c';
- break;
- }
- }
- if (!def->os.nBootDevs) {
- boot[0] = 'c';
- boot[1] = '\0';
- } else {
- boot[def->os.nBootDevs] = '\0';
- }
-
- if (xenXMConfigSetString(conf, "boot", boot) < 0)
- goto no_memory;
-
- if (xenXMConfigSetInt(conf, "pae",
- (def->features &
- (1 << VIR_DOMAIN_FEATURE_PAE)) ? 1 : 0) < 0)
- goto no_memory;
-
- if (xenXMConfigSetInt(conf, "acpi",
- (def->features &
- (1 << VIR_DOMAIN_FEATURE_ACPI)) ? 1 : 0) < 0)
- goto no_memory;
-
- if (xenXMConfigSetInt(conf, "apic",
- (def->features &
- (1 << VIR_DOMAIN_FEATURE_APIC)) ? 1 : 0) < 0)
- goto no_memory;
-
- if (priv->xendConfigVersion >= 3)
- if (xenXMConfigSetInt(conf, "hap",
- (def->features &
- (1 << VIR_DOMAIN_FEATURE_HAP)) ? 1 : 0) < 0)
- goto no_memory;
-
- if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME) {
- if (def->clock.data.timezone) {
- xenXMError(VIR_ERR_CONFIG_UNSUPPORTED,
- "%s", _("configurable timezones are not supported"));
- goto cleanup;
- }
-
- if (xenXMConfigSetInt(conf, "localtime", 1) < 0)
- goto no_memory;
- } else if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_UTC) {
- if (xenXMConfigSetInt(conf, "localtime", 0) < 0)
- goto no_memory;
- } else {
- /* XXX We could support Xen's rtc clock offset */
- xenXMError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("unsupported clock offset '%s'"),
- virDomainClockOffsetTypeToString(def->clock.offset));
- goto cleanup;
- }
-
- if (priv->xendConfigVersion == 1) {
- for (i = 0 ; i < def->ndisks ; i++) {
- if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
- def->disks[i]->dst &&
- STREQ(def->disks[i]->dst, "hdc") &&
- def->disks[i]->src) {
- if (xenXMConfigSetString(conf, "cdrom",
- def->disks[i]->src) < 0)
- goto no_memory;
- break;
- }
- }
- }
-
- /* XXX floppy disks */
- } else {
- if (def->os.bootloader &&
- xenXMConfigSetString(conf, "bootloader", def->os.bootloader) < 0)
- goto no_memory;
- if (def->os.bootloaderArgs &&
- xenXMConfigSetString(conf, "bootargs", def->os.bootloaderArgs) < 0)
- goto no_memory;
- if (def->os.kernel &&
- xenXMConfigSetString(conf, "kernel", def->os.kernel) < 0)
- goto no_memory;
- if (def->os.initrd &&
- xenXMConfigSetString(conf, "ramdisk", def->os.initrd) < 0)
- goto no_memory;
- if (def->os.cmdline &&
- xenXMConfigSetString(conf, "extra", def->os.cmdline) < 0)
- goto no_memory;
-
- }
-
- if (!(lifecycle = virDomainLifecycleTypeToString(def->onPoweroff))) {
- xenXMError(VIR_ERR_INTERNAL_ERROR,
- _("unexpected lifecycle action %d"), def->onPoweroff);
- goto cleanup;
- }
- if (xenXMConfigSetString(conf, "on_poweroff", lifecycle) < 0)
- goto no_memory;
-
-
- if (!(lifecycle = virDomainLifecycleTypeToString(def->onReboot))) {
- xenXMError(VIR_ERR_INTERNAL_ERROR,
- _("unexpected lifecycle action %d"), def->onReboot);
- goto cleanup;
- }
- if (xenXMConfigSetString(conf, "on_reboot", lifecycle) < 0)
- goto no_memory;
-
-
- if (!(lifecycle = virDomainLifecycleCrashTypeToString(def->onCrash))) {
- xenXMError(VIR_ERR_INTERNAL_ERROR,
- _("unexpected lifecycle action %d"), def->onCrash);
- goto cleanup;
- }
- if (xenXMConfigSetString(conf, "on_crash", lifecycle) < 0)
- goto no_memory;
-
-
-
- if (hvm) {
- if (def->emulator &&
- xenXMConfigSetString(conf, "device_model", def->emulator) < 0)
- goto no_memory;
-
- for (i = 0 ; i < def->ninputs ; i++) {
- if (def->inputs[i]->bus == VIR_DOMAIN_INPUT_BUS_USB) {
- if (xenXMConfigSetInt(conf, "usb", 1) < 0)
- goto no_memory;
- if (xenXMConfigSetString(conf, "usbdevice",
- def->inputs[i]->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ?
- "mouse" : "tablet") < 0)
- goto no_memory;
- break;
- }
- }
- }
-
- if (def->ngraphics == 1) {
- if (priv->xendConfigVersion < (hvm ? 4 : XEND_CONFIG_MIN_VERS_PVFB_NEWCONF)) {
- if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
- if (xenXMConfigSetInt(conf, "sdl", 1) < 0)
- goto no_memory;
- if (xenXMConfigSetInt(conf, "vnc", 0) < 0)
- goto no_memory;
- if (def->graphics[0]->data.sdl.display &&
- xenXMConfigSetString(conf, "display",
- def->graphics[0]->data.sdl.display) < 0)
- goto no_memory;
- if (def->graphics[0]->data.sdl.xauth &&
- xenXMConfigSetString(conf, "xauthority",
- def->graphics[0]->data.sdl.xauth) < 0)
- goto no_memory;
- } else {
- if (xenXMConfigSetInt(conf, "sdl", 0) < 0)
- goto no_memory;
- if (xenXMConfigSetInt(conf, "vnc", 1) < 0)
- goto no_memory;
- if (xenXMConfigSetInt(conf, "vncunused",
- def->graphics[0]->data.vnc.autoport ? 1 : 0) < 0)
- goto no_memory;
- if (!def->graphics[0]->data.vnc.autoport &&
- xenXMConfigSetInt(conf, "vncdisplay",
- def->graphics[0]->data.vnc.port - 5900) < 0)
- goto no_memory;
- if (def->graphics[0]->data.vnc.listenAddr &&
- xenXMConfigSetString(conf, "vnclisten",
- def->graphics[0]->data.vnc.listenAddr) < 0)
- goto no_memory;
- if (def->graphics[0]->data.vnc.auth.passwd &&
- xenXMConfigSetString(conf, "vncpasswd",
- def->graphics[0]->data.vnc.auth.passwd) < 0)
- goto no_memory;
- if (def->graphics[0]->data.vnc.keymap &&
- xenXMConfigSetString(conf, "keymap",
- def->graphics[0]->data.vnc.keymap) < 0)
- goto no_memory;
- }
- } else {
- virConfValuePtr vfb, disp;
- char *vfbstr = NULL;
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
- virBufferAddLit(&buf, "type=sdl");
- if (def->graphics[0]->data.sdl.display)
- virBufferVSprintf(&buf, ",display=%s",
- def->graphics[0]->data.sdl.display);
- if (def->graphics[0]->data.sdl.xauth)
- virBufferVSprintf(&buf, ",xauthority=%s",
- def->graphics[0]->data.sdl.xauth);
- } else {
- virBufferAddLit(&buf, "type=vnc");
- virBufferVSprintf(&buf, ",vncunused=%d",
- def->graphics[0]->data.vnc.autoport ? 1 : 0);
- if (!def->graphics[0]->data.vnc.autoport)
- virBufferVSprintf(&buf, ",vncdisplay=%d",
- def->graphics[0]->data.vnc.port - 5900);
- if (def->graphics[0]->data.vnc.listenAddr)
- virBufferVSprintf(&buf, ",vnclisten=%s",
- def->graphics[0]->data.vnc.listenAddr);
- if (def->graphics[0]->data.vnc.auth.passwd)
- virBufferVSprintf(&buf, ",vncpasswd=%s",
- def->graphics[0]->data.vnc.auth.passwd);
- if (def->graphics[0]->data.vnc.keymap)
- virBufferVSprintf(&buf, ",keymap=%s",
- def->graphics[0]->data.vnc.keymap);
- }
- if (virBufferError(&buf)) {
- virBufferFreeAndReset(&buf);
- goto no_memory;
- }
-
- vfbstr = virBufferContentAndReset(&buf);
-
- if (VIR_ALLOC(vfb) < 0) {
- VIR_FREE(vfbstr);
- goto no_memory;
- }
-
- if (VIR_ALLOC(disp) < 0) {
- VIR_FREE(vfb);
- VIR_FREE(vfbstr);
- goto no_memory;
- }
-
- vfb->type = VIR_CONF_LIST;
- vfb->list = disp;
- disp->type = VIR_CONF_STRING;
- disp->str = vfbstr;
-
- if (virConfSetValue(conf, "vfb", vfb) < 0)
- goto no_memory;
- }
- }
-
- /* analyze of the devices */
- if (VIR_ALLOC(diskVal) < 0)
- goto no_memory;
- diskVal->type = VIR_CONF_LIST;
- diskVal->list = NULL;
-
- for (i = 0 ; i < def->ndisks ; i++) {
- if (priv->xendConfigVersion == 1 &&
- def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
- def->disks[i]->dst &&
- STREQ(def->disks[i]->dst, "hdc")) {
- continue;
- }
- if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
- continue;
-
- if (xenXMDomainConfigFormatDisk(diskVal, def->disks[i],
- hvm, priv->xendConfigVersion) < 0)
- goto cleanup;
- }
- if (diskVal->list != NULL) {
- int ret = virConfSetValue(conf, "disk", diskVal);
- diskVal = NULL;
- if (ret < 0)
- goto no_memory;
- }
- VIR_FREE(diskVal);
-
- if (VIR_ALLOC(netVal) < 0)
- goto no_memory;
- netVal->type = VIR_CONF_LIST;
- netVal->list = NULL;
-
- for (i = 0 ; i < def->nnets ; i++) {
- if (xenXMDomainConfigFormatNet(conn, netVal,
- def->nets[i],
- hvm) < 0)
- goto cleanup;
- }
- if (netVal->list != NULL) {
- int ret = virConfSetValue(conf, "vif", netVal);
- netVal = NULL;
- if (ret < 0)
- goto no_memory;
- }
- VIR_FREE(netVal);
-
- if (xenXMDomainConfigFormatPCI(conf, def) < 0)
- goto cleanup;
-
- if (hvm) {
- if (def->nparallels) {
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *str;
- int ret;
-
- ret = xenDaemonFormatSxprChr(def->parallels[0], &buf);
- str = virBufferContentAndReset(&buf);
- if (ret == 0)
- ret = xenXMConfigSetString(conf, "parallel", str);
- VIR_FREE(str);
- if (ret < 0)
- goto no_memory;
- } else {
- if (xenXMConfigSetString(conf, "parallel", "none") < 0)
- goto no_memory;
- }
-
- if (def->nserials) {
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *str;
- int ret;
-
- ret = xenDaemonFormatSxprChr(def->serials[0], &buf);
- str = virBufferContentAndReset(&buf);
- if (ret == 0)
- ret = xenXMConfigSetString(conf, "serial", str);
- VIR_FREE(str);
- if (ret < 0)
- goto no_memory;
- } else {
- if (xenXMConfigSetString(conf, "serial", "none") < 0)
- goto no_memory;
- }
-
-
- if (def->sounds) {
- virBuffer buf = VIR_BUFFER_INITIALIZER;
- char *str = NULL;
- int ret = xenDaemonFormatSxprSound(def, &buf);
- str = virBufferContentAndReset(&buf);
- if (ret == 0)
- ret = xenXMConfigSetString(conf, "soundhw", str);
-
- VIR_FREE(str);
- if (ret < 0)
- goto no_memory;
- }
- }
-
- return conf;
-
-no_memory:
- virReportOOMError();
-
-cleanup:
- virConfFreeValue(diskVal);
- virConfFreeValue(netVal);
- VIR_FREE(cpus);
- if (conf)
- virConfFree(conf);
- return (NULL);
-}
-
/*
* Create a config file for a domain, based on an XML
* document describing its config
virDomainPtr xenXMDomainDefineXML(virConnectPtr con, const char *xml);
int xenXMDomainUndefine(virDomainPtr domain);
-virConfPtr xenXMDomainConfigFormat(virConnectPtr conn, virDomainDefPtr def);
-
int xenXMDomainBlockPeek (virDomainPtr dom, const char *path, unsigned long long offset, size_t size, void *buffer);
int xenXMDomainGetAutostart(virDomainPtr dom, int *autostart);
# include "domain_conf.h"
# include "sexpr.h"
-# ifdef __sun
-# define DEFAULT_VIF_SCRIPT "vif-vnic"
-# else
-# define DEFAULT_VIF_SCRIPT "vif-bridge"
-# endif
-
/* helper functions to get the dom id from a sexpr */
int xenGetDomIdFromSxprString(const char *sexpr, int xendConfigVersion);
int xenGetDomIdFromSxpr(const struct sexpr *root, int xendConfigVersion);
virDomainDefFree(def);
return NULL;
}
+
+
+static
+int xenXMConfigSetInt(virConfPtr conf, const char *setting, long l) {
+ virConfValuePtr value = NULL;
+
+ if (VIR_ALLOC(value) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ value->type = VIR_CONF_LONG;
+ value->next = NULL;
+ value->l = l;
+
+ return virConfSetValue(conf, setting, value);
+}
+
+
+static
+int xenXMConfigSetString(virConfPtr conf, const char *setting, const char *str) {
+ virConfValuePtr value = NULL;
+
+ if (VIR_ALLOC(value) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ value->type = VIR_CONF_STRING;
+ value->next = NULL;
+ if (!(value->str = strdup(str))) {
+ VIR_FREE(value);
+ virReportOOMError();
+ return -1;
+ }
+
+ return virConfSetValue(conf, setting, value);
+}
+
+
+static int xenXMDomainConfigFormatDisk(virConfValuePtr list,
+ virDomainDiskDefPtr disk,
+ int hvm,
+ int xendConfigVersion)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ virConfValuePtr val, tmp;
+
+ if(disk->src) {
+ if (disk->driverName) {
+ virBufferVSprintf(&buf, "%s:", disk->driverName);
+ if (STREQ(disk->driverName, "tap"))
+ virBufferVSprintf(&buf, "%s:", disk->driverType ? disk->driverType : "aio");
+ } else {
+ switch (disk->type) {
+ case VIR_DOMAIN_DISK_TYPE_FILE:
+ virBufferAddLit(&buf, "file:");
+ break;
+ case VIR_DOMAIN_DISK_TYPE_BLOCK:
+ virBufferAddLit(&buf, "phy:");
+ break;
+ default:
+ XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("unsupported disk type %s"),
+ virDomainDiskTypeToString(disk->type));
+ goto cleanup;
+ }
+ }
+ virBufferVSprintf(&buf, "%s", disk->src);
+ }
+ virBufferAddLit(&buf, ",");
+ if (hvm && xendConfigVersion == 1)
+ virBufferAddLit(&buf, "ioemu:");
+
+ virBufferVSprintf(&buf, "%s", disk->dst);
+ if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
+ virBufferAddLit(&buf, ":cdrom");
+
+ if (disk->readonly)
+ virBufferAddLit(&buf, ",r");
+ else if (disk->shared)
+ virBufferAddLit(&buf, ",!");
+ else
+ virBufferAddLit(&buf, ",w");
+
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC(val) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ val->type = VIR_CONF_STRING;
+ val->str = virBufferContentAndReset(&buf);
+ tmp = list->list;
+ while (tmp && tmp->next)
+ tmp = tmp->next;
+ if (tmp)
+ tmp->next = val;
+ else
+ list->list = val;
+
+ return 0;
+
+cleanup:
+ virBufferFreeAndReset(&buf);
+ return -1;
+}
+
+static int xenXMDomainConfigFormatNet(virConnectPtr conn,
+ virConfValuePtr list,
+ virDomainNetDefPtr net,
+ int hvm, int xendConfigVersion)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ virConfValuePtr val, tmp;
+
+ virBufferVSprintf(&buf, "mac=%02x:%02x:%02x:%02x:%02x:%02x",
+ net->mac[0], net->mac[1],
+ net->mac[2], net->mac[3],
+ net->mac[4], net->mac[5]);
+
+ switch (net->type) {
+ case VIR_DOMAIN_NET_TYPE_BRIDGE:
+ virBufferVSprintf(&buf, ",bridge=%s", net->data.bridge.brname);
+ if (net->data.bridge.ipaddr)
+ virBufferVSprintf(&buf, ",ip=%s", net->data.bridge.ipaddr);
+ virBufferVSprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
+ break;
+
+ case VIR_DOMAIN_NET_TYPE_ETHERNET:
+ if (net->data.ethernet.script)
+ virBufferVSprintf(&buf, ",script=%s", net->data.ethernet.script);
+ if (net->data.ethernet.ipaddr)
+ virBufferVSprintf(&buf, ",ip=%s", net->data.ethernet.ipaddr);
+ break;
+
+ case VIR_DOMAIN_NET_TYPE_NETWORK:
+ {
+ virNetworkPtr network = virNetworkLookupByName(conn, net->data.network.name);
+ char *bridge;
+ if (!network) {
+ XENXS_ERROR(VIR_ERR_NO_NETWORK, "%s",
+ net->data.network.name);
+ return -1;
+ }
+ bridge = virNetworkGetBridgeName(network);
+ virNetworkFree(network);
+ if (!bridge) {
+ XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("network %s is not active"),
+ net->data.network.name);
+ return -1;
+ }
+
+ virBufferVSprintf(&buf, ",bridge=%s", bridge);
+ virBufferVSprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
+ }
+ break;
+
+ default:
+ XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("unsupported network type %d"),
+ net->type);
+ goto cleanup;
+ }
+
+ if (!hvm) {
+ if (net->model != NULL)
+ virBufferVSprintf(&buf, ",model=%s", net->model);
+ }
+ else if (net->model == NULL) {
+ /*
+ * apparently type ioemu breaks paravirt drivers on HVM so skip this
+ * from XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU
+ */
+ if (xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
+ virBufferAddLit(&buf, ",type=ioemu");
+ }
+ else if (STREQ(net->model, "netfront")) {
+ virBufferAddLit(&buf, ",type=netfront");
+ }
+ else {
+ virBufferVSprintf(&buf, ",model=%s", net->model);
+ virBufferAddLit(&buf, ",type=ioemu");
+ }
+
+ if (net->ifname)
+ virBufferVSprintf(&buf, ",vifname=%s",
+ net->ifname);
+
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC(val) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ val->type = VIR_CONF_STRING;
+ val->str = virBufferContentAndReset(&buf);
+ tmp = list->list;
+ while (tmp && tmp->next)
+ tmp = tmp->next;
+ if (tmp)
+ tmp->next = val;
+ else
+ list->list = val;
+
+ return 0;
+
+cleanup:
+ virBufferFreeAndReset(&buf);
+ return -1;
+}
+
+
+
+static int
+xenXMDomainConfigFormatPCI(virConfPtr conf,
+ virDomainDefPtr def)
+{
+
+ virConfValuePtr pciVal = NULL;
+ int hasPCI = 0;
+ int i;
+
+ for (i = 0 ; i < def->nhostdevs ; i++)
+ if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+ hasPCI = 1;
+
+ if (!hasPCI)
+ return 0;
+
+ if (VIR_ALLOC(pciVal) < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ pciVal->type = VIR_CONF_LIST;
+ pciVal->list = NULL;
+
+ for (i = 0 ; i < def->nhostdevs ; i++) {
+ if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+ virConfValuePtr val, tmp;
+ char *buf;
+
+ if (virAsprintf(&buf, "%04x:%02x:%02x.%x",
+ def->hostdevs[i]->source.subsys.u.pci.domain,
+ def->hostdevs[i]->source.subsys.u.pci.bus,
+ def->hostdevs[i]->source.subsys.u.pci.slot,
+ def->hostdevs[i]->source.subsys.u.pci.function) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ if (VIR_ALLOC(val) < 0) {
+ VIR_FREE(buf);
+ virReportOOMError();
+ goto error;
+ }
+ val->type = VIR_CONF_STRING;
+ val->str = buf;
+ tmp = pciVal->list;
+ while (tmp && tmp->next)
+ tmp = tmp->next;
+ if (tmp)
+ tmp->next = val;
+ else
+ pciVal->list = val;
+ }
+ }
+
+ if (pciVal->list != NULL) {
+ int ret = virConfSetValue(conf, "pci", pciVal);
+ pciVal = NULL;
+ if (ret < 0)
+ return -1;
+ }
+ VIR_FREE(pciVal);
+
+ return 0;
+
+error:
+ virConfFreeValue(pciVal);
+ return -1;
+}
+
+
+/* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is
+ either 32, or 64 on a platform where long is big enough. */
+verify(MAX_VIRT_CPUS <= sizeof(1UL) * CHAR_BIT);
+
+virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
+ virDomainDefPtr def,
+ int xendConfigVersion) {
+ virConfPtr conf = NULL;
+ int hvm = 0, i;
+ char *cpus = NULL;
+ const char *lifecycle;
+ char uuid[VIR_UUID_STRING_BUFLEN];
+ virConfValuePtr diskVal = NULL;
+ virConfValuePtr netVal = NULL;
+
+ if (!(conf = virConfNew()))
+ goto cleanup;
+
+
+ if (xenXMConfigSetString(conf, "name", def->name) < 0)
+ goto no_memory;
+
+ virUUIDFormat(def->uuid, uuid);
+ if (xenXMConfigSetString(conf, "uuid", uuid) < 0)
+ goto no_memory;
+
+ if (xenXMConfigSetInt(conf, "maxmem", VIR_DIV_UP(def->mem.max_balloon, 1024)) < 0)
+ goto no_memory;
+
+ if (xenXMConfigSetInt(conf, "memory", VIR_DIV_UP(def->mem.cur_balloon, 1024)) < 0)
+ goto no_memory;
+
+ if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
+ goto no_memory;
+ /* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is
+ either 32, or 64 on a platform where long is big enough. */
+ if (def->vcpus < def->maxvcpus &&
+ xenXMConfigSetInt(conf, "vcpu_avail", (1UL << def->vcpus) - 1) < 0)
+ goto no_memory;
+
+ if ((def->cpumask != NULL) &&
+ ((cpus = virDomainCpuSetFormat(def->cpumask,
+ def->cpumasklen)) == NULL))
+ goto cleanup;
+
+ if (cpus &&
+ xenXMConfigSetString(conf, "cpus", cpus) < 0)
+ goto no_memory;
+ VIR_FREE(cpus);
+
+ hvm = STREQ(def->os.type, "hvm") ? 1 : 0;
+
+ if (hvm) {
+ char boot[VIR_DOMAIN_BOOT_LAST+1];
+ if (xenXMConfigSetString(conf, "builder", "hvm") < 0)
+ goto no_memory;
+
+ if (def->os.loader &&
+ xenXMConfigSetString(conf, "kernel", def->os.loader) < 0)
+ goto no_memory;
+
+ for (i = 0 ; i < def->os.nBootDevs ; i++) {
+ switch (def->os.bootDevs[i]) {
+ case VIR_DOMAIN_BOOT_FLOPPY:
+ boot[i] = 'a';
+ break;
+ case VIR_DOMAIN_BOOT_CDROM:
+ boot[i] = 'd';
+ break;
+ case VIR_DOMAIN_BOOT_NET:
+ boot[i] = 'n';
+ break;
+ case VIR_DOMAIN_BOOT_DISK:
+ default:
+ boot[i] = 'c';
+ break;
+ }
+ }
+ if (!def->os.nBootDevs) {
+ boot[0] = 'c';
+ boot[1] = '\0';
+ } else {
+ boot[def->os.nBootDevs] = '\0';
+ }
+
+ if (xenXMConfigSetString(conf, "boot", boot) < 0)
+ goto no_memory;
+
+ if (xenXMConfigSetInt(conf, "pae",
+ (def->features &
+ (1 << VIR_DOMAIN_FEATURE_PAE)) ? 1 : 0) < 0)
+ goto no_memory;
+
+ if (xenXMConfigSetInt(conf, "acpi",
+ (def->features &
+ (1 << VIR_DOMAIN_FEATURE_ACPI)) ? 1 : 0) < 0)
+ goto no_memory;
+
+ if (xenXMConfigSetInt(conf, "apic",
+ (def->features &
+ (1 << VIR_DOMAIN_FEATURE_APIC)) ? 1 : 0) < 0)
+ goto no_memory;
+
+ if (xendConfigVersion >= 3)
+ if (xenXMConfigSetInt(conf, "hap",
+ (def->features &
+ (1 << VIR_DOMAIN_FEATURE_HAP)) ? 1 : 0) < 0)
+ goto no_memory;
+
+ if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME) {
+ if (def->clock.data.timezone) {
+ XENXS_ERROR(VIR_ERR_CONFIG_UNSUPPORTED,
+ "%s", _("configurable timezones are not supported"));
+ goto cleanup;
+ }
+
+ if (xenXMConfigSetInt(conf, "localtime", 1) < 0)
+ goto no_memory;
+ } else if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_UTC) {
+ if (xenXMConfigSetInt(conf, "localtime", 0) < 0)
+ goto no_memory;
+ } else {
+ /* XXX We could support Xen's rtc clock offset */
+ XENXS_ERROR(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unsupported clock offset '%s'"),
+ virDomainClockOffsetTypeToString(def->clock.offset));
+ goto cleanup;
+ }
+
+ if (xendConfigVersion == 1) {
+ for (i = 0 ; i < def->ndisks ; i++) {
+ if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
+ def->disks[i]->dst &&
+ STREQ(def->disks[i]->dst, "hdc") &&
+ def->disks[i]->src) {
+ if (xenXMConfigSetString(conf, "cdrom",
+ def->disks[i]->src) < 0)
+ goto no_memory;
+ break;
+ }
+ }
+ }
+
+ /* XXX floppy disks */
+ } else {
+ if (def->os.bootloader &&
+ xenXMConfigSetString(conf, "bootloader", def->os.bootloader) < 0)
+ goto no_memory;
+ if (def->os.bootloaderArgs &&
+ xenXMConfigSetString(conf, "bootargs", def->os.bootloaderArgs) < 0)
+ goto no_memory;
+ if (def->os.kernel &&
+ xenXMConfigSetString(conf, "kernel", def->os.kernel) < 0)
+ goto no_memory;
+ if (def->os.initrd &&
+ xenXMConfigSetString(conf, "ramdisk", def->os.initrd) < 0)
+ goto no_memory;
+ if (def->os.cmdline &&
+ xenXMConfigSetString(conf, "extra", def->os.cmdline) < 0)
+ goto no_memory;
+
+ }
+
+ if (!(lifecycle = virDomainLifecycleTypeToString(def->onPoweroff))) {
+ XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected lifecycle action %d"), def->onPoweroff);
+ goto cleanup;
+ }
+ if (xenXMConfigSetString(conf, "on_poweroff", lifecycle) < 0)
+ goto no_memory;
+
+
+ if (!(lifecycle = virDomainLifecycleTypeToString(def->onReboot))) {
+ XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected lifecycle action %d"), def->onReboot);
+ goto cleanup;
+ }
+ if (xenXMConfigSetString(conf, "on_reboot", lifecycle) < 0)
+ goto no_memory;
+
+
+ if (!(lifecycle = virDomainLifecycleCrashTypeToString(def->onCrash))) {
+ XENXS_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected lifecycle action %d"), def->onCrash);
+ goto cleanup;
+ }
+ if (xenXMConfigSetString(conf, "on_crash", lifecycle) < 0)
+ goto no_memory;
+
+
+
+ if (hvm) {
+ if (def->emulator &&
+ xenXMConfigSetString(conf, "device_model", def->emulator) < 0)
+ goto no_memory;
+
+ for (i = 0 ; i < def->ninputs ; i++) {
+ if (def->inputs[i]->bus == VIR_DOMAIN_INPUT_BUS_USB) {
+ if (xenXMConfigSetInt(conf, "usb", 1) < 0)
+ goto no_memory;
+ if (xenXMConfigSetString(conf, "usbdevice",
+ def->inputs[i]->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ?
+ "mouse" : "tablet") < 0)
+ goto no_memory;
+ break;
+ }
+ }
+ }
+
+ if (def->ngraphics == 1) {
+ if (xendConfigVersion < (hvm ? 4 : XEND_CONFIG_MIN_VERS_PVFB_NEWCONF)) {
+ if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
+ if (xenXMConfigSetInt(conf, "sdl", 1) < 0)
+ goto no_memory;
+ if (xenXMConfigSetInt(conf, "vnc", 0) < 0)
+ goto no_memory;
+ if (def->graphics[0]->data.sdl.display &&
+ xenXMConfigSetString(conf, "display",
+ def->graphics[0]->data.sdl.display) < 0)
+ goto no_memory;
+ if (def->graphics[0]->data.sdl.xauth &&
+ xenXMConfigSetString(conf, "xauthority",
+ def->graphics[0]->data.sdl.xauth) < 0)
+ goto no_memory;
+ } else {
+ if (xenXMConfigSetInt(conf, "sdl", 0) < 0)
+ goto no_memory;
+ if (xenXMConfigSetInt(conf, "vnc", 1) < 0)
+ goto no_memory;
+ if (xenXMConfigSetInt(conf, "vncunused",
+ def->graphics[0]->data.vnc.autoport ? 1 : 0) < 0)
+ goto no_memory;
+ if (!def->graphics[0]->data.vnc.autoport &&
+ xenXMConfigSetInt(conf, "vncdisplay",
+ def->graphics[0]->data.vnc.port - 5900) < 0)
+ goto no_memory;
+ if (def->graphics[0]->data.vnc.listenAddr &&
+ xenXMConfigSetString(conf, "vnclisten",
+ def->graphics[0]->data.vnc.listenAddr) < 0)
+ goto no_memory;
+ if (def->graphics[0]->data.vnc.auth.passwd &&
+ xenXMConfigSetString(conf, "vncpasswd",
+ def->graphics[0]->data.vnc.auth.passwd) < 0)
+ goto no_memory;
+ if (def->graphics[0]->data.vnc.keymap &&
+ xenXMConfigSetString(conf, "keymap",
+ def->graphics[0]->data.vnc.keymap) < 0)
+ goto no_memory;
+ }
+ } else {
+ virConfValuePtr vfb, disp;
+ char *vfbstr = NULL;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
+ virBufferAddLit(&buf, "type=sdl");
+ if (def->graphics[0]->data.sdl.display)
+ virBufferVSprintf(&buf, ",display=%s",
+ def->graphics[0]->data.sdl.display);
+ if (def->graphics[0]->data.sdl.xauth)
+ virBufferVSprintf(&buf, ",xauthority=%s",
+ def->graphics[0]->data.sdl.xauth);
+ } else {
+ virBufferAddLit(&buf, "type=vnc");
+ virBufferVSprintf(&buf, ",vncunused=%d",
+ def->graphics[0]->data.vnc.autoport ? 1 : 0);
+ if (!def->graphics[0]->data.vnc.autoport)
+ virBufferVSprintf(&buf, ",vncdisplay=%d",
+ def->graphics[0]->data.vnc.port - 5900);
+ if (def->graphics[0]->data.vnc.listenAddr)
+ virBufferVSprintf(&buf, ",vnclisten=%s",
+ def->graphics[0]->data.vnc.listenAddr);
+ if (def->graphics[0]->data.vnc.auth.passwd)
+ virBufferVSprintf(&buf, ",vncpasswd=%s",
+ def->graphics[0]->data.vnc.auth.passwd);
+ if (def->graphics[0]->data.vnc.keymap)
+ virBufferVSprintf(&buf, ",keymap=%s",
+ def->graphics[0]->data.vnc.keymap);
+ }
+ if (virBufferError(&buf)) {
+ virBufferFreeAndReset(&buf);
+ goto no_memory;
+ }
+
+ vfbstr = virBufferContentAndReset(&buf);
+
+ if (VIR_ALLOC(vfb) < 0) {
+ VIR_FREE(vfbstr);
+ goto no_memory;
+ }
+
+ if (VIR_ALLOC(disp) < 0) {
+ VIR_FREE(vfb);
+ VIR_FREE(vfbstr);
+ goto no_memory;
+ }
+
+ vfb->type = VIR_CONF_LIST;
+ vfb->list = disp;
+ disp->type = VIR_CONF_STRING;
+ disp->str = vfbstr;
+
+ if (virConfSetValue(conf, "vfb", vfb) < 0)
+ goto no_memory;
+ }
+ }
+
+ /* analyze of the devices */
+ if (VIR_ALLOC(diskVal) < 0)
+ goto no_memory;
+ diskVal->type = VIR_CONF_LIST;
+ diskVal->list = NULL;
+
+ for (i = 0 ; i < def->ndisks ; i++) {
+ if (xendConfigVersion == 1 &&
+ def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
+ def->disks[i]->dst &&
+ STREQ(def->disks[i]->dst, "hdc")) {
+ continue;
+ }
+ if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
+ continue;
+
+ if (xenXMDomainConfigFormatDisk(diskVal, def->disks[i],
+ hvm, xendConfigVersion) < 0)
+ goto cleanup;
+ }
+ if (diskVal->list != NULL) {
+ int ret = virConfSetValue(conf, "disk", diskVal);
+ diskVal = NULL;
+ if (ret < 0)
+ goto no_memory;
+ }
+ VIR_FREE(diskVal);
+
+ if (VIR_ALLOC(netVal) < 0)
+ goto no_memory;
+ netVal->type = VIR_CONF_LIST;
+ netVal->list = NULL;
+
+ for (i = 0 ; i < def->nnets ; i++) {
+ if (xenXMDomainConfigFormatNet(conn, netVal,
+ def->nets[i],
+ hvm, xendConfigVersion) < 0)
+ goto cleanup;
+ }
+ if (netVal->list != NULL) {
+ int ret = virConfSetValue(conf, "vif", netVal);
+ netVal = NULL;
+ if (ret < 0)
+ goto no_memory;
+ }
+ VIR_FREE(netVal);
+
+ if (xenXMDomainConfigFormatPCI(conf, def) < 0)
+ goto cleanup;
+
+ if (hvm) {
+ if (def->nparallels) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ char *str;
+ int ret;
+
+ ret = xenDaemonFormatSxprChr(def->parallels[0], &buf);
+ str = virBufferContentAndReset(&buf);
+ if (ret == 0)
+ ret = xenXMConfigSetString(conf, "parallel", str);
+ VIR_FREE(str);
+ if (ret < 0)
+ goto no_memory;
+ } else {
+ if (xenXMConfigSetString(conf, "parallel", "none") < 0)
+ goto no_memory;
+ }
+
+ if (def->nserials) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ char *str;
+ int ret;
+
+ ret = xenDaemonFormatSxprChr(def->serials[0], &buf);
+ str = virBufferContentAndReset(&buf);
+ if (ret == 0)
+ ret = xenXMConfigSetString(conf, "serial", str);
+ VIR_FREE(str);
+ if (ret < 0)
+ goto no_memory;
+ } else {
+ if (xenXMConfigSetString(conf, "serial", "none") < 0)
+ goto no_memory;
+ }
+
+
+ if (def->sounds) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ char *str = NULL;
+ int ret = xenDaemonFormatSxprSound(def, &buf);
+ str = virBufferContentAndReset(&buf);
+ if (ret == 0)
+ ret = xenXMConfigSetString(conf, "soundhw", str);
+
+ VIR_FREE(str);
+ if (ret < 0)
+ goto no_memory;
+ }
+ }
+
+ return conf;
+
+no_memory:
+ virReportOOMError();
+
+cleanup:
+ virConfFreeValue(diskVal);
+ virConfFreeValue(netVal);
+ VIR_FREE(cpus);
+ if (conf)
+ virConfFree(conf);
+ return (NULL);
+}
\ No newline at end of file
# include "conf.h"
# include "domain_conf.h"
+virConfPtr xenXMDomainConfigFormat(virConnectPtr conn, virDomainDefPtr def,
+ int xendConfigVersion);
+
virDomainDefPtr xenXMDomainConfigParse(virConfPtr conf, int xendConfigVersion,
virCapsPtr caps);
# define MIN_XEN_GUEST_SIZE 64 /* 64 megabytes */
+# ifdef __sun
+# define DEFAULT_VIF_SCRIPT "vif-vnic"
+# else
+# define DEFAULT_VIF_SCRIPT "vif-bridge"
+# endif
+
# define VIR_FROM_THIS VIR_FROM_NONE
# define XENXS_ERROR(code, ...) \
VIR_DOMAIN_XML_INACTIVE)))
goto fail;
- if (!(conf = xenXMDomainConfigFormat(conn, def)))
+ if (!(conf = xenXMDomainConfigFormat(conn, def, xendConfigVersion)))
goto fail;
if (virConfWriteMem(gotxmcfgPtr, &wrote, conf) < 0)