]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
* include/libvir.h src/Makefile.am src/internal.h src/libvir.c
authorDaniel Veillard <veillard@redhat.com>
Tue, 13 Dec 2005 16:22:05 +0000 (16:22 +0000)
committerDaniel Veillard <veillard@redhat.com>
Tue, 13 Dec 2005 16:22:05 +0000 (16:22 +0000)
  src/libvir_sym.version src/virsh.c src/xml.c: started working on
  the XML dump, added a dumpxml virsh version and a bit of
  infrastructure code. Found a way to detect dead ID from xenstore
  data.
Daniel

ChangeLog
include/libvir.h
src/Makefile.am
src/internal.h
src/libvir.c
src/libvir_sym.version
src/virsh.c
src/xml.c [new file with mode: 0644]

index 14f2f110424faae28596d1400aabc828178cf7f2..c7b6a3ad777b8fb07c131591033f2865b5e26962 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Tue Dec 13 17:20:11 CET 2005 Daniel Veillard <veillard@redhat.com>
+
+       * include/libvir.h src/Makefile.am src/internal.h src/libvir.c
+         src/libvir_sym.version src/virsh.c src/xml.c: started working on
+         the XML dump, added a dumpxml virsh version and a bit of
+         infrastructure code. Found a way to detect dead ID from xenstore
+         data.
+
 Mon Dec 12 14:21:18 CET 2005 Daniel Veillard <veillard@redhat.com>
 
        * src/libvir.c src/xen_internal.c src/xen_internal.h: completing the
index c47720acdf8eee9a46da8624fdcd1ed86f184b0c..c8bbe5df56406cbfe4eeabce107644a6f20f0beb 100644 (file)
@@ -174,6 +174,8 @@ int                 virDomainResume         (virDomainPtr domain);
  */
 int                    virDomainGetInfo        (virDomainPtr domain,
                                                 virDomainInfoPtr info);
+char *                 virDomainGetXMLDesc     (virDomainPtr domain,
+                                                int flags);
                                                 
 /*
  * Dynamic control of domains
index 62e723fc47f4e08b73e864371dfac4086fe38209..5abb20f9d3d33b3974eb7e86694d789c0fa506bc 100644 (file)
@@ -14,7 +14,8 @@ libvir_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libvir_sym.version \
 libvir_la_SOURCES =                                            \
                libvir.c internal.h                             \
                hash.c hash.h                                   \
-               xen_internal.c xen_internal.h
+               xen_internal.c xen_internal.h                   \
+               xml.c
 
 noinst_PROGRAMS=virsh
 
index 4591e8b5de4caef16e95d057eb1d201008b72e56..af3963805ca8d8bd7f48146515a49b2822bfeb8b 100644 (file)
@@ -5,6 +5,9 @@
 #ifndef __VIR_INTERNAL_H__
 #define __VIR_INTERNAL_H__
 
+#include "hash.h"
+#include "libvir.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -34,6 +37,53 @@ extern "C" {
     fprintf(stderr, "Unimplemented block at %s:%d\n",                  \
             __FILE__, __LINE__);
 
+/**
+ * VIR_CONNECT_MAGIC:
+ *
+ * magic value used to protect the API when pointers to connection structures
+ * are passed down by the uers.
+ */
+#define VIR_CONNECT_MAGIC 0x4F23DEAD
+
+/**
+ * VIR_DOMAIN_MAGIC:
+ *
+ * magic value used to protect the API when pointers to domain structures
+ * are passed down by the uers.
+ */
+#define VIR_DOMAIN_MAGIC 0xDEAD4321
+
+/*
+ * Flags for Xen connections
+ */
+#define VIR_CONNECT_RO 1
+
+/**
+ * _virConnect:
+ *
+ * Internal structure associated to a connection
+ */
+struct _virConnect {
+    unsigned int magic;                /* specific value to check */
+    int                 handle;        /* internal handle used for hypercall */
+    struct xs_handle *xshandle;        /* handle to talk to the xenstore */
+    virHashTablePtr   domains; /* hash table for known domains */
+    int          flags;                /* a set of connection flags */
+};
+
+/**
+ * _virDomain:
+ *
+ * Internal structure associated to a domain
+ */
+struct _virDomain {
+    unsigned int magic;                /* specific value to check */
+    virConnectPtr conn;                /* pointer back to the connection */
+    char        *name;         /* the domain external name */
+    char        *path;         /* the domain internal path */
+    int                 handle;        /* internal handle for the dmonain ID */
+};
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 4a8c97bdad1aa7d1a4e15ace2bf2745e7d799f50..07ad35495ed09595f93a244dd09b7f69eb80ce5f 100644 (file)
  * - memory wrappers for malloc/free ?
  */
 
-#define VIR_CONNECT_MAGIC 0x4F23DEAD
-
-/*
- * Flags for Xen connections
- */
-#define VIR_CONNECT_RO 1
-
-/**
- * _virConnect:
- *
- * Internal structure associated to a connection
- */
-struct _virConnect {
-    unsigned int magic;                /* specific value to check */
-    int                 handle;        /* internal handle used for hypercall */
-    struct xs_handle *xshandle;        /* handle to talk to the xenstore */
-    virHashTablePtr   domains; /* hash table for known domains */
-    int          flags;                /* a set of connection flags */
-};
-
-#define VIR_DOMAIN_MAGIC 0xDEAD4321
-
-/**
- * _virDomain:
- *
- * Internal structure associated to a domain
- */
-struct _virDomain {
-    unsigned int magic;                /* specific value to check */
-    virConnectPtr conn;                /* pointer back to the connection */
-    char        *name;         /* the domain external name */
-    char        *path;         /* the domain internal path */
-    int                 handle;        /* internal handle for the dmonain ID */
-};
-
 /**
  * virGetVersion:
  * @libVer: return value for the library version (OUT)
@@ -396,6 +361,8 @@ virConnectNumOfDomains(virConnectPtr conn) {
  * @flags: an optional set of virDomainFlags
  *
  * Launch a new Linux guest domain 
+ * Not implemented yet. Very likely to be modified in order to express
+ * hardware informations in a convenient way.
  * 
  * Returns a new domain object or NULL in case of failure
  */
@@ -531,6 +498,11 @@ virDomainLookupByID(virConnectPtr conn, int id) {
     ret->handle = id;
     ret->path = path;
     ret->name = virDomainDoStoreQuery(ret, "name");
+    if (ret->name == NULL) {
+        free(path);
+        free(ret);
+       return(NULL);
+    }
 
     return(ret);
 }
@@ -540,7 +512,7 @@ virDomainLookupByID(virConnectPtr conn, int id) {
  * @conn: pointer to the hypervisor connection
  * @name: name for the domain
  *
- * Try to lookup a domain on the given hypervisor
+ * Try to lookup a domain on the given hypervisor based on its name.
  *
  * Returns a new domain object or NULL in case of failure
  */
@@ -807,7 +779,7 @@ virDomainSetMaxMemory(virDomainPtr domain, unsigned long memory) {
 
 /**
  * virDomainGetInfo:
- * @domain: a domain object or NULL
+ * @domain: a domain object
  * @info: pointer to a virDomainInfo structure allocated by the user
  * 
  * Extract information about a domain. Note that if the connection
@@ -904,3 +876,4 @@ virDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) {
     }
     return(0);
 }
+
index ead0d41ec3224c0b1053858556e46529c0a77f3f..e62bdee77725728796d3f12342af56c15501dafb 100644 (file)
@@ -19,6 +19,7 @@
        virDomainResume;
        virDomainSetMaxMemory;
        virDomainSuspend;
+       virDomainGetXMLDesc;
        virGetVersion;
     local: *;
 };
index 41f6b9338cd9ceefb17b26e26547efbae41b0941..6ae8eafc8813f7f6ad1892d47f14bfba6af724ef 100644 (file)
@@ -578,6 +578,56 @@ cmdDinfo(vshControl *ctl, vshCmd *cmd) {
     return ret;
 }
 
+/*
+ * "dumpxml" command
+ */
+static vshCmdInfo info_dumpxml[] = {
+    { "syntax",   "dumpxml [--id <number> | --name <string> ]" },
+    { "help",     "domain information in XML" },
+    { "desc",     "Ouput the domain informations as an XML dump to stdout" },
+    { NULL, NULL }
+};
+
+static vshCmdOptDef opts_dumpxml[] = {
+    { "name",      VSH_OT_STRING, 0, "domain name" },
+    { "id",        VSH_OT_INT,    0, "domain id" },
+    { NULL, 0, 0, NULL }
+};
+
+static int
+cmdDumpXML(vshControl *ctl, vshCmd *cmd) {
+    virDomainPtr dom;
+    int found, ret = TRUE;
+    char *name = vshCommandOptString(cmd, "name", NULL);
+    int id = vshCommandOptInt(cmd, "id", &found);
+    char *dump;
+    
+    if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+        return FALSE;
+
+    if (found) {
+        if (!(dom = virDomainLookupByID(ctl->conn, id)))
+            vshError(ctl, FALSE, "failed to get domain '%d'", id);
+    } else {
+        if (!(dom = virDomainLookupByName(ctl->conn, name)))
+            vshError(ctl, FALSE, "failed to get domain '%s'", name);
+    }
+    
+    if (!dom)
+        return FALSE;
+    
+    dump = virDomainGetXMLDesc(dom, 0);
+    if (dump != NULL) {
+        printf("%s", dump);
+        free(dump);
+    } else {
+        ret = FALSE;
+    }
+        
+    virDomainFree(dom);
+    return ret;
+}
+
 /*
  * "nameof" command
  */
@@ -750,6 +800,7 @@ cmdQuit(vshControl *ctl, vshCmd *cmd ATTRIBUTE_UNUSED) {
 static vshCmdDef commands[] = {
     { "connect",    cmdConnect,    opts_connect,   info_connect },
     { "dinfo",      cmdDinfo,      opts_dinfo,     info_dinfo },
+    { "dumpxml",    cmdDumpXML,    opts_dumpxml,   info_dumpxml },
     { "dstate",     cmdDstate,     opts_dstate,    info_dstate },
     { "suspend",    cmdSuspend,    opts_suspend,   info_suspend },
     { "resume",     cmdResume,     opts_resume,    info_resume },
diff --git a/src/xml.c b/src/xml.c
new file mode 100644 (file)
index 0000000..9887da8
--- /dev/null
+++ b/src/xml.c
@@ -0,0 +1,173 @@
+/*
+ * xml.c: XML based interfaces for the libvir library
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * See COPYING.LIB for the License of this software
+ *
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+#include "libvir.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <xs.h>
+#include "internal.h"
+#include "hash.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
+ * @len:  the minimum free size to allocate
+ *
+ * Grow the available space of an XML buffer.
+ *
+ * Returns the new available space or -1 in case of error
+ */
+static int
+virBufferGrow(virBufferPtr buf, unsigned int len) {
+    int size;
+    char *newbuf;
+
+    if (buf == NULL) return(-1);
+    if (len + buf->use < buf->size) return(0);
+
+    size = buf->use + len + 1000;
+
+    newbuf = (char *) realloc(buf->content, size);
+    if (newbuf == NULL) {
+        return(-1);
+    }
+    buf->content = newbuf;
+    buf->size = size;
+    return(buf->size - buf->use);
+}
+
+/**
+ * virBufferAdd:
+ * @buf:  the buffer to dump
+ * @str:  the string
+ * @len:  the number of bytes to add
+ *
+ * Add a string range to an XML buffer. if len == -1, the length of
+ * str is recomputed to the full string.
+ *
+ * Returns 0 successful, -1 in case of internal or API error.
+ */
+static int
+virBufferAdd(virBufferPtr buf, const char *str, int len) {
+    unsigned int needSize;
+
+    if ((str == NULL) || (buf == NULL)) {
+       return -1;
+    }
+    if (len == 0) return 0;
+
+    if (len < 0)
+        len = strlen(str);
+
+    needSize = buf->use + len + 2;
+    if (needSize > buf->size){
+        if (!virBufferGrow(buf, needSize)){
+            return(-1);
+        }
+    }
+
+    memmove(&buf->content[buf->use], str, len);
+    buf->use += len;
+    buf->content[buf->use] = 0;
+    return(0);
+}
+
+/**
+ * virBufferVSprintf:
+ * @buf:  the buffer to dump
+ * @format:  the format
+ * @argptr:  the variable list of arguments
+ *
+ * Do a formatted print to an XML buffer.
+ *
+ * Returns 0 successful, -1 in case of internal or API error.
+ */
+static int
+virBufferVSprintf(virBufferPtr buf, const char *format, ...) {
+    int size, count;
+    va_list locarg, argptr;
+
+    if ((format == NULL) || (buf == NULL)) {
+       return(-1);
+    }
+    size = buf->size - buf->use - 1;
+    va_start(argptr, format);
+    va_copy(locarg, argptr);
+    while (((count = vsnprintf(&buf->content[buf->use], size, format,
+                               locarg)) < 0) || (count >= size - 1)) {
+       buf->content[buf->use] = 0;
+       va_end(locarg);
+       if (virBufferGrow(buf, 1000) < 0) {
+           return(-1);
+       }
+       size = buf->size - buf->use - 1;
+       va_copy(locarg, argptr);
+    }
+    va_end(locarg);
+    buf->use += count;
+    buf->content[buf->use] = 0;
+    return(0);
+}
+
+/**
+ * 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;
+    virBuffer buf;
+    virDomainInfo info;
+
+    if ((domain == NULL) || (domain->magic != VIR_DOMAIN_MAGIC) ||
+        (flags != 0))
+       return(NULL);
+
+    if (virDomainGetInfo(domain, &info) < 0)
+        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",
+                      virDomainGetID(domain));
+    virBufferVSprintf(&buf, "  <name>%s</name>\n", virDomainGetName(domain));
+    virBufferAdd(&buf, "</domain>\n", 10);
+    
+    buf.content[buf.use] = 0;
+    return(ret);
+}