]> xenbits.xensource.com Git - libvirt.git/commitdiff
* src/libvirt.c src/xen_internal.c src/xend_internal.c: more driver
authorDaniel Veillard <veillard@redhat.com>
Fri, 16 Jun 2006 12:36:40 +0000 (12:36 +0000)
committerDaniel Veillard <veillard@redhat.com>
Fri, 16 Jun 2006 12:36:40 +0000 (12:36 +0000)
  related cleanups, nearly finished
Daniel

ChangeLog
src/libvirt.c
src/xen_internal.c
src/xend_internal.c

index f1cca3e869ff32aeba7226a050d2c34e75a89041..11294b77f2e67efc74e0727b76b31909079b0e1a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index d8b33f57f1d2f9d59ef8cf509039eb9a549858cb..c5fe275d07331ed377edd74807ad8b64932de846 100644 (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);
-    }
-
-    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);
 }
 
 
@@ -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);
     }
 
+    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);
 }
 
 /**
@@ -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)) {
index 6ab54779dc158c1dab692297f8cc8ee624bd6a33..0f8dada3e2b88821acfab49f385587cd54ab68c1 100644 (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
index 1a4f124971be42a6973ab0a88d8c14abd99bc21b..fc1ff7a41e93dfa33fb9a00fe82e61e4eca5ee60 100644 (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);
+}
+