]> xenbits.xensource.com Git - libvirt.git/commitdiff
* TODO: updated
authorDaniel Veillard <veillard@redhat.com>
Mon, 20 Feb 2006 17:22:16 +0000 (17:22 +0000)
committerDaniel Veillard <veillard@redhat.com>
Mon, 20 Feb 2006 17:22:16 +0000 (17:22 +0000)
* include/libvirt.h include/libvirt.h.in: cleanup
* src/libvirt.c: remove debugging output
* src/xend_internal.c src/xml.c src/xml.h: reimplement
  virDomainGetXMLDesc() based on xend interface, now work as user too.
Daniel

ChangeLog
TODO
include/libvirt.h
include/libvirt.h.in
include/libvirt/libvirt.h
include/libvirt/libvirt.h.in
src/libvirt.c
src/xend_internal.c
src/xml.c
src/xml.h

index bc895dd9944a4321425646589d2b51be6b539e8e..b5303364255e42f3ba11f96ec28e61a2e65c2c9b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Mon Feb 20 12:20:32 EST 2006 Daniel Veillard <veillard@redhat.com>
+
+       * TODO: updated
+       * include/libvirt.h include/libvirt.h.in: cleanup
+       * src/libvirt.c: remove debugging output
+       * src/xend_internal.c src/xml.c src/xml.h: reimplement 
+         virDomainGetXMLDesc() based on xend interface, now work as user too.
+
 Fri Feb 17 08:17:36 EST 2006 Daniel Veillard <veillard@redhat.com>
 
        * python/tests/create.py: trying to make test more generic, but it's
diff --git a/TODO b/TODO
index beadf81c5fd10a4ff945d14353da7fcb72d95509..c3c82a2ddd817f61e311a647be730231fbe5cfce 100644 (file)
--- a/TODO
+++ b/TODO
@@ -4,6 +4,7 @@ Absolute TODOs:
 - thread protection, reentrancy, refcounting, etc ...
 - documentation and examples on using the toolkit
 - Error API. probably similar to libxml2 structured API
+- extract error messages from the Xend rpc
 
 TODO:
 - track change of xend API, XML-RPC, UUID based lookup and naming
@@ -18,6 +19,10 @@ Would-be-nice TODO:
 - man page for virsh and the libraries entry points
 - support for QEmu and other virtualization engines
 
+Cleanup:
+- now that libxml2 is linked in, drop hash.[ch] and get back to libxml2 ones ?
+  same for the buffers 
+
 Done:
 - make dist and make rpm targets
 - set a no public by default policy for libvir symbols
index b6951868b654a720bc83fed34be30f1f6ae90675..30269299ff110670ae994c7969195874219fc425 100644 (file)
@@ -239,10 +239,12 @@ char *                    virDomainGetOSType      (virDomainPtr domain);
 unsigned long          virDomainGetMaxMemory   (virDomainPtr domain);
 int                    virDomainSetMaxMemory   (virDomainPtr domain,
                                                 unsigned long memory);
+
 /*
  * XML domain description
  */
-char *                 virDomainGetXMLDesc     (virDomainPtr domain, int flags);
+char *                 virDomainGetXMLDesc     (virDomainPtr domain,
+                                                int flags);
 
 #ifdef __cplusplus
 }
index 6655c388e5566b3ae16163bb99d07b981bcb8119..1fe50152322811f97dd9e0d3f37a73b8e240f1dc 100644 (file)
@@ -242,7 +242,8 @@ int                 virDomainSetMaxMemory   (virDomainPtr domain,
 /*
  * XML domain description
  */
-char *                 virDomainGetXMLDesc     (virDomainPtr domain, int flags);
+char *                 virDomainGetXMLDesc     (virDomainPtr domain,
+                                                int flags);
 
 #ifdef __cplusplus
 }
index b6951868b654a720bc83fed34be30f1f6ae90675..30269299ff110670ae994c7969195874219fc425 100644 (file)
@@ -239,10 +239,12 @@ char *                    virDomainGetOSType      (virDomainPtr domain);
 unsigned long          virDomainGetMaxMemory   (virDomainPtr domain);
 int                    virDomainSetMaxMemory   (virDomainPtr domain,
                                                 unsigned long memory);
+
 /*
  * XML domain description
  */
-char *                 virDomainGetXMLDesc     (virDomainPtr domain, int flags);
+char *                 virDomainGetXMLDesc     (virDomainPtr domain,
+                                                int flags);
 
 #ifdef __cplusplus
 }
index 6655c388e5566b3ae16163bb99d07b981bcb8119..1fe50152322811f97dd9e0d3f37a73b8e240f1dc 100644 (file)
@@ -242,7 +242,8 @@ int                 virDomainSetMaxMemory   (virDomainPtr domain,
 /*
  * XML domain description
  */
-char *                 virDomainGetXMLDesc     (virDomainPtr domain, int flags);
+char *                 virDomainGetXMLDesc     (virDomainPtr domain,
+                                                int flags);
 
 #ifdef __cplusplus
 }
index 604882cfd7304e4b31f80ee66333268d549aba05..55506ae064799140073d9690b088b5540c367548 100644 (file)
@@ -427,8 +427,6 @@ virDomainCreateLinux(virConnectPtr conn,
         return(NULL);
     }
 
-    printf("%s\n", sexpr);
-
     ret = xend_create_sexpr(conn, sexpr);
     free(sexpr);
     if (ret != 0) {
index 36045fc49244a5c15b70172fb8d3993d9f605ab2..caa04a7d93e0f7f7cc491a1fa130729d5a81da87 100644 (file)
@@ -30,6 +30,7 @@
 #include "libvirt.h"
 #include "internal.h"
 #include "sexpr.h"
+#include "xml.h"
 #include "xend_internal.h"
 
 /**
@@ -2102,3 +2103,181 @@ xend_log(virConnectPtr xend, char *buffer, size_t n_buffer)
 {
     return http2unix(xend_get(xend, "/xend/node/log", buffer, n_buffer));
 }
+
+/**
+ * virDomainParseSExprDesc:
+ * @root: the root of the parsed S-Expression
+ * @name: output name of the domain
+ *
+ * Parse the xend sexp description and turn it into the XML format similar
+ * to the one unsed for creation.
+ *
+ * Returns the 0 terminated XML string or NULL in case of error.
+ *         the caller must free() the returned value.
+ */
+static char *
+virDomainParseSExprDesc(struct sexpr *root) {
+    char *ret;
+    struct sexpr *cur, *node;
+    const char *tmp;
+    virBuffer buf;
+
+    if (root == NULL) {
+        /* ERROR */
+        return(NULL);
+    }
+    ret = malloc(1000);
+    if (ret == NULL)
+        return(NULL);
+    buf.content = ret;
+    buf.size = 1000;
+    buf.use = 0;
+
+    virBufferVSprintf(&buf, "<domain type='xen' id='%d'>\n",
+                      sexpr_int(root, "domain/domid"));
+    tmp = sexpr_node(root, "domain/name");
+    if (tmp == NULL) {
+        /* VIR_ERR_NO_NAME */
+       goto error;
+    }
+    virBufferVSprintf(&buf, "  <name>%s</name>\n", tmp);
+    tmp = sexpr_node(root, "domain/image/linux/kernel");
+    if (tmp == NULL) {
+        /*
+        * TODO: we will need some fallback here for other guest OSes
+        */
+        /* VIR_ERR_NO_KERNEL */
+       goto error;
+    }
+    virBufferAdd(&buf, "  <os>\n", 7);
+    virBufferVSprintf(&buf, "    <type>linux</type>\n");
+    virBufferVSprintf(&buf, "    <kernel>%s</kernel>\n", tmp);
+    tmp = sexpr_node(root, "domain/image/linux/ramdisk");
+    if ((tmp != NULL) && (tmp[0] != 0))
+       virBufferVSprintf(&buf, "    <initrd>%s</initrd>\n", tmp);
+    tmp = sexpr_node(root, "domain/image/linux/root");
+    if ((tmp != NULL) && (tmp[0] != 0))
+       virBufferVSprintf(&buf, "    <root>%s</root>\n", tmp);
+    tmp = sexpr_node(root, "domain/image/linux/args");
+    if ((tmp != NULL) && (tmp[0] != 0))
+       virBufferVSprintf(&buf, "    <cmdline>%s</cmdline>\n", tmp);
+    virBufferAdd(&buf, "  </os>\n", 8);
+    virBufferVSprintf(&buf, "  <memory>%d</memory>\n", 
+                      (int) (sexpr_u64(root, "domain/maxmem") << 10));
+    virBufferVSprintf(&buf, "  <vcpu>%d</vcpu>\n", 
+                      sexpr_int(root, "domain/vcpus"));
+    virBufferAdd(&buf, "  <devices>\n", 12);
+    for (cur = root; cur->kind == SEXPR_CONS; cur = cur->cdr) {
+        node = cur->car;
+       if (sexpr_lookup(node, "device/vbd")) {
+           tmp = sexpr_node(node, "device/vbd/uname");
+           if (tmp == NULL)
+               continue;
+           if (!memcmp(tmp, "file:", 5)) {
+               tmp += 5;
+               virBufferVSprintf(&buf, "    <disk type='file'>\n");
+               virBufferVSprintf(&buf, "      <source file='%s'/>\n", tmp);
+               tmp = sexpr_node(node, "device/vbd/dev");
+               if (tmp == NULL) {
+                   /* VIR_ERR_NO_DEV */
+                   goto error;
+               }
+               virBufferVSprintf(&buf, "      <target dev='%s'/>\n", tmp);
+               tmp = sexpr_node(node, "device/vbd/mode");
+               if ((tmp != NULL) && (!strcmp(tmp, "r")))
+                   virBufferVSprintf(&buf, "      <readonly/>\n");
+               virBufferAdd(&buf, "    </disk>\n", 12);
+           } else if (!memcmp(tmp, "phy:", 4)) {
+               tmp += 4;
+               virBufferVSprintf(&buf, "    <disk type='block'>\n");
+               virBufferVSprintf(&buf, "      <source dev='%s'/>\n", tmp);
+               tmp = sexpr_node(node, "device/vbd/dev");
+               if (tmp == NULL) {
+                   /* VIR_ERR_NO_DEV */
+                   goto error;
+               }
+               virBufferVSprintf(&buf, "      <target dev='%s'/>\n", tmp);
+               tmp = sexpr_node(node, "device/vbd/mode");
+               if ((tmp != NULL) && (!strcmp(tmp, "r")))
+                   virBufferVSprintf(&buf, "      <readonly/>\n");
+               virBufferAdd(&buf, "    </disk>\n", 12);
+           } else {
+               char serial[1000];
+
+               TODO
+               sexpr2string(node, serial, 1000);
+               virBufferVSprintf(&buf, "<!-- Failed to parse %s -->\n",
+                                 serial);
+               TODO
+           }
+       } else if (sexpr_lookup(node, "device/vif")) {
+           tmp = sexpr_node(node, "device/vif/bridge");
+           if (tmp != NULL) {
+               virBufferVSprintf(&buf, "    <interface type='bridge'>\n");
+               virBufferVSprintf(&buf, "      <source bridge='%s'/>\n", tmp);
+               tmp = sexpr_node(node, "device/vif/vifname");
+               if (tmp != NULL)
+                   virBufferVSprintf(&buf, "      <target dev='%s'/>\n", tmp);
+               tmp = sexpr_node(node, "device/vif/mac");
+               if (tmp != NULL)
+                   virBufferVSprintf(&buf, "      <mac address='%s'/>\n", tmp);
+               tmp = sexpr_node(node, "device/vif/ip");
+               if (tmp != NULL)
+                   virBufferVSprintf(&buf, "      <ip address='%s'/>\n", tmp);
+               tmp = sexpr_node(node, "device/vif/script");
+               if (tmp != NULL)
+                   virBufferVSprintf(&buf, "      <script path='%s'/>\n", tmp);
+               virBufferAdd(&buf, "    </interface>\n", 17);
+           } else {
+               char serial[1000];
+
+               TODO
+               sexpr2string(node->car, serial, 1000);
+               virBufferVSprintf(&buf, "<!-- Failed to parse %s -->\n",
+                                 serial);
+           }
+           
+       }
+    }
+    virBufferAdd(&buf, "  </devices>\n", 13);
+    virBufferAdd(&buf, "</domain>\n", 10);
+
+    buf.content[buf.use] = 0;
+    return(ret);
+
+error:
+    if (ret != NULL)
+        free(ret);
+    return(NULL);
+}
+
+/**
+ * virDomainGetXMLDesc:
+ * @domain: a domain object
+ * @flags: and OR'ed set of extraction flags, not used yet
+ *
+ * Provide an XML description of the domain. NOTE: this API is subject
+ * to changes.
+ *
+ * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error.
+ *         the caller must free() the returned value.
+ */
+char *
+virDomainGetXMLDesc(virDomainPtr domain, int flags) {
+    char *ret = NULL;
+    struct sexpr *root;
+
+    if (!VIR_IS_DOMAIN(domain))
+       return(NULL);
+    if (flags != 0)
+       return(NULL);
+
+    root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
+    if (root == NULL)
+        return(NULL);
+
+    ret = virDomainParseSExprDesc(root);
+    sexpr_free(root);
+
+    return(ret);
+}
index fe4836c234cc172226ece150e894b29d4a6a04b8..fd97a9e9e03f9c6e623671c194656175fe0b3d53 100644 (file)
--- a/src/xml.c
+++ b/src/xml.c
 #include <libxml/xpath.h>
 #include "internal.h"
 #include "hash.h"
+#include "sexpr.h"
 #include "xml.h"
 
-/**
- * virBuffer:
- *
- * A buffer structure.
- */
-typedef struct _virBuffer virBuffer;
-typedef virBuffer *virBufferPtr;
-struct _virBuffer {
-    char *content;             /* The buffer content UTF8 */
-    unsigned int use;          /* The buffer size used */
-    unsigned int size;         /* The buffer size */
-};
-
 /**
  * virBufferGrow:
  * @buf:  the buffer
@@ -74,7 +62,7 @@ virBufferGrow(virBufferPtr buf, unsigned int len) {
  *
  * Returns 0 successful, -1 in case of internal or API error.
  */
-static int
+int
 virBufferAdd(virBufferPtr buf, const char *str, int len) {
     unsigned int needSize;
 
@@ -109,7 +97,7 @@ virBufferAdd(virBufferPtr buf, const char *str, int len) {
  *
  * Returns 0 successful, -1 in case of internal or API error.
  */
-static int
+int
 virBufferVSprintf(virBufferPtr buf, const char *format, ...) {
     int size, count;
     va_list locarg, argptr;
@@ -136,6 +124,12 @@ virBufferVSprintf(virBufferPtr buf, const char *format, ...) {
     return(0);
 }
 
+#if 0
+/*
+ * This block of function are now implemented by a xend poll in
+ * xend_internal.c instead of querying the Xen store, code is kept
+ * for reference of in case Xend may not be available in the future ...
+ */
 /**
  * virDomainGetXMLDevice:
  * @domain: a domain object
@@ -464,6 +458,8 @@ virDomainGetXMLDesc(virDomainPtr domain, int flags) {
     return(ret);
 }
 
+#endif
+
 /**
  * virDomainParseXMLOSDesc:
  * @xmldesc: string with the XML description
@@ -827,7 +823,6 @@ virDomainParseXMLDesc(const char *xmldesc, char **name) {
     virBufferAdd(&buf, ")", 1);
 
     /* analyze of the devices */
-    virBufferAdd(&buf, "(device ", 8);
     obj = xmlXPathEval(BAD_CAST "/domain/devices/disk", ctxt);
     if ((obj == NULL) || (obj->type != XPATH_NODESET) ||
         (obj->nodesetval == NULL) ||
@@ -836,27 +831,30 @@ virDomainParseXMLDesc(const char *xmldesc, char **name) {
         goto error;
     }
     for (i = 0;i < obj->nodesetval->nodeNr;i++) {
+       virBufferAdd(&buf, "(device ", 8);
        res = virDomainParseXMLDiskDesc(obj->nodesetval->nodeTab[i], &buf);
        if (res != 0) {
            goto error;
        }
+       virBufferAdd(&buf, ")", 1);
     }
     xmlXPathFreeObject(obj);
     obj = xmlXPathEval(BAD_CAST "/domain/devices/interface", ctxt);
     if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
         (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) {
        for (i = 0;i < obj->nodesetval->nodeNr;i++) {
+           virBufferAdd(&buf, "(device ", 8);
            res = virDomainParseXMLIfDesc(obj->nodesetval->nodeTab[i], &buf);
            if (res != 0) {
                goto error;
            }
+           virBufferAdd(&buf, ")", 1);
        }
     }
     xmlXPathFreeObject(obj);
-    virBufferAdd(&buf, ")", 1);
 
 
-    virBufferAdd(&buf, ")", 1);
+    virBufferAdd(&buf, ")", 1); /* closes (vm */
     buf.content[buf.use] = 0;
 
     xmlXPathFreeContext(ctxt);
@@ -880,3 +878,4 @@ error:
         free(ret);
     return(NULL);
 }
+
index 1ba6c502802ca246a15a56e23b69fe4b710addee..e802be97177aacd2c7300fa130389c7aa661a9e8 100644 (file)
--- a/src/xml.h
+++ b/src/xml.h
 extern "C" {
 #endif
 
+/**
+ * virBuffer:
+ *
+ * A buffer structure.
+ */
+typedef struct _virBuffer virBuffer;
+typedef virBuffer *virBufferPtr;
+struct _virBuffer {
+    char *content;             /* The buffer content UTF8 */
+    unsigned int use;          /* The buffer size used */
+    unsigned int size;         /* The buffer size */
+};
+
+int    virBufferAdd            (virBufferPtr buf,
+                                const char *str,
+                                int len);
+int    virBufferVSprintf       (virBufferPtr buf,
+                                const char *format,
+                                ...);
 char * virDomainParseXMLDesc   (const char *xmldesc,
                                 char **name);