libvirt/src/xen/xm_internal.c

1651 lines
45 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-2011 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"
2011-02-21 13:40:08 +00:00
#include "xen_sxpr.h"
2011-02-21 13:40:10 +00:00
#include "xen_xm.h"
2006-11-16 19:06:13 +00:00
#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"
#include "count-one-bits.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
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 */
NULL, /* domainScreenshot */
xenXMDomainPinVcpu, /* domainPinVcpu */
2006-11-16 19:06:13 +00:00
NULL, /* domainGetVcpus */
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(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
/* Release memory associated with a cached config object */
static void xenXMConfigFree(void *payload, const void *key ATTRIBUTE_UNUSED) {
2006-11-16 19:06:13 +00:00
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 void *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);
}
return (1);
}
return (0);
}
static virDomainDefPtr
xenXMConfigReadFile(virConnectPtr conn, const char *filename) {
virConfPtr conf;
virDomainDefPtr def;
2011-02-21 13:40:10 +00:00
xenUnifiedPrivatePtr priv = conn->privateData;
if (!(conf = virConfReadFile(filename, 0)))
return NULL;
2011-02-21 13:40:12 +00:00
def = xenParseXM(conf, priv->xendConfigVersion, priv->caps);
virConfFree(conf);
return def;
}
static int
xenXMConfigSaveFile(virConnectPtr conn, const char *filename, virDomainDefPtr def) {
virConfPtr conf;
2011-02-21 13:40:11 +00:00
xenUnifiedPrivatePtr priv = conn->privateData;
int ret;
2011-02-21 13:40:12 +00:00
if (!(conf = xenFormatXM(conn, def, priv->xendConfigVersion)))
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) {
VIR_DEBUG("No config entry for %s", filename);
return 0;
}
virHashRemoveEntry(priv->nameConfigMap, entry->def->name);
virHashRemoveEntry(priv->configCache, filename);
VIR_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);
VIR_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) {
VIR_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);
}
/* 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))) {
VIR_DEBUG("Failed to read %s", entry->filename);
if (!newborn)
virHashSteal(priv->configCache, filename);
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) {
virHashSteal(priv->configCache, filename);
virDomainDefFree(entry->def);
VIR_FREE(entry);
}
}
VIR_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;
2006-11-16 19:06:13 +00:00
/*
* 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 (!(path = virFileBuildPath(priv->configDir, ent->d_name, NULL))) {
closedir(dh);
return -1;
}
2006-11-16 19:06:13 +00:00
/* Skip anything which isn't a file (takes care of scripts/ subdir */
if ((stat(path, &st) < 0) ||
(!S_ISREG(st.st_mode))) {
VIR_FREE(path);
2006-11-16 19:06:13 +00:00
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 */
}
VIR_FREE(path);
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, &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, xenXMConfigFree);
if (!priv->configCache)
return (-1);
priv->nameConfigMap = virHashCreate(50, NULL);
if (!priv->nameConfigMap) {
virHashFree(priv->configCache);
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);
virHashFree(priv->configCache);
2006-11-16 19:06:13 +00:00
return (0);
}
/*
* Since these are all offline domains, the state is always SHUTOFF.
*/
int
xenXMDomainGetState(virDomainPtr domain,
int *state,
int *reason,
unsigned int flags ATTRIBUTE_UNUSED)
{
if (domain->id != -1)
return -1;
*state = VIR_DOMAIN_SHUTOFF;
if (reason)
*reason = 0;
return 0;
}
2006-11-16 19:06:13 +00:00
/*
* 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->mem.max_balloon;
info->memory = entry->def->mem.cur_balloon;
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
}
/*
* Turn a config record into a lump of XML describing the
* domain, suitable for later feeding for virDomainCreateXML
*/
char *xenXMDomainGetXMLDesc(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->mem.cur_balloon = memory;
if (entry->def->mem.cur_balloon > entry->def->mem.max_balloon)
entry->def->mem.cur_balloon = entry->def->mem.max_balloon;
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->mem.max_balloon = memory;
if (entry->def->mem.cur_balloon > entry->def->mem.max_balloon)
entry->def->mem.cur_balloon = entry->def->mem.max_balloon;
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->mem.max_balloon;
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
}
/*
* xenXMDomainSetVcpusFlags:
* @domain: pointer to domain object
* @nvcpus: number of vcpus
* @flags: bitwise-ORd from virDomainVcpuFlags
*
* Change virtual CPUs allocation of domain according to flags.
*
* Returns 0 on success, -1 if an error message was issued, and -2 if
* the unified driver should keep trying.
*/
int
xenXMDomainSetVcpusFlags(virDomainPtr domain, unsigned int vcpus,
unsigned int flags)
{
xenUnifiedPrivatePtr priv;
const char *filename;
xenXMConfCachePtr entry;
int ret = -1;
int max;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1;
}
if (domain->conn->flags & VIR_CONNECT_RO) {
xenXMError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
return -1;
}
if (domain->id != -1)
return -2;
if (flags & VIR_DOMAIN_VCPU_LIVE) {
xenXMError(VIR_ERR_OPERATION_INVALID, "%s",
_("domain is not running"));
return -1;
}
priv = domain->conn->privateData;
xenUnifiedLock(priv);
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename)))
goto cleanup;
/* Hypervisor maximum. */
if ((max = xenUnifiedGetMaxVcpus(domain->conn, NULL)) < 0) {
xenXMError(VIR_ERR_INTERNAL_ERROR, "%s",
_("could not determin max vcpus for the domain"));
goto cleanup;
}
/* Can't specify a current larger than stored maximum; but
* reducing maximum can silently reduce current. */
if (!(flags & VIR_DOMAIN_VCPU_MAXIMUM))
max = entry->def->maxvcpus;
if (vcpus > max) {
xenXMError(VIR_ERR_INVALID_ARG,
_("requested vcpus is greater than max allowable"
" vcpus for the domain: %d > %d"), vcpus, max);
goto cleanup;
}
if (flags & VIR_DOMAIN_VCPU_MAXIMUM) {
entry->def->maxvcpus = vcpus;
if (entry->def->vcpus > vcpus)
entry->def->vcpus = vcpus;
} else {
entry->def->vcpus = vcpus;
}
/* If this fails, should we try to undo our changes to the
2006-11-16 19:06:13 +00:00
* 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
}
/**
* xenXMDomainGetVcpusFlags:
* @domain: pointer to domain object
* @flags: bitwise-ORd from virDomainVcpuFlags
*
* Extract information about virtual CPUs of domain according to flags.
*
* Returns the number of vcpus on success, -1 if an error message was
* issued, and -2 if the unified driver should keep trying.
*/
int
xenXMDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
{
xenUnifiedPrivatePtr priv;
const char *filename;
xenXMConfCachePtr entry;
int ret = -2;
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
xenXMError(VIR_ERR_INVALID_ARG, __FUNCTION__);
return -1;
}
if (domain->id != -1)
return -2;
if (flags & VIR_DOMAIN_VCPU_LIVE) {
xenXMError(VIR_ERR_OPERATION_FAILED, "%s", _("domain not active"));
return -1;
}
priv = domain->conn->privateData;
xenUnifiedLock(priv);
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
goto cleanup;
if (!(entry = virHashLookup(priv->configCache, filename)))
goto cleanup;
ret = ((flags & VIR_DOMAIN_VCPU_MAXIMUM) ? entry->def->maxvcpus
: entry->def->vcpus);
cleanup:
xenUnifiedUnlock(priv);
return ret;
}
/**
* 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;
virBufferAsprintf (&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 void *name ATTRIBUTE_UNUSED, const void *data) {
2006-11-16 19:06:13 +00:00
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
2011-02-21 13:40:12 +00:00
if (!(sexpr = xenFormatSxpr(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
}
/*
* 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;
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) < 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) < 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 (!(filename = virFileBuildPath(priv->configDir, def->name, NULL)))
2006-11-16 19:06:13 +00:00
goto error;
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) {
virHashSteal(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", _("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);
VIR_FREE(filename);
2006-11-16 19:06:13 +00:00
return (ret);
error:
VIR_FREE(filename);
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) < 0)
2009-01-21 18:11:14 +00:00
goto cleanup;
/* Remove the config record itself */
if (virHashRemoveEntry(priv->configCache, entry->filename) < 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 void *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 ((flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) ||
(domain->id != -1 && (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT))) {
xenXMError(VIR_ERR_OPERATION_INVALID, "%s",
_("Xm driver only supports modifying persistent 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_CONFIG_UNSUPPORTED, "%s",
_("Xm driver only supports adding disk or network devices"));
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 ((flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) ||
(domain->id != -1 && (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT))) {
xenXMError(VIR_ERR_OPERATION_INVALID, "%s",
_("Xm driver only supports modifying persistent 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_CONFIG_UNSUPPORTED,
_("device type '%s' cannot be detached"),
virDomainDeviceTypeToString(dev->type));
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;
}