* 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.
Daniel
This commit is contained in:
Daniel Veillard 2005-12-13 16:22:05 +00:00
parent a8d7d679cc
commit 16ff741ff0
8 changed files with 297 additions and 38 deletions

View File

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

View 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

View 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

View 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 */

View File

@ -28,41 +28,6 @@
* - 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);
}

View File

@ -19,6 +19,7 @@
virDomainResume;
virDomainSetMaxMemory;
virDomainSuspend;
virDomainGetXMLDesc;
virGetVersion;
local: *;
};

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

173
src/xml.c Normal file
View File

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