[libvirt] [PATCH 0/5 v2] parallels: Better bridged network interfaces support and some fixes
v2 changes: - syntax check fixed - patches reordered and split - dealing with failed bridged network information fixed Maxim Nestratov (4): parallels: don't forget to unlock domain if unregister fails parallels: better bridge network interface support parallels: fix home directory for VMs parallels: fix initialization of parallels driver Mikhail Feoktistov (1): parallels: set cpu mode when applying xml configuration -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/5] parallels: set cpu mode when applying xml configuration
From: Mikhail Feoktistov mfeoktis...@parallels.com Otherwise exporting existing domain config and defining a new one like this: virsh -c parallels:///system dumpxml instance01 my.xml virsh -c parallels:///system define my.xml leads to an error because PCS default x64 mode turns to x32. Thus, we need to set correct cpuMode in prlsdkDoApplyConfig() explicitly. Signed-off-by: Mikhail Feoktistov mfeoktis...@parallels.com Signed-off-by: Maxim Nestratov mnestra...@parallels.com --- src/parallels/parallels_sdk.c | 13 + 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index d0d2ce2..f49155b 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -2794,6 +2794,19 @@ prlsdkDoApplyConfig(PRL_HANDLE sdkdom, pret = PrlVmCfg_SetCpuCount(sdkdom, def-vcpus); prlsdkCheckRetGoto(pret, error); +switch (def-os.arch) { +case VIR_ARCH_X86_64: +pret = PrlVmCfg_SetCpuMode(sdkdom, PCM_CPU_MODE_64); +break; +case VIR_ARCH_I686: +pret = PrlVmCfg_SetCpuMode(sdkdom, PCM_CPU_MODE_32); +break; +default: +virReportError(VIR_ERR_INTERNAL_ERROR, _(Unknown CPU mode: %X), def-os.arch); +goto error; +} +prlsdkCheckRetGoto(pret, error); + if (prlsdkClearDevices(sdkdom) 0) goto error; -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/5] parallels: don't forget to unlock domain if unregister fails
Signed-off-by: Maxim Nestratov mnestra...@parallels.com --- src/parallels/parallels_driver.c |7 ++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c index c9338b5..90b8b0a 100644 --- a/src/parallels/parallels_driver.c +++ b/src/parallels/parallels_driver.c @@ -938,6 +938,7 @@ parallelsDomainUndefineFlags(virDomainPtr domain, { parallelsConnPtr privconn = domain-conn-privateData; virDomainObjPtr dom = NULL; +int ret; virCheckFlags(0, -1); @@ -947,7 +948,11 @@ parallelsDomainUndefineFlags(virDomainPtr domain, return -1; } -return prlsdkUnregisterDomain(privconn, dom); +ret = prlsdkUnregisterDomain(privconn, dom); +if (ret) + virObjectUnlock(dom); + +return ret; } static int -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/5] parallels: better bridge network interface support
In order to support 'bridge' network adapters in parallels driver we need to plug our veth devices into corresponding linux bridges. We are going to do this by reusing our abstraction of Virtual Networks in terms of PCS. On a domain creation, we create a new Virtual Network naming it with the same name as a source bridge for each network interface. Thus, we plug PCS veth interfaces created with names of target dev with specified bridges using our standard PCS procedures. Signed-off-by: Maxim Nestratov mnestra...@parallels.com --- src/parallels/parallels_sdk.c | 114 --- src/parallels/parallels_utils.h |1 + 2 files changed, 96 insertions(+), 19 deletions(-) diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index f49155b..a324cc5 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -689,12 +689,8 @@ prlsdkGetNetInfo(PRL_HANDLE netAdapter, virDomainNetDefPtr net, bool isCt) net-type = VIR_DOMAIN_NET_TYPE_NETWORK; - /* use device name, shown by prlctl as target device * for identifying network adapter in virDomainDefineXML */ -pret = PrlVmDev_GetIndex(netAdapter, netAdapterIndex); -prlsdkCheckRetGoto(pret, cleanup); - pret = PrlVmDevNet_GetHostInterfaceName(netAdapter, NULL, buflen); prlsdkCheckRetGoto(pret, cleanup); @@ -702,7 +698,10 @@ prlsdkGetNetInfo(PRL_HANDLE netAdapter, virDomainNetDefPtr net, bool isCt) goto cleanup; pret = PrlVmDevNet_GetHostInterfaceName(netAdapter, net-ifname, buflen); -prlsdkCheckRetGoto(pret, cleanup); +prlsdkCheckRetGoto(pret, cleanup); + +pret = PrlVmDev_GetIndex(netAdapter, netAdapterIndex); +prlsdkCheckRetGoto(pret, cleanup); if (isCt netAdapterIndex == (PRL_UINT32) -1) { /* venet devices don't have mac address and @@ -741,6 +740,15 @@ prlsdkGetNetInfo(PRL_HANDLE netAdapter, virDomainNetDefPtr net, bool isCt) net-data.network.name, buflen); prlsdkCheckRetGoto(pret, cleanup); + +/* + * We use VIR_DOMAIN_NET_TYPE_NETWORK for all network adapters + * except those whose Virtual Network Id differ from Parallels + * predefined ones such as PARALLELS_BRIDGED_NETWORK_NAME and PARALLELS_ROUTED_NETWORK_NAME + */ +if (!STREQ(net-data.network.name, PARALLELS_BRIDGED_NETWORK_NAME)) +net-type = VIR_DOMAIN_NET_TYPE_BRIDGE; + } pret = PrlVmDev_IsConnected(netAdapter, isConnected); @@ -1344,7 +1352,6 @@ prlsdkLoadDomains(parallelsConnPtr privconn) error: PrlHandle_Free(result); -PrlHandle_Free(job); return -1; } @@ -1724,8 +1731,6 @@ prlsdkDomainChangeState(virDomainPtr domain, pdom = dom-privateData; pret = chstate(privconn, pdom-sdkdom); -virReportError(VIR_ERR_OPERATION_FAILED, - _(Can't change domain state: %d), pret); if (PRL_FAILED(pret)) { virResetLastError(); @@ -2554,10 +2559,12 @@ static const char * prlsdkFormatMac(virMacAddrPtr mac, char *macstr) return macstr; } -static int prlsdkAddNet(PRL_HANDLE sdkdom, virDomainNetDefPtr net) +static int prlsdkAddNet(PRL_HANDLE sdkdom, parallelsConnPtr privconn, virDomainNetDefPtr net) { PRL_RESULT pret; PRL_HANDLE sdknet = PRL_INVALID_HANDLE; +PRL_HANDLE vnet = PRL_INVALID_HANDLE; +PRL_HANDLE job = PRL_INVALID_HANDLE; int ret = -1; char macstr[PRL_MAC_STRING_BUFNAME]; @@ -2570,7 +2577,7 @@ static int prlsdkAddNet(PRL_HANDLE sdkdom, virDomainNetDefPtr net) pret = PrlVmDev_SetEnabled(sdknet, 1); prlsdkCheckRetGoto(pret, cleanup); -pret = PrlVmDev_SetConnected(sdknet, net-linkstate); +pret = PrlVmDev_SetConnected(sdknet, 1); prlsdkCheckRetGoto(pret, cleanup); if (net-ifname) { @@ -2582,10 +2589,43 @@ static int prlsdkAddNet(PRL_HANDLE sdkdom, virDomainNetDefPtr net) pret = PrlVmDevNet_SetMacAddress(sdknet, macstr); prlsdkCheckRetGoto(pret, cleanup); -if (STREQ(net-data.network.name, PARALLELS_ROUTED_NETWORK_NAME)) { -pret = PrlVmDev_SetEmulatedType(sdknet, PNA_ROUTED); +/* Other alternatives: PNT_VIRTIO, PNT_RTL */ +pret = PrlVmDevNet_SetAdapterType(sdknet, PNT_E1000); +prlsdkCheckRetGoto(pret, cleanup); + +if (net-type == VIR_DOMAIN_NET_TYPE_NETWORK) { +if (STREQ(net-data.network.name, PARALLELS_ROUTED_NETWORK_NAME)) { +pret = PrlVmDev_SetEmulatedType(sdknet, PNA_ROUTED); +prlsdkCheckRetGoto(pret, cleanup); +} else if (STREQ(net-data.network.name, PARALLELS_BRIDGED_NETWORK_NAME)) { +pret = PrlVmDev_SetEmulatedType(sdknet, PNA_BRIDGED_ETHERNET); +prlsdkCheckRetGoto(pret, cleanup); + +pret = PrlVmDevNet_SetVirtualNetworkId(sdknet, net-data.network.name); +prlsdkCheckRetGoto(pret, cleanup); +} +
Re: [libvirt] QEMU capabilities vs machine types
On Wed, Feb 11, 2015 at 05:09:01PM +0100, Michal Privoznik wrote: On 11.02.2015 16:47, Daniel P. Berrange wrote: On Wed, Feb 11, 2015 at 04:31:53PM +0100, Michal Privoznik wrote: There are two reasons why we query check the supported capabilities from QEMU 1. There are multiple possible CLI args for the same feature and we need to choose the best one to use 2. The feature is not supported and we want to give the caller a better error message than they'd get from QEMU I'm unclear from the bug which scenario applies here. If it is scenario 2 though, I'd just mark it as CANTFIX or WONTFIX, as no matter what we do the user would get an error. It is not worth making our capability matrix a factor of 10+ bigger just to get a better error message. If it is scenario 1, I think the burden is on QEMU to solve. The memory-backend-{file,ram} CLI flags shouldn't be tied to guest machine types, as they are backend config setup options that should not impact guest ABI. It's somewhere in between 1 and 2. Back in RHEL-7.0 days libvirt would have created a guest with: -numa node,...,mem=1337 But if qemu reports it support memory-backend-ram, libvirt tries to use it: -object memory-backend-ram,id=ram-node0,size=1337M,... \ -numa node,...,memdev=ram-node0 This breaks migration to newer qemu which is in RHEL-7.1. If qemu would report the correct value, we can generate the correct command line and migration succeeds. However, our fault is, we are not asking the correct question anyway. I understand that RHEL-7.1 QEMU is not providing enough data for libvirt to detect this before it is too late. What I am missing here is: why wasn't commit f309db1f4d51009bad0d32e12efc75530b66836b enough to fix this specific case? For reference: commit f309db1f4d51009bad0d32e12efc75530b66836b Author: Michal Privoznik mpriv...@redhat.com Date: Thu Dec 18 12:36:48 2014 +0100 qemu: Create memory-backend-{ram,file} iff needed Libvirt BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1175397 QEMU BZ:https://bugzilla.redhat.com/show_bug.cgi?id=1170093 In qemu there are two interesting arguments: 1) -numa to create a guest NUMA node 2) -object memory-backend-{ram,file} to tell qemu which memory region on which host's NUMA node it should allocate the guest memory from. Combining these two together we can instruct qemu to create a guest NUMA node that is tied to a host NUMA node. And it works just fine. However, depending on machine type used, there might be some issued during migration when OVMF is enabled (see QEMU BZ). While this truly is a QEMU bug, we can help avoiding it. The problem lies within the memory backend objects somewhere. Having said that, fix on our side consists on putting those objects on the command line if and only if needed. For instance, while previously we would construct this (in all ways correct) command line: -object memory-backend-ram,size=256M,id=ram-node0 \ -numa node,nodeid=0,cpus=0,memdev=ram-node0 now we create just: -numa node,nodeid=0,cpus=0,mem=256 because the backend object is obviously not tied to any specific host NUMA node. Signed-off-by: Michal Privoznik mpriv...@redhat.com -- Eduardo -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 4/5] parallels: fix home directory for VMs
Failures of parallelsStorageOpen occured because we incorrectly treated path to VM' configuration file as a directory. Now initialization of parallels VM domains home directory is fixed. --- src/parallels/parallels_sdk.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/src/parallels/parallels_sdk.c b/src/parallels/parallels_sdk.c index a324cc5..4ca5243 100644 --- a/src/parallels/parallels_sdk.c +++ b/src/parallels/parallels_sdk.c @@ -1255,6 +1255,14 @@ prlsdkLoadDomain(parallelsConnPtr privconn, pret = PrlVmCfg_GetHomePath(sdkdom, pdom-home, buflen); prlsdkCheckRetGoto(pret, error); +/* For VMs pdom-home is actually /directory/config.pvs */ +if (!IS_CT(def)) { +/* Get rid of /config.pvs in path string */ +char *s = strrchr(pdom-home, '/'); +if (s) +*s = '\0'; +} + if (olddom) { /* assign new virDomainDef without any checks */ /* we can't use virDomainObjAssignDef, because it checks -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 5/5] parallels: fix initialization of parallels driver
Don't fail initialization of parallels driver even if parallelsGetBridgedNetInfo fails. This can happen when it is unconfigured (which is a common case on developers hosts for instance) or configured incompletely. In any case it is not a severe error and we can ignore it and use only Routed Networks or don't use network at all. --- src/parallels/parallels_network.c |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/parallels/parallels_network.c b/src/parallels/parallels_network.c index 3e7087d..196d79c 100644 --- a/src/parallels/parallels_network.c +++ b/src/parallels/parallels_network.c @@ -214,8 +214,10 @@ parallelsLoadNetwork(parallelsConnPtr privconn, virJSONValuePtr jobj) if (STREQ(tmp, bridged)) { def-forward.type = VIR_NETWORK_FORWARD_BRIDGE; -if (parallelsGetBridgedNetInfo(def, jobj) 0) -goto cleanup; +/* We shouldn't fail here because it's not that critical + * to prevent connecting to parallels dispatcher */ +parallelsGetBridgedNetInfo(def, jobj); + } else if (STREQ(tmp, host-only)) { def-forward.type = VIR_NETWORK_FORWARD_NONE; -- 1.7.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [RFC PATCH v2 00/12] qemu: add support to hot-plug/unplug cpu device
Hi all, Any comments about this series? I'm not sure whether this series' method to support cpu hotplug in libvirt is reasonable, so could anyone give more suggestions about this function? Thanks. Regards, Zhu On Wed, 2015-02-04 at 17:18 +0800, Zhu Guihua wrote: If you apply the folowing patchset in order [PATCH v3 0/7] cpu: add device_add foo-x86_64-cpu support https://lists.nongnu.org/archive/html/qemu-devel/2015-01/msg01552.html, [PATCH v2 0/5] Common unplug and unplug request cb for memory and CPU hot-unplug https://lists.nongnu.org/archive/html/qemu-devel/2015-01/msg03929.html and [PATCH v2 00/11] cpu: add i386 cpu hot remove support https://lists.nongnu.org/archive/html/qemu-devel/2015-01/msg01557.html, qemu can support hotplug and hot-unplug cpu device. So this patch series will make libvirt support hotplug and hot-unplug cpu device for qemu driver. This patch series add a new API to support cpu hot-plug/unplug, and leave the existing API by invoking qemu command 'cpu-add' as a legacy. This patch series realize cpu hot-plug/unplug by libvirt command 'attach-device' and 'detach-device', and invoke qemu command 'device_add' and 'device_del' to support this feature. v2: - update cpu device's definition, and cpu's apic_id is hidded to users. - add check for compatibility between host cpu and hot added cpu - add a capability for *-x86_64-cpu Zhu Guihua (12): domain_conf: add support for cpu device configuration in XML domain_conf: introduce cpu def helpers domain_conf: introduce cpu device hotplug helpers qemu_driver: implement cpu device hotplug on config level qemu_command: introduce a func for cpu device alias assignment domain_conf: allocate cpu's apic id dynamically qemu: add a capability for x86_64-cpu qemu: introduce qemuBuildCPUDeviceStr qemu: implement cpu device hotplug on live level qemu: implement cpu device hotunplug on live level qemu_monitor_json: sort JSON array of cpu info qemu_driver: detect threads corresponding to Vcpus docs/formatdomain.html.in | 28 docs/schemas/domaincommon.rng | 3 + src/conf/domain_conf.c| 189 +- src/conf/domain_conf.h| 33 + src/libvirt_private.syms | 6 + src/qemu/qemu_capabilities.c | 3 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 120 + src/qemu/qemu_command.h | 10 ++ src/qemu/qemu_driver.c| 299 -- src/qemu/qemu_driver.h| 8 ++ src/qemu/qemu_hotplug.c | 140 src/qemu/qemu_hotplug.h | 12 ++ src/qemu/qemu_monitor_json.c | 31 - src/util/virbitmap.c | 2 +- src/util/virbitmap.h | 2 + 16 files changed, 753 insertions(+), 134 deletions(-) -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] util: make use of VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE in virLockSpaceAcquireResource
When create external disk snapshot with virtlock enabled, libvirtd will hang if flag VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE is missed in virLockSpaceAcquireResource. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1191901 Signed-off-by: Shanzhi Yu s...@redhat.com --- src/util/virlockspace.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/util/virlockspace.c b/src/util/virlockspace.c index 2366a74..25b4433 100644 --- a/src/util/virlockspace.c +++ b/src/util/virlockspace.c @@ -626,8 +626,10 @@ int virLockSpaceAcquireResource(virLockSpacePtr lockspace, virMutexLock(lockspace-lock); if ((res = virHashLookup(lockspace-resources, resname))) { -if ((res-flags VIR_LOCK_SPACE_ACQUIRE_SHARED) -(flags VIR_LOCK_SPACE_ACQUIRE_SHARED)) { +if (((res-flags VIR_LOCK_SPACE_ACQUIRE_SHARED) +(flags VIR_LOCK_SPACE_ACQUIRE_SHARED)) || +((res-flags VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE) +(flags VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE))){ if (VIR_EXPAND_N(res-owners, res-nOwners, 1) 0) goto cleanup; -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] util: make use of VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE in virLockSpaceAcquireResource
On Thu, Feb 12, 2015 at 07:12:57PM +0800, Shanzhi Yu wrote: When create external disk snapshot with virtlock enabled, libvirtd will hang if flag VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE is missed in virLockSpaceAcquireResource. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1191901 Signed-off-by: Shanzhi Yu s...@redhat.com --- src/util/virlockspace.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/util/virlockspace.c b/src/util/virlockspace.c index 2366a74..25b4433 100644 --- a/src/util/virlockspace.c +++ b/src/util/virlockspace.c @@ -626,8 +626,10 @@ int virLockSpaceAcquireResource(virLockSpacePtr lockspace, virMutexLock(lockspace-lock); if ((res = virHashLookup(lockspace-resources, resname))) { -if ((res-flags VIR_LOCK_SPACE_ACQUIRE_SHARED) -(flags VIR_LOCK_SPACE_ACQUIRE_SHARED)) { +if (((res-flags VIR_LOCK_SPACE_ACQUIRE_SHARED) +(flags VIR_LOCK_SPACE_ACQUIRE_SHARED)) || +((res-flags VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE) +(flags VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE))){ No, this is wrong. If virHashLookup returns a non-NULL entry it indicates that the lock is already held. It is not valid to ignore this error if 'autocreate' flag is set, as that would allow multiple VMs to own the same disk which is exactly the scenario we are trying to prevent. Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3] lxc: fix show the wrong xml when guest start failed
On 02/04/2015 08:42 AM, Luyao Huang wrote: https://bugzilla.redhat.com/show_bug.cgi?id=1176503 When guest start failed, libvirt will keep the current vm-def, this will make a issue that we cannot get a right xml after guest start failed. And don't call the stop/release hook to do some other clean work. Call virLXCProcessCleanup to help us clean the source and call the hooks if start a vm failed Signed-off-by: Luyao Huang lhu...@redhat.com --- v2: use virLXCProcessCleanup to free the source and call the hook. v3: rework the patch to suit the virLXCProcessStart code changed. src/lxc/lxc_process.c | 76 ++- 1 file changed, 32 insertions(+), 44 deletions(-) FWIW: v1 review starts here: http://www.redhat.com/archives/libvir-list/2015-January/msg00112.html At first I was 'concerned' about the number of changes, but after doing more investigation - I think the patch is correct in general; however, I think it needs some adjustments as there are really two bugs here... I'll send an update shortly for comparison/review... Essentially though - I think the console check*s* could be done earlier before we get into other setup that requires going thru cleanup: (or what error: was). That's one bug - which is a configuration error which will prevent startup. Since it's easier to check early, provide an error, and return -1 - that's what I think is cleaner solution. Second, the other bug which you were trying to clean up at the same time is that existing cleanup paths don't properly clean all things up. The error path worked only when/once the container started and some pre-container start cleanup was done, but a few important ones were missing - so that's a separate patch. I also will add a patch to add/modify the debugging to help future such efforts... BTW: It seems commit id '88a1b542' from Cédric Bosdonnat caused yet another merge conflict and seemingly from the description might have been in the same area, but alas a quick check shows, it wasn't the same issue. I'll leave the notes I was developing on this patch prior to just biting the bullet and reformatting so you can perhaps see my thought process. diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 01da344..1a6cfbb 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -1022,6 +1022,7 @@ int virLXCProcessStart(virConnectPtr conn, virCgroupPtr selfcgroup; int status; char *pidfile = NULL; +bool need_stop = false; I think the check: if (vm-def-nconsoles == 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, _(At least one PTY console is required)); goto cleanup; } Should perhaps be moved to just before this code: nttyFDs = vm-def-nconsoles; if (VIR_ALLOC_N(ttyFDs, nttyFDs) 0) goto cleanup; for (i = 0; i vm-def-nconsoles; i++) ttyFDs[i] = -1; and that would fix the bug from the bz... as well as ensuring we don't have a if (VIR_ALLOC_N(ttdFDs, 0) 0)... In fact is there a reason why that check cannot move much higher and be after the cgroup checks which return -1? While t it, why not move the following too: for (i = 0; i vm-def-nconsoles; i++) { if (vm-def-consoles[i]-source.type != VIR_DOMAIN_CHR_TYPE_PTY) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, _(Only PTY console types are supported)); goto cleanup; } } and then remove that from the loop later on. This way checks that go to cleanup are a result of some error in processing rather than some container configuration error... Then the remainder of the code could be perhaps patch 2 which is fixing a different, although related problem. if (virCgroupNewSelf(selfcgroup) 0) return -1; @@ -1259,6 +1260,7 @@ int virLXCProcessStart(virConnectPtr conn, goto cleanup; } +need_stop = true; priv-stopReason = VIR_DOMAIN_EVENT_STOPPED_FAILED; priv-wantReboot = false; vm-def-id = vm-pid; I was going to suggest using vm-pid (e.g. 0) instead of 'need_stop'; however, I couldn't convince myself that would be 'safe enough'... @@ -1272,20 +1274,20 @@ int virLXCProcessStart(virConnectPtr conn, if (VIR_CLOSE(handshakefds[1]) 0) { virReportSystemError(errno, %s, _(could not close handshake fd)); -goto error; +goto cleanup; } if (virCommandHandshakeWait(cmd) 0) -goto error; +goto cleanup; /* Write domain status to disk for the controller to * read when it starts */ if (virDomainSaveStatus(driver-xmlopt, cfg-stateDir, vm) 0) -goto error; +goto cleanup; /* Allow the child to exec the controller */ if (virCommandHandshakeNotify(cmd) 0) -goto error; +goto cleanup; if (virAtomicIntInc(driver-nactive) == 1
Re: [libvirt] [PATCH v2 0/4] attach-interface: Learn net type='direct'
On 02/09/2015 10:20 AM, Michal Privoznik wrote: v2 Michal Privoznik (4): libvirt_private.syms: Expose virDomainNetTypeFromString virsh attach-interface: Use enum instead of arbitrary integers virsh attach-interface: Use virDomainNetType{From,To}String() virsh attach-interface: Allow macvtap hotplug src/libvirt_private.syms | 1 + tools/virsh-domain.c | 36 ++-- tools/virsh.pod | 14 -- 3 files changed, 35 insertions(+), 16 deletions(-) ACK series... If you want to merge 1-3 into just one patch that'd be fine too... At the very least 13 are related since the From API isn't used until 3. John -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 0/3] lxc: fix show the wrong xml when guest start failed
This is a rework of the patch Luyao Huang sent to resolve a couple of issues found in virLXCStartProcess. See explanation here: http://www.redhat.com/archives/libvir-list/2015-February/msg00433.html John Ferlan (1): lxc: Modify/add some debug messages Luyao Huang (2): lxc: Move console checks in LXCProcessStart lxc: Fix container cleanup for LXCProcessStart src/lxc/lxc_process.c | 109 -- 1 file changed, 52 insertions(+), 57 deletions(-) -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 0/2] Support mrg_rxbuf attribute for virtio-net devices
On 02/06/2015 09:51 AM, Ján Tomko wrote: For https://bugzilla.redhat.com/show_bug.cgi?id=1186886 Ján Tomko (2): Add mrg_rxbuf option to virtio interfaces Wire up mrg_rxbuf option for qemu docs/formatdomain.html.in | 6 +- docs/schemas/domaincommon.rng | 5 + src/conf/domain_conf.c | 14 ++ src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c| 4 src/qemu/qemu_hotplug.c| 1 + .../qemuxml2argv-net-virtio-disable-offloads.args | 2 +- .../qemuxml2argv-net-virtio-disable-offloads.xml | 2 +- 8 files changed, 32 insertions(+), 3 deletions(-) ACK series John -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 1/3] lxc: Move console checks in LXCProcessStart
From: Luyao Huang lhu...@redhat.com https://bugzilla.redhat.com/show_bug.cgi?id=1176503 Move the two console checks - one for zero nconsoles present and the other for an invalid console type to earlier in the processing rather than getting after performing some setup that has to be undone for what amounts to an invalid configuration. This resolves the above bug since it's not not possible to have changed the security labels when we cause the configuration check failure. Signed-off-by: John Ferlan jfer...@redhat.com --- src/lxc/lxc_process.c | 25 ++--- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 19ea7f3..1a26a70 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -1050,6 +1050,20 @@ int virLXCProcessStart(virConnectPtr conn, } virCgroupFree(selfcgroup); +if (vm-def-nconsoles == 0) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, + _(At least one PTY console is required)); +return -1; +} + +for (i = 0; i vm-def-nconsoles; i++) { +if (vm-def-consoles[i]-source.type != VIR_DOMAIN_CHR_TYPE_PTY) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, + _(Only PTY console types are supported)); +return -1; +} +} + if (virFileMakePath(cfg-logDir) 0) { virReportSystemError(errno, _(Cannot create log directory '%s'), @@ -1146,19 +1160,8 @@ int virLXCProcessStart(virConnectPtr conn, vm-def, NULL) 0) goto cleanup; -if (vm-def-nconsoles == 0) { -virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, - _(At least one PTY console is required)); -goto cleanup; -} - for (i = 0; i vm-def-nconsoles; i++) { char *ttyPath; -if (vm-def-consoles[i]-source.type != VIR_DOMAIN_CHR_TYPE_PTY) { -virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, - _(Only PTY console types are supported)); -goto cleanup; -} if (virFileOpenTty(ttyFDs[i], ttyPath, 1) 0) { virReportSystemError(errno, %s, -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v4 3/3] lxc: Fix container cleanup for LXCProcessStart
From: Luyao Huang lhu...@redhat.com Jumping to the cleanup label prior to starting the container failed to properly clean everything up that is handled by the virLXCProcessCleanup which is called if virLXCProcessStop is called on failure after the container properly starts. Most importantly is prior to this patch none of the stop/release hooks, host device reattachment, and network cleanup (that is reverse of virLXCProcessSetupInterfaces). Signed-off-by: Luyao Huang lhu...@redhat.com Signed-off-by: John Ferlan jfer...@redhat.com --- src/lxc/lxc_process.c | 78 ++- 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 4d9bf67..a3410e4 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -1023,6 +1023,7 @@ int virLXCProcessStart(virConnectPtr conn, int status; char *pidfile = NULL; bool clearSeclabel = false; +bool need_stop = false; if (virCgroupNewSelf(selfcgroup) 0) return -1; @@ -1271,6 +1272,7 @@ int virLXCProcessStart(virConnectPtr conn, goto cleanup; } +need_stop = true; priv-stopReason = VIR_DOMAIN_EVENT_STOPPED_FAILED; priv-wantReboot = false; vm-def-id = vm-pid; @@ -1279,20 +1281,20 @@ int virLXCProcessStart(virConnectPtr conn, if (VIR_CLOSE(handshakefds[1]) 0) { virReportSystemError(errno, %s, _(could not close handshake fd)); -goto error; +goto cleanup; } if (virCommandHandshakeWait(cmd) 0) -goto error; +goto cleanup; /* Write domain status to disk for the controller to * read when it starts */ if (virDomainSaveStatus(driver-xmlopt, cfg-stateDir, vm) 0) -goto error; +goto cleanup; /* Allow the child to exec the controller */ if (virCommandHandshakeNotify(cmd) 0) -goto error; +goto cleanup; if (virAtomicIntInc(driver-nactive) == 1 driver-inhibitCallback) driver-inhibitCallback(true, driver-inhibitOpaque); @@ -1305,7 +1307,7 @@ int virLXCProcessStart(virConnectPtr conn, _(guest failed to start: %s), out); } -goto error; +goto cleanup; } /* We know the cgroup must exist by this synchronization @@ -1317,13 +1319,13 @@ int virLXCProcessStart(virConnectPtr conn, vm-def-resource-partition : NULL, -1, priv-cgroup) 0) -goto error; +goto cleanup; if (!priv-cgroup) { virReportError(VIR_ERR_INTERNAL_ERROR, _(No valid cgroup for machine %s), vm-def-name); -goto error; +goto cleanup; } /* And we can get the first monitor connection now too */ @@ -1336,17 +1338,17 @@ int virLXCProcessStart(virConnectPtr conn, virReportError(VIR_ERR_INTERNAL_ERROR, _(guest failed to start: %s), ebuf); } -goto error; +goto cleanup; } if (autoDestroy virCloseCallbacksSet(driver-closeCallbacks, vm, conn, lxcProcessAutoDestroy) 0) -goto error; +goto cleanup; if (virDomainObjSetDefTransient(caps, driver-xmlopt, vm, false) 0) -goto error; +goto cleanup; /* We don't need the temporary NIC names anymore, clear them */ virLXCProcessCleanInterfaces(vm-def); @@ -1365,48 +1367,39 @@ int virLXCProcessStart(virConnectPtr conn, * If the script raised an error abort the launch */ if (hookret 0) -goto error; +goto cleanup; } rc = 0; cleanup: -if (rc != 0 !err) -err = virSaveLastError(); -virCommandFree(cmd); if (VIR_CLOSE(logfd) 0) { virReportSystemError(errno, %s, _(could not close logfile)); rc = -1; } -for (i = 0; i nveths; i++) { -if (rc != 0 veths[i]) -ignore_value(virNetDevVethDelete(veths[i])); -VIR_FREE(veths[i]); -} if (rc != 0) { -if (vm-newDef) { -virDomainDefFree(vm-newDef); -vm-newDef = NULL; -} -if (priv-monitor) { -virObjectUnref(priv-monitor); -priv-monitor = NULL; -} -virDomainConfVMNWFilterTeardown(vm); - -virSecurityManagerRestoreAllLabel(driver-securityManager, - vm-def, false); -virSecurityManagerReleaseLabel(driver-securityManager, vm-def); -/* Clear out dynamically assigned labels */ -if (vm-def-nseclabels -(vm-def-seclabels[0]-type == VIR_DOMAIN_SECLABEL_DYNAMIC || -clearSeclabel)) { -VIR_FREE(vm-def-seclabels[0]-model); -
[libvirt] [PATCH v4 2/3] lxc: Modify/add some debug messages
Modify the VIR_DEBUG message in virLXCProcessCleanup to make it clearer about the path. Also add some more VIR_DEBUG messages in virLXCProcessStart in order to help debug error flow. Signed-off-by: John Ferlan jfer...@redhat.com --- src/lxc/lxc_process.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 1a26a70..4d9bf67 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -154,7 +154,7 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver, virNetDevVPortProfilePtr vport = NULL; virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver); -VIR_DEBUG(Stopping VM name=%s pid=%d reason=%d, +VIR_DEBUG(Cleanup VM name=%s pid=%d reason=%d, vm-def-name, (int)vm-pid, (int)reason); /* now that we know it's stopped call the hook if present */ @@ -1160,6 +1160,7 @@ int virLXCProcessStart(virConnectPtr conn, vm-def, NULL) 0) goto cleanup; +VIR_DEBUG(Setting up consoles); for (i = 0; i vm-def-nconsoles; i++) { char *ttyPath; @@ -1177,9 +1178,11 @@ int virLXCProcessStart(virConnectPtr conn, goto cleanup; } +VIR_DEBUG(Setting up Interfaces); if (virLXCProcessSetupInterfaces(conn, vm-def, nveths, veths) 0) goto cleanup; +VIR_DEBUG(Preparing to launch); if ((logfd = open(logfile, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR|S_IWUSR)) 0) { virReportSystemError(errno, @@ -1237,6 +1240,7 @@ int virLXCProcessStart(virConnectPtr conn, VIR_WARN(Unable to seek to end of logfile: %s, virStrerror(errno, ebuf, sizeof(ebuf))); +VIR_DEBUG(Launching container); virCommandRawStatus(cmd); if (virCommandRun(cmd, status) 0) goto cleanup; -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v8 1/4] domifaddr: Implement the public APIs
On 01/25/2015 01:38 PM, Nehal J Wani wrote: Define helper function virDomainInterfaceFree, which allows the upper layer application to free the domain interface object conveniently. ...snip... diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index 4ea5cff..ab86543 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -695,4 +695,10 @@ LIBVIRT_1.2.12 { virDomainDefineXMLFlags; } LIBVIRT_1.2.11; +LIBVIRT_1.2.12 { +global: +virDomainInterfaceAddresses; +virDomainInterfaceFree; +} LIBVIRT_1.2.13; + Well this is wrong, but I see in patch 2 you've adjusted it. Since each patch needs to build/check order wise it'll need to be fixed here Something I can do assuming the rest of the patches are OK... John (One of us is going to have a merge forthcoming since I have a new command series posted today as well). # define new API here using predicted next version number -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 1/3] util: Add virProcessSetScheduler() function for scheduler settings
On 11.02.2015 18:34, Eric Blake wrote: On 02/11/2015 07:04 AM, Michal Privoznik wrote: On 10.02.2015 16:35, Martin Kletzander wrote: snip/ + +typedef enum { +VIR_PROC_POLICY_NONE, +VIR_PROC_POLICY_BATCH, +VIR_PROC_POLICY_IDLE, +VIR_PROC_POLICY_FIFO, +VIR_PROC_POLICY_RR, + +VIR_PROC_POLICY_LAST +} virProcessSchedPolicy; The C language guarantees that VIR_PROC_POLICY_NONE == 0, and that VIR_PROC_POLICY_BATCH == (VIR_PROC_POLICY_NONE + 1). That is, C guarantees that an initial enum not otherwise initialized is 0, and that all subsequent enums not otherwise initialized are one more than the previous value (whether or not the previous value was explicitly initialized). So the code you questioned is safe as-is. So in other words, we don't need zero 'initialization' in enums? So for instance the following (taken from daemon/libvirtd.c:122): enum { VIR_DAEMON_ERR_NONE = 0, /* snip */ }; is the same as enum { VIR_DAEMON_ERR_NONE, /* snip */ }; If it is so, is it worth bothering with cleanup patch(es)? There's roughly 250 occurrences in the code: $ git grep [A-Z]\+ = 0 | wc -l 268 Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] Google Summer of Code application submitted
Hi, I have submitted our Google Summer of Code application for QEMU, libvirt, and KVM. Accepted organizations will be announced on March 2nd at 19:00 UTC on http://google-melange.com/. You can still add project ideas if you wish to mentor: http://qemu-project.org/Google_Summer_of_Code_2015 Mentors must be active contributors and willing to commit 5 hours per week during the summer. Please let me know if you have any questions. Stefan -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 3/3] qemuMigrationDriveMirror: Listen to events
On Wed, Feb 11, 2015 at 13:51:11 +0100, Michal Privoznik wrote: When migrating with storage, libvirt iterates over domain disks and instruct qemu to migrate the ones we are interested in (shared, RO and source-less disks are skipped). The disks are migrated in series. No new disk is transferred until the previous one hasn't been quiesced. Quiesce in the libvirt terminology is used in the meaning that the filesystem writes were frozen (see snapshot creation). In this context it's used in the meaning that the qemu block-copy job entered the synchronized phase, but writes are still possible. Please tweak the wording to avoid confusion. This is checked on the qemu monitor via 'query-jobs' command. If the disk has been quiesced, it practically went from copying its content to mirroring state, where all disk writes are mirrored to the other side of migration too. Having said that, there's one inherent error in the design. The monitor command we use reports only active jobs. So if the job fails for whatever reason, we will not see it anymore in the command output. And this can happen fairly simply: just try to migrate a domain with storage. If the storage migration fails (e.g. due to ENOSPC on the destination) we resume the host on the destination and let it run on partly copied disk. The proper fix is what even the comment in the code says: listen for qemu events instead of polling. If storage migration changes state an event is emitted and we can act accordingly: either consider disk copied and continue the process, or consider disk mangled and abort the migration. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- src/qemu/qemu_migration.c | 37 + 1 file changed, 17 insertions(+), 20 deletions(-) Peter signature.asc Description: Digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] util: do not resotre the VF that is in use by another active guest
If we assign a VF, which has already been used by an active guest, to another guest, and try to start the 2nd guest later on, the 2nd guest would not start, and the VF won't work anymore. Steps to reproduce the problem: 1 Assign a VF to guest A, and start the guest. The VF works fine. 2 Assign the VF to guest B, and try to start guest B. guest B can't start. 3 Guest A's network becomes unreachable, because its VF now doesn't work. Reasons for this problem is: 1 When we start guest B, libvirtd checks whether the VF is already used by another guest, if so, qemuPrepareHostDevices() returns with failure. 2 Then, libvirtd calls qemuProcessStop() to cleanup resourses, which would restore the VFs of guest B. Specifically, it reads /var/run/libvirt/hostdevmgr/ethX_vfX to get the VF's original MAC/VLAN, and set it back to current VF. 3 As that the VF is still in use by guest A, libvirtd just set its MAC/VLAN to another value, the VF doesn't work anymore. Detailed flow: qemuProcessStart \___qemuPrepareHostDevices(if it fails, goto cleanup) \ \_qemuPrepareHostdevPCIDevices \\_virHostdevPreparePCIDevices \ \LOOP1:virPCIDeviceListFind \ (whether the device is in use by another active guest) \ if the VF has been assigned to, qemuPrepareHostDevices() fails \___cleanup: \__qemuProcessStop \qemuDomainReAttachHostDevices \qemuDomainReAttachHostdevDevices \virHostdevReAttachPCIDevices \_virHostdevNetConfigRestore (it gets MAC/VLAN form /var/run/libvirt/hostdevmgr/ethX_vfX, and set it back to the VF, making the VF unusable) This patch checks whether the VF is already in use before restoring it. Signed-off-by: Zhang Bo oscar.zhan...@huawei.com Signed-off-by: Zhuang Yanying zhuangyany...@huawei.com --- src/util/virhostdev.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c index 9678e2b..ee19400 100644 --- a/src/util/virhostdev.c +++ b/src/util/virhostdev.c @@ -816,9 +816,21 @@ virHostdevReAttachPCIDevices(virHostdevManagerPtr hostdev_mgr, * For SRIOV net host devices, unset mac and port profile before * reset and reattach device */ -for (i = 0; i nhostdevs; i++) +for (i = 0; i nhostdevs; i++){ + virPCIDevicePtr devNotInuse = NULL; + virDevicePCIAddressPtr addr = NULL; + virDomainHostdevDefPtr hostdev = hostdevs[i]; + addr = hostdev-source.subsys.u.pci.addr; + devNotInuse = virPCIDeviceListFindByIDs(pcidevs, + addr-domain, addr-bus, + addr-slot, addr-function); + if (!devNotInuse) { + continue; + } + virHostdevNetConfigRestore(hostdevs[i], hostdev_mgr-stateDir, oldStateDir); +} for (i = 0; i virPCIDeviceListCount(pcidevs); i++) { virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i); -- 1.7.12.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 1/3] util: Add virProcessSetScheduler() function for scheduler settings
On Tue, Feb 10, 2015 at 16:35:19 +0100, Martin Kletzander wrote: This function uses sched_setscheduler() function so it works with processes and threads as well (even threads not created by us, which is what we'll need in the future). Signed-off-by: Martin Kletzander mklet...@redhat.com --- configure.ac | 4 +- src/libvirt_private.syms | 1 + src/util/virprocess.c| 104 ++- src/util/virprocess.h| 20 - 4 files changed, 124 insertions(+), 5 deletions(-) ... +#if HAVE_SCHED_SETSCHEDULER + +static int +virProcessSchedTranslatePolicy(virProcessSchedPolicy policy) +{ +switch (policy) { +case VIR_PROC_POLICY_NONE: +return SCHED_OTHER; + +case VIR_PROC_POLICY_BATCH: +return SCHED_BATCH; + +case VIR_PROC_POLICY_IDLE: +return SCHED_IDLE; + +case VIR_PROC_POLICY_FIFO: +return SCHED_FIFO; + +case VIR_PROC_POLICY_RR: +return SCHED_RR; + +case VIR_PROC_POLICY_LAST: +/* nada */ I know I'm late with this comment, but: I don't think the _LAST case is so obscure that we would need to comment it with such an insightful comment. +break; +} + +return -1; +} + Peter signature.asc Description: Digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3] lxc: fix show the wrong xml when guest start failed
On 02/13/2015 04:45 AM, John Ferlan wrote: On 02/04/2015 08:42 AM, Luyao Huang wrote: https://bugzilla.redhat.com/show_bug.cgi?id=1176503 When guest start failed, libvirt will keep the current vm-def, this will make a issue that we cannot get a right xml after guest start failed. And don't call the stop/release hook to do some other clean work. Call virLXCProcessCleanup to help us clean the source and call the hooks if start a vm failed Signed-off-by: Luyao Huang lhu...@redhat.com --- v2: use virLXCProcessCleanup to free the source and call the hook. v3: rework the patch to suit the virLXCProcessStart code changed. src/lxc/lxc_process.c | 76 ++- 1 file changed, 32 insertions(+), 44 deletions(-) FWIW: v1 review starts here: http://www.redhat.com/archives/libvir-list/2015-January/msg00112.html At first I was 'concerned' about the number of changes, but after doing more investigation - I think the patch is correct in general; however, I think it needs some adjustments as there are really two bugs here... I'll send an update shortly for comparison/review... Yes, i agree about these patch need more adjustment, because i think maybe there is a better way to fix these issue but i cannot find them ;) and thanks for your patches. Essentially though - I think the console check*s* could be done earlier before we get into other setup that requires going thru cleanup: (or what error: was). That's one bug - which is a configuration error which will prevent startup. Since it's easier to check early, provide an error, and return -1 - that's what I think is cleaner solution. Looks good for me Second, the other bug which you were trying to clean up at the same time is that existing cleanup paths don't properly clean all things up. The error path worked only when/once the container started and some pre-container start cleanup was done, but a few important ones were missing - so that's a separate patch. I also will add a patch to add/modify the debugging to help future such efforts... Thanks BTW: It seems commit id '88a1b542' from Cédric Bosdonnat caused yet another merge conflict and seemingly from the description might have been in the same area, but alas a quick check shows, it wasn't the same issue. I'll leave the notes I was developing on this patch prior to just biting the bullet and reformatting so you can perhaps see my thought process. Yes, commit 88a1b542 is different from the issue i try to fix. diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 01da344..1a6cfbb 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -1022,6 +1022,7 @@ int virLXCProcessStart(virConnectPtr conn, virCgroupPtr selfcgroup; int status; char *pidfile = NULL; +bool need_stop = false; I think the check: if (vm-def-nconsoles == 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, _(At least one PTY console is required)); goto cleanup; } Should perhaps be moved to just before this code: nttyFDs = vm-def-nconsoles; if (VIR_ALLOC_N(ttyFDs, nttyFDs) 0) goto cleanup; for (i = 0; i vm-def-nconsoles; i++) ttyFDs[i] = -1; and that would fix the bug from the bz... as well as ensuring we don't have a if (VIR_ALLOC_N(ttdFDs, 0) 0)... In fact is there a reason why that check cannot move much higher and be after the cgroup checks which return -1? While t it, why not move the following too: for (i = 0; i vm-def-nconsoles; i++) { if (vm-def-consoles[i]-source.type != VIR_DOMAIN_CHR_TYPE_PTY) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, _(Only PTY console types are supported)); goto cleanup; } } and then remove that from the loop later on. Yes, after your words, i think console check in this place should be improved. This way checks that go to cleanup are a result of some error in processing rather than some container configuration error... Then the remainder of the code could be perhaps patch 2 which is fixing a different, although related problem. if (virCgroupNewSelf(selfcgroup) 0) return -1; @@ -1259,6 +1260,7 @@ int virLXCProcessStart(virConnectPtr conn, goto cleanup; } ... -VIR_FREE(vm-def-seclabels[0]-imagelabel); -VIR_DELETE_ELEMENT(vm-def-seclabels, 0, vm-def-nseclabels); +err = virSaveLastError(); +if (need_stop) { +virLXCProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED); +} else { +virSecurityManagerRestoreAllLabel(driver-securityManager, + vm-def, false); +virSecurityManagerReleaseLabel(driver-securityManager, vm-def); +/* Clear out dynamically assigned labels */ +if (vm-def-nseclabels +vm-def-seclabels[0]-type ==
[libvirt] [PATCH 1/4] util: introduce a new helper for get interface IPv6 address
Introduce a new function to help to get interface IPv6 address. Signed-off-by: Luyao Huang lhu...@redhat.com --- src/libvirt_private.syms | 1 + src/util/virnetdev.c | 70 src/util/virnetdev.h | 2 ++ 3 files changed, 73 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 645aef1..f60911c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1659,6 +1659,7 @@ virNetDevDelMulti; virNetDevExists; virNetDevGetIndex; virNetDevGetIPv4Address; +virNetDevGetIPv6Address; virNetDevGetLinkInfo; virNetDevGetMAC; virNetDevGetMTU; diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 2a0eb43..c1a588e 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -33,6 +33,10 @@ #include virstring.h #include virutil.h +#if defined(HAVE_GETIFADDRS) +# include ifaddrs.h +#endif + #include sys/ioctl.h #include net/if.h #include fcntl.h @@ -1432,6 +1436,72 @@ int virNetDevGetIPv4Address(const char *ifname ATTRIBUTE_UNUSED, #endif /* ! SIOCGIFADDR */ +/** + *virNetDevGetIPv6Address: + *@ifname: name of the interface whose IP address we want + *@addr: filled with the IPv6 address + * + *This function gets the IPv6 address for the interface @ifname + *and stores it in @addr + * + *Returns 0 on success, -1 on failure. + */ +#if defined(HAVE_GETIFADDRS) +int virNetDevGetIPv6Address(const char *ifname, +virSocketAddrPtr addr) +{ +struct ifaddrs *ifap, *ifa; +int ret = -1; +bool found_one = false; + +if (getifaddrs(ifap) 0) { +virReportSystemError(errno, %s, + _(Could not get interface list)); +return -1; +} + +for (ifa = ifap; ifa; ifa = ifa-ifa_next) { +if (STRNEQ(ifa-ifa_name, ifname)) +continue; +found_one = true; +if (ifa-ifa_addr-sa_family == AF_INET6) +break; +} + +if (!ifa) { +if (found_one) +virReportError(VIR_ERR_INTERNAL_ERROR, + _(Interface '%s' do not have a IPv6 address), + ifname); +else +virReportError(VIR_ERR_INTERNAL_ERROR, + _(Interface '%s' not found), + ifname); +goto cleanup; +} + +addr-data.stor.ss_family = AF_INET6; +addr-len = sizeof(addr-data.inet6); +memcpy(addr-data.inet6, ifa-ifa_addr, addr-len); +ret = 0; + + cleanup: +freeifaddrs(ifap); +return ret; +} + +#else + +int virNetDevGetIPv6Address(const char *ifname ATTRIBUTE_UNUSED, +virSocketAddrPtr addr ATTRIBUTE_UNUSED) +{ +virReportSystemError(ENOSYS, %s, + _(Unable to get IPv6 address on this platform)); +return -1; +} + +#endif + /** * virNetDevValidateConfig: diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index de8b480..c065381 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -104,6 +104,8 @@ int virNetDevClearIPAddress(const char *ifname, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevGetIPv4Address(const char *ifname, virSocketAddrPtr addr) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; +int virNetDevGetIPv6Address(const char *ifname, virSocketAddrPtr addr) +ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevSetMAC(const char *ifname, -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/4] conf: introduce new family attribute in graphics listen for chose IP family
If a interface or network have both ipv6 and ipv4 address which can be used, we do not know use which be a listen address. So introduce a new attribute to help us chose this. graphics XML will like this after this commit: graphics type='spice' port='5900' autoport='yes' listen type='network' address='192.168.0.1' network='vepa-net' family='default'/ /graphics and this ip family can be set 3 type: default: check if the interface or network have a can be used ipv4 address, if yes use this address, if not will try to get a ipv6 address. ipv4: check if the interface or network have a can be used ipv4 address ipv6: check if the interface or network have a can be used ipv6 address fix some test which will be break by this commit. Signed-off-by: Luyao Huang lhu...@redhat.com --- docs/formatdomain.html.in | 10 +- docs/schemas/domaincommon.rng | 9 + src/conf/domain_conf.c | 21 + src/conf/domain_conf.h | 10 ++ .../qemuxml2argv-graphics-listen-network.xml| 2 +- .../qemuxml2argv-graphics-listen-network2.xml | 2 +- .../qemuxml2xmlout-graphics-listen-network2.xml | 2 +- 7 files changed, 52 insertions(+), 4 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fcf5984..7a07ca0 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -4512,7 +4512,7 @@ qemu-kvm -net nic,model=? /dev/null lt;graphics type='rdp' autoport='yes' multiUser='yes' /gt; lt;graphics type='desktop' fullscreen='yes'/gt; lt;graphics type='spice'gt; - lt;listen type='network' network='rednet'/gt; + lt;listen type='network' network='rednet' family='default'/gt; lt;/graphicsgt; lt;/devicesgt; .../pre @@ -4752,6 +4752,14 @@ qemu-kvm -net nic,model=? /dev/null the first forward dev will be used. /dd /dl +dl + dtcodefamily/code/dt + ddif codetype='network'/code, the codefamily/code +attribute will contain an IP family. This tells which IP address +will be got for the network. IP family can be set to default, ipv4 +or ipv6. + /dd +/dl h4a name=elementsVideoVideo devices/a/h4 p diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 7a1d299..fb8d084 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2888,6 +2888,15 @@ ref name=addrIPorName/ /attribute /optional +optional + attribute name=family +choice + valuedefault/value + valueipv4/value + valueipv6/value +/choice + /attribute +/optional /group /choice /element diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fd36063..307801d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -522,6 +522,12 @@ VIR_ENUM_IMPL(virDomainGraphicsListen, VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST, address, network) +VIR_ENUM_IMPL(virDomainGraphicsListenFamily, + VIR_DOMAIN_GRAPHICS_LISTEN_FAMILY_LAST, + default, + ipv4, + ipv6) + VIR_ENUM_IMPL(virDomainGraphicsAuthConnected, VIR_DOMAIN_GRAPHICS_AUTH_CONNECTED_LAST, default, @@ -9396,6 +9402,7 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def, char *address = virXMLPropString(node, address); char *network = virXMLPropString(node, network); char *fromConfig = virXMLPropString(node, fromConfig); +char *family = virXMLPropString(node, family); int tmp; if (!type) { @@ -9433,6 +9440,16 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def, network = NULL; } +if (def-type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK) { +if (!family) { +def-family = VIR_DOMAIN_GRAPHICS_LISTEN_FAMILY_DEFAULT; +} else if ((def-family = virDomainGraphicsListenFamilyTypeFromString(family)) 0) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(unknown graphics listen IP family '%s'), family); +goto error; +} +} + if (fromConfig flags VIR_DOMAIN_DEF_PARSE_STATUS) { if (virStrToLong_i(fromConfig, NULL, 10, tmp) 0) { @@ -9452,6 +9469,7 @@ virDomainGraphicsListenDefParseXML(virDomainGraphicsListenDefPtr def, VIR_FREE(address); VIR_FREE(network); VIR_FREE(fromConfig); +VIR_FREE(family); return ret; } @@ -19044,6 +19062,9 @@ virDomainGraphicsListenDefFormat(virBufferPtr buf, if (def-network (def-type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK)) { virBufferEscapeString(buf, network='%s',
[libvirt] [PATCH 0/4] add support for graphics to get a IPv6 address
https://bugzilla.redhat.com/show_bug.cgi?id=1192318 We already support add a IPv6 address to graphics listen address and xml like this: graphics type='spice' port='5900' autoport='yes' listen='2001b8:ca2:2::1' keymap='en-us' listen type='address' address='2001b8:ca2:2::1'/ /graphics However we do not support get a IPv6 address for the network. add some helpers and rework networkGetNetworkAddress to make it can get a IPv6 address when we need. Luyao Huang (4): util: introduce a new helper for get interface IPv6 address conf: introduce new family attribute in graphics listen for chose IP family network: rework networkGetNetworkAddress to make it can get IPv6 address qemu: fix a error coverd issue in 2 place docs/formatdomain.html.in | 10 +++- docs/schemas/domaincommon.rng | 9 +++ src/conf/domain_conf.c | 21 +++ src/conf/domain_conf.h | 10 src/conf/network_conf.c| 2 +- src/conf/network_conf.h| 1 + src/libvirt_private.syms | 2 + src/network/bridge_driver.c| 50 +++- src/network/bridge_driver.h| 6 +- src/qemu/qemu_command.c| 18 ++ src/util/virnetdev.c | 70 ++ src/util/virnetdev.h | 2 + .../qemuxml2argv-graphics-listen-network.xml | 2 +- .../qemuxml2argv-graphics-listen-network2.xml | 2 +- .../qemuxml2xmlout-graphics-listen-network2.xml| 2 +- 15 files changed, 174 insertions(+), 33 deletions(-) -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/4] network: rework networkGetNetworkAddress to make it can get IPv6 address
Export the required helpers and rework networkGetNetworkAddress to make it can get IPv6 address. Signed-off-by: Luyao Huang lhu...@redhat.com --- src/conf/network_conf.c | 2 +- src/conf/network_conf.h | 1 + src/libvirt_private.syms| 1 + src/network/bridge_driver.c | 50 - src/network/bridge_driver.h | 6 -- src/qemu/qemu_command.c | 4 ++-- 6 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index f947d89..9eb640b 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -148,7 +148,7 @@ virNetworkDHCPHostDefClear(virNetworkDHCPHostDefPtr def) VIR_FREE(def-name); } -static void +void virNetworkIpDefClear(virNetworkIpDefPtr def) { VIR_FREE(def-family); diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 484522e..0c4b559 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -310,6 +310,7 @@ virNetworkObjPtr virNetworkFindByName(virNetworkObjListPtr nets, void virNetworkDefFree(virNetworkDefPtr def); void virNetworkObjFree(virNetworkObjPtr net); void virNetworkObjListFree(virNetworkObjListPtr vms); +void virNetworkIpDefClear(virNetworkIpDefPtr def); typedef bool (*virNetworkObjListFilter)(virConnectPtr conn, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index f60911c..ff942d8 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -559,6 +559,7 @@ virNetworkDeleteConfig; virNetworkFindByName; virNetworkFindByUUID; virNetworkForwardTypeToString; +virNetworkIpDefClear; virNetworkIpDefNetmask; virNetworkIpDefPrefix; virNetworkLoadAllConfigs; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 2798010..d1afd16 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -4487,6 +4487,7 @@ networkReleaseActualDevice(virDomainDefPtr dom, * networkGetNetworkAddress: * @netname: the name of a network * @netaddr: string representation of IP address for that network. + * @family: IP family * * Attempt to return an IP (v4) address associated with the named * network. If a libvirt virtual network, that will be provided in the @@ -4503,12 +4504,13 @@ networkReleaseActualDevice(virDomainDefPtr dom, * completely unsupported. */ int -networkGetNetworkAddress(const char *netname, char **netaddr) +networkGetNetworkAddress(const char *netname, char **netaddr, int family) { int ret = -1; virNetworkObjPtr network; virNetworkDefPtr netdef; -virNetworkIpDefPtr ipdef; +virNetworkIpDefPtr ipdef = NULL; +virNetworkIpDefPtr ipdef6 = NULL; virSocketAddr addr; virSocketAddrPtr addrptr = NULL; char *dev_name = NULL; @@ -4529,15 +4531,9 @@ networkGetNetworkAddress(const char *netname, char **netaddr) case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: -/* if there's an ipv4def, get it's address */ +/* if there's an ipv4def or ipv6def, get it's address */ ipdef = virNetworkDefGetIpByIndex(netdef, AF_INET, 0); -if (!ipdef) { -virReportError(VIR_ERR_INTERNAL_ERROR, - _(network '%s' doesn't have an IPv4 address), - netdef-name); -break; -} -addrptr = ipdef-address; +ipdef6 = virNetworkDefGetIpByIndex(netdef, AF_INET6, 0); break; case VIR_NETWORK_FORWARD_BRIDGE: @@ -4561,10 +4557,32 @@ networkGetNetworkAddress(const char *netname, char **netaddr) break; } -if (dev_name) { -if (virNetDevGetIPv4Address(dev_name, addr) 0) -goto error; -addrptr = addr; +switch ((virDomainGraphicsListenFamily) family) { +case VIR_DOMAIN_GRAPHICS_LISTEN_FAMILY_DEFAULT: +case VIR_DOMAIN_GRAPHICS_LISTEN_FAMILY_IPV4: +if (ipdef) +addrptr = ipdef-address; +if (dev_name) { +if (virNetDevGetIPv4Address(dev_name, addr) 0) +goto error; +addrptr = addr; +} +/*if the family is default and we do not get a ipv4 address + *in this place, we will try to get a ipv6 address + */ +if (addrptr || family == VIR_DOMAIN_GRAPHICS_LISTEN_FAMILY_IPV4) +break; +case VIR_DOMAIN_GRAPHICS_LISTEN_FAMILY_IPV6: +if (ipdef6) +addrptr = ipdef6-address; +if (dev_name) { +if (virNetDevGetIPv6Address(dev_name, addr) 0) +goto error; +addrptr = addr; +} +break; +case VIR_DOMAIN_GRAPHICS_LISTEN_FAMILY_LAST: +break; } if (!(addrptr @@ -4579,6 +4597,10 @@ networkGetNetworkAddress(const char *netname, char **netaddr) return ret; error: +if (ipdef6) +virNetworkIpDefClear(ipdef6); +if (ipdef) +virNetworkIpDefClear(ipdef); goto cleanup;
[libvirt] [PATCH 4/4] qemu: fix a error coverd issue in 2 place
we already set a more clearly error in networkGetNetworkAddress, so this error will cover our error in networkGetNetworkAddress. Signed-off-by: Luyao Huang lhu...@redhat.com --- src/qemu/qemu_command.c | 14 -- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6bd8f69..b42e0f4 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7284,12 +7284,9 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg, network driver not present)); goto error; } -if (ret 0) { -virReportError(VIR_ERR_XML_ERROR, - _(listen network '%s' had no usable address), - listenNetwork); +if (ret 0) goto error; -} + listenAddr = netAddr; /* store the address we found in the graphics element so it will * show up in status. */ @@ -7448,12 +7445,9 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg, network driver not present)); goto error; } -if (ret 0) { -virReportError(VIR_ERR_XML_ERROR, - _(listen network '%s' had no usable address), - listenNetwork); +if (ret 0) goto error; -} + listenAddr = netAddr; /* store the address we found in the graphics element so it will * show up in status. */ -- 1.8.3.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 1/4] Implement public API for virDomainGetIOThreadsInfo
On 02/12/2015 08:12 AM, Daniel P. Berrange wrote: On Thu, Feb 12, 2015 at 08:03:44AM -0500, John Ferlan wrote: Add virDomainGetIOThreadsInfo in order to returned a list of virDomainIOThreadsInfoPtr structures which list the IOThread ID, the thread_id, and the CPU Affinity map for each IOThread for the active domain. Also added virDomainIOThreadsInfoFree in order to free the cpumap and the array entry structure. For inactive domains or where IOThreads is not supported return an error and an empty structure Signed-off-by: John Ferlan jfer...@redhat.com --- include/libvirt/libvirt-domain.h | 22 +- src/driver-hypervisor.h | 8 - src/libvirt-domain.c | 63 +++- src/libvirt_public.syms | 6 4 files changed, 96 insertions(+), 3 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 4dbd7f5..54f8de4 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -4,7 +4,7 @@ * Description: Provides APIs for the management of domains * Author: Daniel Veillard veill...@redhat.com * - * Copyright (C) 2006-2014 Red Hat, Inc. + * Copyright (C) 2006-2015 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 @@ -1568,6 +1568,26 @@ int virDomainGetEmulatorPinInfo (virDomainPtr domain, unsigned int flags); /** + * virIOThreadsInfo: + * + * The data structure for information about IOThreads in a domain + */ +typedef struct _virDomainIOThreadsInfo virDomainIOThreadsInfo; +typedef virDomainIOThreadsInfo *virDomainIOThreadsInfoPtr; +struct _virDomainIOThreadsInfo { +unsigned int iothread_id; /* IOThread ID */ +unsigned int thread_id;/* Thread ID associated with IOThread */ Hmm, one thing we've avoided doing in the past is to expose the idea of PIDs in any of the libvirt APIs - we never expose the QEMU PID anywhere. So I think I'd leave this thread_id field out of the info here, the iothread_id should be sufficient for apps. The actual thread_is should only be needed internally by libvirt itself, in order to do pinning so forth - we don't want to have apps using it todo pinning themslves. OK no problem - that's folklore I wasn't aware of... Easy enough to remove. John -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] util: make use of VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE in virLockSpaceAcquireResource
On 02/12/2015 07:17 PM, Daniel P. Berrange wrote: On Thu, Feb 12, 2015 at 07:12:57PM +0800, Shanzhi Yu wrote: When create external disk snapshot with virtlock enabled, libvirtd will hang if flag VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE is missed in virLockSpaceAcquireResource. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1191901 Signed-off-by: Shanzhi Yu s...@redhat.com --- src/util/virlockspace.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/util/virlockspace.c b/src/util/virlockspace.c index 2366a74..25b4433 100644 --- a/src/util/virlockspace.c +++ b/src/util/virlockspace.c @@ -626,8 +626,10 @@ int virLockSpaceAcquireResource(virLockSpacePtr lockspace, virMutexLock(lockspace-lock); if ((res = virHashLookup(lockspace-resources, resname))) { -if ((res-flags VIR_LOCK_SPACE_ACQUIRE_SHARED) -(flags VIR_LOCK_SPACE_ACQUIRE_SHARED)) { +if (((res-flags VIR_LOCK_SPACE_ACQUIRE_SHARED) +(flags VIR_LOCK_SPACE_ACQUIRE_SHARED)) || +((res-flags VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE) +(flags VIR_LOCK_SPACE_ACQUIRE_AUTOCREATE))){ No, this is wrong. If virHashLookup returns a non-NULL entry it indicates that the lock is already held. It is not valid to ignore this error if 'autocreate' flag is set, as that would allow multiple VMs to own the same disk which is exactly the scenario we are trying to prevent. Yes. It's really wrong way. Please ignore this. Regards, Daniel -- Regards shyu -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 1/4] security: Refactor virSecurityManagerGenLabel
-if (mgr == NULL || mgr-drv == NULL) -return ret; - Can either of these conditions be true here? If so, we should leave the check here (possibly add an error message), because GetNested will dereference them. If not, they should be cleaned up in a separate patch. Jan Well, the thing is, this was the first function in qemuProcessStart that touched the seclabel structures as well as the security manager and no other function called after this one didn't really need a check like this, because GenLabel would have returned -1 in case of NULL pointer, thus jumping to cleanup. Now, as I introduced a new function that is called before GenLabel, I think it might be correct to move this check up to this CheckAllLabel function and the original meaning remains, i.e. in case of NULL pointer CheckAllLabel returns -1 (I'll fix the return code from 0 to -1 which is clearly wrong and this must be just a typo, but you get the point...) followed by qemuProcessStart jumping to cleanup. Erik -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 1/4] Implement public API for virDomainGetIOThreadsInfo
On Thu, Feb 12, 2015 at 08:03:44AM -0500, John Ferlan wrote: Add virDomainGetIOThreadsInfo in order to returned a list of virDomainIOThreadsInfoPtr structures which list the IOThread ID, the thread_id, and the CPU Affinity map for each IOThread for the active domain. Also added virDomainIOThreadsInfoFree in order to free the cpumap and the array entry structure. For inactive domains or where IOThreads is not supported return an error and an empty structure Signed-off-by: John Ferlan jfer...@redhat.com --- include/libvirt/libvirt-domain.h | 22 +- src/driver-hypervisor.h | 8 - src/libvirt-domain.c | 63 +++- src/libvirt_public.syms | 6 4 files changed, 96 insertions(+), 3 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 4dbd7f5..54f8de4 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -4,7 +4,7 @@ * Description: Provides APIs for the management of domains * Author: Daniel Veillard veill...@redhat.com * - * Copyright (C) 2006-2014 Red Hat, Inc. + * Copyright (C) 2006-2015 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 @@ -1568,6 +1568,26 @@ int virDomainGetEmulatorPinInfo (virDomainPtr domain, unsigned int flags); /** + * virIOThreadsInfo: + * + * The data structure for information about IOThreads in a domain + */ +typedef struct _virDomainIOThreadsInfo virDomainIOThreadsInfo; +typedef virDomainIOThreadsInfo *virDomainIOThreadsInfoPtr; +struct _virDomainIOThreadsInfo { +unsigned int iothread_id; /* IOThread ID */ +unsigned int thread_id;/* Thread ID associated with IOThread */ Hmm, one thing we've avoided doing in the past is to expose the idea of PIDs in any of the libvirt APIs - we never expose the QEMU PID anywhere. So I think I'd leave this thread_id field out of the info here, the iothread_id should be sufficient for apps. The actual thread_is should only be needed internally by libvirt itself, in order to do pinning so forth - we don't want to have apps using it todo pinning themslves. +unsigned char *cpumap; /* CPU map for thread */ +int cpumaplen; /* cpumap size */ +}; + +void virDomainIOThreadsInfoFree(virDomainIOThreadsInfoPtr info); + +int virDomainGetIOThreadsInfo(virDomainPtr domain, + virDomainIOThreadsInfoPtr **info, + unsigned int flags); Regards, Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/4] Introduce display of IOThreads Information
These patches satisfy part of: https://bugzilla.redhat.com/show_bug.cgi?id=1135491 Patches 1 and 2 are fairly straightforward adding a new API type patches although they were implemented with the thought of how patch 3 works. Also rather than implement a get iothreads and a get iothreadspin API, I combined the two into one. I could separate if that's more desirable, but it just seemed more natural to have one API do both. Patch 3 adds the qemu related to code to fetch not only the IOThreads data, but also the cpumap/cpumaplen in order to display the CPU Affinity. For that I somewhat followed how the vcpuinfo code works, but also a bit on how the nodecpumap code does things. Unlike the vcpuinfo code, I had no way to count the IOThreads before calling, so rather than pass in a cpumap/cpumaplen - I allocated them in the qemu code and passed them back within the IOThreadsInfo structure. Of course it did get me to thinking why are we doing 1 for each IOThread, but to that degree I was following the vcpu model. Patch 4 is the new 'virsh iothreads' command with no arguments (for now). It will display the IOThreads of active domains only. Future patches will implement a SetIOThreads API to change the thread pinning and allow for add/delete of IOThreads. I'm hoping to use the same command with new options --pin --cpuset for pinning the IOThreads or --add/--del to add/remove IOThreads, but I wanted to make sure I had buyin on the use of one API to accomplish both get of basic IOThread data and CPU Affinity data. John Ferlan (4): Implement public API for virDomainGetIOThreadsInfo remote: Implement the remote plumbing for virDomainGetIOThreads qemu: Implement the qemu driver fetch for IOThreads virsh: Add 'iothreads' command daemon/remote.c | 75 +- include/libvirt/libvirt-domain.h | 22 +++- src/driver-hypervisor.h | 8 ++- src/libvirt-domain.c | 63 +- src/libvirt_public.syms | 6 +++ src/qemu/qemu_driver.c | 114 +++ src/remote/remote_driver.c | 82 +++- src/remote/remote_protocol.x | 29 +- src/remote_protocol-structs | 20 +++ src/rpc/gendispatch.pl | 1 + tools/virsh-domain.c | 72 + tools/virsh.pod | 7 +++ 12 files changed, 492 insertions(+), 7 deletions(-) -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/4] remote: Implement the remote plumbing for virDomainGetIOThreads
Implement the remote plumbing for virDomainGetIOThreads Signed-off-by: John Ferlan jfer...@redhat.com --- daemon/remote.c | 75 +++- src/remote/remote_driver.c | 82 +++- src/remote/remote_protocol.x | 29 ++-- src/remote_protocol-structs | 20 +++ src/rpc/gendispatch.pl | 1 + 5 files changed, 203 insertions(+), 4 deletions(-) diff --git a/daemon/remote.c b/daemon/remote.c index d657a09..b3c4cc3 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -1,7 +1,7 @@ /* * remote.c: handlers for RPC method calls * - * Copyright (C) 2007-2014 Red Hat, Inc. + * Copyright (C) 2007-2015 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 @@ -2269,6 +2269,79 @@ remoteDispatchDomainGetVcpus(virNetServerPtr server ATTRIBUTE_UNUSED, } static int +remoteDispatchDomainGetIOThreadsInfo(virNetServerPtr server ATTRIBUTE_UNUSED, + virNetServerClientPtr client, + virNetMessagePtr msg ATTRIBUTE_UNUSED, + virNetMessageErrorPtr rerr, + remote_domain_get_iothreads_info_args *args, + remote_domain_get_iothreads_info_ret *ret) +{ +int rv = -1; +size_t i; +struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client); +virDomainIOThreadsInfoPtr *info = NULL; +virDomainPtr dom = NULL; +remote_domain_iothreads_info *dst; +int ninfo = 0; + +if (!priv-conn) { +virReportError(VIR_ERR_INTERNAL_ERROR, %s, _(connection not open)); +goto cleanup; +} + +if (!(dom = get_nonnull_domain(priv-conn, args-dom))) +goto cleanup; + +if ((ninfo = virDomainGetIOThreadsInfo(dom, info, args-flags)) 0) +goto cleanup; + +if (ninfo REMOTE_IOTHREADS_INFO_MAX) { +virReportError(VIR_ERR_RPC, + _(Too many IOThreads in info: %d for limit %d), + ninfo, REMOTE_IOTHREADS_INFO_MAX); +goto cleanup; +} + +if (ninfo) { +if (VIR_ALLOC_N(ret-info.info_val, ninfo) 0) +goto cleanup; + +ret-info.info_len = ninfo; + +for (i = 0; i ninfo; i++) { +dst = ret-info.info_val[i]; +dst-iothread_id = info[i]-iothread_id; +dst-thread_id = info[i]-thread_id; + +/* No need to allocate/copy the cpumap if we make the reasonable + * assumption that unsigned char and char are the same size. + */ +dst-cpumap.cpumap_len = info[i]-cpumaplen; +dst-cpumap.cpumap_val = (char *)info[i]-cpumap; +info[i]-cpumap = NULL; +} +} else { +ret-info.info_len = 0; +ret-info.info_val = NULL; +} + +ret-ret = ninfo; + +rv = 0; + + cleanup: +if (rv 0) +virNetMessageSaveError(rerr); +virObjectUnref(dom); +if (ninfo = 0) +for (i = 0; i ninfo; i++) +virDomainIOThreadsInfoFree(info[i]); +VIR_FREE(info); + +return rv; +} + +static int remoteDispatchDomainMigratePrepare(virNetServerPtr server ATTRIBUTE_UNUSED, virNetServerClientPtr client ATTRIBUTE_UNUSED, virNetMessagePtr msg ATTRIBUTE_UNUSED, diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index d4fd658..2587870 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -2,7 +2,7 @@ * remote_driver.c: driver to provide access to libvirtd running * on a remote machine * - * Copyright (C) 2007-2014 Red Hat, Inc. + * Copyright (C) 2007-2015 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 @@ -2316,6 +2316,85 @@ remoteDomainGetVcpus(virDomainPtr domain, } static int +remoteDomainGetIOThreadsInfo(virDomainPtr dom, + virDomainIOThreadsInfoPtr **info, + unsigned int flags) +{ +int rv = -1; +size_t i; +struct private_data *priv = dom-conn-privateData; +remote_domain_get_iothreads_info_args args; +remote_domain_get_iothreads_info_ret ret; +remote_domain_iothreads_info *src; +virDomainIOThreadsInfoPtr *info_ret = NULL; + +remoteDriverLock(priv); + +make_nonnull_domain(args.dom, dom); + +args.flags = flags; + +memset(ret, 0, sizeof(ret)); + +if (call(dom-conn, priv, 0, REMOTE_PROC_DOMAIN_GET_IOTHREADS_INFO, + (xdrproc_t)xdr_remote_domain_get_iothreads_info_args, + (char *)args, + (xdrproc_t)xdr_remote_domain_get_iothreads_info_ret, + (char *)ret) == -1) +goto done; + +if (ret.info.info_len
[libvirt] [PATCH 3/4] qemu: Implement the qemu driver fetch for IOThreads
Make necessary checks for active domain and IOThread capability before calling the monitor to fetch IOThread data for a domain. If there are threads, then also return the processor affinity maps - this is similar to existing GetVcpuPin, GetVcpuInfo, and GetEmulatorPin fetches of the processor affinity. Having a separate GetIOThreadsPin seemed to be waste if it could be done in one API. Signed-off-by: John Ferlan jfer...@redhat.com --- src/qemu/qemu_driver.c | 114 + 1 file changed, 114 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 709f468..ea61015 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5541,6 +5541,119 @@ qemuDomainGetMaxVcpus(virDomainPtr dom) VIR_DOMAIN_VCPU_MAXIMUM)); } +static int +qemuDomainGetIOThreadsInfo(virDomainPtr dom, + virDomainIOThreadsInfoPtr **info, + unsigned int flags) +{ +virQEMUDriverPtr driver = dom-conn-privateData; +virDomainObjPtr vm; +qemuDomainObjPrivatePtr priv; +qemuMonitorIOThreadsInfoPtr *iothreads = NULL; +virDomainIOThreadsInfoPtr *info_ret = NULL; +int niothreads = 0; +int maxcpu, hostcpus, maplen; +int ret = -1; +size_t i; + +virCheckFlags(0, -1); + +if (!(vm = qemuDomObjFromDomain(dom))) +goto cleanup; + +if (virDomainGetIOThreadsInfoEnsureACL(dom-conn, vm-def) 0) +goto cleanup; + +if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) 0) +goto cleanup; + +if (!virDomainObjIsActive(vm)) { +virReportError(VIR_ERR_OPERATION_INVALID, %s, + _(cannot list IOThreads for an inactive domain)); +goto endjob; +} + +priv = vm-privateData; +if (!virQEMUCapsGet(priv-qemuCaps, QEMU_CAPS_OBJECT_IOTHREAD)) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, + _(IOThreads not supported with this binary)); +goto endjob; +} + +if (qemuDomainObjEnterMonitorAsync(driver, vm, QEMU_ASYNC_JOB_NONE) 0) +goto endjob; +niothreads = qemuMonitorGetIOThreads(priv-mon, iothreads); +if (qemuDomainObjExitMonitor(driver, vm) 0) +goto endjob; +if (niothreads 0) +goto endjob; + +/* Nothing to do */ +if (niothreads == 0) { +ret = 0; +goto endjob; +} + +if ((hostcpus = nodeGetCPUCount()) 0) +goto endjob; + +maplen = VIR_CPU_MAPLEN(hostcpus); +maxcpu = maplen * 8; +if (maxcpu hostcpus) +maxcpu = hostcpus; + +if (VIR_ALLOC_N(info_ret, niothreads) 0) +goto endjob; + +for (i = 0; i niothreads; i++) { +virBitmapPtr map = NULL; +unsigned char *tmpmap = NULL; +int tmpmaplen = 0; + +if (VIR_ALLOC(info_ret[i]) 0) +goto endjob; + +if (virStrToLong_ui(iothreads[i]-name + strlen(iothread), NULL, 10, +info_ret[i]-iothread_id) 0) +goto endjob; +info_ret[i]-thread_id = iothreads[i]-thread_id; + +if (VIR_ALLOC_N(info_ret[i]-cpumap, maplen) 0) +goto endjob; + +if (virProcessGetAffinity(iothreads[i]-thread_id, map, maxcpu) 0) +goto endjob; + +virBitmapToData(map, tmpmap, tmpmaplen); +if (tmpmaplen maplen) +tmpmaplen = maplen; +memcpy(info_ret[i]-cpumap, tmpmap, tmpmaplen); +info_ret[i]-cpumaplen = tmpmaplen; + +VIR_FREE(tmpmap); +virBitmapFree(map); +} + +*info = info_ret; +info_ret = NULL; +ret = niothreads; + + endjob: +qemuDomainObjEndJob(driver, vm); + + cleanup: +qemuDomObjEndAPI(vm); + +if (info_ret) { +for (i = 0; i niothreads; i++) +virDomainIOThreadsInfoFree(info_ret[i]); +VIR_FREE(info_ret); +} +return ret; + +} + + static int qemuDomainGetSecurityLabel(virDomainPtr dom, virSecurityLabelPtr seclabel) { virQEMUDriverPtr driver = dom-conn-privateData; @@ -19141,6 +19254,7 @@ static virHypervisorDriver qemuHypervisorDriver = { .domainGetEmulatorPinInfo = qemuDomainGetEmulatorPinInfo, /* 0.10.0 */ .domainGetVcpus = qemuDomainGetVcpus, /* 0.4.4 */ .domainGetMaxVcpus = qemuDomainGetMaxVcpus, /* 0.4.4 */ +.domainGetIOThreadsInfo = qemuDomainGetIOThreadsInfo, /* 1.2.13 */ .domainGetSecurityLabel = qemuDomainGetSecurityLabel, /* 0.6.1 */ .domainGetSecurityLabelList = qemuDomainGetSecurityLabelList, /* 0.10.0 */ .nodeGetSecurityModel = qemuNodeGetSecurityModel, /* 0.6.1 */ -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/4] Implement public API for virDomainGetIOThreadsInfo
Add virDomainGetIOThreadsInfo in order to returned a list of virDomainIOThreadsInfoPtr structures which list the IOThread ID, the thread_id, and the CPU Affinity map for each IOThread for the active domain. Also added virDomainIOThreadsInfoFree in order to free the cpumap and the array entry structure. For inactive domains or where IOThreads is not supported return an error and an empty structure Signed-off-by: John Ferlan jfer...@redhat.com --- include/libvirt/libvirt-domain.h | 22 +- src/driver-hypervisor.h | 8 - src/libvirt-domain.c | 63 +++- src/libvirt_public.syms | 6 4 files changed, 96 insertions(+), 3 deletions(-) diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h index 4dbd7f5..54f8de4 100644 --- a/include/libvirt/libvirt-domain.h +++ b/include/libvirt/libvirt-domain.h @@ -4,7 +4,7 @@ * Description: Provides APIs for the management of domains * Author: Daniel Veillard veill...@redhat.com * - * Copyright (C) 2006-2014 Red Hat, Inc. + * Copyright (C) 2006-2015 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 @@ -1568,6 +1568,26 @@ int virDomainGetEmulatorPinInfo (virDomainPtr domain, unsigned int flags); /** + * virIOThreadsInfo: + * + * The data structure for information about IOThreads in a domain + */ +typedef struct _virDomainIOThreadsInfo virDomainIOThreadsInfo; +typedef virDomainIOThreadsInfo *virDomainIOThreadsInfoPtr; +struct _virDomainIOThreadsInfo { +unsigned int iothread_id; /* IOThread ID */ +unsigned int thread_id;/* Thread ID associated with IOThread */ +unsigned char *cpumap; /* CPU map for thread */ +int cpumaplen; /* cpumap size */ +}; + +void virDomainIOThreadsInfoFree(virDomainIOThreadsInfoPtr info); + +int virDomainGetIOThreadsInfo(virDomainPtr domain, + virDomainIOThreadsInfoPtr **info, + unsigned int flags); + +/** * VIR_USE_CPU: * @cpumap: pointer to a bit map of real CPUs (in 8-bit bytes) (IN/OUT) * @cpu: the physical CPU number diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h index a1198ad..2ce1a51 100644 --- a/src/driver-hypervisor.h +++ b/src/driver-hypervisor.h @@ -1,7 +1,7 @@ /* * driver-hypervisor.h: entry points for hypervisor drivers * - * Copyright (C) 2006-2014 Red Hat, Inc. + * Copyright (C) 2006-2015 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 @@ -381,6 +381,11 @@ typedef int (*virDrvDomainGetMaxVcpus)(virDomainPtr domain); typedef int +(*virDrvDomainGetIOThreadsInfo)(virDomainPtr domain, +virDomainIOThreadsInfoPtr **info, +unsigned int flags); + +typedef int (*virDrvDomainGetSecurityLabel)(virDomainPtr domain, virSecurityLabelPtr seclabel); @@ -1254,6 +1259,7 @@ struct _virHypervisorDriver { virDrvDomainGetEmulatorPinInfo domainGetEmulatorPinInfo; virDrvDomainGetVcpus domainGetVcpus; virDrvDomainGetMaxVcpus domainGetMaxVcpus; +virDrvDomainGetIOThreadsInfo domainGetIOThreadsInfo; virDrvDomainGetSecurityLabel domainGetSecurityLabel; virDrvDomainGetSecurityLabelList domainGetSecurityLabelList; virDrvNodeGetSecurityModel nodeGetSecurityModel; diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c index 492e90a..6834d38 100644 --- a/src/libvirt-domain.c +++ b/src/libvirt-domain.c @@ -1,7 +1,7 @@ /* * libvirt-domain.c: entry points for virDomainPtr APIs * - * Copyright (C) 2006-2014 Red Hat, Inc. + * Copyright (C) 2006-2015 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 @@ -7891,6 +7891,67 @@ virDomainGetMaxVcpus(virDomainPtr domain) /** + * virDomainGetIOThreadsInfo: + * @dom: a domain object + * @info: pointer to an array of virDomainIOThreadsInfo structures (OUT) + * @flags: extra flags; not used yet, so callers should always pass 0 + * + * Fetch IOThreads of an active domain including the cpumap information to + * determine on which CPU the IOThread has affinity to run. + * + * Returns the number of IOThreads or -1 in case of error. + * On success, the array of information is stored into @info. The caller is + * responsible for calling virDomainIOThreadsInfoFree() on each array element, + * then calling free() on @info. On error, @info is set to NULL. + */ +int +virDomainGetIOThreadsInfo(virDomainPtr dom, + virDomainIOThreadsInfoPtr **info, +
[libvirt] [PATCH 4/4] virsh: Add 'iothreads' command
Add the 'iothreads' command to display live IOThread Info data $ virsh iothreads $dom IOThread ID Thread ID CPU Affinity 1 31983 2 2 31984 3 3 31985 0-3 $ echo $? 0 For domains which don't have IOThreads the following is returned: $ virsh iothreads $dom error: No IOThreads found for the domain $ echo $? 0 For domains which are not running the following is returned: $ virsh iothreads $dom error: Unable to get domain IOThreads information error: Requested operation is not valid: cannot list IOThreads for an inactive domain $ echo $? 1 Signed-off-by: John Ferlan jfer...@redhat.com --- tools/virsh-domain.c | 72 tools/virsh.pod | 7 + 2 files changed, 79 insertions(+) diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 20bafbe..14cb3f8 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -6781,6 +6781,72 @@ cmdSetvcpus(vshControl *ctl, const vshCmd *cmd) } /* + * iothreads command + */ +static const vshCmdInfo info_iothreads[] = { +{.name = help, + .data = N_(view domain IOThreads) +}, +{.name = desc, + .data = N_(Returns basic information about the domain IOThreads.) +}, +{.name = NULL} +}; +static const vshCmdOptDef opts_iothreads[] = { +{.name = domain, + .type = VSH_OT_DATA, + .flags = VSH_OFLAG_REQ, + .help = N_(domain name, id or uuid) +}, +{.name = NULL} +}; + +static bool +cmdIOThreadsInfo(vshControl *ctl, const vshCmd *cmd) +{ +virDomainPtr dom; +int niothreads = 0; +virDomainIOThreadsInfoPtr *info; +size_t i; +int maxcpu; + +if (!(dom = vshCommandOptDomain(ctl, cmd, NULL))) +return false; + +if ((maxcpu = vshNodeGetCPUCount(ctl-conn)) 0) +goto cleanup; + +if ((niothreads = virDomainGetIOThreadsInfo(dom, info, 0)) 0) { +vshError(ctl, _(Unable to get domain IOThreads information)); +goto cleanup; +} + +if (niothreads == 0) { +vshError(ctl, _(No IOThreads found for the domain)); +goto cleanup; +} + +vshPrintExtra(ctl, %-15s %-15s %-15s\n, + _(IOThread ID), _(Thread ID), _(CPU Affinity)); +vshPrintExtra(ctl, \n); +for (i = 0; i niothreads; i++) { + +vshPrintExtra(ctl, %-15u %-15u , + info[i]-iothread_id, + info[i]-thread_id); +ignore_value(vshPrintPinInfo(info[i]-cpumap, info[i]-cpumaplen, + maxcpu, 0)); +vshPrint(ctl, \n); +virDomainIOThreadsInfoFree(info[i]); +} +VIR_FREE(info); + + cleanup: +virDomainFree(dom); +return niothreads = 0; +} + +/* * cpu-compare command */ static const vshCmdInfo info_cpu_compare[] = { @@ -12669,6 +12735,12 @@ const vshCmdDef domManagementCmds[] = { .info = info_inject_nmi, .flags = 0 }, +{.name = iothreads, + .handler = cmdIOThreadsInfo, + .opts = opts_iothreads, + .info = info_iothreads, + .flags = 0 +}, {.name = send-key, .handler = cmdSendKey, .opts = opts_send_key, diff --git a/tools/virsh.pod b/tools/virsh.pod index a3f527f..2c28acc 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1360,6 +1360,13 @@ If I--timeout is specified, the command gives up waiting for events after Iseconds have elapsed. With I--loop, the command prints all events until a timeout or interrupt key. +=item Biothreads Idomain + +Display basic domain IOThreads information including the IOThread ID, the +Thread ID, and the CPU Affinity for each IOThread. + +Note that the display of information only works for active domains. + =item Bmanagedsave Idomain [I--bypass-cache] [{I--running | I--paused}] [I--verbose] -- 2.1.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 2/3] docs, schema, conf: Add support for setting scheduler parameters of guest threads
On Wed, Feb 11, 2015 at 10:37:46AM -0700, Eric Blake wrote: On 02/10/2015 08:35 AM, Martin Kletzander wrote: In order for QEMU vCPU (and other) threads to run with RT scheduler, libvirt needs to take care of that so QEMU doesn't have to run privileged. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1178986 Might be nice to also show a sample XML usage in the commit message. Oh, sorry for that, will do next time! [...] @@ -652,6 +654,20 @@ span class=sinceOnly QEMU driver support since 0.10.0/span /dd + dtcodevcpusched/code and codeiothreadsched/code/dt + dd +The optional codevcpusched/code elements specifie the scheduler +(values codebatch/code, codeidle/code, codefifo/code, +coderr/code) for particular vCPU/IOThread threads (based on +codevcpus/code and codeiothreads/code, leaving out +codevcpus/code/codeiothreads/code sets the default). +For real-time schedulers (codefifo/code, coderr/code), +priority must be specified as well (and is ignored for +non-real-time ones). The value range for the priority depends +on the host kernel (usually 1-99). +span class=sinceSince 1.2.12/span 1.2.13, actually. Fixed as a trivial with this commit: commit a0638ff21972fdbfdd11e56c271e85480aee7620 Author: Martin Kletzander mklet...@redhat.com Date: Thu Feb 12 13:29:08 2015 +0100 docs: Fix version reference in vcpu/iothread scheduling Signed-off-by: Martin Kletzander mklet...@redhat.com diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fcf5984..873a1c7 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -664,7 +664,7 @@ real-time schedulers (codefifo/code, coderr/code), priority must be specified as well (and is ignored for non-real-time ones). The value range for the priority depends on the host kernel (usually 1-99). -span class=sinceSince 1.2.12/span +span class=sinceSince 1.2.13/span /dd /dl -- pgpf2hO7p3ecr.pgp Description: PGP signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Fix a syntax error in the description text of libvirtd.conf
On 02/11/2015 09:22 PM, Zhang Bo wrote: not yet not - not yet. Signed-off-by: Zhang Bo oscar.zhan...@huawei.com --- daemon/libvirtd.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) ACK and pushed. diff --git a/daemon/libvirtd.conf b/daemon/libvirtd.conf index d4f6a1c..069ef3a 100644 --- a/daemon/libvirtd.conf +++ b/daemon/libvirtd.conf @@ -272,7 +272,7 @@ # connection succeeds. #max_queued_clients = 1000 -# The maximum length of queue of accepted but not yet not +# The maximum length of queue of accepted but not yet # authenticated clients. The default value is zero, meaning # the feature is disabled. #max_anonymous_clients = 20 -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/3] virQEMUCapsCacheLookupCopy: Pass machine type
It will come handy in the near future when we will filter some capabilities based on it. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- src/qemu/qemu_capabilities.c | 4 +++- src/qemu/qemu_capabilities.h | 3 ++- src/qemu/qemu_migration.c| 3 ++- src/qemu/qemu_process.c | 9 ++--- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index a04095e..3992b2b 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -3583,7 +3583,9 @@ virQEMUCapsCacheLookup(virQEMUCapsCachePtr cache, const char *binary) virQEMUCapsPtr -virQEMUCapsCacheLookupCopy(virQEMUCapsCachePtr cache, const char *binary) +virQEMUCapsCacheLookupCopy(virQEMUCapsCachePtr cache, + const char *binary, + const char *machineType ATTRIBUTE_UNUSED) { virQEMUCapsPtr qemuCaps = virQEMUCapsCacheLookup(cache, binary); virQEMUCapsPtr ret; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 1c1227a..242a33d 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -291,7 +291,8 @@ virQEMUCapsCachePtr virQEMUCapsCacheNew(const char *libDir, virQEMUCapsPtr virQEMUCapsCacheLookup(virQEMUCapsCachePtr cache, const char *binary); virQEMUCapsPtr virQEMUCapsCacheLookupCopy(virQEMUCapsCachePtr cache, - const char *binary); + const char *binary, + const char *machineType); virQEMUCapsPtr virQEMUCapsCacheLookupByArch(virQEMUCapsCachePtr cache, virArch arch); void virQEMUCapsCacheFree(virQEMUCapsCachePtr cache); diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 4506d87..8309b8f 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -2918,7 +2918,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver, hostIPv6Capable = true; } if (!(qemuCaps = virQEMUCapsCacheLookupCopy(driver-qemuCapsCache, -(*def)-emulator))) +(*def)-emulator, +(*def)-os.machine))) goto cleanup; qemuIPv6Capable = virQEMUCapsGet(qemuCaps, QEMU_CAPS_IPV6_MIGRATION); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 43a64a1..49d6bf3 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3828,7 +3828,8 @@ qemuProcessReconnect(void *opaque) */ if (!priv-qemuCaps !(priv-qemuCaps = virQEMUCapsCacheLookupCopy(driver-qemuCapsCache, - obj-def-emulator))) + obj-def-emulator, + obj-def-os.machine))) goto error; /* In case the domain shutdown while we were not running, @@ -4460,7 +4461,8 @@ int qemuProcessStart(virConnectPtr conn, VIR_DEBUG(Determining emulator version); virObjectUnref(priv-qemuCaps); if (!(priv-qemuCaps = virQEMUCapsCacheLookupCopy(driver-qemuCapsCache, - vm-def-emulator))) + vm-def-emulator, + vm-def-os.machine))) goto cleanup; /* network devices must be prepared before hostdevs, because @@ -5498,7 +5500,8 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, VIR_DEBUG(Determining emulator version); virObjectUnref(priv-qemuCaps); if (!(priv-qemuCaps = virQEMUCapsCacheLookupCopy(driver-qemuCapsCache, - vm-def-emulator))) + vm-def-emulator, + vm-def-os.machine))) goto error; VIR_DEBUG(Preparing monitor state); -- 2.0.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/3] virQEMUCapsCacheLookupCopy: Filter qemuCaps based on machineType
Not all machine types support all devices, device properties, backends, etc. So until we create a matrix of [machineType, qemuCaps], lets just filter out some capabilities before we return them to the consumer (which is going to make decisions based on them straight away). Currently, as qemu is unable to tell which capabilities are (not) enabled for given machine types, it's us who has to hardcode the matrix. One day maybe the hardcoding will go away and we can create the matrix dynamically on the fly based on a few monitor calls. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- src/qemu/qemu_capabilities.c | 39 ++- src/qemu/qemu_capabilities.h | 2 ++ tests/qemuxml2argvtest.c | 2 ++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 3992b2b..233449b 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -3511,6 +3511,42 @@ bool virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps) } +struct virQEMUCapsMachineTypeFilter { +const char *machineType; +virQEMUCapsFlags *flags; +size_t nflags; +}; + +static const struct virQEMUCapsMachineTypeFilter virQEMUCapsMachineFilter[] = { +/* { blah, virQEMUCapsMachineBLAHFilter, + ARRAY_CARDINALITY(virQEMUCapsMachineBLAHFilter) }, */ +{ , NULL, 0 }, +}; + + +void +virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps, + const char *machineType) +{ +size_t i; + +if (!machineType) +return; + +for (i = 0; i ARRAY_CARDINALITY(virQEMUCapsMachineFilter); i++) { +const struct virQEMUCapsMachineTypeFilter *filter = virQEMUCapsMachineFilter[i]; +size_t j; + +if (STRNEQ(filter-machineType, machineType)) +continue; + +for (j = 0; j filter-nflags; j++) +virQEMUCapsClear(qemuCaps, filter-flags[j]); +} + +} + + virQEMUCapsCachePtr virQEMUCapsCacheNew(const char *libDir, const char *cacheDir, @@ -3585,7 +3621,7 @@ virQEMUCapsCacheLookup(virQEMUCapsCachePtr cache, const char *binary) virQEMUCapsPtr virQEMUCapsCacheLookupCopy(virQEMUCapsCachePtr cache, const char *binary, - const char *machineType ATTRIBUTE_UNUSED) + const char *machineType) { virQEMUCapsPtr qemuCaps = virQEMUCapsCacheLookup(cache, binary); virQEMUCapsPtr ret; @@ -3595,6 +3631,7 @@ virQEMUCapsCacheLookupCopy(virQEMUCapsCachePtr cache, ret = virQEMUCapsNewCopy(qemuCaps); virObjectUnref(qemuCaps); +virQEMUCapsFilterByMachineType(ret, machineType); return ret; } diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 242a33d..5d87c18 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -284,6 +284,8 @@ int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps, bool virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps); +void virQEMUCapsFilterByMachineType(virQEMUCapsPtr qemuCaps, +const char *machineType); virQEMUCapsCachePtr virQEMUCapsCacheNew(const char *libDir, const char *cacheDir, diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 316f479..f2120dd 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -308,6 +308,8 @@ static int testCompareXMLToArgvFiles(const char *xml, goto out; } +virQEMUCapsFilterByMachineType(extraFlags, vmdef-os.machine); + if (virQEMUCapsGet(extraFlags, QEMU_CAPS_DEVICE)) { if (qemuDomainAssignAddresses(vmdef, extraFlags, NULL)) { if (flags FLAG_EXPECT_ERROR) -- 2.0.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/3] qemuCaps: Disable memdev for rhel6.5.0 machine type
Well, after [1] qemu doesn't understand '-object memory-backend-ram' nor '-object memory-backend-file'. Make sure we remove that capabilities from our internal list temporarily, so the qemu command line is constructed in correct way. 1: https://bugzilla.redhat.com/show_bug.cgi?id=1170093 Signed-off-by: Michal Privoznik mpriv...@redhat.com --- src/qemu/qemu_capabilities.c | 10 --- .../qemuxml2argv-numatune-memnode-rhel650.args | 7 + .../qemuxml2argv-numatune-memnode-rhel650.xml | 31 ++ tests/qemuxml2argvtest.c | 4 +++ 4 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-rhel650.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-rhel650.xml diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 233449b..940f070 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -3510,6 +3510,11 @@ bool virQEMUCapsIsValid(virQEMUCapsPtr qemuCaps) return sb.st_ctime == qemuCaps-ctime; } +static virQEMUCapsFlags virQEMUCapsMachineRHEL650Filter[] = { +/* For some reason, rhel6.5.0 machine type doesn't understand memdev. */ +QEMU_CAPS_OBJECT_MEMORY_RAM, +QEMU_CAPS_OBJECT_MEMORY_FILE, +}; struct virQEMUCapsMachineTypeFilter { const char *machineType; @@ -3518,9 +3523,8 @@ struct virQEMUCapsMachineTypeFilter { }; static const struct virQEMUCapsMachineTypeFilter virQEMUCapsMachineFilter[] = { -/* { blah, virQEMUCapsMachineBLAHFilter, - ARRAY_CARDINALITY(virQEMUCapsMachineBLAHFilter) }, */ -{ , NULL, 0 }, +{ rhel6.5.0, virQEMUCapsMachineRHEL650Filter, +ARRAY_CARDINALITY(virQEMUCapsMachineRHEL650Filter)}, }; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-rhel650.args b/tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-rhel650.args new file mode 100644 index 000..813f3ea --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-rhel650.args @@ -0,0 +1,7 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/kvm -S -M rhel6.5.0 -m 24104 -smp 32 \ +-numa node,nodeid=0,cpus=0,mem=20 \ +-numa node,nodeid=1,cpus=1-27,cpus=29,mem=645 \ +-numa node,nodeid=2,cpus=28,cpus=30-31,mem=23440 \ +-nographic -monitor unix:/tmp/test-monitor,server,nowait \ +-no-acpi -boot c -usb -net none -serial none -parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-rhel650.xml b/tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-rhel650.xml new file mode 100644 index 000..a659216 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-rhel650.xml @@ -0,0 +1,31 @@ +domain type='qemu' + nameQEMUGuest/name + uuid9f4b6512-e73a-4a25-93e8-5307802821ce/uuid + memory unit='KiB'24682468/memory + currentMemory unit='KiB'24682468/currentMemory + vcpu placement='static'32/vcpu + numatune +memory mode='strict' nodeset='0-7'/ + /numatune + os +type arch='x86_64' machine='rhel6.5.0'hvm/type +boot dev='hd'/ + /os + cpu +numa + cell id='0' cpus='0' memory='20002' unit='KiB'/ + cell id='1' cpus='1-27,29' memory='660066' unit='KiB'/ + cell id='2' cpus='28-31,^29' memory='24002400' unit='KiB'/ +/numa + /cpu + clock offset='utc'/ + on_poweroffdestroy/on_poweroff + on_rebootrestart/on_reboot + on_crashdestroy/on_crash + devices +emulator/usr/bin/kvm/emulator +controller type='usb' index='0'/ +controller type='pci' index='0' model='pci-root'/ +memballoon model='virtio'/ + /devices +/domain diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index f2120dd..a7e14f0 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1263,6 +1263,10 @@ mymain(void) DO_TEST_LINUX(numatune-memnode, QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_RAM); DO_TEST_FAILURE(numatune-memnode, NONE); +DO_TEST_LINUX(numatune-memnode-rhel650, + QEMU_CAPS_NUMA, + QEMU_CAPS_OBJECT_MEMORY_RAM, + QEMU_CAPS_OBJECT_MEMORY_FILE); DO_TEST_LINUX(numatune-memnode-no-memory, QEMU_CAPS_NUMA, QEMU_CAPS_OBJECT_MEMORY_RAM); -- 2.0.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/3] Introduce machine type based capabilities filtering
Well, here's an alternative approach to my question here [1]. 1: https://www.redhat.com/archives/libvir-list/2015-February/msg00369.html Michal Privoznik (3): virQEMUCapsCacheLookupCopy: Pass machine type virQEMUCapsCacheLookupCopy: Filter qemuCaps based on machineType qemuCaps: Disable memdev for rhel6.5.0 machine type src/qemu/qemu_capabilities.c | 45 +- src/qemu/qemu_capabilities.h | 5 ++- src/qemu/qemu_migration.c | 3 +- src/qemu/qemu_process.c| 9 +++-- .../qemuxml2argv-numatune-memnode-rhel650.args | 7 .../qemuxml2argv-numatune-memnode-rhel650.xml | 31 +++ tests/qemuxml2argvtest.c | 6 +++ 7 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-rhel650.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-memnode-rhel650.xml -- 2.0.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/3] numatune_conf: Expose virDomainNumatuneNodeSpecified
This function is going to be needed in the near future. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- src/conf/numatune_conf.c | 2 +- src/conf/numatune_conf.h | 3 +++ src/libvirt_private.syms | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/conf/numatune_conf.c b/src/conf/numatune_conf.c index 7f322ea..d6cedaa 100644 --- a/src/conf/numatune_conf.c +++ b/src/conf/numatune_conf.c @@ -64,7 +64,7 @@ struct _virDomainNumatune { }; -static inline bool +inline bool virDomainNumatuneNodeSpecified(virDomainNumatunePtr numatune, int cellid) { diff --git a/src/conf/numatune_conf.h b/src/conf/numatune_conf.h index 28c4ce2..c4b3f6e 100644 --- a/src/conf/numatune_conf.h +++ b/src/conf/numatune_conf.h @@ -111,4 +111,7 @@ int virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune); bool virDomainNumatuneNodesetIsAvailable(virDomainNumatunePtr numatune, virBitmapPtr auto_nodeset); + +bool virDomainNumatuneNodeSpecified(virDomainNumatunePtr numatune, +int cellid); #endif /* __NUMATUNE_CONF_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 645aef1..5bdd075 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -638,6 +638,7 @@ virDomainNumatuneMaybeGetNodeset; virDomainNumatuneMemModeTypeFromString; virDomainNumatuneMemModeTypeToString; virDomainNumatuneNodesetIsAvailable; +virDomainNumatuneNodeSpecified; virDomainNumatuneParseXML; virDomainNumatunePlacementTypeFromString; virDomainNumatunePlacementTypeToString; -- 2.0.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/3] qemuBuildMemoryBackendStr: Report backend requirement more appropriately
So, when building the '-numa' command line, the qemuBuildMemoryBackendStr() function does quite a lot of checks to chose the best backend, or to check if one is in fact needed. However, it returned that backend is needed even for this little fella: numatune memory mode=strict nodeset=0,2 / /numatune This can be guaranteed via CGroups entirely, there's no need to use memory-backend-ram to let qemu know where to get memory from. Well, as long as there's no memnode/ element, which explicitly requires the backend. Long story short, we wouldn't have to care, as qemu works either way. However, the problem is migration (as always). Previously, libvirt would have started qemu with: -numa node,memory=X in this case and restricted memory placement in CGroups. Today, libvirt creates more complicated command line: -object memory-backend-ram,id=ram-node0,size=X -numa node,memdev=ram-node0 Again, one wouldn't find anything wrong with these two approaches. Both work just fine. Unless you try to migrated from the older libvirt into the newer one. These two approaches are, unfortunately, not compatible. My suggestion is, in order to allow users to migrate, lets use the older approach for as long as the newer one is not needed. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- src/qemu/qemu_command.c | 6 -- tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args | 5 + tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.xml | 2 +- tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.args | 5 + tests/qemuxml2argvtest.c | 5 + 5 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.args diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 9c25788..cbe105e 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4699,7 +4699,9 @@ qemuBuildMemoryBackendStr(unsigned long long size, props = NULL; if (!hugepage) { -if ((nodemask || force) +bool nodeSpecified = virDomainNumatuneNodeSpecified(def-numatune, guestNode); + +if ((userNodeset || nodeSpecified || force) !virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_MEMORY_RAM)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, _(this qemu doesn't support the @@ -4709,7 +4711,7 @@ qemuBuildMemoryBackendStr(unsigned long long size, /* report back that using the new backend is not necessary to achieve * the desired configuration */ -if (!nodemask) { +if (!userNodeset !nodeSpecified) { ret = 1; goto cleanup; } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args b/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args new file mode 100644 index 000..481f72f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args @@ -0,0 +1,5 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-x86_64 -S -M pc-q35-2.3 -m 128 \ +-smp 2,maxcpus=6,sockets=6,cores=1,threads=1 \ +-nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi \ +-boot c -net none -serial none -parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.xml b/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.xml index 01bbb3d..fe7c465 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.xml @@ -1,4 +1,4 @@ -domain type='kvm' +domain type='qemu' namedummy2/name uuid4d92ec27-9ebf-400b-ae91-20c71c647c19/uuid memory unit='KiB'131072/memory diff --git a/tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.args b/tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.args new file mode 100644 index 000..0b1b0f5 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.args @@ -0,0 +1,5 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/kvm -S -M pc -m 64 -smp 1 \ +-numa node,nodeid=0,cpus=0,mem=64 \ +-nographic -monitor unix:/tmp/test-monitor,server,nowait \ +-no-acpi -boot c -usb -net none -serial none -parallel none diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 2de92eb..07a581f 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1260,6 +1260,9 @@ mymain(void) DO_TEST(cputune-zero-shares, QEMU_CAPS_NAME); DO_TEST_PARSE_ERROR(cputune-iothreadsched-toomuch, QEMU_CAPS_NAME); DO_TEST_PARSE_ERROR(cputune-vcpusched-overlap, QEMU_CAPS_NAME); +DO_TEST(cputune-numatune, QEMU_CAPS_SMP_TOPOLOGY, +QEMU_CAPS_OBJECT_MEMORY_RAM, +QEMU_CAPS_OBJECT_MEMORY_FILE); DO_TEST(numatune-memory, NONE);
[libvirt] [PATCH 2/3] qemuxml2argvtest: Fake response from numad
Well, we can pretend that we've asked numad for its suggestion and let qemu command line be built with that respect. Again, this alone has no big value, but see later commits which build on the top of this. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- tests/qemuxml2argvtest.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 316f479..2de92eb 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -265,12 +265,16 @@ static int testCompareXMLToArgvFiles(const char *xml, size_t i; size_t nnicindexes = 0; int *nicindexes = NULL; +virBitmapPtr nodeset = NULL; if (!(conn = virGetConnect())) goto out; conn-secretDriver = fakeSecretDriver; conn-storageDriver = fakeStorageDriver; +if (virBitmapParse(0-3, '\0', nodeset, 4) 0) +goto out; + if (!(vmdef = virDomainDefParseFile(xml, driver.caps, driver.xmlopt, QEMU_EXPECTED_VIRT_TYPES, VIR_DOMAIN_DEF_PARSE_INACTIVE))) { @@ -349,7 +353,7 @@ static int testCompareXMLToArgvFiles(const char *xml, VIR_NETDEV_VPORT_PROFILE_OP_NO_OP, testCallbacks, false, (flags FLAG_FIPS), - NULL, nnicindexes, nicindexes))) { + nodeset, nnicindexes, nicindexes))) { if (!virtTestOOMActive() (flags FLAG_EXPECT_FAILURE)) { ret = 0; @@ -403,6 +407,7 @@ static int testCompareXMLToArgvFiles(const char *xml, virCommandFree(cmd); virDomainDefFree(vmdef); virObjectUnref(conn); +virBitmapFree(nodeset); return ret; } -- 2.0.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/3] numatune: Prefer old approach
Consider the following part of domain XML: numatune memory mode='static' nodeset=0,2/ /numatune cpu numa cell id='0' cpus='0' memory='65536' unit='KiB'/ /numa /cpu Yes, this have a great potential of breaking things. Especially, this will break migration between previous two or three upstream releases and current release we are working on, because libvirt started domains in more complicated way (even if not needed). After these patches, domains will be started in simpler way which is incompatible. On the other hand, we get backward compatibility with much more releases than we are about to break. Michal Privoznik (3): numatune_conf: Expose virDomainNumatuneNodeSpecified qemuxml2argvtest: Fake response from numad qemuBuildMemoryBackendStr: Report backend requirement more appropriately src/conf/numatune_conf.c | 2 +- src/conf/numatune_conf.h | 3 +++ src/libvirt_private.syms | 1 + src/qemu/qemu_command.c | 6 -- tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args| 5 + tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.xml | 2 +- .../qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.args | 5 + tests/qemuxml2argvtest.c | 12 +++- 8 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cputune-numatune.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-numatune-auto-prefer.args -- 2.0.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] virprocess: fix MinGW build and RHEL-5 build
On 02/12/2015 10:01 AM, Pavel Hrdina wrote: Commit b6a2828e introduced new functions to set process scheduler. There is a small typo in ELSE path for systems where scheduler is not available. Also some of the definitions were introduced later in kernel. For example RHEL-5 is running on kernel 2.6.18, but SCHED_IDLE was introduces in 2.6.23 [1] and SCHED_BATCH in 2.6.16 [1]. We should not count only on existence of function sched_setscheduler(), we must also check for existence of used macros as they might not be defined. [1] see 'man 7 sched' Signed-off-by: Pavel Hrdina phrd...@redhat.com --- src/util/virprocess.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) ACK -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCHv2] libxl: set IP address when creating NIC
Jim Fehlig wrote: Jihoon Kim wrote: From: Ji-hoon Kim re...@me.com Currently libxlMakeNic() does not set ip address when creating NIC, this patch makes it to set ip address. FYI, Marek recently sent a patch to do the same https://www.redhat.com/archives/libvir-list/2015-February/msg00139.html I like Marek's error checking for multiple IPs in libxlDomainDeviceDefPostParse(), but do think that ip address='' should also be supported for interface type=network. Marek provided a follow-up patch, which I've pushed http://libvirt.org/git/?p=libvirt.git;a=commit;h=8703ee58bd9d9d02b5d64fae48c96f8940b9d0ff Thanks again for helping with the libxl driver! Any improvements or fixes you have are welcomed. Regards, Jim -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [RFC PATCH v2 00/12] qemu: add support to hot-plug/unplug cpu device
On Thu, Feb 12, 2015 at 19:53:13 +0800, Zhu Guihua wrote: Hi all, Any comments about this series? I'm not sure whether this series' method to support cpu hotplug in libvirt is reasonable, so could anyone give more suggestions about this function? Thanks. Well, as Dan pointed out in his review for this series and previous version, we are not convinced that we need a way to specify the CPU model and other parameters as having dissimilar CPUs doesn't make sense. A solution is either to build the cpu plug on top of the existing API or provide enough information to convince us that having the cpu model in the XML actually makes sense. Regards, Zhu Peter signature.asc Description: Digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] virprocess: fix MinGW build and RHEL-5 build
Commit b6a2828e introduced new functions to set process scheduler. There is a small typo in ELSE path for systems where scheduler is not available. Also some of the definitions were introduced later in kernel. For example RHEL-5 is running on kernel 2.6.18, but SCHED_IDLE was introduces in 2.6.23 [1] and SCHED_BATCH in 2.6.16 [1]. We should not count only on existence of function sched_setscheduler(), we must also check for existence of used macros as they might not be defined. [1] see 'man 7 sched' Signed-off-by: Pavel Hrdina phrd...@redhat.com --- src/util/virprocess.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/util/virprocess.c b/src/util/virprocess.c index b3e5435..342bf40 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -1062,7 +1062,7 @@ virProcessExitWithStatus(int status) exit(value); } -#if HAVE_SCHED_SETSCHEDULER +#if HAVE_SCHED_SETSCHEDULER defined(SCHED_BATCH) defined(SCHED_IDLE) static int virProcessSchedTranslatePolicy(virProcessSchedPolicy policy) @@ -1092,7 +1092,9 @@ virProcessSchedTranslatePolicy(virProcessSchedPolicy policy) } int -virProcessSetScheduler(pid_t pid, virProcessSchedPolicy policy, int priority) +virProcessSetScheduler(pid_t pid, + virProcessSchedPolicy policy, + int priority) { struct sched_param param = {0}; int pol = virProcessSchedTranslatePolicy(policy); @@ -1144,7 +1146,7 @@ virProcessSetScheduler(pid_t pid, virProcessSchedPolicy policy, int priority) int virProcessSetScheduler(pid_t pid ATTRIBUTE_UNUSED, - int policy, + virProcessSchedPolicy policy, int priority ATTRIBUTE_UNUSED) { if (!policy) -- 2.0.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2 1/3] util: Add virProcessSetScheduler() function for scheduler settings
On Thu, Feb 12, 2015 at 09:14:29 +0100, Michal Privoznik wrote: On 11.02.2015 18:34, Eric Blake wrote: On 02/11/2015 07:04 AM, Michal Privoznik wrote: On 10.02.2015 16:35, Martin Kletzander wrote: ... If it is so, is it worth bothering with cleanup patch(es)? There's Worth? I don't think so ... roughly 250 occurrences in the code: $ git grep [A-Z]\+ = 0 | wc -l 4 bytes ( = 0) removed in 250 instances would save you 1 KiB of space. That's probably less than what I wasted writing this mail. 268 Michal Peter signature.asc Description: Digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] virprocess: fix MinGW build and RHEL-5 build
On Thu, Feb 12, 2015 at 10:16:04AM -0700, Eric Blake wrote: On 02/12/2015 10:01 AM, Pavel Hrdina wrote: Commit b6a2828e introduced new functions to set process scheduler. There is a small typo in ELSE path for systems where scheduler is not available. Also some of the definitions were introduced later in kernel. For example RHEL-5 is running on kernel 2.6.18, but SCHED_IDLE was introduces in 2.6.23 [1] and SCHED_BATCH in 2.6.16 [1]. We should not count only on existence of function sched_setscheduler(), we must also check for existence of used macros as they might not be defined. [1] see 'man 7 sched' Signed-off-by: Pavel Hrdina phrd...@redhat.com --- src/util/virprocess.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) ACK -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org Thanks, pushed. Pavel -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 2/2] security: Refactor virSecurityManagerGenLabel
if (mgr == NULL || mgr-drv == NULL) return ret; This check isn't really necessary, security manager cannot be a NULL pointer as it is either selinux (by default) or 'none', if no other driver is set in the config. Even with no config file driver name yields 'none'. The other hunk checks for domain's security model validity, but we should also check devices' security model as well, therefore this hunk is moved into a separate function which is called by virSecurityManagerCheckAllLabel that checks both the domain's security model and devices' security model. https://bugzilla.redhat.com/show_bug.cgi?id=1165485 --- src/security/security_manager.c | 41 ++--- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/security/security_manager.c b/src/security/security_manager.c index 68ed85b..68d2279 100644 --- a/src/security/security_manager.c +++ b/src/security/security_manager.c @@ -576,33 +576,15 @@ virSecurityManagerGenLabel(virSecurityManagerPtr mgr, virDomainDefPtr vm) { int ret = -1; -size_t i, j; +size_t i; virSecurityManagerPtr* sec_managers = NULL; virSecurityLabelDefPtr seclabel; bool generated = false; -if (mgr == NULL || mgr-drv == NULL) -return ret; - if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL) return ret; virObjectLock(mgr); -for (i = 0; i vm-nseclabels; i++) { -if (!vm-seclabels[i]-model) -continue; - -for (j = 0; sec_managers[j]; j++) -if (STREQ(vm-seclabels[i]-model, sec_managers[j]-drv-name)) -break; - -if (!sec_managers[j]) { -virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _(Unable to find security driver for label %s), - vm-seclabels[i]-model); -goto cleanup; -} -} for (i = 0; sec_managers[i]; i++) { generated = false; @@ -731,6 +713,22 @@ static int virSecurityManagerCheckSecurityModel(char *secmodel, static int +virSecurityManagerCheckSecurityDomainLabel(virDomainDefPtr def, + void *opaque) +{ +size_t i; + +for (i = 0; i def-nseclabels; i++) { +if (virSecurityManagerCheckSecurityModel(def-seclabels[i]-model, + opaque) 0) +return -1; +} + +return 0; +} + + +static int virSecurityManagerCheckSecurityDiskLabel(virDomainDiskDefPtr disk, void *opaque) { @@ -776,6 +774,11 @@ int virSecurityManagerCheckAllLabel(virSecurityManagerPtr mgr, { size_t i; +/* first check per-domain seclabels */ +if (virSecurityManagerCheckSecurityDomainLabel(vm, mgr) 0) +return -1; + +/* second check per-device seclabels */ for (i = 0; i vm-ndisks; i++) { if (virSecurityManagerCheckSecurityDiskLabel(vm-disks[i], mgr) 0) -- 1.9.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 1/2] security: introduce virSecurityManagerCheckAllLabel function
We do have a check for valid per-domain security model, however we still do permit an invalid security model for a domain's device (those which are specified with source element). This patch introduces a new function virSecurityManagerCheckAllLabel which compares user specified security model against currently registered security drivers. That being said, it also permits 'none' being specified as a device security model. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1165485 --- src/libvirt_private.syms| 1 + src/lxc/lxc_process.c | 3 ++ src/qemu/qemu_process.c | 6 +++ src/security/security_manager.c | 89 + src/security/security_manager.h | 2 + 5 files changed, 101 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 645aef1..e98e813 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -955,6 +955,7 @@ virSecurityDriverLookup; # security/security_manager.h +virSecurityManagerCheckAllLabel; virSecurityManagerClearSocketLabel; virSecurityManagerGenLabel; virSecurityManagerGetBaseLabel; diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 19ea7f3..52b7f41 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -1135,6 +1135,9 @@ int virLXCProcessStart(virConnectPtr conn, vm-def-seclabels[0]-type == VIR_DOMAIN_SECLABEL_DEFAULT) vm-def-seclabels[0]-type = VIR_DOMAIN_SECLABEL_NONE; +if (virSecurityManagerCheckAllLabel(driver-securityManager, vm-def) 0) +goto cleanup; + if (virSecurityManagerGenLabel(driver-securityManager, vm-def) 0) { virDomainAuditSecurityLabel(vm, false); goto cleanup; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 43a64a1..1d4e957 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4488,6 +4488,10 @@ int qemuProcessStart(virConnectPtr conn, NULL) 0) goto cleanup; +VIR_DEBUG(Checking domain and device security labels); +if (virSecurityManagerCheckAllLabel(driver-securityManager, vm-def) 0) +goto cleanup; + /* If you are using a SecurityDriver with dynamic labelling, then generate a security label for isolation */ VIR_DEBUG(Generating domain security label (if required)); @@ -5488,6 +5492,8 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, } } +if (virSecurityManagerCheckAllLabel(driver-securityManager, vm-def) 0) +goto error; if (virSecurityManagerGenLabel(driver-securityManager, vm-def) 0) goto error; diff --git a/src/security/security_manager.c b/src/security/security_manager.c index 302f54d..68ed85b 100644 --- a/src/security/security_manager.c +++ b/src/security/security_manager.c @@ -703,6 +703,95 @@ virSecurityManagerReleaseLabel(virSecurityManagerPtr mgr, } +static int virSecurityManagerCheckSecurityModel(char *secmodel, +void *opaque) +{ +size_t i; +virSecurityManagerPtr mgr = opaque; +virSecurityManagerPtr *sec_managers = NULL; + +if ((sec_managers = virSecurityManagerGetNested(mgr)) == NULL) +return -1; + +if (STREQ_NULLABLE(secmodel, none)) +return 0; + +for (i = 0; sec_managers[i]; i++) { +if (STREQ_NULLABLE(secmodel, + sec_managers[i]-drv-name)) { +return 0; +} +} + +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(Unable to find security driver for model %s), + secmodel); +return -1; +} + + +static int +virSecurityManagerCheckSecurityDiskLabel(virDomainDiskDefPtr disk, + void *opaque) +{ +size_t i; + +for (i = 0; i disk-src-nseclabels; i++) { +if (virSecurityManagerCheckSecurityModel(disk-src-seclabels[i]-model, +opaque) 0) +return -1; +} + +return 0; +} + + +static int +virSecurityManagerCheckSecurityChardevLabel(virDomainChrDefPtr dev, +void *opaque) +{ +size_t i; + +for (i = 0; i dev-nseclabels; i++) { +if (virSecurityManagerCheckSecurityModel(dev-seclabels[i]-model, +opaque) 0) +return -1; +} + +return 0; +} + + +static int +virSecurityManagerCheckSecurityChardevCallback(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainChrDefPtr dev, + void *opaque) +{ +return virSecurityManagerCheckSecurityChardevLabel(dev, opaque); +} + + +int virSecurityManagerCheckAllLabel(virSecurityManagerPtr mgr, +virDomainDefPtr vm) +{ +size_t i; + +for (i = 0; i vm-ndisks; i++) { +if