mirror of https://gitee.com/openkylin/libvirt.git
* 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:
parent
a8d7d679cc
commit
16ff741ff0
|
@ -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
|
||||
|
|
|
@ -174,6 +174,8 @@ int virDomainResume (virDomainPtr domain);
|
|||
*/
|
||||
int virDomainGetInfo (virDomainPtr domain,
|
||||
virDomainInfoPtr info);
|
||||
char * virDomainGetXMLDesc (virDomainPtr domain,
|
||||
int flags);
|
||||
|
||||
/*
|
||||
* Dynamic control of domains
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
47
src/libvir.c
47
src/libvir.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
virDomainResume;
|
||||
virDomainSetMaxMemory;
|
||||
virDomainSuspend;
|
||||
virDomainGetXMLDesc;
|
||||
virGetVersion;
|
||||
local: *;
|
||||
};
|
||||
|
|
51
src/virsh.c
51
src/virsh.c
|
@ -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 },
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue