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:
parent
82402982c8
commit
144141872b
@ -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
5
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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -427,8 +427,6 @@ virDomainCreateLinux(virConnectPtr conn,
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
printf("%s\n", sexpr);
|
||||
|
||||
ret = xend_create_sexpr(conn, sexpr);
|
||||
free(sexpr);
|
||||
if (ret != 0) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
35
src/xml.c
35
src/xml.c
@ -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);
|
||||
}
|
||||
|
||||
|
19
src/xml.h
19
src/xml.h
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user