Index: libvirt/include/libvirt/libvirt.h =================================================================== RCS file: /data/cvs/libvirt/include/libvirt/libvirt.h,v retrieving revision 1.39 diff -u -p -r1.39 libvirt.h --- libvirt/include/libvirt/libvirt.h 6 Mar 2007 21:55:44 -0000 1.39 +++ libvirt/include/libvirt/libvirt.h 8 Mar 2007 00:46:35 -0000 @@ -231,6 +231,8 @@ int virConnectClose (virConnectPtr co const char * virConnectGetType (virConnectPtr conn); int virConnectGetVersion (virConnectPtr conn, unsigned long *hvVer); +int virConnectGetMaxVcpus (virConnectPtr conn, + const char *type); int virNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info); @@ -310,6 +312,8 @@ int virDomainSetMaxMemory (virDomainPt unsigned long memory); int virDomainSetMemory (virDomainPtr domain, unsigned long memory); +int virDomainGetMaxVcpus (virDomainPtr domain); + /* * XML domain description */ Index: libvirt/include/libvirt/libvirt.h.in =================================================================== RCS file: /data/cvs/libvirt/include/libvirt/libvirt.h.in,v retrieving revision 1.24 diff -u -p -r1.24 libvirt.h.in --- libvirt/include/libvirt/libvirt.h.in 6 Mar 2007 21:55:44 -0000 1.24 +++ libvirt/include/libvirt/libvirt.h.in 8 Mar 2007 00:46:35 -0000 @@ -231,6 +231,8 @@ int virConnectClose (virConnectPtr co const char * virConnectGetType (virConnectPtr conn); int virConnectGetVersion (virConnectPtr conn, unsigned long *hvVer); +int virConnectGetMaxVcpus (virConnectPtr conn, + const char *type); int virNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info); @@ -310,6 +312,8 @@ int virDomainSetMaxMemory (virDomainPt unsigned long memory); int virDomainSetMemory (virDomainPtr domain, unsigned long memory); +int virDomainGetMaxVcpus (virDomainPtr domain); + /* * XML domain description */ Index: libvirt/src/driver.h =================================================================== RCS file: /data/cvs/libvirt/src/driver.h,v retrieving revision 1.22 diff -u -p -r1.22 driver.h --- libvirt/src/driver.h 6 Mar 2007 21:55:44 -0000 1.22 +++ libvirt/src/driver.h 8 Mar 2007 00:46:35 -0000 @@ -44,6 +44,8 @@ typedef int (*virDrvGetVersion) (virConnectPtr conn, unsigned long *hvVer); typedef int + (*virDrvGetMaxVcpus) (virConnectPtr conn); +typedef int (*virDrvNodeGetInfo) (virConnectPtr conn, virNodeInfoPtr info); typedef int @@ -129,6 +131,8 @@ typedef int unsigned char *cpumaps, int maplen); typedef int + (*virDrvDomainGetMaxVcpus) (virDomainPtr domain); +typedef int (*virDrvDomainAttachDevice) (virDomainPtr domain, char *xml); typedef int @@ -158,6 +162,7 @@ struct _virDriver { virDrvClose close; virDrvGetType type; virDrvGetVersion version; + virDrvGetMaxVcpus getMaxVcpus; virDrvNodeGetInfo nodeGetInfo; virDrvListDomains listDomains; virDrvNumOfDomains numOfDomains; @@ -181,6 +186,7 @@ struct _virDriver { virDrvDomainSetVcpus domainSetVcpus; virDrvDomainPinVcpu domainPinVcpu; virDrvDomainGetVcpus domainGetVcpus; + virDrvDomainGetMaxVcpus domainGetMaxVcpus; virDrvDomainDumpXML domainDumpXML; virDrvListDefinedDomains listDefinedDomains; virDrvNumOfDefinedDomains numOfDefinedDomains; Index: libvirt/src/libvirt.c =================================================================== RCS file: /data/cvs/libvirt/src/libvirt.c,v retrieving revision 1.59 diff -u -p -r1.59 libvirt.c --- libvirt/src/libvirt.c 6 Mar 2007 21:55:44 -0000 1.59 +++ libvirt/src/libvirt.c 8 Mar 2007 00:46:35 -0000 @@ -523,6 +523,44 @@ virConnectGetVersion(virConnectPtr conn, } /** + * virConnectGetMaxVcpus: + * @conn: pointer to the hypervisor connection + * @type: value of the 'type' attribute in the element + * + * Returns the maximum number of virtual CPUs supported for a guest VM of a + * specific type. The 'type' parameter here corresponds to the 'type' + * attribute in the element of the XML. + * + * Returns the maximum of virtual CPU or -1 in case of error. + */ +int +virConnectGetMaxVcpus(virConnectPtr conn, + const char *type) +{ + int ret = -1; + int i; + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__); + return (-1); + } + + if (type == NULL) + type = "Xen"; + for (i = 0;i < MAX_DRIVERS;i++) { + if ((virDriverTab[i] != NULL) && + (!strcmp(virDriverTab[i]->name, type))) { + ret = conn->drivers[i]->getMaxVcpus(conn); + if (ret >= 0) + return(ret); + } + } + + return (-1); + +} + +/** * virConnectListDomains: * @conn: pointer to the hypervisor connection * @ids: array to collect the list of IDs of active domains @@ -2110,6 +2148,44 @@ virDomainGetVcpus(virDomainPtr domain, v } /** + * virDomainGetMaxVcpus: + * @domain: pointer to domain object + * + * Returns the maximum number of virtual CPUs supported for + * the guest VM. If the guest is inactive, this is basically + * the same as virConnectGetMaxVcpus. If the guest is running + * this will reflect the maximum number of virtual CPUs the + * guest was booted with. + * + * Returns the maximum of virtual CPU or -1 in case of error. + */ +int +virDomainGetMaxVcpus(virDomainPtr domain) { + int i; + int ret = 0; + virConnectPtr conn; + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + return (-1); + } + + conn = domain->conn; + + for (i = 0;i < conn->nb_drivers;i++) { + if ((conn->drivers[i] != NULL) && + (conn->drivers[i]->domainGetMaxVcpus != NULL)) { + ret = conn->drivers[i]->domainGetMaxVcpus(domain); + if (ret != 0) + return(ret); + } + } + virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__); + return (-1); +} + + +/** * virDomainAttachDevice: * @domain: pointer to domain object * @xml: pointer to XML description of one device Index: libvirt/src/libvirt_sym.version =================================================================== RCS file: /data/cvs/libvirt/src/libvirt_sym.version,v retrieving revision 1.16 diff -u -p -r1.16 libvirt_sym.version --- libvirt/src/libvirt_sym.version 23 Feb 2007 08:51:30 -0000 1.16 +++ libvirt/src/libvirt_sym.version 8 Mar 2007 00:46:36 -0000 @@ -36,6 +36,7 @@ virDomainSuspend; virConnectListDefinedDomains; virConnectNumOfDefinedDomains; + virConnectGetMaxVcpus; virDomainUndefine; virDomainGetAutostart; virDomainSetAutostart; @@ -56,6 +57,7 @@ virDomainSetVcpus; virDomainPinVcpu; virDomainGetVcpus; + virDomainGetMaxVcpus; virDomainAttachDevice; virDomainDetachDevice; Index: libvirt/src/proxy_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/proxy_internal.c,v retrieving revision 1.22 diff -u -p -r1.22 proxy_internal.c --- libvirt/src/proxy_internal.c 23 Feb 2007 08:51:30 -0000 1.22 +++ libvirt/src/proxy_internal.c 8 Mar 2007 00:46:36 -0000 @@ -50,6 +50,7 @@ static virDriver xenProxyDriver = { xenProxyClose, /* close */ NULL, /* type */ xenProxyGetVersion, /* version */ + NULL, /* getMaxVcpus */ xenProxyNodeGetInfo, /* nodeGetInfo */ xenProxyListDomains, /* listDomains */ xenProxyNumOfDomains, /* numOfDomains */ @@ -73,6 +74,7 @@ static virDriver xenProxyDriver = { NULL, /* domainSetVcpus */ NULL, /* domainPinVcpu */ NULL, /* domainGetVcpus */ + NULL, /* domainGetMaxVcpus */ xenProxyDomainDumpXML, /* domainDumpXML */ NULL, /* listDefinedDomains */ NULL, /* numOfDefinedDomains */ Index: libvirt/src/qemu_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/qemu_internal.c,v retrieving revision 1.14 diff -u -p -r1.14 qemu_internal.c --- libvirt/src/qemu_internal.c 6 Mar 2007 21:55:44 -0000 1.14 +++ libvirt/src/qemu_internal.c 8 Mar 2007 00:46:36 -0000 @@ -1167,6 +1167,7 @@ static virDriver qemuDriver = { qemuClose, /* close */ NULL, /* type */ qemuGetVersion, /* version */ + NULL, /* getMaxVcpus */ qemuNodeGetInfo, /* nodeGetInfo */ qemuListDomains, /* listDomains */ qemuNumOfDomains, /* numOfDomains */ @@ -1190,6 +1191,7 @@ static virDriver qemuDriver = { NULL, /* domainSetVcpus */ NULL, /* domainPinVcpu */ NULL, /* domainGetVcpus */ + NULL, /* domainGetMaxVcpus */ qemuDomainDumpXML, /* domainDumpXML */ qemuListDefinedDomains, /* listDomains */ qemuNumOfDefinedDomains, /* numOfDomains */ Index: libvirt/src/test.c =================================================================== RCS file: /data/cvs/libvirt/src/test.c,v retrieving revision 1.21 diff -u -p -r1.21 test.c --- libvirt/src/test.c 6 Mar 2007 21:55:44 -0000 1.21 +++ libvirt/src/test.c 8 Mar 2007 00:46:36 -0000 @@ -94,6 +94,7 @@ static virDriver testDriver = { testClose, /* close */ NULL, /* type */ testGetVersion, /* version */ + NULL, /* getMaxVcpus */ testNodeGetInfo, /* nodeGetInfo */ testListDomains, /* listDomains */ testNumOfDomains, /* numOfDomains */ @@ -117,6 +118,7 @@ static virDriver testDriver = { testSetVcpus, /* domainSetVcpus */ NULL, /* domainPinVcpu */ NULL, /* domainGetVcpus */ + NULL, /* domainGetMaxVcpus */ testDomainDumpXML, /* domainDumpXML */ testListDefinedDomains, /* listDefinedDomains */ testNumOfDefinedDomains, /* numOfDefinedDomains */ Index: libvirt/src/virsh.c =================================================================== RCS file: /data/cvs/libvirt/src/virsh.c,v retrieving revision 1.59 diff -u -p -r1.59 virsh.c --- libvirt/src/virsh.c 6 Mar 2007 21:55:44 -0000 1.59 +++ libvirt/src/virsh.c 8 Mar 2007 00:46:37 -0000 @@ -1383,6 +1383,7 @@ cmdSetvcpus(vshControl * ctl, vshCmd * c { virDomainPtr dom; int count; + int maxcpu; int ret = TRUE; if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) @@ -1397,6 +1398,18 @@ cmdSetvcpus(vshControl * ctl, vshCmd * c return FALSE; } + maxcpu = virDomainGetMaxVcpus(dom); + if (!maxcpu) { + virDomainFree(dom); + return FALSE; + } + + if (count > maxcpu) { + vshError(ctl, FALSE, _("Too many virtual CPU's.")); + virDomainFree(dom); + return FALSE; + } + if (virDomainSetVcpus(dom, count) != 0) { ret = FALSE; } Index: libvirt/src/xen_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/xen_internal.c,v retrieving revision 1.59 diff -u -p -r1.59 xen_internal.c --- libvirt/src/xen_internal.c 6 Mar 2007 21:55:44 -0000 1.59 +++ libvirt/src/xen_internal.c 8 Mar 2007 00:46:37 -0000 @@ -190,6 +190,11 @@ typedef union xen_getdomaininfolist xen_ dominfo.v0.nr_online_vcpus : \ dominfo.v2.nr_online_vcpus) +#define XEN_GETDOMAININFO_MAXCPUID(dominfo) \ + (hypervisor_version < 2 ? \ + dominfo.v0.max_vcpu_id : \ + dominfo.v2.max_vcpu_id) + #define XEN_GETDOMAININFO_FLAGS(dominfo) \ (hypervisor_version < 2 ? \ dominfo.v0.flags : \ @@ -423,6 +428,7 @@ static virDriver xenHypervisorDriver = { xenHypervisorClose, /* close */ xenHypervisorGetType, /* type */ xenHypervisorGetVersion, /* version */ + xenHypervisorNumOfMaxVcpus, /* getMaxVcpus */ NULL, /* nodeGetInfo */ xenHypervisorListDomains, /* listDomains */ xenHypervisorNumOfDomains, /* numOfDomains */ @@ -446,6 +452,7 @@ static virDriver xenHypervisorDriver = { xenHypervisorSetVcpus, /* domainSetVcpus */ xenHypervisorPinVcpu, /* domainPinVcpu */ xenHypervisorGetVcpus, /* domainGetVcpus */ + xenHypervisorGetVcpuMax, /* domainGetMaxVcpus */ NULL, /* domainDumpXML */ NULL, /* listDefinedDomains */ NULL, /* numOfDefinedDomains */ @@ -1448,6 +1455,20 @@ xenHypervisorListDomains(virConnectPtr c } /** + * xenHypervisorNumOfMaxVcpus: + * + * Returns the maximum of CPU defined by Xen. + */ +int +xenHypervisorNumOfMaxVcpus(virConnectPtr conn) +{ + if ((conn == NULL) || (conn->handle < 0)) + return (-1); + + return MAX_VIRT_CPUS; +} + +/** * xenHypervisorGetDomMaxMemory: * @conn: connection data * @id: domain id @@ -1824,6 +1845,41 @@ xenHypervisorGetVcpus(virDomainPtr domai } #endif +/** + * xenHypervisorGetVcpuMax: + * + * Returns the maximum number of virtual CPUs supported for + * the guest VM. If the guest is inactive, this is the maximum + * of CPU defined by Xen. If the guest is running this reflect + * the maximum number of virtual CPUs the guest was booted with. + */ +int +xenHypervisorGetVcpuMax(virDomainPtr domain) +{ + xen_getdomaininfo dominfo; + int ret; + int maxcpu; + + if ((domain == NULL) || (domain->conn == NULL) || + (domain->conn->handle < 0)) + return (-1); + + /* inactive domain */ + if (domain->id < 0) { + maxcpu = MAX_VIRT_CPUS; + } else { + XEN_GETDOMAININFO_CLEAR(dominfo); + ret = virXen_getdomaininfo(domain->conn->handle, domain->id, + &dominfo); + + if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != domain->id)) + return (-1); + maxcpu = XEN_GETDOMAININFO_MAXCPUID(dominfo) + 1; + } + + return maxcpu; +} + /* * Local variables: * indent-tabs-mode: nil Index: libvirt/src/xen_internal.h =================================================================== RCS file: /data/cvs/libvirt/src/xen_internal.h,v retrieving revision 1.14 diff -u -p -r1.14 xen_internal.h --- libvirt/src/xen_internal.h 4 Aug 2006 10:41:05 -0000 1.14 +++ libvirt/src/xen_internal.h 8 Mar 2007 00:46:37 -0000 @@ -32,6 +32,7 @@ int xenHypervisorNumOfDomains (virConnec int xenHypervisorListDomains (virConnectPtr conn, int *ids, int maxids); +int xenHypervisorNumOfMaxVcpus (virConnectPtr conn); int xenHypervisorDestroyDomain (virDomainPtr domain); int xenHypervisorResumeDomain (virDomainPtr domain); int xenHypervisorPauseDomain (virDomainPtr domain); @@ -55,6 +56,7 @@ int xenHypervisorGetVcpus (virDomainPtr int maxinfo, unsigned char *cpumaps, int maplen); +int xenHypervisorGetVcpuMax (virDomainPtr domain); #ifdef __cplusplus } Index: libvirt/src/xend_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/xend_internal.c,v retrieving revision 1.99 diff -u -p -r1.99 xend_internal.c --- libvirt/src/xend_internal.c 6 Mar 2007 21:55:44 -0000 1.99 +++ libvirt/src/xend_internal.c 8 Mar 2007 00:46:37 -0000 @@ -66,6 +66,7 @@ static virDriver xenDaemonDriver = { xenDaemonClose, /* close */ xenDaemonGetType, /* type */ xenDaemonGetVersion, /* version */ + NULL, /* getMaxVcpus */ xenDaemonNodeGetInfo, /* nodeGetInfo */ xenDaemonListDomains, /* listDomains */ xenDaemonNumOfDomains, /* numOfDomains */ @@ -89,6 +90,7 @@ static virDriver xenDaemonDriver = { xenDaemonDomainSetVcpus, /* domainSetVcpus */ xenDaemonDomainPinVcpu, /* domainPinVcpu */ xenDaemonDomainGetVcpus, /* domainGetVcpus */ + NULL, /* domainGetMaxVcpus */ xenDaemonDomainDumpXML, /* domainDumpXML */ xenDaemonListDefinedDomains, /* listDefinedDomains */ xenDaemonNumOfDefinedDomains, /* numOfDefinedDomains */ Index: libvirt/src/xm_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/xm_internal.c,v retrieving revision 1.16 diff -u -p -r1.16 xm_internal.c --- libvirt/src/xm_internal.c 6 Mar 2007 21:55:44 -0000 1.16 +++ libvirt/src/xm_internal.c 8 Mar 2007 00:46:38 -0000 @@ -75,6 +75,7 @@ static virDriver xenXMDriver = { xenXMClose, /* close */ xenXMGetType, /* type */ NULL, /* version */ + NULL, /* getMaxVcpus */ NULL, /* nodeGetInfo */ NULL, /* listDomains */ NULL, /* numOfDomains */ @@ -98,6 +99,7 @@ static virDriver xenXMDriver = { xenXMDomainSetVcpus, /* domainSetVcpus */ NULL, /* domainPinVcpu */ NULL, /* domainGetVcpus */ + NULL, /* domainGetMaxVcpus */ xenXMDomainDumpXML, /* domainDumpXML */ xenXMListDefinedDomains, /* listDefinedDomains */ xenXMNumOfDefinedDomains, /* numOfDefinedDomains */ Index: libvirt/src/xs_internal.c =================================================================== RCS file: /data/cvs/libvirt/src/xs_internal.c,v retrieving revision 1.32 diff -u -p -r1.32 xs_internal.c --- libvirt/src/xs_internal.c 23 Feb 2007 08:51:30 -0000 1.32 +++ libvirt/src/xs_internal.c 8 Mar 2007 00:46:38 -0000 @@ -44,6 +44,7 @@ static virDriver xenStoreDriver = { xenStoreClose, /* close */ NULL, /* type */ NULL, /* version */ + NULL, /* getMaxVcpus */ NULL, /* nodeGetInfo */ xenStoreListDomains, /* listDomains */ NULL, /* numOfDomains */ @@ -67,6 +68,7 @@ static virDriver xenStoreDriver = { NULL, /* domainSetVcpus */ NULL, /* domainPinVcpu */ NULL, /* domainGetVcpus */ + NULL, /* domainGetMaxVcpus */ NULL, /* domainDumpXML */ NULL, /* listDefinedDomains */ NULL, /* numOfDefinedDomains */