+Fri Jun 16 12:44:02 EDT 2006 Daniel Veillard <veillard@redhat.com>
+
+ * src/libvirt.c src/xen_internal.c src/xend_internal.c: more driver
+ related cleanups, nearly finished
+
Thu Jun 15 14:57:39 EDT 2006 Daniel Veillard <veillard@redhat.com>
* src/libvirt.c src/xend_internal.c src/xend_internal.h
* Returns a new domain object or NULL in case of failure
*/
virDomainPtr
-virDomainCreateLinux(virConnectPtr conn,
- const char *xmlDesc,
- unsigned int flags ATTRIBUTE_UNUSED)
+virDomainCreateLinux(virConnectPtr conn, const char *xmlDesc,
+ unsigned int flags)
{
- int ret;
- char *sexpr;
- char *name = NULL;
- virDomainPtr dom;
+ virDomainPtr ret;
+ int i;
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
return (NULL);
}
- sexpr = virDomainParseXMLDesc(xmlDesc, &name);
- if ((sexpr == NULL) || (name == NULL)) {
- if (sexpr != NULL)
- free(sexpr);
- if (name != NULL)
- free(name);
-
- return (NULL);
- }
-
- ret = xenDaemonDomainCreateLinux(conn, sexpr);
- free(sexpr);
- if (ret != 0) {
- fprintf(stderr, "Failed to create domain %s\n", name);
- goto error;
- }
-
- ret = xend_wait_for_devices(conn, name);
- if (ret != 0) {
- fprintf(stderr, "Failed to get devices for domain %s\n", name);
- goto error;
- }
-
- dom = virDomainLookupByName(conn, name);
- if (dom == NULL) {
- goto error;
- }
-
- ret = xenDaemonDomainResume(dom);
- if (ret != 0) {
- fprintf(stderr, "Failed to resume new domain %s\n", name);
- xenDaemonDomainDestroy(dom);
- goto error;
+ for (i = 0;i < conn->nb_drivers;i++) {
+ if ((conn->drivers[i] != NULL) &&
+ (conn->drivers[i]->domainCreateLinux != NULL)) {
+ ret = conn->drivers[i]->domainCreateLinux(conn, xmlDesc, flags);
+ if (ret != NULL)
+ return(ret);
+ }
}
-
- dom = virDomainLookupByName(conn, name);
- free(name);
-
- return (dom);
- error:
- if (name != NULL)
- free(name);
- return (NULL);
+ return(NULL);
}
int
virDomainResume(virDomainPtr domain)
{
- int ret = -1, i;
+ int i;
virConnectPtr conn;
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
if ((conn->drivers[i] != NULL) &&
(conn->drivers[i]->domainResume != NULL)) {
if (conn->drivers[i]->domainResume(domain) == 0)
- ret = 0;
+ return(0);
}
}
- if (ret != 0) {
- virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
- return (ret);
- }
-
- return (ret);
+ virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+ return (-1);
}
/**
int
virDomainSave(virDomainPtr domain, const char *to)
{
- int ret;
+ int ret, i;
char filepath[4096];
+ virConnectPtr conn;
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return (-1);
}
+ conn = domain->conn;
if (to == NULL) {
virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
return (-1);
}
- ret = xenDaemonDomainSave(domain, to);
- return (ret);
+ /* Go though the driver registered entry points */
+ for (i = 0;i < conn->nb_drivers;i++) {
+ if ((conn->drivers[i] != NULL) &&
+ (conn->drivers[i]->domainSave != NULL)) {
+ ret = conn->drivers[i]->domainSave(domain, to);
+ if (ret == 0)
+ return(0);
+ }
+ }
+ virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+ return (-1);
}
/**
int
virDomainRestore(virConnectPtr conn, const char *from)
{
- int ret;
+ int ret, i;
char filepath[4096];
if (!VIR_IS_CONNECT(conn)) {
from = &filepath[0];
}
- ret = xenDaemonDomainRestore(conn, from);
- return (ret);
+ /* Go though the driver registered entry points */
+ for (i = 0;i < conn->nb_drivers;i++) {
+ if ((conn->drivers[i] != NULL) &&
+ (conn->drivers[i]->domainSave != NULL)) {
+ ret = conn->drivers[i]->domainRestore(conn, from);
+ if (ret == 0)
+ return(0);
+ }
+ }
+ virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+ return (-1);
}
/**
virDomainGetMaxMemory(virDomainPtr domain)
{
unsigned long ret = 0;
+ virConnectPtr conn;
+ int i;
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
return (0);
}
+ conn = domain->conn;
+
/*
- * try first with the hypervisor if available
+ * in that case instead of trying only though one method try all availble.
+ * If needed that can be changed back if it's a performcance problem.
*/
- if (!(domain->conn->flags & VIR_CONNECT_RO)) {
- virDomainInfo dominfo;
- int tmp;
-
- tmp = xenHypervisorGetDomainInfo(domain, &dominfo);
- if (tmp >= 0)
- return(dominfo.maxMem);
- }
- ret = xenStoreDomainGetMaxMemory(domain);
- if (ret > 0)
- return(ret);
- ret = xenDaemonDomainGetMaxMemory(domain);
- return (ret);
+ for (i = 0;i < conn->nb_drivers;i++) {
+ if ((conn->drivers[i] != NULL) &&
+ (conn->drivers[i]->domainGetMaxMemory != NULL)) {
+ ret = conn->drivers[i]->domainGetMaxMemory(domain);
+ if (ret != 0)
+ return(ret);
+ }
+ }
+ virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+ return (-1);
}
/**
int
virDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
{
- int ret;
int i;
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
#define XEN_HYPERVISOR_SOCKET "/proc/xen/privcmd"
static const char * xenHypervisorGetType(virConnectPtr conn);
+static unsigned long xenHypervisorGetMaxMemory(virDomainPtr domain);
static virDriver xenHypervisorDriver = {
"Xen",
NULL, /* domainGetID */
NULL, /* domainGetUUID */
NULL, /* domainGetOSType */
- NULL, /* domainGetMaxMemory */
+ xenHypervisorGetMaxMemory, /* domainGetMaxMemory */
xenHypervisorSetMaxMemory, /* domainSetMaxMemory */
NULL, /* domainSetMemory */
xenHypervisorGetDomainInfo, /* domainGetInfo */
return (nbids);
}
+/**
+ * xenHypervisorGetMaxMemory:
+ * @domain: a domain object or NULL
+ *
+ * Retrieve the maximum amount of physical memory allocated to a
+ * domain. If domain is NULL, then this get the amount of memory reserved
+ * to Domain0 i.e. the domain where the application runs.
+ *
+ * Returns the memory size in kilobytes or 0 in case of error.
+ */
+static unsigned long
+xenHypervisorGetMaxMemory(virDomainPtr domain)
+{
+ dom0_op_t op;
+ dom0_getdomaininfo_t dominfo;
+ int ret;
+
+ if ((domain == NULL) || (domain->conn == NULL) ||
+ (domain->conn->handle < 0))
+ return (0);
+
+ memset(&dominfo, 0, sizeof(dom0_getdomaininfo_t));
+
+ if (mlock(&dominfo, sizeof(dom0_getdomaininfo_t)) < 0) {
+ virXenError(VIR_ERR_XEN_CALL, " locking",
+ sizeof(dom0_getdomaininfo_t));
+ return (0);
+ }
+
+ op.cmd = DOM0_GETDOMAININFOLIST;
+ op.u.getdomaininfolist.first_domain = (domid_t) domain->handle;
+ op.u.getdomaininfolist.max_domains = 1;
+ op.u.getdomaininfolist.buffer = &dominfo;
+ op.u.getdomaininfolist.num_domains = 1;
+ dominfo.domain = domain->handle;
+
+ ret = xenHypervisorDoOp(domain->conn->handle, &op);
+
+ if (munlock(&dominfo, sizeof(dom0_getdomaininfo_t)) < 0) {
+ virXenError(VIR_ERR_XEN_CALL, " release",
+ sizeof(dom0_getdomaininfo_t));
+ ret = -1;
+ }
+
+ if (ret < 0)
+ return (0);
+
+ return((unsigned long) dominfo.max_pages * 4);
+}
+
/**
* xenHypervisorGetDomainInfo:
* @domain: pointer to the domain block
static virDomainPtr xenDaemonLookupByID(virConnectPtr conn, int id);
static virDomainPtr xenDaemonLookupByUUID(virConnectPtr conn,
const unsigned char *uuid);
+static virDomainPtr xenDaemonCreateLinux(virConnectPtr conn,
+ const char *xmlDesc,
+ unsigned int flags);
static virDriver xenDaemonDriver = {
"XenDaemon",
xenDaemonNodeGetInfo, /* nodeGetInfo */
xenDaemonListDomains, /* listDomains */
xenDaemonNumOfDomains, /* numOfDomains */
- NULL, /* domainCreateLinux */
+ xenDaemonCreateLinux, /* domainCreateLinux */
xenDaemonLookupByID, /* domainLookupByID */
xenDaemonLookupByUUID, /* domainLookupByUUID */
xenDaemonDomainLookupByName, /* domainLookupByName */
NULL, /* domainGetID */
NULL, /* domainGetUUID */
NULL, /* domainGetOSType */
- NULL, /* domainGetMaxMemory */
+ xenDaemonDomainGetMaxMemory, /* domainGetMaxMemory */
xenDaemonDomainSetMaxMemory, /* domainSetMaxMemory */
xenDaemonDomainSetMemory, /* domainMaxMemory */
xenDaemonDomainGetInfo, /* domainGetInfo */
free(name);
return (NULL);
}
+
+/**
+ * xenDaemonCreateLinux:
+ * @conn: pointer to the hypervisor connection
+ * @xmlDesc: an XML description of the domain
+ * @flags: an optional set of virDomainFlags
+ *
+ * Launch a new Linux guest domain, based on an XML description similar
+ * to the one returned by virDomainGetXMLDesc()
+ * This function may requires priviledged access to the hypervisor.
+ *
+ * Returns a new domain object or NULL in case of failure
+ */
+static virDomainPtr
+xenDaemonCreateLinux(virConnectPtr conn, const char *xmlDesc,
+ unsigned int flags ATTRIBUTE_UNUSED)
+{
+ int ret;
+ char *sexpr;
+ char *name = NULL;
+ virDomainPtr dom;
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virXendError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+ if (xmlDesc == NULL) {
+ virXendError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ return (NULL);
+ }
+
+ sexpr = virDomainParseXMLDesc(xmlDesc, &name);
+ if ((sexpr == NULL) || (name == NULL)) {
+ if (sexpr != NULL)
+ free(sexpr);
+ if (name != NULL)
+ free(name);
+
+ return (NULL);
+ }
+
+ ret = xenDaemonDomainCreateLinux(conn, sexpr);
+ free(sexpr);
+ if (ret != 0) {
+ fprintf(stderr, "Failed to create domain %s\n", name);
+ goto error;
+ }
+
+ ret = xend_wait_for_devices(conn, name);
+ if (ret != 0) {
+ fprintf(stderr, "Failed to get devices for domain %s\n", name);
+ goto error;
+ }
+
+ dom = virDomainLookupByName(conn, name);
+ if (dom == NULL) {
+ goto error;
+ }
+
+ ret = xenDaemonDomainResume(dom);
+ if (ret != 0) {
+ fprintf(stderr, "Failed to resume new domain %s\n", name);
+ xenDaemonDomainDestroy(dom);
+ goto error;
+ }
+
+ dom = virDomainLookupByName(conn, name);
+ free(name);
+
+ return (dom);
+ error:
+ if (name != NULL)
+ free(name);
+ return (NULL);
+}
+