+Tue Jan 17 17:53:43 CET 2006 Daniel Veillard <veillard@redhat.com>
+
+ * include/libvir.h[.in]: added VIR_DOMAIN_CRASHED status, small
+ doc fix
+ * src/virsh.c: fix a integer being formatted as %s in idof
+ * src/internal.h src/libvir.c src/xend_internal.[ch]: started to
+ integrated the xend back-end, especially for getting informations
+ about a domain.
+
Fri Jan 13 17:39:24 CET 2006 Daniel Veillard <veillard@redhat.com>
* include/libvir.h.in include/libvir.h src/internal.h src/libvir.c
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+ <head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<link rel="SHORTCUT ICON" href="/favicon.ico" />
<style type="text/css">
TD {font-family: Verdana,Arial,Helvetica}
VIR_DOMAIN_BLOCKED = 2, /* the domain is blocked on resource */
VIR_DOMAIN_PAUSED = 3, /* the domain is paused by user */
VIR_DOMAIN_SHUTDOWN= 4, /* the domain is being shut down */
- VIR_DOMAIN_SHUTOFF = 5 /* the domain is shut off */
+ VIR_DOMAIN_SHUTOFF = 5, /* the domain is shut off */
+ VIR_DOMAIN_CRASHED = 6 /* the domain is crashed */
} virDomainState;
/**
typedef struct _virDomainInfo virDomainInfo;
struct _virDomainInfo {
- unsigned char state; /* the running state, one of virDomainFlags */
+ unsigned char state; /* the running state, one of virDomainState */
unsigned long maxMem; /* the maximum memory in KBytes allowed */
unsigned long memory; /* the memory in KBytes used by the domain */
unsigned short nrVirtCpu; /* the number of virtual CPUs for the domain */
*/
};
+/**
+ * virDomainInfoPtr:
+ *
+ * a virDomainInfoPtr is a pointer to a virDomainInfo structure.
+ */
+
+typedef virDomainInfo *virDomainInfoPtr;
+
/**
* virDomainKernel:
*
char *path; /* the domain internal path */
int handle; /* internal handle for the dmonain ID */
int flags; /* extra flags */
+ unsigned char uuid[16]; /* the domain unique identifier */
};
/*
#include <string.h>
#include <xs.h>
#include "internal.h"
+#include "xend_internal.h"
#include "hash.h"
*/
virDomainPtr
virDomainLookupByName(virConnectPtr conn, const char *name) {
- struct xs_transaction_handle* t;
+ struct xs_transaction_handle* t = NULL;
virDomainPtr ret = NULL;
unsigned int num, i, len;
long id = -1;
char **idlist = NULL, *endptr;
- char prop[200], *tmp;
+ char prop[200], *tmp, *path = NULL;
+ unsigned char *uuid = NULL;
int found = 0;
+ struct xend_domain *xenddomain = NULL;
if (!VIR_IS_CONNECT(conn))
return(NULL);
if (name == NULL)
return(NULL);
+ /* try first though Xend */
+ xenddomain = xend_get_domain(conn, name);
+ if (xenddomain != NULL) {
+ fprintf(stderr, "Xend: success looking up %s\n", name);
+ id = xenddomain->live->id;
+ uuid = xenddomain->uuid;
+ found = 1;
+ goto do_found;
+ }
+
+ /* then though the XenStore */
+
t = xs_transaction_start(conn->xshandle);
if (t == NULL)
goto done;
break;
}
}
+ path = xs_get_domain_path(conn->xshandle, (unsigned int) id);
+
+do_found:
+
if (found) {
ret = (virDomainPtr) malloc(sizeof(virDomain));
if (ret == NULL)
ret->magic = VIR_DOMAIN_MAGIC;
ret->conn = conn;
ret->handle = id;
- ret->path = xs_get_domain_path(conn->xshandle, (unsigned int) id);
+ ret->path = path;
+ if (uuid != NULL)
+ memcpy(ret->uuid, uuid, 16);
ret->name = strdup(name);
}
done:
+ if (xenddomain != NULL)
+ free(xenddomain);
if (t != NULL)
xs_transaction_end(conn->xshandle, t, 0);
if (idlist != NULL)
int
virDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) {
int ret;
+ char *tmp, **tmp2;
+ unsigned int nb_vcpus;
+ char request[200];
+
if (!VIR_IS_CONNECTED_DOMAIN(domain))
return(-1);
memset(info, 0, sizeof(virDomainInfo));
- if (domain->conn->flags & VIR_CONNECT_RO) {
- char *tmp, **tmp2;
- unsigned int nb_vcpus;
- char request[200];
-
- tmp = virDomainDoStoreQuery(domain, "running");
- if (tmp != NULL) {
- if (tmp[0] == '1')
- info->state = VIR_DOMAIN_RUNNING;
- free(tmp);
- } else {
- info->state = VIR_DOMAIN_NONE;
- }
- tmp = virDomainDoStoreQuery(domain, "memory/target");
- if (tmp != NULL) {
- info->memory = atol(tmp);
- info->maxMem = atol(tmp);
- free(tmp);
- } else {
- info->memory = 0;
- info->maxMem = 0;
- }
-#if 0
- /* doesn't seems to work */
- tmp = virDomainDoStoreQuery(domain, "cpu_time");
- if (tmp != NULL) {
- info->cpuTime = atol(tmp);
- free(tmp);
- } else {
- info->cpuTime = 0;
- }
-#endif
- snprintf(request, 199, "/local/domain/%d/cpu", domain->handle);
- request[199] = 0;
- tmp2 = virConnectDoStoreList(domain->conn, request, &nb_vcpus);
- if (tmp2 != NULL) {
- info->nrVirtCpu = nb_vcpus;
- free(tmp2);
- }
-
- } else {
+ /*
+ * if we have direct access though the hypervisor do a direct call
+ */
+ if (domain->conn->handle >= 0) {
dom0_getdomaininfo_t dominfo;
dominfo.domain = domain->handle;
ret = xenHypervisorGetDomainInfo(domain->conn->handle, domain->handle,
&dominfo);
if (ret < 0)
- return(-1);
+ goto xend_info;
+
switch (dominfo.flags & 0xFF) {
case DOMFLAGS_DYING:
info->state = VIR_DOMAIN_SHUTDOWN;
info->memory = dominfo.tot_pages * 4;
info->maxMem = dominfo.max_pages * 4;
info->nrVirtCpu = dominfo.nr_online_vcpus;
+ return(0);
+ }
+
+xend_info:
+ /*
+ * try to extract the informations though access to the Xen Daemon
+ */
+ if (xend_get_domain_info(domain, info) == 0)
+ return(0);
+
+ /*
+ * last fallback, try to get the inforamtions from the Xen store
+ */
+
+ tmp = virDomainDoStoreQuery(domain, "running");
+ if (tmp != NULL) {
+ if (tmp[0] == '1')
+ info->state = VIR_DOMAIN_RUNNING;
+ free(tmp);
+ } else {
+ info->state = VIR_DOMAIN_NONE;
+ }
+ tmp = virDomainDoStoreQuery(domain, "memory/target");
+ if (tmp != NULL) {
+ info->memory = atol(tmp);
+ info->maxMem = atol(tmp);
+ free(tmp);
+ } else {
+ info->memory = 0;
+ info->maxMem = 0;
+ }
+#if 0
+ /* doesn't seems to work */
+ tmp = virDomainDoStoreQuery(domain, "cpu_time");
+ if (tmp != NULL) {
+ info->cpuTime = atol(tmp);
+ free(tmp);
+ } else {
+ info->cpuTime = 0;
+ }
+#endif
+ snprintf(request, 199, "/local/domain/%d/cpu", domain->handle);
+ request[199] = 0;
+ tmp2 = virConnectDoStoreList(domain->conn, request, &nb_vcpus);
+ if (tmp2 != NULL) {
+ info->nrVirtCpu = nb_vcpus;
+ free(tmp2);
}
return(0);
}
dom = virDomainLookupByName(ctl->conn, name);
if (dom) {
- vshPrint(ctl, VSH_MESG, "%s\n", virDomainGetID(dom));
+ vshPrint(ctl, VSH_MESG, "%d\n", virDomainGetID(dom));
virDomainFree(dom);
} else {
vshError(ctl, FALSE, "failed to get domain '%s'", name);
int
xend_setup(virConnectPtr conn)
{
- return(xend_setup_unix(conn, "/var/lib/xend/xend-socket"));
+ return(xend_setup_tcp(conn, "localhost", 8000));
+/* return(xend_setup_unix(conn, "/var/lib/xend/xend-socket")); */
}
/**
return size;
}
+/**
+ * sexpr_to_xend_domain_info:
+ * @root: an S-Expression describing a domain
+ * @info: a info data structure to fill=up
+ *
+ * Internal routine filling up the info structure with the values from
+ * the domain root provided.
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+static int
+sexpr_to_xend_domain_info(struct sexpr *root, virDomainInfoPtr info)
+{
+ const char *flags;
+
+
+ if ((root == NULL) || (info == NULL))
+ return(-1);
+
+ info->memory = sexpr_u64(root, "domain/memory") << 10;
+ info->maxMem = sexpr_u64(root, "domain/maxmem") << 10;
+ flags = sexpr_node(root, "domain/state");
+
+ if (flags) {
+ if (strchr(flags, 'c'))
+ info->state = VIR_DOMAIN_CRASHED;
+ else if (strchr(flags, 's'))
+ info->state = VIR_DOMAIN_SHUTDOWN;
+ else if (strchr(flags, 'd'))
+ info->state = VIR_DOMAIN_SHUTOFF;
+ else if (strchr(flags, 'p'))
+ info->state = VIR_DOMAIN_PAUSED;
+ else if (strchr(flags, 'b'))
+ info->state = VIR_DOMAIN_BLOCKED;
+ else if (strchr(flags, 'r'))
+ info->state = VIR_DOMAIN_RUNNING;
+ } else {
+ info->state = VIR_DOMAIN_NOSTATE;
+ }
+ info->cpuTime = sexpr_float(root, "domain/cpu_time") * 1000000000;
+ info->nrVirtCpu = sexpr_int(root, "domain/vcpus");
+ return(0);
+}
+
/**
* sexpr_to_xend_domain:
* @root: an S-Expression describing a domain
}
}
+ dom->live->id = sexpr_int(root, "domain/domid");
dom->live->cpu_time = sexpr_float(root, "domain/cpu_time");
dom->live->up_time = sexpr_float(root, "domain/up_time");
dom->live->start_time = sexpr_float(root, "domain/start_time");
return dom;
}
+/**
+ * xend_get_domain_info:
+ * @xend: A xend instance
+ * @name: The name of the domain
+ *
+ * This method looks up information about a domain and update the
+ * information block provided.
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+xend_get_domain_info(virDomainPtr domain, virDomainInfoPtr info)
+{
+ struct sexpr *root;
+ int ret;
+
+ if ((domain == NULL) || (info == NULL))
+ return(-1);
+
+ root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
+ if (root == NULL)
+ return(-1);
+
+ ret = sexpr_to_xend_domain_info(root, info);
+ sexpr_free(root);
+ return(ret);
+}
+
/**
* xend_get_domain:
* @xend: A xend instance
*/
#define XEND_DEFAULT 0
-/**
- Xend context.
-
- Private.
-*/
-struct xend;
-
/**
This structure represents a virtual block device.
*/
the total number of available VCPUs
*/
int vcpu_avail;
+
+ /**
+ the domain id number
+ */
+ int id;
};
/**
struct xend_domain *xend_get_domain(virConnectPtr xend,
const char *name);
+/**
+ * \brief Get status informations for a domain
+ * \param domain A xend domain
+ * \param info An information block provided by the user
+ * \return 0 in case of success, -1 in case of error
+ *
+ * This method looks up information about a domain and update the
+ * information block provided.
+ */
+int xend_get_domain_info(virDomainPtr domain,
+ virDomainInfoPtr info);
+
/**
* \brief Lookup information about the host machine
* \param xend A xend instance