libvirt/src/xen/xm_internal.c

3196 lines
97 KiB
C
Raw Normal View History

2006-11-16 19:06:13 +00:00
/*
* xm_internal.h: helper routines for dealing with inactive domains
*
* Copyright (C) 2006-2007, 2009-2010 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
2006-11-16 19:06:13 +00:00
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Daniel P. Berrange <berrange@redhat.com>
2006-11-16 19:06:13 +00:00
*
*/
#include <config.h>
2006-11-16 19:06:13 +00:00
#include <dirent.h>
#include <time.h>
#include <sys/stat.h>
#include <limits.h>
#include <string.h>
#include <errno.h>
2006-11-16 19:06:13 +00:00
#include <unistd.h>
#include <stdint.h>
#include <xen/dom0_ops.h>
#include "virterror_internal.h"
#include "datatypes.h"
2006-11-16 19:06:13 +00:00
#include "xm_internal.h"
#include "xen_driver.h"
2006-11-16 19:06:13 +00:00
#include "xend_internal.h"
#include "hash.h"
#include "buf.h"
2007-08-09 20:19:12 +00:00
#include "uuid.h"
#include "util.h"
#include "memory.h"
#include "logging.h"
#define VIR_FROM_THIS VIR_FROM_XENXM
2006-11-16 19:06:13 +00:00
#ifdef WITH_RHEL5_API
# define XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU 0
# define XEND_CONFIG_MIN_VERS_PVFB_NEWCONF 2
#else
# define XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU 3
# define XEND_CONFIG_MIN_VERS_PVFB_NEWCONF 3
#endif
/* The true Xen limit varies but so far is always way
less than 1024, which is the Linux kernel limit according
to sched.h, so we'll match that for now */
#define XEN_MAX_PHYSICAL_CPU 1024
static int xenXMConfigSetString(virConfPtr conf, const char *setting,
const char *str);
char * xenXMAutoAssignMac(void);
static int xenXMDomainAttachDeviceFlags(virDomainPtr domain, const char *xml,
unsigned int flags);
static int xenXMDomainDetachDeviceFlags(virDomainPtr domain, const char *xml,
unsigned int flags);
2006-11-16 19:06:13 +00:00
#define XM_REFRESH_INTERVAL 10
#define XM_CONFIG_DIR "/etc/xen"
#define XM_EXAMPLE_PREFIX "xmexample"
#define XEND_CONFIG_FILE "xend-config.sxp"
#define XEND_PCI_CONFIG_PREFIX "xend-pci-"
#define QEMU_IF_SCRIPT "qemu-ifup"
#define XM_XML_ERROR "Invalid xml"
2006-11-16 19:06:13 +00:00
struct xenUnifiedDriver xenXMDriver = {
2006-11-16 19:06:13 +00:00
xenXMOpen, /* open */
xenXMClose, /* close */
NULL, /* version */
NULL, /* hostname */
2006-11-16 19:06:13 +00:00
NULL, /* nodeGetInfo */
NULL, /* getCapabilities */
2006-11-16 19:06:13 +00:00
NULL, /* listDomains */
NULL, /* numOfDomains */
NULL, /* domainCreateXML */
2006-11-16 19:06:13 +00:00
NULL, /* domainSuspend */
NULL, /* domainResume */
NULL, /* domainShutdown */
NULL, /* domainReboot */
NULL, /* domainDestroy */
NULL, /* domainGetOSType */
xenXMDomainGetMaxMemory, /* domainGetMaxMemory */
xenXMDomainSetMaxMemory, /* domainSetMaxMemory */
xenXMDomainSetMemory, /* domainMaxMemory */
xenXMDomainGetInfo, /* domainGetInfo */
NULL, /* domainSave */
NULL, /* domainRestore */
NULL, /* domainCoreDump */
2006-11-16 19:06:13 +00:00
xenXMDomainSetVcpus, /* domainSetVcpus */
xenXMDomainPinVcpu, /* domainPinVcpu */
2006-11-16 19:06:13 +00:00
NULL, /* domainGetVcpus */
NULL, /* domainGetMaxVcpus */
2006-11-16 19:06:13 +00:00
xenXMListDefinedDomains, /* listDefinedDomains */
xenXMNumOfDefinedDomains, /* numOfDefinedDomains */
xenXMDomainCreate, /* domainCreate */
xenXMDomainDefineXML, /* domainDefineXML */
xenXMDomainUndefine, /* domainUndefine */
xenXMDomainAttachDeviceFlags, /* domainAttachDeviceFlags */
xenXMDomainDetachDeviceFlags, /* domainDetachDeviceFlags */
NULL, /* domainUpdateDeviceFlags */
NULL, /* domainGetAutostart */
NULL, /* domainSetAutostart */
NULL, /* domainGetSchedulerType */
NULL, /* domainGetSchedulerParameters */
NULL, /* domainSetSchedulerParameters */
2006-11-16 19:06:13 +00:00
};
#define xenXMError(code, ...) \
virReportErrorHelper(NULL, VIR_FROM_XENXM, code, __FILE__, \
build: consistently use C99 varargs macros Prior to this patch, there was an inconsistent mix between GNU and C99. For consistency, and potential portability to other compilers, stick with the C99 vararg macro syntax. * src/conf/cpu_conf.c (virCPUReportError): Use C99 rather than GNU vararg macro syntax. * src/conf/domain_conf.c (virDomainReportError): Likewise. * src/conf/domain_event.c (eventReportError): Likewise. * src/conf/interface_conf.c (virInterfaceReportError): Likewise. * src/conf/network_conf.c (virNetworkReportError): Likewise. * src/conf/node_device_conf.h (virNodeDeviceReportError): Likewise. * src/conf/secret_conf.h (virSecretReportError): Likewise. * src/conf/storage_conf.h (virStorageReportError): Likewise. * src/esx/esx_device_monitor.c (ESX_ERROR): Use C99 rather than GNU vararg macro syntax. * src/esx/esx_driver.c (ESX_ERROR): Likewise. * src/esx/esx_interface_driver.c (ESX_ERROR): Likewise. * src/esx/esx_network_driver.c (ESX_ERROR): Likewise. * src/esx/esx_secret_driver.c (ESX_ERROR): Likewise. * src/esx/esx_storage_driver.c (ESX_ERROR): Likewise. * src/esx/esx_util.c (ESX_ERROR): Likewise. * src/esx/esx_vi.c (ESX_VI_ERROR): Likewise. * src/esx/esx_vi_methods.c (ESX_VI_ERROR): Likewise. * src/esx/esx_vi_types.c (ESX_VI_ERROR): Likewise. * src/esx/esx_vmx.c (ESX_ERROR): Likewise. * src/util/hostusb.c (usbReportError): Use C99 rather than GNU vararg macro syntax. * src/util/json.c (virJSONError): Likewise. * src/util/macvtap.c (ReportError): Likewise. * src/util/pci.c (pciReportError): Likewise. * src/util/stats_linux.c (virStatsError): Likewise. * src/util/util.c (virUtilError): Likewise. * src/util/xml.c (virXMLError): Likewise. * src/xen/proxy_internal.c (virProxyError): Use C99 rather than GNU vararg macro syntax. * src/xen/sexpr.c (virSexprError): Likewise. * src/xen/xen_driver.c (xenUnifiedError): Likewise. * src/xen/xen_hypervisor.c (virXenError): Likewise. * src/xen/xen_inotify.c (virXenInotifyError): Likewise. * src/xen/xend_internal.c (virXendError): Likewise. * src/xen/xm_internal.c (xenXMError): Likewise. * src/xen/xs_internal.c (virXenStoreError): Likewise. * src/cpu/cpu.h (virCPUReportError): Use C99 rather than GNU vararg macro syntax. * src/datatypes.c (virLibConnError): Likewise. * src/interface/netcf_driver.c (interfaceReportError): Likewise. * src/libvirt.c (virLibStreamError): Likewise. * src/lxc/lxc_conf.h (lxcError): Likewise. * src/network/bridge_driver.c (networkReportError): Likewise. * src/nodeinfo.c (nodeReportError): Likewise. * src/opennebula/one_conf.h (oneError): Likewise. * src/openvz/openvz_conf.h (openvzError): Likewise. * src/phyp/phyp_driver.c (PHYP_ERROR): Likewise. * src/qemu/qemu_conf.h (qemuReportError): Likewise. * src/remote/remote_driver.c (errorf): Likewise. * src/security/security_driver.h (virSecurityReportError): Likewise. * src/test/test_driver.c (testError): Likewise. * src/uml/uml_conf.h (umlReportError): Likewise. * src/vbox/vbox_driver.c (vboxError): Likewise. * src/vbox/vbox_tmpl.c (vboxError): Likewise.
2010-03-01 23:38:28 +00:00
__FUNCTION__, __LINE__, __VA_ARGS__)
2006-11-16 19:06:13 +00:00
#ifndef WITH_XEN_INOTIFY
static int xenInotifyActive(virConnectPtr conn ATTRIBUTE_UNUSED)
{
return 0;
}
#else
static int xenInotifyActive(virConnectPtr conn)
{
xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
return priv->inotifyWatch > 0;
}
#endif
2006-11-16 19:06:13 +00:00
/* Convenience method to grab a int from the config file object */
static int xenXMConfigGetBool(virConfPtr conf,
const char *name,
int *value,
int def) {
2006-11-16 19:06:13 +00:00
virConfValuePtr val;
*value = 0;
2006-11-16 19:06:13 +00:00
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 {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("config value %s was malformed"), name);
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,
int def) {
virConfValuePtr val;
*value = 0;
if (!(val = virConfGetValue(conf, name))) {
*value = def;
return 0;
2006-11-16 19:06:13 +00:00
}
if (val->type == VIR_CONF_LONG) {
*value = val->l;
} else if (val->type == VIR_CONF_STRING) {
char *ret;
*value = strtol(val->str, &ret, 10);
if (ret == val->str) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("config value %s was malformed"), name);
return -1;
}
2006-11-16 19:06:13 +00:00
} else {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("config value %s was malformed"), name);
return -1;
2006-11-16 19:06:13 +00:00
}
return 0;
2006-11-16 19:06:13 +00:00
}
/* Convenience method to grab a string from the config file object */
static int xenXMConfigGetString(virConfPtr conf,
const char *name,
const char **value,
const char *def) {
2006-11-16 19:06:13 +00:00
virConfValuePtr val;
2006-11-16 19:06:13 +00:00
*value = NULL;
if (!(val = virConfGetValue(conf, name))) {
*value = def;
return 0;
}
if (val->type != VIR_CONF_STRING) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("config value %s was malformed"), name);
return -1;
2006-11-16 19:06:13 +00:00
}
if (!val->str)
*value = def;
else
*value = val->str;
return 0;
}
static int xenXMConfigCopyStringInternal(virConfPtr conf,
const char *name,
char **value,
int allowMissing) {
virConfValuePtr val;
*value = NULL;
if (!(val = virConfGetValue(conf, name))) {
if (allowMissing)
return 0;
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("config value %s was missing"), name);
return -1;
}
if (val->type != VIR_CONF_STRING) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("config value %s was not a string"), name);
return -1;
}
if (!val->str) {
if (allowMissing)
return 0;
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("config value %s was missing"), name);
return -1;
}
if (!(*value = strdup(val->str))) {
virReportOOMError();
return -1;
}
return 0;
2006-11-16 19:06:13 +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);
}
2006-11-16 19:06:13 +00:00
/* Convenience method to grab a string UUID from the config file object */
static int xenXMConfigGetUUID(virConfPtr conf, const char *name, unsigned char *uuid) {
virConfValuePtr val;
if (!uuid || !name || !conf)
return (-1);
if (!(val = virConfGetValue(conf, name))) {
return (-1);
}
if (val->type != VIR_CONF_STRING)
return (-1);
if (!val->str)
return (-1);
2007-08-09 20:19:12 +00:00
if (virUUIDParse(val->str, uuid) < 0)
2006-11-16 19:06:13 +00:00
return (-1);
return (0);
}
/* Release memory associated with a cached config object */
static void xenXMConfigFree(void *payload, const char *key ATTRIBUTE_UNUSED) {
xenXMConfCachePtr entry = (xenXMConfCachePtr)payload;
virDomainDefFree(entry->def);
VIR_FREE(entry);
2006-11-16 19:06:13 +00:00
}
struct xenXMConfigReaperData {
xenUnifiedPrivatePtr priv;
time_t now;
};
2006-11-16 19:06:13 +00:00
/* Remove any configs which were not refreshed recently */
static int xenXMConfigReaper(const void *payload, const char *key ATTRIBUTE_UNUSED, const void *data) {
const struct xenXMConfigReaperData *args = data;
xenXMConfCachePtr entry = (xenXMConfCachePtr)payload;
/* We're going to purge this config file, so check if it
is currently mapped as owner of a named domain. */
if (entry->refreshedAt != args->now) {
const char *olddomname = entry->def->name;
char *nameowner = (char *)virHashLookup(args->priv->nameConfigMap, olddomname);
if (nameowner && STREQ(nameowner, key)) {
virHashRemoveEntry(args->priv->nameConfigMap, olddomname, NULL);
}
return (1);
}
return (0);
}
static virDomainDefPtr
xenXMConfigReadFile(virConnectPtr conn, const char *filename) {
virConfPtr conf;
virDomainDefPtr def;
if (!(conf = virConfReadFile(filename, 0)))
return NULL;
def = xenXMDomainConfigParse(conn, conf);
virConfFree(conf);
return def;
}
static int
xenXMConfigSaveFile(virConnectPtr conn, const char *filename, virDomainDefPtr def) {
virConfPtr conf;
int ret;
if (!(conf = xenXMDomainConfigFormat(conn, def)))
return -1;
ret = virConfWriteFile(filename, conf);
virConfFree(conf);
return ret;
}
2009-01-21 18:11:14 +00:00
/*
* Caller must hold the lock on 'conn->privateData' before
* calling this funtion
*/
int
xenXMConfigCacheRemoveFile(virConnectPtr conn,
const char *filename)
{
xenUnifiedPrivatePtr priv = conn->privateData;
xenXMConfCachePtr entry;
entry = virHashLookup(priv->configCache, filename);
if (!entry) {
DEBUG("No config entry for %s", filename);
return 0;
}
virHashRemoveEntry(priv->nameConfigMap, entry->def->name, NULL);
virHashRemoveEntry(priv->configCache, filename, xenXMConfigFree);
DEBUG("Removed %s %s", entry->def->name, filename);
return 0;
}
2009-01-21 18:11:14 +00:00
/*
* Caller must hold the lock on 'conn->privateData' before
* calling this funtion
*/
int
xenXMConfigCacheAddFile(virConnectPtr conn, const char *filename)
{
xenUnifiedPrivatePtr priv = conn->privateData;
xenXMConfCachePtr entry;
struct stat st;
int newborn = 0;
time_t now = time(NULL);
DEBUG("Adding file %s", filename);
/* Get modified time */
if ((stat(filename, &st) < 0)) {
virReportSystemError(errno,
_("cannot stat: %s"),
filename);
return -1;
}
/* Ignore zero length files, because inotify fires before
any content has actually been created */
if (st.st_size == 0) {
DEBUG("Ignoring zero length file %s", filename);
return -1;
}
/* If we already have a matching entry and it is not
modified, then carry on to next one*/
if ((entry = virHashLookup(priv->configCache, filename))) {
char *nameowner;
if (entry->refreshedAt >= st.st_mtime) {
entry->refreshedAt = now;
/* return success if up-to-date */
return 0;
}
/* If we currently own the name, then release it and
re-acquire it later - just in case it was renamed */
nameowner = (char *)virHashLookup(priv->nameConfigMap, entry->def->name);
if (nameowner && STREQ(nameowner, filename)) {
virHashRemoveEntry(priv->nameConfigMap, entry->def->name, NULL);
}
/* Clear existing config entry which needs refresh */
virDomainDefFree(entry->def);
entry->def = NULL;
} else { /* Completely new entry */
newborn = 1;
if (VIR_ALLOC(entry) < 0) {
virReportOOMError();
return -1;
}
memcpy(entry->filename, filename, PATH_MAX);
}
entry->refreshedAt = now;
if (!(entry->def = xenXMConfigReadFile(conn, entry->filename))) {
DEBUG("Failed to read %s", entry->filename);
if (!newborn)
virHashRemoveEntry(priv->configCache, filename, NULL);
VIR_FREE(entry);
return -1;
}
/* If its a completely new entry, it must be stuck into
the cache (refresh'd entries are already registered) */
if (newborn) {
if (virHashAddEntry(priv->configCache, entry->filename, entry) < 0) {
virDomainDefFree(entry->def);
VIR_FREE(entry);
xenXMError(VIR_ERR_INTERNAL_ERROR,
"%s", _("xenXMConfigCacheRefresh: virHashAddEntry"));
return -1;
}
}
/* See if we need to map this config file in as the primary owner
* of the domain in question
*/
if (!virHashLookup(priv->nameConfigMap, entry->def->name)) {
if (virHashAddEntry(priv->nameConfigMap, entry->def->name, entry->filename) < 0) {
virHashRemoveEntry(priv->configCache, filename, NULL);
virDomainDefFree(entry->def);
VIR_FREE(entry);
}
}
DEBUG("Added config %s %s", entry->def->name, filename);
return 0;
}
2006-11-16 19:06:13 +00:00
/* This method is called by various methods to scan /etc/xen
2009-01-21 18:11:14 +00:00
* (or whatever directory was set by LIBVIRT_XM_CONFIG_DIR
* environment variable) and process any domain configs. It
* has rate-limited so never rescans more frequently than
* once every X seconds
*
* Caller must hold the lock on 'conn->privateData' before
* calling this funtion
*/
int xenXMConfigCacheRefresh (virConnectPtr conn) {
xenUnifiedPrivatePtr priv = conn->privateData;
2006-11-16 19:06:13 +00:00
DIR *dh;
struct dirent *ent;
time_t now = time(NULL);
int ret = -1;
struct xenXMConfigReaperData args;
2006-11-16 19:06:13 +00:00
if (now == ((time_t)-1)) {
virReportSystemError(errno,
"%s", _("cannot get time of day"));
2006-11-16 19:06:13 +00:00
return (-1);
}
/* Rate limit re-scans */
if ((now - priv->lastRefresh) < XM_REFRESH_INTERVAL)
2006-11-16 19:06:13 +00:00
return (0);
priv->lastRefresh = now;
2006-11-16 19:06:13 +00:00
/* Process the files in the config dir */
if (!(dh = opendir(priv->configDir))) {
virReportSystemError(errno,
_("cannot read directory %s"),
priv->configDir);
2006-11-16 19:06:13 +00:00
return (-1);
}
while ((ent = readdir(dh))) {
struct stat st;
char path[PATH_MAX];
/*
* Skip a bunch of crufty files that clearly aren't config files
*/
/* Like 'dot' files... */
if (STRPREFIX(ent->d_name, "."))
2006-11-16 19:06:13 +00:00
continue;
/* ...and the XenD server config file */
if (STRPREFIX(ent->d_name, XEND_CONFIG_FILE))
2006-11-16 19:06:13 +00:00
continue;
/* ...and random PCI config cruft */
if (STRPREFIX(ent->d_name, XEND_PCI_CONFIG_PREFIX))
2006-11-16 19:06:13 +00:00
continue;
/* ...and the example domain configs */
if (STRPREFIX(ent->d_name, XM_EXAMPLE_PREFIX))
2006-11-16 19:06:13 +00:00
continue;
/* ...and the QEMU networking script */
if (STRPREFIX(ent->d_name, QEMU_IF_SCRIPT))
2006-11-16 19:06:13 +00:00
continue;
/* ...and editor backups */
if (ent->d_name[0] == '#')
continue;
if (ent->d_name[strlen(ent->d_name)-1] == '~')
continue;
/* Build the full file path */
if ((strlen(priv->configDir) + 1 + strlen(ent->d_name) + 1) > PATH_MAX)
2006-11-16 19:06:13 +00:00
continue;
strcpy(path, priv->configDir);
2006-11-16 19:06:13 +00:00
strcat(path, "/");
strcat(path, ent->d_name);
/* Skip anything which isn't a file (takes care of scripts/ subdir */
if ((stat(path, &st) < 0) ||
(!S_ISREG(st.st_mode))) {
continue;
}
/* If we already have a matching entry and it is not
modified, then carry on to next one*/
if (xenXMConfigCacheAddFile(conn, path) < 0) {
/* Ignoring errors, since alot of stuff goes wrong in /etc/xen */
}
2006-11-16 19:06:13 +00:00
}
/* Reap all entries which were not changed, by comparing
their refresh timestamp - the timestamp should match
'now' if they were refreshed. If timestamp doesn't match
then the config is no longer on disk */
args.now = now;
args.priv = priv;
virHashRemoveSet(priv->configCache, xenXMConfigReaper, xenXMConfigFree, &args);
2006-11-16 19:06:13 +00:00
ret = 0;
closedir(dh);
2006-11-16 19:06:13 +00:00
return (ret);
}
/*
* The XM driver keeps a cache of config files as virDomainDefPtr
* objects in the xenUnifiedPrivatePtr. Optionally inotify lets
* us watch for changes (see separate driver), otherwise we poll
* every few seconds
2006-11-16 19:06:13 +00:00
*/
virDrvOpenStatus
xenXMOpen (virConnectPtr conn,
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
int flags ATTRIBUTE_UNUSED)
{
xenUnifiedPrivatePtr priv = conn->privateData;
priv->configDir = XM_CONFIG_DIR;
priv->configCache = virHashCreate(50);
if (!priv->configCache)
return (-1);
priv->nameConfigMap = virHashCreate(50);
if (!priv->nameConfigMap) {
virHashFree(priv->configCache, NULL);
priv->configCache = NULL;
return (-1);
2006-11-16 19:06:13 +00:00
}
/* Force the cache to be reloaded next time that
* xenXMConfigCacheRefresh is called.
*/
priv->lastRefresh = 0;
2006-11-16 19:06:13 +00:00
return (0);
}
/*
* Free the cached config files associated with this
* connection
2006-11-16 19:06:13 +00:00
*/
int xenXMClose(virConnectPtr conn) {
xenUnifiedPrivatePtr priv = conn->privateData;
virHashFree(priv->nameConfigMap, NULL);
virHashFree(priv->configCache, xenXMConfigFree);
2006-11-16 19:06:13 +00:00
return (0);
}
/*
* Since these are all offline domains, we only return info about
* VCPUs and memory.
2006-11-16 19:06:13 +00:00
*/
int xenXMDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) {
xenUnifiedPrivatePtr priv;
const char *filename;
2006-11-16 19:06:13 +00:00
xenXMConfCachePtr entry;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2006-11-16 19:06:13 +00:00
return(-1);
}
if (domain->id != -1)
2006-11-16 19:06:13 +00:00
return (-1);
priv = domain->conn->privateData;
2009-01-21 18:11:14 +00:00
xenUnifiedLock(priv);
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
2009-01-21 18:11:14 +00:00
goto error;
if (!(entry = virHashLookup(priv->configCache, filename)))
2009-01-21 18:11:14 +00:00
goto error;
2006-11-16 19:06:13 +00:00
memset(info, 0, sizeof(virDomainInfo));
info->maxMem = entry->def->maxmem;
info->memory = entry->def->memory;
info->nrVirtCpu = entry->def->vcpus;
2006-11-16 19:06:13 +00:00
info->state = VIR_DOMAIN_SHUTOFF;
info->cpuTime = 0;
2009-01-21 18:11:14 +00:00
xenUnifiedUnlock(priv);
2006-11-16 19:06:13 +00:00
return (0);
2009-01-21 18:11:14 +00:00
error:
xenUnifiedUnlock(priv);
return -1;
2006-11-16 19:06:13 +00:00
}
#define MAX_VFB 1024
2006-11-16 19:06:13 +00:00
/*
* Turn a config record into a lump of XML describing the
* domain, suitable for later feeding for virDomainCreateXML
2006-11-16 19:06:13 +00:00
*/
virDomainDefPtr
xenXMDomainConfigParse(virConnectPtr conn, virConfPtr conf) {
2006-11-16 19:06:13 +00:00
const char *str;
int hvm = 0;
int val;
2006-11-16 19:06:13 +00:00
virConfValuePtr list;
xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
virDomainDefPtr def = NULL;
virDomainDiskDefPtr disk = NULL;
virDomainNetDefPtr net = NULL;
virDomainGraphicsDefPtr graphics = NULL;
2009-04-03 12:38:52 +00:00
virDomainHostdevDefPtr hostdev = NULL;
int i;
const char *defaultArch, *defaultMachine;
int vmlocaltime = 0;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
return NULL;
}
def->virtType = VIR_DOMAIN_VIRT_XEN;
def->id = -1;
2006-11-16 19:06:13 +00:00
if (xenXMConfigCopyString(conf, "name", &def->name) < 0)
goto cleanup;
if (xenXMConfigGetUUID(conf, "uuid", def->uuid) < 0)
goto cleanup;
2006-11-16 19:06:13 +00:00
if ((xenXMConfigGetString(conf, "builder", &str, "linux") == 0) &&
STREQ(str, "hvm"))
2006-11-16 19:06:13 +00:00
hvm = 1;
if (!(def->os.type = strdup(hvm ? "hvm" : "xen")))
goto no_memory;
defaultArch = virCapabilitiesDefaultGuestArch(priv->caps, def->os.type, virDomainVirtTypeToString(def->virtType));
if (defaultArch == NULL) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("no supported architecture for os type '%s'"),
def->os.type);
goto cleanup;
}
if (!(def->os.arch = strdup(defaultArch)))
goto no_memory;
defaultMachine = virCapabilitiesDefaultGuestMachine(priv->caps,
def->os.type,
def->os.arch,
virDomainVirtTypeToString(def->virtType));
if (defaultMachine != NULL) {
if (!(def->os.machine = strdup(defaultMachine)))
goto no_memory;
}
2006-11-16 19:06:13 +00:00
if (hvm) {
const char *boot;
if (xenXMConfigCopyString(conf, "kernel", &def->os.loader) < 0)
goto cleanup;
if (xenXMConfigGetString(conf, "boot", &boot, "c") < 0)
goto cleanup;
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++;
}
2006-11-16 19:06:13 +00:00
} else {
if (xenXMConfigCopyStringOpt(conf, "bootloader", &def->os.bootloader) < 0)
goto cleanup;
if (xenXMConfigCopyStringOpt(conf, "bootargs", &def->os.bootloaderArgs) < 0)
goto cleanup;
if (xenXMConfigCopyStringOpt(conf, "kernel", &def->os.kernel) < 0)
goto cleanup;
if (xenXMConfigCopyStringOpt(conf, "ramdisk", &def->os.initrd) < 0)
goto cleanup;
if (xenXMConfigCopyStringOpt(conf, "extra", &def->os.cmdline) < 0)
goto cleanup;
2006-11-16 19:06:13 +00:00
}
if (xenXMConfigGetULong(conf, "memory", &def->memory, MIN_XEN_GUEST_SIZE * 2) < 0)
goto cleanup;
2006-11-16 19:06:13 +00:00
if (xenXMConfigGetULong(conf, "maxmem", &def->maxmem, def->memory) < 0)
goto cleanup;
2006-11-16 19:06:13 +00:00
def->memory *= 1024;
def->maxmem *= 1024;
2006-11-16 19:06:13 +00:00
if (xenXMConfigGetULong(conf, "vcpus", &def->vcpus, 1) < 0)
goto cleanup;
2006-11-16 19:06:13 +00:00
if (xenXMConfigGetString(conf, "cpus", &str, NULL) < 0)
goto cleanup;
if (str) {
def->cpumasklen = 4096;
if (VIR_ALLOC_N(def->cpumask, def->cpumasklen) < 0)
goto no_memory;
if (virDomainCpuSetParse(&str, 0,
def->cpumask, def->cpumasklen) < 0)
goto cleanup;
}
if (xenXMConfigGetString(conf, "on_poweroff", &str, "destroy") < 0)
goto cleanup;
if ((def->onPoweroff = virDomainLifecycleTypeFromString(str)) < 0) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("unexpected value %s for on_poweroff"), str);
goto cleanup;
}
if (xenXMConfigGetString(conf, "on_reboot", &str, "restart") < 0)
goto cleanup;
if ((def->onReboot = virDomainLifecycleTypeFromString(str)) < 0) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("unexpected value %s for on_reboot"), str);
goto cleanup;
}
if (xenXMConfigGetString(conf, "on_crash", &str, "restart") < 0)
goto cleanup;
if ((def->onCrash = virDomainLifecycleCrashTypeFromString(str)) < 0) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("unexpected value %s for on_crash"), str);
goto cleanup;
2006-11-16 19:06:13 +00:00
}
2006-11-16 19:06:13 +00:00
if (hvm) {
if (xenXMConfigGetBool(conf, "pae", &val, 0) < 0)
goto cleanup;
else if (val)
def->features |= (1 << VIR_DOMAIN_FEATURE_PAE);
if (xenXMConfigGetBool(conf, "acpi", &val, 0) < 0)
goto cleanup;
else if (val)
def->features |= (1 << VIR_DOMAIN_FEATURE_ACPI);
if (xenXMConfigGetBool(conf, "apic", &val, 0) < 0)
goto cleanup;
else if (val)
def->features |= (1 << VIR_DOMAIN_FEATURE_APIC);
}
if (xenXMConfigGetBool(conf, "localtime", &vmlocaltime, 0) < 0)
2009-04-01 10:36:52 +00:00
goto cleanup;
def->clock.offset = vmlocaltime ?
VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME :
VIR_DOMAIN_CLOCK_OFFSET_UTC;
if (xenXMConfigCopyStringOpt(conf, "device_model", &def->emulator) < 0)
goto cleanup;
list = virConfGetValue(conf, "disk");
if (list && list->type == VIR_CONF_LIST) {
list = list->list;
while (list) {
char *head;
char *offset;
char *tmp;
if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
goto skipdisk;
head = list->str;
if (VIR_ALLOC(disk) < 0)
goto no_memory;
/*
* 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, ',')))
2006-11-16 19:06:13 +00:00
goto skipdisk;
if ((offset - head) >= (PATH_MAX-1))
goto skipdisk;
if (offset == head) {
disk->src = NULL; /* No source file given, eg CDROM with no media */
} else {
if (VIR_ALLOC_N(disk->src, (offset - head) + 1) < 0)
goto no_memory;
if (virStrncpy(disk->src, head, offset - head,
(offset - head) + 1) == NULL) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("Source file %s too big for destination"),
head);
goto cleanup;
}
}
head = offset + 1;
2006-11-16 19:06:13 +00:00
/* Remove legacy ioemu: junk */
if (STRPREFIX(head, "ioemu:"))
head = head + 6;
/* Extract the dest device name */
if (!(offset = strchr(head, ',')))
goto skipdisk;
if (VIR_ALLOC_N(disk->dst, (offset - head) + 1) < 0)
goto no_memory;
if (virStrncpy(disk->dst, head, offset - head,
(offset - head) + 1) == NULL) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("Dest file %s too big for destination"), head);
goto cleanup;
}
head = offset + 1;
2006-11-16 19:06:13 +00:00
/* Extract source driver type */
if (disk->src) {
/* The main type phy:, file:, tap: ... */
if ((tmp = strchr(disk->src, ':')) != NULL) {
if (VIR_ALLOC_N(disk->driverName, (tmp - disk->src) + 1) < 0)
goto no_memory;
if (virStrncpy(disk->driverName, disk->src,
(tmp - disk->src),
(tmp - disk->src) + 1) == NULL) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("Driver name %s too big for destination"),
disk->src);
goto cleanup;
}
/* Strip the prefix we found off the source file name */
memmove(disk->src, disk->src+(tmp-disk->src)+1,
strlen(disk->src)-(tmp-disk->src));
}
/* And the sub-type for tap:XXX: type */
if (disk->driverName &&
STREQ(disk->driverName, "tap")) {
if (!(tmp = strchr(disk->src, ':')))
goto skipdisk;
if (VIR_ALLOC_N(disk->driverType, (tmp - disk->src) + 1) < 0)
goto no_memory;
if (virStrncpy(disk->driverType, disk->src,
(tmp - disk->src),
(tmp - disk->src) + 1) == NULL) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("Driver type %s too big for destination"),
disk->src);
goto cleanup;
}
/* Strip the prefix we found off the source file name */
memmove(disk->src, disk->src+(tmp-disk->src)+1,
strlen(disk->src)-(tmp-disk->src));
}
}
/* No source, or driver name, so fix to phy: */
if (!disk->driverName &&
!(disk->driverName = strdup("phy")))
goto no_memory;
2006-11-16 19:06:13 +00:00
/* phy: type indicates a block device */
disk->type = STREQ(disk->driverName, "phy") ?
VIR_DOMAIN_DISK_TYPE_BLOCK : VIR_DOMAIN_DISK_TYPE_FILE;
/* 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';
}
2006-11-16 19:06:13 +00:00
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"))
disk->readonly = 1;
else if ((STREQ(head, "w!")) ||
(STREQ(head, "!")))
disk->shared = 1;
/* Maintain list in sorted order according to target device name */
if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0)
goto no_memory;
def->disks[def->ndisks++] = disk;
disk = NULL;
skipdisk:
list = list->next;
virDomainDiskDefFree(disk);
}
2006-11-16 19:06:13 +00:00
}
if (hvm && priv->xendConfigVersion == 1) {
if (xenXMConfigGetString(conf, "cdrom", &str, NULL) < 0)
goto cleanup;
if (str) {
if (VIR_ALLOC(disk) < 0)
goto no_memory;
disk->type = VIR_DOMAIN_DISK_TYPE_FILE;
disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
if (!(disk->driverName = strdup("file")))
goto no_memory;
if (!(disk->src = strdup(str)))
goto no_memory;
if (!(disk->dst = strdup("hdc")))
goto no_memory;
disk->bus = VIR_DOMAIN_DISK_BUS_IDE;
disk->readonly = 1;
if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0)
goto no_memory;
def->disks[def->ndisks++] = disk;
disk = NULL;
}
}
2006-11-16 19:06:13 +00:00
list = virConfGetValue(conf, "vif");
if (list && list->type == VIR_CONF_LIST) {
list = list->list;
while (list) {
char script[PATH_MAX];
char model[10];
Support for interface model='netfront' Xen HVM guests with PV drivers end up with two network interfaces for each configured interface. One of them being emulated by qemu and the other one paravirtual. As this might not be desirable, the attached patch provides a way for users to specify that only paravirtual network interface should be presented to the guest. The configuration was inspired by qemu/kvm driver, for which users can specify model='virtio' to use paravirtual network interface. The patch adds support for model='netfront' which results in type=netfront instead of type=ioemu (or nothing for newer xen versions) in guests native configuration. Xen's qemu ignores interfaces with type != ioemu and only paravirtual network device will be seen in the guest. Four possible configuration scenarios follow: - no model specified in domain's XML - libvirt will behave like before this change; it will set type=ioemu for HVM guests on xen host which is not newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU - covered by existing tests - PV guest, any model - no functional change, model is passed as is (and ignored by the hypervisor) - covered by existing tests (e.g., *-net-e1000.*) - HVM guest, model=netfront - type is set to "netfront", model is not specified - covered by new *-net-netfront.* tests - HVM guest, model != netfront - type is set to "ioemu", model is passed as is - covered by new *-net-ioemu.* tests The fourth scenario feels like a regression for xen newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU as users who had a model specified in their guest's configuration won't see a paravirtual interface in their guests any more. On the other hand, the reason for specifying a model is most likely the fact that they want to use such model which implies emulated interface. Users of older xen won't be affected at all as their xen provides paravirtual interface regardless of the type used. - src/xen/xend_internal.c: add netfront support for the xend backend - src/xen/xm_internal.c: add netfront support for the XM serialization too
2009-12-04 15:55:59 +00:00
char type[10];
char ip[16];
char mac[18];
2007-06-07 18:21:58 +00:00
char bridge[50];
char vifname[50];
char *key;
2007-06-07 18:21:58 +00:00
bridge[0] = '\0';
mac[0] = '\0';
script[0] = '\0';
ip[0] = '\0';
model[0] = '\0';
Support for interface model='netfront' Xen HVM guests with PV drivers end up with two network interfaces for each configured interface. One of them being emulated by qemu and the other one paravirtual. As this might not be desirable, the attached patch provides a way for users to specify that only paravirtual network interface should be presented to the guest. The configuration was inspired by qemu/kvm driver, for which users can specify model='virtio' to use paravirtual network interface. The patch adds support for model='netfront' which results in type=netfront instead of type=ioemu (or nothing for newer xen versions) in guests native configuration. Xen's qemu ignores interfaces with type != ioemu and only paravirtual network device will be seen in the guest. Four possible configuration scenarios follow: - no model specified in domain's XML - libvirt will behave like before this change; it will set type=ioemu for HVM guests on xen host which is not newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU - covered by existing tests - PV guest, any model - no functional change, model is passed as is (and ignored by the hypervisor) - covered by existing tests (e.g., *-net-e1000.*) - HVM guest, model=netfront - type is set to "netfront", model is not specified - covered by new *-net-netfront.* tests - HVM guest, model != netfront - type is set to "ioemu", model is passed as is - covered by new *-net-ioemu.* tests The fourth scenario feels like a regression for xen newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU as users who had a model specified in their guest's configuration won't see a paravirtual interface in their guests any more. On the other hand, the reason for specifying a model is most likely the fact that they want to use such model which implies emulated interface. Users of older xen won't be affected at all as their xen provides paravirtual interface regardless of the type used. - src/xen/xend_internal.c: add netfront support for the xend backend - src/xen/xm_internal.c: add netfront support for the XM serialization too
2009-12-04 15:55:59 +00:00
type[0] = '\0';
vifname[0] = '\0';
if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
goto skipnic;
2006-11-16 19:06:13 +00:00
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) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("MAC address %s too big for destination"),
data);
goto skipnic;
}
} else if (STRPREFIX(key, "bridge=")) {
int len = nextkey ? (nextkey - data) : sizeof(bridge) - 1;
if (virStrncpy(bridge, data, len, sizeof(bridge)) == NULL) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("Bridge %s too big for destination"),
data);
goto skipnic;
}
} else if (STRPREFIX(key, "script=")) {
int len = nextkey ? (nextkey - data) : sizeof(script) - 1;
if (virStrncpy(script, data, len, sizeof(script)) == NULL) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("Script %s too big for destination"),
data);
goto skipnic;
}
} else if (STRPREFIX(key, "model=")) {
int len = nextkey ? (nextkey - data) : sizeof(model) - 1;
if (virStrncpy(model, data, len, sizeof(model)) == NULL) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("Model %s too big for destination"), data);
goto skipnic;
}
Support for interface model='netfront' Xen HVM guests with PV drivers end up with two network interfaces for each configured interface. One of them being emulated by qemu and the other one paravirtual. As this might not be desirable, the attached patch provides a way for users to specify that only paravirtual network interface should be presented to the guest. The configuration was inspired by qemu/kvm driver, for which users can specify model='virtio' to use paravirtual network interface. The patch adds support for model='netfront' which results in type=netfront instead of type=ioemu (or nothing for newer xen versions) in guests native configuration. Xen's qemu ignores interfaces with type != ioemu and only paravirtual network device will be seen in the guest. Four possible configuration scenarios follow: - no model specified in domain's XML - libvirt will behave like before this change; it will set type=ioemu for HVM guests on xen host which is not newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU - covered by existing tests - PV guest, any model - no functional change, model is passed as is (and ignored by the hypervisor) - covered by existing tests (e.g., *-net-e1000.*) - HVM guest, model=netfront - type is set to "netfront", model is not specified - covered by new *-net-netfront.* tests - HVM guest, model != netfront - type is set to "ioemu", model is passed as is - covered by new *-net-ioemu.* tests The fourth scenario feels like a regression for xen newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU as users who had a model specified in their guest's configuration won't see a paravirtual interface in their guests any more. On the other hand, the reason for specifying a model is most likely the fact that they want to use such model which implies emulated interface. Users of older xen won't be affected at all as their xen provides paravirtual interface regardless of the type used. - src/xen/xend_internal.c: add netfront support for the xend backend - src/xen/xm_internal.c: add netfront support for the XM serialization too
2009-12-04 15:55:59 +00:00
} else if (STRPREFIX(key, "type=")) {
int len = nextkey ? (nextkey - data) : sizeof(type) - 1;
if (virStrncpy(type, data, len, sizeof(type)) == NULL) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
Support for interface model='netfront' Xen HVM guests with PV drivers end up with two network interfaces for each configured interface. One of them being emulated by qemu and the other one paravirtual. As this might not be desirable, the attached patch provides a way for users to specify that only paravirtual network interface should be presented to the guest. The configuration was inspired by qemu/kvm driver, for which users can specify model='virtio' to use paravirtual network interface. The patch adds support for model='netfront' which results in type=netfront instead of type=ioemu (or nothing for newer xen versions) in guests native configuration. Xen's qemu ignores interfaces with type != ioemu and only paravirtual network device will be seen in the guest. Four possible configuration scenarios follow: - no model specified in domain's XML - libvirt will behave like before this change; it will set type=ioemu for HVM guests on xen host which is not newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU - covered by existing tests - PV guest, any model - no functional change, model is passed as is (and ignored by the hypervisor) - covered by existing tests (e.g., *-net-e1000.*) - HVM guest, model=netfront - type is set to "netfront", model is not specified - covered by new *-net-netfront.* tests - HVM guest, model != netfront - type is set to "ioemu", model is passed as is - covered by new *-net-ioemu.* tests The fourth scenario feels like a regression for xen newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU as users who had a model specified in their guest's configuration won't see a paravirtual interface in their guests any more. On the other hand, the reason for specifying a model is most likely the fact that they want to use such model which implies emulated interface. Users of older xen won't be affected at all as their xen provides paravirtual interface regardless of the type used. - src/xen/xend_internal.c: add netfront support for the xend backend - src/xen/xm_internal.c: add netfront support for the XM serialization too
2009-12-04 15:55:59 +00:00
_("Type %s too big for destination"), data);
goto skipnic;
}
} else if (STRPREFIX(key, "vifname=")) {
int len = nextkey ? (nextkey - data) : sizeof(vifname) - 1;
if (virStrncpy(vifname, data, len, sizeof(vifname)) == NULL) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("Vifname %s too big for destination"),
data);
goto skipnic;
}
} else if (STRPREFIX(key, "ip=")) {
int len = nextkey ? (nextkey - data) : sizeof(ip) - 1;
if (virStrncpy(ip, data, len, sizeof(ip)) == NULL) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("IP %s too big for destination"), data);
goto skipnic;
}
}
2006-11-16 19:06:13 +00:00
while (nextkey && (nextkey[0] == ',' ||
nextkey[0] == ' ' ||
nextkey[0] == '\t'))
nextkey++;
key = nextkey;
}
2006-11-16 19:06:13 +00:00
if (VIR_ALLOC(net) < 0)
goto no_memory;
if (mac[0]) {
if (virParseMacAddr(mac, net->mac) < 0) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("malformed mac address '%s'"), mac);
goto cleanup;
}
}
if (bridge[0] || STREQ(script, "vif-bridge") ||
STREQ(script, "vif-vnic")) {
net->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
} else {
net->type = VIR_DOMAIN_NET_TYPE_ETHERNET;
}
if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
if (bridge[0] &&
!(net->data.bridge.brname = strdup(bridge)))
goto no_memory;
if (script[0] &&
!(net->data.bridge.script = strdup(script)))
goto no_memory;
2009-01-23 01:48:47 +00:00
if (ip[0] &&
!(net->data.bridge.ipaddr = strdup(ip)))
goto no_memory;
} else {
if (script[0] &&
!(net->data.ethernet.script = strdup(script)))
goto no_memory;
if (ip[0] &&
!(net->data.ethernet.ipaddr = strdup(ip)))
goto no_memory;
}
Support for interface model='netfront' Xen HVM guests with PV drivers end up with two network interfaces for each configured interface. One of them being emulated by qemu and the other one paravirtual. As this might not be desirable, the attached patch provides a way for users to specify that only paravirtual network interface should be presented to the guest. The configuration was inspired by qemu/kvm driver, for which users can specify model='virtio' to use paravirtual network interface. The patch adds support for model='netfront' which results in type=netfront instead of type=ioemu (or nothing for newer xen versions) in guests native configuration. Xen's qemu ignores interfaces with type != ioemu and only paravirtual network device will be seen in the guest. Four possible configuration scenarios follow: - no model specified in domain's XML - libvirt will behave like before this change; it will set type=ioemu for HVM guests on xen host which is not newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU - covered by existing tests - PV guest, any model - no functional change, model is passed as is (and ignored by the hypervisor) - covered by existing tests (e.g., *-net-e1000.*) - HVM guest, model=netfront - type is set to "netfront", model is not specified - covered by new *-net-netfront.* tests - HVM guest, model != netfront - type is set to "ioemu", model is passed as is - covered by new *-net-ioemu.* tests The fourth scenario feels like a regression for xen newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU as users who had a model specified in their guest's configuration won't see a paravirtual interface in their guests any more. On the other hand, the reason for specifying a model is most likely the fact that they want to use such model which implies emulated interface. Users of older xen won't be affected at all as their xen provides paravirtual interface regardless of the type used. - src/xen/xend_internal.c: add netfront support for the xend backend - src/xen/xm_internal.c: add netfront support for the XM serialization too
2009-12-04 15:55:59 +00:00
if (model[0] &&
!(net->model = strdup(model)))
goto no_memory;
Support for interface model='netfront' Xen HVM guests with PV drivers end up with two network interfaces for each configured interface. One of them being emulated by qemu and the other one paravirtual. As this might not be desirable, the attached patch provides a way for users to specify that only paravirtual network interface should be presented to the guest. The configuration was inspired by qemu/kvm driver, for which users can specify model='virtio' to use paravirtual network interface. The patch adds support for model='netfront' which results in type=netfront instead of type=ioemu (or nothing for newer xen versions) in guests native configuration. Xen's qemu ignores interfaces with type != ioemu and only paravirtual network device will be seen in the guest. Four possible configuration scenarios follow: - no model specified in domain's XML - libvirt will behave like before this change; it will set type=ioemu for HVM guests on xen host which is not newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU - covered by existing tests - PV guest, any model - no functional change, model is passed as is (and ignored by the hypervisor) - covered by existing tests (e.g., *-net-e1000.*) - HVM guest, model=netfront - type is set to "netfront", model is not specified - covered by new *-net-netfront.* tests - HVM guest, model != netfront - type is set to "ioemu", model is passed as is - covered by new *-net-ioemu.* tests The fourth scenario feels like a regression for xen newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU as users who had a model specified in their guest's configuration won't see a paravirtual interface in their guests any more. On the other hand, the reason for specifying a model is most likely the fact that they want to use such model which implies emulated interface. Users of older xen won't be affected at all as their xen provides paravirtual interface regardless of the type used. - src/xen/xend_internal.c: add netfront support for the xend backend - src/xen/xm_internal.c: add netfront support for the XM serialization too
2009-12-04 15:55:59 +00:00
if (!model[0] && type[0] &&
STREQ(type, "netfront") &&
!(net->model = strdup("netfront")))
goto no_memory;
if (vifname[0] &&
!(net->ifname = strdup(vifname)))
goto no_memory;
if (VIR_REALLOC_N(def->nets, def->nnets+1) < 0)
goto no_memory;
def->nets[def->nnets++] = net;
net = NULL;
skipnic:
list = list->next;
virDomainNetDefFree(net);
}
}
2009-04-03 12:38:52 +00:00
list = virConfGetValue(conf, "pci");
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) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("Domain %s too big for destination"), key);
2009-04-03 12:38:52 +00:00
goto skippci;
}
2009-04-03 12:38:52 +00:00
key = nextkey + 1;
if (!(nextkey = strchr(key, ':')))
goto skippci;
if (virStrncpy(bus, key, (nextkey - key), sizeof(bus)) == NULL) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("Bus %s too big for destination"), key);
goto skippci;
}
2009-04-03 12:38:52 +00:00
key = nextkey + 1;
if (!(nextkey = strchr(key, '.')))
goto skippci;
if (virStrncpy(slot, key, (nextkey - key), sizeof(slot)) == NULL) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("Slot %s too big for destination"), key);
goto skippci;
}
2009-04-03 12:38:52 +00:00
key = nextkey + 1;
if (strlen(key) != 1)
goto skippci;
if (virStrncpy(func, key, 1, sizeof(func)) == NULL) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("Function %s too big for destination"), key);
goto skippci;
}
2009-04-03 12:38:52 +00:00
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 (VIR_ALLOC(hostdev) < 0)
goto no_memory;
2009-04-03 12:38:52 +00:00
hostdev->managed = 0;
hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
hostdev->source.subsys.u.pci.domain = domainID;
hostdev->source.subsys.u.pci.bus = busID;
hostdev->source.subsys.u.pci.slot = slotID;
hostdev->source.subsys.u.pci.function = funcID;
if (VIR_REALLOC_N(def->hostdevs, def->nhostdevs+1) < 0)
goto no_memory;
def->hostdevs[def->nhostdevs++] = hostdev;
hostdev = NULL;
skippci:
list = list->next;
}
}
2007-07-18 21:08:22 +00:00
if (hvm) {
if (xenXMConfigGetString(conf, "usbdevice", &str, NULL) < 0)
goto cleanup;
if (str &&
(STREQ(str, "tablet") ||
STREQ(str, "mouse"))) {
virDomainInputDefPtr input;
if (VIR_ALLOC(input) < 0)
goto no_memory;
input->bus = VIR_DOMAIN_INPUT_BUS_USB;
input->type = STREQ(str, "tablet") ?
VIR_DOMAIN_INPUT_TYPE_TABLET :
VIR_DOMAIN_INPUT_TYPE_MOUSE;
if (VIR_ALLOC_N(def->inputs, 1) < 0) {
virDomainInputDefFree(input);
goto no_memory;
}
def->inputs[0] = input;
def->ninputs = 1;
2007-07-18 21:08:22 +00:00
}
}
/* HVM guests, or old PV guests use this config format */
if (hvm || priv->xendConfigVersion < 3) {
if (xenXMConfigGetBool(conf, "vnc", &val, 0) < 0)
goto cleanup;
if (val) {
if (VIR_ALLOC(graphics) < 0)
goto no_memory;
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", &graphics->data.vnc.listenAddr) < 0)
goto cleanup;
if (xenXMConfigCopyStringOpt(conf, "vncpasswd", &graphics->data.vnc.passwd) < 0)
goto cleanup;
if (xenXMConfigCopyStringOpt(conf, "keymap", &graphics->data.vnc.keymap) < 0)
goto cleanup;
if (VIR_ALLOC_N(def->graphics, 1) < 0)
goto no_memory;
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 no_memory;
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 no_memory;
def->graphics[0] = graphics;
def->ngraphics = 1;
graphics = NULL;
}
2006-11-16 19:06:13 +00:00
}
}
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) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("VFB %s too big for destination"),
list->list->str);
goto cleanup;
}
if (VIR_ALLOC(graphics) < 0)
goto no_memory;
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 = 1;
} else if (STRPREFIX(key, "vnclisten=")) {
if (!(graphics->data.vnc.listenAddr = strdup(key + 10)))
goto no_memory;
} else if (STRPREFIX(key, "vncpasswd=")) {
if (!(graphics->data.vnc.passwd = strdup(key + 10)))
goto no_memory;
} else if (STRPREFIX(key, "keymap=")) {
if (!(graphics->data.vnc.keymap = strdup(key + 7)))
goto no_memory;
} else if (STRPREFIX(key, "vncdisplay=")) {
graphics->data.vnc.port = strtol(key+11, NULL, 10) + 5900;
}
} else {
if (STRPREFIX(key, "display=")) {
if (!(graphics->data.sdl.display = strdup(key + 8)))
goto no_memory;
} else if (STRPREFIX(key, "xauthority=")) {
if (!(graphics->data.sdl.xauth = strdup(key + 11)))
goto no_memory;
}
}
2006-11-16 19:06:13 +00:00
while (nextkey && (nextkey[0] == ',' ||
nextkey[0] == ' ' ||
nextkey[0] == '\t'))
nextkey++;
key = nextkey;
}
if (VIR_ALLOC_N(def->graphics, 1) < 0)
goto no_memory;
def->graphics[0] = graphics;
def->ngraphics = 1;
graphics = NULL;
2006-11-16 19:06:13 +00:00
}
}
2006-11-16 19:06:13 +00:00
if (hvm) {
virDomainChrDefPtr chr = NULL;
if (xenXMConfigGetString(conf, "parallel", &str, NULL) < 0)
goto cleanup;
if (str && STRNEQ(str, "none") &&
!(chr = xenDaemonParseSxprChar(str, NULL)))
goto cleanup;
if (chr) {
if (VIR_ALLOC_N(def->parallels, 1) < 0) {
virDomainChrDefFree(chr);
goto no_memory;
}
chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL;
def->parallels[0] = chr;
def->nparallels++;
chr = NULL;
}
if (xenXMConfigGetString(conf, "serial", &str, NULL) < 0)
goto cleanup;
if (str && STRNEQ(str, "none") &&
!(chr = xenDaemonParseSxprChar(str, NULL)))
goto cleanup;
if (chr) {
if (VIR_ALLOC_N(def->serials, 1) < 0) {
virDomainChrDefFree(chr);
goto no_memory;
}
chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
def->serials[0] = chr;
def->nserials++;
}
} else {
if (!(def->console = xenDaemonParseSxprChar("pty", NULL)))
goto cleanup;
def->console->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE;
def->console->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN;
}
if (hvm) {
if (xenXMConfigGetString(conf, "soundhw", &str, NULL) < 0)
goto cleanup;
2006-11-16 19:06:13 +00:00
if (str &&
xenDaemonParseSxprSound(def, str) < 0)
goto cleanup;
}
return def;
no_memory:
virReportOOMError();
/* fallthrough */
cleanup:
virDomainGraphicsDefFree(graphics);
virDomainNetDefFree(net);
virDomainDiskDefFree(disk);
virDomainDefFree(def);
return NULL;
2006-11-16 19:06:13 +00:00
}
/*
* Turn a config record into a lump of XML describing the
* domain, suitable for later feeding for virDomainCreateXML
*/
char *xenXMDomainDumpXML(virDomainPtr domain, int flags) {
xenUnifiedPrivatePtr priv;
const char *filename;
xenXMConfCachePtr entry;
2009-01-21 18:11:14 +00:00
char *ret = NULL;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return(NULL);
}
if (domain->id != -1)
return (NULL);
priv = domain->conn->privateData;
2009-01-21 18:11:14 +00:00
xenUnifiedLock(priv);
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
2009-01-21 18:11:14 +00:00
goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename)))
2009-01-21 18:11:14 +00:00
goto cleanup;
ret = virDomainDefFormat(entry->def, flags);
2009-01-21 18:11:14 +00:00
cleanup:
xenUnifiedUnlock(priv);
return ret;
}
2006-11-16 19:06:13 +00:00
/*
* Update amount of memory in the config file
*/
int xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory) {
xenUnifiedPrivatePtr priv;
const char *filename;
2006-11-16 19:06:13 +00:00
xenXMConfCachePtr entry;
2009-01-21 18:11:14 +00:00
int ret = -1;
2006-11-16 19:06:13 +00:00
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2006-11-16 19:06:13 +00:00
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO)
return (-1);
if (domain->id != -1)
2006-11-16 19:06:13 +00:00
return (-1);
if (memory < 1024 * MIN_XEN_GUEST_SIZE)
return (-1);
2006-11-16 19:06:13 +00:00
priv = domain->conn->privateData;
2009-01-21 18:11:14 +00:00
xenUnifiedLock(priv);
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
2009-01-21 18:11:14 +00:00
goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename)))
2009-01-21 18:11:14 +00:00
goto cleanup;
2006-11-16 19:06:13 +00:00
entry->def->memory = memory;
if (entry->def->memory > entry->def->maxmem)
entry->def->memory = entry->def->maxmem;
2006-11-16 19:06:13 +00:00
/* If this fails, should we try to undo our changes to the
* in-memory representation of the config file. I say not!
*/
if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
2009-01-21 18:11:14 +00:00
goto cleanup;
ret = 0;
2006-11-16 19:06:13 +00:00
2009-01-21 18:11:14 +00:00
cleanup:
xenUnifiedUnlock(priv);
return ret;
2006-11-16 19:06:13 +00:00
}
/*
* Update maximum memory limit in config
*/
int xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) {
xenUnifiedPrivatePtr priv;
const char *filename;
2006-11-16 19:06:13 +00:00
xenXMConfCachePtr entry;
2009-01-21 18:11:14 +00:00
int ret = -1;
2006-11-16 19:06:13 +00:00
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2006-11-16 19:06:13 +00:00
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO)
return (-1);
if (domain->id != -1)
2006-11-16 19:06:13 +00:00
return (-1);
priv = domain->conn->privateData;
2009-01-21 18:11:14 +00:00
xenUnifiedLock(priv);
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
2009-01-21 18:11:14 +00:00
goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename)))
2009-01-21 18:11:14 +00:00
goto cleanup;
2006-11-16 19:06:13 +00:00
entry->def->maxmem = memory;
if (entry->def->memory > entry->def->maxmem)
entry->def->memory = entry->def->maxmem;
2006-11-16 19:06:13 +00:00
/* If this fails, should we try to undo our changes to the
* in-memory representation of the config file. I say not!
*/
if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
2009-01-21 18:11:14 +00:00
goto cleanup;
ret = 0;
2006-11-16 19:06:13 +00:00
2009-01-21 18:11:14 +00:00
cleanup:
xenUnifiedUnlock(priv);
return ret;
2006-11-16 19:06:13 +00:00
}
/*
* Get max memory limit from config
*/
unsigned long xenXMDomainGetMaxMemory(virDomainPtr domain) {
xenUnifiedPrivatePtr priv;
const char *filename;
2006-11-16 19:06:13 +00:00
xenXMConfCachePtr entry;
2009-01-21 18:11:14 +00:00
unsigned long ret = 0;
2006-11-16 19:06:13 +00:00
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2009-01-21 18:11:14 +00:00
return (0);
2006-11-16 19:06:13 +00:00
}
if (domain->id != -1)
2009-01-21 18:11:14 +00:00
return (0);
2006-11-16 19:06:13 +00:00
priv = domain->conn->privateData;
2009-01-21 18:11:14 +00:00
xenUnifiedLock(priv);
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
2009-01-21 18:11:14 +00:00
goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename)))
2009-01-21 18:11:14 +00:00
goto cleanup;
ret = entry->def->maxmem;
2006-11-16 19:06:13 +00:00
2009-01-21 18:11:14 +00:00
cleanup:
xenUnifiedUnlock(priv);
return ret;
2006-11-16 19:06:13 +00:00
}
/*
* Set the VCPU count in config
*/
int xenXMDomainSetVcpus(virDomainPtr domain, unsigned int vcpus) {
xenUnifiedPrivatePtr priv;
const char *filename;
2006-11-16 19:06:13 +00:00
xenXMConfCachePtr entry;
2009-01-21 18:11:14 +00:00
int ret = -1;
2006-11-16 19:06:13 +00:00
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2006-11-16 19:06:13 +00:00
return (-1);
}
if (domain->conn->flags & VIR_CONNECT_RO)
return (-1);
if (domain->id != -1)
2006-11-16 19:06:13 +00:00
return (-1);
priv = domain->conn->privateData;
2009-01-21 18:11:14 +00:00
xenUnifiedLock(priv);
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
2009-01-21 18:11:14 +00:00
goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename)))
2009-01-21 18:11:14 +00:00
goto cleanup;
2006-11-16 19:06:13 +00:00
entry->def->vcpus = vcpus;
2006-11-16 19:06:13 +00:00
/* If this fails, should we try to undo our changes to the
* in-memory representation of the config file. I say not!
*/
if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
2009-01-21 18:11:14 +00:00
goto cleanup;
ret = 0;
2006-11-16 19:06:13 +00:00
2009-01-21 18:11:14 +00:00
cleanup:
xenUnifiedUnlock(priv);
return ret;
2006-11-16 19:06:13 +00:00
}
/**
* xenXMDomainPinVcpu:
* @domain: pointer to domain object
* @vcpu: virtual CPU number (reserved)
* @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes)
* @maplen: length of cpumap in bytes
*
* Set the vcpu affinity in config
*
* Returns 0 for success; -1 (with errno) on error
*/
int xenXMDomainPinVcpu(virDomainPtr domain,
unsigned int vcpu ATTRIBUTE_UNUSED,
unsigned char *cpumap, int maplen)
{
xenUnifiedPrivatePtr priv;
const char *filename;
xenXMConfCachePtr entry;
virBuffer mapbuf = VIR_BUFFER_INITIALIZER;
char *mapstr = NULL, *mapsave = NULL;
int i, j, n, comma = 0;
int ret = -1;
char *cpuset = NULL;
int maxcpu = XEN_MAX_PHYSICAL_CPU;
if (domain == NULL || domain->conn == NULL || domain->name == NULL
|| cpumap == NULL || maplen < 1 || maplen > (int)sizeof(cpumap_t)) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1;
}
if (domain->conn->flags & VIR_CONNECT_RO) {
xenXMError(VIR_ERR_INVALID_ARG,
avoid many format string warnings Building with --disable-nls exposed many new warnings like these: virsh.c:4952: warning: format not a string literal and no format ... util.c:163: warning: format not a string literal and no format arguments All but one of the following changes add a "%s" argument before the offending _(...) argument. This was the only manual change: * src/lxc_driver.c (lxcVersion): Use %s and strerror(errno) rather than %m, to avoid a warning from gcc -Wformat-security. Add "%s" before each warned about format-string-with-no-%-directive: * src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML) (virDomainDefParseString, virDomainDefParseFile): * src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain) (__virGetNetwork, virReleaseNetwork, __virGetStoragePool) (virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol): * src/lxc_container.c (lxcContainerChild): * src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine) (lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML) (lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart) (lxcVersion, lxcGetSchedulerParameters): * src/network_conf.c (virNetworkDefParseString) (virNetworkDefParseFile): * src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains): * src/openvz_driver.c (openvzDomainDefineCmd) (openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown) (openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML) (openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine) (openvzDomainSetAutostart, openvzDomainGetAutostart) (openvzDomainSetVcpus): * src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek): * src/remote_internal.c (remoteDomainBlockPeek) (remoteDomainMemoryPeek, remoteAuthPolkit): * src/sexpr.c (sexpr_new, _string2sexpr): * src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol) (virStorageBackendDiskCreateVol): * src/storage_backend_fs.c (virStorageBackendFileSystemNetFindPoolSources): * src/storage_backend_logical.c (virStorageBackendLogicalFindLVs) (virStorageBackendLogicalFindPoolSources): * src/test.c (testOpenDefault, testOpenFromFile, testOpen) (testGetDomainInfo, testDomainRestore) (testNodeGetCellsFreeMemory): * src/util.c (virExec): * src/virsh.c (cmdAttachDevice, cmdDetachDevice) (cmdAttachInterface, cmdDetachInterface, cmdAttachDisk) (cmdDetachDisk, cmdEdit): * src/xend_internal.c (do_connect, wr_sync, xend_op_ext) (urlencode, xenDaemonDomainCreateXML) (xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID) (xenDaemonParseSxprOS, xend_parse_sexp_desc_char) (xenDaemonParseSxprChar, xenDaemonParseSxprDisks) (xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain) (xenDaemonDomainFetch, xenDaemonDomainGetAutostart) (xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform) (xenDaemonDomainDefineXML, xenDaemonGetSchedulerType) (xenDaemonGetSchedulerParameters) (xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek) (xenDaemonFormatSxprChr, virDomainXMLDevID): * src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu) (xenXMDomainCreate, xenXMDomainDefineXML) (xenXMDomainAttachDevice, xenXMDomainDetachDevice): * src/xml.c (virXPathString, virXPathNumber, virXPathLong) (virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet): * src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
"%s", _("read only connection"));
return -1;
}
if (domain->id != -1) {
xenXMError(VIR_ERR_INVALID_ARG,
avoid many format string warnings Building with --disable-nls exposed many new warnings like these: virsh.c:4952: warning: format not a string literal and no format ... util.c:163: warning: format not a string literal and no format arguments All but one of the following changes add a "%s" argument before the offending _(...) argument. This was the only manual change: * src/lxc_driver.c (lxcVersion): Use %s and strerror(errno) rather than %m, to avoid a warning from gcc -Wformat-security. Add "%s" before each warned about format-string-with-no-%-directive: * src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML) (virDomainDefParseString, virDomainDefParseFile): * src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain) (__virGetNetwork, virReleaseNetwork, __virGetStoragePool) (virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol): * src/lxc_container.c (lxcContainerChild): * src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine) (lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML) (lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart) (lxcVersion, lxcGetSchedulerParameters): * src/network_conf.c (virNetworkDefParseString) (virNetworkDefParseFile): * src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains): * src/openvz_driver.c (openvzDomainDefineCmd) (openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown) (openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML) (openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine) (openvzDomainSetAutostart, openvzDomainGetAutostart) (openvzDomainSetVcpus): * src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek): * src/remote_internal.c (remoteDomainBlockPeek) (remoteDomainMemoryPeek, remoteAuthPolkit): * src/sexpr.c (sexpr_new, _string2sexpr): * src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol) (virStorageBackendDiskCreateVol): * src/storage_backend_fs.c (virStorageBackendFileSystemNetFindPoolSources): * src/storage_backend_logical.c (virStorageBackendLogicalFindLVs) (virStorageBackendLogicalFindPoolSources): * src/test.c (testOpenDefault, testOpenFromFile, testOpen) (testGetDomainInfo, testDomainRestore) (testNodeGetCellsFreeMemory): * src/util.c (virExec): * src/virsh.c (cmdAttachDevice, cmdDetachDevice) (cmdAttachInterface, cmdDetachInterface, cmdAttachDisk) (cmdDetachDisk, cmdEdit): * src/xend_internal.c (do_connect, wr_sync, xend_op_ext) (urlencode, xenDaemonDomainCreateXML) (xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID) (xenDaemonParseSxprOS, xend_parse_sexp_desc_char) (xenDaemonParseSxprChar, xenDaemonParseSxprDisks) (xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain) (xenDaemonDomainFetch, xenDaemonDomainGetAutostart) (xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform) (xenDaemonDomainDefineXML, xenDaemonGetSchedulerType) (xenDaemonGetSchedulerParameters) (xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek) (xenDaemonFormatSxprChr, virDomainXMLDevID): * src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu) (xenXMDomainCreate, xenXMDomainDefineXML) (xenXMDomainAttachDevice, xenXMDomainDetachDevice): * src/xml.c (virXPathString, virXPathNumber, virXPathLong) (virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet): * src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
"%s", _("not inactive domain"));
return -1;
}
priv = domain->conn->privateData;
2009-01-21 18:11:14 +00:00
xenUnifiedLock(priv);
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) {
xenXMError(VIR_ERR_INTERNAL_ERROR, "%s", _("virHashLookup"));
2009-01-21 18:11:14 +00:00
goto cleanup;
}
if (!(entry = virHashLookup(priv->configCache, filename))) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
avoid many format string warnings Building with --disable-nls exposed many new warnings like these: virsh.c:4952: warning: format not a string literal and no format ... util.c:163: warning: format not a string literal and no format arguments All but one of the following changes add a "%s" argument before the offending _(...) argument. This was the only manual change: * src/lxc_driver.c (lxcVersion): Use %s and strerror(errno) rather than %m, to avoid a warning from gcc -Wformat-security. Add "%s" before each warned about format-string-with-no-%-directive: * src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML) (virDomainDefParseString, virDomainDefParseFile): * src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain) (__virGetNetwork, virReleaseNetwork, __virGetStoragePool) (virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol): * src/lxc_container.c (lxcContainerChild): * src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine) (lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML) (lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart) (lxcVersion, lxcGetSchedulerParameters): * src/network_conf.c (virNetworkDefParseString) (virNetworkDefParseFile): * src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains): * src/openvz_driver.c (openvzDomainDefineCmd) (openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown) (openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML) (openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine) (openvzDomainSetAutostart, openvzDomainGetAutostart) (openvzDomainSetVcpus): * src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek): * src/remote_internal.c (remoteDomainBlockPeek) (remoteDomainMemoryPeek, remoteAuthPolkit): * src/sexpr.c (sexpr_new, _string2sexpr): * src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol) (virStorageBackendDiskCreateVol): * src/storage_backend_fs.c (virStorageBackendFileSystemNetFindPoolSources): * src/storage_backend_logical.c (virStorageBackendLogicalFindLVs) (virStorageBackendLogicalFindPoolSources): * src/test.c (testOpenDefault, testOpenFromFile, testOpen) (testGetDomainInfo, testDomainRestore) (testNodeGetCellsFreeMemory): * src/util.c (virExec): * src/virsh.c (cmdAttachDevice, cmdDetachDevice) (cmdAttachInterface, cmdDetachInterface, cmdAttachDisk) (cmdDetachDisk, cmdEdit): * src/xend_internal.c (do_connect, wr_sync, xend_op_ext) (urlencode, xenDaemonDomainCreateXML) (xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID) (xenDaemonParseSxprOS, xend_parse_sexp_desc_char) (xenDaemonParseSxprChar, xenDaemonParseSxprDisks) (xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain) (xenDaemonDomainFetch, xenDaemonDomainGetAutostart) (xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform) (xenDaemonDomainDefineXML, xenDaemonGetSchedulerType) (xenDaemonGetSchedulerParameters) (xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek) (xenDaemonFormatSxprChr, virDomainXMLDevID): * src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu) (xenXMDomainCreate, xenXMDomainDefineXML) (xenXMDomainAttachDevice, xenXMDomainDetachDevice): * src/xml.c (virXPathString, virXPathNumber, virXPathLong) (virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet): * src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
"%s", _("can't retrieve config file for domain"));
2009-01-21 18:11:14 +00:00
goto cleanup;
}
/* from bit map, build character string of mapped CPU numbers */
for (i = 0; i < maplen; i++)
for (j = 0; j < 8; j++)
if ((cpumap[i] & (1 << j))) {
n = i*8 + j;
if (comma)
virBufferAddLit (&mapbuf, ",");
comma = 1;
virBufferVSprintf (&mapbuf, "%d", n);
}
if (virBufferError(&mapbuf)) {
virBufferFreeAndReset(&mapbuf);
virReportOOMError();
2009-01-21 18:11:14 +00:00
goto cleanup;
}
mapstr = virBufferContentAndReset(&mapbuf);
mapsave = mapstr;
if (VIR_ALLOC_N(cpuset, maxcpu) < 0) {
virReportOOMError();
goto cleanup;
}
if (virDomainCpuSetParse((const char **)&mapstr, 0,
cpuset, maxcpu) < 0)
goto cleanup;
VIR_FREE(entry->def->cpumask);
entry->def->cpumask = cpuset;
entry->def->cpumasklen = maxcpu;
cpuset = NULL;
if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
goto cleanup;
ret = 0;
cleanup:
VIR_FREE(mapsave);
VIR_FREE(cpuset);
2009-01-21 18:11:14 +00:00
xenUnifiedUnlock(priv);
return (ret);
}
2006-11-16 19:06:13 +00:00
/*
* Find an inactive domain based on its name
*/
virDomainPtr xenXMDomainLookupByName(virConnectPtr conn, const char *domname) {
xenUnifiedPrivatePtr priv;
const char *filename;
2006-11-16 19:06:13 +00:00
xenXMConfCachePtr entry;
2009-01-21 18:11:14 +00:00
virDomainPtr ret = NULL;
2006-11-16 19:06:13 +00:00
if (!VIR_IS_CONNECT(conn)) {
xenXMError(VIR_ERR_INVALID_CONN, __FUNCTION__);
2006-11-16 19:06:13 +00:00
return (NULL);
}
if (domname == NULL) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2006-11-16 19:06:13 +00:00
return (NULL);
}
priv = conn->privateData;
2009-01-21 18:11:14 +00:00
xenUnifiedLock(priv);
if (!xenInotifyActive(conn) && xenXMConfigCacheRefresh (conn) < 0)
2009-01-21 18:11:14 +00:00
goto cleanup;
2006-11-16 19:06:13 +00:00
if (!(filename = virHashLookup(priv->nameConfigMap, domname)))
2009-01-21 18:11:14 +00:00
goto cleanup;
2009-01-21 18:11:14 +00:00
if (!(entry = virHashLookup(priv->configCache, filename)))
goto cleanup;
2006-11-16 19:06:13 +00:00
2009-01-21 18:11:14 +00:00
if (!(ret = virGetDomain(conn, domname, entry->def->uuid)))
goto cleanup;
/* Ensure its marked inactive, because may be cached
handle to a previously active domain */
ret->id = -1;
2006-11-16 19:06:13 +00:00
2009-01-21 18:11:14 +00:00
cleanup:
xenUnifiedUnlock(priv);
2006-11-16 19:06:13 +00:00
return (ret);
}
/*
* Hash table iterator to search for a domain based on UUID
*/
static int xenXMDomainSearchForUUID(const void *payload, const char *name ATTRIBUTE_UNUSED, const void *data) {
const unsigned char *wantuuid = (const unsigned char *)data;
const xenXMConfCachePtr entry = (const xenXMConfCachePtr)payload;
if (!memcmp(entry->def->uuid, wantuuid, VIR_UUID_BUFLEN))
2006-11-16 19:06:13 +00:00
return (1);
return (0);
}
/*
* Find an inactive domain based on its UUID
*/
virDomainPtr xenXMDomainLookupByUUID(virConnectPtr conn,
const unsigned char *uuid) {
xenUnifiedPrivatePtr priv;
2006-11-16 19:06:13 +00:00
xenXMConfCachePtr entry;
2009-01-21 18:11:14 +00:00
virDomainPtr ret = NULL;
2006-11-16 19:06:13 +00:00
if (!VIR_IS_CONNECT(conn)) {
xenXMError(VIR_ERR_INVALID_CONN, __FUNCTION__);
2006-11-16 19:06:13 +00:00
return (NULL);
}
if (uuid == NULL) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2006-11-16 19:06:13 +00:00
return (NULL);
}
priv = conn->privateData;
2009-01-21 18:11:14 +00:00
xenUnifiedLock(priv);
if (!xenInotifyActive(conn) && xenXMConfigCacheRefresh (conn) < 0)
2009-01-21 18:11:14 +00:00
goto cleanup;
2006-11-16 19:06:13 +00:00
2009-01-21 18:11:14 +00:00
if (!(entry = virHashSearch(priv->configCache, xenXMDomainSearchForUUID, (const void *)uuid)))
goto cleanup;
2006-11-16 19:06:13 +00:00
2009-01-21 18:11:14 +00:00
if (!(ret = virGetDomain(conn, entry->def->name, uuid)))
goto cleanup;
2006-11-16 19:06:13 +00:00
/* Ensure its marked inactive, because may be cached
handle to a previously active domain */
ret->id = -1;
2009-01-21 18:11:14 +00:00
cleanup:
xenUnifiedUnlock(priv);
2006-11-16 19:06:13 +00:00
return (ret);
}
/*
* Start a domain from an existing defined config file
*/
int xenXMDomainCreate(virDomainPtr domain) {
char *sexpr;
2009-01-21 18:11:14 +00:00
int ret = -1;
xenUnifiedPrivatePtr priv;
const char *filename;
xenXMConfCachePtr entry;
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
2006-11-16 19:06:13 +00:00
if (domain->id != -1)
2006-11-16 19:06:13 +00:00
return (-1);
2009-01-21 18:11:14 +00:00
xenUnifiedLock(priv);
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
2009-01-21 18:11:14 +00:00
goto error;
2006-11-16 19:06:13 +00:00
if (!(entry = virHashLookup(priv->configCache, filename)))
2009-01-21 18:11:14 +00:00
goto error;
2006-11-16 19:06:13 +00:00
if (!(sexpr = xenDaemonFormatSxpr(domain->conn, entry->def, priv->xendConfigVersion)))
2009-01-21 18:11:14 +00:00
goto error;
ret = xenDaemonDomainCreateXML(domain->conn, sexpr);
VIR_FREE(sexpr);
2009-01-21 18:11:14 +00:00
if (ret != 0)
goto error;
2006-11-16 19:06:13 +00:00
if ((ret = xenDaemonDomainLookupByName_ids(domain->conn, domain->name,
2009-01-21 18:11:14 +00:00
entry->def->uuid)) < 0)
goto error;
domain->id = ret;
2006-11-16 19:06:13 +00:00
if (xend_wait_for_devices(domain->conn, domain->name) < 0)
2009-01-21 18:11:14 +00:00
goto error;
if (xenDaemonDomainResume(domain) < 0)
2009-01-21 18:11:14 +00:00
goto error;
2009-01-21 18:11:14 +00:00
xenUnifiedUnlock(priv);
return (0);
2009-01-21 18:11:14 +00:00
error:
if (domain->id != -1) {
2006-11-16 19:06:13 +00:00
xenDaemonDomainDestroy(domain);
domain->id = -1;
2006-11-16 19:06:13 +00:00
}
2009-01-21 18:11:14 +00:00
xenUnifiedUnlock(priv);
return (-1);
2006-11-16 19:06:13 +00:00
}
static
int xenXMConfigSetInt(virConfPtr conf, const char *setting, long l) {
virConfValuePtr value = NULL;
if (VIR_ALLOC(value) < 0) {
virReportOOMError();
return -1;
}
value->type = VIR_CONF_LONG;
value->next = NULL;
value->l = l;
return virConfSetValue(conf, setting, value);
}
static
int xenXMConfigSetString(virConfPtr conf, const char *setting, const char *str) {
virConfValuePtr value = NULL;
if (VIR_ALLOC(value) < 0) {
virReportOOMError();
return -1;
}
value->type = VIR_CONF_STRING;
value->next = NULL;
if (!(value->str = strdup(str))) {
VIR_FREE(value);
virReportOOMError();
return -1;
}
return virConfSetValue(conf, setting, value);
}
static int xenXMDomainConfigFormatDisk(virConfValuePtr list,
virDomainDiskDefPtr disk,
int hvm,
int xendConfigVersion)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
virConfValuePtr val, tmp;
if(disk->src) {
if (disk->driverName) {
virBufferVSprintf(&buf, "%s:", disk->driverName);
if (STREQ(disk->driverName, "tap"))
virBufferVSprintf(&buf, "%s:", disk->driverType ? disk->driverType : "aio");
} else {
switch (disk->type) {
case VIR_DOMAIN_DISK_TYPE_FILE:
virBufferAddLit(&buf, "file:");
break;
case VIR_DOMAIN_DISK_TYPE_BLOCK:
virBufferAddLit(&buf, "phy:");
break;
default:
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("unsupported disk type %s"),
virDomainDiskTypeToString(disk->type));
goto cleanup;
}
}
virBufferVSprintf(&buf, "%s", disk->src);
}
virBufferAddLit(&buf, ",");
if (hvm && xendConfigVersion == 1)
virBufferAddLit(&buf, "ioemu:");
2006-11-16 19:06:13 +00:00
virBufferVSprintf(&buf, "%s", disk->dst);
if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM)
virBufferAddLit(&buf, ":cdrom");
2006-11-16 19:06:13 +00:00
if (disk->readonly)
virBufferAddLit(&buf, ",r");
else if (disk->shared)
virBufferAddLit(&buf, ",!");
else
virBufferAddLit(&buf, ",w");
2006-11-16 19:06:13 +00:00
if (virBufferError(&buf)) {
virReportOOMError();
goto cleanup;
}
2006-11-16 19:06:13 +00:00
if (VIR_ALLOC(val) < 0) {
virReportOOMError();
goto cleanup;
}
2006-11-16 19:06:13 +00:00
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;
2006-11-16 19:06:13 +00:00
return 0;
2006-11-16 19:06:13 +00:00
cleanup:
virBufferFreeAndReset(&buf);
return -1;
}
static int xenXMDomainConfigFormatNet(virConnectPtr conn,
virConfValuePtr list,
virDomainNetDefPtr net,
int hvm)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
virConfValuePtr val, tmp;
xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
virBufferVSprintf(&buf, "mac=%02x:%02x:%02x:%02x:%02x:%02x",
net->mac[0], net->mac[1],
net->mac[2], net->mac[3],
net->mac[4], net->mac[5]);
switch (net->type) {
case VIR_DOMAIN_NET_TYPE_BRIDGE:
virBufferVSprintf(&buf, ",bridge=%s", net->data.bridge.brname);
2009-01-23 01:48:47 +00:00
if (net->data.bridge.ipaddr)
virBufferVSprintf(&buf, ",ip=%s", net->data.bridge.ipaddr);
2009-04-24 12:17:50 +00:00
virBufferVSprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
break;
case VIR_DOMAIN_NET_TYPE_ETHERNET:
if (net->data.ethernet.script)
virBufferVSprintf(&buf, ",script=%s", net->data.ethernet.script);
if (net->data.ethernet.ipaddr)
virBufferVSprintf(&buf, ",ip=%s", net->data.ethernet.ipaddr);
break;
case VIR_DOMAIN_NET_TYPE_NETWORK:
2009-04-24 12:17:50 +00:00
{
virNetworkPtr network = virNetworkLookupByName(conn, net->data.network.name);
char *bridge;
if (!network) {
xenXMError(VIR_ERR_NO_NETWORK, "%s",
2009-04-24 12:17:50 +00:00
net->data.network.name);
return -1;
}
bridge = virNetworkGetBridgeName(network);
virNetworkFree(network);
if (!bridge) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
2009-04-24 12:17:50 +00:00
_("network %s is not active"),
net->data.network.name);
return -1;
}
virBufferVSprintf(&buf, ",bridge=%s", bridge);
virBufferVSprintf(&buf, ",script=%s", DEFAULT_VIF_SCRIPT);
}
break;
default:
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("unsupported network type %d"),
net->type);
goto cleanup;
}
Support for interface model='netfront' Xen HVM guests with PV drivers end up with two network interfaces for each configured interface. One of them being emulated by qemu and the other one paravirtual. As this might not be desirable, the attached patch provides a way for users to specify that only paravirtual network interface should be presented to the guest. The configuration was inspired by qemu/kvm driver, for which users can specify model='virtio' to use paravirtual network interface. The patch adds support for model='netfront' which results in type=netfront instead of type=ioemu (or nothing for newer xen versions) in guests native configuration. Xen's qemu ignores interfaces with type != ioemu and only paravirtual network device will be seen in the guest. Four possible configuration scenarios follow: - no model specified in domain's XML - libvirt will behave like before this change; it will set type=ioemu for HVM guests on xen host which is not newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU - covered by existing tests - PV guest, any model - no functional change, model is passed as is (and ignored by the hypervisor) - covered by existing tests (e.g., *-net-e1000.*) - HVM guest, model=netfront - type is set to "netfront", model is not specified - covered by new *-net-netfront.* tests - HVM guest, model != netfront - type is set to "ioemu", model is passed as is - covered by new *-net-ioemu.* tests The fourth scenario feels like a regression for xen newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU as users who had a model specified in their guest's configuration won't see a paravirtual interface in their guests any more. On the other hand, the reason for specifying a model is most likely the fact that they want to use such model which implies emulated interface. Users of older xen won't be affected at all as their xen provides paravirtual interface regardless of the type used. - src/xen/xend_internal.c: add netfront support for the xend backend - src/xen/xm_internal.c: add netfront support for the XM serialization too
2009-12-04 15:55:59 +00:00
if (!hvm) {
if (net->model != NULL)
virBufferVSprintf(&buf, ",model=%s", net->model);
}
else if (net->model == NULL) {
/*
* apparently type ioemu breaks paravirt drivers on HVM so skip this
* from XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU
*/
if (priv->xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
virBufferAddLit(&buf, ",type=ioemu");
}
else if (STREQ(net->model, "netfront")) {
virBufferAddLit(&buf, ",type=netfront");
}
else {
virBufferVSprintf(&buf, ",model=%s", net->model);
virBufferAddLit(&buf, ",type=ioemu");
Support for interface model='netfront' Xen HVM guests with PV drivers end up with two network interfaces for each configured interface. One of them being emulated by qemu and the other one paravirtual. As this might not be desirable, the attached patch provides a way for users to specify that only paravirtual network interface should be presented to the guest. The configuration was inspired by qemu/kvm driver, for which users can specify model='virtio' to use paravirtual network interface. The patch adds support for model='netfront' which results in type=netfront instead of type=ioemu (or nothing for newer xen versions) in guests native configuration. Xen's qemu ignores interfaces with type != ioemu and only paravirtual network device will be seen in the guest. Four possible configuration scenarios follow: - no model specified in domain's XML - libvirt will behave like before this change; it will set type=ioemu for HVM guests on xen host which is not newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU - covered by existing tests - PV guest, any model - no functional change, model is passed as is (and ignored by the hypervisor) - covered by existing tests (e.g., *-net-e1000.*) - HVM guest, model=netfront - type is set to "netfront", model is not specified - covered by new *-net-netfront.* tests - HVM guest, model != netfront - type is set to "ioemu", model is passed as is - covered by new *-net-ioemu.* tests The fourth scenario feels like a regression for xen newer than XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU as users who had a model specified in their guest's configuration won't see a paravirtual interface in their guests any more. On the other hand, the reason for specifying a model is most likely the fact that they want to use such model which implies emulated interface. Users of older xen won't be affected at all as their xen provides paravirtual interface regardless of the type used. - src/xen/xend_internal.c: add netfront support for the xend backend - src/xen/xm_internal.c: add netfront support for the XM serialization too
2009-12-04 15:55:59 +00:00
}
if (net->ifname)
virBufferVSprintf(&buf, ",vifname=%s",
net->ifname);
if (virBufferError(&buf)) {
virReportOOMError();
goto cleanup;
}
if (VIR_ALLOC(val) < 0) {
virReportOOMError();
goto cleanup;
}
val->type = VIR_CONF_STRING;
val->str = virBufferContentAndReset(&buf);
tmp = list->list;
while (tmp && tmp->next)
tmp = tmp->next;
if (tmp)
tmp->next = val;
else
list->list = val;
return 0;
cleanup:
virBufferFreeAndReset(&buf);
return -1;
2006-11-16 19:06:13 +00:00
}
2009-04-03 12:38:52 +00:00
static int
xenXMDomainConfigFormatPCI(virConfPtr conf,
2009-04-03 12:38:52 +00:00
virDomainDefPtr def)
{
virConfValuePtr pciVal = NULL;
int hasPCI = 0;
int i;
for (i = 0 ; i < def->nhostdevs ; i++)
if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
hasPCI = 1;
if (!hasPCI)
return 0;
if (VIR_ALLOC(pciVal) < 0) {
virReportOOMError();
2009-04-03 12:38:52 +00:00
return -1;
}
2009-04-03 12:38:52 +00:00
pciVal->type = VIR_CONF_LIST;
pciVal->list = NULL;
for (i = 0 ; i < def->nhostdevs ; i++) {
if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
virConfValuePtr val, tmp;
char *buf;
if (virAsprintf(&buf, "%04x:%02x:%02x.%x",
def->hostdevs[i]->source.subsys.u.pci.domain,
def->hostdevs[i]->source.subsys.u.pci.bus,
def->hostdevs[i]->source.subsys.u.pci.slot,
def->hostdevs[i]->source.subsys.u.pci.function) < 0) {
virReportOOMError();
2009-04-03 12:38:52 +00:00
goto error;
}
2009-04-03 12:38:52 +00:00
if (VIR_ALLOC(val) < 0) {
VIR_FREE(buf);
virReportOOMError();
2009-04-03 12:38:52 +00:00
goto error;
}
val->type = VIR_CONF_STRING;
val->str = buf;
tmp = pciVal->list;
while (tmp && tmp->next)
tmp = tmp->next;
if (tmp)
tmp->next = val;
else
pciVal->list = val;
}
}
if (pciVal->list != NULL) {
int ret = virConfSetValue(conf, "pci", pciVal);
pciVal = NULL;
if (ret < 0)
return -1;
}
VIR_FREE(pciVal);
return 0;
error:
virConfFreeValue(pciVal);
return -1;
}
virConfPtr xenXMDomainConfigFormat(virConnectPtr conn,
virDomainDefPtr def) {
2006-11-16 19:06:13 +00:00
virConfPtr conf = NULL;
int hvm = 0, i;
xenUnifiedPrivatePtr priv;
char *cpus = NULL;
const char *lifecycle;
char uuid[VIR_UUID_STRING_BUFLEN];
virConfValuePtr diskVal = NULL;
virConfValuePtr netVal = NULL;
priv = (xenUnifiedPrivatePtr) conn->privateData;
if (!(conf = virConfNew()))
goto cleanup;
2006-11-16 19:06:13 +00:00
if (xenXMConfigSetString(conf, "name", def->name) < 0)
goto no_memory;
2006-11-16 19:06:13 +00:00
virUUIDFormat(def->uuid, uuid);
if (xenXMConfigSetString(conf, "uuid", uuid) < 0)
goto no_memory;
if (xenXMConfigSetInt(conf, "maxmem", def->maxmem / 1024) < 0)
goto no_memory;
2006-11-16 19:06:13 +00:00
if (xenXMConfigSetInt(conf, "memory", def->memory / 1024) < 0)
goto no_memory;
2006-11-16 19:06:13 +00:00
if (xenXMConfigSetInt(conf, "vcpus", def->vcpus) < 0)
goto no_memory;
2006-11-16 19:06:13 +00:00
if ((def->cpumask != NULL) &&
((cpus = virDomainCpuSetFormat(def->cpumask,
def->cpumasklen)) == NULL))
goto cleanup;
2006-11-16 19:06:13 +00:00
if (cpus &&
xenXMConfigSetString(conf, "cpus", cpus) < 0)
goto no_memory;
VIR_FREE(cpus);
2006-11-16 19:06:13 +00:00
hvm = STREQ(def->os.type, "hvm") ? 1 : 0;
2006-11-16 19:06:13 +00:00
if (hvm) {
char boot[VIR_DOMAIN_BOOT_LAST+1];
if (xenXMConfigSetString(conf, "builder", "hvm") < 0)
goto no_memory;
2006-11-16 19:06:13 +00:00
if (def->os.loader &&
xenXMConfigSetString(conf, "kernel", def->os.loader) < 0)
goto no_memory;
for (i = 0 ; i < def->os.nBootDevs ; i++) {
switch (def->os.bootDevs[i]) {
case VIR_DOMAIN_BOOT_FLOPPY:
boot[i] = 'a';
break;
case VIR_DOMAIN_BOOT_CDROM:
boot[i] = 'd';
break;
case VIR_DOMAIN_BOOT_NET:
boot[i] = 'n';
break;
case VIR_DOMAIN_BOOT_DISK:
default:
boot[i] = 'c';
break;
}
}
if (!def->os.nBootDevs) {
boot[0] = 'c';
boot[1] = '\0';
} else {
boot[def->os.nBootDevs] = '\0';
}
if (xenXMConfigSetString(conf, "boot", boot) < 0)
goto no_memory;
if (xenXMConfigSetInt(conf, "pae",
(def->features &
(1 << VIR_DOMAIN_FEATURE_PAE)) ? 1 : 0) < 0)
goto no_memory;
if (xenXMConfigSetInt(conf, "acpi",
(def->features &
(1 << VIR_DOMAIN_FEATURE_ACPI)) ? 1 : 0) < 0)
goto no_memory;
if (xenXMConfigSetInt(conf, "apic",
(def->features &
(1 << VIR_DOMAIN_FEATURE_APIC)) ? 1 : 0) < 0)
goto no_memory;
if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME) {
if (def->clock.data.timezone) {
xenXMError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("configurable timezones are not supported"));
goto cleanup;
}
if (xenXMConfigSetInt(conf, "localtime", 1) < 0)
goto no_memory;
} else if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_UTC) {
if (xenXMConfigSetInt(conf, "localtime", 0) < 0)
goto no_memory;
} else {
/* XXX We could support Xen's rtc clock offset */
xenXMError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported clock offset '%s'"),
virDomainClockOffsetTypeToString(def->clock.offset));
goto cleanup;
}
if (priv->xendConfigVersion == 1) {
for (i = 0 ; i < def->ndisks ; i++) {
if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
def->disks[i]->dst &&
STREQ(def->disks[i]->dst, "hdc") &&
def->disks[i]->src) {
if (xenXMConfigSetString(conf, "cdrom",
def->disks[i]->src) < 0)
goto no_memory;
break;
}
}
}
/* XXX floppy disks */
} else {
if (def->os.bootloader &&
xenXMConfigSetString(conf, "bootloader", def->os.bootloader) < 0)
goto no_memory;
if (def->os.bootloaderArgs &&
xenXMConfigSetString(conf, "bootargs", def->os.bootloaderArgs) < 0)
goto no_memory;
if (def->os.kernel &&
xenXMConfigSetString(conf, "kernel", def->os.kernel) < 0)
goto no_memory;
if (def->os.initrd &&
xenXMConfigSetString(conf, "ramdisk", def->os.initrd) < 0)
goto no_memory;
if (def->os.cmdline &&
xenXMConfigSetString(conf, "extra", def->os.cmdline) < 0)
goto no_memory;
}
2006-11-16 19:06:13 +00:00
if (!(lifecycle = virDomainLifecycleTypeToString(def->onPoweroff))) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("unexpected lifecycle action %d"), def->onPoweroff);
goto cleanup;
}
if (xenXMConfigSetString(conf, "on_poweroff", lifecycle) < 0)
goto no_memory;
2006-11-16 19:06:13 +00:00
if (!(lifecycle = virDomainLifecycleTypeToString(def->onReboot))) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("unexpected lifecycle action %d"), def->onReboot);
goto cleanup;
}
if (xenXMConfigSetString(conf, "on_reboot", lifecycle) < 0)
goto no_memory;
if (!(lifecycle = virDomainLifecycleCrashTypeToString(def->onCrash))) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
_("unexpected lifecycle action %d"), def->onCrash);
goto cleanup;
}
if (xenXMConfigSetString(conf, "on_crash", lifecycle) < 0)
goto no_memory;
2006-11-16 19:06:13 +00:00
if (hvm) {
if (def->emulator &&
xenXMConfigSetString(conf, "device_model", def->emulator) < 0)
goto no_memory;
for (i = 0 ; i < def->ninputs ; i++) {
if (def->inputs[i]->bus == VIR_DOMAIN_INPUT_BUS_USB) {
if (xenXMConfigSetInt(conf, "usb", 1) < 0)
goto no_memory;
if (xenXMConfigSetString(conf, "usbdevice",
def->inputs[i]->type == VIR_DOMAIN_INPUT_TYPE_MOUSE ?
"mouse" : "tablet") < 0)
goto no_memory;
break;
}
}
}
if (def->ngraphics == 1) {
if (priv->xendConfigVersion < (hvm ? 4 : XEND_CONFIG_MIN_VERS_PVFB_NEWCONF)) {
if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
if (xenXMConfigSetInt(conf, "sdl", 1) < 0)
goto no_memory;
if (xenXMConfigSetInt(conf, "vnc", 0) < 0)
goto no_memory;
if (def->graphics[0]->data.sdl.display &&
xenXMConfigSetString(conf, "display",
def->graphics[0]->data.sdl.display) < 0)
goto no_memory;
if (def->graphics[0]->data.sdl.xauth &&
xenXMConfigSetString(conf, "xauthority",
def->graphics[0]->data.sdl.xauth) < 0)
goto no_memory;
} else {
if (xenXMConfigSetInt(conf, "sdl", 0) < 0)
goto no_memory;
if (xenXMConfigSetInt(conf, "vnc", 1) < 0)
goto no_memory;
if (xenXMConfigSetInt(conf, "vncunused",
def->graphics[0]->data.vnc.autoport ? 1 : 0) < 0)
goto no_memory;
if (!def->graphics[0]->data.vnc.autoport &&
xenXMConfigSetInt(conf, "vncdisplay",
def->graphics[0]->data.vnc.port - 5900) < 0)
goto no_memory;
if (def->graphics[0]->data.vnc.listenAddr &&
xenXMConfigSetString(conf, "vnclisten",
def->graphics[0]->data.vnc.listenAddr) < 0)
goto no_memory;
if (def->graphics[0]->data.vnc.passwd &&
xenXMConfigSetString(conf, "vncpasswd",
def->graphics[0]->data.vnc.passwd) < 0)
goto no_memory;
if (def->graphics[0]->data.vnc.keymap &&
xenXMConfigSetString(conf, "keymap",
def->graphics[0]->data.vnc.keymap) < 0)
goto no_memory;
}
} else {
virConfValuePtr vfb, disp;
char *vfbstr = NULL;
virBuffer buf = VIR_BUFFER_INITIALIZER;
if (def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
virBufferAddLit(&buf, "type=sdl");
if (def->graphics[0]->data.sdl.display)
virBufferVSprintf(&buf, ",display=%s",
def->graphics[0]->data.sdl.display);
if (def->graphics[0]->data.sdl.xauth)
virBufferVSprintf(&buf, ",xauthority=%s",
def->graphics[0]->data.sdl.xauth);
} else {
virBufferAddLit(&buf, "type=vnc");
virBufferVSprintf(&buf, ",vncunused=%d",
def->graphics[0]->data.vnc.autoport ? 1 : 0);
if (!def->graphics[0]->data.vnc.autoport)
virBufferVSprintf(&buf, ",vncdisplay=%d",
def->graphics[0]->data.vnc.port - 5900);
if (def->graphics[0]->data.vnc.listenAddr)
virBufferVSprintf(&buf, ",vnclisten=%s",
def->graphics[0]->data.vnc.listenAddr);
if (def->graphics[0]->data.vnc.passwd)
virBufferVSprintf(&buf, ",vncpasswd=%s",
def->graphics[0]->data.vnc.passwd);
if (def->graphics[0]->data.vnc.keymap)
virBufferVSprintf(&buf, ",keymap=%s",
def->graphics[0]->data.vnc.keymap);
}
if (virBufferError(&buf)) {
virBufferFreeAndReset(&buf);
goto no_memory;
}
vfbstr = virBufferContentAndReset(&buf);
if (VIR_ALLOC(vfb) < 0) {
VIR_FREE(vfbstr);
goto no_memory;
}
if (VIR_ALLOC(disp) < 0) {
VIR_FREE(vfb);
VIR_FREE(vfbstr);
goto no_memory;
}
vfb->type = VIR_CONF_LIST;
vfb->list = disp;
disp->type = VIR_CONF_STRING;
disp->str = vfbstr;
if (virConfSetValue(conf, "vfb", vfb) < 0)
goto no_memory;
}
}
/* analyze of the devices */
if (VIR_ALLOC(diskVal) < 0)
goto no_memory;
diskVal->type = VIR_CONF_LIST;
diskVal->list = NULL;
for (i = 0 ; i < def->ndisks ; i++) {
if (priv->xendConfigVersion == 1 &&
def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_CDROM &&
def->disks[i]->dst &&
STREQ(def->disks[i]->dst, "hdc")) {
continue;
}
if (def->disks[i]->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
continue;
if (xenXMDomainConfigFormatDisk(diskVal, def->disks[i],
hvm, priv->xendConfigVersion) < 0)
goto cleanup;
}
if (diskVal->list != NULL) {
int ret = virConfSetValue(conf, "disk", diskVal);
diskVal = NULL;
if (ret < 0)
goto no_memory;
}
VIR_FREE(diskVal);
if (VIR_ALLOC(netVal) < 0)
goto no_memory;
netVal->type = VIR_CONF_LIST;
netVal->list = NULL;
for (i = 0 ; i < def->nnets ; i++) {
if (xenXMDomainConfigFormatNet(conn, netVal,
def->nets[i],
hvm) < 0)
goto cleanup;
}
if (netVal->list != NULL) {
int ret = virConfSetValue(conf, "vif", netVal);
netVal = NULL;
if (ret < 0)
goto no_memory;
}
VIR_FREE(netVal);
if (xenXMDomainConfigFormatPCI(conf, def) < 0)
2009-04-03 12:38:52 +00:00
goto cleanup;
if (hvm) {
if (def->nparallels) {
virBuffer buf = VIR_BUFFER_INITIALIZER;
char *str;
int ret;
ret = xenDaemonFormatSxprChr(def->parallels[0], &buf);
str = virBufferContentAndReset(&buf);
if (ret == 0)
ret = xenXMConfigSetString(conf, "parallel", str);
VIR_FREE(str);
if (ret < 0)
goto no_memory;
} else {
if (xenXMConfigSetString(conf, "parallel", "none") < 0)
goto no_memory;
}
if (def->nserials) {
virBuffer buf = VIR_BUFFER_INITIALIZER;
char *str;
int ret;
ret = xenDaemonFormatSxprChr(def->serials[0], &buf);
str = virBufferContentAndReset(&buf);
if (ret == 0)
ret = xenXMConfigSetString(conf, "serial", str);
VIR_FREE(str);
if (ret < 0)
goto no_memory;
} else {
if (xenXMConfigSetString(conf, "serial", "none") < 0)
goto no_memory;
}
if (def->sounds) {
virBuffer buf = VIR_BUFFER_INITIALIZER;
char *str = NULL;
int ret = xenDaemonFormatSxprSound(def, &buf);
str = virBufferContentAndReset(&buf);
if (ret == 0)
ret = xenXMConfigSetString(conf, "soundhw", str);
VIR_FREE(str);
if (ret < 0)
goto no_memory;
}
}
return conf;
no_memory:
virReportOOMError();
cleanup:
virConfFreeValue(diskVal);
virConfFreeValue(netVal);
VIR_FREE(cpus);
if (conf)
virConfFree(conf);
return (NULL);
}
/*
* Create a config file for a domain, based on an XML
* document describing its config
*/
virDomainPtr xenXMDomainDefineXML(virConnectPtr conn, const char *xml) {
virDomainPtr ret;
char filename[PATH_MAX];
const char * oldfilename;
virDomainDefPtr def = NULL;
xenXMConfCachePtr entry = NULL;
xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
if (!VIR_IS_CONNECT(conn)) {
xenXMError(VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
if (xml == NULL) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return (NULL);
}
if (conn->flags & VIR_CONNECT_RO)
return (NULL);
2009-01-21 18:11:14 +00:00
xenUnifiedLock(priv);
if (!xenInotifyActive(conn) && xenXMConfigCacheRefresh (conn) < 0) {
2009-01-21 18:11:14 +00:00
xenUnifiedUnlock(priv);
return (NULL);
2009-01-21 18:11:14 +00:00
}
if (!(def = virDomainDefParseString(priv->caps, xml,
2009-01-21 18:11:14 +00:00
VIR_DOMAIN_XML_INACTIVE))) {
xenUnifiedUnlock(priv);
return (NULL);
2009-01-21 18:11:14 +00:00
}
2006-11-16 19:06:13 +00:00
/*
* check that if there is another domain defined with the same uuid
* it has the same name
*/
if ((entry = virHashSearch(priv->configCache, xenXMDomainSearchForUUID,
(const void *)&(def->uuid))) != NULL) {
if ((entry->def != NULL) && (entry->def->name != NULL) &&
(STRNEQ(def->name, entry->def->name))) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(entry->def->uuid, uuidstr);
xenXMError(VIR_ERR_OPERATION_FAILED,
_("domain '%s' is already defined with uuid %s"),
entry->def->name, uuidstr);
entry = NULL;
goto error;
}
entry = NULL;
}
if (virHashLookup(priv->nameConfigMap, def->name)) {
/* domain exists, we will overwrite it */
if (!(oldfilename = (char *)virHashLookup(priv->nameConfigMap, def->name))) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
avoid many format string warnings Building with --disable-nls exposed many new warnings like these: virsh.c:4952: warning: format not a string literal and no format ... util.c:163: warning: format not a string literal and no format arguments All but one of the following changes add a "%s" argument before the offending _(...) argument. This was the only manual change: * src/lxc_driver.c (lxcVersion): Use %s and strerror(errno) rather than %m, to avoid a warning from gcc -Wformat-security. Add "%s" before each warned about format-string-with-no-%-directive: * src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML) (virDomainDefParseString, virDomainDefParseFile): * src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain) (__virGetNetwork, virReleaseNetwork, __virGetStoragePool) (virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol): * src/lxc_container.c (lxcContainerChild): * src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine) (lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML) (lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart) (lxcVersion, lxcGetSchedulerParameters): * src/network_conf.c (virNetworkDefParseString) (virNetworkDefParseFile): * src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains): * src/openvz_driver.c (openvzDomainDefineCmd) (openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown) (openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML) (openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine) (openvzDomainSetAutostart, openvzDomainGetAutostart) (openvzDomainSetVcpus): * src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek): * src/remote_internal.c (remoteDomainBlockPeek) (remoteDomainMemoryPeek, remoteAuthPolkit): * src/sexpr.c (sexpr_new, _string2sexpr): * src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol) (virStorageBackendDiskCreateVol): * src/storage_backend_fs.c (virStorageBackendFileSystemNetFindPoolSources): * src/storage_backend_logical.c (virStorageBackendLogicalFindLVs) (virStorageBackendLogicalFindPoolSources): * src/test.c (testOpenDefault, testOpenFromFile, testOpen) (testGetDomainInfo, testDomainRestore) (testNodeGetCellsFreeMemory): * src/util.c (virExec): * src/virsh.c (cmdAttachDevice, cmdDetachDevice) (cmdAttachInterface, cmdDetachInterface, cmdAttachDisk) (cmdDetachDisk, cmdEdit): * src/xend_internal.c (do_connect, wr_sync, xend_op_ext) (urlencode, xenDaemonDomainCreateXML) (xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID) (xenDaemonParseSxprOS, xend_parse_sexp_desc_char) (xenDaemonParseSxprChar, xenDaemonParseSxprDisks) (xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain) (xenDaemonDomainFetch, xenDaemonDomainGetAutostart) (xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform) (xenDaemonDomainDefineXML, xenDaemonGetSchedulerType) (xenDaemonGetSchedulerParameters) (xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek) (xenDaemonFormatSxprChr, virDomainXMLDevID): * src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu) (xenXMDomainCreate, xenXMDomainDefineXML) (xenXMDomainAttachDevice, xenXMDomainDetachDevice): * src/xml.c (virXPathString, virXPathNumber, virXPathLong) (virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet): * src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
"%s", _("can't retrieve config filename for domain to overwrite"));
goto error;
}
if (!(entry = virHashLookup(priv->configCache, oldfilename))) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
avoid many format string warnings Building with --disable-nls exposed many new warnings like these: virsh.c:4952: warning: format not a string literal and no format ... util.c:163: warning: format not a string literal and no format arguments All but one of the following changes add a "%s" argument before the offending _(...) argument. This was the only manual change: * src/lxc_driver.c (lxcVersion): Use %s and strerror(errno) rather than %m, to avoid a warning from gcc -Wformat-security. Add "%s" before each warned about format-string-with-no-%-directive: * src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML) (virDomainDefParseString, virDomainDefParseFile): * src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain) (__virGetNetwork, virReleaseNetwork, __virGetStoragePool) (virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol): * src/lxc_container.c (lxcContainerChild): * src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine) (lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML) (lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart) (lxcVersion, lxcGetSchedulerParameters): * src/network_conf.c (virNetworkDefParseString) (virNetworkDefParseFile): * src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains): * src/openvz_driver.c (openvzDomainDefineCmd) (openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown) (openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML) (openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine) (openvzDomainSetAutostart, openvzDomainGetAutostart) (openvzDomainSetVcpus): * src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek): * src/remote_internal.c (remoteDomainBlockPeek) (remoteDomainMemoryPeek, remoteAuthPolkit): * src/sexpr.c (sexpr_new, _string2sexpr): * src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol) (virStorageBackendDiskCreateVol): * src/storage_backend_fs.c (virStorageBackendFileSystemNetFindPoolSources): * src/storage_backend_logical.c (virStorageBackendLogicalFindLVs) (virStorageBackendLogicalFindPoolSources): * src/test.c (testOpenDefault, testOpenFromFile, testOpen) (testGetDomainInfo, testDomainRestore) (testNodeGetCellsFreeMemory): * src/util.c (virExec): * src/virsh.c (cmdAttachDevice, cmdDetachDevice) (cmdAttachInterface, cmdDetachInterface, cmdAttachDisk) (cmdDetachDisk, cmdEdit): * src/xend_internal.c (do_connect, wr_sync, xend_op_ext) (urlencode, xenDaemonDomainCreateXML) (xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID) (xenDaemonParseSxprOS, xend_parse_sexp_desc_char) (xenDaemonParseSxprChar, xenDaemonParseSxprDisks) (xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain) (xenDaemonDomainFetch, xenDaemonDomainGetAutostart) (xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform) (xenDaemonDomainDefineXML, xenDaemonGetSchedulerType) (xenDaemonGetSchedulerParameters) (xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek) (xenDaemonFormatSxprChr, virDomainXMLDevID): * src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu) (xenXMDomainCreate, xenXMDomainDefineXML) (xenXMDomainAttachDevice, xenXMDomainDetachDevice): * src/xml.c (virXPathString, virXPathNumber, virXPathLong) (virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet): * src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
"%s", _("can't retrieve config entry for domain to overwrite"));
goto error;
}
/* Remove the name -> filename mapping */
if (virHashRemoveEntry(priv->nameConfigMap, def->name, NULL) < 0) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
avoid many format string warnings Building with --disable-nls exposed many new warnings like these: virsh.c:4952: warning: format not a string literal and no format ... util.c:163: warning: format not a string literal and no format arguments All but one of the following changes add a "%s" argument before the offending _(...) argument. This was the only manual change: * src/lxc_driver.c (lxcVersion): Use %s and strerror(errno) rather than %m, to avoid a warning from gcc -Wformat-security. Add "%s" before each warned about format-string-with-no-%-directive: * src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML) (virDomainDefParseString, virDomainDefParseFile): * src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain) (__virGetNetwork, virReleaseNetwork, __virGetStoragePool) (virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol): * src/lxc_container.c (lxcContainerChild): * src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine) (lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML) (lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart) (lxcVersion, lxcGetSchedulerParameters): * src/network_conf.c (virNetworkDefParseString) (virNetworkDefParseFile): * src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains): * src/openvz_driver.c (openvzDomainDefineCmd) (openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown) (openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML) (openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine) (openvzDomainSetAutostart, openvzDomainGetAutostart) (openvzDomainSetVcpus): * src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek): * src/remote_internal.c (remoteDomainBlockPeek) (remoteDomainMemoryPeek, remoteAuthPolkit): * src/sexpr.c (sexpr_new, _string2sexpr): * src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol) (virStorageBackendDiskCreateVol): * src/storage_backend_fs.c (virStorageBackendFileSystemNetFindPoolSources): * src/storage_backend_logical.c (virStorageBackendLogicalFindLVs) (virStorageBackendLogicalFindPoolSources): * src/test.c (testOpenDefault, testOpenFromFile, testOpen) (testGetDomainInfo, testDomainRestore) (testNodeGetCellsFreeMemory): * src/util.c (virExec): * src/virsh.c (cmdAttachDevice, cmdDetachDevice) (cmdAttachInterface, cmdDetachInterface, cmdAttachDisk) (cmdDetachDisk, cmdEdit): * src/xend_internal.c (do_connect, wr_sync, xend_op_ext) (urlencode, xenDaemonDomainCreateXML) (xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID) (xenDaemonParseSxprOS, xend_parse_sexp_desc_char) (xenDaemonParseSxprChar, xenDaemonParseSxprDisks) (xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain) (xenDaemonDomainFetch, xenDaemonDomainGetAutostart) (xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform) (xenDaemonDomainDefineXML, xenDaemonGetSchedulerType) (xenDaemonGetSchedulerParameters) (xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek) (xenDaemonFormatSxprChr, virDomainXMLDevID): * src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu) (xenXMDomainCreate, xenXMDomainDefineXML) (xenXMDomainAttachDevice, xenXMDomainDetachDevice): * src/xml.c (virXPathString, virXPathNumber, virXPathLong) (virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet): * src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
"%s", _("failed to remove old domain from config map"));
goto error;
}
/* Remove the config record itself */
if (virHashRemoveEntry(priv->configCache, oldfilename, xenXMConfigFree) < 0) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
avoid many format string warnings Building with --disable-nls exposed many new warnings like these: virsh.c:4952: warning: format not a string literal and no format ... util.c:163: warning: format not a string literal and no format arguments All but one of the following changes add a "%s" argument before the offending _(...) argument. This was the only manual change: * src/lxc_driver.c (lxcVersion): Use %s and strerror(errno) rather than %m, to avoid a warning from gcc -Wformat-security. Add "%s" before each warned about format-string-with-no-%-directive: * src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML) (virDomainDefParseString, virDomainDefParseFile): * src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain) (__virGetNetwork, virReleaseNetwork, __virGetStoragePool) (virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol): * src/lxc_container.c (lxcContainerChild): * src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine) (lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML) (lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart) (lxcVersion, lxcGetSchedulerParameters): * src/network_conf.c (virNetworkDefParseString) (virNetworkDefParseFile): * src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains): * src/openvz_driver.c (openvzDomainDefineCmd) (openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown) (openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML) (openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine) (openvzDomainSetAutostart, openvzDomainGetAutostart) (openvzDomainSetVcpus): * src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek): * src/remote_internal.c (remoteDomainBlockPeek) (remoteDomainMemoryPeek, remoteAuthPolkit): * src/sexpr.c (sexpr_new, _string2sexpr): * src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol) (virStorageBackendDiskCreateVol): * src/storage_backend_fs.c (virStorageBackendFileSystemNetFindPoolSources): * src/storage_backend_logical.c (virStorageBackendLogicalFindLVs) (virStorageBackendLogicalFindPoolSources): * src/test.c (testOpenDefault, testOpenFromFile, testOpen) (testGetDomainInfo, testDomainRestore) (testNodeGetCellsFreeMemory): * src/util.c (virExec): * src/virsh.c (cmdAttachDevice, cmdDetachDevice) (cmdAttachInterface, cmdDetachInterface, cmdAttachDisk) (cmdDetachDisk, cmdEdit): * src/xend_internal.c (do_connect, wr_sync, xend_op_ext) (urlencode, xenDaemonDomainCreateXML) (xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID) (xenDaemonParseSxprOS, xend_parse_sexp_desc_char) (xenDaemonParseSxprChar, xenDaemonParseSxprDisks) (xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain) (xenDaemonDomainFetch, xenDaemonDomainGetAutostart) (xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform) (xenDaemonDomainDefineXML, xenDaemonGetSchedulerType) (xenDaemonGetSchedulerParameters) (xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek) (xenDaemonFormatSxprChr, virDomainXMLDevID): * src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu) (xenXMDomainCreate, xenXMDomainDefineXML) (xenXMDomainAttachDevice, xenXMDomainDetachDevice): * src/xml.c (virXPathString, virXPathNumber, virXPathLong) (virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet): * src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
"%s", _("failed to remove old domain from config map"));
goto error;
}
entry = NULL;
}
2006-11-16 19:06:13 +00:00
if ((strlen(priv->configDir) + 1 + strlen(def->name) + 1) > PATH_MAX) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
avoid many format string warnings Building with --disable-nls exposed many new warnings like these: virsh.c:4952: warning: format not a string literal and no format ... util.c:163: warning: format not a string literal and no format arguments All but one of the following changes add a "%s" argument before the offending _(...) argument. This was the only manual change: * src/lxc_driver.c (lxcVersion): Use %s and strerror(errno) rather than %m, to avoid a warning from gcc -Wformat-security. Add "%s" before each warned about format-string-with-no-%-directive: * src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML) (virDomainDefParseString, virDomainDefParseFile): * src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain) (__virGetNetwork, virReleaseNetwork, __virGetStoragePool) (virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol): * src/lxc_container.c (lxcContainerChild): * src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine) (lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML) (lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart) (lxcVersion, lxcGetSchedulerParameters): * src/network_conf.c (virNetworkDefParseString) (virNetworkDefParseFile): * src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains): * src/openvz_driver.c (openvzDomainDefineCmd) (openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown) (openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML) (openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine) (openvzDomainSetAutostart, openvzDomainGetAutostart) (openvzDomainSetVcpus): * src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek): * src/remote_internal.c (remoteDomainBlockPeek) (remoteDomainMemoryPeek, remoteAuthPolkit): * src/sexpr.c (sexpr_new, _string2sexpr): * src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol) (virStorageBackendDiskCreateVol): * src/storage_backend_fs.c (virStorageBackendFileSystemNetFindPoolSources): * src/storage_backend_logical.c (virStorageBackendLogicalFindLVs) (virStorageBackendLogicalFindPoolSources): * src/test.c (testOpenDefault, testOpenFromFile, testOpen) (testGetDomainInfo, testDomainRestore) (testNodeGetCellsFreeMemory): * src/util.c (virExec): * src/virsh.c (cmdAttachDevice, cmdDetachDevice) (cmdAttachInterface, cmdDetachInterface, cmdAttachDisk) (cmdDetachDisk, cmdEdit): * src/xend_internal.c (do_connect, wr_sync, xend_op_ext) (urlencode, xenDaemonDomainCreateXML) (xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID) (xenDaemonParseSxprOS, xend_parse_sexp_desc_char) (xenDaemonParseSxprChar, xenDaemonParseSxprDisks) (xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain) (xenDaemonDomainFetch, xenDaemonDomainGetAutostart) (xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform) (xenDaemonDomainDefineXML, xenDaemonGetSchedulerType) (xenDaemonGetSchedulerParameters) (xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek) (xenDaemonFormatSxprChr, virDomainXMLDevID): * src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu) (xenXMDomainCreate, xenXMDomainDefineXML) (xenXMDomainAttachDevice, xenXMDomainDetachDevice): * src/xml.c (virXPathString, virXPathNumber, virXPathLong) (virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet): * src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
"%s", _("config file name is too long"));
2006-11-16 19:06:13 +00:00
goto error;
}
2006-11-16 19:06:13 +00:00
strcpy(filename, priv->configDir);
2006-11-16 19:06:13 +00:00
strcat(filename, "/");
strcat(filename, def->name);
2006-11-16 19:06:13 +00:00
if (xenXMConfigSaveFile(conn, filename, def) < 0)
2006-11-16 19:06:13 +00:00
goto error;
if (VIR_ALLOC(entry) < 0) {
virReportOOMError();
2006-11-16 19:06:13 +00:00
goto error;
}
2006-11-16 19:06:13 +00:00
if ((entry->refreshedAt = time(NULL)) == ((time_t)-1)) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
avoid many format string warnings Building with --disable-nls exposed many new warnings like these: virsh.c:4952: warning: format not a string literal and no format ... util.c:163: warning: format not a string literal and no format arguments All but one of the following changes add a "%s" argument before the offending _(...) argument. This was the only manual change: * src/lxc_driver.c (lxcVersion): Use %s and strerror(errno) rather than %m, to avoid a warning from gcc -Wformat-security. Add "%s" before each warned about format-string-with-no-%-directive: * src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML) (virDomainDefParseString, virDomainDefParseFile): * src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain) (__virGetNetwork, virReleaseNetwork, __virGetStoragePool) (virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol): * src/lxc_container.c (lxcContainerChild): * src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine) (lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML) (lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart) (lxcVersion, lxcGetSchedulerParameters): * src/network_conf.c (virNetworkDefParseString) (virNetworkDefParseFile): * src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains): * src/openvz_driver.c (openvzDomainDefineCmd) (openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown) (openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML) (openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine) (openvzDomainSetAutostart, openvzDomainGetAutostart) (openvzDomainSetVcpus): * src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek): * src/remote_internal.c (remoteDomainBlockPeek) (remoteDomainMemoryPeek, remoteAuthPolkit): * src/sexpr.c (sexpr_new, _string2sexpr): * src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol) (virStorageBackendDiskCreateVol): * src/storage_backend_fs.c (virStorageBackendFileSystemNetFindPoolSources): * src/storage_backend_logical.c (virStorageBackendLogicalFindLVs) (virStorageBackendLogicalFindPoolSources): * src/test.c (testOpenDefault, testOpenFromFile, testOpen) (testGetDomainInfo, testDomainRestore) (testNodeGetCellsFreeMemory): * src/util.c (virExec): * src/virsh.c (cmdAttachDevice, cmdDetachDevice) (cmdAttachInterface, cmdDetachInterface, cmdAttachDisk) (cmdDetachDisk, cmdEdit): * src/xend_internal.c (do_connect, wr_sync, xend_op_ext) (urlencode, xenDaemonDomainCreateXML) (xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID) (xenDaemonParseSxprOS, xend_parse_sexp_desc_char) (xenDaemonParseSxprChar, xenDaemonParseSxprDisks) (xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain) (xenDaemonDomainFetch, xenDaemonDomainGetAutostart) (xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform) (xenDaemonDomainDefineXML, xenDaemonGetSchedulerType) (xenDaemonGetSchedulerParameters) (xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek) (xenDaemonFormatSxprChr, virDomainXMLDevID): * src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu) (xenXMDomainCreate, xenXMDomainDefineXML) (xenXMDomainAttachDevice, xenXMDomainDetachDevice): * src/xml.c (virXPathString, virXPathNumber, virXPathLong) (virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet): * src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
"%s", _("unable to get current time"));
2006-11-16 19:06:13 +00:00
goto error;
}
2006-11-16 19:06:13 +00:00
memmove(entry->filename, filename, PATH_MAX);
entry->def = def;
2006-11-16 19:06:13 +00:00
if (virHashAddEntry(priv->configCache, filename, entry) < 0) {
xenXMError(VIR_ERR_INTERNAL_ERROR,
avoid many format string warnings Building with --disable-nls exposed many new warnings like these: virsh.c:4952: warning: format not a string literal and no format ... util.c:163: warning: format not a string literal and no format arguments All but one of the following changes add a "%s" argument before the offending _(...) argument. This was the only manual change: * src/lxc_driver.c (lxcVersion): Use %s and strerror(errno) rather than %m, to avoid a warning from gcc -Wformat-security. Add "%s" before each warned about format-string-with-no-%-directive: * src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML) (virDomainDefParseString, virDomainDefParseFile): * src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain) (__virGetNetwork, virReleaseNetwork, __virGetStoragePool) (virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol): * src/lxc_container.c (lxcContainerChild): * src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine) (lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML) (lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart) (lxcVersion, lxcGetSchedulerParameters): * src/network_conf.c (virNetworkDefParseString) (virNetworkDefParseFile): * src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains): * src/openvz_driver.c (openvzDomainDefineCmd) (openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown) (openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML) (openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine) (openvzDomainSetAutostart, openvzDomainGetAutostart) (openvzDomainSetVcpus): * src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek): * src/remote_internal.c (remoteDomainBlockPeek) (remoteDomainMemoryPeek, remoteAuthPolkit): * src/sexpr.c (sexpr_new, _string2sexpr): * src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol) (virStorageBackendDiskCreateVol): * src/storage_backend_fs.c (virStorageBackendFileSystemNetFindPoolSources): * src/storage_backend_logical.c (virStorageBackendLogicalFindLVs) (virStorageBackendLogicalFindPoolSources): * src/test.c (testOpenDefault, testOpenFromFile, testOpen) (testGetDomainInfo, testDomainRestore) (testNodeGetCellsFreeMemory): * src/util.c (virExec): * src/virsh.c (cmdAttachDevice, cmdDetachDevice) (cmdAttachInterface, cmdDetachInterface, cmdAttachDisk) (cmdDetachDisk, cmdEdit): * src/xend_internal.c (do_connect, wr_sync, xend_op_ext) (urlencode, xenDaemonDomainCreateXML) (xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID) (xenDaemonParseSxprOS, xend_parse_sexp_desc_char) (xenDaemonParseSxprChar, xenDaemonParseSxprDisks) (xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain) (xenDaemonDomainFetch, xenDaemonDomainGetAutostart) (xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform) (xenDaemonDomainDefineXML, xenDaemonGetSchedulerType) (xenDaemonGetSchedulerParameters) (xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek) (xenDaemonFormatSxprChr, virDomainXMLDevID): * src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu) (xenXMDomainCreate, xenXMDomainDefineXML) (xenXMDomainAttachDevice, xenXMDomainDetachDevice): * src/xml.c (virXPathString, virXPathNumber, virXPathLong) (virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet): * src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
"%s", _("unable to store config file handle"));
goto error;
}
if (virHashAddEntry(priv->nameConfigMap, def->name, entry->filename) < 0) {
virHashRemoveEntry(priv->configCache, filename, NULL);
xenXMError(VIR_ERR_INTERNAL_ERROR,
avoid many format string warnings Building with --disable-nls exposed many new warnings like these: virsh.c:4952: warning: format not a string literal and no format ... util.c:163: warning: format not a string literal and no format arguments All but one of the following changes add a "%s" argument before the offending _(...) argument. This was the only manual change: * src/lxc_driver.c (lxcVersion): Use %s and strerror(errno) rather than %m, to avoid a warning from gcc -Wformat-security. Add "%s" before each warned about format-string-with-no-%-directive: * src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML) (virDomainDefParseString, virDomainDefParseFile): * src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain) (__virGetNetwork, virReleaseNetwork, __virGetStoragePool) (virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol): * src/lxc_container.c (lxcContainerChild): * src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine) (lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML) (lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart) (lxcVersion, lxcGetSchedulerParameters): * src/network_conf.c (virNetworkDefParseString) (virNetworkDefParseFile): * src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains): * src/openvz_driver.c (openvzDomainDefineCmd) (openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown) (openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML) (openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine) (openvzDomainSetAutostart, openvzDomainGetAutostart) (openvzDomainSetVcpus): * src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek): * src/remote_internal.c (remoteDomainBlockPeek) (remoteDomainMemoryPeek, remoteAuthPolkit): * src/sexpr.c (sexpr_new, _string2sexpr): * src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol) (virStorageBackendDiskCreateVol): * src/storage_backend_fs.c (virStorageBackendFileSystemNetFindPoolSources): * src/storage_backend_logical.c (virStorageBackendLogicalFindLVs) (virStorageBackendLogicalFindPoolSources): * src/test.c (testOpenDefault, testOpenFromFile, testOpen) (testGetDomainInfo, testDomainRestore) (testNodeGetCellsFreeMemory): * src/util.c (virExec): * src/virsh.c (cmdAttachDevice, cmdDetachDevice) (cmdAttachInterface, cmdDetachInterface, cmdAttachDisk) (cmdDetachDisk, cmdEdit): * src/xend_internal.c (do_connect, wr_sync, xend_op_ext) (urlencode, xenDaemonDomainCreateXML) (xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID) (xenDaemonParseSxprOS, xend_parse_sexp_desc_char) (xenDaemonParseSxprChar, xenDaemonParseSxprDisks) (xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain) (xenDaemonDomainFetch, xenDaemonDomainGetAutostart) (xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform) (xenDaemonDomainDefineXML, xenDaemonGetSchedulerType) (xenDaemonGetSchedulerParameters) (xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek) (xenDaemonFormatSxprChr, virDomainXMLDevID): * src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu) (xenXMDomainCreate, xenXMDomainDefineXML) (xenXMDomainAttachDevice, xenXMDomainDetachDevice): * src/xml.c (virXPathString, virXPathNumber, virXPathLong) (virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet): * src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
"%s", _("unable to store config file handle"));
2006-11-16 19:06:13 +00:00
goto error;
}
ret = virGetDomain(conn, def->name, def->uuid);
2009-01-21 18:11:14 +00:00
xenUnifiedUnlock(priv);
2006-11-16 19:06:13 +00:00
return (ret);
error:
VIR_FREE(entry);
virDomainDefFree(def);
2009-01-21 18:11:14 +00:00
xenUnifiedUnlock(priv);
2006-11-16 19:06:13 +00:00
return (NULL);
}
/*
* Delete a domain from disk
*/
int xenXMDomainUndefine(virDomainPtr domain) {
xenUnifiedPrivatePtr priv;
const char *filename;
2006-11-16 19:06:13 +00:00
xenXMConfCachePtr entry;
2009-01-21 18:11:14 +00:00
int ret = -1;
2006-11-16 19:06:13 +00:00
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
2006-11-16 19:06:13 +00:00
return (-1);
}
if (domain->id != -1)
2006-11-16 19:06:13 +00:00
return (-1);
if (domain->conn->flags & VIR_CONNECT_RO)
return (-1);
priv = domain->conn->privateData;
2009-01-21 18:11:14 +00:00
xenUnifiedLock(priv);
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
2009-01-21 18:11:14 +00:00
goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename)))
2009-01-21 18:11:14 +00:00
goto cleanup;
2006-11-16 19:06:13 +00:00
if (unlink(entry->filename) < 0)
2009-01-21 18:11:14 +00:00
goto cleanup;
2006-11-16 19:06:13 +00:00
/* Remove the name -> filename mapping */
if (virHashRemoveEntry(priv->nameConfigMap, domain->name, NULL) < 0)
2009-01-21 18:11:14 +00:00
goto cleanup;
/* Remove the config record itself */
if (virHashRemoveEntry(priv->configCache, entry->filename, xenXMConfigFree) < 0)
2009-01-21 18:11:14 +00:00
goto cleanup;
2006-11-16 19:06:13 +00:00
2009-01-21 18:11:14 +00:00
ret = 0;
cleanup:
xenUnifiedUnlock(priv);
return ret;
2006-11-16 19:06:13 +00:00
}
struct xenXMListIteratorContext {
virConnectPtr conn;
int oom;
2006-11-16 19:06:13 +00:00
int max;
int count;
2007-03-06 21:55:44 +00:00
char ** names;
2006-11-16 19:06:13 +00:00
};
static void xenXMListIterator(void *payload ATTRIBUTE_UNUSED, const char *name, void *data) {
struct xenXMListIteratorContext *ctx = data;
2006-11-16 19:06:13 +00:00
virDomainPtr dom = NULL;
if (ctx->oom)
return;
2006-11-16 19:06:13 +00:00
if (ctx->count == ctx->max)
return;
dom = xenDaemonLookupByName(ctx->conn, name);
2006-11-16 19:06:13 +00:00
if (!dom) {
if (!(ctx->names[ctx->count] = strdup(name)))
ctx->oom = 1;
else
ctx->count++;
2006-11-16 19:06:13 +00:00
} else {
virDomainFree(dom);
}
}
/*
* List all defined domains, filtered to remove any which
* are currently running
*/
2007-03-06 21:55:44 +00:00
int xenXMListDefinedDomains(virConnectPtr conn, char **const names, int maxnames) {
xenUnifiedPrivatePtr priv;
2006-11-16 19:06:13 +00:00
struct xenXMListIteratorContext ctx;
int i, ret = -1;
2006-11-16 19:06:13 +00:00
if (!VIR_IS_CONNECT(conn)) {
xenXMError(VIR_ERR_INVALID_CONN, __FUNCTION__);
2006-11-16 19:06:13 +00:00
return (-1);
}
priv = conn->privateData;
2009-01-21 18:11:14 +00:00
xenUnifiedLock(priv);
if (!xenInotifyActive(conn) && xenXMConfigCacheRefresh (conn) < 0)
2009-01-21 18:11:14 +00:00
goto cleanup;
2006-11-16 19:06:13 +00:00
if (maxnames > virHashSize(priv->configCache))
maxnames = virHashSize(priv->configCache);
2006-11-16 19:06:13 +00:00
ctx.conn = conn;
ctx.oom = 0;
2006-11-16 19:06:13 +00:00
ctx.count = 0;
ctx.max = maxnames;
ctx.names = names;
virHashForEach(priv->nameConfigMap, xenXMListIterator, &ctx);
if (ctx.oom) {
for (i = 0; i < ctx.count; i++)
VIR_FREE(ctx.names[i]);
virReportOOMError();
goto cleanup;
}
2009-01-21 18:11:14 +00:00
ret = ctx.count;
cleanup:
xenUnifiedUnlock(priv);
return ret;
2006-11-16 19:06:13 +00:00
}
/*
* Return the maximum number of defined domains - not filtered
* based on number running
*/
int xenXMNumOfDefinedDomains(virConnectPtr conn) {
xenUnifiedPrivatePtr priv;
2009-01-21 18:11:14 +00:00
int ret = -1;
2006-11-16 19:06:13 +00:00
if (!VIR_IS_CONNECT(conn)) {
xenXMError(VIR_ERR_INVALID_CONN, __FUNCTION__);
2006-11-16 19:06:13 +00:00
return (-1);
}
priv = conn->privateData;
2009-01-21 18:11:14 +00:00
xenUnifiedLock(priv);
if (!xenInotifyActive(conn) && xenXMConfigCacheRefresh (conn) < 0)
2009-01-21 18:11:14 +00:00
goto cleanup;
2006-11-16 19:06:13 +00:00
2009-01-21 18:11:14 +00:00
ret = virHashSize(priv->nameConfigMap);
cleanup:
xenUnifiedUnlock(priv);
return ret;
2006-11-16 19:06:13 +00:00
}
/**
* xenXMDomainAttachDeviceFlags:
* @domain: pointer to domain object
* @xml: pointer to XML description of device
* @flags: an OR'ed set of virDomainDeviceModifyFlags
2008-02-07 12:34:19 +00:00
*
* Create a virtual device attachment to backend.
* XML description is translated into config file.
* This driver only supports device allocation to
* persisted config.
2008-02-07 12:34:19 +00:00
*
* Returns 0 in case of success, -1 in case of failure.
*/
static int
xenXMDomainAttachDeviceFlags(virDomainPtr domain, const char *xml,
unsigned int flags) {
const char *filename = NULL;
xenXMConfCachePtr entry = NULL;
int ret = -1;
virDomainDeviceDefPtr dev = NULL;
virDomainDefPtr def;
xenUnifiedPrivatePtr priv;
if ((!domain) || (!domain->conn) || (!domain->name) || (!xml)) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1;
}
if (domain->conn->flags & VIR_CONNECT_RO)
return -1;
if (domain->id != -1 && !(flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG))
return -1;
2009-01-21 18:11:14 +00:00
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
xenUnifiedLock(priv);
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
2009-01-21 18:11:14 +00:00
goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename)))
2009-01-21 18:11:14 +00:00
goto cleanup;
def = entry->def;
if (!(dev = virDomainDeviceDefParse(priv->caps,
entry->def,
2009-01-08 19:52:15 +00:00
xml, VIR_DOMAIN_XML_INACTIVE)))
2009-01-21 18:11:14 +00:00
goto cleanup;
switch (dev->type) {
case VIR_DOMAIN_DEVICE_DISK:
{
if (virDomainDiskInsert(def, dev->data.disk) < 0) {
virReportOOMError();
goto cleanup;
}
dev->data.disk = NULL;
}
break;
case VIR_DOMAIN_DEVICE_NET:
{
if (VIR_REALLOC_N(def->nets, def->nnets+1) < 0) {
virReportOOMError();
goto cleanup;
}
def->nets[def->nnets++] = dev->data.net;
dev->data.net = NULL;
break;
}
default:
xenXMError(VIR_ERR_XML_ERROR,
avoid many format string warnings Building with --disable-nls exposed many new warnings like these: virsh.c:4952: warning: format not a string literal and no format ... util.c:163: warning: format not a string literal and no format arguments All but one of the following changes add a "%s" argument before the offending _(...) argument. This was the only manual change: * src/lxc_driver.c (lxcVersion): Use %s and strerror(errno) rather than %m, to avoid a warning from gcc -Wformat-security. Add "%s" before each warned about format-string-with-no-%-directive: * src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML) (virDomainDefParseString, virDomainDefParseFile): * src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain) (__virGetNetwork, virReleaseNetwork, __virGetStoragePool) (virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol): * src/lxc_container.c (lxcContainerChild): * src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine) (lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML) (lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart) (lxcVersion, lxcGetSchedulerParameters): * src/network_conf.c (virNetworkDefParseString) (virNetworkDefParseFile): * src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains): * src/openvz_driver.c (openvzDomainDefineCmd) (openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown) (openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML) (openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine) (openvzDomainSetAutostart, openvzDomainGetAutostart) (openvzDomainSetVcpus): * src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek): * src/remote_internal.c (remoteDomainBlockPeek) (remoteDomainMemoryPeek, remoteAuthPolkit): * src/sexpr.c (sexpr_new, _string2sexpr): * src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol) (virStorageBackendDiskCreateVol): * src/storage_backend_fs.c (virStorageBackendFileSystemNetFindPoolSources): * src/storage_backend_logical.c (virStorageBackendLogicalFindLVs) (virStorageBackendLogicalFindPoolSources): * src/test.c (testOpenDefault, testOpenFromFile, testOpen) (testGetDomainInfo, testDomainRestore) (testNodeGetCellsFreeMemory): * src/util.c (virExec): * src/virsh.c (cmdAttachDevice, cmdDetachDevice) (cmdAttachInterface, cmdDetachInterface, cmdAttachDisk) (cmdDetachDisk, cmdEdit): * src/xend_internal.c (do_connect, wr_sync, xend_op_ext) (urlencode, xenDaemonDomainCreateXML) (xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID) (xenDaemonParseSxprOS, xend_parse_sexp_desc_char) (xenDaemonParseSxprChar, xenDaemonParseSxprDisks) (xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain) (xenDaemonDomainFetch, xenDaemonDomainGetAutostart) (xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform) (xenDaemonDomainDefineXML, xenDaemonGetSchedulerType) (xenDaemonGetSchedulerParameters) (xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek) (xenDaemonFormatSxprChr, virDomainXMLDevID): * src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu) (xenXMDomainCreate, xenXMDomainDefineXML) (xenXMDomainAttachDevice, xenXMDomainDetachDevice): * src/xml.c (virXPathString, virXPathNumber, virXPathLong) (virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet): * src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
"%s", _("unknown device"));
goto cleanup;
}
/* If this fails, should we try to undo our changes to the
* in-memory representation of the config file. I say not!
*/
if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
goto cleanup;
ret = 0;
cleanup:
virDomainDeviceDefFree(dev);
2009-01-21 18:11:14 +00:00
xenUnifiedUnlock(priv);
return ret;
}
/**
* xenXMDomainDetachDeviceFlags:
* @domain: pointer to domain object
* @xml: pointer to XML description of device
* @flags: an OR'ed set of virDomainDeviceModifyFlags
2008-02-07 12:34:19 +00:00
*
* Destroy a virtual device attachment to backend.
* This driver only supports device deallocation from
* persisted config.
*
* Returns 0 in case of success, -1 in case of failure.
*/
static int
xenXMDomainDetachDeviceFlags(virDomainPtr domain, const char *xml,
unsigned int flags) {
const char *filename = NULL;
xenXMConfCachePtr entry = NULL;
virDomainDeviceDefPtr dev = NULL;
virDomainDefPtr def;
int ret = -1;
int i;
xenUnifiedPrivatePtr priv;
if ((!domain) || (!domain->conn) || (!domain->name) || (!xml)) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1;
}
if (domain->conn->flags & VIR_CONNECT_RO)
return -1;
if (domain->id != -1 && !(flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG))
return -1;
2009-01-21 18:11:14 +00:00
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
xenUnifiedLock(priv);
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
2009-01-21 18:11:14 +00:00
goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename)))
2009-01-21 18:11:14 +00:00
goto cleanup;
def = entry->def;
if (!(dev = virDomainDeviceDefParse(priv->caps,
entry->def,
2009-01-08 19:52:15 +00:00
xml, VIR_DOMAIN_XML_INACTIVE)))
2009-01-21 18:11:14 +00:00
goto cleanup;
switch (dev->type) {
case VIR_DOMAIN_DEVICE_DISK:
{
for (i = 0 ; i < def->ndisks ; i++) {
if (def->disks[i]->dst &&
dev->data.disk->dst &&
STREQ(def->disks[i]->dst, dev->data.disk->dst)) {
virDomainDiskDefFree(def->disks[i]);
if (i < (def->ndisks - 1))
memmove(def->disks + i,
def->disks + i + 1,
sizeof(*def->disks) *
(def->ndisks - (i + 1)));
2010-08-17 14:14:28 +00:00
def->ndisks--;
break;
}
}
break;
}
case VIR_DOMAIN_DEVICE_NET:
{
for (i = 0 ; i < def->nnets ; i++) {
if (!memcmp(def->nets[i]->mac,
dev->data.net->mac,
sizeof(def->nets[i]->mac))) {
virDomainNetDefFree(def->nets[i]);
if (i < (def->nnets - 1))
memmove(def->nets + i,
def->nets + i + 1,
sizeof(*def->nets) *
(def->nnets - (i + 1)));
2010-08-17 14:14:28 +00:00
def->nnets--;
break;
}
}
break;
}
default:
xenXMError(VIR_ERR_XML_ERROR,
avoid many format string warnings Building with --disable-nls exposed many new warnings like these: virsh.c:4952: warning: format not a string literal and no format ... util.c:163: warning: format not a string literal and no format arguments All but one of the following changes add a "%s" argument before the offending _(...) argument. This was the only manual change: * src/lxc_driver.c (lxcVersion): Use %s and strerror(errno) rather than %m, to avoid a warning from gcc -Wformat-security. Add "%s" before each warned about format-string-with-no-%-directive: * src/domain_conf.c (virDomainHostdevSubsysUsbDefParseXML) (virDomainDefParseString, virDomainDefParseFile): * src/hash.c (virGetConnect, __virGetDomain, virReleaseDomain) (__virGetNetwork, virReleaseNetwork, __virGetStoragePool) (virReleaseStoragePool, __virGetStorageVol, virReleaseStorageVol): * src/lxc_container.c (lxcContainerChild): * src/lxc_driver.c (lxcDomainDefine, lxcDomainUndefine) (lxcDomainGetInfo, lxcGetOSType, lxcDomainDumpXML) (lxcSetupInterfaces, lxcDomainStart, lxcDomainCreateAndStart) (lxcVersion, lxcGetSchedulerParameters): * src/network_conf.c (virNetworkDefParseString) (virNetworkDefParseFile): * src/openvz_conf.c (openvzReadNetworkConf, openvzLoadDomains): * src/openvz_driver.c (openvzDomainDefineCmd) (openvzDomainGetInfo, openvzDomainDumpXML, openvzDomainShutdown) (openvzDomainReboot, ADD_ARG_LIT, openvzDomainDefineXML) (openvzDomainCreateXML, openvzDomainCreate, openvzDomainUndefine) (openvzDomainSetAutostart, openvzDomainGetAutostart) (openvzDomainSetVcpus): * src/qemu_driver.c (qemudDomainBlockPeek, qemudDomainMemoryPeek): * src/remote_internal.c (remoteDomainBlockPeek) (remoteDomainMemoryPeek, remoteAuthPolkit): * src/sexpr.c (sexpr_new, _string2sexpr): * src/storage_backend_disk.c (virStorageBackendDiskMakeDataVol) (virStorageBackendDiskCreateVol): * src/storage_backend_fs.c (virStorageBackendFileSystemNetFindPoolSources): * src/storage_backend_logical.c (virStorageBackendLogicalFindLVs) (virStorageBackendLogicalFindPoolSources): * src/test.c (testOpenDefault, testOpenFromFile, testOpen) (testGetDomainInfo, testDomainRestore) (testNodeGetCellsFreeMemory): * src/util.c (virExec): * src/virsh.c (cmdAttachDevice, cmdDetachDevice) (cmdAttachInterface, cmdDetachInterface, cmdAttachDisk) (cmdDetachDisk, cmdEdit): * src/xend_internal.c (do_connect, wr_sync, xend_op_ext) (urlencode, xenDaemonDomainCreateXML) (xenDaemonDomainLookupByName_ids, xenDaemonDomainLookupByID) (xenDaemonParseSxprOS, xend_parse_sexp_desc_char) (xenDaemonParseSxprChar, xenDaemonParseSxprDisks) (xenDaemonParseSxpr, sexpr_to_xend_topology, sexpr_to_domain) (xenDaemonDomainFetch, xenDaemonDomainGetAutostart) (xenDaemonDomainSetAutostart, xenDaemonDomainMigratePerform) (xenDaemonDomainDefineXML, xenDaemonGetSchedulerType) (xenDaemonGetSchedulerParameters) (xenDaemonSetSchedulerParameters, xenDaemonDomainBlockPeek) (xenDaemonFormatSxprChr, virDomainXMLDevID): * src/xm_internal.c (xenXMConfigCacheRefresh, xenXMDomainPinVcpu) (xenXMDomainCreate, xenXMDomainDefineXML) (xenXMDomainAttachDevice, xenXMDomainDetachDevice): * src/xml.c (virXPathString, virXPathNumber, virXPathLong) (virXPathULong, virXPathBoolean, virXPathNode, virXPathNodeSet): * src/xs_internal.c (xenStoreOpen):
2008-10-13 16:46:28 +00:00
"%s", _("unknown device"));
goto cleanup;
}
/* If this fails, should we try to undo our changes to the
* in-memory representation of the config file. I say not!
*/
if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
goto cleanup;
ret = 0;
cleanup:
virDomainDeviceDefFree(dev);
2009-01-21 18:11:14 +00:00
xenUnifiedUnlock(priv);
return (ret);
}
int
xenXMDomainBlockPeek (virDomainPtr dom ATTRIBUTE_UNUSED,
const char *path ATTRIBUTE_UNUSED,
unsigned long long offset ATTRIBUTE_UNUSED,
size_t size ATTRIBUTE_UNUSED,
void *buffer ATTRIBUTE_UNUSED)
{
xenXMError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
return -1;
}
2008-11-25 11:04:34 +00:00
static char *xenXMAutostartLinkName(virDomainPtr dom)
{
char *ret;
if (virAsprintf(&ret, "/etc/xen/auto/%s", dom->name) < 0)
return NULL;
2008-11-25 11:04:34 +00:00
return ret;
}
static char *xenXMDomainConfigName(virDomainPtr dom)
{
char *ret;
if (virAsprintf(&ret, "/etc/xen/%s", dom->name) < 0)
return NULL;
2008-11-25 11:04:34 +00:00
return ret;
}
int xenXMDomainGetAutostart(virDomainPtr dom, int *autostart)
{
char *linkname = xenXMAutostartLinkName(dom);
char *config = xenXMDomainConfigName(dom);
int ret = -1;
if (!linkname || !config) {
virReportOOMError();
2008-11-25 11:04:34 +00:00
goto cleanup;
}
*autostart = virFileLinkPointsTo(linkname, config);
if (*autostart < 0) {
virReportSystemError(errno,
_("cannot check link %s points to config %s"),
linkname, config);
2008-11-25 11:04:34 +00:00
goto cleanup;
}
ret = 0;
cleanup:
VIR_FREE(linkname);
VIR_FREE(config);
return ret;
}
int xenXMDomainSetAutostart(virDomainPtr dom, int autostart)
{
char *linkname = xenXMAutostartLinkName(dom);
char *config = xenXMDomainConfigName(dom);
int ret = -1;
if (!linkname || !config) {
virReportOOMError();
2008-11-25 11:04:34 +00:00
goto cleanup;
}
if (autostart) {
if (symlink(config, linkname) < 0 &&
errno != EEXIST) {
virReportSystemError(errno,
_("failed to create link %s to %s"),
config, linkname);
2008-11-25 11:04:34 +00:00
goto cleanup;
}
} else {
if (unlink(linkname) < 0 &&
errno != ENOENT) {
virReportSystemError(errno,
_("failed to remove link %s"),
linkname);
2008-11-25 11:04:34 +00:00
goto cleanup;
}
}
ret = 0;
cleanup:
VIR_FREE(linkname);
VIR_FREE(config);
return ret;
}