[libvirt] [RFC][PATCHv1 0/5] libvirt - show per cpu accounting information

2011-04-15 Thread KAMEZAWA Hiroyuki


When running 'virt-top -1' , "show percpu statistics mode", 
virt-top shows a fake value.

When running 'while true; do echo hello;done' on a 4vcpu guest,
==
   00.0
   10.0
   20.0
   30.0
   4   25.0 25.0=
   5   25.0 25.0=#
   6   25.0 25.0=
   7   25.0 25.0=

==

All cpus just used equally ;)

This is because there is no interface to get per-cpu usage of domain.
This patch adds an interface virDomainPcpuStats() to get per-cpu
statistics, cpuTime in nanoseconds.

Here is a test result with a python script using new interface.
==
[root@bluextal python]# ./virt-cpuacct.py
({'cpuTime': 0L}, {'cpuTime': 0L}, {'cpuTime': 0L}, {'cpuTime': 0L}, 
{'cpuTime': 4679204346L}, {'cpuTime': 2103820380L}, {'cpuTime': 8904513019L}, 
{'cpuTime': 7424701195L})
[root@bluextal python]# ./virt-cpuacct.py
({'cpuTime': 0L}, {'cpuTime': 0L}, {'cpuTime': 0L}, {'cpuTime': 0L}, 
{'cpuTime': 57010689139L}, {'cpuTime': 26152907202L}, {'cpuTime': 
53759693931L}, {'cpuTime': 43074348218L})
==

Although I added a new interface, I still wonder what interface is better...
any comments are welcome.

Thanks,
-Kame

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [RFC][PATCHv1 1/5] libvirt - show cpuacct cgroup's percpu statistics.

2011-04-15 Thread KAMEZAWA Hiroyuki

cpuacct cgroup provides per cpu cputime. Add an interface
for that.

Signed-off-by: KAMEZAWA Hiroyuki 
---
 src/libvirt_private.syms |1 +
 src/util/cgroup.c|   27 +++
 src/util/cgroup.h|2 ++
 3 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index ba7739d..f7a1ee7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -70,6 +70,7 @@ virCgroupFree;
 virCgroupGetBlkioWeight;
 virCgroupGetCpuShares;
 virCgroupGetCpuacctUsage;
+virCgroupGetCpuacctUsagePercpu;
 virCgroupGetFreezerState;
 virCgroupGetMemoryHardLimit;
 virCgroupGetMemorySoftLimit;
diff --git a/src/util/cgroup.c b/src/util/cgroup.c
index afe8731..58ea805 100644
--- a/src/util/cgroup.c
+++ b/src/util/cgroup.c
@@ -1329,6 +1329,33 @@ int virCgroupGetCpuacctUsage(virCgroupPtr group, 
unsigned long long *usage)
 "cpuacct.usage", usage);
 }
 
+int virCgroupGetCpuacctUsagePercpu(virCgroupPtr group,
+ int nr, unsigned long long *usage)
+{
+int i, rc;
+char *strval = NULL;
+char *startp, *endp;
+unsigned long long int value;
+
+memset(usage, 0, sizeof(unsigned long long) * nr);
+
+rc = virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPUACCT,
+  "cpuacct.usage_percpu", &strval);
+if (rc)
+goto out;
+
+for (i = 0, startp = strval; i < nr; i++) {
+if (virStrToLong_ull(startp, &endp, 10, &value))
+break;
+startp = endp;
+usage[i] = value;
+}
+rc = i;
+out:
+VIR_FREE(strval);
+return rc;
+}
+
 int virCgroupSetFreezerState(virCgroupPtr group, const char *state)
 {
 return virCgroupSetValueStr(group,
diff --git a/src/util/cgroup.h b/src/util/cgroup.h
index 8ae756d..31cbcba 100644
--- a/src/util/cgroup.h
+++ b/src/util/cgroup.h
@@ -100,6 +100,8 @@ int virCgroupSetCpuShares(virCgroupPtr group, unsigned long 
long shares);
 int virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares);
 
 int virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage);
+int virCgroupGetCpuacctUsagePercpu(virCgroupPtr group,
+   int nr, unsigned long long *usage);
 
 int virCgroupSetFreezerState(virCgroupPtr group, const char *state);
 int virCgroupGetFreezerState(virCgroupPtr group, char **state);
-- 
1.7.4.1


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [RFC][PATCHv1 2/5] libvirt - new API for getting percpu statistics of VM

2011-04-15 Thread KAMEZAWA Hiroyuki
Per (host) cpu activity of VMs are very insterested numbers
when running VMs on large SMPs. virt-top -1 mode tries to
provide the information. (But it's not implemented.)

This patch adds a libvirt interface to get per cpu statistics
of each nodes. This patch just adds an interface and driver
entry points. So,
  - doesn't include patches for python.
  - doesn't include any driver.

Following patches will add some drivers and codes for python.

Signed-off-by: KAMEZAWA Hiroyuki 
---
 include/libvirt/libvirt.h.in |   13 ++
 src/driver.h |6 
 src/esx/esx_driver.c |1 +
 src/libvirt.c|   55 ++
 src/libvirt_public.syms  |4 +++
 src/libxl/libxl_driver.c |1 +
 src/lxc/lxc_driver.c |1 +
 src/openvz/openvz_driver.c   |1 +
 src/phyp/phyp_driver.c   |1 +
 src/qemu/qemu_driver.c   |1 +
 src/remote/remote_driver.c   |1 +
 src/test/test_driver.c   |1 +
 src/uml/uml_driver.c |1 +
 src/vbox/vbox_tmpl.c |1 +
 src/vmware/vmware_driver.c   |1 +
 src/xen/xen_driver.c |1 +
 src/xenapi/xenapi_driver.c   |1 +
 17 files changed, 91 insertions(+), 0 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 5783303..6b9292c 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -400,6 +400,13 @@ struct _virDomainMemoryStat {
 
 typedef virDomainMemoryStatStruct *virDomainMemoryStatPtr;
 
+typedef struct _virDomainPcpuStat virDomainPcpuStatStruct;
+
+struct _virDomainPcpuStat {
+unsigned long long cpuTime;
+};
+
+typedef virDomainPcpuStatStruct *virDomainPcpuStatPtr;
 
 /* Domain core dump flags. */
 typedef enum {
@@ -923,6 +930,12 @@ int virDomainMemoryStats (virDomainPtr 
dom,
   virDomainMemoryStatPtr stats,
   unsigned int nr_stats,
   unsigned int flags);
+
+int virDomainPcpuStats (virDomainPtr dom,
+virDomainPcpuStatPtr stats,
+unsigned int nr_stats,
+unsigned int flags);
+
 int virDomainBlockPeek (virDomainPtr dom,
 const char *path,
 unsigned long long offset,
diff --git a/src/driver.h b/src/driver.h
index a8b79e6..ee1dac7 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -291,6 +291,11 @@ typedef int
 (virDomainPtr domain,
  struct _virDomainMemoryStat *stats,
  unsigned int nr_stats);
+typedef int
+(*virDrvDomainPcpuStats)
+(virDomainPtr domain,
+ struct _virDomainPcpuStat *stats,
+ unsigned int nr_stats);
 
 typedef int
 (*virDrvDomainBlockPeek)
@@ -599,6 +604,7 @@ struct _virDriver {
 virDrvDomainBlockStats  domainBlockStats;
 virDrvDomainInterfaceStats  domainInterfaceStats;
 virDrvDomainMemoryStats domainMemoryStats;
+virDrvDomainPcpuStats   domainPcpuStats;
 virDrvDomainBlockPeek  domainBlockPeek;
 virDrvDomainMemoryPeek  domainMemoryPeek;
 virDrvDomainGetBlockInfodomainGetBlockInfo;
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 50c631b..34a31f0 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -4632,6 +4632,7 @@ static virDriver esxDriver = {
 NULL,/* domainBlockStats */
 NULL,/* domainInterfaceStats */
 NULL,/* domainMemoryStats */
+NULL,/* domainPcpuStats */
 NULL,/* domainBlockPeek */
 NULL,/* domainMemoryPeek */
 NULL,/* domainGetBlockInfo */
diff --git a/src/libvirt.c b/src/libvirt.c
index 0da9885..24ef621 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -4595,6 +4595,61 @@ error:
 }
 
 /**
+ * virDomainPcpuStats:
+ * @dom: pointer to the domain object
+ * @stats: nr_stats-sized array of stat structures (returned)
+ * @nr_stats: number of cpu statistics requested
+ * @flags: unused, always pass 0
+ *
+ * This function provides per-cpu statistics for the domain. 'cpu' here means
+ * not vcpu.
+ *
+ * Up to 'nr_stats' elements of 'stats' will be populated with cpu statistics
+ * from the domain.  Only statistics supported by the domain, the driver, and
+ * this version of libvirt will be returned.
+ *
+ * Now, only cpuTime per cpu is reported in nanoseconds.
+ *
+ * Returns: The number of stats provided or -1 in case of failure.
+ */
+int virDomainPcpuStats (virDomainPtr dom, virDomainPcpuStatPtr stats,
+  

[libvirt] [RFC][PATCHv1 3/5] Add a remote driver for virDomainPcpuStats()

2011-04-15 Thread KAMEZAWA Hiroyuki

Signed-off-by: KAMEZAWA Hiroyuki 
---
 daemon/remote.c |   61 +++
 daemon/remote_dispatch_args.h   |1 +
 daemon/remote_dispatch_prototypes.h |8 
 daemon/remote_dispatch_ret.h|1 +
 daemon/remote_dispatch_table.h  |5 +++
 src/remote/remote_driver.c  |   39 +-
 src/remote/remote_protocol.c|   31 ++
 src/remote/remote_protocol.h|   27 +++
 src/remote/remote_protocol.x|   18 ++-
 9 files changed, 189 insertions(+), 2 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 5de1055..9757f13 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1138,6 +1138,67 @@ remoteDispatchDomainMemoryStats(struct qemud_server 
*server ATTRIBUTE_UNUSED,
 }
 
 static int
+remoteDispatchDomainPcpuStats(struct qemud_server *server ATTRIBUTE_UNUSED,
+  struct qemud_client *client ATTRIBUTE_UNUSED,
+  virConnectPtr conn,
+  remote_message_header *hdr ATTRIBUTE_UNUSED,
+  remote_error *rerr,
+  remote_domain_pcpu_stats_args *args,
+  remote_domain_pcpu_stats_ret *ret)
+{
+virDomainPtr dom;
+struct _virDomainPcpuStat *stats;
+unsigned int nr_stats, i;
+
+if (!conn) {
+remoteDispatchFormatError(rerr, "%s", _("connection not open"));
+return -1;
+}
+
+if (args->nr_stats > REMOTE_DOMAIN_PCPU_STATS_MAX) {
+remoteDispatchFormatError(rerr, "%s",
+   _("nr_stats > REMOTE_DOMAIN_PCPU_STATS_MAX"));
+return -1;
+}
+
+dom = get_nonnull_domain(conn, args->dom);
+if (dom == NULL) {
+remoteDispatchConnError(rerr, conn);
+return -1;
+}
+
+/* Allocate stats array for making dispatch call */
+if (VIR_ALLOC_N(stats, args->nr_stats) < 0) {
+virDomainFree(dom);
+remoteDispatchOOMError(rerr);
+return -1;
+}
+
+nr_stats = virDomainPcpuStats(dom, stats, args->nr_stats, 0);
+if (nr_stats == -1) {
+VIR_FREE(stats);
+remoteDispatchConnError(rerr, conn);
+virDomainFree(dom);
+return -1;
+}
+virDomainFree(dom);
+
+/* Allocate return buffer */
+if (VIR_ALLOC_N(ret->stats.stats_val, nr_stats) < 0) {
+VIR_FREE(stats);
+remoteDispatchOOMError(rerr);
+return -1;
+}
+
+/* Copy the stats into the xdr return structure */
+for (i = 0; i < nr_stats; i++)
+ret->stats.stats_val[i].val = stats[i].cpuTime;
+ret->stats.stats_len = nr_stats;
+VIR_FREE(stats);
+return 0;
+}
+
+static int
 remoteDispatchDomainBlockPeek(struct qemud_server *server ATTRIBUTE_UNUSED,
   struct qemud_client *client ATTRIBUTE_UNUSED,
   virConnectPtr conn,
diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h
index f9537d7..42fc7b2 100644
--- a/daemon/remote_dispatch_args.h
+++ b/daemon/remote_dispatch_args.h
@@ -178,3 +178,4 @@
 remote_domain_migrate_set_max_speed_args 
val_remote_domain_migrate_set_max_speed_args;
 remote_storage_vol_upload_args val_remote_storage_vol_upload_args;
 remote_storage_vol_download_args val_remote_storage_vol_download_args;
+remote_domain_pcpu_stats_args val_remote_domain_pcpu_stats_args;
diff --git a/daemon/remote_dispatch_prototypes.h 
b/daemon/remote_dispatch_prototypes.h
index 18bf41d..5dece04 100644
--- a/daemon/remote_dispatch_prototypes.h
+++ b/daemon/remote_dispatch_prototypes.h
@@ -498,6 +498,14 @@ static int remoteDispatchDomainOpenConsole(
 remote_error *err,
 remote_domain_open_console_args *args,
 void *ret);
+static int remoteDispatchDomainPcpuStats(
+struct qemud_server *server,
+struct qemud_client *client,
+virConnectPtr conn,
+remote_message_header *hdr,
+remote_error *err,
+remote_domain_pcpu_stats_args *args,
+remote_domain_pcpu_stats_ret *ret);
 static int remoteDispatchDomainPinVcpu(
 struct qemud_server *server,
 struct qemud_client *client,
diff --git a/daemon/remote_dispatch_ret.h b/daemon/remote_dispatch_ret.h
index 114e832..4c0b66d 100644
--- a/daemon/remote_dispatch_ret.h
+++ b/daemon/remote_dispatch_ret.h
@@ -140,3 +140,4 @@
 remote_domain_is_updated_ret val_remote_domain_is_updated_ret;
 remote_get_sysinfo_ret val_remote_get_sysinfo_ret;
 remote_domain_get_blkio_parameters_ret 
val_remote_domain_get_blkio_parameters_ret;
+remote_domain_pcpu_stats_ret val_remote_domain_pcpu_stats_ret;
diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h
index b39f7c2..cb1fa05 100644
--- a/daemon/remote_dispatch_table.h
+++ b/daemon/remote_dispatch_table.h
@@ -1052,3 +1052,8 @@
 .args_filter = (xdrproc_t) xdr_remote_storage_vol_download_args,
 .ret_filter = (xdrproc

[libvirt] [RFC][PATCHv1 4/5] Add a python interface for virDomainPcpuStats.

2011-04-15 Thread KAMEZAWA Hiroyuki

Values of all cpus are returned by a tuple of Dict as:

[{cpuTime: }, {cpuTime: }} # when the number of cpu is 2.

Signed-off-by: KAMEZAWA Hiroyuki 
---
 python/generator.py |1 +
 python/libvirt-override-api.xml |5 
 python/libvirt-override.c   |   42 +++
 3 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/python/generator.py b/python/generator.py
index 4fa4f65..d2695bb 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -307,6 +307,7 @@ skip_impl = (
 'virDomainBlockStats',
 'virDomainInterfaceStats',
 'virDomainMemoryStats',
+'virDomainPcpuStats',
 'virNodeGetCellsFreeMemory',
 'virDomainGetSchedulerType',
 'virDomainGetSchedulerParameters',
diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
index 54deeb5..5ee3881 100644
--- a/python/libvirt-override-api.xml
+++ b/python/libvirt-override-api.xml
@@ -127,6 +127,11 @@
   
   
 
+
+  Extracts per cpu statistics for a domain 
+  
+  
+
 
   Returns the available memory for a list of cells
   
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 4a9b432..c2ff0aa 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -164,6 +164,47 @@ libvirt_virDomainMemoryStats(PyObject *self 
ATTRIBUTE_UNUSED, PyObject *args) {
 return info;
 }
 
+static PyObject*
+libvirt_virDomainPcpuStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+virDomainPtr domain;
+virNodeInfo nodeinfo;
+PyObject *pyobj_domain;
+PyObject *info, *info2;
+int nr_stats, i_retval, i;
+virDomainPcpuStatPtr stats;
+
+if (!PyArg_ParseTuple(args, (char *)"O:virDomainPcpuStats", &pyobj_domain))
+return (NULL);
+
+domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+LIBVIRT_BEGIN_ALLOW_THREADS;
+i_retval = virNodeGetInfo(virDomainGetConnect(domain), &nodeinfo);
+LIBVIRT_END_ALLOW_THREADS;
+if (i_retval < 0)
+return VIR_PY_NONE;
+
+stats = malloc(sizeof(struct _virDomainPcpuStat) * nodeinfo.cpus);
+
+nr_stats = virDomainPcpuStats(domain, stats, nodeinfo.cpus, 0);
+
+if (nr_stats == -1)
+return VIR_PY_NONE;
+
+if ((info = PyTuple_New(nodeinfo.cpus)) == NULL)
+return VIR_PY_NONE;
+
+for (i = 0; i < nr_stats; i++) {
+if ((info2 = PyDict_New()) == NULL)
+return VIR_PY_NONE;
+PyDict_SetItem(info2, libvirt_constcharPtrWrap("cpuTime"),
+  PyLong_FromLongLong(stats[i].cpuTime));
+PyTuple_SetItem(info, i, info2);
+}
+return (info);
+}
+
+
 static PyObject *
 libvirt_virDomainGetSchedulerType(PyObject *self ATTRIBUTE_UNUSED,
   PyObject *args) {
@@ -3545,6 +3586,7 @@ static PyMethodDef libvirtMethods[] = {
 {(char *) "virDomainBlockStats", libvirt_virDomainBlockStats, 
METH_VARARGS, NULL},
 {(char *) "virDomainInterfaceStats", libvirt_virDomainInterfaceStats, 
METH_VARARGS, NULL},
 {(char *) "virDomainMemoryStats", libvirt_virDomainMemoryStats, 
METH_VARARGS, NULL},
+{(char *) "virDomainPcpuStats", libvirt_virDomainPcpuStats, METH_VARARGS, 
NULL},
 {(char *) "virNodeGetCellsFreeMemory", libvirt_virNodeGetCellsFreeMemory, 
METH_VARARGS, NULL},
 {(char *) "virDomainGetSchedulerType", libvirt_virDomainGetSchedulerType, 
METH_VARARGS, NULL},
 {(char *) "virDomainGetSchedulerParameters", 
libvirt_virDomainGetSchedulerParameters, METH_VARARGS, NULL},
-- 
1.7.4.1


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [RFC][PATCHv1 5/5] Add a qemu driver for virDomainPcpuStats()

2011-04-15 Thread KAMEZAWA Hiroyuki


Signed-off-by: KAMEZAWA Hiroyuki 
---
 src/qemu/qemu_conf.c   |1 +
 src/qemu/qemu_driver.c |   71 +++-
 2 files changed, 71 insertions(+), 1 deletions(-)

diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index bb5421b..89c5b4c 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -302,6 +302,7 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
 } else {
 driver->cgroupControllers =
 (1 << VIR_CGROUP_CONTROLLER_CPU) |
+(1 << VIR_CGROUP_CONTROLLER_CPUACCT) |
 (1 << VIR_CGROUP_CONTROLLER_DEVICES) |
 (1 << VIR_CGROUP_CONTROLLER_MEMORY) |
 (1 << VIR_CGROUP_CONTROLLER_BLKIO);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0a78a70..6db4f8a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5011,6 +5011,75 @@ cleanup:
 }
 
 static int
+qemuDomainPcpuStats (virDomainPtr dom,
+  struct _virDomainPcpuStat *stats,
+  unsigned int nr_stats)
+{
+struct qemud_driver *driver = dom->conn->privateData;
+virDomainObjPtr vm = NULL;
+virCgroupPtr group = NULL;
+int ret = -1;
+unsigned long long *array = NULL;
+int i;
+
+
+qemuDriverLock(driver);
+if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUACCT)) {
+qemuDriverUnlock(driver);
+qemuReportError(VIR_ERR_OPERATION_INVALID,
+"%s", _("cgroup CPUACCT controller is not mounted"));
+goto cleanup;
+}
+
+vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+qemuDriverUnlock(driver);
+
+if (!vm) {
+char uuidstr[VIR_UUID_STRING_BUFLEN];
+virUUIDFormat(dom->uuid, uuidstr);
+qemuReportError(VIR_ERR_NO_DOMAIN,
+_("no domain with matching uuid '%s'"), uuidstr);
+goto cleanup;
+}
+
+if (VIR_ALLOC_N(array, nr_stats) < 0) {
+virReportOOMError();
+goto cleanup;
+}
+
+if (!virDomainObjIsActive(vm)) {
+qemuReportError(VIR_ERR_OPERATION_INVALID,
+"%s", _("domain is not running"));
+goto cleanup;
+}
+
+if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
+qemuReportError(VIR_ERR_INTERNAL_ERROR,
+_("cannot find cgroup for domain %s"), vm->def->name);
+goto cleanup;
+}
+
+ret = virCgroupGetCpuacctUsagePercpu(group, nr_stats, array);
+if (ret <= 0) {
+ret = -1;
+goto cleanup;
+}
+
+for (i = 0; i < ret; i++)
+   stats[i].cpuTime = array[i];
+
+cleanup:
+if (group)
+virCgroupFree(&group);
+VIR_FREE(array);
+if (vm)
+virDomainObjUnlock(vm);
+return ret;
+}
+
+
+
+static int
 qemudDomainBlockPeek (virDomainPtr dom,
   const char *path,
   unsigned long long offset, size_t size,
@@ -6981,7 +7050,7 @@ static virDriver qemuDriver = {
 qemudDomainBlockStats, /* domainBlockStats */
 qemudDomainInterfaceStats, /* domainInterfaceStats */
 qemudDomainMemoryStats, /* domainMemoryStats */
-NULL, /* domainPcpuStats */
+qemuDomainPcpuStats, /* domainPcpuStats */
 qemudDomainBlockPeek, /* domainBlockPeek */
 qemudDomainMemoryPeek, /* domainMemoryPeek */
 qemuDomainGetBlockInfo, /* domainGetBlockInfo */
-- 
1.7.4.1


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 7/8] schedinfo: Support new API for lxc driver

2011-04-15 Thread Osier Yang
---
 src/lxc/lxc_driver.c |   41 -
 1 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 72c0a0a..5db1035 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -2244,21 +2244,28 @@ static char *lxcGetSchedulerType(virDomainPtr domain 
ATTRIBUTE_UNUSED,
 return schedulerType;
 }
 
-static int lxcSetSchedulerParameters(virDomainPtr domain,
- virSchedParameterPtr params,
- int nparams)
+static int lxcSetSchedulerParametersFlags(virDomainPtr domain,
+  virSchedParameterPtr params,
+  int nparams,
+  unsigned int flags)
 {
 lxc_driver_t *driver = domain->conn->privateData;
 int i;
 virCgroupPtr group = NULL;
 virDomainObjPtr vm = NULL;
+virDomainDefPtr persistentDef = NULL;
 int ret = -1;
+bool isActive;
+
+virCheckFlags(VIR_DOMAIN_SCHED_PARAMS_LIVE |
+  VIR_DOMAIN_SCHED_PARAMS_PERSISTENT, -1);
 
 if (driver->cgroup == NULL)
 return -1;
 
 lxcDriverLock(driver);
 vm = virDomainFindByUUID(&driver->domains, domain->uuid);
+lxcDriverUnlock(driver);
 
 if (vm == NULL) {
 char uuidstr[VIR_UUID_STRING_BUFLEN];
@@ -2268,9 +2275,20 @@ static int lxcSetSchedulerParameters(virDomainPtr domain,
 goto cleanup;
 }
 
+/* Could find cgroup for domain implies the domain is running. */
 if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0)
 goto cleanup;
 
+if (flags & VIR_DOMAIN_SCHED_PARAMS_PERSISTENT) {
+if (!vm->persistent) {
+lxcError(VIR_ERR_OPERATION_INVALID, "%s",
+_("cannot change persistent config of a transient 
domain"));
+goto cleanup;
+}
+if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm)))
+goto cleanup;
+}
+
 for (i = 0; i < nparams; i++) {
 virSchedParameterPtr param = ¶ms[i];
 
@@ -2294,17 +2312,30 @@ static int lxcSetSchedulerParameters(virDomainPtr 
domain,
 }
 
 vm->def->cputune.shares = params[i].value.ul;
+
+if (flags & VIR_DOMAIN_SCHED_PARAMS_PERSISTENT) {
+persistentDef->cputune.shares = params[i].value.ul;
+ret = virDomainSaveConfig(driver->configDir, persistentDef);
+goto cleanup;
+}
 }
 ret = 0;
 
 cleanup:
-lxcDriverUnlock(driver);
 virCgroupFree(&group);
 if (vm)
 virDomainObjUnlock(vm);
 return ret;
 }
 
+static int lxcSetSchedulerParameters(virDomainPtr domain,
+ virSchedParameterPtr params,
+ int nparams)
+{
+return lxcSetSchedulerParametersFlags(domain, params, nparams,
+  VIR_DOMAIN_SCHED_PARAMS_LIVE);
+}
+
 static int lxcGetSchedulerParameters(virDomainPtr domain,
  virSchedParameterPtr params,
  int *nparams)
@@ -2860,7 +2891,7 @@ static virDriver lxcDriver = {
 lxcGetSchedulerType, /* domainGetSchedulerType */
 lxcGetSchedulerParameters, /* domainGetSchedulerParameters */
 lxcSetSchedulerParameters, /* domainSetSchedulerParameters */
-NULL, /* domainSetSchedulerParametersFlags */
+lxcSetSchedulerParametersFlags, /* domainSetSchedulerParametersFlags */
 NULL, /* domainMigratePrepare */
 NULL, /* domainMigratePerform */
 NULL, /* domainMigrateFinish */
-- 
1.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [RFC] Support changing scheduler setting persistently

2011-04-15 Thread Osier Yang
This patch series introduce a new API virDomainSetSchedulerParametersFlags
to change the scheduler setting persistently.

The new API accepts two flags, VIR_DOMAIN_SCHED_PARAMS_LIVE and
VIR_DOMAIN_SCHED_PARAMS_PERSISTENT, "LIVE" flag affects the running domain
config, "PERSISTENT" affects both the running and persistent domain config,
both flags require the domain is running. "LIVE" flags is used by default.

It's not like "setvcpus", which accepts "--live", "--config", and "--current"
flags, as scheduler setting relates with cgroup (QEMU/LXC), upper layer apps
probably need to use virDomainGetSchedulerParameter and 
virDomainSetSchedulerParametersFlags
together, such as virsh, virDomainGetSchedulerParameter looks up parameters,
so support changing the scheduler setting on inactive domain probably is not
good idea.

Regards
Osier

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 1/8] schedinfo: Define new API virDomainSetSchedulerParametersFlags

2011-04-15 Thread Osier Yang
Flags may include VIR_DOMAIN_SCHED_PARAMS_LIVE and
VIR_DOMAIN_SCHED_PARAMS_PERSISTENT, the first one means changing
the domain scheduler setting only for running domain config, and
the later one means changing both the running and persistent domain
config.

Both flags require domain is running, VIR_DOMAIN_SCHED_PARAMS_LIVE
is used by default.
---
 include/libvirt/libvirt.h.in |   14 ++
 src/libvirt_public.syms  |5 +
 2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 04b7fbf..c87608c 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -280,6 +280,13 @@ struct _virSchedParameter {
 
 typedef virSchedParameter *virSchedParameterPtr;
 
+/* Domain scheduler parameters setting flags. */
+typedef enum {
+/* Both these two flags works on running domain. */
+VIR_DOMAIN_SCHED_PARAMS_LIVE= (1 << 0), /* Affects active domain 
config */
+VIR_DOMAIN_SCHED_PARAMS_PERSISTENT  = (1 << 1), /* Affects both active and 
persistent domain config. */
+} virDomainSchedParametersFlags;
+
 /*
  * Fetch scheduler parameters, caller allocates 'params' field of size 
'nparams'
  */
@@ -293,6 +300,13 @@ int virDomainGetSchedulerParameters (virDomainPtr 
domain,
 int virDomainSetSchedulerParameters (virDomainPtr domain,
  virSchedParameterPtr params,
  int nparams);
+/*
+ * Change scheduler parameters according to flags.
+ */
+int virDomainSetSchedulerParametersFlags (virDomainPtr domain,
+  virSchedParameterPtr params,
+  int nparams,
+  unsigned int flags);
 
 /**
  * virDomainBlockStats:
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index b4aed41..03d08f1 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -436,4 +436,9 @@ LIBVIRT_0.9.0 {
 virStorageVolUpload;
 } LIBVIRT_0.8.8;
 
+LIBVIRT_0.9.1 {
+global:
+virDomainSetSchedulerParametersFlags;
+} LIBVIRT_0.9.0;
+
 #  define new API here using predicted next version number 
-- 
1.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 3/8] schedinfo: Implemente the public API

2011-04-15 Thread Osier Yang
---
 src/libvirt.c |   60 +
 1 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/src/libvirt.c b/src/libvirt.c
index 0da9885..fae83fe 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -4401,6 +4401,66 @@ error:
 return -1;
 }
 
+/**
+ * virDomainSetSchedulerParameters:
+ * @domain: pointer to domain object
+ * @params: pointer to scheduler parameter objects
+ * @nparams: number of scheduler parameter
+ *  (this value should be same or less than the returned value
+ *   nparams of virDomainGetSchedulerType)
+ * @flags: an OR'ed set of virDomainMemoryModFlags
+ *
+ * Change the scheduler parameters according to the specified flags
+ *
+ * @flags may include VIR_DOMAIN_SCHED_PARAMS_LIVE or
+ * VIR_DOMAIN_SCHED_PARAMS_CONFIG, both flags may be set, and both flags
+ * requires the domain is running.
+ * If VIR_DOMAIN_SCHED_PARAMS_LIVE is set, the change affects a running
+ * domain and will fail if the domain is not active.
+ * If VIR_DOMAIN_SCHED_PARAMS_CONFIG is set, the change affects both the
+ * running and persistent domain config, and will fail for transient
+ * domains or the domain is not active.
+
+ * Returns -1 in case of error, 0 in case of success.
+ */
+int
+virDomainSetSchedulerParametersFlags(virDomainPtr domain,
+ virSchedParameterPtr params,
+ int nparams,
+ unsigned int flags)
+{
+virConnectPtr conn;
+
+VIR_DOMAIN_DEBUG(domain, "params=%p, nparams=%d", params, nparams);
+
+virResetLastError();
+
+if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+virDispatchError(NULL);
+return -1;
+}
+if (domain->conn->flags & VIR_CONNECT_RO) {
+virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+goto error;
+}
+conn = domain->conn;
+
+if (conn->driver->domainSetSchedulerParametersFlags) {
+int ret;
+ret = conn->driver->domainSetSchedulerParametersFlags (domain, params, 
nparams, flags);
+if (ret < 0)
+goto error;
+return ret;
+}
+
+virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+virDispatchError(domain->conn);
+return -1;
+}
+
 
 /**
  * virDomainBlockStats:
-- 
1.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 8/8] schedinfo: Modify schedinfo command to accepts flags

2011-04-15 Thread Osier Yang
---
 tools/virsh.c   |   26 +++---
 tools/virsh.pod |8 +++-
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index 2e35021..e6e80b5 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1598,6 +1598,8 @@ static const vshCmdOptDef opts_schedinfo[] = {
 {"set", VSH_OT_STRING, VSH_OFLAG_NONE, N_("parameter=value")},
 {"weight", VSH_OT_INT, VSH_OFLAG_NONE, N_("weight for XEN_CREDIT")},
 {"cap", VSH_OT_INT, VSH_OFLAG_NONE, N_("cap for XEN_CREDIT")},
+{"live", VSH_OT_BOOL, 0, N_("affect running domain")},
+{"persistent", VSH_OT_BOOL, 0, N_("affect both running domain and next 
boot")},
 {NULL, 0, 0, NULL}
 };
 
@@ -1705,6 +1707,18 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
 int update = 0;
 int i, ret;
 int ret_val = FALSE;
+int live = vshCommandOptBool(cmd, "live");
+int persistent = vshCommandOptBool(cmd, "persistent");
+int flags = 0;
+
+if (live)
+flags |= VIR_DOMAIN_SCHED_PARAMS_LIVE;
+if (persistent)
+flags |= VIR_DOMAIN_SCHED_PARAMS_PERSISTENT;
+
+/* neither option is specified */
+if (!live && !persistent)
+flags = -1;
 
 if (!vshConnectionUsability(ctl, ctl->conn))
 return FALSE;
@@ -1714,9 +1728,10 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
 
 /* Print SchedulerType */
 schedulertype = virDomainGetSchedulerType(dom, &nparams);
-if (schedulertype!= NULL){
+
+if (schedulertype != NULL){
 vshPrint(ctl, "%-15s: %s\n", _("Scheduler"),
- schedulertype);
+ schedulertype);
 VIR_FREE(schedulertype);
 } else {
 vshPrint(ctl, "%-15s: %s\n", _("Scheduler"), _("Unknown"));
@@ -1743,7 +1758,12 @@ cmdSchedinfo(vshControl *ctl, const vshCmd *cmd)
 
 /* Update parameters & refresh data */
 if (update) {
-ret = virDomainSetSchedulerParameters(dom, params, nparams);
+if (flags == -1)
+ret = virDomainSetSchedulerParameters(dom, params, nparams);
+else {
+ret = virDomainSetSchedulerParametersFlags(dom, params, 
nparams, flags);
+}
+
 if (ret == -1)
 goto cleanup;
 
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 2a708f6..8c1005b 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -567,7 +567,8 @@ severed upon restore, as TCP timeouts may have expired.
 
 =item B optional I<--set> B I
 
-=item B optional I<--weight> B optional I<--cap> B 
I
+=item B optional I<--weight> B optional I<--cap> B
+I I<--live> I<--persistent>
 
 Allows you to show (and set) the domain scheduler parameters. The parameters 
available for each hypervisor are:
 
@@ -577,6 +578,11 @@ Xen (credit scheduler): weight, cap
 
 ESX (allocation scheduler): reservation, limit, shares
 
+Both I<--live> and I<--persistent> may be set, and both of them requires the 
domain
+is running, I<--live> affects the running domain and fails if the domain is not
+active. I<--persistent> affects both the active and persistent domain config, 
and
+fails if the domain is transient or not active. I<--live> is the default flag.
+
 B: The cpu_shares parameter has a valid value range of 0-262144; Negative
 values are wrapped to positive, and larger values are capped at the maximum.
 Therefore, -1 is a useful shorthand for 262144.
-- 
1.7.4

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 4/8] schedinfo: Expose the new public API for Python binding

2011-04-15 Thread Osier Yang
---
 python/generator.py |1 +
 python/libvirt-override-api.xml |7 +++
 python/libvirt-override.c   |   95 +++
 3 files changed, 103 insertions(+), 0 deletions(-)

diff --git a/python/generator.py b/python/generator.py
index 4fa4f65..a44a4d0 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -311,6 +311,7 @@ skip_impl = (
 'virDomainGetSchedulerType',
 'virDomainGetSchedulerParameters',
 'virDomainSetSchedulerParameters',
+'virDomainSetSchedulerParametersFlags',
 'virDomainSetBlkioParameters',
 'virDomainGetBlkioParameters',
 'virDomainSetMemoryParameters',
diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
index 54deeb5..490217b 100644
--- a/python/libvirt-override-api.xml
+++ b/python/libvirt-override-api.xml
@@ -162,6 +162,13 @@
   
   
 
+
+  Change the scheduler parameters according to flags
+  
+  
+  
+  
+
 
   Change the blkio tunables
   
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 4a9b432..35e823c 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -371,7 +371,101 @@ libvirt_virDomainSetSchedulerParameters(PyObject *self 
ATTRIBUTE_UNUSED,
 return VIR_PY_INT_SUCCESS;
 }
 
+static PyObject *
+libvirt_virDomainSetSchedulerParametersFlags(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args) {
+virDomainPtr domain;
+PyObject *pyobj_domain, *info;
+char *c_retval;
+int i_retval;
+int nparams, i;
+virSchedParameterPtr params;
+unsigned int flags;
+
+if (!PyArg_ParseTuple(args, (char *)"OO:virDomainSetScedulerParameters",
+  &pyobj_domain, &info, &flags))
+return(NULL);
+domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+LIBVIRT_BEGIN_ALLOW_THREADS;
+c_retval = virDomainGetSchedulerType(domain, &nparams);
+LIBVIRT_END_ALLOW_THREADS;
+
+if (c_retval == NULL)
+return VIR_PY_INT_FAIL;
+free(c_retval);
+
+if ((params = malloc(sizeof(*params)*nparams)) == NULL)
+return VIR_PY_INT_FAIL;
+
+LIBVIRT_BEGIN_ALLOW_THREADS;
+i_retval = virDomainGetSchedulerParameters(domain, params, &nparams);
+LIBVIRT_END_ALLOW_THREADS;
+
+if (i_retval < 0) {
+free(params);
+return VIR_PY_INT_FAIL;
+}
+
+/* convert to a Python tuple of long objects */
+for (i = 0 ; i < nparams ; i++) {
+PyObject *key, *val;
+key = libvirt_constcharPtrWrap(params[i].field);
+val = PyDict_GetItem(info, key);
+Py_DECREF(key);
+
+if (val == NULL)
+continue;
+
+switch (params[i].type) {
+case VIR_DOMAIN_SCHED_FIELD_INT:
+params[i].value.i = (int)PyInt_AS_LONG(val);
+break;
+
+case VIR_DOMAIN_SCHED_FIELD_UINT:
+params[i].value.ui = (unsigned int)PyInt_AS_LONG(val);
+break;
 
+case VIR_DOMAIN_SCHED_FIELD_LLONG:
+params[i].value.l = (long long)PyLong_AsLongLong(val);
+break;
+
+case VIR_DOMAIN_SCHED_FIELD_ULLONG:
+params[i].value.ul = (unsigned long long)PyLong_AsLongLong(val);
+break;
+
+case VIR_DOMAIN_SCHED_FIELD_DOUBLE:
+params[i].value.d = (double)PyFloat_AsDouble(val);
+break;
+
+case VIR_DOMAIN_SCHED_FIELD_BOOLEAN:
+{
+/* Hack - Python's definition of Py_True breaks strict
+ * aliasing rules, so can't directly compare :-(
+ */
+PyObject *hacktrue = PyBool_FromLong(1);
+params[i].value.b = hacktrue == val ? 1 : 0;
+Py_DECREF(hacktrue);
+}
+break;
+
+default:
+free(params);
+return VIR_PY_INT_FAIL;
+}
+}
+
+LIBVIRT_BEGIN_ALLOW_THREADS;
+i_retval = virDomainSetSchedulerParametersFlags(domain, params, nparams, 
flags);
+LIBVIRT_END_ALLOW_THREADS;
+if (i_retval < 0) {
+free(params);
+return VIR_PY_INT_FAIL;
+}
+
+free(params);
+return VIR_PY_INT_SUCCESS;
+}
 
 
 /* FIXME: This is a place holder for the implementation. */
@@ -3549,6 +3643,7 @@ static PyMethodDef libvirtMethods[] = {
 {(char *) "virDomainGetSchedulerType", libvirt_virDomainGetSchedulerType, 
METH_VARARGS, NULL},
 {(char *) "virDomainGetSchedulerParameters", 
libvirt_virDomainGetSchedulerParameters, METH_VARARGS, NULL},
 {(char *) "virDomainSetSchedulerParameters", 
libvirt_virDomainSetSchedulerParameters, METH_VARARGS, NULL},
+{(char *) "virDomainSetSchedulerParametersFlags", 
libvirt_virDomainSetSchedulerParametersFlags, METH_VARARGS, NULL},
 {(char *) "virDomainSetBlkioParameters", 
libvirt_virDomainSetBlkioParameters, METH_VARARGS, NULL},
 {(char *) "virDomainGetBlkioParameters", 
libvirt_virDoma

[libvirt] [PATCH 2/8] schedinfo: Define the internal API

2011-04-15 Thread Osier Yang
---
 src/driver.h   |8 
 src/esx/esx_driver.c   |1 +
 src/libxl/libxl_driver.c   |1 +
 src/lxc/lxc_driver.c   |1 +
 src/openvz/openvz_driver.c |1 +
 src/phyp/phyp_driver.c |1 +
 src/qemu/qemu_driver.c |1 +
 src/remote/remote_driver.c |6 --
 src/test/test_driver.c |1 +
 src/uml/uml_driver.c   |1 +
 src/vbox/vbox_tmpl.c   |1 +
 src/vmware/vmware_driver.c |1 +
 src/xen/xen_driver.c   |1 +
 src/xenapi/xenapi_driver.c |1 +
 14 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/driver.h b/src/driver.h
index e5f91ca..55ffab2 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -276,6 +276,13 @@ typedef int
  int nparams);
 
 typedef int
+(*virDrvDomainSetSchedulerParametersFlags)
+ (virDomainPtr domain,
+ virSchedParameterPtr params,
+ int nparams,
+ unsigned int flags);
+
+typedef int
 (*virDrvDomainBlockStats)
 (virDomainPtr domain,
  const char *path,
@@ -593,6 +600,7 @@ struct _virDriver {
 virDrvDomainGetSchedulerType   domainGetSchedulerType;
 virDrvDomainGetSchedulerParameters domainGetSchedulerParameters;
 virDrvDomainSetSchedulerParameters domainSetSchedulerParameters;
+virDrvDomainSetSchedulerParametersFlags
domainSetSchedulerParametersFlags;
 virDrvDomainMigratePrepare domainMigratePrepare;
 virDrvDomainMigratePerform domainMigratePerform;
 virDrvDomainMigrateFinish  domainMigrateFinish;
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index deda372..5c7bd80 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -4629,6 +4629,7 @@ static virDriver esxDriver = {
 esxDomainGetSchedulerType,   /* domainGetSchedulerType */
 esxDomainGetSchedulerParameters, /* domainGetSchedulerParameters */
 esxDomainSetSchedulerParameters, /* domainSetSchedulerParameters */
+NULL,/* domainSetSchedulerParametersFlags */
 esxDomainMigratePrepare, /* domainMigratePrepare */
 esxDomainMigratePerform, /* domainMigratePerform */
 esxDomainMigrateFinish,  /* domainMigrateFinish */
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 3040914..ef3ea46 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -2617,6 +2617,7 @@ static virDriver libxlDriver = {
 libxlDomainGetSchedulerType,/* domainGetSchedulerType */
 libxlDomainGetSchedulerParameters,/* domainGetSchedulerParameters */
 libxlDomainSetSchedulerParameters,/* domainSetSchedulerParameters */
+NULL/* domainSetSchedulerParametersFlags */
 NULL,   /* domainMigratePrepare */
 NULL,   /* domainMigratePerform */
 NULL,   /* domainMigrateFinish */
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index e905302..72c0a0a 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -2860,6 +2860,7 @@ static virDriver lxcDriver = {
 lxcGetSchedulerType, /* domainGetSchedulerType */
 lxcGetSchedulerParameters, /* domainGetSchedulerParameters */
 lxcSetSchedulerParameters, /* domainSetSchedulerParameters */
+NULL, /* domainSetSchedulerParametersFlags */
 NULL, /* domainMigratePrepare */
 NULL, /* domainMigratePerform */
 NULL, /* domainMigrateFinish */
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index 4af28e9..d3d3365 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -1621,6 +1621,7 @@ static virDriver openvzDriver = {
 NULL, /* domainGetSchedulerType */
 NULL, /* domainGetSchedulerParameters */
 NULL, /* domainSetSchedulerParameters */
+NULL, /* domainSetSchedulerParametersFlags */
 NULL, /* domainMigratePrepare */
 NULL, /* domainMigratePerform */
 NULL, /* domainMigrateFinish */
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index ddbc103..dd90fca 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -4026,6 +4026,7 @@ static virDriver phypDriver = {
 NULL,   /* domainGetSchedulerType */
 NULL,   /* domainGetSchedulerParameters */
 NULL,   /* domainSetSchedulerParameters */
+NULL,   /* domainSetSchedulerParametersFlags */
 NULL,   /* domainMigratePrepare */
 NULL,   /* domainMigratePerform */
 NULL,   /* domainMigrateFinish */
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 04a5f65..f06dcea 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6924,6 +6924,7 @@ static virDriver qemuDriver = {
   

[libvirt] [PATCH 5/8] schedinfo: Implemente the remote protocol

2011-04-15 Thread Osier Yang
---
 daemon/remote.c |   71 
 daemon/remote_dispatch_args.h   |1 +
 daemon/remote_dispatch_prototypes.h |8 
 daemon/remote_dispatch_table.h  |5 ++
 src/remote/remote_driver.c  |   77 +--
 src/remote/remote_protocol.c|   15 +++
 src/remote/remote_protocol.h|   13 ++
 src/remote/remote_protocol.x|9 -
 8 files changed, 194 insertions(+), 5 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index dd85ef1..3ad116b 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -921,6 +921,77 @@ remoteDispatchDomainSetSchedulerParameters (struct 
qemud_server *server ATTRIBUT
 }
 
 static int
+remoteDispatchDomainSetSchedulerParametersFlags (struct qemud_server *server 
ATTRIBUTE_UNUSED,
+ struct qemud_client *client 
ATTRIBUTE_UNUSED,
+ virConnectPtr conn,
+ remote_message_header *hdr 
ATTRIBUTE_UNUSED,
+ remote_error *rerr,
+ 
remote_domain_set_scheduler_parameters_flags_args *args,
+ void *ret ATTRIBUTE_UNUSED)
+{
+virDomainPtr dom;
+int i, r, nparams;
+virSchedParameterPtr params;
+unsigned int flags;
+
+nparams = args->params.params_len;
+
+if (nparams > REMOTE_DOMAIN_SCHEDULER_PARAMETERS_MAX) {
+remoteDispatchFormatError (rerr, "%s", _("nparams too large"));
+return -1;
+}
+if (VIR_ALLOC_N(params, nparams) < 0) {
+remoteDispatchOOMError(rerr);
+return -1;
+}
+
+/* Deserialise parameters. */
+for (i = 0; i < nparams; ++i) {
+if (virStrcpyStatic(params[i].field, args->params.params_val[i].field) 
== NULL) {
+remoteDispatchFormatError(rerr, _("Field %s too big for 
destination"),
+  args->params.params_val[i].field);
+return -1;
+}
+params[i].type = args->params.params_val[i].value.type;
+switch (params[i].type) {
+case VIR_DOMAIN_SCHED_FIELD_INT:
+params[i].value.i = 
args->params.params_val[i].value.remote_sched_param_value_u.i; break;
+case VIR_DOMAIN_SCHED_FIELD_UINT:
+params[i].value.ui = 
args->params.params_val[i].value.remote_sched_param_value_u.ui; break;
+case VIR_DOMAIN_SCHED_FIELD_LLONG:
+params[i].value.l = 
args->params.params_val[i].value.remote_sched_param_value_u.l; break;
+case VIR_DOMAIN_SCHED_FIELD_ULLONG:
+params[i].value.ul = 
args->params.params_val[i].value.remote_sched_param_value_u.ul; break;
+case VIR_DOMAIN_SCHED_FIELD_DOUBLE:
+params[i].value.d = 
args->params.params_val[i].value.remote_sched_param_value_u.d; break;
+case VIR_DOMAIN_SCHED_FIELD_BOOLEAN:
+params[i].value.b = 
args->params.params_val[i].value.remote_sched_param_value_u.b; break;
+}
+}
+
+dom = get_nonnull_domain (conn, args->dom);
+if (dom == NULL) {
+VIR_FREE(params);
+remoteDispatchConnError(rerr, conn);
+return -1;
+}
+
+flags = args->flags;
+
+r = virDomainSetSchedulerParametersFlags (dom, params, nparams, flags);
+VIR_FREE(params);
+if (r == -1) {
+remoteDispatchConnError(rerr, conn);
+virDomainFree(dom);
+return -1;
+}
+virDomainFree(dom);
+
+return 0;
+}
+
+
+static int
 remoteDispatchDomainBlockStats (struct qemud_server *server ATTRIBUTE_UNUSED,
 struct qemud_client *client ATTRIBUTE_UNUSED,
 virConnectPtr conn,
diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h
index f9537d7..5cb2572 100644
--- a/daemon/remote_dispatch_args.h
+++ b/daemon/remote_dispatch_args.h
@@ -178,3 +178,4 @@
 remote_domain_migrate_set_max_speed_args 
val_remote_domain_migrate_set_max_speed_args;
 remote_storage_vol_upload_args val_remote_storage_vol_upload_args;
 remote_storage_vol_download_args val_remote_storage_vol_download_args;
+remote_domain_set_scheduler_parameters_flags_args 
val_remote_domain_set_scheduler_parameters_flags_args;
diff --git a/daemon/remote_dispatch_prototypes.h 
b/daemon/remote_dispatch_prototypes.h
index 18bf41d..8b249ad 100644
--- a/daemon/remote_dispatch_prototypes.h
+++ b/daemon/remote_dispatch_prototypes.h
@@ -602,6 +602,14 @@ static int remoteDispatchDomainSetSchedulerParameters(
 remote_error *err,
 remote_domain_set_scheduler_parameters_args *args,
 void *ret);
+static int remoteDispatchDomainSetSchedulerParametersFlags(
+struct qemud_server *server,
+struct qemud_client *client,
+virConnectPtr conn,
+remote_message_header *hdr,
+remote_error *err,
+  

[libvirt] [PATCH 6/8] schedinfo: Support new API for qemu driver

2011-04-15 Thread Osier Yang
---
 src/qemu/qemu_driver.c |   64 +++-
 1 files changed, 52 insertions(+), 12 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f06dcea..1c71962 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4651,37 +4651,59 @@ cleanup:
 return ret;
 }
 
-static int qemuSetSchedulerParameters(virDomainPtr dom,
-  virSchedParameterPtr params,
-  int nparams)
+static int qemuSetSchedulerParametersFlags(virDomainPtr dom,
+   virSchedParameterPtr params,
+   int nparams,
+   unsigned int flags)
 {
 struct qemud_driver *driver = dom->conn->privateData;
 int i;
 virCgroupPtr group = NULL;
 virDomainObjPtr vm = NULL;
+virDomainDefPtr persistentDef = NULL;
 int ret = -1;
 
-qemuDriverLock(driver);
+virCheckFlags(VIR_DOMAIN_SCHED_PARAMS_LIVE |
+  VIR_DOMAIN_SCHED_PARAMS_PERSISTENT, -1);
+
 if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) {
 qemuReportError(VIR_ERR_OPERATION_INVALID,
 "%s", _("cgroup CPU controller is not mounted"));
 goto cleanup;
 }
 
+qemuDriverLock(driver);
 vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+qemuDriverUnlock(driver);
 
 if (vm == NULL) {
-qemuReportError(VIR_ERR_INTERNAL_ERROR,
-_("No such domain %s"), dom->uuid);
+char uuidstr[VIR_UUID_STRING_BUFLEN];
+virUUIDFormat(dom->uuid, uuidstr);
+qemuReportError(VIR_ERR_NO_DOMAIN,
+_("No domain with uuid: %s"), uuidstr);
 goto cleanup;
 }
 
+/* Could find the cgroup for domain implies the domain is running. */
 if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) {
 qemuReportError(VIR_ERR_INTERNAL_ERROR,
-_("cannot find cgroup for domain %s"), vm->def->name);
+   _("cannot find cgroup for domain %s"), vm->def->name);
 goto cleanup;
 }
 
+if (qemuDomainObjBeginJob(vm) < 0)
+goto cleanup;
+
+if (flags & VIR_DOMAIN_SCHED_PARAMS_PERSISTENT) {
+if (!vm->persistent) {
+qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+_("cannot change persistent config of a transient 
domain"));
+goto endjob;
+}
+if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm)))
+goto endjob;
+}
+
 for (i = 0; i < nparams; i++) {
 virSchedParameterPtr param = ¶ms[i];
 
@@ -4690,25 +4712,35 @@ static int qemuSetSchedulerParameters(virDomainPtr dom,
 if (param->type != VIR_DOMAIN_SCHED_FIELD_ULLONG) {
 qemuReportError(VIR_ERR_INVALID_ARG, "%s",
 _("invalid type for cpu_shares tunable, 
expected a 'ullong'"));
-goto cleanup;
+goto endjob;
 }
 
 rc = virCgroupSetCpuShares(group, params[i].value.ul);
 if (rc != 0) {
 virReportSystemError(-rc, "%s",
- _("unable to set cpu shares tunable"));
-goto cleanup;
+_("unable to set cpu shares tunable"));
+goto endjob;
 }
 
 vm->def->cputune.shares = params[i].value.ul;
+
+if (flags & VIR_DOMAIN_SCHED_PARAMS_PERSISTENT) {
+persistentDef->cputune.shares = params[i].value.ul;
+ret = virDomainSaveConfig(driver->configDir, persistentDef);
+goto endjob;
+}
 } else {
 qemuReportError(VIR_ERR_INVALID_ARG,
 _("Invalid parameter `%s'"), param->field);
-goto cleanup;
+goto endjob;
 }
 }
 ret = 0;
 
+endjob:
+if (qemuDomainObjEndJob(vm) == 0)
+vm = NULL;
+
 cleanup:
 virCgroupFree(&group);
 if (vm)
@@ -4717,6 +4749,14 @@ cleanup:
 return ret;
 }
 
+static int qemuSetSchedulerParameters(virDomainPtr dom,
+  virSchedParameterPtr params,
+  int nparams)
+{
+return qemuSetSchedulerParametersFlags(dom, params, nparams,
+   VIR_DOMAIN_SCHED_PARAMS_LIVE);
+}
+
 static int qemuGetSchedulerParameters(virDomainPtr dom,
   virSchedParameterPtr params,
   int *nparams)
@@ -6924,7 +6964,7 @@ static virDriver qemuDriver = {
 qemuGetSchedulerType, /* domainGetSchedulerType */
 qemuGetSchedulerParameters, /* domainGetSchedulerParameters */
 qemuSetSchedulerParameters, /* domainSetSchedulerParameters *

Re: [libvirt] [RFC][PATCHv1 2/5] libvirt - new API for getting percpu statistics of VM

2011-04-15 Thread Matthias Bolte
2011/4/15 KAMEZAWA Hiroyuki :
> Per (host) cpu activity of VMs are very insterested numbers
> when running VMs on large SMPs. virt-top -1 mode tries to
> provide the information. (But it's not implemented.)
>
> This patch adds a libvirt interface to get per cpu statistics
> of each nodes. This patch just adds an interface and driver
> entry points. So,
>  - doesn't include patches for python.
>  - doesn't include any driver.
>
> Following patches will add some drivers and codes for python.
>
> Signed-off-by: KAMEZAWA Hiroyuki 
> ---
>  include/libvirt/libvirt.h.in |   13 ++
>  src/driver.h                 |    6 
>  src/esx/esx_driver.c         |    1 +
>  src/libvirt.c                |   55 
> ++
>  src/libvirt_public.syms      |    4 +++
>  src/libxl/libxl_driver.c     |    1 +
>  src/lxc/lxc_driver.c         |    1 +
>  src/openvz/openvz_driver.c   |    1 +
>  src/phyp/phyp_driver.c       |    1 +
>  src/qemu/qemu_driver.c       |    1 +
>  src/remote/remote_driver.c   |    1 +
>  src/test/test_driver.c       |    1 +
>  src/uml/uml_driver.c         |    1 +
>  src/vbox/vbox_tmpl.c         |    1 +
>  src/vmware/vmware_driver.c   |    1 +
>  src/xen/xen_driver.c         |    1 +
>  src/xenapi/xenapi_driver.c   |    1 +
>  17 files changed, 91 insertions(+), 0 deletions(-)
>
> diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
> index 5783303..6b9292c 100644
> --- a/include/libvirt/libvirt.h.in
> +++ b/include/libvirt/libvirt.h.in
> @@ -400,6 +400,13 @@ struct _virDomainMemoryStat {
>
>  typedef virDomainMemoryStatStruct *virDomainMemoryStatPtr;
>
> +typedef struct _virDomainPcpuStat virDomainPcpuStatStruct;
> +
> +struct _virDomainPcpuStat {
> +    unsigned long long cpuTime;
> +};
> +

NACK to adding another public struct to the API. It's not expendable.
As a stylistic nit pleas don't use the term PCPU as this looks like
"Physical CPU". Just call it virDomainPerVcpuStat at least.

Also do you really need the absolute CPU time? As noted elsewhere,
this is in fact not implementable for ESX. But ESX can provide the
virtual CPU utilization in MHz and percent.

See the virNodeGetCpuTime series [1] for a better approach.

[1] https://www.redhat.com/archives/libvir-list/2011-April/msg00702.html

Matthias

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [RFC][PATCHv1 2/5] libvirt - new API for getting percpu statistics of VM

2011-04-15 Thread KAMEZAWA Hiroyuki
On Fri, 15 Apr 2011 09:43:15 +0200
Matthias Bolte  wrote:

> 2011/4/15 KAMEZAWA Hiroyuki :
> > Per (host) cpu activity of VMs are very insterested numbers
> > when running VMs on large SMPs. virt-top -1 mode tries to
> > provide the information. (But it's not implemented.)
> >
> > This patch adds a libvirt interface to get per cpu statistics
> > of each nodes. This patch just adds an interface and driver
> > entry points. So,
> >  - doesn't include patches for python.
> >  - doesn't include any driver.
> >
> > Following patches will add some drivers and codes for python.
> >
> > Signed-off-by: KAMEZAWA Hiroyuki 
> > ---
> >  include/libvirt/libvirt.h.in |   13 ++
> >  src/driver.h                 |    6 
> >  src/esx/esx_driver.c         |    1 +
> >  src/libvirt.c                |   55 
> > ++
> >  src/libvirt_public.syms      |    4 +++
> >  src/libxl/libxl_driver.c     |    1 +
> >  src/lxc/lxc_driver.c         |    1 +
> >  src/openvz/openvz_driver.c   |    1 +
> >  src/phyp/phyp_driver.c       |    1 +
> >  src/qemu/qemu_driver.c       |    1 +
> >  src/remote/remote_driver.c   |    1 +
> >  src/test/test_driver.c       |    1 +
> >  src/uml/uml_driver.c         |    1 +
> >  src/vbox/vbox_tmpl.c         |    1 +
> >  src/vmware/vmware_driver.c   |    1 +
> >  src/xen/xen_driver.c         |    1 +
> >  src/xenapi/xenapi_driver.c   |    1 +
> >  17 files changed, 91 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
> > index 5783303..6b9292c 100644
> > --- a/include/libvirt/libvirt.h.in
> > +++ b/include/libvirt/libvirt.h.in
> > @@ -400,6 +400,13 @@ struct _virDomainMemoryStat {
> >
> >  typedef virDomainMemoryStatStruct *virDomainMemoryStatPtr;
> >
> > +typedef struct _virDomainPcpuStat virDomainPcpuStatStruct;
> > +
> > +struct _virDomainPcpuStat {
> > +    unsigned long long cpuTime;
> > +};
> > +
> 
> NACK to adding another public struct to the API. 

Oh, yes. I searched a sutiable existing API but cannot found.

Maybe adding new enum to Usui's work will be good but I need an array.
Hmm, returning an array of unsigned long long is ok ?

> It's not expendable.
> As a stylistic nit pleas don't use the term PCPU as this looks like
> "Physical CPU". Just call it virDomainPerVcpuStat at least.
> 
Ah, no, this is PerPhysicalStat


> Also do you really need the absolute CPU time? 
yes, for virt-top -1.

> As noted elsewhere,
> this is in fact not implementable for ESX. But ESX can provide the
> virtual CPU utilization in MHz and percent.
> 
I need physical cpu utilization by domain.

> See the virNodeGetCpuTime series [1] for a better approach.
> 
> [1] https://www.redhat.com/archives/libvir-list/2011-April/msg00702.html
> 
Thank you.

-Kame

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH] implement BOOT_TIMEOUT

2011-04-15 Thread Alexander Todorov

Hello folks,
here's a second try at this wrt to Eric's comments.
BOOT_TIMEOUT changed to START_DELAY, updated wording in the conf file to better 
reflect what this does and added a flag to skip sleeping for the first ever 
started guest.



---
 tools/libvirt-guests.init.sh |7 +++
 tools/libvirt-guests.sysconf |3 +++
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/tools/libvirt-guests.init.sh b/tools/libvirt-guests.init.sh
index f247e5e..30f957a 100644
--- a/tools/libvirt-guests.init.sh
+++ b/tools/libvirt-guests.init.sh
@@ -42,6 +42,7 @@ URIS=default
 ON_BOOT=start
 ON_SHUTDOWN=suspend
 SHUTDOWN_TIMEOUT=0
+START_DELAY=0

 test -f "$sysconfdir"/sysconfig/libvirt-guests &&
 . "$sysconfdir"/sysconfig/libvirt-guests
@@ -141,6 +142,7 @@ start() {
 return 0
 fi

+isfirst=true
 while read uri list; do
 configured=false
 set -f
@@ -165,6 +167,11 @@ start() {
 if "$guest_running"; then
 gettext "already active"; echo
 else
+if "$isfirst"; then
+isfirst=false
+else
+sleep $START_DELAY
+fi
 retval run_virsh "$uri" start "$name" >/dev/null && \
 gettext "done"; echo
 fi
diff --git a/tools/libvirt-guests.sysconf b/tools/libvirt-guests.sysconf
index cd58728..37b258e 100644
--- a/tools/libvirt-guests.sysconf
+++ b/tools/libvirt-guests.sysconf
@@ -10,6 +10,9 @@
 #   libvirtd
 #ON_BOOT=start

+# number of seconds to wait between each guest start
+#START_DELAY=0
+
 # action taken on host shutdown
 # - suspend   all running guests are suspended using virsh managedsave
 # - shutdown  all running guests are asked to shutdown. Please be careful with


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] esx: Fix gcc 4.6 warning about initialized but unused variables

2011-04-15 Thread Christophe Fergeau
Hi Matthias,

On Thu, Apr 14, 2011 at 07:18:27PM +0200, Matthias Bolte wrote:
> This is a speculative patch as I don't have gcc 4.6 at hand to test it.

I no longer get the warning with this patch applied. At first I was worried
about the use of ATTRIBUTE_UNUSED (I assumed it meant "this var is unused,
feel free to optimize it away"), but gcc documentation indeed says:
"unused
This attribute, attached to a variable, means that the variable is
meant to be possibly unused. GCC will not produce a warning for this
variable."

So this all looks good to me (aka ack from me)

Christophe



pgpZ7yNoe46Ip.pgp
Description: PGP signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] libvirt-guests - order of stopping/starting guests

2011-04-15 Thread Alexander Todorov

Hi all,
on a previous thread [1] Eric Blake mentioned:


Without more code on the libvirt front, I think you're stuck renaming
the guests to enforce naming order (assuming that libvirt even goes by
sorted name order, as opposed to readdir() order where you have no control).


I poked around the code and experimented a little bit and found the following.

* When you first create new guest (or start already created guest) it is 
assigned a sequential ID, name and also UUID. IDs start from 1 and increase as 
long as libvirtd is running.


* When libvirt-guests wants to start/shutdown guests it relies on the file 
/var/lib/libvirt/libvirt-guests. The format of this file is:

URI 

libvirt-guests script will start the guests as written in the file.

* The libvirt-guests file is initially created from the output of `virsh list' 
and `virsh dominfo' (to get the UUID). virsh list will list the guests ordered 
by their ID.


* Order of starting/stopping guests is unreliable.


The only thing that matters wrt start/shutdown order is the guest ID at the time 
when the libvirt-guests file is generated. By default the order is the order in 
which guests were created and it can change if you randomly stop/start guests 
while libvirtd is running . Names or UUIDs don't play here at all.


I'm not exactly sure what IDs are used for but they change every time when a 
guest is stopped/started manually. Which in turn reflects the order in which 
libvirt-guests stops/starts all guests.


Example:
On a freshly installed system I created 5 guests in the following order:
a1, b1, a2, c1, a11. Then I left all guests running.

Upon stop/start of the libvirt-guests service the guests were stoped/started in 
the same order.


Then I stopped libvirt-guests and libvirtd, renamed a1 to c2 and restarted both 
services. c2 was first in the list - name doesn't matter.


virsh list shows IDs are 1 to 5 (c2 = 1).

Then I did: virsh shutdown c2 && virsh start c2. c2 now has id of 6.

Doing service libvirt-guests stop/start again now showed me a different order:
b1, a2, c1, a11, c2


You see how the order in which guests are started/stopped is unreliable. If I 
were to stop c1 while all other guests were running and then start it again 
(e.g. after attaching a new disk image) then it will have the highest ID number 
and will become last in the list used for stopping/starting guests.



I'm not sure if this can easily be fixed or it needs the concept of 
groups/relations implemented.



[1] - https://www.redhat.com/archives/libvir-list/2011-April/msg00789.html

Regards,
Alexander.

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] libvirt 0.9.0 crashes on first start since boot

2011-04-15 Thread Thomas Treutner

Am 14.04.2011 17:34, schrieb Laine Stump:

On 04/14/2011 06:47 AM, Thomas Treutner wrote:

Hi,

I've upgraded to 0.9.0 today on my Debian Squeeze boxes. Everything
went fine, expect on one node (and only on that one, although the
setup is identical), the first start of libvirtd since boot (and
again, only that start) crashes with SEGV.

Here are traces from gdb:

http://pastebin.com/DiZrw0S5
http://pastebin.com/eacJRv07

If I delete the PID-file and start libvirtd again, it works fine. It
doesn't seem to matter when the first start since boot happens, I've
deactivated startup of libvirtd at boot time.

Any ideas or further infos needed?


Aside from Michal's fix to the error *recovery*, the more interesting
question is why this is now failing.

The bits of system log we can see in the pastebin shows that dnsmasq
failed with an exit code of 2. From the manpage, this means:

2 - A problem with network access occurred (address in use, attempt to
use privileged ports without permission).

Do you have a system instance of dnsmasq already running? (perhaps it's
already listening on all interfaces) Can you send the output of "dnsmasq
-v; ps -AlF | grep dnsmasq"?


Indeed:

root@node05:~# dnsmasq -v; ps -AlF | grep dnsmasq
Dnsmasq version 2.55  Copyright (c) 2000-2010 Simon Kelley
Compile time options IPv6 GNU-getopt DBus I18N DHCP TFTP

This software comes with ABSOLUTELY NO WARRANTY.
Dnsmasq is free software, and you are welcome to redistribute it
under the terms of the GNU General Public License, version 2 or 3.
5 S dnsmasq   2647 1  0  80   0 -  5981 -856   3 14:54 ? 
00:00:00 /usr/sbin/dnsmasq -x /var/run/dnsmasq/dnsmasq.pid -u 
dnsmasq -7 /etc/dnsmasq.d,.dpkg-dist,.dpkg-old,.dpkg-new
0 S root  3544  3473  0  80   0 -  2180 -852   3 14:56 pts/0 
   00:00:00 grep dnsmasq


I removed dnsmasq startup from the runlevel, now it works fine. I have 
seen dnsmasq errors for a long time, but I didn't really care too much 
about, as I don't need dnsmasq and the warnings didn't stop libvrit from 
working. I think I'll just deinstall dnsmasq.



Also, does the directory
/usr/local/var/lib/libvirt/dnsmasq exist?


Jep:

# ls /usr/local/var/lib/libvirt/dnsmasq
default.leases


thanks,
-t

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] libvirt 0.9.0 crashes on first start since boot

2011-04-15 Thread Thomas Treutner

Am 14.04.2011 17:34, schrieb Laine Stump:

Do you have a system instance of dnsmasq already running?


PS: It was the only node where dnsmasq was installed, for whatever 
reason. Seems to narrow down the problem pretty good.


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] LPC2011 Virtualization Micro Conf

2011-04-15 Thread Jes Sorensen
Hi,

With the success of last year's Virtualization micro-conference track
at Linux Plumbers 2010, I have accepted to organize a similar track
for Linux Plumbers 2011 in Santa Rosa. Please see the official Linux
Plumbers 2011 website for full details about the conference:
http://www.linuxplumbersconf.org/2011/

The Linux Plumbers 2011 Virtualization track is focusing on general
free software Linux Virtualization. It is not reserved for a specific
hypervisor, but will focus on general virtualization issues and in
particular collaboration amongst projects. This would include KVM,
Xen, QEMU, containers etc.

Deadline:
-
The deadline for submissions is April 30th. Please visit the following
link to submit your proposal:
http://www.linuxplumbersconf.org/2011/ocw/events/LPC2011MC/proposals

Example topics:
---
- Kernel and Hypervisor KVM/QEMU/Xen interaction
- QEMU integration, sharing of code between the different projects
- IO Performance and scalability
- Live Migration
- Managing and supporting enterprise storage
- Support for new hardware features, and/or provide guest access to
  these features.
- Guest agents
- Virtualization management tools, libvirt, etc.
- Desktop integration
- Consumer Electronics device emulation
- Custom platform configuration and coordination with the kernel

Audience:
-
Virtualization hypervisor developers, developers of virtualization
management tools and applications, embedded virtualization developers,
vendors and others.

Best regards,
Jes

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v2] Merge all returns paths from dispatcher into single path

2011-04-15 Thread Eric Blake
On 04/14/2011 07:28 AM, Daniel P. Berrange wrote:
> The dispatcher functions have numerous places where they
> return to the caller. This leads to duplicated cleanup
> code, often resulting in memory leaks. It makes it harder
> to ensure that errors are dispatched before freeing objects,
> which may overwrite the original error.
> 

Rather than review your entire patch again, I just reviewed this interdiff.

You really did get rid of all remoteDispatchOOMError callers; I'd be
fine if you squashed in deleting the declaration from
daemon/dispatch.[ch] as part of this patch, or as a followup.

> diff --git c/daemon/remote.c w/daemon/remote.c
> index 8f4d6a6..a25c095 100644
> --- c/daemon/remote.c
> +++ w/daemon/remote.c
> @@ -912,7 +912,7 @@ remoteDispatchDomainGetSchedulerParameters(struct 
> qemud_server *server ATTRIBUTE
> 
> remote_domain_get_scheduler_parameters_ret *ret)
>  {
>  virDomainPtr dom = NULL;
> -virSchedParameterPtr params;
> +virSchedParameterPtr params = NULL;
>  int i, r, nparams;
>  int rv = -1;
> 
> @@ -927,10 +927,8 @@ remoteDispatchDomainGetSchedulerParameters(struct 
> qemud_server *server ATTRIBUTE
>  virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
>  goto cleanup;
>  }
> -if (VIR_ALLOC_N(params, nparams) < 0) {
> -virReportOOMError();
> -goto cleanup;
> -}
> +if (VIR_ALLOC_N(params, nparams) < 0)
> +goto no_memory;
> 
>  dom = get_nonnull_domain(conn, args->dom);
>  if (dom == NULL) {
> @@ -1002,7 +1000,7 @@ remoteDispatchDomainSetSchedulerParameters(struct 
> qemud_server *server ATTRIBUTE
>  {
>  virDomainPtr dom = NULL;
>  int i, r, nparams;
> -virSchedParameterPtr params;
> +virSchedParameterPtr params = NULL;
>  int rv = -1;
> 
>  if (!conn) {
> @@ -1960,7 +1958,7 @@ remoteDispatchDomainGetSecurityLabel(struct 
> qemud_server *server ATTRIBUTE_UNUSE
>   remote_domain_get_security_label_ret 
> *ret)
>  {
>  virDomainPtr dom = NULL;
> -virSecurityLabelPtr seclabel;
> +virSecurityLabelPtr seclabel = NULL;
>  int rv = -1;
> 
>  if (!conn) {
> @@ -3041,7 +3039,7 @@ remoteDispatchDomainSetMemoryParameters(struct 
> qemud_server *server
>  {
>  virDomainPtr dom = NULL;
>  int i, r, nparams;
> -virMemoryParameterPtr params;
> +virMemoryParameterPtr params = NULL;
>  unsigned int flags;
>  int rv = -1;
> 
> @@ -3142,7 +3140,7 @@ remoteDispatchDomainGetMemoryParameters(struct 
> qemud_server *server
>  * ret)
>  {
>  virDomainPtr dom = NULL;
> -virMemoryParameterPtr params;
> +virMemoryParameterPtr params = NULL;
>  int i, r, nparams;
>  unsigned int flags;
>  int rv = -1;
> @@ -3233,8 +3231,6 @@ remoteDispatchDomainGetMemoryParameters(struct 
> qemud_server *server
>  success:
>  rv = 0;
> 
> -no_memory:
> -virReportOOMError();
>  cleanup:
>  if (rv < 0) {
>  remoteDispatchError(rerr);
> @@ -3246,6 +3242,10 @@ cleanup:
>  virDomainFree(dom);
>  VIR_FREE(params);
>  return rv;
> +
> +no_memory:
> +virReportOOMError();
> +goto cleanup;
>  }

Good, this addresses my review comments.

> 
>  static int
> @@ -3262,7 +3262,7 @@ remoteDispatchDomainSetBlkioParameters(struct 
> qemud_server *server
>  {
>  virDomainPtr dom = NULL;
>  int i, r, nparams;
> -virBlkioParameterPtr params;
> +virBlkioParameterPtr params = NULL;
>  unsigned int flags;
>  int rv = -1;
> 
> @@ -3363,7 +3363,7 @@ remoteDispatchDomainGetBlkioParameters(struct 
> qemud_server *server
>  * ret)
>  {
>  virDomainPtr dom = NULL;
> -virBlkioParameterPtr params;
> +virBlkioParameterPtr params = NULL;
>  int i, r, nparams;
>  unsigned int flags;
>  int rv = -1;
> @@ -4846,9 +4846,8 @@ remoteDispatchAuthSaslInit(struct qemud_server *server,
>  virStrerror(errno, ebuf, sizeof ebuf));
>  goto error;
>  }
> -if ((localAddr = virSocketFormatAddrFull(&sa, true, ";")) == NULL) {
> +if ((localAddr = virSocketFormatAddrFull(&sa, true, ";")) == NULL)
>  goto error;
> -}

Looks like the cleanups from one of your followup patches leaked in here
when you reverted your sasl changes, but no real harm leaving this hunk in.

> 
>  /* Get remote address in form  IPADDR:PORT */
>  sa.len = sizeof(sa.data.stor);
> @@ -4964,7 +4963,7 @@ authfail:
>  error:
>  PROBE(CLIENT_AUTH_FAIL, "fd=%d, auth=%d", client->fd, REMOTE_AUTH_SASL);
>  virMutexUnlock(&client->lock);
> -goto error;
> +return -1;
>  }
> 
> 
> @@ -5126,6 +5125,7 @@ remoteDispatchAuthSaslStart(struct qemud_server *server,
>  if (serverout) {
>  if (VIR_ALLOC_N(ret->data.data_val, serveroutlen) < 0) {
>  virReportOOMError();
> +remoteDispatch

Re: [libvirt] [PATCH V3 2/2] enhance processWatchdogEvent()

2011-04-15 Thread Eric Blake
On 04/14/2011 09:11 PM, Wen Congyang wrote:
> This patch do the following two things:

s/do/does/

> 1. hold an extra reference while handling watchdog event
>If the domain is not persistent, and qemu quits unexpectedly before
>calling processWatchdogEvent(), vm will be freed and the function
>processWatchdogEvent() will be dangerous.
> 
> 2. unlock qemu driver and vm before returning from processWatchdogEvent()
>When the function processWatchdogEvent() failed, we only free wdEvent,
>but forget to unlock qemu driver and vm, free dumpfile.
> 
> 
> ---
>  src/qemu/qemu_driver.c  |   34 ++
>  src/qemu/qemu_process.c |4 
>  2 files changed, 26 insertions(+), 12 deletions(-)

Looks like your v2 caught my review comments correctly.  But I found one
more issue:

> +++ b/src/qemu/qemu_process.c
> @@ -428,6 +428,10 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon 
> ATTRIBUTE_UNUSED,
>  if (VIR_ALLOC(wdEvent) == 0) {
>  wdEvent->action = VIR_DOMAIN_WATCHDOG_ACTION_DUMP;
>  wdEvent->vm = vm;
> +/* Hold an extra reference because we can't allow 'vm' to be
> + * deleted before handling watchdog event is finished.
> + */
> +virDomainObjRef(vm);
>  ignore_value(virThreadPoolSendJob(driver->workerPool, wdEvent));

Now that we have increased the ref count, we should decrease it if we
are unable to send a job to the thread pool.  That is, replace the
ignore_value() with:

if (virThreadPoolSendJob(...) < 0) {
virDomainObjUnref(vm);
VIR_FREE(wdEvent);
}

ACK with that change squashed in.

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH] implement BOOT_TIMEOUT

2011-04-15 Thread Eric Blake
On 04/15/2011 02:57 AM, Alexander Todorov wrote:
> Hello folks,
> here's a second try at this wrt to Eric's comments.
> BOOT_TIMEOUT changed to START_DELAY, updated wording in the conf file to
> better reflect what this does and added a flag to skip sleeping for the
> first ever started guest.
> 
> 
> ---
>  tools/libvirt-guests.init.sh |7 +++
>  tools/libvirt-guests.sysconf |3 +++
>  2 files changed, 10 insertions(+), 0 deletions(-)

Your mailer botched the patch (it used 2 instead of 1 leading space for
each context line), and 'git apply' had a hard time applying it; I had
to redo it by hand.

ACK and pushed.  Thanks for the contribution!  I added you to AUTHORS;
feel free to let me know (off-list if desired) if I need to adjust your
listing.

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] virsh memset

2011-04-15 Thread Eric Blake
On 04/14/2011 06:04 AM, Zvi Dubitzky wrote:
> Hi
> 
> Does anybody know if  'virsh memset' is working ok  with its parameters 
> with the late  libvirt code
> (>= 0.8.8 )?   With what libcgroup version ?

'virsh memset' doesn't depend on cgroups.  It relies on the guest
honoring virtio ballooning requests.  Guests like Fedora are wired to do
this out of the box, but not all guests support it.  I'm not sure
whether the virtio drivers for Windows can do ballooning.  If a guest
can't honor ballooning, then you can't change current memory at runtime;
however, with very recent git (0.9.1), 'virsh memset --persistent' can
be used to modify the persistent storage to affect the memory usage on
the next guest boot.

Or are you referring to 'virsh memtune', which does indeed require
cgroup support, but does not require any guest interaction?

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 0/6] Add support for injecting NMI to guest

2011-04-15 Thread Eric Blake
On 04/12/2011 10:56 PM, Lai Jiangshan wrote:
> 
> 
> This patch series implements a feature of injecting NMI to guest,
> which is accessible via new virDomainInjectNMI API and
> 'inject-nmi' command in virsh.
> 
> Lai Jiangshan (6):
>   inject-nmi: Defining the public API
>   inject-nmi: Defining the internal API
>   inject-nmi: Implementing the public API
>   inject-nmi: Implementing the remote protocol
>   inject-nmi: Expose the new API in virsh
>   qemu,inject-nmi: Implement the driver methods

This is v2 of:
https://www.redhat.com/archives/libvir-list/2011-April/msg00036.html
If you use 'git format-patch --subject-prefix=PATCHv2' (or send-email
instead of format-patch), it makes it easier to see that this is a resend.

Thanks for splitting it up; that helps review.

My quick glance at 1-5 didn't turn up any glaring problems, but I'm
still not sure we've got the semantics right.  I'll reply to patch 6,
and think we'll need another spin to get the API right.

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 6/6] qemu, inject-nmi: Implement the driver methods

2011-04-15 Thread Eric Blake
On 04/12/2011 11:01 PM, Lai Jiangshan wrote:
> +++ b/src/qemu/qemu_driver.c
> @@ -1701,6 +1701,48 @@ static int qemudDomainSetMaxMemory(virDomainPtr dom, 
> unsigned long memory)
>  return qemudDomainSetMemoryFlags(dom, memory, VIR_DOMAIN_MEM_MAXIMUM);
>  }
>  
> +static int qemuDomainInjectNMI(virDomainPtr domain, unsigned int flags)
> +{
> +struct qemud_driver *driver = domain->conn->privateData;
> +virDomainObjPtr vm = NULL;
> +int ret = -1;
> +qemuDomainObjPrivatePtr priv;
> +

Right here, you should have a virCheckFlags(0, -1) to enforce that we
don't honor any flags for now.  At which point, you don't need to pass
flags on down to the monitor calls.

> +++ b/src/qemu/qemu_monitor_json.c
> @@ -2513,3 +2513,32 @@ cleanup:
>  
>  return ret;
>  }
> +
> +int qemuMonitorJSONInjectNMI(qemuMonitorPtr mon, unsigned int flags 
> ATTRIBUTE_UNUSED)
> +{

Since neither monitor needed flags this low, you don't have to propogate
it any further than qemu_driver.c's virCheckFlags().

> +int ret;
> +virJSONValuePtr cmd;
> +virJSONValuePtr reply = NULL;
> +
> +/*
> + * FIXME: qmp nmi is not supported until qemu-0.16.0,
> + * use human-monitor-command instead temporary.
> + *
> + * FIXME: qemu's nmi command just injects NMI to a specified CPU,
> + * use "nmi 0" instead temporary.
> + */
> +cmd = qemuMonitorJSONMakeCommand("human-monitor-command",
> + "s:command-line", "nmi 0",
> + NULL);

We've already got a preferred form for issuing HMP commands from JSON.
Rather than building up human-monitor-command manually, you should
instead be using qemuMonitorTextInjectNMI; for example, see how
qemuMonitorJSONDriveDel falls back to hmp.  This also covers the case of
a qemu binary that has JSON but not hmp giving a more useful error message.

> +++ b/src/qemu/qemu_monitor_text.c
> @@ -2628,3 +2628,23 @@ int qemuMonitorTextArbitraryCommand(qemuMonitorPtr 
> mon, const char *cmd,
>  
>  return ret;
>  }
> +
> +int qemuMonitorTextInjectNMI(qemuMonitorPtr mon, unsigned int flags 
> ATTRIBUTE_UNUSED)
> +{
> +const char *cmd = "nmi 0";
> +char *reply = NULL;
> +
> +/*
> + * FIXME: qemu's nmi command just injects NMI to a specified CPU,
> + * use "nmi 0" instead temporary.
> + */

This bothers me.  Is it possible to inject NMI to a particular CPU in
bare-metal hardware?  If so, then we ought to support that in the API.

I know what Dan said:

>>> +int virDomainSendEventNMI(virDomainPtr domain, unsigned int vcpu)
>> 
>> Your proposal to qemu-devel to add inject-nmi for QMP does not
>> include any CPU index parameter anymore. Instead it will automatically
>> inject the NMI to all present CPUs. This libvirt API would appear to
>> be incompatible with that QMP design.  For Xen, it appears the API
>> also does not allow a CPU index to be given - it just injects to the
>> first CPU AFAICT.
>> 
>> So do we really need to have a 'unsigned int vcpu' parameter in the
>> libvirt API, or can we just leave it out and always inject to
>> CPU==0 for HMP ?
>> 
>> eg simplify to
>> 
>>   int virDomainSendNMI(virDomainPtr domain)

but if there's ever any possibility that qemu might learn how to direct
an NMI to a particular vcpu, I wonder if we should instead have:

enum {
VIR_DOMAIN_INJECT_NMI_FIRST = 1,
VIR_DOMAIN_INJECT_NMI_ALL = 2,
}

/**
 * virDomainInjectNMI:
 * @domain: pointer to domain object, or NULL for Domain0
 * @vcpu:   which vcpu to send the NMI to
 * @flags:  the flags for controlling behaviours
 *
 * Send NMI to the guest.  If @flags contains
 * VIR_DOMAIN_INJECT_NMI_FIRST or VIR_DOMAIN_INJECT_NMI_ALL,
 * then @vcpu is ignored, and the NMI is sent to the first
 * possible vcpu or to all vcpus, respectively.  Otherwise,
 * the NMI is sent to the specified vcpu; it is an error if
 * @vcpu does not correspond to a currently online processor.
 *
 * Not all hypervisors support fine-tuned control over which
 * vcpu(s) can be targetted, and might succeed only for a
 * particular value of @flags.
 *
 * Returns 0 in case of success, -1 in case of failure.
 */

int virDomainInjectNMI(virDomainPtr domain, unsigned int vcpu,
   unsigned int flags);

Then xen would be hardcoded to require flags==_FIRST (and always ignore
vcpu), whereas qemu can honor a particular vcpu.

Or is the first vcpu always 0?  That is, are there any hypervisors that
let you offline vcpu 0 while leaving vcpu1 up, so that FIRST would imply
1?  Maybe we don't need a flag for FIRST, but document that vcpu is
ignored if ALL is passed, and then make xen error out if ALL is passed
or if vcpu != 0.

That said, I haven't looked at the proposed qemu side of the patches for
how the monitor command for nmi will be implemented in the first place,
and until that is in a formal qemu release, we may still need to be a
bit flexible here on the libvirt side.  Do any other hypervisors allow
NMI injection, and with what 

Re: [libvirt] [PATCH] esx: Fix gcc 4.6 warning about initialized but unused variables

2011-04-15 Thread Eric Blake
On 04/15/2011 03:25 AM, Christophe Fergeau wrote:
> Hi Matthias,
> 
> On Thu, Apr 14, 2011 at 07:18:27PM +0200, Matthias Bolte wrote:
>> This is a speculative patch as I don't have gcc 4.6 at hand to test it.
> 
> I no longer get the warning with this patch applied. At first I was worried
> about the use of ATTRIBUTE_UNUSED (I assumed it meant "this var is unused,
> feel free to optimize it away"), but gcc documentation indeed says:
> "unused
> This attribute, attached to a variable, means that the variable is
> meant to be possibly unused. GCC will not produce a warning for this
> variable."
> 
> So this all looks good to me (aka ack from me)

ACK from me as well; I went ahead and pushed it under the build-breaker
rule.

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCHv2 1/9] maint: use lighter-weight function for straight appends

2011-04-15 Thread Matthias Bolte
2011/4/14 Eric Blake :
> It costs quite a few processor cycles to go through printf parsing
> just to determine that we only meant to append.

> -        virBufferVSprintf(&buf, "%s", k);
> -        virBufferVSprintf(&buf, "%s", "=");
> -        virBufferVSprintf(&buf, "%s", v);
> +        virBufferVSprintf(&buf, "%s=%s", k, v);

Nice one :)

ACK.

Matthias

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH] tests: Unit tests for internal hash APIs

2011-04-15 Thread Jiri Denemark
This is a basic set of tests for testing removals of hash entries during
iteration.
---
More tests for all other hash APIs will come on Monday.

 tests/Makefile.am |8 +++-
 tests/hashdata.h  |   33 +++
 tests/hashtest.c  |  157 +
 3 files changed, 197 insertions(+), 1 deletions(-)
 create mode 100644 tests/hashdata.h
 create mode 100644 tests/hashtest.c

diff --git a/tests/Makefile.am b/tests/Makefile.am
index 5896442..063ab60 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -77,7 +77,8 @@ EXTRA_DIST =  \
 
 check_PROGRAMS = virshtest conftest sockettest \
nodeinfotest qparamtest virbuftest \
-   commandtest commandhelper seclabeltest
+   commandtest commandhelper seclabeltest \
+   hashtest
 
 if WITH_XEN
 check_PROGRAMS += xml2sexprtest sexpr2xmltest \
@@ -159,6 +160,7 @@ TESTS = virshtest \
sockettest \
commandtest \
seclabeltest \
+   hashtest \
$(test_scripts)
 
 if WITH_XEN
@@ -373,6 +375,10 @@ virbuftest_SOURCES = \
virbuftest.c testutils.h testutils.c
 virbuftest_LDADD = $(LDADDS)
 
+hashtest_SOURCES = \
+   hashtest.c hashdata.h testutils.h testutils.c
+hashtest_LDADD = $(LDADDS)
+
 if WITH_LIBVIRTD
 eventtest_SOURCES = \
eventtest.c testutils.h testutils.c
diff --git a/tests/hashdata.h b/tests/hashdata.h
new file mode 100644
index 000..2782255
--- /dev/null
+++ b/tests/hashdata.h
@@ -0,0 +1,33 @@
+const char *uuids[] = {
+/* [ 46] */ "f17494ba-2353-4af0-b1ba-13680858edcc",
+"64ab4e78-1b6e-4b88-b47f-2def46c79a86",
+"f99b0d59-ecff-4cc6-a9d3-20159536edc8",
+/* [ 75] */ "e1bfa30f-bc0b-4a24-99ae-bed7f3f21a7b",
+"acda5fa0-58de-4e1e-aa65-2124d1e29c54",
+/* [ 76] */ "5f476c28-8f26-48e0-98de-85745fe2f304",
+/* [123] */ "8be1d21c-cd35-4c7c-8fee-4b5046c7a62b",
+"830f0d57-9f21-40e8-bb86-cbf41de23fd6",
+"57044958-1b8a-4c02-ab75-2298c6e44263",
+"d526cd6c-4a99-4d5f-abfb-fc9419edd9d0",
+/* [237] */ "3ab39f7f-4613-4da6-a216-c2d6acc441bb",
+"ae20cf3c-38b8-483c-baea-6fb0994dc30c",
+"cd204d90-2414-4b9e-9d4f-fed09c9a816f",
+/* [240] */ "ed2cc723-db4b-43aa-ab02-0e3161087499",
+/* [246] */ "8ada85bc-9bdf-4507-8334-849635ea0a01",
+"8a7d5deb-615f-4cd3-8977-b5fab8ec4d05",
+/* [247] */ "dc2173b0-48fe-4555-b190-8052be1120eb",
+"040e434d-68d8-41a9-b3a1-1bee239914c1",
+"d1a564b2-c7f3-4b76-8712-3b8f5aae6ded",
+"0e614f33-c1da-4cfe-b6d5-65ecd2d066f2"
+};
+
+const char *uuids_subset[] = {
+"64ab4e78-1b6e-4b88-b47f-2def46c79a86",
+"acda5fa0-58de-4e1e-aa65-2124d1e29c54",
+"830f0d57-9f21-40e8-bb86-cbf41de23fd6",
+"57044958-1b8a-4c02-ab75-2298c6e44263",
+"ae20cf3c-38b8-483c-baea-6fb0994dc30c",
+"040e434d-68d8-41a9-b3a1-1bee239914c1",
+"d1a564b2-c7f3-4b76-8712-3b8f5aae6ded",
+"8ada85bc-9bdf-4507-8334-849635ea0a01"
+};
diff --git a/tests/hashtest.c b/tests/hashtest.c
new file mode 100644
index 000..dff0181
--- /dev/null
+++ b/tests/hashtest.c
@@ -0,0 +1,157 @@
+#include 
+
+#include 
+#include 
+#include 
+
+#include "internal.h"
+#include "hash.h"
+#include "hashdata.h"
+#include "testutils.h"
+
+
+#define testError(...)  \
+do {\
+fprintf(stderr, __VA_ARGS__);   \
+/* Pad to line up with test name ... in virTestRun */   \
+fprintf(stderr, "%74s", "... ");\
+} while (0)
+
+
+static virHashTablePtr
+testHashInit(int size)
+{
+virHashTablePtr hash;
+int i;
+
+if (!(hash = virHashCreate(size, NULL)))
+return NULL;
+
+/* entires are added in reverse order so that they will be linked in
+ * collision list in the same order as in the uuids array
+ */
+for (i = ARRAY_CARDINALITY(uuids) - 1; i >= 0; i--) {
+if (virHashAddEntry(hash, uuids[i], (void *) uuids[i]) < 0) {
+virHashFree(hash);
+return NULL;
+}
+}
+
+return hash;
+}
+
+
+static int
+testHashCheckCount(virHashTablePtr hash, int count)
+{
+if (virHashSize(hash) != count) {
+testError("\nhash contains %d instead of %d elements\n",
+  virHashSize(hash), count);
+return -1;
+}
+
+return 0;
+}
+
+
+struct testInfo {
+void *data;
+int count;
+};
+
+
+const int testHashCountRemoveForEachSome =
+ARRAY_CARDINALITY(uuids) - ARRAY_CARDINALITY(uuids_subset);
+
+static void
+testHashRemoveForEachSome(void *payload ATTRIBUTE_UNUSED,
+  const void *name,
+  void *data)
+{
+virHashTablePtr hash = data;
+int i;
+
+for (i = 0; i < ARRAY_CARDINALITY(uuids_subset); i++) {
+if (STREQ(uuids_subset[i], name)) {
+if (virHashRemoveEntry(hash, name) < 0 && virTestGetVerbose()) {
+  

Re: [libvirt] [PATCHv2 2/9] phyp: avoid a logic bug

2011-04-15 Thread Matthias Bolte
2011/4/14 Eric Blake :
> Ever since commit ebc46f, the destroy function built two command
> variants but only used one.  I went with the variant that matches
> the idiom used in the counterpart of phypBuildStoragePool.
>
> * src/phyp/phyp_driver.c (phypDestroyStoragePool): Avoid
> clobbering cmd.  Fix error message typo.
> ---
>  src/phyp/phyp_driver.c |   11 +--
>  1 files changed, 1 insertions(+), 10 deletions(-)
>
> diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
> index 5742d95..7aa494d 100644
> --- a/src/phyp/phyp_driver.c
> +++ b/src/phyp/phyp_driver.c
> @@ -2936,19 +2936,10 @@ phypDestroyStoragePool(virStoragePoolPtr pool)
>         return -1;
>     }
>     cmd = virBufferContentAndReset(&buf);
> -
> -    if (virAsprintf(&cmd,
> -                    "viosvrcmd -m %s --id %d -c "
> -                    "'rmsp %s'", managed_system, vios_id,
> -                    pool->name) < 0) {
> -        virReportOOMError();
> -        goto cleanup;
> -    }
> -
>     ret = phypExec(session, cmd, &exit_status, conn);
>
>     if (exit_status < 0) {
> -        VIR_ERROR(_("Unable to create Storage Pool: %s"), ret);
> +        VIR_ERROR(_("Unable to destroy Storage Pool: %s"), ret);
>         goto cleanup;
>     }

I just noticed that the driver uses VIR_ERROR in many places where
PHYP_ERROR should be used to report an actual libvirt API level error.
But that a problem for another patch.

ACK, to this one.

Matthias

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCHv2 3/9] phyp: avoid memory leak on failure

2011-04-15 Thread Matthias Bolte
2011/4/14 Eric Blake :
> * src/phyp/phyp_driver.c (phypUUIDTable_Init): Avoid memory leak
> on error.
> ---
>  src/phyp/phyp_driver.c |   46 +++---
>  1 files changed, 27 insertions(+), 19 deletions(-)
>

ACK.

Matthias

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 1/2] virsh: list required options first

2011-04-15 Thread Jiri Denemark
On Tue, Apr 12, 2011 at 15:35:06 -0600, Eric Blake wrote:
> The current state of virsh parsing is that:
> 
> all lookup the volume by path (technically, the last two also attempt
> a name lookup within a pool, whereas the first skips that step, but
> the end result is the same); meanwhile:

Is example virsh command line missing here?

> complains about unexpected data.  Why?  Because the --pool option is
> optional, so default was parsed as the --vol argument, and
> /path/to/image.img doesn't match up with any remaining options that
> require an argument.  Therefore, the only way to specify pool is with
> an explicit "--pool" argument (you can't specify it positionally).
> However, named arguments can appear in any order, so:

and here

> have also always worked.  Therefore, this patch has no functional
> change on vol-info option parsing, but only on 'virsh help vol-info'
> synopsis layout.  However, it also allows the next patch to 1) enforce
> that required options are always first (without this patch, the next
> patch would fail the testsuite), and 2) allow the user to omit the
> "--pool" argument.  That is, the next patch makes it possible to do:

and here

> instead of the longer

and here as well.

> * tools/virsh.c (opts_vol_create_from, opts_vol_clone)
> (opts_vol_upload, opts_vol_download, opts_vol_delete)
> (opts_vol_wipe, opts_vol_info, opts_vol_dumpxml, opts_vol_key)
> (opts_vol_path): List optional pool parameter after required
> arguments.
> ---
>  tools/virsh.c |   20 ++--
>  1 files changed, 10 insertions(+), 10 deletions(-)

Makes sense. I went through all virsh.c and didn't find more options that
would need fixing. The only options which don't follow this "optional after
required" rule are bool options which can safely stay where they are.

ACK

Jirka

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCHv2 4/9] phyp: more return handling cleanup

2011-04-15 Thread Matthias Bolte
2011/4/14 Eric Blake :
> * src/phyp/phyp_driver.c (phypInterfaceDestroy)
> (phypInterfaceDefineXML, phypInterfaceLookupByName)
> (phypInterfaceIsActive, phypListInterfaces, phypNumOfInterfaces):
> Clean up return handling of recent additions.
> ---
>  src/phyp/phyp_driver.c |  130 
> +---
>  1 files changed, 56 insertions(+), 74 deletions(-)
>

ACK.

Mathias

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCHv2 5/9] phyp: use consistent style for labels

2011-04-15 Thread Matthias Bolte
2011/4/14 Eric Blake :
> * src/phyp/phyp_driver.c: Match label style of rest of project.
> (phypExec, phypUUIDTable_Pull): Drop an extra label.
> ---
>  src/phyp/phyp_driver.c |  129 
> +++-
>  1 files changed, 62 insertions(+), 67 deletions(-)
>

ACK.

Matthias

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCHv2 6/9] phyp: prefer memcpy over memmove when legal

2011-04-15 Thread Matthias Bolte
2011/4/14 Eric Blake :
> * src/phyp/phyp_driver.c (phypUUIDTable_AddLpar)
> (phypGetLparUUID, phypGetStoragePoolUUID, phypVolumeGetXMLDesc)
> (phypGetStoragePoolXMLDesc): Use faster method.
> ---
>  src/phyp/phyp_driver.c |   10 +-
>  1 files changed, 5 insertions(+), 5 deletions(-)
>

ACK.

Matthias

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCHv2 7/9] phyp: use consistent return string handling

2011-04-15 Thread Matthias Bolte
2011/4/14 Eric Blake :
> Use the name 'ret' for all phypExec results, to make it easier
> to wrap phypExec.  Don't allow a possibly NULL ret through printf.
>
> * src/phyp/phyp_driver.c (phypBuildVolume, phypDestroyStoragePool)
> (phypBuildStoragePool, phypBuildLpar): Avoid NULL dereference.
> (phypInterfaceDestroy): Avoid redundant free.
> (phypVolumeLookupByPath, phypVolumeGetPath): Use consistent
> naming.
> ---
>  src/phyp/phyp_driver.c |   37 +
>  1 files changed, 17 insertions(+), 20 deletions(-)
>

ACK.

Matthias

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 1/2] virsh: list required options first

2011-04-15 Thread Eric Blake
On 04/15/2011 02:26 PM, Jiri Denemark wrote:
> On Tue, Apr 12, 2011 at 15:35:06 -0600, Eric Blake wrote:
>> The current state of virsh parsing is that:
>>
>> all lookup the volume by path (technically, the last two also attempt
>> a name lookup within a pool, whereas the first skips that step, but
>> the end result is the same); meanwhile:
> 
> Is example virsh command line missing here?

Aargh.  I wrote my commit message by using sample command prompts:

# virsh ...

But # is a comment character, and ate my message (and now I don't
remember it off the top of my head).  I'll have to figure that out
again, and use $ prompts instead...

>> * tools/virsh.c (opts_vol_create_from, opts_vol_clone)
>> (opts_vol_upload, opts_vol_download, opts_vol_delete)
>> (opts_vol_wipe, opts_vol_info, opts_vol_dumpxml, opts_vol_key)
>> (opts_vol_path): List optional pool parameter after required
>> arguments.
>> ---
>>  tools/virsh.c |   20 ++--
>>  1 files changed, 10 insertions(+), 10 deletions(-)
> 
> Makes sense. I went through all virsh.c and didn't find more options that
> would need fixing. The only options which don't follow this "optional after
> required" rule are bool options which can safely stay where they are.
> 
> ACK

The review would have been much easier with a non-broken commit message,
but you caught on to my drift.  I'll post my revised commit message once
I remember what it was...

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCHv2 8/9] phyp: avoid memory leaks in command values

2011-04-15 Thread Matthias Bolte
2011/4/14 Eric Blake :
> * src/phyp/phyp_driver.c (phypExecBuffer): New function. Use it
> throughout file for less code, and for plugging a few leaks.
> ---
>
> Amazing how much copy-and-paste code this consolidated.
>
>  src/phyp/phyp_driver.c |  803 
> ++--
>  1 files changed, 92 insertions(+), 711 deletions(-)
>

> @@ -1823,17 +1706,8 @@ phypCreateServerSCSIAdapter(virConnectPtr conn)
>     virBufferVSprintf(&buf, " -r prof -i 'name=%s,lpar_id=%d,"
>                       "\"virtual_scsi_adapters=%s,%d/server/any/any/1\"'",
>                       vios_name, vios_id, ret, slot);
> -    if (virBufferError(&buf)) {
> -        virBufferFreeAndReset(&buf);
> -        virReportOOMError();
> -        goto cleanup;
> -    }
> -
> -    VIR_FREE(cmd);
>     VIR_FREE(ret);
> -
> -    cmd = virBufferContentAndReset(&buf);
> -    ret = phypExec(session, cmd, &exit_status, conn);
> +    ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
>
>     if (exit_status < 0 || ret == NULL)
>         goto cleanup;
> @@ -1847,17 +1721,7 @@ phypCreateServerSCSIAdapter(virConnectPtr conn)
>     virBufferVSprintf(&buf,
>                       " -p %s -o a -s %d -d 0 -a \"adapter_type=server\"",
>                       vios_name, slot);
> -    if (virBufferError(&buf)) {
> -        virBufferFreeAndReset(&buf);
> -        virReportOOMError();
> -        goto cleanup;
> -    }
> -
> -    VIR_FREE(cmd);
> -    VIR_FREE(ret);

Why are you killing the VIR_FREE(ret) here, in the hunk before you
left it in. It's necessary here too.

> -    cmd = virBufferContentAndReset(&buf);
> -    ret = phypExec(session, cmd, &exit_status, conn);
> +    ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
>
>     if (exit_status < 0 || ret == NULL)
>         goto cleanup;


> @@ -2000,18 +1841,7 @@ phypAttachDevice(virDomainPtr domain, const char *xml)
>
>     if (system_type == HMC)
>         virBufferAddChar(&buf, '\'');
> -
> -    if (virBufferError(&buf)) {
> -        virBufferFreeAndReset(&buf);
> -        virReportOOMError();
> -        goto cleanup;
> -    }
> -
> -    VIR_FREE(cmd);
> -    VIR_FREE(ret);

Same for this VIR_FREE(ret) here, removing it produces a leak, doesn't it.

> -
> -    cmd = virBufferContentAndReset(&buf);
> -    ret = phypExec(session, cmd, &exit_status, conn);
> +    ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
>
>     if (exit_status < 0 || ret == NULL)
>         goto cleanup;
> @@ -2029,17 +1859,7 @@ phypAttachDevice(virDomainPtr domain, const char *xml)
>     virBufferVSprintf(&buf,
>                       " slot_num,backing_device|grep %s|cut -d, -f1",
>                       dev->data.disk->src);
> -    if (virBufferError(&buf)) {
> -        virBufferFreeAndReset(&buf);
> -        virReportOOMError();
> -        goto cleanup;
> -    }
> -
> -    VIR_FREE(cmd);
> -    VIR_FREE(ret);

And this VIR_FREE(ret) needs to stay too.

> -
> -    cmd = virBufferContentAndReset(&buf);
> -    ret = phypExec(session, cmd, &exit_status, conn);
> +    ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
>
>     if (exit_status < 0 || ret == NULL)
>         goto cleanup;
> @@ -2057,17 +1877,7 @@ phypAttachDevice(virDomainPtr domain, const char *xml)
>                       " -r prof --filter lpar_ids=%d,profile_names=%s"
>                       " -F virtual_scsi_adapters|sed -e 's/\"//g'",
>                       vios_id, profile);
> -    if (virBufferError(&buf)) {
> -        virBufferFreeAndReset(&buf);
> -        virReportOOMError();
> -        goto cleanup;
> -    }
> -
> -    VIR_FREE(cmd);
> -    VIR_FREE(ret);

And this VIR_FREE(ret) needs to stay too.

> -
> -    cmd = virBufferContentAndReset(&buf);
> -    ret = phypExec(session, cmd, &exit_status, conn);
> +    ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
>
>     if (exit_status < 0 || ret == NULL)
>         goto cleanup;
> @@ -2083,17 +1893,8 @@ phypAttachDevice(virDomainPtr domain, const char *xml)
>                       "\"virtual_scsi_adapters=%s,%d/client/%d/%s/0\"'",
>                       domain_name, domain->id, ret, slot,
>                       vios_id, vios_name);
> -    if (virBufferError(&buf)) {
> -        virBufferFreeAndReset(&buf);
> -        virReportOOMError();
> -        goto cleanup;
> -    }
> -
> -    VIR_FREE(cmd);
>     VIR_FREE(ret);

This one is left in correctly.

> -
> -    cmd = virBufferContentAndReset(&buf);
> -    ret = phypExec(session, cmd, &exit_status, conn);
> +    ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
>
>     if (virStrToLong_i(ret, &char_ptr, 10, &slot) == -1)
>         goto cleanup;
> @@ -2107,17 +1908,7 @@ phypAttachDevice(virDomainPtr domain, const char *xml)
>     virBufferVSprintf(&buf,
>                       " -p %s -o a -s %d -d 0 -a \"adapter_type=server\"",
>                       domain_name, slot);
> -    if (virBufferError(&buf)) {
> -        virBufferFreeAndReset(&buf);
> -   

Re: [libvirt] [PATCHv2 9/9] phyp: another simplification

2011-04-15 Thread Matthias Bolte
2011/4/14 Eric Blake :
> Rather than copying and pasting lots of code, factor it into a
> single helper function.
>
> * src/phyp/phyp_driver.c (phypExecInt): New function.
> (phypGetVIOSPartitionID, phypNumDomainsGeneric, phypGetLparID)
> (phypGetLparMem, phypGetLparCPUGeneric, phypGetRemoteSlot)
> (phypGetVIOSNextSlotNumber, phypAttachDevice)
> (phypGetStoragePoolSize, phypStoragePoolNumOfVolumes)
> (phypNumOfStoragePools, phypInterfaceDestroy)
> (phypInterfaceDefineXML, phypInterfaceLookupByName)
> (phypInterfaceIsActive, phypNumOfInterfaces): Use it.
> ---
>  src/phyp/phyp_driver.c |  316 
> ++--
>  1 files changed, 67 insertions(+), 249 deletions(-)
>
> diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
> index bc24b76..98d5cd6 100644
> --- a/src/phyp/phyp_driver.c
> +++ b/src/phyp/phyp_driver.c
> @@ -228,6 +228,26 @@ phypExecBuffer(LIBSSH2_SESSION *session, virBufferPtr 
> buf, int *exit_status,
>     return ret;
>  }
>
> +/* Convenience wrapper function */
> +static int phypExecInt(LIBSSH2_SESSION *, virBufferPtr, virConnectPtr, int *)
> +    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
> +static int
> +phypExecInt(LIBSSH2_SESSION *session, virBufferPtr buf, virConnectPtr conn,
> +            int *result)
> +{
> +    char *str;
> +    int ret;
> +
> +    str = phypExecBuffer(session, buf, &ret, conn, true);
> +    if (!str || ret) {
> +        VIR_FREE(str);
> +        return -1;
> +    }
> +    ret = virStrToLong_i(str, NULL, 10, result);

You made the parsing stricter by passing NULL as second argument to
virStrToLong_i. I don't expect it but this might be possible that this
breaks the behavior of the driver.

> +    VIR_FREE(str);
> +    return ret;
> +}
> +

The rest of the patch looks fine.

Matthias

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCHv2 9/9] phyp: another simplification

2011-04-15 Thread Eric Blake
On 04/15/2011 03:01 PM, Matthias Bolte wrote:
>> +str = phypExecBuffer(session, buf, &ret, conn, true);
>> +if (!str || ret) {
>> +VIR_FREE(str);
>> +return -1;
>> +}
>> +ret = virStrToLong_i(str, NULL, 10, result);
> 
> You made the parsing stricter by passing NULL as second argument to
> virStrToLong_i. I don't expect it but this might be possible that this
> breaks the behavior of the driver.

That was an intentional decision of mine (I guess I should have
documented it better), since the rest of the code was getting the
character after the parsed integer but doing nothing with it.  In most
cases, it was like the code _expected_ a newline after the integer (such
as the output of a sed -c run, where that holds true), but wasn't
enforcing that expectation.

Should I modify the commit message and push with the newer strict
behavior, or modify the code to keep the older relaxed behavior (but
this time add a VIR_WARN if garbage is found after the parse)?

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCHv9 1/4] libvirt/qemu - persistent modification of devices.

2011-04-15 Thread Eric Blake
On 04/12/2011 08:49 PM, KAMEZAWA Hiroyuki wrote:
> 
> Now, qemudDomainAttachDeviceFlags() and qemudDomainDetachDeviceFlags()
> doesn't support VIR_DOMAIN_DEVICE_MODIFY_CONFIG. By this, virsh's
> at(de)tatch-device --persistent cannot modify qemu config.
> (Xen allows it.)
> 
> This patch is a base patch for adding support of devices in
> step by step manner. Following patches will add some device
> support.
> 
> Signed-off-by: KAMEZAWA Hiroyuki 
> 
> Changelog: v8->v9
>   - removed unnecessary comments.

It's taken quite a few iterations, but I've finally scheduled time to
start reviewing it.

> +static int qemuDomainModifyDevicePersistent(virDomainPtr dom,
> +const char *xml,
> +unsigned int attach,

You missed one.  You changed attach and detach, but not update.  This
parameter can usefully forward to all three types of updates.

In fact, I think I'd like to go one further, and refactor things further
before we start adding persistent devices.

It seems like there are two steps in all three categories of functions -
obtain the locks, then do the work.  I like how you've factored things
into one function that obtains the locks then forwards on to other
functions that do the work.  Furthermore, I don't see any reason why we
can't support LIVE|CONFIG at once, provided we know for which devices we
can make a successful CONFIG change.

> + * When both of MODIFY_CONFIG and MODIFY_LIVE are passed at the same 
> time,
> + * return error for now. We should support this later.
> + */
> +if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) {
> +qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
> +_("cannot modify active domain and its definition "
> +  "at the same time."));
> +return -1;
> +}

You are right that it's not implemented yet, but no worse than what we
already have, so it's not a regression.  But I think it is doable, by
rewriting this into one giant function:

1. obtain lock
2. if CURRENT, convert to LIVE or CONFIG
3. if LIVE but not active, error
4. if CONFIG but not persistent, error
5. if CONFIG call, make temporary vmdef and modify that, or quit if that
device is not supported yet
6. if LIVE, make live modification; if that errors out, quit
7. if CONFIG, make temporary vmdef permanent (hopefully it succeeds,
because we don't roll back the LIVE portion of LIVE|CONFIG)
8. clean up locks

I'll propose a followup patch that tries to capture this idiom in code.

> +static int qemudDomainAttachDeviceFlags(virDomainPtr dom,
> +const char *xml,
> +unsigned int flags)
> +{
> +int ret = -1;
> +
> +virCheckFlags((VIR_DOMAIN_DEVICE_MODIFY_CONFIG |
> +   VIR_DOMAIN_DEVICE_MODIFY_LIVE), -1);

This causes a change in behavior.  Previously, we silently ignored
VIR_DOMAIN_DEVICE_MODIFY_FORCE, now we error out.  But overall, that's a
good change (FORCE only made sense for ModifyDevice, not Attach), and it
goes to show that we don't use virCheckFlags on nearly enough APIs.

> +
> +if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG)
> +ret = qemuDomainModifyDevicePersistent(dom, xml, 1, flags);
> +else if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE)
> +ret = qemudDomainAttachDevice(dom, xml);

For example, here your logic is wrong.  You covered the CONFIG|LIVE case
with qemuDomainModifyDevicePersistent (by erroring out), but you _don't_
cover the CURRENT case (which should be either CONFIG or LIVE).  But to
learn if the vm is active, you have to obtain the lock, and the way
you've written this, you've already forwarded into one of the two
routines.  Rather, all the public entries should forward into the one
giant helper routine which grabs the locks, checks the flags, then calls
into the right callbacks.

> @@ -4141,14 +4242,19 @@ cleanup:
>  
>  static int qemudDomainDetachDeviceFlags(virDomainPtr dom,
>  const char *xml,
> -unsigned int flags) {
> -if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) {
> -qemuReportError(VIR_ERR_OPERATION_INVALID,
> -"%s", _("cannot modify the persistent configuration 
> of a domain"));
> -return -1;
> -}
> +unsigned int flags)
> +{
> +int ret = -1;
> +
> +virCheckFlags((VIR_DOMAIN_DEVICE_MODIFY_CONFIG |
> +   VIR_DOMAIN_DEVICE_MODIFY_LIVE), -1);

Another change in noisily rejecting FORCE, but I think it's good.

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCHv2 8/9] phyp: avoid memory leaks in command values

2011-04-15 Thread Eric Blake
On 04/15/2011 02:56 PM, Matthias Bolte wrote:
> 2011/4/14 Eric Blake :
>> * src/phyp/phyp_driver.c (phypExecBuffer): New function. Use it
>> throughout file for less code, and for plugging a few leaks.
>> ---
>>
>> Amazing how much copy-and-paste code this consolidated.
>>
>>   " -p %s -o a -s %d -d 0 -a \"adapter_type=server\"",
>>   vios_name, slot);
>> -if (virBufferError(&buf)) {
>> -virBufferFreeAndReset(&buf);
>> -virReportOOMError();
>> -goto cleanup;
>> -}
>> -
>> -VIR_FREE(cmd);
>> -VIR_FREE(ret);
> 
> Why are you killing the VIR_FREE(ret) here, in the hunk before you
> left it in. It's necessary here too.

Accident of rebasing.  I had previously inserted VIR_FREE(ret) earlier
in the function, before your patch to independently fix leaks of ret,
and missed that my rebase was deleting your instances.

> 
> ACK, with that VIR_FREEs left in.

I've added those back in, and pushed 1-8.

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 2/2] virsh: fix regression in parsing optional integer

2011-04-15 Thread Jiri Denemark
On Tue, Apr 12, 2011 at 15:35:07 -0600, Eric Blake wrote:
> Regression introduced in 0.8.5, commit c1564268.  The command
> 'virsh freecell 0' quit working when it changed from an optional
> string to an optional integer.
> 
> This patch introduces a slight change that specifying an option
> twice is now detected as an error.
> 
> * tools/virsh.c (vshCmddefGetData, vshCmddefGetOption)
> (vshCommandCheckOpts): Alter parameters to use bitmaps.
> (vshCmddefOptParse): New function.
> (vshCommandParse): Update for better handling of positional
> arguments.
> (vshCmddefHelp): Allow unit tests to validate options.
> ---
>  tools/virsh.c |  149 +++-
>  1 files changed, 104 insertions(+), 45 deletions(-)

100iI hate command line parsing in virsh.
^[

The code looks like it does what it's supposed to do and I guess we should be
fine with the limit for 32 arguments for a single virsh command :-) If not,
there's clearly something wrong about the command which would need more.

ACK

Jirka

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 3/2] tests: test recent virsh option parsing changes

2011-04-15 Thread Jiri Denemark
On Tue, Apr 12, 2011 at 16:01:00 -0600, Eric Blake wrote:
> * tests/virsh-optparse: New file.
> * tests/Makefile.am (test_scripts): Use it.
> ---
> 
> Hmm, I'd better take my own advice and test this stuff :)
> 
>  tests/Makefile.am|1 +
>  tests/virsh-optparse |   70 
> ++
>  2 files changed, 71 insertions(+), 0 deletions(-)
>  create mode 100755 tests/virsh-optparse

And you also introduce this test for option parsing, nice.

ACK

Jirka

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1/2] virsh: list required options first

2011-04-15 Thread Eric Blake
On 04/15/2011 02:33 PM, Eric Blake wrote:
>> Is example virsh command line missing here?
> 
> Aargh.  I wrote my commit message by using sample command prompts:
> 
> # virsh ...
> 
> But # is a comment character, and ate my message (and now I don't
> remember it off the top of my head).  I'll have to figure that out
> again, and use $ prompts instead...
> 
>> ACK
> 
> The review would have been much easier with a non-broken commit message,
> but you caught on to my drift.  I'll post my revised commit message once
> I remember what it was...

Pushed with the following commit message:

commit 6b75a1a5b0d10b42e3fd344b2067a176ee294f46
Author: Eric Blake 
Date:   Tue Apr 12 14:58:02 2011 -0600

virsh: list required options first

The current state of virsh parsing is that:

$ virsh vol-info /path/to/image
$ virsh vol-info --pool default /path/to/image
$ virsh vol-info --pool default --vol /path/to/image

all lookup the volume by path (technically, the last two also attempt
a name lookup within a pool, whereas the first skips that step, but
the end result is the same); meanwhile:

$ virsh vol-info default /path/to/image

complains about unexpected data.  Why?  Because the --pool option is
optional, so default was parsed as the --vol argument, and
/path/to/image.img doesn't match up with any remaining options that
require an argument.  For proof, note that:

$ virsh vol-info default --vol /path/to/image

complains about looking up 'default' - the parser mis-associated both
arguments with --vol.  Given the above, the only way to specify pool
is with an explicit "--pool" argument (you can't specify it
positionally).  However, named arguments can appear in any order, so:

$ virsh vol-info /path/to/image --pool default
$ virsh vol-info --vol /path/to/image --pool default

have also always worked.  Therefore, this patch has no functional
change on vol-info option parsing, but only on 'virsh help vol-info'
synopsis layout.  However, it also allows the next patch to 1) enforce
that required options are always first (without this patch, the next
patch would fail the testsuite), and 2) allow the user to omit the
"--pool" argument.  That is, the next patch makes it possible to do:

$ virsh vol-info /path/to/image default

which to date was not possible.

* tools/virsh.c (opts_vol_create_from, opts_vol_clone)
(opts_vol_upload, opts_vol_download, opts_vol_delete)
(opts_vol_wipe, opts_vol_info, opts_vol_dumpxml, opts_vol_key)
(opts_vol_path): List optional pool parameter after required
arguments.

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 2/2] virsh: fix regression in parsing optional integer

2011-04-15 Thread Eric Blake
On 04/15/2011 03:35 PM, Jiri Denemark wrote:
> On Tue, Apr 12, 2011 at 15:35:07 -0600, Eric Blake wrote:
>> Regression introduced in 0.8.5, commit c1564268.  The command
>> 'virsh freecell 0' quit working when it changed from an optional
>> string to an optional integer.
>>
>> This patch introduces a slight change that specifying an option
>> twice is now detected as an error.
>>
>> * tools/virsh.c (vshCmddefGetData, vshCmddefGetOption)
>> (vshCommandCheckOpts): Alter parameters to use bitmaps.
>> (vshCmddefOptParse): New function.
>> (vshCommandParse): Update for better handling of positional
>> arguments.
>> (vshCmddefHelp): Allow unit tests to validate options.
>> ---
>>  tools/virsh.c |  149 
>> +++-
>>  1 files changed, 104 insertions(+), 45 deletions(-)
> 
> 100iI hate command line parsing in virsh.
> ^[

Me too.  But it should be a lot better now.

> 
> The code looks like it does what it's supposed to do and I guess we should be
> fine with the limit for 32 arguments for a single virsh command :-) If not,
> there's clearly something wrong about the command which would need more.
> 
> ACK

I tweaked the commit message, then pushed:

commit b9973f526cb12b8e3d751ed19fb071b4a54ea1c0
Author: Eric Blake 
Date:   Tue Apr 12 14:42:59 2011 -0600

virsh: fix regression in parsing optional integer

Regression introduced in 0.8.5, commit c1564268.  The command
'virsh freecell 0' quit working when it changed from an optional
string to an optional integer.

This patch introduces a slight change that specifying an option
twice is now detected as an error.  It also changes things so
that a command that has more than 1 required option will not
complain about missing options if one but not all of the options
were given in long format, as in 'virsh vol-create --pool p file',
as well as making positional parsing work for all optional
options (each positional argument is associated with the earliest
option that has not yet been seen by name).

Optional boolean options can appear before required argument
options, because they don't affect positional argument parsing,
and obviously a required boolean option makes no sense.

Technically, this patch renders VSH_OT_STRING and VSH_OT_DATA
redundant; but cleaning that up can be a separate patch.

No command should ever need more than 32 options, right? :)

* tools/virsh.c (vshCmddefGetData, vshCmddefGetOption)
(vshCommandCheckOpts): Alter parameters to use bitmaps.
(vshCmddefOptParse): New function.
(vshCommandParse): Update for better handling of positional
arguments.
(vshCmddefHelp): Allow unit tests to validate options.


-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH 3/2] tests: test recent virsh option parsing changes

2011-04-15 Thread Eric Blake
On 04/15/2011 03:37 PM, Jiri Denemark wrote:
> On Tue, Apr 12, 2011 at 16:01:00 -0600, Eric Blake wrote:
>> * tests/virsh-optparse: New file.
>> * tests/Makefile.am (test_scripts): Use it.
>> ---
>>
>> Hmm, I'd better take my own advice and test this stuff :)
>>
>>  tests/Makefile.am|1 +
>>  tests/virsh-optparse |   70 
>> ++
>>  2 files changed, 71 insertions(+), 0 deletions(-)
>>  create mode 100755 tests/virsh-optparse
> 
> And you also introduce this test for option parsing, nice.
> 
> ACK

Thanks; pushed.

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH] tests: Unit tests for internal hash APIs

2011-04-15 Thread Eric Blake
On 04/15/2011 02:04 PM, Jiri Denemark wrote:
> This is a basic set of tests for testing removals of hash entries during
> iteration.
> ---
> More tests for all other hash APIs will come on Monday.

Such as a test that gets 8 collisions into a single bucket to force hash
table growth, or a test of custom hasher/comparator functions?

> 
>  tests/Makefile.am |8 +++-
>  tests/hashdata.h  |   33 +++
>  tests/hashtest.c  |  157 
> +
>  3 files changed, 197 insertions(+), 1 deletions(-)
>  create mode 100644 tests/hashdata.h
>  create mode 100644 tests/hashtest.c
> 
> +++ b/tests/hashdata.h
> @@ -0,0 +1,33 @@
> +const char *uuids[] = {
> +/* [ 46] */ "f17494ba-2353-4af0-b1ba-13680858edcc",
> +"64ab4e78-1b6e-4b88-b47f-2def46c79a86",
> +"f99b0d59-ecff-4cc6-a9d3-20159536edc8",
> +/* [ 75] */ "e1bfa30f-bc0b-4a24-99ae-bed7f3f21a7b",
> +"acda5fa0-58de-4e1e-aa65-2124d1e29c54",
> +/* [ 76] */ "5f476c28-8f26-48e0-98de-85745fe2f304",

Looks suspiciously like you used gdb to dump an existing hash structure
on a machine with lots of VMs :)  Works for me.

> +static virHashTablePtr
> +testHashInit(int size)
> +{
> +virHashTablePtr hash;
> +int i;
> +
> +if (!(hash = virHashCreate(size, NULL)))
> +return NULL;
> +
> +/* entires are added in reverse order so that they will be linked in
> + * collision list in the same order as in the uuids array

We're abusing an an internal detail.  So good to have the comment - if
the test breaks because of another rewrite, but the only breakage is due
to a different link order in each bucket, then I'm okay modifying the
test at that point, and meanwhile it justifies our abuse (that is, no
change needed).

> +#define DO_TEST_DATA(name, cmd, data)   \
> +DO_TEST_FULL(name "(" #data ")",\
> + cmd,   \
> + testHash ## cmd ## data,   \
> + testHashCount ## cmd ## data)
> +
> +DO_TEST_DATA("Remove in ForEach", RemoveForEach, Some);
> +DO_TEST_DATA("Remove in ForEach", RemoveForEach, All);
> +
> +return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;

Looks like a good test; it certainly would have caught the previous bugs
before the most recent hash.c fixes.

ACK.

-- 
Eric Blake   ebl...@redhat.com+1-801-349-2682
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH] build: include esx_vi.generated.* into dist file

2011-04-15 Thread Matthias Bolte
2011/4/15 Matthias Bolte :
> 2011/4/15 Wen Congyang :
>> commit d4601696 introduces two more generated files: esx_vi.generated.h
>> and esx_vi.generated.h. But we do not include them into dist file.
>> It will break building if using dist file to build.
>>
>> ---
>>  src/Makefile.am |    4 +++-
>>  1 files changed, 3 insertions(+), 1 deletions(-)
>>
>> diff --git a/src/Makefile.am b/src/Makefile.am
>> index dce866e..1eaa7d1 100644
>> --- a/src/Makefile.am
>> +++ b/src/Makefile.am
>> @@ -332,7 +332,9 @@ ESX_DRIVER_GENERATED =                                   
>>                    \
>>                esx/esx_vi_types.generated.typedef                      \
>>                esx/esx_vi_types.generated.typeenum                     \
>>                esx/esx_vi_types.generated.typetostring                 \
>> -               esx/esx_vi_types.generated.typefromstring
>> +               esx/esx_vi_types.generated.typefromstring               \
>> +               esx/esx_vi.generated.c                                  \
>> +               esx/esx_vi.generated.h
>>
>>  ESX_DRIVER_EXTRA_DIST =                                                \
>>                esx/README                                              \
>> --
>> 1.7.1
>>
>
> ACK.
>
> Matthias
>

I went ahead and pushed it.

Matthias

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] virsh memset

2011-04-15 Thread Zvi Dubitzky
Sorry , I refer to 'virsh memtune' . Do you know if it is  working ok for 
any  late combination
of libvirt and libcgroup   ( e.g libvirt-0.8.8 ) . I could not operate it 
.,

thanks

Zvi Dubitzky 
Email:d...@il.ibm.com



Eric Blake  wrote on 15/04/2011 20:38:55:

> From: Eric Blake 
> To: Zvi Dubitzky/Haifa/IBM@IBMIL
> Cc: libvir-list@redhat.com
> Date: 15/04/2011 20:39
> Subject: Re: [libvirt] virsh memset
> 
> On 04/14/2011 06:04 AM, Zvi Dubitzky wrote:
> > Hi
> > 
> > Does anybody know if  'virsh memset' is working ok  with its 
parameters 
> > with the late  libvirt code
> > (>= 0.8.8 )?   With what libcgroup version ?
> 
> 'virsh memset' doesn't depend on cgroups.  It relies on the guest
> honoring virtio ballooning requests.  Guests like Fedora are wired to do
> this out of the box, but not all guests support it.  I'm not sure
> whether the virtio drivers for Windows can do ballooning.  If a guest
> can't honor ballooning, then you can't change current memory at runtime;
> however, with very recent git (0.9.1), 'virsh memset --persistent' can
> be used to modify the persistent storage to affect the memory usage on
> the next guest boot.
> 
> Or are you referring to 'virsh memtune', which does indeed require
> cgroup support, but does not require any guest interaction?
> 
> -- 
> Eric Blake   ebl...@redhat.com+1-801-349-2682
> Libvirt virtualization library http://libvirt.org
> 
> [attachment "signature.asc" deleted by Zvi Dubitzky/Haifa/IBM] 

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCHv2 9/9] phyp: another simplification

2011-04-15 Thread Matthias Bolte
2011/4/14 Eric Blake :
> Rather than copying and pasting lots of code, factor it into a
> single helper function.
>
> * src/phyp/phyp_driver.c (phypExecInt): New function.
> (phypGetVIOSPartitionID, phypNumDomainsGeneric, phypGetLparID)
> (phypGetLparMem, phypGetLparCPUGeneric, phypGetRemoteSlot)
> (phypGetVIOSNextSlotNumber, phypAttachDevice)
> (phypGetStoragePoolSize, phypStoragePoolNumOfVolumes)
> (phypNumOfStoragePools, phypInterfaceDestroy)
> (phypInterfaceDefineXML, phypInterfaceLookupByName)
> (phypInterfaceIsActive, phypNumOfInterfaces): Use it.
> ---
>  src/phyp/phyp_driver.c |  316 
> ++--
>  1 files changed, 67 insertions(+), 249 deletions(-)

Okay lets take a look at each instance if stricter parsing is safe or not.

> @@ -267,17 +284,7 @@ phypGetVIOSPartitionID(virConnectPtr conn)
>         virBufferVSprintf(&buf, " -m %s", managed_system);
>     virBufferAddLit(&buf, " -r lpar -F lpar_id,lpar_env"
>                     "|sed -n '/vioserver/ {\n s/,.*$//\n p\n}'");
> -    ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
> -
> -    if (exit_status < 0 || ret == NULL)
> -        goto cleanup;
> -
> -    if (virStrToLong_i(ret, &char_ptr, 10, &id) == -1)
> -        goto cleanup;
> -
> -cleanup:
> -    VIR_FREE(ret);
> -
> +    phypExecInt(session, &buf, conn, &id);
>     return id;
>  }

In this case I'm not sure that your change is safe. The executed
command looks like it requests a table with two columns
lpar_id,lpar_env and the uses some sed construct to pick the line that
contains "vioserver". Then the lpar_id is parsed from the beginning of
that line. I'm not sure that this sed construct just returns the
number from the beginning of the line. If that is the case that your
stricter parsing it safe. But it looks like that's not that case and
ignoring content after the number in the selected line is important.

> @@ -364,17 +368,7 @@ phypNumDomainsGeneric(virConnectPtr conn, unsigned int 
> type)
>         virBufferVSprintf(&buf, " -m %s", managed_system);
>     virBufferVSprintf(&buf, " -F lpar_id,state %s |grep -c '^[0-9]*'",
>                       state);
> -    ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
> -
> -    if (exit_status < 0 || ret == NULL)
> -        goto cleanup;
> -
> -    if (virStrToLong_i(ret, &char_ptr, 10, &ndom) == -1)
> -        goto cleanup;
> -
> -cleanup:
> -    VIR_FREE(ret);
> -
> +    phypExecInt(session, &buf, conn, &ndom);
>     return ndom;
>  }

Here the stricter parsing will be safe as the last grep returns a count.

But I wonder about the last grep. I thought it would be there to count
the number of lines that start with a number, but it doesn't work:

$ printf "aa\n22\n33\n" | grep -c '^[0-9]*'
3

I expected it to print 2 here.

$ printf "aa\n22\n33\n\n" | grep -c '^[0-9]*'
4

So the '^[0-9]*' pattern matches every line. But

$ printf "aa\n22\n33\n\n" | grep -c '^[0-9]+'
0

So the last grep here is just a wc -l.

> @@ -1298,27 +1292,14 @@ phypGetLparID(LIBSSH2_SESSION * session, const char 
> *managed_system,
>  {
>     phyp_driverPtr phyp_driver = conn->privateData;
>     int system_type = phyp_driver->system_type;
> -    int exit_status = 0;
>     int lpar_id = -1;
> -    char *char_ptr;
> -    char *ret = NULL;
>     virBuffer buf = VIR_BUFFER_INITIALIZER;
>
>     virBufferAddLit(&buf, "lssyscfg -r lpar");
>     if (system_type == HMC)
>         virBufferVSprintf(&buf, " -m %s", managed_system);
>     virBufferVSprintf(&buf, " --filter lpar_names=%s -F lpar_id", name);
> -    ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
> -
> -    if (exit_status < 0 || ret == NULL)
> -        goto cleanup;
> -
> -    if (virStrToLong_i(ret, &char_ptr, 10, &lpar_id) == -1)
> -        goto cleanup;
> -
> -cleanup:
> -    VIR_FREE(ret);
> -
> +    phypExecInt(session, &buf, conn, &lpar_id);
>     return lpar_id;
>  }

This one is safe too, as the requested output is just the lpar_id.

> @@ -1397,17 +1375,7 @@ phypGetLparMem(virConnectPtr conn, const char 
> *managed_system, int lpar_id,
>     virBufferVSprintf(&buf,
>                       " -r mem --level lpar -F %s --filter lpar_ids=%d",
>                       type ? "curr_mem" : "curr_max_mem", lpar_id);
> -    ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
> -
> -    if (exit_status < 0 || ret == NULL)
> -        goto cleanup;
> -
> -    if (virStrToLong_i(ret, &char_ptr, 10, &memory) == -1)
> -        goto cleanup;
> -
> -cleanup:
> -    VIR_FREE(ret);
> -
> +    phypExecInt(session, &buf, conn, &memory);
>     return memory;
>  }

This one is safe too, as the requested output is just the curr_mem or
curr_max_mem.

> @@ -1431,17 +1396,7 @@ phypGetLparCPUGeneric(virConnectPtr conn, const char 
> *managed_system,
>     virBufferVSprintf(&buf,
>                       " -r proc --level lpar -F %s --filter lpar_ids=%d",
>                       type ? "curr_max_procs" : "curr_procs", lpar_id);
> -    ret = phy

Re: [libvirt] [PATCHv2 9/9] phyp: another simplification

2011-04-15 Thread Matthias Bolte
2011/4/15 Eric Blake :
> On 04/15/2011 03:01 PM, Matthias Bolte wrote:
>>> +    str = phypExecBuffer(session, buf, &ret, conn, true);
>>> +    if (!str || ret) {
>>> +        VIR_FREE(str);
>>> +        return -1;
>>> +    }
>>> +    ret = virStrToLong_i(str, NULL, 10, result);
>>
>> You made the parsing stricter by passing NULL as second argument to
>> virStrToLong_i. I don't expect it but this might be possible that this
>> breaks the behavior of the driver.
>
> That was an intentional decision of mine (I guess I should have
> documented it better), since the rest of the code was getting the
> character after the parsed integer but doing nothing with it.  In most
> cases, it was like the code _expected_ a newline after the integer (such
> as the output of a sed -c run, where that holds true), but wasn't
> enforcing that expectation.
>
> Should I modify the commit message and push with the newer strict
> behavior, or modify the code to keep the older relaxed behavior (but
> this time add a VIR_WARN if garbage is found after the parse)?
>

See my other mail in this thread for a detailed analysis.

Yes, lets stick to the relaxed parsing and add a VIR_WARN.

Matthias

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list