mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-03 17:47:15 +03:00
Moved XM formatting functions to xenxs
This commit is contained in:
parent
1556ced2de
commit
2e69e66e38
@ -1266,7 +1266,7 @@ xenUnifiedDomainXMLToNative(virConnectPtr conn,
|
||||
|
||||
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;
|
||||
|
||||
|
@ -65,8 +65,6 @@
|
||||
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);
|
||||
@ -189,9 +187,10 @@ xenXMConfigReadFile(virConnectPtr conn, const char *filename) {
|
||||
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);
|
||||
@ -1043,724 +1042,6 @@ int xenXMDomainCreate(virDomainPtr domain) {
|
||||
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
|
||||
|
@ -61,8 +61,6 @@ int xenXMDomainCreate(virDomainPtr domain);
|
||||
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);
|
||||
|
@ -32,12 +32,6 @@
|
||||
# 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);
|
||||
|
@ -1008,3 +1008,718 @@ cleanup:
|
||||
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);
|
||||
}
|
@ -30,6 +30,9 @@
|
||||
# include "conf.h"
|
||||
# include "domain_conf.h"
|
||||
|
||||
virConfPtr xenXMDomainConfigFormat(virConnectPtr conn, virDomainDefPtr def,
|
||||
int xendConfigVersion);
|
||||
|
||||
virDomainDefPtr xenXMDomainConfigParse(virConfPtr conf, int xendConfigVersion,
|
||||
virCapsPtr caps);
|
||||
|
||||
|
@ -48,6 +48,12 @@
|
||||
|
||||
# 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, ...) \
|
||||
|
@ -75,7 +75,7 @@ static int testCompareParseXML(const char *xmcfg, const char *xml,
|
||||
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user