2006-11-16 19:06:13 +00:00
|
|
|
/*
|
|
|
|
* xm_internal.h: helper routines for dealing with inactive domains
|
|
|
|
*
|
2013-01-29 14:24:42 +00:00
|
|
|
* Copyright (C) 2006-2007, 2009-2013 Red Hat, Inc.
|
2007-01-19 20:23:37 +00:00
|
|
|
* Copyright (C) 2006 Daniel P. Berrange
|
2006-11-16 19:06:13 +00:00
|
|
|
*
|
2007-01-19 20:23:37 +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
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-21 10:06:23 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
2007-01-19 20:23:37 +00:00
|
|
|
*
|
|
|
|
* Author: Daniel P. Berrange <berrange@redhat.com>
|
2006-11-16 19:06:13 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2008-01-29 18:15:54 +00:00
|
|
|
#include <config.h>
|
2007-12-07 10:08:06 +00:00
|
|
|
|
2006-11-16 19:06:13 +00:00
|
|
|
#include <dirent.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <sys/stat.h>
|
2007-06-15 15:24:20 +00:00
|
|
|
#include <limits.h>
|
2007-07-04 13:16:57 +00:00
|
|
|
#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>
|
|
|
|
|
2012-12-13 18:21:53 +00:00
|
|
|
#include "virerror.h"
|
2008-11-04 23:22:06 +00:00
|
|
|
#include "datatypes.h"
|
2006-11-16 19:06:13 +00:00
|
|
|
#include "xm_internal.h"
|
Move xen driver code into src/xen/ directory
* src/Makefile.am, src/proxy_internal.c, src/proxy_internal.h
src/sexpr.c, src/sexpr.h, src/xen_unified.c, src/xen_unified.h,
src/xen_internal.c, src/xen_internal.h, src/xen_inotify.c,
src/xen_inotify.h, src/xend_internal.c, src/xend_internal.h,
src/xm_internal.c, src/xm_internal.h, src/xs_internal.c,
src/xs_internal.h: Move to src/xen/ directory
* proxy/Makefile.am, proxy/libvirt_proxy.c, src/Makefile.am,
src/libvirt.c, tests/sexpr2xmltest.c, tests/statstest.c,
tests/xencapstest.c, tests/xmconfigtest.c, tests/xml2sexprtest.c:
Adapt to changed xen location
* src/stats_linux.h, src/stats_linux.c: Remove xen specific block
stats APIs
* src/qemu_driver.c, src/uml_driver.c: Add missing sys/un.h include
uncovered after change to stats_linux.h
* src/xen/block_stats.h, src/xen/block_stats.c: Add xen specific
block stats APIs
2009-09-15 15:38:33 +00:00
|
|
|
#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"
|
2012-01-25 16:13:59 +00:00
|
|
|
#include "virhash.h"
|
2012-12-04 12:04:07 +00:00
|
|
|
#include "virbuffer.h"
|
2012-12-13 18:01:25 +00:00
|
|
|
#include "viruuid.h"
|
2012-12-13 17:44:57 +00:00
|
|
|
#include "virutil.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2012-12-12 17:59:27 +00:00
|
|
|
#include "virlog.h"
|
2010-10-05 14:18:52 +00:00
|
|
|
#include "count-one-bits.h"
|
2008-11-25 10:44:52 +00:00
|
|
|
|
2009-01-20 17:13:33 +00:00
|
|
|
#define VIR_FROM_THIS VIR_FROM_XENXM
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2009-01-19 18:12:00 +00:00
|
|
|
#ifdef WITH_RHEL5_API
|
2010-03-09 18:22:22 +00:00
|
|
|
# define XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU 0
|
|
|
|
# define XEND_CONFIG_MIN_VERS_PVFB_NEWCONF 2
|
2009-01-19 18:12:00 +00:00
|
|
|
#else
|
2010-03-09 18:22:22 +00:00
|
|
|
# define XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU 3
|
|
|
|
# define XEND_CONFIG_MIN_VERS_PVFB_NEWCONF 3
|
2009-01-19 18:12:00 +00:00
|
|
|
#endif
|
|
|
|
|
2008-07-25 13:39:02 +00:00
|
|
|
/* 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
|
|
|
|
|
2008-02-06 17:57:10 +00:00
|
|
|
char * xenXMAutoAssignMac(void);
|
2010-01-14 01:44:26 +00:00
|
|
|
static int xenXMDomainAttachDeviceFlags(virDomainPtr domain, const char *xml,
|
|
|
|
unsigned int flags);
|
|
|
|
static int xenXMDomainDetachDeviceFlags(virDomainPtr domain, const char *xml,
|
|
|
|
unsigned int flags);
|
2008-02-06 17:57:10 +00:00
|
|
|
|
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"
|
2008-02-06 17:57:10 +00:00
|
|
|
#define XM_XML_ERROR "Invalid xml"
|
2006-11-16 19:06:13 +00:00
|
|
|
|
Fri Jul 6 16:08:00 BST 2007 Richard W.M. Jones <rjones@redhat.com>
* src/proxy_internal.c, src/proxy_internal.h,
src.xen_internal.c, src/xen_internal.h,
src/xen_unified.c, src/xen_unified.h,
src/xend_internal.c, src/xend_internal.h,
src/xm_internal.c, src/xm_internal.h,
src/xs_internal.c, src/xs_internal.h: The interface
between xen_unified.c and its underlying driver now uses
a custom structure (struct xenUnifiedDriver) instead
of reusing virDriver.
* src/xen_unified.c: virDomainLookup* functions in Xen
now throw VIR_ERR_NO_DOMAIN if the domain does not exist.
* src/xs_internal.c: Fix indentation.
2007-07-06 15:11:22 +00:00
|
|
|
struct xenUnifiedDriver xenXMDriver = {
|
2011-07-21 20:10:33 +00:00
|
|
|
.xenClose = xenXMClose,
|
|
|
|
.xenDomainGetMaxMemory = xenXMDomainGetMaxMemory,
|
|
|
|
.xenDomainSetMaxMemory = xenXMDomainSetMaxMemory,
|
|
|
|
.xenDomainSetMemory = xenXMDomainSetMemory,
|
|
|
|
.xenDomainGetInfo = xenXMDomainGetInfo,
|
|
|
|
.xenDomainPinVcpu = xenXMDomainPinVcpu,
|
|
|
|
.xenListDefinedDomains = xenXMListDefinedDomains,
|
|
|
|
.xenNumOfDefinedDomains = xenXMNumOfDefinedDomains,
|
|
|
|
.xenDomainCreate = xenXMDomainCreate,
|
|
|
|
.xenDomainDefineXML = xenXMDomainDefineXML,
|
|
|
|
.xenDomainUndefine = xenXMDomainUndefine,
|
|
|
|
.xenDomainAttachDeviceFlags = xenXMDomainAttachDeviceFlags,
|
|
|
|
.xenDomainDetachDeviceFlags = xenXMDomainDetachDeviceFlags,
|
2006-11-16 19:06:13 +00:00
|
|
|
};
|
|
|
|
|
2009-08-05 09:46:33 +00:00
|
|
|
#ifndef WITH_XEN_INOTIFY
|
2009-08-05 10:04:26 +00:00
|
|
|
static int xenInotifyActive(virConnectPtr conn ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2009-08-05 09:46:33 +00:00
|
|
|
#else
|
2009-08-05 10:04:26 +00:00
|
|
|
static int xenInotifyActive(virConnectPtr conn)
|
|
|
|
{
|
2013-01-29 14:24:42 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2009-08-05 10:04:26 +00:00
|
|
|
return priv->inotifyWatch > 0;
|
2009-08-05 09:46:33 +00:00
|
|
|
}
|
2009-08-05 10:04:26 +00:00
|
|
|
#endif
|
2009-08-05 09:46:33 +00:00
|
|
|
|
2006-11-16 19:06:13 +00:00
|
|
|
|
|
|
|
/* Release memory associated with a cached config object */
|
Allow hash tables to use generic pointers as keys
Relax the restriction that the hash table key must be a string
by allowing an arbitrary hash code generator + comparison func
to be provided
* util/hash.c, util/hash.h: Allow any pointer as a key
* internal.h: Include stdbool.h as standard.
* conf/domain_conf.c, conf/domain_conf.c,
conf/nwfilter_params.c, nwfilter/nwfilter_gentech_driver.c,
nwfilter/nwfilter_gentech_driver.h, nwfilter/nwfilter_learnipaddr.c,
qemu/qemu_command.c, qemu/qemu_driver.c,
qemu/qemu_process.c, uml/uml_driver.c,
xen/xm_internal.c: s/char */void */ in hash callbacks
2011-02-22 15:11:59 +00:00
|
|
|
static void xenXMConfigFree(void *payload, const void *key ATTRIBUTE_UNUSED) {
|
2006-11-16 19:06:13 +00:00
|
|
|
xenXMConfCachePtr entry = (xenXMConfCachePtr)payload;
|
2008-07-25 13:39:02 +00:00
|
|
|
virDomainDefFree(entry->def);
|
2011-06-22 20:31:45 +00:00
|
|
|
VIR_FREE(entry->filename);
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(entry);
|
2006-11-16 19:06:13 +00:00
|
|
|
}
|
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
struct xenXMConfigReaperData {
|
|
|
|
xenUnifiedPrivatePtr priv;
|
|
|
|
time_t now;
|
|
|
|
};
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2006-12-19 21:54:20 +00:00
|
|
|
/* Remove any configs which were not refreshed recently */
|
2013-01-29 14:24:42 +00:00
|
|
|
static int
|
|
|
|
xenXMConfigReaper(const void *payload,
|
|
|
|
const void *key ATTRIBUTE_UNUSED,
|
|
|
|
const void *data)
|
|
|
|
{
|
2009-01-20 17:34:56 +00:00
|
|
|
const struct xenXMConfigReaperData *args = data;
|
2006-12-19 21:54:20 +00:00
|
|
|
xenXMConfCachePtr entry = (xenXMConfCachePtr)payload;
|
|
|
|
|
2008-07-25 13:39:02 +00:00
|
|
|
/* We're going to purge this config file, so check if it
|
|
|
|
is currently mapped as owner of a named domain. */
|
2009-01-20 17:34:56 +00:00
|
|
|
if (entry->refreshedAt != args->now) {
|
2008-07-25 13:39:02 +00:00
|
|
|
const char *olddomname = entry->def->name;
|
2009-01-20 17:34:56 +00:00
|
|
|
char *nameowner = (char *)virHashLookup(args->priv->nameConfigMap, olddomname);
|
2008-07-25 13:39:02 +00:00
|
|
|
if (nameowner && STREQ(nameowner, key)) {
|
2011-02-22 15:11:59 +00:00
|
|
|
virHashRemoveEntry(args->priv->nameConfigMap, olddomname);
|
2006-12-19 21:54:20 +00:00
|
|
|
}
|
2012-03-22 11:33:35 +00:00
|
|
|
return 1;
|
2006-12-19 21:54:20 +00:00
|
|
|
}
|
2012-03-22 11:33:35 +00:00
|
|
|
return 0;
|
2006-12-19 21:54:20 +00:00
|
|
|
}
|
|
|
|
|
2008-07-25 13:39:02 +00:00
|
|
|
|
|
|
|
static virDomainDefPtr
|
2013-01-29 14:24:42 +00:00
|
|
|
xenXMConfigReadFile(virConnectPtr conn, const char *filename)
|
|
|
|
{
|
2008-07-25 13:39:02 +00:00
|
|
|
virConfPtr conf;
|
|
|
|
virDomainDefPtr def;
|
2011-02-21 13:40:10 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2008-07-25 13:39:02 +00:00
|
|
|
|
2009-06-19 12:34:30 +00:00
|
|
|
if (!(conf = virConfReadFile(filename, 0)))
|
2008-07-25 13:39:02 +00:00
|
|
|
return NULL;
|
|
|
|
|
2011-02-21 13:40:12 +00:00
|
|
|
def = xenParseXM(conf, priv->xendConfigVersion, priv->caps);
|
2008-07-25 13:39:02 +00:00
|
|
|
virConfFree(conf);
|
|
|
|
|
|
|
|
return def;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2013-01-29 14:24:42 +00:00
|
|
|
xenXMConfigSaveFile(virConnectPtr conn,
|
|
|
|
const char *filename,
|
|
|
|
virDomainDefPtr def)
|
|
|
|
{
|
2008-07-25 13:39:02 +00:00
|
|
|
virConfPtr conf;
|
2011-02-21 13:40:11 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2008-07-25 13:39:02 +00:00
|
|
|
int ret;
|
|
|
|
|
2011-02-21 13:40:12 +00:00
|
|
|
if (!(conf = xenFormatXM(conn, def, priv->xendConfigVersion)))
|
2008-07-25 13:39:02 +00:00
|
|
|
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
|
2012-10-11 16:31:20 +00:00
|
|
|
* calling this function
|
2009-01-21 18:11:14 +00:00
|
|
|
*/
|
2008-11-25 10:44:52 +00:00
|
|
|
int
|
2013-01-29 14:24:42 +00:00
|
|
|
xenXMConfigCacheRemoveFile(virConnectPtr conn, const char *filename)
|
2008-11-25 10:44:52 +00:00
|
|
|
{
|
2009-01-20 17:34:56 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2008-11-25 10:44:52 +00:00
|
|
|
xenXMConfCachePtr entry;
|
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
entry = virHashLookup(priv->configCache, filename);
|
2008-11-25 10:44:52 +00:00
|
|
|
if (!entry) {
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("No config entry for %s", filename);
|
2008-11-25 10:44:52 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-02-22 15:11:59 +00:00
|
|
|
virHashRemoveEntry(priv->nameConfigMap, entry->def->name);
|
|
|
|
virHashRemoveEntry(priv->configCache, filename);
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Removed %s %s", entry->def->name, filename);
|
2008-11-25 10:44:52 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
/*
|
|
|
|
* Caller must hold the lock on 'conn->privateData' before
|
2012-10-11 16:31:20 +00:00
|
|
|
* calling this function
|
2009-01-21 18:11:14 +00:00
|
|
|
*/
|
2008-11-25 10:44:52 +00:00
|
|
|
int
|
|
|
|
xenXMConfigCacheAddFile(virConnectPtr conn, const char *filename)
|
|
|
|
{
|
2009-01-20 17:34:56 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2008-11-25 10:44:52 +00:00
|
|
|
xenXMConfCachePtr entry;
|
|
|
|
struct stat st;
|
|
|
|
int newborn = 0;
|
|
|
|
time_t now = time(NULL);
|
|
|
|
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Adding file %s", filename);
|
2008-11-25 10:44:52 +00:00
|
|
|
|
|
|
|
/* Get modified time */
|
|
|
|
if ((stat(filename, &st) < 0)) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno,
|
2009-01-20 17:13:33 +00:00
|
|
|
_("cannot stat: %s"),
|
|
|
|
filename);
|
2008-11-25 10:44:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ignore zero length files, because inotify fires before
|
|
|
|
any content has actually been created */
|
|
|
|
if (st.st_size == 0) {
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Ignoring zero length file %s", filename);
|
2008-11-25 10:44:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If we already have a matching entry and it is not
|
|
|
|
modified, then carry on to next one*/
|
2009-01-20 17:34:56 +00:00
|
|
|
if ((entry = virHashLookup(priv->configCache, filename))) {
|
2008-11-25 10:44:52 +00:00
|
|
|
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 */
|
2009-01-20 17:34:56 +00:00
|
|
|
nameowner = (char *)virHashLookup(priv->nameConfigMap, entry->def->name);
|
2008-11-25 10:44:52 +00:00
|
|
|
if (nameowner && STREQ(nameowner, filename)) {
|
2011-02-22 15:11:59 +00:00
|
|
|
virHashRemoveEntry(priv->nameConfigMap, entry->def->name);
|
2008-11-25 10:44:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear existing config entry which needs refresh */
|
|
|
|
virDomainDefFree(entry->def);
|
|
|
|
entry->def = NULL;
|
|
|
|
} else { /* Completely new entry */
|
|
|
|
newborn = 1;
|
|
|
|
if (VIR_ALLOC(entry) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-11-25 10:44:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2011-06-22 20:31:45 +00:00
|
|
|
if ((entry->filename = strdup(filename)) == NULL) {
|
|
|
|
virReportOOMError();
|
|
|
|
VIR_FREE(entry);
|
|
|
|
return -1;
|
|
|
|
}
|
2008-11-25 10:44:52 +00:00
|
|
|
}
|
|
|
|
entry->refreshedAt = now;
|
|
|
|
|
|
|
|
if (!(entry->def = xenXMConfigReadFile(conn, entry->filename))) {
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Failed to read %s", entry->filename);
|
2008-11-25 10:44:52 +00:00
|
|
|
if (!newborn)
|
2011-02-22 15:11:59 +00:00
|
|
|
virHashSteal(priv->configCache, filename);
|
2011-06-22 20:31:45 +00:00
|
|
|
VIR_FREE(entry->filename);
|
2008-11-25 10:44:52 +00:00
|
|
|
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) {
|
2009-01-20 17:34:56 +00:00
|
|
|
if (virHashAddEntry(priv->configCache, entry->filename, entry) < 0) {
|
2008-11-25 10:44:52 +00:00
|
|
|
virDomainDefFree(entry->def);
|
2011-06-22 20:31:45 +00:00
|
|
|
VIR_FREE(entry->filename);
|
2008-11-25 10:44:52 +00:00
|
|
|
VIR_FREE(entry);
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("xenXMConfigCacheRefresh: virHashAddEntry"));
|
2008-11-25 10:44:52 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* See if we need to map this config file in as the primary owner
|
|
|
|
* of the domain in question
|
|
|
|
*/
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!virHashLookup(priv->nameConfigMap, entry->def->name)) {
|
2011-06-22 20:31:45 +00:00
|
|
|
if (virHashAddEntry(priv->nameConfigMap, entry->def->name,
|
|
|
|
entry->filename) < 0) {
|
2011-02-22 15:11:59 +00:00
|
|
|
virHashSteal(priv->configCache, filename);
|
2008-11-25 10:44:52 +00:00
|
|
|
virDomainDefFree(entry->def);
|
2011-06-22 20:31:45 +00:00
|
|
|
VIR_FREE(entry->filename);
|
2008-11-25 10:44:52 +00:00
|
|
|
VIR_FREE(entry);
|
|
|
|
}
|
|
|
|
}
|
2011-02-16 23:37:57 +00:00
|
|
|
VIR_DEBUG("Added config %s %s", entry->def->name, filename);
|
2008-11-25 10:44:52 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2008-07-25 13:39:02 +00:00
|
|
|
|
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
|
2012-10-11 16:31:20 +00:00
|
|
|
* calling this function
|
2009-01-21 18:11:14 +00:00
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
int
|
|
|
|
xenXMConfigCacheRefresh(virConnectPtr conn)
|
|
|
|
{
|
2009-01-20 17:34:56 +00:00
|
|
|
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;
|
2009-01-20 17:34:56 +00:00
|
|
|
struct xenXMConfigReaperData args;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
|
|
|
if (now == ((time_t)-1)) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno,
|
2009-01-20 17:13:33 +00:00
|
|
|
"%s", _("cannot get time of day"));
|
2012-03-22 11:33:35 +00:00
|
|
|
return -1;
|
2006-11-16 19:06:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Rate limit re-scans */
|
2009-01-20 17:34:56 +00:00
|
|
|
if ((now - priv->lastRefresh) < XM_REFRESH_INTERVAL)
|
2012-03-22 11:33:35 +00:00
|
|
|
return 0;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
priv->lastRefresh = now;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
|
|
|
/* Process the files in the config dir */
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!(dh = opendir(priv->configDir))) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno,
|
2009-01-20 17:13:33 +00:00
|
|
|
_("cannot read directory %s"),
|
2009-01-20 17:34:56 +00:00
|
|
|
priv->configDir);
|
2012-03-22 11:33:35 +00:00
|
|
|
return -1;
|
2006-11-16 19:06:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
while ((ent = readdir(dh))) {
|
|
|
|
struct stat st;
|
2011-04-03 09:21:14 +00:00
|
|
|
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... */
|
2008-05-15 14:21:34 +00:00
|
|
|
if (STRPREFIX(ent->d_name, "."))
|
2006-11-16 19:06:13 +00:00
|
|
|
continue;
|
|
|
|
/* ...and the XenD server config file */
|
2008-05-15 14:21:34 +00:00
|
|
|
if (STRPREFIX(ent->d_name, XEND_CONFIG_FILE))
|
2006-11-16 19:06:13 +00:00
|
|
|
continue;
|
|
|
|
/* ...and random PCI config cruft */
|
2008-05-15 14:21:34 +00:00
|
|
|
if (STRPREFIX(ent->d_name, XEND_PCI_CONFIG_PREFIX))
|
2006-11-16 19:06:13 +00:00
|
|
|
continue;
|
|
|
|
/* ...and the example domain configs */
|
2008-05-15 14:21:34 +00:00
|
|
|
if (STRPREFIX(ent->d_name, XM_EXAMPLE_PREFIX))
|
2006-11-16 19:06:13 +00:00
|
|
|
continue;
|
|
|
|
/* ...and the QEMU networking script */
|
2008-05-15 14:21:34 +00:00
|
|
|
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 */
|
2011-04-03 09:21:14 +00:00
|
|
|
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))) {
|
2011-04-03 09:21:14 +00:00
|
|
|
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*/
|
2008-11-25 10:44:52 +00:00
|
|
|
if (xenXMConfigCacheAddFile(conn, path) < 0) {
|
2012-10-11 16:31:20 +00:00
|
|
|
/* Ignoring errors, since a lot of stuff goes wrong in /etc/xen */
|
2006-12-19 21:54:20 +00:00
|
|
|
}
|
2011-04-03 09:21:14 +00:00
|
|
|
|
|
|
|
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 */
|
2009-01-20 17:34:56 +00:00
|
|
|
args.now = now;
|
|
|
|
args.priv = priv;
|
2011-02-22 15:11:59 +00:00
|
|
|
virHashRemoveSet(priv->configCache, xenXMConfigReaper, &args);
|
2006-11-16 19:06:13 +00:00
|
|
|
ret = 0;
|
|
|
|
|
2009-11-10 11:56:11 +00:00
|
|
|
closedir(dh);
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2012-03-22 11:33:35 +00:00
|
|
|
return ret;
|
2006-11-16 19:06:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2009-01-20 18:20:09 +00:00
|
|
|
* 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
|
|
|
*/
|
2008-12-17 21:26:16 +00:00
|
|
|
virDrvOpenStatus
|
2012-10-17 09:23:12 +00:00
|
|
|
xenXMOpen(virConnectPtr conn,
|
|
|
|
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
|
|
|
unsigned int flags)
|
2007-04-04 14:19:49 +00:00
|
|
|
{
|
2009-01-20 17:34:56 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
|
|
|
|
xen: reject unknown flags
Also fix a logic bug in xenXMDomain{Attach,Detach}DeviceFlags,
where (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT) is always false.
* src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative)
(xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject
unknown flags.
* src/xen/xen_hypervisor.c (xenHypervisorOpen)
(xenHypervisorGetDomainState): Likewise.
* src/xen/xen_inotify.c (xenInotifyOpen): Likewise.
* src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState)
(xenStoreDomainReboot): Likewise.
* src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot)
(xenDaemonDomainCoreDump, xenDaemonDomainGetState)
(xenDaemonDomainMigratePrepare, xenDaemonDomainSetVcpusFlags,
xenDaemonDomainGetVcpusFlags, xenDaemonAttachDeviceFlags,
xenDaemonDetachDeviceFlags): Likewise.
(xenDaemonDomainGetXMLDesc): Prefer unsigned flags.
* src/xen/xend_internal.h (xenDaemonDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.c (xenXMDomainGetXMLDesc): Likewise.
(xenXMOpen, xenXMDomainGetState, xenXMDomainSetVcpusFlags)
(xenXMDomainGetVcpusFlags): Reject unknown flags.
(xenXMDomainAttachDeviceFlags, xenXMDomainDetachDeviceFlags):
Likewise, and avoid always-false conditional.
* src/xen/xen_driver.h (XEN_MIGRATION_FLAGS): New define.
2011-07-06 23:15:33 +00:00
|
|
|
virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
|
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
priv->configDir = XM_CONFIG_DIR;
|
|
|
|
|
2011-02-18 21:30:24 +00:00
|
|
|
priv->configCache = virHashCreate(50, xenXMConfigFree);
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!priv->configCache)
|
2012-03-22 11:33:35 +00:00
|
|
|
return -1;
|
2011-02-18 21:30:24 +00:00
|
|
|
priv->nameConfigMap = virHashCreate(50, NULL);
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!priv->nameConfigMap) {
|
2011-02-18 21:30:24 +00:00
|
|
|
virHashFree(priv->configCache);
|
2009-01-20 17:34:56 +00:00
|
|
|
priv->configCache = NULL;
|
2012-03-22 11:33:35 +00:00
|
|
|
return -1;
|
2006-11-16 19:06:13 +00:00
|
|
|
}
|
2009-01-20 17:34:56 +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
|
|
|
|
2012-03-22 11:33:35 +00:00
|
|
|
return 0;
|
2006-11-16 19:06:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2009-01-20 18:20:09 +00:00
|
|
|
* Free the cached config files associated with this
|
|
|
|
* connection
|
2006-11-16 19:06:13 +00:00
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
int
|
|
|
|
xenXMClose(virConnectPtr conn)
|
|
|
|
{
|
2009-01-20 17:34:56 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
|
|
|
|
2011-02-18 21:30:24 +00:00
|
|
|
virHashFree(priv->nameConfigMap);
|
|
|
|
virHashFree(priv->configCache);
|
2009-01-20 17:34:56 +00:00
|
|
|
|
2012-03-22 11:33:35 +00:00
|
|
|
return 0;
|
2006-11-16 19:06:13 +00:00
|
|
|
}
|
|
|
|
|
2011-05-02 09:35:29 +00:00
|
|
|
/*
|
|
|
|
* Since these are all offline domains, the state is always SHUTOFF.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
xenXMDomainGetState(virDomainPtr domain,
|
2013-01-29 14:24:42 +00:00
|
|
|
int *state, int *reason,
|
xen: reject unknown flags
Also fix a logic bug in xenXMDomain{Attach,Detach}DeviceFlags,
where (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT) is always false.
* src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative)
(xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject
unknown flags.
* src/xen/xen_hypervisor.c (xenHypervisorOpen)
(xenHypervisorGetDomainState): Likewise.
* src/xen/xen_inotify.c (xenInotifyOpen): Likewise.
* src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState)
(xenStoreDomainReboot): Likewise.
* src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot)
(xenDaemonDomainCoreDump, xenDaemonDomainGetState)
(xenDaemonDomainMigratePrepare, xenDaemonDomainSetVcpusFlags,
xenDaemonDomainGetVcpusFlags, xenDaemonAttachDeviceFlags,
xenDaemonDetachDeviceFlags): Likewise.
(xenDaemonDomainGetXMLDesc): Prefer unsigned flags.
* src/xen/xend_internal.h (xenDaemonDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.c (xenXMDomainGetXMLDesc): Likewise.
(xenXMOpen, xenXMDomainGetState, xenXMDomainSetVcpusFlags)
(xenXMDomainGetVcpusFlags): Reject unknown flags.
(xenXMDomainAttachDeviceFlags, xenXMDomainDetachDeviceFlags):
Likewise, and avoid always-false conditional.
* src/xen/xen_driver.h (XEN_MIGRATION_FLAGS): New define.
2011-07-06 23:15:33 +00:00
|
|
|
unsigned int flags)
|
2011-05-02 09:35:29 +00:00
|
|
|
{
|
xen: reject unknown flags
Also fix a logic bug in xenXMDomain{Attach,Detach}DeviceFlags,
where (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT) is always false.
* src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative)
(xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject
unknown flags.
* src/xen/xen_hypervisor.c (xenHypervisorOpen)
(xenHypervisorGetDomainState): Likewise.
* src/xen/xen_inotify.c (xenInotifyOpen): Likewise.
* src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState)
(xenStoreDomainReboot): Likewise.
* src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot)
(xenDaemonDomainCoreDump, xenDaemonDomainGetState)
(xenDaemonDomainMigratePrepare, xenDaemonDomainSetVcpusFlags,
xenDaemonDomainGetVcpusFlags, xenDaemonAttachDeviceFlags,
xenDaemonDetachDeviceFlags): Likewise.
(xenDaemonDomainGetXMLDesc): Prefer unsigned flags.
* src/xen/xend_internal.h (xenDaemonDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.c (xenXMDomainGetXMLDesc): Likewise.
(xenXMOpen, xenXMDomainGetState, xenXMDomainSetVcpusFlags)
(xenXMDomainGetVcpusFlags): Reject unknown flags.
(xenXMDomainAttachDeviceFlags, xenXMDomainDetachDeviceFlags):
Likewise, and avoid always-false conditional.
* src/xen/xen_driver.h (XEN_MIGRATION_FLAGS): New define.
2011-07-06 23:15:33 +00:00
|
|
|
virCheckFlags(0, -1);
|
|
|
|
|
2011-05-02 09:35:29 +00:00
|
|
|
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
|
2007-01-19 20:23:37 +00:00
|
|
|
* VCPUs and memory.
|
2006-11-16 19:06:13 +00:00
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
int
|
|
|
|
xenXMDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
|
|
|
|
{
|
|
|
|
xenUnifiedPrivatePtr priv = domain->conn->privateData;
|
2006-12-19 21:54:20 +00:00
|
|
|
const char *filename;
|
2006-11-16 19:06:13 +00:00
|
|
|
xenXMConfCachePtr entry;
|
|
|
|
|
2007-01-22 16:25:27 +00:00
|
|
|
if (domain->id != -1)
|
2012-03-22 11:33:35 +00:00
|
|
|
return -1;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
2009-01-20 17:34:56 +00:00
|
|
|
|
|
|
|
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto error;
|
2006-12-19 21:54:20 +00:00
|
|
|
|
2009-01-20 17:34:56 +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
|
|
|
|
|
|
|
memset(info, 0, sizeof(virDomainInfo));
|
2010-10-12 14:43:39 +00:00
|
|
|
info->maxMem = entry->def->mem.max_balloon;
|
|
|
|
info->memory = entry->def->mem.cur_balloon;
|
2008-07-25 13:39:02 +00:00
|
|
|
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);
|
2012-03-22 11:33:35 +00:00
|
|
|
return 0;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
error:
|
|
|
|
xenUnifiedUnlock(priv);
|
|
|
|
return -1;
|
2006-11-16 19:06:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-19 20:23:37 +00:00
|
|
|
/*
|
|
|
|
* Turn a config record into a lump of XML describing the
|
2008-10-10 09:32:27 +00:00
|
|
|
* domain, suitable for later feeding for virDomainCreateXML
|
2007-01-19 20:23:37 +00:00
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
char *
|
|
|
|
xenXMDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
|
xen: reject unknown flags
Also fix a logic bug in xenXMDomain{Attach,Detach}DeviceFlags,
where (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT) is always false.
* src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative)
(xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject
unknown flags.
* src/xen/xen_hypervisor.c (xenHypervisorOpen)
(xenHypervisorGetDomainState): Likewise.
* src/xen/xen_inotify.c (xenInotifyOpen): Likewise.
* src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState)
(xenStoreDomainReboot): Likewise.
* src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot)
(xenDaemonDomainCoreDump, xenDaemonDomainGetState)
(xenDaemonDomainMigratePrepare, xenDaemonDomainSetVcpusFlags,
xenDaemonDomainGetVcpusFlags, xenDaemonAttachDeviceFlags,
xenDaemonDetachDeviceFlags): Likewise.
(xenDaemonDomainGetXMLDesc): Prefer unsigned flags.
* src/xen/xend_internal.h (xenDaemonDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.c (xenXMDomainGetXMLDesc): Likewise.
(xenXMOpen, xenXMDomainGetState, xenXMDomainSetVcpusFlags)
(xenXMDomainGetVcpusFlags): Reject unknown flags.
(xenXMDomainAttachDeviceFlags, xenXMDomainDetachDeviceFlags):
Likewise, and avoid always-false conditional.
* src/xen/xen_driver.h (XEN_MIGRATION_FLAGS): New define.
2011-07-06 23:15:33 +00:00
|
|
|
{
|
2013-01-29 14:24:42 +00:00
|
|
|
xenUnifiedPrivatePtr priv = domain->conn->privateData;
|
2007-01-19 20:23:37 +00:00
|
|
|
const char *filename;
|
|
|
|
xenXMConfCachePtr entry;
|
2009-01-21 18:11:14 +00:00
|
|
|
char *ret = NULL;
|
2007-01-19 20:23:37 +00:00
|
|
|
|
xen: reject unknown flags
Also fix a logic bug in xenXMDomain{Attach,Detach}DeviceFlags,
where (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT) is always false.
* src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative)
(xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject
unknown flags.
* src/xen/xen_hypervisor.c (xenHypervisorOpen)
(xenHypervisorGetDomainState): Likewise.
* src/xen/xen_inotify.c (xenInotifyOpen): Likewise.
* src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState)
(xenStoreDomainReboot): Likewise.
* src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot)
(xenDaemonDomainCoreDump, xenDaemonDomainGetState)
(xenDaemonDomainMigratePrepare, xenDaemonDomainSetVcpusFlags,
xenDaemonDomainGetVcpusFlags, xenDaemonAttachDeviceFlags,
xenDaemonDetachDeviceFlags): Likewise.
(xenDaemonDomainGetXMLDesc): Prefer unsigned flags.
* src/xen/xend_internal.h (xenDaemonDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.c (xenXMDomainGetXMLDesc): Likewise.
(xenXMOpen, xenXMDomainGetState, xenXMDomainSetVcpusFlags)
(xenXMDomainGetVcpusFlags): Reject unknown flags.
(xenXMDomainAttachDeviceFlags, xenXMDomainDetachDeviceFlags):
Likewise, and avoid always-false conditional.
* src/xen/xen_driver.h (XEN_MIGRATION_FLAGS): New define.
2011-07-06 23:15:33 +00:00
|
|
|
/* Flags checked by virDomainDefFormat */
|
|
|
|
|
2007-01-22 16:25:27 +00:00
|
|
|
if (domain->id != -1)
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2007-01-19 20:23:37 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
2009-01-20 17:34:56 +00:00
|
|
|
|
|
|
|
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2007-01-19 20:23:37 +00:00
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!(entry = virHashLookup(priv->configCache, filename)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2010-02-09 18:58:01 +00:00
|
|
|
ret = virDomainDefFormat(entry->def, flags);
|
2007-01-19 20:23:37 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
cleanup:
|
|
|
|
xenUnifiedUnlock(priv);
|
|
|
|
return ret;
|
2007-01-19 20:23:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-16 19:06:13 +00:00
|
|
|
/*
|
|
|
|
* Update amount of memory in the config file
|
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
int
|
|
|
|
xenXMDomainSetMemory(virDomainPtr domain, unsigned long memory)
|
|
|
|
{
|
|
|
|
xenUnifiedPrivatePtr priv = domain->conn->privateData;
|
2006-12-19 21:54:20 +00:00
|
|
|
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
|
|
|
|
2013-01-29 14:24:42 +00:00
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO || domain->id != -1 ||
|
|
|
|
memory < 1024 * MIN_XEN_GUEST_SIZE)
|
2012-03-22 11:33:35 +00:00
|
|
|
return -1;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
2009-01-20 17:34:56 +00:00
|
|
|
|
|
|
|
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2006-12-19 21:54:20 +00:00
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!(entry = virHashLookup(priv->configCache, filename)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2010-10-12 14:43:39 +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!
|
|
|
|
*/
|
2008-07-25 13:39:02 +00:00
|
|
|
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
|
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
int
|
|
|
|
xenXMDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
|
|
|
|
{
|
|
|
|
xenUnifiedPrivatePtr priv = domain->conn->privateData;
|
2006-12-19 21:54:20 +00:00
|
|
|
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
|
|
|
|
2013-01-29 14:24:42 +00:00
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO || domain->id != -1)
|
2012-03-22 11:33:35 +00:00
|
|
|
return -1;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
2009-01-20 17:34:56 +00:00
|
|
|
|
|
|
|
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2006-12-19 21:54:20 +00:00
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!(entry = virHashLookup(priv->configCache, filename)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2010-10-12 14:43:39 +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!
|
|
|
|
*/
|
2008-07-25 13:39:02 +00:00
|
|
|
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
|
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
unsigned long long
|
|
|
|
xenXMDomainGetMaxMemory(virDomainPtr domain)
|
|
|
|
{
|
|
|
|
xenUnifiedPrivatePtr priv = domain->conn->privateData;
|
2006-12-19 21:54:20 +00:00
|
|
|
const char *filename;
|
2006-11-16 19:06:13 +00:00
|
|
|
xenXMConfCachePtr entry;
|
xml: use long long internally, to centralize overflow checks
On 64-bit platforms, unsigned long and unsigned long long are
identical, so we don't have to worry about overflow checks.
On 32-bit platforms, anywhere we narrow unsigned long long back
to unsigned long, we have to worry about overflow; it's easier
to do this in one place by having most of the code use the same
or wider types, and only doing the narrowing at the last minute.
Therefore, the memory set commands remain unsigned long, and
the memory get command now centralizes the overflow check into
libvirt.c, so that drivers don't have to repeat the work.
This also fixes a bug where xen returned the wrong value on
failure (most APIs return -1 on failure, but getMaxMemory
must return 0 on failure).
* src/driver.h (virDrvDomainGetMaxMemory): Use long long.
* src/libvirt.c (virDomainGetMaxMemory): Raise overflow.
* src/test/test_driver.c (testGetMaxMemory): Fix driver.
* src/rpc/gendispatch.pl (name_to_ProcName): Likewise.
* src/xen/xen_hypervisor.c (xenHypervisorGetMaxMemory): Likewise.
* src/xen/xen_driver.c (xenUnifiedDomainGetMaxMemory): Likewise.
* src/xen/xend_internal.c (xenDaemonDomainGetMaxMemory):
Likewise.
* src/xen/xend_internal.h (xenDaemonDomainGetMaxMemory):
Likewise.
* src/xen/xm_internal.c (xenXMDomainGetMaxMemory): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetMaxMemory): Likewise.
* src/xen/xs_internal.c (xenStoreDomainGetMaxMemory): Likewise.
* src/xen/xs_internal.h (xenStoreDomainGetMaxMemory): Likewise.
* src/xenapi/xenapi_driver.c (xenapiDomainGetMaxMemory):
Likewise.
* src/esx/esx_driver.c (esxDomainGetMaxMemory): Likewise.
* src/libxl/libxl_driver.c (libxlDomainGetMaxMemory): Likewise.
* src/qemu/qemu_driver.c (qemudDomainGetMaxMemory): Likewise.
* src/lxc/lxc_driver.c (lxcDomainGetMaxMemory): Likewise.
* src/uml/uml_driver.c (umlDomainGetMaxMemory): Likewise.
2012-03-03 00:47:16 +00:00
|
|
|
unsigned long long ret = 0;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2007-01-22 16:25:27 +00:00
|
|
|
if (domain->id != -1)
|
2012-03-22 11:33:35 +00:00
|
|
|
return 0;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
2009-01-20 17:34:56 +00:00
|
|
|
|
|
|
|
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2006-12-19 21:54:20 +00:00
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!(entry = virHashLookup(priv->configCache, filename)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2010-10-12 14:43:39 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2010-10-14 22:17:18 +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
|
2013-01-29 14:24:42 +00:00
|
|
|
xenXMDomainSetVcpusFlags(virDomainPtr domain,
|
|
|
|
unsigned int vcpus,
|
2010-10-14 22:17:18 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2013-01-29 14:24:42 +00:00
|
|
|
xenUnifiedPrivatePtr priv = domain->conn->privateData;
|
2010-10-14 22:17:18 +00:00
|
|
|
const char *filename;
|
|
|
|
xenXMConfCachePtr entry;
|
|
|
|
int ret = -1;
|
|
|
|
int max;
|
|
|
|
|
xen: reject unknown flags
Also fix a logic bug in xenXMDomain{Attach,Detach}DeviceFlags,
where (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT) is always false.
* src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative)
(xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject
unknown flags.
* src/xen/xen_hypervisor.c (xenHypervisorOpen)
(xenHypervisorGetDomainState): Likewise.
* src/xen/xen_inotify.c (xenInotifyOpen): Likewise.
* src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState)
(xenStoreDomainReboot): Likewise.
* src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot)
(xenDaemonDomainCoreDump, xenDaemonDomainGetState)
(xenDaemonDomainMigratePrepare, xenDaemonDomainSetVcpusFlags,
xenDaemonDomainGetVcpusFlags, xenDaemonAttachDeviceFlags,
xenDaemonDetachDeviceFlags): Likewise.
(xenDaemonDomainGetXMLDesc): Prefer unsigned flags.
* src/xen/xend_internal.h (xenDaemonDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.c (xenXMDomainGetXMLDesc): Likewise.
(xenXMOpen, xenXMDomainGetState, xenXMDomainSetVcpusFlags)
(xenXMDomainGetVcpusFlags): Reject unknown flags.
(xenXMDomainAttachDeviceFlags, xenXMDomainDetachDeviceFlags):
Likewise, and avoid always-false conditional.
* src/xen/xen_driver.h (XEN_MIGRATION_FLAGS): New define.
2011-07-06 23:15:33 +00:00
|
|
|
virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
|
|
|
|
VIR_DOMAIN_VCPU_CONFIG |
|
|
|
|
VIR_DOMAIN_VCPU_MAXIMUM, -1);
|
|
|
|
|
2010-10-14 22:17:18 +00:00
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
|
2010-10-14 22:17:18 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (domain->id != -1)
|
|
|
|
return -2;
|
|
|
|
if (flags & VIR_DOMAIN_VCPU_LIVE) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("domain is not running"));
|
2010-10-14 22:17:18 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
|
_("could not determine max vcpus for the domain"));
|
2010-10-14 22:17:18 +00:00
|
|
|
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) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
_("requested vcpus is greater than max allowable"
|
|
|
|
" vcpus for the domain: %d > %d"), vcpus, max);
|
2010-10-14 22:17:18 +00:00
|
|
|
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!
|
|
|
|
*/
|
2008-07-25 13:39:02 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2010-10-06 23:54:41 +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)
|
|
|
|
{
|
2013-01-29 14:24:42 +00:00
|
|
|
xenUnifiedPrivatePtr priv = domain->conn->privateData;
|
2010-10-06 23:54:41 +00:00
|
|
|
const char *filename;
|
|
|
|
xenXMConfCachePtr entry;
|
|
|
|
int ret = -2;
|
|
|
|
|
xen: reject unknown flags
Also fix a logic bug in xenXMDomain{Attach,Detach}DeviceFlags,
where (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT) is always false.
* src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative)
(xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject
unknown flags.
* src/xen/xen_hypervisor.c (xenHypervisorOpen)
(xenHypervisorGetDomainState): Likewise.
* src/xen/xen_inotify.c (xenInotifyOpen): Likewise.
* src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState)
(xenStoreDomainReboot): Likewise.
* src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot)
(xenDaemonDomainCoreDump, xenDaemonDomainGetState)
(xenDaemonDomainMigratePrepare, xenDaemonDomainSetVcpusFlags,
xenDaemonDomainGetVcpusFlags, xenDaemonAttachDeviceFlags,
xenDaemonDetachDeviceFlags): Likewise.
(xenDaemonDomainGetXMLDesc): Prefer unsigned flags.
* src/xen/xend_internal.h (xenDaemonDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.c (xenXMDomainGetXMLDesc): Likewise.
(xenXMOpen, xenXMDomainGetState, xenXMDomainSetVcpusFlags)
(xenXMDomainGetVcpusFlags): Reject unknown flags.
(xenXMDomainAttachDeviceFlags, xenXMDomainDetachDeviceFlags):
Likewise, and avoid always-false conditional.
* src/xen/xen_driver.h (XEN_MIGRATION_FLAGS): New define.
2011-07-06 23:15:33 +00:00
|
|
|
virCheckFlags(VIR_DOMAIN_VCPU_LIVE |
|
|
|
|
VIR_DOMAIN_VCPU_CONFIG |
|
|
|
|
VIR_DOMAIN_VCPU_MAXIMUM, -1);
|
|
|
|
|
2010-10-06 23:54:41 +00:00
|
|
|
if (domain->id != -1)
|
|
|
|
return -2;
|
|
|
|
if (flags & VIR_DOMAIN_VCPU_LIVE) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("domain not active"));
|
2010-10-06 23:54:41 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2007-11-28 10:11:18 +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
|
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
int
|
|
|
|
xenXMDomainPinVcpu(virDomainPtr domain,
|
|
|
|
unsigned int vcpu ATTRIBUTE_UNUSED,
|
|
|
|
unsigned char *cpumap,
|
|
|
|
int maplen)
|
2007-11-28 10:11:18 +00:00
|
|
|
{
|
2013-01-29 14:24:42 +00:00
|
|
|
xenUnifiedPrivatePtr priv = domain->conn->privateData;
|
2007-11-28 10:11:18 +00:00
|
|
|
const char *filename;
|
|
|
|
xenXMConfCachePtr entry;
|
|
|
|
int ret = -1;
|
|
|
|
|
2013-01-29 14:24:42 +00:00
|
|
|
if (maplen > (int)sizeof(cpumap_t)) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG, __FUNCTION__);
|
2007-11-28 10:11:18 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
"%s", _("read only connection"));
|
2007-11-28 10:11:18 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (domain->id != -1) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INVALID_ARG,
|
|
|
|
"%s", _("not inactive domain"));
|
2007-11-28 10:11:18 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
2009-01-20 17:34:56 +00:00
|
|
|
|
|
|
|
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name))) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("virHashLookup"));
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2007-11-28 10:11:18 +00:00
|
|
|
}
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!(entry = virHashLookup(priv->configCache, filename))) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("can't retrieve config file for domain"));
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2007-11-28 10:11:18 +00:00
|
|
|
}
|
|
|
|
|
2012-09-14 07:47:01 +00:00
|
|
|
virBitmapFree(entry->def->cpumask);
|
2012-09-20 05:31:57 +00:00
|
|
|
entry->def->cpumask = virBitmapNewData(cpumap, maplen);
|
|
|
|
if (!entry->def->cpumask)
|
|
|
|
goto cleanup;
|
2008-07-25 13:39:02 +00:00
|
|
|
if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
|
2007-11-28 10:11:18 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedUnlock(priv);
|
2012-03-22 11:33:35 +00:00
|
|
|
return ret;
|
2007-11-28 10:11:18 +00:00
|
|
|
}
|
|
|
|
|
2006-11-16 19:06:13 +00:00
|
|
|
/*
|
|
|
|
* Find an inactive domain based on its name
|
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
virDomainPtr
|
|
|
|
xenXMDomainLookupByName(virConnectPtr conn, const char *domname)
|
|
|
|
{
|
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2006-12-19 21:54:20 +00:00
|
|
|
const char *filename;
|
2006-11-16 19:06:13 +00:00
|
|
|
xenXMConfCachePtr entry;
|
2009-01-21 18:11:14 +00:00
|
|
|
virDomainPtr ret = NULL;
|
2008-07-25 13:39:02 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
2009-01-20 17:34:56 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
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-20 17:34:56 +00:00
|
|
|
if (!(filename = virHashLookup(priv->nameConfigMap, domname)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2006-12-19 21:54:20 +00:00
|
|
|
|
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;
|
2007-01-19 20:23:37 +00:00
|
|
|
|
|
|
|
/* Ensure its marked inactive, because may be cached
|
|
|
|
handle to a previously active domain */
|
2007-01-22 16:25:27 +00:00
|
|
|
ret->id = -1;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
cleanup:
|
|
|
|
xenUnifiedUnlock(priv);
|
2012-03-22 11:33:35 +00:00
|
|
|
return ret;
|
2006-11-16 19:06:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Hash table iterator to search for a domain based on UUID
|
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
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;
|
|
|
|
|
2008-07-25 13:39:02 +00:00
|
|
|
if (!memcmp(entry->def->uuid, wantuuid, VIR_UUID_BUFLEN))
|
2012-03-22 11:33:35 +00:00
|
|
|
return 1;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2012-03-22 11:33:35 +00:00
|
|
|
return 0;
|
2006-11-16 19:06:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Find an inactive domain based on its UUID
|
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
virDomainPtr
|
|
|
|
xenXMDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
|
|
|
|
{
|
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
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
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
2009-01-20 17:34:56 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
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
|
|
|
|
2007-01-19 20:23:37 +00:00
|
|
|
/* Ensure its marked inactive, because may be cached
|
|
|
|
handle to a previously active domain */
|
2007-01-22 16:25:27 +00:00
|
|
|
ret->id = -1;
|
2007-01-19 20:23:37 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
cleanup:
|
|
|
|
xenUnifiedUnlock(priv);
|
2012-03-22 11:33:35 +00:00
|
|
|
return ret;
|
2006-11-16 19:06:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Start a domain from an existing defined config file
|
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
int
|
|
|
|
xenXMDomainCreate(virDomainPtr domain)
|
|
|
|
{
|
2006-11-16 19:06:13 +00:00
|
|
|
char *sexpr;
|
2009-01-21 18:11:14 +00:00
|
|
|
int ret = -1;
|
2013-01-29 14:24:42 +00:00
|
|
|
xenUnifiedPrivatePtr priv= domain->conn->privateData;
|
2008-07-25 13:39:02 +00:00
|
|
|
const char *filename;
|
|
|
|
xenXMConfCachePtr entry;
|
|
|
|
|
2007-01-22 16:25:27 +00:00
|
|
|
if (domain->id != -1)
|
2012-03-22 11:33:35 +00:00
|
|
|
return -1;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
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
|
|
|
|
2009-01-20 17:34:56 +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;
|
2008-07-25 13:17:27 +00:00
|
|
|
|
2008-10-10 09:32:27 +00:00
|
|
|
ret = xenDaemonDomainCreateXML(domain->conn, sexpr);
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(sexpr);
|
2009-01-21 18:11:14 +00:00
|
|
|
if (ret != 0)
|
|
|
|
goto error;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2008-07-25 13:39:02 +00:00
|
|
|
if ((ret = xenDaemonDomainLookupByName_ids(domain->conn, domain->name,
|
2009-01-21 18:11:14 +00:00
|
|
|
entry->def->uuid)) < 0)
|
|
|
|
goto error;
|
2007-01-22 16:25:27 +00:00
|
|
|
domain->id = ret;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2009-09-04 15:22:19 +00:00
|
|
|
if (xend_wait_for_devices(domain->conn, domain->name) < 0)
|
2009-01-21 18:11:14 +00:00
|
|
|
goto error;
|
2007-02-22 19:09:29 +00:00
|
|
|
|
2009-09-04 15:22:19 +00:00
|
|
|
if (xenDaemonDomainResume(domain) < 0)
|
2009-01-21 18:11:14 +00:00
|
|
|
goto error;
|
2007-02-22 19:09:29 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedUnlock(priv);
|
2012-03-22 11:33:35 +00:00
|
|
|
return 0;
|
2007-02-22 19:09:29 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
error:
|
2007-02-22 19:09:29 +00:00
|
|
|
if (domain->id != -1) {
|
2011-07-21 19:41:15 +00:00
|
|
|
xenDaemonDomainDestroyFlags(domain, 0);
|
2007-01-22 16:25:27 +00:00
|
|
|
domain->id = -1;
|
2006-11-16 19:06:13 +00:00
|
|
|
}
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedUnlock(priv);
|
2012-03-22 11:33:35 +00:00
|
|
|
return -1;
|
2006-11-16 19:06:13 +00:00
|
|
|
}
|
|
|
|
|
2007-01-19 20:23:37 +00:00
|
|
|
/*
|
|
|
|
* Create a config file for a domain, based on an XML
|
|
|
|
* document describing its config
|
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
virDomainPtr
|
|
|
|
xenXMDomainDefineXML(virConnectPtr conn, const char *xml)
|
2011-04-03 09:21:14 +00:00
|
|
|
{
|
2007-01-19 20:23:37 +00:00
|
|
|
virDomainPtr ret;
|
2012-02-06 13:13:18 +00:00
|
|
|
char *filename = NULL;
|
2011-04-03 09:21:14 +00:00
|
|
|
const char *oldfilename;
|
2008-07-25 13:39:02 +00:00
|
|
|
virDomainDefPtr def = NULL;
|
2012-02-06 13:09:12 +00:00
|
|
|
virConfPtr conf = NULL;
|
2007-01-19 20:23:37 +00:00
|
|
|
xenXMConfCachePtr entry = NULL;
|
2013-01-29 14:24:42 +00:00
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2007-01-19 20:23:37 +00:00
|
|
|
|
|
|
|
if (conn->flags & VIR_CONNECT_RO)
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2007-01-19 20:23:37 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
if (!xenInotifyActive(conn) && xenXMConfigCacheRefresh(conn) < 0) {
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedUnlock(priv);
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2009-01-21 18:11:14 +00:00
|
|
|
}
|
2007-01-19 20:23:37 +00:00
|
|
|
|
2013-03-31 18:03:42 +00:00
|
|
|
if (!(def = virDomainDefParseString(priv->caps, priv->xmlopt, xml,
|
2011-07-11 17:29:09 +00:00
|
|
|
1 << VIR_DOMAIN_VIRT_XEN,
|
2009-01-21 18:11:14 +00:00
|
|
|
VIR_DOMAIN_XML_INACTIVE))) {
|
2009-01-22 19:18:24 +00:00
|
|
|
xenUnifiedUnlock(priv);
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2009-01-21 18:11:14 +00:00
|
|
|
}
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2012-02-06 13:09:12 +00:00
|
|
|
if (!(conf = xenFormatXM(conn, def, priv->xendConfigVersion)))
|
|
|
|
goto error;
|
|
|
|
|
2009-11-17 11:06:46 +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);
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_FAILED,
|
|
|
|
_("domain '%s' is already defined with uuid %s"),
|
|
|
|
entry->def->name, uuidstr);
|
2009-11-17 11:06:46 +00:00
|
|
|
entry = NULL;
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
entry = NULL;
|
|
|
|
}
|
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
if (virHashLookup(priv->nameConfigMap, def->name)) {
|
2007-05-22 00:39:59 +00:00
|
|
|
/* domain exists, we will overwrite it */
|
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!(oldfilename = (char *)virHashLookup(priv->nameConfigMap, def->name))) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("can't retrieve config filename for domain to overwrite"));
|
2007-05-22 00:39:59 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!(entry = virHashLookup(priv->configCache, oldfilename))) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("can't retrieve config entry for domain to overwrite"));
|
2007-05-22 00:39:59 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remove the name -> filename mapping */
|
2011-02-22 15:11:59 +00:00
|
|
|
if (virHashRemoveEntry(priv->nameConfigMap, def->name) < 0) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("failed to remove old domain from config map"));
|
2007-05-22 00:39:59 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remove the config record itself */
|
2011-02-22 15:11:59 +00:00
|
|
|
if (virHashRemoveEntry(priv->configCache, oldfilename) < 0) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("failed to remove old domain from config map"));
|
2007-05-22 00:39:59 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
entry = NULL;
|
2007-01-19 20:23:37 +00:00
|
|
|
}
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2011-04-24 09:48:00 +00:00
|
|
|
if (!(filename = virFileBuildPath(priv->configDir, def->name, NULL)))
|
2006-11-16 19:06:13 +00:00
|
|
|
goto error;
|
|
|
|
|
2012-02-06 13:09:12 +00:00
|
|
|
if (virConfWriteFile(filename, conf) < 0)
|
2006-11-16 19:06:13 +00:00
|
|
|
goto error;
|
|
|
|
|
2008-05-29 19:20:22 +00:00
|
|
|
if (VIR_ALLOC(entry) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2006-11-16 19:06:13 +00:00
|
|
|
goto error;
|
2007-01-19 20:23:37 +00:00
|
|
|
}
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2007-01-19 20:23:37 +00:00
|
|
|
if ((entry->refreshedAt = time(NULL)) == ((time_t)-1)) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("unable to get current time"));
|
2006-11-16 19:06:13 +00:00
|
|
|
goto error;
|
2007-01-19 20:23:37 +00:00
|
|
|
}
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2011-06-22 20:31:45 +00:00
|
|
|
if ((entry->filename = strdup(filename)) == NULL) {
|
|
|
|
virReportOOMError();
|
|
|
|
goto error;
|
|
|
|
}
|
2008-07-25 13:39:02 +00:00
|
|
|
entry->def = def;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
if (virHashAddEntry(priv->configCache, filename, entry) < 0) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("unable to store config file handle"));
|
2006-12-19 21:54:20 +00:00
|
|
|
goto error;
|
2007-01-19 20:23:37 +00:00
|
|
|
}
|
2006-12-19 21:54:20 +00:00
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
if (virHashAddEntry(priv->nameConfigMap, def->name, entry->filename) < 0) {
|
2011-02-22 15:11:59 +00:00
|
|
|
virHashSteal(priv->configCache, filename);
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
"%s", _("unable to store config file handle"));
|
2006-11-16 19:06:13 +00:00
|
|
|
goto error;
|
2006-12-19 21:54:20 +00:00
|
|
|
}
|
|
|
|
|
2009-08-05 09:39:31 +00:00
|
|
|
ret = virGetDomain(conn, def->name, def->uuid);
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedUnlock(priv);
|
2011-04-03 09:21:14 +00:00
|
|
|
VIR_FREE(filename);
|
2012-03-22 11:33:35 +00:00
|
|
|
return ret;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
|
|
|
error:
|
2011-04-03 09:21:14 +00:00
|
|
|
VIR_FREE(filename);
|
2012-02-06 11:50:47 +00:00
|
|
|
if (entry)
|
|
|
|
VIR_FREE(entry->filename);
|
2008-05-29 19:20:22 +00:00
|
|
|
VIR_FREE(entry);
|
2012-02-06 13:09:12 +00:00
|
|
|
virConfFree(conf);
|
2008-07-25 13:39:02 +00:00
|
|
|
virDomainDefFree(def);
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedUnlock(priv);
|
2012-03-22 11:33:35 +00:00
|
|
|
return NULL;
|
2006-11-16 19:06:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Delete a domain from disk
|
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
int
|
|
|
|
xenXMDomainUndefine(virDomainPtr domain)
|
|
|
|
{
|
|
|
|
xenUnifiedPrivatePtr priv = domain->conn->privateData;
|
2006-12-19 21:54:20 +00:00
|
|
|
const char *filename;
|
2006-11-16 19:06:13 +00:00
|
|
|
xenXMConfCachePtr entry;
|
2009-01-21 18:11:14 +00:00
|
|
|
int ret = -1;
|
|
|
|
|
2011-08-19 14:19:34 +00:00
|
|
|
if (domain->id != -1)
|
2012-03-22 11:33:35 +00:00
|
|
|
return -1;
|
2006-11-16 19:06:13 +00:00
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO)
|
2012-03-22 11:33:35 +00:00
|
|
|
return -1;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
2009-01-20 17:34:56 +00:00
|
|
|
|
|
|
|
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2006-12-19 21:54:20 +00:00
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
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
|
|
|
|
2011-08-19 14:19:34 +00:00
|
|
|
/* Remove the name -> filename mapping */
|
|
|
|
if (virHashRemoveEntry(priv->nameConfigMap, domain->name) < 0)
|
|
|
|
goto cleanup;
|
2006-12-19 21:54:20 +00:00
|
|
|
|
2011-08-19 14:19:34 +00:00
|
|
|
/* Remove the config record itself */
|
|
|
|
if (virHashRemoveEntry(priv->configCache, entry->filename) < 0)
|
|
|
|
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;
|
2009-11-08 21:08:54 +00:00
|
|
|
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
|
|
|
};
|
|
|
|
|
2013-01-29 14:24:42 +00:00
|
|
|
static void
|
|
|
|
xenXMListIterator(void *payload ATTRIBUTE_UNUSED, const void *name, void *data) {
|
2009-10-14 10:17:24 +00:00
|
|
|
struct xenXMListIteratorContext *ctx = data;
|
2006-11-16 19:06:13 +00:00
|
|
|
virDomainPtr dom = NULL;
|
|
|
|
|
2009-11-08 21:08:54 +00:00
|
|
|
if (ctx->oom)
|
|
|
|
return;
|
|
|
|
|
2006-11-16 19:06:13 +00:00
|
|
|
if (ctx->count == ctx->max)
|
|
|
|
return;
|
|
|
|
|
Fri Jul 6 16:08:00 BST 2007 Richard W.M. Jones <rjones@redhat.com>
* src/proxy_internal.c, src/proxy_internal.h,
src.xen_internal.c, src/xen_internal.h,
src/xen_unified.c, src/xen_unified.h,
src/xend_internal.c, src/xend_internal.h,
src/xm_internal.c, src/xm_internal.h,
src/xs_internal.c, src/xs_internal.h: The interface
between xen_unified.c and its underlying driver now uses
a custom structure (struct xenUnifiedDriver) instead
of reusing virDriver.
* src/xen_unified.c: virDomainLookup* functions in Xen
now throw VIR_ERR_NO_DOMAIN if the domain does not exist.
* src/xs_internal.c: Fix indentation.
2007-07-06 15:11:22 +00:00
|
|
|
dom = xenDaemonLookupByName(ctx->conn, name);
|
2006-11-16 19:06:13 +00:00
|
|
|
if (!dom) {
|
2009-11-08 21:08:54 +00:00
|
|
|
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
|
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
int
|
|
|
|
xenXMListDefinedDomains(virConnectPtr conn, char **const names, int maxnames)
|
|
|
|
{
|
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2006-11-16 19:06:13 +00:00
|
|
|
struct xenXMListIteratorContext ctx;
|
2009-11-08 21:08:54 +00:00
|
|
|
int i, ret = -1;
|
2006-11-16 19:06:13 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
2009-01-20 17:34:56 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
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-20 17:34:56 +00:00
|
|
|
if (maxnames > virHashSize(priv->configCache))
|
|
|
|
maxnames = virHashSize(priv->configCache);
|
2006-11-16 19:06:13 +00:00
|
|
|
|
|
|
|
ctx.conn = conn;
|
2009-11-08 21:08:54 +00:00
|
|
|
ctx.oom = 0;
|
2006-11-16 19:06:13 +00:00
|
|
|
ctx.count = 0;
|
|
|
|
ctx.max = maxnames;
|
|
|
|
ctx.names = names;
|
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
virHashForEach(priv->nameConfigMap, xenXMListIterator, &ctx);
|
2009-11-08 21:08:54 +00:00
|
|
|
|
|
|
|
if (ctx.oom) {
|
|
|
|
for (i = 0; i < ctx.count; i++)
|
|
|
|
VIR_FREE(ctx.names[i]);
|
|
|
|
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2009-11-08 21:08:54 +00:00
|
|
|
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
|
|
|
|
*/
|
2013-01-29 14:24:42 +00:00
|
|
|
int
|
|
|
|
xenXMNumOfDefinedDomains(virConnectPtr conn)
|
|
|
|
{
|
|
|
|
xenUnifiedPrivatePtr priv = conn->privateData;
|
2009-01-21 18:11:14 +00:00
|
|
|
int ret = -1;
|
2009-01-20 17:34:56 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
2009-01-20 17:34:56 +00:00
|
|
|
|
2012-10-17 09:23:12 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2008-07-25 13:39:02 +00:00
|
|
|
|
2008-02-06 17:57:10 +00:00
|
|
|
/**
|
2010-01-14 01:44:26 +00:00
|
|
|
* xenXMDomainAttachDeviceFlags:
|
2008-02-06 17:57:10 +00:00
|
|
|
* @domain: pointer to domain object
|
|
|
|
* @xml: pointer to XML description of device
|
2010-01-14 01:44:26 +00:00
|
|
|
* @flags: an OR'ed set of virDomainDeviceModifyFlags
|
2008-02-07 12:34:19 +00:00
|
|
|
*
|
2008-02-06 17:57:10 +00:00
|
|
|
* Create a virtual device attachment to backend.
|
|
|
|
* XML description is translated into config file.
|
2010-01-14 01:44:26 +00:00
|
|
|
* This driver only supports device allocation to
|
|
|
|
* persisted config.
|
2008-02-07 12:34:19 +00:00
|
|
|
*
|
2008-02-06 17:57:10 +00:00
|
|
|
* Returns 0 in case of success, -1 in case of failure.
|
|
|
|
*/
|
|
|
|
static int
|
2013-01-29 14:24:42 +00:00
|
|
|
xenXMDomainAttachDeviceFlags(virDomainPtr domain,
|
|
|
|
const char *xml,
|
xen: reject unknown flags
Also fix a logic bug in xenXMDomain{Attach,Detach}DeviceFlags,
where (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT) is always false.
* src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative)
(xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject
unknown flags.
* src/xen/xen_hypervisor.c (xenHypervisorOpen)
(xenHypervisorGetDomainState): Likewise.
* src/xen/xen_inotify.c (xenInotifyOpen): Likewise.
* src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState)
(xenStoreDomainReboot): Likewise.
* src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot)
(xenDaemonDomainCoreDump, xenDaemonDomainGetState)
(xenDaemonDomainMigratePrepare, xenDaemonDomainSetVcpusFlags,
xenDaemonDomainGetVcpusFlags, xenDaemonAttachDeviceFlags,
xenDaemonDetachDeviceFlags): Likewise.
(xenDaemonDomainGetXMLDesc): Prefer unsigned flags.
* src/xen/xend_internal.h (xenDaemonDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.c (xenXMDomainGetXMLDesc): Likewise.
(xenXMOpen, xenXMDomainGetState, xenXMDomainSetVcpusFlags)
(xenXMDomainGetVcpusFlags): Reject unknown flags.
(xenXMDomainAttachDeviceFlags, xenXMDomainDetachDeviceFlags):
Likewise, and avoid always-false conditional.
* src/xen/xen_driver.h (XEN_MIGRATION_FLAGS): New define.
2011-07-06 23:15:33 +00:00
|
|
|
unsigned int flags)
|
|
|
|
{
|
2008-02-06 17:57:10 +00:00
|
|
|
const char *filename = NULL;
|
|
|
|
xenXMConfCachePtr entry = NULL;
|
2008-07-25 13:39:02 +00:00
|
|
|
int ret = -1;
|
|
|
|
virDomainDeviceDefPtr dev = NULL;
|
2008-10-10 16:08:01 +00:00
|
|
|
virDomainDefPtr def;
|
2013-01-29 14:24:42 +00:00
|
|
|
xenUnifiedPrivatePtr priv = domain->conn->privateData;
|
2008-02-06 17:57:10 +00:00
|
|
|
|
xen: reject unknown flags
Also fix a logic bug in xenXMDomain{Attach,Detach}DeviceFlags,
where (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT) is always false.
* src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative)
(xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject
unknown flags.
* src/xen/xen_hypervisor.c (xenHypervisorOpen)
(xenHypervisorGetDomainState): Likewise.
* src/xen/xen_inotify.c (xenInotifyOpen): Likewise.
* src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState)
(xenStoreDomainReboot): Likewise.
* src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot)
(xenDaemonDomainCoreDump, xenDaemonDomainGetState)
(xenDaemonDomainMigratePrepare, xenDaemonDomainSetVcpusFlags,
xenDaemonDomainGetVcpusFlags, xenDaemonAttachDeviceFlags,
xenDaemonDetachDeviceFlags): Likewise.
(xenDaemonDomainGetXMLDesc): Prefer unsigned flags.
* src/xen/xend_internal.h (xenDaemonDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.c (xenXMDomainGetXMLDesc): Likewise.
(xenXMOpen, xenXMDomainGetState, xenXMDomainSetVcpusFlags)
(xenXMDomainGetVcpusFlags): Reject unknown flags.
(xenXMDomainAttachDeviceFlags, xenXMDomainDetachDeviceFlags):
Likewise, and avoid always-false conditional.
* src/xen/xen_driver.h (XEN_MIGRATION_FLAGS): New define.
2011-07-06 23:15:33 +00:00
|
|
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1);
|
|
|
|
|
2008-02-06 17:57:10 +00:00
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO)
|
2008-07-25 13:39:02 +00:00
|
|
|
return -1;
|
2010-10-01 14:37:53 +00:00
|
|
|
|
|
|
|
if ((flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) ||
|
xen: reject unknown flags
Also fix a logic bug in xenXMDomain{Attach,Detach}DeviceFlags,
where (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT) is always false.
* src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative)
(xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject
unknown flags.
* src/xen/xen_hypervisor.c (xenHypervisorOpen)
(xenHypervisorGetDomainState): Likewise.
* src/xen/xen_inotify.c (xenInotifyOpen): Likewise.
* src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState)
(xenStoreDomainReboot): Likewise.
* src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot)
(xenDaemonDomainCoreDump, xenDaemonDomainGetState)
(xenDaemonDomainMigratePrepare, xenDaemonDomainSetVcpusFlags,
xenDaemonDomainGetVcpusFlags, xenDaemonAttachDeviceFlags,
xenDaemonDetachDeviceFlags): Likewise.
(xenDaemonDomainGetXMLDesc): Prefer unsigned flags.
* src/xen/xend_internal.h (xenDaemonDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.c (xenXMDomainGetXMLDesc): Likewise.
(xenXMOpen, xenXMDomainGetState, xenXMDomainSetVcpusFlags)
(xenXMDomainGetVcpusFlags): Reject unknown flags.
(xenXMDomainAttachDeviceFlags, xenXMDomainDetachDeviceFlags):
Likewise, and avoid always-false conditional.
* src/xen/xen_driver.h (XEN_MIGRATION_FLAGS): New define.
2011-07-06 23:15:33 +00:00
|
|
|
(domain->id != -1 && flags == VIR_DOMAIN_DEVICE_MODIFY_CURRENT)) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("Xm driver only supports modifying persistent config"));
|
2008-07-25 13:39:02 +00:00
|
|
|
return -1;
|
2010-10-01 14:37:53 +00:00
|
|
|
}
|
2008-07-25 13:39:02 +00:00
|
|
|
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedLock(priv);
|
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!(entry = virHashLookup(priv->configCache, filename)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2008-10-10 16:08:01 +00:00
|
|
|
def = entry->def;
|
2008-02-06 17:57:10 +00:00
|
|
|
|
2010-02-09 18:58:01 +00:00
|
|
|
if (!(dev = virDomainDeviceDefParse(priv->caps,
|
2013-02-19 16:29:39 +00:00
|
|
|
priv->xmlopt,
|
2008-07-25 13:39:02 +00:00
|
|
|
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;
|
2008-02-06 17:57:10 +00:00
|
|
|
|
2008-07-25 13:39:02 +00:00
|
|
|
switch (dev->type) {
|
|
|
|
case VIR_DOMAIN_DEVICE_DISK:
|
|
|
|
{
|
2009-08-14 09:31:36 +00:00
|
|
|
if (virDomainDiskInsert(def, dev->data.disk) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-10-10 16:08:01 +00:00
|
|
|
goto cleanup;
|
2008-07-25 13:39:02 +00:00
|
|
|
}
|
|
|
|
dev->data.disk = NULL;
|
2008-02-06 17:57:10 +00:00
|
|
|
}
|
2008-07-25 13:39:02 +00:00
|
|
|
break;
|
2008-02-06 17:57:10 +00:00
|
|
|
|
2008-07-25 13:39:02 +00:00
|
|
|
case VIR_DOMAIN_DEVICE_NET:
|
|
|
|
{
|
2008-10-10 16:08:01 +00:00
|
|
|
if (VIR_REALLOC_N(def->nets, def->nnets+1) < 0) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-10-10 16:08:01 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
def->nets[def->nnets++] = dev->data.net;
|
2008-07-25 13:39:02 +00:00
|
|
|
dev->data.net = NULL;
|
|
|
|
break;
|
2008-02-06 17:57:10 +00:00
|
|
|
}
|
|
|
|
|
2008-07-25 13:39:02 +00:00
|
|
|
default:
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
|
|
_("Xm driver only supports adding disk or network devices"));
|
2008-02-06 17:57:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If this fails, should we try to undo our changes to the
|
|
|
|
* in-memory representation of the config file. I say not!
|
|
|
|
*/
|
2008-07-25 13:39:02 +00:00
|
|
|
if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
|
2008-02-06 17:57:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2008-07-25 13:39:02 +00:00
|
|
|
virDomainDeviceDefFree(dev);
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedUnlock(priv);
|
2008-02-06 17:57:10 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2010-01-14 01:44:26 +00:00
|
|
|
* xenXMDomainDetachDeviceFlags:
|
2008-02-06 17:57:10 +00:00
|
|
|
* @domain: pointer to domain object
|
|
|
|
* @xml: pointer to XML description of device
|
2010-01-14 01:44:26 +00:00
|
|
|
* @flags: an OR'ed set of virDomainDeviceModifyFlags
|
2008-02-07 12:34:19 +00:00
|
|
|
*
|
2008-02-06 17:57:10 +00:00
|
|
|
* Destroy a virtual device attachment to backend.
|
2010-01-14 01:44:26 +00:00
|
|
|
* This driver only supports device deallocation from
|
|
|
|
* persisted config.
|
2008-02-06 17:57:10 +00:00
|
|
|
*
|
|
|
|
* Returns 0 in case of success, -1 in case of failure.
|
|
|
|
*/
|
|
|
|
static int
|
2013-01-29 14:24:42 +00:00
|
|
|
xenXMDomainDetachDeviceFlags(virDomainPtr domain,
|
|
|
|
const char *xml,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
2008-02-06 17:57:10 +00:00
|
|
|
const char *filename = NULL;
|
|
|
|
xenXMConfCachePtr entry = NULL;
|
2008-07-25 13:39:02 +00:00
|
|
|
virDomainDeviceDefPtr dev = NULL;
|
2008-10-10 16:08:01 +00:00
|
|
|
virDomainDefPtr def;
|
2008-02-06 17:57:10 +00:00
|
|
|
int ret = -1;
|
2008-10-10 16:08:01 +00:00
|
|
|
int i;
|
2013-01-29 14:24:42 +00:00
|
|
|
xenUnifiedPrivatePtr priv = domain->conn->privateData;
|
2008-02-06 17:57:10 +00:00
|
|
|
|
xen: reject unknown flags
Also fix a logic bug in xenXMDomain{Attach,Detach}DeviceFlags,
where (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT) is always false.
* src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative)
(xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject
unknown flags.
* src/xen/xen_hypervisor.c (xenHypervisorOpen)
(xenHypervisorGetDomainState): Likewise.
* src/xen/xen_inotify.c (xenInotifyOpen): Likewise.
* src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState)
(xenStoreDomainReboot): Likewise.
* src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot)
(xenDaemonDomainCoreDump, xenDaemonDomainGetState)
(xenDaemonDomainMigratePrepare, xenDaemonDomainSetVcpusFlags,
xenDaemonDomainGetVcpusFlags, xenDaemonAttachDeviceFlags,
xenDaemonDetachDeviceFlags): Likewise.
(xenDaemonDomainGetXMLDesc): Prefer unsigned flags.
* src/xen/xend_internal.h (xenDaemonDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.c (xenXMDomainGetXMLDesc): Likewise.
(xenXMOpen, xenXMDomainGetState, xenXMDomainSetVcpusFlags)
(xenXMDomainGetVcpusFlags): Reject unknown flags.
(xenXMDomainAttachDeviceFlags, xenXMDomainDetachDeviceFlags):
Likewise, and avoid always-false conditional.
* src/xen/xen_driver.h (XEN_MIGRATION_FLAGS): New define.
2011-07-06 23:15:33 +00:00
|
|
|
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1);
|
|
|
|
|
2008-02-06 17:57:10 +00:00
|
|
|
if (domain->conn->flags & VIR_CONNECT_RO)
|
2008-07-25 13:39:02 +00:00
|
|
|
return -1;
|
2010-10-01 14:37:53 +00:00
|
|
|
|
|
|
|
if ((flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) ||
|
xen: reject unknown flags
Also fix a logic bug in xenXMDomain{Attach,Detach}DeviceFlags,
where (flags & VIR_DOMAIN_DEVICE_MODIFY_CURRENT) is always false.
* src/xen/xen_driver.c (xenUnifiedDomainXMLFromNative)
(xenUnifiedDomainXMLToNative, xenUnifiedDomainBlockPeek): Reject
unknown flags.
* src/xen/xen_hypervisor.c (xenHypervisorOpen)
(xenHypervisorGetDomainState): Likewise.
* src/xen/xen_inotify.c (xenInotifyOpen): Likewise.
* src/xen/xs_internal.c (xenStoreOpen, xenStoreDomainGetState)
(xenStoreDomainReboot): Likewise.
* src/xen/xend_internal.c (xenDaemonOpen, xenDaemonDomainReboot)
(xenDaemonDomainCoreDump, xenDaemonDomainGetState)
(xenDaemonDomainMigratePrepare, xenDaemonDomainSetVcpusFlags,
xenDaemonDomainGetVcpusFlags, xenDaemonAttachDeviceFlags,
xenDaemonDetachDeviceFlags): Likewise.
(xenDaemonDomainGetXMLDesc): Prefer unsigned flags.
* src/xen/xend_internal.h (xenDaemonDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.h (xenXMDomainGetXMLDesc): Likewise.
* src/xen/xm_internal.c (xenXMDomainGetXMLDesc): Likewise.
(xenXMOpen, xenXMDomainGetState, xenXMDomainSetVcpusFlags)
(xenXMDomainGetVcpusFlags): Reject unknown flags.
(xenXMDomainAttachDeviceFlags, xenXMDomainDetachDeviceFlags):
Likewise, and avoid always-false conditional.
* src/xen/xen_driver.h (XEN_MIGRATION_FLAGS): New define.
2011-07-06 23:15:33 +00:00
|
|
|
(domain->id != -1 && flags == VIR_DOMAIN_DEVICE_MODIFY_CURRENT)) {
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("Xm driver only supports modifying persistent config"));
|
2008-07-25 13:39:02 +00:00
|
|
|
return -1;
|
2010-10-01 14:37:53 +00:00
|
|
|
}
|
2009-01-21 18:11:14 +00:00
|
|
|
|
|
|
|
xenUnifiedLock(priv);
|
|
|
|
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!(filename = virHashLookup(priv->nameConfigMap, domain->name)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2009-01-20 17:34:56 +00:00
|
|
|
if (!(entry = virHashLookup(priv->configCache, filename)))
|
2009-01-21 18:11:14 +00:00
|
|
|
goto cleanup;
|
2008-10-10 16:08:01 +00:00
|
|
|
def = entry->def;
|
2008-02-06 17:57:10 +00:00
|
|
|
|
2010-02-09 18:58:01 +00:00
|
|
|
if (!(dev = virDomainDeviceDefParse(priv->caps,
|
2013-02-19 16:29:39 +00:00
|
|
|
priv->xmlopt,
|
2008-07-25 13:39:02 +00:00
|
|
|
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;
|
2008-02-06 17:57:10 +00:00
|
|
|
|
2008-07-25 13:39:02 +00:00
|
|
|
switch (dev->type) {
|
|
|
|
case VIR_DOMAIN_DEVICE_DISK:
|
|
|
|
{
|
2008-10-10 16:08:01 +00:00
|
|
|
for (i = 0 ; i < def->ndisks ; i++) {
|
|
|
|
if (def->disks[i]->dst &&
|
2008-07-25 13:39:02 +00:00
|
|
|
dev->data.disk->dst &&
|
2008-10-10 16:08:01 +00:00
|
|
|
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,
|
2009-06-04 13:56:49 +00:00
|
|
|
sizeof(*def->disks) *
|
|
|
|
(def->ndisks - (i + 1)));
|
2010-08-17 14:14:28 +00:00
|
|
|
def->ndisks--;
|
2008-07-25 13:39:02 +00:00
|
|
|
break;
|
2008-02-06 17:57:10 +00:00
|
|
|
}
|
|
|
|
}
|
2008-07-25 13:39:02 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case VIR_DOMAIN_DEVICE_NET:
|
|
|
|
{
|
2008-10-10 16:08:01 +00:00
|
|
|
for (i = 0 ; i < def->nnets ; i++) {
|
2012-07-17 12:07:59 +00:00
|
|
|
if (!virMacAddrCmp(&def->nets[i]->mac, &dev->data.net->mac)) {
|
2008-10-10 16:08:01 +00:00
|
|
|
virDomainNetDefFree(def->nets[i]);
|
|
|
|
if (i < (def->nnets - 1))
|
|
|
|
memmove(def->nets + i,
|
|
|
|
def->nets + i + 1,
|
2009-06-04 13:56:49 +00:00
|
|
|
sizeof(*def->nets) *
|
|
|
|
(def->nnets - (i + 1)));
|
2010-08-17 14:14:28 +00:00
|
|
|
def->nnets--;
|
2008-07-25 13:39:02 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2008-02-06 17:57:10 +00:00
|
|
|
}
|
2008-07-25 13:39:02 +00:00
|
|
|
default:
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
|
|
_("device type '%s' cannot be detached"),
|
|
|
|
virDomainDeviceTypeToString(dev->type));
|
2008-02-06 17:57:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If this fails, should we try to undo our changes to the
|
|
|
|
* in-memory representation of the config file. I say not!
|
|
|
|
*/
|
2008-07-25 13:39:02 +00:00
|
|
|
if (xenXMConfigSaveFile(domain->conn, entry->filename, entry->def) < 0)
|
2008-02-06 17:57:10 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
cleanup:
|
2008-07-25 13:39:02 +00:00
|
|
|
virDomainDeviceDefFree(dev);
|
2009-01-21 18:11:14 +00:00
|
|
|
xenUnifiedUnlock(priv);
|
2012-03-22 11:33:35 +00:00
|
|
|
return ret;
|
2008-02-06 17:57:10 +00:00
|
|
|
}
|
|
|
|
|
virDomainBlockPeek call
* configure.in: Document AC_SYS_LARGEFILE.
* docs/hvsupport.html.in: Document HV support for virDomainBlockPeek.
* include/libvirt/libvirt.h.in, src/driver.h, src/libvirt.c,
src/libvirt_sym.version: Add virDomainBlockPeek infrastructure.
* src/qemu_driver.c, src/test.c: Null versions of this call.
* src/xen_unified.c, src/xend_internal.c, src/xend_internal.h,
src/xm_internal.c, src/xm_internal.h: Xen implementation.
* tests/sexpr2xmldata/sexpr2xml-curmem.xml,
tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml: XML output
has been reordered slightly in the Xen driver, but should be
functionally the same.
2008-06-05 13:17:45 +00:00
|
|
|
int
|
2012-10-17 09:23:12 +00:00
|
|
|
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)
|
virDomainBlockPeek call
* configure.in: Document AC_SYS_LARGEFILE.
* docs/hvsupport.html.in: Document HV support for virDomainBlockPeek.
* include/libvirt/libvirt.h.in, src/driver.h, src/libvirt.c,
src/libvirt_sym.version: Add virDomainBlockPeek infrastructure.
* src/qemu_driver.c, src/test.c: Null versions of this call.
* src/xen_unified.c, src/xend_internal.c, src/xend_internal.h,
src/xm_internal.c, src/xm_internal.h: Xen implementation.
* tests/sexpr2xmldata/sexpr2xml-curmem.xml,
tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml: XML output
has been reordered slightly in the Xen driver, but should be
functionally the same.
2008-06-05 13:17:45 +00:00
|
|
|
{
|
2012-07-18 13:48:05 +00:00
|
|
|
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
|
|
|
_("block peeking not implemented"));
|
virDomainBlockPeek call
* configure.in: Document AC_SYS_LARGEFILE.
* docs/hvsupport.html.in: Document HV support for virDomainBlockPeek.
* include/libvirt/libvirt.h.in, src/driver.h, src/libvirt.c,
src/libvirt_sym.version: Add virDomainBlockPeek infrastructure.
* src/qemu_driver.c, src/test.c: Null versions of this call.
* src/xen_unified.c, src/xend_internal.c, src/xend_internal.h,
src/xm_internal.c, src/xm_internal.h: Xen implementation.
* tests/sexpr2xmldata/sexpr2xml-curmem.xml,
tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml: XML output
has been reordered slightly in the Xen driver, but should be
functionally the same.
2008-06-05 13:17:45 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-11-25 11:04:34 +00:00
|
|
|
|
2013-01-29 14:24:42 +00:00
|
|
|
static char *
|
|
|
|
xenXMAutostartLinkName(virDomainPtr dom)
|
2008-11-25 11:04:34 +00:00
|
|
|
{
|
|
|
|
char *ret;
|
2009-10-16 10:09:13 +00:00
|
|
|
if (virAsprintf(&ret, "/etc/xen/auto/%s", dom->name) < 0)
|
|
|
|
return NULL;
|
2008-11-25 11:04:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-01-29 14:24:42 +00:00
|
|
|
static char *
|
|
|
|
xenXMDomainConfigName(virDomainPtr dom)
|
2008-11-25 11:04:34 +00:00
|
|
|
{
|
|
|
|
char *ret;
|
2009-10-16 10:09:13 +00:00
|
|
|
if (virAsprintf(&ret, "/etc/xen/%s", dom->name) < 0)
|
|
|
|
return NULL;
|
2008-11-25 11:04:34 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-01-29 14:24:42 +00:00
|
|
|
int
|
|
|
|
xenXMDomainGetAutostart(virDomainPtr dom, int *autostart)
|
2008-11-25 11:04:34 +00:00
|
|
|
{
|
|
|
|
char *linkname = xenXMAutostartLinkName(dom);
|
|
|
|
char *config = xenXMDomainConfigName(dom);
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if (!linkname || !config) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-11-25 11:04:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
*autostart = virFileLinkPointsTo(linkname, config);
|
|
|
|
if (*autostart < 0) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno,
|
2009-01-20 17:13:33 +00:00
|
|
|
_("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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-01-29 14:24:42 +00:00
|
|
|
int
|
|
|
|
xenXMDomainSetAutostart(virDomainPtr dom, int autostart)
|
2008-11-25 11:04:34 +00:00
|
|
|
{
|
|
|
|
char *linkname = xenXMAutostartLinkName(dom);
|
|
|
|
char *config = xenXMDomainConfigName(dom);
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if (!linkname || !config) {
|
2010-02-04 18:19:08 +00:00
|
|
|
virReportOOMError();
|
2008-11-25 11:04:34 +00:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (autostart) {
|
|
|
|
if (symlink(config, linkname) < 0 &&
|
|
|
|
errno != EEXIST) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno,
|
2009-01-20 17:13:33 +00:00
|
|
|
_("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) {
|
2010-02-04 20:02:58 +00:00
|
|
|
virReportSystemError(errno,
|
2009-01-20 17:13:33 +00:00
|
|
|
_("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;
|
|
|
|
}
|