[libvirt] OVMF exposure in libvirt
Dear list, there's been a lot of development in QEMU on this part. And I think it's settled down enough long so I can start looking at it. So I'd like to hear you opinion what's the best way to expose this in libvirt. OVMF can bee looked at as a UEFI enablement in guest. Standard UEFI consists of two parts: a) the firmware binary image (RO) b) UEFI variables flash (RW) IIUC both of these are to be passed to qemu on the command line as: -drive file=img_1,if=pflash,format=raw,readonly \ -drive file=img_2,if=pflash,format=raw Subsequently, -bios parameter should be dropped. The idea of splitting the UEFI into two files allows distros to update the UEFI firmware (FW for short) without modifying guest written UEFI variables file (the variables should have unified name so they should be transferable between two versions of UEFI FW). So my question is: how to expose this in the domain XML? We have the element which handles the booting arguments. It can have (which would be great for the FW, wouldn't it?). But then we need to invent a different element (say ) which would contain path the the UEFI vars file. Moreover, the element would exclude other elements like , or . So my proposal is: hvm /path/to/uefi.fw /path/to/uefi.nvvarstore Does this make any sense or am I just blabbing? Michal BTW OVMF stands for Open Virtual Machine Firmware. -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 3/3] virSecurityLabelDef: use enum type for @type
On 11.07.2014 18:59, Eric Blake wrote: > On 07/11/2014 03:32 AM, Michal Privoznik wrote: >> There's this trend in libvirt of using enum types wherever possible. >> Now that I'm at virSecurityLabelDef let's rework @type item of the >> structure so we don't have to typecast it elsewhere. >> >> Signed-off-by: Michal Privoznik >> --- >> src/conf/domain_conf.c | 6 -- >> src/security/security_dac.c | 2 +- >> src/util/virseclabel.h | 2 +- >> 3 files changed, 6 insertions(+), 4 deletions(-) > > I'm not quite as sure about this one. This solves the issue of how to > detect errors when parsing strings to enum, but required the use of an > intermediate variable which in turn made the patch a net gain in lines > of code. If someone forgets to use the intermediate variable for > parsing, this backfires. On the other hand, parsing string to enum > should be done in just one location, and that's the location touched by > this patch. I'm 50-50 on whether to take this, so I'd like someone else > to chime in with an opinion. I hear you. This patch is just a refactor. It does not add anything useful nor solve any issue. It's okay if dropped. But the more I think about our vir*TypeFromString() the more I feel we should do something about it. How about making it follow our typical function return pattern: int func() { virMyFavourite x; const char *string; if (virMyFavouriteTypeFromString(string, &x) < 0) { virReportError("unknown value: %s", string); goto error; } That is, we need this diff: diff --git a/src/util/virutil.c b/src/util/virutil.c index 95d1ff9..40075e9 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -407,15 +407,20 @@ virParseVersionString(const char *str, unsigned long *version, int virEnumFromString(const char *const*types, unsigned int ntypes, - const char *type) + const char *type, + int *val) { size_t i; if (!type) return -1; -for (i = 0; i < ntypes; i++) -if (STREQ(types[i], type)) -return i; +for (i = 0; i < ntypes; i++) { +if (STREQ(types[i], type)) { +if (val) +*val = i; +return 0; +} +} return -1; } diff --git a/src/util/virutil.h b/src/util/virutil.h index 2bb74e2..670b2e1 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -73,7 +73,8 @@ char *virIndexToDiskName(int idx, const char *prefix); int virEnumFromString(const char *const*types, unsigned int ntypes, - const char *type); + const char *type, + int *val); const char *virEnumToString(const char *const*types, unsigned int ntypes, @@ -87,10 +88,10 @@ const char *virEnumToString(const char *const*types, ARRAY_CARDINALITY(name ## TypeList), \ type); \ } \ -int name ## TypeFromString(const char *type) { \ +int name ## TypeFromString(const char *type, name *val) { \ return virEnumFromString(name ## TypeList, \ ARRAY_CARDINALITY(name ## TypeList), \ - type); \ + type, (int *) val);\ } # define VIR_ENUM_DECL(name) \ And then a tons of follow up patches. Or even make virEnumString() report the error (that could save a lot of virReportError() calls). Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv2]util:openvswitch:Delete port if it is exist when add port
On 12.07.2014 06:47, Lichunhe wrote: If the ovs service stop abnormal, or host cold reboot, vm is destroyed after ovs service stop. The ovs port which connect to interface of vm will not be clear. When the ovs service restart, recover configuration from db, but the interface is no exist, port recovery failed, and then vm restart on the same host, libvirt add port again, but the port configuration is same as before, ovs will not connect the interface, only store the configuration in db. Below will trigger this problem, We like the commit messages wrapped at 80 characters per line. Moreover, I find it somehow hard to parse. virsh start vm service openvswitch-switch stop virsh destroy vm service openvswitch-switch start virsh start vm Signed-off-by: Chunhe Li --- src/util/virnetdevopenvswitch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) I had some difficulties applying this patch. Did you hand edit it before sending? diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c index 9bcbfb1..2c414ad 100644 --- a/src/util/virnetdevopenvswitch.c +++ b/src/util/virnetdevopenvswitch.c @@ -84,8 +84,8 @@ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, cmd = virCommandNew(OVSVSCTL); -virCommandAddArgList(cmd, "--timeout=5", "--", "--may-exist", "add-port", -brname, ifname, NULL); +virCommandAddArgList(cmd, "--timeout=5", "--", "--if-exists", "del-port", Trailing whitespace. +ifname, "--", "add-port", brname, ifname, NULL); if (virtVlan && virtVlan->nTags > 0) { -- 1.9.2.msysgit.0 Strange git version string :) -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list Well, I've pointed out enough problems to request v3, but since this practically oneliner, I rather fix all the nits and push. ACKed and pushed. Congratulations on your first libvirt contribution! Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 0/2] Implement interface stats for BSD
On 06.07.2014 18:28, Roman Bogorodskiy wrote: This series implements support for querying network interface stats on (Free)BSD. It's more of an RFC, because I'm uncertain about few things: - It feels a little strange to have a source file that implements only a single function like this. I am wondering if it would be better to just move it to something like util/virnetdev.c? - FreeBSD stores interface data in the if_data struct and a number of outgoing packet drops is stored in a field 'ifi_oqdrops'. This field was added in -CURRENT and later merged back to 10-STABLE. In order not to break the ABI, it's available only if _IFI_OQDROPS is defined. I've added a configure.ac check which adds -D_IFI_OQDROPS before checking this field and resetting it back if it is not present. This way, this flag will present when the field is available even if the flag is not needed (e.g. on -CURRENT). Is there a better way of doing it? I was thinking about trying to check this field without the flag and if it fails check one more time with the flag, but it looks a little messy. - Did I get it right that the stats reported are from the guest POV, e.g. when downloading a large file from guest, it should look like: vnet0 rx_bytes 731603341 vnet0 rx_packets 518354 vnet0 rx_errs 0 vnet0 rx_drop 0 vnet0 tx_bytes 17577834 vnet0 tx_packets 264226 vnet0 tx_errs 0 vnet0 tx_drop 0 Roman Bogorodskiy (2): util: virstatslinux: make more generic Implement interface stats for BSD configure.ac | 13 - po/POTFILES.in | 2 +- src/Makefile.am | 2 +- src/libvirt_linux.syms | 3 -- src/libvirt_private.syms | 2 + src/lxc/lxc_driver.c | 2 +- src/openvz/openvz_driver.c | 2 +- src/qemu/qemu_driver.c | 16 +- src/uml/uml_driver.c | 2 +- src/util/{virstatslinux.c => virstats.c} | 93 +--- src/util/{virstatslinux.h => virstats.h} | 12 ++--- src/xen/xen_hypervisor.c | 2 +- tests/statstest.c| 2 +- 13 files changed, 102 insertions(+), 51 deletions(-) rename src/util/{virstatslinux.c => virstats.c} (61%) rename src/util/{virstatslinux.h => virstats.h} (77%) ACK to both patches. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 07/16] numatune: Encapsulate numatune configuration in order to unify results
On 15.07.2014 08:33, Martin Kletzander wrote: On Fri, Jul 11, 2014 at 05:11:00PM +0200, Michal Privoznik wrote: On 08.07.2014 13:50, Martin Kletzander wrote: There were numerous places where numatune configuration (and thus domain config as well) was changed in different ways. On some places this even resulted in persistent domain definition not to be stable (it would change with daemon's restart). In order to uniformly change how numatune config is dealt with, all the internals are now accessible directly only in numatune_conf.c and outside this file accessors must be used. Signed-off-by: Martin Kletzander --- po/POTFILES.in | 1 + src/conf/domain_conf.c | 159 ++- src/conf/domain_conf.h | 8 +- src/conf/numatune_conf.c | 316 + src/conf/numatune_conf.h | 72 - src/libvirt_private.syms | 11 + src/lxc/lxc_cgroup.c | 19 +- src/lxc/lxc_controller.c | 5 +- src/lxc/lxc_native.c | 15 +- src/parallels/parallels_driver.c | 7 +- src/qemu/qemu_cgroup.c | 23 +- src/qemu/qemu_driver.c | 84 +++--- src/qemu/qemu_process.c| 8 +- src/util/virnuma.c | 48 ++-- src/util/virnuma.h | 2 +- .../qemuxml2argv-numatune-auto-prefer.xml | 29 ++ .../qemuxml2xmlout-numatune-auto-prefer.xml| 29 ++ tests/qemuxml2xmltest.c| 2 + 18 files changed, 553 insertions(+), 285 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-numatune-auto-prefer.xml Nice. Thanks :) [...] +tmp = virXMLPropString(node, "nodeset"); +if (tmp && virBitmapParse(tmp, 0, &nodeset, VIR_DOMAIN_CPUMASK_LEN) < 0) +goto cleanup; +VIR_FREE(tmp); + +if (virDomainNumatuneSet(def, placement, mode, nodeset) < 0) The virDomainNumatuneSet() takes a copy of @nodeset, so you need to call virBitmaskFree(nodeset); at the cleanup label. Yep, that happens when you change the behaviour of a function that used to steal a pointer, in a rebase. Thanks! +goto cleanup; + +if (!n) { +ret = 0; +goto cleanup; +} + +ret = 0; + cleanup: +VIR_FREE(tmp); +return ret; +} + +int +virDomainNumatuneFormatXML(virBufferPtr buf, + virDomainNumatunePtr numatune) +{ +const char *tmp = NULL; s /const// .. + +if (!numatune) +return 0; + +virBufferAddLit(buf, "\n"); +virBufferAdjustIndent(buf, 2); + +tmp = virDomainNumatuneMemModeTypeToString(numatune->memory.mode); +virBufferAsprintf(buf, "memory.placement == VIR_DOMAIN_NUMATUNE_PLACEMENT_STATIC) { +if (!(tmp = virBitmapFormat(numatune->memory.nodeset))) +return -1; +virBufferAsprintf(buf, "nodeset='%s'/>\n", tmp); +VIR_FREE(tmp); .. because free()-ing a const char * is not nice. If you, however, do this I bet you'll get error in TypeToString(). So just leave tmp as const char * and introduce char *nodeset; I take the 'const' as a sign of the fact that I won't be modifying any part of the string. Just adding 'const' to a pointer should be perfectly OK, but I have not objections to your idea, so I squashed this in: Well, I look at free()-ing as modification of the pointee. Therefore freeing a const pointer is in fact its modification and hence should be rejected. It's just that our VIR_FREE throws away the const-ness of passed pointers. Maybe (as completely separate patchset) we may fix the VIR_FREE() macro which is obviously const-incorrect. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 04/16] conf, schema: add 'id' field for cells
On 15.07.2014 08:23, Martin Kletzander wrote: On Fri, Jul 11, 2014 at 05:11:05PM +0200, Michal Privoznik wrote: On 08.07.2014 13:50, Martin Kletzander wrote: In XML format, by definition, order of fields should not matter, so order of parsing the elements doesn't affect the end result. When specifying guest NUMA cells, we depend only on the order of the 'cell' elements. With this patch all older domain XMLs are parsed as before, but with the 'id' attribute they are parsed and formatted according to that field. This will be useful when we have tuning settings for particular guest NUMA node. Signed-off-by: Martin Kletzander --- docs/formatdomain.html.in | 11 +++--- docs/schemas/domaincommon.rng | 5 +++ src/conf/cpu_conf.c| 39 +++--- src/conf/cpu_conf.h| 3 +- src/qemu/qemu_command.c| 2 +- tests/qemuxml2argvdata/qemuxml2argv-cpu-numa1.xml | 6 ++-- tests/qemuxml2argvdata/qemuxml2argv-cpu-numa2.xml | 6 ++-- tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml | 25 ++ tests/qemuxml2argvtest.c | 1 + .../qemuxml2xmlout-cpu-numa1.xml | 28 .../qemuxml2xmlout-cpu-numa2.xml | 28 tests/qemuxml2xmltest.c| 3 ++ 12 files changed, 139 insertions(+), 18 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa1.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-cpu-numa2.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index b69da4c..ad87b7c 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in [...] @@ -1041,8 +1041,11 @@ Each cell element specifies a NUMA cell or a NUMA node. cpus specifies the CPU or range of CPUs that are part of the node. memory specifies the node memory in kibibytes - (i.e. blocks of 1024 bytes). Each cell or node is assigned cellid - or nodeid in the increasing order starting from 0. + (i.e. blocks of 1024 bytes). All cells should have id + attribute in case referring to some cell is necessary in the code, + otherwise the cells are assigned ids in the increasing order starting + from 0. Mixing cells with and without the id attribute + is not recommended as it may result in unwanted behaviour. I'd note here, that the @id attribute is since 1.2.7 I wasn't sure this is needed for attributes, but it cannot hurt, right? The new hunk would now look like this: @@ -1039,10 +1039,15 @@ Each cell element specifies a NUMA cell or a NUMA node. - cpus specifies the CPU or range of CPUs that are part of - the node. memory specifies the node memory in kibibytes - (i.e. blocks of 1024 bytes). Each cell or node is assigned cellid - or nodeid in the increasing order starting from 0. + cpus specifies the CPU or range of CPUs that are + part of the node. memory specifies the node memory + in kibibytes (i.e. blocks of 1024 bytes). + Since 1.2.7 all cells should + have id attribute in case referring to some cell is + necessary in the code, otherwise the cells are + assigned ids in the increasing order starting from + 0. Mixing cells with and without the id attribute + is not recommended as it may result in unwanted behaviour. -- Is that OK? Okay. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/4] Resolve const correctness isues
Okay, okay. The approach in 4/4 can be considered hackish, but hey - it works! Michal Privoznik (4): Fix const correctness viralloc: Honor const correctness in VIR_FREE VIR_FREE: Avoid doing side work in callees virFree: Check const correctness src/conf/network_conf.c | 12 src/locking/lock_driver_lockd.c | 2 +- src/qemu/qemu_capabilities.c | 2 +- src/remote/remote_driver.c | 2 +- src/util/viralloc.c | 6 -- src/util/viralloc.h | 33 - src/xenapi/xenapi_utils.c| 3 ++- tools/virsh-domain.c | 4 ++-- tools/wireshark/src/packet-libvirt.c | 6 +++--- tools/wireshark/src/packet-libvirt.h | 4 ++-- 10 files changed, 40 insertions(+), 34 deletions(-) -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/4] viralloc: Honor const correctness in VIR_FREE
Since we've corrected all the callers that passed a const pointer to VIR_FREE() we may drop the typecasting horribility and let the macro be a simple wrapper over the virFree() function. Signed-off-by: Michal Privoznik --- src/util/viralloc.h | 15 +-- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/util/viralloc.h b/src/util/viralloc.h index 7125e67..71b4a45 100644 --- a/src/util/viralloc.h +++ b/src/util/viralloc.h @@ -547,20 +547,7 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1); * * This macro is safe to use on arguments with side effects. */ -# if !STATIC_ANALYSIS -/* The ternary ensures that ptr is a pointer and not an integer type, - * while evaluating ptr only once. This gives us extra compiler - * safety when compiling under gcc. For now, we intentionally cast - * away const, since a number of callers safely pass const char *. - */ -# define VIR_FREE(ptr) virFree((void *) (1 ? (const void *) &(ptr) : (ptr))) -# else -/* The Coverity static analyzer considers the else path of the "?:" and - * flags the VIR_FREE() of the address of the address of memory as a - * RESOURCE_LEAK resulting in numerous false positives (eg, VIR_FREE(&ptr)) - */ -# define VIR_FREE(ptr) virFree((void *) &(ptr)) -# endif +# define VIR_FREE(ptr) virFree(&(ptr)) void virAllocTestInit(void); int virAllocTestCount(void); -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 4/4] virFree: Check const correctness
Up to now it's possible to do something like this: const char *ptr; ptr = strdup("my example string"); VIR_FREE(ptr); The problem is, const char * pointers should not be modified (and freeing them is kind of modification). We should avoid this. A little trick is used: assigning a const pointer into 'void *' triggers compiler warning about discarding 'const' qualifier from pointer. So the virFree() function gains new dummy argument, that is not touched anyhow, just fulfills the const correctness check duty. Signed-off-by: Michal Privoznik --- src/util/viralloc.c | 6 -- src/util/viralloc.h | 20 src/xenapi/xenapi_utils.c | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/util/viralloc.c b/src/util/viralloc.c index be9f0fe..0134e67 100644 --- a/src/util/viralloc.c +++ b/src/util/viralloc.c @@ -372,7 +372,7 @@ void virShrinkN(void *ptrptr, size_t size, size_t *countptr, size_t toremove) ignore_value(virReallocN(ptrptr, size, *countptr -= toremove, false, 0, NULL, NULL, 0)); else { -virFree(ptrptr); +virFree(NULL, ptrptr); *countptr = 0; } } @@ -569,13 +569,15 @@ int virAllocVar(void *ptrptr, /** * virFree: + * @ptr: dummy pointer to check const correctness * @ptrptr: pointer to pointer for address of memory to be freed * * Release the chunk of memory in the pointer pointed to by * the 'ptrptr' variable. After release, 'ptrptr' will be * updated to point to NULL. */ -void virFree(void *ptrptr) +void virFree(void *ptr ATTRIBUTE_UNUSED, + void *ptrptr) { int save_errno = errno; diff --git a/src/util/viralloc.h b/src/util/viralloc.h index 71b4a45..8fbe56f 100644 --- a/src/util/viralloc.h +++ b/src/util/viralloc.h @@ -76,7 +76,7 @@ int virAllocVar(void *ptrptr, size_t struct_size, size_t element_size, size_t co bool report, int domcode, const char *filename, const char *funcname, size_t linenr) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1); -void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1); +void virFree(void *ptr, void *ptrptr) ATTRIBUTE_NONNULL(2); /** * VIR_ALLOC: @@ -543,11 +543,23 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1); * @ptr: pointer holding address to be freed * * Free the memory stored in 'ptr' and update to point - * to NULL. + * to NULL. Moreover, this macro has a side effect in + * form of evaluating passed argument multiple times. + * But advantage is, it checks the cont correctness + * (that you are not freeing a const pointer). + */ +# define VIR_FREE(ptr) virFree(ptr, &(ptr)) + +/** + * VIR_FREE_BROKEN: + * @ptr: pointer holding address to be freed * - * This macro is safe to use on arguments with side effects. + * Twin macro of VIR_FREE. While it does evaluate + * argument only once, it does not check const + * correctness and therefore you want to use it if and + * only if necessary. */ -# define VIR_FREE(ptr) virFree(&(ptr)) +# define VIR_FREE_BROKEN(ptr) virFree(NULL, &(ptr)) void virAllocTestInit(void); int virAllocTestCount(void); diff --git a/src/xenapi/xenapi_utils.c b/src/xenapi/xenapi_utils.c index a80d136..db555d2 100644 --- a/src/xenapi/xenapi_utils.c +++ b/src/xenapi/xenapi_utils.c @@ -50,7 +50,7 @@ xenSessionFree(xen_session *session) VIR_FREE(session->error_description); } /* The session_id member is type of 'const char *'. Sigh. */ -VIR_FREE(session->session_id); +VIR_FREE_BROKEN(session->session_id); VIR_FREE(session); } -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/4] VIR_FREE: Avoid doing side work in callees
There are just two places where we rely on the fact that VIR_FREE() macro is without any side effects. In the future, this property of the macro is going to change, so we need the code to be adjusted to deal with argument passed to VIR_FREE() being evaluated multiple times. Signed-off-by: Michal Privoznik --- src/conf/network_conf.c | 12 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index ce4d4d8..d60a60e 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -180,8 +180,10 @@ virNetworkDNSTxtDefClear(virNetworkDNSTxtDefPtr def) static void virNetworkDNSHostDefClear(virNetworkDNSHostDefPtr def) { -while (def->nnames) -VIR_FREE(def->names[--def->nnames]); +size_t i; + +for (i = 0; i < def->nnames; i++) +VIR_FREE(def->names[i]); VIR_FREE(def->names); } @@ -197,9 +199,11 @@ virNetworkDNSSrvDefClear(virNetworkDNSSrvDefPtr def) static void virNetworkDNSDefClear(virNetworkDNSDefPtr def) { +size_t i; + if (def->forwarders) { -while (def->nfwds) -VIR_FREE(def->forwarders[--def->nfwds]); +for (i = 0; i < def->nfwds; i++) +VIR_FREE(def->forwarders[i]); VIR_FREE(def->forwarders); } if (def->txts) { -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/4] Fix const correctness
In many places we define a variable as a 'const char *' when in fact we modify it just a few lines below. Or even free it. We should not do that. There's one exception though, in xenSessionFree() xenapi_utils.c. We are freeing the xen_session structure which is defined in xen/api/xen_common.h public header. The structure contains session_id which is type of 'const char *' when in fact it should have been just 'char *'. So I'm leaving this unmodified, just noticing the fact in comment. Signed-off-by: Michal Privoznik --- src/locking/lock_driver_lockd.c | 2 +- src/qemu/qemu_capabilities.c | 2 +- src/remote/remote_driver.c | 2 +- src/xenapi/xenapi_utils.c| 1 + tools/virsh-domain.c | 4 ++-- tools/wireshark/src/packet-libvirt.c | 6 +++--- tools/wireshark/src/packet-libvirt.h | 4 ++-- 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/locking/lock_driver_lockd.c b/src/locking/lock_driver_lockd.c index 1ca7772..367d0ce 100644 --- a/src/locking/lock_driver_lockd.c +++ b/src/locking/lock_driver_lockd.c @@ -243,7 +243,7 @@ static virNetClientPtr virLockManagerLockDaemonConnectionNew(bool privileged, { virNetClientPtr client = NULL; char *lockdpath; -const char *daemonPath = NULL; +char *daemonPath = NULL; *prog = NULL; diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 37e0588..8271e28 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2652,7 +2652,7 @@ static int virQEMUCapsSaveCache(virQEMUCapsPtr qemuCaps, const char *filename) { virBuffer buf = VIR_BUFFER_INITIALIZER; -const char *xml = NULL; +char *xml = NULL; int ret = -1; size_t i; diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 9d8120f..9a1d78f 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -582,7 +582,7 @@ doRemoteOpen(virConnectPtr conn, trans_tcp, } transport; #ifndef WIN32 -const char *daemonPath = NULL; +char *daemonPath = NULL; #endif /* We handle *ALL* URIs here. The caller has rejected any diff --git a/src/xenapi/xenapi_utils.c b/src/xenapi/xenapi_utils.c index 8b28914..a80d136 100644 --- a/src/xenapi/xenapi_utils.c +++ b/src/xenapi/xenapi_utils.c @@ -49,6 +49,7 @@ xenSessionFree(xen_session *session) VIR_FREE(session->error_description[i]); VIR_FREE(session->error_description); } +/* The session_id member is type of 'const char *'. Sigh. */ VIR_FREE(session->session_id); VIR_FREE(session); } diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 5a17aff..ba47258 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -10349,8 +10349,8 @@ vshPrepareDiskXML(xmlNodePtr disk_node, int type) { xmlNodePtr cur = NULL; -const char *disk_type = NULL; -const char *device_type = NULL; +char *disk_type = NULL; +char *device_type = NULL; xmlNodePtr new_node = NULL; char *ret = NULL; diff --git a/tools/wireshark/src/packet-libvirt.c b/tools/wireshark/src/packet-libvirt.c index 0fe5f03..5c3c369 100644 --- a/tools/wireshark/src/packet-libvirt.c +++ b/tools/wireshark/src/packet-libvirt.c @@ -105,7 +105,7 @@ dissect_xdr_string(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, } } -static gchar * +static const gchar * format_xdr_bytes(guint8 *bytes, guint32 length) { gchar *buf; @@ -206,7 +206,7 @@ dissect_xdr_iterable(tvbuff_t *tvb, proto_item *ti, XDR *xdrs, gint ett, int rhf static gboolean dissect_xdr_vector(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett, - int rhf, gchar *rtype, guint32 size, vir_xdr_dissector_t dissect) + int rhf, const gchar *rtype, guint32 size, vir_xdr_dissector_t dissect) { goffset start; proto_item *ti; @@ -219,7 +219,7 @@ dissect_xdr_vector(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett, static gboolean dissect_xdr_array(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett, - int rhf, gchar *rtype, guint32 maxlen, vir_xdr_dissector_t dissect) + int rhf, const gchar *rtype, guint32 maxlen, vir_xdr_dissector_t dissect) { goffset start; proto_item *ti; diff --git a/tools/wireshark/src/packet-libvirt.h b/tools/wireshark/src/packet-libvirt.h index af54407..5f99fdf 100644 --- a/tools/wireshark/src/packet-libvirt.h +++ b/tools/wireshark/src/packet-libvirt.h @@ -105,9 +105,9 @@ static gboolean dissect_xdr_bytes(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, in static gboolean dissect_xdr_pointer(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, vir_xdr_dissector_t dp); static gboolean dissect_xdr_vector(tvbuff_t *tvb, proto_tree *tree, XDR *xdrs, int hf, gint ett, - i
Re: [libvirt] [PATCH 4/4] virFree: Check const correctness
On 15.07.2014 15:27, Martin Kletzander wrote: On Tue, Jul 15, 2014 at 02:38:36PM +0200, Michal Privoznik wrote: Up to now it's possible to do something like this: const char *ptr; ptr = strdup("my example string"); VIR_FREE(ptr); The problem is, const char * pointers should not be modified (and freeing them is kind of modification). We should avoid this. A little trick is used: assigning a const pointer into 'void *' triggers compiler warning about discarding 'const' qualifier from pointer. So the virFree() function gains new dummy argument, that is not touched anyhow, just fulfills the const correctness check duty. Signed-off-by: Michal Privoznik --- src/util/viralloc.c | 6 -- src/util/viralloc.h | 20 src/xenapi/xenapi_utils.c | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/util/viralloc.c b/src/util/viralloc.c index be9f0fe..0134e67 100644 --- a/src/util/viralloc.c +++ b/src/util/viralloc.c [...] @@ -569,13 +569,15 @@ int virAllocVar(void *ptrptr, /** * virFree: + * @ptr: dummy pointer to check const correctness * @ptrptr: pointer to pointer for address of memory to be freed * * Release the chunk of memory in the pointer pointed to by * the 'ptrptr' variable. After release, 'ptrptr' will be * updated to point to NULL. */ -void virFree(void *ptrptr) +void virFree(void *ptr ATTRIBUTE_UNUSED, + void *ptrptr) What if you don't add another argument, but just change the void *ptrptr to void **ptrptr. Compiler shouldn't be mad about not knowing the size resulting of de-referencing ptrptr, you get the check you want and keep the macro without side-effects. That won't work. Consider: char *tmp; VIR_FREE(tmp); which in turn is equal to: virFree(&tmp); so the &tmp is type of 'char **' while virFree() would expect 'void **' which confuses compiler. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 3/4] VIR_FREE: Avoid doing side work in callees
On 15.07.2014 14:58, Ján Tomko wrote: On 07/15/2014 02:38 PM, Michal Privoznik wrote: There are just two places where we rely on the fact that VIR_FREE() macro is without any side effects. In the future, this property of the macro is going to change, so we need the code to be adjusted to deal with argument passed to VIR_FREE() being evaluated multiple times. Signed-off-by: Michal Privoznik --- src/conf/network_conf.c | 12 1 file changed, 8 insertions(+), 4 deletions(-) NACK, this completely removes the side effect. You need to adjust the callers for that. Well, the arrays that n refer to are freed immediately, but I agree that we should keep the code clean. IMO we should set n to 0 in all *Clear functions, not just virNetworkDNSHostDefClear, after which NULL might be dereferenced based on the n variable. I don't see how that could be possible with current code. The virNetworkDNSHostDefClear is called only on cleanup paths where accessing def->names or def->forwarders is not possible anymore. Jan Okay, consider this squashed in: diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index d60a60e..dcb521f 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -184,6 +184,7 @@ virNetworkDNSHostDefClear(virNetworkDNSHostDefPtr def) for (i = 0; i < def->nnames; i++) VIR_FREE(def->names[i]); +def->nnames = 0; VIR_FREE(def->names); } @@ -204,6 +205,7 @@ virNetworkDNSDefClear(virNetworkDNSDefPtr def) if (def->forwarders) { for (i = 0; i < def->nfwds; i++) VIR_FREE(def->forwarders[i]); +def->nfwds = 0; VIR_FREE(def->forwarders); } if (def->txts) { Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] examples: Introduce domtop
There's this question on the list that is asked over and over again. How do I get {cpu, memory, ...} usage in percentage? Or its modified version: How do I plot nice graphs like virt-manager does? It would be nice if we have an example to inspire people. And that's what domtop should do. Yes, it could be written in different ways, but I've chosen this one as I think it show explicitly what users need to implement in order to imitate virt-manager's graphing. Signed-off-by: Michal Privoznik --- .gitignore | 1 + Makefile.am | 2 +- cfg.mk | 2 +- configure.ac| 1 + examples/domtop/Makefile.am | 27 +++ examples/domtop/domtop.c| 388 libvirt.spec.in | 2 +- 7 files changed, 420 insertions(+), 3 deletions(-) create mode 100644 examples/domtop/Makefile.am create mode 100644 examples/domtop/domtop.c diff --git a/.gitignore b/.gitignore index 2d4d401..90fee91 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,7 @@ /examples/dominfo/info1 /examples/domsuspend/suspend /examples/dommigrate/dommigrate +/examples/domtop/domtop /examples/hellolibvirt/hellolibvirt /examples/openauth/openauth /gnulib/lib/* diff --git a/Makefile.am b/Makefile.am index a374e1a..4aafe94 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,7 +24,7 @@ SUBDIRS = . gnulib/lib include src daemon tools docs gnulib/tests \ examples/dominfo examples/domsuspend examples/apparmor \ examples/xml/nwfilter examples/openauth examples/systemtap \ tools/wireshark examples/dommigrate \ - examples/lxcconvert + examples/lxcconvert examples/domtop ACLOCAL_AMFLAGS = -I m4 diff --git a/cfg.mk b/cfg.mk index baaab71..9880704 100644 --- a/cfg.mk +++ b/cfg.mk @@ -1078,7 +1078,7 @@ exclude_file_name_regexp--sc_prohibit_sprintf = \ exclude_file_name_regexp--sc_prohibit_strncpy = ^src/util/virstring\.c$$ exclude_file_name_regexp--sc_prohibit_strtol = \ - ^(src/(util/virsexpr|(vbox|xen|xenxs)/.*)\.c)|(examples/domsuspend/suspend.c)$$ + ^(src/(util/virsexpr|(vbox|xen|xenxs)/.*)\.c)|(examples/domsuspend/suspend.c)|(examples/domtop/domtop.c)$$ exclude_file_name_regexp--sc_prohibit_xmlGetProp = ^src/util/virxml\.c$$ diff --git a/configure.ac b/configure.ac index 8001e24..f37c716 100644 --- a/configure.ac +++ b/configure.ac @@ -2755,6 +2755,7 @@ AC_CONFIG_FILES([\ examples/domsuspend/Makefile \ examples/dominfo/Makefile \ examples/dommigrate/Makefile \ +examples/domtop/Makefile \ examples/openauth/Makefile \ examples/hellolibvirt/Makefile \ examples/systemtap/Makefile \ diff --git a/examples/domtop/Makefile.am b/examples/domtop/Makefile.am new file mode 100644 index 000..c5cb6c7 --- /dev/null +++ b/examples/domtop/Makefile.am @@ -0,0 +1,27 @@ +## Process this file with automake to produce Makefile.in + +## Copyright (C) 2014 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 +LDADDS = $(STATIC_BINARIES) $(WARN_CFLAGS) $(top_builddir)/src/libvirt.la \ + $(COVERAGE_LDFLAGS) + +noinst_PROGRAMS=domtop + +domtop_SOURCES=domtop.c +domtop_LDFLAGS= +domtop_LDADD= $(LDADDS) diff --git a/examples/domtop/domtop.c b/examples/domtop/domtop.c new file mode 100644 index 000..fcdcc66 --- /dev/null +++ b/examples/domtop/domtop.c @@ -0,0 +1,388 @@ +/* + * domtop.c: Demo program showing how to calculate CPU usage + * + * Copyright (C) 2014 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/>. + * + * Author: Michal Privoznik + */ + +#include +#include +#include
Re: [libvirt] [PATCH 2/3] lxc conf2xml: convert lxc.network.name for veth networks
On 02.07.2014 15:57, Cédric Bosdonnat wrote: --- src/lxc/lxc_native.c | 22 -- .../lxcconf2xmldata/lxcconf2xml-physnetwork.config | 1 + tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 1 + 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index f4c4556..e14face 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -338,7 +338,8 @@ lxcCreateNetDef(const char *type, const char *linkdev, const char *mac, const char *flag, -const char *macvlanmode) +const char *macvlanmode, +const char *name) { virDomainNetDefPtr net = NULL; virMacAddr macAddr; @@ -353,6 +354,8 @@ lxcCreateNetDef(const char *type, net->linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN; } +if (name && VIR_STRDUP(net->ifname_guest, name) < 0) +goto error; One of the requirements when I introduced VIR_STRDUP was, that it's NULL safe so we don't have to do this. s/name && // ACK Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 1/3] lxc network configuration allows setting target container NIC name
On 02.07.2014 15:57, Cédric Bosdonnat wrote: LXC network devices can now be assigned a custom NIC device name on the container side. For example, this is configured with: In this example the network card will appear as eth1 in the guest. --- docs/schemas/domaincommon.rng | 17 + src/conf/domain_conf.c | 27 +++ src/conf/domain_conf.h | 2 ++ src/lxc/lxc_container.c| 29 + src/lxc/lxc_process.c | 25 + tests/lxcxml2xmldata/lxc-idmap.xml | 1 + 6 files changed, 97 insertions(+), 4 deletions(-) The 3/3 should be merged with this so any element addition goes with RNG schema adjustment and is documented. diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 33d0308..e7ca992 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2165,6 +2165,23 @@ + + + + + + + + + + + + + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b7aa4f5..5cd6ae6 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1383,6 +1383,8 @@ void virDomainNetDefFree(virDomainNetDefPtr def) VIR_FREE(def->virtPortProfile); VIR_FREE(def->script); VIR_FREE(def->ifname); +VIR_FREE(def->ifname_guest); +VIR_FREE(def->ifname_guest_actual); virDomainDeviceInfoClear(&def->info); @@ -6618,6 +6620,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, char *bridge = NULL; char *dev = NULL; char *ifname = NULL; +char *ifname_guest = NULL; +char *ifname_guest_actual = NULL; char *script = NULL; char *address = NULL; char *port = NULL; @@ -6723,6 +6727,10 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, /* An auto-generated target name, blank it out */ VIR_FREE(ifname); } +} else if ((!ifname_guest || !ifname_guest_actual) && + xmlStrEqual(cur->name, BAD_CAST "guest")) { +ifname_guest = virXMLPropString(cur, "dev"); +ifname_guest_actual = virXMLPropString(cur, "actual"); } else if (!linkstate && xmlStrEqual(cur->name, BAD_CAST "link")) { linkstate = virXMLPropString(cur, "state"); @@ -6964,6 +6972,14 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt, def->ifname = ifname; ifname = NULL; } +if (ifname_guest != NULL) { +def->ifname_guest = ifname_guest; +ifname_guest = NULL; +} +if (ifname_guest_actual != NULL) { +def->ifname_guest_actual = ifname_guest_actual; +ifname_guest_actual = NULL; +} /* NIC model (see -net nic,model=?). We only check that it looks * reasonable, not that it is a supported NIC type. FWIW kvm @@ -15883,6 +15899,17 @@ virDomainNetDefFormat(virBufferPtr buf, /* Skip auto-generated target names for inactive config. */ virBufferEscapeString(buf, "\n", def->ifname); } +if (def->ifname_guest || def->ifname_guest_actual) { +virBufferAddLit(buf, "ifname_guest) +virBufferEscapeString(buf, " dev='%s'", def->ifname_guest); + +/* Only set if the host is running, so shouldn't pollute output */ +if (def->ifname_guest_actual) +virBufferEscapeString(buf, " actual='%s'", def->ifname_guest_actual); +virBufferAddLit(buf, "/>\n"); +} if (def->model) { virBufferEscapeString(buf, "\n", def->model); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 1122eb2..60aa491 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -915,6 +915,8 @@ struct _virDomainNetDef { } tune; char *script; char *ifname; +char *ifname_guest; +char *ifname_guest_actual; virDomainDeviceInfo info; char *filter; virNWFilterHashTablePtr filterparams; diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index fd8ab16..c7423db 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -464,6 +464,21 @@ static int lxcContainerSetID(virDomainDefPtr def) } +static virDomainNetDefPtr +lxcContainerGetNetDef(virDomainDefPtr vmDef, const char *devName) +{ +size_t i; +virDomainNetDefPtr netDef; + +for (i = 0; i < vmDef->nnets; i++) { +netDef = vmDef->nets[i]; +if (STREQ(netDef->ifname_guest_actual, devName)) +return netDef; +} + +return NULL; +} + /** * lxcContainerRenameAndEnableInterfaces: * @nveths: numb
Re: [libvirt] [PATCH v2] support for QEMU vhost-user
On 11.07.2014 19:47, Michele Paolino wrote: > This patch adds support for the QEMU vhost-user feature to libvirt. > vhost-user enables the communication between a QEMU virtual machine > and other userspace process using the Virtio transport protocol. > It uses a char dev (e.g. Unix socket) for the control plane, > while the data plane based on shared memory. > > The XML looks like: > > > > > > > > changes from v1: > * addressed comments > * removed unnecessary checks > * series merged in a single patch We tend to write the diff to previous versions into notes not in the commit message as it pollutes git log. BTW: I didn't ask the whole patchset to be merged into a single patch, but it doesn't hurt in this specific case either (the diff stat seems reasonably big). > > The previous version of this patch can be found at: > http://www.redhat.com/archives/libvir-list/2014-July/msg00111.html > > Signed-off-by: Michele Paolino > --- > docs/formatdomain.html.in | 34 + > docs/schemas/domaincommon.rng | 25 +++ > src/conf/domain_conf.c | 87 > ++ > src/conf/domain_conf.h | 10 ++- > src/libxl/libxl_conf.c | 1 + > src/lxc/lxc_process.c | 1 + > src/qemu/qemu_command.c| 63 > src/uml/uml_conf.c | 5 ++ > src/xenxs/xen_sxpr.c | 1 + > .../qemuxml2argv-net-vhostuser.args| 7 ++ > .../qemuxml2argv-net-vhostuser.xml | 33 > tests/qemuxml2argvtest.c | 1 + > tests/qemuxml2xmltest.c| 1 + > 13 files changed, 267 insertions(+), 2 deletions(-) > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser.args > create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-vhostuser.xml > > diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in > index 3f8bbee..606b7d4 100644 > --- a/docs/formatdomain.html.in > +++ b/docs/formatdomain.html.in > @@ -3927,6 +3927,40 @@ qemu-kvm -net nic,model=? /dev/null > Since 0.9.5 > > > +vhost-user interface > + > + > + vhost-user enables the communication between a QEMU virtual machine > + and other userspace process using the Virtio transport protocol. > + A char dev (e.g. Unix socket) is used for the control plane, while > + the data plane is based on shared memory. > + > + > + > + ... > +> + > + ... > + > + > + The> + > + > +> + > +> + I don't think so. Empty bodies elements are written as . And that's how libvirt formats them too. And if I were to be really picky, is formated before . > +
Re: [libvirt] [PATCH v3 00/16] Support for per-guest-node binding
On 16.07.2014 16:42, Martin Kletzander wrote: v3 of https://www.redhat.com/archives/libvir-list/2014-July/msg00372.html v3: - Michal's suggestions worked in - rebased on current master Martin Kletzander (16): qemu: purely a code movement qemu: remove useless error check conf: purely a code movement conf, schema: add 'id' field for cells numatune: create new module for numatune numatune: unify numatune struct and enum names numatune: Encapsulate numatune configuration in order to unify results conf, schema: add support for memnode elements numatune: add support for per-node memory bindings in private APIs qemu: allow qmp probing for cmdline options without params qemu: memory-backend-ram capability probing qemu: newer -numa parameter capability probing qemu: enable disjoint numa cpu ranges qemu: pass numa node binding preferences to qemu qemu: split out cpuset.mems setting qemu: leave restricting cpuset.mems after initialization docs/formatdomain.html.in | 32 +- docs/schemas/domaincommon.rng | 22 + po/POTFILES.in | 1 + src/Makefile.am| 3 +- src/conf/cpu_conf.c| 41 +- src/conf/cpu_conf.h| 3 +- src/conf/domain_conf.c | 203 ++- src/conf/domain_conf.h | 10 +- src/conf/numatune_conf.c | 595 + src/conf/numatune_conf.h | 108 src/libvirt_private.syms | 24 +- src/lxc/lxc_cgroup.c | 20 +- src/lxc/lxc_controller.c | 5 +- src/lxc/lxc_native.c | 15 +- src/parallels/parallels_driver.c | 7 +- src/qemu/qemu_capabilities.c | 16 +- src/qemu/qemu_capabilities.h | 2 + src/qemu/qemu_cgroup.c | 52 +- src/qemu/qemu_cgroup.h | 4 +- src/qemu/qemu_command.c| 98 +++- src/qemu/qemu_driver.c | 84 ++- src/qemu/qemu_monitor.c| 6 +- src/qemu/qemu_monitor.h| 3 +- src/qemu/qemu_monitor_json.c | 8 +- src/qemu/qemu_monitor_json.h | 3 +- src/qemu/qemu_process.c| 12 +- src/util/virnuma.c | 61 +-- src/util/virnuma.h | 28 +- tests/qemucapabilitiesdata/caps_1.6.50-1.caps | 1 + tests/qemucapabilitiesdata/caps_1.6.50-1.replies | 5 + tests/qemumonitorjsontest.c| 20 +- .../qemuxml2argv-cpu-numa-disjoint.args| 6 + .../qemuxml2argv-cpu-numa-disjoint.xml | 28 + tests/qemuxml2argvdata/qemuxml2argv-cpu-numa1.xml | 6 +- tests/qemuxml2argvdata/qemuxml2argv-cpu-numa2.xml | 6 +- tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml | 25 + .../qemuxml2argv-numatune-auto-prefer.xml | 29 + .../qemuxml2argv-numatune-memnode-no-memory.args | 8 + .../qemuxml2argv-numatune-memnode-no-memory.xml| 30 ++ .../qemuxml2argv-numatune-memnode-nocpu.xml| 25 + .../qemuxml2argv-numatune-memnode.args | 11 + .../qemuxml2argv-numatune-memnode.xml | 33 ++ .../qemuxml2argv-numatune-memnodes-problematic.xml | 31 ++ tests/qemuxml2argvtest.c | 12 + .../qemuxml2xmlout-cpu-numa1.xml | 28 + .../qemuxml2xmlout-cpu-numa2.xml | 28 + .../qemuxml2xmlout-numatune-auto-prefer.xml| 29 + .../qemuxml2xmlout-numatune-memnode.xml| 33 ++ tests/qemuxml2xmltest.c| 8 + 49 files changed, 1479 insertions(+), 389 deletions(-) create mode 100644 src/conf/numatune_conf.c create mode 100644 src/conf/numatune_conf.h create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-disjoint.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa-disjoint.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-numa3.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-no-memory.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-no-memory.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-nocpu.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune
Re: [libvirt] virsh capabilities vs. domcapabilities
On 16.07.2014 21:00, Eric Blake wrote: We have some inconsistencies in the node capabilities (which shows guest capabilities for some default binaries) and domcapabilities (which shows guest capabilities for a specified binary). It might be nicer for client applications if the two XML components share a common schema and output layout, so that the same client code can be used to parse either (sub-tree of) XML, modulo the name of the top-most element containing the tree. Furthermore, I'm trying to figure out how to advertise whether a given domain will support active commit (and similarly, Peter's patches for relative backing name preservation). Advertising the feature just through 'virsh capabilities' is insufficient, because that only covers the default binary; so it seems like the sort of thing that should also be in 'virsh domcapabilities'. That depends on how's active commit accepted by libvirt. IIUC it's a flag to an API. (Okay, you got me there, I'm not paying much attention to snapshot work). The best solution would be to introduce another section, where supported flags to APIs would be enumerated (same way that attribute values are). But this is sooo much more work than in attribute part (esp. without introspection) that the resulting code would be unmaintainable. So my suggestion is to come up with yet another section and put arbitrary strings there to represent features like active commit. For instance: ... active-commit {some ordinary commit} Since virConnectGetDomainCapabilities is brand new to 1.2.7, we still have time to change its XML. But I want consensus on whether we need things to match, or whether we intentionally want people to rely only on the newer XML format of the new API call (that is, don't bloat 'virsh capabilities'/virConnectGetCapabilities any further, and learning whether active commit is supported will have to be done via 'virsh domcapabilities'/virConnectGetDomainCapabilities). That is, I'm wondering if should use / as its starting point, rather than completely inventing new XML. I'm also finding 'virsh domcapabilities' a bit hard to use - even though it allows all its arguments to be optional at the RPC level, the qemu implementation isn't so happy: # tools/virsh domcapabilities error: failed to get emulator capabilities error: virttype_str in qemuConnectGetDomainCapabilities must not be NULL but how am I supposed to know what --virttype strings are valid? By reading the documentation :P From the virsh manpage: The virttype option specifies the virtualization type used. The value to be used is either from the 'type' attribute of the top level element from the domain XML or the 'type' attribute found within each element from the virsh capabilities output. I know virsh user is user unfriendly, but I think this could be solved by wise auto completion (if I find another student to complete it). Or if you have any idea meanwhile ... # tools/virsh domcapabilities --virttype kvm error: failed to get emulator capabilities error: invalid argument: at least one of emulatorbin or architecture fields must be present Would it be nicer to behave the same as 'virsh capabilities' and give the details of the default binary in this case? Sure, but in order to get default binary we must know architecture (consider the case where you have both /usr/bin/qemu-system-x86_64 and /usr/bin/qemu-system-i686). Although, having only one qemu binary on the system makes it easy to find the default, doesn't it? Patch on the way. Now, for a comparison between the two XML per binary: 'virsh capabilities' gives me this segment: hvm 64 /usr/bin/qemu-system-alpha clipper while 'virsh domcapabilities --emulatorbin /usr/bin/qemu-system-alpha --virttype kvm' gives this: /usr/bin/qemu-system-alpha kvm clipper alpha disk cdrom floppy lun ide fdc scsi virtio usb subsystem default mandatory requisite optional usb pci scsi I'm okay that the domcapabilites output is longer, and don't think we need to backport any of the new stuff to the older API. But any information present in the old API should be easily retrieved using the new API, so that the information isn't lost, and so that a client can learn the same amount of detail about a non-default binary as they can about the defaults. Look at the difference in XPath to get to some of the same information: /guest/os_type vs. ? - where is os_type in domcapabilities? nowhere yet. /guest/arch@name vs. /domainCapabilities/arch - why is one an attribute and the other an element? /
[libvirt] [PATCH] qemuConnectGetDomainCapabilities: Use wiser defaults
Up to now, users have to pass two arguments at least: domain virt type ('qemu' vs 'kvm') and one of emulatorbin or architecture. This is not much user friendly. Nowadays users mostly use KVM and share the host architecture with the guest. So now, the API (and subsequently virsh command) can be called with all NULLs (without any arguments). Before this patch: # virsh domcapabilities error: failed to get emulator capabilities error: virttype_str in qemuConnectGetDomainCapabilities must not be NULL # virsh domcapabilities kvm error: failed to get emulator capabilities error: invalid argument: at least one of emulatorbin or architecture fields must be present After: # virsh domcapabilities /usr/bin/qemu-system-x86_64 kvm pc-i440fx-2.1 x86_64 Signed-off-by: Michal Privoznik --- src/qemu/qemu_driver.c | 24 ++-- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 33541d3..7d99435 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -16849,17 +16849,17 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn, char *ret = NULL; virQEMUDriverPtr driver = conn->privateData; virQEMUCapsPtr qemuCaps = NULL; -int virttype; /* virDomainVirtType */ +int virttype = VIR_DOMAIN_VIRT_KVM; /* virDomainVirtType */ virDomainCapsPtr domCaps = NULL; -int arch = VIR_ARCH_NONE; /* virArch */ +int arch = virArchFromHost(); /* virArch */ virCheckFlags(0, ret); -virCheckNonNullArgReturn(virttype_str, ret); if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0) return ret; -if ((virttype = virDomainVirtTypeFromString(virttype_str)) < 0) { +if (virttype_str && +(virttype = virDomainVirtTypeFromString(virttype_str)) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("unknown virttype: %s"), virttype_str); @@ -16882,9 +16882,6 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn, arch_from_caps = virQEMUCapsGetArch(qemuCaps); -if (arch == VIR_ARCH_NONE) -arch = arch_from_caps; - if (arch_from_caps != arch) { virReportError(VIR_ERR_INVALID_ARG, _("architecture from emulator '%s' doesn't " @@ -16893,21 +16890,12 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn, virArchToString(arch)); goto cleanup; } -} else if (arch_str) { +} else { if (!(qemuCaps = virQEMUCapsCacheLookupByArch(driver->qemuCapsCache, arch))) goto cleanup; -if (!emulatorbin) -emulatorbin = virQEMUCapsGetBinary(qemuCaps); -/* Deliberately not checking if provided @emulatorbin matches @arch, - * since if @emulatorbin was specified the match has been checked a few - * lines above. */ -} else { -virReportError(VIR_ERR_INVALID_ARG, "%s", - _("at least one of emulatorbin or " - "architecture fields must be present")); -goto cleanup; +emulatorbin = virQEMUCapsGetBinary(qemuCaps); } if (machine) { -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] virsh capabilities vs. domcapabilities
On 17.07.2014 11:11, Daniel P. Berrange wrote: On Thu, Jul 17, 2014 at 11:05:08AM +0200, Michal Privoznik wrote: # tools/virsh domcapabilities --virttype kvm error: failed to get emulator capabilities error: invalid argument: at least one of emulatorbin or architecture fields must be present Would it be nicer to behave the same as 'virsh capabilities' and give the details of the default binary in this case? Sure, but in order to get default binary we must know architecture (consider the case where you have both /usr/bin/qemu-system-x86_64 and /usr/bin/qemu-system-i686). Although, having only one qemu binary on the system makes it easy to find the default, doesn't it? Patch on the way. IMHO it would be preferrable to always default to virArchFromHost() if arch is none, since that gives a predictable default value, as opposed to probing emulators which is unpredictable Yep, that's exactly what I've done in my patch: https://www.redhat.com/archives/libvir-list/2014-July/msg00884.html Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v1 0/7] Hugepages wrt to NUMA
Up to now, domains are either backed by an arbitrary huge page but without any NUMA awareness. This is suboptimal and I'm trying to fix it. Michal Privoznik (7): configure: Check for statfs Introduce virFileFindHugeTLBFS qemu: Utilize virFileFindHugeTLBFS virbitmap: Introduce virBitmapDoesIntersect domain: Introduce ./hugepages/page/[@size,@unit,@nodeset] qemu: Implement ./hugepages/page/[@size,@unit,@nodeset] tests: Some testing of hugepages mapping configure.ac | 4 +- docs/formatdomain.html.in | 18 +- docs/schemas/domaincommon.rng | 19 +- src/Makefile.am| 1 + src/conf/domain_conf.c | 197 +++-- src/conf/domain_conf.h | 13 +- src/libvirt_private.syms | 2 + src/parallels/parallels_driver.c | 2 +- src/qemu/qemu_capabilities.c | 2 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c| 111 ++-- src/qemu/qemu_conf.c | 124 +++-- src/qemu/qemu_conf.h | 9 +- src/qemu/qemu_driver.c | 39 ++-- src/qemu/qemu_process.c| 21 ++- src/util/virbitmap.c | 20 +++ src/util/virbitmap.h | 3 + src/util/virfile.c | 176 +- src/util/virfile.h | 12 ++ .../qemuxml2argv-hugepages-pages.args | 16 ++ .../qemuxml2argv-hugepages-pages.xml | 45 + .../qemuxml2argv-hugepages-pages2.args | 10 ++ .../qemuxml2argv-hugepages-pages2.xml | 38 .../qemuxml2argv-hugepages-pages3.args | 9 + .../qemuxml2argv-hugepages-pages3.xml | 38 tests/qemuxml2argvdata/qemuxml2argv-hugepages.args | 2 +- tests/qemuxml2argvtest.c | 18 +- tests/qemuxml2xmltest.c| 3 + tests/virbitmaptest.c | 26 +++ 29 files changed, 884 insertions(+), 95 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.xml -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v1 7/7] tests: Some testing of hugepages mapping
Signed-off-by: Michal Privoznik --- .../qemuxml2argv-hugepages-pages2.args | 10 ++ .../qemuxml2argv-hugepages-pages2.xml | 38 ++ .../qemuxml2argv-hugepages-pages3.args | 9 + .../qemuxml2argv-hugepages-pages3.xml | 38 ++ tests/qemuxml2argvtest.c | 4 +++ tests/qemuxml2xmltest.c| 2 ++ 6 files changed, 101 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.xml diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.args b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.args new file mode 100644 index 000..9211bc6 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.args @@ -0,0 +1,10 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/qemu -S -M pc -m 1024 -smp 2 \ +-object memory-backend-file,prealloc=yes,\ +mem-path=/dev/hugepages2M/libvirt/qemu,size=256M,id=ram-node0 \ +-numa node,nodeid=0,cpus=0,memdev=ram-node0 \ +-object memory-backend-file,prealloc=yes,\ +mem-path=/dev/hugepages2M/libvirt/qemu,size=768M,id=ram-node1 \ +-numa node,nodeid=1,cpus=1,memdev=ram-node1 \ +-nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ +-usb -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.xml b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.xml new file mode 100644 index 000..3df870b --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.xml @@ -0,0 +1,38 @@ + + SomeDummyHugepagesGuest + ef1bdff4-27f3-4e85-a807-5fb4d58463cc + 1048576 + 1048576 + + + + + + 2 + +hvm + + + + + + + + + + destroy + restart + destroy + +/usr/bin/qemu + + + + + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.args b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.args new file mode 100644 index 000..27b3f8e --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.args @@ -0,0 +1,9 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/qemu -S -M pc -m 1024 -smp 2 \ +-object memory-backend-ram,size=256M,id=ram-node0 \ +-numa node,nodeid=0,cpus=0,memdev=ram-node0 \ +-object memory-backend-file,prealloc=yes,\ +mem-path=/dev/hugepages1G/libvirt/qemu,size=768M,id=ram-node1 \ +-numa node,nodeid=1,cpus=1,memdev=ram-node1 \ +-nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \ +-hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.xml b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.xml new file mode 100644 index 000..35aa2cf --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.xml @@ -0,0 +1,38 @@ + + SomeDummyHugepagesGuest + ef1bdff4-27f3-4e85-a807-5fb4d58463cc + 1048576 + 1048576 + + + + + + 2 + +hvm + + + + + + + + + + destroy + restart + destroy + +/usr/bin/qemu + + + + + + + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 63c9c4b..b4505a9 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -669,6 +669,10 @@ mymain(void) DO_TEST("hugepages", QEMU_CAPS_MEM_PATH); DO_TEST("hugepages-pages", QEMU_CAPS_MEM_PATH, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE); +DO_TEST("hugepages-pages2", QEMU_CAPS_MEM_PATH, QEMU_CAPS_OBJECT_MEMORY_RAM, +QEMU_CAPS_OBJECT_MEMORY_FILE); +DO_TEST("hugepages-pages3", QEMU_CAPS_MEM_PATH, QEMU_CAPS_OBJECT_MEMORY_RAM, +QEMU_CAPS_OBJECT_MEMORY_FILE); DO_TEST("nosharepages", QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_MEM_MERGE); DO_TEST("disk-cdrom", NONE); DO_TEST("disk-cdrom-network-http", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE, diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 09cb228..8d46b40 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -198,6 +198,8 @@ mymain(void) DO_TEST("hugepages"); DO_TEST("hugepages-pages"); +DO_TEST("hugepages-pages2"); +DO_TEST("hugepages-pages3"); DO_TEST("nosharepages"); DO_TEST("disk-aio"); DO_TEST("disk-cdrom"); -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v1 2/7] Introduce virFileFindHugeTLBFS
This should iterate over mount tab and search for hugetlbfs among with looking for the default value of huge pages. Signed-off-by: Michal Privoznik --- src/libvirt_private.syms | 1 + src/util/virfile.c | 155 +++ src/util/virfile.h | 12 3 files changed, 168 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8d3671c..44403fd 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1297,6 +1297,7 @@ virFileDirectFdFlag; virFileExists; virFileFclose; virFileFdopen; +virFileFindHugeTLBFS; virFileFindMountPoint; virFileFindResource; virFileFindResourceFull; diff --git a/src/util/virfile.c b/src/util/virfile.c index 699b9f8..e1034b7 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -2841,6 +2841,9 @@ int virFilePrintf(FILE *fp, const char *msg, ...) # ifndef CIFS_SUPER_MAGIC # define CIFS_SUPER_MAGIC 0xFF534D42 # endif +# ifndef HUGETLBFS_MAGIC +# define HUGETLBFS_MAGIC 0x958458f6 +# endif int virFileIsSharedFSType(const char *path, @@ -2914,6 +2917,33 @@ virFileIsSharedFSType(const char *path, return 0; } +int +virFileGetHugepageSize(const char *path, + unsigned long long *size) +{ +int ret = -1; +struct statfs fs; + +if (statfs(path, &fs) < 0) { +virReportSystemError(errno, + _("cannot determine filesystem for '%s'"), + path); +goto cleanup; +} + +if (fs.f_type != HUGETLBFS_MAGIC) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("not a hugetlbfs mount: '%s'"), + path); +goto cleanup; +} + +*size = fs.f_bsize / 1024; /* we are storing size in KiB */ +ret = 0; + cleanup: +return ret; +} + #else /* ! HAVE_STATFS */ int virFileIsSharedFSType(const char *path ATTRIBUTE_UNUSED, @@ -2923,6 +2953,17 @@ int virFileIsSharedFSType(const char *path ATTRIBUTE_UNUSED, return 0; } +int +virFileGetHugepageSize(const char *path, + unsigned long long *size) +{ +/* XXX implement me :-) */ +VIR_WARN("Trying to get huge page size on %s is not implemented yet.", + path); +*size = 2048; /* Pure guess */ +return 0; +} + #endif /* HAVE_STATFS */ int virFileIsSharedFS(const char *path) @@ -2935,3 +2976,117 @@ int virFileIsSharedFS(const char *path) VIR_FILE_SHFS_SMB | VIR_FILE_SHFS_CIFS); } + + +#if defined __linux__ && defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R + +# define PROC_MEMINFO "/proc/meminfo" +# define HUGEPAGESIZE_STR "Hugepagesize:" + +static int +virFileGetDefaultHugepageSize(unsigned long long *size) +{ +int ret = -1; +char *meminfo, *c, *n, *unit; + +if (virFileReadAll(PROC_MEMINFO, 4096, &meminfo) < 0) +goto cleanup; + +if (!(c = strstr(meminfo, HUGEPAGESIZE_STR))) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse %s"), + PROC_MEMINFO); +goto cleanup; +} +c += strlen(HUGEPAGESIZE_STR); + +if ((n = strchr(c, '\n'))) { +/* Cut off the rest of the meminfo file */ +*n = '\0'; +} + +if (virStrToLong_ull(c, &unit, 10, size) < 0 || STRNEQ(unit, " kB")) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse %s %s"), + HUGEPAGESIZE_STR, c); +goto cleanup; +} + +ret = 0; + cleanup: +VIR_FREE(meminfo); +return ret; +} + +# define PROC_MOUNTS "/proc/mounts" + +int +virFileFindHugeTLBFS(virHugeTLBFSPtr *ret_fs, + size_t *ret_nfs) +{ +int ret = -1; +FILE *f = NULL; +struct mntent mb; +char mntbuf[1024]; +virHugeTLBFSPtr fs = NULL; +size_t nfs = 0; +unsigned long long default_hugepagesz; + +if (virFileGetDefaultHugepageSize(&default_hugepagesz) < 0) +goto cleanup; + +if (!(f = setmntent(PROC_MOUNTS, "r"))) { +virReportSystemError(errno, + _("Unable to open %s"), + PROC_MOUNTS); +goto cleanup; +} + +while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) { +virHugeTLBFSPtr tmp; + +if (STRNEQ(mb.mnt_type, "hugetlbfs")) +continue; + +if (VIR_REALLOC_N(fs, nfs + 1) < 0) +goto cleanup; + +tmp = &fs[nfs]; +nfs++; + +if (VIR_STRDUP(tmp->mnt_dir, mb.mnt_dir) < 0) +goto cleanup; + +if (virFileGetHugepageSize(tmp->mnt_dir, &tmp->size) < 0) +goto cleanup; + +tmp->deflt = tmp-&g
[libvirt] [PATCH v1 4/7] virbitmap: Introduce virBitmapDoesIntersect
This internal API just checks if two bitmaps intersect or not. Signed-off-by: Michal Privoznik --- src/libvirt_private.syms | 1 + src/util/virbitmap.c | 20 src/util/virbitmap.h | 3 +++ tests/virbitmaptest.c| 26 ++ 4 files changed, 50 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 44403fd..256edd5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1016,6 +1016,7 @@ virBitmapClearBit; virBitmapCopy; virBitmapCountBits; virBitmapDataToString; +virBitmapDoesIntersect; virBitmapEqual; virBitmapFormat; virBitmapFree; diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c index 1029635..9f82eb9 100644 --- a/src/util/virbitmap.c +++ b/src/util/virbitmap.c @@ -732,3 +732,23 @@ virBitmapDataToString(void *data, virBitmapFree(map); return ret; } + +bool +virBitmapDoesIntersect(virBitmapPtr b1, + virBitmapPtr b2) +{ +size_t i; + +if (b1->max_bit > b2->max_bit) { +virBitmapPtr tmp = b1; +b1 = b2; +b2 = tmp; +} + +for (i = 0; i < b1->map_len; i++) { +if (b1->map[i] & b2->map[i]) +return true; +} + +return false; +} diff --git a/src/util/virbitmap.h b/src/util/virbitmap.h index 142a218..063516a 100644 --- a/src/util/virbitmap.h +++ b/src/util/virbitmap.h @@ -114,5 +114,8 @@ size_t virBitmapCountBits(virBitmapPtr bitmap) char *virBitmapDataToString(void *data, int len) ATTRIBUTE_NONNULL(1); +bool virBitmapDoesIntersect(virBitmapPtr b1, +virBitmapPtr b2) +ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); #endif diff --git a/tests/virbitmaptest.c b/tests/virbitmaptest.c index 048946f..09b40d7 100644 --- a/tests/virbitmaptest.c +++ b/tests/virbitmaptest.c @@ -510,6 +510,30 @@ test9(const void *opaque ATTRIBUTE_UNUSED) } static int +test10(const void *opaque ATTRIBUTE_UNUSED) +{ +int ret = -1; +virBitmapPtr b1 = NULL, b2 = NULL, b3 = NULL; + +if (virBitmapParse("0-3,5-8,11-15", 0, &b1, 20) < 0 || +virBitmapParse("4,9,10,16-19", 0, &b2, 20) < 0 || +virBitmapParse("15", 0, &b3, 20) < 0) +goto cleanup; + +if (virBitmapDoesIntersect(b1, b2) || +virBitmapDoesIntersect(b2, b3) || +!virBitmapDoesIntersect(b1, b3)) +goto cleanup; + +ret = 0; + cleanup: +virBitmapFree(b1); +virBitmapFree(b2); +virBitmapFree(b3); +return ret; +} + +static int mymain(void) { int ret = 0; @@ -532,6 +556,8 @@ mymain(void) ret = -1; if (virtTestRun("test9", test9, NULL) < 0) ret = -1; +if (virtTestRun("test10", test10, NULL) < 0) +ret = -1; return ret; } -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v1 1/7] configure: Check for statfs
The statfs(2) gets filesystem statistics. Currently, we use it only on linux, and leave stub to implement on other platforms. But hey, other platforms (like FreeBSD) have statfs() too. If we check it in configure we can wider platforms supported. Speaking of FreeBSD, the headers to include are of course different: sys/param.h and sys/mount.h on the FreeBSD and sys/statfs.h on the Linux. The header files are checked too. Signed-off-by: Michal Privoznik --- configure.ac | 4 ++-- src/util/virfile.c | 21 ++--- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 8001e24..68ebf75 100644 --- a/configure.ac +++ b/configure.ac @@ -275,7 +275,7 @@ dnl and various less common threadsafe functions AC_CHECK_FUNCS_ONCE([cfmakeraw fallocate geteuid getgid getgrnam_r \ getmntent_r getpwuid_r getuid kill mmap newlocale posix_fallocate \ posix_memalign prlimit regexec sched_getaffinity setgroups setns \ - setrlimit symlink sysctlbyname getifaddrs]) + setrlimit symlink sysctlbyname getifaddrs statfs]) dnl Availability of pthread functions. Because of $LIB_PTHREAD, we dnl cannot use AC_CHECK_FUNCS_ONCE. LIB_PTHREAD and LIBMULTITHREAD @@ -316,7 +316,7 @@ dnl Availability of various common headers (non-fatal if missing). AC_CHECK_HEADERS([pwd.h paths.h regex.h sys/un.h \ sys/poll.h syslog.h mntent.h net/ethernet.h linux/magic.h \ sys/un.h sys/syscall.h sys/sysctl.h netinet/tcp.h ifaddrs.h \ - libtasn1.h sys/ucred.h sys/mount.h]) + libtasn1.h sys/ucred.h sys/mount.h sys/param.h sys/statfs.h]) dnl Check whether endian provides handy macros. AC_CHECK_DECLS([htole64], [], [], [[#include ]]) diff --git a/src/util/virfile.c b/src/util/virfile.c index 463064c..699b9f8 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -43,11 +43,15 @@ # include #endif -#ifdef __linux__ -# if HAVE_LINUX_MAGIC_H -# include -# endif +#if HAVE_LINUX_MAGIC_H +# include +#endif + +#ifdef HAVE_SYS_STATFS_H # include +#elif defined HAVE_SYS_PARAM_H && defined HAVE_SYS_MOUNT_H +# include +# include #endif #if defined(__linux__) && HAVE_DECL_LO_FLAGS_AUTOCLEAR @@ -2817,7 +2821,7 @@ int virFilePrintf(FILE *fp, const char *msg, ...) } -#ifdef __linux__ +#ifdef HAVE_STATFS # ifndef NFS_SUPER_MAGIC # define NFS_SUPER_MAGIC 0x6969 @@ -2909,14 +2913,17 @@ virFileIsSharedFSType(const char *path, return 0; } -#else + +#else /* ! HAVE_STATFS */ + int virFileIsSharedFSType(const char *path ATTRIBUTE_UNUSED, int fstypes ATTRIBUTE_UNUSED) { /* XXX implement me :-) */ return 0; } -#endif + +#endif /* HAVE_STATFS */ int virFileIsSharedFS(const char *path) { -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v1 5/7] domain: Introduce ./hugepages/page/[@size, @unit, @nodeset]
Signed-off-by: Michal Privoznik --- docs/formatdomain.html.in | 18 +- docs/schemas/domaincommon.rng | 19 +- src/conf/domain_conf.c | 197 +++-- src/conf/domain_conf.h | 13 +- src/parallels/parallels_driver.c | 2 +- src/qemu/qemu_command.c| 2 +- src/qemu/qemu_conf.c | 20 ++- src/qemu/qemu_process.c| 2 +- .../qemuxml2argv-hugepages-pages.xml | 45 + tests/qemuxml2xmltest.c| 1 + 10 files changed, 288 insertions(+), 31 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 3c85fc5..f4362e6 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -617,7 +617,9 @@ <domain> ... <memoryBacking> -<hugepages/> +<hugepages> + <page size="1" unit="G" nodeset="0-3,5"/> + <page size="2" unit="M" nodeset="4"/> <nosharepages/> <locked/> </memoryBacking> @@ -632,7 +634,19 @@ hugepages This tells the hypervisor that the guest should have its memory -allocated using hugepages instead of the normal native page size. + allocated using hugepages instead of the normal native page size. + Since 1.2.5 it's possible to set hugepages + more specifically per numa node. The page element is + introduced. It has one compulsory attribute size which + specifies which hugepages should be used (especially useful on systems + supporting hugepages of different sizes). The default unit for the + size attribute is kilobytes (multiplier of 1024). If you + want to use different unit, use optional unit attribute. + For systems with NUMA, the optional nodeset attribute may + come handy as it ties given guest's NUMA nodes to certain hugepage + sizes. From the example snippet, one gigabyte hugepages are used for + every NUMA node except node number four. For the correct syntax see + this. nosharepages Instructs hypervisor to disable shared pages (memory merge, KSM) for this domain. Since 1.0.6 diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 2caeef9..d9da0bc 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -567,7 +567,24 @@ - + + + + + + + + + + + + + + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a1ef374..b49bcb0 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -11258,6 +11258,57 @@ virDomainParseMemory(const char *xpath, xmlXPathContextPtr ctxt, } +static int +virDomainHugepagesParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt, + virDomainHugePagePtr hugepage) +{ +int ret = -1; +xmlNodePtr oldnode = ctxt->node; +unsigned long long bytes, max; +char *unit = NULL, *nodeset = NULL; + +ctxt->node = node; + +/* On 32-bit machines, our bound is 0x * KiB. On 64-bit + * machines, our bound is off_t (2^63). */ +if (sizeof(unsigned long) < sizeof(long long)) +max = 1024ull * ULONG_MAX; +else +max = LLONG_MAX; + +if (virXPathULongLong("string(./@size)", ctxt, &bytes) < 0) { +virReportError(VIR_ERR_XML_DETAIL, "%s", + _("unable to parse size attribute")); +goto cleanup; +} + +unit = virXPathString("string(./@unit)", ctxt); + +if (virScaleInteger(&bytes, unit, 1024, max) < 0) +goto cleanup; + +if (!(hugepage->size = VIR_DIV_UP(bytes, 1024))) { +virReportError(VIR_ERR_XML_DETAIL, "%s", + _("hugepage size can't be zero")); +goto cleanup; +} + +if ((nodeset = virXMLPropString(node, "nodeset"))) { +if (virBitmapParse(nodeset, 0, &hugepage->nodemask, + VIR_DOMAIN_CPUMASK_LEN) < 0) +goto cleanup; +} + +ret = 0; + cleanup: +VIR_FREE(unit); +VIR_FREE(nodeset); +ctxt->node = o
[libvirt] [PATCH v1 3/7] qemu: Utilize virFileFindHugeTLBFS
Use better detection of hugetlbfs mount points. Yes, there can be multiple mount points each serving different huge page size. Since we already have ability to override the mount point in the qemu.conf file, this crazy backward compatibility code is brought in. Now we allow multiple mount points, so the "hugetlbfs_mount" option must take an list of strings (mount points). But previously, it was just a string, so we must accept both types now. Signed-off-by: Michal Privoznik --- src/Makefile.am | 1 + src/qemu/qemu_command.c | 20 src/qemu/qemu_conf.c | 122 +-- src/qemu/qemu_conf.h | 9 +++- src/qemu/qemu_driver.c | 39 +++ src/qemu/qemu_process.c | 21 +--- tests/qemuxml2argvtest.c | 10 ++-- 7 files changed, 166 insertions(+), 56 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 982f63d..85e61c2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1212,6 +1212,7 @@ libvirt_driver_qemu_impl_la_LIBADD = $(CAPNG_LIBS) \ $(GNUTLS_LIBS) \ $(LIBNL_LIBS) \ $(LIBXML_LIBS) \ + libvirt_util.la \ $(NULL) libvirt_driver_qemu_impl_la_SOURCES = $(QEMU_DRIVER_SOURCES) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 8062510..b14ce83 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7333,14 +7333,12 @@ qemuBuildCommandLine(virConnectPtr conn, def->mem.max_balloon = VIR_DIV_UP(def->mem.max_balloon, 1024) * 1024; virCommandAddArgFormat(cmd, "%llu", def->mem.max_balloon / 1024); if (def->mem.hugepage_backed) { -if (!cfg->hugetlbfsMount) { +char *mem_path; + +if (!cfg->nhugetlbfs) { virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("hugetlbfs filesystem is not mounted")); -goto error; -} -if (!cfg->hugepagePath) { -virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("hugepages are disabled by administrator config")); + "%s", _("hugetlbfs filesystem is not mounted " + "or disabled by administrator config")); goto error; } if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_PATH)) { @@ -7349,8 +7347,14 @@ qemuBuildCommandLine(virConnectPtr conn, def->emulator); goto error; } + +if (!(mem_path = qemuGetDefaultHugepath(cfg->hugetlbfs, +cfg->nhugetlbfs))) +goto error; + virCommandAddArgList(cmd, "-mem-prealloc", "-mem-path", - cfg->hugepagePath, NULL); + mem_path, NULL); +VIR_FREE(mem_path); } if (def->mem.locked && !virQEMUCapsGet(qemuCaps, QEMU_CAPS_MLOCK)) { diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index e62bec0..cf5ce97 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -230,19 +230,13 @@ virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged) cfg->migrationPortMin = QEMU_MIGRATION_PORT_MIN; cfg->migrationPortMax = QEMU_MIGRATION_PORT_MAX; -#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R -/* For privileged driver, try and find hugepage mount automatically. +/* For privileged driver, try and find hugetlbfs mounts automatically. * Non-privileged driver requires admin to create a dir for the - * user, chown it, and then let user configure it manually */ + * user, chown it, and then let user configure it manually. */ if (privileged && -!(cfg->hugetlbfsMount = virFileFindMountPoint("hugetlbfs"))) { -if (errno != ENOENT) { -virReportSystemError(errno, "%s", - _("unable to find hugetlbfs mountpoint")); -goto error; -} -} -#endif +virFileFindHugeTLBFS(&cfg->hugetlbfs, &cfg->nhugetlbfs) < 0) +goto error; + if (VIR_STRDUP(cfg->bridgeHelperName, "/usr/libexec/qemu-bridge-helper") < 0) goto error; @@ -293,8 +287,11 @@ static void virQEMUDriverConfigDispose(void *obj) VIR_FREE(cfg->spicePassword); VIR_FREE(cfg->spiceSASLdir); -VIR_FREE(cfg->hugetlbfsMount); -VIR_FREE(cfg->hugepagePath); +while (cfg->nhugetlbfs) { +cfg->nhugetlbfs--; +VIR_FREE(cfg->hugetlbfs[cfg->nhugetlbfs].mnt_dir); +} +VIR_FREE(cfg->hugetlbfs); VIR_FREE(cfg->bridgeHelperName); VIR_FREE(cfg->saveImageFor
[libvirt] [PATCH v1 6/7] qemu: Implement ./hugepages/page/[@size, @unit, @nodeset]
Signed-off-by: Michal Privoznik --- src/qemu/qemu_capabilities.c | 2 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c| 91 +++--- .../qemuxml2argv-hugepages-pages.args | 16 tests/qemuxml2argvdata/qemuxml2argv-hugepages.args | 2 +- tests/qemuxml2argvtest.c | 10 ++- 6 files changed, 109 insertions(+), 13 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages.args diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 07306e5..f69c4d0 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -263,6 +263,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "memory-backend-ram", /* 170 */ "numa", + "memory-backend-file", ); @@ -1481,6 +1482,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "pvpanic", QEMU_CAPS_DEVICE_PANIC }, { "usb-kbd", QEMU_CAPS_DEVICE_USB_KBD }, { "memory-backend-ram", QEMU_CAPS_OBJECT_MEMORY_RAM }, +{ "memory-backend-file", QEMU_CAPS_OBJECT_MEMORY_FILE }, }; static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 4332633..e80a377 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -211,6 +211,7 @@ typedef enum { QEMU_CAPS_CHANGE_BACKING_FILE = 169, /* change name of backing file in metadata */ QEMU_CAPS_OBJECT_MEMORY_RAM = 170, /* -object memory-backend-ram */ QEMU_CAPS_NUMA = 171, /* newer -numa handling with disjoint cpu ranges */ +QEMU_CAPS_OBJECT_MEMORY_FILE = 172, /* -object memory-backend-file */ QEMU_CAPS_LAST, /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 0b8cef5..cb35727 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6381,24 +6381,36 @@ qemuBuildSmpArgStr(const virDomainDef *def, } static int -qemuBuildNumaArgStr(const virDomainDef *def, +qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, +const virDomainDef *def, virCommandPtr cmd, virQEMUCapsPtr qemuCaps) { -size_t i; +size_t i, j; virBuffer buf = VIR_BUFFER_INITIALIZER; +virDomainHugePagePtr master_hugepage = NULL; char *cpumask = NULL, *tmpmask = NULL, *next = NULL; char *nodemask = NULL; +char *mem_path = NULL; int ret = -1; if (virDomainNumatuneHasPerNodeBinding(def->numatune) && -!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM)) { +!(virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) || + virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE))) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Per-node memory binding is not supported " "with this QEMU")); goto cleanup; } +if (def->mem.nhugepages && def->mem.hugepages[0].size && +!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("huge pages pre NUMA node are not " + "supported with this QEMU")); +goto cleanup; +} + for (i = 0; i < def->cpu->ncells; i++) { int cellmem = VIR_DIV_UP(def->cpu->cells[i].mem, 1024); def->cpu->cells[i].mem = cellmem * 1024; @@ -6417,15 +6429,74 @@ qemuBuildNumaArgStr(const virDomainDef *def, goto cleanup; } -if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM)) { +if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) || +virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) { virDomainNumatuneMemMode mode; +virDomainHugePagePtr hugepage = NULL; const char *policy = NULL; mode = virDomainNumatuneGetMode(def->numatune, i); policy = qemuNumaPolicyTypeToString(mode); -virBufferAsprintf(&buf, "memory-backend-ram,size=%dM,id=ram-node%zu", - cellmem, i); +/* Find the huge page size we want to use */ +for (j = 0; j < def->mem.nhugepages; j++) { +bool thisHugepage = false; + +hugepage = &def->mem.hugepages[j]; + +if (!hugepage->nodemask) { +master_hugepage = hugepage; +continue; +} + +if (virBitmapGetBit(hugepage->nodemask, i, &this
[libvirt] [PATCH v2] examples: Introduce domtop
There's this question on the list that is asked over and over again. How do I get {cpu, memory, ...} usage in percentage? Or its modified version: How do I plot nice graphs like virt-manager does? It would be nice if we have an example to inspire people. And that's what domtop should do. Yes, it could be written in different ways, but I've chosen this one as I think it show explicitly what users need to implement in order to imitate virt-manager's graphing. Note: The usage is displayed from host perspective. That is, how much host CPUs the domain is using. But it should be fairly simple to switch do just guest CPU usage if needed. Signed-off-by: Michal Privoznik --- .gitignore | 1 + Makefile.am | 2 +- cfg.mk | 2 +- configure.ac| 1 + examples/domtop/Makefile.am | 27 +++ examples/domtop/domtop.c| 400 libvirt.spec.in | 2 +- 7 files changed, 432 insertions(+), 3 deletions(-) create mode 100644 examples/domtop/Makefile.am create mode 100644 examples/domtop/domtop.c diff --git a/.gitignore b/.gitignore index 2d4d401..90fee91 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,7 @@ /examples/dominfo/info1 /examples/domsuspend/suspend /examples/dommigrate/dommigrate +/examples/domtop/domtop /examples/hellolibvirt/hellolibvirt /examples/openauth/openauth /gnulib/lib/* diff --git a/Makefile.am b/Makefile.am index a374e1a..4aafe94 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,7 +24,7 @@ SUBDIRS = . gnulib/lib include src daemon tools docs gnulib/tests \ examples/dominfo examples/domsuspend examples/apparmor \ examples/xml/nwfilter examples/openauth examples/systemtap \ tools/wireshark examples/dommigrate \ - examples/lxcconvert + examples/lxcconvert examples/domtop ACLOCAL_AMFLAGS = -I m4 diff --git a/cfg.mk b/cfg.mk index c3d89a0..0559edd 100644 --- a/cfg.mk +++ b/cfg.mk @@ -1078,7 +1078,7 @@ exclude_file_name_regexp--sc_prohibit_sprintf = \ exclude_file_name_regexp--sc_prohibit_strncpy = ^src/util/virstring\.c$$ exclude_file_name_regexp--sc_prohibit_strtol = \ - ^(src/util/.*|examples/domsuspend/suspend)\.c$$ + ^(src/util/.*|examples/dom.*/.*)\.c$$ exclude_file_name_regexp--sc_prohibit_xmlGetProp = ^src/util/virxml\.c$$ diff --git a/configure.ac b/configure.ac index 8001e24..f37c716 100644 --- a/configure.ac +++ b/configure.ac @@ -2755,6 +2755,7 @@ AC_CONFIG_FILES([\ examples/domsuspend/Makefile \ examples/dominfo/Makefile \ examples/dommigrate/Makefile \ +examples/domtop/Makefile \ examples/openauth/Makefile \ examples/hellolibvirt/Makefile \ examples/systemtap/Makefile \ diff --git a/examples/domtop/Makefile.am b/examples/domtop/Makefile.am new file mode 100644 index 000..c5cb6c7 --- /dev/null +++ b/examples/domtop/Makefile.am @@ -0,0 +1,27 @@ +## Process this file with automake to produce Makefile.in + +## Copyright (C) 2014 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 +LDADDS = $(STATIC_BINARIES) $(WARN_CFLAGS) $(top_builddir)/src/libvirt.la \ + $(COVERAGE_LDFLAGS) + +noinst_PROGRAMS=domtop + +domtop_SOURCES=domtop.c +domtop_LDFLAGS= +domtop_LDADD= $(LDADDS) diff --git a/examples/domtop/domtop.c b/examples/domtop/domtop.c new file mode 100644 index 000..6fb6cbe --- /dev/null +++ b/examples/domtop/domtop.c @@ -0,0 +1,400 @@ +/* + * domtop.c: Demo program showing how to calculate CPU usage + * + * Copyright (C) 2014 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/licen
Re: [libvirt] [PATCH] qemuConnectGetDomainCapabilities: Use wiser defaults
On 17.07.2014 11:28, Daniel P. Berrange wrote: > On Thu, Jul 17, 2014 at 11:12:05AM +0200, Michal Privoznik wrote: >> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c >> index 33541d3..7d99435 100644 >> --- a/src/qemu/qemu_driver.c >> +++ b/src/qemu/qemu_driver.c >> @@ -16849,17 +16849,17 @@ qemuConnectGetDomainCapabilities(virConnectPtr >> conn, >> char *ret = NULL; >> virQEMUDriverPtr driver = conn->privateData; >> virQEMUCapsPtr qemuCaps = NULL; >> -int virttype; /* virDomainVirtType */ >> +int virttype = VIR_DOMAIN_VIRT_KVM; /* virDomainVirtType */ > > Isn't this going to always fail when we run inside a guest which does not > have nested virt? When we know the QEMU binary, we probe to see whether > it can do KVM or not, so could we postpone this decision about virt type > until after we've checked if KVM was available ? I don't think we can. I mean, in order to construct virDomainCaps object we need to know the virttype. The KVM is checked later in the process when the object exits already. What we can do, however, is check for KVM twice. How about this squashed in? diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 7d99435..33d6e47 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -16849,7 +16849,7 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn, char *ret = NULL; virQEMUDriverPtr driver = conn->privateData; virQEMUCapsPtr qemuCaps = NULL; -int virttype = VIR_DOMAIN_VIRT_KVM; /* virDomainVirtType */ +int virttype; /* virDomainVirtType */ virDomainCapsPtr domCaps = NULL; int arch = virArchFromHost(); /* virArch */ @@ -16858,6 +16858,11 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn, if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0) return ret; +if (qemuHostdevHostSupportsPassthroughLegacy()) +virttype = VIR_DOMAIN_VIRT_KVM; +else +virttype = VIR_DOMAIN_VIRT_QEMU; + if (virttype_str && (virttype = virDomainVirtTypeFromString(virttype_str)) < 0) { virReportError(VIR_ERR_INVALID_ARG, Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] OVMF exposure in libvirt
On 14.07.2014 16:12, Paolo Bonzini wrote: Il 14/07/2014 11:27, Daniel P. Berrange ha scritto: -drive file=img_1,if=pflash,format=raw,readonly \ -drive file=img_2,if=pflash,format=raw It's safer to add ",unit=0" and ",unit=1" too. We already use for specifying alternative BIOS blobs for the QEMU -bios arg. Since you say this obsoletes the -bios arg, I think it makes sense to use for the read-only firmware image. It obsoletes the -bios argument, but it is not the same thing: 1) on some machines you can use "-drive if=pflash" for the nvram, but not for the firmware And how should the FW cmd line look like then? 2) on some older versions of QEMU, "-drive if=pflash" will work only on TCG or will not work at all so you cannot blindly replace it. Whoa. How to detect this? I mean, how do detect both? What about: ... ... where the mapping from to -drive if=flash is partly machine-dependent. On x86, for example, adds the ",unit=1" sub-option and fails if the element is absent; it also fails if has type='rom'. Makes sense. For the variable storage, I'd probably suggest as the element name, since IIUC that's a fairly commonly used term for this concept. I like this. Additionally it would be great if we'd be able to generate an empty nvram for a guest if the user doesn't specify it. I'm not big fan of this. Pre-creating storage is something that should be done by mgmt applications (migration with non-shared storage is something different). Laszlo has OVMF patches to "auto-format" an all-zero nvram file. Great. Do they work automagically or does libvirt need to enable the formatting somehow (e.g. monitor command, cmd line argument, ...)? Paolo -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [REPOST 4/8] scsi_backend: Use existing LINUX_SYSFS_SCSI_HOST_PREFIX definition
On 08.07.2014 13:54, John Ferlan wrote: Rather than supplying the path again in the formatting of the sysfs scsi_host directory. Signed-off-by: John Ferlan --- src/storage/storage_backend_scsi.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index b5dbe51..e42778f 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -475,7 +475,8 @@ virStorageBackendSCSITriggerRescan(uint32_t host) VIR_DEBUG("Triggering rescan of host %d", host); -if (virAsprintf(&path, "/sys/class/scsi_host/host%u/scan", host) < 0) { +if (virAsprintf(&path, "%s/host%u/scan", +LINUX_SYSFS_SCSI_HOST_PREFIX, host) < 0) { retval = -1; goto out; } @@ -663,7 +664,8 @@ virStorageBackendSCSICheckPool(virConnectPtr conn ATTRIBUTE_UNUSED, if (getHostNumber(name, &host) < 0) goto cleanup; -if (virAsprintf(&path, "/sys/class/scsi_host/host%d", host) < 0) +if (virAsprintf(&path, "%s/host%d", +LINUX_SYSFS_SCSI_HOST_PREFIX, host) < 0) goto cleanup; *isActive = virFileExists(path); Huh, it's been defined, but not used anywhere till now. :) Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [REPOST 0/8] storage_scsi: Stable SCSI host addressing
On 08.07.2014 13:54, John Ferlan wrote: Reposting of a series from last month changing only the span version in the docs from 1.2.6 to 1.2.7. Previous posting here: http://www.redhat.com/archives/libvir-list/2014-June/msg00448.html The concept still remains the same - rather than rely on the hostNN numbers for the scsi_host to remain stable and unique across host reboots and/or kernel rebuilds, allow use a combination of the scsi_host's PCI address and the value from the hostNN's 'unique_id' file. John Ferlan (6): getAdapterName: check for SCSI_HOST scsi_backend: Use existing LINUX_SYSFS_SCSI_HOST_PREFIX definition virutil: Introduce virReadSCSIUniqueId Add unique_id to nodedev output scsi_host: Introduce virFindSCSIHostByPCI getAdapterName: Lookup stable scsi_host Osier Yang (2): virStoragePoolSourceAdapter: Refine the SCSI_HOST adapter name storage: Introduce parentaddr into virStoragePoolSourceAdapter docs/formatnode.html.in| 11 + docs/formatstorage.html.in | 143 -- docs/schemas/basictypes.rng| 24 +- docs/schemas/nodedev.rng | 6 + src/conf/node_device_conf.c| 23 +- src/conf/node_device_conf.h| 1 + src/conf/storage_conf.c| 111 +++- src/conf/storage_conf.h| 8 +- src/libvirt_private.syms | 2 + src/node_device/node_device_linux_sysfs.c | 6 + src/phyp/phyp_driver.c | 8 +- src/storage/storage_backend_scsi.c | 53 +++- src/test/test_driver.c | 5 +- src/util/virutil.c | 154 +++ src/util/virutil.h | 8 + tests/Makefile.am | 7 + .../pci_8086_27c5_scsi_host_0_unique_id.xml| 8 + tests/nodedevxml2xmltest.c | 1 + tests/scsihosttest.c | 308 + .../pool-scsi-type-scsi-host-stable.xml| 19 ++ .../pool-scsi-type-scsi-host-stable.xml| 22 ++ tests/storagepoolxml2xmltest.c | 1 + 22 files changed, 868 insertions(+), 61 deletions(-) create mode 100644 tests/nodedevschemadata/pci_8086_27c5_scsi_host_0_unique_id.xml create mode 100644 tests/scsihosttest.c create mode 100644 tests/storagepoolxml2xmlin/pool-scsi-type-scsi-host-stable.xml create mode 100644 tests/storagepoolxml2xmlout/pool-scsi-type-scsi-host-stable.xml ACK series, but please see my inline comments. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [REPOST 5/8] virutil: Introduce virReadSCSIUniqueId
On 08.07.2014 13:54, John Ferlan wrote: Introduce a new function to read the current scsi_host entry and return the value found in the 'unique_id' file. Add a 'scsihosttest' test (similar to the fchosttest, but incorporating some of the concepts of the mocked pci test library) in order to read the unique_id file like would be found in the /sys/class/scsi_host tree. Signed-off-by: John Ferlan --- src/libvirt_private.syms | 1 + src/util/virutil.c | 53 ++ src/util/virutil.h | 4 + tests/Makefile.am| 7 ++ tests/scsihosttest.c | 254 +++ 5 files changed, 319 insertions(+) create mode 100644 tests/scsihosttest.c diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6d7bf41..bf365ac 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2119,6 +2119,7 @@ virParseOwnershipIds; virParseVersionString; virPipeReadUntilEOF; virReadFCHost; +virReadSCSIUniqueId; virScaleInteger; virSetBlocking; virSetCloseExec; diff --git a/src/util/virutil.c b/src/util/virutil.c index 95d1ff9..c73ce06 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -1681,6 +1681,50 @@ virGetDeviceUnprivSGIO(const char *path, # define SYSFS_FC_HOST_PATH "/sys/class/fc_host/" # define SYSFS_SCSI_HOST_PATH "/sys/class/scsi_host/" +/* virReadSCSIUniqueId: + * @sysfs_prefix: "scsi_host" sysfs path, defaults to SYSFS_SCSI_HOST_PATH + * @host: Host number, E.g. 5 of "scsi_host/host5" + * @result: Return the entry value as an unsigned int + * + * Read the value of the "scsi_host" unique_id file. + * + * Returns 0 on success, and @result is filled with the unique_id value + * Otherwise returns -1 + */ +int +virReadSCSIUniqueId(const char *sysfs_prefix, +int host, +int *result) +{ +char *sysfs_path = NULL; +char *p = NULL; +int ret = -1; +char *buf = NULL; +int unique_id; + +if (virAsprintf(&sysfs_path, "%s/host%d/unique_id", +sysfs_prefix ? sysfs_prefix : SYSFS_SCSI_HOST_PATH, +host) < 0) +goto cleanup; This prints a message on error. + +if (virFileReadAll(sysfs_path, 1024, &buf) < 0) +goto cleanup; And so does this. + +if ((p = strchr(buf, '\n'))) +*p = '\0'; + +if (virStrToLong_i(buf, NULL, 10, &unique_id) < 0) +goto cleanup; This, however does not. If the unique_id file didn't contain a number, the caller gets -1 returned but have no clue why. I think: virReportError(VIR_ERR_INTERNAL_ERROR, _(unable to parse unique_id: %s"), buf); will do. (yes, we are misusing the VIR_ERR_INTERNAL_ERROR code soo much). + +*result = unique_id; +ret = 0; + + cleanup: +VIR_FREE(sysfs_path); +VIR_FREE(buf); +return ret; +} + /* virReadFCHost: * @sysfs_prefix: "fc_host" sysfs path, defaults to SYSFS_FC_HOST_PATH * @host: Host number, E.g. 5 of "fc_host/host5" @@ -2034,6 +2078,15 @@ virFindFCHostCapableVport(const char *sysfs_prefix) } #else int +virReadSCSIUniqueId(const char *sysfs_prefix ATTRIBUTE_UNUSED, +int host ATTRIBUTE_UNUSED, +unsigned int *result ATTRIBUTE_UNUSED) +{ +virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); +return -1; +} + +int virReadFCHost(const char *sysfs_prefix ATTRIBUTE_UNUSED, int host ATTRIBUTE_UNUSED, const char *entry ATTRIBUTE_UNUSED, diff --git a/src/util/virutil.h b/src/util/virutil.h index 2bb74e2..1407dfd 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -164,6 +164,10 @@ int virGetDeviceUnprivSGIO(const char *path, int *unpriv_sgio); char *virGetUnprivSGIOSysfsPath(const char *path, const char *sysfs_dir); +int virReadSCSIUniqueId(const char *sysfs_prefix, +int host, +int *result) +ATTRIBUTE_NONNULL(3); int virReadFCHost(const char *sysfs_prefix, int host, const char *entry, diff --git a/tests/Makefile.am b/tests/Makefile.am index bc1040a..ecb2f34 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -83,6 +83,7 @@ EXTRA_DIST = \ domainsnapshotxml2xmlin \ domainsnapshotxml2xmlout \ fchostdata \ + scsihostdata \ interfaceschemadata \ lxcconf2xmldata \ lxcxml2xmldata \ @@ -188,6 +189,7 @@ endif WITH_REMOTE if WITH_LINUX test_programs += fchosttest +test_programs += scsihosttest endif WITH_LINUX if WITH_LIBVIRTD @@ -1146,8 +1148,13 @@ fchosttest_SOURCES = \ fchosttest.c testutils.h testutils.c fchosttest_LDADD = $(LDADDS) +scsihosttest_SOURCES = \ + scsihosttest.c testutils.h testutils.c +scsihosttest_LDADD = $(LDADDS) + else ! WITH_LINUX EXTRA_DIST += fchosttest.c +EXTRA_DIST += scsihosttest.c endif ! WIT
Re: [libvirt] [REPOST 1/8] getAdapterName: check for SCSI_HOST
On 08.07.2014 13:54, John Ferlan wrote: Rather than assume that NOT FC_HOST is SCSI_HOST, let's call them out specifically. Makes it easier to find SCSI_HOST code/structs and ensures something isn't missed in the future Signed-off-by: John Ferlan --- src/storage/storage_backend_scsi.c | 21 ++--- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index f6f3ca2..21c13e5 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -547,18 +547,17 @@ getAdapterName(virStoragePoolSourceAdapter adapter) { char *name = NULL; -if (adapter.type != VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { +if (adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { ignore_value(VIR_STRDUP(name, adapter.data.name)); -return name; -} - -if (!(name = virGetFCHostNameByWWN(NULL, - adapter.data.fchost.wwnn, - adapter.data.fchost.wwpn))) { -virReportError(VIR_ERR_XML_ERROR, - _("Failed to find SCSI host with wwnn='%s', " - "wwpn='%s'"), adapter.data.fchost.wwnn, - adapter.data.fchost.wwpn); +} else if (adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { +if (!(name = virGetFCHostNameByWWN(NULL, + adapter.data.fchost.wwnn, + adapter.data.fchost.wwpn))) { +virReportError(VIR_ERR_XML_ERROR, + _("Failed to find SCSI host with wwnn='%s', " + "wwpn='%s'"), adapter.data.fchost.wwnn, + adapter.data.fchost.wwpn); +} } return name; Or even better use switch((virStoragePoolSourceAdapterType) adapter.type) {}. But I can live with this version too. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2] examples: Introduce domtop
On 18.07.2014 15:48, Eric Blake wrote: On 07/18/2014 03:08 AM, Michal Privoznik wrote: There's this question on the list that is asked over and over again. How do I get {cpu, memory, ...} usage in percentage? Or its modified version: How do I plot nice graphs like virt-manager does? It would be nice if we have an example to inspire people. And that's what domtop should do. Yes, it could be written in different ways, but I've chosen this one as I think it show explicitly what users need to implement in order to imitate virt-manager's graphing. Note: The usage is displayed from host perspective. That is, how much host CPUs the domain is using. But it should be fairly simple to switch do just guest CPU usage if needed. Signed-off-by: Michal Privoznik --- ACK with nits fixed. Fixed and pushed. Thanks! Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] domtop: Fix build on mingw
Firstly, there's no sigaction() nor struct sigaction on mingw. We have to use the one implemented by gnulib (and hence link with gnulib). Then, for some reason one header file from windows defines ERROR symbol. Yes it does. Sigh. Signed-off-by: Michal Privoznik --- examples/domtop/Makefile.am | 6 -- examples/domtop/domtop.c| 17 + 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/examples/domtop/Makefile.am b/examples/domtop/Makefile.am index c5cb6c7..dbebb46 100644 --- a/examples/domtop/Makefile.am +++ b/examples/domtop/Makefile.am @@ -16,9 +16,11 @@ ## License along with this library. If not, see ## <http://www.gnu.org/licenses/>. -INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include +INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ + -I$(top_builddir)/gnulib/lib -I$(top_srcdir)/gnulib/lib \ + -I$(top_srcdir) LDADDS = $(STATIC_BINARIES) $(WARN_CFLAGS) $(top_builddir)/src/libvirt.la \ - $(COVERAGE_LDFLAGS) + $(top_builddir)/gnulib/lib/libgnu.la $(COVERAGE_LDFLAGS) noinst_PROGRAMS=domtop diff --git a/examples/domtop/domtop.c b/examples/domtop/domtop.c index 4ac7889..af5da46 100644 --- a/examples/domtop/domtop.c +++ b/examples/domtop/domtop.c @@ -20,6 +20,8 @@ * Author: Michal Privoznik */ +#include + #include #include #include @@ -35,6 +37,21 @@ static bool debug; static bool run_top; +/* On mingw, there's a header file that poisons the well: + * + * + * CC domtop.o + *domtop.c:40:0: warning: "ERROR" redefined [enabled by default] + * #define ERROR(...) \ + * ^ + *In file included from /usr/i686-w64-mingw32/sys-root/mingw/include/windows.h:71:0, + * from /usr/i686-w64-mingw32/sys-root/mingw/include/winsock2.h:23, + * from ../../gnulib/lib/unistd.h:48, + * from domtop.c:35: + * /usr/i686-w64-mingw32/sys-root/mingw/include/wingdi.h:75:0: note: this is the location of the previous definition + * #define ERROR 0 + */ +#undef ERROR #define ERROR(...) \ do {\ fprintf(stderr, "ERROR %s:%d : ", __FUNCTION__, __LINE__); \ -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] tests: Remove stale scsihostdata dir
In the fbd91d49 commit, new scsihostdata dir is added to EXTRA_DIST in the tests/Makefile.am. However, the directory itself is not created anywhere, nor in the commit. Signed-off-by: Michal Privoznik --- Notes: Pushed under build-breaker rule. tests/Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index ecb2f34..3e71069 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -83,7 +83,6 @@ EXTRA_DIST = \ domainsnapshotxml2xmlin \ domainsnapshotxml2xmlout \ fchostdata \ - scsihostdata \ interfaceschemadata \ lxcconf2xmldata \ lxcxml2xmldata \ -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v1 5/7] domain: Introduce ./hugepages/page/[@size, @unit, @nodeset]
On 21.07.2014 17:09, Daniel P. Berrange wrote: On Thu, Jul 17, 2014 at 06:12:46PM +0200, Michal Privoznik wrote: + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 4194304 + 4194304 + + + + + + + 4 + + + + + +hvm + + + + + + + + + + There's nothing functionally wrong with what you have here, but I'm wondering if you considered just adding a page size attribute against the element under here ? Feels like that might be a bit less verbose for the XML Huh funny. That idea came up to my mind, but I thought it was more verbose so I went down this road. I'm not fundamentally against it, but I like my approach more. In most common case, users will use only one size of huge pages to back their guests, so all they need to do is: instead of repeating @pagesize attribute in each . But as far as I see it's just question of preference without any technical impact, right? Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 0/6] Hugepages wrt NUMA
Another attempt. I've dropped the 1/7 from v1, and changed a few bits raised during review. Although, I'm still using: as I don't feel there's any disagreement. But if there is I can rework the patches. Michal Privoznik (6): Introduce virFileFindHugeTLBFS qemu: Utilize virFileFindHugeTLBFS virbitmap: Introduce virBitmapOverlaps domain: Introduce ./hugepages/page/[@size,@unit,@nodeset] qemu: Implement ./hugepages/page/[@size,@unit,@nodeset] tests: Some testing of hugepages mapping docs/formatdomain.html.in | 18 +- docs/schemas/domaincommon.rng | 19 +- src/Makefile.am| 12 +- src/conf/domain_conf.c | 197 +++-- src/conf/domain_conf.h | 13 +- src/libvirt_private.syms | 3 + src/parallels/parallels_driver.c | 2 +- src/qemu/qemu.conf | 9 +- src/qemu/qemu_capabilities.c | 2 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c| 111 ++-- src/qemu/qemu_conf.c | 124 +++-- src/qemu/qemu_conf.h | 9 +- src/qemu/qemu_driver.c | 39 ++-- src/qemu/qemu_process.c| 21 ++- src/util/virbitmap.c | 20 +++ src/util/virbitmap.h | 3 + src/util/virfile.c | 151 +++- src/util/virfile.h | 12 ++ .../qemuxml2argv-hugepages-pages.args | 16 ++ .../qemuxml2argv-hugepages-pages.xml | 45 + .../qemuxml2argv-hugepages-pages2.args | 10 ++ .../qemuxml2argv-hugepages-pages2.xml | 38 .../qemuxml2argv-hugepages-pages3.args | 9 + .../qemuxml2argv-hugepages-pages3.xml | 38 tests/qemuxml2argvdata/qemuxml2argv-hugepages.args | 2 +- tests/qemuxml2argvtest.c | 18 +- tests/qemuxml2xmltest.c| 3 + tests/virbitmaptest.c | 26 +++ 29 files changed, 878 insertions(+), 93 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.xml -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 2/6] qemu: Utilize virFileFindHugeTLBFS
Use better detection of hugetlbfs mount points. Yes, there can be multiple mount points each serving different huge page size. Since we already have ability to override the mount point in the qemu.conf file, this crazy backward compatibility code is brought in. Now we allow multiple mount points, so the "hugetlbfs_mount" option must take an list of strings (mount points). But previously, it was just a string, so we must accept both types now. Signed-off-by: Michal Privoznik --- Notes: Yes, the libvirtd_qemu.aug change is missing here. The reason is prosaic: I don't know how to make augeas accept both array of string and a single string for a configuration variable. BTW: the security_drivers which does exactly what I'm doing here, accepts only single string in the aug file too. src/Makefile.am | 12 ++--- src/qemu/qemu.conf | 9 +++- src/qemu/qemu_command.c | 20 +--- src/qemu/qemu_conf.c | 124 ++- src/qemu/qemu_conf.h | 9 +++- src/qemu/qemu_driver.c | 39 +++ src/qemu/qemu_process.c | 21 +--- tests/qemuxml2argvtest.c | 10 ++-- 8 files changed, 183 insertions(+), 61 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 982f63d..2444d51 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1209,10 +1209,10 @@ libvirt_driver_qemu_impl_la_CFLAGS = \ $(AM_CFLAGS) libvirt_driver_qemu_impl_la_LDFLAGS = $(AM_LDFLAGS) libvirt_driver_qemu_impl_la_LIBADD = $(CAPNG_LIBS) \ -$(GNUTLS_LIBS) \ - $(LIBNL_LIBS) \ - $(LIBXML_LIBS) \ - $(NULL) +$(GNUTLS_LIBS) \ +$(LIBNL_LIBS) \ +$(LIBXML_LIBS) \ +libvirt_util.la libvirt_driver_qemu_impl_la_SOURCES = $(QEMU_DRIVER_SOURCES) conf_DATA += qemu/qemu.conf @@ -1995,8 +1995,8 @@ endif WITH_DRIVER_MODULES BUILT_SOURCES += libvirt_probes.h libvirt_probes.stp libvirt_functions.stp if WITH_QEMU -libvirt_driver_qemu_la_LIBADD += libvirt_qemu_probes.lo -nodist_libvirt_driver_qemu_la_SOURCES = libvirt_qemu_probes.h +libvirt_driver_qemu_impl_la_LIBADD += libvirt_qemu_probes.lo libvirt_probes.lo +libvirt_driver_qemu_impl_la_SOURCES += libvirt_qemu_probes.h BUILT_SOURCES += libvirt_qemu_probes.h endif WITH_QEMU diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 18ce2a8..a079b93 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -330,7 +330,14 @@ # unspecified here, determination of a host mount point in /proc/mounts # will be attempted. Specifying an explicit mount overrides detection # of the same in /proc/mounts. Setting the mount point to "" will -# disable guest hugepage backing. +# disable guest hugepage backing. If desired, multiple mount points can +# be specified at once, separated by comma and enclosed in square +# brackets, for example: +# +# hugetlbfs_mount = ["/dev/hugepages2M", "/dev/hugepages1G"] +# +# The size of huge page served by specific mount point is determined by +# libvirt at the daemon startup. # # NB, within this mount point, guests will create memory backing files # in a location of $MOUNTPOINT/libvirt/qemu diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index fe207a4..091447a 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7333,14 +7333,12 @@ qemuBuildCommandLine(virConnectPtr conn, def->mem.max_balloon = VIR_DIV_UP(def->mem.max_balloon, 1024) * 1024; virCommandAddArgFormat(cmd, "%llu", def->mem.max_balloon / 1024); if (def->mem.hugepage_backed) { -if (!cfg->hugetlbfsMount) { +char *mem_path; + +if (!cfg->nhugetlbfs) { virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("hugetlbfs filesystem is not mounted")); -goto error; -} -if (!cfg->hugepagePath) { -virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("hugepages are disabled by administrator config")); + "%s", _("hugetlbfs filesystem is not mounted " + "or disabled by administrator config")); goto error; } if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_PATH)) { @@ -7349,8 +7347,14 @@ qemuBuildCommandLine(virConnectPtr conn, def->emulator); goto error; } + +if (!(mem_path = qemuGetDefaultHugepath(cfg->hugetlbfs, +cfg->nhugetlbfs))) +goto error; + virCommandAddArgList(cmd, "-mem-prealloc", "-mem-path", - cfg->hugepagePath, NULL); + mem_path
[libvirt] [PATCH v2 6/6] tests: Some testing of hugepages mapping
Signed-off-by: Michal Privoznik --- .../qemuxml2argv-hugepages-pages2.args | 10 ++ .../qemuxml2argv-hugepages-pages2.xml | 38 ++ .../qemuxml2argv-hugepages-pages3.args | 9 + .../qemuxml2argv-hugepages-pages3.xml | 38 ++ tests/qemuxml2argvtest.c | 4 +++ tests/qemuxml2xmltest.c| 2 ++ 6 files changed, 101 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.xml diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.args b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.args new file mode 100644 index 000..9211bc6 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.args @@ -0,0 +1,10 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/qemu -S -M pc -m 1024 -smp 2 \ +-object memory-backend-file,prealloc=yes,\ +mem-path=/dev/hugepages2M/libvirt/qemu,size=256M,id=ram-node0 \ +-numa node,nodeid=0,cpus=0,memdev=ram-node0 \ +-object memory-backend-file,prealloc=yes,\ +mem-path=/dev/hugepages2M/libvirt/qemu,size=768M,id=ram-node1 \ +-numa node,nodeid=1,cpus=1,memdev=ram-node1 \ +-nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ +-usb -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.xml b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.xml new file mode 100644 index 000..3df870b --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages2.xml @@ -0,0 +1,38 @@ + + SomeDummyHugepagesGuest + ef1bdff4-27f3-4e85-a807-5fb4d58463cc + 1048576 + 1048576 + + + + + + 2 + +hvm + + + + + + + + + + destroy + restart + destroy + +/usr/bin/qemu + + + + + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.args b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.args new file mode 100644 index 000..27b3f8e --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.args @@ -0,0 +1,9 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/qemu -S -M pc -m 1024 -smp 2 \ +-object memory-backend-ram,size=256M,id=ram-node0 \ +-numa node,nodeid=0,cpus=0,memdev=ram-node0 \ +-object memory-backend-file,prealloc=yes,\ +mem-path=/dev/hugepages1G/libvirt/qemu,size=768M,id=ram-node1 \ +-numa node,nodeid=1,cpus=1,memdev=ram-node1 \ +-nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \ +-hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.xml b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.xml new file mode 100644 index 000..35aa2cf --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages3.xml @@ -0,0 +1,38 @@ + + SomeDummyHugepagesGuest + ef1bdff4-27f3-4e85-a807-5fb4d58463cc + 1048576 + 1048576 + + + + + + 2 + +hvm + + + + + + + + + + destroy + restart + destroy + +/usr/bin/qemu + + + + + + + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 63c9c4b..b4505a9 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -669,6 +669,10 @@ mymain(void) DO_TEST("hugepages", QEMU_CAPS_MEM_PATH); DO_TEST("hugepages-pages", QEMU_CAPS_MEM_PATH, QEMU_CAPS_OBJECT_MEMORY_RAM, QEMU_CAPS_OBJECT_MEMORY_FILE); +DO_TEST("hugepages-pages2", QEMU_CAPS_MEM_PATH, QEMU_CAPS_OBJECT_MEMORY_RAM, +QEMU_CAPS_OBJECT_MEMORY_FILE); +DO_TEST("hugepages-pages3", QEMU_CAPS_MEM_PATH, QEMU_CAPS_OBJECT_MEMORY_RAM, +QEMU_CAPS_OBJECT_MEMORY_FILE); DO_TEST("nosharepages", QEMU_CAPS_MACHINE_OPT, QEMU_CAPS_MEM_MERGE); DO_TEST("disk-cdrom", NONE); DO_TEST("disk-cdrom-network-http", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE, diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 09cb228..8d46b40 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -198,6 +198,8 @@ mymain(void) DO_TEST("hugepages"); DO_TEST("hugepages-pages"); +DO_TEST("hugepages-pages2"); +DO_TEST("hugepages-pages3"); DO_TEST("nosharepages"); DO_TEST("disk-aio"); DO_TEST("disk-cdrom"); -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 1/6] Introduce virFileFindHugeTLBFS
This should iterate over mount tab and search for hugetlbfs among with looking for the default value of huge pages. Signed-off-by: Michal Privoznik --- src/libvirt_private.syms | 2 + src/util/virfile.c | 151 ++- src/util/virfile.h | 12 3 files changed, 163 insertions(+), 2 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 51504d1..c928564 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1276,9 +1276,11 @@ virFileDirectFdFlag; virFileExists; virFileFclose; virFileFdopen; +virFileFindHugeTLBFS; virFileFindMountPoint; virFileFindResource; virFileFindResourceFull; +virFileGetHugepageSize; virFileGetMountReverseSubtree; virFileGetMountSubtree; virFileHasSuffix; diff --git a/src/util/virfile.c b/src/util/virfile.c index 463064c..f18a0f5 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -2837,6 +2837,9 @@ int virFilePrintf(FILE *fp, const char *msg, ...) # ifndef CIFS_SUPER_MAGIC # define CIFS_SUPER_MAGIC 0xFF534D42 # endif +# ifndef HUGETLBFS_MAGIC +# define HUGETLBFS_MAGIC 0x958458f6 +# endif int virFileIsSharedFSType(const char *path, @@ -2909,14 +2912,158 @@ virFileIsSharedFSType(const char *path, return 0; } -#else + +int +virFileGetHugepageSize(const char *path, + unsigned long long *size) +{ +int ret = -1; +struct statfs fs; + +if (statfs(path, &fs) < 0) { +virReportSystemError(errno, + _("cannot determine filesystem for '%s'"), + path); +goto cleanup; +} + +if (fs.f_type != HUGETLBFS_MAGIC) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("not a hugetlbfs mount: '%s'"), + path); +goto cleanup; +} + +*size = fs.f_bsize / 1024; /* we are storing size in KiB */ +ret = 0; + cleanup: +return ret; +} + +# define PROC_MEMINFO "/proc/meminfo" +# define HUGEPAGESIZE_STR "Hugepagesize:" + +static int +virFileGetDefaultHugepageSize(unsigned long long *size) +{ +int ret = -1; +char *meminfo, *c, *n, *unit; + +if (virFileReadAll(PROC_MEMINFO, 4096, &meminfo) < 0) +goto cleanup; + +if (!(c = strstr(meminfo, HUGEPAGESIZE_STR))) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse %s"), + PROC_MEMINFO); +goto cleanup; +} +c += strlen(HUGEPAGESIZE_STR); + +if ((n = strchr(c, '\n'))) { +/* Cut off the rest of the meminfo file */ +*n = '\0'; +} + +if (virStrToLong_ull(c, &unit, 10, size) < 0 || STRNEQ(unit, " kB")) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse %s %s"), + HUGEPAGESIZE_STR, c); +goto cleanup; +} + +ret = 0; + cleanup: +VIR_FREE(meminfo); +return ret; +} + +# define PROC_MOUNTS "/proc/mounts" + +int +virFileFindHugeTLBFS(virHugeTLBFSPtr *ret_fs, + size_t *ret_nfs) +{ +int ret = -1; +FILE *f = NULL; +struct mntent mb; +char mntbuf[1024]; +virHugeTLBFSPtr fs = NULL; +size_t nfs = 0; +unsigned long long default_hugepagesz; + +if (virFileGetDefaultHugepageSize(&default_hugepagesz) < 0) +goto cleanup; + +if (!(f = setmntent(PROC_MOUNTS, "r"))) { +virReportSystemError(errno, + _("Unable to open %s"), + PROC_MOUNTS); +goto cleanup; +} + +while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) { +virHugeTLBFSPtr tmp; + +if (STRNEQ(mb.mnt_type, "hugetlbfs")) +continue; + +if (VIR_REALLOC_N(fs, nfs + 1) < 0) +goto cleanup; + +tmp = &fs[nfs]; +nfs++; + +if (VIR_STRDUP(tmp->mnt_dir, mb.mnt_dir) < 0) +goto cleanup; + +if (virFileGetHugepageSize(tmp->mnt_dir, &tmp->size) < 0) +goto cleanup; + +tmp->deflt = tmp->size == default_hugepagesz; +} + +*ret_fs = fs; +*ret_nfs = nfs; +fs = NULL; +nfs = 0; +ret = 0; + + cleanup: +endmntent(f); +while (nfs) +VIR_FREE(fs[--nfs].mnt_dir); +VIR_FREE(fs); +return ret; +} + +#else /* defined __linux__ */ + int virFileIsSharedFSType(const char *path ATTRIBUTE_UNUSED, int fstypes ATTRIBUTE_UNUSED) { /* XXX implement me :-) */ return 0; } -#endif + +int +virFileGetHugepageSize(const char *path ATTRIBUTE_UNUSED, + unsigned long long *size ATTRIBUTE_UNUSED) +{ +/* XXX implement me :-) */ +virReportUnsupportedError(); +return -1; +} + +int +virFileFind
[libvirt] [PATCH v2 5/6] qemu: Implement ./hugepages/page/[@size, @unit, @nodeset]
Signed-off-by: Michal Privoznik --- src/qemu/qemu_capabilities.c | 2 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c| 91 +++--- .../qemuxml2argv-hugepages-pages.args | 16 tests/qemuxml2argvdata/qemuxml2argv-hugepages.args | 2 +- tests/qemuxml2argvtest.c | 10 ++- 6 files changed, 109 insertions(+), 13 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages.args diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 07306e5..f69c4d0 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -263,6 +263,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "memory-backend-ram", /* 170 */ "numa", + "memory-backend-file", ); @@ -1481,6 +1482,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { { "pvpanic", QEMU_CAPS_DEVICE_PANIC }, { "usb-kbd", QEMU_CAPS_DEVICE_USB_KBD }, { "memory-backend-ram", QEMU_CAPS_OBJECT_MEMORY_RAM }, +{ "memory-backend-file", QEMU_CAPS_OBJECT_MEMORY_FILE }, }; static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 4332633..e80a377 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -211,6 +211,7 @@ typedef enum { QEMU_CAPS_CHANGE_BACKING_FILE = 169, /* change name of backing file in metadata */ QEMU_CAPS_OBJECT_MEMORY_RAM = 170, /* -object memory-backend-ram */ QEMU_CAPS_NUMA = 171, /* newer -numa handling with disjoint cpu ranges */ +QEMU_CAPS_OBJECT_MEMORY_FILE = 172, /* -object memory-backend-file */ QEMU_CAPS_LAST, /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d5f5f02..81be42a 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6381,24 +6381,36 @@ qemuBuildSmpArgStr(const virDomainDef *def, } static int -qemuBuildNumaArgStr(const virDomainDef *def, +qemuBuildNumaArgStr(virQEMUDriverConfigPtr cfg, +const virDomainDef *def, virCommandPtr cmd, virQEMUCapsPtr qemuCaps) { -size_t i; +size_t i, j; virBuffer buf = VIR_BUFFER_INITIALIZER; +virDomainHugePagePtr master_hugepage = NULL; char *cpumask = NULL, *tmpmask = NULL, *next = NULL; char *nodemask = NULL; +char *mem_path = NULL; int ret = -1; if (virDomainNumatuneHasPerNodeBinding(def->numatune) && -!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM)) { +!(virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) || + virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE))) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Per-node memory binding is not supported " "with this QEMU")); goto cleanup; } +if (def->mem.nhugepages && def->mem.hugepages[0].size && +!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("huge pages pre NUMA node are not " + "supported with this QEMU")); +goto cleanup; +} + for (i = 0; i < def->cpu->ncells; i++) { int cellmem = VIR_DIV_UP(def->cpu->cells[i].mem, 1024); def->cpu->cells[i].mem = cellmem * 1024; @@ -6417,15 +6429,74 @@ qemuBuildNumaArgStr(const virDomainDef *def, goto cleanup; } -if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM)) { +if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM) || +virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_FILE)) { virDomainNumatuneMemMode mode; +virDomainHugePagePtr hugepage = NULL; const char *policy = NULL; mode = virDomainNumatuneGetMode(def->numatune, i); policy = qemuNumaPolicyTypeToString(mode); -virBufferAsprintf(&buf, "memory-backend-ram,size=%dM,id=ram-node%zu", - cellmem, i); +/* Find the huge page size we want to use */ +for (j = 0; j < def->mem.nhugepages; j++) { +bool thisHugepage = false; + +hugepage = &def->mem.hugepages[j]; + +if (!hugepage->nodemask) { +master_hugepage = hugepage; +continue; +} + +if (virBitmapGetBit(hugepage->nodemask, i, &this
[libvirt] [PATCH v2 3/6] virbitmap: Introduce virBitmapOverlaps
This internal API just checks if two bitmaps intersect or not. Signed-off-by: Michal Privoznik --- Notes: This has been ACKed already, but the name of the function was not quite right. But there's no functional change since then. src/libvirt_private.syms | 1 + src/util/virbitmap.c | 20 src/util/virbitmap.h | 3 +++ tests/virbitmaptest.c| 26 ++ 4 files changed, 50 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c928564..8b50417 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1005,6 +1005,7 @@ virBitmapNewCopy; virBitmapNewData; virBitmapNextClearBit; virBitmapNextSetBit; +virBitmapOverlaps; virBitmapParse; virBitmapSetAll; virBitmapSetBit; diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c index 1029635..27282df 100644 --- a/src/util/virbitmap.c +++ b/src/util/virbitmap.c @@ -732,3 +732,23 @@ virBitmapDataToString(void *data, virBitmapFree(map); return ret; } + +bool +virBitmapOverlaps(virBitmapPtr b1, + virBitmapPtr b2) +{ +size_t i; + +if (b1->max_bit > b2->max_bit) { +virBitmapPtr tmp = b1; +b1 = b2; +b2 = tmp; +} + +for (i = 0; i < b1->map_len; i++) { +if (b1->map[i] & b2->map[i]) +return true; +} + +return false; +} diff --git a/src/util/virbitmap.h b/src/util/virbitmap.h index 142a218..4493cc9 100644 --- a/src/util/virbitmap.h +++ b/src/util/virbitmap.h @@ -114,5 +114,8 @@ size_t virBitmapCountBits(virBitmapPtr bitmap) char *virBitmapDataToString(void *data, int len) ATTRIBUTE_NONNULL(1); +bool virBitmapOverlaps(virBitmapPtr b1, + virBitmapPtr b2) +ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); #endif diff --git a/tests/virbitmaptest.c b/tests/virbitmaptest.c index 048946f..ea832ad 100644 --- a/tests/virbitmaptest.c +++ b/tests/virbitmaptest.c @@ -510,6 +510,30 @@ test9(const void *opaque ATTRIBUTE_UNUSED) } static int +test10(const void *opaque ATTRIBUTE_UNUSED) +{ +int ret = -1; +virBitmapPtr b1 = NULL, b2 = NULL, b3 = NULL; + +if (virBitmapParse("0-3,5-8,11-15", 0, &b1, 20) < 0 || +virBitmapParse("4,9,10,16-19", 0, &b2, 20) < 0 || +virBitmapParse("15", 0, &b3, 20) < 0) +goto cleanup; + +if (virBitmapOverlaps(b1, b2) || +virBitmapOverlaps(b2, b3) || +!virBitmapOverlaps(b1, b3)) +goto cleanup; + +ret = 0; + cleanup: +virBitmapFree(b1); +virBitmapFree(b2); +virBitmapFree(b3); +return ret; +} + +static int mymain(void) { int ret = 0; @@ -532,6 +556,8 @@ mymain(void) ret = -1; if (virtTestRun("test9", test9, NULL) < 0) ret = -1; +if (virtTestRun("test10", test10, NULL) < 0) +ret = -1; return ret; } -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 4/6] domain: Introduce ./hugepages/page/[@size, @unit, @nodeset]
Signed-off-by: Michal Privoznik --- docs/formatdomain.html.in | 18 +- docs/schemas/domaincommon.rng | 19 +- src/conf/domain_conf.c | 197 +++-- src/conf/domain_conf.h | 13 +- src/parallels/parallels_driver.c | 2 +- src/qemu/qemu_command.c| 2 +- src/qemu/qemu_process.c| 2 +- .../qemuxml2argv-hugepages-pages.xml | 45 + tests/qemuxml2xmltest.c| 1 + 9 files changed, 277 insertions(+), 22 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hugepages-pages.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 8950959..bce5885 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -617,7 +617,9 @@ <domain> ... <memoryBacking> -<hugepages/> +<hugepages> + <page size="1" unit="G" nodeset="0-3,5"/> + <page size="2" unit="M" nodeset="4"/> <nosharepages/> <locked/> </memoryBacking> @@ -632,7 +634,19 @@ hugepages This tells the hypervisor that the guest should have its memory -allocated using hugepages instead of the normal native page size. + allocated using hugepages instead of the normal native page size. + Since 1.2.5 it's possible to set hugepages + more specifically per numa node. The page element is + introduced. It has one compulsory attribute size which + specifies which hugepages should be used (especially useful on systems + supporting hugepages of different sizes). The default unit for the + size attribute is kilobytes (multiplier of 1024). If you + want to use different unit, use optional unit attribute. + For systems with NUMA, the optional nodeset attribute may + come handy as it ties given guest's NUMA nodes to certain hugepage + sizes. From the example snippet, one gigabyte hugepages are used for + every NUMA node except node number four. For the correct syntax see + this. nosharepages Instructs hypervisor to disable shared pages (memory merge, KSM) for this domain. Since 1.0.6 diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index f6f697c..cf4cda8 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -567,7 +567,24 @@ - + + + + + + + + + + + + + + + + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index d8d1fe7..ff50252 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -11260,6 +11260,57 @@ virDomainParseMemory(const char *xpath, xmlXPathContextPtr ctxt, } +static int +virDomainHugepagesParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt, + virDomainHugePagePtr hugepage) +{ +int ret = -1; +xmlNodePtr oldnode = ctxt->node; +unsigned long long bytes, max; +char *unit = NULL, *nodeset = NULL; + +ctxt->node = node; + +/* On 32-bit machines, our bound is 0x * KiB. On 64-bit + * machines, our bound is off_t (2^63). */ +if (sizeof(unsigned long) < sizeof(long long)) +max = 1024ull * ULONG_MAX; +else +max = LLONG_MAX; + +if (virXPathULongLong("string(./@size)", ctxt, &bytes) < 0) { +virReportError(VIR_ERR_XML_DETAIL, "%s", + _("unable to parse size attribute")); +goto cleanup; +} + +unit = virXPathString("string(./@unit)", ctxt); + +if (virScaleInteger(&bytes, unit, 1024, max) < 0) +goto cleanup; + +if (!(hugepage->size = VIR_DIV_UP(bytes, 1024))) { +virReportError(VIR_ERR_XML_DETAIL, "%s", + _("hugepage size can't be zero")); +goto cleanup; +} + +if ((nodeset = virXMLPropString(node, "nodeset"))) { +if (virBitmapParse(nodeset, 0, &hugepage->nodemask, + VIR_DOMAIN_CPUMASK_LEN) < 0) +goto cleanup; +} + +ret = 0; + cleanup: +VIR_FREE(unit); +VIR_FREE(nodeset); +ctxt->node = oldnode; +return ret; +} + + static virDomainResourceDefPtr
[libvirt] [PATCH v2] qemuConnectGetDomainCapabilities: Use wiser defaults
Up to now, users have to pass two arguments at least: domain virt type ('qemu' vs 'kvm') and one of emulatorbin or architecture. This is not much user friendly. Nowadays users mostly use KVM and share the host architecture with the guest. So now, the API (and subsequently virsh command) can be called with all NULLs (without any arguments). Before this patch: # virsh domcapabilities error: failed to get emulator capabilities error: virttype_str in qemuConnectGetDomainCapabilities must not be NULL # virsh domcapabilities kvm error: failed to get emulator capabilities error: invalid argument: at least one of emulatorbin or architecture fields must be present After: # virsh domcapabilities /usr/bin/qemu-system-x86_64 kvm pc-i440fx-2.1 x86_64 Signed-off-by: Michal Privoznik --- Notes: It would be nice to have this in the same release as the new API it's fixing. So please, review. src/qemu/qemu_driver.c | 27 ++- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b85d909..008f101 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -16893,15 +16893,20 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn, virQEMUCapsPtr qemuCaps = NULL; int virttype; /* virDomainVirtType */ virDomainCapsPtr domCaps = NULL; -int arch = VIR_ARCH_NONE; /* virArch */ +int arch = virArchFromHost(); /* virArch */ virCheckFlags(0, ret); -virCheckNonNullArgReturn(virttype_str, ret); if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0) return ret; -if ((virttype = virDomainVirtTypeFromString(virttype_str)) < 0) { +if (qemuHostdevHostSupportsPassthroughLegacy()) +virttype = VIR_DOMAIN_VIRT_KVM; +else +virttype = VIR_DOMAIN_VIRT_QEMU; + +if (virttype_str && +(virttype = virDomainVirtTypeFromString(virttype_str)) < 0) { virReportError(VIR_ERR_INVALID_ARG, _("unknown virttype: %s"), virttype_str); @@ -16924,9 +16929,6 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn, arch_from_caps = virQEMUCapsGetArch(qemuCaps); -if (arch == VIR_ARCH_NONE) -arch = arch_from_caps; - if (arch_from_caps != arch) { virReportError(VIR_ERR_INVALID_ARG, _("architecture from emulator '%s' doesn't " @@ -16935,21 +16937,12 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn, virArchToString(arch)); goto cleanup; } -} else if (arch_str) { +} else { if (!(qemuCaps = virQEMUCapsCacheLookupByArch(driver->qemuCapsCache, arch))) goto cleanup; -if (!emulatorbin) -emulatorbin = virQEMUCapsGetBinary(qemuCaps); -/* Deliberately not checking if provided @emulatorbin matches @arch, - * since if @emulatorbin was specified the match has been checked a few - * lines above. */ -} else { -virReportError(VIR_ERR_INVALID_ARG, "%s", - _("at least one of emulatorbin or " - "architecture fields must be present")); -goto cleanup; +emulatorbin = virQEMUCapsGetBinary(qemuCaps); } if (machine) { -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 1/6] Introduce virFileFindHugeTLBFS
On 24.07.2014 08:41, Peter Krempa wrote: > On 07/23/14 21:06, Daniel P. Berrange wrote: >> On Wed, Jul 23, 2014 at 05:37:17PM +0200, Michal Privoznik wrote: >>> +int >>> +virFileFindHugeTLBFS(virHugeTLBFSPtr *ret_fs, >>> + size_t *ret_nfs) >>> +{ >>> +int ret = -1; >>> +FILE *f = NULL; >>> +struct mntent mb; >>> +char mntbuf[1024]; >>> +virHugeTLBFSPtr fs = NULL; >>> +size_t nfs = 0; >>> +unsigned long long default_hugepagesz; >>> + >>> +if (virFileGetDefaultHugepageSize(&default_hugepagesz) < 0) >>> +goto cleanup; >>> + >>> +if (!(f = setmntent(PROC_MOUNTS, "r"))) { >>> +virReportSystemError(errno, >>> + _("Unable to open %s"), >>> + PROC_MOUNTS); >>> +goto cleanup; >>> +} >>> + >>> +while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) { >>> +virHugeTLBFSPtr tmp; >>> + >>> +if (STRNEQ(mb.mnt_type, "hugetlbfs")) >>> +continue; >>> + >>> +if (VIR_REALLOC_N(fs, nfs + 1) < 0) >>> +goto cleanup; >>> + >>> +tmp = &fs[nfs]; >>> +nfs++; >> >> Stilll think we should be using VIR_EXPAND_N here to ensure >> new space is fully zerod. > > Or perhaps use VIR_APPEND_ELEMENT? Okay, I'm squashing this in: diff --git a/src/util/virfile.c b/src/util/virfile.c index f18a0f5..8ce20f5 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -3008,11 +3008,10 @@ virFileFindHugeTLBFS(virHugeTLBFSPtr *ret_fs, if (STRNEQ(mb.mnt_type, "hugetlbfs")) continue; -if (VIR_REALLOC_N(fs, nfs + 1) < 0) +if (VIR_EXPAND_N(fs, nfs, 1) < 0) goto cleanup; -tmp = &fs[nfs]; -nfs++; +tmp = &fs[nfs - 1]; if (VIR_STRDUP(tmp->mnt_dir, mb.mnt_dir) < 0) goto cleanup; Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 1/2] LXC: add support for --config in setmaxmem command
On 16.07.2014 11:51, Chen Hanxiao wrote: In lxc, we could not use setmaxmem command with --config options. This patch will add support for this. Signed-off-by: Chen Hanxiao --- src/lxc/lxc_driver.c | 69 ++-- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index b7b4b02..be6ee19 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -721,10 +721,10 @@ static int lxcDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, virLXCDomainObjPrivatePtr priv; virLXCDriverPtr driver = dom->conn->privateData; virLXCDriverConfigPtr cfg = NULL; -unsigned long oldmax = 0; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | - VIR_DOMAIN_AFFECT_CONFIG, -1); + VIR_DOMAIN_AFFECT_CONFIG | + VIR_DOMAIN_MEM_MAXIMUM, -1); if (!(vm = lxcDomObjFromDomain(dom))) goto cleanup; @@ -743,32 +743,55 @@ static int lxcDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, &persistentDef) < 0) goto cleanup; -if (flags & VIR_DOMAIN_AFFECT_LIVE) -oldmax = vm->def->mem.max_balloon; -if (flags & VIR_DOMAIN_AFFECT_CONFIG) { -if (!oldmax || oldmax > persistentDef->mem.max_balloon) -oldmax = persistentDef->mem.max_balloon; -} +if (flags & VIR_DOMAIN_MEM_MAXIMUM) { +if (flags & VIR_DOMAIN_AFFECT_LIVE) { +if (newmem < vm->def->mem.cur_balloon) { +virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("Cannot resize the max memory less than current" + " memory for an active domain")); +goto cleanup; +} +vm->def->mem.max_balloon = newmem; Are things that easy? Don't we need to communicate this with the lxc_controler somehow? Even though you allow only extending, I think unless we are 100% sure guest will see the resize, we shouldn't allow this. +} -if (newmem > oldmax) { -virReportError(VIR_ERR_INVALID_ARG, - "%s", _("Cannot set memory higher than max memory")); -goto cleanup; -} +if (flags & VIR_DOMAIN_AFFECT_CONFIG) { +sa_assert(persistentDef); Is this assert needed? Did clang complain or is this just a pure lefover from copying from qemu_driver.c? +persistentDef->mem.max_balloon = newmem; +if (persistentDef->mem.cur_balloon > newmem) +persistentDef->mem.cur_balloon = newmem; +if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0) +goto cleanup; +} +} else { +unsigned long oldmax = 0; -if (flags & VIR_DOMAIN_AFFECT_LIVE) { -if (virCgroupSetMemory(priv->cgroup, newmem) < 0) { -virReportError(VIR_ERR_OPERATION_FAILED, - "%s", _("Failed to set memory for domain")); -goto cleanup; +if (flags & VIR_DOMAIN_AFFECT_LIVE) +oldmax = vm->def->mem.max_balloon; +if (flags & VIR_DOMAIN_AFFECT_CONFIG) { +if (!oldmax || oldmax > persistentDef->mem.max_balloon) +oldmax = persistentDef->mem.max_balloon; } -} -if (flags & VIR_DOMAIN_AFFECT_CONFIG) { -sa_assert(persistentDef); Well, since it has been here already, I think we can leave it in your patch too. -persistentDef->mem.cur_balloon = newmem; -if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0) +if (newmem > oldmax) { +virReportError(VIR_ERR_INVALID_ARG, + "%s", _("Cannot set memory higher than max memory")); goto cleanup; +} + +if (flags & VIR_DOMAIN_AFFECT_LIVE) { +if (virCgroupSetMemory(priv->cgroup, newmem) < 0) { +virReportError(VIR_ERR_OPERATION_FAILED, + "%s", _("Failed to set memory for domain")); +goto cleanup; +} +} + +if (flags & VIR_DOMAIN_AFFECT_CONFIG) { +sa_assert(persistentDef); +persistentDef->mem.cur_balloon = newmem; +if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0) +goto cleanup; +} } ret = 0; But what I miss in this patch is, what would: virDomainSetMaxMemoryFlags(dom, newmem, VIR_DOMAIN_AFFECT_CURRENT | VIR_DOMAIN_MEM_MAXIMUM) do? I mean, the _CURRENT is not translated to _LIVE or _CONFIG anywhere in the function. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 2/2] LXC: use lxcDomainSetMemoryFlags to do lxcDomainSetMaxMemory's work
On 16.07.2014 11:51, Chen Hanxiao wrote: Signed-off-by: Chen Hanxiao --- src/lxc/lxc_driver.c | 36 +--- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index be6ee19..9f974eb 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -680,37 +680,6 @@ lxcDomainGetMaxMemory(virDomainPtr dom) return ret; } -static int lxcDomainSetMaxMemory(virDomainPtr dom, unsigned long newmax) -{ -virDomainObjPtr vm; -int ret = -1; - -if (!(vm = lxcDomObjFromDomain(dom))) -goto cleanup; - -if (virDomainSetMaxMemoryEnsureACL(dom->conn, vm->def) < 0) -goto cleanup; - -if (newmax < vm->def->mem.cur_balloon) { -if (!virDomainObjIsActive(vm)) { -vm->def->mem.cur_balloon = newmax; -} else { -virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("Cannot set max memory lower than current" - " memory for an active domain")); -goto cleanup; -} -} - -vm->def->mem.max_balloon = newmax; -ret = 0; - - cleanup: -if (vm) -virObjectUnlock(vm); -return ret; -} - A-ha! This is what I was looking for in 1/2. Okay, but I'd rather note this fact in 1/2 commit message to make it more obvious. static int lxcDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, unsigned int flags) { @@ -809,6 +778,11 @@ static int lxcDomainSetMemory(virDomainPtr dom, unsigned long newmem) return lxcDomainSetMemoryFlags(dom, newmem, VIR_DOMAIN_AFFECT_LIVE); } +static int lxcDomainSetMaxMemory(virDomainPtr dom, unsigned long memory) +{ +return lxcDomainSetMemoryFlags(dom, memory, VIR_DOMAIN_MEM_MAXIMUM); +} + So previously, calling virDomainSetMaxMemory() on an inactive LXC domain would succeed. Now, after the change, due to problem with _CURRENT, _LIVE and _CONFIG this will basically return success, but without any effect on the domain config. And that's wrong. static int lxcDomainSetMemoryParameters(virDomainPtr dom, virTypedParameterPtr params, Moreover, I think these two patches can be joined into one. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH V2 2/6] qemu: Introduce vgamem attribute for video model
On 14.07.2014 13:20, Wang Rui wrote: From: Zeng Junliang This patch introduces vgamem attribute for video model, and sets its default value as qemu used. Parse it in two ways accroding to qemu startup parameters supported: -device or -vga. Signed-off-by: Zeng Junliang Signed-off-by: Wang Rui --- src/conf/domain_conf.c | 48 ++- src/conf/domain_conf.h | 3 +- src/libvirt_private.syms | 1 + src/qemu/qemu_command.c | 75 4 files changed, 101 insertions(+), 26 deletions(-) missing docs and RNG schema adjustment. And I'd introduce a new XML to test too. diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 63d97ec..d5a65c3 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -9328,6 +9328,20 @@ virDomainVideoDefaultRAM(const virDomainDef *def, } } +int +virDomainVideoDefaultVgamem(int type) +{ +switch (type) { +case VIR_DOMAIN_VIDEO_TYPE_VGA: +case VIR_DOMAIN_VIDEO_TYPE_VMVGA: +case VIR_DOMAIN_VIDEO_TYPE_QXL: +/* QEMU use 16M as default value for vga/vmvga/qxl device*/ +return 16 * 1024; + +default: +return 0; +} +} int virDomainVideoDefaultType(const virDomainDef *def) @@ -9413,6 +9427,7 @@ virDomainVideoDefParseXML(xmlNodePtr node, char *type = NULL; char *heads = NULL; char *vram = NULL; +char *vgamem = NULL; char *ram = NULL; char *primary = NULL; @@ -9422,11 +9437,12 @@ virDomainVideoDefParseXML(xmlNodePtr node, cur = node->children; while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { -if (!type && !vram && !ram && !heads && +if (!type && !vram && !ram && !heads && !vgamem && xmlStrEqual(cur->name, BAD_CAST "model")) { type = virXMLPropString(cur, "type"); ram = virXMLPropString(cur, "ram"); vram = virXMLPropString(cur, "vram"); +vgamem = virXMLPropString(cur, "vgamem"); heads = virXMLPropString(cur, "heads"); if ((primary = virXMLPropString(cur, "primary")) != NULL) { @@ -9490,6 +9506,24 @@ virDomainVideoDefParseXML(xmlNodePtr node, def->vram = virDomainVideoDefaultRAM(dom, def->type); } +if (vgamem) { +if (def->type != VIR_DOMAIN_VIDEO_TYPE_VGA && +def->type != VIR_DOMAIN_VIDEO_TYPE_VMVGA && +def->type != VIR_DOMAIN_VIDEO_TYPE_QXL) { +virReportError(VIR_ERR_XML_ERROR, "%s", + _("vgamem attribute only supported " + "for type of vga, vmvga and qxl")); +goto error; +} Spaces at EOL +if (virStrToLong_ui(vgamem, NULL, 10, &def->vgamem) < 0) { +virReportError(VIR_ERR_XML_ERROR, + _("cannot parse video vgamem '%s'"), vgamem); +goto error; +} +} else { +def->vgamem = virDomainVideoDefaultVgamem(def->type); +} + And again. But I'm wondering how's vgamem different to vram. If it covers the same attribute but for different models, I'd vote for keeping already existing attribute name. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [libvirt-sandbox PATCH 0/2] virt-sandbox-service fixes
On 07.07.2014 15:47, Cédric Bosdonnat wrote: Here are a 2 fixes that make virt-sandbox-service work for me. One allows it to work if selinux isn't handled by libvirtd, the other safely handles some file copying that can be different across distros. Cédric Bosdonnat (2): virt-sandbox-service: check for security label only if they can be handled virt-sandbox-service: fix some paths for SUSE bin/virt-sandbox-service | 42 -- 1 file changed, 36 insertions(+), 6 deletions(-) ACK to both patches. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 1/2] Add test for virtio serial port assignment
On 25.06.2014 19:22, Ján Tomko wrote: Add a test to demonstrate the effect of the next patch. --- .../qemuxml2argv-channel-virtio-autoassign.args| 20 + .../qemuxml2argv-channel-virtio-autoassign.xml | 50 ++ tests/qemuxml2argvtest.c | 2 + 3 files changed, 72 insertions(+) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-autoassign.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-autoassign.xml ACK. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [RFC PATCH 2/2] Implement virtio serial address allocation
On 25.06.2014 19:22, Ján Tomko wrote: Over-engineered to allow non-contiguous indexes. Free ports of a controller are stored in a virBitmap. These bitmaps are stored in a hash table, indexed by the controller index formatted as a string. Buses are ignored for now, QEMU doesn't seem to support anything else than .0 For virtconsoles, addresses are reserved silently, since we don't put those in the XML, but they occupy virtio-serial ports. Missing: auto-adding controllers when all ports are occupied Fixes https://bugzilla.redhat.com/show_bug.cgi?id=890606 Paritally fixes https://bugzilla.redhat.com/show_bug.cgi?id=1076708 --- RFC, since it hashes the string of an integer. Yeah, out hash tables require pointers, and we don't like to see an integer taken as a pointer... However, I like the idea (I mean the whole idea). src/conf/domain_addr.c | 426 + src/conf/domain_addr.h | 49 +++ src/conf/domain_conf.c | 30 -- src/libvirt_private.syms | 9 + src/qemu/qemu_command.c| 61 +++ src/qemu/qemu_domain.c | 1 + src/qemu/qemu_domain.h | 1 + src/qemu/qemu_hotplug.c| 31 +- tests/qemuhotplugtest.c| 2 +- .../qemuxml2argv-channel-virtio-auto.args | 8 +- .../qemuxml2argv-channel-virtio-autoassign.args| 10 +- .../qemuxml2xmlout-channel-virtio-auto.xml | 10 +- 12 files changed, 591 insertions(+), 47 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 9cd6a3e..6e4c456 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -367,6 +367,7 @@ int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver, char *devstr = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; bool releaseaddr = false; +bool needs_remove = false;; s/;;/;/ if (virDomainControllerFind(vm->def, controller->type, controller->idx) >= 0) { virReportError(VIR_ERR_OPERATION_FAILED, I'd say ACK but since this is an RFC I let others to chime in. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] qemuConnectGetDomainCapabilities: Report error on unknown arch
If user hasn't provided any @emulatorbin, the qemuCaps are searched by @arch provided (which in fact can be guessed from the host). However, there's no guarantee that the qemu binary for @arch will exist. Therefore qemu capabilities may be nonexistent too. If that's the case, we should throw an error message prior jumping onto 'cleanup' label as the helper lookup function remains silent on no search result. Signed-off-by: Michal Privoznik --- Notes: This would qualify to be pushed under trivial rule, but maybe somebody has a better idea for the error message (or its code). src/qemu/qemu_driver.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 06d3f53..8e01965 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -16990,8 +16990,12 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn, } } else { if (!(qemuCaps = virQEMUCapsCacheLookupByArch(driver->qemuCapsCache, - arch))) + arch))) { +virReportError(VIR_ERR_INVALID_ARG, + _("unable to find any emulator to serve '%s' " + "architecture"), virArchToString(arch)); goto cleanup; +} emulatorbin = virQEMUCapsGetBinary(qemuCaps); } -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] domtop: Turn parse_argv into void
Currently, the function follows the usual pattern used in our code: int ret = -1; ... ret = 0; cleanup: return ret; However, the function always call exit() on error, so the cleanup label is never jumped onto. Therefore, it doesn't make any sense to have the parse_argv function return an integer value, if it effectively can return only value of zero. Signed-off-by: Michal Privoznik --- examples/domtop/domtop.c | 10 ++ 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/examples/domtop/domtop.c b/examples/domtop/domtop.c index af5da46..204fdc3 100644 --- a/examples/domtop/domtop.c +++ b/examples/domtop/domtop.c @@ -94,13 +94,12 @@ print_usage(const char *progname) unified_progname); } -static int +static void parse_argv(int argc, char *argv[], const char **uri, const char **dom_name, unsigned int *milliseconds) { -int ret = -1; int arg; unsigned long val; char *p; @@ -155,10 +154,6 @@ parse_argv(int argc, char *argv[], if (argc > optind) *dom_name = argv[optind]; - -ret = 0; - cleanup: -return ret; } static int @@ -368,8 +363,7 @@ main(int argc, char *argv[]) unsigned int milliseconds = 500; /* Sleep this long between two API calls */ const int connect_flags = 0; /* No connect flags for now */ -if (parse_argv(argc, argv, &uri, &dom_name, &milliseconds) < 0) -goto cleanup; +parse_argv(argc, argv, &uri, &dom_name, &milliseconds); DEBUG("Proceeding with uri=%s dom_name=%s milliseconds=%u", uri, dom_name, milliseconds); -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] domtop: Remove unused variable
The variable 'k' in the print_cpu_usage function is not used anywhere and can fire a warning on some compilers. Signed-off-by: Michal Privoznik --- examples/domtop/domtop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/domtop/domtop.c b/examples/domtop/domtop.c index 204fdc3..e50988e 100644 --- a/examples/domtop/domtop.c +++ b/examples/domtop/domtop.c @@ -199,7 +199,7 @@ print_cpu_usage(const char *dom_name, virTypedParameterPtr now_params, size_t now_nparams) { -size_t i, j, k; +size_t i, j; size_t nparams = now_nparams; bool delim = false; -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] help
[Dropping libvirt-announce list] On 05.08.2014 11:47, Himanshu Sharma wrote: Dear Team, Greetings!! I'm testing libvirt with VMware ESXi. I'm able to connect to VMware ESXi with libvirt driver but not able to connect it through "Virtual Machine manager" GUI also not able to run virt-clone command inturn to clone ESXi VM. Can you please guide me how to do so? The virt-manager does not support ESX yet. It merely supports QEMU/KVM, XEN and LXC. And for the virt-clone issue: 1) "computer broken" is usually not much descriptive. Is there any error message you are seeing? What behavior are you experiencing? 2) virt tools have a separate mailing list: http://www.redhat.com/mailman/listinfo/virt-tools-list Try asking there. Usually it's considered bad practice to repeat your question every 5 minutes, crosspost it over several mailing lists (even libvirt-announce which is not user support channel but a low traffic list for announcements as it name suggests) or forward the e-mail that is irrelevant (Welcome to the list). Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] qemu: Make virFileFindHugeTLBFS fault tolerant
Since commit be0782e1 we are parsing /proc/meminfo to find out the default huge page size. However, if the host we are running at does not support any huge pages (e.g. CONFIG_HUGETLB_PAGE is turned off), we will not successfully parse the meminfo file and hence the whole qemu driver init process fails. Moreover, the default huge page size is needed if and only if there's at least one hugetlbfs mount point. So the fix consists of moving the virFileGetDefaultHugepageSize function call after the first hugetlbfs mount point is found. With this fix, we fail to start with one or more hugetlbfs mounts and malformed meminfo file, but that's expected (how can one mount hugetlbfs without kernel supporting huge pages?). Workaround in that case is to umount all the hugetlbfs mounts. Reported-by: Jim Fehlig Signed-off-by: Michal Privoznik --- src/util/virfile.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/util/virfile.c b/src/util/virfile.c index 9863fd0..f9efc65 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -2990,10 +2990,7 @@ virFileFindHugeTLBFS(virHugeTLBFSPtr *ret_fs, char mntbuf[1024]; virHugeTLBFSPtr fs = NULL; size_t nfs = 0; -unsigned long long default_hugepagesz; - -if (virFileGetDefaultHugepageSize(&default_hugepagesz) < 0) -goto cleanup; +unsigned long long default_hugepagesz = 0; if (!(f = setmntent(PROC_MOUNTS, "r"))) { virReportSystemError(errno, @@ -3019,6 +3016,10 @@ virFileFindHugeTLBFS(virHugeTLBFSPtr *ret_fs, if (virFileGetHugepageSize(tmp->mnt_dir, &tmp->size) < 0) goto cleanup; +if (!default_hugepagesz && +virFileGetDefaultHugepageSize(&default_hugepagesz) < 0) +goto cleanup; + tmp->deflt = tmp->size == default_hugepagesz; } -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v1 0/3] OVMF exposure
Not so long ago, QEMU introduced support for UEFI instead of standard BIOS. Our domain XML needs to be adjusted, however. Users are expected to use mainly OVMF which works in two modes: 1) UEFI code and UEFI variables are mixed in one file 2) The code and variables are split in two separate files For the case number one we are almost ready. The second case, however, needs more changes on our side. Especially if you consider fact, that the UEFI code can be shared among multiple domains while the variables store can't. Michal Privoznik (3): conf: Extend and introduce qemu: Implement extended loader and nvram qemu: Automatically create NVRAM store configure.ac | 27 + docs/formatdomain.html.in | 19 +++- docs/schemas/domaincommon.rng | 21 libvirt.spec.in| 2 + src/Makefile.am| 1 + src/conf/domain_conf.c | 87 +- src/conf/domain_conf.h | 22 +++- src/libvirt_private.syms | 3 + src/qemu/libvirtd_qemu.aug | 3 + src/qemu/qemu.conf | 9 ++ src/qemu/qemu_command.c| 87 +- src/qemu/qemu_conf.c | 8 ++ src/qemu/qemu_conf.h | 3 + src/qemu/qemu_process.c| 125 + src/qemu/test_libvirtd_qemu.aug.in | 1 + src/security/security_dac.c| 8 ++ src/security/security_selinux.c| 8 ++ src/security/virt-aa-helper.c | 4 +- src/vbox/vbox_tmpl.c | 7 +- src/xenapi/xenapi_driver.c | 3 +- src/xenxs/xen_sxpr.c | 16 +-- src/xenxs/xen_xm.c | 8 +- .../qemuxml2argvdata/qemuxml2argv-bios-nvram.args | 10 ++ tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.xml | 40 +++ tests/qemuxml2argvtest.c | 2 + .../qemuxml2xmlout-pci-bridge-many-disks.xml | 2 +- tests/qemuxml2xmltest.c| 2 + tests/sexpr2xmldata/sexpr2xml-fv-autoport.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-force-hpet.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-force-nohpet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-kernel.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-legacy-vfb.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-localtime.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-net-ioemu.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-net-netfront.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-parallel-tcp.xml | 2 +- .../sexpr2xml-fv-serial-dev-2-ports.xml| 2 +- .../sexpr2xml-fv-serial-dev-2nd-port.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-file.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-null.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-pipe.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-pty.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-stdio.xml | 2 +- .../sexpr2xml-fv-serial-tcp-telnet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-udp.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-unix.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-sound.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-usbmouse.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-usbtablet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-utc.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-v2.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml | 2 +- tests/xmconfigdata/test-escape-paths.xml | 2 +- tests/xmconfigdata/test-fullvirt-force-hpet.xml| 2 +- tests/xmconfigdata/test-fullvirt-force-nohpet.xml | 2 +- tests/xmconfigdata/test-fullvirt-localtime.xml | 2 +- tests/xmconfigdata/test-fullvirt-net-ioemu.xml | 2 +- tests/xmconfigdata/test-fullvirt-net-netfront.xml | 2 +- tests/xmconfigdata/test-fullvirt-new-cdrom.xml | 2 +- tests/xmconfigdata/test-fullvirt-old-cdrom.xml | 2 +- tests/xmconfigdata/test-fullvirt-parallel-tcp.xml | 2 +- .../test-fullvirt-serial-dev-2-ports.xml | 2 +- .../test-fullvirt-serial-dev-2nd-port.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-file.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-null.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-pipe.xml | 2 +-
[libvirt] [PATCH v1 1/3] conf: Extend and introduce
Up to now, users can configure BIOS via the element. With the upcoming implementation of UEFI this is not enough as BIOS and UEFI are conceptually different. For instance, while BIOS is ROM, UEFI is programmable flash (although all writes to code section are denied). Therefore we need new attribute @type which will differentiate the two. Then, new attribute @readonly is introduced to reflect the fact that some images are RO. Moreover, the OVMF (which is going to be used mostly), works in two modes: 1) Code and UEFI variable store is mixed in one file. 2) Code and UEFI variable store is separated in two files The latter has advantage of updating the UEFI code without losing the configuration. However, in order to represent the latter case we need yet another XML element: . Currently, it has no additional attributes, it's just a bare element containing path to the variable store file. Signed-off-by: Michal Privoznik --- docs/formatdomain.html.in | 19 - docs/schemas/domaincommon.rng | 21 ++ src/conf/domain_conf.c | 87 +- src/conf/domain_conf.h | 22 +- src/libvirt_private.syms | 3 + src/qemu/qemu_command.c| 5 +- src/security/virt-aa-helper.c | 4 +- src/vbox/vbox_tmpl.c | 7 +- src/xenapi/xenapi_driver.c | 3 +- src/xenxs/xen_sxpr.c | 16 ++-- src/xenxs/xen_xm.c | 8 +- tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.xml | 40 ++ .../qemuxml2xmlout-pci-bridge-many-disks.xml | 2 +- tests/qemuxml2xmltest.c| 2 + tests/sexpr2xmldata/sexpr2xml-fv-autoport.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-force-hpet.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-force-nohpet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-kernel.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-legacy-vfb.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-localtime.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-net-ioemu.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-net-netfront.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-parallel-tcp.xml | 2 +- .../sexpr2xml-fv-serial-dev-2-ports.xml| 2 +- .../sexpr2xml-fv-serial-dev-2nd-port.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-file.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-null.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-pipe.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-pty.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-stdio.xml | 2 +- .../sexpr2xml-fv-serial-tcp-telnet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-udp.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-unix.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-sound.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-usbmouse.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-usbtablet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-utc.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-v2.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml | 2 +- tests/xmconfigdata/test-escape-paths.xml | 2 +- tests/xmconfigdata/test-fullvirt-force-hpet.xml| 2 +- tests/xmconfigdata/test-fullvirt-force-nohpet.xml | 2 +- tests/xmconfigdata/test-fullvirt-localtime.xml | 2 +- tests/xmconfigdata/test-fullvirt-net-ioemu.xml | 2 +- tests/xmconfigdata/test-fullvirt-net-netfront.xml | 2 +- tests/xmconfigdata/test-fullvirt-new-cdrom.xml | 2 +- tests/xmconfigdata/test-fullvirt-old-cdrom.xml | 2 +- tests/xmconfigdata/test-fullvirt-parallel-tcp.xml | 2 +- .../test-fullvirt-serial-dev-2-ports.xml | 2 +- .../test-fullvirt-serial-dev-2nd-port.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-file.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-null.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-pipe.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-pty.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-stdio.xml | 2 +- .../test-fullvirt-serial-tcp-telnet.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-tcp.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-udp.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-unix.xml | 2 +- tests/xmconfigdata/test-fullvirt-sound.xml | 2 +- tests/xmconfigdata/test-fullvirt-usbmouse.xml | 2 +- tests/xmconfigdata/test-fullvirt-usbtablet.xml | 2 +- tests/xmconfigdata/test-fullvirt-utc.xml
[libvirt] [PATCH v1 2/3] qemu: Implement extended loader and nvram
QEMU now supports UEFI with the following command line: -drive file=/usr/share/OVMF/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on \ -drive file=/usr/share/OVMF/OVMF_VARS.fd,if=pflash,format=raw,unit=1 \ where the first line reflects and the second one . Moreover, these two lines obsoletes the -bios argument. Note that UEFI is unusable without ACPI. This is handled properly now. Among with this extension, the variable file is expected to be writable and hence we need security drivers to label it. Signed-off-by: Michal Privoznik --- src/qemu/qemu_command.c| 84 -- src/security/security_dac.c| 8 +++ src/security/security_selinux.c| 8 +++ .../qemuxml2argvdata/qemuxml2argv-bios-nvram.args | 10 +++ tests/qemuxml2argvtest.c | 2 + 5 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.args diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a3c048f..982dd7b 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7284,6 +7284,84 @@ qemuBuildChrDeviceCommandLine(virCommandPtr cmd, return 0; } +static int +qemuBuilDomainLoaderCommandLine(virCommandPtr cmd, +virDomainDefPtr def, +virQEMUCapsPtr qemuCaps) +{ +int ret = -1; +virDomainLoaderDefPtr loader = def->os.loader; +virBuffer buf = VIR_BUFFER_INITIALIZER; + +if (!loader) +return 0; + +switch ((virDomainLoader) loader->type) { +case VIR_DOMAIN_LOADER_TYPE_ROM: +virCommandAddArg(cmd, "-bios"); +virCommandAddArg(cmd, loader->path); +break; + +case VIR_DOMAIN_LOADER_TYPE_PFLASH: +if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support -drive")); +goto cleanup; +} +if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_FORMAT)) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support passing " + "drive format")); +goto cleanup; +} +if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_ACPI) && +def->features[VIR_DOMAIN_FEATURE_ACPI] != VIR_TRISTATE_SWITCH_ON) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("ACPI must be enabled in order to use UEFI")); +goto cleanup; +} + +virBufferAsprintf(&buf, + "file=%s,if=pflash,format=raw,unit=0", + loader->path); + +if (loader->readonly) { +if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_READONLY)) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support passing " + "readonly attribute")); +goto cleanup; +} + +virBufferAsprintf(&buf, ",readonly=%s", + virTristateSwitchTypeToString(loader->readonly)); +} + +virCommandAddArg(cmd, "-drive"); +virCommandAddArgBuffer(cmd, &buf); + +if (loader->nvram) { +virBufferFreeAndReset(&buf); +virBufferAsprintf(&buf, + "file=%s,if=pflash,format=raw,unit=1", + loader->nvram); + +virCommandAddArg(cmd, "-drive"); +virCommandAddArgBuffer(cmd, &buf); +} +break; + +case VIR_DOMAIN_LOADER_TYPE_LAST: +/* nada */ +break; +} + +ret = 0; + cleanup: +virBufferFreeAndReset(&buf); +return ret; +} + qemuBuildCommandLineCallbacks buildCommandLineCallbacks = { .qemuGetSCSIDeviceSgName = virSCSIDeviceGetSgName, }; @@ -7439,10 +7517,8 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-enable-nesting"); } -if (def->os.loader) { -virCommandAddArg(cmd, "-bios"); -virCommandAddArg(cmd, def->os.loader->path); -} +if (qemuBuilDomainLoaderCommandLine(cmd, def, qemuCaps) < 0) +goto error; /* Set '-m MB' based on maxmem, because the lower 'memory' limit * is set post-startup using the balloon driver. If balloon driver diff --git a/src/security/security_dac.c b/src/security/security_dac.c index e62828e..e398d2c 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c
[libvirt] [PATCH v1 3/3] qemu: Automatically create NVRAM store
When using split UEFI image, it may come handy if libvirt manages per domain _VARS file automatically. While the _CODE file is RO and can be shared among multiple domains, you certainly don't want to do that on the _VARS file. This latter one needs to be per domain. So at the domain startup process, if it's determined that domain needs _VARS file it's copied from this master _VARS file. The location of the master file is configurable in qemu.conf and the default path can be compiled in via --with-qemu-nvram-file configure option. Signed-off-by: Michal Privoznik --- configure.ac | 27 libvirt.spec.in| 2 + src/Makefile.am| 1 + src/qemu/libvirtd_qemu.aug | 3 + src/qemu/qemu.conf | 9 +++ src/qemu/qemu_conf.c | 8 +++ src/qemu/qemu_conf.h | 3 + src/qemu/qemu_process.c| 125 + src/qemu/test_libvirtd_qemu.aug.in | 1 + 9 files changed, 179 insertions(+) diff --git a/configure.ac b/configure.ac index 9dd07d2..16ca266 100644 --- a/configure.ac +++ b/configure.ac @@ -569,6 +569,11 @@ AC_ARG_WITH([chrdev-lock-files], [location for UUCP style lock files for character devices (use auto for default paths on some platforms) @<:@default=auto@:>@])]) m4_divert_text([DEFAULTS], [with_chrdev_lock_files=auto]) +AC_ARG_WITH([qemu-nvram-file], + [AS_HELP_STRING([--with-qemu-nvram-file], +[location of OVMF_VARS.fd file + (use auto for default path on some platforms) @<:@default=auto@:>@])]) +m4_divert_text([DEFAULTS], [with_qemu_nvram_file=auto]) AC_ARG_WITH([pm-utils], [AS_HELP_STRING([--with-pm-utils], [use pm-utils for power management @<:@default=yes@:>@])]) @@ -1418,6 +1423,27 @@ platform]) fi AM_CONDITIONAL([VIR_CHRDEV_LOCK_FILE_PATH], [test "$with_chrdev_lock_files" != "no"]) +dnl OVMF_VARS.fd file +if test "$with_qemu_nvram_file" != "no"; then + case $with_qemu_nvram_file in + yes | auto) +dnl Default locations for platforms, or disable if unknown +if test "$with_linux" = "yes"; then + with_qemu_nvram_file=/usr/share/OVMF/OVMF_VARS.fd +elif test "$with_chrdev_lock_files" = "auto"; then + with_qemu_nvram_file=no +fi ;; + esac + if test "$with_qemu_nvram_file" = "yes"; then +AC_MSG_ERROR([You must specify path for the lock files on this +platform]) + fi + if test "$with_qemu_nvram_file" != "no"; then +AC_DEFINE_UNQUOTED([VIR_QEMU_NVRAM_FILE_PATH], "$with_qemu_nvram_file", + [default path to OVMF_VARS.fd file]) + fi +fi +AM_CONDITIONAL([VIR_QEMU_NVRAM_FILE_PATH], [test "$with_qemu_nvram_file" != "no"]) AC_ARG_WITH([secdriver-selinux], [AS_HELP_STRING([--with-secdriver-selinux], @@ -2925,6 +2951,7 @@ AC_MSG_NOTICE([numad: $with_numad]) AC_MSG_NOTICE([ XML Catalog: $XML_CATALOG_FILE]) AC_MSG_NOTICE([ Init script: $with_init_script]) AC_MSG_NOTICE([Char device locks: $with_chrdev_lock_files]) +AC_MSG_NOTICE([ OVMF_VARS.fd loc: $with_qemu_nvram_file]) AC_MSG_NOTICE([]) AC_MSG_NOTICE([Developer Tools]) AC_MSG_NOTICE([]) diff --git a/libvirt.spec.in b/libvirt.spec.in index 29da071..486fc66 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1947,6 +1947,7 @@ exit 0 %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/target/ +%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/ %{_datadir}/augeas/lenses/libvirtd_qemu.aug %{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug @@ -2049,6 +2050,7 @@ exit 0 %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/target/ +%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/ %{_datadir}/augeas/lenses/libvirtd_qemu.aug %{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug diff --git a/src/Makefile.am b/src/Makefile.am index 982f63d..9bd38f5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2632,6 +2632,7 @@ endif WITH_SANLOCK if WITH_QEMU $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/qemu" $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/qemu/channel/target"
Re: [libvirt] [PATCH v1 2/3] qemu: Implement extended loader and nvram
On 08.08.2014 14:08, Paolo Bonzini wrote: Il 08/08/2014 12:17, Michal Privoznik ha scritto: +if (loader->nvram) { +virBufferFreeAndReset(&buf); +virBufferAsprintf(&buf, + "file=%s,if=pflash,format=raw,unit=1", + loader->nvram); + +virCommandAddArg(cmd, "-drive"); +virCommandAddArgBuffer(cmd, &buf); +} Note that other machines may not need unit=1, for example pseries doesn't need it (it uses -bios for the firmware, not -drive if=pflash). It would be nice to make this easily configurable. Is there a table anywhere where I can see what machine types support this? Or does it makes sense to enable this only for qemu-system-{x86_64,i386} -M pc and error out for all other combinations? Alternatively you could use unit=1 if there is a element, and unit=0 otherwise. We can then patch QEMU to reject unit=1 on machines that use -bios + -drive if=pflash,unit=0. Laszlo, what happens on x86 with -bios + -drive if=pflash,unit=0? Paolo Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Include param.h in case of HAVE_BSD_CPU_AFFINITY
On 10.08.2014 11:44, Guido Günther wrote: This fixes compilation on kFreeBSD which otherwise fails like CC util/libvirt_util_la-virprocess.lo In file included from /usr/include/sys/cpuset.h:35:0, from util/virprocess.c:43: /usr/include/sys/_cpuset.h:49:43: error: 'NBBY' undeclared here (not in a function) long __bits[howmany(CPU_SETSIZE, _NCPUBITS)]; ^ In file included from util/virprocess.c:43:0: /usr/include/sys/cpuset.h:215:12: error: unknown type name 'cpusetid_t' int cpuset(cpusetid_t *); ^ /usr/include/sys/cpuset.h:216:30: error: expected ')' before 'id_t' int cpuset_setid(cpuwhich_t, id_t, cpusetid_t); ^ /usr/include/sys/cpuset.h:217:42: error: expected ')' before 'id_t' int cpuset_getid(cpulevel_t, cpuwhich_t, id_t, cpusetid_t *); ^ /usr/include/sys/cpuset.h:218:48: error: expected ')' before 'id_t' int cpuset_getaffinity(cpulevel_t, cpuwhich_t, id_t, size_t, cpuset_t *); ^ /usr/include/sys/cpuset.h:219:48: error: expected ')' before 'id_t' int cpuset_setaffinity(cpulevel_t, cpuwhich_t, id_t, size_t, const cpuset_t *); And it's the correct usage as documented in http://www.freebsd.org/cgi/man.cgi?query=cpuset_setid --- src/util/virprocess.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/util/virprocess.c b/src/util/virprocess.c index 9179d73..4d6c50d 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -40,6 +40,7 @@ #endif #ifdef HAVE_BSD_CPU_AFFINITY +# include # include #endif ACK Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Don't fail qemu driver intialization if we can't determine hugepage size
On 10.08.2014 13:51, Guido Günther wrote: Otherwise we fail like libvirt version: 1.2.7, package: 6 (root 2014-08-08-16:09:22 bogon) virAuditOpen:62 : Unable to initialize audit layer: Protocol not supported virFileGetDefaultHugepageSize:2958 : internal error: Unable to parse /proc/meminfo virStateInitialize:749 : Initialization of QEMU state driver failed: internal error: Unable to parse /proc/meminfo daemonRunStateInit:922 : Driver state initialization failed if the data can't be determined. Reference: http://bugs.debian.org/757609 --- src/util/virfile.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/util/virfile.c b/src/util/virfile.c index f9efc65..b6f5e3f 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -2953,8 +2953,9 @@ virFileGetDefaultHugepageSize(unsigned long long *size) goto cleanup; if (!(c = strstr(meminfo, HUGEPAGESIZE_STR))) { -virReportError(VIR_ERR_INTERNAL_ERROR, - _("Unable to parse %s"), +virReportError(VIR_ERR_NO_SUPPORT, + _("%s not found in %s"), + HUGEPAGESIZE_STR, PROC_MEMINFO); goto cleanup; } This merely changes the error code and error message. But the initialization will fail anyway. Well, it would up till d26e81083. But the error message you suggests is more verbose and describes the origin of fault more accurately. ACK Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] qemu driver fails to load on Xen after be0782e1
On 11.08.2014 11:16, Daniel P. Berrange wrote: On Tue, Aug 05, 2014 at 11:16:53AM -0600, Jim Fehlig wrote: Jim Fehlig wrote: Until recently, the qemu driver has always succeeded in loading even on a system booted to Xen. Commit be0782e1 broke this, hence libvirtd no longer loads xendom0 # /usr/sbin/libvirtd -l 2014-08-04 22:27:31.586+: 35859: info : libvirt version: 1.2.8 2014-08-04 22:27:31.586+: 35859: error : virFileGetDefaultHugepageSize:2958 : internal error: Unable to parse /proc/meminfo 2014-08-04 22:27:31.586+: 35859: error : virStateInitialize:749 : Initialization of QEMU state driver failed: internal error: Unable to parse /proc/meminfo 2014-08-04 22:27:31.586+: 35859: error : daemonRunStateInit:922 : Driver state initialization failed Problem is the Xen kernel does not provide any huge page info in /proc/meminfo xendom0 # cat /proc/meminfo | grep -i huge xendom0 # BTW, I think this would be the case for any kernel with CONFIG_HUGETLB_PAGE turned off. Yes, we should be robust to this situation. And as of d26e810838fad we are fault tolerant. Michal, short of always building with '--without-qemu' on a Xen system, is it possible to make detection of huge pages less fatal wrt loading the qemu driver? E.g. assume zero/default for entries not present? If the dirs / files don't exist, we should just not report any huge page info at all. Regards, Daniel Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Clear bandwidth settings for a shutoff domain using domiftune
On 11.08.2014 08:41, Jianwei Hu wrote: qemu: To clear bandwidth settings for a shutoff domain by using domiftune. After applying this patch, we can use virsh domiftune command to clear inbound or/and outbound setting for a shutoff domain. for example: virsh domiftune $domain $interface 0 0 Thanks for catching this. Please refer to below virsh help message: man virsh: To clear inbound or outbound settings, use --inbound or --outbound respectfully with average value of zero. --- src/qemu/qemu_driver.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 82a82aa..7db2e9c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9983,11 +9983,17 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom, VIR_FREE(persistentNet->bandwidth->in); persistentNet->bandwidth->in = bandwidth->in; bandwidth->in = NULL; +} else { +VIR_FREE(persistentNet->bandwidth->in); +persistentNet->bandwidth->in = 0; We like NULL for pointer more than 0. Moreover, there's no need to explicitly set pointer freed to NULL as the VIR_FREE() macro does that already for you (in fact virFree() function does that, whatever). } if (bandwidth->out) { VIR_FREE(persistentNet->bandwidth->out); persistentNet->bandwidth->out = bandwidth->out; bandwidth->out = NULL; +} else { +VIR_FREE(persistentNet->bandwidth->out); +persistentNet->bandwidth->out = 0; } } But the fix isn't quite right. For instance: virsh # domiftune dummy 52:54:00:89:3a:c2 --config inbound.average: 10 inbound.peak : 0 inbound.burst : 0 outbound.average: 10 outbound.peak : 0 outbound.burst : 0 virsh # domiftune dummy 52:54:00:89:3a:c2 --config 100 virsh # domiftune dummy 52:54:00:89:3a:c2 --config inbound.average: 100 inbound.peak : 0 inbound.burst : 0 outbound.average: 0 outbound.peak : 0 outbound.burst : 0 The bandwidth is cleared unconditionally. What we really need is: diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 82a82aa..2c3f179 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9983,11 +9983,15 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom, VIR_FREE(persistentNet->bandwidth->in); persistentNet->bandwidth->in = bandwidth->in; bandwidth->in = NULL; +} else if (inboundSpecified) { +VIR_FREE(persistentNet->bandwidth->in); } if (bandwidth->out) { VIR_FREE(persistentNet->bandwidth->out); persistentNet->bandwidth->out = bandwidth->out; bandwidth->out = NULL; +} else if (outboundSpecified) { +VIR_FREE(persistentNet->bandwidth->out); } } I'm fixing this patch though and pushing. ACK. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] conf: Format interface's driver more frequently
There's this element under which can have several attributes. However, the driver element is currently formated only if the driver's name or txmode has been specified. This makes only a little sense as we parse even partial , for instance: But such XML would never get formatted back. Signed-off-by: Michal Privoznik --- src/conf/domain_conf.c | 4 +- .../qemuxml2argv-interface-driver.xml | 51 ++ tests/qemuxml2xmltest.c| 1 + 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-interface-driver.xml diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c7016f3..934f6cb 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -16286,7 +16286,9 @@ virDomainNetDefFormat(virBufferPtr buf, virBufferEscapeString(buf, "\n", def->model); if (STREQ(def->model, "virtio") && -(def->driver.virtio.name || def->driver.virtio.txmode)) { +(def->driver.virtio.name || def->driver.virtio.txmode || + def->driver.virtio.ioeventfd || def->driver.virtio.event_idx || + def->driver.virtio.queues)) { virBufferAddLit(buf, "driver.virtio.name) { virBufferAsprintf(buf, " name='%s'", diff --git a/tests/qemuxml2argvdata/qemuxml2argv-interface-driver.xml b/tests/qemuxml2argvdata/qemuxml2argv-interface-driver.xml new file mode 100644 index 000..ec5ab61 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-interface-driver.xml @@ -0,0 +1,51 @@ + + test + 15d091de-0181-456b-9554-e4382dc1f1ab + 1048576 + 1048576 + 1 + +hvm + + + + + + destroy + restart + restart + +/usr/bin/qemu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 7d416d0..5941323 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -299,6 +299,7 @@ mymain(void) DO_TEST("lease"); DO_TEST("event_idx"); DO_TEST("vhost_queues"); +DO_TEST("interface-driver"); DO_TEST("virtio-lun"); DO_TEST("usb-redir"); -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: use guest-fsfreeze-freeze-list command if mountpoints to freeze specified
On 08.08.2014 22:03, Tomoki Sekiyama wrote: A command to freeze a part of mounted file systems is implemented in upstream QEMU-guest-agent with a name of 'guest-fsfreeze-freeze-list'. This fixes the name of the command used to partial fsfreeze in qemu driver when 'mountpoints' option is specified to virDomainFSFreeze API. Signed-off-by: Tomoki Sekiyama --- src/qemu/qemu_agent.c |2 +- tests/qemuagenttest.c |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index 0421733..a10954a 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -1336,7 +1336,7 @@ int qemuAgentFSFreeze(qemuAgentPtr mon, const char **mountpoints, if (!arg) return -1; -cmd = qemuAgentMakeCommand("guest-fsfreeze-freeze", +cmd = qemuAgentMakeCommand("guest-fsfreeze-freeze-list", "a:mountpoints", arg, NULL); } else { cmd = qemuAgentMakeCommand("guest-fsfreeze-freeze", NULL); diff --git a/tests/qemuagenttest.c b/tests/qemuagenttest.c index be207e8..bc649b4 100644 --- a/tests/qemuagenttest.c +++ b/tests/qemuagenttest.c @@ -45,7 +45,7 @@ testQemuAgentFSFreeze(const void *data) if (qemuMonitorTestAddAgentSyncResponse(test) < 0) goto cleanup; -if (qemuMonitorTestAddItem(test, "guest-fsfreeze-freeze", +if (qemuMonitorTestAddItem(test, "guest-fsfreeze-freeze-list", "{ \"return\" : 5 }") < 0) goto cleanup; -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list ACKed & pushed. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [python-PATCH] Fix libvirt_longlongWrap returning a very large value
On 11.08.2014 14:59, Wang Rui wrote: From: Zhou Yimin If hypervisor is not Xen, the errs in struct _virDomainBlockStats will be -1. But in KVM when we call domain.blockStats(), errs is 18446744073709551615. To fix that, this patch has two changes: 1. Replace use of the PyLong_FromUnsignedLongLong with PyLong_FromLongLong in function libvirt_longlongWrap 2. If the paramemter of libvirt_longlongWrap is unsigned long long, use libvirt_ulonglongWrap instead because of above change. After this patch, errs is -1 which is consistent with virDomainBlockStats api. Signed-off-by: Zhou Yimin Signed-off-by: Wang Rui --- libvirt-override.c | 18 +- typewrappers.c | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) ACKed & pushed. Congratulations on your first libvirt-python commit! Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 10/66] vbox: Rewrite vboxConnectGetCapabilities
On 11.08.2014 12:06, Taowei wrote: --- src/vbox/vbox_common.c| 11 +++ src/vbox/vbox_tmpl.c | 16 ++-- src/vbox/vbox_uniformed_api.h |1 + 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index cb73f97..eaefe81 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -463,3 +463,14 @@ vboxConnectGetMaxVcpus(virConnectPtr conn, const char *type ATTRIBUTE_UNUSED) VBOX_RELEASE(systemProperties); return ret; } + +char *vboxConnectGetCapabilities(virConnectPtr conn) +{ +VBOX_OBJECT_CHECK(conn, char *, NULL); + +vboxDriverLock(data); +ret = virCapabilitiesFormatXML(data->caps); +vboxDriverUnlock(data); + +return ret; +} diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index deb3067..7f9b4cc 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -256,6 +256,10 @@ static virDomainPtr vboxDomainDefineXML(virConnectPtr conn, const char *xml); static int vboxDomainCreate(virDomainPtr dom); static int vboxDomainUndefineFlags(virDomainPtr dom, unsigned int flags); +#if VBOX_API_VERSION > 2002000 && VBOX_API_VERSION < 400 +/* Since vboxConnectGetCapabilities has been rewriten, + * vboxDiverLock and Unlock only be used in 3.* */ + s/rewriten/rewritten/ s/vboxDiverLock/vboxDriverLock/ we are not locking any diver but the driver :-P static void vboxDriverLock(vboxGlobalData *data) { virMutexLock(&data->lock); @@ -266,6 +270,8 @@ static void vboxDriverUnlock(vboxGlobalData *data) virMutexUnlock(&data->lock); } +#endif + #if VBOX_API_VERSION == 2002000 static void nsIDtoChar(unsigned char *uuid, const nsID *iid) @@ -914,16 +920,6 @@ vboxSocketParseAddrUtf16(vboxGlobalData *data, const PRUnichar *utf16, return result; } -static char *vboxConnectGetCapabilities(virConnectPtr conn) { -VBOX_OBJECT_CHECK(conn, char *, NULL); - -vboxDriverLock(data); -ret = virCapabilitiesFormatXML(data->caps); -vboxDriverUnlock(data); - -return ret; -} - static int vboxConnectListDomains(virConnectPtr conn, int *ids, int nids) { VBOX_OBJECT_CHECK(conn, int, -1); diff --git a/src/vbox/vbox_uniformed_api.h b/src/vbox/vbox_uniformed_api.h index 2cc0674..e49b881 100644 --- a/src/vbox/vbox_uniformed_api.h +++ b/src/vbox/vbox_uniformed_api.h @@ -233,6 +233,7 @@ int vboxConnectIsSecure(virConnectPtr conn); int vboxConnectIsEncrypted(virConnectPtr conn); int vboxConnectIsAlive(virConnectPtr conn); int vboxConnectGetMaxVcpus(virConnectPtr conn, const char *type); +char *vboxConnectGetCapabilities(virConnectPtr conn); /* Version specified functions for installing uniformed API */ void vbox22InstallUniformedAPI(vboxUniformedAPI *pVBoxAPI); Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 14/66] vbox: Rewrite vboxDomainLookupByUUID
On 11.08.2014 12:06, Taowei wrote: --- src/vbox/vbox_common.c| 73 + src/vbox/vbox_tmpl.c | 73 - src/vbox/vbox_uniformed_api.h |2 ++ 3 files changed, 75 insertions(+), 73 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index d901b7f..5d9a4f0 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -624,3 +624,76 @@ virDomainPtr vboxDomainLookupByID(virConnectPtr conn, int id) gVBoxAPI.UArray.vboxArrayRelease(&machines); return ret; } + +virDomainPtr vboxDomainLookupByUUID(virConnectPtr conn, +const unsigned char *uuid) +{ +VBOX_OBJECT_CHECK(conn, virDomainPtr, NULL); +vboxArray machines = VBOX_ARRAY_INITIALIZER; +vboxIIDUnion iid; +char *machineNameUtf8 = NULL; +PRUnichar *machineNameUtf16 = NULL; +unsigned char iid_as_uuid[VIR_UUID_BUFLEN]; +size_t i; +int matched = 0; When you're at this, s/int matched/bool matched/. It's used as a boolean anyway. Here and in the following patches too. +nsresult rc; + +VBOX_IID_INITIALIZE(&iid); +rc = gVBoxAPI.UArray.vboxArrayGet(&machines, data->vboxObj, ARRAY_GET_MACHINES); +if (NS_FAILED(rc)) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _("Could not get list of machines, rc=%08x"), (unsigned)rc); +return NULL; +} + +for (i = 0; i < machines.count; ++i) { +IMachine *machine = machines.items[i]; +PRBool isAccessible = PR_FALSE; + +if (!machine) +continue; + +gVBoxAPI.UIMachine.GetAccessible(machine, &isAccessible); +if (!isAccessible) +continue; + +rc = gVBoxAPI.UIMachine.GetId(machine, &iid); +if (NS_FAILED(rc)) +continue; +vboxIIDToUUID(&iid, iid_as_uuid); +vboxIIDUnalloc(&iid); + +if (memcmp(uuid, iid_as_uuid, VIR_UUID_BUFLEN) == 0) { + +PRUint32 state; + +matched = 1; + +gVBoxAPI.UIMachine.GetName(machine, &machineNameUtf16); +VBOX_UTF16_TO_UTF8(machineNameUtf16, &machineNameUtf8); + +gVBoxAPI.UIMachine.GetState(machine, &state); + +/* get a new domain pointer from virGetDomain, if it fails + * then no need to assign the id, else assign the id, cause + * it is -1 by default. rest is taken care by virGetDomain + * itself, so need not worry. + */ + +ret = virGetDomain(conn, machineNameUtf8, iid_as_uuid); +if (ret && +gVBoxAPI.machineStateChecker.Online(state)) +ret->id = i + 1; + } + + if (matched == 1) + break; +} + +/* Do the cleanup and take care you dont leak any memory */ +VBOX_UTF8_FREE(machineNameUtf8); +VBOX_COM_UNALLOC_MEM(machineNameUtf16); +gVBoxAPI.UArray.vboxArrayRelease(&machines); + +return ret; +} Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 45/66] vbox: Rewrite vboxDomainAttachDeviceFlags
On 11.08.2014 12:06, Taowei wrote: --- src/vbox/vbox_common.c| 14 ++ src/vbox/vbox_tmpl.c | 15 --- src/vbox/vbox_uniformed_api.h |2 ++ 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c index 84d82d7..f22cb5b 100644 --- a/src/vbox/vbox_common.c +++ b/src/vbox/vbox_common.c @@ -4155,3 +4155,17 @@ int vboxDomainAttachDevice(virDomainPtr dom, const char *xml) { return vboxDomainAttachDeviceImpl(dom, xml, 0); } + +int vboxDomainAttachDeviceFlags(virDomainPtr dom, const char *xml, +unsigned int flags) +{ +virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); + +if (flags & VIR_DOMAIN_AFFECT_CONFIG) { +virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("cannot modify the persistent configuration of a domain")); +return -1; +} I know you're just copying pre-existing code, but this doesn't make much sense to me. I'd just drop VIR_DOMAIN_AFFECT_CONFIG flag from the virCheckFlags(). Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 00/66] vbox: Rewrite vbox domain driver
On 11.08.2014 12:06, Taowei wrote: This series of patches rewrite the vbox's domain driver. The driver is separated into two parts: the version specified and the common part. The common driver use vboxUniformedAPI to build a general driver for all vbox versions. The vboxUniformedAPI take the responsiblity to communicate with virtualbox. Since there are some incompatible changes in virtualbox, vboxUniformedAPI should be aware of these changes and provide a uniformed api for the upper layer. The significant result of this patch is that we replace all vir${vbox_version}Driver into one virCommonDriver. So, we will have only one vbox driver implementation for all vbox versions in libvirt. PS: I have send part of my patches before: https://www.redhat.com/archives/libvir-list/2014-July/msg00937.html But I have to resend it beacuse I did some improvement on previous patches: *Remove the test case for vboxUniformedAPI, because it would raise "break strict-aliasing rules" warning in some distibutions *Merged the flag fdWatchNeedInitialize into domainEventCallbacks, So, we use one flag to indicate whether vbox support callbacks as well as we need to initialize variables for it. Taowei (66): vbox: Begin to rewrite, vboxConnectOpen vbox: Rewrite vboxConnectClose vbox: Rewrite vboxDomainSave vbox: Rewrite vboxConnectGetVersion vbox: Rewrite vboxConnectGetHostname vbox: Rewrite vboxConnectIsSecure vbox: Rewrite vboxConnectIsEncrypted vbox: Rewrite vboxConnectIsAlive vbox: Rewrite vboxConnectGetMaxVcpus vbox: Rewrite vboxConnectGetCapabilities vbox: Rewrite vboxConnectListDomains vbox: Rewrite vboxConnectNumOfDomains vbox: Rewrite vboxDomainLookupById vbox: Rewrite vboxDomainLookupByUUID vbox: Rewrite vboxDomainUndefineFlags vbox: Rewrite vboxDomainDefineXML vbox: Rewrite vboxDomainCreateWithFlags vbox: Rewrite vboxDomainCreate vbox: Rewrite vboxDomainCreateXML vbox: Rewrite vboxDomainLookupByName vbox: Rewrite vboxDomainIsActive vbox: Rewrite vboxDomainIsPersistent vbox: Rewrite vboxDomainIsUpdated vbox: Rewrite vboxDomainSuspend vbox: Rewrite vboxDomainResume vbox: Rewrite vboxDomainShutdownFlags vbox: Rewrite vboxDomainShutdown vbox: Rewrite vboxDomainReboot vbox: Rewrite vboxDomainDestroyFlags vbox: Rewrite vboxDomainDestroy vbox: Rewrite vboxDomainGetOSType vbox: Rewrite vboxDomainSetMemory vbox: Rewrite vboxDomainGetInfo vbox: Rewrite vboxDomainGetState vbox: Rewrite vboxDomainSetVcpusFlags vbox: Rewrite vboxDomainSetVcpus vbox: Rewrite vboxDomainGetVcpusFlags vbox: Rewrite vboxDomainGetMaxVcpus vbox: Add API for vboxDomainGetXMLDesc vbox: Rewrite vboxDomainGetXMLDesc vbox: Rewrite vboxConnectListDefinedDomains vbox: Rewrite vboxConnectNumOfDefinedDomains vbox: Rewrite vboxDomainUndefine vbox: Rewrite vboxDomainAttachDevice vbox: Rewrite vboxDomainAttachDeviceFlags vbox: Rewrite vboxDomainUpdateDeviceFlags vbox: Rewrite vboxDomainDetachDevice vbox: Rewrite vboxDomainDetachDeviceFlags vbox: Add API for vboxDomainSnapshotCreateXML vbox: Rewrite vboxDomainSnapshotCreateXML vbox: Rewrite vboxDomainSnapshotGetXMLDesc vbox: Rewrite vboxDomainSnapshotNum vbox: Rewrite vboxDomainSnapshotListNames vbox: Rewrite vboxSnapshotLookupByName vbox: Rewrite vboxDomainHasCurrentSnapshot vbox: Rewrite vboxDomainSnapshotGetParent vbox: Rewrite vboxDomainSnapshotCurrent vbox: Rewrite vboxDomainSnapshotIsCurrent vbox: Rewrite vboxDomainSnapshotHasMetadata vbox: Rewrite vboxDomainRevertToSnapshot vbox: Rewrite vboxDomainSnapshotDelete vbox: Rewrite vboxDomainScreenshot vbox: Rewrite vboxConnectListAllDomains vbox: Rewrite vboxNode functions vbox: Add registerDomainEvent vbox: Introducing vboxCommonDriver po/POTFILES.in|1 + src/Makefile.am |5 +- src/vbox/README |7 +- src/vbox/vbox_common.c| 7550 + src/vbox/vbox_common.h| 306 + src/vbox/vbox_driver.c| 40 +- src/vbox/vbox_install_api.h | 26 + src/vbox/vbox_tmpl.c |14557 + src/vbox/vbox_uniformed_api.h | 551 ++ 9 files changed, 13186 insertions(+), 9857 deletions(-) create mode 100644 src/vbox/vbox_common.c create mode 100644 src/vbox/vbox_common.h create mode 100644 src/vbox/vbox_install_api.h create mode 100644 src/vbox/vbox_uniformed_api.h ACK to all the patches. I've fixed all the small nits I found. I'm keeping the patches on my private branch for some time to give others time to share their opinions. Nevertheless, incredible work in making the vbox driver look more sane what you've done! Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] qemu_conf: Undefine the correct symbol
At the beginning of the qemu config file parsing function there are 3 helper macros defined: GET_VALUE_BOOL, GET_VALUE_LONG and GET_VALUE_STR. Later, when they are no longer needed they are undefined in order to keep the namespace clean. However, the GET_VALUE_STRING is undefined instead of GET_VALUE_STR. Signed-off-by: Michal Privoznik --- Pushed as trivial. src/qemu/qemu_conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index b14b1bc..238d2b1 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -662,7 +662,7 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg, } #undef GET_VALUE_BOOL #undef GET_VALUE_LONG -#undef GET_VALUE_STRING +#undef GET_VALUE_STR virQEMUDriverConfigPtr virQEMUDriverGetConfig(virQEMUDriverPtr driver) { -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Initializing qemu driver
On 13.08.2014 00:00, David kiarie wrote: Hi there, I get this errors trying to intialialize libvirtd $libvirtd -vvv 2014-08-12 21:57:47.887+: 6449: info : libvirt version: 1.2.8 2014-08-12 21:57:47.887+: 6449: warning : virGetHostname:665 : getaddrinfo failed for 'linux-xzc4': Name or service not known 2014-08-12 21:57:48.034+: 6461: info : libvirt version: 1.2.8 2014-08-12 21:57:48.034+: 6461: error : virFileGetDefaultHugepageSize:2958 : internal error: Unable to parse /proc/meminfo 2014-08-12 21:57:48.034+: 6461: error : virStateInitialize:749 : Initialization of QEMU state driver failed: internal error: Unable to parse /proc/meminfo 2014-08-12 21:57:48.034+: 6461: error : daemonRunStateInit:922 : Driver state initialization failed Is someone else experiencing the same thing? There's been several patches that are merged now that fixes the problem (e.g. d26e810838fad49). So please try fetching the currnet git HEAD and build it. The problem should be fixed already. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] Pass additional environmental variables
On 12.08.2014 21:09, Sean Noonan wrote: > We're using sasl+gssapi+kerberos to do authentication for libvirt, > including from hypervisor to hypervisor. However, the environmental > variable filtering implemented in libvirt prevents this from working, so > we're forced to run a locally patched version. > > Thoughts on the following patch to pass the location of the local > credential cache as well? > > --- a/src/util/vircommand.c2014-01-07 14:14:11.388934108 + > +++ b/src/util/vircommand.c2014-01-07 14:18:14.725082505 + > @@ -1314,6 +1314,7 @@ > > virCommandAddEnvPair(cmd, "LC_ALL", "C"); > > +virCommandAddEnvPassBlockSUID(cmd, "KRB5CCNAME", NULL); > virCommandAddEnvPassBlockSUID(cmd, "LD_PRELOAD", NULL); > virCommandAddEnvPassBlockSUID(cmd, "LD_LIBRARY_PATH", NULL); > virCommandAddEnvPassBlockSUID(cmd, "PATH", "/bin:/usr/bin"); I've got some doubts whether this is the correct approach. This will pass the environment variable to every command spawned. Do we really want every command have access to kerberos tickets? On the other hand, we've done this for a limited use case: commit afc984af2e055b33f7c7b06ccacaf00103d4ce5e Author: Michal Privoznik AuthorDate: Fri Sep 9 15:59:26 2011 +0200 Commit: Michal Privoznik CommitDate: Fri Sep 9 15:59:26 2011 +0200 virnetsocket: Pass KRB5CCNAME env variable So we can allow GSSAPI authentication for ssh. Signed-off-by: Matthias Witte diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index 275b70d..88dc2a4 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -615,6 +615,7 @@ int virNetSocketNewConnectSSH(const char *nodename, cmd = virCommandNew(binary ? binary : "ssh"); virCommandAddEnvPassCommon(cmd); +virCommandAddEnvPass(cmd, "KRB5CCNAME"); virCommandAddEnvPass(cmd, "SSH_AUTH_SOCK"); virCommandAddEnvPass(cmd, "SSH_ASKPASS"); virCommandAddEnvPass(cmd, "DISPLAY"); Moreover, is KRB5CCNAME enough? What about KRB5_KTNAME? And regarding the patch itself, I think you want to increase the preallocation constant too: diff --git a/src/util/vircommand.c b/src/util/vircommand.c index e775ba6..aa493cd 100644 --- a/src/util/vircommand.c +++ b/src/util/vircommand.c @@ -1312,7 +1312,7 @@ virCommandAddEnvPassCommon(virCommandPtr cmd) if (!cmd || cmd->has_error) return; -if (VIR_RESIZE_N(cmd->env, cmd->maxenv, cmd->nenv, 9) < 0) { +if (VIR_RESIZE_N(cmd->env, cmd->maxenv, cmd->nenv, 10) < 0) { cmd->has_error = ENOMEM; return; } @@ -1326,6 +1326,7 @@ virCommandAddEnvPassCommon(virCommandPtr cmd) virCommandAddEnvPassAllowSUID(cmd, "USER"); virCommandAddEnvPassAllowSUID(cmd, "LOGNAME"); virCommandAddEnvPassBlockSUID(cmd, "TMPDIR", NULL); +virCommandAddEnvPassBlockSUID(cmd, "KRB5CCNAME", NULL); } /** Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] qemu: Issue rtc_reset_reinjection command after guest-set-time
An advice appeared there on the qemu-devel list [1]. When a domain is suspended and then resumed guest kernel is not aware of this. So we've introduced virDomainSetTime API that resets the time within guest using qemu-ga. On the other hand, qemu itself is trying to make RTC beat faster to catch the difference. But if we don't tell qemu that guest's time was reset via the other method, both mechanisms are applied resulting in again wrong guest time. In order to avoid summing both corrections we need to tell qemu that it should not use the RTC injection if the guest time is set via guest agent. 1: http://www.mail-archive.com/qemu-devel@nongnu.org/msg236435.html Signed-off-by: Michal Privoznik --- src/qemu/qemu_driver.c | 10 ++ src/qemu/qemu_monitor.c | 33 + src/qemu/qemu_monitor.h | 2 ++ src/qemu/qemu_monitor_json.c | 21 + src/qemu/qemu_monitor_json.h | 2 ++ 5 files changed, 68 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b6219ba..bdfd155 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -16879,6 +16879,16 @@ qemuDomainSetTime(virDomainPtr dom, rv = qemuAgentSetTime(priv->agent, seconds, nseconds, rtcSync); qemuDomainObjExitAgent(vm); +if (!virDomainObjIsActive(vm)) { +virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); +goto endjob; +} + +qemuDomainObjEnterMonitor(driver, vm); +rv = qemuMonitorRTCResetReinjection(priv->mon); +qemuDomainObjExitMonitor(driver, vm); + if (rv < 0) goto endjob; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 3d9f87b..77627bc 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -4037,3 +4037,36 @@ qemuMonitorGetGuestCPU(qemuMonitorPtr mon, return qemuMonitorJSONGetGuestCPU(mon, arch, data); } + +/** + * qemuMonitorRTCResetReinjection: + * @mon: Pointer to the monitor + * + * Issue rtc-reset-reinjection command. + * This should be used in cases where guest time is restored via + * guest agent so RTC injection is not needed (in fact it will + * confuse guest's RTC). + * + * Returns 0 on success + *-1 on error. + */ +int +qemuMonitorRTCResetReinjection(qemuMonitorPtr mon) +{ + +VIR_DEBUG("mon=%p", mon); + +if (!mon) { +virReportError(VIR_ERR_INVALID_ARG, "%s", + _("monitor must not be NULL")); +return -1; +} + +if (!mon->json) { +virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("JSON monitor is required")); +return -1; +} + +return qemuMonitorJSONRTCResetReinjection(mon); +} diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index c3695f2..4fd6f01 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -790,6 +790,8 @@ int qemuMonitorGetGuestCPU(qemuMonitorPtr mon, virArch arch, virCPUDataPtr *data); +int qemuMonitorRTCResetReinjection(qemuMonitorPtr mon); + /** * When running two dd process and using <> redirection, we need a * shell that will not truncate files. These two strings serve that diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index a62c02f..538110c 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5851,3 +5851,24 @@ qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon, return -1; } } + +int +qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon) +{ +int ret = -1; +virJSONValuePtr cmd; +virJSONValuePtr reply = NULL; + +if (!(cmd = qemuMonitorJSONMakeCommand("rtc-reset-reinjection", + NULL))) +return ret; + +ret = qemuMonitorJSONCommand(mon, cmd, &reply); + +if (ret == 0) +ret = qemuMonitorJSONCheckError(cmd, reply); + +virJSONValueFree(cmd); +virJSONValueFree(reply); +return ret; +} diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 5f6c846..d8c9308 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -437,4 +437,6 @@ int qemuMonitorJSONGetDeviceAliases(qemuMonitorPtr mon, int qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon, virArch arch, virCPUDataPtr *data); + +int qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon); #endif /* QEMU_MONITOR_JSON_H */ -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 00/66] vbox: Rewrite vbox domain driver
[CC-ing Yohan BELLEGUIC and Manuel VIVES] On 12.08.2014 17:31, Michal Privoznik wrote: On 11.08.2014 12:06, Taowei wrote: This series of patches rewrite the vbox's domain driver. The driver is separated into two parts: the version specified and the common part. The common driver use vboxUniformedAPI to build a general driver for all vbox versions. The vboxUniformedAPI take the responsiblity to communicate with virtualbox. Since there are some incompatible changes in virtualbox, vboxUniformedAPI should be aware of these changes and provide a uniformed api for the upper layer. The significant result of this patch is that we replace all vir${vbox_version}Driver into one virCommonDriver. So, we will have only one vbox driver implementation for all vbox versions in libvirt. PS: I have send part of my patches before: https://www.redhat.com/archives/libvir-list/2014-July/msg00937.html But I have to resend it beacuse I did some improvement on previous patches: *Remove the test case for vboxUniformedAPI, because it would raise "break strict-aliasing rules" warning in some distibutions *Merged the flag fdWatchNeedInitialize into domainEventCallbacks, So, we use one flag to indicate whether vbox support callbacks as well as we need to initialize variables for it. Taowei (66): vbox: Begin to rewrite, vboxConnectOpen vbox: Rewrite vboxConnectClose vbox: Rewrite vboxDomainSave vbox: Rewrite vboxConnectGetVersion vbox: Rewrite vboxConnectGetHostname vbox: Rewrite vboxConnectIsSecure vbox: Rewrite vboxConnectIsEncrypted vbox: Rewrite vboxConnectIsAlive vbox: Rewrite vboxConnectGetMaxVcpus vbox: Rewrite vboxConnectGetCapabilities vbox: Rewrite vboxConnectListDomains vbox: Rewrite vboxConnectNumOfDomains vbox: Rewrite vboxDomainLookupById vbox: Rewrite vboxDomainLookupByUUID vbox: Rewrite vboxDomainUndefineFlags vbox: Rewrite vboxDomainDefineXML vbox: Rewrite vboxDomainCreateWithFlags vbox: Rewrite vboxDomainCreate vbox: Rewrite vboxDomainCreateXML vbox: Rewrite vboxDomainLookupByName vbox: Rewrite vboxDomainIsActive vbox: Rewrite vboxDomainIsPersistent vbox: Rewrite vboxDomainIsUpdated vbox: Rewrite vboxDomainSuspend vbox: Rewrite vboxDomainResume vbox: Rewrite vboxDomainShutdownFlags vbox: Rewrite vboxDomainShutdown vbox: Rewrite vboxDomainReboot vbox: Rewrite vboxDomainDestroyFlags vbox: Rewrite vboxDomainDestroy vbox: Rewrite vboxDomainGetOSType vbox: Rewrite vboxDomainSetMemory vbox: Rewrite vboxDomainGetInfo vbox: Rewrite vboxDomainGetState vbox: Rewrite vboxDomainSetVcpusFlags vbox: Rewrite vboxDomainSetVcpus vbox: Rewrite vboxDomainGetVcpusFlags vbox: Rewrite vboxDomainGetMaxVcpus vbox: Add API for vboxDomainGetXMLDesc vbox: Rewrite vboxDomainGetXMLDesc vbox: Rewrite vboxConnectListDefinedDomains vbox: Rewrite vboxConnectNumOfDefinedDomains vbox: Rewrite vboxDomainUndefine vbox: Rewrite vboxDomainAttachDevice vbox: Rewrite vboxDomainAttachDeviceFlags vbox: Rewrite vboxDomainUpdateDeviceFlags vbox: Rewrite vboxDomainDetachDevice vbox: Rewrite vboxDomainDetachDeviceFlags vbox: Add API for vboxDomainSnapshotCreateXML vbox: Rewrite vboxDomainSnapshotCreateXML vbox: Rewrite vboxDomainSnapshotGetXMLDesc vbox: Rewrite vboxDomainSnapshotNum vbox: Rewrite vboxDomainSnapshotListNames vbox: Rewrite vboxSnapshotLookupByName vbox: Rewrite vboxDomainHasCurrentSnapshot vbox: Rewrite vboxDomainSnapshotGetParent vbox: Rewrite vboxDomainSnapshotCurrent vbox: Rewrite vboxDomainSnapshotIsCurrent vbox: Rewrite vboxDomainSnapshotHasMetadata vbox: Rewrite vboxDomainRevertToSnapshot vbox: Rewrite vboxDomainSnapshotDelete vbox: Rewrite vboxDomainScreenshot vbox: Rewrite vboxConnectListAllDomains vbox: Rewrite vboxNode functions vbox: Add registerDomainEvent vbox: Introducing vboxCommonDriver po/POTFILES.in|1 + src/Makefile.am |5 +- src/vbox/README |7 +- src/vbox/vbox_common.c| 7550 + src/vbox/vbox_common.h| 306 + src/vbox/vbox_driver.c| 40 +- src/vbox/vbox_install_api.h | 26 + src/vbox/vbox_tmpl.c |14557 + src/vbox/vbox_uniformed_api.h | 551 ++ 9 files changed, 13186 insertions(+), 9857 deletions(-) create mode 100644 src/vbox/vbox_common.c create mode 100644 src/vbox/vbox_common.h create mode 100644 src/vbox/vbox_install_api.h create mode 100644 src/vbox/vbox_uniformed_api.h ACK to all the patches. I've fixed all the small nits I found. I'm keeping the patches on my private branch for some time to give others time to share their opinions. Nevertheless, incredible work in making the vbox driver look more sane what you've done! Yohan and Manuel, can you guys please give this patchset a test? You seem to be interes
Re: [libvirt] [PATCH] qemuDomainFSFreeze: report unless the agent supports mountpoints param
On 13.08.2014 17:42, Tomoki Sekiyama wrote: > This patch gives users a nicer error message when the QEMU guest agent is > not new enough to support 'guest-fsfreeze-freeze-list' command, which is > used by qemuDomainFSFreeze() to freeze specified filesystems only. > > Before this patch, it was depending on the agent to complain about unknown > command: ># virsh domfsfreeze domain --mountpoint /mnt/point >error: Unable to freeze filesystems >error: internal error: unable to execute QEMU agent command 'guest- >fsfreeze-freeze-list': The command guest-fsfreeze-freeze-list has not been >found > > After: ># virsh domfsfreeze domain --mountpoint /mnt/point >error: Unable to freeze filesystems >error: argument unsupported: this version of guest agent doesn't support >specifying mountpoints > > Signed-off-by: Tomoki Sekiyama > --- > src/qemu/qemu_agent.c | 79 > - > 1 file changed, 78 insertions(+), 1 deletion(-) > > diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c > index a10954a..8102b36 100644 > --- a/src/qemu/qemu_agent.c > +++ b/src/qemu/qemu_agent.c > @@ -1279,6 +1279,75 @@ void qemuAgentNotifyEvent(qemuAgentPtr mon, > } > } > > +static int qemuAgentCommandSupported(qemuAgentPtr mon, > + const char *cmdname) > +{ > +int ret = -1; > +size_t i; > +int ndata; > +virJSONValuePtr cmd; > +virJSONValuePtr data; > +virJSONValuePtr reply = NULL; > + > +cmd = qemuAgentMakeCommand("guest-info", NULL); > +if (!cmd) > +return -1; > + > +if (qemuAgentCommand(mon, cmd, &reply, false, > + VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) > +goto cleanup; > + > +if (!(data = virJSONValueObjectGet(reply, "return"))) { > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("guest-info reply was missing return data")); > +goto cleanup; > +} > + > +if (!(data = virJSONValueObjectGet(data, "supported_commands"))) { > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("guest-info reply was missing supported_commands")); > +goto cleanup; > +} > + > +if (data->type != VIR_JSON_TYPE_ARRAY) { > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("guest-info supported_commands was not an array")); > +goto cleanup; > +} > + > +ndata = virJSONValueArraySize(data); > + > +for (i = 0; i < ndata; i++) { > +virJSONValuePtr entry = virJSONValueArrayGet(data, i); > +const char *name; > + > +if (!entry) { > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("array element missing in guest-info " > + "supported_commands")); > +goto cleanup; > +} > + > +if (!(name = virJSONValueObjectGetString(entry, "name"))) { > +virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("guest-info supported_commands was missing > name")); > +goto cleanup; > +} > + > +if (strcmp(name, cmdname) == 0) { > +ret = 1; > +goto cleanup; > +} > +} > + > +ret = 0; > + > + cleanup: > +virJSONValueFree(cmd); > +virJSONValueFree(reply); > +return ret; > +} > + > VIR_ENUM_DECL(qemuAgentShutdownMode); > > VIR_ENUM_IMPL(qemuAgentShutdownMode, > @@ -1346,8 +1415,16 @@ int qemuAgentFSFreeze(qemuAgentPtr mon, const char > **mountpoints, > return -1; > > if (qemuAgentCommand(mon, cmd, &reply, true, > - VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) > + VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) { > +if (mountpoints && nmountpoints) { > +if (qemuAgentCommandSupported(mon, > + "guest-fsfreeze-freeze-list") == 0) > +virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s", > + _("this version of guest agent doesn't > support " > + "specifying mountpoints")); > +} > goto cleanup; > +} > > if (virJSONValueObjectGetNumberInt(reply, "return", &ret) < 0) { > virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > It's not that I'm against this patch in general. I'm just against it now :) I mean, with current implementation libvirt doesn't know what qemu-ga is it talking to. The guest agent can come and go, without libvirt noticing anything [1]. So in this specific case, guest-info can be executed by say newer qemu-ga which does support guest-fsfreeze-freeze-list and thus direct libvirt to use it. But then the freeze command is executed by downgraded qemu-ga so user will still see the ugly error message. At qemu monitor level it makes sense to query supported comman
Re: [libvirt] [PATCH] qemu: Issue rtc_reset_reinjection command after guest-set-time
On 13.08.2014 18:30, Eric Blake wrote: On 08/13/2014 06:51 AM, Michal Privoznik wrote: s/_/-/2 in the subject line An advice appeared there on the qemu-devel list [1]. When a domain is suspended and then resumed guest kernel is not aware of this. So we've introduced virDomainSetTime API that resets the time within guest using qemu-ga. On the other hand, qemu itself is trying to make RTC beat faster to catch the difference. But if we don't tell qemu that guest's time was reset via the other method, both mechanisms are applied resulting in again wrong guest time. In order to avoid summing both corrections we need to tell qemu that it should not use the RTC injection if the guest time is set via guest agent. 1: http://www.mail-archive.com/qemu-devel@nongnu.org/msg236435.html Signed-off-by: Michal Privoznik --- +++ b/src/qemu/qemu_driver.c @@ -16879,6 +16879,16 @@ qemuDomainSetTime(virDomainPtr dom, rv = qemuAgentSetTime(priv->agent, seconds, nseconds, rtcSync); qemuDomainObjExitAgent(vm); +if (!virDomainObjIsActive(vm)) { +virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); +goto endjob; +} + +qemuDomainObjEnterMonitor(driver, vm); +rv = qemuMonitorRTCResetReinjection(priv->mon); +qemuDomainObjExitMonitor(driver, vm); This forces the command to fail if qemu is too old to have rtc-reset-reinjection but the agent is new enough to set time. Should you make this code conditional on whether qemu supports the QMP command? I'm not sure. If that's the case, both corrections will apply so guest ends up with incorrect time anyway. And if the API is to guarantee correctly set time, it must fail if such guarantees can't be made IMO. } + +int +qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon) +{ +int ret = -1; +virJSONValuePtr cmd; +virJSONValuePtr reply = NULL; + +if (!(cmd = qemuMonitorJSONMakeCommand("rtc-reset-reinjection", + NULL))) +return ret; + +ret = qemuMonitorJSONCommand(mon, cmd, &reply); + +if (ret == 0) +ret = qemuMonitorJSONCheckError(cmd, reply); + +virJSONValueFree(cmd); +virJSONValueFree(reply); +return ret; +} Is it worth enhancing the testsuite to add coverage for this command and expected response? Yeah. I'll post v2. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCHv2 libvirt] qemu: Issue rtc-reset-reinjection command after guest-set-time
https://bugzilla.redhat.com/show_bug.cgi?id=1103245 An advice appeared there on the qemu-devel list [1]. When a domain is suspended and then resumed guest kernel is not aware of this. So we've introduced virDomainSetTime API that resets the time within guest using qemu-ga. On the other hand, qemu itself is trying to make RTC beat faster to catch the difference. But if we don't tell qemu that guest's time was reset via the other method, both mechanisms are applied resulting in again wrong guest time. In order to avoid summing both corrections we need to tell qemu that it should not use the RTC injection if the guest time is set via guest agent. 1: http://www.mail-archive.com/qemu-devel@nongnu.org/msg236435.html Signed-off-by: Michal Privoznik --- Notes: diff to v1: -fixed command name in subject -added testcase src/qemu/qemu_driver.c | 10 ++ src/qemu/qemu_monitor.c | 33 + src/qemu/qemu_monitor.h | 2 ++ src/qemu/qemu_monitor_json.c | 21 + src/qemu/qemu_monitor_json.h | 2 ++ tests/qemumonitorjsontest.c | 1 + 6 files changed, 69 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b6219ba..bdfd155 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -16879,6 +16879,16 @@ qemuDomainSetTime(virDomainPtr dom, rv = qemuAgentSetTime(priv->agent, seconds, nseconds, rtcSync); qemuDomainObjExitAgent(vm); +if (!virDomainObjIsActive(vm)) { +virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); +goto endjob; +} + +qemuDomainObjEnterMonitor(driver, vm); +rv = qemuMonitorRTCResetReinjection(priv->mon); +qemuDomainObjExitMonitor(driver, vm); + if (rv < 0) goto endjob; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 3d9f87b..77627bc 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -4037,3 +4037,36 @@ qemuMonitorGetGuestCPU(qemuMonitorPtr mon, return qemuMonitorJSONGetGuestCPU(mon, arch, data); } + +/** + * qemuMonitorRTCResetReinjection: + * @mon: Pointer to the monitor + * + * Issue rtc-reset-reinjection command. + * This should be used in cases where guest time is restored via + * guest agent so RTC injection is not needed (in fact it will + * confuse guest's RTC). + * + * Returns 0 on success + *-1 on error. + */ +int +qemuMonitorRTCResetReinjection(qemuMonitorPtr mon) +{ + +VIR_DEBUG("mon=%p", mon); + +if (!mon) { +virReportError(VIR_ERR_INVALID_ARG, "%s", + _("monitor must not be NULL")); +return -1; +} + +if (!mon->json) { +virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("JSON monitor is required")); +return -1; +} + +return qemuMonitorJSONRTCResetReinjection(mon); +} diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index c3695f2..4fd6f01 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -790,6 +790,8 @@ int qemuMonitorGetGuestCPU(qemuMonitorPtr mon, virArch arch, virCPUDataPtr *data); +int qemuMonitorRTCResetReinjection(qemuMonitorPtr mon); + /** * When running two dd process and using <> redirection, we need a * shell that will not truncate files. These two strings serve that diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index a62c02f..538110c 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -5851,3 +5851,24 @@ qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon, return -1; } } + +int +qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon) +{ +int ret = -1; +virJSONValuePtr cmd; +virJSONValuePtr reply = NULL; + +if (!(cmd = qemuMonitorJSONMakeCommand("rtc-reset-reinjection", + NULL))) +return ret; + +ret = qemuMonitorJSONCommand(mon, cmd, &reply); + +if (ret == 0) +ret = qemuMonitorJSONCheckError(cmd, reply); + +virJSONValueFree(cmd); +virJSONValueFree(reply); +return ret; +} diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 5f6c846..d8c9308 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -437,4 +437,6 @@ int qemuMonitorJSONGetDeviceAliases(qemuMonitorPtr mon, int qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon, virArch arch, virCPUDataPtr *data); + +int qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon); #endif /* QEMU_MONITOR_JSON_H */ diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index baee80a..e3fb4f7 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjson
Re: [libvirt] [PATCH] conf: fix parsing 'cmd_per_lun' and 'max_sectors'
On 14.08.2014 09:55, Wang Rui wrote: From: Mo yuxiang commit d9504941 introduces two new attributes "cmd_per_lun" and "max_sectors" same with the names QEMU uses for virtio-scsi. But the case of parsing them is not exact. Change to parse them if controller has "driver" element. Signed-off-by: Mo yuxiang --- src/conf/domain_conf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 934f6cb..5c762fa 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6295,10 +6295,11 @@ virDomainControllerDefParseXML(xmlNodePtr node, cur = node->children; while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { -if (xmlStrEqual(cur->name, BAD_CAST "driver")) +if (xmlStrEqual(cur->name, BAD_CAST "driver")) { queues = virXMLPropString(cur, "queues"); cmd_per_lun = virXMLPropString(cur, "cmd_per_lun"); max_sectors = virXMLPropString(cur, "max_sectors"); +} } cur = cur->next; } ACKed and pushed. Unfortunately, the 1.2.7 release is broken so I'm pushing this into 1.2.7 maint branch too. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] build: force configure failed when perl is missing
On 14.08.2014 05:37, Jincheng Miao wrote: Perl is necessary to our build processing, it will invoke a lot of generating script, like: gendispatch.pl. If perl is missing, it's ok for build from git checkout, because autogen.sh will tell you. But for compiling from a release tarball, configure will just record a missing message, and continue, then build failed, like: https://www.redhat.com/archives/libvirt-users/2014-August/msg00050.html So need to enhance configure script to handle this negative case. Reported-by: Hongbin Lu Signed-off-by: Jincheng Miao --- configure.ac |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/configure.ac b/configure.ac index 081f298..af3fe28 100644 --- a/configure.ac +++ b/configure.ac @@ -2173,6 +2173,9 @@ AM_CONDITIONAL([WITH_HYPERV], [test "$with_hyperv" = "yes"]) dnl Allow perl/python overrides AC_PATH_PROGS([PYTHON], [python2 python]) AC_PATH_PROG([PERL], [perl]) +if test -z "$PERL"; then + AC_MSG_ERROR([Failed to find perl.]) +fi AC_ARG_WITH([test-suite], [AS_HELP_STRING([--with-test-suite], I'm inclined to ACK this. We currently have some files that can be built from git and are contained in the release so we cut off the set of required tools to build the libvirt. However, with so widely accessible tool as perl (which is almost everywhere) we don't need to do that. Moreover, there are some Makefile targets which have runtime dependency on perl, e.g. bracket-spacing-check syntax-check rule. And with this change I think we need this one too: diff --git a/libvirt.spec.in b/libvirt.spec.in index 29da071..f491de7 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -446,6 +446,7 @@ BuildRequires: gettext-devel BuildRequires: libtool BuildRequires: /usr/bin/pod2man %endif +BuildRequires: perl BuildRequires: python %if %{with_systemd} BuildRequires: systemd-units Again, I'm not expecting to see any RPM based distribution without perl (esp. if rpm-build package requires perl itself). But we should have it for completeness. So I'm squashing it in and pushing. ACK Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] fix
On 14.08.2014 10:41, Ján Tomko wrote: Also add qemuDomainChangeGraphicsPasswords, qemuProcessVerifyGuestCPU and qemuProcessInitPCIAddresses. Replace tabs by spaces. --- I'll do some testing on the patch and push it later with this squashed in if it works well. src/qemu/qemu_domain.c | 2 +- src/qemu/qemu_hotplug.c | 12 src/qemu/qemu_hotplug.h | 3 ++- src/qemu/qemu_process.c | 33 - 4 files changed, 31 insertions(+), 19 deletions(-) ACK to the original with this squashed in. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 00/66] vbox: Rewrite vbox domain driver
On 14.08.2014 17:50, Yohan Belleguic wrote: Le Wednesday 13 August 2014 17:18:44, Michal Privoznik a écrit : [CC-ing Yohan BELLEGUIC and Manuel VIVES] On 12.08.2014 17:31, Michal Privoznik wrote: On 11.08.2014 12:06, Taowei wrote: This series of patches rewrite the vbox's domain driver. The driver is separated into two parts: the version specified and the common part. The common driver use vboxUniformedAPI to build a general driver for all vbox versions. The vboxUniformedAPI take the responsiblity to communicate with virtualbox. Since there are some incompatible changes in virtualbox, vboxUniformedAPI should be aware of these changes and provide a uniformed api for the upper layer. The significant result of this patch is that we replace all vir${vbox_version}Driver into one virCommonDriver. So, we will have only one vbox driver implementation for all vbox versions in libvirt. PS: I have send part of my patches before: https://www.redhat.com/archives/libvir-list/2014-July/msg00937.html But I have to resend it beacuse I did some improvement on previous patches: *Remove the test case for vboxUniformedAPI, because it would raise "break strict-aliasing rules" warning in some distibutions *Merged the flag fdWatchNeedInitialize into domainEventCallbacks, So, we use one flag to indicate whether vbox support callbacks as well as we need to initialize variables for it. Taowei (66): vbox: Begin to rewrite, vboxConnectOpen vbox: Rewrite vboxConnectClose vbox: Rewrite vboxDomainSave vbox: Rewrite vboxConnectGetVersion vbox: Rewrite vboxConnectGetHostname vbox: Rewrite vboxConnectIsSecure vbox: Rewrite vboxConnectIsEncrypted vbox: Rewrite vboxConnectIsAlive vbox: Rewrite vboxConnectGetMaxVcpus vbox: Rewrite vboxConnectGetCapabilities vbox: Rewrite vboxConnectListDomains vbox: Rewrite vboxConnectNumOfDomains vbox: Rewrite vboxDomainLookupById vbox: Rewrite vboxDomainLookupByUUID vbox: Rewrite vboxDomainUndefineFlags vbox: Rewrite vboxDomainDefineXML vbox: Rewrite vboxDomainCreateWithFlags vbox: Rewrite vboxDomainCreate vbox: Rewrite vboxDomainCreateXML vbox: Rewrite vboxDomainLookupByName vbox: Rewrite vboxDomainIsActive vbox: Rewrite vboxDomainIsPersistent vbox: Rewrite vboxDomainIsUpdated vbox: Rewrite vboxDomainSuspend vbox: Rewrite vboxDomainResume vbox: Rewrite vboxDomainShutdownFlags vbox: Rewrite vboxDomainShutdown vbox: Rewrite vboxDomainReboot vbox: Rewrite vboxDomainDestroyFlags vbox: Rewrite vboxDomainDestroy vbox: Rewrite vboxDomainGetOSType vbox: Rewrite vboxDomainSetMemory vbox: Rewrite vboxDomainGetInfo vbox: Rewrite vboxDomainGetState vbox: Rewrite vboxDomainSetVcpusFlags vbox: Rewrite vboxDomainSetVcpus vbox: Rewrite vboxDomainGetVcpusFlags vbox: Rewrite vboxDomainGetMaxVcpus vbox: Add API for vboxDomainGetXMLDesc vbox: Rewrite vboxDomainGetXMLDesc vbox: Rewrite vboxConnectListDefinedDomains vbox: Rewrite vboxConnectNumOfDefinedDomains vbox: Rewrite vboxDomainUndefine vbox: Rewrite vboxDomainAttachDevice vbox: Rewrite vboxDomainAttachDeviceFlags vbox: Rewrite vboxDomainUpdateDeviceFlags vbox: Rewrite vboxDomainDetachDevice vbox: Rewrite vboxDomainDetachDeviceFlags vbox: Add API for vboxDomainSnapshotCreateXML vbox: Rewrite vboxDomainSnapshotCreateXML vbox: Rewrite vboxDomainSnapshotGetXMLDesc vbox: Rewrite vboxDomainSnapshotNum vbox: Rewrite vboxDomainSnapshotListNames vbox: Rewrite vboxSnapshotLookupByName vbox: Rewrite vboxDomainHasCurrentSnapshot vbox: Rewrite vboxDomainSnapshotGetParent vbox: Rewrite vboxDomainSnapshotCurrent vbox: Rewrite vboxDomainSnapshotIsCurrent vbox: Rewrite vboxDomainSnapshotHasMetadata vbox: Rewrite vboxDomainRevertToSnapshot vbox: Rewrite vboxDomainSnapshotDelete vbox: Rewrite vboxDomainScreenshot vbox: Rewrite vboxConnectListAllDomains vbox: Rewrite vboxNode functions vbox: Add registerDomainEvent vbox: Introducing vboxCommonDriver po/POTFILES.in|1 + src/Makefile.am |5 +- src/vbox/README |7 +- src/vbox/vbox_common.c| 7550 + src/vbox/vbox_common.h| 306 + src/vbox/vbox_driver.c| 40 +- src/vbox/vbox_install_api.h | 26 + src/vbox/vbox_tmpl.c |14557 + src/vbox/vbox_uniformed_api.h | 551 ++ 9 files changed, 13186 insertions(+), 9857 deletions(-) create mode 100644 src/vbox/vbox_common.c create mode 100644 src/vbox/vbox_common.h create mode 100644 src/vbox/vbox_install_api.h create mode 100644 src/vbox/vbox_uniformed_api.h ACK to all the patches. I've fixed all the small nits I found. I'm keeping the patches on my private branch for some time to give others time to share the
[libvirt] Virtual box storage and network sub-drivers
Dear list, Virtualbox driver has its own implementation of storage and network sub-drivers. But as of commit ba5f3c7c8ecc1037e44904916989a1c65777a9d5 (contained in the 1.0.6 release) when the VBox moved from client to daemon, the storage and network sub-drivers are indeed registered but in fact never called. It's due to our virConnectOpen function where the general network and storage drivers take precedence. So I guess my question is: should we drop the VBox sub-drivers or perhaps fix the virConnectOpen function? Reported-by: Taowei Luo Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] daemon: Fix driver registration ordering
There are some stateless drivers which implement subdrivers (typically vbox and its own network and storage subdrivers). However, as of ba5f3c7c8ecc10 the vbox driver lives in the daemon, not the client library. This means, in order for vbox (or any stateless domain driver) to use its subdrivers, it must register before the general drivers. Later, when the virConnectOpen function goes through the subdrivers, stateless drivers are searched first. If the connection request is aiming at stateless driver, it will be opened. Otherwise the generic subdriver is opened. The other change done in this commit is moving interface module load a bit earlier to match the ordering in case libvirt is built without driver modules. Reported-by: Taowei Luo Signed-off-by: Michal Privoznik --- daemon/libvirtd.c | 31 ++- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index a1f64ad..69baef6 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -365,10 +365,15 @@ static void daemonInitialize(void) { /* * Note that the order is important: the first ones have a higher - * priority when calling virStateInitialize. We must register - * the network, storage and nodedev drivers before any domain - * drivers, since their resources must be auto-started before - * any domains can be auto-started. + * priority when calling virStateInitialize. We must register the + * network, storage and nodedev drivers before any stateless + * domain drivers, since their resources must be auto-started + * before any domains can be auto-started. Moreover, some + * stateless drivers implement their own subdrivers (e.g. the vbox + * driver has its own network and storage subdriers) which need to + * have higher priority. Otherwise, when connecting the such + * driver generic subdriver may be opened instead of the one + * corresponding to the stateless driver. */ #ifdef WITH_DRIVER_MODULES /* We don't care if any of these fail, because the whole point @@ -376,9 +381,15 @@ static void daemonInitialize(void) * If they try to open a connection for a module that * is not loaded they'll get a suitable error at that point */ +# ifdef WITH_VBOX +virDriverLoadModule("vbox"); +# endif # ifdef WITH_NETWORK virDriverLoadModule("network"); # endif +# ifdef WITH_INTERFACE +virDriverLoadModule("interface"); +# endif # ifdef WITH_STORAGE virDriverLoadModule("storage"); # endif @@ -391,9 +402,6 @@ static void daemonInitialize(void) # ifdef WITH_NWFILTER virDriverLoadModule("nwfilter"); # endif -# ifdef WITH_INTERFACE -virDriverLoadModule("interface"); -# endif # ifdef WITH_XEN virDriverLoadModule("xen"); # endif @@ -409,13 +417,13 @@ static void daemonInitialize(void) # ifdef WITH_UML virDriverLoadModule("uml"); # endif -# ifdef WITH_VBOX -virDriverLoadModule("vbox"); -# endif # ifdef WITH_BHYVE virDriverLoadModule("bhyve"); # endif #else +# ifdef WITH_VBOX +vboxRegister(); +# endif # ifdef WITH_NETWORK networkRegister(); # endif @@ -449,9 +457,6 @@ static void daemonInitialize(void) # ifdef WITH_UML umlRegister(); # endif -# ifdef WITH_VBOX -vboxRegister(); -# endif # ifdef WITH_BHYVE bhyveRegister(); # endif -- 1.8.5.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 1/3] conf: Extend and introduce
Up to now, users can configure BIOS via the element. With the upcoming implementation of UEFI this is not enough as BIOS and UEFI are conceptually different. For instance, while BIOS is ROM, UEFI is programmable flash (although all writes to code section are denied). Therefore we need new attribute @type which will differentiate the two. Then, new attribute @readonly is introduced to reflect the fact that some images are RO. Moreover, the OVMF (which is going to be used mostly), works in two modes: 1) Code and UEFI variable store is mixed in one file. 2) Code and UEFI variable store is separated in two files The latter has advantage of updating the UEFI code without losing the configuration. However, in order to represent the latter case we need yet another XML element: . Currently, it has no additional attributes, it's just a bare element containing path to the variable store file. Signed-off-by: Michal Privoznik --- docs/formatdomain.html.in | 19 - docs/schemas/domaincommon.rng | 21 ++ src/conf/domain_conf.c | 87 +- src/conf/domain_conf.h | 22 +- src/libvirt_private.syms | 3 + src/qemu/qemu_command.c| 5 +- src/security/virt-aa-helper.c | 4 +- src/vbox/vbox_common.c | 7 +- src/xenapi/xenapi_driver.c | 3 +- src/xenxs/xen_sxpr.c | 16 ++-- src/xenxs/xen_xm.c | 7 +- tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.xml | 40 ++ .../qemuxml2xmlout-pci-bridge-many-disks.xml | 2 +- tests/qemuxml2xmltest.c| 2 + tests/sexpr2xmldata/sexpr2xml-fv-autoport.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-force-hpet.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-force-nohpet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-kernel.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-legacy-vfb.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-localtime.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-net-ioemu.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-net-netfront.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-parallel-tcp.xml | 2 +- .../sexpr2xml-fv-serial-dev-2-ports.xml| 2 +- .../sexpr2xml-fv-serial-dev-2nd-port.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-file.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-null.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-pipe.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-pty.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-stdio.xml | 2 +- .../sexpr2xml-fv-serial-tcp-telnet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-udp.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-unix.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-sound.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-usbmouse.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-usbtablet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-utc.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-v2.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml | 2 +- tests/xmconfigdata/test-escape-paths.xml | 2 +- tests/xmconfigdata/test-fullvirt-force-hpet.xml| 2 +- tests/xmconfigdata/test-fullvirt-force-nohpet.xml | 2 +- tests/xmconfigdata/test-fullvirt-localtime.xml | 2 +- tests/xmconfigdata/test-fullvirt-net-ioemu.xml | 2 +- tests/xmconfigdata/test-fullvirt-net-netfront.xml | 2 +- tests/xmconfigdata/test-fullvirt-new-cdrom.xml | 2 +- tests/xmconfigdata/test-fullvirt-old-cdrom.xml | 2 +- tests/xmconfigdata/test-fullvirt-parallel-tcp.xml | 2 +- .../test-fullvirt-serial-dev-2-ports.xml | 2 +- .../test-fullvirt-serial-dev-2nd-port.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-file.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-null.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-pipe.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-pty.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-stdio.xml | 2 +- .../test-fullvirt-serial-tcp-telnet.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-tcp.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-udp.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-unix.xml | 2 +- tests/xmconfigdata/test-fullvirt-sound.xml | 2 +- tests/xmconfigdata/test-fullvirt-usbmouse.xml | 2 +- tests/xmconfigdata/test-fullvirt-usbtablet.xml | 2 +- tests/xmconfigdata/test-fullvirt-utc.xml
[libvirt] [PATCH v2 0/3] OVMF exposure
diff to v1: - adapt to new code - restrict usage to x86_64 qemu guests - Adapted to Laszlo's suggestion for qemu.conf format Michal Privoznik (3): conf: Extend and introduce qemu: Implement extended loader and nvram qemu: Automatically create NVRAM store configure.ac | 1 - docs/formatdomain.html.in | 19 ++- docs/schemas/domaincommon.rng | 21 libvirt.spec.in| 2 + src/Makefile.am| 1 + src/conf/domain_conf.c | 87 +- src/conf/domain_conf.h | 22 +++- src/libvirt_private.syms | 3 + src/qemu/libvirtd_qemu.aug | 3 + src/qemu/qemu.conf | 14 +++ src/qemu/qemu_command.c| 97 ++- src/qemu/qemu_conf.c | 92 +++ src/qemu/qemu_conf.h | 5 + src/qemu/qemu_process.c| 131 + src/qemu/test_libvirtd_qemu.aug.in | 3 + src/security/security_dac.c| 8 ++ src/security/security_selinux.c| 8 ++ src/security/virt-aa-helper.c | 4 +- src/vbox/vbox_common.c | 7 +- src/xenapi/xenapi_driver.c | 3 +- src/xenxs/xen_sxpr.c | 16 +-- src/xenxs/xen_xm.c | 7 +- .../qemuxml2argvdata/qemuxml2argv-bios-nvram.args | 10 ++ tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.xml | 40 +++ tests/qemuxml2argvtest.c | 2 + .../qemuxml2xmlout-pci-bridge-many-disks.xml | 2 +- tests/qemuxml2xmltest.c| 2 + tests/sexpr2xmldata/sexpr2xml-fv-autoport.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-force-hpet.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-force-nohpet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-kernel.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-legacy-vfb.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-localtime.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-net-ioemu.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-net-netfront.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-parallel-tcp.xml | 2 +- .../sexpr2xml-fv-serial-dev-2-ports.xml| 2 +- .../sexpr2xml-fv-serial-dev-2nd-port.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-file.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-null.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-pipe.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-pty.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-stdio.xml | 2 +- .../sexpr2xml-fv-serial-tcp-telnet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-udp.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-unix.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-sound.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-usbmouse.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-usbtablet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-utc.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-v2.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml | 2 +- tests/xmconfigdata/test-escape-paths.xml | 2 +- tests/xmconfigdata/test-fullvirt-force-hpet.xml| 2 +- tests/xmconfigdata/test-fullvirt-force-nohpet.xml | 2 +- tests/xmconfigdata/test-fullvirt-localtime.xml | 2 +- tests/xmconfigdata/test-fullvirt-net-ioemu.xml | 2 +- tests/xmconfigdata/test-fullvirt-net-netfront.xml | 2 +- tests/xmconfigdata/test-fullvirt-new-cdrom.xml | 2 +- tests/xmconfigdata/test-fullvirt-old-cdrom.xml | 2 +- tests/xmconfigdata/test-fullvirt-parallel-tcp.xml | 2 +- .../test-fullvirt-serial-dev-2-ports.xml | 2 +- .../test-fullvirt-serial-dev-2nd-port.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-file.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-null.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-pipe.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-pty.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-stdio.xml | 2 +- .../test-fullvirt-serial-tcp-telnet.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-tcp.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-udp.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-unix.xml | 2 +- tests/xmconfigdata/test-ful
[libvirt] [PATCH v2 3/3] qemu: Automatically create NVRAM store
When using split UEFI image, it may come handy if libvirt manages per domain _VARS file automatically. While the _CODE file is RO and can be shared among multiple domains, you certainly don't want to do that on the _VARS file. This latter one needs to be per domain. So at the domain startup process, if it's determined that domain needs _VARS file it's copied from this master _VARS file. The location of the master file is configurable in qemu.conf. Signed-off-by: Michal Privoznik --- configure.ac | 1 - libvirt.spec.in| 2 + src/Makefile.am| 1 + src/qemu/libvirtd_qemu.aug | 3 + src/qemu/qemu.conf | 14 src/qemu/qemu_conf.c | 92 ++ src/qemu/qemu_conf.h | 5 ++ src/qemu/qemu_process.c| 131 + src/qemu/test_libvirtd_qemu.aug.in | 3 + 9 files changed, 251 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index af3fe28..8668e60 100644 --- a/configure.ac +++ b/configure.ac @@ -1418,7 +1418,6 @@ platform]) fi AM_CONDITIONAL([VIR_CHRDEV_LOCK_FILE_PATH], [test "$with_chrdev_lock_files" != "no"]) - AC_ARG_WITH([secdriver-selinux], [AS_HELP_STRING([--with-secdriver-selinux], [use SELinux security driver @<:@default=check@:>@])], diff --git a/libvirt.spec.in b/libvirt.spec.in index f491de7..762b404 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1948,6 +1948,7 @@ exit 0 %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/target/ +%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/ %{_datadir}/augeas/lenses/libvirtd_qemu.aug %{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug @@ -2050,6 +2051,7 @@ exit 0 %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/target/ +%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/ %{_datadir}/augeas/lenses/libvirtd_qemu.aug %{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug diff --git a/src/Makefile.am b/src/Makefile.am index f69923f..78ef54e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2643,6 +2643,7 @@ endif WITH_SANLOCK if WITH_QEMU $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/qemu" $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/qemu/channel/target" + $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/qemu/nvram" $(MKDIR_P) "$(DESTDIR)$(localstatedir)/run/libvirt/qemu" $(MKDIR_P) "$(DESTDIR)$(localstatedir)/cache/libvirt/qemu" $(MKDIR_P) "$(DESTDIR)$(localstatedir)/log/libvirt/qemu" diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index e7db7fe..62951da 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -88,6 +88,8 @@ module Libvirtd_qemu = let log_entry = bool_entry "log_timestamp" + let nvram_entry = str_array_entry "nvram" + (* Each entry in the config is one of the following ... *) let entry = vnc_entry | spice_entry @@ -100,6 +102,7 @@ module Libvirtd_qemu = | rpc_entry | network_entry | log_entry + | nvram_entry let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ] let empty = [ label "#empty" . eol ] diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 7bbbe09..79bba36 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -487,3 +487,17 @@ # Defaults to 1. # #log_timestamp = 0 + + +# Location of master nvram file +# +# When a domain is configured to use UEFI instead of standard +# BIOS it may use a separate storage for UEFI variables. If +# that's the case libvirt creates the variable store per domain +# using this master file as image. Each UEFI firmware can, +# however, have different variables store. Therefore the nvram is +# a list of strings when a single item is in form of: +# ${PATH_TO_UEFI_FW}:${PATH_TO_UEFI_VARS}. +# Later, when libvirt creates per domain variable store, this +# list is searched for the master image. +#nvram = [ "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.
[libvirt] [PATCH v2 2/3] qemu: Implement extended loader and nvram
QEMU now supports UEFI with the following command line: -drive file=/usr/share/OVMF/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on \ -drive file=/usr/share/OVMF/OVMF_VARS.fd,if=pflash,format=raw,unit=1 \ where the first line reflects and the second one . Moreover, these two lines obsoletes the -bios argument. Note that UEFI is unusable without ACPI. This is handled properly now. Among with this extension, the variable file is expected to be writable and hence we need security drivers to label it. Signed-off-by: Michal Privoznik --- src/qemu/qemu_command.c| 94 +- src/security/security_dac.c| 8 ++ src/security/security_selinux.c| 8 ++ .../qemuxml2argvdata/qemuxml2argv-bios-nvram.args | 10 +++ tests/qemuxml2argvtest.c | 2 + 5 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.args diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 5142e2a..fe6b329 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7294,6 +7294,94 @@ qemuBuildChrDeviceCommandLine(virCommandPtr cmd, return 0; } +static int +qemuBuilDomainLoaderCommandLine(virCommandPtr cmd, +virDomainDefPtr def, +virQEMUCapsPtr qemuCaps) +{ +int ret = -1; +virDomainLoaderDefPtr loader = def->os.loader; +virBuffer buf = VIR_BUFFER_INITIALIZER; +int unit = 0; + +if (!loader) +return 0; + +switch ((virDomainLoader) loader->type) { +case VIR_DOMAIN_LOADER_TYPE_ROM: +virCommandAddArg(cmd, "-bios"); +virCommandAddArg(cmd, loader->path); +break; + +case VIR_DOMAIN_LOADER_TYPE_PFLASH: +/* UEFI is supported inly for x86_64 currently */ +if (def->os.arch != VIR_ARCH_X86_64) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("pflash is not supported for %s guest achitecture"), + virArchToString(def->os.arch)); +goto cleanup; +} + +if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support -drive")); +goto cleanup; +} +if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_FORMAT)) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support passing " + "drive format")); +goto cleanup; +} +if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_ACPI) && +def->features[VIR_DOMAIN_FEATURE_ACPI] != VIR_TRISTATE_SWITCH_ON) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("ACPI must be enabled in order to use UEFI")); +goto cleanup; +} + +virBufferAsprintf(&buf, + "file=%s,if=pflash,format=raw,unit=%d", + loader->path, unit); +unit++; + +if (loader->readonly) { +if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_READONLY)) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support passing " + "readonly attribute")); +goto cleanup; +} + +virBufferAsprintf(&buf, ",readonly=%s", + virTristateSwitchTypeToString(loader->readonly)); +} + +virCommandAddArg(cmd, "-drive"); +virCommandAddArgBuffer(cmd, &buf); + +if (loader->nvram) { +virBufferFreeAndReset(&buf); +virBufferAsprintf(&buf, + "file=%s,if=pflash,format=raw,unit=%d", + loader->nvram, unit); + +virCommandAddArg(cmd, "-drive"); +virCommandAddArgBuffer(cmd, &buf); +} +break; + +case VIR_DOMAIN_LOADER_TYPE_LAST: +/* nada */ +break; +} + +ret = 0; + cleanup: +virBufferFreeAndReset(&buf); +return ret; +} + qemuBuildCommandLineCallbacks buildCommandLineCallbacks = { .qemuGetSCSIDeviceSgName = virSCSIDeviceGetSgName, }; @@ -7449,10 +7537,8 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-enable-nesting"); } -if (def->os.loader) { -virCommandAddArg(cmd, "-bios"); -virCommandAddArg(cmd, def->os.loader->path); -} +if (qemuBuilDomainLoaderCommandLine(cmd, def, qemuCap
Re: [libvirt] [PATCH v2 1/3] conf: Extend and introduce
On 15.08.2014 16:13, Laszlo Ersek wrote: On 08/15/14 15:43, Michal Privoznik wrote: Up to now, users can configure BIOS via the element. With the upcoming implementation of UEFI this is not enough as BIOS and UEFI are conceptually different. For instance, while BIOS is ROM, UEFI is programmable flash (although all writes to code section are denied). Therefore we need new attribute @type which will differentiate the two. Then, new attribute @readonly is introduced to reflect the fact that some images are RO. Moreover, the OVMF (which is going to be used mostly), works in two modes: 1) Code and UEFI variable store is mixed in one file. 2) Code and UEFI variable store is separated in two files The latter has advantage of updating the UEFI code without losing the configuration. However, in order to represent the latter case we need yet another XML element: . Currently, it has no additional attributes, it's just a bare element containing path to the variable store file. I compared this version against v1 1/3, and my earlier notes on that v1 patch. It looks good to me. I don't know enough about libvirt to give an R-b that's really worth its face value, so I'll just ack. Acked-by: Laszlo Ersek In addition, is there an easy way for me to test this patchset? I can pluck the series from the list, apply it manually to my upstream clone, build etc. My main question is if there's going to be some interference with my "normal", RHEL-7, system-wide libvirtd installation. No, there shouldn't be any interference unless you 'make install'. If I follow <http://libvirt.org/deployment.html> and just install (as non-root) to a private --prefix, will that just work? I vaguely remember that I did get this working once before (when I was working on commits ccca5dc3 and 51e184e9), but I don't remember any longer. You don't need even need to use that. I have libvirt installed via the packaging system on my distribution too and all I do is: ./autogen.sh --system && make then I run (as root) ./run daemon/libvirtd and that's it. Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 2/3] qemu: Implement extended loader and nvram
QEMU now supports UEFI with the following command line: -drive file=/usr/share/OVMF/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on \ -drive file=/usr/share/OVMF/OVMF_VARS.fd,if=pflash,format=raw,unit=1 \ where the first line reflects and the second one . Moreover, these two lines obsoletes the -bios argument. Note that UEFI is unusable without ACPI. This is handled properly now. Among with this extension, the variable file is expected to be writable and hence we need security drivers to label it. Signed-off-by: Michal Privoznik --- src/qemu/qemu_command.c| 94 +- src/security/security_dac.c| 8 ++ src/security/security_selinux.c| 8 ++ .../qemuxml2argvdata/qemuxml2argv-bios-nvram.args | 10 +++ tests/qemuxml2argvtest.c | 2 + 5 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.args diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 5142e2a..a8159d8 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7294,6 +7294,94 @@ qemuBuildChrDeviceCommandLine(virCommandPtr cmd, return 0; } +static int +qemuBuilDomainLoaderCommandLine(virCommandPtr cmd, +virDomainDefPtr def, +virQEMUCapsPtr qemuCaps) +{ +int ret = -1; +virDomainLoaderDefPtr loader = def->os.loader; +virBuffer buf = VIR_BUFFER_INITIALIZER; +int unit = 0; + +if (!loader) +return 0; + +switch ((virDomainLoader) loader->type) { +case VIR_DOMAIN_LOADER_TYPE_ROM: +virCommandAddArg(cmd, "-bios"); +virCommandAddArg(cmd, loader->path); +break; + +case VIR_DOMAIN_LOADER_TYPE_PFLASH: +/* UEFI is supported only for x86_64 currently */ +if (def->os.arch != VIR_ARCH_X86_64) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("pflash is not supported for %s guest achitecture"), + virArchToString(def->os.arch)); +goto cleanup; +} + +if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support -drive")); +goto cleanup; +} +if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_FORMAT)) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support passing " + "drive format")); +goto cleanup; +} +if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_ACPI) && +def->features[VIR_DOMAIN_FEATURE_ACPI] != VIR_TRISTATE_SWITCH_ON) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("ACPI must be enabled in order to use UEFI")); +goto cleanup; +} + +virBufferAsprintf(&buf, + "file=%s,if=pflash,format=raw,unit=%d", + loader->path, unit); +unit++; + +if (loader->readonly) { +if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_READONLY)) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support passing " + "readonly attribute")); +goto cleanup; +} + +virBufferAsprintf(&buf, ",readonly=%s", + virTristateSwitchTypeToString(loader->readonly)); +} + +virCommandAddArg(cmd, "-drive"); +virCommandAddArgBuffer(cmd, &buf); + +if (loader->nvram) { +virBufferFreeAndReset(&buf); +virBufferAsprintf(&buf, + "file=%s,if=pflash,format=raw,unit=%d", + loader->nvram, unit); + +virCommandAddArg(cmd, "-drive"); +virCommandAddArgBuffer(cmd, &buf); +} +break; + +case VIR_DOMAIN_LOADER_TYPE_LAST: +/* nada */ +break; +} + +ret = 0; + cleanup: +virBufferFreeAndReset(&buf); +return ret; +} + qemuBuildCommandLineCallbacks buildCommandLineCallbacks = { .qemuGetSCSIDeviceSgName = virSCSIDeviceGetSgName, }; @@ -7449,10 +7537,8 @@ qemuBuildCommandLine(virConnectPtr conn, virCommandAddArg(cmd, "-enable-nesting"); } -if (def->os.loader) { -virCommandAddArg(cmd, "-bios"); -virCommandAddArg(cmd, def->os.loader->path); -} +if (qemuBuilDomainLoaderCommandLine(cmd, def, qemuCap
[libvirt] [PATCH v3 3/3] qemu: Automatically create NVRAM store
When using split UEFI image, it may come handy if libvirt manages per domain _VARS file automatically. While the _CODE file is RO and can be shared among multiple domains, you certainly don't want to do that on the _VARS file. This latter one needs to be per domain. So at the domain startup process, if it's determined that domain needs _VARS file it's copied from this master _VARS file. The location of the master file is configurable in qemu.conf. Signed-off-by: Michal Privoznik --- libvirt.spec.in| 2 + src/Makefile.am| 1 + src/qemu/libvirtd_qemu.aug | 3 + src/qemu/qemu.conf | 14 src/qemu/qemu_conf.c | 93 ++ src/qemu/qemu_conf.h | 5 ++ src/qemu/qemu_process.c| 132 + src/qemu/test_libvirtd_qemu.aug.in | 3 + 8 files changed, 253 insertions(+) diff --git a/libvirt.spec.in b/libvirt.spec.in index f491de7..762b404 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1948,6 +1948,7 @@ exit 0 %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/target/ +%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/ %{_datadir}/augeas/lenses/libvirtd_qemu.aug %{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug @@ -2050,6 +2051,7 @@ exit 0 %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/target/ +%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/ %dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/ %{_datadir}/augeas/lenses/libvirtd_qemu.aug %{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug diff --git a/src/Makefile.am b/src/Makefile.am index f69923f..78ef54e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2643,6 +2643,7 @@ endif WITH_SANLOCK if WITH_QEMU $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/qemu" $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/qemu/channel/target" + $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/qemu/nvram" $(MKDIR_P) "$(DESTDIR)$(localstatedir)/run/libvirt/qemu" $(MKDIR_P) "$(DESTDIR)$(localstatedir)/cache/libvirt/qemu" $(MKDIR_P) "$(DESTDIR)$(localstatedir)/log/libvirt/qemu" diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug index e7db7fe..62951da 100644 --- a/src/qemu/libvirtd_qemu.aug +++ b/src/qemu/libvirtd_qemu.aug @@ -88,6 +88,8 @@ module Libvirtd_qemu = let log_entry = bool_entry "log_timestamp" + let nvram_entry = str_array_entry "nvram" + (* Each entry in the config is one of the following ... *) let entry = vnc_entry | spice_entry @@ -100,6 +102,7 @@ module Libvirtd_qemu = | rpc_entry | network_entry | log_entry + | nvram_entry let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ] let empty = [ label "#empty" . eol ] diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 7bbbe09..79bba36 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -487,3 +487,17 @@ # Defaults to 1. # #log_timestamp = 0 + + +# Location of master nvram file +# +# When a domain is configured to use UEFI instead of standard +# BIOS it may use a separate storage for UEFI variables. If +# that's the case libvirt creates the variable store per domain +# using this master file as image. Each UEFI firmware can, +# however, have different variables store. Therefore the nvram is +# a list of strings when a single item is in form of: +# ${PATH_TO_UEFI_FW}:${PATH_TO_UEFI_VARS}. +# Later, when libvirt creates per domain variable store, this +# list is searched for the master image. +#nvram = [ "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd" ] diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 238d2b1..195fe8e 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -107,6 +107,9 @@ void qemuDomainCmdlineDefFree(qemuDomainCmdlineDefPtr def) VIR_FREE(def); } +#define VIR_QEMU_LOADER_FILE_PATH "/usr/share/OVMF/OVMF_CODE.fd" +#define VIR_QEMU_NVRAM_FILE_PATH "/usr/share/OVMF/OVMF_VARS.fd" + virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged) { vi
[libvirt] [PATCH v3 1/3] conf: Extend and introduce
Up to now, users can configure BIOS via the element. With the upcoming implementation of UEFI this is not enough as BIOS and UEFI are conceptually different. For instance, while BIOS is ROM, UEFI is programmable flash (although all writes to code section are denied). Therefore we need new attribute @type which will differentiate the two. Then, new attribute @readonly is introduced to reflect the fact that some images are RO. Moreover, the OVMF (which is going to be used mostly), works in two modes: 1) Code and UEFI variable store is mixed in one file. 2) Code and UEFI variable store is separated in two files The latter has advantage of updating the UEFI code without losing the configuration. However, in order to represent the latter case we need yet another XML element: . Currently, it has no additional attributes, it's just a bare element containing path to the variable store file. Signed-off-by: Michal Privoznik --- docs/formatdomain.html.in | 19 - docs/schemas/domaincommon.rng | 21 ++ src/conf/domain_conf.c | 87 +- src/conf/domain_conf.h | 22 +- src/libvirt_private.syms | 3 + src/qemu/qemu_command.c| 5 +- src/security/virt-aa-helper.c | 4 +- src/vbox/vbox_common.c | 7 +- src/xenapi/xenapi_driver.c | 3 +- src/xenxs/xen_sxpr.c | 16 ++-- src/xenxs/xen_xm.c | 7 +- tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.xml | 40 ++ .../qemuxml2xmlout-pci-bridge-many-disks.xml | 2 +- tests/qemuxml2xmltest.c| 2 + tests/sexpr2xmldata/sexpr2xml-fv-autoport.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-force-hpet.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-force-nohpet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-kernel.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-legacy-vfb.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-localtime.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-net-ioemu.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-net-netfront.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-parallel-tcp.xml | 2 +- .../sexpr2xml-fv-serial-dev-2-ports.xml| 2 +- .../sexpr2xml-fv-serial-dev-2nd-port.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-file.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-null.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-pipe.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-pty.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-stdio.xml | 2 +- .../sexpr2xml-fv-serial-tcp-telnet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-udp.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-unix.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-sound.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-usbmouse.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-usbtablet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-utc.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-v2.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml | 2 +- tests/xmconfigdata/test-escape-paths.xml | 2 +- tests/xmconfigdata/test-fullvirt-force-hpet.xml| 2 +- tests/xmconfigdata/test-fullvirt-force-nohpet.xml | 2 +- tests/xmconfigdata/test-fullvirt-localtime.xml | 2 +- tests/xmconfigdata/test-fullvirt-net-ioemu.xml | 2 +- tests/xmconfigdata/test-fullvirt-net-netfront.xml | 2 +- tests/xmconfigdata/test-fullvirt-new-cdrom.xml | 2 +- tests/xmconfigdata/test-fullvirt-old-cdrom.xml | 2 +- tests/xmconfigdata/test-fullvirt-parallel-tcp.xml | 2 +- .../test-fullvirt-serial-dev-2-ports.xml | 2 +- .../test-fullvirt-serial-dev-2nd-port.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-file.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-null.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-pipe.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-pty.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-stdio.xml | 2 +- .../test-fullvirt-serial-tcp-telnet.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-tcp.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-udp.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-unix.xml | 2 +- tests/xmconfigdata/test-fullvirt-sound.xml | 2 +- tests/xmconfigdata/test-fullvirt-usbmouse.xml | 2 +- tests/xmconfigdata/test-fullvirt-usbtablet.xml | 2 +- tests/xmconfigdata/test-fullvirt-utc.xml
[libvirt] [PATCH v3 0/3] OVMF exposure
diff to v2: -Adapted to Laszlo's review on v2 Michal Privoznik (3): conf: Extend and introduce qemu: Implement extended loader and nvram qemu: Automatically create NVRAM store docs/formatdomain.html.in | 19 ++- docs/schemas/domaincommon.rng | 21 libvirt.spec.in| 2 + src/Makefile.am| 1 + src/conf/domain_conf.c | 87 +- src/conf/domain_conf.h | 22 +++- src/libvirt_private.syms | 3 + src/qemu/libvirtd_qemu.aug | 3 + src/qemu/qemu.conf | 14 +++ src/qemu/qemu_command.c| 97 ++- src/qemu/qemu_conf.c | 93 +++ src/qemu/qemu_conf.h | 5 + src/qemu/qemu_process.c| 132 + src/qemu/test_libvirtd_qemu.aug.in | 3 + src/security/security_dac.c| 8 ++ src/security/security_selinux.c| 8 ++ src/security/virt-aa-helper.c | 4 +- src/vbox/vbox_common.c | 7 +- src/xenapi/xenapi_driver.c | 3 +- src/xenxs/xen_sxpr.c | 16 +-- src/xenxs/xen_xm.c | 7 +- .../qemuxml2argvdata/qemuxml2argv-bios-nvram.args | 10 ++ tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.xml | 40 +++ tests/qemuxml2argvtest.c | 2 + .../qemuxml2xmlout-pci-bridge-many-disks.xml | 2 +- tests/qemuxml2xmltest.c| 2 + tests/sexpr2xmldata/sexpr2xml-fv-autoport.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-force-hpet.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-force-nohpet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-kernel.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-legacy-vfb.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-localtime.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-net-ioemu.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-net-netfront.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-parallel-tcp.xml | 2 +- .../sexpr2xml-fv-serial-dev-2-ports.xml| 2 +- .../sexpr2xml-fv-serial-dev-2nd-port.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-file.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-null.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-pipe.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-pty.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-stdio.xml | 2 +- .../sexpr2xml-fv-serial-tcp-telnet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-udp.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv-serial-unix.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-sound.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-usbmouse.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-usbtablet.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-utc.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-fv-v2.xml| 2 +- tests/sexpr2xmldata/sexpr2xml-fv.xml | 2 +- tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml | 2 +- tests/xmconfigdata/test-escape-paths.xml | 2 +- tests/xmconfigdata/test-fullvirt-force-hpet.xml| 2 +- tests/xmconfigdata/test-fullvirt-force-nohpet.xml | 2 +- tests/xmconfigdata/test-fullvirt-localtime.xml | 2 +- tests/xmconfigdata/test-fullvirt-net-ioemu.xml | 2 +- tests/xmconfigdata/test-fullvirt-net-netfront.xml | 2 +- tests/xmconfigdata/test-fullvirt-new-cdrom.xml | 2 +- tests/xmconfigdata/test-fullvirt-old-cdrom.xml | 2 +- tests/xmconfigdata/test-fullvirt-parallel-tcp.xml | 2 +- .../test-fullvirt-serial-dev-2-ports.xml | 2 +- .../test-fullvirt-serial-dev-2nd-port.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-file.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-null.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-pipe.xml | 2 +- tests/xmconfigdata/test-fullvirt-serial-pty.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-stdio.xml | 2 +- .../test-fullvirt-serial-tcp-telnet.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-tcp.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-udp.xml| 2 +- tests/xmconfigdata/test-fullvirt-serial-unix.xml | 2 +- tests/xmconfigdata/test-fullvirt-sound.xml | 2 +- tests/xmconfigdata/test-fullvirt-usbmouse.xml | 2 +- tests/xmconfigdata/test-fullvirt-usbtable
Re: [libvirt] [PATCHv2 libvirt] qemu: Issue rtc-reset-reinjection command after guest-set-time
On 18.08.2014 17:28, Eric Blake wrote: On 08/14/2014 02:24 AM, Michal Privoznik wrote: https://bugzilla.redhat.com/show_bug.cgi?id=1103245 An advice appeared there on the qemu-devel list [1]. When a domain is suspended and then resumed guest kernel is not aware of this. So we've introduced virDomainSetTime API that resets the time within guest using qemu-ga. On the other hand, qemu itself is trying to make RTC beat faster to catch the difference. But if we don't tell qemu that guest's time was reset via the other method, both mechanisms are applied resulting in again wrong guest time. In order to avoid summing both corrections we need to tell qemu that it should not use the RTC injection if the guest time is set via guest agent. 1: http://www.mail-archive.com/qemu-devel@nongnu.org/msg236435.html Signed-off-by: Michal Privoznik --- Notes: diff to v1: -fixed command name in subject -added testcase +++ b/src/qemu/qemu_driver.c @@ -16879,6 +16879,16 @@ qemuDomainSetTime(virDomainPtr dom, rv = qemuAgentSetTime(priv->agent, seconds, nseconds, rtcSync); qemuDomainObjExitAgent(vm); +if (!virDomainObjIsActive(vm)) { +virReportError(VIR_ERR_OPERATION_INVALID, + "%s", _("domain is not running")); +goto endjob; +} + +qemuDomainObjEnterMonitor(driver, vm); +rv = qemuMonitorRTCResetReinjection(priv->mon); +qemuDomainObjExitMonitor(driver, vm); We have four combinations: 1. old qemu, old qga: command fails because qga doesn't support it, qemu tries to catch up time manually (might eventually match real time) 2. new qemu, old qga: command fails because qga doesn't support it, qemu tries to catch up time manually (might eventually match real time) 3. new qemu, new qga: both qga and qemu commands work, no additional catchup attempted and guest is now accurate 4. old qemu, new qga: qga succeeds, but qemu command fails, so we have overcorrected and qemu is trying to catch up time manually (overcorrected, so it cannot match real time) I guess reporting failure in those three cases is fine, although I'm still worried about case 4. I'd feel a lot better if there were a qemu_capabilities.h bit that detects if the qemu command is present, and skip even attempting the qga command unless we ALSO know the qemu command is present (that is, use the capability check to completely avoid case 4, by turning it into the same behavior as case 1). Okay. Although I've just realized one (corner) case. From my understanding of rtc-reset-reinjection time it's only necessary if guest was suspended for a while and the guest's RTC clock skewed. But what if I start fresh new guest and just want to set its time (leave aside the reasoning why would I do that for a while)? Is the rtc-reset-reinjection necessary? I wouldn't say. But on the other hand - libvirt doesn't know if the RTC is synced already or not. Hence it's safer for libvirt to issue the command every single time. In fact, there are two ways to set guest time: a) {"execute":"guest-set-time"} b) {"execute":"guest-set-time, "arguments":{"time":1234567890}} While in the case a) guest time is set by reading from guest's RTC, in case of b) guest time is set by calling settimeofday() and RTC is written thereafter. So is the rtc-reset-reinjection necessary only for case a) and in case b) QEMU somehow detects RTC write and cancels the reinjection itself? Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list