Hi The maximum of virtual CPU is not guarded in virsh setvcpus now. Then, when 32767 was set to virtual CPU of virsh setvcpus, the problem that Xend became abnormal was detected. example: ---------------------------------------------------------------------- # virsh setvcpus 0 32767 libvir: Xen Daemon error : POST operation failed: (xend.err "(9, 'Bad file descriptor')") libvir: Xen error : failed Xen syscall ioctl 3166208 libvir: error : library call virDomainSetVcpus failed, possibly not supported # xm list -l Error: (9, 'Bad file descriptor') Usage: xm list [options] [Domain, ...] List information about all/some domains. -l, --long Output all VM details in SXP --label Include security labels --state=<state> Select only VMs with the specified state ---------------------------------------------------------------------- Therefore, I propose the correction that adjusts the maximum of virtual CPU to the same value as Xen. This patch is over 200lines. If you request, I am ready to repost it with split this patch. Signed-off-by: Masayuki Sunou <fj1826dm@xxxxxxxxxxxxxxxxx> Thanks, Masayuki Sunou. libvirt-0.2.0 ---------------------------------------------------------------------- diff -rup a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h --- a/include/libvirt/libvirt.h 2007-02-23 17:51:30.000000000 +0900 +++ b/include/libvirt/libvirt.h 2007-03-01 03:02:20.000000000 +0900 @@ -233,6 +233,7 @@ int virConnectGetVersion (virConnectPt unsigned long *hvVer); int virNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info); +int virGetCpuMax (virConnectPtr conn); /* * Gather list of running domains diff -rup a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in --- a/include/libvirt/libvirt.h.in 2007-02-23 17:51:30.000000000 +0900 +++ b/include/libvirt/libvirt.h.in 2007-03-01 03:02:50.000000000 +0900 @@ -233,6 +233,7 @@ int virConnectGetVersion (virConnectPt unsigned long *hvVer); int virNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info); +int virGetCpuMax (virConnectPtr conn); /* * Gather list of running domains diff -rup a/src/driver.h b/src/driver.h --- a/src/driver.h 2007-02-23 17:51:30.000000000 +0900 +++ b/src/driver.h 2007-03-01 03:09:32.000000000 +0900 @@ -140,6 +140,8 @@ typedef int typedef int (*virDrvDomainSetAutostart) (virDomainPtr domain, int autostart); +typedef int + (*virDrvGetCpuMax) (void); typedef struct _virDriver virDriver; typedef virDriver *virDriverPtr; @@ -191,6 +193,7 @@ struct _virDriver { virDrvDomainDetachDevice domainDetachDevice; virDrvDomainGetAutostart domainGetAutostart; virDrvDomainSetAutostart domainSetAutostart; + virDrvGetCpuMax cpumax; }; typedef int diff -rup a/src/libvirt.c b/src/libvirt.c --- a/src/libvirt.c 2007-02-23 17:51:30.000000000 +0900 +++ b/src/libvirt.c 2007-03-01 02:16:49.000000000 +0900 @@ -1670,6 +1670,35 @@ virNodeGetInfo(virConnectPtr conn, virNo return(0); } +/** + * virDrvGetCpuMax: + * + * Returns the maximum of CPU defined by Hypervisor. + * + * Returns the maximum of CPU or 0 in case of error. + */ +int +virGetCpuMax(virConnectPtr conn) { + int i; + int ret = -1; + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__); + return (0); + } + + for (i = 0;i < conn->nb_drivers;i++) { + if ((conn->drivers[i] != NULL) && + (conn->drivers[i]->cpumax != NULL)) { + ret = conn->drivers[i]->cpumax(); + if (ret != 0) + return(ret); + } + } + virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__); + return (-1); +} + /************************************************************************ * * * Handling of defined but not running domains * diff -rup a/src/libvirt_sym.version b/src/libvirt_sym.version --- a/src/libvirt_sym.version 2007-02-23 17:51:30.000000000 +0900 +++ b/src/libvirt_sym.version 2007-03-01 02:17:18.000000000 +0900 @@ -52,6 +52,7 @@ virConnResetLastError; virDefaultErrorFunc; virNodeGetInfo; + virGetCpuMax; virDomainSetVcpus; virDomainPinVcpu; diff -rup a/src/proxy_internal.c b/src/proxy_internal.c --- a/src/proxy_internal.c 2007-02-23 17:51:30.000000000 +0900 +++ b/src/proxy_internal.c 2007-03-01 02:17:40.000000000 +0900 @@ -83,6 +83,7 @@ static virDriver xenProxyDriver = { NULL, /* domainDetachDevice */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ + NULL, /* cpumax */ }; /** diff -rup a/src/qemu_internal.c b/src/qemu_internal.c --- a/src/qemu_internal.c 2007-02-23 21:46:35.000000000 +0900 +++ b/src/qemu_internal.c 2007-03-01 02:18:02.000000000 +0900 @@ -1200,6 +1200,7 @@ static virDriver qemuDriver = { NULL, /* domainDetachDevice */ qemuDomainGetAutostart, /* domainGetAutostart */ qemuDomainSetAutostart, /* domainSetAutostart */ + NULL, /* cpumax */ }; static virNetworkDriver qemuNetworkDriver = { diff -rup a/src/test.c b/src/test.c --- a/src/test.c 2007-02-23 17:51:30.000000000 +0900 +++ b/src/test.c 2007-03-01 02:18:53.000000000 +0900 @@ -127,6 +127,7 @@ static virDriver testDriver = { NULL, /* domainDetachDevice */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ + NULL, /* cpumax */ }; typedef struct _testDev { diff -rup a/src/virsh.c b/src/virsh.c --- a/src/virsh.c 2007-02-28 00:35:50.000000000 +0900 +++ b/src/virsh.c 2007-03-01 02:19:59.000000000 +0900 @@ -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 = virGetCpuMax(ctl->conn); + 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; } diff -rup a/src/xend_internal.c b/src/xend_internal.c --- a/src/xend_internal.c 2007-02-28 00:50:03.000000000 +0900 +++ b/src/xend_internal.c 2007-03-01 02:21:34.000000000 +0900 @@ -99,6 +99,7 @@ static virDriver xenDaemonDriver = { xenDaemonDetachDevice, /* domainDetachDevice */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ + NULL, /* cpumax */ }; /** diff -rup a/src/xen_internal.c b/src/xen_internal.c --- a/src/xen_internal.c 2007-02-23 17:51:30.000000000 +0900 +++ b/src/xen_internal.c 2007-02-28 18:06:08.000000000 +0900 @@ -456,6 +456,7 @@ static virDriver xenHypervisorDriver = { NULL, /* domainDetachDevice */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ + xenHypervisorGetCpuMax, /* cpumax */ }; #endif /* !PROXY */ @@ -1824,6 +1825,17 @@ xenHypervisorGetVcpus(virDomainPtr domai } #endif +/** + * xend_get_cpu_max: + * + * Returns the maximum of CPU defined by Xen. + */ +int +xenHypervisorGetCpuMax(void) +{ + return MAX_VIRT_CPUS; +} + /* * Local variables: * indent-tabs-mode: nil diff -rup a/src/xen_internal.h b/src/xen_internal.h --- a/src/xen_internal.h 2006-08-04 19:41:05.000000000 +0900 +++ b/src/xen_internal.h 2007-03-01 02:21:13.000000000 +0900 @@ -55,6 +55,7 @@ int xenHypervisorGetVcpus (virDomainPtr int maxinfo, unsigned char *cpumaps, int maplen); +int xenHypervisorGetCpuMax (void); #ifdef __cplusplus } diff -rup a/src/xm_internal.c b/src/xm_internal.c --- a/src/xm_internal.c 2007-02-23 17:51:30.000000000 +0900 +++ b/src/xm_internal.c 2007-03-01 02:23:54.000000000 +0900 @@ -108,6 +108,7 @@ static virDriver xenXMDriver = { NULL, /* domainDetachDevice */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ + NULL, /* cpumax */ }; static void diff -rup a/src/xs_internal.c b/src/xs_internal.c --- a/src/xs_internal.c 2007-02-23 17:51:30.000000000 +0900 +++ b/src/xs_internal.c 2007-03-01 02:24:20.000000000 +0900 @@ -77,6 +77,7 @@ static virDriver xenStoreDriver = { NULL, /* domainDetachDevice */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ + NULL, /* cpumax */ }; /**