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(a)aa.jp.fujitsu.com>
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 */
};
/**