1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2024-12-22 17:34:18 +03:00

* 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.
Daniel
This commit is contained in:
Daniel Veillard 2006-02-20 17:22:16 +00:00
parent 82402982c8
commit 144141872b
10 changed files with 238 additions and 24 deletions

View File

@ -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

5
TODO
View File

@ -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

View 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
}

View 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
}

View 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
}

View 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
}

View 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) {

View 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);
}

View File

@ -20,21 +20,9 @@
#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);
}

View File

@ -11,6 +11,25 @@
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);