* src/libvirt.c src/xen_internal.c src/xend_internal.c: more driver

related cleanups, nearly finished
Daniel
This commit is contained in:
Daniel Veillard 2006-06-16 12:36:40 +00:00
parent 442b733e6c
commit 15b40d295d
4 changed files with 196 additions and 81 deletions

View File

@ -1,3 +1,8 @@
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

View File

@ -516,14 +516,11 @@ virConnectNumOfDomains(virConnectPtr conn)
* 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__);
@ -534,49 +531,15 @@ virDomainCreateLinux(virConnectPtr conn,
return (NULL);
}
sexpr = virDomainParseXMLDesc(xmlDesc, &name);
if ((sexpr == NULL) || (name == NULL)) {
if (sexpr != NULL)
free(sexpr);
if (name != NULL)
free(name);
return (NULL);
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);
}
}
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);
return(NULL);
}
@ -865,7 +828,7 @@ virDomainSuspend(virDomainPtr domain)
int
virDomainResume(virDomainPtr domain)
{
int ret = -1, i;
int i;
virConnectPtr conn;
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@ -884,16 +847,12 @@ virDomainResume(virDomainPtr 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);
}
/**
@ -911,13 +870,15 @@ virDomainResume(virDomainPtr domain)
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);
@ -943,8 +904,17 @@ virDomainSave(virDomainPtr domain, const char *to)
}
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);
}
/**
@ -959,7 +929,7 @@ virDomainSave(virDomainPtr domain, const char *to)
int
virDomainRestore(virConnectPtr conn, const char *from)
{
int ret;
int ret, i;
char filepath[4096];
if (!VIR_IS_CONNECT(conn)) {
@ -990,8 +960,17 @@ virDomainRestore(virConnectPtr conn, const char *from)
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);
}
/**
@ -1242,28 +1221,30 @@ unsigned long
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);
}
/*
* try first with the hypervisor if available
*/
if (!(domain->conn->flags & VIR_CONNECT_RO)) {
virDomainInfo dominfo;
int tmp;
conn = domain->conn;
tmp = xenHypervisorGetDomainInfo(domain, &dominfo);
if (tmp >= 0)
return(dominfo.maxMem);
/*
* 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.
*/
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);
}
}
ret = xenStoreDomainGetMaxMemory(domain);
if (ret > 0)
return(ret);
ret = xenDaemonDomainGetMaxMemory(domain);
return (ret);
virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
return (-1);
}
/**
@ -1384,7 +1365,6 @@ virDomainSetMemory(virDomainPtr domain, unsigned long memory)
int
virDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
{
int ret;
int i;
if (!VIR_IS_CONNECTED_DOMAIN(domain)) {

View File

@ -41,6 +41,7 @@ typedef struct hypercall_struct {
#define XEN_HYPERVISOR_SOCKET "/proc/xen/privcmd"
static const char * xenHypervisorGetType(virConnectPtr conn);
static unsigned long xenHypervisorGetMaxMemory(virDomainPtr domain);
static virDriver xenHypervisorDriver = {
"Xen",
@ -69,7 +70,7 @@ static virDriver xenHypervisorDriver = {
NULL, /* domainGetID */
NULL, /* domainGetUUID */
NULL, /* domainGetOSType */
NULL, /* domainGetMaxMemory */
xenHypervisorGetMaxMemory, /* domainGetMaxMemory */
xenHypervisorSetMaxMemory, /* domainSetMaxMemory */
NULL, /* domainSetMemory */
xenHypervisorGetDomainInfo, /* domainGetInfo */
@ -396,6 +397,56 @@ xenHypervisorListDomains(virConnectPtr conn, int *ids, int maxids)
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

View File

@ -44,6 +44,9 @@ static int xenDaemonNumOfDomains(virConnectPtr conn);
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",
@ -58,7 +61,7 @@ static virDriver xenDaemonDriver = {
xenDaemonNodeGetInfo, /* nodeGetInfo */
xenDaemonListDomains, /* listDomains */
xenDaemonNumOfDomains, /* numOfDomains */
NULL, /* domainCreateLinux */
xenDaemonCreateLinux, /* domainCreateLinux */
xenDaemonLookupByID, /* domainLookupByID */
xenDaemonLookupByUUID, /* domainLookupByUUID */
xenDaemonDomainLookupByName, /* domainLookupByName */
@ -72,7 +75,7 @@ static virDriver xenDaemonDriver = {
NULL, /* domainGetID */
NULL, /* domainGetUUID */
NULL, /* domainGetOSType */
NULL, /* domainGetMaxMemory */
xenDaemonDomainGetMaxMemory, /* domainGetMaxMemory */
xenDaemonDomainSetMaxMemory, /* domainSetMaxMemory */
xenDaemonDomainSetMemory, /* domainMaxMemory */
xenDaemonDomainGetInfo, /* domainGetInfo */
@ -2340,3 +2343,79 @@ error:
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);
}