Re: [libvirt] [PATCH 5/6] virtlockd: make re-exec more robust
On Tue, 10 Dec 2013, Daniel P. Berrange wrote: It would seem to be simpler to instead change the main() method so that --daemon is ignored when re-exec'ing. Yes, that does sound saner. I also noticed that virtlockd attempts to write out a re-exec state file under /var/ even when running unprivileged, when it probably should go under $XDG_RUNTIME_DIR. I'll roll in a fix for this as well. - Michael -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2] virtlockd: make re-exec more robust
- Use $XDG_RUNTIME_DIR for re-exec state file when running unprivileged. - argv[0] may not contain a full path to the binary, however it should contain something that can be looked up in the PATH. Use execvp() to do path lookup on re-exec. - As per list discussion [1], ignore --daemon on re-exec. [1] https://www.redhat.com/archives/libvir-list/2013-December/msg00514.html Signed-off-by: Michael Chapman m...@very.puzzling.org --- src/locking/lock_daemon.c | 128 ++ 1 file changed, 94 insertions(+), 34 deletions(-) diff --git a/src/locking/lock_daemon.c b/src/locking/lock_daemon.c index a6be43c..b405e3a 100644 --- a/src/locking/lock_daemon.c +++ b/src/locking/lock_daemon.c @@ -925,7 +925,41 @@ error: } -#define VIR_LOCK_DAEMON_RESTART_EXEC_FILE LOCALSTATEDIR /run/virtlockd-restart-exec.json +static int +virLockDaemonExecRestartStatePath(bool privileged, + char **state_file) +{ +if (privileged) { +if (VIR_STRDUP(*state_file, LOCALSTATEDIR /run/virtlockd-restart-exec.json) 0) +goto error; +} else { +char *rundir = NULL; +mode_t old_umask; + +if (!(rundir = virGetUserRuntimeDirectory())) +goto error; + +old_umask = umask(077); +if (virFileMakePath(rundir) 0) { +umask(old_umask); +goto error; +} +umask(old_umask); + +if (virAsprintf(state_file, %s/virtlockd-restart-exec.json, rundir) 0) { +VIR_FREE(rundir); +goto error; +} + +VIR_FREE(rundir); +} + +return 0; + +error: +return -1; +} + static char * virLockDaemonGetExecRestartMagic(void) @@ -938,7 +972,10 @@ virLockDaemonGetExecRestartMagic(void) static int -virLockDaemonPostExecRestart(bool privileged) +virLockDaemonPostExecRestart(const char *state_file, + const char *pid_file, + int *pid_file_fd, + bool privileged) { const char *gotmagic; char *wantmagic = NULL; @@ -948,14 +985,14 @@ virLockDaemonPostExecRestart(bool privileged) VIR_DEBUG(Running post-restart exec); -if (!virFileExists(VIR_LOCK_DAEMON_RESTART_EXEC_FILE)) { -VIR_DEBUG(No restart file %s present, - VIR_LOCK_DAEMON_RESTART_EXEC_FILE); +if (!virFileExists(state_file)) { +VIR_DEBUG(No restart state file %s present, + state_file); ret = 0; goto cleanup; } -if (virFileReadAll(VIR_LOCK_DAEMON_RESTART_EXEC_FILE, +if (virFileReadAll(state_file, 1024 * 1024 * 10, /* 10 MB */ state) 0) goto cleanup; @@ -982,13 +1019,18 @@ virLockDaemonPostExecRestart(bool privileged) goto cleanup; } +/* Re-claim PID file now as we will not be daemonizing */ +if (pid_file +(*pid_file_fd = virPidFileAcquirePath(pid_file, getpid())) 0) +goto cleanup; + if (!(lockDaemon = virLockDaemonNewPostExecRestart(object, privileged))) goto cleanup; ret = 1; cleanup: -unlink(VIR_LOCK_DAEMON_RESTART_EXEC_FILE); +unlink(state_file); VIR_FREE(wantmagic); VIR_FREE(state); virJSONValueFree(object); @@ -997,7 +1039,8 @@ cleanup: static int -virLockDaemonPreExecRestart(virNetServerPtr srv, +virLockDaemonPreExecRestart(const char *state_file, +virNetServerPtr srv, char **argv) { virJSONValuePtr child; @@ -1065,15 +1108,15 @@ virLockDaemonPreExecRestart(virNetServerPtr srv, VIR_DEBUG(Saving state %s, state); -if (virFileWriteStr(VIR_LOCK_DAEMON_RESTART_EXEC_FILE, +if (virFileWriteStr(state_file, state, 0700) 0) { virReportSystemError(errno, _(Unable to save state file %s), - VIR_LOCK_DAEMON_RESTART_EXEC_FILE); + state_file); goto cleanup; } -if (execv(argv[0], argv) 0) { +if (execvp(argv[0], argv) 0) { virReportSystemError(errno, %s, _(Unable to restart self)); goto cleanup; @@ -1153,6 +1196,7 @@ int main(int argc, char **argv) { char *pid_file = NULL; int pid_file_fd = -1; char *sock_file = NULL; +char *state_file = NULL; bool implicit_conf = false; mode_t old_umask; bool privileged = false; @@ -1276,21 +1320,13 @@ int main(int argc, char **argv) { VIR_DEBUG(Decided on socket paths '%s', sock_file); -if (godaemon) { -char ebuf[1024]; - -if (chdir(/) 0) { -VIR_ERROR(_(cannot change to root directory: %s), - virStrerror(errno, ebuf, sizeof(ebuf))); -goto cleanup; -} - -if ((statuswrite =
[libvirt] [PATCH] storage_backend_rbd: rename stat variable
This variable shadows the stat(2) function, which only became visible in this scope as of commit 9cac8639. Rename the variable so it doesn't conflict. Signed-off-by: Michael Chapman m...@very.puzzling.org --- src/storage/storage_backend_rbd.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c index b8a553d..4b6f18c 100644 --- a/src/storage/storage_backend_rbd.c +++ b/src/storage/storage_backend_rbd.c @@ -314,8 +314,8 @@ static int virStorageBackendRBDRefreshPool(virConnectPtr conn, goto cleanup; } -struct rados_cluster_stat_t stat; -if (rados_cluster_stat(ptr.cluster, stat) 0) { +struct rados_cluster_stat_t clusterstat; +if (rados_cluster_stat(ptr.cluster, clusterstat) 0) { virReportError(VIR_ERR_INTERNAL_ERROR, %s, _(failed to stat the RADOS cluster)); goto cleanup; @@ -329,13 +329,13 @@ static int virStorageBackendRBDRefreshPool(virConnectPtr conn, goto cleanup; } -pool-def-capacity = stat.kb * 1024; -pool-def-available = stat.kb_avail * 1024; +pool-def-capacity = clusterstat.kb * 1024; +pool-def-available = clusterstat.kb_avail * 1024; pool-def-allocation = poolstat.num_bytes; VIR_DEBUG(Utilization of RBD pool %s: (kb: %llu kb_avail: %llu num_bytes: %llu), - pool-def-source.name, (unsigned long long)stat.kb, - (unsigned long long)stat.kb_avail, + pool-def-source.name, (unsigned long long)clusterstat.kb, + (unsigned long long)clusterstat.kb_avail, (unsigned long long)poolstat.num_bytes); while (true) { -- 1.8.4.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 0/8] Add throttle blkio cgroup support for libvirt
Right now, libvirt only supports the cfq based blkio cgorup, this means if the block devices doesn't use cfq scheduler, the blkio cgroup will loss effect. This patchset adds the throttle blkio cgroup support for libvirt, introduces four elements for domain configuration and extend the virsh command blkiotune. This patchset is a new version of Guan Qiang's patchset ://www.redhat.com/archives/libvir-list/2013-October/msg01066.html Change from v1: 1, rearrange the order of patches 2, change the options/elements of throttle blkio cgroup to consist with disk iotune. 3, fix complie error when cgroup is unavailable. 4, remove virCgroupSetBlkioDevice, split virCgroupSetBlkioDeviceBps and virCgroupSetBlkioDeviceIops Change from Guan Qiang's patchset: 1, split to 8 patches, make logic more clear 2, change the type of read/write iops form unsigned long long to unsigned int, trying to set read/write iops to the value which bigger than max number of unsigned int will fail. 3, fix some logic shortage. Gao feng (8): rename virDomainBlkioDeviceWeightParseXML to virDomainBlkioDeviceParseXML rename virBlkioDeviceWeightArrayClear to virBlkioDeviceArrayClear rename virBlkioDeviceWeightPtr to virBlkioDevicePtr domain: introduce xml elements for throttle blkio cgroup blkio: Setting throttle blkio cgroup for domain virsh: add setting throttle blkio cgroup option to blkiotune qemu: allow to setup throttle blkio cgroup through virsh lxc: allow to setup throttle blkio cgroup through virsh docs/schemas/domaincommon.rng | 28 +- include/libvirt/libvirt.h.in | 45 ++ src/conf/domain_conf.c | 113 +++- src/conf/domain_conf.h | 16 +- src/libvirt_private.syms | 6 +- src/lxc/lxc_cgroup.c | 29 +- src/lxc/lxc_driver.c | 649 - src/qemu/qemu_cgroup.c | 29 +- src/qemu/qemu_driver.c | 443 -- src/util/vircgroup.c | 224 ++- src/util/vircgroup.h | 16 + .../qemuxml2argv-blkiotune-device.xml | 8 + tools/virsh-domain.c | 64 ++ tools/virsh.pod| 36 +- 14 files changed, 1583 insertions(+), 123 deletions(-) -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/8] rename virBlkioDeviceWeightArrayClear to virBlkioDeviceArrayClear
Signed-off-by: Gao feng gaof...@cn.fujitsu.com --- src/conf/domain_conf.c | 8 src/conf/domain_conf.h | 4 ++-- src/libvirt_private.syms | 2 +- src/qemu/qemu_driver.c | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e2219f2..397671a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -882,8 +882,8 @@ virDomainXMLOptionGetNamespace(virDomainXMLOptionPtr xmlopt) void -virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights, - int ndevices) +virBlkioDeviceArrayClear(virBlkioDeviceWeightPtr deviceWeights, + int ndevices) { size_t i; @@ -2050,8 +2050,8 @@ void virDomainDefFree(virDomainDefPtr def) VIR_FREE(def-description); VIR_FREE(def-title); -virBlkioDeviceWeightArrayClear(def-blkio.devices, - def-blkio.ndevices); +virBlkioDeviceArrayClear(def-blkio.devices, + def-blkio.ndevices); VIR_FREE(def-blkio.devices); virDomainWatchdogDefFree(def-watchdog); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 4934911..96598b5 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1911,8 +1911,8 @@ struct _virDomainIdMapDef { }; -void virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights, -int ndevices); +void virBlkioDeviceArrayClear(virBlkioDeviceWeightPtr deviceWeights, + int ndevices); typedef struct _virDomainResourceDef virDomainResourceDef; typedef virDomainResourceDef *virDomainResourceDefPtr; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 3ca20e4..d8f8f7e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -104,7 +104,7 @@ virDomainAuditVcpu; # conf/domain_conf.h -virBlkioDeviceWeightArrayClear; +virBlkioDeviceArrayClear; virDiskNameToBusDeviceIndex; virDiskNameToIndex; virDomainActualNetDefFree; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 1c90798..a7d96a9 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7505,7 +7505,7 @@ error: virReportError(VIR_ERR_INVALID_ARG, _(unable to parse device weight '%s'), deviceWeightStr); cleanup: -virBlkioDeviceWeightArrayClear(result, ndevices); +virBlkioDeviceArrayClear(result, ndevices); VIR_FREE(result); return -1; } @@ -7636,7 +7636,7 @@ qemuDomainSetBlkioParameters(virDomainPtr dom, vm-def-blkio.ndevices, devices, ndevices) 0) ret = -1; -virBlkioDeviceWeightArrayClear(devices, ndevices); +virBlkioDeviceArrayClear(devices, ndevices); VIR_FREE(devices); } } @@ -7673,7 +7673,7 @@ qemuDomainSetBlkioParameters(virDomainPtr dom, persistentDef-blkio.ndevices, devices, ndevices) 0) ret = -1; -virBlkioDeviceWeightArrayClear(devices, ndevices); +virBlkioDeviceArrayClear(devices, ndevices); VIR_FREE(devices); } } -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/8] rename virDomainBlkioDeviceWeightParseXML to virDomainBlkioDeviceParseXML
virDomainBlkioDeviceWeightParseXML will be used to parse the xml element read_bps, write_bps, read_iops, write_iops. Signed-off-by: Gao feng gaof...@cn.fujitsu.com --- src/conf/domain_conf.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e0ab4b1..e2219f2 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -892,7 +892,7 @@ virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights, } /** - * virDomainBlkioDeviceWeightParseXML + * virDomainBlkioDeviceParseXML * * this function parses a XML node: * @@ -904,8 +904,8 @@ virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights, * and fills a virBlkioDeviceWeight struct. */ static int -virDomainBlkioDeviceWeightParseXML(xmlNodePtr root, - virBlkioDeviceWeightPtr dw) +virDomainBlkioDeviceParseXML(xmlNodePtr root, + virBlkioDeviceWeightPtr dw) { char *c; xmlNodePtr node; @@ -11097,8 +11097,8 @@ virDomainDefParseXML(xmlDocPtr xml, for (i = 0; i n; i++) { size_t j; -if (virDomainBlkioDeviceWeightParseXML(nodes[i], - def-blkio.devices[i]) 0) +if (virDomainBlkioDeviceParseXML(nodes[i], + def-blkio.devices[i]) 0) goto error; def-blkio.ndevices++; for (j = 0; j i; j++) { -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/8] rename virBlkioDeviceWeightPtr to virBlkioDevicePtr
The throttle blkio cgroup will reuse this struct. Signed-off-by: Gao feng gaof...@cn.fujitsu.com --- src/conf/domain_conf.c | 18 +- src/conf/domain_conf.h | 10 +- src/lxc/lxc_cgroup.c | 6 +++--- src/qemu/qemu_cgroup.c | 8 src/qemu/qemu_driver.c | 18 +- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 397671a..26242b6 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -882,13 +882,13 @@ virDomainXMLOptionGetNamespace(virDomainXMLOptionPtr xmlopt) void -virBlkioDeviceArrayClear(virBlkioDeviceWeightPtr deviceWeights, +virBlkioDeviceArrayClear(virBlkioDevicePtr devices, int ndevices) { size_t i; for (i = 0; i ndevices; i++) -VIR_FREE(deviceWeights[i].path); +VIR_FREE(devices[i].path); } /** @@ -901,11 +901,11 @@ virBlkioDeviceArrayClear(virBlkioDeviceWeightPtr deviceWeights, * weightweight/weight * /device * - * and fills a virBlkioDeviceWeight struct. + * and fills a virBlkioDeviceTune struct. */ static int virDomainBlkioDeviceParseXML(xmlNodePtr root, - virBlkioDeviceWeightPtr dw) + virBlkioDevicePtr dev) { char *c; xmlNodePtr node; @@ -913,16 +913,16 @@ virDomainBlkioDeviceParseXML(xmlNodePtr root, node = root-children; while (node) { if (node-type == XML_ELEMENT_NODE) { -if (xmlStrEqual(node-name, BAD_CAST path) !dw-path) { -dw-path = (char *)xmlNodeGetContent(node); +if (xmlStrEqual(node-name, BAD_CAST path) !dev-path) { +dev-path = (char *)xmlNodeGetContent(node); } else if (xmlStrEqual(node-name, BAD_CAST weight)) { c = (char *)xmlNodeGetContent(node); -if (virStrToLong_ui(c, NULL, 10, dw-weight) 0) { +if (virStrToLong_ui(c, NULL, 10, dev-weight) 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _(could not parse weight %s), c); VIR_FREE(c); -VIR_FREE(dw-path); +VIR_FREE(dev-path); return -1; } VIR_FREE(c); @@ -930,7 +930,7 @@ virDomainBlkioDeviceParseXML(xmlNodePtr root, } node = node-next; } -if (!dw-path) { +if (!dev-path) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, _(missing per-device path)); return -1; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 96598b5..b410fd0 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1860,9 +1860,9 @@ virDomainVcpuPinDefPtr virDomainVcpuPinFindByVcpu(virDomainVcpuPinDefPtr *def, int nvcpupin, int vcpu); -typedef struct _virBlkioDeviceWeight virBlkioDeviceWeight; -typedef virBlkioDeviceWeight *virBlkioDeviceWeightPtr; -struct _virBlkioDeviceWeight { +typedef struct _virBlkioDevice virBlkioDevice; +typedef virBlkioDevice *virBlkioDevicePtr; +struct _virBlkioDevice { char *path; unsigned int weight; }; @@ -1911,7 +1911,7 @@ struct _virDomainIdMapDef { }; -void virBlkioDeviceArrayClear(virBlkioDeviceWeightPtr deviceWeights, +void virBlkioDeviceArrayClear(virBlkioDevicePtr deviceWeights, int ndevices); typedef struct _virDomainResourceDef virDomainResourceDef; @@ -1940,7 +1940,7 @@ struct _virDomainDef { unsigned int weight; size_t ndevices; -virBlkioDeviceWeightPtr devices; +virBlkioDevicePtr devices; } blkio; struct { diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c index 275e250..310a476 100644 --- a/src/lxc/lxc_cgroup.c +++ b/src/lxc/lxc_cgroup.c @@ -112,10 +112,10 @@ static int virLXCCgroupSetupBlkioTune(virDomainDefPtr def, if (def-blkio.ndevices) { for (i = 0; i def-blkio.ndevices; i++) { -virBlkioDeviceWeightPtr dw = def-blkio.devices[i]; -if (!dw-weight) +virBlkioDevicePtr dev = def-blkio.devices[i]; +if (!dev-weight) continue; -if (virCgroupSetBlkioDeviceWeight(cgroup, dw-path, dw-weight) 0) +if (virCgroupSetBlkioDeviceWeight(cgroup, dev-path, dev-weight) 0) return -1; } } diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index f0cacd0..a18955e 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -399,11 +399,11 @@ qemuSetupBlkioCgroup(virDomainObjPtr vm) if (vm-def-blkio.ndevices) { for (i = 0; i vm-def-blkio.ndevices; i++) { -virBlkioDeviceWeightPtr dw = vm-def-blkio.devices[i]; -if (!dw-weight) +
[libvirt] [PATCH 6/8] virsh: add setting throttle blkio cgroup option to blkiotune
With this patch, user can setup the throttle blkio cgorup for domain through the virsh cmd, such as: virsh blkiotune domain1 --device-read-bytes-sec /dev/sda1,100,/dev/sda2,200 --device-write-bytes-sec /dev/sda1,100 --device-read-iops-sec /dev/sda1,1 --device-write-iops-sec /dev/sda1,1,/dev/sda2,0 This patch also add manpage for these new options. Signed-off-by: Guan Qiang hzguanqi...@corp.netease.com Signed-off-by: Gao feng gaof...@cn.fujitsu.com --- include/libvirt/libvirt.h.in | 45 +++ tools/virsh-domain.c | 64 tools/virsh.pod | 36 +++-- 3 files changed, 143 insertions(+), 2 deletions(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 29d4dce..9ebf3c4 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1806,6 +1806,51 @@ char * virDomainGetSchedulerType(virDomainPtr domain, #define VIR_DOMAIN_BLKIO_DEVICE_WEIGHT device_weight +/** + * VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS: + * + * Macro for the blkio tunable throttle.read_iops_device: it represents + * the number of reading the block device per second, as a string. The + * string is parsed as a series of /path/to/device, read_iops elements, + * separated by ','. + */ + +#define VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS device_read_iops_sec + + +/** + * VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS: + * + * Macro for the blkio tunable throttle.write_iops_device: it represents + * the number of writing the block device per second, as a string. The + * string is parsed as a series of /path/to/device, write_iops elements, + * separated by ','. + */ +#define VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS device_write_iops_sec + + +/** + * VIR_DOMAIN_BLKIO_DEVICE_READ_BPS: + * + * Macro for the blkio tunable throttle.read_iops_device: it represents + * the bytes of reading the block device per second, as a string. The + * string is parsed as a series of /path/to/device, read_bps elements, + * separated by ','. + */ +#define VIR_DOMAIN_BLKIO_DEVICE_READ_BPS device_read_bytes_sec + + +/** + * VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS: + * + * Macro for the blkio tunable throttle.read_iops_device: it represents + * the number of reading the block device per second, as a string. The + * string is parsed as a series of /path/to/device, write_bps elements, + * separated by ','. + */ +#define VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS device_write_bytes_sec + + /* Set Blkio tunables for the domain*/ int virDomainSetBlkioParameters(virDomainPtr domain, virTypedParameterPtr params, diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 8b80e1e..f7e7959 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -1250,6 +1250,22 @@ static const vshCmdOptDef opts_blkiotune[] = { .type = VSH_OT_STRING, .help = N_(per-device IO Weights, in the form of /path/to/device,weight,...) }, +{.name = device-read-iops-sec, + .type = VSH_OT_STRING, + .help = N_(per-device read I/O limit per second, in the form of /path/to/device,read_iops_sec,...) +}, +{.name = device-write-iops-sec, + .type = VSH_OT_STRING, + .help = N_(per-device write I/O limit per second, in the form of /path/to/device,write_iops_sec,...) +}, +{.name = device-read-bytes-sec, + .type = VSH_OT_STRING, + .help = N_(per-device bytes read per second, in the form of /path/to/device,read_bytes_sec,...) +}, +{.name = device-write-bytes-sec, + .type = VSH_OT_STRING, + .help = N_(per-device bytes wrote per second, in the form of /path/to/device,write_bytes_sec,...) +}, {.name = config, .type = VSH_OT_BOOL, .help = N_(affect next boot) @@ -1270,6 +1286,10 @@ cmdBlkiotune(vshControl * ctl, const vshCmd * cmd) { virDomainPtr dom; const char *device_weight = NULL; +const char *device_riops = NULL; +const char *device_wiops = NULL; +const char *device_rbps = NULL; +const char *device_wbps = NULL; int weight = 0; int nparams = 0; int maxparams = 0; @@ -1317,6 +1337,50 @@ cmdBlkiotune(vshControl * ctl, const vshCmd * cmd) goto save_error; } +rv = vshCommandOptString(cmd, device-read-iops-sec, device_riops); +if (rv 0) { +vshError(ctl, %s, _(Unable to parse string parameter)); +goto cleanup; +} else if (rv 0) { +if (virTypedParamsAddString(params, nparams, maxparams, +VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS, +device_riops) 0) +goto save_error; +} + +rv = vshCommandOptString(cmd, device-write-iops-sec, device_wiops); +if (rv 0) { +vshError(ctl, %s, _(Unable to parse string parameter)); +goto cleanup; +} else if (rv 0) { +if (virTypedParamsAddString(params, nparams, maxparams, +
[libvirt] [PATCH 8/8] lxc: allow to setup throttle blkio cgroup through virsh
With this patch,user can set throttle blkio cgroup for lxc domain through virsh tool. The functions are copied from qemu_driver. Signed-off-by: Guan Qiang hzguanqi...@corp.netease.com Signed-off-by: Gao feng gaof...@cn.fujitsu.com --- src/lxc/lxc_driver.c | 649 +-- 1 file changed, 624 insertions(+), 25 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index c499182..1f73b52 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -1545,6 +1545,20 @@ static int lxcStateCleanup(void) return 0; } +static int +lxcConnectSupportsFeature(virConnectPtr conn, int feature) +{ +if (virConnectSupportsFeatureEnsureACL(conn) 0) +return -1; + +switch (feature) { +case VIR_DRV_FEATURE_TYPED_PARAM_STRING: +return 1; +default: +return 0; +} +} + static int lxcConnectGetVersion(virConnectPtr conn, unsigned long *version) { @@ -1910,6 +1924,159 @@ lxcDomainGetSchedulerParameters(virDomainPtr domain, return lxcDomainGetSchedulerParametersFlags(domain, params, nparams, 0); } +static int +lxcDomainParseBlkioDeviceStr(char *blkioDeviceStr, const char *type, + virBlkioDevicePtr *dev, size_t *size) +{ +char *temp; +int ndevices = 0; +int nsep = 0; +size_t i; +virBlkioDevicePtr result = NULL; + +*dev = NULL; +*size = 0; + +if (STREQ(blkioDeviceStr, )) +return 0; + +temp = blkioDeviceStr; +while (temp) { +temp = strchr(temp, ','); +if (temp) { +temp++; +nsep++; +} +} + +/* A valid string must have even number of fields, hence an odd + * number of commas. */ +if (!(nsep 1)) +goto error; + +ndevices = (nsep + 1) / 2; + +if (VIR_ALLOC_N(result, ndevices) 0) +return -1; + +i = 0; +temp = blkioDeviceStr; +while (temp) { +char *p = temp; + +/* device path */ +p = strchr(p, ','); +if (!p) +goto error; + +if (VIR_STRNDUP(result[i].path, temp, p - temp) 0) +goto cleanup; + +/* value */ +temp = p + 1; + +if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) { +if (virStrToLong_ui(temp, p, 10, result[i].weight) 0) +goto error; +} else if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS)) { +if (virStrToLong_ui(temp, p, 10, result[i].riops) 0) +goto error; +} else if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS)) { +if (virStrToLong_ui(temp, p, 10, result[i].wiops) 0) +goto error; +} else if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS)) { +if (virStrToLong_ull(temp, p, 10, result[i].rbps) 0) +goto error; +} else { +if (virStrToLong_ull(temp, p, 10, result[i].wbps) 0) +goto error; +} + +i++; + +if (*p == '\0') +break; +else if (*p != ',') +goto error; +temp = p + 1; +} + +if (!i) +VIR_FREE(result); + +*dev = result; +*size = i; + +return 0; + +error: +virReportError(VIR_ERR_INVALID_ARG, + _(unable to parse device weight '%s'), blkioDeviceStr); +cleanup: +virBlkioDeviceArrayClear(result, ndevices); +VIR_FREE(result); +return -1; +} + +static int +lxcDomainMergeBlkioDevice(virBlkioDevicePtr *dest_array, + size_t *dest_size, + virBlkioDevicePtr src_array, + size_t src_size, + const char *type) +{ +size_t i, j; +virBlkioDevicePtr dest, src; + +for (i = 0; i src_size; i++) { +bool found = false; + +src = src_array[i]; +for (j = 0; j *dest_size; j++) { +dest = (*dest_array)[j]; +if (STREQ(src-path, dest-path)) { +found = true; + +if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) +dest-weight = src-weight; +else if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS)) +dest-riops = src-riops; +else if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS)) +dest-wiops = src-wiops; +else if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS)) +dest-rbps = src-rbps; +else +dest-wbps = src-wbps; + +break; +} +} +if (!found) { +if (!src-weight !src-riops !src-wiops !src-rbps !src-wbps) +continue; +if (VIR_EXPAND_N(*dest_array, *dest_size, 1) 0) +return -1; +dest = (*dest_array)[*dest_size - 1]; +dest-path = src-path; + +if (STREQ(type,
[libvirt] [PATCH 4/8] domain: introduce xml elements for throttle blkio cgroup
This patch introduces new xml elements under blkiotune, we use these new elements to setup the throttle blkio cgroup for domain. The new blkiotune node looks like this: blkiotune device path/path/to/block/path weight1000/weight read_iops_sec1/read_iops_sec write_iops_sec1/write_iops_sec read_bytes_sec100/read_bytes_sec write_bytes_sec100/write_bytes_sec /device /blkiotune Signed-off-by: Guan Qiang hzguanqi...@corp.netease.com Signed-off-by: Gao feng gaof...@cn.fujitsu.com --- docs/schemas/domaincommon.rng | 28 -- src/conf/domain_conf.c| 85 +-- src/conf/domain_conf.h| 4 ++ 3 files changed, 103 insertions(+), 14 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 38c6801..bc8ed5d 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -621,9 +621,31 @@ element name=path ref name=absFilePath/ /element - element name=weight -ref name=weight/ - /element + optional +element name=weight + ref name=weight/ +/element + /optional + optional +element name=read_iops_sec + data type='unsignedInt'/ +/element + /optional + optional +element name=write_iops_sec + data type='unsignedInt'/ +/element + /optional + optional +element name=read_bytes_sec + data type='unsignedLong'/ +/element + /optional + optional +element name=write_bytes_sec + data type='unsignedLong'/ +/element + /optional /interleave /element /zeroOrMore diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 26242b6..c4d51b4 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -899,15 +899,19 @@ virBlkioDeviceArrayClear(virBlkioDevicePtr devices, * device * path/fully/qualified/device/path/path * weightweight/weight + * read_bytes_secbps/read_bytes_sec + * write_bytes_secbps/write_bytes_sec + * read_iops_seciops/read_iops_sec + * write_iops_seciops/write_iops_sec * /device * - * and fills a virBlkioDeviceTune struct. + * and fills a virBlkioDevicePtr struct. */ static int virDomainBlkioDeviceParseXML(xmlNodePtr root, virBlkioDevicePtr dev) { -char *c; +char *c = NULL; xmlNodePtr node; node = root-children; @@ -921,9 +925,43 @@ virDomainBlkioDeviceParseXML(xmlNodePtr root, virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _(could not parse weight %s), c); -VIR_FREE(c); -VIR_FREE(dev-path); -return -1; +goto error; +} +VIR_FREE(c); +} else if (xmlStrEqual(node-name, BAD_CAST read_bytes_sec)) { +c = (char *)xmlNodeGetContent(node); +if (virStrToLong_ull(c, NULL, 10, dev-rbps) 0) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(could not parse read bytes sec %s), + c); +goto error; +} +VIR_FREE(c); +} else if (xmlStrEqual(node-name, BAD_CAST write_bytes_sec)) { +c = (char *)xmlNodeGetContent(node); +if (virStrToLong_ull(c, NULL, 10, dev-wbps) 0) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(could not parse write bytes sec %s), + c); +goto error; +} +VIR_FREE(c); +} else if (xmlStrEqual(node-name, BAD_CAST read_iops_sec)) { +c = (char *)xmlNodeGetContent(node); +if (virStrToLong_ui(c, NULL, 10, dev-riops) 0) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(could not parse read iops sec %s), + c); +goto error; +} +VIR_FREE(c); +} else if (xmlStrEqual(node-name, BAD_CAST write_iops_sec)) { +c = (char *)xmlNodeGetContent(node); +if (virStrToLong_ui(c, NULL, 10, dev-wiops) 0) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(could not parse write iops sec %s), + c); +goto
Re: [libvirt] ANNOUNCE: ruby-libvirt 0.5.0
On 11/12/13 01:31, Chris Lalancette wrote: On Tue, Dec 10, 2013 at 8:35 AM, Chris Lalancette clalance...@gmail.com wrote: gcc -I. -I. -I/usr/local/rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/x86_64-linux -I. -DRUBY_EXTCONF_H=\extconf.h\-fPIC -g -O2 -fPIC -c common.c common.c: In function ‘ruby_libvirt_typed_parameter_assign’: common.c:385: error: ‘ST_CONTINUE’ undeclared (first use in this function) common.c:385: error: (Each undeclared identifier is reported only once common.c:385: error: for each function it appears in.) common.c: In function ‘ruby_libvirt_set_typed_parameters’: common.c:405: error: dereferencing pointer to incomplete type make: *** [common.o] Error 1 Yeah, it turns out that ST_CONTINUE is in st.h in ruby 1.8 and ruby/st.h in later versions. Luckily the old st.h still works on later version (albeit with a warning). I fixed that, and also added a compatibility hack in the Rakefile that allows it to build on ruby 1.8. With both of those in place, I'm now able to build on CentOS-6.4. I've pushed these compatibility hacks to the main ruby-libvirt repository. At the moment, I'm not planning to put out a new release for this minor fix. Dominic, if you really want this in an official release, let me know and I can do a 0.5.1. Otherwise I'll just let you handle it when building a package for RHEL-6/CentOS-6. Thanks again for the bug report. Thanks for the fix Chris. A new release would be much appreciated as we're hitting this issue on gems, not RPMs. Our CI for Foreman (http://theforeman.org/) runs under a few Ruby versions and picked up this new version of the gem, so we'll need to pin to 0.5 otherwise. Regards, -- Dominic Cleal Red Hat Engineering -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 5/8] blkio: Setting throttle blkio cgroup for domain
This patch introduces virCgroupSetBlkioDeviceReadIops, virCgroupSetBlkioDeviceWriteIops, virCgroupSetBlkioDeviceReadBps and virCgroupSetBlkioDeviceWriteBps, we can use these interfaces to set up throttle blkio cgroup for domain. This patch also adds the new throttle blkio cgroup elements to the test xml. Signed-off-by: Guan Qiang hzguanqi...@corp.netease.com Signed-off-by: Gao feng gaof...@cn.fujitsu.com --- src/libvirt_private.syms | 4 + src/lxc/lxc_cgroup.c | 27 ++- src/qemu/qemu_cgroup.c | 27 ++- src/util/vircgroup.c | 224 - src/util/vircgroup.h | 16 ++ .../qemuxml2argv-blkiotune-device.xml | 8 + 6 files changed, 295 insertions(+), 11 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d8f8f7e..a535bf3 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1031,7 +1031,11 @@ virCgroupNewVcpu; virCgroupPathOfController; virCgroupRemove; virCgroupRemoveRecursively; +virCgroupSetBlkioDeviceReadBps; +virCgroupSetBlkioDeviceReadIops; virCgroupSetBlkioDeviceWeight; +virCgroupSetBlkioDeviceWriteBps; +virCgroupSetBlkioDeviceWriteIops; virCgroupSetBlkioWeight; virCgroupSetCpuCfsPeriod; virCgroupSetCpuCfsQuota; diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c index 310a476..cc0d5e8 100644 --- a/src/lxc/lxc_cgroup.c +++ b/src/lxc/lxc_cgroup.c @@ -113,9 +113,30 @@ static int virLXCCgroupSetupBlkioTune(virDomainDefPtr def, if (def-blkio.ndevices) { for (i = 0; i def-blkio.ndevices; i++) { virBlkioDevicePtr dev = def-blkio.devices[i]; -if (!dev-weight) -continue; -if (virCgroupSetBlkioDeviceWeight(cgroup, dev-path, dev-weight) 0) + +if (dev-weight +(virCgroupSetBlkioDeviceWeight(cgroup, dev-path, + dev-weight) 0)) +return -1; + +if (dev-riops +(virCgroupSetBlkioDeviceReadIops(cgroup, dev-path, + dev-riops) 0)) +return -1; + +if (dev-wiops +(virCgroupSetBlkioDeviceWriteIops(cgroup, dev-path, + dev-wiops) 0)) +return -1; + +if (dev-rbps +(virCgroupSetBlkioDeviceReadBps(cgroup, dev-path, +dev-rbps) 0)) +return -1; + +if (dev-wbps +(virCgroupSetBlkioDeviceWriteBps(cgroup, dev-path, + dev-wbps) 0)) return -1; } } diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index a18955e..1cc929c 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -400,10 +400,29 @@ qemuSetupBlkioCgroup(virDomainObjPtr vm) if (vm-def-blkio.ndevices) { for (i = 0; i vm-def-blkio.ndevices; i++) { virBlkioDevicePtr dev = vm-def-blkio.devices[i]; -if (!dev-weight) -continue; -if (virCgroupSetBlkioDeviceWeight(priv-cgroup, dev-path, - dev-weight) 0) +if (dev-weight +(virCgroupSetBlkioDeviceWeight(priv-cgroup, dev-path, + dev-weight) 0)) +return -1; + +if (dev-riops +(virCgroupSetBlkioDeviceReadIops(priv-cgroup, dev-path, + dev-riops) 0)) +return -1; + +if (dev-wiops +(virCgroupSetBlkioDeviceWriteIops(priv-cgroup, dev-path, + dev-wiops) 0)) +return -1; + +if (dev-rbps +(virCgroupSetBlkioDeviceReadBps(priv-cgroup, dev-path, +dev-rbps) 0)) +return -1; + +if (dev-wbps +(virCgroupSetBlkioDeviceWriteBps(priv-cgroup, dev-path, + dev-wbps) 0)) return -1; } } diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index 43eb649..a6d60c5 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -1824,12 +1824,189 @@ virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight) return ret; } +/** + * virCgroupSetBlkioDeviceReadIops: + * @group: The cgroup to change block io setting for + * @path: The path of device + * @riops: The new device read iops throttle, or 0 to clear + * + * Returns: 0 on success, -1 on error + */ +int +virCgroupSetBlkioDeviceReadIops(virCgroupPtr group, +const char *path, +
[libvirt] [PATCH 7/8] qemu: allow to setup throttle blkio cgroup through virsh
With this patch, user can setup throttle blkio cgroup through virsh for qemu domain. Signed-off-by: Guan Qiang hzguanqi...@corp.netease.com Signed-off-by: Gao feng gaof...@cn.fujitsu.com --- src/qemu/qemu_driver.c | 425 - 1 file changed, 386 insertions(+), 39 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 45d11cd..0300db9 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -131,7 +131,7 @@ # define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */ #endif -#define QEMU_NB_BLKIO_PARAM 2 +#define QEMU_NB_BLKIO_PARAM 6 #define QEMU_NB_BANDWIDTH_PARAM 6 @@ -7427,12 +7427,12 @@ cleanup: return ret; } -/* deviceWeightStr in the form of /device/path,weight,/device/path,weight +/* blkioDeviceStr in the form of /device/path,weight,/device/path,weight * for example, /dev/disk/by-path/pci-:00:1f.2-scsi-0:0:0:0,800 */ static int -qemuDomainParseDeviceWeightStr(char *deviceWeightStr, - virBlkioDevicePtr *dev, size_t *size) +qemuDomainParseBlkioDeviceStr(char *blkioDeviceStr, const char *type, + virBlkioDevicePtr *dev, size_t *size) { char *temp; int ndevices = 0; @@ -7443,10 +7443,10 @@ qemuDomainParseDeviceWeightStr(char *deviceWeightStr, *dev = NULL; *size = 0; -if (STREQ(deviceWeightStr, )) +if (STREQ(blkioDeviceStr, )) return 0; -temp = deviceWeightStr; +temp = blkioDeviceStr; while (temp) { temp = strchr(temp, ','); if (temp) { @@ -7466,7 +7466,7 @@ qemuDomainParseDeviceWeightStr(char *deviceWeightStr, return -1; i = 0; -temp = deviceWeightStr; +temp = blkioDeviceStr; while (temp) { char *p = temp; @@ -7478,11 +7478,25 @@ qemuDomainParseDeviceWeightStr(char *deviceWeightStr, if (VIR_STRNDUP(result[i].path, temp, p - temp) 0) goto cleanup; -/* weight */ +/* value */ temp = p + 1; -if (virStrToLong_ui(temp, p, 10, result[i].weight) 0) -goto error; +if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) { +if (virStrToLong_ui(temp, p, 10, result[i].weight) 0) +goto error; +} else if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS)) { +if (virStrToLong_ui(temp, p, 10, result[i].riops) 0) +goto error; +} else if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS)) { +if (virStrToLong_ui(temp, p, 10, result[i].wiops) 0) +goto error; +} else if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS)) { +if (virStrToLong_ull(temp, p, 10, result[i].rbps) 0) +goto error; +} else { +if (virStrToLong_ull(temp, p, 10, result[i].wbps) 0) +goto error; +} i++; @@ -7503,20 +7517,21 @@ qemuDomainParseDeviceWeightStr(char *deviceWeightStr, error: virReportError(VIR_ERR_INVALID_ARG, - _(unable to parse device weight '%s'), deviceWeightStr); + _(unable to parse blkio device '%s'), blkioDeviceStr); cleanup: virBlkioDeviceArrayClear(result, ndevices); VIR_FREE(result); return -1; } -/* Modify dest_array to reflect all device weight changes described in +/* Modify dest_array to reflect all blkio device changes described in * src_array. */ static int -qemuDomainMergeDeviceWeights(virBlkioDevicePtr *dest_array, - size_t *dest_size, - virBlkioDevicePtr src_array, - size_t src_size) +qemuDomainMergeBlkioDevice(virBlkioDevicePtr *dest_array, + size_t *dest_size, + virBlkioDevicePtr src_array, + size_t src_size, + const char *type) { size_t i, j; virBlkioDevicePtr dest, src; @@ -7529,18 +7544,40 @@ qemuDomainMergeDeviceWeights(virBlkioDevicePtr *dest_array, dest = (*dest_array)[j]; if (STREQ(src-path, dest-path)) { found = true; -dest-weight = src-weight; + +if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) +dest-weight = src-weight; +else if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS)) +dest-riops = src-riops; +else if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS)) +dest-wiops = src-wiops; +else if (STREQ(type, VIR_DOMAIN_BLKIO_DEVICE_READ_BPS)) +dest-rbps = src-rbps; +else +dest-wbps = src-wbps; + break; } } if (!found) { -if (!src-weight) +if (!src-weight !src-riops src-wiops src-rbps src-wbps)
[libvirt] [PATCH 0/2] Fix interface state transitions logic
Right now it's possible to start an interface that is already running, or destroy an interface multiple times. Such state transitions are not allowed and we check for such cases explicitly in other areas like qemu driver. Michal Privoznik (2): interface: Introduce netcfInterfaceObjIsActive interface: Take interface status into account when starting and destroying src/interface/interface_backend_netcf.c | 77 +++-- 1 file changed, 53 insertions(+), 24 deletions(-) -- 1.8.5.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/2] interface: Introduce netcfInterfaceObjIsActive
This function barely wraps ncf_if_status() and error handling code. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- src/interface/interface_backend_netcf.c | 57 +++-- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/src/interface/interface_backend_netcf.c b/src/interface/interface_backend_netcf.c index c4e18c4..2e681ec 100644 --- a/src/interface/interface_backend_netcf.c +++ b/src/interface/interface_backend_netcf.c @@ -238,6 +238,32 @@ static struct netcf_if *interfaceDriverGetNetcfIF(struct netcf *ncf, virInterfac return iface; } +static int +netcfInterfaceObjIsActive(struct netcf_if *iface, + bool *active) +{ +int ret = -1; +unsigned int flags = 0; + +virObjectRef(driverState); +if (ncf_if_status(iface, flags) 0) { +const char *errmsg, *details; +int errcode = ncf_error(driverState-netcf, errmsg, details); +virReportError(netcf_to_vir_err(errcode), + _(failed to get status of interface %s: %s%s%s), + ncf_if_name(iface), errmsg, details ? - : , + details ? details : ); +goto cleanup; +} + +*active = flags NETCF_IFACE_ACTIVE; +ret = 0; + +cleanup: +virObjectUnref(driverState); +return ret; +} + static virDrvOpenStatus netcfInterfaceOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, @@ -539,7 +565,7 @@ netcfConnectListAllInterfaces(virConnectPtr conn, struct netcf_if *iface = NULL; virInterfacePtr *tmp_iface_objs = NULL; virInterfacePtr iface_obj = NULL; -unsigned int status; +bool active; int niface_objs = 0; int ret = -1; char **names = NULL; @@ -611,15 +637,8 @@ netcfConnectListAllInterfaces(virConnectPtr conn, } } -if (ncf_if_status(iface, status) 0) { -const char *errmsg, *details; -int errcode = ncf_error(driver-netcf, errmsg, details); -virReportError(netcf_to_vir_err(errcode), - _(failed to get status of interface %s: %s%s%s), - names[i], errmsg, details ? - : , - details ? details : ); +if (netcfInterfaceObjIsActive(iface, active) 0) goto cleanup; -} if (!(def = netcfGetMinimalDefForDevice(iface))) goto cleanup; @@ -636,10 +655,8 @@ netcfConnectListAllInterfaces(virConnectPtr conn, * except active|inactive are supported. */ if (MATCH(VIR_CONNECT_LIST_INTERFACES_FILTERS_ACTIVE) -!((MATCH(VIR_CONNECT_LIST_INTERFACES_ACTIVE) - (status NETCF_IFACE_ACTIVE)) || - (MATCH(VIR_CONNECT_LIST_INTERFACES_INACTIVE) - (status NETCF_IFACE_INACTIVE { +!((MATCH(VIR_CONNECT_LIST_INTERFACES_ACTIVE) active) || + (MATCH(VIR_CONNECT_LIST_INTERFACES_INACTIVE) !active))) { ncf_if_free(iface); iface = NULL; continue; @@ -1010,9 +1027,9 @@ static int netcfInterfaceIsActive(virInterfacePtr ifinfo) { virNetcfDriverStatePtr driver = ifinfo-conn-interfacePrivateData; struct netcf_if *iface = NULL; -unsigned int flags = 0; virInterfaceDefPtr def = NULL; int ret = -1; +bool active; virObjectLock(driver); @@ -1022,24 +1039,16 @@ static int netcfInterfaceIsActive(virInterfacePtr ifinfo) goto cleanup; } - if (!(def = netcfGetMinimalDefForDevice(iface))) goto cleanup; if (virInterfaceIsActiveEnsureACL(ifinfo-conn, def) 0) goto cleanup; -if (ncf_if_status(iface, flags) 0) { -const char *errmsg, *details; -int errcode = ncf_error(driver-netcf, errmsg, details); -virReportError(netcf_to_vir_err(errcode), - _(failed to get status of interface %s: %s%s%s), - ifinfo-name, errmsg, details ? - : , - details ? details : ); +if (netcfInterfaceObjIsActive(iface, active) 0) goto cleanup; -} -ret = flags NETCF_IFACE_ACTIVE ? 1 : 0; +ret = active ? 1 : 0; cleanup: ncf_if_free(iface); -- 1.8.5.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/2] interface: Take interface status into account when starting and destroying
https://bugzilla.redhat.com/show_bug.cgi?id=956994 Currently, it is possible to start an interface that is already running: # virsh iface-start eth2 Interface eth2 started # echo $? 0 # virsh iface-start eth2 Interface eth2 started # echo $? 0 # virsh iface-start eth2 Interface eth2 started # echo $? 0 Same applies for destroying a dead interface. We should not allow such state transitions. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- src/interface/interface_backend_netcf.c | 20 1 file changed, 20 insertions(+) diff --git a/src/interface/interface_backend_netcf.c b/src/interface/interface_backend_netcf.c index 2e681ec..c525ca9 100644 --- a/src/interface/interface_backend_netcf.c +++ b/src/interface/interface_backend_netcf.c @@ -944,6 +944,7 @@ static int netcfInterfaceCreate(virInterfacePtr ifinfo, struct netcf_if *iface = NULL; virInterfaceDefPtr def = NULL; int ret = -1; +bool active; virCheckFlags(0, -1); @@ -962,6 +963,15 @@ static int netcfInterfaceCreate(virInterfacePtr ifinfo, if (virInterfaceCreateEnsureACL(ifinfo-conn, def) 0) goto cleanup; +if (netcfInterfaceObjIsActive(iface, active) 0) +goto cleanup; + +if (active) { +virReportError(VIR_ERR_OPERATION_INVALID, %s, + _(interface is already running)); +goto cleanup; +} + ret = ncf_if_up(iface); if (ret 0) { const char *errmsg, *details; @@ -987,6 +997,7 @@ static int netcfInterfaceDestroy(virInterfacePtr ifinfo, struct netcf_if *iface = NULL; virInterfaceDefPtr def = NULL; int ret = -1; +bool active; virCheckFlags(0, -1); @@ -1005,6 +1016,15 @@ static int netcfInterfaceDestroy(virInterfacePtr ifinfo, if (virInterfaceDestroyEnsureACL(ifinfo-conn, def) 0) goto cleanup; +if (netcfInterfaceObjIsActive(iface, active) 0) +goto cleanup; + +if (!active) { +virReportError(VIR_ERR_OPERATION_INVALID, %s, + _(interface is not running)); +goto cleanup; +} + ret = ncf_if_down(iface); if (ret 0) { const char *errmsg, *details; -- 1.8.5.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] storage_backend_rbd: rename stat variable
On 11.12.2013 09:14, Michael Chapman wrote: This variable shadows the stat(2) function, which only became visible in this scope as of commit 9cac8639. Rename the variable so it doesn't conflict. Signed-off-by: Michael Chapman m...@very.puzzling.org --- src/storage/storage_backend_rbd.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c index b8a553d..4b6f18c 100644 --- a/src/storage/storage_backend_rbd.c +++ b/src/storage/storage_backend_rbd.c @@ -314,8 +314,8 @@ static int virStorageBackendRBDRefreshPool(virConnectPtr conn, goto cleanup; } -struct rados_cluster_stat_t stat; -if (rados_cluster_stat(ptr.cluster, stat) 0) { +struct rados_cluster_stat_t clusterstat; +if (rados_cluster_stat(ptr.cluster, clusterstat) 0) { virReportError(VIR_ERR_INTERNAL_ERROR, %s, _(failed to stat the RADOS cluster)); goto cleanup; @@ -329,13 +329,13 @@ static int virStorageBackendRBDRefreshPool(virConnectPtr conn, goto cleanup; } -pool-def-capacity = stat.kb * 1024; -pool-def-available = stat.kb_avail * 1024; +pool-def-capacity = clusterstat.kb * 1024; +pool-def-available = clusterstat.kb_avail * 1024; pool-def-allocation = poolstat.num_bytes; VIR_DEBUG(Utilization of RBD pool %s: (kb: %llu kb_avail: %llu num_bytes: %llu), - pool-def-source.name, (unsigned long long)stat.kb, - (unsigned long long)stat.kb_avail, + pool-def-source.name, (unsigned long long)clusterstat.kb, + (unsigned long long)clusterstat.kb_avail, (unsigned long long)poolstat.num_bytes); while (true) { ACKed and pushed. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 4/7] Add network events to the remote driver
--- daemon/libvirtd.h| 1 + daemon/remote.c | 139 +++ src/remote/remote_driver.c | 127 +++ src/remote/remote_protocol.x | 46 +- 4 files changed, 312 insertions(+), 1 deletion(-) diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h index d0afdc8..47f2589 100644 --- a/daemon/libvirtd.h +++ b/daemon/libvirtd.h @@ -50,6 +50,7 @@ struct daemonClientPrivate { virMutex lock; int domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LAST]; +int networkEventCallbackID[VIR_NETWORK_EVENT_ID_LAST]; # if WITH_SASL virNetSASLSessionPtr sasl; diff --git a/daemon/remote.c b/daemon/remote.c index f060006..bcd73d4 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -49,6 +49,7 @@ #include qemu_protocol.h #include lxc_protocol.h #include virstring.h +#include object_event.h #define VIR_FROM_THIS VIR_FROM_RPC @@ -653,6 +654,38 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = { verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST); +static int remoteRelayNetworkEventLifecycle(virConnectPtr conn ATTRIBUTE_UNUSED, + virNetworkPtr net, + int event, + int detail, + void *opaque) +{ +virNetServerClientPtr client = opaque; +remote_network_event_lifecycle_msg data; + +if (!client) +return -1; + +VIR_DEBUG(Relaying network lifecycle event %d, detail %d, event, detail); + +/* build return data */ +memset(data, 0, sizeof(data)); +make_nonnull_network(data.net, net); +data.event = event; + +remoteDispatchObjectEventSend(client, remoteProgram, + REMOTE_PROC_NETWORK_EVENT_LIFECYCLE, + (xdrproc_t)xdr_remote_network_event_lifecycle_msg, data); + +return 0; +} + +static virConnectNetworkEventGenericCallback networkEventCallbacks[] = { +VIR_NETWORK_EVENT_CALLBACK(remoteRelayNetworkEventLifecycle), +}; + +verify(ARRAY_CARDINALITY(networkEventCallbacks) == VIR_NETWORK_EVENT_ID_LAST); + /* * You must hold lock for at least the client * We don't free stuff here, merely disconnect the client's @@ -680,6 +713,15 @@ void remoteClientFreeFunc(void *data) priv-domainEventCallbackID[i] = -1; } +for (i = 0; i VIR_NETWORK_EVENT_ID_LAST; i++) { +if (priv-networkEventCallbackID[i] != -1) { +VIR_DEBUG(Deregistering to relay remote events %zu, i); +virConnectNetworkEventDeregisterAny(priv-conn, + priv-networkEventCallbackID[i]); +} +priv-networkEventCallbackID[i] = -1; +} + virConnectClose(priv-conn); virIdentitySetCurrent(NULL); @@ -716,6 +758,9 @@ void *remoteClientInitHook(virNetServerClientPtr client, for (i = 0; i VIR_DOMAIN_EVENT_ID_LAST; i++) priv-domainEventCallbackID[i] = -1; +for (i = 0; i VIR_NETWORK_EVENT_ID_LAST; i++) +priv-networkEventCallbackID[i] = -1; + virNetServerClientSetCloseHook(client, remoteClientCloseFunc); return priv; } @@ -5216,6 +5261,100 @@ cleanup: } +static int +remoteDispatchConnectNetworkEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client ATTRIBUTE_UNUSED, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED, + remote_connect_network_event_register_any_args *args, + remote_connect_network_event_register_any_ret *ret ATTRIBUTE_UNUSED) +{ +int callbackID; +int rv = -1; +struct daemonClientPrivate *priv = +virNetServerClientGetPrivateData(client); + +if (!priv-conn) { +virReportError(VIR_ERR_INTERNAL_ERROR, %s, _(connection not open)); +goto cleanup; +} + +virMutexLock(priv-lock); + +if ((args-eventID 0xFF) = VIR_NETWORK_EVENT_ID_LAST) { +virReportError(VIR_ERR_INTERNAL_ERROR, _(unsupported network event ID %d), args-eventID); +goto cleanup; +} + +if (priv-networkEventCallbackID[args-eventID] != -1) { +virReportError(VIR_ERR_INTERNAL_ERROR, _(network event %d already registered), args-eventID); +goto cleanup; +} + +if ((callbackID = virConnectNetworkEventRegisterAny(priv-conn, +NULL, +args-eventID, + networkEventCallbacks[args-eventID], +
[libvirt] [PATCH v4 0/7] Network events API
This patch serie include changes to respond to Eric and Daniel's comments. The event namespace part of the ID is only handled at the object event's level, though we need to strip it out of virObjectEventStateEventID to get the remote driver properly deregister. Cédric Bosdonnat (7): Added Network events API and virNetworkEventLifecycle. test driver: implemented network events Add network events unit tests Add network events to the remote driver Added network events to the bridged network driver Fixed indentation in src/conf/*_event* Added default case with error for object event dispatching daemon/libvirtd.h| 1 + daemon/remote.c | 139 + include/libvirt/libvirt.h.in | 80 ++ src/Makefile.am | 5 + src/conf/domain_event.c | 286 --- src/conf/domain_event.h | 271 +++-- src/conf/network_event.c | 154 +++ src/conf/network_event.h | 51 +++ src/conf/object_event.c | 50 +++--- src/conf/object_event.h | 1 + src/conf/object_event_private.h | 20 ++- src/driver.h | 14 ++ src/libvirt.c| 125 +++ src/libvirt_private.syms | 2 + src/libvirt_public.syms | 7 + src/network/bridge_driver.c | 90 +++ src/network/bridge_driver_platform.h | 3 + src/remote/remote_driver.c | 127 src/remote/remote_protocol.x | 46 +- src/test/test_driver.c | 62 tests/objecteventtest.c | 167 21 files changed, 1444 insertions(+), 257 deletions(-) create mode 100644 src/conf/network_event.c create mode 100644 src/conf/network_event.h -- 1.8.4.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 2/7] test driver: implemented network events
--- src/test/test_driver.c | 62 ++ 1 file changed, 62 insertions(+) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 4972e3d..66afdf7 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -45,6 +45,7 @@ #include interface_conf.h #include domain_conf.h #include domain_event.h +#include network_event.h #include snapshot_conf.h #include fdstream.h #include storage_conf.h @@ -3529,6 +3530,7 @@ static virNetworkPtr testNetworkCreateXML(virConnectPtr conn, const char *xml) { virNetworkDefPtr def; virNetworkObjPtr net = NULL; virNetworkPtr ret = NULL; +virObjectEventPtr event = NULL; testDriverLock(privconn); if ((def = virNetworkDefParseString(xml)) == NULL) @@ -3539,10 +3541,15 @@ static virNetworkPtr testNetworkCreateXML(virConnectPtr conn, const char *xml) { def = NULL; net-active = 1; +event = virNetworkEventLifecycleNew(net-def-name, net-def-uuid, +VIR_NETWORK_EVENT_STARTED); + ret = virGetNetwork(conn, net-def-name, net-def-uuid); cleanup: virNetworkDefFree(def); +if (event) +testObjectEventQueue(privconn, event); if (net) virNetworkObjUnlock(net); testDriverUnlock(privconn); @@ -3556,6 +3563,7 @@ virNetworkPtr testNetworkDefineXML(virConnectPtr conn, const char *xml) virNetworkDefPtr def; virNetworkObjPtr net = NULL; virNetworkPtr ret = NULL; +virObjectEventPtr event = NULL; testDriverLock(privconn); if ((def = virNetworkDefParseString(xml)) == NULL) @@ -3566,10 +3574,15 @@ virNetworkPtr testNetworkDefineXML(virConnectPtr conn, const char *xml) def = NULL; net-persistent = 1; +event = virNetworkEventLifecycleNew(net-def-name, net-def-uuid, +VIR_NETWORK_EVENT_DEFINED); + ret = virGetNetwork(conn, net-def-name, net-def-uuid); cleanup: virNetworkDefFree(def); +if (event) +testObjectEventQueue(privconn, event); if (net) virNetworkObjUnlock(net); testDriverUnlock(privconn); @@ -3580,6 +3593,7 @@ static int testNetworkUndefine(virNetworkPtr network) { testConnPtr privconn = network-conn-privateData; virNetworkObjPtr privnet; int ret = -1; +virObjectEventPtr event = NULL; testDriverLock(privconn); privnet = virNetworkFindByName(privconn-networks, @@ -3596,12 +3610,17 @@ static int testNetworkUndefine(virNetworkPtr network) { goto cleanup; } +event = virNetworkEventLifecycleNew(network-name, network-uuid, +VIR_NETWORK_EVENT_UNDEFINED); + virNetworkRemoveInactive(privconn-networks, privnet); privnet = NULL; ret = 0; cleanup: +if (event) +testObjectEventQueue(privconn, event); if (privnet) virNetworkObjUnlock(privnet); testDriverUnlock(privconn); @@ -3660,6 +3679,7 @@ static int testNetworkCreate(virNetworkPtr network) { testConnPtr privconn = network-conn-privateData; virNetworkObjPtr privnet; int ret = -1; +virObjectEventPtr event = NULL; testDriverLock(privconn); privnet = virNetworkFindByName(privconn-networks, @@ -3678,9 +3698,13 @@ static int testNetworkCreate(virNetworkPtr network) { } privnet-active = 1; +event = virNetworkEventLifecycleNew(privnet-def-name, privnet-def-uuid, +VIR_NETWORK_EVENT_STARTED); ret = 0; cleanup: +if (event) +testObjectEventQueue(privconn, event); if (privnet) virNetworkObjUnlock(privnet); return ret; @@ -3690,6 +3714,7 @@ static int testNetworkDestroy(virNetworkPtr network) { testConnPtr privconn = network-conn-privateData; virNetworkObjPtr privnet; int ret = -1; +virObjectEventPtr event = NULL; testDriverLock(privconn); privnet = virNetworkFindByName(privconn-networks, @@ -3701,6 +3726,8 @@ static int testNetworkDestroy(virNetworkPtr network) { } privnet-active = 0; +event = virNetworkEventLifecycleNew(privnet-def-name, privnet-def-uuid, +VIR_NETWORK_EVENT_STOPPED); if (!privnet-persistent) { virNetworkRemoveInactive(privconn-networks, privnet); @@ -3709,6 +3736,8 @@ static int testNetworkDestroy(virNetworkPtr network) { ret = 0; cleanup: +if (event) +testObjectEventQueue(privconn, event); if (privnet) virNetworkObjUnlock(privnet); testDriverUnlock(privconn); @@ -6027,6 +6056,37 @@ testConnectDomainEventDeregisterAny(virConnectPtr conn, } +static int +testConnectNetworkEventRegisterAny(virConnectPtr conn, + virNetworkPtr net, + int eventID, +
[libvirt] [PATCH v4 6/7] Fixed indentation in src/conf/*_event*
--- src/conf/domain_event.c | 286 +++- src/conf/domain_event.h | 271 + src/conf/object_event.c | 47 --- src/conf/object_event_private.h | 20 +-- 4 files changed, 364 insertions(+), 260 deletions(-) diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index da57129..45e48b6 100644 --- a/src/conf/domain_event.c +++ b/src/conf/domain_event.c @@ -443,11 +443,12 @@ virDomainEventCallbackListAdd(virConnectPtr conn, } -static void *virDomainEventNew(virClassPtr klass, - int eventID, - int id, - const char *name, - const unsigned char *uuid) +static void +*virDomainEventNew(virClassPtr klass, + int eventID, + int id, + const char *name, + const unsigned char *uuid) { virDomainEventPtr event; @@ -468,9 +469,12 @@ static void *virDomainEventNew(virClassPtr klass, return (virObjectEventPtr)event; } -virObjectEventPtr virDomainEventLifecycleNew(int id, const char *name, - const unsigned char *uuid, - int type, int detail) +virObjectEventPtr +virDomainEventLifecycleNew(int id, + const char *name, + const unsigned char *uuid, + int type, + int detail) { virDomainEventLifecyclePtr event; @@ -488,25 +492,36 @@ virObjectEventPtr virDomainEventLifecycleNew(int id, const char *name, return (virObjectEventPtr)event; } -virObjectEventPtr virDomainEventLifecycleNewFromDom(virDomainPtr dom, int type, int detail) +virObjectEventPtr +virDomainEventLifecycleNewFromDom(virDomainPtr dom, + int type, + int detail) { return virDomainEventLifecycleNew(dom-id, dom-name, dom-uuid, type, detail); } -virObjectEventPtr virDomainEventLifecycleNewFromObj(virDomainObjPtr obj, int type, int detail) +virObjectEventPtr +virDomainEventLifecycleNewFromObj(virDomainObjPtr obj, + int type, + int detail) { return virDomainEventLifecycleNewFromDef(obj-def, type, detail); } -virObjectEventPtr virDomainEventLifecycleNewFromDef(virDomainDefPtr def, int type, int detail) +virObjectEventPtr +virDomainEventLifecycleNewFromDef(virDomainDefPtr def, + int type, + int detail) { return virDomainEventLifecycleNew(def-id, def-name, def-uuid, type, detail); } -virObjectEventPtr virDomainEventRebootNew(int id, const char *name, - const unsigned char *uuid) +virObjectEventPtr +virDomainEventRebootNew(int id, +const char *name, +const unsigned char *uuid) { if (virDomainEventsInitialize() 0) return NULL; @@ -516,7 +531,8 @@ virObjectEventPtr virDomainEventRebootNew(int id, const char *name, id, name, uuid); } -virObjectEventPtr virDomainEventRebootNewFromDom(virDomainPtr dom) +virObjectEventPtr +virDomainEventRebootNewFromDom(virDomainPtr dom) { if (virDomainEventsInitialize() 0) return NULL; @@ -526,7 +542,8 @@ virObjectEventPtr virDomainEventRebootNewFromDom(virDomainPtr dom) dom-id, dom-name, dom-uuid); } -virObjectEventPtr virDomainEventRebootNewFromObj(virDomainObjPtr obj) +virObjectEventPtr +virDomainEventRebootNewFromObj(virDomainObjPtr obj) { if (virDomainEventsInitialize() 0) return NULL; @@ -536,8 +553,9 @@ virObjectEventPtr virDomainEventRebootNewFromObj(virDomainObjPtr obj) obj-def-id, obj-def-name, obj-def-uuid); } -virObjectEventPtr virDomainEventRTCChangeNewFromDom(virDomainPtr dom, -long long offset) +virObjectEventPtr +virDomainEventRTCChangeNewFromDom(virDomainPtr dom, + long long offset) { virDomainEventRTCChangePtr ev; @@ -553,8 +571,9 @@ virObjectEventPtr virDomainEventRTCChangeNewFromDom(virDomainPtr dom, return (virObjectEventPtr)ev; } -virObjectEventPtr virDomainEventRTCChangeNewFromObj(virDomainObjPtr obj, -long long offset) +virObjectEventPtr +virDomainEventRTCChangeNewFromObj(virDomainObjPtr obj, + long long offset) { virDomainEventRTCChangePtr ev; @@ -572,7 +591,9 @@ virObjectEventPtr virDomainEventRTCChangeNewFromObj(virDomainObjPtr obj, return (virObjectEventPtr)ev; } -virObjectEventPtr
[libvirt] [PATCH v4 3/7] Add network events unit tests
--- tests/objecteventtest.c | 167 1 file changed, 167 insertions(+) diff --git a/tests/objecteventtest.c b/tests/objecteventtest.c index 33e2551..ae29792 100644 --- a/tests/objecteventtest.c +++ b/tests/objecteventtest.c @@ -40,6 +40,18 @@ static const char domainDef[] = /os /domain; +static const char networkDef[] = +network\n + nametest/name\n + bridge name=\virbr0\/\n + forward/\n + ip address=\192.168.122.1\ netmask=\255.255.255.0\\n +dhcp\n + range start=\192.168.122.2\ end=\192.168.122.254\/\n +/dhcp\n + /ip\n +/network\n; + typedef struct { int startEvents; int stopEvents; @@ -60,6 +72,7 @@ lifecycleEventCounter_reset(lifecycleEventCounter *counter) typedef struct { virConnectPtr conn; +virNetworkPtr net; } objecteventTest; @@ -92,6 +105,26 @@ domainLifecycleCb(virConnectPtr conn ATTRIBUTE_UNUSED, return 0; } +static void +networkLifecycleCb(virConnectPtr conn ATTRIBUTE_UNUSED, + virNetworkPtr net ATTRIBUTE_UNUSED, + int event, + int detail ATTRIBUTE_UNUSED, + void* opaque) +{ +lifecycleEventCounter *counter = opaque; + +if (event == VIR_NETWORK_EVENT_STARTED) +counter-startEvents++; +else if (event == VIR_NETWORK_EVENT_STOPPED) +counter-stopEvents++; +else if (event == VIR_NETWORK_EVENT_DEFINED) +counter-defineEvents++; +else if (event == VIR_NETWORK_EVENT_UNDEFINED) +counter-undefineEvents++; +} + + static int testDomainCreateXML(const void *data) { @@ -223,6 +256,125 @@ cleanup: } static int +testNetworkCreateXML(const void *data) +{ +const objecteventTest *test = data; +lifecycleEventCounter counter; +virNetworkPtr net; +int id; +int ret = 0; + +lifecycleEventCounter_reset(counter); + +id = virConnectNetworkEventRegisterAny(test-conn, NULL, + VIR_NETWORK_EVENT_ID_LIFECYCLE, + VIR_NETWORK_EVENT_CALLBACK(networkLifecycleCb), + counter, NULL); +net = virNetworkCreateXML(test-conn, networkDef); + +if (virEventRunDefaultImpl() 0) { +ret = -1; +goto cleanup; +} + +if (counter.startEvents != 1 || counter.unexpectedEvents 0) { +ret = -1; +goto cleanup; +} + +cleanup: +virConnectNetworkEventDeregisterAny(test-conn, id); +virNetworkDestroy(net); + +virNetworkFree(net); + +return ret; +} + +static int +testNetworkDefine(const void *data) +{ +const objecteventTest *test = data; +lifecycleEventCounter counter; +virNetworkPtr net; +int id; +int ret = 0; + +lifecycleEventCounter_reset(counter); + +id = virConnectNetworkEventRegisterAny(test-conn, NULL, + VIR_NETWORK_EVENT_ID_LIFECYCLE, + VIR_NETWORK_EVENT_CALLBACK(networkLifecycleCb), + counter, NULL); + +/* Make sure the define event is triggered */ +net = virNetworkDefineXML(test-conn, networkDef); + +if (virEventRunDefaultImpl() 0) { +ret = -1; +goto cleanup; +} + +if (counter.defineEvents != 1 || counter.unexpectedEvents 0) { +ret = -1; +goto cleanup; +} + +/* Make sure the undefine event is triggered */ +virNetworkUndefine(net); + +if (virEventRunDefaultImpl() 0) { +ret = -1; +goto cleanup; +} + +if (counter.undefineEvents != 1 || counter.unexpectedEvents 0) { +ret = -1; +goto cleanup; +} + + +cleanup: +virConnectNetworkEventDeregisterAny(test-conn, id); +virNetworkFree(net); + +return ret; +} + +static int +testNetworkStartStopEvent(const void *data) +{ +const objecteventTest *test = data; +lifecycleEventCounter counter; +int id; +int ret = 0; + +lifecycleEventCounter_reset(counter); + +id = virConnectNetworkEventRegisterAny(test-conn, test-net, + VIR_NETWORK_EVENT_ID_LIFECYCLE, + VIR_NETWORK_EVENT_CALLBACK(networkLifecycleCb), + counter, NULL); +virNetworkCreate(test-net); +virNetworkDestroy(test-net); + +if (virEventRunDefaultImpl() 0) { +ret = -1; +goto cleanup; +} + +if (counter.startEvents != 1 || counter.stopEvents != 1 || +counter.unexpectedEvents 0) { +ret = -1; +goto cleanup; +} +cleanup: +virConnectNetworkEventDeregisterAny(test-conn, id); + +return ret; +} + +static int mymain(void) { objecteventTest test; @@ -243,6 +395,21 @@ mymain(void) if (virtTestRun(Domain start stop events, testDomainStartStopEvent, test) 0) ret = EXIT_FAILURE; +/* Network event tests */ +/* Tests requiring the test network not to be set up*/ +if (virtTestRun(Network createXML start event , testNetworkCreateXML,
[libvirt] [PATCH v4 1/7] Added Network events API and virNetworkEventLifecycle.
Put all network-events related code in src/conf/network_event.[ch] --- include/libvirt/libvirt.h.in | 80 ++ src/Makefile.am | 5 ++ src/conf/network_event.c | 154 +++ src/conf/network_event.h | 51 ++ src/conf/object_event.c | 9 +++ src/conf/object_event.h | 1 + src/driver.h | 14 src/libvirt.c| 125 +++ src/libvirt_private.syms | 2 + src/libvirt_public.syms | 7 ++ 10 files changed, 448 insertions(+) create mode 100644 src/conf/network_event.c create mode 100644 src/conf/network_event.h diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 29d4dce..73a77c0 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -4974,6 +4974,86 @@ int virConnectDomainEventRegisterAny(virConnectPtr conn, int virConnectDomainEventDeregisterAny(virConnectPtr conn, int callbackID); +/** + * virNetworkEventLifecycleType: + * + * a virNetworkEventLifecycleType is emitted during network lifecycle events + */ +typedef enum { +VIR_NETWORK_EVENT_DEFINED = 0, +VIR_NETWORK_EVENT_UNDEFINED = 1, +VIR_NETWORK_EVENT_STARTED = 2, +VIR_NETWORK_EVENT_STOPPED = 3, + +#ifdef VIR_ENUM_SENTINELS +VIR_NETWORK_EVENT_LAST +#endif +} virNetworkEventLifecycleType; + +/** + * virConnectNetworkEventLifecycleCallback: + * @conn: connection object + * @net: network on which the event occurred + * @event: The specific virNetworkEventLifeCycleType which occurred + * @detail: contains some details on the reason of the event. + * It will be 0 for the while. + * @opaque: application specified data + * + * This callback occurs when the network is started or stopped. + * + * The callback signature to use when registering for an event of type + * VIR_NETWORK_EVENT_ID_LIFECYCLE with virConnectNetworkEventRegisterAny() + */ +typedef void (*virConnectNetworkEventLifecycleCallback)(virConnectPtr conn, +virNetworkPtr net, +int event, +int detail, +void *opaque); + +/** + * VIR_NETWORK_EVENT_CALLBACK: + * + * Used to cast the event specific callback into the generic one + * for use for virNetworkEventRegister + */ +#define VIR_NETWORK_EVENT_CALLBACK(cb) ((virConnectNetworkEventGenericCallback)(cb)) + +typedef enum { +VIR_NETWORK_EVENT_ID_LIFECYCLE = 0, /* virConnectNetworkEventLifecycleCallback */ + +#ifdef VIR_ENUM_SENTINELS +VIR_NETWORK_EVENT_ID_LAST +/* + * NB: this enum value will increase over time as new events are + * added to the libvirt API. It reflects the last event ID supported + * by this version of the libvirt API. + */ +#endif +} virNetworkEventID; + +/* + * virConnectNetworkEventGenericCallback: + * @conn: the connection pointer + * @net: the network pointer + * @opaque: application specified data + * + * A generic network event callback handler. Specific events usually + * have a customization with extra parameters + */ +typedef void (*virConnectNetworkEventGenericCallback)(virConnectPtr conn, + virNetworkPtr net, + void *opaque); + +/* Use VIR_NETWORK_EVENT_CALLBACK() to cast the 'cb' parameter */ +int virConnectNetworkEventRegisterAny(virConnectPtr conn, + virNetworkPtr net, /* Optional, to filter */ + int eventID, + virConnectNetworkEventGenericCallback cb, + void *opaque, + virFreeCallback freecb); + +int virConnectNetworkEventDeregisterAny(virConnectPtr conn, +int callbackID); /** * virNWFilter: diff --git a/src/Makefile.am b/src/Makefile.am index a3ea55c..57e163f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -248,6 +248,9 @@ OBJECT_EVENT_SOURCES = \ DOMAIN_EVENT_SOURCES = \ conf/domain_event.c conf/domain_event.h +NETWORK_EVENT_SOURCES =\ + conf/network_event.c conf/network_event.h + # Network driver generic impl APIs NETWORK_CONF_SOURCES = \ conf/network_conf.c conf/network_conf.h @@ -298,6 +301,7 @@ CONF_SOURCES = \ $(DOMAIN_CONF_SOURCES) \ $(OBJECT_EVENT_SOURCES) \
[libvirt] [PATCH v4 7/7] Added default case with error for object event dispatching
Hitting this should be pretty rare, but at least developers will know that they are providing a weird event ID. Otherwise for namespace that are added in the normal way, gcc will raise a warning about unhandled case in the switch. --- src/conf/object_event.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/conf/object_event.c b/src/conf/object_event.c index 0f21c37..1e0b33d 100644 --- a/src/conf/object_event.c +++ b/src/conf/object_event.c @@ -646,6 +646,8 @@ virObjectEventStateDispatchFunc(virConnectPtr conn, virNetworkEventDispatchDefaultFunc(conn, event, VIR_NETWORK_EVENT_CALLBACK(cb), cbopaque, NULL); break; +default: +VIR_ERROR(_(Unknown event namespace to dispatch)); } virObjectEventStateLock(state); } -- 1.8.4.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 5/7] Added network events to the bridged network driver
--- src/network/bridge_driver.c | 90 src/network/bridge_driver_platform.h | 3 ++ 2 files changed, 93 insertions(+) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 80c5acb..4c0c352 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -70,6 +70,7 @@ #include virfile.h #include virstring.h #include viraccessapicheck.h +#include network_event.h #define VIR_FROM_THIS VIR_FROM_NETWORK @@ -438,6 +439,8 @@ networkStateInitialize(bool privileged, networkReloadFirewallRules(driverState); networkRefreshDaemons(driverState); +driverState-networkEventState = virObjectEventStateNew(); + networkDriverUnlock(driverState); #ifdef HAVE_FIREWALLD @@ -532,6 +535,8 @@ networkStateCleanup(void) { networkDriverLock(driverState); +virObjectEventStateFree(driverState-networkEventState); + /* free inactive networks */ virNetworkObjListFree(driverState-networks); @@ -2290,6 +2295,55 @@ cleanup: return ret; } +static int +networkConnectNetworkEventRegisterAny(virConnectPtr conn, + virNetworkPtr net, + int eventID, + virConnectNetworkEventGenericCallback callback, + void *opaque, + virFreeCallback freecb) +{ +virNetworkDriverStatePtr driver = conn-networkPrivateData; +int ret = -1; + +networkDriverLock(driver); + +if (virConnectNetworkEventRegisterAnyEnsureACL(conn) 0) +goto cleanup; + +if (virNetworkEventStateRegisterID(conn, driver-networkEventState, + net, eventID, + VIR_OBJECT_EVENT_CALLBACK(callback), + opaque, freecb, ret) 0) +ret = -1; + +networkDriverUnlock(driver); + +cleanup: +return ret; +} + +static int +networkConnectNetworkEventDeregisterAny(virConnectPtr conn, +int callbackID) +{ +virNetworkDriverStatePtr driver = conn-networkPrivateData; +int ret = -1; + +if (virConnectNetworkEventDeregisterAnyEnsureACL(conn) 0) +goto cleanup; + + +networkDriverLock(driver); +ret = virObjectEventStateDeregisterID(conn, + driver-networkEventState, + callbackID); +networkDriverUnlock(driver); + +cleanup: +return ret; +} + static int networkIsActive(virNetworkPtr net) { virNetworkObjPtr obj; @@ -2483,6 +2537,7 @@ static virNetworkPtr networkCreateXML(virConnectPtr conn, const char *xml) { virNetworkDefPtr def; virNetworkObjPtr network = NULL; virNetworkPtr ret = NULL; +virObjectEventPtr event = NULL; networkDriverLock(driver); @@ -2509,11 +2564,17 @@ static virNetworkPtr networkCreateXML(virConnectPtr conn, const char *xml) { goto cleanup; } +event = virNetworkEventLifecycleNew(network-def-name, +network-def-uuid, +VIR_NETWORK_EVENT_STARTED); + VIR_INFO(Creating network '%s', network-def-name); ret = virGetNetwork(conn, network-def-name, network-def-uuid); cleanup: virNetworkDefFree(def); +if (event) +virObjectEventStateQueue(driver-networkEventState, event); if (network) virNetworkObjUnlock(network); networkDriverUnlock(driver); @@ -2526,6 +2587,7 @@ static virNetworkPtr networkDefineXML(virConnectPtr conn, const char *xml) { bool freeDef = true; virNetworkObjPtr network = NULL; virNetworkPtr ret = NULL; +virObjectEventPtr event = NULL; networkDriverLock(driver); @@ -2565,10 +2627,15 @@ static virNetworkPtr networkDefineXML(virConnectPtr conn, const char *xml) { goto cleanup; } +event = virNetworkEventLifecycleNew(def-name, def-uuid, +VIR_NETWORK_EVENT_DEFINED); + VIR_INFO(Defining network '%s', def-name); ret = virGetNetwork(conn, def-name, def-uuid); cleanup: +if (event) +virObjectEventStateQueue(driver-networkEventState, event); if (freeDef) virNetworkDefFree(def); if (network) @@ -2583,6 +2650,7 @@ networkUndefine(virNetworkPtr net) { virNetworkObjPtr network; int ret = -1; bool active = false; +virObjectEventPtr event = NULL; networkDriverLock(driver); @@ -2610,6 +2678,10 @@ networkUndefine(virNetworkPtr net) { virNetworkDefFree(network-newDef); network-newDef = NULL; +event = virNetworkEventLifecycleNew(network-def-name, +network-def-uuid, +VIR_NETWORK_EVENT_UNDEFINED); + VIR_INFO(Undefining network '%s', network-def-name);
Re: [libvirt] [PATCH 1/2] interface: Introduce netcfInterfaceObjIsActive
On Wed, Dec 11, 2013 at 10:16:37AM +0100, Michal Privoznik wrote: This function barely wraps ncf_if_status() and error handling code. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- src/interface/interface_backend_netcf.c | 57 +++-- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/src/interface/interface_backend_netcf.c b/src/interface/interface_backend_netcf.c index c4e18c4..2e681ec 100644 --- a/src/interface/interface_backend_netcf.c +++ b/src/interface/interface_backend_netcf.c @@ -238,6 +238,32 @@ static struct netcf_if *interfaceDriverGetNetcfIF(struct netcf *ncf, virInterfac return iface; } +static int +netcfInterfaceObjIsActive(struct netcf_if *iface, + bool *active) +{ +int ret = -1; +unsigned int flags = 0; + +virObjectRef(driverState); What's the ref / unref of driverState for ? The code you're replacing doesn't do that, and AFAICT this shouldn't be required since we're always calling this from public API context +if (ncf_if_status(iface, flags) 0) { +const char *errmsg, *details; +int errcode = ncf_error(driverState-netcf, errmsg, details); +virReportError(netcf_to_vir_err(errcode), + _(failed to get status of interface %s: %s%s%s), + ncf_if_name(iface), errmsg, details ? - : , + details ? details : ); +goto cleanup; +} + +*active = flags NETCF_IFACE_ACTIVE; +ret = 0; + +cleanup: +virObjectUnref(driverState); +return ret; +} + Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [Qemu-devel] [PATCH V17 02/11] NUMA: check if the total numa memory size is equal to ram_size
On Tue, Dec 10, 2013 at 05:01:02PM -0200, Eduardo Habkost wrote: On Tue, Dec 10, 2013 at 07:03:50PM +0100, Paolo Bonzini wrote: Il 10/12/2013 14:15, Eduardo Habkost ha scritto: If the total number of the assigned numa nodes memory is not equal to the assigned ram size, it will write the wrong data to ACPI talb, then the guest will ignore the wrong ACPI table and recognize all memory to one node. It's buggy, we should check it to ensure that we write the right data to ACPI table. Signed-off-by: Wanlong Gao gaowanl...@cn.fujitsu.com This will make configurations that could be running for years (except that the guest OS was ignoring the NUMA data) suddenly stop running. I just want to confirm: we really want that, right? Does libvirt allow this kind of broken configuration to be generated, or it already ensures the total NUMA node sizes match RAM size? It allows this. It just converts the numa XML to -numa node. In that case, if we apply this patch we may want to make libvirt validate the NUMA configuration instead of getting a cryptic QEMU aborted error message with the actual problem buried in a log file. (Well, even if we do not apply this patch, I believe it is a good idea to make libvirt validate the NUMA configuration.) Yes, libvirt really ought to validate this, since such inconsistency is a bogus configuration. It would be desirable for libvirt to reject it completely as an error, but we should check if there any common apps which are (accidentally) relying on such broken configs already. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Read PCI class from sysfs class file instead of config space.
On Tue, Dec 10, 2013 at 07:57:01AM -0200, Thadeu Lima de Souza Cascardo wrote: When determining if a device is behind a PCI bridge, the PCI device class is checked by reading the config space. However, there are some devices which have the wrong class on the config space, but the class is initialized by Linux correctly as a PCI BRIDGE. This class can be read by the sysfs file '/sys/bus/pci/devices/:xx:xx.x/class'. Do you have any idea how long this file has been present in sysfs ? Hopefully it is a fairly ancient feature, so we can rely on it existing ? Otherwise we'll need to fallback to reading the config space when the sysfs file does not exist. One example of such bridge is IBM PCI Bridge 1014:03b9, which is identified as a Host Bridge when reading the config space. Signed-off-by: Thadeu Lima de Souza Cascardo casca...@linux.vnet.ibm.com --- src/util/virpci.c | 38 +++--- 1 files changed, 35 insertions(+), 3 deletions(-) Looks reasonable to me, though prefer Laine to ACK it since he knows the PCI code best of anyone Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] docs: fix a typo in libvirt.h
From: Chen Hanxiao chenhanx...@cn.fujitsu.com s/pausde/paused Signed-off-by: Chen Hanxiao chenhanx...@cn.fujitsu.com --- include/libvirt/libvirt.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 29d4dce..51a02f5 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -4576,7 +4576,7 @@ typedef void (*virConnectDomainEventWatchdogCallback)(virConnectPtr conn, */ typedef enum { VIR_DOMAIN_EVENT_IO_ERROR_NONE = 0, /* No action, IO error ignored */ -VIR_DOMAIN_EVENT_IO_ERROR_PAUSE, /* Guest CPUs are pausde */ +VIR_DOMAIN_EVENT_IO_ERROR_PAUSE, /* Guest CPUs are paused */ VIR_DOMAIN_EVENT_IO_ERROR_REPORT,/* IO error reported to guest OS */ #ifdef VIR_ENUM_SENTINELS -- 1.8.2.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] docs: fix a typo in libvirt.h
On Wed, Dec 11, 2013 at 08:30:53PM +0800, Chen Hanxiao wrote: From: Chen Hanxiao chenhanx...@cn.fujitsu.com s/pausde/paused Signed-off-by: Chen Hanxiao chenhanx...@cn.fujitsu.com --- include/libvirt/libvirt.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 29d4dce..51a02f5 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -4576,7 +4576,7 @@ typedef void (*virConnectDomainEventWatchdogCallback)(virConnectPtr conn, */ typedef enum { VIR_DOMAIN_EVENT_IO_ERROR_NONE = 0, /* No action, IO error ignored */ -VIR_DOMAIN_EVENT_IO_ERROR_PAUSE, /* Guest CPUs are pausde */ +VIR_DOMAIN_EVENT_IO_ERROR_PAUSE, /* Guest CPUs are paused */ VIR_DOMAIN_EVENT_IO_ERROR_REPORT,/* IO error reported to guest OS */ #ifdef VIR_ENUM_SENTINELS -- 1.8.2.1 ACK pushed. Martin signature.asc Description: Digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Read PCI class from sysfs class file instead of config space.
On 10.12.2013 10:57, Thadeu Lima de Souza Cascardo wrote: When determining if a device is behind a PCI bridge, the PCI device class is checked by reading the config space. However, there are some devices which have the wrong class on the config space, but the class is initialized by Linux correctly as a PCI BRIDGE. This class can be read by the sysfs file '/sys/bus/pci/devices/:xx:xx.x/class'. One example of such bridge is IBM PCI Bridge 1014:03b9, which is identified as a Host Bridge when reading the config space. Signed-off-by: Thadeu Lima de Souza Cascardo casca...@linux.vnet.ibm.com --- src/util/virpci.c | 38 +++--- 1 files changed, 35 insertions(+), 3 deletions(-) Adding a regression test should be easy (esp. when virpcitest is already written). Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [python PATCH v2] Added python binding for the new network events API
--- Changes to previous patch: * Fixed Eric's comments * Updated code to latest libvirt patches submitted generator.py | 2 + libvirt-override-virConnect.py | 34 + libvirt-override.c | 152 + 3 files changed, 188 insertions(+) diff --git a/generator.py b/generator.py index 84c7678..42f3913 100755 --- a/generator.py +++ b/generator.py @@ -491,6 +491,8 @@ skip_function = ( 'virConnectDomainEventDeregister', # overridden in virConnect.py 'virConnectDomainEventRegisterAny', # overridden in virConnect.py 'virConnectDomainEventDeregisterAny', # overridden in virConnect.py +'virConnectNetworkEventRegisterAny', # overridden in virConnect.py +'virConnectNetworkEventDeregisterAny', # overridden in virConnect.py 'virSaveLastError', # We have our own python error wrapper 'virFreeError', # Only needed if we use virSaveLastError 'virConnectListAllDomains', # overridden in virConnect.py diff --git a/libvirt-override-virConnect.py b/libvirt-override-virConnect.py index 0beaf9c..c228eb2 100644 --- a/libvirt-override-virConnect.py +++ b/libvirt-override-virConnect.py @@ -198,6 +198,40 @@ except AttributeError: pass +def _dispatchNetworkEventLifecycleCallback(self, net, event, detail, cbData): +Dispatches events to python user network lifecycle event callbacks + +cb = cbData[cb] +opaque = cbData[opaque] + +cb(self, virNetwork(self, _obj=net), event, detail, opaque) +return 0 + +def networkEventDeregisterAny(self, callbackID): +Removes a Network Event Callback. De-registering for a + network callback will disable delivery of this event type +try: +ret = libvirtmod.virConnectNetworkEventDeregisterAny(self._o, callbackID) +if ret == -1: raise libvirtError ('virConnectNetworkEventDeregisterAny() failed', conn=self) +del self.networkEventCallbackID[callbackID] +except AttributeError: +pass + +def networkEventRegisterAny(self, net, eventID, cb, opaque): +Adds a Network Event Callback. Registering for a network + callback will enable delivery of the events +if not hasattr(self, 'networkEventCallbackID'): +self.networkEventCallbackID = {} +cbData = { cb: cb, conn: self, opaque: opaque } +if net is None: +ret = libvirtmod.virConnectNetworkEventRegisterAny(self._o, None, eventID, cbData) +else: +ret = libvirtmod.virConnectNetworkEventRegisterAny(self._o, net._o, eventID, cbData) +if ret == -1: +raise libvirtError ('virConnectNetworkEventRegisterAny() failed', conn=self) +self.networkEventCallbackID[ret] = opaque +return ret + def domainEventRegisterAny(self, dom, eventID, cb, opaque): Adds a Domain Event Callback. Registering for a domain callback will enable delivery of the events diff --git a/libvirt-override.c b/libvirt-override.c index 5deb414..fbcd1c8 100644 --- a/libvirt-override.c +++ b/libvirt-override.c @@ -6515,6 +6515,154 @@ libvirt_virConnectDomainEventDeregisterAny(ATTRIBUTE_UNUSED PyObject * self, return py_retval; } +#if LIBVIR_CHECK_VERSION(1, 2, 1) +static void +libvirt_virConnectNetworkEventFreeFunc(void *opaque) +{ +PyObject *pyobj_conn = (PyObject*)opaque; +LIBVIRT_ENSURE_THREAD_STATE; +Py_DECREF(pyobj_conn); +LIBVIRT_RELEASE_THREAD_STATE; +} + +static int +libvirt_virConnectNetworkEventLifecycleCallback(virConnectPtr conn ATTRIBUTE_UNUSED, +virNetworkPtr net, +int event, +int detail, +void *opaque) +{ +PyObject *pyobj_cbData = (PyObject*)opaque; +PyObject *pyobj_net; +PyObject *pyobj_ret; +PyObject *pyobj_conn; +PyObject *dictKey; +int ret = -1; + +LIBVIRT_ENSURE_THREAD_STATE; + +dictKey = libvirt_constcharPtrWrap(conn); +if (!dictKey) +return ret; +pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); +Py_DECREF(dictKey); + +/* Create a python instance of this virNetworkPtr */ +virNetworkRef(net); +pyobj_net = libvirt_virNetworkPtrWrap(net); +Py_INCREF(pyobj_cbData); + +/* Call the Callback Dispatcher */ +pyobj_ret = PyObject_CallMethod(pyobj_conn, + (char*)_dispatchNetworkEventLifecycleCallback, +(char*)OiiO, +pyobj_net, +event, +detail, +pyobj_cbData); + +Py_DECREF(pyobj_cbData); +Py_DECREF(pyobj_net); + +if (!pyobj_ret) { +DEBUG(%s - ret:%p\n,
Re: [libvirt] [PATCH 1/2] interface: Introduce netcfInterfaceObjIsActive
On 11.12.2013 13:19, Daniel P. Berrange wrote: On Wed, Dec 11, 2013 at 10:16:37AM +0100, Michal Privoznik wrote: This function barely wraps ncf_if_status() and error handling code. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- src/interface/interface_backend_netcf.c | 57 +++-- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/src/interface/interface_backend_netcf.c b/src/interface/interface_backend_netcf.c index c4e18c4..2e681ec 100644 --- a/src/interface/interface_backend_netcf.c +++ b/src/interface/interface_backend_netcf.c @@ -238,6 +238,32 @@ static struct netcf_if *interfaceDriverGetNetcfIF(struct netcf *ncf, virInterfac return iface; } +static int +netcfInterfaceObjIsActive(struct netcf_if *iface, + bool *active) +{ +int ret = -1; +unsigned int flags = 0; + +virObjectRef(driverState); What's the ref / unref of driverState for ? The code you're replacing doesn't do that, and AFAICT this shouldn't be required since we're always calling this from public API context Well, for now it is not required, true. But I was thinking if somebody rewrites something this part wouldn't need any change as it's already foolproof. But I don't mind dropping ref and unref. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v4 1/7] Added Network events API and virNetworkEventLifecycle.
On Wed, Dec 11, 2013 at 11:37:58AM +0100, Cédric Bosdonnat wrote: diff --git a/src/conf/network_event.c b/src/conf/network_event.c new file mode 100644 index 000..74e9d3d --- /dev/null +++ b/src/conf/network_event.c +int +virNetworkEventStateRegisterID(virConnectPtr conn, + virObjectEventStatePtr state, + virNetworkPtr net, + int eventID, + virConnectObjectEventGenericCallback cb, + void *opaque, + virFreeCallback freecb, + int *callbackID) Small indentation bug I'll fix when pushing. +{ +int nsEventID = (VIR_EVENT_NAMESPACE_NETWORK 8) + eventID; +if (net) +return virObjectEventStateRegisterID(conn, state, + net-uuid, net-name, 0, nsEventID, + cb, opaque, freecb, callbackID); +else +return virObjectEventStateRegisterID(conn, state, + NULL, NULL, 0, nsEventID, + cb, opaque, freecb, callbackID); +} + +void +*virNetworkEventLifecycleNew(const char *name, + const unsigned char *uuid, + int type) The return type should be virObjectEventPtr - will fix +{ +virNetworkEventLifecyclePtr event; +int eventId = (VIR_EVENT_NAMESPACE_NETWORK 8) + VIR_NETWORK_EVENT_ID_LIFECYCLE; + +if (virNetworkEventsInitialize() 0) +return NULL; + +if (!(event = virObjectEventNew(virNetworkEventLifecycleClass, +eventId, +0, name, uuid))) +return NULL; + +event-type = type; + +return event; +} +int +virNetworkEventStateRegisterID(virConnectPtr conn, + virObjectEventStatePtr state, + virNetworkPtr net, + int eventID, + virConnectObjectEventGenericCallback cb, + void *opaque, + virFreeCallback freecb, + int *callbackID); Same indent issue + +void +*virNetworkEventLifecycleNew(const char *name, + const unsigned char *uuid, + int type); + +void +virNetworkEventDispatchDefaultFunc(virConnectPtr conn, + virObjectEventPtr event, + virConnectNetworkEventGenericCallback cb, + void *cbopaque, + void *opaque); +#endif + +typedef int +(*virDrvConnectNetworkEventDeregisterAny)(virConnectPtr conn, + int callbackID); Tiny indent issue. diff --git a/src/libvirt.c b/src/libvirt.c index b3543d0..97175b2 100644 --- a/src/libvirt.c +++ b/src/libvirt.c +int +virConnectNetworkEventDeregisterAny(virConnectPtr conn, +int callbackID) +{ +VIR_DEBUG(conn=%p, callbackID=%d, conn, callbackID); + +virResetLastError(); + +if (!VIR_IS_CONNECT(conn)) { +virLibConnError(VIR_ERR_INVALID_CONN, __FUNCTION__); +virDispatchError(NULL); +return -1; +} +virCheckNonNegativeArgGoto(callbackID, error); + +if ((conn-networkDriver) +(conn-networkDriver-connectNetworkEventDeregisterAny)) { Small indent issue ACK will push with fixes Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v4 2/7] test driver: implemented network events
On Wed, Dec 11, 2013 at 11:37:59AM +0100, Cédric Bosdonnat wrote: --- src/test/test_driver.c | 62 ++ 1 file changed, 62 insertions(+) @@ -6027,6 +6056,37 @@ testConnectDomainEventDeregisterAny(virConnectPtr conn, } +static int +testConnectNetworkEventRegisterAny(virConnectPtr conn, + virNetworkPtr net, + int eventID, + virConnectNetworkEventGenericCallback callback, + void *opaque, + virFreeCallback freecb) +{ +testConnPtr driver = conn-privateData; +int ret; + +testDriverLock(driver); +if (virNetworkEventStateRegisterID(conn, + driver-domainEventState, + net, eventID, + VIR_OBJECT_EVENT_CALLBACK(callback), + opaque, freecb, ret) 0) +ret = -1; +testDriverUnlock(driver); + +return ret; +} + +static int +testConnectNetworkEventDeregisterAny(virConnectPtr conn, +int callbackID) Indentation. +{ +return testConnectDomainEventDeregisterAny(conn, callbackID); +} We generally aim to avoid having one public API calling into another one, so I'm going to expand this to the explicit code. ACK and will fix issues before pushing. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v4 3/7] Add network events unit tests
On Wed, Dec 11, 2013 at 11:38:00AM +0100, Cédric Bosdonnat wrote: --- tests/objecteventtest.c | 167 1 file changed, 167 insertions(+) ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v4 4/7] Add network events to the remote driver
On Wed, Dec 11, 2013 at 11:38:01AM +0100, Cédric Bosdonnat wrote: --- daemon/libvirtd.h| 1 + daemon/remote.c | 139 +++ src/remote/remote_driver.c | 127 +++ src/remote/remote_protocol.x | 46 +- 4 files changed, 312 insertions(+), 1 deletion(-) diff --git a/daemon/libvirtd.h b/daemon/libvirtd.h index d0afdc8..47f2589 100644 --- a/daemon/libvirtd.h +++ b/daemon/libvirtd.h @@ -50,6 +50,7 @@ struct daemonClientPrivate { virMutex lock; int domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LAST]; +int networkEventCallbackID[VIR_NETWORK_EVENT_ID_LAST]; # if WITH_SASL virNetSASLSessionPtr sasl; diff --git a/daemon/remote.c b/daemon/remote.c index f060006..bcd73d4 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -49,6 +49,7 @@ #include qemu_protocol.h #include lxc_protocol.h #include virstring.h +#include object_event.h #define VIR_FROM_THIS VIR_FROM_RPC @@ -653,6 +654,38 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = { verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST); +static int remoteRelayNetworkEventLifecycle(virConnectPtr conn ATTRIBUTE_UNUSED, + virNetworkPtr net, + int event, + int detail, + void *opaque) Indent. @@ -5216,6 +5261,100 @@ cleanup: } +static int +remoteDispatchConnectNetworkEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client ATTRIBUTE_UNUSED, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED, + remote_connect_network_event_register_any_args *args, + remote_connect_network_event_register_any_ret *ret ATTRIBUTE_UNUSED) +{ +int callbackID; +int rv = -1; +struct daemonClientPrivate *priv = +virNetServerClientGetPrivateData(client); + +if (!priv-conn) { +virReportError(VIR_ERR_INTERNAL_ERROR, %s, _(connection not open)); +goto cleanup; +} + +virMutexLock(priv-lock); + +if ((args-eventID 0xFF) = VIR_NETWORK_EVENT_ID_LAST) { We can drop the 0xFF bit now namespaces aren't visible on the wire +virReportError(VIR_ERR_INTERNAL_ERROR, _(unsupported network event ID %d), args-eventID); +goto cleanup; +} + +if (priv-networkEventCallbackID[args-eventID] != -1) { +virReportError(VIR_ERR_INTERNAL_ERROR, _(network event %d already registered), args-eventID); +goto cleanup; +} + +if ((callbackID = virConnectNetworkEventRegisterAny(priv-conn, +NULL, +args-eventID, + networkEventCallbacks[args-eventID], +client, NULL)) 0) +goto cleanup; + +priv-networkEventCallbackID[args-eventID 0xFF] = callbackID; And again here. + +rv = 0; + +cleanup: +if (rv 0) +virNetMessageSaveError(rerr); +virMutexUnlock(priv-lock); +return rv; +} + + +static int +remoteDispatchConnectNetworkEventDeregisterAny(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client ATTRIBUTE_UNUSED, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED, + remote_connect_network_event_deregister_any_args *args, + remote_connect_network_event_deregister_any_ret *ret ATTRIBUTE_UNUSED) +{ +int callbackID = -1; +int rv = -1; +struct daemonClientPrivate *priv = +virNetServerClientGetPrivateData(client); + +if (!priv-conn) { +virReportError(VIR_ERR_INTERNAL_ERROR, %s, _(connection not open)); +goto cleanup; +} + +virMutexLock(priv-lock); + +if ((args-eventID 0xFF) = VIR_NETWORK_EVENT_ID_LAST) { And here diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 4a84a52..046f424 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -2902,6 +2912,99 @@ done: } static int +remoteConnectNetworkEventRegisterAny(virConnectPtr conn, + virNetworkPtr net, +
Re: [libvirt] [PATCH 00/34] network events feature v2
On 29.11.2013 16:18, Cédric Bosdonnat wrote: This patch serie is replacing the previous one I sent. The improvements that were made in between are: * splitting the 2 huge commits into smaller reviewable ones. * Get rid of the huge union in virDomainEvent and use virObjects instead. * No domain events-related code in object_event.c. I left the network events related code there as it would be pretty small in a separate set of files. * Rebased on the python split repository I saw something weird in the domain events code when working on this: VIR_DOMAIN_EVENT_LAST is defined if VIR_ENUM_SENTINELS is defined, but is generally used independently of it. I did the same for the VIR_NETWORK_EVENT_LAST thought I'm not sure that's the correct thing to do. These changes are all about bringing events for network object like the ones existing for domains. This feature is needed for virt-manager to refresh its UI when networks are started/destroyed/defined/undefined. The network events are implemented in the test, bridge network and remote drivers ATM. Cédric Bosdonnat (34): Added domain start/stop/define/undefine event unit tests Rename virDomainEventCallback to virObjectEventCallback Renamed virDomainMeta to virObjectMeta Renamed virDomainEventQueue to virObjectEventQueue Renamed virDomainEventState to virObjectEventState Renamed virDomainEventCallbackList* to virObjectEventCallbackList* Created virObjectEventStateRegisterID virObject-ified virDomainEvent Create virDomainEventLifecycle to start removing the huge union Renamed virDomainEventNew* to virDomainEventLifecycleNew* Renamed virDomainEventNewInternal to virDomainEventNew Create virDomainEventRTCChange to get rid of the huge union Created virDomainEventWatchdog to get rid of the huge union Created virDomainEventIOError Created virDomainEventGraphics Created virDomainEventBlockJob Create virDomainEventDiskChange Created virDomainEventTrayChange Created virDomainEventBalloonChange Created virDomainEventDeviceRemoved and removed the huge union Changed the remaining domain event creation methods results to void* Removed virDomainEventPtr in favor of virObjectEventPtr Add object event namespaces for the event IDs Renamed virDomainEventTimer to virObjectEventTimer Split the virObjectEvent and virDomainEvent* to separate them after Extracted common parts of domain_event.[ch] to object_event.[ch] Added virNetworkEventLifecycle object Added API for network events similar to the one from Domain events test driver: renamed testDomainEventQueue into testObjectEventQueue test driver: implemented network events Add network events unit tests daemon/remote.c: renamed remoteDispatchDomainEventSend Add network events to the remote driver Added network events to the bridged network driver .gitignore |1 + cfg.mk |6 +- daemon/libvirtd.h|1 + daemon/remote.c | 175 ++- include/libvirt/libvirt.h.in | 86 ++ src/Makefile.am |6 + src/conf/domain_event.c | 1954 ++ src/conf/domain_event.h | 219 ++-- src/conf/object_event.c | 903 src/conf/object_event.h | 113 ++ src/conf/object_event_private.h | 113 ++ src/driver.h | 14 + src/libvirt.c| 133 +++ src/libvirt_private.syms | 25 +- src/libvirt_public.syms |7 + src/libxl/libxl_conf.h |2 +- src/libxl/libxl_driver.c | 46 +- src/lxc/lxc_conf.h |2 +- src/lxc/lxc_driver.c | 54 +- src/lxc/lxc_process.c| 20 +- src/network/bridge_driver.c | 89 ++ src/network/bridge_driver_platform.h |3 + src/parallels/parallels_utils.h |2 +- src/qemu/qemu_conf.h |2 +- src/qemu/qemu_domain.c |6 +- src/qemu/qemu_domain.h |2 +- src/qemu/qemu_driver.c | 116 +- src/qemu/qemu_hotplug.c | 10 +- src/qemu/qemu_migration.c| 38 +- src/qemu/qemu_process.c | 70 +- src/remote/remote_driver.c | 178 +++- src/remote/remote_protocol.x | 46 +- src/test/test_driver.c | 197 ++-- src/uml/uml_conf.h |2 +- src/uml/uml_driver.c | 44 +- src/vbox/vbox_tmpl.c | 22 +- src/xen/xen_driver.c | 10 +- src/xen/xen_driver.h |4 +- src/xen/xen_inotify.c| 10 +- src/xen/xs_internal.c| 20 +- tests/Makefile.am|7 + tests/objecteventtest.c
Re: [libvirt] [PATCH v4 4/7] Add network events to the remote driver
On Wed, Dec 11, 2013 at 11:38:01AM +0100, Cédric Bosdonnat wrote: --- daemon/libvirtd.h| 1 + daemon/remote.c | 139 +++ src/remote/remote_driver.c | 127 +++ src/remote/remote_protocol.x | 46 +- 4 files changed, 312 insertions(+), 1 deletion(-) Oppps, missed changes to src/remote_protocol-structs which causes 'make check' to fail - I've added the obvious bits. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v4 5/7] Added network events to the bridged network driver
On Wed, Dec 11, 2013 at 11:38:02AM +0100, Cédric Bosdonnat wrote: --- src/network/bridge_driver.c | 90 src/network/bridge_driver_platform.h | 3 ++ 2 files changed, 93 insertions(+) ACK +static int +networkConnectNetworkEventRegisterAny(virConnectPtr conn, + virNetworkPtr net, + int eventID, + virConnectNetworkEventGenericCallback callback, + void *opaque, + virFreeCallback freecb) +{ +virNetworkDriverStatePtr driver = conn-networkPrivateData; +int ret = -1; + +networkDriverLock(driver); + +if (virConnectNetworkEventRegisterAnyEnsureACL(conn) 0) +goto cleanup; + +if (virNetworkEventStateRegisterID(conn, driver-networkEventState, + net, eventID, + VIR_OBJECT_EVENT_CALLBACK(callback), + opaque, freecb, ret) 0) +ret = -1; + +networkDriverUnlock(driver); + +cleanup: +return ret; +} Opps, locking is wrong - if the ACL check fails we leave the driver locked. We can actually do without locking entirely, since the event state struct is self-locking, so I'll remove the lock/unlock + +static int +networkConnectNetworkEventDeregisterAny(virConnectPtr conn, +int callbackID) +{ +virNetworkDriverStatePtr driver = conn-networkPrivateData; +int ret = -1; + +if (virConnectNetworkEventDeregisterAnyEnsureACL(conn) 0) +goto cleanup; + + +networkDriverLock(driver); +ret = virObjectEventStateDeregisterID(conn, + driver-networkEventState, + callbackID); +networkDriverUnlock(driver); + +cleanup: +return ret; +} Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v4 7/7] Added default case with error for object event dispatching
On Wed, Dec 11, 2013 at 11:38:04AM +0100, Cédric Bosdonnat wrote: Hitting this should be pretty rare, but at least developers will know that they are providing a weird event ID. Otherwise for namespace that are added in the normal way, gcc will raise a warning about unhandled case in the switch. --- src/conf/object_event.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/conf/object_event.c b/src/conf/object_event.c index 0f21c37..1e0b33d 100644 --- a/src/conf/object_event.c +++ b/src/conf/object_event.c @@ -646,6 +646,8 @@ virObjectEventStateDispatchFunc(virConnectPtr conn, virNetworkEventDispatchDefaultFunc(conn, event, VIR_NETWORK_EVENT_CALLBACK(cb), cbopaque, NULL); break; +default: +VIR_ERROR(_(Unknown event namespace to dispatch)); } virObjectEventStateLock(state); } ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v4 6/7] Fixed indentation in src/conf/*_event*
On Wed, Dec 11, 2013 at 11:38:03AM +0100, Cédric Bosdonnat wrote: --- src/conf/domain_event.c | 286 +++- src/conf/domain_event.h | 271 + src/conf/object_event.c | 47 --- src/conf/object_event_private.h | 20 +-- 4 files changed, 364 insertions(+), 260 deletions(-) diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index da57129..45e48b6 100644 --- a/src/conf/domain_event.c +++ b/src/conf/domain_event.c @@ -443,11 +443,12 @@ virDomainEventCallbackListAdd(virConnectPtr conn, } -static void *virDomainEventNew(virClassPtr klass, - int eventID, - int id, - const char *name, - const unsigned char *uuid) +static void +*virDomainEventNew(virClassPtr klass, The '*' should be on the same line as the void. + int eventID, + int id, + const char *name, + const unsigned char *uuid) { virDomainEventPtr event; @@ -460,11 +464,12 @@ error: return NULL; } -void *virObjectEventNew(virClassPtr klass, -int eventID, -int id, -const char *name, -const unsigned char *uuid) +void +*virObjectEventNew(virClassPtr klass, And here + int eventID, + int id, + const char *name, + const unsigned char *uuid) { virObjectEventPtr event; -void *virObjectEventNew(virClassPtr klass, -int eventID, -int id, -const char *name, -const unsigned char *uuid); +void +*virObjectEventNew(virClassPtr klass, And here + int eventID, + int id, + const char *name, + const unsigned char *uuid); ACK will fix those bugs. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] ANNOUNCE: ruby-libvirt 0.5.0
On Wed, Dec 11, 2013 at 3:28 AM, Dominic Cleal dcl...@redhat.com wrote: Thanks for the fix Chris. A new release would be much appreciated as we're hitting this issue on gems, not RPMs. Our CI for Foreman (http://theforeman.org/) runs under a few Ruby versions and picked up this new version of the gem, so we'll need to pin to 0.5 otherwise. OK, I'll put out a new release. I may not get to it until tomorrow night; just FYI. Chris -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Read PCI class from sysfs class file instead of config space.
On Wed, Dec 11, 2013 at 12:23:59PM +, Daniel P. Berrange wrote: On Tue, Dec 10, 2013 at 07:57:01AM -0200, Thadeu Lima de Souza Cascardo wrote: When determining if a device is behind a PCI bridge, the PCI device class is checked by reading the config space. However, there are some devices which have the wrong class on the config space, but the class is initialized by Linux correctly as a PCI BRIDGE. This class can be read by the sysfs file '/sys/bus/pci/devices/:xx:xx.x/class'. Do you have any idea how long this file has been present in sysfs ? Hopefully it is a fairly ancient feature, so we can rely on it existing ? Otherwise we'll need to fallback to reading the config space when the sysfs file does not exist. At least 10 years, and before the config file was available (also more than 10 years). :-) One example of such bridge is IBM PCI Bridge 1014:03b9, which is identified as a Host Bridge when reading the config space. Signed-off-by: Thadeu Lima de Souza Cascardo casca...@linux.vnet.ibm.com --- src/util/virpci.c | 38 +++--- 1 files changed, 35 insertions(+), 3 deletions(-) Looks reasonable to me, though prefer Laine to ACK it since he knows the PCI code best of anyone Thanks for your review. Cascardo. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Read PCI class from sysfs class file instead of config space.
On 12/11/2013 02:23 PM, Daniel P. Berrange wrote: On Tue, Dec 10, 2013 at 07:57:01AM -0200, Thadeu Lima de Souza Cascardo wrote: When determining if a device is behind a PCI bridge, the PCI device class is checked by reading the config space. However, there are some devices which have the wrong class on the config space, but the class is initialized by Linux correctly as a PCI BRIDGE. This class can be read by the sysfs file '/sys/bus/pci/devices/:xx:xx.x/class'. Do you have any idea how long this file has been present in sysfs ? Hopefully it is a fairly ancient feature, so we can rely on it existing ? Otherwise we'll need to fallback to reading the config space when the sysfs file does not exist. One example of such bridge is IBM PCI Bridge 1014:03b9, which is identified as a Host Bridge when reading the config space. Signed-off-by: Thadeu Lima de Souza Cascardo casca...@linux.vnet.ibm.com --- src/util/virpci.c | 38 +++--- 1 files changed, 35 insertions(+), 3 deletions(-) Looks reasonable to me, though prefer Laine to ACK it since he knows the PCI code best of anyone ??? It's possible I'm the most recent person to poke it in a major way, but I still consider myself fairly unschooled on PCI. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Read PCI class from sysfs class file instead of config space.
On 12/10/2013 11:57 AM, Thadeu Lima de Souza Cascardo wrote: When determining if a device is behind a PCI bridge, the PCI device class is checked by reading the config space. However, there are some devices which have the wrong class on the config space, but the class is initialized by Linux correctly as a PCI BRIDGE. This class can be read by the sysfs file '/sys/bus/pci/devices/:xx:xx.x/class'. Since I'm not an expert on the PCI spec, I'll just have to take your word for this :-) One example of such bridge is IBM PCI Bridge 1014:03b9, which is identified as a Host Bridge when reading the config space. Signed-off-by: Thadeu Lima de Souza Cascardo casca...@linux.vnet.ibm.com --- src/util/virpci.c | 38 +++--- 1 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/util/virpci.c b/src/util/virpci.c index 8ec642f..8353411 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -344,6 +344,34 @@ virPCIDeviceRead32(virPCIDevicePtr dev, int cfgfd, unsigned int pos) } static int +virPCIDeviceReadClass(virPCIDevicePtr dev, uint16_t *device_class) +{ +char *path = NULL; +char *id_str; +int ret = 0; +unsigned int value; + +if (virPCIFile(path, dev-name, class) 0) +return -1; + +/* class string is '0xNN\n' ... i.e. 9 bytes */ +if (virFileReadAll(path, 9, id_str) 0) { +VIR_FREE(path); +return -1; +} + +VIR_FREE(path); + +id_str[8] = '\0'; +ret = virStrToLong_ui(id_str, NULL, 16, value); +if (ret == 0) +*device_class = (value 8) 0x; If the class file for some reason doesn't contain a hexadecimal number, this will return an error (-1) without having logged an error. This results in one of those An error occurred, but the cause is unknown messages, which is always very frustrating to debug. Even though it's *highly* unlikely that such an error would occur, we should still have the code to log it just in case. + +VIR_FREE(id_str); +return ret; +} + +static int virPCIDeviceWrite(virPCIDevicePtr dev, int cfgfd, unsigned int pos, @@ -645,8 +673,8 @@ virPCIDeviceIsParent(virPCIDevicePtr dev, virPCIDevicePtr check, void *data) return 0; /* Is it a bridge? */ -device_class = virPCIDeviceRead16(check, fd, PCI_CLASS_DEVICE); -if (device_class != PCI_CLASS_BRIDGE_PCI) +ret = virPCIDeviceReadClass(check, device_class); +if (ret == -1 || device_class != PCI_CLASS_BRIDGE_PCI) goto cleanup; /* Is it a plane? */ @@ -2110,6 +2138,7 @@ virPCIDeviceDownstreamLacksACS(virPCIDevicePtr dev) unsigned int pos; int fd; int ret = 0; +uint16_t device_class; if ((fd = virPCIDeviceConfigOpen(dev, true)) 0) return -1; @@ -2119,8 +2148,11 @@ virPCIDeviceDownstreamLacksACS(virPCIDevicePtr dev) goto cleanup; } +if (virPCIDeviceReadClass(dev, device_class)) +goto cleanup; + pos = dev-pcie_cap_pos; -if (!pos || virPCIDeviceRead16(dev, fd, PCI_CLASS_DEVICE) != PCI_CLASS_BRIDGE_PCI) +if (!pos || device_class != PCI_CLASS_BRIDGE_PCI) goto cleanup; flags = virPCIDeviceRead16(dev, fd, pos + PCI_EXP_FLAGS); Aside from the above lack of error logging, as Michal suggested a test case would be very useful. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Read PCI class from sysfs class file instead of config space.
On Wed, Dec 11, 2013 at 04:30:48PM +0200, Laine Stump wrote: On 12/10/2013 11:57 AM, Thadeu Lima de Souza Cascardo wrote: When determining if a device is behind a PCI bridge, the PCI device class is checked by reading the config space. However, there are some devices which have the wrong class on the config space, but the class is initialized by Linux correctly as a PCI BRIDGE. This class can be read by the sysfs file '/sys/bus/pci/devices/:xx:xx.x/class'. Since I'm not an expert on the PCI spec, I'll just have to take your word for this :-) Well, I'm not an expert either, but in this case, it's just a matter of dealing with bad hardware. After this patch, I managed to get a guest up with the PCI device and it worked. But if it makes everybody more comfortable (or less comfortable, realizing there is broken hardware out there :-), here are two snippets from kernel code: arch/powerpc/platforms/powernv/pci.c: /* Fixup wrong class code in p7ioc and p8 root complex */ static void pnv_p7ioc_rc_quirk(struct pci_dev *dev) { dev-class = PCI_CLASS_BRIDGE_PCI 8; } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IBM, 0x3b9, pnv_p7ioc_rc_quirk); vers/pci/host/pci-tegra.c: /* Tegra PCIE root complex wrongly reports device class */ static void tegra_pcie_fixup_class(struct pci_dev *dev) { dev-class = PCI_CLASS_BRIDGE_PCI 8; } DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf0, tegra_pcie_fixup_class); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_fixup_class); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_fixup_class); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_fixup_class); I just believe that, instead of introducing those same quirks into libvirt code, it's so much better to leave this at the kernel, and read the fixed value of class. One example of such bridge is IBM PCI Bridge 1014:03b9, which is identified as a Host Bridge when reading the config space. Signed-off-by: Thadeu Lima de Souza Cascardo casca...@linux.vnet.ibm.com --- src/util/virpci.c | 38 +++--- 1 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/util/virpci.c b/src/util/virpci.c index 8ec642f..8353411 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -344,6 +344,34 @@ virPCIDeviceRead32(virPCIDevicePtr dev, int cfgfd, unsigned int pos) } static int +virPCIDeviceReadClass(virPCIDevicePtr dev, uint16_t *device_class) +{ +char *path = NULL; +char *id_str; +int ret = 0; +unsigned int value; + +if (virPCIFile(path, dev-name, class) 0) +return -1; + +/* class string is '0xNN\n' ... i.e. 9 bytes */ +if (virFileReadAll(path, 9, id_str) 0) { +VIR_FREE(path); +return -1; +} + +VIR_FREE(path); + +id_str[8] = '\0'; +ret = virStrToLong_ui(id_str, NULL, 16, value); +if (ret == 0) +*device_class = (value 8) 0x; If the class file for some reason doesn't contain a hexadecimal number, this will return an error (-1) without having logged an error. This results in one of those An error occurred, but the cause is unknown messages, which is always very frustrating to debug. Even though it's *highly* unlikely that such an error would occur, we should still have the code to log it just in case. I will work it out and repost. + +VIR_FREE(id_str); +return ret; +} + +static int virPCIDeviceWrite(virPCIDevicePtr dev, int cfgfd, unsigned int pos, @@ -645,8 +673,8 @@ virPCIDeviceIsParent(virPCIDevicePtr dev, virPCIDevicePtr check, void *data) return 0; /* Is it a bridge? */ -device_class = virPCIDeviceRead16(check, fd, PCI_CLASS_DEVICE); -if (device_class != PCI_CLASS_BRIDGE_PCI) +ret = virPCIDeviceReadClass(check, device_class); +if (ret == -1 || device_class != PCI_CLASS_BRIDGE_PCI) goto cleanup; /* Is it a plane? */ @@ -2110,6 +2138,7 @@ virPCIDeviceDownstreamLacksACS(virPCIDevicePtr dev) unsigned int pos; int fd; int ret = 0; +uint16_t device_class; if ((fd = virPCIDeviceConfigOpen(dev, true)) 0) return -1; @@ -2119,8 +2148,11 @@ virPCIDeviceDownstreamLacksACS(virPCIDevicePtr dev) goto cleanup; } +if (virPCIDeviceReadClass(dev, device_class)) +goto cleanup; + pos = dev-pcie_cap_pos; -if (!pos || virPCIDeviceRead16(dev, fd, PCI_CLASS_DEVICE) != PCI_CLASS_BRIDGE_PCI) +if (!pos || device_class != PCI_CLASS_BRIDGE_PCI) goto cleanup; flags = virPCIDeviceRead16(dev, fd, pos + PCI_EXP_FLAGS); Aside from the above lack of error logging, as Michal suggested a test case would be very useful. I will work on that as well. I guess this should be a different commit, and
[libvirt] [PATCH] rbd: Use rbd_create3 to create RBD format 2 images by default
This new RBD format supports snapshotting and cloning. By having libvirt create images in format 2 end-users of the created images can benefit of the new RBD format. Older versions of libvirt can work with this new RBD format as long as librbd supports format 2, something that all recent versions of librbd do. Signed-off-by: Wido den Hollander w...@widodh.nl --- src/storage/storage_backend_rbd.c | 23 +-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c index 4b6f18c..f3dd7a0 100644 --- a/src/storage/storage_backend_rbd.c +++ b/src/storage/storage_backend_rbd.c @@ -435,6 +435,26 @@ cleanup: return ret; } +static int virStorageBackendRBDCreateImage(rados_ioctx_t io, + char *name, long capacity) +{ +int order = 0; +#if LIBRBD_VERSION_CODE 260 +uint64_t features = 3; +uint64_t stripe_count = 1; +uint64_t stripe_unit = 4194304; + +if (rbd_create3(io, name, capacity, features, order, +stripe_count, stripe_unit) 0) { +#else +if (rbd_create(io, name, capacity, order) 0) { +#endif +return -1; +} + +return 0; +} + static int virStorageBackendRBDCreateVol(virConnectPtr conn, virStoragePoolObjPtr pool, virStorageVolDefPtr vol) @@ -442,7 +462,6 @@ static int virStorageBackendRBDCreateVol(virConnectPtr conn, virStorageBackendRBDState ptr; ptr.cluster = NULL; ptr.ioctx = NULL; -int order = 0; int ret = -1; VIR_DEBUG(Creating RBD image %s/%s with size %llu, @@ -467,7 +486,7 @@ static int virStorageBackendRBDCreateVol(virConnectPtr conn, goto cleanup; } -if (rbd_create(ptr.ioctx, vol-name, vol-capacity, order) 0) { +if (virStorageBackendRBDCreateImage(ptr.ioctx, vol-name, vol-capacity) 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _(failed to create volume '%s/%s'), pool-def-source.name, -- 1.7.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/6] Update event demo program to support network events too
From: Daniel P. Berrange berra...@redhat.com --- examples/object-events/event-test.c | 45 +++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/examples/object-events/event-test.c b/examples/object-events/event-test.c index 52aa3d0..6a279cf 100644 --- a/examples/object-events/event-test.c +++ b/examples/object-events/event-test.c @@ -223,6 +223,27 @@ static const char *eventDetailToString(int event, int detail) { return ret; } +static const char * +networkEventToString(int event) +{ +const char *ret = ; +switch ((virNetworkEventLifecycleType) event) { +case VIR_NETWORK_EVENT_DEFINED: +ret =Defined; +break; +case VIR_NETWORK_EVENT_UNDEFINED: +ret =Undefined; +break; +case VIR_NETWORK_EVENT_STARTED: +ret =Started; +break; +case VIR_NETWORK_EVENT_STOPPED: +ret =Stopped; +break; +} +return ret; +} + static int myDomainEventCallback1(virConnectPtr conn ATTRIBUTE_UNUSED, virDomainPtr dom, int event, @@ -432,6 +453,18 @@ myDomainEventDeviceRemovedCallback(virConnectPtr conn ATTRIBUTE_UNUSED, return 0; } +static int myNetworkEventCallback2(virConnectPtr conn ATTRIBUTE_UNUSED, + virNetworkPtr dom, + int event, + int detail, + void *opaque ATTRIBUTE_UNUSED) +{ +printf(%s EVENT: Network %s %s %d\n, __func__, virNetworkGetName(dom), + networkEventToString(event), detail); +return 0; +} + + static void myFreeFunc(void *opaque) { char *str = opaque; @@ -472,6 +505,7 @@ int main(int argc, char **argv) int callback13ret = -1; int callback14ret = -1; int callback15ret = -1; +int callback16ret = -1; struct sigaction action_stop; memset(action_stop, 0, sizeof(action_stop)); @@ -510,7 +544,7 @@ int main(int argc, char **argv) sigaction(SIGTERM, action_stop, NULL); sigaction(SIGINT, action_stop, NULL); -VIR_DEBUG(Registering domain event cbs); +VIR_DEBUG(Registering event cbs); /* Add 2 callbacks to prove this works with more than just one */ callback1ret = virConnectDomainEventRegister(dconn, myDomainEventCallback1, @@ -585,6 +619,11 @@ int main(int argc, char **argv) VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED, VIR_DOMAIN_EVENT_CALLBACK(myDomainEventDeviceRemovedCallback), strdup(device removed), myFreeFunc); +callback16ret = virConnectNetworkEventRegisterAny(dconn, + NULL, + VIR_NETWORK_EVENT_ID_LIFECYCLE, + VIR_NETWORK_EVENT_CALLBACK(myNetworkEventCallback2), + strdup(callback 2), myFreeFunc); if ((callback1ret != -1) (callback2ret != -1) @@ -599,7 +638,8 @@ int main(int argc, char **argv) (callback12ret != -1) (callback13ret != -1) (callback14ret != -1) -(callback15ret != -1)) { +(callback15ret != -1) +(callback16ret != -1)) { if (virConnectSetKeepAlive(dconn, 5, 3) 0) { virErrorPtr err = virGetLastError(); fprintf(stderr, Failed to start keepalive protocol: %s\n, @@ -630,6 +670,7 @@ int main(int argc, char **argv) virConnectDomainEventDeregisterAny(dconn, callback13ret); virConnectDomainEventDeregisterAny(dconn, callback14ret); virConnectDomainEventDeregisterAny(dconn, callback15ret); +virConnectNetworkEventDeregisterAny(dconn, callback16ret); if (callback8ret != -1) virConnectDomainEventDeregisterAny(dconn, callback8ret); } -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 4/6] Introduce abstract virNetworkEvent class
From: Daniel P. Berrange berra...@redhat.com Inject a virNetworkEvent class between virObjectEvent and virNetworkEventLifecycle to mirror virDomainEvent. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- src/conf/network_event.c | 29 +++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/conf/network_event.c b/src/conf/network_event.c index b885ced..b1312b7 100644 --- a/src/conf/network_event.c +++ b/src/conf/network_event.c @@ -28,23 +28,40 @@ #include datatypes.h #include virlog.h -struct _virNetworkEventLifecycle { +struct _virNetworkEvent { virObjectEvent parent; +/* Unused attribute to get virNetworkEvent class being created */ +bool dummy; +}; +typedef struct _virNetworkEvent virNetworkEvent; +typedef virNetworkEvent *virNetworkEventPtr; + +struct _virNetworkEventLifecycle { +virNetworkEvent parent; + int type; int detail; }; typedef struct _virNetworkEventLifecycle virNetworkEventLifecycle; typedef virNetworkEventLifecycle *virNetworkEventLifecyclePtr; +static virClassPtr virNetworkEventClass; static virClassPtr virNetworkEventLifecycleClass; +static void virNetworkEventDispose(void *obj); static void virNetworkEventLifecycleDispose(void *obj); static int virNetworkEventsOnceInit(void) { -if (!(virNetworkEventLifecycleClass = +if (!(virNetworkEventClass = virClassNew(virClassForObjectEvent(), + virNetworkEvent, + sizeof(virNetworkEvent), + virNetworkEventDispose))) +return -1; +if (!(virNetworkEventLifecycleClass = + virClassNew(virNetworkEventClass, virNetworkEventLifecycle, sizeof(virNetworkEventLifecycle), virNetworkEventLifecycleDispose))) @@ -55,6 +72,14 @@ virNetworkEventsOnceInit(void) VIR_ONCE_GLOBAL_INIT(virNetworkEvents) void +virNetworkEventDispose(void *obj) +{ +virNetworkEventPtr event = obj; +VIR_DEBUG(obj=%p, event); +} + + +void virNetworkEventLifecycleDispose(void *obj) { virNetworkEventLifecyclePtr event = obj; -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/6] Misc improvements to events code
From: Daniel P. Berrange berra...@redhat.com This is a followup to the recent network events patches to improve a few things I noticed when testing this out for real. Daniel P. Berrange (6): Move examples/domain-events/event-c to examples/object-events Update event demo program to support network events too Add 'detail' arg to network lifecycle event internals Introduce abstract virNetworkEvent class Remove the event namespace concept Add debug output when registering event handlers Makefile.am | 2 +- configure.ac | 2 +- examples/domain-events/events-c/Makefile.am | 24 - examples/domain-events/events-c/event-test.c | 644 - examples/object-events/Makefile.am | 24 + examples/object-events/event-test.c | 685 +++ src/conf/domain_event.c | 18 +- src/conf/domain_event.h | 2 + src/conf/network_event.c | 58 ++- src/conf/network_event.h | 6 +- src/conf/object_event.c | 33 +- src/conf/object_event.h | 11 +- src/conf/object_event_private.h | 2 + src/network/bridge_driver.c | 15 +- src/remote/remote_driver.c | 2 +- src/test/test_driver.c | 15 +- 16 files changed, 828 insertions(+), 715 deletions(-) delete mode 100644 examples/domain-events/events-c/Makefile.am delete mode 100644 examples/domain-events/events-c/event-test.c create mode 100644 examples/object-events/Makefile.am create mode 100644 examples/object-events/event-test.c -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/6] Move examples/domain-events/event-c to examples/object-events
From: Daniel P. Berrange berra...@redhat.com The domain events demo program isn't really tied to domain events anymore, so rename it to object events. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- Makefile.am | 2 +- configure.ac | 2 +- examples/domain-events/events-c/Makefile.am | 24 - examples/domain-events/events-c/event-test.c | 644 --- examples/object-events/Makefile.am | 24 + examples/object-events/event-test.c | 644 +++ 6 files changed, 670 insertions(+), 670 deletions(-) delete mode 100644 examples/domain-events/events-c/Makefile.am delete mode 100644 examples/domain-events/events-c/event-test.c create mode 100644 examples/object-events/Makefile.am create mode 100644 examples/object-events/event-test.c diff --git a/Makefile.am b/Makefile.am index 2cbf71a..88c7073 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,7 +20,7 @@ LCOV = lcov GENHTML = genhtml SUBDIRS = . gnulib/lib include src daemon tools docs gnulib/tests \ - tests po examples/domain-events/events-c examples/hellolibvirt \ + tests po examples/object-events examples/hellolibvirt \ examples/dominfo examples/apparmor examples/xml/nwfilter \ examples/openauth examples/systemtap diff --git a/configure.ac b/configure.ac index 4465e01..d99e0df 100644 --- a/configure.ac +++ b/configure.ac @@ -2554,7 +2554,7 @@ AC_CONFIG_FILES([\ tools/Makefile \ tests/Makefile \ examples/apparmor/Makefile \ -examples/domain-events/events-c/Makefile \ +examples/object-events/Makefile \ examples/dominfo/Makefile \ examples/openauth/Makefile \ examples/hellolibvirt/Makefile \ diff --git a/examples/domain-events/events-c/Makefile.am b/examples/domain-events/events-c/Makefile.am deleted file mode 100644 index 86500a0..000 --- a/examples/domain-events/events-c/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -## Copyright (C) 2005-2011, 2013 Red Hat, Inc. -## -## This library is free software; you can redistribute it and/or -## modify it under the terms of the GNU Lesser General Public -## License as published by the Free Software Foundation; either -## version 2.1 of the License, or (at your option) any later version. -## -## This library is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## Lesser General Public License for more details. -## -## You should have received a copy of the GNU Lesser General Public -## License along with this library. If not, see -## http://www.gnu.org/licenses/. - -INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ - -I$(top_builddir)/gnulib/lib -I$(top_srcdir)/gnulib/lib \ - -I$(top_srcdir) -noinst_PROGRAMS = event-test -event_test_CFLAGS = $(WARN_CFLAGS) -event_test_SOURCES = event-test.c -event_test_LDADD = $(top_builddir)/src/libvirt.la \ -$(top_builddir)/gnulib/lib/libgnu.la diff --git a/examples/domain-events/events-c/event-test.c b/examples/domain-events/events-c/event-test.c deleted file mode 100644 index 52aa3d0..000 --- a/examples/domain-events/events-c/event-test.c +++ /dev/null @@ -1,644 +0,0 @@ -#include config.h - -#include stdio.h -#include stdlib.h -#include string.h -#include signal.h -#include inttypes.h - -#include libvirt/libvirt.h -#include libvirt/virterror.h - -#define VIR_DEBUG(fmt) printf(%s:%d: fmt \n, __func__, __LINE__) -#define STREQ(a,b) (strcmp(a,b) == 0) - -#ifndef ATTRIBUTE_UNUSED -# define ATTRIBUTE_UNUSED __attribute__((__unused__)) -#endif - -int run = 1; - -/* Prototypes */ -const char *eventToString(int event); -int myEventAddHandleFunc (int fd, int event, - virEventHandleCallback cb, - void *opaque, - virFreeCallback ff); -void myEventUpdateHandleFunc(int watch, int event); -int myEventRemoveHandleFunc(int watch); - -int myEventAddTimeoutFunc(int timeout, - virEventTimeoutCallback cb, - void *opaque, - virFreeCallback ff); -void myEventUpdateTimeoutFunc(int timer, int timout); -int myEventRemoveTimeoutFunc(int timer); - -int myEventHandleTypeToPollEvent(virEventHandleType events); -virEventHandleType myPollEventToEventHandleType(int events); - -void usage(const char *pname); - -/* Callback functions */ - - -static void connectClose(virConnectPtr conn ATTRIBUTE_UNUSED, - int reason, - void *opaque ATTRIBUTE_UNUSED) -{ -switch (reason) { -case VIR_CONNECT_CLOSE_REASON_ERROR: -fprintf(stderr, Connection closed due to I/O error\n); -break; -case VIR_CONNECT_CLOSE_REASON_EOF: -fprintf(stderr, Connection closed due to end of file\n); -
[libvirt] [PATCH 3/6] Add 'detail' arg to network lifecycle event internals
From: Daniel P. Berrange berra...@redhat.com While the public API wire protocol included the 'detail' arg for network lifecycle events, the internal event handling code did not process it. This meant that if a future libvirtd server starts sending non-0 'detail' args, the current libvirt client will not process them. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- src/conf/network_event.c| 7 +-- src/conf/network_event.h| 3 ++- src/network/bridge_driver.c | 15 ++- src/remote/remote_driver.c | 2 +- src/test/test_driver.c | 15 ++- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/conf/network_event.c b/src/conf/network_event.c index 4a02523..b885ced 100644 --- a/src/conf/network_event.c +++ b/src/conf/network_event.c @@ -32,6 +32,7 @@ struct _virNetworkEventLifecycle { virObjectEvent parent; int type; +int detail; }; typedef struct _virNetworkEventLifecycle virNetworkEventLifecycle; typedef virNetworkEventLifecycle *virNetworkEventLifecyclePtr; @@ -80,7 +81,7 @@ virNetworkEventDispatchDefaultFunc(virConnectPtr conn, networkLifecycleEvent = (virNetworkEventLifecyclePtr)event; ((virConnectNetworkEventLifecycleCallback)cb)(conn, net, networkLifecycleEvent-type, - 0, + networkLifecycleEvent-detail, cbopaque); goto cleanup; } @@ -135,7 +136,8 @@ virNetworkEventStateRegisterID(virConnectPtr conn, virObjectEventPtr virNetworkEventLifecycleNew(const char *name, const unsigned char *uuid, -int type) +int type, +int detail) { virNetworkEventLifecyclePtr event; int eventId = (VIR_EVENT_NAMESPACE_NETWORK 8) + VIR_NETWORK_EVENT_ID_LIFECYCLE; @@ -149,6 +151,7 @@ virNetworkEventLifecycleNew(const char *name, return NULL; event-type = type; +event-detail = detail; return (virObjectEventPtr)event; } diff --git a/src/conf/network_event.h b/src/conf/network_event.h index 44b762e..1eef771 100644 --- a/src/conf/network_event.h +++ b/src/conf/network_event.h @@ -40,7 +40,8 @@ virNetworkEventStateRegisterID(virConnectPtr conn, virObjectEventPtr virNetworkEventLifecycleNew(const char *name, const unsigned char *uuid, -int type); +int type, +int detail); void virNetworkEventDispatchDefaultFunc(virConnectPtr conn, diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 1bde7d7..3e10758 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -2559,7 +2559,8 @@ static virNetworkPtr networkCreateXML(virConnectPtr conn, const char *xml) { event = virNetworkEventLifecycleNew(network-def-name, network-def-uuid, -VIR_NETWORK_EVENT_STARTED); +VIR_NETWORK_EVENT_STARTED, +0); VIR_INFO(Creating network '%s', network-def-name); ret = virGetNetwork(conn, network-def-name, network-def-uuid); @@ -2621,7 +2622,8 @@ static virNetworkPtr networkDefineXML(virConnectPtr conn, const char *xml) { } event = virNetworkEventLifecycleNew(def-name, def-uuid, -VIR_NETWORK_EVENT_DEFINED); +VIR_NETWORK_EVENT_DEFINED, +0); VIR_INFO(Defining network '%s', def-name); ret = virGetNetwork(conn, def-name, def-uuid); @@ -2673,7 +2675,8 @@ networkUndefine(virNetworkPtr net) { event = virNetworkEventLifecycleNew(network-def-name, network-def-uuid, -VIR_NETWORK_EVENT_UNDEFINED); +VIR_NETWORK_EVENT_UNDEFINED, +0); VIR_INFO(Undefining network '%s', network-def-name); if (!active) { @@ -2890,7 +2893,8 @@ static int networkCreate(virNetworkPtr net) { event = virNetworkEventLifecycleNew(network-def-name, network-def-uuid, -VIR_NETWORK_EVENT_STARTED); +VIR_NETWORK_EVENT_STARTED, +0); cleanup: if (event) @@ -2930,7 +2934,8 @@ static int networkDestroy(virNetworkPtr net) { event = virNetworkEventLifecycleNew(network-def-name, network-def-uuid, -
[libvirt] [PATCH 6/6] Add debug output when registering event handlers
From: Daniel P. Berrange berra...@redhat.com Signed-off-by: Daniel P. Berrange berra...@redhat.com --- src/conf/object_event.c | 5 + 1 file changed, 5 insertions(+) diff --git a/src/conf/object_event.c b/src/conf/object_event.c index 964dccf..518fa1e 100644 --- a/src/conf/object_event.c +++ b/src/conf/object_event.c @@ -252,6 +252,11 @@ virObjectEventCallbackListAddID(virConnectPtr conn, size_t i; int ret = 0; +VIR_DEBUG(conn=%p cblist=%p uuid=%p name=%s id=%d + klass=%p eventID=%d callback=%p opaque=%p, + conn, cbList, uuid, name, id, klass, eventID, + callback, opaque); + /* Check incoming */ if (!cbList) { return -1; -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 5/6] Remove the event namespace concept
From: Daniel P. Berrange berra...@redhat.com The event namespace concept is redundant since the same information is available by looking at the class hierarchy of the events. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- src/conf/domain_event.c | 18 -- src/conf/domain_event.h | 2 ++ src/conf/network_event.c| 22 -- src/conf/network_event.h| 3 +++ src/conf/object_event.c | 28 +++- src/conf/object_event.h | 11 +++ src/conf/object_event_private.h | 2 ++ 7 files changed, 57 insertions(+), 29 deletions(-) diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index 64035f7..03164dc 100644 --- a/src/conf/domain_event.c +++ b/src/conf/domain_event.c @@ -437,6 +437,7 @@ virDomainEventCallbackListAdd(virConnectPtr conn, virFreeCallback freecb) { return virObjectEventCallbackListAddID(conn, cbList, NULL, NULL, 0, + virDomainEventClass, VIR_DOMAIN_EVENT_ID_LIFECYCLE, VIR_OBJECT_EVENT_CALLBACK(callback), opaque, freecb, NULL); @@ -1366,6 +1367,9 @@ virDomainEventStateRegister(virConnectPtr conn, { int ret = -1; +if (virDomainEventsInitialize() 0) +return -1; + virObjectEventStateLock(state); if ((state-callbacks-count == 0) @@ -1420,14 +1424,17 @@ virDomainEventStateRegisterID(virConnectPtr conn, virFreeCallback freecb, int *callbackID) { +if (virDomainEventsInitialize() 0) +return -1; + if (dom) return virObjectEventStateRegisterID(conn, state, dom-uuid, dom-name, - dom-id, eventID, + dom-id, virDomainEventClass, eventID, VIR_OBJECT_EVENT_CALLBACK(cb), opaque, freecb, callbackID); else return virObjectEventStateRegisterID(conn, state, NULL, NULL, 0, - eventID, + virDomainEventClass, eventID, VIR_OBJECT_EVENT_CALLBACK(cb), opaque, freecb, callbackID); } @@ -1468,3 +1475,10 @@ virDomainEventStateDeregister(virConnectPtr conn, virObjectEventStateUnlock(state); return ret; } + + +virClassPtr +virDomainEventGetBaseClass(void) +{ +return virDomainEventClass; +} diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h index 30156ed..5433950 100644 --- a/src/conf/domain_event.h +++ b/src/conf/domain_event.h @@ -30,6 +30,8 @@ # include object_event.h # include domain_conf.h +virClassPtr +virDomainEventGetBaseClass(void); virObjectEventPtr virDomainEventLifecycleNew(int id, diff --git a/src/conf/network_event.c b/src/conf/network_event.c index b1312b7..3108fea 100644 --- a/src/conf/network_event.c +++ b/src/conf/network_event.c @@ -98,7 +98,7 @@ virNetworkEventDispatchDefaultFunc(virConnectPtr conn, if (!net) return; -switch ((virNetworkEventID) (event-eventID 0xFF)) { +switch ((virNetworkEventID)event-eventID) { case VIR_NETWORK_EVENT_ID_LIFECYCLE: { virNetworkEventLifecyclePtr networkLifecycleEvent; @@ -147,14 +147,18 @@ virNetworkEventStateRegisterID(virConnectPtr conn, virFreeCallback freecb, int *callbackID) { -int nsEventID = (VIR_EVENT_NAMESPACE_NETWORK 8) + eventID; +if (virNetworkEventsInitialize() 0) +return -1; + if (net) return virObjectEventStateRegisterID(conn, state, - net-uuid, net-name, 0, nsEventID, + net-uuid, net-name, 0, + virNetworkEventClass, eventID, cb, opaque, freecb, callbackID); else return virObjectEventStateRegisterID(conn, state, - NULL, NULL, 0, nsEventID, + NULL, NULL, 0, + virNetworkEventClass, eventID, cb, opaque, freecb, callbackID); } @@ -165,13 +169,12 @@ virNetworkEventLifecycleNew(const char *name, int detail) { virNetworkEventLifecyclePtr event; -int eventId = (VIR_EVENT_NAMESPACE_NETWORK 8) + VIR_NETWORK_EVENT_ID_LIFECYCLE; if (virNetworkEventsInitialize() 0) return NULL; if (!(event = virObjectEventNew(virNetworkEventLifecycleClass, -
Re: [libvirt] [python PATCH v2] Added python binding for the new network events API
On Wed, Dec 11, 2013 at 01:37:18PM +0100, Cédric Bosdonnat wrote: --- Changes to previous patch: * Fixed Eric's comments * Updated code to latest libvirt patches submitted generator.py | 2 + libvirt-override-virConnect.py | 34 + libvirt-override.c | 152 + 3 files changed, 188 insertions(+) ACK and pushed Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH python 06/14] override: Replace PyString_AsString with libvirt_charPtrUnwrap
On Mon, Dec 09, 2013 at 10:33:25AM -0600, Doug Goldstein wrote: On Mon, Dec 9, 2013 at 9:15 AM, Daniel P. Berrange berra...@redhat.com wrote: From: Daniel P. Berrange berra...@redhat.com Replace calls to PyString_AsString with the helper method libvirt_charPtrUnwrap. This isolates the code that will change in Python3. In making this change, all callers now have responsibility for free'ing the string. Signed-off-by: Daniel P. Berrange berra...@redhat.com --- libvirt-override.c | 106 +++-- typewrappers.c | 18 + typewrappers.h | 1 + 3 files changed, 81 insertions(+), 44 deletions(-) @@ -194,12 +193,14 @@ setPyVirTypedParameter(PyObject *info, PyErr_Format(PyExc_LookupError, Attribute name \%s\ could not be recognized, keystr); +free(keystr); Here you use free() but goto cleanup; } strncpy(temp-field, keystr, sizeof(*temp-field) - 1); temp-field[sizeof(*temp-field) - 1] = '\0'; temp-type = params[i].type; +free(keystr); switch (params[i].type) { case VIR_TYPED_PARAM_INT: @@ -396,15 +399,20 @@ virPyDictToTypedParams(PyObject *dict, } case VIR_TYPED_PARAM_STRING: { -char *val = PyString_AsString(value); -if (!val || -virTypedParamsAddString(params, n, max, keystr, val) 0) +char *val;; +if (libvirt_charPtrUnwrap(value, val) 0 || +!val || +virTypedParamsAddString(params, n, max, keystr, val) 0) { +VIR_FREE(val); Here you use VIR_FREE(). We should probably be consistent. Yes, will fix to use VIR_FREE everywhere. @@ -5105,18 +5117,18 @@ libvirt_virConnectDomainEventDeregister(ATTRIBUTE_UNUSED PyObject * self, /*** * Event Impl ***/ -static PyObject *addHandleObj = NULL; -static char *addHandleName= NULL; -static PyObject *updateHandleObj = NULL; -static char *updateHandleName = NULL; -static PyObject *removeHandleObj = NULL; -static char *removeHandleName = NULL; -static PyObject *addTimeoutObj= NULL; -static char *addTimeoutName = NULL; -static PyObject *updateTimeoutObj = NULL; -static char *updateTimeoutName= NULL; -static PyObject *removeTimeoutObj = NULL; -static char *removeTimeoutName= NULL; +static PyObject *addHandleObj; +static char *addHandleName; +static PyObject *updateHandleObj; +static char *updateHandleName; +static PyObject *removeHandleObj; +static char *removeHandleName; +static PyObject *addTimeoutObj; +static char *addTimeoutName; +static PyObject *updateTimeoutObj; +static char *updateTimeoutName; +static PyObject *removeTimeoutObj; +static char *removeTimeoutName; Not sure the advantage of this change. Static variables are always NULL initially. Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH python 00/14] Finished port to Python3
On Mon, Dec 09, 2013 at 03:15:35PM +, Daniel P. Berrange wrote: From: Daniel P. Berrange berra...@redhat.com This series finishes the initial port to Python3. The code generator works, the C code compiles without warnings, and the sanitytest passes. The APIs using strings have all switched to PyUnicode except for thos which deal with binary data which now use PyBytes in Python 3 builds. This series is pushed with Doug's feedback incorporated. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH python] Add python3 to the automated build and RPM
From: Daniel P. Berrange berra...@redhat.com This updates autobuild.sh to test the python3 build process. The RPM specfile is changed to build a libvirt-python3 RPM on Fedora 18 Signed-off-by: Daniel P. Berrange berra...@redhat.com --- autobuild.sh | 6 ++ libvirt-python.spec.in | 57 +++--- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/autobuild.sh b/autobuild.sh index b3beaf1..c7d2661 100755 --- a/autobuild.sh +++ b/autobuild.sh @@ -13,6 +13,12 @@ python setup.py build python setup.py test python setup.py install --root=$AUTOBUILD_INSTALL_ROOT +if test -f /usr/bin/python3 ; then + python3 setup.py build + python3 setup.py test + python3 setup.py install --root=$AUTOBUILD_INSTALL_ROOT +fi + type -p /usr/bin/rpmbuild /dev/null 21 || exit 0 if [ -n $AUTOBUILD_COUNTER ]; then diff --git a/libvirt-python.spec.in b/libvirt-python.spec.in index 7c6257e..c61febc 100644 --- a/libvirt-python.spec.in +++ b/libvirt-python.spec.in @@ -1,5 +1,10 @@ -Summary: The libvirt virtualization API python binding +%global with_python3 0 +%if 0%{?fedora} 18 +%global with_python3 1 +%endif + +Summary: The libvirt virtualization API python2 binding Name: libvirt-python Version: @PY_VERSION@ Release: 1%{?dist}%{?extra_release} @@ -9,6 +14,17 @@ License: LGPLv2+ Group: Development/Libraries BuildRequires: libvirt-devel = @C_VERSION@ BuildRequires: python-devel +%if %{with_python3} +BuildRequires: python3-devel +%endif + +%if %{with_python3} +%package -n libvirt-python3 +Summary: The libvirt virtualization API python3 binding +Url: http://libvirt.org +License: LGPLv2+ +Group: Development/Libraries +%endif # Don't want provides for python shared objects %{?filter_provides_in: %filter_provides_in %{python_sitearch}/.*\.so} @@ -20,22 +36,49 @@ written in the Python programming language to use the interface supplied by the libvirt library to use the virtualization capabilities of recent versions of Linux (and other OSes). +%if %{with_python3} +%description -n libvirt-python3 +The libvirt-python package contains a module that permits applications +written in the Python programming language to use the interface +supplied by the libvirt library to use the virtualization capabilities +of recent versions of Linux (and other OSes). +%endif + %prep %setup -q %build -CFLAGS=$RPM_OPT_FLAGS %{__python} setup.py build +CFLAGS=$RPM_OPT_FLAGS %{__python2} setup.py build +%if %{with_python3} +CFLAGS=$RPM_OPT_FLAGS %{__python3} setup.py build +%endif %install -%{__python} setup.py install --skip-build --root=%{buildroot} +%{__python2} setup.py install --skip-build --root=%{buildroot} +%if %{with_python3} +%{__python3} setup.py install --skip-build --root=%{buildroot} +%endif rm -f %{buildroot}%{_libdir}/python*/site-packages/*egg-info %files %defattr(-,root,root) %doc ChangeLog AUTHORS NEWS README COPYING COPYING.LESSER examples/ -%{_libdir}/python*/site-packages/libvirt.py* -%{_libdir}/python*/site-packages/libvirt_qemu.py* -%{_libdir}/python*/site-packages/libvirt_lxc.py* -%{_libdir}/python*/site-packages/libvirtmod* +%{_libdir}/python2*/site-packages/libvirt.py* +%{_libdir}/python2*/site-packages/libvirt_qemu.py* +%{_libdir}/python2*/site-packages/libvirt_lxc.py* +%{_libdir}/python2*/site-packages/libvirtmod* + +%if %{with_python3} +%files -n libvirt-python3 +%defattr(-,root,root) +%doc ChangeLog AUTHORS NEWS README COPYING COPYING.LESSER examples/ +%{_libdir}/python3*/site-packages/libvirt.py* +%{_libdir}/python3*/site-packages/libvirt_qemu.py* +%{_libdir}/python3*/site-packages/libvirt_lxc.py* +%{_libdir}/python3*/site-packages/__pycache__/libvirt.cpython-*.py* +%{_libdir}/python3*/site-packages/__pycache__/libvirt_qemu.cpython-*.py* +%{_libdir}/python3*/site-packages/__pycache__/libvirt_lxc.cpython-*.py* +%{_libdir}/python3*/site-packages/libvirtmod* +%endif %changelog -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] RFC: Changing version number at start of dev cycle instead of end
Currently throughout the dev cycle we stick on the current release number. The release number in configure.ac is only changed by DV when he is actually cutting the release. With the python bindings now being split out, this is causing us problems. The python code aims to build against any libvirt version that exists, so for example, the new network events APIs in libvirt will be included with version 1.2.1. So the python binding does #if LIBVIR_CHECK_VERSION(1, 2, 1) static void libvirt_virConnectNetworkEventFreeFunc(void *opaque) { PyObject *pyobj_conn = (PyObject*)opaque; LIBVIRT_ENSURE_THREAD_STATE; Py_DECREF(pyobj_conn); LIBVIRT_RELEASE_THREAD_STATE; } ... This works fine if a python release is built against a libvirt release. It does not work if a python git snapshot is built against a libvirt git snapshot. This is bad because it prevents us doing automated builds of GIT. The solution here is fairly simple. We should increase the version number in configure.ac at the *start* of each release cycle. This means that libvirt-python can use the next version number and things will 'just work'. I don't think this is a burden really - we already encode the next version number in our source code when tagging new APIs or driver methods. We're really just bringing autoconf's view of the version number inline with the rest of the code. So if no one objects, we should immediately change configure.ac to be 1.2.1 Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] ?????? about libvirt install
Hello Daniel Very thank you for your reply.And i use libvirt-1.2.0 .The problem solved. Thank you again. Wang -- -- ??: Daniel P. Berrange;berra...@redhat.com; : 2013??12??10??(??) 11:19 ??: -89931...@qq.com; : libvir-listlibvir-list@redhat.com; : Re: [libvirt] about libvirt install On Tue, Dec 10, 2013 at 07:28:40PM +0800, - wrote: hello: when i configure libvirt-0.9.0 it always show: configure: error: You must install kernel-headers in order to compile libvirt with QEMU or LXC support Please show the output of configure leading upto this - ie what it was checking for when it failed. I'd also *STRONGLY* suggest using a newer libvirt - 0.9.0 is ancient history and there are known problems when building against some glibc/kernel versions. Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| .-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] RFC: Changing version number at start of dev cycle instead of end
On 12/11/2013 09:44 AM, Daniel P. Berrange wrote: Currently throughout the dev cycle we stick on the current release number. The release number in configure.ac is only changed by DV when he is actually cutting the release. The solution here is fairly simple. We should increase the version number in configure.ac at the *start* of each release cycle. This means that libvirt-python can use the next version number and things will 'just work'. I don't think this is a burden really - we already encode the next version number in our source code when tagging new APIs or driver methods. We're really just bringing autoconf's view of the version number inline with the rest of the code. So if no one objects, we should immediately change configure.ac to be 1.2.1 Makes sense to me, but I'd wait for DV to concur. -- Eric Blake eblake redhat com+1-919-301-3266 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 1/2] interface: Introduce netcfInterfaceObjIsActive
On 12/11/2013 05:41 AM, Michal Privoznik wrote: +static int +netcfInterfaceObjIsActive(struct netcf_if *iface, + bool *active) +{ +int ret = -1; +unsigned int flags = 0; + +virObjectRef(driverState); What's the ref / unref of driverState for ? The code you're replacing doesn't do that, and AFAICT this shouldn't be required since we're always calling this from public API context Well, for now it is not required, true. But I was thinking if somebody rewrites something this part wouldn't need any change as it's already foolproof. But I don't mind dropping ref and unref. Spurious locking now for future code patches is counter-productive; if someone adds code that needs locking, we can add the locking at that point (and ideally keeping things lockless is the better approach). So yes, let's drop the ref and unref. -- Eric Blake eblake redhat com+1-919-301-3266 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 00/34] network events feature v2
On 12/11/2013 06:18 AM, Michal Privoznik wrote: I'm getting some compile errors on ARM: CC conf/libvirt_conf_la-domain_event.lo conf/domain_event.c: In function 'virDomainEventDispatchDefaultFunc': conf/domain_event.c:1148:30: error: cast increases required alignment of target type [-Werror=cast-align] rtcChangeEvent = (virDomainEventRTCChangePtr)event; Hmm. In this case, event is virObjectEventPtr, and rtcChangeEvent is virDomainEventRTCChangePtr. Comparing the two structs, I see the problem: struct _virObjectEvent { virObject parent; int eventID; virObjectMeta meta; }; Only has alignment specified by virObject (which in turn is unsigned int, int, void*), int, and virObjectMeta (which in turn is int, char*, unsigned char[]). vs. struct _virDomainEventRTCChange { virDomainEvent parent; long long offset; }; I think one possible solution would be as simple as altering src/util/virobject.h to change 'magic' from 'unsigned int' to 'unsigned long long' - then ALL virObject structs will be forcefully aligned to the worst case between void* and long long, so that any subclass can use long long without requiring stricter alignment than the parent class, and so that downcasting code like domain_event.c no longer warns. But it does make every object consume more memory on 64-bit platforms (from 16 bytes into 24 bytes), is that okay? -- Eric Blake eblake redhat com+1-919-301-3266 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 00/34] network events feature v2
On 12/11/2013 12:15 PM, Eric Blake wrote: struct _virObjectEvent { virObject parent; int eventID; virObjectMeta meta; }; Only has alignment specified by virObject (which in turn is unsigned int, int, void*), struct _virObject { unsigned int magic; int refs; virClassPtr klass; }; I think one possible solution would be as simple as altering src/util/virobject.h to change 'magic' from 'unsigned int' to 'unsigned long long' - then ALL virObject structs will be forcefully aligned to the worst case between void* and long long, so that any subclass can use long long without requiring stricter alignment than the parent class, and so that downcasting code like domain_event.c no longer warns. But it does make every object consume more memory on 64-bit platforms (from 16 bytes into 24 bytes), is that okay? Or maybe even change _virObject to contain a union: struct _virObject { union { long long align; struct { unsigned int magic; int refs; } s; } u; virClassPtr klass; } which keeps the size at 16 bytes on 64-bit platform, keeps things at 12 bytes on 32-bit platforms that don't care about long long alignment, and for ARM (*) would change things from 12 to 16 bytes with 8-byte alignment for the long long. Yeah, that means using obj-u.s.refs instead of obj-refs, but most code shouldn't be directly mucking with object-internal fields, so hopefully the fallout would be limited to just virobject.c (if only C99 had anonymous struct/unions; C11 does, but we don't require that yet). (*) Am I correct that your platform with the compile failure is a 32-bit ARM platform with 4-byte pointers? Because if it were 64-bit, then I would have guessed that an 8-byte pointer would already be forcing 8-byte alignment, such that use of 'long long' in a subclass wouldn't be warning about changed alignment. -- Eric Blake eblake redhat com+1-919-301-3266 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] Glusterfs Libvirt issue
On 12/10/2013 10:34 PM, Umar Draz wrote: Hi, I am trying to create glusterfs pool with libvirt but its working, and following is the error *libvirt_storagepool_define_xml(): internal error unknown storage pool type gluster* What version of libvirt? If older than 1.2.0, upgrade (gluster pool was added only in 1.2.0); if it is 1.2.0, then figure out why your build was not configured to link against libgfapi (if you self-built, use --with-storage-gluster=yes; if it is a distro build, complain to the distro packagers). [Oh phooey - I just noticed that 'virsh --version=long' doesn't give any hints about whether gluster support was compiled in. Looks like I have a patch coming up to fix that - although not including that information doesn't impact anything except easier diagnosis of whether it was compiled in] -- Eric Blake eblake redhat com+1-919-301-3266 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 python] Add python3 to the automated build and RPM
On 12/11/2013 09:31 AM, Daniel P. Berrange wrote: From: Daniel P. Berrange berra...@redhat.com This updates autobuild.sh to test the python3 build process. The RPM specfile is changed to build a libvirt-python3 RPM on Fedora 18 Signed-off-by: Daniel P. Berrange berra...@redhat.com --- autobuild.sh | 6 ++ libvirt-python.spec.in | 57 +++--- 2 files changed, 56 insertions(+), 7 deletions(-) +++ b/libvirt-python.spec.in @@ -1,5 +1,10 @@ -Summary: The libvirt virtualization API python binding +%global with_python3 0 +%if 0%{?fedora} 18 +%global with_python3 1 +%endif Is %global the right thing to use? Elsewhere we have just used %define when setting up a variable that conditionalizes the rest of the spec file. %build -CFLAGS=$RPM_OPT_FLAGS %{__python} setup.py build +CFLAGS=$RPM_OPT_FLAGS %{__python2} setup.py build How far back can we assume that %{__python2} exists? Is it going to bite us on RHEL 6 (where I'm guessing there is just %{__python})? +%if %{with_python3} +CFLAGS=$RPM_OPT_FLAGS %{__python3} setup.py build +%endif %install -%{__python} setup.py install --skip-build --root=%{buildroot} +%{__python2} setup.py install --skip-build --root=%{buildroot} More use of %{__python2}. Everything else looks okay to me, although I did not actually do any testing of the rpms. -- Eric Blake eblake redhat com+1-919-301-3266 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] Glusterfs Libvirt issue
Hi Eric Here is the output of rpm [root@centos ~]# rpm -qa | grep libvirt libvirt-python-0.10.2-29.el6.1.x86_64 libvirt-0.10.2-29.el6.1.x86_64 libvirt-client-0.10.2-29.el6.1.x86_64 libvirt-devel-0.10.2-29.el6.1.x86_64 and here is output of php code Array ( [libvirt.release] = 2 [libvirt.minor] = 10 [libvirt.major] = 0 [connector.version] = 0.4.8 [connector.major] = 0 [connector.minor] = 4 [connector.release] = 8 ) Br. Umar On Thu, Dec 12, 2013 at 12:51 AM, Eric Blake ebl...@redhat.com wrote: On 12/10/2013 10:34 PM, Umar Draz wrote: Hi, I am trying to create glusterfs pool with libvirt but its working, and following is the error *libvirt_storagepool_define_xml(): internal error unknown storage pool type gluster* What version of libvirt? If older than 1.2.0, upgrade (gluster pool was added only in 1.2.0); if it is 1.2.0, then figure out why your build was not configured to link against libgfapi (if you self-built, use --with-storage-gluster=yes; if it is a distro build, complain to the distro packagers). [Oh phooey - I just noticed that 'virsh --version=long' doesn't give any hints about whether gluster support was compiled in. Looks like I have a patch coming up to fix that - although not including that information doesn't impact anything except easier diagnosis of whether it was compiled in] -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org -- Umar Draz Network Architect -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Glusterfs Libvirt issue
On 12/11/2013 01:18 PM, Umar Draz wrote: Hi Eric [please don't top-post on technical lists] Here is the output of rpm [root@centos ~]# rpm -qa | grep libvirt libvirt-python-0.10.2-29.el6.1.x86_64 libvirt-0.10.2-29.el6.1.x86_64 There's your problem - gluster pools did not exist in libvirt 0.10.2. If you have a Red Hat support contract, you can request that it be added for RHEL 6.6 and/or RHEL 7.0 (the RHEL 7 public beta began today, but even that build is based off of libvirt 1.1.1 rather than 1.2.0). If you are using CentOS, you'll just have to wait and/or self-build. -- Eric Blake eblake redhat com+1-919-301-3266 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
[libvirt] [PATCH] qemu: add support for error messages greater than 1024 characters
In libvirt, the default error message length is 1024 bytes. This is not enough for qemu to print long error messages such as the list of supported ARM machine models (more than 1700 chars). This is raised when the machine entry in the XML file is wrong, but there may be now or in future other verbose error messages. The above patch enables libvirt to print error messages 1024 for qemu. Signed-off-by: Michele Paolino m.paol...@virtualopensystems.com --- src/qemu/qemu_process.c | 23 +++ 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index bd9546e..c2e2136 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1904,10 +1904,25 @@ cleanup: * a possible read of the fd in the monitor code doesn't influence this * error delivery option */ ignore_value(lseek(logfd, pos, SEEK_SET)); -qemuProcessReadLog(logfd, buf + len, buf_size - len - 1, 0, true); -virReportError(VIR_ERR_INTERNAL_ERROR, - _(process exited while connecting to monitor: %s), - buf); +len = qemuProcessReadLog(logfd, buf + len, buf_size - len - 1, 0, true); + +/* virReportError error buffer is limited to 1024 byte*/ +if (len 1024){ +virReportError(VIR_ERR_INTERNAL_ERROR, +_(process exited while connecting to monitor: %s), +buf); +} else { + if (STRPREFIX(buf, Supported machines are:)) + virReportError(VIR_ERR_INTERNAL_ERROR, + _(process exited while connecting to monitor: + please check machine model)); + else + virReportError(VIR_ERR_INTERNAL_ERROR, + _(process exited while connecting to monitor)); + + VIR_ERROR(%s, buf); +} + ret = -1; } -- 1.7.9.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Glusterfs Libvirt issue
Hi Eric Thanks Br. Umar On Thu, Dec 12, 2013 at 1:23 AM, Eric Blake ebl...@redhat.com wrote: On 12/11/2013 01:18 PM, Umar Draz wrote: Hi Eric [please don't top-post on technical lists] Here is the output of rpm [root@centos ~]# rpm -qa | grep libvirt libvirt-python-0.10.2-29.el6.1.x86_64 libvirt-0.10.2-29.el6.1.x86_64 There's your problem - gluster pools did not exist in libvirt 0.10.2. If you have a Red Hat support contract, you can request that it be added for RHEL 6.6 and/or RHEL 7.0 (the RHEL 7 public beta began today, but even that build is based off of libvirt 1.1.1 rather than 1.2.0). If you are using CentOS, you'll just have to wait and/or self-build. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org -- Umar Draz Network Architect -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] RFC: Changing version number at start of dev cycle instead of end
On Wed, Dec 11, 2013 at 11:59:55AM -0700, Eric Blake wrote: On 12/11/2013 09:44 AM, Daniel P. Berrange wrote: Currently throughout the dev cycle we stick on the current release number. The release number in configure.ac is only changed by DV when he is actually cutting the release. The solution here is fairly simple. We should increase the version number in configure.ac at the *start* of each release cycle. This means that libvirt-python can use the next version number and things will 'just work'. I don't think this is a burden really - we already encode the next version number in our source code when tagging new APIs or driver methods. We're really just bringing autoconf's view of the version number inline with the rest of the code. So if no one objects, we should immediately change configure.ac to be 1.2.1 Makes sense to me, but I'd wait for DV to concur. ACK Daniel -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org -- Daniel Veillard | Open Source and Standards, Red Hat veill...@redhat.com | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [test-API][PATCH] Add new case for listAllVolumes and update releated conf
listAllVolumes is a new API in RHEL7, so add a new case for it. And add the case to releated conf to check the volumes list. modified: cases/storage_dir.conf modified: cases/storage_dir_vol_resize_delta.conf modified: cases/storage_logical.conf modified: cases/storage_netfs.conf new file: repos/storage/list_volumes.py --- cases/storage_dir.conf | 16 + cases/storage_dir_vol_resize_delta.conf |8 +++ cases/storage_logical.conf | 16 + cases/storage_netfs.conf| 16 + repos/storage/list_volumes.py | 97 +++ 5 files changed, 153 insertions(+), 0 deletions(-) create mode 100644 repos/storage/list_volumes.py diff --git a/cases/storage_dir.conf b/cases/storage_dir.conf index 38b349d..393d34f 100644 --- a/cases/storage_dir.conf +++ b/cases/storage_dir.conf @@ -20,6 +20,10 @@ storage:create_dir_volume capacity $defaultvolumesize +storage:list_volumes +poolname +$defaultpoolname + storage:vol_clone poolname $defaultpoolname @@ -28,18 +32,30 @@ storage:vol_clone clonevolname $defaultvolclonename +storage:list_volumes +poolname +$defaultpoolname + storage:delete_dir_volume poolname $defaultpoolname volname $defaultvolclonename +storage:list_volumes +poolname +$defaultpoolname + storage:delete_dir_volume poolname $defaultpoolname volname $defaultvolumename +storage:list_volumes +poolname +$defaultpoolname + storage:destroy_pool poolname $defaultpoolname diff --git a/cases/storage_dir_vol_resize_delta.conf b/cases/storage_dir_vol_resize_delta.conf index 58e15bf..22d3b47 100644 --- a/cases/storage_dir_vol_resize_delta.conf +++ b/cases/storage_dir_vol_resize_delta.conf @@ -12,6 +12,10 @@ storage:create_dir_volume capacity $defaultvolumesize +storage:list_volumes +poolname +$defaultpoolname + storage:vol_resize_delta poolname $defaultpoolname @@ -42,6 +46,10 @@ storage:delete_dir_volume volname $defaultvolumename +storage:list_volumes +poolname +$defaultpoolname + storage:destroy_pool poolname $defaultpoolname diff --git a/cases/storage_logical.conf b/cases/storage_logical.conf index d374dfa..a0fdad6 100644 --- a/cases/storage_logical.conf +++ b/cases/storage_logical.conf @@ -22,6 +22,10 @@ storage:create_logical_volume capacity $defaultvolumesize +storage:list_volumes +poolname +$defaultpoolname + storage:vol_clone poolname $defaultpoolname @@ -30,18 +34,30 @@ storage:vol_clone clonevolname $defaultvolclonename +storage:list_volumes +poolname +$defaultpoolname + storage:delete_logical_volume poolname $defaultpoolname volname $defaultvolclonename +storage:list_volumes +poolname +$defaultpoolname + storage:delete_logical_volume poolname $defaultpoolname volname $defaultvolumename +storage:list_volumes +poolname +$defaultpoolname + storage:destroy_pool poolname $defaultpoolname diff --git a/cases/storage_netfs.conf b/cases/storage_netfs.conf index f486ff4..6880763 100644 --- a/cases/storage_netfs.conf +++ b/cases/storage_netfs.conf @@ -24,6 +24,10 @@ storage:create_netfs_volume capacity $defaultvolumesize +storage:list_volumes +poolname +$defaultpoolname + storage:vol_clone poolname $defaultpoolname @@ -32,18 +36,30 @@ storage:vol_clone clonevolname $defaultvolclonename +storage:list_volumes +poolname +$defaultpoolname + storage:delete_netfs_volume poolname $defaultpoolname volname $defaultvolclonename +storage:list_volumes +poolname +$defaultpoolname + storage:delete_netfs_volume poolname $defaultpoolname volname $defaultvolumename +storage:list_volumes +poolname +$defaultpoolname + storage:destroy_pool poolname $defaultpoolname diff --git a/repos/storage/list_volumes.py b/repos/storage/list_volumes.py new file mode 100644 index 000..9555720 --- /dev/null +++ b/repos/storage/list_volumes.py @@ -0,0 +1,97 @@ +#!/usr/bin/evn python + +import libvirt +from libvirt import libvirtError +from xml.dom import minidom + +from utils import utils + +from src import sharedmod + +required_params = ('poolname',) +optional_params = {} + + +def get_pool_path(pool_obj): + +Get the pool path + +poolxml = pool_obj.XMLDesc(0) +logger.debug(the xml description of pool is %s % poolxml) + +doc = minidom.parseString(poolxml) +path_element = doc.getElementsByTagName('path')[0] +textnode = path_element.childNodes[0] +path_value = textnode.data + +
[libvirt] [PATCH] storage: show compile options in virsh --version=long
Adding output to 'virsh --version=long' makes it easier to tell if a distro built with particular libraries (it doesn't tell you what a remote libvirtd is built with, but is still better than nothing). * tools/virsh.c (vshShowVersion): Add gluster witness. Signed-off-by: Eric Blake ebl...@redhat.com --- tools/virsh.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/virsh.c b/tools/virsh.c index 5559d71..9d07d3e 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -3069,6 +3069,9 @@ vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED) #ifdef WITH_STORAGE_SHEEPDOG vshPrint(ctl, Sheepdog); #endif +#ifdef WITH_STORAGE_GLUSTER +vshPrint(ctl, Gluster); +#endif vshPrint(ctl, \n); vshPrint(ctl, %s, _( Miscellaneous:)); -- 1.8.4.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] storage: show compile options in virsh --version=long
On Wed, Dec 11, 2013 at 9:10 PM, Eric Blake ebl...@redhat.com wrote: Adding output to 'virsh --version=long' makes it easier to tell if a distro built with particular libraries (it doesn't tell you what a remote libvirtd is built with, but is still better than nothing). * tools/virsh.c (vshShowVersion): Add gluster witness. Signed-off-by: Eric Blake ebl...@redhat.com --- tools/virsh.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/virsh.c b/tools/virsh.c index 5559d71..9d07d3e 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -3069,6 +3069,9 @@ vshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED) #ifdef WITH_STORAGE_SHEEPDOG vshPrint(ctl, Sheepdog); #endif +#ifdef WITH_STORAGE_GLUSTER +vshPrint(ctl, Gluster); +#endif vshPrint(ctl, \n); vshPrint(ctl, %s, _( Miscellaneous:)); -- 1.8.4.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From a code stand point this is fine. But the commit subject and message are ambiguous and don't really explain what you're doing. It seems like you're adding all storage compile options into the output when really they were there already and just Gluster was missing. Wouldn't be better to say storage: show gluster option in virsh --version=long? I realize I'm nitpicking the commit message/subject, the code is fine so ACK from that stand point. -- Doug Goldstein -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [RFC/PATCH python] expose the bindings version to Python
The method getVersion() retrieves the version of the libvirt library that the binaries are linked against but there is no way to retrieve the version of the bindings you are using. In the future if we support new APIs in Python that don't rely on features in the library there needs to be a way for programmers to detect the version. --- I would expect there's a cleaner way to implement this than I've done but I opted for what I saw as the smallest implementation. If anyone has a suggestion for a better way to do this I'm ok with redoing this patch. --- libvirt-override.py | 3 +++ setup.py| 16 2 files changed, 19 insertions(+) diff --git a/libvirt-override.py b/libvirt-override.py index 63f8ecb..ed8f73a 100644 --- a/libvirt-override.py +++ b/libvirt-override.py @@ -2,6 +2,9 @@ # Manually written part of python bindings for libvirt # +__version__ = '@VERSION@' +version = @VER_TUPLE@ + # On cygwin, the DLL is called cygvirtmod.dll import sys diff --git a/setup.py b/setup.py index 24d4cf2..ad4f406 100755 --- a/setup.py +++ b/setup.py @@ -119,6 +119,21 @@ if have_libvirt_lxc: class my_build(build): +def gen_version(self, filename): +os.rename(filename, filename + '.tmp') + +version = self.distribution.get_version() +ver_tuple = tuple(int(x) for x in version.split('.')) + +f1 = open(filename + '.tmp', 'r') +f2 = open(filename, 'w') +for line in f1: +f2.write(line +.replace('@VER_TUPLE@', str(ver_tuple)) +.replace('@VERSION@', version)) +f1.close() +f2.close() + def run(self): apis = get_api_xml_files() @@ -127,6 +142,7 @@ class my_build(build): if have_libvirt_lxc: self.spawn([sys.executable, generator.py, libvirt-lxc, apis[2]]) +self.gen_version('build/libvirt.py') build.run(self) class my_sdist(sdist): -- 1.8.3.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [test-API][PATCH] Add new case for listAllVolumes and update releated conf
On 2013年12月12日 10:13, codong wrote: listAllVolumes is a new API in RHEL7, so add a new case for it. And add the case to releated conf to check the volumes list. modified: cases/storage_dir.conf modified: cases/storage_dir_vol_resize_delta.conf modified: cases/storage_logical.conf modified: cases/storage_netfs.conf new file: repos/storage/list_volumes.py --- cases/storage_dir.conf | 16 + cases/storage_dir_vol_resize_delta.conf |8 +++ cases/storage_logical.conf | 16 + cases/storage_netfs.conf| 16 + repos/storage/list_volumes.py | 97 +++ 5 files changed, 153 insertions(+), 0 deletions(-) create mode 100644 repos/storage/list_volumes.py The testcase works for the pool of dir type only. If you want to test pool of all type in one testcase, the testcase is not good enough obviously. Guannan -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] storage: show compile options in virsh --version=long
On 12/11/2013 08:38 PM, Doug Goldstein wrote: On Wed, Dec 11, 2013 at 9:10 PM, Eric Blake ebl...@redhat.com wrote: Adding output to 'virsh --version=long' makes it easier to tell if a distro built with particular libraries (it doesn't tell you what a remote libvirtd is built with, but is still better than nothing). From a code stand point this is fine. But the commit subject and message are ambiguous and don't really explain what you're doing. It seems like you're adding all storage compile options into the output when really they were there already and just Gluster was missing. Wouldn't be better to say storage: show gluster option in virsh --version=long? Sure, that sounds nicer. I realize I'm nitpicking the commit message/subject, the code is fine so ACK from that stand point. Amended and pushed -- Eric Blake eblake redhat com+1-919-301-3266 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] [test-API][PATCH] Add new case for listAllVolumes and update releated conf
- Original Message - From: Guannan Ren g...@redhat.com To: codong cod...@redhat.com Cc: libvir-list@redhat.com Sent: Thursday, December 12, 2013 11:57:31 AM Subject: Re: [libvirt][test-API][PATCH] Add new case for listAllVolumes and update releated conf On 2013年12月12日 10:13, codong wrote: listAllVolumes is a new API in RHEL7, so add a new case for it. And add the case to releated conf to check the volumes list. modified: cases/storage_dir.conf modified: cases/storage_dir_vol_resize_delta.conf modified: cases/storage_logical.conf modified: cases/storage_netfs.conf new file: repos/storage/list_volumes.py --- cases/storage_dir.conf | 16 + cases/storage_dir_vol_resize_delta.conf |8 +++ cases/storage_logical.conf | 16 + cases/storage_netfs.conf| 16 + repos/storage/list_volumes.py | 97 +++ 5 files changed, 153 insertions(+), 0 deletions(-) create mode 100644 repos/storage/list_volumes.py The testcase works for the pool of dir type only. If you want to test pool of all type in one testcase, the testcase is not good enough obviously. The pool will be mappeed to the local filesystem , so I can check the volumes list in the pool path as a dir type, right? Info from libvirt.org/formatstorage.html#StoragePoolTarget Target elements in storage xml is used to describe the mapping of the storage pool into the host filesystem. path is one of the child elements. path Provides the location at which the pool will be mapped into the local filesystem namespace. For a filesystem/directory based pool it will be the name of the directory in which volumes will be created. For device based pools it will be the name of the directory in which devices nodes exist. For the latter /dev/ may seem like the logical choice, however, devices nodes there are not guaranteed stable across reboots, since they are allocated on demand. It is preferable to use a stable location such as one of the /dev/disk/by-{path,id,uuid,label locations. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 5/6] qemu: parse qemu command line for USB keyboard
From: Li Zhang zhlci...@linux.vnet.ibm.com This patch is to format qemu command line and xen driver for USB keyboard and add test cases for it. Signed-off-by: Li Zhang zhlci...@linux.vnet.ibm.com --- src/qemu/qemu_command.c| 41 -- src/xenxs/xen_sxpr.c | 27 +- src/xenxs/xen_xm.c | 30 +++- .../qemuxml2argv-pseries-usb-kbd.args | 9 + .../qemuxml2argv-pseries-usb-kbd.xml | 19 ++ tests/qemuxml2argvtest.c | 3 ++ 6 files changed, 103 insertions(+), 26 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pseries-usb-kbd.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pseries-usb-kbd.xml diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 9539be7..e2f449f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5307,9 +5307,19 @@ qemuBuildUSBInputDevStr(virDomainDefPtr def, { virBuffer buf = VIR_BUFFER_INITIALIZER; -virBufferAsprintf(buf, %s,id=%s, - dev-type == VIR_DOMAIN_INPUT_TYPE_MOUSE ? - usb-mouse : usb-tablet, dev-info.alias); +switch (dev-type) { +case VIR_DOMAIN_INPUT_TYPE_MOUSE: +virBufferAsprintf(buf, usb-mouse,id=%s, dev-info.alias); +break; +case VIR_DOMAIN_INPUT_TYPE_TABLET: +virBufferAsprintf(buf, usb-tablet,id=%s, dev-info.alias); +break; +case VIR_DOMAIN_INPUT_TYPE_KBD: +if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_KBD)) +goto error; +virBufferAsprintf(buf, usb-kbd,id=%s, dev-info.alias); +break; +} if (qemuBuildDeviceAddressStr(buf, def, dev-info, qemuCaps) 0) goto error; @@ -8996,9 +9006,17 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, optstr); VIR_FREE(optstr); } else { -virCommandAddArgList(cmd, -usbdevice, - input-type == VIR_DOMAIN_INPUT_TYPE_MOUSE - ? mouse : tablet, NULL); +switch (input-type) { +case VIR_DOMAIN_INPUT_TYPE_MOUSE: +virCommandAddArgList(cmd, -usbdevice, mouse, NULL); +break; +case VIR_DOMAIN_INPUT_TYPE_TABLET: +virCommandAddArgList(cmd, -usbdevice, tablet, NULL); +break; +case VIR_DOMAIN_INPUT_TYPE_KBD: +virCommandAddArgList(cmd, -usbdevice, kbd, NULL); +break; +} } } } @@ -11668,20 +11686,23 @@ qemuParseCommandLine(virCapsPtr qemuCaps, } else if (STREQ(arg, -usbdevice)) { WANT_VALUE(); if (STREQ(val, tablet) || -STREQ(val, mouse)) { +STREQ(val, mouse) || +STREQ(val, kbd)) { virDomainInputDefPtr input; if (VIR_ALLOC(input) 0) goto error; input-bus = VIR_DOMAIN_INPUT_BUS_USB; if (STREQ(val, tablet)) input-type = VIR_DOMAIN_INPUT_TYPE_TABLET; -else +else if (STREQ(val, mouse)) input-type = VIR_DOMAIN_INPUT_TYPE_MOUSE; -if (VIR_REALLOC_N(def-inputs, def-ninputs+1) 0) { +else +input-type = VIR_DOMAIN_INPUT_TYPE_KBD; + +if (VIR_APPEND_ELEMENT(def-inputs, def-ninputs, input) 0) { virDomainInputDefFree(input); goto error; } -def-inputs[def-ninputs++] = input; } else if (STRPREFIX(val, disk:)) { if (VIR_ALLOC(disk) 0) goto error; diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c index d514725..a02f999 100644 --- a/src/xenxs/xen_sxpr.c +++ b/src/xenxs/xen_sxpr.c @@ -724,21 +724,23 @@ xenParseSxprUSB(virDomainDefPtr def, tmp = sexpr_node(node, usbdevice); if (tmp *tmp) { if (STREQ(tmp, tablet) || -STREQ(tmp, mouse)) { +STREQ(tmp, mouse) || +STREQ(tmp, kbd)) { virDomainInputDefPtr input; if (VIR_ALLOC(input) 0) goto error; input-bus = VIR_DOMAIN_INPUT_BUS_USB; if (STREQ(tmp, tablet)) input-type = VIR_DOMAIN_INPUT_TYPE_TABLET; -else +else if (STREQ(tmp, mouse)) input-type = VIR_DOMAIN_INPUT_TYPE_MOUSE; +else +input-type = VIR_DOMAIN_INPUT_TYPE_KBD; -
[libvirt] [PATCH v4 1/6] conf: Add a keyboard input device type
From: Li Zhang zhlci...@linux.vnet.ibm.com There is no keyboard for non-x86 platforms when graphics are enabled. It's preferred to add one USB keyboard. This patch is to add keyboard input device type. Signed-off-by: Li Zhang zhlci...@linux.vnet.ibm.com --- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c| 3 ++- src/conf/domain_conf.h| 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 38c6801..964350d 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3167,6 +3167,7 @@ choice valuetablet/value valuemouse/value + valuekbd/value /choice /attribute optional diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e0ab4b1..3dee9a8 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -504,7 +504,8 @@ VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST, VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST, mouse, - tablet) + tablet, + kbd) VIR_ENUM_IMPL(virDomainInputBus, VIR_DOMAIN_INPUT_BUS_LAST, ps2, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 4934911..8aa5f50 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1223,6 +1223,7 @@ struct _virDomainTPMDef { enum virDomainInputType { VIR_DOMAIN_INPUT_TYPE_MOUSE, VIR_DOMAIN_INPUT_TYPE_TABLET, +VIR_DOMAIN_INPUT_TYPE_KBD, VIR_DOMAIN_INPUT_TYPE_LAST }; -- 1.8.2.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 4/6] qemu_cap: Add USB keyboard capability
From: Li Zhang zhlci...@linux.vnet.ibm.com QEMU can support USB keyboard but libvirt haven't supportted it yet. This patch is to add USB keyboard capabilities and test cases. Signed-off-by: Li Zhang zhlci...@linux.vnet.ibm.com --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_1.2.2-1.caps | 1 + tests/qemucapabilitiesdata/caps_1.3.1-1.caps | 1 + tests/qemucapabilitiesdata/caps_1.4.2-1.caps | 1 + tests/qemucapabilitiesdata/caps_1.5.3-1.caps | 1 + tests/qemucapabilitiesdata/caps_1.6.0-1.caps | 2 ++ tests/qemucapabilitiesdata/caps_1.6.50-1.caps | 1 + tests/qemuhelptest.c | 8 9 files changed, 18 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index a68e555..580d598 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -245,6 +245,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, kvm-pit-lost-tick-policy, boot-strict, /* 160 */ + usb-kbd, ); struct _virQEMUCaps { @@ -1396,6 +1397,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { usb-storage, QEMU_CAPS_DEVICE_USB_STORAGE }, { virtio-mmio, QEMU_CAPS_DEVICE_VIRTIO_MMIO }, { ich9-intel-hda, QEMU_CAPS_DEVICE_ICH9_INTEL_HDA }, +{ usb-kbd, QEMU_CAPS_DEVICE_USB_KBD }, }; static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index aea64ea..05837b2 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -199,6 +199,7 @@ enum virQEMUCapsFlags { QEMU_CAPS_DEVICE_ICH9_INTEL_HDA = 158, /* -device ich9-intel-hda */ QEMU_CAPS_KVM_PIT_TICK_POLICY = 159, /* kvm-pit.lost_tick_policy */ QEMU_CAPS_BOOT_STRICT= 160, /* -boot strict */ +QEMU_CAPS_DEVICE_USB_KBD = 161, /*-device usb-kbd*/ QEMU_CAPS_LAST, /* this must always be the last item */ }; diff --git a/tests/qemucapabilitiesdata/caps_1.2.2-1.caps b/tests/qemucapabilitiesdata/caps_1.2.2-1.caps index 73a561d..b620341 100644 --- a/tests/qemucapabilitiesdata/caps_1.2.2-1.caps +++ b/tests/qemucapabilitiesdata/caps_1.2.2-1.caps @@ -112,4 +112,5 @@ flag name='usb-storage'/ flag name='usb-storage.removable'/ flag name='kvm-pit-lost-tick-policy'/ +flag name='usb-kbd'/ /qemuCaps diff --git a/tests/qemucapabilitiesdata/caps_1.3.1-1.caps b/tests/qemucapabilitiesdata/caps_1.3.1-1.caps index da15d8b..6b4a8f0 100644 --- a/tests/qemucapabilitiesdata/caps_1.3.1-1.caps +++ b/tests/qemucapabilitiesdata/caps_1.3.1-1.caps @@ -126,4 +126,5 @@ flag name='usb-storage'/ flag name='usb-storage.removable'/ flag name='kvm-pit-lost-tick-policy'/ +flag name='usb-kbd'/ /qemuCaps diff --git a/tests/qemucapabilitiesdata/caps_1.4.2-1.caps b/tests/qemucapabilitiesdata/caps_1.4.2-1.caps index c419068..e3d0047 100644 --- a/tests/qemucapabilitiesdata/caps_1.4.2-1.caps +++ b/tests/qemucapabilitiesdata/caps_1.4.2-1.caps @@ -127,4 +127,5 @@ flag name='usb-storage.removable'/ flag name='ich9-intel-hda'/ flag name='kvm-pit-lost-tick-policy'/ +flag name='usb-kbd'/ /qemuCaps diff --git a/tests/qemucapabilitiesdata/caps_1.5.3-1.caps b/tests/qemucapabilitiesdata/caps_1.5.3-1.caps index 2b00449..b29ea60 100644 --- a/tests/qemucapabilitiesdata/caps_1.5.3-1.caps +++ b/tests/qemucapabilitiesdata/caps_1.5.3-1.caps @@ -132,4 +132,5 @@ flag name='ich9-intel-hda'/ flag name='kvm-pit-lost-tick-policy'/ flag name='boot-strict'/ +flag name='usb-kbd'/ /qemuCaps diff --git a/tests/qemucapabilitiesdata/caps_1.6.0-1.caps b/tests/qemucapabilitiesdata/caps_1.6.0-1.caps index 7bce4aa..2fa7d20 100644 --- a/tests/qemucapabilitiesdata/caps_1.6.0-1.caps +++ b/tests/qemucapabilitiesdata/caps_1.6.0-1.caps @@ -136,4 +136,6 @@ flag name='ich9-intel-hda'/ flag name='kvm-pit-lost-tick-policy'/ flag name='boot-strict'/ +flag name='usb-kbd'/ + /qemuCaps diff --git a/tests/qemucapabilitiesdata/caps_1.6.50-1.caps b/tests/qemucapabilitiesdata/caps_1.6.50-1.caps index bfaab9d..0151cde 100644 --- a/tests/qemucapabilitiesdata/caps_1.6.50-1.caps +++ b/tests/qemucapabilitiesdata/caps_1.6.50-1.caps @@ -135,4 +135,5 @@ flag name='ich9-intel-hda'/ flag name='kvm-pit-lost-tick-policy'/ flag name='boot-strict'/ +flag name='usb-kbd'/ /qemuCaps diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c index 3628fbe..6e0a5f8 100644 --- a/tests/qemuhelptest.c +++ b/tests/qemuhelptest.c @@ -403,6 +403,7 @@ mymain(void) QEMU_CAPS_DEVICE_VMWARE_SVGA, QEMU_CAPS_DEVICE_USB_SERIAL, QEMU_CAPS_DEVICE_USB_NET, +QEMU_CAPS_DEVICE_USB_KBD, QEMU_CAPS_DEVICE_PCI_BRIDGE); DO_TEST(qemu-kvm-0.12.3, 12003, 1, 0, QEMU_CAPS_VNC_COLON, @@ -515,6 +516,7 @@
[libvirt] [PATCH v4 2/6] conf: Add one interface to add default input devices.
From: Li Zhang zhlci...@linux.vnet.ibm.com This patch is to add one new interface to add input devices. Signed-off-by: Li Zhang zhlci...@linux.vnet.ibm.com --- src/conf/domain_conf.c | 29 + src/conf/domain_conf.h | 4 src/libvirt_private.syms | 1 + 3 files changed, 34 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 3dee9a8..d107e6f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -10822,6 +10822,35 @@ virDomainDefMaybeAddController(virDomainDefPtr def, return 0; } +int +virDomainDefMaybeAddInput(virDomainDefPtr def, + int type, + int bus) +{ +size_t i; +virDomainInputDefPtr input; + +for (i = 0; i def-ninputs; i++) { +if (def-inputs[i]-type == type +def-inputs[i]-bus == bus) +return 0; +} + +if (VIR_ALLOC(input) 0) +return -1; + +input-type = type; +input-bus = bus; + +if (VIR_APPEND_ELEMENT(def-inputs, def-ninputs, input) 0) { +VIR_FREE(input); +return -1; +} + +return 0; +} + + /* Parse a memory element located at XPATH within CTXT, and store the * result into MEM. If REQUIRED, then the value must exist; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 8aa5f50..8616066 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2764,6 +2764,10 @@ virDomainDefMaybeAddController(virDomainDefPtr def, int type, int idx, int model); +int +virDomainDefMaybeAddInput(virDomainDefPtr def, + int type, + int bus); char *virDomainDefGetDefaultEmulator(virDomainDefPtr def, virCapsPtr caps); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 0e749b1..aa497b5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -165,6 +165,7 @@ virDomainDefGenSecurityLabelDef; virDomainDefGetDefaultEmulator; virDomainDefGetSecurityLabelDef; virDomainDefMaybeAddController; +virDomainDefMaybeAddInput; virDomainDefNew; virDomainDefParseFile; virDomainDefParseNode; -- 1.8.2.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 0/6] Support keyboard device
From: Li Zhang zhlci...@linux.vnet.ibm.com This patchset is to add keyboard input device. For PPC64, it doesn't support a default keyboard device when the graphic is enabled. Libvirt supports QEMU command line as -device VGA which won't create any keyboard device for it. So it requires libvirt to add a default USB keyboard device for it. This patchset is to add keyboard input device and a default USB keyboard for PPC64. The related discussion in QEMU community: http://lists.nongnu.org/archive/html/qemu-devel/2013-11/msg01734.html Li Zhang (6): conf: Add a keyboard input device type conf: Add one interface to add default input devices. conf: Remove PS2 mouse device for non-X86 platforms qemu_cap: Add USB keyboard capability qemu: parse qemu command line for USB keyboard Add a default USB keyboard and USB mouse for PPC64 v4 - v3: * Don't remove PS2 mouse device for other virtualization drivers (Jan Tomko). v3 - v2: * Handle the KBD device type in xen and QEMU driver. (Daniel.P.Berrange) * Remove PS2 mouse device for non-X86 platforms. * Move virDomainDefMaybeAddInput to a new patch. (Jan Tomko) * Replace VIR_REALLOC_N with VIR_APPEND_ELEMENT. (Jan Tomoko) * Fix several typos. (Jan Tomoko) * Add a virReportError when QEMU_CAPS_DEVICE_USB_KBD can't be gotten. (Jan Tomoko) v2 - v1: * change ifs to switch clause. * reconstruct the patches docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 92 ++ src/conf/domain_conf.h | 5 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_capabilities.c | 2 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c| 41 +++--- src/qemu/qemu_domain.c | 23 +- src/util/virarch.h | 2 + src/xenxs/xen_sxpr.c | 27 +-- src/xenxs/xen_xm.c | 30 +-- tests/qemucapabilitiesdata/caps_1.2.2-1.caps | 1 + tests/qemucapabilitiesdata/caps_1.3.1-1.caps | 1 + tests/qemucapabilitiesdata/caps_1.4.2-1.caps | 1 + tests/qemucapabilitiesdata/caps_1.5.3-1.caps | 1 + tests/qemucapabilitiesdata/caps_1.6.0-1.caps | 2 + tests/qemucapabilitiesdata/caps_1.6.50-1.caps | 1 + tests/qemuhelptest.c | 8 ++ .../qemuxml2argvdata/qemuxml2argv-pseries-disk.xml | 3 +- .../qemuxml2argv-pseries-usb-kbd.args | 9 +++ .../qemuxml2argv-pseries-usb-kbd.xml | 19 + tests/qemuxml2argvtest.c | 3 + 22 files changed, 212 insertions(+), 62 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pseries-usb-kbd.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pseries-usb-kbd.xml -- 1.8.2.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 6/6] Add a default USB keyboard and USB mouse for PPC64
From: Li Zhang zhlci...@linux.vnet.ibm.com There is no keyboard working on PPC64 and PS2 mouse is only for PPC64 when graphics are enabled. It needs to add a USB keyboard and USB mouse for it. This patch is to add a USB keyboard and USB mouse when graphics are enabled. Signed-off-by: Li Zhang zhlci...@linux.vnet.ibm.com --- src/qemu/qemu_domain.c | 23 +- .../qemuxml2argvdata/qemuxml2argv-pseries-disk.xml | 2 ++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e964c75..82d6948 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -691,6 +691,8 @@ qemuDomainDefPostParse(virDomainDefPtr def, bool addPCIRoot = false; bool addPCIeRoot = false; bool addDefaultMemballoon = true; +bool addDefaultUSBKBD = false; +bool addDefaultUSBMouse = false; /* check for emulator and create a default one if needed */ if (!def-emulator @@ -728,9 +730,14 @@ qemuDomainDefPostParse(virDomainDefPtr def, addDefaultMemballoon = false; break; +case VIR_ARCH_PPC64: +addPCIRoot = true; +addDefaultUSBKBD = true; +addDefaultUSBMouse = true; +break; + case VIR_ARCH_ALPHA: case VIR_ARCH_PPC: -case VIR_ARCH_PPC64: case VIR_ARCH_PPCEMB: case VIR_ARCH_SH4: case VIR_ARCH_SH4EB: @@ -783,6 +790,20 @@ qemuDomainDefPostParse(virDomainDefPtr def, def-memballoon = memballoon; } +if (addDefaultUSBKBD +def-ngraphics 0 +virDomainDefMaybeAddInput(def, + VIR_DOMAIN_INPUT_TYPE_KBD, + VIR_DOMAIN_INPUT_BUS_USB) 0) +return -1; + +if (addDefaultUSBMouse +def-ngraphics 0 +virDomainDefMaybeAddInput(def, + VIR_DOMAIN_INPUT_TYPE_MOUSE, + VIR_DOMAIN_INPUT_BUS_USB) 0) +return -1; + return 0; } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pseries-disk.xml b/tests/qemuxml2argvdata/qemuxml2argv-pseries-disk.xml index 8dde776..ac1767b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-pseries-disk.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-pseries-disk.xml @@ -30,6 +30,8 @@ controller type='usb' index='0'/ controller type='scsi' index='0'/ controller type='pci' index='0' model='pci-root'/ +input type='kbd' bus='usb'/ +input type='mouse' bus='usb'/ graphics type='sdl'/ video model type='cirrus' vram='9216' heads='1'/ -- 1.8.2.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 3/6] conf: Remove PS2 mouse device for non-X86 platforms
From: Li Zhang zhlci...@linux.vnet.ibm.com PS2 device only works for X86 platform, other platforms may need USB mouse. Athough it doesn't influence the QEMU command line, but It's not right to add one PS2 mouse for non-X86 platform. This patch is to remove PS2 device definition from other platforms. Add one default USB mouse for PPC64. It can be also added for other platforms if necessary. Signed-off-by: Li Zhang zhlci...@linux.vnet.ibm.com --- src/conf/domain_conf.c | 60 ++ src/util/virarch.h | 2 + .../qemuxml2argvdata/qemuxml2argv-pseries-disk.xml | 1 - 3 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d107e6f..cd38cbd 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -7567,7 +7567,7 @@ error: /* Parse the XML definition for an input device */ static virDomainInputDefPtr -virDomainInputDefParseXML(const char *ostype, +virDomainInputDefParseXML(const virDomainDef *dom, xmlNodePtr node, unsigned int flags) { @@ -7600,7 +7600,7 @@ virDomainInputDefParseXML(const char *ostype, goto error; } -if (STREQ(ostype, hvm)) { +if (STREQ(dom-os.type, hvm)) { if (def-bus == VIR_DOMAIN_INPUT_BUS_PS2 /* Only allow mouse for ps2 */ def-type != VIR_DOMAIN_INPUT_TYPE_MOUSE) { virReportError(VIR_ERR_INTERNAL_ERROR, @@ -7628,8 +7628,9 @@ virDomainInputDefParseXML(const char *ostype, } } } else { -if (STREQ(ostype, hvm)) { -if (def-type == VIR_DOMAIN_INPUT_TYPE_MOUSE) +if (STREQ(dom-os.type, hvm)) { +if (def-type == VIR_DOMAIN_INPUT_TYPE_MOUSE +ARCH_IS_X86(dom-os.arch)) def-bus = VIR_DOMAIN_INPUT_BUS_PS2; else def-bus = VIR_DOMAIN_INPUT_BUS_USB; @@ -9631,7 +9632,7 @@ virDomainDeviceDefParse(const char *xmlStr, goto error; break; case VIR_DOMAIN_DEVICE_INPUT: -if (!(dev-data.input = virDomainInputDefParseXML(def-os.type, +if (!(dev-data.input = virDomainInputDefParseXML(def, node, flags))) goto error; break; @@ -12211,7 +12212,7 @@ virDomainDefParseXML(xmlDocPtr xml, goto error; for (i = 0; i n; i++) { -virDomainInputDefPtr input = virDomainInputDefParseXML(def-os.type, +virDomainInputDefPtr input = virDomainInputDefParseXML(def, nodes[i], flags); if (!input) @@ -12230,9 +12231,11 @@ virDomainDefParseXML(xmlDocPtr xml, * with graphics, so don't store it. * XXX will this be true for other virt types ? */ if ((STREQ(def-os.type, hvm) + ARCH_IS_X86(def-os.arch) input-bus == VIR_DOMAIN_INPUT_BUS_PS2 input-type == VIR_DOMAIN_INPUT_TYPE_MOUSE) || (STRNEQ(def-os.type, hvm) + ARCH_IS_X86(def-os.arch) input-bus == VIR_DOMAIN_INPUT_BUS_XEN input-type == VIR_DOMAIN_INPUT_TYPE_MOUSE)) { virDomainInputDefFree(input); @@ -12261,29 +12264,19 @@ virDomainDefParseXML(xmlDocPtr xml, VIR_FREE(nodes); /* If graphics are enabled, there's an implicit PS2 mouse */ -if (def-ngraphics 0) { -virDomainInputDefPtr input; +if (def-ngraphics 0 +ARCH_IS_X86(def-os.arch)) { +int input_bus = VIR_DOMAIN_INPUT_BUS_XEN; -if (VIR_ALLOC(input) 0) { -goto error; -} -if (STREQ(def-os.type, hvm)) { -input-type = VIR_DOMAIN_INPUT_TYPE_MOUSE; -input-bus = VIR_DOMAIN_INPUT_BUS_PS2; -} else { -input-type = VIR_DOMAIN_INPUT_TYPE_MOUSE; -input-bus = VIR_DOMAIN_INPUT_BUS_XEN; -} +if (STREQ(def-os.type, hvm)) +input_bus = VIR_DOMAIN_INPUT_BUS_PS2; -if (VIR_REALLOC_N(def-inputs, def-ninputs + 1) 0) { -virDomainInputDefFree(input); +if (virDomainDefMaybeAddInput(def, + VIR_DOMAIN_INPUT_TYPE_MOUSE, + input_bus) 0) goto error; -} -def-inputs[def-ninputs] = input; -def-ninputs++; } - /* analysis of the sound devices */ if ((n = virXPathNodeSet(./devices/sound, ctxt, nodes)) 0) { goto error; @@ -17205,15 +17198,16 @@ virDomainDefFormatInternal(virDomainDefPtr def, if (def-ngraphics 0) { /* If graphics is enabled, add the implicit mouse */ -virDomainInputDef autoInput = { -VIR_DOMAIN_INPUT_TYPE_MOUSE, -STREQ(def-os.type, hvm) ?