mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 02:51:16 +00:00
Fixed up various functions for Xen 3.0.5
This commit is contained in:
parent
dfe570a9ef
commit
42ee7111c3
21
ChangeLog
21
ChangeLog
@ -1,3 +1,24 @@
|
||||
Thu Apr 12 19:51:00 EST 2007 Daniel Berrange <berrange@redhat.com>
|
||||
|
||||
* src/xen_internal.c: Updated structs to work with new Xen 3.0.5
|
||||
hypercall ABI. Mask out HVM bit when determining domain status.
|
||||
Limit number of iterations when counting active IDs to 65000
|
||||
* src/xen_unified.c: Fix checking of return value for the
|
||||
domainGetVCpus method.
|
||||
* src/xend_internal.c: Added an impl of the DomainGetOSType
|
||||
method which works with inactive domains too. Don't do a
|
||||
redundant ping test against GetVersion, since we now already
|
||||
fetch config file format number which serves as a ping test.
|
||||
Allow the kernel SEXPR field to be missing for domain0, or if
|
||||
using a bootloader. Mark interface as type=bridge, if there
|
||||
is a bridge device listed, but no explicit script to fix inactive
|
||||
domains. Allow multiple boot devices to be provided for HVM
|
||||
* src/xml.c: Allow multiple boot devices to be provided for HVM.
|
||||
Support new style graphics config for HVM in xen 3.0.5
|
||||
* src/xs_internal.c: Don't hardcode domain type of 'linux',
|
||||
since we now have a fallback driver with xend that can make
|
||||
the correct diagnosis for inactive domains.
|
||||
|
||||
Thu Apr 12 15:18:00 BST 2007 Richard Jones <rjones@redhat.com>
|
||||
|
||||
* src/libvirt.c: set VIR_CONNECT_RO on read-only connections.
|
||||
|
@ -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))
|
||||
(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) : \
|
||||
free(domlist.v2))
|
||||
#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) : \
|
||||
memset(domlist.v2, 0, sizeof(xen_v2_getdomaininfo) * size))
|
||||
#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)
|
||||
(dom_interface_version < 5 ? \
|
||||
domlist.v2[n].domain : \
|
||||
domlist.v2d5[n].domain))
|
||||
|
||||
#define XEN_GETDOMAININFOLIST_DATA(domlist) \
|
||||
(hypervisor_version < 2 ? \
|
||||
(void*)(domlist->v0) : \
|
||||
(void*)(domlist->v2))
|
||||
#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) : \
|
||||
sizeof(xen_v2_getdomaininfo))
|
||||
#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)) : \
|
||||
memset(&(dominfo.v2), 0, sizeof(xen_v2_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 first_domain, int maxids,
|
||||
|
||||
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, unsigned long memory)
|
||||
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, unsigned int vcpu,
|
||||
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, unsigned int vcpu, virVcpuInfoPtr ipt,
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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 ((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 conn)
|
||||
return (-1);
|
||||
|
||||
nbids = ret;
|
||||
/* Can't possibly have more than 65,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 < 65000) {
|
||||
last_maxids *= 2;
|
||||
maxids *= 2;
|
||||
goto retry;
|
||||
}
|
||||
nbids = -1;
|
||||
}
|
||||
if ((nbids < 0) || (nbids > maxids))
|
||||
return(-1);
|
||||
@ -1994,7 +2149,8 @@ xenHypervisorGetDomInfo(virConnectPtr conn, int id, virDomainInfoPtr info)
|
||||
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;
|
||||
|
@ -546,13 +546,14 @@ xenUnifiedDomainGetVcpus (virDomainPtr dom,
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,7 @@ static virDomainPtr xenDaemonLookupByUUID(virConnectPtr conn,
|
||||
static virDomainPtr xenDaemonCreateLinux(virConnectPtr conn,
|
||||
const char *xmlDesc,
|
||||
unsigned int flags);
|
||||
static char *xenDaemonDomainGetOSType(virDomainPtr domain);
|
||||
static int xenDaemonAttachDevice(virDomainPtr domain, char *xml);
|
||||
static int xenDaemonDetachDevice(virDomainPtr domain, char *xml);
|
||||
static int xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename,
|
||||
@ -85,7 +86,7 @@ virDriver xenDaemonDriver = {
|
||||
xenDaemonDomainShutdown, /* domainShutdown */
|
||||
xenDaemonDomainReboot, /* domainReboot */
|
||||
xenDaemonDomainDestroy, /* domainDestroy */
|
||||
NULL, /* domainGetOSType */
|
||||
xenDaemonDomainGetOSType, /* domainGetOSType */
|
||||
xenDaemonDomainGetMaxMemory, /* domainGetMaxMemory */
|
||||
xenDaemonDomainSetMaxMemory, /* domainSetMaxMemory */
|
||||
xenDaemonDomainSetMemory, /* domainMaxMemory */
|
||||
@ -1151,7 +1152,7 @@ xend_detect_config_version(virConnectPtr conn) {
|
||||
priv->xendConfigVersion = 1;
|
||||
}
|
||||
sexpr_free(root);
|
||||
return priv->xendConfigVersion;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1251,13 +1252,14 @@ xend_log(virConnectPtr xend, char *buffer, size_t n_buffer)
|
||||
* @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 +1271,44 @@ xend_parse_sexp_desc_os(virConnectPtr xend, struct sexpr *node, virBufferPtr buf
|
||||
if (hvm) {
|
||||
virBufferVSprintf(buf, " <type>hvm</type>\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, " <loader>%s</loader>\n", tmp);
|
||||
}
|
||||
if (tmp)
|
||||
virBufferVSprintf(buf, " <loader>%s</loader>\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, " <boot dev='fd'/>\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, " <boot dev='hd'/>\n", 21 );
|
||||
else if (strcmp(tmp, "d") == 0)
|
||||
virBufferAdd(buf, " <boot dev='cdrom'/>\n", 24 );
|
||||
while (*tmp) {
|
||||
if (*tmp == 'a')
|
||||
/* XXX no way to deal with boot from 2nd floppy */
|
||||
virBufferAdd(buf, " <boot dev='fd'/>\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, " <boot dev='hd'/>\n", 21 );
|
||||
else if (*tmp == 'd')
|
||||
virBufferAdd(buf, " <boot dev='cdrom'/>\n", 24 );
|
||||
else if (*tmp == 'n')
|
||||
virBufferAdd(buf, " <boot dev='network'/>\n", 26 );
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
virBufferVSprintf(buf, " <type>linux</type>\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, " <kernel>%s</kernel>\n", tmp);
|
||||
}
|
||||
if (tmp)
|
||||
virBufferVSprintf(buf, " <kernel>%s</kernel>\n", tmp);
|
||||
tmp = sexpr_node(node, "domain/image/linux/ramdisk");
|
||||
if ((tmp != NULL) && (tmp[0] != 0))
|
||||
virBufferVSprintf(buf, " <initrd>%s</initrd>\n", tmp);
|
||||
@ -1334,7 +1343,7 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root, int xendConfigVersi
|
||||
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 +1394,20 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root, int xendConfigVersi
|
||||
virBufferVSprintf(&buf, " <uuid>%s</uuid>\n", compact);
|
||||
}
|
||||
tmp = sexpr_node(root, "domain/bootloader");
|
||||
if (tmp != NULL)
|
||||
if (tmp != NULL) {
|
||||
bootloader = 1;
|
||||
virBufferVSprintf(&buf, " <bootloader>%s</bootloader>\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);
|
||||
if (domid == 0) {
|
||||
virBufferAdd(&buf, " <os>\n", -1);
|
||||
virBufferAdd(&buf, " <type>linux</type>\n", -1);
|
||||
virBufferAdd(&buf, " </os>\n", -1);
|
||||
} else {
|
||||
if (sexpr_lookup(root, "domain/image")) {
|
||||
hvm = sexpr_lookup(root, "domain/image/hvm") ? 1 : 0;
|
||||
xend_parse_sexp_desc_os(conn, root, &buf, hvm, bootloader);
|
||||
}
|
||||
}
|
||||
|
||||
max_mem = (int) (sexpr_u64(root, "domain/maxmem") << 10);
|
||||
@ -1585,9 +1602,9 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root, int xendConfigVersi
|
||||
} else if (sexpr_lookup(node, "device/vif")) {
|
||||
const char *tmp2;
|
||||
tmp2 = sexpr_node(node, "device/vif/script");
|
||||
if (tmp2 && strstr(tmp2, "bridge")) {
|
||||
tmp = sexpr_node(node, "device/vif/bridge");
|
||||
if ((tmp2 && strstr(tmp2, "bridge")) || tmp) {
|
||||
virBufferVSprintf(&buf, " <interface type='bridge'>\n");
|
||||
tmp = sexpr_node(node, "device/vif/bridge");
|
||||
if (tmp != NULL)
|
||||
virBufferVSprintf(&buf, " <source bridge='%s'/>\n",
|
||||
tmp);
|
||||
@ -1612,9 +1629,9 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root, int xendConfigVersi
|
||||
tmp2);
|
||||
|
||||
virBufferAdd(&buf, " </interface>\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 +1680,7 @@ xend_parse_sexp_desc(virConnectPtr conn, struct sexpr *root, int xendConfigVersi
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 +1918,6 @@ xenDaemonOpen(virConnectPtr conn, const char *name, int flags)
|
||||
{
|
||||
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 +1930,8 @@ xenDaemonOpen(virConnectPtr conn, const char *name, int flags)
|
||||
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 +1941,8 @@ xenDaemonOpen(virConnectPtr conn, const char *name, int flags)
|
||||
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 +1966,15 @@ xenDaemonOpen(virConnectPtr conn, const char *name, int flags)
|
||||
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))
|
||||
@ -1968,16 +1984,6 @@ xenDaemonOpen(virConnectPtr conn, const char *name, int flags)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (uri != NULL)
|
||||
xmlFreeURI(uri);
|
||||
return(ret);
|
||||
@ -2122,6 +2128,49 @@ xenDaemonDomainDestroy(virDomainPtr domain)
|
||||
return xend_op(domain->conn, domain->name, "op", "destroy", NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* xenDaemonDomainGetOSType:
|
||||
* @domain: a domain object
|
||||
*
|
||||
* Get the type of domain operation system.
|
||||
*
|
||||
* Returns the new string or NULL in case of error, the string must be
|
||||
* freed by the caller.
|
||||
*/
|
||||
static char *
|
||||
xenDaemonDomainGetOSType(virDomainPtr domain)
|
||||
{
|
||||
char *type;
|
||||
struct sexpr *root;
|
||||
xenUnifiedPrivatePtr priv;
|
||||
|
||||
if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
|
||||
virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
|
||||
__FUNCTION__);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
|
||||
|
||||
if (domain->id < 0 && priv->xendConfigVersion < 3)
|
||||
return(NULL);
|
||||
|
||||
/* can we ask for a subset ? worth it ? */
|
||||
root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
|
||||
if (root == NULL)
|
||||
return(NULL);
|
||||
|
||||
if (sexpr_lookup(root, "domain/image/hvm")) {
|
||||
type = strdup("hvm");
|
||||
} else {
|
||||
type = strdup("linux");
|
||||
}
|
||||
|
||||
sexpr_free(root);
|
||||
|
||||
return(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* xenDaemonDomainSave:
|
||||
* @domain: pointer to the Domain block
|
||||
@ -2892,7 +2941,7 @@ xenDaemonLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
|
||||
uuid[4], uuid[5], uuid[6], uuid[7],
|
||||
uuid[8], uuid[9], uuid[10], uuid[11],
|
||||
uuid[12], uuid[13], uuid[14], uuid[15]);
|
||||
printf("Dpooing %s\n", uuidstr);
|
||||
|
||||
root = sexpr_get(conn, "/xend/domain/%s?detail=1", uuidstr);
|
||||
if (root == NULL)
|
||||
return (NULL);
|
||||
|
157
src/xml.c
157
src/xml.c
@ -591,7 +591,8 @@ virDomainParseXMLOSDescHVM(virConnectPtr conn, xmlNodePtr node, virBufferPtr buf
|
||||
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 conn, xmlNodePtr node, virBufferPtr buf
|
||||
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 conn, xmlNodePtr node, virBufferPtr buf
|
||||
|
||||
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 conn, xmlNodePtr node, virBufferPtr buf
|
||||
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 conn, xmlNodePtr node, virBufferPtr buf,
|
||||
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, const char *xmldesc, char **name, int
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
free(nodes);
|
||||
free(nodes);
|
||||
}
|
||||
|
||||
nb_nodes = virXPathNodeSet("/domain/devices/interface", ctxt, &nodes);
|
||||
@ -1340,21 +1343,23 @@ virDomainParseXMLDesc(virConnectPtr conn, const char *xmldesc, char **name, int
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -741,8 +741,6 @@ xenStoreDomainGetOSType(virDomainPtr domain) {
|
||||
str = virDomainGetVMInfo(domain, vm, "image/ostype");
|
||||
free(vm);
|
||||
}
|
||||
if (str == NULL)
|
||||
str = strdup("linux");
|
||||
|
||||
return (str);
|
||||
}
|
||||
|
@ -19,7 +19,8 @@
|
||||
</features>
|
||||
<devices>
|
||||
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||
<interface type='ethernet'>
|
||||
<interface type='bridge'>
|
||||
<source bridge='xenbr0'/>
|
||||
<mac address='00:16:3e:0a:7b:39'/>
|
||||
</interface>
|
||||
<disk type='block' device='disk'>
|
||||
|
Loading…
Reference in New Issue
Block a user