libvirt/src/xenconfig/xen_sxpr.c

2495 lines
80 KiB
C
Raw Normal View History

2011-02-21 13:40:08 +00:00
/*
* xen_sxpr.c: Xen SEXPR parsing functions
*
* Copyright (C) 2010-2016 Red Hat, Inc.
2011-02-21 13:40:08 +00:00
* Copyright (C) 2011 Univention GmbH
* Copyright (C) 2005 Anthony Liguori <aliguori@us.ibm.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
2011-02-21 13:40:08 +00:00
*
* Author: Anthony Liguori <aliguori@us.ibm.com>
* Author: Daniel Veillard <veillard@redhat.com>
* Author: Markus Groß <gross@univention.de>
*/
#include <config.h>
#include <regex.h>
2011-02-21 13:40:08 +00:00
#include "internal.h"
#include "virerror.h"
2012-12-12 16:35:35 +00:00
#include "virconf.h"
2012-12-12 18:06:53 +00:00
#include "viralloc.h"
2011-02-21 13:40:08 +00:00
#include "verify.h"
2012-12-13 18:01:25 +00:00
#include "viruuid.h"
2012-12-12 17:59:27 +00:00
#include "virlog.h"
2011-02-21 13:40:08 +00:00
#include "count-one-bits.h"
#include "xenxs_private.h"
#include "xen_sxpr.h"
#include "virstoragefile.h"
#include "virstring.h"
2011-02-21 13:40:08 +00:00
#define VIR_FROM_THIS VIR_FROM_SEXPR
VIR_LOG_INIT("xenconfig.xen_sxpr");
/* Get a domain id from a S-expression string */
int xenGetDomIdFromSxprString(const char *sexpr, int *id)
2011-02-21 13:40:08 +00:00
{
struct sexpr *root = string2sexpr(sexpr);
int ret;
*id = -1;
2011-02-21 13:40:08 +00:00
if (!root)
return -1;
ret = xenGetDomIdFromSxpr(root, id);
2011-02-21 13:40:08 +00:00
sexpr_free(root);
return ret;
2011-02-21 13:40:08 +00:00
}
/* Get a domain id from a S-expression */
int xenGetDomIdFromSxpr(const struct sexpr *root, int *id)
2011-02-21 13:40:08 +00:00
{
const char * tmp = sexpr_node(root, "domain/domid");
*id = tmp ? sexpr_int(root, "domain/domid") : -1;
return 0;
2011-02-21 13:40:08 +00:00
}
/**
* xenParseSxprOS:
2011-02-21 13:40:08 +00:00
* @node: the root of the parsed S-Expression
* @def: the domain config
* @hvm: true or 1 if node contains HVM S-Expression
2011-02-21 13:40:08 +00:00
*
* Parse the xend sexp for description of os and append it to buf.
*
* Returns 0 in case of success and -1 in case of error
*/
static int
2011-02-21 13:40:12 +00:00
xenParseSxprOS(const struct sexpr *node,
virDomainDefPtr def,
int hvm)
2011-02-21 13:40:08 +00:00
{
if (hvm) {
if (VIR_ALLOC(def->os.loader) < 0)
goto error;
if (sexpr_node_copy(node, "domain/image/hvm/loader", &def->os.loader->path) < 0)
goto error;
if (def->os.loader->path == NULL) {
if (sexpr_node_copy(node, "domain/image/hvm/kernel", &def->os.loader->path) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (def->os.loader->path == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("domain information incomplete, missing HVM loader"));
return -1;
2011-02-21 13:40:08 +00:00
}
} else {
if (sexpr_node_copy(node, "domain/image/hvm/kernel", &def->os.kernel) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (sexpr_node_copy(node, "domain/image/hvm/ramdisk", &def->os.initrd) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (sexpr_node_copy(node, "domain/image/hvm/args", &def->os.cmdline) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (sexpr_node_copy(node, "domain/image/hvm/root", &def->os.root) < 0)
goto error;
2011-02-21 13:40:08 +00:00
}
} else {
if (sexpr_node_copy(node, "domain/image/linux/kernel", &def->os.kernel) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (sexpr_node_copy(node, "domain/image/linux/ramdisk", &def->os.initrd) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (sexpr_node_copy(node, "domain/image/linux/args", &def->os.cmdline) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (sexpr_node_copy(node, "domain/image/linux/root", &def->os.root) < 0)
goto error;
2011-02-21 13:40:08 +00:00
}
/* If HVM kenrel == loader, then old xend, so kill off kernel */
if (hvm &&
def->os.kernel &&
STREQ(def->os.kernel, def->os.loader->path)) {
2011-02-21 13:40:08 +00:00
VIR_FREE(def->os.kernel);
}
/* Drop kernel argument that has no value */
if (hvm &&
def->os.kernel && *def->os.kernel == '\0' &&
def->os.loader) {
VIR_FREE(def->os.kernel);
}
2011-02-21 13:40:08 +00:00
if (!def->os.kernel &&
hvm) {
const char *boot = sexpr_node(node, "domain/image/hvm/boot");
if ((boot != NULL) && (boot[0] != 0)) {
while (*boot &&
def->os.nBootDevs < VIR_DOMAIN_BOOT_LAST) {
if (*boot == 'a')
def->os.bootDevs[def->os.nBootDevs++] = VIR_DOMAIN_BOOT_FLOPPY;
else if (*boot == 'c')
def->os.bootDevs[def->os.nBootDevs++] = VIR_DOMAIN_BOOT_DISK;
else if (*boot == 'd')
def->os.bootDevs[def->os.nBootDevs++] = VIR_DOMAIN_BOOT_CDROM;
else if (*boot == 'n')
def->os.bootDevs[def->os.nBootDevs++] = VIR_DOMAIN_BOOT_NET;
boot++;
}
}
}
if (!hvm &&
!def->os.kernel &&
!def->os.bootloader) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("domain information incomplete, missing kernel & bootloader"));
2011-02-21 13:40:08 +00:00
return -1;
}
return 0;
error:
2011-02-21 13:40:08 +00:00
return -1;
}
/**
* xenParseSxprChar:
* @value: A string describing a character device.
* @tty: the console pty path
*
* Parse the xend S-expression for description of a character device.
*
* Returns a character device object or NULL in case of failure.
*/
2011-02-21 13:40:08 +00:00
virDomainChrDefPtr
2011-02-21 13:40:12 +00:00
xenParseSxprChar(const char *value,
const char *tty)
2011-02-21 13:40:08 +00:00
{
const char *prefix;
char *tmp;
virDomainChrDefPtr def;
if (!(def = virDomainChrDefNew(NULL)))
2011-02-21 13:40:08 +00:00
return NULL;
prefix = value;
if (value[0] == '/') {
def->source->type = VIR_DOMAIN_CHR_TYPE_DEV;
if (VIR_STRDUP(def->source->data.file.path, value) < 0)
goto error;
2011-02-21 13:40:08 +00:00
} else {
if ((tmp = strchr(value, ':')) != NULL) {
*tmp = '\0';
value = tmp + 1;
}
if (STRPREFIX(prefix, "telnet")) {
def->source->type = VIR_DOMAIN_CHR_TYPE_TCP;
def->source->data.tcp.protocol = VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET;
2011-02-21 13:40:08 +00:00
} else {
if ((def->source->type = virDomainChrTypeFromString(prefix)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown chr device type '%s'"), prefix);
2011-02-21 13:40:08 +00:00
goto error;
}
}
}
switch (def->source->type) {
2011-02-21 13:40:08 +00:00
case VIR_DOMAIN_CHR_TYPE_PTY:
if (VIR_STRDUP(def->source->data.file.path, tty) < 0)
goto error;
2011-02-21 13:40:08 +00:00
break;
case VIR_DOMAIN_CHR_TYPE_FILE:
case VIR_DOMAIN_CHR_TYPE_PIPE:
if (VIR_STRDUP(def->source->data.file.path, value) < 0)
goto error;
2011-02-21 13:40:08 +00:00
break;
case VIR_DOMAIN_CHR_TYPE_TCP:
{
const char *offset = strchr(value, ':');
const char *offset2;
if (offset == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("malformed char device string"));
2011-02-21 13:40:08 +00:00
goto error;
}
if (offset != value &&
VIR_STRNDUP(def->source->data.tcp.host, value, offset - value) < 0)
goto error;
2011-02-21 13:40:08 +00:00
offset2 = strchr(offset, ',');
offset++;
if (VIR_STRNDUP(def->source->data.tcp.service, offset,
offset2 ? offset2 - offset : -1) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (offset2 && strstr(offset2, ",server"))
def->source->data.tcp.listen = true;
2011-02-21 13:40:08 +00:00
}
break;
case VIR_DOMAIN_CHR_TYPE_UDP:
{
const char *offset = strchr(value, ':');
const char *offset2, *offset3;
if (offset == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("malformed char device string"));
2011-02-21 13:40:08 +00:00
goto error;
}
if (offset != value &&
VIR_STRNDUP(def->source->data.udp.connectHost, value, offset - value) < 0)
goto error;
2011-02-21 13:40:08 +00:00
offset2 = strchr(offset, '@');
if (offset2 != NULL) {
if (VIR_STRNDUP(def->source->data.udp.connectService,
offset + 1, offset2 - offset - 1) < 0)
goto error;
2011-02-21 13:40:08 +00:00
offset3 = strchr(offset2, ':');
if (offset3 == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("malformed char device string"));
2011-02-21 13:40:08 +00:00
goto error;
}
if (offset3 > (offset2 + 1) &&
VIR_STRNDUP(def->source->data.udp.bindHost,
offset2 + 1, offset3 - offset2 - 1) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (VIR_STRDUP(def->source->data.udp.bindService, offset3 + 1) < 0)
goto error;
2011-02-21 13:40:08 +00:00
} else {
if (VIR_STRDUP(def->source->data.udp.connectService, offset + 1) < 0)
goto error;
2011-02-21 13:40:08 +00:00
}
}
break;
case VIR_DOMAIN_CHR_TYPE_UNIX:
{
const char *offset = strchr(value, ',');
if (VIR_STRNDUP(def->source->data.nix.path, value,
offset ? offset - value : -1) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (offset != NULL &&
strstr(offset, ",server") != NULL)
def->source->data.nix.listen = true;
2011-02-21 13:40:08 +00:00
}
break;
}
return def;
error:
2011-02-21 13:40:08 +00:00
virDomainChrDefFree(def);
return NULL;
}
static const char *vif_bytes_per_sec_re = "^[0-9]+[GMK]?[Bb]/s$";
int
xenParseSxprVifRate(const char *rate, unsigned long long *kbytes_per_sec)
{
char *trate = NULL;
char *p;
regex_t rec;
int err;
char *suffix;
unsigned long long tmp;
int ret = -1;
if (VIR_STRDUP(trate, rate) < 0)
return -1;
p = strchr(trate, '@');
if (p != NULL)
*p = 0;
err = regcomp(&rec, vif_bytes_per_sec_re, REG_EXTENDED|REG_NOSUB);
if (err != 0) {
char error[100];
regerror(err, &rec, error, sizeof(error));
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to compile regular expression '%s': %s"),
vif_bytes_per_sec_re, error);
goto cleanup;
}
if (regexec(&rec, trate, 0, NULL, 0)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid rate '%s' specified"), rate);
goto cleanup;
}
if (virStrToLong_ull(rate, &suffix, 10, &tmp)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to parse rate '%s'"), rate);
goto cleanup;
}
if (*suffix == 'G')
tmp *= 1024 * 1024;
else if (*suffix == 'M')
tmp *= 1024;
if (*suffix == 'b' || *(suffix + 1) == 'b')
tmp /= 8;
*kbytes_per_sec = tmp;
ret = 0;
cleanup:
regfree(&rec);
VIR_FREE(trate);
return ret;
}
2011-02-21 13:40:08 +00:00
/**
* xenParseSxprDisks:
* @def: the domain config
* @root: root S-expression
* @hvm: true or 1 if node contains HVM S-Expression
2011-02-21 13:40:08 +00:00
*
* This parses out block devices from the domain S-expression
2011-02-21 13:40:08 +00:00
*
* Returns 0 if successful or -1 if failed.
*/
static int
2011-02-21 13:40:12 +00:00
xenParseSxprDisks(virDomainDefPtr def,
const struct sexpr *root,
int hvm)
2011-02-21 13:40:08 +00:00
{
const struct sexpr *cur, *node;
virDomainDiskDefPtr disk = NULL;
for (cur = root; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
node = cur->u.s.car;
/* Normally disks are in a (device (vbd ...)) block
but blktap disks ended up in a differently named
(device (tap ....)) block.... */
if (sexpr_lookup(node, "device/vbd") ||
sexpr_lookup(node, "device/tap") ||
sexpr_lookup(node, "device/tap2")) {
char *offset;
const char *src = NULL;
const char *dst = NULL;
const char *mode = NULL;
const char *bootable = NULL;
2011-02-21 13:40:08 +00:00
/* Again dealing with (vbd...) vs (tap ...) differences */
if (sexpr_lookup(node, "device/vbd")) {
src = sexpr_node(node, "device/vbd/uname");
dst = sexpr_node(node, "device/vbd/dev");
mode = sexpr_node(node, "device/vbd/mode");
bootable = sexpr_node(node, "device/vbd/bootable");
2011-02-21 13:40:08 +00:00
} else if (sexpr_lookup(node, "device/tap2")) {
src = sexpr_node(node, "device/tap2/uname");
dst = sexpr_node(node, "device/tap2/dev");
mode = sexpr_node(node, "device/tap2/mode");
bootable = sexpr_node(node, "device/tap2/bootable");
2011-02-21 13:40:08 +00:00
} else {
src = sexpr_node(node, "device/tap/uname");
dst = sexpr_node(node, "device/tap/dev");
mode = sexpr_node(node, "device/tap/mode");
bootable = sexpr_node(node, "device/tap/bootable");
2011-02-21 13:40:08 +00:00
}
if (!(disk = virDomainDiskDefNew(NULL)))
goto error;
2011-02-21 13:40:08 +00:00
if (dst == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("domain information incomplete, vbd has no dev"));
2011-02-21 13:40:08 +00:00
goto error;
}
if (src == NULL) {
/* There is a case without the uname to the CD-ROM device */
offset = strchr(dst, ':');
if (!offset ||
!hvm ||
STRNEQ(offset, ":cdrom")) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("domain information incomplete, vbd has no src"));
2011-02-21 13:40:08 +00:00
goto error;
}
}
if (src != NULL) {
offset = strchr(src, ':');
if (!offset) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot parse vbd filename, missing driver name"));
2011-02-21 13:40:08 +00:00
goto error;
}
if (sexpr_lookup(node, "device/tap2") &&
STRPREFIX(src, "tap:")) {
if (virDomainDiskSetDriver(disk, "tap2") < 0)
goto error;
} else {
char *tmp;
if (VIR_STRNDUP(tmp, src, offset - src) < 0)
goto error;
if (virDomainDiskSetDriver(disk, tmp) < 0) {
VIR_FREE(tmp);
goto error;
}
VIR_FREE(tmp);
2011-02-21 13:40:08 +00:00
}
src = offset + 1;
if (STREQ(virDomainDiskGetDriver(disk), "tap") ||
STREQ(virDomainDiskGetDriver(disk), "tap2")) {
char *driverType = NULL;
2011-02-21 13:40:08 +00:00
offset = strchr(src, ':');
if (!offset) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("cannot parse vbd filename, missing driver type"));
2011-02-21 13:40:08 +00:00
goto error;
}
if (VIR_STRNDUP(driverType, src, offset - src) < 0)
goto error;
if (STREQ(driverType, "aio"))
virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_RAW);
else
virDomainDiskSetFormat(disk,
virStorageFileFormatTypeFromString(driverType));
VIR_FREE(driverType);
if (virDomainDiskGetFormat(disk) <= 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unknown driver type %s"), src);
2011-02-21 13:40:08 +00:00
goto error;
}
src = offset + 1;
/* Its possible to use blktap driver for block devs
too, but kinda pointless because blkback is better,
so we assume common case here. If blktap becomes
omnipotent, we can revisit this, perhaps stat()'ing
the src file in question */
conf: move host disk type to util/ A continuation of the migration of disk details to virstoragefile. This patch moves a single enum, but converting the name has quite a bit of fallout. * src/conf/domain_conf.h (virDomainDiskType): Move... * src/util/virstoragefile.h (virStorageType): ...and rename. * src/bhyve/bhyve_command.c (bhyveBuildDiskArgStr) (virBhyveProcessBuildLoadCmd): Update clients. * src/conf/domain_conf.c (virDomainDiskSourceDefParse) (virDomainDiskDefParseXML, virDomainDiskSourceDefFormatInternal) (virDomainDiskDefFormat, virDomainDiskGetActualType) (virDomainDiskDefForeachPath, virDomainDiskSourceIsBlockType): Likewise. * src/conf/snapshot_conf.h (_virDomainSnapshotDiskDef): Likewise. * src/conf/snapshot_conf.c (virDomainSnapshotDiskDefParseXML) (virDomainSnapshotAlignDisks, virDomainSnapshotDiskDefFormat): Likewise. * src/esx/esx_driver.c (esxAutodetectSCSIControllerModel) (esxDomainDefineXML): Likewise. * src/locking/domain_lock.c (virDomainLockManagerAddDisk): Likewise. * src/lxc/lxc_controller.c (virLXCControllerSetupLoopDeviceDisk) (virLXCControllerSetupNBDDeviceDisk) (virLXCControllerSetupLoopDevices, virLXCControllerSetupDisk): Likewise. * src/parallels/parallels_driver.c (parallelsGetHddInfo): Likewise. * src/phyp/phyp_driver.c (phypDiskType): Likewise. * src/qemu/qemu_command.c (qemuGetDriveSourceString) (qemuDomainDiskGetSourceString, qemuBuildDriveStr) (qemuBuildCommandLine, qemuParseCommandLineDisk) (qemuParseCommandLine): Likewise. * src/qemu/qemu_conf.c (qemuCheckSharedDevice) (qemuTranslateDiskSourcePool) (qemuTranslateSnapshotDiskSourcePool): Likewise. * src/qemu/qemu_domain.c (qemuDomainDeviceDefPostParse) (qemuDomainDetermineDiskChain): Likewise. * src/qemu/qemu_driver.c (qemuDomainGetBlockInfo) (qemuDomainSnapshotPrepareDiskExternalBackingInactive) (qemuDomainSnapshotPrepareDiskExternalBackingActive) (qemuDomainSnapshotPrepareDiskExternalOverlayActive) (qemuDomainSnapshotPrepareDiskExternalOverlayInactive) (qemuDomainSnapshotPrepareDiskInternal) (qemuDomainSnapshotPrepare) (qemuDomainSnapshotCreateSingleDiskActive): Likewise. * src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia): Likewise. * src/qemu/qemu_migration.c (qemuMigrationIsSafe): Likewise. * src/security/security_apparmor.c (AppArmorRestoreSecurityImageLabel) (AppArmorSetSecurityImageLabel): Likewise. * src/security/security_dac.c (virSecurityDACSetSecurityImageLabel) (virSecurityDACRestoreSecurityImageLabelInt) (virSecurityDACSetSecurityAllLabel): Likewise. * src/security/security_selinux.c (virSecuritySELinuxRestoreSecurityImageLabelInt) (virSecuritySELinuxSetSecurityImageLabel) (virSecuritySELinuxSetSecurityAllLabel): Likewise. * src/storage/storage_backend.c (virStorageFileBackendForType): Likewise. * src/storage/storage_backend_fs.c (virStorageFileBackendFile) (virStorageFileBackendBlock): Likewise. * src/storage/storage_backend_gluster.c (virStorageFileBackendGluster): Likewise. * src/vbox/vbox_tmpl.c (vboxDomainGetXMLDesc, vboxAttachDrives) (vboxDomainAttachDeviceImpl, vboxDomainDetachDevice): Likewise. * src/vmware/vmware_conf.c (vmwareVmxPath): Likewise. * src/vmx/vmx.c (virVMXParseDisk, virVMXFormatDisk) (virVMXFormatFloppy): Likewise. * src/xenxs/xen_sxpr.c (xenParseSxprDisks, xenParseSxpr) (xenFormatSxprDisk): Likewise. * src/xenxs/xen_xm.c (xenParseXM, xenFormatXMDisk): Likewise. * tests/securityselinuxlabeltest.c (testSELinuxLoadDef): Likewise. * src/libvirt_private.syms (domain_conf.h): Move symbols... (virstoragefile.h): ...as appropriate. Signed-off-by: Eric Blake <eblake@redhat.com>
2014-03-27 21:57:49 +00:00
virDomainDiskSetType(disk, VIR_STORAGE_TYPE_FILE);
} else if (STREQ(virDomainDiskGetDriver(disk), "phy")) {
conf: move host disk type to util/ A continuation of the migration of disk details to virstoragefile. This patch moves a single enum, but converting the name has quite a bit of fallout. * src/conf/domain_conf.h (virDomainDiskType): Move... * src/util/virstoragefile.h (virStorageType): ...and rename. * src/bhyve/bhyve_command.c (bhyveBuildDiskArgStr) (virBhyveProcessBuildLoadCmd): Update clients. * src/conf/domain_conf.c (virDomainDiskSourceDefParse) (virDomainDiskDefParseXML, virDomainDiskSourceDefFormatInternal) (virDomainDiskDefFormat, virDomainDiskGetActualType) (virDomainDiskDefForeachPath, virDomainDiskSourceIsBlockType): Likewise. * src/conf/snapshot_conf.h (_virDomainSnapshotDiskDef): Likewise. * src/conf/snapshot_conf.c (virDomainSnapshotDiskDefParseXML) (virDomainSnapshotAlignDisks, virDomainSnapshotDiskDefFormat): Likewise. * src/esx/esx_driver.c (esxAutodetectSCSIControllerModel) (esxDomainDefineXML): Likewise. * src/locking/domain_lock.c (virDomainLockManagerAddDisk): Likewise. * src/lxc/lxc_controller.c (virLXCControllerSetupLoopDeviceDisk) (virLXCControllerSetupNBDDeviceDisk) (virLXCControllerSetupLoopDevices, virLXCControllerSetupDisk): Likewise. * src/parallels/parallels_driver.c (parallelsGetHddInfo): Likewise. * src/phyp/phyp_driver.c (phypDiskType): Likewise. * src/qemu/qemu_command.c (qemuGetDriveSourceString) (qemuDomainDiskGetSourceString, qemuBuildDriveStr) (qemuBuildCommandLine, qemuParseCommandLineDisk) (qemuParseCommandLine): Likewise. * src/qemu/qemu_conf.c (qemuCheckSharedDevice) (qemuTranslateDiskSourcePool) (qemuTranslateSnapshotDiskSourcePool): Likewise. * src/qemu/qemu_domain.c (qemuDomainDeviceDefPostParse) (qemuDomainDetermineDiskChain): Likewise. * src/qemu/qemu_driver.c (qemuDomainGetBlockInfo) (qemuDomainSnapshotPrepareDiskExternalBackingInactive) (qemuDomainSnapshotPrepareDiskExternalBackingActive) (qemuDomainSnapshotPrepareDiskExternalOverlayActive) (qemuDomainSnapshotPrepareDiskExternalOverlayInactive) (qemuDomainSnapshotPrepareDiskInternal) (qemuDomainSnapshotPrepare) (qemuDomainSnapshotCreateSingleDiskActive): Likewise. * src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia): Likewise. * src/qemu/qemu_migration.c (qemuMigrationIsSafe): Likewise. * src/security/security_apparmor.c (AppArmorRestoreSecurityImageLabel) (AppArmorSetSecurityImageLabel): Likewise. * src/security/security_dac.c (virSecurityDACSetSecurityImageLabel) (virSecurityDACRestoreSecurityImageLabelInt) (virSecurityDACSetSecurityAllLabel): Likewise. * src/security/security_selinux.c (virSecuritySELinuxRestoreSecurityImageLabelInt) (virSecuritySELinuxSetSecurityImageLabel) (virSecuritySELinuxSetSecurityAllLabel): Likewise. * src/storage/storage_backend.c (virStorageFileBackendForType): Likewise. * src/storage/storage_backend_fs.c (virStorageFileBackendFile) (virStorageFileBackendBlock): Likewise. * src/storage/storage_backend_gluster.c (virStorageFileBackendGluster): Likewise. * src/vbox/vbox_tmpl.c (vboxDomainGetXMLDesc, vboxAttachDrives) (vboxDomainAttachDeviceImpl, vboxDomainDetachDevice): Likewise. * src/vmware/vmware_conf.c (vmwareVmxPath): Likewise. * src/vmx/vmx.c (virVMXParseDisk, virVMXFormatDisk) (virVMXFormatFloppy): Likewise. * src/xenxs/xen_sxpr.c (xenParseSxprDisks, xenParseSxpr) (xenFormatSxprDisk): Likewise. * src/xenxs/xen_xm.c (xenParseXM, xenFormatXMDisk): Likewise. * tests/securityselinuxlabeltest.c (testSELinuxLoadDef): Likewise. * src/libvirt_private.syms (domain_conf.h): Move symbols... (virstoragefile.h): ...as appropriate. Signed-off-by: Eric Blake <eblake@redhat.com>
2014-03-27 21:57:49 +00:00
virDomainDiskSetType(disk, VIR_STORAGE_TYPE_BLOCK);
} else if (STREQ(virDomainDiskGetDriver(disk), "file")) {
conf: move host disk type to util/ A continuation of the migration of disk details to virstoragefile. This patch moves a single enum, but converting the name has quite a bit of fallout. * src/conf/domain_conf.h (virDomainDiskType): Move... * src/util/virstoragefile.h (virStorageType): ...and rename. * src/bhyve/bhyve_command.c (bhyveBuildDiskArgStr) (virBhyveProcessBuildLoadCmd): Update clients. * src/conf/domain_conf.c (virDomainDiskSourceDefParse) (virDomainDiskDefParseXML, virDomainDiskSourceDefFormatInternal) (virDomainDiskDefFormat, virDomainDiskGetActualType) (virDomainDiskDefForeachPath, virDomainDiskSourceIsBlockType): Likewise. * src/conf/snapshot_conf.h (_virDomainSnapshotDiskDef): Likewise. * src/conf/snapshot_conf.c (virDomainSnapshotDiskDefParseXML) (virDomainSnapshotAlignDisks, virDomainSnapshotDiskDefFormat): Likewise. * src/esx/esx_driver.c (esxAutodetectSCSIControllerModel) (esxDomainDefineXML): Likewise. * src/locking/domain_lock.c (virDomainLockManagerAddDisk): Likewise. * src/lxc/lxc_controller.c (virLXCControllerSetupLoopDeviceDisk) (virLXCControllerSetupNBDDeviceDisk) (virLXCControllerSetupLoopDevices, virLXCControllerSetupDisk): Likewise. * src/parallels/parallels_driver.c (parallelsGetHddInfo): Likewise. * src/phyp/phyp_driver.c (phypDiskType): Likewise. * src/qemu/qemu_command.c (qemuGetDriveSourceString) (qemuDomainDiskGetSourceString, qemuBuildDriveStr) (qemuBuildCommandLine, qemuParseCommandLineDisk) (qemuParseCommandLine): Likewise. * src/qemu/qemu_conf.c (qemuCheckSharedDevice) (qemuTranslateDiskSourcePool) (qemuTranslateSnapshotDiskSourcePool): Likewise. * src/qemu/qemu_domain.c (qemuDomainDeviceDefPostParse) (qemuDomainDetermineDiskChain): Likewise. * src/qemu/qemu_driver.c (qemuDomainGetBlockInfo) (qemuDomainSnapshotPrepareDiskExternalBackingInactive) (qemuDomainSnapshotPrepareDiskExternalBackingActive) (qemuDomainSnapshotPrepareDiskExternalOverlayActive) (qemuDomainSnapshotPrepareDiskExternalOverlayInactive) (qemuDomainSnapshotPrepareDiskInternal) (qemuDomainSnapshotPrepare) (qemuDomainSnapshotCreateSingleDiskActive): Likewise. * src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia): Likewise. * src/qemu/qemu_migration.c (qemuMigrationIsSafe): Likewise. * src/security/security_apparmor.c (AppArmorRestoreSecurityImageLabel) (AppArmorSetSecurityImageLabel): Likewise. * src/security/security_dac.c (virSecurityDACSetSecurityImageLabel) (virSecurityDACRestoreSecurityImageLabelInt) (virSecurityDACSetSecurityAllLabel): Likewise. * src/security/security_selinux.c (virSecuritySELinuxRestoreSecurityImageLabelInt) (virSecuritySELinuxSetSecurityImageLabel) (virSecuritySELinuxSetSecurityAllLabel): Likewise. * src/storage/storage_backend.c (virStorageFileBackendForType): Likewise. * src/storage/storage_backend_fs.c (virStorageFileBackendFile) (virStorageFileBackendBlock): Likewise. * src/storage/storage_backend_gluster.c (virStorageFileBackendGluster): Likewise. * src/vbox/vbox_tmpl.c (vboxDomainGetXMLDesc, vboxAttachDrives) (vboxDomainAttachDeviceImpl, vboxDomainDetachDevice): Likewise. * src/vmware/vmware_conf.c (vmwareVmxPath): Likewise. * src/vmx/vmx.c (virVMXParseDisk, virVMXFormatDisk) (virVMXFormatFloppy): Likewise. * src/xenxs/xen_sxpr.c (xenParseSxprDisks, xenParseSxpr) (xenFormatSxprDisk): Likewise. * src/xenxs/xen_xm.c (xenParseXM, xenFormatXMDisk): Likewise. * tests/securityselinuxlabeltest.c (testSELinuxLoadDef): Likewise. * src/libvirt_private.syms (domain_conf.h): Move symbols... (virstoragefile.h): ...as appropriate. Signed-off-by: Eric Blake <eblake@redhat.com>
2014-03-27 21:57:49 +00:00
virDomainDiskSetType(disk, VIR_STORAGE_TYPE_FILE);
2011-02-21 13:40:08 +00:00
}
} else {
/* No CDROM media so can't really tell. We'll just
call if a FILE for now and update when media
is inserted later */
conf: move host disk type to util/ A continuation of the migration of disk details to virstoragefile. This patch moves a single enum, but converting the name has quite a bit of fallout. * src/conf/domain_conf.h (virDomainDiskType): Move... * src/util/virstoragefile.h (virStorageType): ...and rename. * src/bhyve/bhyve_command.c (bhyveBuildDiskArgStr) (virBhyveProcessBuildLoadCmd): Update clients. * src/conf/domain_conf.c (virDomainDiskSourceDefParse) (virDomainDiskDefParseXML, virDomainDiskSourceDefFormatInternal) (virDomainDiskDefFormat, virDomainDiskGetActualType) (virDomainDiskDefForeachPath, virDomainDiskSourceIsBlockType): Likewise. * src/conf/snapshot_conf.h (_virDomainSnapshotDiskDef): Likewise. * src/conf/snapshot_conf.c (virDomainSnapshotDiskDefParseXML) (virDomainSnapshotAlignDisks, virDomainSnapshotDiskDefFormat): Likewise. * src/esx/esx_driver.c (esxAutodetectSCSIControllerModel) (esxDomainDefineXML): Likewise. * src/locking/domain_lock.c (virDomainLockManagerAddDisk): Likewise. * src/lxc/lxc_controller.c (virLXCControllerSetupLoopDeviceDisk) (virLXCControllerSetupNBDDeviceDisk) (virLXCControllerSetupLoopDevices, virLXCControllerSetupDisk): Likewise. * src/parallels/parallels_driver.c (parallelsGetHddInfo): Likewise. * src/phyp/phyp_driver.c (phypDiskType): Likewise. * src/qemu/qemu_command.c (qemuGetDriveSourceString) (qemuDomainDiskGetSourceString, qemuBuildDriveStr) (qemuBuildCommandLine, qemuParseCommandLineDisk) (qemuParseCommandLine): Likewise. * src/qemu/qemu_conf.c (qemuCheckSharedDevice) (qemuTranslateDiskSourcePool) (qemuTranslateSnapshotDiskSourcePool): Likewise. * src/qemu/qemu_domain.c (qemuDomainDeviceDefPostParse) (qemuDomainDetermineDiskChain): Likewise. * src/qemu/qemu_driver.c (qemuDomainGetBlockInfo) (qemuDomainSnapshotPrepareDiskExternalBackingInactive) (qemuDomainSnapshotPrepareDiskExternalBackingActive) (qemuDomainSnapshotPrepareDiskExternalOverlayActive) (qemuDomainSnapshotPrepareDiskExternalOverlayInactive) (qemuDomainSnapshotPrepareDiskInternal) (qemuDomainSnapshotPrepare) (qemuDomainSnapshotCreateSingleDiskActive): Likewise. * src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia): Likewise. * src/qemu/qemu_migration.c (qemuMigrationIsSafe): Likewise. * src/security/security_apparmor.c (AppArmorRestoreSecurityImageLabel) (AppArmorSetSecurityImageLabel): Likewise. * src/security/security_dac.c (virSecurityDACSetSecurityImageLabel) (virSecurityDACRestoreSecurityImageLabelInt) (virSecurityDACSetSecurityAllLabel): Likewise. * src/security/security_selinux.c (virSecuritySELinuxRestoreSecurityImageLabelInt) (virSecuritySELinuxSetSecurityImageLabel) (virSecuritySELinuxSetSecurityAllLabel): Likewise. * src/storage/storage_backend.c (virStorageFileBackendForType): Likewise. * src/storage/storage_backend_fs.c (virStorageFileBackendFile) (virStorageFileBackendBlock): Likewise. * src/storage/storage_backend_gluster.c (virStorageFileBackendGluster): Likewise. * src/vbox/vbox_tmpl.c (vboxDomainGetXMLDesc, vboxAttachDrives) (vboxDomainAttachDeviceImpl, vboxDomainDetachDevice): Likewise. * src/vmware/vmware_conf.c (vmwareVmxPath): Likewise. * src/vmx/vmx.c (virVMXParseDisk, virVMXFormatDisk) (virVMXFormatFloppy): Likewise. * src/xenxs/xen_sxpr.c (xenParseSxprDisks, xenParseSxpr) (xenFormatSxprDisk): Likewise. * src/xenxs/xen_xm.c (xenParseXM, xenFormatXMDisk): Likewise. * tests/securityselinuxlabeltest.c (testSELinuxLoadDef): Likewise. * src/libvirt_private.syms (domain_conf.h): Move symbols... (virstoragefile.h): ...as appropriate. Signed-off-by: Eric Blake <eblake@redhat.com>
2014-03-27 21:57:49 +00:00
virDomainDiskSetType(disk, VIR_STORAGE_TYPE_FILE);
2011-02-21 13:40:08 +00:00
}
if (STREQLEN(dst, "ioemu:", 6))
2011-02-21 13:40:08 +00:00
dst += 6;
disk->device = VIR_DOMAIN_DISK_DEVICE_DISK;
offset = strrchr(dst, ':');
if (offset) {
if (STREQ(offset, ":cdrom")) {
disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
} else if (STREQ(offset, ":disk")) {
/* The default anyway */
} else {
/* Unknown, lets pretend its a disk too */
2011-02-21 13:40:08 +00:00
}
offset[0] = '\0';
2011-02-21 13:40:08 +00:00
}
if (VIR_STRDUP(disk->dst, dst) < 0)
goto error;
if (virDomainDiskSetSource(disk, src) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (STRPREFIX(disk->dst, "xvd"))
disk->bus = VIR_DOMAIN_DISK_BUS_XEN;
else if (STRPREFIX(disk->dst, "hd"))
disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
else if (STRPREFIX(disk->dst, "sd"))
disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
else
disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
if (mode &&
strchr(mode, 'r'))
disk->src->readonly = true;
2011-02-21 13:40:08 +00:00
if (mode &&
strchr(mode, '!'))
disk->src->shared = true;
2011-02-21 13:40:08 +00:00
if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0)
goto error;
2011-02-21 13:40:08 +00:00
/* re-order disks if there is a bootable device */
if (STREQ_NULLABLE(bootable, "1")) {
def->disks[def->ndisks++] = def->disks[0];
def->disks[0] = disk;
} else {
def->disks[def->ndisks++] = disk;
}
2011-02-21 13:40:08 +00:00
disk = NULL;
}
}
return 0;
error:
2011-02-21 13:40:08 +00:00
virDomainDiskDefFree(disk);
return -1;
}
/**
* xenParseSxprNets:
* @def: the domain config
* @root: root S-expression
*
* This parses out network devices from the domain S-expression
*
* Returns 0 if successful or -1 if failed.
*/
2011-02-21 13:40:08 +00:00
static int
2011-02-21 13:40:12 +00:00
xenParseSxprNets(virDomainDefPtr def,
const struct sexpr *root)
2011-02-21 13:40:08 +00:00
{
virDomainNetDefPtr net = NULL;
const struct sexpr *cur, *node;
const char *tmp;
int vif_index = 0;
for (cur = root; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
node = cur->u.s.car;
if (sexpr_lookup(node, "device/vif")) {
const char *tmp2, *model, *type;
tmp2 = sexpr_node(node, "device/vif/script");
tmp = sexpr_node(node, "device/vif/bridge");
model = sexpr_node(node, "device/vif/model");
type = sexpr_node(node, "device/vif/type");
if (VIR_ALLOC(net) < 0)
goto cleanup;
2011-02-21 13:40:08 +00:00
if (tmp != NULL ||
(tmp2 != NULL && STREQ(tmp2, DEFAULT_VIF_SCRIPT))) {
net->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
/* XXX virtual network reverse resolve */
if (VIR_STRDUP(net->data.bridge.brname, tmp) < 0)
goto cleanup;
if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE &&
VIR_STRDUP(net->script, tmp2) < 0)
goto cleanup;
2011-02-21 13:40:08 +00:00
tmp = sexpr_node(node, "device/vif/ip");
if (tmp && virDomainNetAppendIPAddress(net, tmp, AF_UNSPEC, 0) < 0)
goto cleanup;
2011-02-21 13:40:08 +00:00
} else {
net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
if (VIR_STRDUP(net->script, tmp2) < 0)
goto cleanup;
2011-02-21 13:40:08 +00:00
tmp = sexpr_node(node, "device/vif/ip");
if (tmp && virDomainNetAppendIPAddress(net, tmp, AF_UNSPEC, 0) < 0)
goto cleanup;
2011-02-21 13:40:08 +00:00
}
tmp = sexpr_node(node, "device/vif/vifname");
/* If vifname is specified in xend config, include it in net
* definition regardless of domain state. If vifname is not
* specified, only generate one if domain is active (id != -1). */
if (tmp) {
if (VIR_STRDUP(net->ifname, tmp) < 0)
goto cleanup;
} else if (def->id != -1) {
if (virAsprintf(&net->ifname, "vif%d.%d", def->id, vif_index) < 0)
goto cleanup;
2011-02-21 13:40:08 +00:00
}
tmp = sexpr_node(node, "device/vif/mac");
if (tmp) {
if (virMacAddrParse(tmp, &net->mac) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("malformed mac address '%s'"), tmp);
2011-02-21 13:40:08 +00:00
goto cleanup;
}
}
if (VIR_STRDUP(net->model, model) < 0)
goto cleanup;
2011-02-21 13:40:08 +00:00
if (!model && type && STREQ(type, "netfront") &&
VIR_STRDUP(net->model, "netfront") < 0)
goto cleanup;
2011-02-21 13:40:08 +00:00
tmp = sexpr_node(node, "device/vif/rate");
if (tmp) {
virNetDevBandwidthPtr bandwidth;
unsigned long long kbytes_per_sec;
if (xenParseSxprVifRate(tmp, &kbytes_per_sec) < 0)
goto cleanup;
if (VIR_ALLOC(bandwidth) < 0)
goto cleanup;
if (VIR_ALLOC(bandwidth->out) < 0) {
VIR_FREE(bandwidth);
goto cleanup;
}
bandwidth->out->average = kbytes_per_sec;
net->bandwidth = bandwidth;
}
if (VIR_APPEND_ELEMENT(def->nets, def->nnets, net) < 0)
goto cleanup;
2011-02-21 13:40:08 +00:00
vif_index++;
}
}
return 0;
cleanup:
2011-02-21 13:40:08 +00:00
virDomainNetDefFree(net);
return -1;
}
/**
* xenParseSxprSound:
* @def: the domain config
* @str: comma separated list of sound models
*
* This parses out sound devices from the domain S-expression
*
* Returns 0 if successful or -1 if failed.
*/
2011-02-21 13:40:08 +00:00
int
2011-02-21 13:40:12 +00:00
xenParseSxprSound(virDomainDefPtr def,
const char *str)
2011-02-21 13:40:08 +00:00
{
if (STREQ(str, "all")) {
size_t i;
2011-02-21 13:40:08 +00:00
/*
* Special compatibility code for Xen with a bogus
2011-02-21 13:40:08 +00:00
* sound=all in config.
*
* NB deliberately, don't include all possible
2011-02-21 13:40:08 +00:00
* sound models anymore, just the 2 that were
* historically present in Xen's QEMU.
*
* ie just es1370 + sb16.
*
* Hence use of MODEL_ES1370 + 1, instead of MODEL_LAST
*/
if (VIR_ALLOC_N(def->sounds,
VIR_DOMAIN_SOUND_MODEL_ES1370 + 1) < 0)
goto error;
2011-02-21 13:40:08 +00:00
for (i = 0; i < (VIR_DOMAIN_SOUND_MODEL_ES1370 + 1); i++) {
2011-02-21 13:40:08 +00:00
virDomainSoundDefPtr sound;
if (VIR_ALLOC(sound) < 0)
goto error;
2011-02-21 13:40:08 +00:00
sound->model = i;
def->sounds[def->nsounds++] = sound;
}
} else {
char model[10];
const char *offset = str, *offset2;
do {
int len;
virDomainSoundDefPtr sound;
offset2 = strchr(offset, ',');
if (offset2)
len = (offset2 - offset);
else
len = strlen(offset);
if (virStrncpy(model, offset, len, sizeof(model)) == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Sound model %s too big for destination"),
offset);
2011-02-21 13:40:08 +00:00
goto error;
}
if (VIR_ALLOC(sound) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if ((sound->model = virDomainSoundModelTypeFromString(model)) < 0) {
VIR_FREE(sound);
goto error;
}
if (VIR_APPEND_ELEMENT(def->sounds, def->nsounds, sound) < 0) {
2011-02-21 13:40:08 +00:00
virDomainSoundDefFree(sound);
goto error;
2011-02-21 13:40:08 +00:00
}
offset = offset2 ? offset2 + 1 : NULL;
} while (offset);
}
return 0;
error:
2011-02-21 13:40:08 +00:00
return -1;
}
/**
* xenParseSxprUSB:
* @def: the domain config
* @root: root S-expression
*
* This parses out USB devices from the domain S-expression
*
* Returns 0 if successful or -1 if failed.
*/
2011-02-21 13:40:08 +00:00
static int
2011-02-21 13:40:12 +00:00
xenParseSxprUSB(virDomainDefPtr def,
const struct sexpr *root)
2011-02-21 13:40:08 +00:00
{
struct sexpr *cur, *node;
const char *tmp;
for (cur = sexpr_lookup(root, "domain/image/hvm"); cur && cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
node = cur->u.s.car;
if (sexpr_lookup(node, "usbdevice")) {
tmp = sexpr_node(node, "usbdevice");
if (tmp && *tmp) {
if (STREQ(tmp, "tablet") ||
STREQ(tmp, "mouse") ||
STREQ(tmp, "keyboard")) {
2011-02-21 13:40:08 +00:00
virDomainInputDefPtr input;
if (VIR_ALLOC(input) < 0)
goto error;
2011-02-21 13:40:08 +00:00
input->bus = VIR_DOMAIN_INPUT_BUS_USB;
if (STREQ(tmp, "tablet"))
input->type = VIR_DOMAIN_INPUT_TYPE_TABLET;
else if (STREQ(tmp, "mouse"))
2011-02-21 13:40:08 +00:00
input->type = VIR_DOMAIN_INPUT_TYPE_MOUSE;
else
input->type = VIR_DOMAIN_INPUT_TYPE_KBD;
2011-02-21 13:40:08 +00:00
if (VIR_APPEND_ELEMENT(def->inputs, def->ninputs, input) < 0) {
2011-02-21 13:40:08 +00:00
VIR_FREE(input);
goto error;
2011-02-21 13:40:08 +00:00
}
} else {
/* XXX Handle other non-input USB devices later */
}
}
}
}
return 0;
error:
2011-02-21 13:40:08 +00:00
return -1;
}
/*
* xenParseSxprGraphicsOld:
* @def: the domain config
* @root: root S-expression
* @hvm: true or 1 if root contains HVM S-Expression
* @vncport: VNC port number
*
* This parses out VNC devices from the domain S-expression
*
* Returns 0 if successful or -1 if failed.
*/
2011-02-21 13:40:08 +00:00
static int
2011-02-21 13:40:12 +00:00
xenParseSxprGraphicsOld(virDomainDefPtr def,
const struct sexpr *root,
int hvm,
int vncport)
2011-02-21 13:40:08 +00:00
{
const char *tmp;
virDomainGraphicsDefPtr graphics = NULL;
if ((tmp = sexpr_fmt_node(root, "domain/image/%s/vnc", hvm ? "hvm" : "linux")) &&
tmp[0] == '1') {
/* Graphics device (HVM, or old (pre-3.0.4) style PV VNC config) */
int port;
const char *listenAddr = sexpr_fmt_node(root, "domain/image/%s/vnclisten", hvm ? "hvm" : "linux");
const char *vncPasswd = sexpr_fmt_node(root, "domain/image/%s/vncpasswd", hvm ? "hvm" : "linux");
const char *keymap = sexpr_fmt_node(root, "domain/image/%s/keymap", hvm ? "hvm" : "linux");
const char *unused = sexpr_fmt_node(root, "domain/image/%s/vncunused", hvm ? "hvm" : "linux");
port = vncport;
if (VIR_ALLOC(graphics) < 0)
goto error;
2011-02-21 13:40:08 +00:00
graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
if ((unused && STREQ(unused, "1")) || port == -1)
graphics->data.vnc.autoport = true;
2011-02-21 13:40:08 +00:00
graphics->data.vnc.port = port;
if (virDomainGraphicsListenAppendAddress(graphics, listenAddr) < 0)
conf: add <listen> subelement to domain <graphics> element Once it's plugged in, the <listen> element will be an optional replacement for the "listen" attribute that graphics elements already have. If the <listen> element is type='address', it will have an attribute called 'address' which will contain an IP address or dns name that the guest's display server should listen on. If, however, type='network', the <listen> element should have an attribute called 'network' that will be set to the name of a network configuration to get the IP address from. * docs/schemas/domain.rng: updated to allow the <listen> element * docs/formatdomain.html.in: document the <listen> element and its attributes. * src/conf/domain_conf.[hc]: 1) The domain parser, formatter, and data structure are modified to support 0 or more <listen> subelements to each <graphics> element. The old style "legacy" listen attribute is also still accepted, and will be stored internally just as if it were a separate <listen> element. On output (i.e. format), the address attribute of the first <listen> element of type 'address' will be duplicated in the legacy "listen" attribute of the <graphic> element. 2) The "listenAddr" attribute has been removed from the unions in virDomainGRaphicsDef for graphics types vnc, rdp, and spice. This attribute is now in the <listen> subelement (aka virDomainGraphicsListenDef) 3) Helper functions were written to provide simple access (both Get and Set) to the listen elements and their attributes. * src/libvirt_private.syms: export the listen helper functions * src/qemu/qemu_command.c, src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c, src/vbox/vbox_tmpl.c, src/vmx/vmx.c, src/xenxs/xen_sxpr.c, src/xenxs/xen_xm.c Modify all these files to use the listen helper functions rather than directly referencing the (now missing) listenAddr attribute. There can be multiple <listen> elements to a single <graphics>, but the drivers all currently only support one, so all replacements of direct access with a helper function indicate index "0". * tests/* - only 3 of these are new files added explicitly to test the new <listen> element. All the others have been modified to reflect the fact that any legacy "listen" attributes passed in to the domain parse will be saved in a <listen> element (i.e. one of the virDomainGraphicsListenDefs), and during the domain format function, both the <listen> element as well as the legacy attributes will be output.
2011-07-07 04:20:28 +00:00
goto error;
2011-02-21 13:40:08 +00:00
if (VIR_STRDUP(graphics->data.vnc.auth.passwd, vncPasswd) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (VIR_STRDUP(graphics->data.vnc.keymap, keymap) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (VIR_ALLOC_N(def->graphics, 1) < 0)
goto error;
2011-02-21 13:40:08 +00:00
def->graphics[0] = graphics;
def->ngraphics = 1;
graphics = NULL;
} else if ((tmp = sexpr_fmt_node(root, "domain/image/%s/sdl", hvm ? "hvm" : "linux")) &&
tmp[0] == '1') {
/* Graphics device (HVM, or old (pre-3.0.4) style PV sdl config) */
const char *display = sexpr_fmt_node(root, "domain/image/%s/display", hvm ? "hvm" : "linux");
const char *xauth = sexpr_fmt_node(root, "domain/image/%s/xauthority", hvm ? "hvm" : "linux");
if (VIR_ALLOC(graphics) < 0)
goto error;
2011-02-21 13:40:08 +00:00
graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_SDL;
if (VIR_STRDUP(graphics->data.sdl.display, display) < 0)
goto error;
if (VIR_STRDUP(graphics->data.sdl.xauth, xauth) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (VIR_ALLOC_N(def->graphics, 1) < 0)
goto error;
2011-02-21 13:40:08 +00:00
def->graphics[0] = graphics;
def->ngraphics = 1;
graphics = NULL;
}
return 0;
error:
2011-02-21 13:40:08 +00:00
virDomainGraphicsDefFree(graphics);
return -1;
}
/*
* xenParseSxprGraphicsNew:
* @def: the domain config
* @root: root S-expression
* @vncport: VNC port number
*
* This parses out VNC devices from the domain S-expression
*
* Returns 0 if successful or -1 if failed.
*/
2011-02-21 13:40:08 +00:00
static int
2011-02-21 13:40:12 +00:00
xenParseSxprGraphicsNew(virDomainDefPtr def,
const struct sexpr *root, int vncport)
2011-02-21 13:40:08 +00:00
{
virDomainGraphicsDefPtr graphics = NULL;
const struct sexpr *cur, *node;
const char *tmp;
int typeVal;
2011-02-21 13:40:08 +00:00
/* append network devices and framebuffer */
for (cur = root; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
node = cur->u.s.car;
if (sexpr_lookup(node, "device/vfb")) {
/* New style graphics config for PV guests in >= 3.0.4,
* or for HVM guests in >= 3.0.5 */
if (sexpr_node(node, "device/vfb/type")) {
tmp = sexpr_node(node, "device/vfb/type");
} else if (sexpr_node(node, "device/vfb/vnc")) {
tmp = "vnc";
} else if (sexpr_node(node, "device/vfb/sdl")) {
tmp = "sdl";
} else {
tmp = "unknown";
}
if (VIR_ALLOC(graphics) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if ((typeVal = virDomainGraphicsTypeFromString(tmp)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown graphics type '%s'"), tmp);
2011-02-21 13:40:08 +00:00
goto error;
}
graphics->type = typeVal;
2011-02-21 13:40:08 +00:00
if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
const char *display = sexpr_node(node, "device/vfb/display");
const char *xauth = sexpr_node(node, "device/vfb/xauthority");
if (VIR_STRDUP(graphics->data.sdl.display, display) < 0)
goto error;
if (VIR_STRDUP(graphics->data.sdl.xauth, xauth) < 0)
goto error;
2011-02-21 13:40:08 +00:00
} else {
int port;
const char *listenAddr = sexpr_node(node, "device/vfb/vnclisten");
const char *vncPasswd = sexpr_node(node, "device/vfb/vncpasswd");
const char *keymap = sexpr_node(node, "device/vfb/keymap");
const char *unused = sexpr_node(node, "device/vfb/vncunused");
port = vncport;
/* Didn't find port entry in xenstore */
if (port == -1) {
const char *str = sexpr_node(node, "device/vfb/vncdisplay");
int val;
if (str != NULL && virStrToLong_i(str, NULL, 0, &val) == 0)
port = val;
}
if ((unused && STREQ(unused, "1")) || port == -1)
graphics->data.vnc.autoport = true;
2011-02-21 13:40:08 +00:00
if (port >= 0 && port < 5900)
port += 5900;
graphics->data.vnc.port = port;
if (virDomainGraphicsListenAppendAddress(graphics, listenAddr) < 0)
conf: add <listen> subelement to domain <graphics> element Once it's plugged in, the <listen> element will be an optional replacement for the "listen" attribute that graphics elements already have. If the <listen> element is type='address', it will have an attribute called 'address' which will contain an IP address or dns name that the guest's display server should listen on. If, however, type='network', the <listen> element should have an attribute called 'network' that will be set to the name of a network configuration to get the IP address from. * docs/schemas/domain.rng: updated to allow the <listen> element * docs/formatdomain.html.in: document the <listen> element and its attributes. * src/conf/domain_conf.[hc]: 1) The domain parser, formatter, and data structure are modified to support 0 or more <listen> subelements to each <graphics> element. The old style "legacy" listen attribute is also still accepted, and will be stored internally just as if it were a separate <listen> element. On output (i.e. format), the address attribute of the first <listen> element of type 'address' will be duplicated in the legacy "listen" attribute of the <graphic> element. 2) The "listenAddr" attribute has been removed from the unions in virDomainGRaphicsDef for graphics types vnc, rdp, and spice. This attribute is now in the <listen> subelement (aka virDomainGraphicsListenDef) 3) Helper functions were written to provide simple access (both Get and Set) to the listen elements and their attributes. * src/libvirt_private.syms: export the listen helper functions * src/qemu/qemu_command.c, src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c, src/vbox/vbox_tmpl.c, src/vmx/vmx.c, src/xenxs/xen_sxpr.c, src/xenxs/xen_xm.c Modify all these files to use the listen helper functions rather than directly referencing the (now missing) listenAddr attribute. There can be multiple <listen> elements to a single <graphics>, but the drivers all currently only support one, so all replacements of direct access with a helper function indicate index "0". * tests/* - only 3 of these are new files added explicitly to test the new <listen> element. All the others have been modified to reflect the fact that any legacy "listen" attributes passed in to the domain parse will be saved in a <listen> element (i.e. one of the virDomainGraphicsListenDefs), and during the domain format function, both the <listen> element as well as the legacy attributes will be output.
2011-07-07 04:20:28 +00:00
goto error;
2011-02-21 13:40:08 +00:00
if (VIR_STRDUP(graphics->data.vnc.auth.passwd, vncPasswd) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (VIR_STRDUP(graphics->data.vnc.keymap, keymap) < 0)
goto error;
2011-02-21 13:40:08 +00:00
}
if (VIR_ALLOC_N(def->graphics, 1) < 0)
goto error;
2011-02-21 13:40:08 +00:00
def->graphics[0] = graphics;
def->ngraphics = 1;
graphics = NULL;
break;
}
}
return 0;
error:
2011-02-21 13:40:08 +00:00
virDomainGraphicsDefFree(graphics);
return -1;
}
2011-02-21 13:40:08 +00:00
/**
* xenParseSxprPCI:
* @def: the domain config
2011-02-21 13:40:08 +00:00
* @root: root sexpr
*
* This parses out PCI devices from the domain sexpr
2011-02-21 13:40:08 +00:00
*
* Returns 0 if successful or -1 if failed.
*/
static int
2011-02-21 13:40:12 +00:00
xenParseSxprPCI(virDomainDefPtr def,
const struct sexpr *root)
2011-02-21 13:40:08 +00:00
{
const struct sexpr *cur, *tmp = NULL, *node;
virDomainHostdevDefPtr dev = NULL;
/*
* With the (domain ...) block we have the following odd setup
*
* (device
* (pci
* (dev (domain 0x0000) (bus 0x00) (slot 0x1b) (func 0x0))
* (dev (domain 0x0000) (bus 0x00) (slot 0x13) (func 0x0))
* )
* )
*
* Normally there is one (device ...) block per device, but in
* weird world of Xen PCI, once (device ...) covers multiple
2011-02-21 13:40:08 +00:00
* devices.
*/
for (cur = root; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
node = cur->u.s.car;
if ((tmp = sexpr_lookup(node, "device/pci")) != NULL)
break;
}
if (!tmp)
return 0;
for (cur = tmp; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
const char *domain = NULL;
const char *bus = NULL;
const char *slot = NULL;
const char *func = NULL;
int domainID;
int busID;
int slotID;
int funcID;
node = cur->u.s.car;
if (!sexpr_lookup(node, "dev"))
continue;
if (!(domain = sexpr_node(node, "dev/domain"))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("missing PCI domain"));
2011-02-21 13:40:08 +00:00
goto error;
}
if (!(bus = sexpr_node(node, "dev/bus"))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("missing PCI bus"));
2011-02-21 13:40:08 +00:00
goto error;
}
if (!(slot = sexpr_node(node, "dev/slot"))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("missing PCI slot"));
2011-02-21 13:40:08 +00:00
goto error;
}
if (!(func = sexpr_node(node, "dev/func"))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("missing PCI func"));
2011-02-21 13:40:08 +00:00
goto error;
}
if (virStrToLong_i(domain, NULL, 0, &domainID) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot parse PCI domain '%s'"), domain);
2011-02-21 13:40:08 +00:00
goto error;
}
if (virStrToLong_i(bus, NULL, 0, &busID) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot parse PCI bus '%s'"), bus);
2011-02-21 13:40:08 +00:00
goto error;
}
if (virStrToLong_i(slot, NULL, 0, &slotID) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot parse PCI slot '%s'"), slot);
2011-02-21 13:40:08 +00:00
goto error;
}
if (virStrToLong_i(func, NULL, 0, &funcID) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot parse PCI func '%s'"), func);
2011-02-21 13:40:08 +00:00
goto error;
}
if (!(dev = virDomainHostdevDefNew(NULL)))
goto error;
2011-02-21 13:40:08 +00:00
dev->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
dev->managed = false;
2011-02-21 13:40:08 +00:00
dev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
dev->source.subsys.u.pci.addr.domain = domainID;
dev->source.subsys.u.pci.addr.bus = busID;
dev->source.subsys.u.pci.addr.slot = slotID;
dev->source.subsys.u.pci.addr.function = funcID;
2011-02-21 13:40:08 +00:00
if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, dev) < 0)
goto error;
2011-02-21 13:40:08 +00:00
}
return 0;
error:
2011-02-21 13:40:08 +00:00
virDomainHostdevDefFree(dev);
return -1;
}
/**
2011-02-21 13:40:12 +00:00
* xenParseSxpr:
2011-02-21 13:40:08 +00:00
* @root: the root of the parsed S-Expression
* @cpus: set of cpus the domain may be pinned to
* @tty: the console pty path
* @vncport: VNC port number
2011-02-21 13:40:08 +00:00
*
* Parse the xend S-expression description and turn it into a virDomainDefPtr
* representing these settings as closely as is practical.
2011-02-21 13:40:08 +00:00
*
* Returns the domain config or NULL in case of error.
* The caller must free() the returned value.
2011-02-21 13:40:08 +00:00
*/
virDomainDefPtr
2011-02-21 13:40:12 +00:00
xenParseSxpr(const struct sexpr *root,
const char *cpus,
char *tty,
int vncport,
virCapsPtr caps,
virDomainXMLOptionPtr xmlopt)
2011-02-21 13:40:08 +00:00
{
const char *tmp;
virDomainDefPtr def;
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
int hvm = 0, vmlocaltime;
unsigned int vcpus;
2011-02-21 13:40:08 +00:00
if (!(def = virDomainDefNew()))
goto error;
2011-02-21 13:40:08 +00:00
tmp = sexpr_node(root, "domain/domid");
def->virtType = VIR_DOMAIN_VIRT_XEN;
if (tmp)
def->id = sexpr_int(root, "domain/domid");
else
def->id = -1;
if (sexpr_node_copy(root, "domain/name", &def->name) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (def->name == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("domain information incomplete, missing name"));
2011-02-21 13:40:08 +00:00
goto error;
}
tmp = sexpr_node(root, "domain/uuid");
if (tmp == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("domain information incomplete, missing name"));
2011-02-21 13:40:08 +00:00
goto error;
}
if (virUUIDParse(tmp, def->uuid) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (sexpr_node_copy(root, "domain/description", &def->description) < 0)
goto error;
2011-02-21 13:40:08 +00:00
hvm = sexpr_lookup(root, "domain/image/hvm") ? 1 : 0;
if (!hvm) {
if (sexpr_node_copy(root, "domain/bootloader",
&def->os.bootloader) < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (!def->os.bootloader &&
sexpr_has(root, "domain/bootloader") &&
VIR_STRDUP(def->os.bootloader, "") < 0)
goto error;
2011-02-21 13:40:08 +00:00
if (def->os.bootloader &&
sexpr_node_copy(root, "domain/bootloader_args",
&def->os.bootloaderArgs) < 0)
goto error;
2011-02-21 13:40:08 +00:00
}
def->os.type = (hvm ? VIR_DOMAIN_OSTYPE_HVM : VIR_DOMAIN_OSTYPE_LINUX);
2011-02-21 13:40:08 +00:00
if (def->id != 0) {
if (sexpr_lookup(root, "domain/image")) {
2011-02-21 13:40:12 +00:00
if (xenParseSxprOS(root, def, hvm) < 0)
2011-02-21 13:40:08 +00:00
goto error;
}
}
virDomainDefSetMemoryTotal(def, (sexpr_u64(root, "domain/maxmem") << 10));
xml: use better types for memory values Using 'unsigned long' for memory values is risky on 32-bit platforms, as a PAE guest can have more than 4GiB memory. Our API is (unfortunately) locked at 'unsigned long' and a scale of 1024, but the rest of our system should consistently use 64-bit values, especially since the previous patch centralized overflow checking. * src/conf/domain_conf.h (_virDomainDef): Always use 64-bit values for memory. Change hugepage_backed to a bool. * src/conf/domain_conf.c (virDomainDefParseXML) (virDomainDefCheckABIStability, virDomainDefFormatInternal): Fix clients. * src/vmx/vmx.c (virVMXFormatConfig): Likewise. * src/xenxs/xen_sxpr.c (xenParseSxpr, xenFormatSxpr): Likewise. * src/xenxs/xen_xm.c (xenXMConfigGetULongLong): New function. (xenXMConfigGetULong, xenXMConfigSetInt): Avoid truncation. (xenParseXM, xenFormatXM): Fix clients. * src/phyp/phyp_driver.c (phypBuildLpar): Likewise. * src/openvz/openvz_driver.c (openvzDomainSetMemoryInternal): Likewise. * src/vbox/vbox_tmpl.c (vboxDomainDefineXML): Likewise. * src/qemu/qemu_command.c (qemuBuildCommandLine): Likewise. * src/qemu/qemu_process.c (qemuProcessStart): Likewise. * src/qemu/qemu_monitor.h (qemuMonitorGetBalloonInfo): Likewise. * src/qemu/qemu_monitor_text.h (qemuMonitorTextGetBalloonInfo): Likewise. * src/qemu/qemu_monitor_text.c (qemuMonitorTextGetBalloonInfo): Likewise. * src/qemu/qemu_monitor_json.h (qemuMonitorJSONGetBalloonInfo): Likewise. * src/qemu/qemu_monitor_json.c (qemuMonitorJSONGetBalloonInfo): Likewise. * src/qemu/qemu_driver.c (qemudDomainGetInfo) (qemuDomainGetXMLDesc): Likewise. * src/uml/uml_conf.c (umlBuildCommandLine): Likewise.
2012-03-02 20:27:39 +00:00
def->mem.cur_balloon = (sexpr_u64(root, "domain/memory") << 10);
if (def->mem.cur_balloon > virDomainDefGetMemoryTotal(def))
def->mem.cur_balloon = virDomainDefGetMemoryTotal(def);
2011-02-21 13:40:08 +00:00
if (cpus != NULL) {
if (virBitmapParse(cpus, &def->cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0)
2011-02-21 13:40:08 +00:00
goto error;
if (virBitmapIsAllClear(def->cpumask)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Invalid value of 'cpumask': %s"),
cpus);
goto error;
}
2011-02-21 13:40:08 +00:00
}
if (virDomainDefSetVcpusMax(def, sexpr_int(root, "domain/vcpus"), xmlopt) < 0)
goto error;
vcpus = count_one_bits_l(sexpr_u64(root, "domain/vcpu_avail"));
if (!vcpus || virDomainDefGetVcpusMax(def) < vcpus)
vcpus = virDomainDefGetVcpusMax(def);
if (virDomainDefSetVcpus(def, vcpus) < 0)
goto error;
2011-02-21 13:40:08 +00:00
tmp = sexpr_node(root, "domain/on_poweroff");
if (tmp != NULL) {
if ((def->onPoweroff = virDomainLifecycleActionTypeFromString(tmp)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown lifecycle type %s"), tmp);
2011-02-21 13:40:08 +00:00
goto error;
}
} else {
def->onPoweroff = VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY;
}
2011-02-21 13:40:08 +00:00
tmp = sexpr_node(root, "domain/on_reboot");
if (tmp != NULL) {
if ((def->onReboot = virDomainLifecycleActionTypeFromString(tmp)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown lifecycle type %s"), tmp);
2011-02-21 13:40:08 +00:00
goto error;
}
} else {
def->onReboot = VIR_DOMAIN_LIFECYCLE_ACTION_RESTART;
}
2011-02-21 13:40:08 +00:00
tmp = sexpr_node(root, "domain/on_crash");
if (tmp != NULL) {
if ((def->onCrash = virDomainLifecycleActionTypeFromString(tmp)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown lifecycle type %s"), tmp);
2011-02-21 13:40:08 +00:00
goto error;
}
} else {
def->onCrash = VIR_DOMAIN_LIFECYCLE_ACTION_DESTROY;
}
2011-02-21 13:40:08 +00:00
if (hvm) {
if (sexpr_int(root, "domain/image/hvm/acpi"))
def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_TRISTATE_SWITCH_ON;
2011-02-21 13:40:08 +00:00
if (sexpr_int(root, "domain/image/hvm/apic"))
def->features[VIR_DOMAIN_FEATURE_APIC] = VIR_TRISTATE_SWITCH_ON;
2011-02-21 13:40:08 +00:00
if (sexpr_int(root, "domain/image/hvm/pae"))
def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_TRISTATE_SWITCH_ON;
2011-02-21 13:40:08 +00:00
if (sexpr_int(root, "domain/image/hvm/hap"))
def->features[VIR_DOMAIN_FEATURE_HAP] = VIR_TRISTATE_SWITCH_ON;
if (sexpr_int(root, "domain/image/hvm/viridian"))
def->features[VIR_DOMAIN_FEATURE_VIRIDIAN] = VIR_TRISTATE_SWITCH_ON;
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
}
2011-02-21 13:40:08 +00:00
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
/* 12aaf4a2486b (3.0.3) added a second low-priority 'localtime' setting */
vmlocaltime = sexpr_int(root, "domain/localtime");
if (hvm) {
const char *value = sexpr_node(root, "domain/image/hvm/localtime");
int rtc_offset;
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
if (value) {
if (virStrToLong_i(value, NULL, 0, &vmlocaltime) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown localtime offset %s"), value);
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
goto error;
}
}
def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_VARIABLE;
rtc_offset = sexpr_int(root, "domain/image/hvm/rtc_timeoffset");
def->clock.data.variable.adjustment = rtc_offset;
def->clock.data.variable.basis = vmlocaltime ?
VIR_DOMAIN_CLOCK_BASIS_LOCALTIME :
VIR_DOMAIN_CLOCK_BASIS_UTC;
if (sexpr_lookup(root, "domain/image/hvm/hpet")) {
virDomainTimerDefPtr timer;
if (VIR_ALLOC_N(def->clock.timers, 1) < 0 ||
VIR_ALLOC(timer) < 0)
goto error;
timer->name = VIR_DOMAIN_TIMER_NAME_HPET;
timer->present = sexpr_int(root, "domain/image/hvm/hpet");
timer->tickpolicy = -1;
timer->mode = -1;
timer->track = -1;
def->clock.ntimers = 1;
def->clock.timers[0] = timer;
}
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
} else {
const char *value = sexpr_node(root, "domain/image/linux/localtime");
if (value) {
if (virStrToLong_i(value, NULL, 0, &vmlocaltime) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown localtime offset %s"), value);
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
goto error;
}
}
/* PV domains do not have an emulated RTC and the offset is fixed. */
if (vmlocaltime)
def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME;
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
else
def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC;
def->clock.data.utc_reset = true;
} /* !hvm */
2011-02-21 13:40:08 +00:00
if (sexpr_node_copy(root, hvm ?
"domain/image/hvm/device_model" :
"domain/image/linux/device_model",
&def->emulator) < 0)
goto error;
2011-02-21 13:40:08 +00:00
/* append block devices */
if (xenParseSxprDisks(def, root, hvm) < 0)
2011-02-21 13:40:08 +00:00
goto error;
2011-02-21 13:40:12 +00:00
if (xenParseSxprNets(def, root) < 0)
2011-02-21 13:40:08 +00:00
goto error;
2011-02-21 13:40:12 +00:00
if (xenParseSxprPCI(def, root) < 0)
2011-02-21 13:40:08 +00:00
goto error;
/* New style graphics device config */
2011-02-21 13:40:12 +00:00
if (xenParseSxprGraphicsNew(def, root, vncport) < 0)
2011-02-21 13:40:08 +00:00
goto error;
/* Graphics device (HVM <= 3.0.4, or PV <= 3.0.3) vnc config */
if ((def->ngraphics == 0) &&
xenParseSxprGraphicsOld(def, root, hvm, vncport) < 0)
2011-02-21 13:40:08 +00:00
goto error;
/* in case of HVM we have USB device emulation */
if (hvm &&
2011-02-21 13:40:12 +00:00
xenParseSxprUSB(def, root) < 0)
2011-02-21 13:40:08 +00:00
goto error;
/* Character device config */
if (hvm) {
const struct sexpr *serial_root;
bool have_multiple_serials = false;
serial_root = sexpr_lookup(root, "domain/image/hvm/serial");
if (serial_root) {
const struct sexpr *cur, *node, *cur2;
int ports_skipped = 0;
for (cur = serial_root; cur->kind == SEXPR_CONS; cur = cur->u.s.cdr) {
node = cur->u.s.car;
for (cur2 = node; cur2->kind == SEXPR_CONS; cur2 = cur2->u.s.cdr) {
tmp = cur2->u.s.car->u.value;
if (tmp && STRNEQ(tmp, "none")) {
virDomainChrDefPtr chr;
if ((chr = xenParseSxprChar(tmp, tty)) == NULL)
goto error;
chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
chr->target.port = def->nserials + ports_skipped;
if (VIR_APPEND_ELEMENT(def->serials, def->nserials, chr) < 0) {
virDomainChrDefFree(chr);
goto error;
}
}
else
ports_skipped++;
have_multiple_serials = true;
}
2011-02-21 13:40:08 +00:00
}
}
if (!have_multiple_serials) {
tmp = sexpr_node(root, "domain/image/hvm/serial");
if (tmp && STRNEQ(tmp, "none")) {
virDomainChrDefPtr chr;
if ((chr = xenParseSxprChar(tmp, tty)) == NULL)
goto error;
chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
chr->target.port = 0;
if (VIR_APPEND_ELEMENT(def->serials, def->nserials, chr) < 0) {
virDomainChrDefFree(chr);
goto error;
}
}
}
2011-02-21 13:40:08 +00:00
tmp = sexpr_node(root, "domain/image/hvm/parallel");
if (tmp && STRNEQ(tmp, "none")) {
virDomainChrDefPtr chr;
/* XXX does XenD stuff parallel port tty info into xenstore somewhere ? */
2011-02-21 13:40:12 +00:00
if ((chr = xenParseSxprChar(tmp, NULL)) == NULL)
2011-02-21 13:40:08 +00:00
goto error;
chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL;
chr->target.port = 0;
if (VIR_APPEND_ELEMENT(def->parallels, def->nparallels, chr) < 0) {
2011-02-21 13:40:08 +00:00
virDomainChrDefFree(chr);
goto error;
2011-02-21 13:40:08 +00:00
}
}
} else if (def->id != 0) {
if (VIR_ALLOC_N(def->consoles, 1) < 0)
goto error;
def->nconsoles = 1;
2011-02-21 13:40:08 +00:00
/* Fake a paravirt console, since that's not in the sexpr */
if (!(def->consoles[0] = xenParseSxprChar("pty", tty)))
2011-02-21 13:40:08 +00:00
goto error;
def->consoles[0]->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE;
def->consoles[0]->target.port = 0;
def->consoles[0]->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN;
2011-02-21 13:40:08 +00:00
}
VIR_FREE(tty);
/* Sound device config */
if (hvm &&
(tmp = sexpr_node(root, "domain/image/hvm/soundhw")) != NULL &&
*tmp) {
2011-02-21 13:40:12 +00:00
if (xenParseSxprSound(def, tmp) < 0)
2011-02-21 13:40:08 +00:00
goto error;
}
if (virDomainDefPostParse(def, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
xmlopt, NULL) < 0)
goto error;
2011-02-21 13:40:08 +00:00
return def;
error:
2011-02-21 13:40:08 +00:00
VIR_FREE(tty);
virDomainDefFree(def);
return NULL;
}
/**
* xenParseSxprString:
* @sexpr: the root of the parsed S-Expression
* @tty: the console pty path
* @vncport: VNC port number
*
* Parse the xend S-expression description and turn it into a virDomainDefPtr
* representing these settings as closely as is practical.
*
* Returns the domain config or NULL in case of error.
* The caller must free() the returned value.
*/
2011-02-21 13:40:08 +00:00
virDomainDefPtr
2011-02-21 13:40:12 +00:00
xenParseSxprString(const char *sexpr,
char *tty,
int vncport,
virCapsPtr caps,
virDomainXMLOptionPtr xmlopt)
2011-02-21 13:40:08 +00:00
{
struct sexpr *root = string2sexpr(sexpr);
virDomainDefPtr def;
if (!root)
return NULL;
def = xenParseSxpr(root, NULL, tty, vncport, caps, xmlopt);
2011-02-21 13:40:08 +00:00
sexpr_free(root);
return def;
}
/************************************************************************
* *
* Converter functions to go from the XML tree to an S-Expr for Xen *
* *
************************************************************************/
/**
* xenFormatSxprGraphicsNew:
* @def: the domain config
* @buf: a buffer for the result S-expression
*
* Convert the graphics part of the domain description into a S-expression
* in buf. (HVM > 3.0.4 or PV > 3.0.3)
*
* Returns 0 in case of success, -1 in case of error
*/
static int
2011-02-21 13:40:12 +00:00
xenFormatSxprGraphicsNew(virDomainGraphicsDefPtr def,
virBufferPtr buf)
{
virDomainGraphicsListenDefPtr glisten;
conf: add <listen> subelement to domain <graphics> element Once it's plugged in, the <listen> element will be an optional replacement for the "listen" attribute that graphics elements already have. If the <listen> element is type='address', it will have an attribute called 'address' which will contain an IP address or dns name that the guest's display server should listen on. If, however, type='network', the <listen> element should have an attribute called 'network' that will be set to the name of a network configuration to get the IP address from. * docs/schemas/domain.rng: updated to allow the <listen> element * docs/formatdomain.html.in: document the <listen> element and its attributes. * src/conf/domain_conf.[hc]: 1) The domain parser, formatter, and data structure are modified to support 0 or more <listen> subelements to each <graphics> element. The old style "legacy" listen attribute is also still accepted, and will be stored internally just as if it were a separate <listen> element. On output (i.e. format), the address attribute of the first <listen> element of type 'address' will be duplicated in the legacy "listen" attribute of the <graphic> element. 2) The "listenAddr" attribute has been removed from the unions in virDomainGRaphicsDef for graphics types vnc, rdp, and spice. This attribute is now in the <listen> subelement (aka virDomainGraphicsListenDef) 3) Helper functions were written to provide simple access (both Get and Set) to the listen elements and their attributes. * src/libvirt_private.syms: export the listen helper functions * src/qemu/qemu_command.c, src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c, src/vbox/vbox_tmpl.c, src/vmx/vmx.c, src/xenxs/xen_sxpr.c, src/xenxs/xen_xm.c Modify all these files to use the listen helper functions rather than directly referencing the (now missing) listenAddr attribute. There can be multiple <listen> elements to a single <graphics>, but the drivers all currently only support one, so all replacements of direct access with a helper function indicate index "0". * tests/* - only 3 of these are new files added explicitly to test the new <listen> element. All the others have been modified to reflect the fact that any legacy "listen" attributes passed in to the domain parse will be saved in a <listen> element (i.e. one of the virDomainGraphicsListenDefs), and during the domain format function, both the <listen> element as well as the legacy attributes will be output.
2011-07-07 04:20:28 +00:00
if (def->type != VIR_DOMAIN_GRAPHICS_TYPE_SDL &&
def->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected graphics type %d"),
def->type);
return -1;
}
virBufferAddLit(buf, "(device (vkbd))");
virBufferAddLit(buf, "(device (vfb ");
if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
virBufferAddLit(buf, "(type sdl)");
if (def->data.sdl.display)
virBufferAsprintf(buf, "(display '%s')", def->data.sdl.display);
if (def->data.sdl.xauth)
virBufferAsprintf(buf, "(xauthority '%s')", def->data.sdl.xauth);
} else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
virBufferAddLit(buf, "(type vnc)");
if (def->data.vnc.autoport) {
virBufferAddLit(buf, "(vncunused 1)");
} else {
virBufferAddLit(buf, "(vncunused 0)");
virBufferAsprintf(buf, "(vncdisplay %d)", def->data.vnc.port-5900);
}
if ((glisten = virDomainGraphicsGetListen(def, 0)) &&
glisten->address)
virBufferAsprintf(buf, "(vnclisten '%s')", glisten->address);
if (def->data.vnc.auth.passwd)
virBufferAsprintf(buf, "(vncpasswd '%s')", def->data.vnc.auth.passwd);
if (def->data.vnc.keymap)
virBufferAsprintf(buf, "(keymap '%s')", def->data.vnc.keymap);
}
virBufferAddLit(buf, "))");
return 0;
}
/**
* xenFormatSxprGraphicsOld:
* @def: the domain config
* @buf: a buffer for the result S-expression
*
* Convert the graphics part of the domain description into a S-expression
* in buf. (HVM <= 3.0.4 or PV <= 3.0.3)
*
* Returns 0 in case of success, -1 in case of error
*/
static int
xenFormatSxprGraphicsOld(virDomainGraphicsDefPtr def, virBufferPtr buf)
{
virDomainGraphicsListenDefPtr glisten;
conf: add <listen> subelement to domain <graphics> element Once it's plugged in, the <listen> element will be an optional replacement for the "listen" attribute that graphics elements already have. If the <listen> element is type='address', it will have an attribute called 'address' which will contain an IP address or dns name that the guest's display server should listen on. If, however, type='network', the <listen> element should have an attribute called 'network' that will be set to the name of a network configuration to get the IP address from. * docs/schemas/domain.rng: updated to allow the <listen> element * docs/formatdomain.html.in: document the <listen> element and its attributes. * src/conf/domain_conf.[hc]: 1) The domain parser, formatter, and data structure are modified to support 0 or more <listen> subelements to each <graphics> element. The old style "legacy" listen attribute is also still accepted, and will be stored internally just as if it were a separate <listen> element. On output (i.e. format), the address attribute of the first <listen> element of type 'address' will be duplicated in the legacy "listen" attribute of the <graphic> element. 2) The "listenAddr" attribute has been removed from the unions in virDomainGRaphicsDef for graphics types vnc, rdp, and spice. This attribute is now in the <listen> subelement (aka virDomainGraphicsListenDef) 3) Helper functions were written to provide simple access (both Get and Set) to the listen elements and their attributes. * src/libvirt_private.syms: export the listen helper functions * src/qemu/qemu_command.c, src/qemu/qemu_hotplug.c, src/qemu/qemu_migration.c, src/vbox/vbox_tmpl.c, src/vmx/vmx.c, src/xenxs/xen_sxpr.c, src/xenxs/xen_xm.c Modify all these files to use the listen helper functions rather than directly referencing the (now missing) listenAddr attribute. There can be multiple <listen> elements to a single <graphics>, but the drivers all currently only support one, so all replacements of direct access with a helper function indicate index "0". * tests/* - only 3 of these are new files added explicitly to test the new <listen> element. All the others have been modified to reflect the fact that any legacy "listen" attributes passed in to the domain parse will be saved in a <listen> element (i.e. one of the virDomainGraphicsListenDefs), and during the domain format function, both the <listen> element as well as the legacy attributes will be output.
2011-07-07 04:20:28 +00:00
if (def->type != VIR_DOMAIN_GRAPHICS_TYPE_SDL &&
def->type != VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected graphics type %d"),
def->type);
return -1;
}
if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
virBufferAddLit(buf, "(sdl 1)");
if (def->data.sdl.display)
virBufferAsprintf(buf, "(display '%s')", def->data.sdl.display);
if (def->data.sdl.xauth)
virBufferAsprintf(buf, "(xauthority '%s')", def->data.sdl.xauth);
} else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
virBufferAddLit(buf, "(vnc 1)");
if (def->data.vnc.autoport) {
virBufferAddLit(buf, "(vncunused 1)");
} else {
virBufferAddLit(buf, "(vncunused 0)");
virBufferAsprintf(buf, "(vncdisplay %d)", def->data.vnc.port-5900);
}
if ((glisten = virDomainGraphicsGetListen(def, 0)) &&
glisten->address)
virBufferAsprintf(buf, "(vnclisten '%s')", glisten->address);
if (def->data.vnc.auth.passwd)
virBufferAsprintf(buf, "(vncpasswd '%s')", def->data.vnc.auth.passwd);
if (def->data.vnc.keymap)
virBufferAsprintf(buf, "(keymap '%s')", def->data.vnc.keymap);
}
return 0;
}
/**
* xenFormatSxprChr:
* @def: the domain config
* @buf: a buffer for the result S-expression
*
* Convert the character device part of the domain config into a S-expression
* in buf.
*
* Returns 0 in case of success, -1 in case of error
*/
int
2011-02-21 13:40:12 +00:00
xenFormatSxprChr(virDomainChrDefPtr def,
virBufferPtr buf)
{
const char *type = virDomainChrTypeToString(def->source->type);
if (!type) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("unexpected chr device type"));
return -1;
}
switch (def->source->type) {
case VIR_DOMAIN_CHR_TYPE_NULL:
case VIR_DOMAIN_CHR_TYPE_STDIO:
case VIR_DOMAIN_CHR_TYPE_VC:
case VIR_DOMAIN_CHR_TYPE_PTY:
virBufferAdd(buf, type, -1);
break;
case VIR_DOMAIN_CHR_TYPE_FILE:
case VIR_DOMAIN_CHR_TYPE_PIPE:
virBufferAsprintf(buf, "%s:", type);
virBufferEscapeSexpr(buf, "%s", def->source->data.file.path);
break;
case VIR_DOMAIN_CHR_TYPE_DEV:
virBufferEscapeSexpr(buf, "%s", def->source->data.file.path);
break;
case VIR_DOMAIN_CHR_TYPE_TCP:
virBufferAsprintf(buf, "%s:%s:%s%s",
(def->source->data.tcp.protocol
== VIR_DOMAIN_CHR_TCP_PROTOCOL_RAW ?
"tcp" : "telnet"),
(def->source->data.tcp.host ?
def->source->data.tcp.host : ""),
(def->source->data.tcp.service ?
def->source->data.tcp.service : ""),
(def->source->data.tcp.listen ?
",server,nowait" : ""));
break;
case VIR_DOMAIN_CHR_TYPE_UDP:
virBufferAsprintf(buf, "%s:%s:%s@%s:%s", type,
(def->source->data.udp.connectHost ?
def->source->data.udp.connectHost : ""),
(def->source->data.udp.connectService ?
def->source->data.udp.connectService : ""),
(def->source->data.udp.bindHost ?
def->source->data.udp.bindHost : ""),
(def->source->data.udp.bindService ?
def->source->data.udp.bindService : ""));
break;
case VIR_DOMAIN_CHR_TYPE_UNIX:
virBufferAsprintf(buf, "%s:", type);
virBufferEscapeSexpr(buf, "%s", def->source->data.nix.path);
if (def->source->data.nix.listen)
virBufferAddLit(buf, ",server,nowait");
break;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported chr device type '%s'"), type);
return -1;
}
if (virBufferCheckError(buf) < 0)
return -1;
return 0;
}
/**
* xenFormatSxprDisk:
* @node: node containing the disk description
* @buf: a buffer for the result S-expression
* @hvm: true or 1 if domain is HVM
* @isAttach: create expression for device attach (1).
*
* Convert the disk device part of the domain config into a S-expresssion in buf.
*
* Returns 0 in case of success, -1 in case of error.
*/
int
xenFormatSxprDisk(virDomainDiskDefPtr def,
2011-02-21 13:40:12 +00:00
virBufferPtr buf,
int hvm,
int isAttach)
{
const char *src = virDomainDiskGetSource(def);
const char *driver = virDomainDiskGetDriver(def);
/* Xend (all versions) put the floppy device config
* under the hvm (image (os)) block
*/
if (hvm &&
def->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) {
if (isAttach) {
virReportError(VIR_ERR_INVALID_ARG,
_("Cannot directly attach floppy %s"), src);
return -1;
}
return 0;
}
if (!isAttach)
virBufferAddLit(buf, "(device ");
/* Normally disks are in a (device (vbd ...)) block
* but blktap disks ended up in a differently named
* (device (tap ....)) block.... */
if (STREQ_NULLABLE(driver, "tap")) {
virBufferAddLit(buf, "(tap ");
} else if (STREQ_NULLABLE(driver, "tap2")) {
virBufferAddLit(buf, "(tap2 ");
} else {
virBufferAddLit(buf, "(vbd ");
}
if (hvm) {
virBufferEscapeSexpr(buf, "(dev '%s:", def->dst);
virBufferAsprintf(buf, "%s')",
def->device == VIR_DOMAIN_DISK_DEVICE_CDROM ?
"cdrom" : "disk");
} else if (def->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
virBufferEscapeSexpr(buf, "(dev '%s:cdrom')", def->dst);
} else {
virBufferEscapeSexpr(buf, "(dev '%s')", def->dst);
}
if (src) {
if (driver) {
if (STREQ(driver, "tap") ||
STREQ(driver, "tap2")) {
const char *type;
int format = virDomainDiskGetFormat(def);
if (!format || format == VIR_STORAGE_FILE_RAW)
type = "aio";
else
type = virStorageFileFormatTypeToString(format);
virBufferEscapeSexpr(buf, "(uname '%s:", driver);
virBufferEscapeSexpr(buf, "%s:", type);
virBufferEscapeSexpr(buf, "%s')", src);
} else {
virBufferEscapeSexpr(buf, "(uname '%s:", driver);
virBufferEscapeSexpr(buf, "%s')", src);
}
} else {
int type = virDomainDiskGetType(def);
conf: move host disk type to util/ A continuation of the migration of disk details to virstoragefile. This patch moves a single enum, but converting the name has quite a bit of fallout. * src/conf/domain_conf.h (virDomainDiskType): Move... * src/util/virstoragefile.h (virStorageType): ...and rename. * src/bhyve/bhyve_command.c (bhyveBuildDiskArgStr) (virBhyveProcessBuildLoadCmd): Update clients. * src/conf/domain_conf.c (virDomainDiskSourceDefParse) (virDomainDiskDefParseXML, virDomainDiskSourceDefFormatInternal) (virDomainDiskDefFormat, virDomainDiskGetActualType) (virDomainDiskDefForeachPath, virDomainDiskSourceIsBlockType): Likewise. * src/conf/snapshot_conf.h (_virDomainSnapshotDiskDef): Likewise. * src/conf/snapshot_conf.c (virDomainSnapshotDiskDefParseXML) (virDomainSnapshotAlignDisks, virDomainSnapshotDiskDefFormat): Likewise. * src/esx/esx_driver.c (esxAutodetectSCSIControllerModel) (esxDomainDefineXML): Likewise. * src/locking/domain_lock.c (virDomainLockManagerAddDisk): Likewise. * src/lxc/lxc_controller.c (virLXCControllerSetupLoopDeviceDisk) (virLXCControllerSetupNBDDeviceDisk) (virLXCControllerSetupLoopDevices, virLXCControllerSetupDisk): Likewise. * src/parallels/parallels_driver.c (parallelsGetHddInfo): Likewise. * src/phyp/phyp_driver.c (phypDiskType): Likewise. * src/qemu/qemu_command.c (qemuGetDriveSourceString) (qemuDomainDiskGetSourceString, qemuBuildDriveStr) (qemuBuildCommandLine, qemuParseCommandLineDisk) (qemuParseCommandLine): Likewise. * src/qemu/qemu_conf.c (qemuCheckSharedDevice) (qemuTranslateDiskSourcePool) (qemuTranslateSnapshotDiskSourcePool): Likewise. * src/qemu/qemu_domain.c (qemuDomainDeviceDefPostParse) (qemuDomainDetermineDiskChain): Likewise. * src/qemu/qemu_driver.c (qemuDomainGetBlockInfo) (qemuDomainSnapshotPrepareDiskExternalBackingInactive) (qemuDomainSnapshotPrepareDiskExternalBackingActive) (qemuDomainSnapshotPrepareDiskExternalOverlayActive) (qemuDomainSnapshotPrepareDiskExternalOverlayInactive) (qemuDomainSnapshotPrepareDiskInternal) (qemuDomainSnapshotPrepare) (qemuDomainSnapshotCreateSingleDiskActive): Likewise. * src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia): Likewise. * src/qemu/qemu_migration.c (qemuMigrationIsSafe): Likewise. * src/security/security_apparmor.c (AppArmorRestoreSecurityImageLabel) (AppArmorSetSecurityImageLabel): Likewise. * src/security/security_dac.c (virSecurityDACSetSecurityImageLabel) (virSecurityDACRestoreSecurityImageLabelInt) (virSecurityDACSetSecurityAllLabel): Likewise. * src/security/security_selinux.c (virSecuritySELinuxRestoreSecurityImageLabelInt) (virSecuritySELinuxSetSecurityImageLabel) (virSecuritySELinuxSetSecurityAllLabel): Likewise. * src/storage/storage_backend.c (virStorageFileBackendForType): Likewise. * src/storage/storage_backend_fs.c (virStorageFileBackendFile) (virStorageFileBackendBlock): Likewise. * src/storage/storage_backend_gluster.c (virStorageFileBackendGluster): Likewise. * src/vbox/vbox_tmpl.c (vboxDomainGetXMLDesc, vboxAttachDrives) (vboxDomainAttachDeviceImpl, vboxDomainDetachDevice): Likewise. * src/vmware/vmware_conf.c (vmwareVmxPath): Likewise. * src/vmx/vmx.c (virVMXParseDisk, virVMXFormatDisk) (virVMXFormatFloppy): Likewise. * src/xenxs/xen_sxpr.c (xenParseSxprDisks, xenParseSxpr) (xenFormatSxprDisk): Likewise. * src/xenxs/xen_xm.c (xenParseXM, xenFormatXMDisk): Likewise. * tests/securityselinuxlabeltest.c (testSELinuxLoadDef): Likewise. * src/libvirt_private.syms (domain_conf.h): Move symbols... (virstoragefile.h): ...as appropriate. Signed-off-by: Eric Blake <eblake@redhat.com>
2014-03-27 21:57:49 +00:00
if (type == VIR_STORAGE_TYPE_FILE) {
virBufferEscapeSexpr(buf, "(uname 'file:%s')", src);
conf: move host disk type to util/ A continuation of the migration of disk details to virstoragefile. This patch moves a single enum, but converting the name has quite a bit of fallout. * src/conf/domain_conf.h (virDomainDiskType): Move... * src/util/virstoragefile.h (virStorageType): ...and rename. * src/bhyve/bhyve_command.c (bhyveBuildDiskArgStr) (virBhyveProcessBuildLoadCmd): Update clients. * src/conf/domain_conf.c (virDomainDiskSourceDefParse) (virDomainDiskDefParseXML, virDomainDiskSourceDefFormatInternal) (virDomainDiskDefFormat, virDomainDiskGetActualType) (virDomainDiskDefForeachPath, virDomainDiskSourceIsBlockType): Likewise. * src/conf/snapshot_conf.h (_virDomainSnapshotDiskDef): Likewise. * src/conf/snapshot_conf.c (virDomainSnapshotDiskDefParseXML) (virDomainSnapshotAlignDisks, virDomainSnapshotDiskDefFormat): Likewise. * src/esx/esx_driver.c (esxAutodetectSCSIControllerModel) (esxDomainDefineXML): Likewise. * src/locking/domain_lock.c (virDomainLockManagerAddDisk): Likewise. * src/lxc/lxc_controller.c (virLXCControllerSetupLoopDeviceDisk) (virLXCControllerSetupNBDDeviceDisk) (virLXCControllerSetupLoopDevices, virLXCControllerSetupDisk): Likewise. * src/parallels/parallels_driver.c (parallelsGetHddInfo): Likewise. * src/phyp/phyp_driver.c (phypDiskType): Likewise. * src/qemu/qemu_command.c (qemuGetDriveSourceString) (qemuDomainDiskGetSourceString, qemuBuildDriveStr) (qemuBuildCommandLine, qemuParseCommandLineDisk) (qemuParseCommandLine): Likewise. * src/qemu/qemu_conf.c (qemuCheckSharedDevice) (qemuTranslateDiskSourcePool) (qemuTranslateSnapshotDiskSourcePool): Likewise. * src/qemu/qemu_domain.c (qemuDomainDeviceDefPostParse) (qemuDomainDetermineDiskChain): Likewise. * src/qemu/qemu_driver.c (qemuDomainGetBlockInfo) (qemuDomainSnapshotPrepareDiskExternalBackingInactive) (qemuDomainSnapshotPrepareDiskExternalBackingActive) (qemuDomainSnapshotPrepareDiskExternalOverlayActive) (qemuDomainSnapshotPrepareDiskExternalOverlayInactive) (qemuDomainSnapshotPrepareDiskInternal) (qemuDomainSnapshotPrepare) (qemuDomainSnapshotCreateSingleDiskActive): Likewise. * src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia): Likewise. * src/qemu/qemu_migration.c (qemuMigrationIsSafe): Likewise. * src/security/security_apparmor.c (AppArmorRestoreSecurityImageLabel) (AppArmorSetSecurityImageLabel): Likewise. * src/security/security_dac.c (virSecurityDACSetSecurityImageLabel) (virSecurityDACRestoreSecurityImageLabelInt) (virSecurityDACSetSecurityAllLabel): Likewise. * src/security/security_selinux.c (virSecuritySELinuxRestoreSecurityImageLabelInt) (virSecuritySELinuxSetSecurityImageLabel) (virSecuritySELinuxSetSecurityAllLabel): Likewise. * src/storage/storage_backend.c (virStorageFileBackendForType): Likewise. * src/storage/storage_backend_fs.c (virStorageFileBackendFile) (virStorageFileBackendBlock): Likewise. * src/storage/storage_backend_gluster.c (virStorageFileBackendGluster): Likewise. * src/vbox/vbox_tmpl.c (vboxDomainGetXMLDesc, vboxAttachDrives) (vboxDomainAttachDeviceImpl, vboxDomainDetachDevice): Likewise. * src/vmware/vmware_conf.c (vmwareVmxPath): Likewise. * src/vmx/vmx.c (virVMXParseDisk, virVMXFormatDisk) (virVMXFormatFloppy): Likewise. * src/xenxs/xen_sxpr.c (xenParseSxprDisks, xenParseSxpr) (xenFormatSxprDisk): Likewise. * src/xenxs/xen_xm.c (xenParseXM, xenFormatXMDisk): Likewise. * tests/securityselinuxlabeltest.c (testSELinuxLoadDef): Likewise. * src/libvirt_private.syms (domain_conf.h): Move symbols... (virstoragefile.h): ...as appropriate. Signed-off-by: Eric Blake <eblake@redhat.com>
2014-03-27 21:57:49 +00:00
} else if (type == VIR_STORAGE_TYPE_BLOCK) {
if (src[0] == '/')
virBufferEscapeSexpr(buf, "(uname 'phy:%s')", src);
else
virBufferEscapeSexpr(buf, "(uname 'phy:/dev/%s')",
src);
} else {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported disk type %s"),
conf: move host disk type to util/ A continuation of the migration of disk details to virstoragefile. This patch moves a single enum, but converting the name has quite a bit of fallout. * src/conf/domain_conf.h (virDomainDiskType): Move... * src/util/virstoragefile.h (virStorageType): ...and rename. * src/bhyve/bhyve_command.c (bhyveBuildDiskArgStr) (virBhyveProcessBuildLoadCmd): Update clients. * src/conf/domain_conf.c (virDomainDiskSourceDefParse) (virDomainDiskDefParseXML, virDomainDiskSourceDefFormatInternal) (virDomainDiskDefFormat, virDomainDiskGetActualType) (virDomainDiskDefForeachPath, virDomainDiskSourceIsBlockType): Likewise. * src/conf/snapshot_conf.h (_virDomainSnapshotDiskDef): Likewise. * src/conf/snapshot_conf.c (virDomainSnapshotDiskDefParseXML) (virDomainSnapshotAlignDisks, virDomainSnapshotDiskDefFormat): Likewise. * src/esx/esx_driver.c (esxAutodetectSCSIControllerModel) (esxDomainDefineXML): Likewise. * src/locking/domain_lock.c (virDomainLockManagerAddDisk): Likewise. * src/lxc/lxc_controller.c (virLXCControllerSetupLoopDeviceDisk) (virLXCControllerSetupNBDDeviceDisk) (virLXCControllerSetupLoopDevices, virLXCControllerSetupDisk): Likewise. * src/parallels/parallels_driver.c (parallelsGetHddInfo): Likewise. * src/phyp/phyp_driver.c (phypDiskType): Likewise. * src/qemu/qemu_command.c (qemuGetDriveSourceString) (qemuDomainDiskGetSourceString, qemuBuildDriveStr) (qemuBuildCommandLine, qemuParseCommandLineDisk) (qemuParseCommandLine): Likewise. * src/qemu/qemu_conf.c (qemuCheckSharedDevice) (qemuTranslateDiskSourcePool) (qemuTranslateSnapshotDiskSourcePool): Likewise. * src/qemu/qemu_domain.c (qemuDomainDeviceDefPostParse) (qemuDomainDetermineDiskChain): Likewise. * src/qemu/qemu_driver.c (qemuDomainGetBlockInfo) (qemuDomainSnapshotPrepareDiskExternalBackingInactive) (qemuDomainSnapshotPrepareDiskExternalBackingActive) (qemuDomainSnapshotPrepareDiskExternalOverlayActive) (qemuDomainSnapshotPrepareDiskExternalOverlayInactive) (qemuDomainSnapshotPrepareDiskInternal) (qemuDomainSnapshotPrepare) (qemuDomainSnapshotCreateSingleDiskActive): Likewise. * src/qemu/qemu_hotplug.c (qemuDomainChangeEjectableMedia): Likewise. * src/qemu/qemu_migration.c (qemuMigrationIsSafe): Likewise. * src/security/security_apparmor.c (AppArmorRestoreSecurityImageLabel) (AppArmorSetSecurityImageLabel): Likewise. * src/security/security_dac.c (virSecurityDACSetSecurityImageLabel) (virSecurityDACRestoreSecurityImageLabelInt) (virSecurityDACSetSecurityAllLabel): Likewise. * src/security/security_selinux.c (virSecuritySELinuxRestoreSecurityImageLabelInt) (virSecuritySELinuxSetSecurityImageLabel) (virSecuritySELinuxSetSecurityAllLabel): Likewise. * src/storage/storage_backend.c (virStorageFileBackendForType): Likewise. * src/storage/storage_backend_fs.c (virStorageFileBackendFile) (virStorageFileBackendBlock): Likewise. * src/storage/storage_backend_gluster.c (virStorageFileBackendGluster): Likewise. * src/vbox/vbox_tmpl.c (vboxDomainGetXMLDesc, vboxAttachDrives) (vboxDomainAttachDeviceImpl, vboxDomainDetachDevice): Likewise. * src/vmware/vmware_conf.c (vmwareVmxPath): Likewise. * src/vmx/vmx.c (virVMXParseDisk, virVMXFormatDisk) (virVMXFormatFloppy): Likewise. * src/xenxs/xen_sxpr.c (xenParseSxprDisks, xenParseSxpr) (xenFormatSxprDisk): Likewise. * src/xenxs/xen_xm.c (xenParseXM, xenFormatXMDisk): Likewise. * tests/securityselinuxlabeltest.c (testSELinuxLoadDef): Likewise. * src/libvirt_private.syms (domain_conf.h): Move symbols... (virstoragefile.h): ...as appropriate. Signed-off-by: Eric Blake <eblake@redhat.com>
2014-03-27 21:57:49 +00:00
virStorageTypeToString(type));
return -1;
}
}
}
if (def->src->readonly)
virBufferAddLit(buf, "(mode 'r')");
else if (def->src->shared)
virBufferAddLit(buf, "(mode 'w!')");
else
virBufferAddLit(buf, "(mode 'w')");
if (def->transient) {
maint: don't permit format strings without % Any time we have a string with no % passed through gettext, a translator can inject a % to cause a stack overread. When there is nothing to format, it's easier to ask for a string that cannot be used as a formatter, by using a trivial "%s" format instead. In the past, we have used --disable-nls to catch some of the offenders, but that doesn't get run very often, and many more uses have crept in. Syntax check to the rescue! The syntax check can catch uses such as virReportError(code, _("split " "string")); by using a sed script to fold context lines into one pattern space before checking for a string without %. This patch is just mechanical insertion of %s; there are probably several messages touched by this patch where we would be better off giving the user more information than a fixed string. * cfg.mk (sc_prohibit_diagnostic_without_format): New rule. * src/datatypes.c (virUnrefConnect, virGetDomain) (virUnrefDomain, virGetNetwork, virUnrefNetwork, virGetInterface) (virUnrefInterface, virGetStoragePool, virUnrefStoragePool) (virGetStorageVol, virUnrefStorageVol, virGetNodeDevice) (virGetSecret, virUnrefSecret, virGetNWFilter, virUnrefNWFilter) (virGetDomainSnapshot, virUnrefDomainSnapshot): Add %s wrapper. * src/lxc/lxc_driver.c (lxcDomainSetBlkioParameters) (lxcDomainGetBlkioParameters): Likewise. * src/conf/domain_conf.c (virSecurityDeviceLabelDefParseXML) (virDomainDiskDefParseXML, virDomainGraphicsDefParseXML): Likewise. * src/conf/network_conf.c (virNetworkDNSHostsDefParseXML) (virNetworkDefParseXML): Likewise. * src/conf/nwfilter_conf.c (virNWFilterIsValidChainName): Likewise. * src/conf/nwfilter_params.c (virNWFilterVarValueCreateSimple) (virNWFilterVarAccessParse): Likewise. * src/libvirt.c (virDomainSave, virDomainSaveFlags) (virDomainRestore, virDomainRestoreFlags) (virDomainSaveImageGetXMLDesc, virDomainSaveImageDefineXML) (virDomainCoreDump, virDomainGetXMLDesc) (virDomainMigrateVersion1, virDomainMigrateVersion2) (virDomainMigrateVersion3, virDomainMigrate, virDomainMigrate2) (virStreamSendAll, virStreamRecvAll) (virDomainSnapshotGetXMLDesc): Likewise. * src/nwfilter/nwfilter_dhcpsnoop.c (virNWFilterSnoopReqLeaseDel) (virNWFilterDHCPSnoopReq): Likewise. * src/openvz/openvz_driver.c (openvzUpdateDevice): Likewise. * src/openvz/openvz_util.c (openvzKBPerPages): Likewise. * src/qemu/qemu_cgroup.c (qemuSetupCgroup): Likewise. * src/qemu/qemu_command.c (qemuBuildHubDevStr, qemuBuildChrChardevStr) (qemuBuildCommandLine): Likewise. * src/qemu/qemu_driver.c (qemuDomainGetPercpuStats): Likewise. * src/qemu/qemu_hotplug.c (qemuDomainAttachNetDevice): Likewise. * src/rpc/virnetsaslcontext.c (virNetSASLSessionGetIdentity): Likewise. * src/rpc/virnetsocket.c (virNetSocketNewConnectUNIX) (virNetSocketSendFD, virNetSocketRecvFD): Likewise. * src/storage/storage_backend_disk.c (virStorageBackendDiskBuildPool): Likewise. * src/storage/storage_backend_fs.c (virStorageBackendFileSystemProbe) (virStorageBackendFileSystemBuild): Likewise. * src/storage/storage_backend_rbd.c (virStorageBackendRBDOpenRADOSConn): Likewise. * src/storage/storage_driver.c (storageVolumeResize): Likewise. * src/test/test_driver.c (testInterfaceChangeBegin) (testInterfaceChangeCommit, testInterfaceChangeRollback): Likewise. * src/vbox/vbox_tmpl.c (vboxListAllDomains): Likewise. * src/xenxs/xen_sxpr.c (xenFormatSxprDisk, xenFormatSxpr): Likewise. * src/xenxs/xen_xm.c (xenXMConfigGetUUID, xenFormatXMDisk) (xenFormatXM): Likewise.
2012-07-23 20:33:08 +00:00
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("transient disks not supported yet"));
return -1;
}
if (!isAttach)
virBufferAddLit(buf, ")");
virBufferAddLit(buf, ")");
return 0;
}
/**
* xenFormatSxprNet:
* @conn: connection
* @def: the domain config
* @buf: a buffer for the result S-expression
* @hvm: true or 1 if domain is HVM
* @isAttach: create expression for device attach (1).
*
* Convert the interface description of the domain config into a S-expression in buf.
* This is a temporary interface as the S-Expr interface
* will be replaced by XML-RPC in the future. However the XML format should
* stay valid over time.
*
* Returns 0 in case of success, -1 in case of error.
*/
int
2011-02-21 13:40:12 +00:00
xenFormatSxprNet(virConnectPtr conn,
virDomainNetDefPtr def,
virBufferPtr buf,
int hvm,
int isAttach)
{
const char *script = DEFAULT_VIF_SCRIPT;
char macaddr[VIR_MAC_STRING_BUFLEN];
if (def->type != VIR_DOMAIN_NET_TYPE_BRIDGE &&
def->type != VIR_DOMAIN_NET_TYPE_NETWORK &&
def->type != VIR_DOMAIN_NET_TYPE_ETHERNET) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unsupported network type %d"), def->type);
return -1;
}
config: report error when script given for inappropriate interface type This fixes https://bugzilla.redhat.com/show_bug.cgi?id=638633 Although scripts are not used by interfaces of type other than "ethernet" in qemu, due to the fact that the parser stores the script name in a union that is only valid when type is ethernet or bridge, there is no way for anyone except the parser itself to catch the problem of specifying an interface script for an inappropriate interface type (by the time the parsed data gets back to the code that called the parser, all evidence that a script was specified is forgotten). Since the parser itself should be agnostic to which type of interface allows scripts (an example of why: a script specified for an interface of type bridge is valid for xen domains, but not for qemu domains), the solution here is to move the script out of the union(s) in the DomainNetDef, always populate it when specified (regardless of interface type), and let the driver decide whether or not it is appropriate. Currently the qemu, xen, libxml, and uml drivers recognize the script parameter and do something with it (the uml driver only to report that it isn't supported). Those drivers have been updated to log a CONFIG_UNSUPPORTED error when a script is specified for an interface type that's inappropriate for that particular hypervisor. (NB: There was earlier discussion of solving this problem by adding a VALIDATE flag to all libvirt APIs that accept XML, which would cause the XML to be validated against the RNG files. One statement during that discussion was that the RNG shouldn't contain hypervisor-specific things, though, and a proper solution to this problem would require that (again, because a script for an interface of type "bridge" is accepted by xen, but not by qemu).
2012-01-06 17:59:47 +00:00
if (def->script &&
def->type != VIR_DOMAIN_NET_TYPE_BRIDGE &&
def->type != VIR_DOMAIN_NET_TYPE_ETHERNET) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("scripts are not supported on interfaces of type %s"),
virDomainNetTypeToString(def->type));
config: report error when script given for inappropriate interface type This fixes https://bugzilla.redhat.com/show_bug.cgi?id=638633 Although scripts are not used by interfaces of type other than "ethernet" in qemu, due to the fact that the parser stores the script name in a union that is only valid when type is ethernet or bridge, there is no way for anyone except the parser itself to catch the problem of specifying an interface script for an inappropriate interface type (by the time the parsed data gets back to the code that called the parser, all evidence that a script was specified is forgotten). Since the parser itself should be agnostic to which type of interface allows scripts (an example of why: a script specified for an interface of type bridge is valid for xen domains, but not for qemu domains), the solution here is to move the script out of the union(s) in the DomainNetDef, always populate it when specified (regardless of interface type), and let the driver decide whether or not it is appropriate. Currently the qemu, xen, libxml, and uml drivers recognize the script parameter and do something with it (the uml driver only to report that it isn't supported). Those drivers have been updated to log a CONFIG_UNSUPPORTED error when a script is specified for an interface type that's inappropriate for that particular hypervisor. (NB: There was earlier discussion of solving this problem by adding a VALIDATE flag to all libvirt APIs that accept XML, which would cause the XML to be validated against the RNG files. One statement during that discussion was that the RNG shouldn't contain hypervisor-specific things, though, and a proper solution to this problem would require that (again, because a script for an interface of type "bridge" is accepted by xen, but not by qemu).
2012-01-06 17:59:47 +00:00
return -1;
}
if (!isAttach)
virBufferAddLit(buf, "(device ");
virBufferAddLit(buf, "(vif ");
virBufferAsprintf(buf, "(mac '%s')", virMacAddrFormat(&def->mac, macaddr));
if (def->bandwidth && def->bandwidth->out && def->bandwidth->out->average)
virBufferAsprintf(buf, "(rate '%lluKB/s')", def->bandwidth->out->average);
switch (def->type) {
case VIR_DOMAIN_NET_TYPE_BRIDGE:
virBufferEscapeSexpr(buf, "(bridge '%s')", def->data.bridge.brname);
config: report error when script given for inappropriate interface type This fixes https://bugzilla.redhat.com/show_bug.cgi?id=638633 Although scripts are not used by interfaces of type other than "ethernet" in qemu, due to the fact that the parser stores the script name in a union that is only valid when type is ethernet or bridge, there is no way for anyone except the parser itself to catch the problem of specifying an interface script for an inappropriate interface type (by the time the parsed data gets back to the code that called the parser, all evidence that a script was specified is forgotten). Since the parser itself should be agnostic to which type of interface allows scripts (an example of why: a script specified for an interface of type bridge is valid for xen domains, but not for qemu domains), the solution here is to move the script out of the union(s) in the DomainNetDef, always populate it when specified (regardless of interface type), and let the driver decide whether or not it is appropriate. Currently the qemu, xen, libxml, and uml drivers recognize the script parameter and do something with it (the uml driver only to report that it isn't supported). Those drivers have been updated to log a CONFIG_UNSUPPORTED error when a script is specified for an interface type that's inappropriate for that particular hypervisor. (NB: There was earlier discussion of solving this problem by adding a VALIDATE flag to all libvirt APIs that accept XML, which would cause the XML to be validated against the RNG files. One statement during that discussion was that the RNG shouldn't contain hypervisor-specific things, though, and a proper solution to this problem would require that (again, because a script for an interface of type "bridge" is accepted by xen, but not by qemu).
2012-01-06 17:59:47 +00:00
if (def->script)
script = def->script;
virBufferEscapeSexpr(buf, "(script '%s')", script);
if (def->guestIP.nips == 1) {
char *ipStr = virSocketAddrFormat(&def->guestIP.ips[0]->address);
virBufferEscapeSexpr(buf, "(ip '%s')", ipStr);
VIR_FREE(ipStr);
} else if (def->guestIP.nips > 1) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Driver does not support setting multiple IP addresses"));
return -1;
}
break;
case VIR_DOMAIN_NET_TYPE_NETWORK:
{
virNetworkPtr network =
virNetworkLookupByName(conn, def->data.network.name);
char *bridge;
if (!network) {
virReportError(VIR_ERR_NO_NETWORK, "%s",
def->data.network.name);
return -1;
}
bridge = virNetworkGetBridgeName(network);
virObjectUnref(network);
if (!bridge) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("network %s is not active"),
def->data.network.name);
return -1;
}
virBufferEscapeSexpr(buf, "(bridge '%s')", bridge);
virBufferEscapeSexpr(buf, "(script '%s')", script);
VIR_FREE(bridge);
}
break;
case VIR_DOMAIN_NET_TYPE_ETHERNET:
config: report error when script given for inappropriate interface type This fixes https://bugzilla.redhat.com/show_bug.cgi?id=638633 Although scripts are not used by interfaces of type other than "ethernet" in qemu, due to the fact that the parser stores the script name in a union that is only valid when type is ethernet or bridge, there is no way for anyone except the parser itself to catch the problem of specifying an interface script for an inappropriate interface type (by the time the parsed data gets back to the code that called the parser, all evidence that a script was specified is forgotten). Since the parser itself should be agnostic to which type of interface allows scripts (an example of why: a script specified for an interface of type bridge is valid for xen domains, but not for qemu domains), the solution here is to move the script out of the union(s) in the DomainNetDef, always populate it when specified (regardless of interface type), and let the driver decide whether or not it is appropriate. Currently the qemu, xen, libxml, and uml drivers recognize the script parameter and do something with it (the uml driver only to report that it isn't supported). Those drivers have been updated to log a CONFIG_UNSUPPORTED error when a script is specified for an interface type that's inappropriate for that particular hypervisor. (NB: There was earlier discussion of solving this problem by adding a VALIDATE flag to all libvirt APIs that accept XML, which would cause the XML to be validated against the RNG files. One statement during that discussion was that the RNG shouldn't contain hypervisor-specific things, though, and a proper solution to this problem would require that (again, because a script for an interface of type "bridge" is accepted by xen, but not by qemu).
2012-01-06 17:59:47 +00:00
if (def->script)
virBufferEscapeSexpr(buf, "(script '%s')",
config: report error when script given for inappropriate interface type This fixes https://bugzilla.redhat.com/show_bug.cgi?id=638633 Although scripts are not used by interfaces of type other than "ethernet" in qemu, due to the fact that the parser stores the script name in a union that is only valid when type is ethernet or bridge, there is no way for anyone except the parser itself to catch the problem of specifying an interface script for an inappropriate interface type (by the time the parsed data gets back to the code that called the parser, all evidence that a script was specified is forgotten). Since the parser itself should be agnostic to which type of interface allows scripts (an example of why: a script specified for an interface of type bridge is valid for xen domains, but not for qemu domains), the solution here is to move the script out of the union(s) in the DomainNetDef, always populate it when specified (regardless of interface type), and let the driver decide whether or not it is appropriate. Currently the qemu, xen, libxml, and uml drivers recognize the script parameter and do something with it (the uml driver only to report that it isn't supported). Those drivers have been updated to log a CONFIG_UNSUPPORTED error when a script is specified for an interface type that's inappropriate for that particular hypervisor. (NB: There was earlier discussion of solving this problem by adding a VALIDATE flag to all libvirt APIs that accept XML, which would cause the XML to be validated against the RNG files. One statement during that discussion was that the RNG shouldn't contain hypervisor-specific things, though, and a proper solution to this problem would require that (again, because a script for an interface of type "bridge" is accepted by xen, but not by qemu).
2012-01-06 17:59:47 +00:00
def->script);
if (def->guestIP.nips == 1) {
char *ipStr = virSocketAddrFormat(&def->guestIP.ips[0]->address);
virBufferEscapeSexpr(buf, "(ip '%s')", ipStr);
VIR_FREE(ipStr);
} else if (def->guestIP.nips > 1) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Driver does not support setting multiple IP addresses"));
return -1;
}
break;
case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
case VIR_DOMAIN_NET_TYPE_USER:
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
case VIR_DOMAIN_NET_TYPE_UDP:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_DIRECT:
conf: parse/format type='hostdev' network interfaces This is the new interface type that sets up an SR-IOV PCI network device to be assigned to the guest with PCI passthrough after initializing some network device-specific things from the config (e.g. MAC address, virtualport profile parameters). Here is an example of the syntax: <interface type='hostdev' managed='yes'> <source> <address type='pci' domain='0' bus='0' slot='4' function='3'/> </source> <mac address='00:11:22:33:44:55'/> <address type='pci' domain='0' bus='0' slot='7' function='0'/> </interface> This would assign the PCI card from bus 0 slot 4 function 3 on the host, to bus 0 slot 7 function 0 on the guest, but would first set the MAC address of the card to 00:11:22:33:44:55. NB: The parser and formatter don't care if the PCI card being specified is a standard single function network adapter, or a virtual function (VF) of an SR-IOV capable network adapter, but the upcoming code that implements the back end of this config will work *only* with SR-IOV VFs. This is because modifying the mac address of a standard network adapter prior to assigning it to a guest is pointless - part of the device reset that occurs during that process will reset the MAC address to the value programmed into the card's firmware. Although it's not supported by any of libvirt's hypervisor drivers, usb network hostdevs are also supported in the parser and formatter for completeness and consistency. <source> syntax is identical to that for plain <hostdev> devices, except that the <address> element should have "type='usb'" added if bus/device are specified: <interface type='hostdev'> <source> <address type='usb' bus='0' device='4'/> </source> <mac address='00:11:22:33:44:55'/> </interface> If the vendor/product form of usb specification is used, type='usb' is implied: <interface type='hostdev'> <source> <vendor id='0x0012'/> <product id='0x24dd'/> </source> <mac address='00:11:22:33:44:55'/> </interface> Again, the upcoming patch to fill in the backend of this functionality will log an error and fail with "Unsupported Config" if you actually try to assign a USB network adapter to a guest using <interface type='hostdev'> - just use a standard <hostdev> entry in that case (and also for single-port PCI adapters).
2012-02-15 17:37:15 +00:00
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
case VIR_DOMAIN_NET_TYPE_LAST:
break;
}
if (def->ifname != NULL &&
!STRPREFIX(def->ifname, "vif"))
virBufferEscapeSexpr(buf, "(vifname '%s')", def->ifname);
if (!hvm) {
if (def->model != NULL)
virBufferEscapeSexpr(buf, "(model '%s')", def->model);
} else {
if (def->model != NULL && STREQ(def->model, "netfront")) {
virBufferAddLit(buf, "(type netfront)");
} else {
if (def->model != NULL)
virBufferEscapeSexpr(buf, "(model '%s')", def->model);
}
}
if (!isAttach)
virBufferAddLit(buf, ")");
virBufferAddLit(buf, ")");
return 0;
}
/**
* xenFormatSxprPCI:
* @def: the device config
* @buf: a buffer for the result S-expression
*
* Convert a single PCI device part of the domain config into a S-expresssion in buf.
*
* Returns 0 in case of success, -1 in case of error.
*/
static void
2011-02-21 13:40:12 +00:00
xenFormatSxprPCI(virDomainHostdevDefPtr def,
virBufferPtr buf)
{
virBufferAsprintf(buf, "(dev (domain 0x%04x)(bus 0x%02x)(slot 0x%02x)(func 0x%x))",
def->source.subsys.u.pci.addr.domain,
def->source.subsys.u.pci.addr.bus,
def->source.subsys.u.pci.addr.slot,
def->source.subsys.u.pci.addr.function);
}
/**
* xenFormatSxprOnePCI:
* @def: the device config
* @buf: a buffer for the result S-expression
* @detach: create expression for device detach (1).
*
* Convert a single PCI device part of the domain config into a S-expresssion in buf.
*
* Returns 0 in case of success, -1 in case of error.
*/
int
2011-02-21 13:40:12 +00:00
xenFormatSxprOnePCI(virDomainHostdevDefPtr def,
virBufferPtr buf,
int detach)
{
if (def->managed) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("managed PCI devices not supported with XenD"));
return -1;
}
virBufferAddLit(buf, "(pci ");
2011-02-21 13:40:12 +00:00
xenFormatSxprPCI(def, buf);
if (detach)
virBufferAddLit(buf, "(state 'Closing')");
else
virBufferAddLit(buf, "(state 'Initialising')");
virBufferAddLit(buf, ")");
return 0;
}
/**
* xenFormatSxprAllPCI:
* @def: the domain config
* @buf: a buffer for the result S-expression
*
* Convert all PCI device parts of the domain config into a S-expresssion in buf.
*
* Returns 0 in case of success, -1 in case of error.
*/
static int
2011-02-21 13:40:12 +00:00
xenFormatSxprAllPCI(virDomainDefPtr def,
virBufferPtr buf)
{
int hasPCI = 0;
size_t 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;
/*
* With the (domain ...) block we have the following odd setup
*
* (device
* (pci
* (dev (domain 0x0000) (bus 0x00) (slot 0x1b) (func 0x0))
* (dev (domain 0x0000) (bus 0x00) (slot 0x13) (func 0x0))
* )
* )
*
* Normally there is one (device ...) block per device, but in the
* weird world of Xen PCI, one (device ...) covers multiple devices.
*/
virBufferAddLit(buf, "(device (pci ");
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) {
if (def->hostdevs[i]->managed) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("managed PCI devices not supported with XenD"));
return -1;
}
2011-02-21 13:40:12 +00:00
xenFormatSxprPCI(def->hostdevs[i], buf);
}
}
virBufferAddLit(buf, "))");
return 0;
}
/**
* xenFormatSxprSound:
* @def: the domain config
* @buf: a buffer for the result S-expression
*
* Convert all sound device parts of the domain config into S-expression in buf.
*
* Returns 0 if successful or -1 if failed.
*/
int
2011-02-21 13:40:12 +00:00
xenFormatSxprSound(virDomainDefPtr def,
virBufferPtr buf)
{
const char *str;
size_t i;
for (i = 0; i < def->nsounds; i++) {
if (!(str = virDomainSoundModelTypeToString(def->sounds[i]->model))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected sound model %d"),
def->sounds[i]->model);
return -1;
}
if (i)
virBufferAddChar(buf, ',');
virBufferEscapeSexpr(buf, "%s", str);
}
if (virBufferCheckError(buf) < 0)
return -1;
return 0;
}
/**
* xenFormatSxprInput:
* @input: the input config
* @buf: a buffer for the result S-expression
*
* Convert all input device parts of the domain config into S-expression in buf.
*
* Returns 0 if successful or -1 if failed.
*/
static int
2011-02-21 13:40:12 +00:00
xenFormatSxprInput(virDomainInputDefPtr input,
virBufferPtr buf)
{
if (input->bus != VIR_DOMAIN_INPUT_BUS_USB)
return 0;
if (input->type != VIR_DOMAIN_INPUT_TYPE_MOUSE &&
input->type != VIR_DOMAIN_INPUT_TYPE_TABLET &&
input->type != VIR_DOMAIN_INPUT_TYPE_KBD) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected input type %d"), input->type);
return -1;
}
switch (input->type) {
case VIR_DOMAIN_INPUT_TYPE_MOUSE:
virBufferAsprintf(buf, "(usbdevice %s)", "mouse");
break;
case VIR_DOMAIN_INPUT_TYPE_TABLET:
virBufferAsprintf(buf, "(usbdevice %s)", "tablet");
break;
case VIR_DOMAIN_INPUT_TYPE_KBD:
virBufferAsprintf(buf, "(usbdevice %s)", "keyboard");
break;
}
return 0;
}
/* 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);
/**
2011-02-21 13:40:12 +00:00
* xenFormatSxpr:
* @conn: pointer to the hypervisor connection
* @def: domain config definition
*
* Generate an S-expression representing the domain configuration.
*
* Returns the 0 terminated S-Expr string or NULL in case of error.
* the caller must free() the returned value.
*/
char *
xenFormatSxpr(virConnectPtr conn, virDomainDefPtr def)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
char uuidstr[VIR_UUID_STRING_BUFLEN];
const char *tmp;
char *bufout;
int hvm = 0, vmlocaltime = -1;
size_t i;
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
bool in_image = false;
VIR_DEBUG("Formatting domain sexpr");
virBufferAddLit(&buf, "(vm ");
virBufferEscapeSexpr(&buf, "(name '%s')", def->name);
xml: use better types for memory values Using 'unsigned long' for memory values is risky on 32-bit platforms, as a PAE guest can have more than 4GiB memory. Our API is (unfortunately) locked at 'unsigned long' and a scale of 1024, but the rest of our system should consistently use 64-bit values, especially since the previous patch centralized overflow checking. * src/conf/domain_conf.h (_virDomainDef): Always use 64-bit values for memory. Change hugepage_backed to a bool. * src/conf/domain_conf.c (virDomainDefParseXML) (virDomainDefCheckABIStability, virDomainDefFormatInternal): Fix clients. * src/vmx/vmx.c (virVMXFormatConfig): Likewise. * src/xenxs/xen_sxpr.c (xenParseSxpr, xenFormatSxpr): Likewise. * src/xenxs/xen_xm.c (xenXMConfigGetULongLong): New function. (xenXMConfigGetULong, xenXMConfigSetInt): Avoid truncation. (xenParseXM, xenFormatXM): Fix clients. * src/phyp/phyp_driver.c (phypBuildLpar): Likewise. * src/openvz/openvz_driver.c (openvzDomainSetMemoryInternal): Likewise. * src/vbox/vbox_tmpl.c (vboxDomainDefineXML): Likewise. * src/qemu/qemu_command.c (qemuBuildCommandLine): Likewise. * src/qemu/qemu_process.c (qemuProcessStart): Likewise. * src/qemu/qemu_monitor.h (qemuMonitorGetBalloonInfo): Likewise. * src/qemu/qemu_monitor_text.h (qemuMonitorTextGetBalloonInfo): Likewise. * src/qemu/qemu_monitor_text.c (qemuMonitorTextGetBalloonInfo): Likewise. * src/qemu/qemu_monitor_json.h (qemuMonitorJSONGetBalloonInfo): Likewise. * src/qemu/qemu_monitor_json.c (qemuMonitorJSONGetBalloonInfo): Likewise. * src/qemu/qemu_driver.c (qemudDomainGetInfo) (qemuDomainGetXMLDesc): Likewise. * src/uml/uml_conf.c (umlBuildCommandLine): Likewise.
2012-03-02 20:27:39 +00:00
virBufferAsprintf(&buf, "(memory %llu)(maxmem %llu)",
VIR_DIV_UP(def->mem.cur_balloon, 1024),
VIR_DIV_UP(virDomainDefGetMemoryTotal(def), 1024));
virBufferAsprintf(&buf, "(vcpus %u)", virDomainDefGetVcpusMax(def));
/* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is
either 32, or 64 on a platform where long is big enough. */
if (virDomainDefHasVcpusOffline(def))
virBufferAsprintf(&buf, "(vcpu_avail %lu)",
(1UL << virDomainDefGetVcpus(def)) - 1);
if (def->cpumask) {
2012-09-14 07:47:01 +00:00
char *ranges = virBitmapFormat(def->cpumask);
if (ranges == NULL)
goto error;
virBufferEscapeSexpr(&buf, "(cpus '%s')", ranges);
VIR_FREE(ranges);
}
virUUIDFormat(def->uuid, uuidstr);
virBufferAsprintf(&buf, "(uuid '%s')", uuidstr);
if (def->description)
virBufferEscapeSexpr(&buf, "(description '%s')", def->description);
if (def->os.bootloader) {
if (def->os.bootloader[0])
virBufferEscapeSexpr(&buf, "(bootloader '%s')", def->os.bootloader);
else
virBufferAddLit(&buf, "(bootloader)");
if (def->os.bootloaderArgs)
virBufferEscapeSexpr(&buf, "(bootloader_args '%s')", def->os.bootloaderArgs);
}
if (!(tmp = virDomainLifecycleActionTypeToString(def->onPoweroff))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected lifecycle value %d"), def->onPoweroff);
goto error;
}
virBufferAsprintf(&buf, "(on_poweroff '%s')", tmp);
if (!(tmp = virDomainLifecycleActionTypeToString(def->onReboot))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected lifecycle value %d"), def->onReboot);
goto error;
}
virBufferAsprintf(&buf, "(on_reboot '%s')", tmp);
if (!(tmp = virDomainLifecycleActionTypeToString(def->onCrash))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected lifecycle value %d"), def->onCrash);
goto error;
}
virBufferAsprintf(&buf, "(on_crash '%s')", tmp);
if (def->os.type == VIR_DOMAIN_OSTYPE_HVM)
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
hvm = 1;
if (!def->os.bootloader) {
if (hvm)
virBufferAddLit(&buf, "(image (hvm ");
else
virBufferAddLit(&buf, "(image (linux ");
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
in_image = true;
if (hvm &&
def->os.loader == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("no HVM domain loader"));
goto error;
}
if (def->os.kernel)
virBufferEscapeSexpr(&buf, "(kernel '%s')", def->os.kernel);
if (def->os.initrd)
virBufferEscapeSexpr(&buf, "(ramdisk '%s')", def->os.initrd);
if (def->os.root)
virBufferEscapeSexpr(&buf, "(root '%s')", def->os.root);
if (def->os.cmdline)
virBufferEscapeSexpr(&buf, "(args '%s')", def->os.cmdline);
if (hvm) {
char bootorder[VIR_DOMAIN_BOOT_LAST+1];
if (def->os.kernel)
virBufferEscapeSexpr(&buf, "(loader '%s')", def->os.loader->path);
else
virBufferEscapeSexpr(&buf, "(kernel '%s')", def->os.loader->path);
virBufferAsprintf(&buf, "(vcpus %u)", virDomainDefGetVcpusMax(def));
if (virDomainDefHasVcpusOffline(def))
virBufferAsprintf(&buf, "(vcpu_avail %lu)",
(1UL << virDomainDefGetVcpus(def)) - 1);
for (i = 0; i < def->os.nBootDevs; i++) {
switch (def->os.bootDevs[i]) {
case VIR_DOMAIN_BOOT_FLOPPY:
bootorder[i] = 'a';
break;
default:
case VIR_DOMAIN_BOOT_DISK:
bootorder[i] = 'c';
break;
case VIR_DOMAIN_BOOT_CDROM:
bootorder[i] = 'd';
break;
case VIR_DOMAIN_BOOT_NET:
bootorder[i] = 'n';
break;
}
}
if (def->os.nBootDevs == 0) {
bootorder[0] = 'c';
bootorder[1] = '\0';
} else {
bootorder[def->os.nBootDevs] = '\0';
}
virBufferAsprintf(&buf, "(boot %s)", bootorder);
if (def->features[VIR_DOMAIN_FEATURE_ACPI] == VIR_TRISTATE_SWITCH_ON)
virBufferAddLit(&buf, "(acpi 1)");
if (def->features[VIR_DOMAIN_FEATURE_APIC] == VIR_TRISTATE_SWITCH_ON)
virBufferAddLit(&buf, "(apic 1)");
if (def->features[VIR_DOMAIN_FEATURE_PAE] == VIR_TRISTATE_SWITCH_ON)
virBufferAddLit(&buf, "(pae 1)");
if (def->features[VIR_DOMAIN_FEATURE_HAP] == VIR_TRISTATE_SWITCH_ON)
virBufferAddLit(&buf, "(hap 1)");
if (def->features[VIR_DOMAIN_FEATURE_VIRIDIAN] == VIR_TRISTATE_SWITCH_ON)
virBufferAddLit(&buf, "(viridian 1)");
virBufferAddLit(&buf, "(usb 1)");
for (i = 0; i < def->ninputs; i++)
2011-02-21 13:40:12 +00:00
if (xenFormatSxprInput(def->inputs[i], &buf) < 0)
goto error;
if (def->parallels) {
virBufferAddLit(&buf, "(parallel ");
2011-02-21 13:40:12 +00:00
if (xenFormatSxprChr(def->parallels[0], &buf) < 0)
goto error;
virBufferAddLit(&buf, ")");
} else {
virBufferAddLit(&buf, "(parallel none)");
}
if (def->serials) {
if ((def->nserials > 1) || (def->serials[0]->target.port != 0)) {
int maxport = -1, port;
size_t j = 0;
virBufferAddLit(&buf, "(serial (");
for (i = 0; i < def->nserials; i++)
if (def->serials[i]->target.port > maxport)
maxport = def->serials[i]->target.port;
for (port = 0; port <= maxport; port++) {
virDomainChrDefPtr chr = NULL;
if (port)
virBufferAddLit(&buf, " ");
for (j = 0; j < def->nserials; j++) {
if (def->serials[j]->target.port == port) {
chr = def->serials[j];
break;
}
}
if (chr) {
if (xenFormatSxprChr(chr, &buf) < 0)
goto error;
} else {
virBufferAddLit(&buf, "none");
}
}
virBufferAddLit(&buf, "))");
} else {
virBufferAddLit(&buf, "(serial ");
if (xenFormatSxprChr(def->serials[0], &buf) < 0)
goto error;
virBufferAddLit(&buf, ")");
}
} else {
virBufferAddLit(&buf, "(serial none)");
}
if (def->sounds) {
virBufferAddLit(&buf, "(soundhw '");
2011-02-21 13:40:12 +00:00
if (xenFormatSxprSound(def, &buf) < 0)
goto error;
virBufferAddLit(&buf, "')");
}
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
} /* hvm */
/* get the device emulation model */
if (def->emulator && hvm)
virBufferEscapeSexpr(&buf, "(device_model '%s')", def->emulator);
/* look for HPET in order to override the hypervisor/xend default */
for (i = 0; i < def->clock.ntimers; i++) {
if (def->clock.timers[i]->name == VIR_DOMAIN_TIMER_NAME_HPET &&
def->clock.timers[i]->present != -1) {
virBufferAsprintf(&buf, "(hpet %d)",
def->clock.timers[i]->present);
break;
}
}
/* PV graphics for xen <= 3.0.4, or HVM graphics */
if (hvm) {
if ((def->ngraphics == 1) &&
xenFormatSxprGraphicsOld(def->graphics[0], &buf) < 0)
goto error;
}
} else {
/* PV domains accept kernel cmdline args */
if (def->os.cmdline) {
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
virBufferEscapeSexpr(&buf, "(image (linux (args '%s')", def->os.cmdline);
in_image = true;
}
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
} /* os.bootloader */
if (!in_image) {
if (hvm)
virBufferAddLit(&buf, "(image (hvm ");
else
virBufferAddLit(&buf, "(image (linux ");
in_image = true;
}
if (hvm) {
/* >=3.1 HV: VARIABLE */
int rtc_timeoffset;
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
switch (def->clock.offset) {
case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE:
vmlocaltime = (int)def->clock.data.variable.basis;
rtc_timeoffset = def->clock.data.variable.adjustment;
break;
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
case VIR_DOMAIN_CLOCK_OFFSET_UTC:
if (def->clock.data.utc_reset) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("unsupported clock adjustment='reset'"));
goto error;
}
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
vmlocaltime = 0;
rtc_timeoffset = 0;
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
break;
case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME:
if (def->clock.data.utc_reset) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("unsupported clock adjustment='reset'"));
goto error;
}
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
vmlocaltime = 1;
rtc_timeoffset = 0;
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
break;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported clock offset='%s'"),
virDomainClockOffsetTypeToString(def->clock.offset));
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
goto error;
}
virBufferAsprintf(&buf, "(rtc_timeoffset %d)", rtc_timeoffset);
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
} else {
/* >=3.1 PV: UTC and LOCALTIME */
switch (def->clock.offset) {
case VIR_DOMAIN_CLOCK_OFFSET_UTC:
vmlocaltime = 0;
break;
case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME:
vmlocaltime = 1;
break;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported clock offset='%s'"),
virDomainClockOffsetTypeToString(def->clock.offset));
goto error;
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
}
} /* !hvm */
/* default post-XenD-3.1 location: */
virBufferAsprintf(&buf, "(localtime %d)", vmlocaltime);
Xen: Fix <clock> handling XenD-3.1 introduced managed domains. HV-domains have rtc_timeoffset (hgd24f37b31030 from 2007-04-03), which tracks the offset between the hypervisors clock and the domains RTC, and is persisted by XenD. In combination with localtime=1 this had a bug until XenD-3.4 (hg5d701be7c37b from 2009-04-01) (I'm not 100% sure how that bug manifests, but at least for me in TZ=Europe/Berlin I see the previous offset relative to utc being applied to localtime again, which manifests in an extra hour being added) XenD implements the following variants for clock/@offset: - PV domains don't have a RTC → 'localtime' | 'utc' - <3.1: no managed domains → 'localtime' | 'utc' - ≥3.1: the offset is tracked for HV → 'variable' due to the localtime=1 bug → 'localtime' | 'utc' - ≥3.4: the offset is tracked for HV → 'variable' Current libvirtd still thinks XenD only implements <clock offset='utc'/> and <clock offset='localtime'/>, which is wrong, since the semantic of 'utc' and 'localtime' specifies, that the offset will be reset on domain-restart, while with 'variable' the offset is kept. (keeping the offset over "virsh edit" is important, since otherwise the clock might jump, which confuses certain guest OSs) xendConfigVersion was last incremented to 4 by the xen-folks for xen-3.1.0. I know of no way to reliably detect the version of XenD (user space tools), which may be different from the version of the hypervisor (kernel) version! Because of this only the change from 'utc'/'localtime' to 'variable' in XenD-3.1 is handled, not the buggy behaviour of XenD-3.1 until XenD-3.4. For backward compatibility with previous versions of libvirt Xen-HV still accepts 'utc' and 'localtime', but they are returned as 'variable' on the next read-back from Xend to libvirt, since this is what XenD implements: The RTC is NOT reset back to the specified time on next restart, but the previous offset is kept. This behaviour can be turned off by adding the additional attribute adjustment='reset', in which case libvirt will report an error instead of doing the conversion. The attribute can also be used as a shortcut to offset='variable' with basis='...'. With these changes, it is also necessary to adjust the xen tests: "localtime = 0" is always inserted, because otherwise on updates the value is not changed within XenD. adjustment='reset' is inserted for all cases, since they're all < XEND_CONFIG_VERSION_3_1_0, only 3.1 introduced persistent rtc_timeoffset. Some statements change their order because code was moved around. Signed-off-by: Philipp Hahn <hahn@univention.de>
2012-02-08 16:32:34 +00:00
if (in_image) {
/* closes (image(hvm|linux */
virBufferAddLit(&buf, "))");
in_image = false;
}
/* pre-XenD-3.1 and compatibility location */
virBufferAsprintf(&buf, "(localtime %d)", vmlocaltime);
for (i = 0; i < def->ndisks; i++)
if (xenFormatSxprDisk(def->disks[i], &buf, hvm, 0) < 0)
goto error;
for (i = 0; i < def->nnets; i++)
if (xenFormatSxprNet(conn, def->nets[i], &buf, hvm, 0) < 0)
goto error;
2011-02-21 13:40:12 +00:00
if (xenFormatSxprAllPCI(def, &buf) < 0)
goto error;
/* New style PV graphics config xen >= 3.0.4 */
if (!hvm) {
if ((def->ngraphics == 1) &&
2011-02-21 13:40:12 +00:00
xenFormatSxprGraphicsNew(def->graphics[0], &buf) < 0)
goto error;
}
virBufferAddLit(&buf, ")"); /* closes (vm */
if (virBufferCheckError(&buf) < 0)
goto error;
bufout = virBufferContentAndReset(&buf);
VIR_DEBUG("Formatted sexpr: \n%s", bufout);
return bufout;
error:
virBufferFreeAndReset(&buf);
return NULL;
}