2011-02-21 13:40:10 +00:00
|
|
|
/*
|
|
|
|
* xen_xm.c: Xen XM parsing functions
|
|
|
|
*
|
2014-03-24 18:14:48 +00:00
|
|
|
* Copyright (C) 2006-2007, 2009-2014 Red Hat, Inc.
|
2011-02-21 13:40:10 +00:00
|
|
|
* Copyright (C) 2011 Univention GmbH
|
|
|
|
* Copyright (C) 2006 Daniel P. Berrange
|
|
|
|
*
|
|
|
|
* 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
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-21 10:06:23 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
2011-02-21 13:40:10 +00:00
|
|
|
*
|
|
|
|
* Author: Daniel P. Berrange <berrange@redhat.com>
|
|
|
|
* Author: Markus Groß <gross@univention.de>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include "internal.h"
|
2012-12-13 18:21:53 +00:00
|
|
|
#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:10 +00:00
|
|
|
#include "verify.h"
|
2012-12-13 18:01:25 +00:00
|
|
|
#include "viruuid.h"
|
2012-12-13 15:07:43 +00:00
|
|
|
#include "virsexpr.h"
|
2011-02-21 13:40:10 +00:00
|
|
|
#include "count-one-bits.h"
|
|
|
|
#include "xenxs_private.h"
|
|
|
|
#include "xen_xm.h"
|
|
|
|
#include "xen_sxpr.h"
|
2011-04-14 16:05:14 +00:00
|
|
|
#include "domain_conf.h"
|
2012-12-13 15:25:48 +00:00
|
|
|
#include "virstoragefile.h"
|
2013-04-03 10:36:23 +00:00
|
|
|
#include "virstring.h"
|
2011-02-21 13:40:10 +00:00
|
|
|
|
2012-03-02 20:27:39 +00:00
|
|
|
/* Convenience method to grab a long int from the config file object */
|
2011-02-21 13:40:10 +00:00
|
|
|
static int xenXMConfigGetBool(virConfPtr conf,
|
|
|
|
const char *name,
|
|
|
|
int *value,
|
2014-03-18 08:14:16 +00:00
|
|
|
int def)
|
|
|
|
{
|
2011-02-21 13:40:10 +00:00
|
|
|
virConfValuePtr val;
|
|
|
|
|
|
|
|
*value = 0;
|
|
|
|
if (!(val = virConfGetValue(conf, name))) {
|
|
|
|
*value = def;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (val->type == VIR_CONF_LONG) {
|
|
|
|
*value = val->l ? 1 : 0;
|
|
|
|
} else if (val->type == VIR_CONF_STRING) {
|
|
|
|
*value = STREQ(val->str, "1") ? 1 : 0;
|
|
|
|
} else {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("config value %s was malformed"), name);
|
2011-02-21 13:40:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Convenience method to grab a int from the config file object */
|
|
|
|
static int xenXMConfigGetULong(virConfPtr conf,
|
|
|
|
const char *name,
|
|
|
|
unsigned long *value,
|
2014-03-18 08:14:16 +00:00
|
|
|
unsigned long def)
|
|
|
|
{
|
2011-02-21 13:40:10 +00:00
|
|
|
virConfValuePtr val;
|
|
|
|
|
|
|
|
*value = 0;
|
|
|
|
if (!(val = virConfGetValue(conf, name))) {
|
|
|
|
*value = def;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (val->type == VIR_CONF_LONG) {
|
|
|
|
*value = val->l;
|
|
|
|
} else if (val->type == VIR_CONF_STRING) {
|
2014-07-18 07:46:39 +00:00
|
|
|
if (virStrToLong_ul(val->str, NULL, 10, value) < 0) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("config value %s was malformed"), name);
|
2011-02-21 13:40:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("config value %s was malformed"), name);
|
2011-02-21 13:40:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-03-02 20:27:39 +00:00
|
|
|
/* Convenience method to grab a int from the config file object */
|
|
|
|
static int xenXMConfigGetULongLong(virConfPtr conf,
|
|
|
|
const char *name,
|
|
|
|
unsigned long long *value,
|
2014-03-18 08:14:16 +00:00
|
|
|
unsigned long long def)
|
|
|
|
{
|
2012-03-02 20:27:39 +00:00
|
|
|
virConfValuePtr val;
|
|
|
|
|
|
|
|
*value = 0;
|
|
|
|
if (!(val = virConfGetValue(conf, name))) {
|
|
|
|
*value = def;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (val->type == VIR_CONF_LONG) {
|
|
|
|
*value = val->l;
|
|
|
|
} else if (val->type == VIR_CONF_STRING) {
|
2014-07-18 07:46:39 +00:00
|
|
|
if (virStrToLong_ull(val->str, NULL, 10, value) < 0) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("config value %s was malformed"), name);
|
2012-03-02 20:27:39 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} else {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("config value %s was malformed"), name);
|
2012-03-02 20:27:39 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-02-21 13:40:10 +00:00
|
|
|
/* Convenience method to grab a string from the config file object */
|
|
|
|
static int xenXMConfigGetString(virConfPtr conf,
|
|
|
|
const char *name,
|
|
|
|
const char **value,
|
2014-03-18 08:14:16 +00:00
|
|
|
const char *def)
|
|
|
|
{
|
2011-02-21 13:40:10 +00:00
|
|
|
virConfValuePtr val;
|
|
|
|
|
|
|
|
*value = NULL;
|
|
|
|
if (!(val = virConfGetValue(conf, name))) {
|
|
|
|
*value = def;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (val->type != VIR_CONF_STRING) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("config value %s was malformed"), name);
|
2011-02-21 13:40:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (!val->str)
|
|
|
|
*value = def;
|
|
|
|
else
|
|
|
|
*value = val->str;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int xenXMConfigCopyStringInternal(virConfPtr conf,
|
|
|
|
const char *name,
|
|
|
|
char **value,
|
2014-03-18 08:14:16 +00:00
|
|
|
int allowMissing)
|
|
|
|
{
|
2011-02-21 13:40:10 +00:00
|
|
|
virConfValuePtr val;
|
|
|
|
|
|
|
|
*value = NULL;
|
|
|
|
if (!(val = virConfGetValue(conf, name))) {
|
|
|
|
if (allowMissing)
|
|
|
|
return 0;
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("config value %s was missing"), name);
|
2011-02-21 13:40:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (val->type != VIR_CONF_STRING) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("config value %s was not a string"), name);
|
2011-02-21 13:40:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (!val->str) {
|
|
|
|
if (allowMissing)
|
|
|
|
return 0;
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("config value %s was missing"), name);
|
2011-02-21 13:40:10 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-05-03 12:51:56 +00:00
|
|
|
return VIR_STRDUP(*value, val->str);
|
2011-02-21 13:40:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int xenXMConfigCopyString(virConfPtr conf,
|
|
|
|
const char *name,
|
|
|
|
char **value) {
|
|
|
|
return xenXMConfigCopyStringInternal(conf, name, value, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int xenXMConfigCopyStringOpt(virConfPtr conf,
|
|
|
|
const char *name,
|
|
|
|
char **value) {
|
|
|
|
return xenXMConfigCopyStringInternal(conf, name, value, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Convenience method to grab a string UUID from the config file object */
|
2014-03-18 08:14:16 +00:00
|
|
|
static int
|
|
|
|
xenXMConfigGetUUID(virConfPtr conf, const char *name, unsigned char *uuid)
|
|
|
|
{
|
2011-02-21 13:40:10 +00:00
|
|
|
virConfValuePtr val;
|
2011-10-06 10:42:39 +00:00
|
|
|
|
|
|
|
if (!uuid || !name || !conf) {
|
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_INVALID_ARG, "%s",
|
2012-07-18 13:17:20 +00:00
|
|
|
_("Arguments must be non null"));
|
2011-10-06 10:42:39 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-02-21 13:40:10 +00:00
|
|
|
if (!(val = virConfGetValue(conf, name))) {
|
2012-08-03 21:10:13 +00:00
|
|
|
if (virUUIDGenerate(uuid)) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("Failed to generate UUID"));
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
2011-02-21 13:40:10 +00:00
|
|
|
}
|
|
|
|
|
2011-10-06 10:42:39 +00:00
|
|
|
if (val->type != VIR_CONF_STRING) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_CONF_SYNTAX,
|
|
|
|
_("config value %s not a string"), name);
|
2011-10-06 10:42:39 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!val->str) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_CONF_SYNTAX,
|
|
|
|
_("%s can't be empty"), name);
|
2011-10-06 10:42:39 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2011-02-21 13:40:10 +00:00
|
|
|
|
2011-10-06 10:42:39 +00:00
|
|
|
if (virUUIDParse(val->str, uuid) < 0) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_CONF_SYNTAX,
|
|
|
|
_("%s not parseable"), val->str);
|
2011-10-06 10:42:39 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2011-02-21 13:40:10 +00:00
|
|
|
|
2011-10-06 10:42:39 +00:00
|
|
|
return 0;
|
2011-02-21 13:40:10 +00:00
|
|
|
}
|
|
|
|
|
2014-08-07 18:32:50 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
xenParseXMMem(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
if (xenXMConfigGetULongLong(conf, "memory", &def->mem.cur_balloon,
|
|
|
|
MIN_XEN_GUEST_SIZE * 2) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (xenXMConfigGetULongLong(conf, "maxmem", &def->mem.max_balloon,
|
|
|
|
def->mem.cur_balloon) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
def->mem.cur_balloon *= 1024;
|
|
|
|
def->mem.max_balloon *= 1024;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-07 18:32:51 +00:00
|
|
|
static int
|
|
|
|
xenParseXMTimeOffset(virConfPtr conf, virDomainDefPtr def,
|
|
|
|
int xendConfigVersion)
|
|
|
|
{
|
|
|
|
int vmlocaltime;
|
|
|
|
|
|
|
|
if (xenXMConfigGetBool(conf, "localtime", &vmlocaltime, 0) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (STREQ(def->os.type, "hvm")) {
|
|
|
|
/* only managed HVM domains since 3.1.0 have persistent rtc_timeoffset */
|
|
|
|
if (xendConfigVersion < XEND_CONFIG_VERSION_3_1_0) {
|
|
|
|
if (vmlocaltime)
|
|
|
|
def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME;
|
|
|
|
else
|
|
|
|
def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_UTC;
|
|
|
|
def->clock.data.utc_reset = true;
|
|
|
|
} else {
|
|
|
|
unsigned long rtc_timeoffset;
|
|
|
|
def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_VARIABLE;
|
|
|
|
if (xenXMConfigGetULong(conf, "rtc_timeoffset", &rtc_timeoffset, 0) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
def->clock.data.variable.adjustment = (int)rtc_timeoffset;
|
|
|
|
def->clock.data.variable.basis = vmlocaltime ?
|
|
|
|
VIR_DOMAIN_CLOCK_BASIS_LOCALTIME :
|
|
|
|
VIR_DOMAIN_CLOCK_BASIS_UTC;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* PV domains do not have an emulated RTC and the offset is fixed. */
|
|
|
|
def->clock.offset = vmlocaltime ?
|
|
|
|
VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME :
|
|
|
|
VIR_DOMAIN_CLOCK_OFFSET_UTC;
|
|
|
|
def->clock.data.utc_reset = true;
|
|
|
|
} /* !hvm */
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-07 18:32:52 +00:00
|
|
|
static int
|
|
|
|
xenParseXMEventsActions(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
const char *str = NULL;
|
|
|
|
|
|
|
|
if (xenXMConfigGetString(conf, "on_poweroff", &str, "destroy") < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if ((def->onPoweroff = virDomainLifecycleTypeFromString(str)) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unexpected value %s for on_poweroff"), str);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xenXMConfigGetString(conf, "on_reboot", &str, "restart") < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if ((def->onReboot = virDomainLifecycleTypeFromString(str)) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unexpected value %s for on_reboot"), str);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xenXMConfigGetString(conf, "on_crash", &str, "restart") < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if ((def->onCrash = virDomainLifecycleCrashTypeFromString(str)) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unexpected value %s for on_crash"), str);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-07 18:32:53 +00:00
|
|
|
static int
|
|
|
|
xenParseXMPCI(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
virConfValuePtr list = virConfGetValue(conf, "pci");
|
|
|
|
virDomainHostdevDefPtr hostdev = NULL;
|
|
|
|
|
|
|
|
if (list && list->type == VIR_CONF_LIST) {
|
|
|
|
list = list->list;
|
|
|
|
while (list) {
|
|
|
|
char domain[5];
|
|
|
|
char bus[3];
|
|
|
|
char slot[3];
|
|
|
|
char func[2];
|
|
|
|
char *key, *nextkey;
|
|
|
|
int domainID;
|
|
|
|
int busID;
|
|
|
|
int slotID;
|
|
|
|
int funcID;
|
|
|
|
|
|
|
|
domain[0] = bus[0] = slot[0] = func[0] = '\0';
|
|
|
|
|
|
|
|
if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
|
|
|
|
goto skippci;
|
|
|
|
/* pci=['0000:00:1b.0','0000:00:13.0'] */
|
|
|
|
if (!(key = list->str))
|
|
|
|
goto skippci;
|
|
|
|
if (!(nextkey = strchr(key, ':')))
|
|
|
|
goto skippci;
|
|
|
|
if (virStrncpy(domain, key, (nextkey - key), sizeof(domain)) == NULL) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Domain %s too big for destination"), key);
|
|
|
|
goto skippci;
|
|
|
|
}
|
|
|
|
|
|
|
|
key = nextkey + 1;
|
|
|
|
if (!(nextkey = strchr(key, ':')))
|
|
|
|
goto skippci;
|
|
|
|
if (virStrncpy(bus, key, (nextkey - key), sizeof(bus)) == NULL) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Bus %s too big for destination"), key);
|
|
|
|
goto skippci;
|
|
|
|
}
|
|
|
|
|
|
|
|
key = nextkey + 1;
|
|
|
|
if (!(nextkey = strchr(key, '.')))
|
|
|
|
goto skippci;
|
|
|
|
if (virStrncpy(slot, key, (nextkey - key), sizeof(slot)) == NULL) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Slot %s too big for destination"), key);
|
|
|
|
goto skippci;
|
|
|
|
}
|
|
|
|
|
|
|
|
key = nextkey + 1;
|
|
|
|
if (strlen(key) != 1)
|
|
|
|
goto skippci;
|
|
|
|
if (virStrncpy(func, key, 1, sizeof(func)) == NULL) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Function %s too big for destination"), key);
|
|
|
|
goto skippci;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virStrToLong_i(domain, NULL, 16, &domainID) < 0)
|
|
|
|
goto skippci;
|
|
|
|
if (virStrToLong_i(bus, NULL, 16, &busID) < 0)
|
|
|
|
goto skippci;
|
|
|
|
if (virStrToLong_i(slot, NULL, 16, &slotID) < 0)
|
|
|
|
goto skippci;
|
|
|
|
if (virStrToLong_i(func, NULL, 16, &funcID) < 0)
|
|
|
|
goto skippci;
|
|
|
|
if (!(hostdev = virDomainHostdevDefAlloc()))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
hostdev->managed = false;
|
|
|
|
hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
|
|
|
|
hostdev->source.subsys.u.pci.addr.domain = domainID;
|
|
|
|
hostdev->source.subsys.u.pci.addr.bus = busID;
|
|
|
|
hostdev->source.subsys.u.pci.addr.slot = slotID;
|
|
|
|
hostdev->source.subsys.u.pci.addr.function = funcID;
|
|
|
|
|
|
|
|
if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0) {
|
|
|
|
virDomainHostdevDefFree(hostdev);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
skippci:
|
|
|
|
list = list->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-07 18:32:54 +00:00
|
|
|
static int
|
|
|
|
xenParseXMCPUFeatures(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
unsigned long count = 0;
|
|
|
|
const char *str = NULL;
|
|
|
|
int val = 0;
|
|
|
|
|
|
|
|
if (xenXMConfigGetULong(conf, "vcpus", &count, 1) < 0 ||
|
|
|
|
MAX_VIRT_CPUS < count)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
def->maxvcpus = count;
|
|
|
|
if (xenXMConfigGetULong(conf, "vcpu_avail", &count, -1) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
def->vcpus = MIN(count_one_bits_l(count), def->maxvcpus);
|
|
|
|
if (xenXMConfigGetString(conf, "cpus", &str, NULL) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (str && (virBitmapParse(str, 0, &def->cpumask, 4096) < 0))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (STREQ(def->os.type, "hvm")) {
|
|
|
|
if (xenXMConfigGetBool(conf, "pae", &val, 0) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
else if (val)
|
|
|
|
def->features[VIR_DOMAIN_FEATURE_PAE] = VIR_TRISTATE_SWITCH_ON;
|
|
|
|
if (xenXMConfigGetBool(conf, "acpi", &val, 0) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
else if (val)
|
|
|
|
def->features[VIR_DOMAIN_FEATURE_ACPI] = VIR_TRISTATE_SWITCH_ON;
|
|
|
|
if (xenXMConfigGetBool(conf, "apic", &val, 0) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
else if (val)
|
|
|
|
def->features[VIR_DOMAIN_FEATURE_APIC] = VIR_TRISTATE_SWITCH_ON;
|
|
|
|
if (xenXMConfigGetBool(conf, "hap", &val, 0) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
else if (val)
|
|
|
|
def->features[VIR_DOMAIN_FEATURE_HAP] = VIR_TRISTATE_SWITCH_ON;
|
|
|
|
if (xenXMConfigGetBool(conf, "viridian", &val, 0) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
else if (val)
|
|
|
|
def->features[VIR_DOMAIN_FEATURE_VIRIDIAN] = VIR_TRISTATE_SWITCH_ON;
|
|
|
|
|
|
|
|
if (xenXMConfigGetBool(conf, "hpet", &val, -1) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
else if (val != -1) {
|
|
|
|
virDomainTimerDefPtr timer;
|
|
|
|
|
|
|
|
if (VIR_ALLOC_N(def->clock.timers, 1) < 0 ||
|
|
|
|
VIR_ALLOC(timer) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
timer->name = VIR_DOMAIN_TIMER_NAME_HPET;
|
|
|
|
timer->present = val;
|
|
|
|
timer->tickpolicy = -1;
|
|
|
|
|
|
|
|
def->clock.ntimers = 1;
|
|
|
|
def->clock.timers[0] = timer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-07 18:32:55 +00:00
|
|
|
static int
|
|
|
|
xenParseXMDisk(virConfPtr conf, virDomainDefPtr def, int xendConfigVersion)
|
2014-03-18 08:14:16 +00:00
|
|
|
{
|
2014-08-07 18:32:55 +00:00
|
|
|
const char *str = NULL;
|
2011-02-21 13:40:10 +00:00
|
|
|
virDomainDiskDefPtr disk = NULL;
|
2014-08-07 18:32:55 +00:00
|
|
|
int hvm = STREQ(def->os.type, "hvm");
|
|
|
|
virConfValuePtr list = virConfGetValue(conf, "disk");
|
2011-02-21 13:40:10 +00:00
|
|
|
|
|
|
|
if (list && list->type == VIR_CONF_LIST) {
|
|
|
|
list = list->list;
|
|
|
|
while (list) {
|
|
|
|
char *head;
|
|
|
|
char *offset;
|
|
|
|
char *tmp;
|
2014-03-24 18:14:48 +00:00
|
|
|
const char *src;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
|
|
|
if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
|
|
|
|
goto skipdisk;
|
|
|
|
|
2014-08-07 18:32:55 +00:00
|
|
|
head = list->str;
|
2014-05-21 22:50:41 +00:00
|
|
|
if (!(disk = virDomainDiskDefNew()))
|
2014-08-07 18:32:55 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Disks have 3 components, SOURCE,DEST-DEVICE,MODE
|
|
|
|
* eg, phy:/dev/HostVG/XenGuest1,xvda,w
|
|
|
|
* The SOURCE is usually prefixed with a driver type,
|
|
|
|
* and optionally driver sub-type
|
|
|
|
* The DEST-DEVICE is optionally post-fixed with disk type
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Extract the source file path*/
|
|
|
|
if (!(offset = strchr(head, ',')))
|
|
|
|
goto skipdisk;
|
|
|
|
|
|
|
|
if (offset == head) {
|
2014-03-24 18:14:48 +00:00
|
|
|
/* No source file given, eg CDROM with no media */
|
|
|
|
ignore_value(virDomainDiskSetSource(disk, NULL));
|
2011-02-21 13:40:10 +00:00
|
|
|
} else {
|
2014-03-24 18:14:48 +00:00
|
|
|
if (VIR_STRNDUP(tmp, head, offset - head) < 0)
|
2013-07-04 10:19:27 +00:00
|
|
|
goto cleanup;
|
2014-08-07 18:32:55 +00:00
|
|
|
|
2014-03-24 18:14:48 +00:00
|
|
|
if (virDomainDiskSetSource(disk, tmp) < 0) {
|
|
|
|
VIR_FREE(tmp);
|
2011-02-21 13:40:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2014-03-24 18:14:48 +00:00
|
|
|
VIR_FREE(tmp);
|
2011-02-21 13:40:10 +00:00
|
|
|
}
|
|
|
|
|
2014-08-07 18:32:55 +00:00
|
|
|
head = offset + 1;
|
2011-02-21 13:40:10 +00:00
|
|
|
/* Remove legacy ioemu: junk */
|
|
|
|
if (STRPREFIX(head, "ioemu:"))
|
|
|
|
head = head + 6;
|
|
|
|
|
|
|
|
/* Extract the dest device name */
|
|
|
|
if (!(offset = strchr(head, ',')))
|
|
|
|
goto skipdisk;
|
2014-08-07 18:32:55 +00:00
|
|
|
|
2011-02-21 13:40:10 +00:00
|
|
|
if (VIR_ALLOC_N(disk->dst, (offset - head) + 1) < 0)
|
2013-07-04 10:19:27 +00:00
|
|
|
goto cleanup;
|
2014-08-07 18:32:55 +00:00
|
|
|
|
2011-02-21 13:40:10 +00:00
|
|
|
if (virStrncpy(disk->dst, head, offset - head,
|
|
|
|
(offset - head) + 1) == NULL) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Dest file %s too big for destination"), head);
|
2011-02-21 13:40:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2014-08-07 18:32:55 +00:00
|
|
|
head = offset + 1;
|
2011-02-21 13:40:10 +00:00
|
|
|
/* Extract source driver type */
|
2014-03-24 18:14:48 +00:00
|
|
|
src = virDomainDiskGetSource(disk);
|
|
|
|
if (src) {
|
|
|
|
size_t len;
|
2011-02-21 13:40:10 +00:00
|
|
|
/* The main type phy:, file:, tap: ... */
|
2014-03-24 18:14:48 +00:00
|
|
|
if ((tmp = strchr(src, ':')) != NULL) {
|
|
|
|
len = tmp - src;
|
|
|
|
if (VIR_STRNDUP(tmp, src, len) < 0)
|
2013-07-04 10:19:27 +00:00
|
|
|
goto cleanup;
|
2014-08-07 18:32:55 +00:00
|
|
|
|
2014-03-24 18:14:48 +00:00
|
|
|
if (virDomainDiskSetDriver(disk, tmp) < 0) {
|
|
|
|
VIR_FREE(tmp);
|
2011-02-21 13:40:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2014-03-24 18:14:48 +00:00
|
|
|
VIR_FREE(tmp);
|
2011-02-21 13:40:10 +00:00
|
|
|
|
|
|
|
/* Strip the prefix we found off the source file name */
|
2014-03-24 18:14:48 +00:00
|
|
|
if (virDomainDiskSetSource(disk, src + len + 1) < 0)
|
|
|
|
goto cleanup;
|
2014-08-07 18:32:55 +00:00
|
|
|
|
2014-03-24 18:14:48 +00:00
|
|
|
src = virDomainDiskGetSource(disk);
|
2011-02-21 13:40:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* And the sub-type for tap:XXX: type */
|
2014-03-24 18:14:48 +00:00
|
|
|
if (STREQ_NULLABLE(virDomainDiskGetDriver(disk), "tap")) {
|
2012-10-15 21:47:42 +00:00
|
|
|
char *driverType;
|
|
|
|
|
2014-03-24 18:14:48 +00:00
|
|
|
if (!(tmp = strchr(src, ':')))
|
2011-02-21 13:40:10 +00:00
|
|
|
goto skipdisk;
|
2014-03-24 18:14:48 +00:00
|
|
|
len = tmp - src;
|
2012-10-15 21:47:42 +00:00
|
|
|
|
2014-03-24 18:14:48 +00:00
|
|
|
if (VIR_STRNDUP(driverType, src, len) < 0)
|
2013-05-03 12:51:56 +00:00
|
|
|
goto cleanup;
|
2014-08-07 18:32:55 +00:00
|
|
|
|
2012-10-15 21:47:42 +00:00
|
|
|
if (STREQ(driverType, "aio"))
|
2014-03-24 18:14:48 +00:00
|
|
|
virDomainDiskSetFormat(disk, VIR_STORAGE_FILE_RAW);
|
2012-10-15 21:47:42 +00:00
|
|
|
else
|
2014-03-24 18:14:48 +00:00
|
|
|
virDomainDiskSetFormat(disk,
|
|
|
|
virStorageFileFormatTypeFromString(driverType));
|
2012-10-15 21:47:42 +00:00
|
|
|
VIR_FREE(driverType);
|
2014-03-24 18:14:48 +00:00
|
|
|
if (virDomainDiskGetFormat(disk) <= 0) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
2012-10-15 21:47:42 +00:00
|
|
|
_("Unknown driver type %s"),
|
2014-03-24 18:14:48 +00:00
|
|
|
src);
|
2011-02-21 13:40:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Strip the prefix we found off the source file name */
|
2014-03-24 18:14:48 +00:00
|
|
|
if (virDomainDiskSetSource(disk, src + len + 1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
src = virDomainDiskGetSource(disk);
|
2011-02-21 13:40:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No source, or driver name, so fix to phy: */
|
2014-03-24 18:14:48 +00:00
|
|
|
if (!virDomainDiskGetDriver(disk) &&
|
|
|
|
virDomainDiskSetDriver(disk, "phy") < 0)
|
2013-05-03 12:51:56 +00:00
|
|
|
goto cleanup;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
|
|
|
/* phy: type indicates a block device */
|
2014-03-24 18:14:48 +00:00
|
|
|
virDomainDiskSetType(disk,
|
|
|
|
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
|
|
|
VIR_STORAGE_TYPE_BLOCK :
|
|
|
|
VIR_STORAGE_TYPE_FILE);
|
2011-02-21 13:40:10 +00:00
|
|
|
|
|
|
|
/* Check for a :cdrom/:disk postfix */
|
|
|
|
disk->device = VIR_DOMAIN_DISK_DEVICE_DISK;
|
|
|
|
if ((tmp = strchr(disk->dst, ':')) != NULL) {
|
|
|
|
if (STREQ(tmp, ":cdrom"))
|
|
|
|
disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
|
|
|
|
tmp[0] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (STRPREFIX(disk->dst, "xvd") || !hvm) {
|
|
|
|
disk->bus = VIR_DOMAIN_DISK_BUS_XEN;
|
|
|
|
} else if (STRPREFIX(disk->dst, "sd")) {
|
|
|
|
disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
|
|
|
|
} else {
|
|
|
|
disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (STREQ(head, "r") ||
|
|
|
|
STREQ(head, "ro"))
|
2014-06-24 13:15:55 +00:00
|
|
|
disk->src->readonly = true;
|
2011-02-21 13:40:10 +00:00
|
|
|
else if ((STREQ(head, "w!")) ||
|
|
|
|
(STREQ(head, "!")))
|
2014-06-24 13:15:55 +00:00
|
|
|
disk->src->shared = true;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
|
|
|
/* Maintain list in sorted order according to target device name */
|
2014-03-07 08:33:31 +00:00
|
|
|
if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
|
2013-07-04 10:19:27 +00:00
|
|
|
goto cleanup;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
|
|
|
skipdisk:
|
|
|
|
list = list->next;
|
|
|
|
virDomainDiskDefFree(disk);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-31 17:08:09 +00:00
|
|
|
if (hvm && xendConfigVersion == XEND_CONFIG_VERSION_3_0_2) {
|
2011-02-21 13:40:10 +00:00
|
|
|
if (xenXMConfigGetString(conf, "cdrom", &str, NULL) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (str) {
|
2014-05-21 22:50:41 +00:00
|
|
|
if (!(disk = virDomainDiskDefNew()))
|
2013-07-04 10:19:27 +00:00
|
|
|
goto cleanup;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
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:10 +00:00
|
|
|
disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
|
2014-03-24 18:14:48 +00:00
|
|
|
if (virDomainDiskSetDriver(disk, "file") < 0)
|
2013-05-03 12:51:56 +00:00
|
|
|
goto cleanup;
|
2014-03-24 18:14:48 +00:00
|
|
|
if (virDomainDiskSetSource(disk, str) < 0)
|
2013-05-03 12:51:56 +00:00
|
|
|
goto cleanup;
|
|
|
|
if (VIR_STRDUP(disk->dst, "hdc") < 0)
|
|
|
|
goto cleanup;
|
2011-02-21 13:40:10 +00:00
|
|
|
disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
|
2014-06-24 13:15:55 +00:00
|
|
|
disk->src->readonly = true;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
2014-03-07 08:33:31 +00:00
|
|
|
if (VIR_APPEND_ELEMENT(def->disks, def->ndisks, disk) < 0)
|
2013-07-04 10:19:27 +00:00
|
|
|
goto cleanup;
|
2011-02-21 13:40:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-07 18:32:55 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainDiskDefFree(disk);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define MAX_VFB 1024
|
|
|
|
|
2014-08-07 18:32:56 +00:00
|
|
|
static int
|
|
|
|
xenParseXMVfb(virConfPtr conf, virDomainDefPtr def, int xendConfigVersion)
|
|
|
|
{
|
|
|
|
int val;
|
|
|
|
char *listenAddr = NULL;
|
|
|
|
int hvm = STREQ(def->os.type, "hvm");
|
|
|
|
virConfValuePtr list;
|
|
|
|
virDomainGraphicsDefPtr graphics = NULL;
|
|
|
|
|
|
|
|
if (hvm || xendConfigVersion < XEND_CONFIG_VERSION_3_0_4) {
|
|
|
|
if (xenXMConfigGetBool(conf, "vnc", &val, 0) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (val) {
|
|
|
|
if (VIR_ALLOC(graphics) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
|
|
|
|
if (xenXMConfigGetBool(conf, "vncunused", &val, 1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
graphics->data.vnc.autoport = val ? 1 : 0;
|
|
|
|
if (!graphics->data.vnc.autoport) {
|
|
|
|
unsigned long vncdisplay;
|
|
|
|
if (xenXMConfigGetULong(conf, "vncdisplay", &vncdisplay, 0) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
graphics->data.vnc.port = (int)vncdisplay + 5900;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xenXMConfigCopyStringOpt(conf, "vnclisten", &listenAddr) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (listenAddr &&
|
|
|
|
virDomainGraphicsListenSetAddress(graphics, 0, listenAddr,
|
|
|
|
-1, true) < 0) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FREE(listenAddr);
|
|
|
|
if (xenXMConfigCopyStringOpt(conf, "vncpasswd", &graphics->data.vnc.auth.passwd) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (xenXMConfigCopyStringOpt(conf, "keymap", &graphics->data.vnc.keymap) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (VIR_ALLOC_N(def->graphics, 1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
def->graphics[0] = graphics;
|
|
|
|
def->ngraphics = 1;
|
|
|
|
graphics = NULL;
|
|
|
|
} else {
|
|
|
|
if (xenXMConfigGetBool(conf, "sdl", &val, 0) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (val) {
|
|
|
|
if (VIR_ALLOC(graphics) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_SDL;
|
|
|
|
if (xenXMConfigCopyStringOpt(conf, "display", &graphics->data.sdl.display) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (xenXMConfigCopyStringOpt(conf, "xauthority", &graphics->data.sdl.xauth) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (VIR_ALLOC_N(def->graphics, 1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
def->graphics[0] = graphics;
|
|
|
|
def->ngraphics = 1;
|
|
|
|
graphics = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!hvm && def->graphics == NULL) { /* New PV guests use this format */
|
|
|
|
list = virConfGetValue(conf, "vfb");
|
|
|
|
if (list && list->type == VIR_CONF_LIST &&
|
|
|
|
list->list && list->list->type == VIR_CONF_STRING &&
|
|
|
|
list->list->str) {
|
|
|
|
char vfb[MAX_VFB];
|
|
|
|
char *key = vfb;
|
|
|
|
|
|
|
|
if (virStrcpyStatic(vfb, list->list->str) == NULL) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("VFB %s too big for destination"),
|
|
|
|
list->list->str);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VIR_ALLOC(graphics) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (strstr(key, "type=sdl"))
|
|
|
|
graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_SDL;
|
|
|
|
else
|
|
|
|
graphics->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
|
|
|
|
while (key) {
|
|
|
|
char *nextkey = strchr(key, ',');
|
|
|
|
char *end = nextkey;
|
|
|
|
if (nextkey) {
|
|
|
|
*end = '\0';
|
|
|
|
nextkey++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strchr(key, '='))
|
|
|
|
break;
|
|
|
|
if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC) {
|
|
|
|
if (STRPREFIX(key, "vncunused=")) {
|
|
|
|
if (STREQ(key + 10, "1"))
|
|
|
|
graphics->data.vnc.autoport = true;
|
|
|
|
} else if (STRPREFIX(key, "vnclisten=")) {
|
|
|
|
if (virDomainGraphicsListenSetAddress(graphics, 0, key+10,
|
|
|
|
-1, true) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
} else if (STRPREFIX(key, "vncpasswd=")) {
|
|
|
|
if (VIR_STRDUP(graphics->data.vnc.auth.passwd, key + 10) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
} else if (STRPREFIX(key, "keymap=")) {
|
|
|
|
if (VIR_STRDUP(graphics->data.vnc.keymap, key + 7) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
} else if (STRPREFIX(key, "vncdisplay=")) {
|
|
|
|
if (virStrToLong_i(key + 11, NULL, 10,
|
|
|
|
&graphics->data.vnc.port) < 0) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("invalid vncdisplay value '%s'"),
|
|
|
|
key + 11);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
graphics->data.vnc.port += 5900;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (STRPREFIX(key, "display=")) {
|
|
|
|
if (VIR_STRDUP(graphics->data.sdl.display, key + 8) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
} else if (STRPREFIX(key, "xauthority=")) {
|
|
|
|
if (VIR_STRDUP(graphics->data.sdl.xauth, key + 11) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while (nextkey && (nextkey[0] == ',' ||
|
|
|
|
nextkey[0] == ' ' ||
|
|
|
|
nextkey[0] == '\t'))
|
|
|
|
nextkey++;
|
|
|
|
key = nextkey;
|
|
|
|
}
|
|
|
|
if (VIR_ALLOC_N(def->graphics, 1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
def->graphics[0] = graphics;
|
|
|
|
def->ngraphics = 1;
|
|
|
|
graphics = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainGraphicsDefFree(graphics);
|
|
|
|
VIR_FREE(listenAddr);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-07 18:32:57 +00:00
|
|
|
static int
|
|
|
|
xenParseXMCharDev(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
const char *str;
|
|
|
|
virConfValuePtr value = NULL;
|
|
|
|
virDomainChrDefPtr chr = NULL;
|
|
|
|
|
|
|
|
if (STREQ(def->os.type, "hvm")) {
|
|
|
|
if (xenXMConfigGetString(conf, "parallel", &str, NULL) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (str && STRNEQ(str, "none") &&
|
|
|
|
!(chr = xenParseSxprChar(str, NULL)))
|
|
|
|
goto cleanup;
|
|
|
|
if (chr) {
|
|
|
|
if (VIR_ALLOC_N(def->parallels, 1) < 0) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL;
|
|
|
|
chr->target.port = 0;
|
|
|
|
def->parallels[0] = chr;
|
|
|
|
def->nparallels++;
|
|
|
|
chr = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Try to get the list of values to support multiple serial ports */
|
|
|
|
value = virConfGetValue(conf, "serial");
|
|
|
|
if (value && value->type == VIR_CONF_LIST) {
|
|
|
|
int portnum = -1;
|
|
|
|
|
|
|
|
value = value->list;
|
|
|
|
while (value) {
|
|
|
|
char *port = NULL;
|
|
|
|
|
|
|
|
if ((value->type != VIR_CONF_STRING) || (value->str == NULL))
|
|
|
|
goto cleanup;
|
|
|
|
port = value->str;
|
|
|
|
portnum++;
|
|
|
|
if (STREQ(port, "none")) {
|
|
|
|
value = value->next;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(chr = xenParseSxprChar(port, NULL)))
|
|
|
|
goto cleanup;
|
|
|
|
chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
|
|
|
|
chr->target.port = portnum;
|
|
|
|
if (VIR_APPEND_ELEMENT(def->serials, def->nserials, chr) < 0) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
value = value->next;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* If domain is not using multiple serial ports we parse data old way */
|
|
|
|
if (xenXMConfigGetString(conf, "serial", &str, NULL) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (str && STRNEQ(str, "none") &&
|
|
|
|
!(chr = xenParseSxprChar(str, NULL)))
|
|
|
|
goto cleanup;
|
|
|
|
if (chr) {
|
|
|
|
if (VIR_ALLOC_N(def->serials, 1) < 0) {
|
|
|
|
virDomainChrDefFree(chr);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
|
|
|
|
chr->target.port = 0;
|
|
|
|
def->serials[0] = chr;
|
|
|
|
def->nserials++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (VIR_ALLOC_N(def->consoles, 1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
def->nconsoles = 1;
|
|
|
|
if (!(def->consoles[0] = xenParseSxprChar("pty", NULL)))
|
|
|
|
goto cleanup;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virDomainChrDefFree(chr);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-07 18:32:58 +00:00
|
|
|
static int
|
|
|
|
xenParseXMVif(virConfPtr conf, virDomainDefPtr def)
|
2014-08-07 18:32:55 +00:00
|
|
|
{
|
|
|
|
char *script = NULL;
|
2014-08-07 18:32:58 +00:00
|
|
|
virDomainNetDefPtr net = NULL;
|
|
|
|
virConfValuePtr list = virConfGetValue(conf, "vif");
|
2014-08-07 18:32:55 +00:00
|
|
|
|
2011-02-21 13:40:10 +00:00
|
|
|
if (list && list->type == VIR_CONF_LIST) {
|
|
|
|
list = list->list;
|
|
|
|
while (list) {
|
|
|
|
char model[10];
|
|
|
|
char type[10];
|
|
|
|
char ip[16];
|
|
|
|
char mac[18];
|
|
|
|
char bridge[50];
|
|
|
|
char vifname[50];
|
|
|
|
char *key;
|
|
|
|
|
|
|
|
bridge[0] = '\0';
|
|
|
|
mac[0] = '\0';
|
|
|
|
ip[0] = '\0';
|
|
|
|
model[0] = '\0';
|
|
|
|
type[0] = '\0';
|
|
|
|
vifname[0] = '\0';
|
|
|
|
|
|
|
|
if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
|
|
|
|
goto skipnic;
|
|
|
|
|
|
|
|
key = list->str;
|
|
|
|
while (key) {
|
|
|
|
char *data;
|
|
|
|
char *nextkey = strchr(key, ',');
|
|
|
|
|
|
|
|
if (!(data = strchr(key, '=')))
|
|
|
|
goto skipnic;
|
|
|
|
data++;
|
|
|
|
|
|
|
|
if (STRPREFIX(key, "mac=")) {
|
|
|
|
int len = nextkey ? (nextkey - data) : sizeof(mac) - 1;
|
|
|
|
if (virStrncpy(mac, data, len, sizeof(mac)) == NULL) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("MAC address %s too big for destination"),
|
|
|
|
data);
|
2011-02-21 13:40:10 +00:00
|
|
|
goto skipnic;
|
|
|
|
}
|
|
|
|
} else if (STRPREFIX(key, "bridge=")) {
|
|
|
|
int len = nextkey ? (nextkey - data) : sizeof(bridge) - 1;
|
|
|
|
if (virStrncpy(bridge, data, len, sizeof(bridge)) == NULL) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Bridge %s too big for destination"),
|
|
|
|
data);
|
2011-02-21 13:40:10 +00:00
|
|
|
goto skipnic;
|
|
|
|
}
|
|
|
|
} else if (STRPREFIX(key, "script=")) {
|
2011-04-03 09:21:21 +00:00
|
|
|
int len = nextkey ? (nextkey - data) : strlen(data);
|
|
|
|
VIR_FREE(script);
|
2013-05-03 12:51:56 +00:00
|
|
|
if (VIR_STRNDUP(script, data, len) < 0)
|
|
|
|
goto cleanup;
|
2011-02-21 13:40:10 +00:00
|
|
|
} else if (STRPREFIX(key, "model=")) {
|
|
|
|
int len = nextkey ? (nextkey - data) : sizeof(model) - 1;
|
|
|
|
if (virStrncpy(model, data, len, sizeof(model)) == NULL) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
2014-08-07 18:32:58 +00:00
|
|
|
_("Model %s too big for destination"),
|
|
|
|
data);
|
2011-02-21 13:40:10 +00:00
|
|
|
goto skipnic;
|
|
|
|
}
|
|
|
|
} else if (STRPREFIX(key, "type=")) {
|
|
|
|
int len = nextkey ? (nextkey - data) : sizeof(type) - 1;
|
|
|
|
if (virStrncpy(type, data, len, sizeof(type)) == NULL) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
2014-08-07 18:32:58 +00:00
|
|
|
_("Type %s too big for destination"),
|
|
|
|
data);
|
2011-02-21 13:40:10 +00:00
|
|
|
goto skipnic;
|
|
|
|
}
|
|
|
|
} else if (STRPREFIX(key, "vifname=")) {
|
|
|
|
int len = nextkey ? (nextkey - data) : sizeof(vifname) - 1;
|
|
|
|
if (virStrncpy(vifname, data, len, sizeof(vifname)) == NULL) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("Vifname %s too big for destination"),
|
|
|
|
data);
|
2011-02-21 13:40:10 +00:00
|
|
|
goto skipnic;
|
|
|
|
}
|
|
|
|
} else if (STRPREFIX(key, "ip=")) {
|
|
|
|
int len = nextkey ? (nextkey - data) : sizeof(ip) - 1;
|
|
|
|
if (virStrncpy(ip, data, len, sizeof(ip)) == NULL) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("IP %s too big for destination"), data);
|
2011-02-21 13:40:10 +00:00
|
|
|
goto skipnic;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
while (nextkey && (nextkey[0] == ',' ||
|
|
|
|
nextkey[0] == ' ' ||
|
|
|
|
nextkey[0] == '\t'))
|
|
|
|
nextkey++;
|
|
|
|
key = nextkey;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VIR_ALLOC(net) < 0)
|
2013-07-04 10:19:27 +00:00
|
|
|
goto cleanup;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
|
|
|
if (mac[0]) {
|
2012-07-17 12:07:59 +00:00
|
|
|
if (virMacAddrParse(mac, &net->mac) < 0) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("malformed mac address '%s'"), mac);
|
2011-02-21 13:40:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-06 10:56:52 +00:00
|
|
|
if (bridge[0] || STREQ_NULLABLE(script, "vif-bridge") ||
|
|
|
|
STREQ_NULLABLE(script, "vif-vnic")) {
|
2011-02-21 13:40:10 +00:00
|
|
|
net->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
|
|
|
|
} else {
|
|
|
|
net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
|
2013-05-03 12:51:56 +00:00
|
|
|
if (bridge[0] && VIR_STRDUP(net->data.bridge.brname, bridge) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
if (ip[0] && VIR_STRDUP(net->data.bridge.ipaddr, ip) < 0)
|
|
|
|
goto cleanup;
|
2011-02-21 13:40:10 +00:00
|
|
|
} else {
|
2013-05-03 12:51:56 +00:00
|
|
|
if (ip[0] && VIR_STRDUP(net->data.ethernet.ipaddr, ip) < 0)
|
|
|
|
goto cleanup;
|
2011-02-21 13:40:10 +00:00
|
|
|
}
|
|
|
|
|
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 (script && script[0] &&
|
2013-05-03 12:51:56 +00:00
|
|
|
VIR_STRDUP(net->script, script) < 0)
|
|
|
|
goto cleanup;
|
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
|
|
|
|
2011-02-21 13:40:10 +00:00
|
|
|
if (model[0] &&
|
2013-05-03 12:51:56 +00:00
|
|
|
VIR_STRDUP(net->model, model) < 0)
|
2013-07-04 10:19:27 +00:00
|
|
|
goto cleanup;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
2013-05-03 12:51:56 +00:00
|
|
|
if (!model[0] && type[0] && STREQ(type, "netfront") &&
|
|
|
|
VIR_STRDUP(net->model, "netfront") < 0)
|
|
|
|
goto cleanup;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
|
|
|
if (vifname[0] &&
|
2013-05-03 12:51:56 +00:00
|
|
|
VIR_STRDUP(net->ifname, vifname) < 0)
|
|
|
|
goto cleanup;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
2014-03-07 08:33:31 +00:00
|
|
|
if (VIR_APPEND_ELEMENT(def->nets, def->nnets, net) < 0)
|
2013-07-04 10:19:27 +00:00
|
|
|
goto cleanup;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
|
|
|
skipnic:
|
|
|
|
list = list->next;
|
|
|
|
virDomainNetDefFree(net);
|
2014-08-07 18:32:58 +00:00
|
|
|
VIR_FREE(script);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(script);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-07 18:32:59 +00:00
|
|
|
static int
|
|
|
|
xenParseXMEmulatedDevices(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
const char *str;
|
|
|
|
|
|
|
|
if (STREQ(def->os.type, "hvm")) {
|
|
|
|
if (xenXMConfigGetString(conf, "soundhw", &str, NULL) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (str &&
|
|
|
|
xenParseSxprSound(def, str) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (xenXMConfigGetString(conf, "usbdevice", &str, NULL) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (str &&
|
|
|
|
(STREQ(str, "tablet") ||
|
|
|
|
STREQ(str, "mouse") ||
|
|
|
|
STREQ(str, "keyboard"))) {
|
|
|
|
virDomainInputDefPtr input;
|
|
|
|
if (VIR_ALLOC(input) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
input->bus = VIR_DOMAIN_INPUT_BUS_USB;
|
|
|
|
if (STREQ(str, "mouse"))
|
|
|
|
input->type = VIR_DOMAIN_INPUT_TYPE_MOUSE;
|
|
|
|
else if (STREQ(str, "tablet"))
|
|
|
|
input->type = VIR_DOMAIN_INPUT_TYPE_TABLET;
|
|
|
|
else if (STREQ(str, "keyboard"))
|
|
|
|
input->type = VIR_DOMAIN_INPUT_TYPE_KBD;
|
|
|
|
if (VIR_ALLOC_N(def->inputs, 1) < 0) {
|
|
|
|
virDomainInputDefFree(input);
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
def->inputs[0] = input;
|
|
|
|
def->ninputs = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-07 18:33:00 +00:00
|
|
|
static int
|
|
|
|
xenParseXMGeneralMeta(virConfPtr conf, virDomainDefPtr def, virCapsPtr caps)
|
2014-08-07 18:32:58 +00:00
|
|
|
{
|
2014-08-07 18:33:00 +00:00
|
|
|
const char *defaultMachine;
|
2014-08-07 18:32:58 +00:00
|
|
|
const char *str;
|
|
|
|
int hvm = 0;
|
|
|
|
|
|
|
|
if (xenXMConfigCopyString(conf, "name", &def->name) < 0)
|
2014-08-07 18:33:00 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
|
2014-08-07 18:33:00 +00:00
|
|
|
if (xenXMConfigGetUUID(conf, "uuid", def->uuid) < 0)
|
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
|
|
|
|
if ((xenXMConfigGetString(conf, "builder", &str, "linux") == 0) &&
|
|
|
|
STREQ(str, "hvm"))
|
|
|
|
hvm = 1;
|
|
|
|
|
|
|
|
if (VIR_STRDUP(def->os.type, hvm ? "hvm" : "xen") < 0)
|
2014-08-07 18:33:00 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
|
|
|
|
def->os.arch =
|
|
|
|
virCapabilitiesDefaultGuestArch(caps,
|
|
|
|
def->os.type,
|
|
|
|
virDomainVirtTypeToString(def->virtType));
|
|
|
|
if (!def->os.arch) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("no supported architecture for os type '%s'"),
|
|
|
|
def->os.type);
|
2014-08-07 18:33:00 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
defaultMachine = virCapabilitiesDefaultGuestMachine(caps,
|
|
|
|
def->os.type,
|
|
|
|
def->os.arch,
|
|
|
|
virDomainVirtTypeToString(def->virtType));
|
|
|
|
if (defaultMachine != NULL) {
|
|
|
|
if (VIR_STRDUP(def->os.machine, defaultMachine) < 0)
|
2014-08-07 18:33:00 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
}
|
|
|
|
|
2014-08-07 18:33:00 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-07 18:33:01 +00:00
|
|
|
static int
|
|
|
|
xenParseXMOS(virConfPtr conf, virDomainDefPtr def)
|
2014-08-07 18:33:00 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
2014-08-07 18:33:01 +00:00
|
|
|
if (xenXMConfigCopyStringOpt(conf, "device_model", &def->emulator) < 0)
|
|
|
|
return -1;
|
2014-08-07 18:33:00 +00:00
|
|
|
|
|
|
|
if (STREQ(def->os.type, "hvm")) {
|
2014-08-07 18:32:58 +00:00
|
|
|
const char *boot;
|
2014-08-07 18:33:01 +00:00
|
|
|
|
|
|
|
if (xenXMConfigCopyString(conf, "kernel", &def->os.loader) < 0)
|
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
|
|
|
|
if (xenXMConfigGetString(conf, "boot", &boot, "c") < 0)
|
2014-08-07 18:33:01 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
|
|
|
|
for (i = 0; i < VIR_DOMAIN_BOOT_LAST && boot[i]; i++) {
|
|
|
|
switch (*boot) {
|
|
|
|
case 'a':
|
|
|
|
def->os.bootDevs[i] = VIR_DOMAIN_BOOT_FLOPPY;
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
def->os.bootDevs[i] = VIR_DOMAIN_BOOT_CDROM;
|
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
def->os.bootDevs[i] = VIR_DOMAIN_BOOT_NET;
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
default:
|
|
|
|
def->os.bootDevs[i] = VIR_DOMAIN_BOOT_DISK;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
def->os.nBootDevs++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
const char *extra, *root;
|
|
|
|
|
|
|
|
if (xenXMConfigCopyStringOpt(conf, "bootloader", &def->os.bootloader) < 0)
|
2014-08-07 18:33:01 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
if (xenXMConfigCopyStringOpt(conf, "bootargs", &def->os.bootloaderArgs) < 0)
|
2014-08-07 18:33:01 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
|
|
|
|
if (xenXMConfigCopyStringOpt(conf, "kernel", &def->os.kernel) < 0)
|
2014-08-07 18:33:01 +00:00
|
|
|
return -1;
|
|
|
|
|
2014-08-07 18:32:58 +00:00
|
|
|
if (xenXMConfigCopyStringOpt(conf, "ramdisk", &def->os.initrd) < 0)
|
2014-08-07 18:33:01 +00:00
|
|
|
return -1;
|
|
|
|
|
2014-08-07 18:32:58 +00:00
|
|
|
if (xenXMConfigGetString(conf, "extra", &extra, NULL) < 0)
|
2014-08-07 18:33:01 +00:00
|
|
|
return -1;
|
|
|
|
|
2014-08-07 18:32:58 +00:00
|
|
|
if (xenXMConfigGetString(conf, "root", &root, NULL) < 0)
|
2014-08-07 18:33:01 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
|
|
|
|
if (root) {
|
|
|
|
if (virAsprintf(&def->os.cmdline, "root=%s %s", root, extra) < 0)
|
2014-08-07 18:33:01 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
} else {
|
|
|
|
if (VIR_STRDUP(def->os.cmdline, extra) < 0)
|
2014-08-07 18:33:01 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-07 18:33:01 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-11 21:21:24 +00:00
|
|
|
int
|
|
|
|
xenParseConfigCommon(virConfPtr conf,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
virCapsPtr caps,
|
|
|
|
int xendConfigVersion)
|
2014-08-07 18:33:01 +00:00
|
|
|
{
|
|
|
|
if (xenParseXMGeneralMeta(conf, def, caps) < 0)
|
2014-08-11 21:21:24 +00:00
|
|
|
return -1;
|
2014-08-07 18:33:01 +00:00
|
|
|
|
|
|
|
if (xenParseXMOS(conf, def) < 0)
|
2014-08-11 21:21:24 +00:00
|
|
|
return -1;
|
2014-08-07 18:33:01 +00:00
|
|
|
|
2014-08-07 18:32:58 +00:00
|
|
|
if (xenParseXMMem(conf, def) < 0)
|
2014-08-11 21:21:24 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
|
|
|
|
if (xenParseXMEventsActions(conf, def) < 0)
|
2014-08-11 21:21:24 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
|
|
|
|
if (xenParseXMCPUFeatures(conf, def) < 0)
|
2014-08-11 21:21:24 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
|
|
|
|
if (xenParseXMTimeOffset(conf, def, xendConfigVersion) < 0)
|
2014-08-11 21:21:24 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
|
|
|
|
if (xenXMConfigCopyStringOpt(conf, "device_model", &def->emulator) < 0)
|
2014-08-11 21:21:24 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
|
|
|
|
if (xenParseXMVif(conf, def) < 0)
|
2014-08-11 21:21:24 +00:00
|
|
|
return -1;
|
2014-08-07 18:32:58 +00:00
|
|
|
|
2014-08-07 18:32:53 +00:00
|
|
|
if (xenParseXMPCI(conf, def) < 0)
|
2014-08-11 21:21:24 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
2014-08-07 18:32:59 +00:00
|
|
|
if (xenParseXMEmulatedDevices(conf, def) < 0)
|
2014-08-11 21:21:24 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
2014-08-07 18:32:56 +00:00
|
|
|
if (xenParseXMVfb(conf, def, xendConfigVersion) < 0)
|
2014-08-11 21:21:24 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
2014-08-07 18:32:57 +00:00
|
|
|
if (xenParseXMCharDev(conf, def) < 0)
|
2014-08-11 21:21:24 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Turn a config record into a lump of XML describing the
|
|
|
|
* domain, suitable for later feeding for virDomainCreateXML
|
|
|
|
*/
|
|
|
|
virDomainDefPtr
|
|
|
|
xenParseXM(virConfPtr conf,
|
|
|
|
int xendConfigVersion,
|
|
|
|
virCapsPtr caps)
|
|
|
|
{
|
|
|
|
virDomainDefPtr def = NULL;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(def) < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
def->virtType = VIR_DOMAIN_VIRT_XEN;
|
|
|
|
def->id = -1;
|
|
|
|
|
|
|
|
if (xenParseConfigCommon(conf, def, caps, xendConfigVersion) < 0)
|
2014-08-07 18:32:57 +00:00
|
|
|
goto cleanup;
|
2011-02-21 13:40:10 +00:00
|
|
|
|
2014-08-11 21:21:24 +00:00
|
|
|
if (xenParseXMDisk(conf, def, xendConfigVersion) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2011-02-21 13:40:10 +00:00
|
|
|
return def;
|
|
|
|
|
2014-03-25 06:57:22 +00:00
|
|
|
cleanup:
|
2011-02-21 13:40:10 +00:00
|
|
|
virDomainDefFree(def);
|
|
|
|
return NULL;
|
|
|
|
}
|
2011-02-21 13:40:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
static
|
2014-03-18 08:14:16 +00:00
|
|
|
int xenXMConfigSetInt(virConfPtr conf, const char *setting, long long l)
|
|
|
|
{
|
2011-02-21 13:40:11 +00:00
|
|
|
virConfValuePtr value = NULL;
|
|
|
|
|
2012-03-02 20:27:39 +00:00
|
|
|
if ((long) l != l) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_OVERFLOW, _("failed to store %lld to %s"),
|
|
|
|
l, setting);
|
2012-03-02 20:27:39 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2013-07-04 10:19:27 +00:00
|
|
|
if (VIR_ALLOC(value) < 0)
|
2011-02-21 13:40:11 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
value->type = VIR_CONF_LONG;
|
|
|
|
value->next = NULL;
|
|
|
|
value->l = l;
|
|
|
|
|
|
|
|
return virConfSetValue(conf, setting, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-18 08:14:16 +00:00
|
|
|
static int
|
|
|
|
xenXMConfigSetString(virConfPtr conf, const char *setting, const char *str)
|
|
|
|
{
|
2011-02-21 13:40:11 +00:00
|
|
|
virConfValuePtr value = NULL;
|
|
|
|
|
2013-07-04 10:19:27 +00:00
|
|
|
if (VIR_ALLOC(value) < 0)
|
2011-02-21 13:40:11 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
value->type = VIR_CONF_STRING;
|
|
|
|
value->next = NULL;
|
2013-05-03 12:51:56 +00:00
|
|
|
if (VIR_STRDUP(value->str, str) < 0) {
|
2011-02-21 13:40:11 +00:00
|
|
|
VIR_FREE(value);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return virConfSetValue(conf, setting, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-24 18:14:48 +00:00
|
|
|
static int
|
|
|
|
xenFormatXMDisk(virConfValuePtr list,
|
|
|
|
virDomainDiskDefPtr disk,
|
|
|
|
int hvm,
|
|
|
|
int xendConfigVersion)
|
2011-02-21 13:40:11 +00:00
|
|
|
{
|
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
virConfValuePtr val, tmp;
|
2014-03-24 18:14:48 +00:00
|
|
|
const char *src = virDomainDiskGetSource(disk);
|
|
|
|
int format = virDomainDiskGetFormat(disk);
|
|
|
|
const char *driver = virDomainDiskGetDriver(disk);
|
2011-02-21 13:40:11 +00:00
|
|
|
|
2014-03-24 18:14:48 +00:00
|
|
|
if (src) {
|
|
|
|
if (format) {
|
2012-10-15 21:47:42 +00:00
|
|
|
const char *type;
|
|
|
|
|
2014-03-24 18:14:48 +00:00
|
|
|
if (format == VIR_STORAGE_FILE_RAW)
|
2012-09-28 23:48:58 +00:00
|
|
|
type = "aio";
|
2012-10-15 21:47:42 +00:00
|
|
|
else
|
2014-03-24 18:14:48 +00:00
|
|
|
type = virStorageFileFormatTypeToString(format);
|
|
|
|
virBufferAsprintf(&buf, "%s:", driver);
|
|
|
|
if (STREQ(driver, "tap"))
|
2012-09-28 23:48:58 +00:00
|
|
|
virBufferAsprintf(&buf, "%s:", type);
|
2011-02-21 13:40:11 +00:00
|
|
|
} else {
|
2014-03-24 18:14:48 +00:00
|
|
|
switch (virDomainDiskGetType(disk)) {
|
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
|
|
|
case VIR_STORAGE_TYPE_FILE:
|
2011-02-21 13:40:11 +00:00
|
|
|
virBufferAddLit(&buf, "file:");
|
|
|
|
break;
|
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
|
|
|
case VIR_STORAGE_TYPE_BLOCK:
|
2011-02-21 13:40:11 +00:00
|
|
|
virBufferAddLit(&buf, "phy:");
|
|
|
|
break;
|
|
|
|
default:
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("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(virDomainDiskGetType(disk)));
|
2011-02-21 13:40:11 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
2014-03-24 18:14:48 +00:00
|
|
|
virBufferAdd(&buf, src, -1);
|
2011-02-21 13:40:11 +00:00
|
|
|
}
|
|
|
|
virBufferAddLit(&buf, ",");
|
2012-01-31 17:08:09 +00:00
|
|
|
if (hvm && xendConfigVersion == XEND_CONFIG_VERSION_3_0_2)
|
2011-02-21 13:40:11 +00:00
|
|
|
virBufferAddLit(&buf, "ioemu:");
|
|
|
|
|
2011-04-14 19:27:47 +00:00
|
|
|
virBufferAdd(&buf, disk->dst, -1);
|
2011-02-21 13:40:11 +00:00
|
|
|
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
|
|
|
|
virBufferAddLit(&buf, ":cdrom");
|
|
|
|
|
2014-06-24 13:15:55 +00:00
|
|
|
if (disk->src->readonly)
|
2011-02-21 13:40:11 +00:00
|
|
|
virBufferAddLit(&buf, ",r");
|
2014-06-24 13:15:55 +00:00
|
|
|
else if (disk->src->shared)
|
2011-02-21 13:40:11 +00:00
|
|
|
virBufferAddLit(&buf, ",!");
|
|
|
|
else
|
|
|
|
virBufferAddLit(&buf, ",w");
|
2011-08-13 21:42:48 +00:00
|
|
|
if (disk->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",
|
2012-07-18 13:17:20 +00:00
|
|
|
_("transient disks not supported yet"));
|
2011-08-13 21:42:48 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2011-02-21 13:40:11 +00:00
|
|
|
|
2014-06-27 08:40:15 +00:00
|
|
|
if (virBufferCheckError(&buf) < 0)
|
2011-02-21 13:40:11 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2013-07-04 10:19:27 +00:00
|
|
|
if (VIR_ALLOC(val) < 0)
|
2011-02-21 13:40:11 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
val->type = VIR_CONF_STRING;
|
|
|
|
val->str = virBufferContentAndReset(&buf);
|
|
|
|
tmp = list->list;
|
|
|
|
while (tmp && tmp->next)
|
|
|
|
tmp = tmp->next;
|
|
|
|
if (tmp)
|
|
|
|
tmp->next = val;
|
|
|
|
else
|
|
|
|
list->list = val;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 06:57:22 +00:00
|
|
|
cleanup:
|
2011-02-21 13:40:11 +00:00
|
|
|
virBufferFreeAndReset(&buf);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-02-25 14:41:12 +00:00
|
|
|
static int xenFormatXMSerial(virConfValuePtr list,
|
|
|
|
virDomainChrDefPtr serial)
|
|
|
|
{
|
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
virConfValuePtr val, tmp;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (serial) {
|
|
|
|
ret = xenFormatSxprChr(serial, &buf);
|
2013-07-04 10:19:27 +00:00
|
|
|
if (ret < 0)
|
2011-02-25 14:41:12 +00:00
|
|
|
goto cleanup;
|
|
|
|
} else {
|
|
|
|
virBufferAddLit(&buf, "none");
|
|
|
|
}
|
2014-06-27 08:40:15 +00:00
|
|
|
if (virBufferCheckError(&buf) < 0)
|
2011-02-25 14:41:12 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2013-07-04 10:19:27 +00:00
|
|
|
if (VIR_ALLOC(val) < 0)
|
2011-02-25 14:41:12 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
val->type = VIR_CONF_STRING;
|
|
|
|
val->str = virBufferContentAndReset(&buf);
|
|
|
|
tmp = list->list;
|
|
|
|
while (tmp && tmp->next)
|
|
|
|
tmp = tmp->next;
|
|
|
|
if (tmp)
|
|
|
|
tmp->next = val;
|
|
|
|
else
|
|
|
|
list->list = val;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 06:57:22 +00:00
|
|
|
cleanup:
|
2011-02-25 14:41:12 +00:00
|
|
|
virBufferFreeAndReset(&buf);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-02-21 13:40:12 +00:00
|
|
|
static int xenFormatXMNet(virConnectPtr conn,
|
2011-02-21 13:40:11 +00:00
|
|
|
virConfValuePtr list,
|
|
|
|
virDomainNetDefPtr net,
|
|
|
|
int hvm, int xendConfigVersion)
|
|
|
|
{
|
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
virConfValuePtr val, tmp;
|
2013-03-26 11:21:33 +00:00
|
|
|
char macaddr[VIR_MAC_STRING_BUFLEN];
|
2011-02-21 13:40:11 +00:00
|
|
|
|
2013-03-26 11:21:33 +00:00
|
|
|
virBufferAsprintf(&buf, "mac=%s", virMacAddrFormat(&net->mac, macaddr));
|
2011-02-21 13:40:11 +00:00
|
|
|
|
|
|
|
switch (net->type) {
|
|
|
|
case VIR_DOMAIN_NET_TYPE_BRIDGE:
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(&buf, ",bridge=%s", net->data.bridge.brname);
|
2011-02-21 13:40:11 +00:00
|
|
|
if (net->data.bridge.ipaddr)
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(&buf, ",ip=%s", net->data.bridge.ipaddr);
|
|
|
|
virBufferAsprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
|
2011-02-21 13:40:11 +00:00
|
|
|
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 (net->script)
|
|
|
|
virBufferAsprintf(&buf, ",script=%s", net->script);
|
2011-02-21 13:40:11 +00:00
|
|
|
if (net->data.ethernet.ipaddr)
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(&buf, ",ip=%s", net->data.ethernet.ipaddr);
|
2011-02-21 13:40:11 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case VIR_DOMAIN_NET_TYPE_NETWORK:
|
|
|
|
{
|
|
|
|
virNetworkPtr network = virNetworkLookupByName(conn, net->data.network.name);
|
|
|
|
char *bridge;
|
|
|
|
if (!network) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_NO_NETWORK, "%s",
|
|
|
|
net->data.network.name);
|
2011-02-21 13:40:11 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
bridge = virNetworkGetBridgeName(network);
|
|
|
|
virNetworkFree(network);
|
|
|
|
if (!bridge) {
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("network %s is not active"),
|
|
|
|
net->data.network.name);
|
2011-02-21 13:40:11 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(&buf, ",bridge=%s", bridge);
|
|
|
|
virBufferAsprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
|
2011-02-21 13:40:11 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2012-07-18 13:17:20 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unsupported network type %d"),
|
|
|
|
net->type);
|
2011-02-21 13:40:11 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!hvm) {
|
|
|
|
if (net->model != NULL)
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(&buf, ",model=%s", net->model);
|
2011-02-21 13:40:11 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-04-13 13:14:56 +00:00
|
|
|
if (net->model != NULL && STREQ(net->model, "netfront")) {
|
|
|
|
virBufferAddLit(&buf, ",type=netfront");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (net->model != NULL)
|
|
|
|
virBufferAsprintf(&buf, ",model=%s", net->model);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* apparently type ioemu breaks paravirt drivers on HVM so skip this
|
|
|
|
* from XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU
|
|
|
|
*/
|
|
|
|
if (xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
|
|
|
|
virBufferAddLit(&buf, ",type=ioemu");
|
|
|
|
}
|
2011-02-21 13:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (net->ifname)
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(&buf, ",vifname=%s",
|
2011-02-21 13:40:11 +00:00
|
|
|
net->ifname);
|
|
|
|
|
2014-06-27 08:40:15 +00:00
|
|
|
if (virBufferCheckError(&buf) < 0)
|
2011-02-21 13:40:11 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2013-07-04 10:19:27 +00:00
|
|
|
if (VIR_ALLOC(val) < 0)
|
2011-02-21 13:40:11 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
val->type = VIR_CONF_STRING;
|
|
|
|
val->str = virBufferContentAndReset(&buf);
|
|
|
|
tmp = list->list;
|
|
|
|
while (tmp && tmp->next)
|
|
|
|
tmp = tmp->next;
|
|
|
|
if (tmp)
|
|
|
|
tmp->next = val;
|
|
|
|
else
|
|
|
|
list->list = val;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 06:57:22 +00:00
|
|
|
cleanup:
|
2011-02-21 13:40:11 +00:00
|
|
|
virBufferFreeAndReset(&buf);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
2011-02-21 13:40:12 +00:00
|
|
|
xenFormatXMPCI(virConfPtr conf,
|
2011-02-21 13:40:11 +00:00
|
|
|
virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
|
|
|
|
virConfValuePtr pciVal = NULL;
|
|
|
|
int hasPCI = 0;
|
Convert 'int i' to 'size_t i' in src/{xen,xenapi,xenxs} files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2011-02-21 13:40:11 +00:00
|
|
|
|
2013-05-21 07:21:19 +00:00
|
|
|
for (i = 0; i < def->nhostdevs; i++)
|
2011-02-21 13:40:11 +00:00
|
|
|
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;
|
|
|
|
|
2013-07-04 10:19:27 +00:00
|
|
|
if (VIR_ALLOC(pciVal) < 0)
|
2011-02-21 13:40:11 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
pciVal->type = VIR_CONF_LIST;
|
|
|
|
pciVal->list = NULL;
|
|
|
|
|
2013-05-21 07:21:19 +00:00
|
|
|
for (i = 0; i < def->nhostdevs; i++) {
|
2011-02-21 13:40:11 +00:00
|
|
|
if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
|
|
|
|
def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
|
|
|
|
virConfValuePtr val, tmp;
|
|
|
|
char *buf;
|
|
|
|
|
|
|
|
if (virAsprintf(&buf, "%04x:%02x:%02x.%x",
|
2013-03-18 19:56:12 +00:00
|
|
|
def->hostdevs[i]->source.subsys.u.pci.addr.domain,
|
|
|
|
def->hostdevs[i]->source.subsys.u.pci.addr.bus,
|
|
|
|
def->hostdevs[i]->source.subsys.u.pci.addr.slot,
|
2013-07-04 10:19:27 +00:00
|
|
|
def->hostdevs[i]->source.subsys.u.pci.addr.function) < 0)
|
2011-02-21 13:40:11 +00:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(val) < 0) {
|
|
|
|
VIR_FREE(buf);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
val->type = VIR_CONF_STRING;
|
|
|
|
val->str = buf;
|
|
|
|
tmp = pciVal->list;
|
|
|
|
while (tmp && tmp->next)
|
|
|
|
tmp = tmp->next;
|
|
|
|
if (tmp)
|
|
|
|
tmp->next = val;
|
|
|
|
else
|
|
|
|
pciVal->list = val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pciVal->list != NULL) {
|
|
|
|
int ret = virConfSetValue(conf, "pci", pciVal);
|
|
|
|
pciVal = NULL;
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
VIR_FREE(pciVal);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 06:57:22 +00:00
|
|
|
error:
|
2011-02-21 13:40:11 +00:00
|
|
|
virConfFreeValue(pciVal);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-11 21:21:25 +00:00
|
|
|
static int
|
|
|
|
xenFormatXMGeneralMeta(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
char uuid[VIR_UUID_STRING_BUFLEN];
|
|
|
|
|
|
|
|
if (xenXMConfigSetString(conf, "name", def->name) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
virUUIDFormat(def->uuid, uuid);
|
|
|
|
if (xenXMConfigSetString(conf, "uuid", uuid) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-11 21:21:26 +00:00
|
|
|
static int
|
|
|
|
xenFormatXMMem(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
if (xenXMConfigSetInt(conf, "maxmem",
|
|
|
|
VIR_DIV_UP(def->mem.max_balloon, 1024)) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (xenXMConfigSetInt(conf, "memory",
|
|
|
|
VIR_DIV_UP(def->mem.cur_balloon, 1024)) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-11 21:21:27 +00:00
|
|
|
static int
|
|
|
|
xenFormatXMTimeOffset(virConfPtr conf,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
int xendConfigVersion)
|
|
|
|
{
|
|
|
|
int vmlocaltime;
|
|
|
|
|
|
|
|
if (xendConfigVersion < XEND_CONFIG_VERSION_3_1_0) {
|
|
|
|
/* <3.1: 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));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
if (STREQ(def->os.type, "hvm")) {
|
|
|
|
/* >=3.1 HV: VARIABLE */
|
|
|
|
int rtc_timeoffset;
|
|
|
|
|
|
|
|
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;
|
|
|
|
case VIR_DOMAIN_CLOCK_OFFSET_UTC:
|
|
|
|
if (def->clock.data.utc_reset) {
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("unsupported clock adjustment='reset'"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
vmlocaltime = 0;
|
|
|
|
rtc_timeoffset = 0;
|
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME:
|
|
|
|
if (def->clock.data.utc_reset) {
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("unsupported clock adjustment='reset'"));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
vmlocaltime = 1;
|
|
|
|
rtc_timeoffset = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("unsupported clock offset='%s'"),
|
|
|
|
virDomainClockOffsetTypeToString(def->clock.offset));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (xenXMConfigSetInt(conf, "rtc_timeoffset", rtc_timeoffset) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
} 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));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
} /* !hvm */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xenXMConfigSetInt(conf, "localtime", vmlocaltime) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-11 21:21:28 +00:00
|
|
|
static int
|
|
|
|
xenFormatXMEventActions(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
const char *lifecycle = NULL;
|
|
|
|
|
|
|
|
if (!(lifecycle = virDomainLifecycleTypeToString(def->onPoweroff))) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unexpected lifecycle action %d"), def->onPoweroff);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (xenXMConfigSetString(conf, "on_poweroff", lifecycle) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
if (!(lifecycle = virDomainLifecycleTypeToString(def->onReboot))) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unexpected lifecycle action %d"), def->onReboot);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (xenXMConfigSetString(conf, "on_reboot", lifecycle) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
|
|
if (!(lifecycle = virDomainLifecycleCrashTypeToString(def->onCrash))) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("unexpected lifecycle action %d"), def->onCrash);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (xenXMConfigSetString(conf, "on_crash", lifecycle) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-11 21:21:29 +00:00
|
|
|
static int
|
|
|
|
xenFormatXMCharDev(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
if (STREQ(def->os.type, "hvm")) {
|
|
|
|
if (def->nparallels) {
|
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
char *str;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = xenFormatSxprChr(def->parallels[0], &buf);
|
|
|
|
str = virBufferContentAndReset(&buf);
|
|
|
|
if (ret == 0)
|
|
|
|
ret = xenXMConfigSetString(conf, "parallel", str);
|
|
|
|
VIR_FREE(str);
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
if (xenXMConfigSetString(conf, "parallel", "none") < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (def->nserials) {
|
|
|
|
if ((def->nserials == 1) && (def->serials[0]->target.port == 0)) {
|
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
char *str;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = xenFormatSxprChr(def->serials[0], &buf);
|
|
|
|
str = virBufferContentAndReset(&buf);
|
|
|
|
if (ret == 0)
|
|
|
|
ret = xenXMConfigSetString(conf, "serial", str);
|
|
|
|
VIR_FREE(str);
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
size_t j = 0;
|
|
|
|
int maxport = -1, port;
|
|
|
|
virConfValuePtr serialVal = NULL;
|
|
|
|
|
|
|
|
if (VIR_ALLOC(serialVal) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
serialVal->type = VIR_CONF_LIST;
|
|
|
|
serialVal->list = NULL;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
for (j = 0; j < def->nserials; j++) {
|
|
|
|
if (def->serials[j]->target.port == port) {
|
|
|
|
chr = def->serials[j];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xenFormatXMSerial(serialVal, chr) < 0) {
|
|
|
|
VIR_FREE(serialVal);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (serialVal->list != NULL) {
|
|
|
|
int ret = virConfSetValue(conf, "serial", serialVal);
|
|
|
|
|
|
|
|
serialVal = NULL;
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
VIR_FREE(serialVal);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (xenXMConfigSetString(conf, "serial", "none") < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-11 21:21:30 +00:00
|
|
|
static int
|
|
|
|
xenFormatXMDisks(virConfPtr conf, virDomainDefPtr def, int xendConfigVersion)
|
|
|
|
{
|
|
|
|
virConfValuePtr diskVal = NULL;
|
|
|
|
size_t i = 0;
|
|
|
|
int hvm = STREQ(def->os.type, "hvm");
|
|
|
|
|
|
|
|
if (VIR_ALLOC(diskVal) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
diskVal->type = VIR_CONF_LIST;
|
|
|
|
diskVal->list = NULL;
|
|
|
|
|
|
|
|
for (i = 0; i < def->ndisks; i++) {
|
|
|
|
if (xendConfigVersion == XEND_CONFIG_VERSION_3_0_2 &&
|
|
|
|
def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
|
|
|
|
def->disks[i]->dst &&
|
|
|
|
STREQ(def->disks[i]->dst, "hdc")) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (xenFormatXMDisk(diskVal, def->disks[i],
|
|
|
|
hvm, xendConfigVersion) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (diskVal->list != NULL) {
|
|
|
|
int ret = virConfSetValue(conf, "disk", diskVal);
|
|
|
|
diskVal = NULL;
|
|
|
|
if (ret < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
VIR_FREE(diskVal);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virConfFreeValue(diskVal);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-11 21:21:31 +00:00
|
|
|
static int
|
|
|
|
xenFormatXMCPUAllocation(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
int ret = -1;
|
|
|
|
char *cpus = NULL;
|
|
|
|
|
|
|
|
if (xenXMConfigSetInt(conf, "vcpus", def->maxvcpus) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
/* Computing the vcpu_avail bitmask works because MAX_VIRT_CPUS is
|
|
|
|
either 32, or 64 on a platform where long is big enough. */
|
|
|
|
if (def->vcpus < def->maxvcpus &&
|
|
|
|
xenXMConfigSetInt(conf, "vcpu_avail", (1UL << def->vcpus) - 1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if ((def->cpumask != NULL) &&
|
|
|
|
((cpus = virBitmapFormat(def->cpumask)) == NULL)) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cpus &&
|
|
|
|
xenXMConfigSetString(conf, "cpus", cpus) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
VIR_FREE(cpus);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
xenFormatXMCPUFeatures(virConfPtr conf,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
int xendConfigVersion)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
if (STREQ(def->os.type, "hvm")) {
|
|
|
|
if (xenXMConfigSetInt(conf, "pae",
|
|
|
|
(def->features[VIR_DOMAIN_FEATURE_PAE] ==
|
|
|
|
VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (xenXMConfigSetInt(conf, "acpi",
|
|
|
|
(def->features[VIR_DOMAIN_FEATURE_ACPI] ==
|
|
|
|
VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (xenXMConfigSetInt(conf, "apic",
|
|
|
|
(def->features[VIR_DOMAIN_FEATURE_APIC] ==
|
|
|
|
VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (xendConfigVersion >= XEND_CONFIG_VERSION_3_0_4) {
|
|
|
|
if (xenXMConfigSetInt(conf, "hap",
|
|
|
|
(def->features[VIR_DOMAIN_FEATURE_HAP] ==
|
|
|
|
VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (xenXMConfigSetInt(conf, "viridian",
|
|
|
|
(def->features[VIR_DOMAIN_FEATURE_VIRIDIAN] ==
|
|
|
|
VIR_TRISTATE_SWITCH_ON) ? 1 : 0) < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
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 &&
|
|
|
|
xenXMConfigSetInt(conf, "hpet", def->clock.timers[i]->present) < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-11 21:21:32 +00:00
|
|
|
static int
|
|
|
|
xenFormatXMEmulator(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
if (def->emulator &&
|
|
|
|
xenXMConfigSetString(conf, "device_model", def->emulator) < 0)
|
|
|
|
return -1;
|
2011-02-21 13:40:11 +00:00
|
|
|
|
2014-08-11 21:21:32 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
xenFormatXMCDROM(virConfPtr conf,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
int xendConfigVersion)
|
2014-03-18 08:14:16 +00:00
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/{xen,xenapi,xenxs} files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
2011-02-21 13:40:11 +00:00
|
|
|
|
2014-08-11 21:21:32 +00:00
|
|
|
if (STREQ(def->os.type, "hvm")) {
|
|
|
|
if (xendConfigVersion == XEND_CONFIG_VERSION_3_0_2) {
|
|
|
|
for (i = 0; i < def->ndisks; i++) {
|
|
|
|
if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
|
|
|
|
def->disks[i]->dst &&
|
|
|
|
STREQ(def->disks[i]->dst, "hdc") &&
|
|
|
|
virDomainDiskGetSource(def->disks[i])) {
|
|
|
|
if (xenXMConfigSetString(conf, "cdrom",
|
|
|
|
virDomainDiskGetSource(def->disks[i])) < 0)
|
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-02-21 13:40:11 +00:00
|
|
|
|
2014-08-11 21:21:32 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2011-02-21 13:40:11 +00:00
|
|
|
|
|
|
|
|
2014-08-11 21:21:32 +00:00
|
|
|
static int
|
|
|
|
xenFormatXMOS(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
size_t i;
|
2011-02-21 13:40:11 +00:00
|
|
|
|
2014-08-11 21:21:32 +00:00
|
|
|
if (STREQ(def->os.type, "hvm")) {
|
2011-02-21 13:40:11 +00:00
|
|
|
char boot[VIR_DOMAIN_BOOT_LAST+1];
|
|
|
|
if (xenXMConfigSetString(conf, "builder", "hvm") < 0)
|
2014-08-11 21:21:32 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:11 +00:00
|
|
|
|
|
|
|
if (def->os.loader &&
|
|
|
|
xenXMConfigSetString(conf, "kernel", def->os.loader) < 0)
|
2014-08-11 21:21:32 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:11 +00:00
|
|
|
|
2013-05-21 07:21:19 +00:00
|
|
|
for (i = 0; i < def->os.nBootDevs; i++) {
|
2011-02-21 13:40:11 +00:00
|
|
|
switch (def->os.bootDevs[i]) {
|
|
|
|
case VIR_DOMAIN_BOOT_FLOPPY:
|
|
|
|
boot[i] = 'a';
|
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_BOOT_CDROM:
|
|
|
|
boot[i] = 'd';
|
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_BOOT_NET:
|
|
|
|
boot[i] = 'n';
|
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_BOOT_DISK:
|
|
|
|
default:
|
|
|
|
boot[i] = 'c';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-08-11 21:21:32 +00:00
|
|
|
|
2011-02-21 13:40:11 +00:00
|
|
|
if (!def->os.nBootDevs) {
|
|
|
|
boot[0] = 'c';
|
|
|
|
boot[1] = '\0';
|
|
|
|
} else {
|
|
|
|
boot[def->os.nBootDevs] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xenXMConfigSetString(conf, "boot", boot) < 0)
|
2014-08-11 21:21:32 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:11 +00:00
|
|
|
|
|
|
|
/* XXX floppy disks */
|
|
|
|
} else {
|
|
|
|
if (def->os.bootloader &&
|
2014-08-11 21:21:32 +00:00
|
|
|
xenXMConfigSetString(conf, "bootloader", def->os.bootloader) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (def->os.bootloaderArgs &&
|
|
|
|
xenXMConfigSetString(conf, "bootargs", def->os.bootloaderArgs) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (def->os.kernel &&
|
|
|
|
xenXMConfigSetString(conf, "kernel", def->os.kernel) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (def->os.initrd &&
|
|
|
|
xenXMConfigSetString(conf, "ramdisk", def->os.initrd) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (def->os.cmdline &&
|
|
|
|
xenXMConfigSetString(conf, "extra", def->os.cmdline) < 0)
|
|
|
|
return -1;
|
|
|
|
} /* !hvm */
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-11 21:21:33 +00:00
|
|
|
static int
|
|
|
|
xenFormatXMVfb(virConfPtr conf,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
int xendConfigVersion)
|
2014-08-11 21:21:32 +00:00
|
|
|
{
|
|
|
|
int hvm = STREQ(def->os.type, "hvm") ? 1 : 0;
|
2011-02-21 13:40:11 +00:00
|
|
|
|
|
|
|
if (def->ngraphics == 1) {
|
2012-04-05 16:44:35 +00:00
|
|
|
if (hvm || (xendConfigVersion < XEND_CONFIG_MIN_VERS_PVFB_NEWCONF)) {
|
2011-02-21 13:40:11 +00:00
|
|
|
if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
|
|
|
|
if (xenXMConfigSetInt(conf, "sdl", 1) < 0)
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
|
|
|
|
2011-02-21 13:40:11 +00:00
|
|
|
if (xenXMConfigSetInt(conf, "vnc", 0) < 0)
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
|
|
|
|
2011-02-21 13:40:11 +00:00
|
|
|
if (def->graphics[0]->data.sdl.display &&
|
|
|
|
xenXMConfigSetString(conf, "display",
|
|
|
|
def->graphics[0]->data.sdl.display) < 0)
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
|
|
|
|
2011-02-21 13:40:11 +00:00
|
|
|
if (def->graphics[0]->data.sdl.xauth &&
|
|
|
|
xenXMConfigSetString(conf, "xauthority",
|
|
|
|
def->graphics[0]->data.sdl.xauth) < 0)
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:11 +00:00
|
|
|
} else {
|
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
|
|
|
const char *listenAddr;
|
|
|
|
|
2011-02-21 13:40:11 +00:00
|
|
|
if (xenXMConfigSetInt(conf, "sdl", 0) < 0)
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
|
|
|
|
2011-02-21 13:40:11 +00:00
|
|
|
if (xenXMConfigSetInt(conf, "vnc", 1) < 0)
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
|
|
|
|
2011-02-21 13:40:11 +00:00
|
|
|
if (xenXMConfigSetInt(conf, "vncunused",
|
|
|
|
def->graphics[0]->data.vnc.autoport ? 1 : 0) < 0)
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
|
|
|
|
2011-02-21 13:40:11 +00:00
|
|
|
if (!def->graphics[0]->data.vnc.autoport &&
|
|
|
|
xenXMConfigSetInt(conf, "vncdisplay",
|
|
|
|
def->graphics[0]->data.vnc.port - 5900) < 0)
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
|
|
|
|
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
|
|
|
listenAddr = virDomainGraphicsListenGetAddress(def->graphics[0], 0);
|
|
|
|
if (listenAddr &&
|
|
|
|
xenXMConfigSetString(conf, "vnclisten", listenAddr) < 0)
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
|
|
|
|
2011-02-21 13:40:11 +00:00
|
|
|
if (def->graphics[0]->data.vnc.auth.passwd &&
|
|
|
|
xenXMConfigSetString(conf, "vncpasswd",
|
|
|
|
def->graphics[0]->data.vnc.auth.passwd) < 0)
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
|
|
|
|
2011-02-21 13:40:11 +00:00
|
|
|
if (def->graphics[0]->data.vnc.keymap &&
|
|
|
|
xenXMConfigSetString(conf, "keymap",
|
|
|
|
def->graphics[0]->data.vnc.keymap) < 0)
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:11 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
virConfValuePtr vfb, disp;
|
|
|
|
char *vfbstr = NULL;
|
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
2014-08-11 21:21:33 +00:00
|
|
|
|
2011-02-21 13:40:11 +00:00
|
|
|
if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
|
|
|
|
virBufferAddLit(&buf, "type=sdl");
|
|
|
|
if (def->graphics[0]->data.sdl.display)
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(&buf, ",display=%s",
|
2011-02-21 13:40:11 +00:00
|
|
|
def->graphics[0]->data.sdl.display);
|
|
|
|
if (def->graphics[0]->data.sdl.xauth)
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(&buf, ",xauthority=%s",
|
2011-02-21 13:40:11 +00:00
|
|
|
def->graphics[0]->data.sdl.xauth);
|
|
|
|
} else {
|
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
|
|
|
const char *listenAddr
|
|
|
|
= virDomainGraphicsListenGetAddress(def->graphics[0], 0);
|
|
|
|
|
2011-02-21 13:40:11 +00:00
|
|
|
virBufferAddLit(&buf, "type=vnc");
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(&buf, ",vncunused=%d",
|
2011-02-21 13:40:11 +00:00
|
|
|
def->graphics[0]->data.vnc.autoport ? 1 : 0);
|
|
|
|
if (!def->graphics[0]->data.vnc.autoport)
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(&buf, ",vncdisplay=%d",
|
2011-02-21 13:40:11 +00:00
|
|
|
def->graphics[0]->data.vnc.port - 5900);
|
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 (listenAddr)
|
|
|
|
virBufferAsprintf(&buf, ",vnclisten=%s", listenAddr);
|
2011-02-21 13:40:11 +00:00
|
|
|
if (def->graphics[0]->data.vnc.auth.passwd)
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(&buf, ",vncpasswd=%s",
|
2011-02-21 13:40:11 +00:00
|
|
|
def->graphics[0]->data.vnc.auth.passwd);
|
|
|
|
if (def->graphics[0]->data.vnc.keymap)
|
2011-04-30 16:34:49 +00:00
|
|
|
virBufferAsprintf(&buf, ",keymap=%s",
|
2011-02-21 13:40:11 +00:00
|
|
|
def->graphics[0]->data.vnc.keymap);
|
|
|
|
}
|
2014-06-27 08:40:15 +00:00
|
|
|
if (virBufferCheckError(&buf) < 0)
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:11 +00:00
|
|
|
|
|
|
|
vfbstr = virBufferContentAndReset(&buf);
|
|
|
|
|
|
|
|
if (VIR_ALLOC(vfb) < 0) {
|
|
|
|
VIR_FREE(vfbstr);
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (VIR_ALLOC(disp) < 0) {
|
|
|
|
VIR_FREE(vfb);
|
|
|
|
VIR_FREE(vfbstr);
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
vfb->type = VIR_CONF_LIST;
|
|
|
|
vfb->list = disp;
|
|
|
|
disp->type = VIR_CONF_STRING;
|
|
|
|
disp->str = vfbstr;
|
|
|
|
|
|
|
|
if (virConfSetValue(conf, "vfb", vfb) < 0)
|
2014-08-11 21:21:33 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-11 21:21:33 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-11 21:21:34 +00:00
|
|
|
static int
|
|
|
|
xenFormatXMSound(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
if (STREQ(def->os.type, "hvm")) {
|
|
|
|
if (def->sounds) {
|
|
|
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
|
|
|
char *str = NULL;
|
|
|
|
int ret = xenFormatSxprSound(def, &buf);
|
|
|
|
|
|
|
|
str = virBufferContentAndReset(&buf);
|
|
|
|
if (ret == 0)
|
|
|
|
ret = xenXMConfigSetString(conf, "soundhw", str);
|
|
|
|
|
|
|
|
VIR_FREE(str);
|
|
|
|
if (ret < 0)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
xenFormatXMInputDevs(virConfPtr conf, virDomainDefPtr def)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
if (STREQ(def->os.type, "hvm")) {
|
|
|
|
for (i = 0; i < def->ninputs; i++) {
|
|
|
|
if (def->inputs[i]->bus == VIR_DOMAIN_INPUT_BUS_USB) {
|
|
|
|
if (xenXMConfigSetInt(conf, "usb", 1) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
switch (def->inputs[i]->type) {
|
|
|
|
case VIR_DOMAIN_INPUT_TYPE_MOUSE:
|
|
|
|
if (xenXMConfigSetString(conf, "usbdevice", "mouse") < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_INPUT_TYPE_TABLET:
|
|
|
|
if (xenXMConfigSetString(conf, "usbdevice", "tablet") < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
break;
|
|
|
|
case VIR_DOMAIN_INPUT_TYPE_KBD:
|
|
|
|
if (xenXMConfigSetString(conf, "usbdevice", "keyboard") < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-13 20:46:16 +00:00
|
|
|
static int
|
|
|
|
xenFormatXMVif(virConfPtr conf,
|
|
|
|
virConnectPtr conn,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
int xendConfigVersion)
|
|
|
|
{
|
|
|
|
virConfValuePtr netVal = NULL;
|
|
|
|
size_t i;
|
|
|
|
int hvm = STREQ(def->os.type, "hvm");
|
|
|
|
|
|
|
|
if (VIR_ALLOC(netVal) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
netVal->type = VIR_CONF_LIST;
|
|
|
|
netVal->list = NULL;
|
|
|
|
|
|
|
|
for (i = 0; i < def->nnets; i++) {
|
|
|
|
if (xenFormatXMNet(conn, netVal, def->nets[i],
|
|
|
|
hvm, xendConfigVersion) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (netVal->list != NULL) {
|
|
|
|
int ret = virConfSetValue(conf, "vif", netVal);
|
|
|
|
netVal = NULL;
|
|
|
|
if (ret < 0)
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
VIR_FREE(netVal);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
virConfFreeValue(netVal);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-08-11 21:21:35 +00:00
|
|
|
int
|
|
|
|
xenFormatConfigCommon(virConfPtr conf,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
virConnectPtr conn,
|
|
|
|
int xendConfigVersion)
|
2014-08-11 21:21:33 +00:00
|
|
|
{
|
|
|
|
if (xenFormatXMGeneralMeta(conf, def) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;
|
2014-08-11 21:21:33 +00:00
|
|
|
|
|
|
|
if (xenFormatXMMem(conf, def) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;
|
2014-08-11 21:21:33 +00:00
|
|
|
|
|
|
|
if (xenFormatXMCPUAllocation(conf, def) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;
|
2014-08-11 21:21:33 +00:00
|
|
|
|
|
|
|
if (xenFormatXMOS(conf, def) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;
|
2014-08-11 21:21:33 +00:00
|
|
|
|
|
|
|
if (xenFormatXMCPUFeatures(conf, def, xendConfigVersion) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;;
|
2014-08-11 21:21:33 +00:00
|
|
|
|
|
|
|
if (xenFormatXMCDROM(conf, def, xendConfigVersion) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;
|
2014-08-11 21:21:33 +00:00
|
|
|
|
|
|
|
if (xenFormatXMTimeOffset(conf, def, xendConfigVersion) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;
|
2014-08-11 21:21:33 +00:00
|
|
|
|
|
|
|
if (xenFormatXMEventActions(conf, def) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;
|
2014-08-11 21:21:33 +00:00
|
|
|
|
|
|
|
if (xenFormatXMEmulator(conf, def) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;
|
2014-08-11 21:21:33 +00:00
|
|
|
|
2014-08-11 21:21:34 +00:00
|
|
|
if (xenFormatXMInputDevs(conf, def) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;
|
2014-08-11 21:21:33 +00:00
|
|
|
|
|
|
|
if (xenFormatXMVfb(conf, def, xendConfigVersion) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:11 +00:00
|
|
|
|
2014-08-13 20:46:16 +00:00
|
|
|
if (xenFormatXMVif(conf, conn, def, xendConfigVersion) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:11 +00:00
|
|
|
|
2011-02-21 13:40:12 +00:00
|
|
|
if (xenFormatXMPCI(conf, def) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:11 +00:00
|
|
|
|
2014-08-11 21:21:29 +00:00
|
|
|
if (xenFormatXMCharDev(conf, def) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;
|
2011-02-21 13:40:11 +00:00
|
|
|
|
2014-08-11 21:21:34 +00:00
|
|
|
if (xenFormatXMSound(conf, def) < 0)
|
2014-08-11 21:21:35 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
virConfPtr
|
|
|
|
xenFormatXM(virConnectPtr conn,
|
|
|
|
virDomainDefPtr def,
|
|
|
|
int xendConfigVersion)
|
|
|
|
{
|
|
|
|
virConfPtr conf = NULL;
|
|
|
|
|
|
|
|
if (!(conf = virConfNew()))
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (xenFormatConfigCommon(conf, def, conn, xendConfigVersion) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
if (xenFormatXMDisks(conf, def, xendConfigVersion) < 0)
|
2014-08-11 21:21:34 +00:00
|
|
|
goto cleanup;
|
2011-02-21 13:40:11 +00:00
|
|
|
|
|
|
|
return conf;
|
|
|
|
|
2014-03-25 06:57:22 +00:00
|
|
|
cleanup:
|
2011-02-21 13:40:11 +00:00
|
|
|
if (conf)
|
|
|
|
virConfFree(conf);
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2011-02-25 14:41:12 +00:00
|
|
|
}
|