Index: xen_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xen_internal.c,v
retrieving revision 1.70
diff -u -p -r1.70 xen_internal.c
--- xen_internal.c 4 Apr 2007 14:19:49 -0000 1.70
+++ xen_internal.c 12 Apr 2007 00:52:26 -0000
@@ -93,6 +93,7 @@ static regex_t xen_cap_rec;
*/
#ifndef DOMFLAGS_DYING
#define DOMFLAGS_DYING (1<<0) /* Domain is scheduled to die. */
+#define DOMFLAGS_HVM (1<<1) /* Domain is HVM */
#define DOMFLAGS_SHUTDOWN (1<<2) /* The guest OS has shut down. */
#define DOMFLAGS_PAUSED (1<<3) /* Currently paused by control software. */
#define DOMFLAGS_BLOCKED (1<<4) /* Currently blocked pending an event. */
@@ -146,87 +147,136 @@ struct xen_v2_getdomaininfo {
};
typedef struct xen_v2_getdomaininfo xen_v2_getdomaininfo;
+
+/* As of Hypervisor Call v2, DomCtl v5 we are now 8-byte aligned
+ even on 32-bit archs when dealing with uint64_t */
+#define ALIGN_64 __attribute__((aligned(8)))
+
+struct xen_v2d5_getdomaininfo {
+ domid_t domain; /* the domain number */
+ uint32_t flags; /* falgs, see before */
+ uint64_t tot_pages ALIGN_64; /* total number of pages used */
+ uint64_t max_pages ALIGN_64; /* maximum number of pages allowed */
+ uint64_t shared_info_frame ALIGN_64; /* MFN of shared_info struct */
+ uint64_t cpu_time ALIGN_64; /* CPU time used */
+ uint32_t nr_online_vcpus; /* Number of VCPUs currently online. */
+ uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */
+ uint32_t ssidref;
+ xen_domain_handle_t handle;
+};
+typedef struct xen_v2d5_getdomaininfo xen_v2d5_getdomaininfo;
+
union xen_getdomaininfo {
struct xen_v0_getdomaininfo v0;
struct xen_v2_getdomaininfo v2;
+ struct xen_v2d5_getdomaininfo v2d5;
};
typedef union xen_getdomaininfo xen_getdomaininfo;
union xen_getdomaininfolist {
struct xen_v0_getdomaininfo *v0;
struct xen_v2_getdomaininfo *v2;
+ struct xen_v2d5_getdomaininfo *v2d5;
};
typedef union xen_getdomaininfolist xen_getdomaininfolist;
#define XEN_GETDOMAININFOLIST_ALLOC(domlist, size) \
(hypervisor_version < 2 ? \
((domlist.v0 = malloc(sizeof(xen_v0_getdomaininfo)*(size))) != NULL) : \
- ((domlist.v2 = malloc(sizeof(xen_v2_getdomaininfo)*(size))) != NULL))
-
-#define XEN_GETDOMAININFOLIST_FREE(domlist) \
- (hypervisor_version < 2 ? \
- free(domlist.v0) : \
- free(domlist.v2))
-
-#define XEN_GETDOMAININFOLIST_CLEAR(domlist, size) \
- (hypervisor_version < 2 ? \
- memset(domlist.v0, 0, sizeof(xen_v0_getdomaininfo) * size) : \
- memset(domlist.v2, 0, sizeof(xen_v2_getdomaininfo) * size))
+ (dom_interface_version < 5 ? \
+ ((domlist.v2 = malloc(sizeof(xen_v2_getdomaininfo)*(size))) != NULL) : \
+ ((domlist.v2d5 = malloc(sizeof(xen_v2d5_getdomaininfo)*(size))) != NULL)))
+
+#define XEN_GETDOMAININFOLIST_FREE(domlist) \
+ (hypervisor_version < 2 ? \
+ free(domlist.v0) : \
+ (dom_interface_version < 5 ? \
+ free(domlist.v2) : \
+ free(domlist.v2d5)))
+
+#define XEN_GETDOMAININFOLIST_CLEAR(domlist, size) \
+ (hypervisor_version < 2 ? \
+ memset(domlist.v0, 0, sizeof(xen_v0_getdomaininfo) * size) : \
+ (dom_interface_version < 5 ? \
+ memset(domlist.v2, 0, sizeof(xen_v2_getdomaininfo) * size) : \
+ memset(domlist.v2d5, 0, sizeof(xen_v2d5_getdomaininfo) * size)))
#define XEN_GETDOMAININFOLIST_DOMAIN(domlist, n) \
(hypervisor_version < 2 ? \
domlist.v0[n].domain : \
- domlist.v2[n].domain)
-
-#define XEN_GETDOMAININFOLIST_DATA(domlist) \
- (hypervisor_version < 2 ? \
- (void*)(domlist->v0) : \
- (void*)(domlist->v2))
-
-#define XEN_GETDOMAININFO_SIZE \
- (hypervisor_version < 2 ? \
- sizeof(xen_v0_getdomaininfo) : \
- sizeof(xen_v2_getdomaininfo))
-
-#define XEN_GETDOMAININFO_CLEAR(dominfo) \
- (hypervisor_version < 2 ? \
- memset(&(dominfo.v0), 0, sizeof(xen_v0_getdomaininfo)) : \
- memset(&(dominfo.v2), 0, sizeof(xen_v2_getdomaininfo)))
+ (dom_interface_version < 5 ? \
+ domlist.v2[n].domain : \
+ domlist.v2d5[n].domain))
+
+#define XEN_GETDOMAININFOLIST_DATA(domlist) \
+ (hypervisor_version < 2 ? \
+ (void*)(domlist->v0) : \
+ (dom_interface_version < 5 ? \
+ (void*)(domlist->v2) : \
+ (void*)(domlist->v2d5)))
+
+#define XEN_GETDOMAININFO_SIZE \
+ (hypervisor_version < 2 ? \
+ sizeof(xen_v0_getdomaininfo) : \
+ (dom_interface_version < 5 ? \
+ sizeof(xen_v2_getdomaininfo) : \
+ sizeof(xen_v2d5_getdomaininfo)))
+
+#define XEN_GETDOMAININFO_CLEAR(dominfo) \
+ (hypervisor_version < 2 ? \
+ memset(&(dominfo.v0), 0, sizeof(xen_v0_getdomaininfo)) : \
+ (dom_interface_version < 5 ? \
+ memset(&(dominfo.v2), 0, sizeof(xen_v2_getdomaininfo)) : \
+ memset(&(dominfo.v2d5), 0, sizeof(xen_v2d5_getdomaininfo))))
#define XEN_GETDOMAININFO_DOMAIN(dominfo) \
(hypervisor_version < 2 ? \
dominfo.v0.domain : \
- dominfo.v2.domain)
+ (dom_interface_version < 5 ? \
+ dominfo.v2.domain : \
+ dominfo.v2d5.domain))
#define XEN_GETDOMAININFO_CPUTIME(dominfo) \
(hypervisor_version < 2 ? \
dominfo.v0.cpu_time : \
- dominfo.v2.cpu_time)
+ (dom_interface_version < 5 ? \
+ dominfo.v2.cpu_time : \
+ dominfo.v2d5.cpu_time))
#define XEN_GETDOMAININFO_CPUCOUNT(dominfo) \
(hypervisor_version < 2 ? \
dominfo.v0.nr_online_vcpus : \
- dominfo.v2.nr_online_vcpus)
+ (dom_interface_version < 5 ? \
+ dominfo.v2.nr_online_vcpus : \
+ dominfo.v2d5.nr_online_vcpus))
#define XEN_GETDOMAININFO_MAXCPUID(dominfo) \
(hypervisor_version < 2 ? \
dominfo.v0.max_vcpu_id : \
- dominfo.v2.max_vcpu_id)
+ (dom_interface_version < 5 ? \
+ dominfo.v2.max_vcpu_id : \
+ dominfo.v2d5.max_vcpu_id))
#define XEN_GETDOMAININFO_FLAGS(dominfo) \
(hypervisor_version < 2 ? \
dominfo.v0.flags : \
- dominfo.v2.flags)
+ (dom_interface_version < 5 ? \
+ dominfo.v2.flags : \
+ dominfo.v2d5.flags))
#define XEN_GETDOMAININFO_TOT_PAGES(dominfo) \
(hypervisor_version < 2 ? \
dominfo.v0.tot_pages : \
- dominfo.v2.tot_pages)
+ (dom_interface_version < 5 ? \
+ dominfo.v2.tot_pages : \
+ dominfo.v2d5.tot_pages))
#define XEN_GETDOMAININFO_MAX_PAGES(dominfo) \
(hypervisor_version < 2 ? \
dominfo.v0.max_pages : \
- dominfo.v2.max_pages)
+ (dom_interface_version < 5 ? \
+ dominfo.v2.max_pages : \
+ dominfo.v2d5.max_pages))
@@ -247,6 +297,18 @@ struct xen_v2_getdomaininfolistop {
};
typedef struct xen_v2_getdomaininfolistop xen_v2_getdomaininfolistop;
+/* As of HV version 2, sysctl version 3 the *buffer pointer is 64-bit aligned */
+struct xen_v2s3_getdomaininfolistop {
+ domid_t first_domain;
+ uint32_t max_domains;
+ union {
+ struct xen_v2d5_getdomaininfo *v;
+ uint64_t pad ALIGN_64;
+ } buffer;
+ uint32_t num_domains;
+};
+typedef struct xen_v2s3_getdomaininfolistop xen_v2s3_getdomaininfolistop;
+
struct xen_v0_domainop {
@@ -294,6 +356,11 @@ struct xen_v2_setmaxmem {
};
typedef struct xen_v2_setmaxmem xen_v2_setmaxmem;
+struct xen_v2d5_setmaxmem {
+ uint64_t maxmem ALIGN_64;
+};
+typedef struct xen_v2d5_setmaxmem xen_v2d5_setmaxmem;
+
/*
* The informations for an setmaxvcpu system hypercall
*/
@@ -340,6 +407,20 @@ struct xen_v2_setvcpumap {
};
typedef struct xen_v2_setvcpumap xen_v2_setvcpumap;
+/* HV version 2, Dom version 5 requires 64-bit alignment */
+struct xen_v2d5_cpumap {
+ union {
+ uint8_t *v;
+ uint64_t pad ALIGN_64;
+ } bitmap;
+ uint32_t nr_cpus;
+};
+struct xen_v2d5_setvcpumap {
+ uint32_t vcpu;
+ struct xen_v2d5_cpumap cpumap;
+};
+typedef struct xen_v2d5_setvcpumap xen_v2d5_setvcpumap;
+
/*
* The informations for an vcpuinfo system hypercall
*/
@@ -370,11 +451,22 @@ struct xen_v2_vcpuinfo {
};
typedef struct xen_v2_vcpuinfo xen_v2_vcpuinfo;
+struct xen_v2d5_vcpuinfo {
+ uint32_t vcpu; /* the vcpu number */
+ uint8_t online; /* seen as on line */
+ uint8_t blocked; /* blocked on event */
+ uint8_t running; /* scheduled on CPU */
+ uint64_t cpu_time ALIGN_64; /* nanosecond of CPU used */
+ uint32_t cpu; /* current mapping */
+};
+typedef struct xen_v2d5_vcpuinfo xen_v2d5_vcpuinfo;
+
/*
* from V2 the pinning of a vcpu is read with a separate call
*/
#define XEN_V2_OP_GETVCPUMAP 25
typedef struct xen_v2_setvcpumap xen_v2_getvcpumap;
+typedef struct xen_v2d5_setvcpumap xen_v2d5_getvcpumap;
/*
* The hypercall operation structures also have changed on
@@ -402,7 +494,8 @@ struct xen_op_v2_sys {
uint32_t cmd;
uint32_t interface_version;
union {
- xen_v2_getdomaininfolistop getdomaininfolist;
+ xen_v2_getdomaininfolistop getdomaininfolist;
+ xen_v2s3_getdomaininfolistop getdomaininfolists3;
uint8_t padding[128];
} u;
};
@@ -415,10 +508,14 @@ struct xen_op_v2_dom {
domid_t domain;
union {
xen_v2_setmaxmem setmaxmem;
+ xen_v2d5_setmaxmem setmaxmemd5;
xen_v2_setmaxvcpu setmaxvcpu;
xen_v2_setvcpumap setvcpumap;
+ xen_v2d5_setvcpumap setvcpumapd5;
xen_v2_vcpuinfo getvcpuinfo;
+ xen_v2d5_vcpuinfo getvcpuinfod5;
xen_v2_getvcpumap getvcpumap;
+ xen_v2d5_getvcpumap getvcpumapd5;
uint8_t padding[128];
} u;
};
@@ -726,13 +823,26 @@ virXen_getdomaininfolist(int handle, int
memset(&op, 0, sizeof(op));
op.cmd = XEN_V2_OP_GETDOMAININFOLIST;
- op.u.getdomaininfolist.first_domain = (domid_t) first_domain;
- op.u.getdomaininfolist.max_domains = maxids;
- op.u.getdomaininfolist.buffer = dominfos->v2;
- op.u.getdomaininfolist.num_domains = maxids;
+
+ if (sys_interface_version < 3) {
+ op.u.getdomaininfolist.first_domain = (domid_t) first_domain;
+ op.u.getdomaininfolist.max_domains = maxids;
+ op.u.getdomaininfolist.buffer = dominfos->v2;
+ op.u.getdomaininfolist.num_domains = maxids;
+ } else {
+ op.u.getdomaininfolists3.first_domain = (domid_t) first_domain;
+ op.u.getdomaininfolists3.max_domains = maxids;
+ op.u.getdomaininfolists3.buffer.v = dominfos->v2d5;
+ op.u.getdomaininfolists3.num_domains = maxids;
+ }
ret = xenHypervisorDoV2Sys(handle, &op);
- if (ret == 0)
- ret = op.u.getdomaininfolist.num_domains;
+
+ if (ret == 0) {
+ if (sys_interface_version < 3)
+ ret = op.u.getdomaininfolist.num_domains;
+ else
+ ret = op.u.getdomaininfolists3.num_domains;
+ }
} else if (hypervisor_version == 1) {
xen_op_v1 op;
@@ -921,7 +1031,10 @@ virXen_setmaxmem(int handle, int id, uns
memset(&op, 0, sizeof(op));
op.cmd = XEN_V2_OP_SETMAXMEM;
op.domain = (domid_t) id;
- op.u.setmaxmem.maxmem = memory;
+ if (dom_interface_version < 5)
+ op.u.setmaxmem.maxmem = memory;
+ else
+ op.u.setmaxmemd5.maxmem = memory;
ret = xenHypervisorDoV2Dom(handle, &op);
} else if (hypervisor_version == 1) {
xen_op_v1 op;
@@ -1014,10 +1127,17 @@ virXen_setvcpumap(int handle, int id, un
memset(&op, 0, sizeof(op));
op.cmd = XEN_V2_OP_SETVCPUMAP;
op.domain = (domid_t) id;
- op.u.setvcpumap.vcpu = vcpu;
- op.u.setvcpumap.cpumap.bitmap = cpumap;
- op.u.setvcpumap.cpumap.nr_cpus = maplen * 8;
+ if (dom_interface_version < 5) {
+ op.u.setvcpumap.vcpu = vcpu;
+ op.u.setvcpumap.cpumap.bitmap = cpumap;
+ op.u.setvcpumap.cpumap.nr_cpus = maplen * 8;
+ } else {
+ op.u.setvcpumapd5.vcpu = vcpu;
+ op.u.setvcpumapd5.cpumap.bitmap.v = cpumap;
+ op.u.setvcpumapd5.cpumap.nr_cpus = maplen * 8;
+ }
ret = xenHypervisorDoV2Dom(handle, &op);
+
if (munlock(cpumap, maplen) < 0) {
virXenError(VIR_ERR_XEN_CALL, " release", maplen);
ret = -1;
@@ -1082,29 +1202,56 @@ virXen_getvcpusinfo(int handle, int id,
memset(&op, 0, sizeof(op));
op.cmd = XEN_V2_OP_GETVCPUINFO;
op.domain = (domid_t) id;
- op.u.getvcpuinfo.vcpu = (uint16_t) vcpu;
+ if (dom_interface_version < 5)
+ op.u.getvcpuinfo.vcpu = (uint16_t) vcpu;
+ else
+ op.u.getvcpuinfod5.vcpu = (uint16_t) vcpu;
ret = xenHypervisorDoV2Dom(handle, &op);
+
if (ret < 0)
return(-1);
ipt->number = vcpu;
- if (op.u.getvcpuinfo.online) {
- if (op.u.getvcpuinfo.running) ipt->state = VIR_VCPU_RUNNING;
- if (op.u.getvcpuinfo.blocked) ipt->state = VIR_VCPU_BLOCKED;
- }
- else ipt->state = VIR_VCPU_OFFLINE;
- ipt->cpuTime = op.u.getvcpuinfo.cpu_time;
- ipt->cpu = op.u.getvcpuinfo.online ? (int)op.u.getvcpuinfo.cpu : -1;
+ if (dom_interface_version < 5) {
+ if (op.u.getvcpuinfo.online) {
+ if (op.u.getvcpuinfo.running)
+ ipt->state = VIR_VCPU_RUNNING;
+ if (op.u.getvcpuinfo.blocked)
+ ipt->state = VIR_VCPU_BLOCKED;
+ } else
+ ipt->state = VIR_VCPU_OFFLINE;
+
+ ipt->cpuTime = op.u.getvcpuinfo.cpu_time;
+ ipt->cpu = op.u.getvcpuinfo.online ? (int)op.u.getvcpuinfo.cpu : -1;
+ } else {
+ if (op.u.getvcpuinfod5.online) {
+ if (op.u.getvcpuinfod5.running)
+ ipt->state = VIR_VCPU_RUNNING;
+ if (op.u.getvcpuinfod5.blocked)
+ ipt->state = VIR_VCPU_BLOCKED;
+ } else
+ ipt->state = VIR_VCPU_OFFLINE;
+
+ ipt->cpuTime = op.u.getvcpuinfod5.cpu_time;
+ ipt->cpu = op.u.getvcpuinfod5.online ? (int)op.u.getvcpuinfod5.cpu : -1;
+ }
if ((cpumap != NULL) && (maplen > 0)) {
if (mlock(cpumap, maplen) < 0) {
virXenError(VIR_ERR_XEN_CALL, " locking", maplen);
return (-1);
}
+ memset(cpumap, 0, maplen);
memset(&op, 0, sizeof(op));
op.cmd = XEN_V2_OP_GETVCPUMAP;
op.domain = (domid_t) id;
- op.u.setvcpumap.vcpu = vcpu;
- op.u.setvcpumap.cpumap.bitmap = cpumap;
- op.u.setvcpumap.cpumap.nr_cpus = maplen * 8;
+ if (dom_interface_version < 5) {
+ op.u.getvcpumap.vcpu = vcpu;
+ op.u.getvcpumap.cpumap.bitmap = cpumap;
+ op.u.getvcpumap.cpumap.nr_cpus = maplen * 8;
+ } else {
+ op.u.getvcpumapd5.vcpu = vcpu;
+ op.u.getvcpumapd5.cpumap.bitmap.v = cpumap;
+ op.u.getvcpumapd5.cpumap.nr_cpus = maplen * 8;
+ }
ret = xenHypervisorDoV2Dom(handle, &op);
if (munlock(cpumap, maplen) < 0) {
virXenError(VIR_ERR_XEN_CALL, " release", maplen);
@@ -1802,10 +1949,18 @@ xenHypervisorNumOfDomains(virConnectPtr
return (-1);
nbids = ret;
+ /* Can't possibly have more than 10,000 concurrent guests
+ * so limit how many times we try, to avoid increasing
+ * without bound & thus allocating all of system memory !
+ * XXX I'll regret this comment in a few years time ;-)
+ */
if (nbids == maxids) {
- last_maxids *= 2;
- maxids *= 2;
- goto retry;
+ if (maxids < 10000) {
+ last_maxids *= 2;
+ maxids *= 2;
+ goto retry;
+ }
+ nbids = -1;
}
if ((nbids < 0) || (nbids > maxids))
return(-1);
@@ -1994,7 +2149,8 @@ xenHypervisorGetDomInfo(virConnectPtr co
return (-1);
domain_flags = XEN_GETDOMAININFO_FLAGS(dominfo);
- domain_state = domain_flags & 0xFF;
+ domain_flags &= ~DOMFLAGS_HVM; /* Mask out HVM flags */
+ domain_state = domain_flags & 0xFF; /* Mask out high bits */
switch (domain_state) {
case DOMFLAGS_DYING:
info->state = VIR_DOMAIN_SHUTDOWN;
Index: xen_unified.c
===================================================================
RCS file: /data/cvs/libvirt/src/xen_unified.c,v
retrieving revision 1.3
diff -u -p -r1.3 xen_unified.c
--- xen_unified.c 10 Apr 2007 13:00:26 -0000 1.3
+++ xen_unified.c 12 Apr 2007 00:52:26 -0000
@@ -546,13 +546,14 @@ xenUnifiedDomainGetVcpus (virDomainPtr d
virVcpuInfoPtr info, int maxinfo,
unsigned char *cpumaps, int maplen)
{
- int i;
+ int i, ret;
for (i = 0; i < nb_drivers; ++i)
- if (drivers[i]->domainGetVcpus &&
- drivers[i]->domainGetVcpus (dom, info, maxinfo, cpumaps, maplen) == 0)
- return 0;
-
+ if (drivers[i]->domainGetVcpus) {
+ ret = drivers[i]->domainGetVcpus (dom, info, maxinfo, cpumaps, maplen);
+ if (ret > 0)
+ return ret;
+ }
return -1;
}
Index: xend_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xend_internal.c,v
retrieving revision 1.107
diff -u -p -r1.107 xend_internal.c
--- xend_internal.c 11 Apr 2007 16:06:30 -0000 1.107
+++ xend_internal.c 12 Apr 2007 00:52:28 -0000
@@ -1151,7 +1151,7 @@ xend_detect_config_version(virConnectPtr
priv->xendConfigVersion = 1;
}
sexpr_free(root);
- return priv->xendConfigVersion;
+ return (0);
}
/**
@@ -1251,13 +1251,14 @@ xend_log(virConnectPtr xend, char *buffe
* @node: the root of the parsed S-Expression
* @buf: output buffer object
* @hvm: true or 1 if no contains HVM S-Expression
+ * @bootloader: true or 1 if a bootloader is defined
*
* Parse the xend sexp for description of os and append it to buf.
*
* Returns 0 in case of success and -1 in case of error
*/
static int
-xend_parse_sexp_desc_os(virConnectPtr xend, struct sexpr *node, virBufferPtr buf, int hvm)
+xend_parse_sexp_desc_os(virConnectPtr xend, struct sexpr *node, virBufferPtr buf, int hvm, int bootloader)
{
const char *tmp;
@@ -1269,37 +1270,44 @@ xend_parse_sexp_desc_os(virConnectPtr xe
if (hvm) {
virBufferVSprintf(buf, " hvm\n");
tmp = sexpr_node(node, "domain/image/hvm/kernel");
- if (tmp == NULL) {
+ if (tmp == NULL && !bootloader) {
virXendError(xend, VIR_ERR_INTERNAL_ERROR,
- _("domain information incomplete, missing kernel"));
+ _("domain information incomplete, missing kernel & bootloader"));
return(-1);
- }
- virBufferVSprintf(buf, " %s\n", tmp);
+ }
+ if (tmp)
+ virBufferVSprintf(buf, " %s\n", tmp);
tmp = sexpr_node(node, "domain/image/hvm/boot");
if ((tmp != NULL) && (tmp[0] != 0)) {
- if (tmp[0] == 'a')
- /* XXX no way to deal with boot from 2nd floppy */
- virBufferAdd(buf, " \n", 21 );
- else if (tmp[0] == 'c')
- /*
- * Don't know what to put here. Say the vm has been given 3
- * disks - hda, hdb, hdc. How does one identify the boot disk?
- * We're going to assume that first disk is the boot disk since
- * this is most common practice
- */
- virBufferAdd(buf, " \n", 21 );
- else if (strcmp(tmp, "d") == 0)
- virBufferAdd(buf, " \n", 24 );
+ while (*tmp) {
+ if (*tmp == 'a')
+ /* XXX no way to deal with boot from 2nd floppy */
+ virBufferAdd(buf, " \n", 21 );
+ else if (*tmp == 'c')
+ /*
+ * Don't know what to put here. Say the vm has been given 3
+ * disks - hda, hdb, hdc. How does one identify the boot disk?
+ * We're going to assume that first disk is the boot disk since
+ * this is most common practice
+ */
+ virBufferAdd(buf, " \n", 21 );
+ else if (*tmp == 'd')
+ virBufferAdd(buf, " \n", 24 );
+ else if (*tmp == 'n')
+ virBufferAdd(buf, " \n", 26 );
+ tmp++;
+ }
}
} else {
virBufferVSprintf(buf, " linux\n");
tmp = sexpr_node(node, "domain/image/linux/kernel");
- if (tmp == NULL) {
+ if (tmp == NULL && !bootloader) {
virXendError(xend, VIR_ERR_INTERNAL_ERROR,
- _("domain information incomplete, missing kernel"));
+ _("domain information incomplete, missing kernel & bootloader"));
return(-1);
- }
- virBufferVSprintf(buf, " %s\n", tmp);
+ }
+ if (tmp)
+ virBufferVSprintf(buf, " %s\n", tmp);
tmp = sexpr_node(node, "domain/image/linux/ramdisk");
if ((tmp != NULL) && (tmp[0] != 0))
virBufferVSprintf(buf, " %s\n", tmp);
@@ -1334,7 +1342,7 @@ xend_parse_sexp_desc(virConnectPtr conn,
const char *tmp;
char *tty;
virBuffer buf;
- int hvm = 0;
+ int hvm = 0, bootloader = 0;
int domid = -1;
int max_mem, cur_mem;
@@ -1385,12 +1393,14 @@ xend_parse_sexp_desc(virConnectPtr conn,
virBufferVSprintf(&buf, " %s\n", compact);
}
tmp = sexpr_node(root, "domain/bootloader");
- if (tmp != NULL)
+ if (tmp != NULL) {
+ bootloader = 1;
virBufferVSprintf(&buf, " %s\n", tmp);
+ }
if (sexpr_lookup(root, "domain/image")) {
hvm = sexpr_lookup(root, "domain/image/hvm") ? 1 : 0;
- xend_parse_sexp_desc_os(conn, root, &buf, hvm);
+ xend_parse_sexp_desc_os(conn, root, &buf, hvm, bootloader);
}
max_mem = (int) (sexpr_u64(root, "domain/maxmem") << 10);
@@ -1612,9 +1622,9 @@ xend_parse_sexp_desc(virConnectPtr conn,
tmp2);
virBufferAdd(&buf, " \n", 17);
- } else if (!hvm &&
- sexpr_lookup(node, "device/vfb")) {
- /* New style graphics config for PV guests only in 3.0.4 */
+ } else if (sexpr_lookup(node, "device/vfb")) {
+ /* New style graphics config for PV guests in >= 3.0.4,
+ * or for HVM guests in >= 3.0.5 */
tmp = sexpr_node(node, "device/vfb/type");
if (tmp && !strcmp(tmp, "sdl")) {
@@ -1663,7 +1673,7 @@ xend_parse_sexp_desc(virConnectPtr conn,
}
}
- /* Graphics device (HVM, or old (pre-3.0.4) style PV vnc config) */
+ /* Graphics device (HVM <= 3.0.4, or PV <= 3.0.4) vnc config */
tmp = sexpr_fmt_node(root, "domain/image/%s/vnc", hvm ? "hvm" : "linux");
if (tmp != NULL) {
if (tmp[0] == '1') {
@@ -1901,7 +1911,6 @@ xenDaemonOpen(virConnectPtr conn, const
{
xmlURIPtr uri = NULL;
int ret;
- unsigned long version;
/* If the name is just "xen" (it might originally have been NULL, see
* xenUnifiedOpen) then try default paths and methods to get to the
@@ -1914,8 +1923,8 @@ xenDaemonOpen(virConnectPtr conn, const
ret = xenDaemonOpen_unix(conn, "/var/lib/xend/xend-socket");
if (ret < 0)
goto try_http;
- ret = xenDaemonGetVersion(conn, &version);
- if (ret == 0)
+ ret = xend_detect_config_version(conn);
+ if (ret != -1)
goto done;
try_http:
@@ -1925,8 +1934,8 @@ xenDaemonOpen(virConnectPtr conn, const
ret = xenDaemonOpen_tcp(conn, "localhost", 8000);
if (ret < 0)
goto failed;
- ret = xenDaemonGetVersion(conn, &version);
- if (ret < 0)
+ ret = xend_detect_config_version(conn);
+ if (ret == -1)
goto failed;
} else {
/*
@@ -1950,15 +1959,15 @@ xenDaemonOpen(virConnectPtr conn, const
if (ret < 0)
goto failed;
- ret = xenDaemonGetVersion(conn, &version);
- if (ret < 0)
+ ret = xend_detect_config_version(conn);
+ if (ret == -1)
goto failed;
} else if (!strcasecmp(uri->scheme, "http")) {
ret = xenDaemonOpen_tcp(conn, uri->server, uri->port);
if (ret < 0)
goto failed;
- ret = xenDaemonGetVersion(conn, &version);
- if (ret < 0)
+ ret = xend_detect_config_version(conn);
+ if (ret == -1)
goto failed;
} else {
if (!(flags & VIR_DRV_OPEN_QUIET))
@@ -1967,17 +1976,7 @@ xenDaemonOpen(virConnectPtr conn, const
}
}
- done:
- /* The XenD config version is used to determine
- * which APIs / features to activate. Lookup & cache
- * it now to avoid repeated HTTP calls
- */
- if (xend_detect_config_version(conn) < 0) {
- virXendError(conn, VIR_ERR_INTERNAL_ERROR,
- "cannot determine xend config version");
- goto failed;
- }
-
+ done:
if (uri != NULL)
xmlFreeURI(uri);
return(ret);
@@ -2962,7 +2961,7 @@ xenDaemonCreateLinux(virConnectPtr conn,
return (NULL);
}
-
+ printf("%s\n", sexpr);
ret = xenDaemonDomainCreateLinux(conn, sexpr);
free(sexpr);
if (ret != 0) {
Index: xml.c
===================================================================
RCS file: /data/cvs/libvirt/src/xml.c,v
retrieving revision 1.71
diff -u -p -r1.71 xml.c
--- xml.c 11 Apr 2007 16:06:30 -0000 1.71
+++ xml.c 12 Apr 2007 00:52:29 -0000
@@ -591,7 +591,8 @@ virDomainParseXMLOSDescHVM(virConnectPtr
xmlNodePtr cur, txt;
xmlChar *type = NULL;
xmlChar *loader = NULL;
- xmlChar *boot_dev = NULL;
+ char bootorder[5];
+ int nbootorder = 0;
int res;
char *str;
@@ -610,13 +611,32 @@ virDomainParseXMLOSDescHVM(virConnectPtr
if ((txt != NULL) && (txt->type == XML_TEXT_NODE) &&
(txt->next == NULL))
loader = txt->content;
- } else if ((boot_dev == NULL) &&
- (xmlStrEqual(cur->name, BAD_CAST "boot"))) {
- boot_dev = xmlGetProp(cur, BAD_CAST "dev");
+ } else if ((xmlStrEqual(cur->name, BAD_CAST "boot"))) {
+ xmlChar *boot_dev = xmlGetProp(cur, BAD_CAST "dev");
+ if (nbootorder == ((sizeof(bootorder)/sizeof(bootorder[0]))-1)) {
+ virXMLError(conn, VIR_ERR_XML_ERROR, "too many boot devices", 0);
+ return (-1);
+ }
+ if (xmlStrEqual(boot_dev, BAD_CAST "fd")) {
+ bootorder[nbootorder++] = 'a';
+ } else if (xmlStrEqual(boot_dev, BAD_CAST "cdrom")) {
+ bootorder[nbootorder++] = 'd';
+ } else if (xmlStrEqual(boot_dev, BAD_CAST "network")) {
+ bootorder[nbootorder++] = 'n';
+ } else if (xmlStrEqual(boot_dev, BAD_CAST "hd")) {
+ bootorder[nbootorder++] = 'c';
+ } else {
+ xmlFree(boot_dev);
+ /* Any other type of boot dev is unsupported right now */
+ virXMLError(conn, VIR_ERR_XML_ERROR, NULL, 0);
+ return (-1);
+ }
+ xmlFree(boot_dev);
}
}
cur = cur->next;
}
+ bootorder[nbootorder] = '\0';
if ((type == NULL) || (!xmlStrEqual(type, BAD_CAST "hvm"))) {
/* VIR_ERR_OS_TYPE */
virXMLError(conn, VIR_ERR_OS_TYPE, (const char *) type, 0);
@@ -641,73 +661,58 @@ virDomainParseXMLOSDescHVM(virConnectPtr
virBufferVSprintf(buf, "(vcpus %d)", vcpus);
- if (boot_dev) {
- if (xmlStrEqual(boot_dev, BAD_CAST "fd")) {
- virBufferVSprintf(buf, "(boot a)" /*, (const char *) boot_dev*/);
- } else if (xmlStrEqual(boot_dev, BAD_CAST "cdrom")) {
- virBufferVSprintf(buf, "(boot d)" /*, (const char *) boot_dev*/);
- } else if (xmlStrEqual(boot_dev, BAD_CAST "hd")) {
- virBufferVSprintf(buf, "(boot c)" /*, (const char *) boot_dev*/);
- } else {
- /* Any other type of boot dev is unsupported right now */
- virXMLError(conn, VIR_ERR_XML_ERROR, NULL, 0);
- }
+ if (nbootorder)
+ virBufferVSprintf(buf, "(boot %s)", bootorder);
- /* get the 1st floppy device file */
- cur = virXPathNode(
- "/domain/devices/disk[@device='floppy' and target/@dev='fda']/source",
- ctxt);
+ /* get the 1st floppy device file */
+ cur = virXPathNode("/domain/devices/disk[@device='floppy' and target/@dev='fda']/source",
+ ctxt);
if (cur != NULL) {
- xmlChar *fdfile;
-
- fdfile = xmlGetProp(cur, BAD_CAST "file");
+ xmlChar *fdfile;
+ fdfile = xmlGetProp(cur, BAD_CAST "file");
if (fdfile != NULL) {
- virBufferVSprintf(buf, "(fda '%s')", fdfile);
- free(fdfile);
+ virBufferVSprintf(buf, "(fda '%s')", fdfile);
+ free(fdfile);
}
- }
+ }
- /* get the 2nd floppy device file */
- cur = virXPathNode(
- "/domain/devices/disk[@device='floppy' and target/@dev='fdb']/source",
- ctxt);
+ /* get the 2nd floppy device file */
+ cur = virXPathNode("/domain/devices/disk[@device='floppy' and target/@dev='fdb']/source",
+ ctxt);
if (cur != NULL) {
- xmlChar *fdfile;
-
- fdfile = xmlGetProp(cur, BAD_CAST "file");
+ xmlChar *fdfile;
+ fdfile = xmlGetProp(cur, BAD_CAST "file");
if (fdfile != NULL) {
- virBufferVSprintf(buf, "(fdb '%s')", fdfile);
- free(fdfile);
+ virBufferVSprintf(buf, "(fdb '%s')", fdfile);
+ free(fdfile);
}
- }
+ }
- /* get the cdrom device file */
- /* Only XenD <= 3.0.2 wants cdrom config here */
- if (xendConfigVersion == 1) {
- cur = virXPathNode(
- "/domain/devices/disk[@device='cdrom' and target/@dev='hdc']/source",
+ /* get the cdrom device file */
+ /* Only XenD <= 3.0.2 wants cdrom config here */
+ if (xendConfigVersion == 1) {
+ cur = virXPathNode("/domain/devices/disk[@device='cdrom' and target/@dev='hdc']/source",
ctxt);
if (cur != NULL) {
- xmlChar *cdfile;
+ xmlChar *cdfile;
- cdfile = xmlGetProp(cur, BAD_CAST "file");
- if (cdfile != NULL) {
- virBufferVSprintf(buf, "(cdrom '%s')",
- (const char *)cdfile);
- xmlFree(cdfile);
- }
+ cdfile = xmlGetProp(cur, BAD_CAST "file");
+ if (cdfile != NULL) {
+ virBufferVSprintf(buf, "(cdrom '%s')",
+ (const char *)cdfile);
+ xmlFree(cdfile);
}
}
-
- if (virXPathNode("/domain/features/acpi", ctxt) != NULL)
- virBufferAdd(buf, "(acpi 1)", 8);
- if (virXPathNode("/domain/features/apic", ctxt) != NULL)
- virBufferAdd(buf, "(apic 1)", 8);
- if (virXPathNode("/domain/features/pae", ctxt) != NULL)
- virBufferAdd(buf, "(pae 1)", 7);
}
+ if (virXPathNode("/domain/features/acpi", ctxt) != NULL)
+ virBufferAdd(buf, "(acpi 1)", 8);
+ if (virXPathNode("/domain/features/apic", ctxt) != NULL)
+ virBufferAdd(buf, "(apic 1)", 8);
+ if (virXPathNode("/domain/features/pae", ctxt) != NULL)
+ virBufferAdd(buf, "(pae 1)", 7);
+
res = virXPathBoolean("count(domain/devices/console) > 0", ctxt);
if (res < 0) {
virXMLError(conn, VIR_ERR_XML_ERROR, NULL, 0);
@@ -717,25 +722,24 @@ virDomainParseXMLOSDescHVM(virConnectPtr
virBufferAdd(buf, "(serial pty)", 12);
}
- /* Is a graphics device specified? */
- cur = virXPathNode("/domain/devices/graphics[1]", ctxt);
- if (cur != NULL) {
- res = virDomainParseXMLGraphicsDescImage(conn, cur, buf,
- xendConfigVersion);
- if (res != 0) {
- goto error;
+ /* HVM graphics for xen <= 3.0.5 */
+ if (xendConfigVersion < 4) {
+ /* Is a graphics device specified? */
+ cur = virXPathNode("/domain/devices/graphics[1]", ctxt);
+ if (cur != NULL) {
+ res = virDomainParseXMLGraphicsDescImage(conn, cur, buf,
+ xendConfigVersion);
+ if (res != 0) {
+ goto error;
+ }
}
}
virBufferAdd(buf, "))", 2);
- if (boot_dev)
- xmlFree(boot_dev);
-
return (0);
+
error:
- if (boot_dev)
- xmlFree(boot_dev);
return(-1);
}
@@ -821,13 +825,12 @@ virDomainParseXMLOSDescPV(virConnectPtr
if (cmdline != NULL)
virBufferVSprintf(buf, "(args '%s')", (const char *) cmdline);
- /* Is a graphics device specified? */
- /* Old style config before merge of PVFB */
+ /* PV graphics for xen <= 3.0.4 */
if (xendConfigVersion < 3) {
cur = virXPathNode("/domain/devices/graphics[1]", ctxt);
if (cur != NULL) {
res = virDomainParseXMLGraphicsDescImage(conn, cur, buf,
- xendConfigVersion);
+ xendConfigVersion);
if (res != 0) {
goto error;
}
@@ -1326,7 +1329,7 @@ virDomainParseXMLDesc(virConnectPtr conn
goto error;
}
}
- free(nodes);
+ free(nodes);
}
nb_nodes = virXPathNodeSet("/domain/devices/interface", ctxt, &nodes);
@@ -1340,21 +1343,23 @@ virDomainParseXMLDesc(virConnectPtr conn
}
virBufferAdd(&buf, ")", 1);
}
- free(nodes);
+ free(nodes);
}
- /* New style PVFB config - 3.0.4 merge */
- if (xendConfigVersion >= 3 && !hvm) {
+ /* New style PV graphics config xen >= 3.0.4,
+ * or HVM graphics config xen >= 3.0.5 */
+ if ((xendConfigVersion >= 3 && !hvm) ||
+ (xendConfigVersion >= 4 && hvm)) {
nb_nodes = virXPathNodeSet("/domain/devices/graphics", ctxt, &nodes);
- if (nb_nodes > 0) {
+ if (nb_nodes > 0) {
for (i = 0; i < nb_nodes; i++) {
res = virDomainParseXMLGraphicsDescVFB(conn, nodes[i], &buf);
if (res != 0) {
- free(nodes);
+ free(nodes);
goto error;
}
}
- free(nodes);
+ free(nodes);
}
}