Re: [libvirt] 1.2.0 segfault on Centos 6
On 02/04/2014 11:23 PM, Jiri Denemark wrote: On Tue, Feb 04, 2014 at 17:02:41 +0100, Franky Van Liedekerke wrote: Hi, using libvirt 1.2.0 on a up-to-date Centos6.5 machine leads to occasional segmentation faults (see below). Sometimes it runs for 5 minutes, sometimes for an hour, but after that the result is always the same: segfault after some weird qom-list, that apparently the qemu version on centos doesn't know. Has 1.2.1 a known fix for this? I believe the following patch should fix the crash. I'll do some testing tomorrow and send it as a proper patch afterwards: diff --git i/src/qemu/qemu_monitor.c w/src/qemu/qemu_monitor.c index a968901..cdd817f 100644 --- i/src/qemu/qemu_monitor.c +++ w/src/qemu/qemu_monitor.c @@ -1019,7 +1019,9 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, virDomainObjPtr vm, const char *curpath) { -size_t i, j, npaths = 0, nprops = 0; +size_t i, j; +int npaths = 0; +int nprops = 0; int ret = 0; char *nextpath = NULL; qemuMonitorJSONListPathPtr *paths = NULL; @@ -1045,6 +1047,8 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, VIR_DEBUG(Searching for Balloon Object Path starting at %s, curpath); npaths = qemuMonitorJSONGetObjectListPaths(mon, curpath, paths); +if (npaths 0) +return -1; for (i = 0; i npaths ret == 0; i++) { @@ -1061,6 +1065,11 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, * then this version of qemu/kvm does not support the feature. */ nprops = qemuMonitorJSONGetObjectListPaths(mon, nextpath, bprops); +if (nprops 0) { +ret = -1; +goto cleanup; +} + for (j = 0; j nprops; j++) { if (STREQ(bprops[j]-name, guest-stats-polling-interval)) { VIR_DEBUG(Found Balloon Object Path %s, nextpath); npaths and nprops are also compared against size_t in the cleanup section. Jan signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v4] : Sheepdog .... No news
No news about my patch? -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] 1.2.0 segfault on Centos 6
On Tue, Feb 04, 2014 at 11:34:39AM -0700, Eric Blake wrote: On 02/04/2014 11:28 AM, Franky Van Liedekerke wrote: Are you in a position to bisect which libvirt patch introduced the problem? It looks like our first use of qom-list was in 1.1.1, with commit d76a897. Errr ... I don't really know what you mean with bisect ... but tell me what to do, and I'll try my best tomorrow. 'git bisect' is a powerful driver that lets you do a binary search through git history to find which patch changed a particular behavior. If you are comfortable using git and building your own libvirt, I can help you come up with a command line to drive the test for looking for where this behavior started. I wonder if we should not add a small section on bugs.html.in about how git bissect can help locating the bug and the simpler alternatives like below: But even if you are not, it would be nice if you could test a build of libvirt 1.1.0 vs. libvirt 1.1.1; if my guess above was correct, 1.1.0 will not have the problem. Or, if you are comfortable using gdb, it might be nice to step through program execution at the point where qemuMonitorJSONGetObjectListPaths returns failure because qemu didn't support the qom-list command. And if not, the fact that you reported it means that one of the regular developers will hopefully have some time in the near future to further investigate, based on what we've learned so far. At any rate, we should have a fix before releasing libvirt 1.2.2. 3 weeks to find the problem and get a fix :-) Daniel -- Daniel Veillard | Open Source and Standards, Red Hat veill...@redhat.com | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] add flag to enforce hugepage backing of guest RAM
On Tue, Feb 04, 2014 at 03:04:11PM -0700, Eric Blake wrote: On 02/04/2014 02:57 PM, Marcelo Tosatti wrote: So perhaps we do need some policy attribute on the hugepages/ element to indicate desired behaviour here. What about the following new element under hugepages/ ? enforce_hugepage_size=integer Which feels a bit redundant (we're already under the hugepages element, after all). Maybe: hugepages size strict='yes' unit='G'1/size /hugepages where strict could be no if we are giving a hint but don't care if the hint cannot be honored (default yes if omitted), and where unit + value allows the user to input the size in a sensible unit (on output, we'd probably want to use unit='k' and spell out 1048576, for similarity with all our other memory interfaces that output in k for back-compat reasons). I don't think strict=yes|no is neccessarily the best. Per my previous mail in this thread there are at least 3 possible policies that could be implemented. - Require memory size multiple of hugepage size - Round memory size upto multiple of huge page size - Fill in with smaller huge pages So I'd say policy=round|exact|bestfit even if QEMU doesn't decide to actually implement all 3 possible policies, we at least futureproof ourselves by not using a boolean. 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] rpm: create libvirt-wireshark sub-package
On Tue, Feb 04, 2014 at 03:15:56PM -0700, Eric Blake wrote: On Fedora 20, with wireshark-devel installed, 'make rpm' failed due to installed but unpackaged files related to wireshark. As F20 is already released without wireshark, I chose to add a new sub-package that is enabled only for F21 and later. Furthermore, all existing wireshark plugins belong to the wireshark package, so I got to invent behavior of how the first third-part wireshark module will behave. * libvirt.spec.in (with_wireshark): Add new conditional. * configure.ac (ws-plugindir): Improve wording. Signed-off-by: Eric Blake ebl...@redhat.com --- I was tempted to push this as a build-breaker fix for 'make rpm', but rpms are close enough to black magic that I decided a review is safer, after all. Tested with both F20 (not built) and F21 (new subpackage built just fine), using normal build of all subpackages and also a build with '%client_only 1' in ~/.rpmmacros to ensure that it indeed works in a client-only setup. configure.ac| 4 ++-- libvirt.spec.in | 34 ++ 2 files changed, 36 insertions(+), 2 deletions(-) ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 1/3] networkStartNetwork: Be more verbose
The lack of debug printings might be frustrating in the future. Moreover, this function doesn't follow the usual pattern we have in the rest of the code: int ret = -1; /* do some work */ ret = 0; cleanup: /* some cleanup work */ return ret; Signed-off-by: Michal Privoznik mpriv...@redhat.com --- src/network/bridge_driver.c | 35 +++ 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index c8b167b..2bd015b 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -1992,23 +1992,29 @@ static int networkStartNetwork(virNetworkDriverStatePtr driver, virNetworkObjPtr network) { -int ret = 0; +int ret = -1; + +VIR_DEBUG(driver=%p, network=%p, driver, network); if (virNetworkObjIsActive(network)) { virReportError(VIR_ERR_OPERATION_INVALID, %s, _(network is already active)); -return -1; +return ret; } +VIR_DEBUG(Beginning network startup process); + +VIR_DEBUG(Setting current network def as transient); if (virNetworkObjSetDefTransient(network, true) 0) -return -1; +goto cleanup; switch (network-def-forward.type) { case VIR_NETWORK_FORWARD_NONE: case VIR_NETWORK_FORWARD_NAT: case VIR_NETWORK_FORWARD_ROUTE: -ret = networkStartNetworkVirtual(driver, network); +if (networkStartNetworkVirtual(driver, network) 0) +goto cleanup; break; case VIR_NETWORK_FORWARD_BRIDGE: @@ -2016,28 +2022,25 @@ networkStartNetwork(virNetworkDriverStatePtr driver, case VIR_NETWORK_FORWARD_VEPA: case VIR_NETWORK_FORWARD_PASSTHROUGH: case VIR_NETWORK_FORWARD_HOSTDEV: -ret = networkStartNetworkExternal(driver, network); +if (networkStartNetworkExternal(driver, network) 0) +goto cleanup; break; } -if (ret 0) { -virNetworkObjUnsetDefTransient(network); -return ret; -} - /* Persist the live configuration now that anything autogenerated * is setup. */ -if ((ret = virNetworkSaveStatus(driverState-stateDir, -network)) 0) { -goto error; -} +VIR_DEBUG(Writing network status to disk); +if (virNetworkSaveStatus(driverState-stateDir, network) 0) +goto cleanup; -VIR_INFO(Starting up network '%s', network-def-name); network-active = 1; +VIR_INFO(Network '%s' started up, network-def-name); +ret = 0; -error: +cleanup: if (ret 0) { +virNetworkObjUnsetDefTransient(network); virErrorPtr save_err = virSaveLastError(); int save_errno = errno; networkShutdownNetwork(driver, network); -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 0/3] Network hooks
Yet another version, this time with more hooks (after the network is started, on interface plug and unplug) and tainting. Michal Privoznik (3): networkStartNetwork: Be more verbose network: Introduce start and shutdown hooks network: Taint networks that are using hook script docs/hooks.html.in | 60 --- src/conf/network_conf.c | 16 src/conf/network_conf.h | 17 + src/libvirt_private.syms| 3 + src/lxc/lxc_driver.c| 4 +- src/lxc/lxc_process.c | 6 +- src/network/bridge_driver.c | 179 +++- src/network/bridge_driver.h | 14 ++-- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_hotplug.c | 14 ++-- src/qemu/qemu_process.c | 2 +- src/util/virhook.c | 13 +++- src/util/virhook.h | 11 +++ 13 files changed, 292 insertions(+), 49 deletions(-) -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v2 2/3] network: Introduce start and shutdown hooks
There might be some use cases, where user wants to prepare the host or its environment prior to starting a network and do some cleanup after the network has been shut down. Consider all the functionality that libvirt doesn't currently have as an example what a hook script can possibly do. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- docs/hooks.html.in | 60 ++ src/lxc/lxc_driver.c| 4 +- src/lxc/lxc_process.c | 6 +-- src/network/bridge_driver.c | 120 +++- src/network/bridge_driver.h | 14 +++--- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_hotplug.c | 14 +++--- src/qemu/qemu_process.c | 2 +- src/util/virhook.c | 13 - src/util/virhook.h | 11 10 files changed, 212 insertions(+), 34 deletions(-) diff --git a/docs/hooks.html.in b/docs/hooks.html.in index f0f692b..9deb215 100644 --- a/docs/hooks.html.in +++ b/docs/hooks.html.in @@ -16,6 +16,9 @@ configurationbr/br//li liA QEMU guest is started or stoppedbr/br//li liAn LXC guest is started or stoppedbr/br//li + liA network is started or stopped or an interface is + un-/plugged from/to the network + (span class=sincesince 1.2.2/span)br/br//li /ul h2a name=locationScript location/a/h2 @@ -44,6 +47,9 @@ Executed when a QEMU guest is started, stopped, or migratedbr/br//li licode/etc/libvirt/hooks/lxc/codebr /br/ Executed when an LXC guest is started or stopped/li + licode/etc/libvirt/hooks/network/codebr/br/ + Executed when a network is started or stopped or an + interface is un-/plugged from/to the network/li /ul br/ @@ -66,6 +72,12 @@ XML description for the domain on their stdin. This includes items such the UUID of the domain and its storage information, and is intended to provide all the libvirt information the script needs./p +pThe network hook script is fed on its stdin with bfull/b XML + description of network in which an action occurs. However, in cases of + interface being plugged or unplugged to the network, script can expect + full XML description of corresponding domain appended after the network + XML (this happens when a domain with an lt;interface/gt; belonging to + the network is started or destroyed)./p pThe command line arguments take this approach:/p ol @@ -181,23 +193,49 @@ pre/etc/libvirt/hooks/lxc guest_name reconnect begin -/pre /li /ul + +h5a name=network/etc/libvirt/hooks/network/a/h5 +ul + lispan class=sinceSince 1.2.2/span, before a network is started, +this script is called as:br/ + pre/etc/libvirt/hooks/network network_name start begin -/pre/li + liAfter the network is started, up and; running, the script is +called as:br/ + pre/etc/libvirt/hooks/network network_name started begin -/pre/li + liWhen a network is shut down, this script is called as:br/ + pre/etc/libvirt/hooks/network network_name stopped end -/pre/li + liLater, when network is started and there's an interface from a +domain to be plugged into the network (plugged may not be the correct +expression when it comes to bridgeless netowrks, perhaps allocated is +better one then), the hook script is called as:br/ + pre/etc/libvirt/hooks/network network_name plugged begin -/pre +Please note, that in this case, the script is passed both network and +domain XMLs on its stdin./li + liWhen the domain from previous case is shutting down, the interface +is unplugged. This leads to another script invocation:br/ + pre/etc/libvirt/hooks/network network_name unplugged begin -/pre +And again, as in previous case, both network and domain XMLs are passed +onto script's stdin./li +/ul + br/ h2a name=executionScript execution/a/h2 ul - liThe start operation for the guest hook scripts, qemu and lxc, - executes bprior/b to the guest being created. This allows the - guest start operation to be aborted if the script returns indicating - failure.br/br//li - liThe shutdown operation for the guest hook scripts, qemu and lxc, - executes bafter/b the guest has stopped. If the hook script - indicates failure in its return, the shut down of the guest cannot - be aborted because it has already been performed.br/br//li + liThe start operation for the guest and network hook scripts, + executes bprior/b to the object (guest or network) being created. + This allows the object start operation to be aborted if the script + returns indicating failure.br/br//li + liThe shutdown operation for the guest and network hook scripts, + executes bafter/b the object
[libvirt] [PATCH v2 3/3] network: Taint networks that are using hook script
Basically, the idea is copied from domain code, where tainting exists for a while. Currently, only one taint reason exists - VIR_NETWORK_TAINT_HOOK to mark those networks which caused invoking of hook script. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- src/conf/network_conf.c | 16 src/conf/network_conf.h | 17 + src/libvirt_private.syms| 3 +++ src/network/bridge_driver.c | 26 ++ 4 files changed, 62 insertions(+) diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index e59938c..aa881d8 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -72,6 +72,22 @@ VIR_ENUM_IMPL(virNetworkDNSForwardPlainNames, yes, no) +VIR_ENUM_IMPL(virNetworkTaint, VIR_NETWORK_TAINT_LAST, + hook-script); + +bool +virNetworkObjTaint(virNetworkObjPtr obj, + enum virNetworkTaintFlags taint) +{ +unsigned int flag = (1 taint); + +if (obj-taint flag) +return false; + +obj-taint |= flag; +return true; +} + virNetworkObjPtr virNetworkFindByUUID(virNetworkObjListPtr nets, const unsigned char *uuid) { diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index b84762a..edcc49f 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -287,6 +287,8 @@ struct _virNetworkObj { virBitmapPtr class_id; /* bitmap of class IDs for QoS */ unsigned long long floor_sum; /* sum of all 'floor'-s of attached NICs */ + +unsigned int taint; }; typedef struct _virNetworkObjList virNetworkObjList; @@ -296,12 +298,26 @@ struct _virNetworkObjList { virNetworkObjPtr *objs; }; +enum virNetworkTaintFlags { +VIR_NETWORK_TAINT_HOOK, /* Hook script was executed over + network. We can't guarantee + connectivity or other settings + as the script may have played + with iptables, tc, you name it. + */ + +VIR_NETWORK_TAINT_LAST +}; + static inline int virNetworkObjIsActive(const virNetworkObj *net) { return net-active; } +bool virNetworkObjTaint(virNetworkObjPtr obj, +enum virNetworkTaintFlags taint); + virNetworkObjPtr virNetworkFindByUUID(virNetworkObjListPtr nets, const unsigned char *uuid); virNetworkObjPtr virNetworkFindByName(virNetworkObjListPtr nets, @@ -452,4 +468,5 @@ virNetworkDefUpdateSection(virNetworkDefPtr def, const char *xml, unsigned int flags); /* virNetworkUpdateFlags */ +VIR_ENUM_DECL(virNetworkTaint) #endif /* __NETWORK_CONF_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c5a7637..0759d73 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -525,6 +525,7 @@ virNetworkObjListFree; virNetworkObjLock; virNetworkObjReplacePersistentDef; virNetworkObjSetDefTransient; +virNetworkObjTaint; virNetworkObjUnlock; virNetworkObjUnsetDefTransient; virNetworkObjUpdate; @@ -533,6 +534,8 @@ virNetworkSaveConfig; virNetworkSaveStatus; virNetworkSetBridgeMacAddr; virNetworkSetBridgeName; +virNetworkTaintTypeFromString; +virNetworkTaintTypeToString; virPortGroupFindByName; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 1ba2b2d..f2aef48 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -112,6 +112,9 @@ static int networkPlugBandwidth(virNetworkObjPtr net, static int networkUnplugBandwidth(virNetworkObjPtr net, virDomainNetDefPtr iface); +static void networkNetworkObjTaint(virNetworkObjPtr net, + enum virNetworkTaintFlags taint); + static virNetworkDriverStatePtr driverState = NULL; static virNetworkObjPtr @@ -2024,6 +2027,8 @@ networkStartNetwork(virNetworkDriverStatePtr driver, */ if (hookret 0) goto cleanup; + +networkNetworkObjTaint(network, VIR_NETWORK_TAINT_HOOK); } switch (network-def-forward.type) { @@ -2067,6 +2072,8 @@ networkStartNetwork(virNetworkDriverStatePtr driver, */ if (hookret 0) goto cleanup; + +networkNetworkObjTaint(network, VIR_NETWORK_TAINT_HOOK); } network-active = 1; @@ -3649,6 +3656,8 @@ validate: */ if (hookret 0) goto error; + +networkNetworkObjTaint(network, VIR_NETWORK_TAINT_HOOK); } if (dev) { @@ -4023,6 +4032,8 @@ success: VIR_HOOK_NETWORK_OP_IFACE_UNPLUGGED, VIR_HOOK_SUBOP_BEGIN, NULL, xml, NULL); VIR_FREE(xml); + +networkNetworkObjTaint(network,
Re: [libvirt] [PATCH python] Fix calling of virStreamSend method
On Tue, Feb 04, 2014 at 06:31:26AM -0700, Eric Blake wrote: On 02/04/2014 03:21 AM, Daniel P. Berrange wrote: On Mon, Feb 03, 2014 at 02:32:27PM -0700, Eric Blake wrote: On 01/23/2014 07:25 AM, Daniel P. Berrange wrote: Change d40861 removed the 'len' argument from the virStreamSend C level wrapper, but forgot to remove it from the python level wrapper. Reported-by: Robie Basak robie.ba...@canonical.com Signed-off-by: Daniel P. Berrange berra...@redhat.com --- libvirt-override-virStream.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Hmm, you pushed this patch onto the release before 1.2.1; I had to push a merge commit to get the master branch to include both this and the release. I'm not sure why git let you push a non-fast-forward, unless DV forgot to push the 1.2.1 tag to the master branch until after you had already pushed this. That is very odd - the commit dates all show a normal sequence of committing. I can only imagine that perhaps we forgot to set the deny merge bit in the git repo config and I wasn't up2date when I pushed ? The git config looks OK right now, but I see you modified it last night, so did you fix something ? I had to temporarily disable the deny merge to push the merge that fixed things, but turned it back on after fixing things and verified that the hooks were indeed working as expected. So I don't know how we got in that state; oh well. By the way, what's the best way to test libvirt-python.git against uninstalled libvirt.git? I'm trying to add bindings for my virConnectDomainQemuMonitorEvent patches, but as my system installed libvirt is not yet at 1.2.2, I'm not sure the python bindings are building my new code. Could we expand HACKING to give better instructions on how to set up a build pointing to uninstalled libvirt? You can change the prefix of the upstream libvirt, install it and then run setup.py with PKG_CONFIG_PATH changed. Or you can apply my patch which was NACKed in this discussion: http://www.redhat.com/archives/libvir-list/2013-November/msg01127.html Martin signature.asc Description: Digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCHv2 0/3] add support for HyperV RTC enlightenment
Version 2 now adds the as a timer mode instead of the hyperv feature as this is a timer in fact. Peter Krempa (3): schema: Fix guest timer specification schema according to the docs conf: Enforce supported options for certain timers qemu: hyperv: Add support for reference time couter enlightenment docs/formatdomain.html.in | 7 +- docs/schemas/domaincommon.rng | 156 + src/conf/domain_conf.c | 59 +++- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c| 31 ++-- .../qemuxml2argv-clock-timer-hyperv-rtc.args | 5 + .../qemuxml2argv-clock-timer-hyperv-rtc.xml| 26 tests/qemuxml2argvtest.c | 1 + tests/qemuxml2xmltest.c| 1 + 9 files changed, 212 insertions(+), 75 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.xml -- 1.8.5.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/3] schema: Fix guest timer specification schema according to the docs
According to the documentation describing various tunables for domain timers not all the fields are supported by all the driver types. Express these in the RNG: - rtc, platform: Only these support the track attribute. - tsc: only one to support frequency and mode attributes - hpet, pit: tickpolicy/catchup attribute/element - kvmclock: no extra attributes are supported --- docs/schemas/domaincommon.rng | 153 +- 1 file changed, 93 insertions(+), 60 deletions(-) diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 7f55f24..12fc0db 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -857,54 +857,68 @@ /define define name=timer element name=timer - attribute name=name -choice - valueplatform/value - valuehpet/value - valuekvmclock/value - valuepit/value - valuertc/value - valuetsc/value -/choice - /attribute - optional -attribute name=track - choice -valueboot/value -valueguest/value -valuewall/value - /choice -/attribute - /optional - optional -attribute name=tickpolicy - choice -valuedelay/value -valuecatchup/value -valuemerge/value -valuediscard/value - /choice -/attribute - /optional - optional -ref name=catchup/ - /optional - optional -attribute name=frequency - ref name=unsignedInt/ -/attribute - /optional - optional -attribute name=mode - choice -valueauto/value -valuenative/value -valueemulate/value -valueparavirt/value -valuesmpsafe/value - /choice -/attribute - /optional + choice +group + attribute name=name +choice + valueplatform/value + valuertc/value +/choice + /attribute + optional +attribute name=track + choice +valueboot/value +valueguest/value +valuewall/value + /choice +/attribute + /optional + optional +ref name=tickpolicy/ + /optional +/group +group + attribute name=name +valuetsc/value + /attribute + optional +ref name=tickpolicy/ + /optional + optional +attribute name=frequency + ref name=unsignedInt/ +/attribute + /optional + optional +attribute name=mode + choice +valueauto/value +valuenative/value +valueemulate/value +valueparavirt/value +valuesmpsafe/value + /choice +/attribute + /optional +/group +group + attribute name=name +choice + valuehpet/value + valuepit/value +/choice + /attribute + optional +ref name=tickpolicy/ + /optional +/group +group + attribute name=name +valuekvmclock/value + /attribute +/group + /choice optional attribute name=present choice @@ -916,20 +930,39 @@ empty/ /element /define - define name=catchup -element name=catchup - optional -attribute name=threshold - ref name=unsignedInt/ -/attribute -attribute name=slew - ref name=unsignedInt/ + + define name=tickpolicy +choice + group +attribute name=tickpolicy + choice +valuedelay/value +valuemerge/value +valuediscard/value + /choice /attribute -attribute name=limit - ref name=unsignedInt/ + /group + group +attribute name=tickpolicy + valuecatchup/value /attribute - /optional -/element +optional + element name=catchup +optional + attribute name=threshold +ref name=unsignedInt/ + /attribute + attribute name=slew +ref name=unsignedInt/ + /attribute + attribute name=limit +ref name=unsignedInt/ + /attribute +/optional + /element +/optional + /group +/choice /define !-- A bootloader may be used to extract the OS information instead of -- 1.8.5.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/3] conf: Enforce supported options for certain timers
According to the documentation various timer options are only supported by certain timer types. Add a post parse check to verify that the user didn't specify invalid options. Also fix the qemu command line parsing function to set correct default values for the kvmclock timer so that it passes the new check. --- src/conf/domain_conf.c | 55 + src/qemu/qemu_command.c | 1 + 2 files changed, 56 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 28e24f9..b6c984b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2924,6 +2924,61 @@ virDomainDefPostParseInternal(virDomainDefPtr def, if (virDomainDefRejectDuplicateControllers(def) 0) return -1; + +/* verify settings of guest timers */ +for (i = 0; i def-clock.ntimers; i++) { +virDomainTimerDefPtr timer = def-clock.timers[i]; + +if (timer-name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK) { +if (timer-tickpolicy != -1) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(timer %s doesn't support setting of + timer tickpolicy), + virDomainTimerNameTypeToString(timer-name)); +return -1; +} +} + +if (timer-tickpolicy != VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP +(timer-catchup.threshold != 0 || + timer-catchup.limit != 0 || + timer-catchup.slew != 0)) { +virReportError(VIR_ERR_XML_ERROR, %s, + _(setting of timer catchup policies is only + supported with tickpolicy='catchup')); +return -1; +} + +if (timer-name != VIR_DOMAIN_TIMER_NAME_TSC) { +if (timer-frequency != 0) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(timer %s doesn't support setting of + timer frequency), + virDomainTimerNameTypeToString(timer-name)); +return -1; + } + +if (timer-mode != -1) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(timer %s doesn't support setting of + timer mode), + virDomainTimerNameTypeToString(timer-name)); +return -1; + } +} + +if (timer-name != VIR_DOMAIN_TIMER_NAME_PLATFORM +timer-name != VIR_DOMAIN_TIMER_NAME_RTC) { +if (timer-track != -1) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(timer %s doesn't support setting of + timer track), + virDomainTimerNameTypeToString(timer-name)); +return -1; +} +} +} + return 0; } diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 5b94de1..eef65ae 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -10920,6 +10920,7 @@ qemuParseCommandLineCPU(virDomainDefPtr dom, dom-clock.timers[j]-present = present; dom-clock.timers[j]-tickpolicy = -1; dom-clock.timers[j]-track = -1; +dom-clock.timers[j]-mode = -1; dom-clock.ntimers++; } else if (dom-clock.timers[j]-present != -1 dom-clock.timers[j]-present != present) { -- 1.8.5.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/3] qemu: hyperv: Add support for reference time couter enlightenment
Add a new timer for the HyperV reference time counter enlightenment for Windows guests. This feature provides a paravirtual approach to track timer events for the quest (similar to kvmclock). --- docs/formatdomain.html.in | 7 - docs/schemas/domaincommon.rng | 5 +++- src/conf/domain_conf.c | 6 +++-- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c| 30 -- .../qemuxml2argv-clock-timer-hyperv-rtc.args | 5 .../qemuxml2argv-clock-timer-hyperv-rtc.xml| 26 +++ tests/qemuxml2argvtest.c | 1 + tests/qemuxml2xmltest.c| 1 + 9 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-timer-hyperv-rtc.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fd02864..451ce8f 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1367,7 +1367,12 @@ being modified, and can be one of platform (currently unsupported), hpet (libxl, xen, qemu), kvmclock (qemu), -pit (qemu), rtc (qemu), or tsc (libxl). +pit (qemu), rtc (qemu), tsc (libxl) or hyperv_rtc +(qemu - span class=sincesince 1.2.2/span). + +The codehyperv_rtc/code timer adds support for the +reference time counter feature for guests running the +Microsoft Windows operating system. /dd dtcodetrack/code/dt dd diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 12fc0db..96e62d3 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -915,7 +915,10 @@ /group group attribute name=name -valuekvmclock/value +choice + valuekvmclock/value + valuehyperv_rtc/value +/choice /attribute /group /choice diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b6c984b..33b5bee 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -726,7 +726,8 @@ VIR_ENUM_IMPL(virDomainTimerName, VIR_DOMAIN_TIMER_NAME_LAST, rtc, hpet, tsc, - kvmclock); + kvmclock, + hyperv_rtc); VIR_ENUM_IMPL(virDomainTimerTrack, VIR_DOMAIN_TIMER_TRACK_LAST, boot, @@ -2929,7 +2930,8 @@ virDomainDefPostParseInternal(virDomainDefPtr def, for (i = 0; i def-clock.ntimers; i++) { virDomainTimerDefPtr timer = def-clock.timers[i]; -if (timer-name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK) { +if (timer-name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK || +timer-name == VIR_DOMAIN_TIMER_NAME_HYPERV_RTC) { if (timer-tickpolicy != -1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _(timer %s doesn't support setting of diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d8f2e49..300ba26 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1750,6 +1750,7 @@ enum virDomainTimerNameType { VIR_DOMAIN_TIMER_NAME_HPET, VIR_DOMAIN_TIMER_NAME_TSC, VIR_DOMAIN_TIMER_NAME_KVMCLOCK, +VIR_DOMAIN_TIMER_NAME_HYPERV_RTC, VIR_DOMAIN_TIMER_NAME_LAST }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index eef65ae..bc5219c 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6728,20 +6728,23 @@ qemuBuildCpuArgStr(virQEMUDriverPtr driver, } } -/* Now force kvmclock on/off based on the corresponding timer element. */ +/* Handle paravirtual timers */ for (i = 0; i def-clock.ntimers; i++) { -if (def-clock.timers[i]-name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK -def-clock.timers[i]-present != -1) { -char sign; -if (def-clock.timers[i]-present) -sign = '+'; -else -sign = '-'; +virDomainTimerDefPtr timer = def-clock.timers[i]; + +if (timer-present == -1) +continue; + +if (timer-name == VIR_DOMAIN_TIMER_NAME_KVMCLOCK) { virBufferAsprintf(buf, %s,%ckvmclock, have_cpu ? : default_model, - sign); + timer-present ? '+' : '-'); +have_cpu = true; +} else if (timer-name == VIR_DOMAIN_TIMER_NAME_HYPERV_RTC + timer-present) { +virBufferAsprintf(buf, %s,hv_time, + have_cpu ? : default_model); have_cpu = true; -break; } } @@ -8003,8 +8006,7 @@
Re: [libvirt] 1.2.0 segfault on Centos 6
On 02/04/2014 05:23 PM, Jiri Denemark wrote: On Tue, Feb 04, 2014 at 17:02:41 +0100, Franky Van Liedekerke wrote: Hi, using libvirt 1.2.0 on a up-to-date Centos6.5 machine leads to occasional segmentation faults (see below). Sometimes it runs for 5 minutes, sometimes for an hour, but after that the result is always the same: segfault after some weird qom-list, that apparently the qemu version on centos doesn't know. Has 1.2.1 a known fix for this? I believe the following patch should fix the crash. I'll do some testing tomorrow and send it as a proper patch afterwards: diff --git i/src/qemu/qemu_monitor.c w/src/qemu/qemu_monitor.c index a968901..cdd817f 100644 --- i/src/qemu/qemu_monitor.c +++ w/src/qemu/qemu_monitor.c @@ -1019,7 +1019,9 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, virDomainObjPtr vm, const char *curpath) { -size_t i, j, npaths = 0, nprops = 0; +size_t i, j; +int npaths = 0; +int nprops = 0; Reading into what the contention of the issue is, then these are perhaps all that's needed since the conflict is I assume the difference in size between 'int' and 'size_t'. Perhaps something Eric Blake understands best. My simple testing shows while difference in size (4 bytes vs. 8 bytes), the compiler seems to have done the right thing on the return value (eg, assigning 'size_t' value to a function returning int of -1). I know when I implemented this http://www.redhat.com/archives/libvir-list/2013-July/msg00770.html that I had tested without qom-list available. Curious to know if the issue was seen in a provided or built libvirt. It should be very simple to create a small C program that exhibits the issue - just have a variable of size_t initialized to 0 that gets set by a function that returns int, then print the result. int ret = 0; char *nextpath = NULL; qemuMonitorJSONListPathPtr *paths = NULL; @@ -1045,6 +1047,8 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, VIR_DEBUG(Searching for Balloon Object Path starting at %s, curpath); npaths = qemuMonitorJSONGetObjectListPaths(mon, curpath, paths); +if (npaths 0) +return -1; for (i = 0; i npaths ret == 0; i++) { We wouldn't enter the loop in the 0 -1 case, but would if 0 0x @@ -1061,6 +1065,11 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, * then this version of qemu/kvm does not support the feature. */ nprops = qemuMonitorJSONGetObjectListPaths(mon, nextpath, bprops); +if (nprops 0) { +ret = -1; +goto cleanup; +} + for (j = 0; j nprops; j++) { same here. if (STREQ(bprops[j]-name, guest-stats-polling-interval)) { VIR_DEBUG(Found Balloon Object Path %s, nextpath); -- 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
Re: [libvirt] 1.2.0 segfault on Centos 6
On Wed, Feb 05, 2014 at 07:02:38 -0500, John Ferlan wrote: On 02/04/2014 05:23 PM, Jiri Denemark wrote: On Tue, Feb 04, 2014 at 17:02:41 +0100, Franky Van Liedekerke wrote: Hi, using libvirt 1.2.0 on a up-to-date Centos6.5 machine leads to occasional segmentation faults (see below). Sometimes it runs for 5 minutes, sometimes for an hour, but after that the result is always the same: segfault after some weird qom-list, that apparently the qemu version on centos doesn't know. Has 1.2.1 a known fix for this? I believe the following patch should fix the crash. I'll do some testing tomorrow and send it as a proper patch afterwards: diff --git i/src/qemu/qemu_monitor.c w/src/qemu/qemu_monitor.c index a968901..cdd817f 100644 --- i/src/qemu/qemu_monitor.c +++ w/src/qemu/qemu_monitor.c @@ -1019,7 +1019,9 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, virDomainObjPtr vm, const char *curpath) { -size_t i, j, npaths = 0, nprops = 0; +size_t i, j; +int npaths = 0; +int nprops = 0; Reading into what the contention of the issue is, then these are perhaps all that's needed since the conflict is I assume the difference in size between 'int' and 'size_t'. Perhaps something Eric Blake understands best. My simple testing shows while difference in size (4 bytes vs. 8 bytes), the compiler seems to have done the right thing on the return value (eg, assigning 'size_t' value to a function returning int of -1). I know when I implemented this http://www.redhat.com/archives/libvir-list/2013-July/msg00770.html that I had tested without qom-list available. Curious to know if the issue was seen in a provided or built libvirt. It should be very simple to create a small C program that exhibits the issue - just have a variable of size_t initialized to 0 that gets set by a function that returns int, then print the result. int ret = 0; char *nextpath = NULL; qemuMonitorJSONListPathPtr *paths = NULL; @@ -1045,6 +1047,8 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, VIR_DEBUG(Searching for Balloon Object Path starting at %s, curpath); npaths = qemuMonitorJSONGetObjectListPaths(mon, curpath, paths); +if (npaths 0) +return -1; for (i = 0; i npaths ret == 0; i++) { We wouldn't enter the loop in the 0 -1 case, but would if 0 0x Sure, we wouldn't but then we would just return 0 from this function, which would be wrong. @@ -1061,6 +1065,11 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, * then this version of qemu/kvm does not support the feature. */ nprops = qemuMonitorJSONGetObjectListPaths(mon, nextpath, bprops); +if (nprops 0) { +ret = -1; +goto cleanup; +} + for (j = 0; j nprops; j++) { same here. And here we would overwrite the error from qemuMonitorJSONGetObjectListPaths with a different one. Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] qemu: Fix crash in virDomainMemoryStats with old qemu
If virDomainMemoryStats was run on a domain with virtio balloon driver running on an old qemu which supports QMP but does not support qom-list QMP command, libvirtd would crash. The reason is we did not check if qemuMonitorJSONGetObjectListPaths failed and moreover we even stored its result in an unsigned integer type. Signed-off-by: Jiri Denemark jdene...@redhat.com --- src/qemu/qemu_monitor.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index a968901..cdd817f 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1019,7 +1019,9 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, virDomainObjPtr vm, const char *curpath) { -size_t i, j, npaths = 0, nprops = 0; +size_t i, j; +int npaths = 0; +int nprops = 0; int ret = 0; char *nextpath = NULL; qemuMonitorJSONListPathPtr *paths = NULL; @@ -1045,6 +1047,8 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, VIR_DEBUG(Searching for Balloon Object Path starting at %s, curpath); npaths = qemuMonitorJSONGetObjectListPaths(mon, curpath, paths); +if (npaths 0) +return -1; for (i = 0; i npaths ret == 0; i++) { @@ -1061,6 +1065,11 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, * then this version of qemu/kvm does not support the feature. */ nprops = qemuMonitorJSONGetObjectListPaths(mon, nextpath, bprops); +if (nprops 0) { +ret = -1; +goto cleanup; +} + for (j = 0; j nprops; j++) { if (STREQ(bprops[j]-name, guest-stats-polling-interval)) { VIR_DEBUG(Found Balloon Object Path %s, nextpath); -- 1.8.5.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] 1.2.0 segfault on Centos 6
On Tue, Feb 04, 2014 at 11:23:42PM +0100, Jiri Denemark wrote: On Tue, Feb 04, 2014 at 17:02:41 +0100, Franky Van Liedekerke wrote: Hi, using libvirt 1.2.0 on a up-to-date Centos6.5 machine leads to occasional segmentation faults (see below). Sometimes it runs for 5 minutes, sometimes for an hour, but after that the result is always the same: segfault after some weird qom-list, that apparently the qemu version on centos doesn't know. Has 1.2.1 a known fix for this? I believe the following patch should fix the crash. I'll do some testing tomorrow and send it as a proper patch afterwards: diff --git i/src/qemu/qemu_monitor.c w/src/qemu/qemu_monitor.c index a968901..cdd817f 100644 --- i/src/qemu/qemu_monitor.c +++ w/src/qemu/qemu_monitor.c @@ -1019,7 +1019,9 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, virDomainObjPtr vm, const char *curpath) { -size_t i, j, npaths = 0, nprops = 0; +size_t i, j; +int npaths = 0; +int nprops = 0; int ret = 0; char *nextpath = NULL; qemuMonitorJSONListPathPtr *paths = NULL; @@ -1045,6 +1047,8 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, VIR_DEBUG(Searching for Balloon Object Path starting at %s, curpath); npaths = qemuMonitorJSONGetObjectListPaths(mon, curpath, paths); +if (npaths 0) +return -1; for (i = 0; i npaths ret == 0; i++) { @@ -1061,6 +1065,11 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, * then this version of qemu/kvm does not support the feature. */ nprops = qemuMonitorJSONGetObjectListPaths(mon, nextpath, bprops); +if (nprops 0) { +ret = -1; +goto cleanup; +} + for (j = 0; j nprops; j++) { if (STREQ(bprops[j]-name, guest-stats-polling-interval)) { VIR_DEBUG(Found Balloon Object Path %s, nextpath); It would be desirable to extend the qemujsonmonitor test suite to exercise the crash scenario too. 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 v2] qemu: Fix crash in virDomainMemoryStats with old qemu
If virDomainMemoryStats was run on a domain with virtio balloon driver running on an old qemu which supports QMP but does not support qom-list QMP command, libvirtd would crash. The reason is we did not check if qemuMonitorJSONGetObjectListPaths failed and moreover we even stored its result in an unsigned integer type. Signed-off-by: Jiri Denemark jdene...@redhat.com --- Notes: version 2: - use signed type for i and j to avoid comparison between signed and unsigned types; gcc-- for not complaining about it src/qemu/qemu_monitor.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index a968901..a2769db 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1019,7 +1019,7 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, virDomainObjPtr vm, const char *curpath) { -size_t i, j, npaths = 0, nprops = 0; +ssize_t i, j, npaths = 0, nprops = 0; int ret = 0; char *nextpath = NULL; qemuMonitorJSONListPathPtr *paths = NULL; @@ -1045,6 +1045,8 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, VIR_DEBUG(Searching for Balloon Object Path starting at %s, curpath); npaths = qemuMonitorJSONGetObjectListPaths(mon, curpath, paths); +if (npaths 0) +return -1; for (i = 0; i npaths ret == 0; i++) { @@ -1061,6 +1063,11 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, * then this version of qemu/kvm does not support the feature. */ nprops = qemuMonitorJSONGetObjectListPaths(mon, nextpath, bprops); +if (nprops 0) { +ret = -1; +goto cleanup; +} + for (j = 0; j nprops; j++) { if (STREQ(bprops[j]-name, guest-stats-polling-interval)) { VIR_DEBUG(Found Balloon Object Path %s, nextpath); -- 1.8.5.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: hyperv: Add enlightenment support for TSC timekeeping
On Tue, 2014-02-04 at 16:04 +0100, Peter Krempa wrote: [adding Vadim as he implemented the qemu/kvm parts] On 01/22/14 11:35, Daniel P. Berrange wrote: On Tue, Jan 21, 2014 at 06:54:34PM +0100, Peter Krempa wrote: The hyperv enlightenment features allow to ease guests timekeeping by allowing to store offset from the TSC as a reference. Add the support for enabling this flag in qemu. I'm not sure I entirely understand what this is doing with TSC, but we do have a generic timer element for controlling various attributes of platform timers. I can't help thinking it'd be better to keep this TSC related setting there instead This functionality provides hypercalls defined by the Microsoft's enlightenment standards. These provide calibration data and actual values that can be used by the guest to calculate time. [1] The actual implementation uses data provided by the kvmclock code: + case HV_X64_MSR_TIME_REF_COUNT: { + data = + div_u64(get_kernel_ns() + kvm-arch.kvmclock_offset, 100); + break; + } along with a few values that will allow the guest to use the data. Technically this is a new timer for VM's running windows and as with kvmclock, cpu features are used to show the availability of this feature to the guest. There is yet another enlightenment option for windows guests that run on platforms that support the invariant TSC (iTSC). This option will add hypercall to retrieve calibration data so that the host processors iTSC will be used as the timing source eliminating the need to read the timer value via a hypercall. Technically, it is not a hypercall, just a normal call RDTSC, but then kernel normalizes the returned value to 10MHz and adds offset. Kernel (KVM) shares scale and offset date with a guest through a dedicated page allocated by guest. We have pretty good working prototype at the moment, but this part has not been committed to upstream yet. Best regards, Vadim. I agree on your idea of moving this option into the timer section. How about naming it timer name=hv-rtc ? Daniel Peter [1]: http://msdn.microsoft.com/en-us/library/windows/hardware/ff542637(v=vs.85).aspx -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] network: disallow bandwidth/mac for bridged/macvtap networks
On 01/30/2014 12:29 PM, Michal Privoznik wrote: On 30.01.2014 11:26, Laine Stump wrote: On 01/27/2014 06:08 PM, Michal Privoznik wrote: On 24.01.2014 13:18, Laine Stump wrote: https://bugzilla.redhat.com/show_bug.cgi?id=1057321 pointed out that we weren't honoring the bandwidth element in libvirt networks using forward mode='bridge'/. In fact, these networks are just a method of giving a libvirt network name to an existing Linux host bridge on the system, and even if it were technically possible for us to set network-wide bandwidth limits for all the taps on a bridge, it's probably not a polite thing to do since libvirt is just using a bridge that was created by someone else for other purposes. So the proper thing is to just log an error when someone tries to put a bandwidth element in that type of network. While looking through the network XML documentation and comparing it to the networkValidate function, I noticed that we also ignore the presence of a mac address in the config, even though we do nothing with it in this case either. This patch updates networkValidate() (which is called any time a persistent network is defined, or a transient network created) to log an error and fail if it finds either a bandwidth or mac element and the network forward mode is anything except 'route'. 'nat', or nothing. (Yes, neither of those elements is acceptable for any macvtap mode, nor for a hostdev network). NB: This does *not* cause failure to start any existing network that contains one of those elements, so someone might have erroneously defined such a network in the past, and that network will continue to function unmodified. I considered it too disruptive to suddenly break working configs on the next reboot after a libvirt upgrade. --- src/network/bridge_driver.c | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 0b43a67..3b9b58d 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -2407,8 +2407,17 @@ networkValidate(virNetworkDriverStatePtr driver, virNetworkSetBridgeMacAddr(def); } else { /* They are also the only types that currently support setting - * an IP address for the host-side device (bridge) + * a MAC or IP address for the host-side device (bridge), DNS + * configuration, or network-wide bandwidth limits. */ +if (def-mac_specified) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(Unsupported mac element in network %s + with forward mode='%s'), + def-name, + virNetworkForwardTypeToString(def-forward.type)); +return -1; +} if (virNetworkDefGetIpByIndex(def, AF_UNSPEC, 0)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _(Unsupported ip element in network %s @@ -2433,6 +2442,14 @@ networkValidate(virNetworkDriverStatePtr driver, virNetworkForwardTypeToString(def-forward.type)); return -1; } +if (def-bandwidth) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(Unsupported network-wide bandwidth element + in network %s with forward mode='%s'), + def-name, + virNetworkForwardTypeToString(def-forward.type)); +return -1; +} } /* We only support dhcp on one IPv4 address and I think think this is exactly the opposite of what I've just pushed :) Indeed :-) I really should get myself Cc'ed on more bugzilla copmonents/products so that I notice these things sooner. I mean: commit 2996e6be19a13199ded7c2aa21039cca97318e01 Author: Michal Privoznik mpriv...@redhat.com AuthorDate: Wed Jan 22 18:58:33 2014 +0100 Commit: Michal Privoznik mpriv...@redhat.com CommitDate: Mon Jan 27 12:11:27 2014 +0100 networkAllocateActualDevice: Set QoS for bridgeless networks too https://bugzilla.redhat.com/show_bug.cgi?id=1055484 In the commit I'm trying to inherit network QoS to the interface that is just being created. Yes, it involves some magic but it works. I guess we need to agree if we want this approach or mine as they seem to be contradictionary. Since you've reverted yours, should I push this? After that, we may want to talk about 1) supporting use of the dev attribute in forward to name a *single* forwarding interface, and applying a network's bandwidth to that interface (while still failing in other cases), and 2) maybe supporting Open vSwitch in a more thorough manner so that projects like ovirt can use it to create intermediate bridges and manage their bandwidth via libvirt network xml. Yes. Please do push your patch. ACK. Okay, after a delay while considering the
Re: [libvirt] [PATCH] qemu: introduce spiceport serial backend
On Tue, Feb 04, 2014 at 02:25:03PM +0100, Martin Kletzander wrote: On Tue, Feb 04, 2014 at 01:34:38PM +0100, Christophe Fergeau wrote: Regarding the way it's exposed, you have chosen to go with devices serial type=spiceport source channel=org.qemu.console.serial.0/ target port=1/ /serial /devices This exposes the 'org.qemu.console.serial.0' spiceport as a serial port in the guest. This spiceport can then be used by client applications to interact with the guest. This is very similar to what is done for the spice agent channel (a virtio serial port is made available in the guest and is used for client-guest communication). Wouldn't it be more consistent to use channel type=spiceport target type=virtio name=org.qemu.console.serial.0/ /channel here? When I gave some thoughts about how to expose spiceport in libvirt, I got confused as in addition to this guest-spice client channel, spiceport is much more generic and can also be used to create some host-spice client channels (eg forward a local host socket/... over to the client through spice). If we use channel, maybe this can be added later with channel type=spiceport target type=host name=org.qemu.console.serial.0/ source ... / /channel ? (thinking out loud, and something which can be added when there is need for it) From the technical POV, you can interconnect spiceport as a source with any other target that qemu supports. [...] In the example I went with using isa-serial as a target, because that was the usage mentioned in the mail thanks to which I started working on it [1], but I to meet your needs you can go with: channel type=spiceport source channel=org.qemu.console.serial.0/ target type=virtio name=whatever-name.you.want/ /channel which works with this patch too Ah, I missed this was possible, hence the comments. It would probably be worth it to add a !isa-serial example either to the documentation or to the commit log. Thanks for the detailed explanation! P.S.: Due to spicevmc channel being implemented the way it is, it took me non-trivial amount of time to figure out how to expose this and I went through more designs before I figured this is just a backend, nothing else :) Yeah, had trouble wrapping my head around exposing spiceport when I gave it a quick look, good that you managed to get on top of it ;) Christophe pgpnva0Y0OrKf.pgp Description: PGP signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] event: move event filtering to daemon (regression fix)
On 01/28/2014 03:48 PM, Eric Blake wrote: Commit f9f56340 for CVE-2014-0028 almost had the right idea - we need to check the ACL rules to filter which events to send. But it overlooked one thing: the event dispatch queue is running in the main loop thread, and therefore does not normally have a current virIdentityPtr. But filter checks can be based on current identity, so when libvirtd.conf contains access_drivers=[polkit], we ended up rejecting access for EVERY event due to failure to look up the current identity, even if it should have been allowed. Ping. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] rpm: create libvirt-wireshark sub-package
On 02/05/2014 02:51 AM, Daniel P. Berrange wrote: On Tue, Feb 04, 2014 at 03:15:56PM -0700, Eric Blake wrote: On Fedora 20, with wireshark-devel installed, 'make rpm' failed due to installed but unpackaged files related to wireshark. As F20 is already released without wireshark, I chose to add a new sub-package that is enabled only for F21 and later. Furthermore, all existing wireshark plugins belong to the wireshark package, so I got to invent behavior of how the first third-part wireshark module will behave. * libvirt.spec.in (with_wireshark): Add new conditional. * configure.ac (ws-plugindir): Improve wording. Signed-off-by: Eric Blake ebl...@redhat.com --- I was tempted to push this as a build-breaker fix for 'make rpm', but rpms are close enough to black magic that I decided a review is safer, after all. Tested with both F20 (not built) and F21 (new subpackage built just fine), using normal build of all subpackages and also a build with '%client_only 1' in ~/.rpmmacros to ensure that it indeed works in a client-only setup. configure.ac| 4 ++-- libvirt.spec.in | 34 ++ 2 files changed, 36 insertions(+), 2 deletions(-) ACK Thanks; pushed. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] event: move event filtering to daemon (regression fix)
On Tue, Jan 28, 2014 at 03:48:19PM -0700, Eric Blake wrote: Commit f9f56340 for CVE-2014-0028 almost had the right idea - we need to check the ACL rules to filter which events to send. But it overlooked one thing: the event dispatch queue is running in the main loop thread, and therefore does not normally have a current virIdentityPtr. But filter checks can be based on current identity, so when libvirtd.conf contains access_drivers=[polkit], we ended up rejecting access for EVERY event due to failure to look up the current identity, even if it should have been allowed. Furthermore, even for events that are triggered by API calls, it is important to remember that the point of events is that they can be copied across multiple connections, which may have separate identities and permissions. So even if events were dispatched from a context where we have an identity, we must change to the correct identity of the connection that will be receiving the event, rather than basing a decision on the context that triggered the event, when deciding whether to filter an event to a particular connection. If there were an easy way to get from virConnectPtr to the appropriate virIdentityPtr, then object_event.c could adjust the identity prior to checking whether to dispatch an event. But setting up that back-reference is a bit invasive. Instead, it is easier to delay the filtering check until lower down the stack, at the point where we have direct access to the RPC client object that owns an identity. As such, this patch ends up reverting a large portion of the framework of commit f9f56340. We also have to teach 'make check' to special-case the fact that the event registration filtering is done at the point of dispatch, rather than the point of registration. Note that even though we don't actually use virConnectDomainEventRegisterCheckACL (because the RegisterAny variant is sufficient), we still generate the function for the purposes of documenting that the filtering takes place. Also note that I did not entirely delete the notion of a filter from object_event.c; I still plan on using that for my upcoming patch series for qemu monitor events in libvirt-qemu.so. In other words, while this patch changes ACL filtering to live in remote.c and therefore we have no current client of the filtering in object_event.c, the notion of filtering in object_event.c is still useful down the road. * src/check-aclrules.pl: Exempt event registration from having to pass checkACL filter down call stack. * daemon/remote.c (remoteRelayDomainEventCheckACL) (remoteRelayNetworkEventCheckACL): New functions. (remoteRelay*Event*): Use new functions. * src/conf/domain_event.h (virDomainEventStateRegister) (virDomainEventStateRegisterID): Drop unused parameter. * src/conf/network_event.h (virNetworkEventStateRegisterID): Likewise. * src/conf/domain_event.c (virDomainEventFilter): Delete unused function. * src/conf/network_event.c (virNetworkEventFilter): Likewise. * src/libxl/libxl_driver.c: Adjust caller. * src/lxc/lxc_driver.c: Likewise. * src/network/bridge_driver.c: Likewise. * src/qemu/qemu_driver.c: Likewise. * src/remote/remote_driver.c: Likewise. * src/test/test_driver.c: Likewise. * src/uml/uml_driver.c: Likewise. * src/vbox/vbox_tmpl.c: Likewise. * src/xen/xen_driver.c: Likewise. Signed-off-by: Eric Blake ebl...@redhat.com --- daemon/remote.c | 257 src/check-aclrules.pl | 7 +- src/conf/domain_event.c | 35 +- src/conf/domain_event.h | 8 +- src/conf/network_event.c| 31 +- src/conf/network_event.h| 6 +- src/libxl/libxl_driver.c| 2 - src/lxc/lxc_driver.c| 2 - src/network/bridge_driver.c | 1 - src/qemu/qemu_driver.c | 2 - src/remote/remote_driver.c | 4 +- src/test/test_driver.c | 6 +- src/uml/uml_driver.c| 2 - src/vbox/vbox_tmpl.c| 4 +- src/xen/xen_driver.c| 2 - 15 files changed, 188 insertions(+), 181 deletions(-) ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [1.1.3 PATCH] event: move event filtering to daemon (regression fix)
On Tue, Jan 28, 2014 at 05:14:40PM -0700, Eric Blake wrote: Commit f9f56340 for CVE-2014-0028 almost had the right idea - we need to check the ACL rules to filter which events to send. But it overlooked one thing: the event dispatch queue is running in the main loop thread, and therefore does not normally have a current virIdentityPtr. But filter checks can be based on current identity, so when libvirtd.conf contains access_drivers=[polkit], we ended up rejecting access for EVERY event due to failure to look up the current identity, even if it should have been allowed. Furthermore, even for events that are triggered by API calls, it is important to remember that the point of events is that they can be copied across multiple connections, which may have separate identities and permissions. So even if events were dispatched from a context where we have an identity, we must change to the correct identity of the connection that will be receiving the event, rather than basing a decision on the context that triggered the event, when deciding whether to filter an event to a particular connection. If there were an easy way to get from virConnectPtr to the appropriate virIdentityPtr, then object_event.c could adjust the identity prior to checking whether to dispatch an event. But setting up that back-reference is a bit invasive. Instead, it is easier to delay the filtering check until lower down the stack, at the point where we have direct access to the RPC client object that owns an identity. As such, this patch ends up reverting a large portion of the framework of commit f9f56340. We also have to teach 'make check' to special-case the fact that the event registration filtering is done at the point of dispatch, rather than the point of registration. Note that even though we don't actually use virConnectDomainEventRegisterCheckACL (because the RegisterAny variant is sufficient), we still generate the function for the purposes of documenting that the filtering takes place. Also note that I did not entirely delete the notion of a filter from object_event.c; I still plan on using that for my upcoming patch series for qemu monitor events in libvirt-qemu.so. In other words, while this patch changes ACL filtering to live in remote.c and therefore we have no current client of the filtering in object_event.c, the notion of filtering in object_event.c is still useful down the road. * src/check-aclrules.pl: Exempt event registration from having to pass checkACL filter down call stack. * daemon/remote.c (remoteRelayDomainEventCheckACL) (remoteRelayNetworkEventCheckACL): New functions. (remoteRelay*Event*): Use new functions. * src/conf/domain_event.h (virDomainEventStateRegister) (virDomainEventStateRegisterID): Drop unused parameter. * src/conf/network_event.h (virNetworkEventStateRegisterID): Likewise. * src/conf/domain_event.c (virDomainEventFilter): Delete unused function. * src/conf/network_event.c (virNetworkEventFilter): Likewise. * src/libxl/libxl_driver.c: Adjust caller. * src/lxc/lxc_driver.c: Likewise. * src/network/bridge_driver.c: Likewise. * src/qemu/qemu_driver.c: Likewise. * src/remote/remote_driver.c: Likewise. * src/test/test_driver.c: Likewise. * src/uml/uml_driver.c: Likewise. * src/vbox/vbox_tmpl.c: Likewise. * src/xen/xen_driver.c: Likewise. Signed-off-by: Eric Blake ebl...@redhat.com (cherry picked from commit TBD) Conflicts: daemon/remote.c - not backporting network events src/conf/network_event.c - likewise src/conf/network_event.h - likewise src/network/bridge_driver.c - likewise src/conf/domain_event.c - revert back to pre-CVE state src/conf/domain_event.h - likewise src/libxl/libxl_driver.c - likewise src/lxc/lxc_driver.c - likewise src/remote/remote_driver.c - likewise src/test/test_driver.c - likewise src/uml/uml_driver.c - likewise src/xen/xen_driver.c - likewise --- This is the backport to the various stable branches, assuming the main patch is accepted for the master branch. I'm also going to send an alternative representation that might make review easier. ACK Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 10/21] LXC from native: convert lxc.id_map into idmap
--- src/lxc/lxc_native.c | 44 ++ tests/lxcconf2xmldata/lxcconf2xml-idmap.config | 5 +++ tests/lxcconf2xmldata/lxcconf2xml-idmap.xml| 28 tests/lxcconf2xmltest.c| 1 + 4 files changed, 78 insertions(+) create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-idmap.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-idmap.xml diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index b413e42..dd706f8 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -567,6 +567,46 @@ error: return -1; } +static int +lxcIdmapWalkCallback(const char *name, virConfValuePtr value, void *data) +{ +virDomainDefPtr def = data; +virDomainIdMapEntryPtr idmap = NULL; +char type; +unsigned long start, target, count; + +if (STRNEQ(name, lxc.id_map) || !value-str) +return 0; + +if (sscanf(value-str, %c %lu %lu %lu, type, + target, start, count) != 4) { +virReportError(VIR_ERR_INTERNAL_ERROR, _(invalid lxc.id_map: '%s'), + value-str); +return -1; +} + +if (VIR_ALLOC(idmap) 0) +return -1; + +if (type == 'u') { +if (VIR_EXPAND_N(def-idmap.uidmap, def-idmap.nuidmap, 1) 0) +return -1; +idmap = def-idmap.uidmap[def-idmap.nuidmap - 1]; +} else if (type == 'g') { +if (VIR_EXPAND_N(def-idmap.gidmap, def-idmap.ngidmap, 1) 0) +return -1; +idmap = def-idmap.gidmap[def-idmap.ngidmap - 1]; +} else { +return -1; +} + +idmap-start = start; +idmap-target = target; +idmap-count = count; + +return 0; +} + virDomainDefPtr lxcParseConfigString(const char *config) { @@ -635,6 +675,10 @@ lxcParseConfigString(const char *config) if (lxcCreateConsoles(vmdef, properties) 0) goto error; +/* lxc.id_map */ +if (virConfWalk(properties, lxcIdmapWalkCallback, vmdef) 0) +goto error; + goto cleanup; error: diff --git a/tests/lxcconf2xmldata/lxcconf2xml-idmap.config b/tests/lxcconf2xmldata/lxcconf2xml-idmap.config new file mode 100644 index 000..4c3657a --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-idmap.config @@ -0,0 +1,5 @@ +lxc.rootfs = /var/lib/lxc/migrate_test/rootfs +lxc.utsname = migrate_test + +lxc.id_map = u 1 0 2000 +lxc.id_map = g 1 0 1000 diff --git a/tests/lxcconf2xmldata/lxcconf2xml-idmap.xml b/tests/lxcconf2xmldata/lxcconf2xml-idmap.xml new file mode 100644 index 000..576c903 --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-idmap.xml @@ -0,0 +1,28 @@ +domain type='lxc' + namemigrate_test/name + uuidc7a5fdbd-edaf-9455-926a-d65c16db1809/uuid + memory unit='KiB'65536/memory + currentMemory unit='KiB'0/currentMemory + vcpu placement='static' current='0'1/vcpu + os +typeexe/type +init/sbin/init/init + /os + idmap +uid start='0' target='1' count='2000'/ +gid start='0' target='1' count='1000'/ + /idmap + features +privnet/ + /features + clock offset='utc'/ + on_poweroffdestroy/on_poweroff + on_rebootrestart/on_reboot + on_crashdestroy/on_crash + devices +filesystem type='mount' accessmode='passthrough' + source dir='/var/lib/lxc/migrate_test/rootfs'/ + target dir='/'/ +/filesystem + /devices +/domain diff --git a/tests/lxcconf2xmltest.c b/tests/lxcconf2xmltest.c index 4e7dd58..7042bdf 100644 --- a/tests/lxcconf2xmltest.c +++ b/tests/lxcconf2xmltest.c @@ -108,6 +108,7 @@ mymain(void) DO_TEST(nonenetwork, false); DO_TEST(physnetwork, false); DO_TEST(macvlannetwork, false); +DO_TEST(idmap, false); return ret; } -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 03/21] LXC from native: import rootfs
LXC rootfs can be either a directory or a block device or an image file. The first two types have been implemented, but the image file is still to be done since LXC auto-guesses the file format at mount time and the LXC driver doesn't support the 'auto' format. --- src/lxc/lxc_native.c | 69 tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 4 ++ 2 files changed, 73 insertions(+) diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index 723ebcf..86d0dd3 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -31,6 +31,72 @@ #define VIR_FROM_THIS VIR_FROM_LXC + +static virDomainFSDefPtr +lxcCreateFSDef(int type, char *src, char* dst) +{ +virDomainFSDefPtr def; + +if (VIR_ALLOC(def) 0) +return NULL; + +def-type = type; +def-accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH; +def-src = src; +def-dst = dst; + +return def; +} + +static int +lxcAddFSDef(virDomainDefPtr def, int type, char *src, char *dst) +{ +virDomainFSDefPtr fsDef = NULL; + +if (!(fsDef = lxcCreateFSDef(type, src, dst))) +goto error; + +if (VIR_EXPAND_N(def-fss, def-nfss, 1) 0) +goto error; +def-fss[def-nfss - 1] = fsDef; + +return 0; + +error: +virDomainFSDefFree(fsDef); +return -1; +} + +static int +lxcSetRootfs(virDomainDefPtr def, + virConfPtr properties) +{ +char *fssrc = NULL; +char *fsdst = NULL; +int type = VIR_DOMAIN_FS_TYPE_MOUNT; +virConfValuePtr value; + +if (!(value = virConfGetValue(properties, lxc.rootfs)) || + !value-str || + (VIR_STRDUP(fssrc, value-str) 0) || +VIR_STRDUP(fsdst, /) 0) +goto error; + +if (STRPREFIX(fssrc, /dev/)) +type = VIR_DOMAIN_FS_TYPE_BLOCK; + + +if (lxcAddFSDef(def, type, fssrc, fsdst) 0) +goto error; + +return 0; + +error: +VIR_FREE(fssrc); +VIR_FREE(fsdst); +return -1; +} + virDomainDefPtr lxcParseConfigString(const char *config) { @@ -73,6 +139,9 @@ lxcParseConfigString(const char *config) if (!vmdef-name (VIR_STRDUP(vmdef-name, unnamed) 0)) goto error; +if (lxcSetRootfs(vmdef, properties) 0) +goto error; + goto cleanup; error: diff --git a/tests/lxcconf2xmldata/lxcconf2xml-simple.xml b/tests/lxcconf2xmldata/lxcconf2xml-simple.xml index 641e624..eebcb4e 100644 --- a/tests/lxcconf2xmldata/lxcconf2xml-simple.xml +++ b/tests/lxcconf2xmldata/lxcconf2xml-simple.xml @@ -13,5 +13,9 @@ on_rebootrestart/on_reboot on_crashdestroy/on_crash devices +filesystem type='mount' accessmode='passthrough' + source dir='/var/lib/lxc/migrate_test/rootfs'/ + target dir='/'/ +/filesystem /devices /domain -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 13/21] LXC from native: map lxc.cgroup.cpuset.*
--- src/lxc/lxc_native.c | 30 ++ .../lxcconf2xmldata/lxcconf2xml-cpusettune.config | 6 + tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml | 27 +++ tests/lxcconf2xmltest.c| 1 + 4 files changed, 64 insertions(+) create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cpusettune.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index 65a1d0d..ee8fa75 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -673,6 +673,32 @@ error: return -1; } +static int +lxcSetCpusetTune(virDomainDefPtr def, virConfPtr properties) +{ +virConfValuePtr value; + +if ((value = virConfGetValue(properties, lxc.cgroup.cpuset.cpus)) +value-str) { +if (virBitmapParse(value-str, 0, def-cpumask, + VIR_DOMAIN_CPUMASK_LEN) 0) +return -1; + +def-placement_mode = VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC; +} + +if ((value = virConfGetValue(properties, lxc.cgroup.cpuset.mems)) +value-str) { +def-numatune.memory.placement_mode = VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_STATIC; +def-numatune.memory.mode = VIR_DOMAIN_NUMATUNE_MEM_STRICT; +if (virBitmapParse(value-str, 0, def-numatune.memory.nodemask, + VIR_DOMAIN_CPUMASK_LEN) 0) +return -1; +} + +return 0; +} + virDomainDefPtr lxcParseConfigString(const char *config) { @@ -753,6 +779,10 @@ lxcParseConfigString(const char *config) if (lxcSetCpuTune(vmdef, properties) 0) goto error; +/* lxc.cgroup.cpuset.* */ +if (lxcSetCpusetTune(vmdef, properties) 0) +goto error; + goto cleanup; error: diff --git a/tests/lxcconf2xmldata/lxcconf2xml-cpusettune.config b/tests/lxcconf2xmldata/lxcconf2xml-cpusettune.config new file mode 100644 index 000..a550f57 --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-cpusettune.config @@ -0,0 +1,6 @@ +lxc.rootfs = /var/lib/lxc/migrate_test/rootfs +lxc.utsname = migrate_test +lxc.autodev=1 + +lxc.cgroup.cpuset.cpus = 1,2,5-7 +lxc.cgroup.cpuset.mems = 1-4 diff --git a/tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml b/tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml new file mode 100644 index 000..1b8fb0c --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml @@ -0,0 +1,27 @@ +domain type='lxc' + namemigrate_test/name + uuidc7a5fdbd-edaf-9455-926a-d65c16db1809/uuid + memory unit='KiB'65536/memory + currentMemory unit='KiB'0/currentMemory + vcpu placement='static' cpuset='1-2,5-7' current='0'1/vcpu + numatune +memory mode='strict' nodeset='1-4'/ + /numatune + os +typeexe/type +init/sbin/init/init + /os + features +privnet/ + /features + clock offset='utc'/ + on_poweroffdestroy/on_poweroff + on_rebootrestart/on_reboot + on_crashdestroy/on_crash + devices +filesystem type='mount' accessmode='passthrough' + source dir='/var/lib/lxc/migrate_test/rootfs'/ + target dir='/'/ +/filesystem + /devices +/domain diff --git a/tests/lxcconf2xmltest.c b/tests/lxcconf2xmltest.c index 1148cd3..6bee5c5 100644 --- a/tests/lxcconf2xmltest.c +++ b/tests/lxcconf2xmltest.c @@ -111,6 +111,7 @@ mymain(void) DO_TEST(idmap, false); DO_TEST(memtune, false); DO_TEST(cputune, false); +DO_TEST(cpusettune, false); return ret; } -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 07/21] LXC from native: convert phys network types to net hostdev devices
--- src/lxc/lxc_native.c | 44 +++--- .../lxcconf2xmldata/lxcconf2xml-physnetwork.config | 6 +++ tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml | 26 + tests/lxcconf2xmltest.c| 1 + 4 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index 42eccfc..7997fda 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -366,6 +366,26 @@ error: return NULL; } +static virDomainHostdevDefPtr +lxcCreateHostdevDef(int mode, int type, const char *data) +{ +virDomainHostdevDefPtr hostdev = virDomainHostdevDefAlloc(); + +if (!hostdev) +return NULL; + +hostdev-mode = mode; +hostdev-source.caps.type = type; + +if (type == VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET +VIR_STRDUP(hostdev-source.caps.u.net.iface, data) 0) { +virDomainHostdevDefFree(hostdev); +hostdev = NULL; +} + +return hostdev; +} + static int lxcAddNetworkDefinition(virDomainDefPtr def, const char *type, @@ -374,22 +394,36 @@ lxcAddNetworkDefinition(virDomainDefPtr def, const char *flag) { virDomainNetDefPtr net = NULL; +virDomainHostdevDefPtr hostdev = NULL; if ((type == NULL) || STREQ(type, empty) || STREQ(type, ) || STREQ(type, none)) return 0; -if (!(net = lxcCreateNetDef(type, link, mac, flag))) -goto error; +if (type != NULL STREQ(type, phys)) { +if (!link || +!(hostdev = lxcCreateHostdevDef(VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES, +VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET, +link))) +goto error; -if (VIR_EXPAND_N(def-nets, def-nnets, 1) 0) -goto error; -def-nets[def-nnets - 1] = net; +if (VIR_EXPAND_N(def-hostdevs, def-nhostdevs, 1) 0) +goto error; +def-hostdevs[def-nhostdevs - 1] = hostdev; +} else { +if (!(net = lxcCreateNetDef(type, link, mac, flag))) +goto error; + +if (VIR_EXPAND_N(def-nets, def-nnets, 1) 0) +goto error; +def-nets[def-nnets - 1] = net; +} return 1; error: virDomainNetDefFree(net); +virDomainHostdevDefFree(hostdev); return -1; } diff --git a/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config b/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config new file mode 100644 index 000..63a4aa1 --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.config @@ -0,0 +1,6 @@ +lxc.network.type = phys +lxc.network.link = eth0 + +lxc.rootfs = /var/lib/lxc/migrate_test/rootfs +lxc.utsname = migrate_test +lxc.autodev=1 diff --git a/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml b/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml new file mode 100644 index 000..35a2a96 --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml @@ -0,0 +1,26 @@ +domain type='lxc' + namemigrate_test/name + uuidc7a5fdbd-edaf-9455-926a-d65c16db1809/uuid + memory unit='KiB'65536/memory + currentMemory unit='KiB'0/currentMemory + vcpu placement='static' current='0'1/vcpu + os +typeexe/type +init/sbin/init/init + /os + clock offset='utc'/ + on_poweroffdestroy/on_poweroff + on_rebootrestart/on_reboot + on_crashdestroy/on_crash + devices +filesystem type='mount' accessmode='passthrough' + source dir='/var/lib/lxc/migrate_test/rootfs'/ + target dir='/'/ +/filesystem +hostdev mode='capabilities' type='net' + source +interfaceeth0/interface + /source +/hostdev + /devices +/domain diff --git a/tests/lxcconf2xmltest.c b/tests/lxcconf2xmltest.c index 50041a5..c888b42 100644 --- a/tests/lxcconf2xmltest.c +++ b/tests/lxcconf2xmltest.c @@ -106,6 +106,7 @@ mymain(void) DO_TEST(fstab, true); DO_TEST(nonetwork, false); DO_TEST(nonenetwork, false); +DO_TEST(physnetwork, false); return ret; } -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 02/21] LXC driver: started implementing connectDomainXMLFromNative
This function aims at converting LXC configuration into a libvirt domain XML description to help users migrate from LXC to libvirt. Here is an example of how the lxc configuration works: virsh -c lxc:/// domxml-from-native lxc-tools /var/lib/lxc/migrate_test/config It is possible that some parts couldn't be properly mapped into a domain XML fragment, so users should carefully review the result before creating the domain. fstab files in lxc.mount lines will need to be merged into the configuration file as lxc.mount.entry. As we can't know the amount of memory of the host, we have to set a default value for max_balloon that users will probably want to adjust. --- .gitignore | 1 + po/POTFILES.in | 1 + src/Makefile.am | 1 + src/lxc/lxc_driver.c| 31 +++ src/lxc/lxc_native.c| 86 +++ src/lxc/lxc_native.h| 32 +++ tests/Makefile.am | 7 +- tests/lxcconf2xmldata/lxcconf2xml-simple.config | 38 + tests/lxcconf2xmldata/lxcconf2xml-simple.xml| 17 tests/lxcconf2xmltest.c | 107 10 files changed, 320 insertions(+), 1 deletion(-) create mode 100644 src/lxc/lxc_native.c create mode 100644 src/lxc/lxc_native.h create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-simple.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-simple.xml create mode 100644 tests/lxcconf2xmltest.c diff --git a/.gitignore b/.gitignore index 757dfed..65b6763 100644 --- a/.gitignore +++ b/.gitignore @@ -157,6 +157,7 @@ /tests/hashtest /tests/jsontest /tests/libvirtdconftest +/tests/lxcconf2xmltest /tests/metadatatest /tests/networkxml2argvtest /tests/nodeinfotest diff --git a/po/POTFILES.in b/po/POTFILES.in index 0359b2f..fd36bc5 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -62,6 +62,7 @@ src/locking/sanlock_helper.c src/lxc/lxc_cgroup.c src/lxc/lxc_fuse.c src/lxc/lxc_hostdev.c +src/lxc/lxc_native.c src/lxc/lxc_container.c src/lxc/lxc_conf.c src/lxc/lxc_controller.c diff --git a/src/Makefile.am b/src/Makefile.am index 3f8d22f..4ac31e2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -619,6 +619,7 @@ LXC_DRIVER_SOURCES = \ lxc/lxc_monitor.c lxc/lxc_monitor.h \ lxc/lxc_process.c lxc/lxc_process.h \ lxc/lxc_fuse.c lxc/lxc_fuse.h \ + lxc/lxc_native.c lxc/lxc_native.h \ lxc/lxc_driver.c lxc/lxc_driver.h LXC_CONTROLLER_SOURCES = \ diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 138c706..dc0e8e0 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -44,6 +44,7 @@ #include lxc_container.h #include lxc_domain.h #include lxc_driver.h +#include lxc_native.h #include lxc_process.h #include viralloc.h #include virnetdevbridge.h @@ -988,6 +989,35 @@ cleanup: return ret; } +static char *lxcConnectDomainXMLFromNative(virConnectPtr conn, + const char *nativeFormat, + const char *nativeConfig, + unsigned int flags) +{ +char *xml = NULL; +virDomainDefPtr def = NULL; + +virCheckFlags(0, NULL); + +if (virConnectDomainXMLFromNativeEnsureACL(conn) 0) +goto cleanup; + +if (STRNEQ(nativeFormat, LXC_CONFIG_FORMAT)) { +virReportError(VIR_ERR_INVALID_ARG, + _(unsupported config type %s), nativeFormat); +goto cleanup; +} + +if (!(def = lxcParseConfigString(nativeConfig))) +goto cleanup; + +xml = virDomainDefFormat(def, 0); + +cleanup: +virDomainDefFree(def); +return xml; +} + /** * lxcDomainCreateWithFiles: * @dom: domain to start @@ -5376,6 +5406,7 @@ static virDriver lxcDriver = { .domainGetSecurityLabel = lxcDomainGetSecurityLabel, /* 0.9.10 */ .nodeGetSecurityModel = lxcNodeGetSecurityModel, /* 0.9.10 */ .domainGetXMLDesc = lxcDomainGetXMLDesc, /* 0.4.2 */ +.connectDomainXMLFromNative = lxcConnectDomainXMLFromNative, /* 1.2.2 */ .connectListDefinedDomains = lxcConnectListDefinedDomains, /* 0.4.2 */ .connectNumOfDefinedDomains = lxcConnectNumOfDefinedDomains, /* 0.4.2 */ .domainCreate = lxcDomainCreate, /* 0.4.4 */ diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c new file mode 100644 index 000..723ebcf --- /dev/null +++ b/src/lxc/lxc_native.c @@ -0,0 +1,86 @@ +/* + * lxc_native.c: LXC native configuration import + * + * Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the
[libvirt] [PATCH v3 12/21] LXC from native: map lxc.cgroup.cpu.*
--- src/lxc/lxc_native.c | 34 tests/lxcconf2xmldata/lxcconf2xml-cputune.config | 7 + tests/lxcconf2xmldata/lxcconf2xml-cputune.xml| 29 tests/lxcconf2xmltest.c | 1 + 4 files changed, 71 insertions(+) create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cputune.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cputune.xml diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index d430abc..65a1d0d 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -643,6 +643,36 @@ lxcSetMemTune(virDomainDefPtr def, virConfPtr properties) return 0; } +static int +lxcSetCpuTune(virDomainDefPtr def, virConfPtr properties) +{ +virConfValuePtr value; + +if ((value = virConfGetValue(properties, lxc.cgroup.cpu.shares)) +value-str virStrToLong_ul(value-str, NULL, 10, + def-cputune.shares) 0) +goto error; + +if ((value = virConfGetValue(properties, + lxc.cgroup.cpu.cfs_quota_us)) +value-str virStrToLong_ll(value-str, NULL, 10, + def-cputune.quota) 0) +goto error; + +if ((value = virConfGetValue(properties, + lxc.cgroup.cpu.cfs_period_us)) +value-str virStrToLong_ull(value-str, NULL, 10, + def-cputune.period) 0) +goto error; + +return 0; + +error: +virReportError(VIR_ERR_INTERNAL_ERROR, + _(failed to parse integer: '%s'), value-str); +return -1; +} + virDomainDefPtr lxcParseConfigString(const char *config) { @@ -719,6 +749,10 @@ lxcParseConfigString(const char *config) if (lxcSetMemTune(vmdef, properties) 0) goto error; +/* lxc.cgroup.cpu.* */ +if (lxcSetCpuTune(vmdef, properties) 0) +goto error; + goto cleanup; error: diff --git a/tests/lxcconf2xmldata/lxcconf2xml-cputune.config b/tests/lxcconf2xmldata/lxcconf2xml-cputune.config new file mode 100644 index 000..9797dec --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-cputune.config @@ -0,0 +1,7 @@ +lxc.rootfs = /var/lib/lxc/migrate_test/rootfs +lxc.utsname = migrate_test +lxc.autodev=1 + +lxc.cgroup.cpu.shares = 1024 +lxc.cgroup.cpu.cfs_quota_us = -1 +lxc.cgroup.cpu.cfs_period_us = 50 diff --git a/tests/lxcconf2xmldata/lxcconf2xml-cputune.xml b/tests/lxcconf2xmldata/lxcconf2xml-cputune.xml new file mode 100644 index 000..a511dcf --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-cputune.xml @@ -0,0 +1,29 @@ +domain type='lxc' + namemigrate_test/name + uuidc7a5fdbd-edaf-9455-926a-d65c16db1809/uuid + memory unit='KiB'65536/memory + currentMemory unit='KiB'0/currentMemory + vcpu placement='static' current='0'1/vcpu + cputune +shares1024/shares +period50/period +quota-1/quota + /cputune + os +typeexe/type +init/sbin/init/init + /os + features +privnet/ + /features + clock offset='utc'/ + on_poweroffdestroy/on_poweroff + on_rebootrestart/on_reboot + on_crashdestroy/on_crash + devices +filesystem type='mount' accessmode='passthrough' + source dir='/var/lib/lxc/migrate_test/rootfs'/ + target dir='/'/ +/filesystem + /devices +/domain diff --git a/tests/lxcconf2xmltest.c b/tests/lxcconf2xmltest.c index 3dd0a0b..1148cd3 100644 --- a/tests/lxcconf2xmltest.c +++ b/tests/lxcconf2xmltest.c @@ -110,6 +110,7 @@ mymain(void) DO_TEST(macvlannetwork, false); DO_TEST(idmap, false); DO_TEST(memtune, false); +DO_TEST(cputune, false); return ret; } -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 08/21] LXC from native: convert lxc.tty to console devices
--- src/lxc/lxc_native.c | 44 tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 6 2 files changed, 50 insertions(+) diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index 7997fda..96523c4 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -500,6 +500,46 @@ lxcConvertNetworkSettings(virDomainDefPtr def, virConfPtr properties) return 0; } +static int +lxcCreateConsoles(virDomainDefPtr def, virConfPtr properties) +{ +virConfValuePtr value; +int nbttys = 0; +virDomainChrDefPtr console; +size_t i; + +if (!(value = virConfGetValue(properties, lxc.tty)) || !value-str) +return 0; + +if (virStrToLong_i(value-str, NULL, 10, nbttys) 0) { +virReportError(VIR_ERR_INTERNAL_ERROR, _(failed to parse int: '%s'), + value-str); +return -1; +} + +if (VIR_ALLOC_N(def-consoles, nbttys) 0) +return -1; + +def-nconsoles = nbttys; +for (i = 0; i nbttys; i++) { +if (!(console = virDomainChrDefNew())) +goto error; + +console-deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE; +console-targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LXC; +console-target.port = i; +console-source.type = VIR_DOMAIN_CHR_TYPE_PTY; + +def-consoles[i] = console; +} + +return 0; + +error: +virDomainChrDefFree(console); +return -1; +} + virDomainDefPtr lxcParseConfigString(const char *config) { @@ -564,6 +604,10 @@ lxcParseConfigString(const char *config) if (lxcConvertNetworkSettings(vmdef, properties) 0) goto error; +/* Consoles */ +if (lxcCreateConsoles(vmdef, properties) 0) +goto error; + goto cleanup; error: diff --git a/tests/lxcconf2xmldata/lxcconf2xml-simple.xml b/tests/lxcconf2xmldata/lxcconf2xml-simple.xml index 75c3b28..711e0d9 100644 --- a/tests/lxcconf2xmldata/lxcconf2xml-simple.xml +++ b/tests/lxcconf2xmldata/lxcconf2xml-simple.xml @@ -31,5 +31,11 @@ source bridge='virbr0'/ link state='up'/ /interface +console type='pty' + target type='lxc' port='0'/ +/console +console type='pty' + target type='lxc' port='1'/ +/console /devices /domain -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 11/21] LXC from native: migrate memory tuning
--- src/lxc/lxc_native.c | 40 tests/lxcconf2xmldata/lxcconf2xml-memtune.config | 10 ++ tests/lxcconf2xmldata/lxcconf2xml-memtune.xml| 29 + tests/lxcconf2xmltest.c | 1 + 4 files changed, 80 insertions(+) create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-memtune.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-memtune.xml diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index dd706f8..d430abc 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -607,6 +607,42 @@ lxcIdmapWalkCallback(const char *name, virConfValuePtr value, void *data) return 0; } +static int +lxcSetMemTune(virDomainDefPtr def, virConfPtr properties) +{ +virConfValuePtr value; +unsigned long long size = 0; + +if ((value = virConfGetValue(properties, +lxc.cgroup.memory.limit_in_bytes)) +value-str STRNEQ(value-str, -1)) { +if (lxcConvertSize(value-str, size) 0) +return -1; +size = size / 1024; +def-mem.max_balloon = size; +def-mem.hard_limit = size; +} + +if ((value = virConfGetValue(properties, +lxc.cgroup.memory.soft_limit_in_bytes)) +value-str STRNEQ(value-str, -1)) { +if (lxcConvertSize(value-str, size) 0) +return -1; + +def-mem.soft_limit = size / 1024; +} + +if ((value = virConfGetValue(properties, +lxc.cgroup.memory.memsw.limit_in_bytes)) +value-str STRNEQ(value-str, -1)) { +if (lxcConvertSize(value-str, size) 0) +return -1; + + def-mem.swap_hard_limit = size / 1024; +} +return 0; +} + virDomainDefPtr lxcParseConfigString(const char *config) { @@ -679,6 +715,10 @@ lxcParseConfigString(const char *config) if (virConfWalk(properties, lxcIdmapWalkCallback, vmdef) 0) goto error; +/* lxc.cgroup.memory.* */ +if (lxcSetMemTune(vmdef, properties) 0) +goto error; + goto cleanup; error: diff --git a/tests/lxcconf2xmldata/lxcconf2xml-memtune.config b/tests/lxcconf2xmldata/lxcconf2xml-memtune.config new file mode 100644 index 000..ef07a51 --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-memtune.config @@ -0,0 +1,10 @@ +lxc.rootfs = /var/lib/lxc/migrate_test/rootfs +lxc.utsname = migrate_test +lxc.autodev=1 + +# 1GiB +lxc.cgroup.memory.limit_in_bytes = 1073741824 +# 128MiB +lxc.cgroup.memory.soft_limit_in_bytes = 134217728 +# 2GiB +lxc.cgroup.memory.memsw.limit_in_bytes = 2147483648 diff --git a/tests/lxcconf2xmldata/lxcconf2xml-memtune.xml b/tests/lxcconf2xmldata/lxcconf2xml-memtune.xml new file mode 100644 index 000..0264356 --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-memtune.xml @@ -0,0 +1,29 @@ +domain type='lxc' + namemigrate_test/name + uuidc7a5fdbd-edaf-9455-926a-d65c16db1809/uuid + memory unit='KiB'1048576/memory + currentMemory unit='KiB'0/currentMemory + memtune +hard_limit unit='KiB'1048576/hard_limit +soft_limit unit='KiB'131072/soft_limit +swap_hard_limit unit='KiB'2097152/swap_hard_limit + /memtune + vcpu placement='static' current='0'1/vcpu + os +typeexe/type +init/sbin/init/init + /os + features +privnet/ + /features + clock offset='utc'/ + on_poweroffdestroy/on_poweroff + on_rebootrestart/on_reboot + on_crashdestroy/on_crash + devices +filesystem type='mount' accessmode='passthrough' + source dir='/var/lib/lxc/migrate_test/rootfs'/ + target dir='/'/ +/filesystem + /devices +/domain diff --git a/tests/lxcconf2xmltest.c b/tests/lxcconf2xmltest.c index 7042bdf..3dd0a0b 100644 --- a/tests/lxcconf2xmltest.c +++ b/tests/lxcconf2xmltest.c @@ -109,6 +109,7 @@ mymain(void) DO_TEST(physnetwork, false); DO_TEST(macvlannetwork, false); DO_TEST(idmap, false); +DO_TEST(memtune, false); return ret; } -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 17/21] LXC from native: map vlan network type
The problem with VLAN is that the user still has to manually create the vlan interface on the host. Then the generated configuration will use it as a nerwork hostdev device. So the generated configurations of the following two fragments are equivalent (see rhbz#1059637). lxc.network.type = phys lxc.network.link = eth0.5 lxc.network.type = vlan lxc.network.link = eth0 lxc.network.vlan.id = 5 --- src/lxc/lxc_native.c | 28 ++ .../lxcconf2xmldata/lxcconf2xml-vlannetwork.config | 12 ++ tests/lxcconf2xmldata/lxcconf2xml-vlannetwork.xml | 26 tests/lxcconf2xmltest.c| 1 + 4 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-vlannetwork.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-vlannetwork.xml diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index 9a16523..8d8c50a 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -411,22 +411,33 @@ lxcAddNetworkDefinition(virDomainDefPtr def, const char *link, const char *mac, const char *flag, -const char *macvlanmode) +const char *macvlanmode, +const char *vlanid) { virDomainNetDefPtr net = NULL; virDomainHostdevDefPtr hostdev = NULL; +bool isPhys, isVlan = false; if ((type == NULL) || STREQ(type, empty) || STREQ(type, ) || STREQ(type, none)) return 0; -if (type != NULL STREQ(type, phys)) { +isPhys = STREQ(type, phys); +isVlan = STREQ(type, vlan); +if (type != NULL (isPhys || isVlan)) { if (!link || !(hostdev = lxcCreateHostdevDef(VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES, VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET, link))) goto error; +/* This still requires the user to manually setup the vlan interface + * on the host */ +if (isVlan !(link vlanid +virAsprintf(hostdev-source.caps.u.net.iface, +%s.%s, link, vlanid) = 0)) +goto error; + if (VIR_EXPAND_N(def-hostdevs, def-nhostdevs, 1) 0) goto error; def-hostdevs[def-nhostdevs - 1] = hostdev; @@ -454,6 +465,7 @@ typedef struct { char *mac; char *flag; char *macvlanmode; +char *vlanid; bool privnet; size_t networks; } lxcNetworkParseData; @@ -469,7 +481,8 @@ lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) status = lxcAddNetworkDefinition(parseData-def, parseData-type, parseData-link, parseData-mac, parseData-flag, - parseData-macvlanmode); + parseData-macvlanmode, + parseData-vlanid); if (status 0) return -1; @@ -484,6 +497,7 @@ lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) parseData-mac = NULL; parseData-flag = NULL; parseData-macvlanmode = NULL; +parseData-vlanid = NULL; /* Keep the new value */ parseData-type = value-str; @@ -496,6 +510,8 @@ lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) parseData-flag = value-str; else if (STREQ(name, lxc.network.macvlan.mode)) parseData-macvlanmode = value-str; +else if (STREQ(name, lxc.network.vlan.id)) +parseData-vlanid = value-str; else if (STRPREFIX(name, lxc.network)) VIR_WARN(Unhandled network property: %s = %s, name, @@ -508,14 +524,16 @@ static int lxcConvertNetworkSettings(virDomainDefPtr def, virConfPtr properties) { int status; -lxcNetworkParseData data = {def, NULL, NULL, NULL, NULL, NULL, true, 0}; +lxcNetworkParseData data = {def, NULL, NULL, NULL, NULL, +NULL, NULL, true, 0}; virConfWalk(properties, lxcNetworkWalkCallback, data); /* Add the last network definition found */ status = lxcAddNetworkDefinition(def, data.type, data.link, data.mac, data.flag, - data.macvlanmode); + data.macvlanmode, + data.vlanid); if (status 0) return -1; else if (status 0) diff --git a/tests/lxcconf2xmldata/lxcconf2xml-vlannetwork.config b/tests/lxcconf2xmldata/lxcconf2xml-vlannetwork.config new file mode 100644 index 000..327202c --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-vlannetwork.config @@ -0,0 +1,12 @@ +# Template used to create this
[libvirt] [PATCH v3 16/21] LXC from native: map block filesystems
--- src/lxc/lxc_native.c | 4 1 file changed, 4 insertions(+) diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index 1997370..9a16523 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -286,6 +286,10 @@ lxcAddFstabLine(virDomainDefPtr def, lxcFstabPtr fstab) goto error; } +/* Is it a block device that needs special favor? */ +if (STRPREFIX(fstab-src, /dev/)) +type = VIR_DOMAIN_FS_TYPE_BLOCK; + /* Do we have ro in options? */ readonly = virStringArrayHasString(options, ro); -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 01/21] Improve virConf parse to handle LXC config format
virConf now honours a VIR_CONF_FLAG_LXC_FORMAT flag to handle LXC configuration files. The differences are that property names can contain '.' character and values are all strings without any bounding quotes. Provide a new virConfWalk function calling a handler on all non-comment values. This function will be used by the LXC conversion code to loop over LXC configuration lines. --- src/libvirt_private.syms | 1 + src/util/virconf.c | 46 -- src/util/virconf.h | 10 ++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c5a7637..ba10b4e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1128,6 +1128,7 @@ virConfNew; virConfReadFile; virConfReadMem; virConfSetValue; +virConfWalk; virConfWriteFile; virConfWriteMem; diff --git a/src/util/virconf.c b/src/util/virconf.c index e882d15..63aa569 100644 --- a/src/util/virconf.c +++ b/src/util/virconf.c @@ -429,6 +429,16 @@ virConfParseString(virConfParserCtxtPtr ctxt) if (VIR_STRNDUP(ret, base, ctxt-cur - base) 0) return NULL; NEXT; +} else if (ctxt-conf-flags VIR_CONF_FLAG_LXC_FORMAT) { +base = ctxt-cur; +/* LXC config format doesn't support comments after the value */ +while ((ctxt-cur ctxt-end) (!IS_EOL(CUR))) +NEXT; +/* Reverse to exclude the trailing blanks from the value */ +while ((ctxt-cur base) (c_isblank(CUR))) +ctxt-cur--; +if (VIR_STRNDUP(ret, base, ctxt-cur - base) 0) +return NULL; } return ret; } @@ -454,7 +464,8 @@ virConfParseValue(virConfParserCtxtPtr ctxt) virConfError(ctxt, VIR_ERR_CONF_SYNTAX, _(expecting a value)); return NULL; } -if ((CUR == '') || (CUR == '\'')) { +if ((CUR == '') || (CUR == '\'') || + (ctxt-conf-flags VIR_CONF_FLAG_LXC_FORMAT)) { type = VIR_CONF_STRING; str = virConfParseString(ctxt); if (str == NULL) @@ -561,7 +572,9 @@ virConfParseName(virConfParserCtxtPtr ctxt) while ((ctxt-cur ctxt-end) (c_isalnum(CUR) || (CUR == '_') || ((ctxt-conf-flags VIR_CONF_FLAG_VMX_FORMAT) - ((CUR == ':') || (CUR == '.') || (CUR == '-') + ((CUR == ':') || (CUR == '.') || (CUR == '-'))) || +((ctxt-conf-flags VIR_CONF_FLAG_LXC_FORMAT) + (CUR == '.' NEXT; if (VIR_STRNDUP(ret, base, ctxt-cur - base) 0) return NULL; @@ -905,6 +918,35 @@ virConfSetValue(virConfPtr conf, return 0; } +/** + * virConfWalk: + * @conf: a configuration file handle + * @callback: the function to call to process each entry + * @data: obscure data passed to callback + * + * Walk over all entries of the configuration file and run the callback + * for each with entry name, value and the obscure data. + * + * Returns 0 on success, or -1 on failure. + */ +int virConfWalk(virConfPtr conf, + virConfWalkCallback callback, + void *opaque) +{ +virConfEntryPtr cur; + +if (!conf) +return 0; + +cur = conf-entries; +while (cur != NULL) { +if (cur-name cur-value +callback(cur-name, cur-value, opaque) 0) +return -1; +cur = cur-next; +} +return 0; +} /** * virConfWriteFile: diff --git a/src/util/virconf.h b/src/util/virconf.h index 577af8c..2a6b050 100644 --- a/src/util/virconf.h +++ b/src/util/virconf.h @@ -40,6 +40,9 @@ typedef enum { VIR_CONF_FLAG_VMX_FORMAT = 1, /* allow ':', '.' and '-' in names for compatibility with VMware VMX configuration file, but restrict allowed value types to string only */ +VIR_CONF_FLAG_LXC_FORMAT = 2, /* allow '.' in names for compatibility with LXC + configuration file, restricts allowed value types + to string only and don't expect quotes for values */ } virConfFlags; static inline const char * @@ -79,6 +82,10 @@ struct _virConfValue { typedef struct _virConf virConf; typedef virConf *virConfPtr; +typedef int (*virConfWalkCallback)(const char* name, + virConfValuePtr value, + void *opaque); + virConfPtr virConfNew (void); virConfPtr virConfReadFile (const char *filename, unsigned int flags); virConfPtr virConfReadMem (const char *memory, @@ -91,6 +98,9 @@ virConfValuePtr virConfGetValue (virConfPtr conf, int virConfSetValue(virConfPtr conf, const char *setting, virConfValuePtr value); +int virConfWalk(virConfPtr conf, +virConfWalkCallback callback, +
[libvirt] [PATCH v3 06/21] LXC from native: migrate veth network configuration
Some of the LXC configuration properties aren't migrated since they would only cause problems in libvirt-lxc: * lxc.network.ipv[46]: LXC driver doesn't setup IP address of guests, see rhbz#1059624 * lxc.network.name, see rhbz#1059630 --- src/lxc/lxc_native.c | 114 --- tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 5 ++ 2 files changed, 107 insertions(+), 12 deletions(-) diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index bc14d69..42eccfc 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -325,8 +325,80 @@ lxcFstabWalkCallback(const char* name, virConfValuePtr value, void * data) return ret; } +static virDomainNetDefPtr +lxcCreateNetDef(const char *type, +const char *link, +const char *mac, +const char *flag) +{ +virDomainNetDefPtr net = NULL; + +if (VIR_ALLOC(net) 0) +goto error; + +if (flag) { +if (STREQ(flag, up)) +net-linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP; +else +net-linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN; +} + +if (STREQ(type, veth)) { +virMacAddr macAddr; + +if (!link) +goto error; + +net-type = VIR_DOMAIN_NET_TYPE_BRIDGE; + +if (VIR_STRDUP(net-data.bridge.brname, link) 0) +goto error; + +if (mac virMacAddrParse(mac, macAddr) == 0) +net-mac = macAddr; + +} + +return net; + +error: +virDomainNetDefFree(net); +return NULL; +} + +static int +lxcAddNetworkDefinition(virDomainDefPtr def, +const char *type, +const char *link, +const char *mac, +const char *flag) +{ +virDomainNetDefPtr net = NULL; + +if ((type == NULL) || STREQ(type, empty) || STREQ(type, ) || +STREQ(type, none)) +return 0; + +if (!(net = lxcCreateNetDef(type, link, mac, flag))) +goto error; + +if (VIR_EXPAND_N(def-nets, def-nnets, 1) 0) +goto error; +def-nets[def-nnets - 1] = net; + +return 1; + +error: +virDomainNetDefFree(net); +return -1; +} + typedef struct { +virDomainDefPtr def; char *type; +char *link; +char *mac; +char *flag; bool privnet; size_t networks; } lxcNetworkParseData; @@ -335,38 +407,56 @@ static int lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) { lxcNetworkParseData *parseData = data; +int status; if (STREQ(name, lxc.network.type)) { -if (parseData-type != NULL STREQ(parseData-type, none)) -parseData-privnet = false; -else if ((parseData-type != NULL) -STRNEQ(parseData-type, empty) -STRNEQ(parseData-type, )) { +/* Store the previous NIC */ +status = lxcAddNetworkDefinition(parseData-def, parseData-type, + parseData-link, parseData-mac, + parseData-flag); +if (status 0) +return -1; +else if (status 0) parseData-networks++; -} +else if (parseData-type != NULL STREQ(parseData-type, none)) +parseData-privnet = false; /* Start a new network interface config */ parseData-type = NULL; +parseData-link = NULL; +parseData-mac = NULL; +parseData-flag = NULL; /* Keep the new value */ parseData-type = value-str; } +else if (STREQ(name, lxc.network.link)) +parseData-link = value-str; +else if (STREQ(name, lxc.network.hwaddr)) +parseData-mac = value-str; +else if (STREQ(name, lxc.network.flags)) +parseData-flag = value-str; + return 0; } static int lxcConvertNetworkSettings(virDomainDefPtr def, virConfPtr properties) { -lxcNetworkParseData data = {NULL, true, 0}; +int status; +lxcNetworkParseData data = {def, NULL, NULL, NULL, NULL, true, 0}; virConfWalk(properties, lxcNetworkWalkCallback, data); -if ((data.type != NULL) STREQ(data.type, none)) -data.privnet = false; -else if ((data.type != NULL) STRNEQ(data.type, empty) -STRNEQ(data.type, )) { +/* Add the last network definition found */ +status = lxcAddNetworkDefinition(def, data.type, data.link, + data.mac, data.flag); +if (status 0) +return -1; +else if (status 0) data.networks++; -} +else if (data.type != NULL STREQ(data.type, none)) +data.privnet = false; if (data.networks == 0 data.privnet) { /* When no network type is provided LXC only adds loopback */ diff --git a/tests/lxcconf2xmldata/lxcconf2xml-simple.xml b/tests/lxcconf2xmldata/lxcconf2xml-simple.xml index fadbdca..75c3b28 100644 ---
[libvirt] [PATCH v3 04/21] LXC from native: migrate fstab and lxc.mount.entry
Tmpfs relative size and default 50% size values aren't supported as we have no idea of the available memory at the conversion time. --- src/lxc/lxc_container.c | 2 +- src/lxc/lxc_container.h | 2 + src/lxc/lxc_native.c| 251 +++- tests/lxcconf2xmldata/lxcconf2xml-fstab.config | 37 tests/lxcconf2xmldata/lxcconf2xml-simple.config | 4 +- tests/lxcconf2xmldata/lxcconf2xml-simple.xml| 9 + tests/lxcconf2xmltest.c | 60 +++--- 7 files changed, 336 insertions(+), 29 deletions(-) create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-fstab.config diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index c6bdc8c..f08dbc2 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -744,7 +744,7 @@ static const virLXCBasicMountInfo lxcBasicMounts[] = { }; -static bool lxcIsBasicMountLocation(const char *path) +bool lxcIsBasicMountLocation(const char *path) { size_t i; diff --git a/src/lxc/lxc_container.h b/src/lxc/lxc_container.h index e74a7d7..67292ab 100644 --- a/src/lxc/lxc_container.h +++ b/src/lxc/lxc_container.h @@ -71,4 +71,6 @@ virArch lxcContainerGetAlt32bitArch(virArch arch); int lxcContainerChown(virDomainDefPtr def, const char *path); +bool lxcIsBasicMountLocation(const char *path); + #endif /* LXC_CONTAINER_H */ diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index 86d0dd3..acd68db 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -21,10 +21,13 @@ */ #include config.h +#include stdio.h #include internal.h +#include lxc_container.h #include lxc_native.h #include util/viralloc.h +#include util/virfile.h #include util/virlog.h #include util/virstring.h #include util/virconf.h @@ -33,7 +36,11 @@ static virDomainFSDefPtr -lxcCreateFSDef(int type, char *src, char* dst) +lxcCreateFSDef(int type, + char *src, + char* dst, + bool readonly, + unsigned long long usage) { virDomainFSDefPtr def; @@ -44,16 +51,124 @@ lxcCreateFSDef(int type, char *src, char* dst) def-accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH; def-src = src; def-dst = dst; +def-readonly = readonly; +def-usage = usage; return def; } +typedef struct _lxcFstab lxcFstab; +typedef lxcFstab *lxcFstabPtr; +struct _lxcFstab { +lxcFstabPtr next; +char *src; +char *dst; +char *type; +char *options; +}; + +static void +lxcFstabFree(lxcFstabPtr fstab) +{ +while (fstab) { +lxcFstabPtr next = NULL; +next = fstab-next; + +VIR_FREE(fstab-src); +VIR_FREE(fstab-dst); +VIR_FREE(fstab-type); +VIR_FREE(fstab-options); +VIR_FREE(fstab); + +fstab = next; +} +} + +static char ** lxcStringSplit(const char *string) +{ +char *tmp; +size_t i; +size_t ntokens = 0; +char **parts; +char **result = NULL; + +if (VIR_STRDUP(tmp, string) 0) +return NULL; + +/* Replace potential \t by a space */ +for (i = 0; tmp[i]; i++) { +if (tmp[i] == '\t') +tmp[i] = ' '; +} + +parts = virStringSplit(tmp, , 0); +for (i = 0; parts[i]; i++) { +if (STREQ(parts[i], )) +continue; + +if (VIR_EXPAND_N(result, ntokens, 1) 0) +goto error; + +if (VIR_STRDUP(result[ntokens-1], parts[i]) 0) +goto error; +} + +/* Append NULL element */ +if (VIR_EXPAND_N(result, ntokens, 1) 0) +goto error; + +VIR_FREE(tmp); +virStringFreeList(parts); +return result; + +error: +VIR_FREE(tmp); +virStringFreeList(parts); +virStringFreeList(result); +return NULL; +} + +static lxcFstabPtr +lxcParseFstabLine(char *fstabLine) +{ +lxcFstabPtr fstab = NULL; +char **parts; + +if (!fstabLine || VIR_ALLOC(fstab) 0) +return NULL; + +parts = lxcStringSplit(fstabLine); + +if (!parts[0] || !parts[1] || !parts[2] || !parts[3]) +goto error; + +if (VIR_STRDUP(fstab-src, parts[0]) 0 || +VIR_STRDUP(fstab-dst, parts[1]) 0 || +VIR_STRDUP(fstab-type, parts[2]) 0 || +VIR_STRDUP(fstab-options, parts[3]) 0) +goto error; + +virStringFreeList(parts); + +return fstab; + +error: +lxcFstabFree(fstab); +virStringFreeList(parts); +return NULL; +} + static int -lxcAddFSDef(virDomainDefPtr def, int type, char *src, char *dst) +lxcAddFSDef(virDomainDefPtr def, +int type, +char *src, +char *dst, +bool readonly, +unsigned long long usage) { virDomainFSDefPtr fsDef = NULL; -if (!(fsDef = lxcCreateFSDef(type, src, dst))) +if (!(fsDef = lxcCreateFSDef(type, src, dst, readonly, usage))) goto error; if (VIR_EXPAND_N(def-fss, def-nfss, 1) 0) @@ -86,7 +201,7 @@
[libvirt] [PATCH v3 00/21] LXC configuration conversion
Here is an updated version of the patch set fixing comments from Daniel. It also adds 3 commits: * One adding conversion for the newly supported blkio throttle tune in lxc driver. * One actually using the state of the veth network device in lxc driver. * One adding the ability to give major:minor numbers instead of a path for blkio tune devices. The last one is a way to address Daniel's comment on the /dev/block/... paths. Cédric Bosdonnat (21): Improve virConf parse to handle LXC config format LXC driver: started implementing connectDomainXMLFromNative LXC from native: import rootfs LXC from native: migrate fstab and lxc.mount.entry LXC from native: implement no network conversion LXC from native: migrate veth network configuration LXC from native: convert phys network types to net hostdev devices LXC from native: convert lxc.tty to console devices LXC from native: convert macvlan network configuration LXC from native: convert lxc.id_map into idmap LXC from native: migrate memory tuning LXC from native: map lxc.cgroup.cpu.* LXC from native: map lxc.cgroup.cpuset.* LXC from native: add lxc.cgroup.blkio.* mapping LXC from native: map lxc.arch to /domain/os/type@arch LXC from native: map block filesystems LXC from native: map vlan network type LXC: added some doc on domxml-from-native with mention of limitations LXC from native: convert blkio throttle config lxc: honor link state=up for veth interfaces blkiotune: allow node major='' minor=''/ in place of path .gitignore | 1 + docs/drvlxc.html.in| 34 +- docs/formatdomain.html.in | 10 +- po/POTFILES.in | 1 + src/Makefile.am| 1 + src/conf/domain_conf.c | 45 +- src/conf/domain_conf.h | 2 + src/libvirt_private.syms | 1 + src/lxc/lxc_cgroup.c | 5 + src/lxc/lxc_container.c| 2 +- src/lxc/lxc_container.h| 2 + src/lxc/lxc_driver.c | 41 + src/lxc/lxc_native.c | 952 + src/lxc/lxc_native.h | 32 + src/lxc/lxc_process.c | 5 + src/qemu/qemu_cgroup.c | 5 + src/qemu/qemu_driver.c | 10 + src/util/vircgroup.c | 126 ++- src/util/vircgroup.h | 10 + src/util/virconf.c | 46 +- src/util/virconf.h | 10 + tests/Makefile.am | 7 +- tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config | 11 + tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml| 39 + .../lxcconf2xmldata/lxcconf2xml-cpusettune.config | 6 + tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml | 27 + tests/lxcconf2xmldata/lxcconf2xml-cputune.config | 7 + tests/lxcconf2xmldata/lxcconf2xml-cputune.xml | 29 + tests/lxcconf2xmldata/lxcconf2xml-fstab.config | 37 + tests/lxcconf2xmldata/lxcconf2xml-idmap.config | 5 + tests/lxcconf2xmldata/lxcconf2xml-idmap.xml| 28 + .../lxcconf2xml-macvlannetwork.config | 13 + .../lxcconf2xmldata/lxcconf2xml-macvlannetwork.xml | 26 + tests/lxcconf2xmldata/lxcconf2xml-memtune.config | 10 + tests/lxcconf2xmldata/lxcconf2xml-memtune.xml | 29 + .../lxcconf2xmldata/lxcconf2xml-nonenetwork.config | 4 + tests/lxcconf2xmldata/lxcconf2xml-nonenetwork.xml | 21 + tests/lxcconf2xmldata/lxcconf2xml-nonetwork.config | 3 + tests/lxcconf2xmldata/lxcconf2xml-nonetwork.xml| 24 + .../lxcconf2xmldata/lxcconf2xml-physnetwork.config | 6 + tests/lxcconf2xmldata/lxcconf2xml-physnetwork.xml | 26 + tests/lxcconf2xmldata/lxcconf2xml-simple.config| 41 + tests/lxcconf2xmldata/lxcconf2xml-simple.xml | 41 + .../lxcconf2xmldata/lxcconf2xml-vlannetwork.config | 12 + tests/lxcconf2xmldata/lxcconf2xml-vlannetwork.xml | 26 + tests/lxcconf2xmltest.c| 131 +++ 46 files changed, 1865 insertions(+), 85 deletions(-) create mode 100644 src/lxc/lxc_native.c create mode 100644 src/lxc/lxc_native.h create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cpusettune.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cpusettune.xml create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cputune.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-cputune.xml create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-fstab.config create mode 100644
[libvirt] [PATCH v3 15/21] LXC from native: map lxc.arch to /domain/os/type@arch
--- src/lxc/lxc_native.c| 9 + tests/lxcconf2xmldata/lxcconf2xml-simple.config | 1 + tests/lxcconf2xmldata/lxcconf2xml-simple.xml| 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index 15c03f2..1997370 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -794,6 +794,15 @@ lxcParseConfigString(const char *config) if (VIR_STRDUP(vmdef-os.type, exe) 0) goto error; +if ((value = virConfGetValue(properties, lxc.arch)) value-str) { +virArch arch = virArchFromString(value-str); +if (arch == VIR_ARCH_NONE STREQ(value-str, x86)) +arch = VIR_ARCH_I686; +else if (arch == VIR_ARCH_NONE STREQ(value-str, amd64)) +arch = VIR_ARCH_X86_64; +vmdef-os.arch = arch; +} + if (VIR_STRDUP(vmdef-os.init, /sbin/init) 0) goto error; diff --git a/tests/lxcconf2xmldata/lxcconf2xml-simple.config b/tests/lxcconf2xmldata/lxcconf2xml-simple.config index f75e8fc..b90abc1 100644 --- a/tests/lxcconf2xmldata/lxcconf2xml-simple.config +++ b/tests/lxcconf2xmldata/lxcconf2xml-simple.config @@ -14,6 +14,7 @@ lxc.mount.entry = tmpfs run tmpfs size=8m,mode=0755,nodev,nosuid 0 0 lxc.mount.entry = /etc/resolv.conf etc/resolv.conf none bind,ro 0 0 lxc.rootfs = /var/lib/lxc/migrate_test/rootfs lxc.utsname = migrate_test +lxc.arch = x86 lxc.autodev=1 lxc.tty = 2 lxc.pts = 1024 diff --git a/tests/lxcconf2xmldata/lxcconf2xml-simple.xml b/tests/lxcconf2xmldata/lxcconf2xml-simple.xml index 711e0d9..6ec0f17 100644 --- a/tests/lxcconf2xmldata/lxcconf2xml-simple.xml +++ b/tests/lxcconf2xmldata/lxcconf2xml-simple.xml @@ -5,7 +5,7 @@ currentMemory unit='KiB'0/currentMemory vcpu placement='static' current='0'1/vcpu os -typeexe/type +type arch='i686'exe/type init/sbin/init/init /os clock offset='utc'/ -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 05/21] LXC from native: implement no network conversion
If no network configuration is provided, LXC only provides the loopback interface. To match this, we need to use the privnet feature. LXC will also define a 'none' network type in its 1.0.0 version that fits libvirt LXC driver's default. --- src/lxc/lxc_native.c | 55 ++ .../lxcconf2xmldata/lxcconf2xml-nonenetwork.config | 4 ++ tests/lxcconf2xmldata/lxcconf2xml-nonenetwork.xml | 21 + tests/lxcconf2xmldata/lxcconf2xml-nonetwork.config | 3 ++ tests/lxcconf2xmldata/lxcconf2xml-nonetwork.xml| 24 ++ tests/lxcconf2xmltest.c| 2 + 6 files changed, 109 insertions(+) create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-nonenetwork.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-nonenetwork.xml create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-nonetwork.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-nonetwork.xml diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index acd68db..bc14d69 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -325,6 +325,57 @@ lxcFstabWalkCallback(const char* name, virConfValuePtr value, void * data) return ret; } +typedef struct { +char *type; +bool privnet; +size_t networks; +} lxcNetworkParseData; + +static int +lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) +{ +lxcNetworkParseData *parseData = data; + +if (STREQ(name, lxc.network.type)) { +if (parseData-type != NULL STREQ(parseData-type, none)) +parseData-privnet = false; +else if ((parseData-type != NULL) +STRNEQ(parseData-type, empty) +STRNEQ(parseData-type, )) { +parseData-networks++; +} + +/* Start a new network interface config */ +parseData-type = NULL; + +/* Keep the new value */ +parseData-type = value-str; +} +return 0; +} + +static int +lxcConvertNetworkSettings(virDomainDefPtr def, virConfPtr properties) +{ +lxcNetworkParseData data = {NULL, true, 0}; + +virConfWalk(properties, lxcNetworkWalkCallback, data); + +if ((data.type != NULL) STREQ(data.type, none)) +data.privnet = false; +else if ((data.type != NULL) STRNEQ(data.type, empty) +STRNEQ(data.type, )) { +data.networks++; +} + +if (data.networks == 0 data.privnet) { +/* When no network type is provided LXC only adds loopback */ +def-features[VIR_DOMAIN_FEATURE_PRIVNET] = VIR_DOMAIN_FEATURE_STATE_ON; +} + +return 0; +} + virDomainDefPtr lxcParseConfigString(const char *config) { @@ -385,6 +436,10 @@ lxcParseConfigString(const char *config) if (virConfWalk(properties, lxcFstabWalkCallback, vmdef) 0) goto error; +/* Network configuration */ +if (lxcConvertNetworkSettings(vmdef, properties) 0) +goto error; + goto cleanup; error: diff --git a/tests/lxcconf2xmldata/lxcconf2xml-nonenetwork.config b/tests/lxcconf2xmldata/lxcconf2xml-nonenetwork.config new file mode 100644 index 000..c1bb9a6 --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-nonenetwork.config @@ -0,0 +1,4 @@ +lxc.rootfs = /var/lib/lxc/migrate_test/rootfs +lxc.utsname = migrate_test +lxc.autodev=1 +lxc.network.type = none diff --git a/tests/lxcconf2xmldata/lxcconf2xml-nonenetwork.xml b/tests/lxcconf2xmldata/lxcconf2xml-nonenetwork.xml new file mode 100644 index 000..eebcb4e --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-nonenetwork.xml @@ -0,0 +1,21 @@ +domain type='lxc' + namemigrate_test/name + uuidc7a5fdbd-edaf-9455-926a-d65c16db1809/uuid + memory unit='KiB'65536/memory + currentMemory unit='KiB'0/currentMemory + vcpu placement='static' current='0'1/vcpu + os +typeexe/type +init/sbin/init/init + /os + clock offset='utc'/ + on_poweroffdestroy/on_poweroff + on_rebootrestart/on_reboot + on_crashdestroy/on_crash + devices +filesystem type='mount' accessmode='passthrough' + source dir='/var/lib/lxc/migrate_test/rootfs'/ + target dir='/'/ +/filesystem + /devices +/domain diff --git a/tests/lxcconf2xmldata/lxcconf2xml-nonetwork.config b/tests/lxcconf2xmldata/lxcconf2xml-nonetwork.config new file mode 100644 index 000..b6fbe1d --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-nonetwork.config @@ -0,0 +1,3 @@ +lxc.rootfs = /var/lib/lxc/migrate_test/rootfs +lxc.utsname = migrate_test +lxc.autodev=1 diff --git a/tests/lxcconf2xmldata/lxcconf2xml-nonetwork.xml b/tests/lxcconf2xmldata/lxcconf2xml-nonetwork.xml new file mode 100644 index 000..511e3dd --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-nonetwork.xml @@ -0,0 +1,24 @@ +domain type='lxc' + namemigrate_test/name + uuidc7a5fdbd-edaf-9455-926a-d65c16db1809/uuid + memory unit='KiB'65536/memory + currentMemory unit='KiB'0/currentMemory + vcpu placement='static' current='0'1/vcpu + os +typeexe/type +
[libvirt] [PATCH v3 20/21] lxc: honor link state=up for veth interfaces
direct interfaces are already brought up when creating them. --- src/lxc/lxc_process.c | 5 + 1 file changed, 5 insertions(+) diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index ed729f6..6f7ff74 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -245,6 +245,7 @@ char *virLXCProcessSetupInterfaceBridged(virConnectPtr conn, char *parentVeth; char *containerVeth = NULL; virNetDevVPortProfilePtr vport = virDomainNetGetActualVirtPortProfile(net); +bool vethUp = false; VIR_DEBUG(calling vethCreate()); parentVeth = net-ifname; @@ -283,6 +284,10 @@ char *virLXCProcessSetupInterfaceBridged(virConnectPtr conn, virDomainConfNWFilterInstantiate(conn, vm-uuid, net) 0) goto cleanup; +vethUp = net-linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP; +if (virNetDevSetOnline(containerVeth, vethUp) 0) +goto cleanup; + ret = containerVeth; cleanup: -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 21/21] blkiotune: allow node major='' minor=''/ in place of path
To ease LXC configuration conversion, allow blkiotune device XML fragments to define the device using its major:minor numbers. --- docs/formatdomain.html.in | 10 +- src/conf/domain_conf.c | 45 - src/conf/domain_conf.h | 2 + src/lxc/lxc_cgroup.c| 5 + src/lxc/lxc_driver.c| 10 ++ src/lxc/lxc_native.c| 24 - src/qemu/qemu_cgroup.c | 5 + src/qemu/qemu_driver.c | 10 ++ src/util/vircgroup.c| 126 ++-- src/util/vircgroup.h| 10 ++ tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml | 4 +- 11 files changed, 165 insertions(+), 86 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index fd02864..2ab7d39 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -761,6 +761,10 @@ lt;pathgt;/dev/sdblt;/pathgt; lt;weightgt;500lt;/weightgt; lt;/devicegt; +lt;devicegt; + lt;node major='8' minor='0'/gt; + lt;weightgt;500lt;/weightgt; +lt;/devicegt; lt;/blkiotunegt; ... lt;/domaingt; @@ -794,7 +798,11 @@ absolute path of the device, and codeweight/code giving the relative weight of that device, in the range [100, 1000]. After kernel 2.6.39, the value could be in the -range [10, 1000].span class=sinceSince 0.9.8/span/dd +range [10, 1000].span class=sinceSince 0.9.8/span. +span class=sinceSince 1.2.2/span each codedevice/code +element can replace the mandatory codepath/code sub-element +by a codenode/code one. codenode/code has two mandatory +attributes codemajor/code and codeminor/code./dd /dl diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 28e24f9..65192df 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -905,6 +905,7 @@ virBlkioDeviceArrayClear(virBlkioDevicePtr devices, * * device * path/fully/qualified/device/path/path + * node major='8' minor='0/ * weightweight/weight * read_bytes_secbps/read_bytes_sec * write_bytes_secbps/write_bytes_sec @@ -920,12 +921,38 @@ virDomainBlkioDeviceParseXML(xmlNodePtr root, { char *c = NULL; xmlNodePtr node; +char *major = NULL; +char *minor = NULL; +bool hasNumbers = false; node = root-children; while (node) { if (node-type == XML_ELEMENT_NODE) { if (xmlStrEqual(node-name, BAD_CAST path) !dev-path) { dev-path = (char *)xmlNodeGetContent(node); +} else if (xmlStrEqual(node-name, BAD_CAST node) +!hasNumbers){ +if (!(major = virXMLPropString(node, major)) || +(!(minor = virXMLPropString(node, minor { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(node missing major or minor attribute)); +goto error; +} +if (virStrToLong_ui(major, NULL, 10, dev-major) 0) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(could not parse major %s), + major); +goto error; +} +if (virStrToLong_ui(major, NULL, 10, dev-minor) 0) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _(could not parse minor %s), + minor); +goto error; +} +hasNumbers = true; +VIR_FREE(major); +VIR_FREE(minor); } else if (xmlStrEqual(node-name, BAD_CAST weight)) { c = (char *)xmlNodeGetContent(node); if (virStrToLong_ui(c, NULL, 10, dev-weight) 0) { @@ -975,9 +1002,13 @@ virDomainBlkioDeviceParseXML(xmlNodePtr root, } node = node-next; } -if (!dev-path) { +if (!dev-path !hasNumbers) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, - _(missing per-device path)); + _(missing per-device path or major/minor)); +return -1; +} else if (dev-path hasNumbers) { +virReportError(VIR_ERR_CONFIG_UNSUPPORTED, %s, + _(cannot have both per-device path and major/minor)); return -1; } @@ -985,6 +1016,8 @@ virDomainBlkioDeviceParseXML(xmlNodePtr root, error: VIR_FREE(c); +VIR_FREE(major); +VIR_FREE(minor); VIR_FREE(dev-path); return -1; } @@ -16855,8 +16888,12 @@ virDomainDefFormatInternal(virDomainDefPtr def, !dev-rbps !dev-wbps) continue; virBufferAddLit(buf, device\n); -
[libvirt] [PATCH v3 14/21] LXC from native: add lxc.cgroup.blkio.* mapping
--- src/lxc/lxc_native.c | 63 ++ tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config | 7 +++ tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml| 35 tests/lxcconf2xmltest.c| 1 + 4 files changed, 106 insertions(+) create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index ee8fa75..15c03f2 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -699,6 +699,65 @@ lxcSetCpusetTune(virDomainDefPtr def, virConfPtr properties) return 0; } +static int +lxcBlkioDeviceWalkCallback(const char *name, virConfValuePtr value, void *data) +{ +char **parts = NULL; +virBlkioDevicePtr device = NULL; +virDomainDefPtr def = data; + +if (STRNEQ(name, lxc.cgroup.blkio.device_weight) || !value-str) +return 0; + +if ((!(parts = lxcStringSplit(value-str)) (!parts[0] || !parts[1]))) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(invalid blkio.device_weight value: '%s'), + value-str); +goto error; +} + +if (VIR_EXPAND_N(def-blkio.devices, def-blkio.ndevices, 1) 0) +goto error; +device = def-blkio.devices[def-blkio.ndevices - 1]; + +if (virAsprintf(device-path, /dev/block/%s, parts[0]) 0) +goto error; + +if (virStrToLong_ui(parts[1], NULL, 10, device-weight) 0) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(failed to parse integer: '%s'), parts[1]); +goto error; +} + +virStringFreeList(parts); + +return 0; + +error: +if (parts) +virStringFreeList(parts); +return -1; +} + +static int +lxcSetBlkioTune(virDomainDefPtr def, virConfPtr properties) +{ +virConfValuePtr value; + +if ((value = virConfGetValue(properties, lxc.cgroup.blkio.weight)) +value-str virStrToLong_ui(value-str, NULL, 10, + def-blkio.weight) 0) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(failed to parse integer: '%s'), value-str); +return -1; +} + +if (virConfWalk(properties, lxcBlkioDeviceWalkCallback, def) 0) +return -1; + +return 0; +} + virDomainDefPtr lxcParseConfigString(const char *config) { @@ -783,6 +842,10 @@ lxcParseConfigString(const char *config) if (lxcSetCpusetTune(vmdef, properties) 0) goto error; +/* lxc.cgroup.blkio.* */ +if (lxcSetBlkioTune(vmdef, properties) 0) +goto error; + goto cleanup; error: diff --git a/tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config b/tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config new file mode 100644 index 000..8083c71 --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config @@ -0,0 +1,7 @@ +lxc.rootfs = /var/lib/lxc/migrate_test/rootfs +lxc.utsname = migrate_test +lxc.autodev=1 + +lxc.cgroup.blkio.weight = 500 +lxc.cgroup.blkio.device_weight = 8:16 1000 +lxc.cgroup.blkio.device_weight = 8:0300 diff --git a/tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml b/tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml new file mode 100644 index 000..d2408f4 --- /dev/null +++ b/tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml @@ -0,0 +1,35 @@ +domain type='lxc' + namemigrate_test/name + uuidc7a5fdbd-edaf-9455-926a-d65c16db1809/uuid + memory unit='KiB'65536/memory + currentMemory unit='KiB'0/currentMemory + blkiotune +weight500/weight +device + path/dev/block/8:16/path + weight1000/weight +/device +device + path/dev/block/8:0/path + weight300/weight +/device + /blkiotune + vcpu placement='static' current='0'1/vcpu + os +typeexe/type +init/sbin/init/init + /os + features +privnet/ + /features + clock offset='utc'/ + on_poweroffdestroy/on_poweroff + on_rebootrestart/on_reboot + on_crashdestroy/on_crash + devices +filesystem type='mount' accessmode='passthrough' + source dir='/var/lib/lxc/migrate_test/rootfs'/ + target dir='/'/ +/filesystem + /devices +/domain diff --git a/tests/lxcconf2xmltest.c b/tests/lxcconf2xmltest.c index 6bee5c5..77baf20 100644 --- a/tests/lxcconf2xmltest.c +++ b/tests/lxcconf2xmltest.c @@ -112,6 +112,7 @@ mymain(void) DO_TEST(memtune, false); DO_TEST(cputune, false); DO_TEST(cpusettune, false); +DO_TEST(blkiotune, false); return ret; } -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH v3 19/21] LXC from native: convert blkio throttle config
--- src/lxc/lxc_native.c | 68 ++ tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config | 4 ++ tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml| 4 ++ 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index 8d8c50a..675883c 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -727,28 +727,73 @@ lxcBlkioDeviceWalkCallback(const char *name, virConfValuePtr value, void *data) char **parts = NULL; virBlkioDevicePtr device = NULL; virDomainDefPtr def = data; +size_t i = 0; +char *path = NULL; -if (STRNEQ(name, lxc.cgroup.blkio.device_weight) || !value-str) +if (!STRPREFIX(name, lxc.cgroup.blkio.) || +STREQ(name, lxc.cgroup.blkio.weight)|| !value-str) return 0; if ((!(parts = lxcStringSplit(value-str)) (!parts[0] || !parts[1]))) { virReportError(VIR_ERR_INTERNAL_ERROR, - _(invalid blkio.device_weight value: '%s'), - value-str); + _(invalid %s value: '%s'), + name, value-str); goto error; } -if (VIR_EXPAND_N(def-blkio.devices, def-blkio.ndevices, 1) 0) +if (virAsprintf(path, /dev/block/%s, parts[0]) 0) goto error; -device = def-blkio.devices[def-blkio.ndevices - 1]; -if (virAsprintf(device-path, /dev/block/%s, parts[0]) 0) -goto error; +/* Do we already have a device definition for this path? + * Get that device or create a new one */ +for (i = 0; !device i def-blkio.ndevices; i++) { +if (STREQ(def-blkio.devices[i].path, path)) +device = def-blkio.devices[i]; +} +if (!device) { +if (VIR_EXPAND_N(def-blkio.devices, def-blkio.ndevices, 1) 0) +goto error; +device = def-blkio.devices[def-blkio.ndevices - 1]; +device-path = path; +} -if (virStrToLong_ui(parts[1], NULL, 10, device-weight) 0) { -virReportError(VIR_ERR_INTERNAL_ERROR, - _(failed to parse integer: '%s'), parts[1]); -goto error; +/* Set the value */ +if (STREQ(name, lxc.cgroup.blkio.device_weight)) { +if (virStrToLong_ui(parts[1], NULL, 10, device-weight) 0) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(failed to parse device weight: '%s'), parts[1]); +goto error; +} +} else if (STREQ(name, lxc.cgroup.blkio.throttle.read_bps_device)) { +if (virStrToLong_ull(parts[1], NULL, 10, device-rbps) 0) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(failed to parse read_bps_device: '%s'), + parts[1]); +goto error; +} +} else if (STREQ(name, lxc.cgroup.blkio.throttle.write_bps_device)) { +if (virStrToLong_ull(parts[1], NULL, 10, device-wbps) 0) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(failed to parse write_bps_device: '%s'), + parts[1]); +goto error; +} +} else if (STREQ(name, lxc.cgroup.blkio.throttle.read_iops_device)) { +if (virStrToLong_ui(parts[1], NULL, 10, device-riops) 0) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(failed to parse read_iops_device: '%s'), + parts[1]); +goto error; +} +} else if (STREQ(name, lxc.cgroup.blkio.throttle.write_iops_device)) { +if (virStrToLong_ui(parts[1], NULL, 10, device-wiops) 0) { +virReportError(VIR_ERR_INTERNAL_ERROR, + _(failed to parse write_iops_device: '%s'), + parts[1]); +goto error; +} +} else { +VIR_WARN(Unhandled blkio tune config: %s, name); } virStringFreeList(parts); @@ -758,6 +803,7 @@ lxcBlkioDeviceWalkCallback(const char *name, virConfValuePtr value, void *data) error: if (parts) virStringFreeList(parts); +VIR_FREE(path); return -1; } diff --git a/tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config b/tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config index 8083c71..b19d9a5 100644 --- a/tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config +++ b/tests/lxcconf2xmldata/lxcconf2xml-blkiotune.config @@ -5,3 +5,7 @@ lxc.autodev=1 lxc.cgroup.blkio.weight = 500 lxc.cgroup.blkio.device_weight = 8:16 1000 lxc.cgroup.blkio.device_weight = 8:0300 +lxc.cgroup.blkio.throttle.read_bps_device = 8:16 1234 +lxc.cgroup.blkio.throttle.write_bps_device = 8:16 5678 +lxc.cgroup.blkio.throttle.read_iops_device = 8:16 4321 +lxc.cgroup.blkio.throttle.write_iops_device = 8:16 8765 diff --git a/tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml b/tests/lxcconf2xmldata/lxcconf2xml-blkiotune.xml index d2408f4..628798d 100644 ---
[libvirt] [PATCH v3 09/21] LXC from native: convert macvlan network configuration
--- src/lxc/lxc_native.c | 47 +- .../lxcconf2xml-macvlannetwork.config | 13 ++ .../lxcconf2xmldata/lxcconf2xml-macvlannetwork.xml | 26 tests/lxcconf2xmltest.c| 1 + 4 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-macvlannetwork.config create mode 100644 tests/lxcconf2xmldata/lxcconf2xml-macvlannetwork.xml diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c index 96523c4..b413e42 100644 --- a/src/lxc/lxc_native.c +++ b/src/lxc/lxc_native.c @@ -329,9 +329,11 @@ static virDomainNetDefPtr lxcCreateNetDef(const char *type, const char *link, const char *mac, -const char *flag) +const char *flag, +const char *macvlanmode) { virDomainNetDefPtr net = NULL; +virMacAddr macAddr; if (VIR_ALLOC(net) 0) goto error; @@ -343,9 +345,11 @@ lxcCreateNetDef(const char *type, net-linkstate = VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN; } -if (STREQ(type, veth)) { -virMacAddr macAddr; +if (mac virMacAddrParse(mac, macAddr) == 0) +net-mac = macAddr; + +if (STREQ(type, veth)) { if (!link) goto error; @@ -354,9 +358,20 @@ lxcCreateNetDef(const char *type, if (VIR_STRDUP(net-data.bridge.brname, link) 0) goto error; -if (mac virMacAddrParse(mac, macAddr) == 0) -net-mac = macAddr; +} else if (STREQ(type, macvlan)) { +net-type = VIR_DOMAIN_NET_TYPE_DIRECT; +if (!link || VIR_STRDUP(net-data.direct.linkdev, link) 0) +goto error; + +if (!macvlanmode || STREQ(macvlanmode, private)) +net-data.direct.mode = VIR_NETDEV_MACVLAN_MODE_PRIVATE; +else if (STREQ(macvlanmode, vepa)) +net-data.direct.mode = VIR_NETDEV_MACVLAN_MODE_VEPA; +else if (STREQ(macvlanmode, bridge)) +net-data.direct.mode = VIR_NETDEV_MACVLAN_MODE_BRIDGE; +else +VIR_WARN(Unknown macvlan type: %s, macvlanmode); } return net; @@ -391,7 +406,8 @@ lxcAddNetworkDefinition(virDomainDefPtr def, const char *type, const char *link, const char *mac, -const char *flag) +const char *flag, +const char *macvlanmode) { virDomainNetDefPtr net = NULL; virDomainHostdevDefPtr hostdev = NULL; @@ -411,7 +427,7 @@ lxcAddNetworkDefinition(virDomainDefPtr def, goto error; def-hostdevs[def-nhostdevs - 1] = hostdev; } else { -if (!(net = lxcCreateNetDef(type, link, mac, flag))) +if (!(net = lxcCreateNetDef(type, link, mac, flag, macvlanmode))) goto error; if (VIR_EXPAND_N(def-nets, def-nnets, 1) 0) @@ -433,6 +449,7 @@ typedef struct { char *link; char *mac; char *flag; +char *macvlanmode; bool privnet; size_t networks; } lxcNetworkParseData; @@ -447,7 +464,9 @@ lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) /* Store the previous NIC */ status = lxcAddNetworkDefinition(parseData-def, parseData-type, parseData-link, parseData-mac, - parseData-flag); + parseData-flag, + parseData-macvlanmode); + if (status 0) return -1; else if (status 0) @@ -460,6 +479,7 @@ lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) parseData-link = NULL; parseData-mac = NULL; parseData-flag = NULL; +parseData-macvlanmode = NULL; /* Keep the new value */ parseData-type = value-str; @@ -470,6 +490,12 @@ lxcNetworkWalkCallback(const char *name, virConfValuePtr value, void *data) parseData-mac = value-str; else if (STREQ(name, lxc.network.flags)) parseData-flag = value-str; +else if (STREQ(name, lxc.network.macvlan.mode)) +parseData-macvlanmode = value-str; +else if (STRPREFIX(name, lxc.network)) +VIR_WARN(Unhandled network property: %s = %s, + name, + value-str); return 0; } @@ -478,13 +504,14 @@ static int lxcConvertNetworkSettings(virDomainDefPtr def, virConfPtr properties) { int status; -lxcNetworkParseData data = {def, NULL, NULL, NULL, NULL, true, 0}; +lxcNetworkParseData data = {def, NULL, NULL, NULL, NULL, NULL, true, 0}; virConfWalk(properties, lxcNetworkWalkCallback, data); /* Add the last network definition found */ status = lxcAddNetworkDefinition(def, data.type, data.link, -
[libvirt] [PATCH v3 18/21] LXC: added some doc on domxml-from-native with mention of limitations
--- docs/drvlxc.html.in | 34 +- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/docs/drvlxc.html.in b/docs/drvlxc.html.in index 0f3efb0..fc4bc20 100644 --- a/docs/drvlxc.html.in +++ b/docs/drvlxc.html.in @@ -555,7 +555,7 @@ and LXC. For further details about usage of virsh consult its manual page. /p -h3a name=usageSaveDefining (saving) container configuration/a/h3 +h3a name=usageSaveDefining (saving) container configuration/a/h3 p The codevirsh define/code command takes an XML configuration @@ -702,5 +702,37 @@ host # virt-top -c lxc:/// /pre +h3a name=usageConvertConverting LXC container configuration/a/h3 + +p +The codevirsh domxml-from-native/code command can be used to convert +most of the LXC container configuration into a domain XML fragment +/p + +pre +# virsh -c lxc:/// domxml-from-native lxc-tools /var/lib/lxc/myguest/config +/pre + +p +This conversion has some limitations due to the fact that the +domxml-from-native command output has to be independent of the host. Here +are a few things to take care of before converting: +/p + +ul +li +Replace the fstab file referenced by ttlxc.mount/tt by the corresponding +lxc.mount.entry lines. +/li +li +Replace all relative sizes of tmpfs mount entries to absolute sizes. Also +make sure that tmpfs entries all have a size option (default is 50%). +/li +li +Define ttlxc.cgroup.memory.limit_in_bytes/tt to properly limit the memory +available to the container. The conversion will use 64MiB as the default. +/li +/ul + /body /html -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/2] Allow localtime clock basis
With a nice test enhancement ... Michal Privoznik (2): qemuBuildClockArgStr: Allow localtime clock basis qemuxml2argvtest: Test localtime clock basis src/qemu/qemu_command.c| 18 +++ tests/Makefile.am | 7 ...muxml2argv-clock-localtime-basis-localtime.args | 5 +++ ...emuxml2argv-clock-localtime-basis-localtime.xml | 28 tests/qemuxml2argvmock.c | 37 ++ tests/qemuxml2argvtest.c | 3 +- 6 files changed, 90 insertions(+), 8 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-localtime-basis-localtime.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-localtime-basis-localtime.xml create mode 100644 tests/qemuxml2argvmock.c -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] conf: add localtime support in guest clock with variable attibute
On 24.12.2013 07:31, Jincheng Miao wrote: commit b8bf79a, which add clock=variable, forgets to check localtime basis in qemuBuildClockArgStr(). So that localtime basis could not be used, like this bug: https://bugzilla.redhat.com/show_bug.cgi?id=1046192 --- src/qemu/qemu_command.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d723dc8..749ad54 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6490,15 +6490,21 @@ qemuBuildClockArgStr(virDomainClockDefPtr def) time_t now = time(NULL); struct tm nowbits; -if (def-data.variable.basis != VIR_DOMAIN_CLOCK_BASIS_UTC) { +if (def-data.variable.basis == VIR_DOMAIN_CLOCK_BASIS_UTC) { +now += def-data.variable.adjustment; +gmtime_r(now, nowbits); +} +else if (def-data.variable.basis == VIR_DOMAIN_CLOCK_BASIS_LOCALTIME) { +now += def-data.variable.adjustment; +localtime_r(now, nowbits); +} +else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _(unsupported clock basis '%s'), virDomainClockBasisTypeToString(def-data.variable.basis)); goto error; } -now += def-data.variable.adjustment; -gmtime_r(now, nowbits); - + /* Store the guest's basedate */ def-data.variable.basedate = now; I've changed the patch to use switch instead of if-else and introduced a test: https://www.redhat.com/archives/libvir-list/2014-February/msg00250.html Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/2] qemuxml2argvtest: Test localtime clock basis
When trying to introduce a test for previous patch, I've noticed that the command line is constructed using current time. This won't work in our test suite (unless you guys wants to set a specific time prior to each test run :) ). Therefore we need to mock calls to time(2) to return the same value every time it's called. Signed-off-by: Michal Privoznik mpriv...@redhat.com --- tests/Makefile.am | 7 ...muxml2argv-clock-localtime-basis-localtime.args | 5 +++ ...emuxml2argv-clock-localtime-basis-localtime.xml | 28 tests/qemuxml2argvmock.c | 37 ++ tests/qemuxml2argvtest.c | 3 +- 5 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-localtime-basis-localtime.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-localtime-basis-localtime.xml create mode 100644 tests/qemuxml2argvmock.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 30cdd1d..eb96f38 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -325,6 +325,7 @@ test_libraries = libshunload.la \ virnetserverclientmock.la \ vircgroupmock.la \ virpcimock.la \ + qemuxml2argvmock.la \ $(NULL) if WITH_QEMU test_libraries += libqemumonitortestutils.la @@ -441,6 +442,12 @@ qemuxml2argvtest_SOURCES = \ testutils.c testutils.h qemuxml2argvtest_LDADD = $(qemu_LDADDS) $(LIBXML_LIBS) +qemuxml2argvmock_la_SOURCES = \ + qemuxml2argvmock.c +qemuxml2argvmock_la_CFLAGS = $(AM_CFLAGS) +qemuxml2argvmock_la_LDFLAGS = -module -avoid-version \ + -rpath /evil/libtool/hack/to/force/shared/lib/creation + qemuxml2xmltest_SOURCES = \ qemuxml2xmltest.c testutilsqemu.c testutilsqemu.h \ testutils.c testutils.h diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime-basis-localtime.args b/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime-basis-localtime.args new file mode 100644 index 000..24fe89c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime-basis-localtime.args @@ -0,0 +1,5 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic \ +-monitor unix:/tmp/test-monitor,server,nowait -rtc base=2009-02-14T01:31:30 \ +-no-acpi -boot c -usb -hda /dev/HostVG/QEMUGuest1 -net none -serial none \ +-parallel none diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime-basis-localtime.xml b/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime-basis-localtime.xml new file mode 100644 index 000..91d57b9 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime-basis-localtime.xml @@ -0,0 +1,28 @@ +domain type='qemu' + nameQEMUGuest1/name + uuid1c15a1f6-f4f0-4d3c-9002-667ddb458736/uuid + memory unit='KiB'219100/memory + currentMemory unit='KiB'219100/currentMemory + vcpu placement='static'1/vcpu + os +type arch='i686' machine='pc'hvm/type +boot dev='hd'/ + /os + clock offset='variable' adjustment='3600' basis='localtime'/ + on_poweroffdestroy/on_poweroff + on_rebootrestart/on_reboot + on_crashdestroy/on_crash + devices +emulator/usr/bin/qemu/emulator +disk type='block' device='disk' + driver name='qemu' type='raw'/ + source dev='/dev/HostVG/QEMUGuest1'/ + target dev='hda' bus='ide'/ + address type='drive' controller='0' bus='0' target='0' unit='0'/ +/disk +controller type='usb' index='0'/ +controller type='ide' index='0'/ +controller type='pci' index='0' model='pci-root'/ +memballoon model='virtio'/ + /devices +/domain diff --git a/tests/qemuxml2argvmock.c b/tests/qemuxml2argvmock.c new file mode 100644 index 000..ed9fb13 --- /dev/null +++ b/tests/qemuxml2argvmock.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * http://www.gnu.org/licenses/. + * + * Author: Michal Privoznik mpriv...@redhat.com + */ + +#include config.h + +#ifdef __linux__ +# include internal.h +# include time.h + +time_t time(time_t *t) +{ +const time_t ret = 1234567890; +if (t) +*t = ret; +return ret; +} + +#else +/* Nothing to override on non-__linux__ platforms */ +#endif diff --git
[libvirt] [PATCH 1/2] qemuBuildClockArgStr: Allow localtime clock basis
https://bugzilla.redhat.com/show_bug.cgi?id=1046192 Commit b8bf79a, which adds clock='variable', forgets to check localtime basis in qemuBuildClockArgStr(). So that localtime basis could not be used. Reported-by: Jincheng Miao jm...@redhat.com Signed-off-by: Michal Privoznik mpriv...@redhat.com --- src/qemu/qemu_command.c | 18 +++--- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 5b94de1..6cc32f9 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6491,14 +6491,18 @@ qemuBuildClockArgStr(virDomainClockDefPtr def) time_t now = time(NULL); struct tm nowbits; -if (def-data.variable.basis != VIR_DOMAIN_CLOCK_BASIS_UTC) { -virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _(unsupported clock basis '%s'), - virDomainClockBasisTypeToString(def-data.variable.basis)); -goto error; +switch ((enum virDomainClockBasis) def-data.variable.basis) { +case VIR_DOMAIN_CLOCK_BASIS_UTC: +now += def-data.variable.adjustment; +gmtime_r(now, nowbits); +break; +case VIR_DOMAIN_CLOCK_BASIS_LOCALTIME: +now += def-data.variable.adjustment; +localtime_r(now, nowbits); +break; +case VIR_DOMAIN_CLOCK_BASIS_LAST: +break; } -now += def-data.variable.adjustment; -gmtime_r(now, nowbits); /* Store the guest's basedate */ def-data.variable.basedate = now; -- 1.8.5.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: introduce spiceport serial backend
On Mon, Feb 03, 2014 at 05:41:00PM +0100, Martin Kletzander wrote: signed-off-by: martin kletzander mklet...@redhat.com --- notes: this applies on top of qemu: minor cleanups: https://www.redhat.com/archives/libvir-list/2014-january/msg01584.html docs/formatdomain.html.in | 22 + docs/schemas/domaincommon.rng | 4 + src/conf/domain_audit.c| 3 +- src/conf/domain_conf.c | 40 - src/conf/domain_conf.h | 6 +- src/qemu/qemu_capabilities.c | 8 ++ src/qemu/qemu_capabilities.h | 3 +- src/qemu/qemu_command.c| 96 +- src/qemu/qemu_monitor_json.c | 3 +- tests/qemucapabilitiesdata/caps_1.5.3-1.caps | 1 + tests/qemucapabilitiesdata/caps_1.6.0-1.caps | 1 + tests/qemucapabilitiesdata/caps_1.6.50-1.caps | 1 + .../qemuxml2argv-serial-spiceport-nospice.args | 6 ++ .../qemuxml2argv-serial-spiceport-nospice.xml | 40 + .../qemuxml2argv-serial-spiceport.args | 13 +++ .../qemuxml2argv-serial-spiceport.xml | 43 ++ tests/qemuxml2argvtest.c | 7 ++ tests/qemuxml2xmltest.c| 2 + 18 files changed, 255 insertions(+), 44 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport-nospice.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport-nospice.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport.xml diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fa1ecb5..8cdd0e9 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -437,7 +437,8 @@ VIR_ENUM_IMPL(virDomainChr, VIR_DOMAIN_CHR_TYPE_LAST, udp, tcp, unix, - spicevmc) + spicevmc, + spiceport) VIR_ENUM_IMPL(virDomainChrTcpProtocol, VIR_DOMAIN_CHR_TCP_PROTOCOL_LAST, raw, @@ -1583,6 +1584,12 @@ virDomainChrSourceDefIsEqual(const virDomainChrSourceDef *src, STREQ_NULLABLE(src-data.nix.path, tgt-data.nix.path); break; +case VIR_DOMAIN_CHR_TYPE_SPICEPORT: +return STREQ_NULLABLE(src-data.spiceport.channel, + tgt-data.spiceport.channel); +return true; this 'return true' is not needed +break; + case VIR_DOMAIN_CHR_TYPE_NULL: case VIR_DOMAIN_CHR_TYPE_VC: case VIR_DOMAIN_CHR_TYPE_STDIO: @@ -7090,6 +7097,9 @@ error: return ret; } +#define SERIAL_CHANNEL_NAME_CHARS \ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-. + /* Parse the source half of the XML definition for a character device, * where node is the first element of node-children of the parent * element. def-type must already be valid. Return -1 on failure, @@ -7110,6 +7120,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, char *path = NULL; char *mode = NULL; char *protocol = NULL; +char *channel = NULL; int remaining = 0; while (cur != NULL) { @@ -7154,6 +7165,11 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, VIR_FREE(mode); break; +case VIR_DOMAIN_CHR_TYPE_SPICEPORT: +if (!channel) +channel = virXMLPropString(cur, channel); +break; + case VIR_DOMAIN_CHR_TYPE_LAST: case VIR_DOMAIN_CHR_TYPE_NULL: case VIR_DOMAIN_CHR_TYPE_VC: @@ -7293,6 +7309,21 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, def-data.nix.path = path; path = NULL; break; + +case VIR_DOMAIN_CHR_TYPE_SPICEPORT: +if (!channel) { +virReportError(VIR_ERR_XML_ERROR, %s, + _(Missing source channel attribute for char device)); +goto error; +} Code before that uses VIR_ERR_INTERNAL_ERROR for missing attributes, but VIR_ERR_XML_ERROR seems indeed better. +if (strcspn(channel, SERIAL_CHANNEL_NAME_CHARS)) { If I understood the man page correctly, strcspn will return the number of characters at the beginning of channel which are not in SERIAL_CHANNEL_NAME_CHARS. It seems this won't catch org.éâò. The net code does: if (strspn(channel, SERIAL_CHANNEL_NAME_CHARS) strlen(channel)) { which seems ok. +virReportError(VIR_ERR_XML_ERROR, %s, + _(Invalid character in source channel for char device)); The network code uses VIR_ERR_INVALID_ARG here. +
Re: [libvirt] [PATCH v2] qemu: Fix crash in virDomainMemoryStats with old qemu
On 02/05/2014 08:19 AM, Jiri Denemark wrote: If virDomainMemoryStats was run on a domain with virtio balloon driver running on an old qemu which supports QMP but does not support qom-list QMP command, libvirtd would crash. The reason is we did not check if qemuMonitorJSONGetObjectListPaths failed and moreover we even stored its result in an unsigned integer type. Signed-off-by: Jiri Denemark jdene...@redhat.com --- Notes: version 2: - use signed type for i and j to avoid comparison between signed and unsigned types; gcc-- for not complaining about it src/qemu/qemu_monitor.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index a968901..a2769db 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1019,7 +1019,7 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, virDomainObjPtr vm, const char *curpath) { -size_t i, j, npaths = 0, nprops = 0; +ssize_t i, j, npaths = 0, nprops = 0; int ret = 0; char *nextpath = NULL; qemuMonitorJSONListPathPtr *paths = NULL; @@ -1045,6 +1045,8 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, VIR_DEBUG(Searching for Balloon Object Path starting at %s, curpath); npaths = qemuMonitorJSONGetObjectListPaths(mon, curpath, paths); +if (npaths 0) +return -1; Returning 0 from this function isn't necessarily bad - it means not found still looking... It's a recursive nightmare. As for the non recursive callers... For the qemuMonitorGetMemoryStats() path that's OK - it's allowed to fallback to trying the older former method of calling query-balloon in qemuMonitorJSONGetMemoryStats(). Returning -1 if qom-list isn't found means we won't go the fallback route. For the qemuMonitorSetMemoryStatsPeriod() returning 0 means don't even try to set. for (i = 0; i npaths ret == 0; i++) { @@ -1061,6 +1063,11 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, * then this version of qemu/kvm does not support the feature. */ nprops = qemuMonitorJSONGetObjectListPaths(mon, nextpath, bprops); +if (nprops 0) { +ret = -1; +goto cleanup; +} + Failure here wouldn't be because 'qom-list' doesn't exist, rather there was some other property error or malformed return object. Since not finding guest-stats-polling-interval property for a linkvirtio-balloon-pci object. After the for loop that error is reported. So if nprops = 0, then we fall through to that. The other errors are still logged (right?), but we report the error below. for (j = 0; j nprops; j++) { if (STREQ(bprops[j]-name, guest-stats-polling-interval)) { VIR_DEBUG(Found Balloon Object Path %s, nextpath); FWIW: To Dan's comment - not sure how simple it would be to add a test for this condition. I'm still thinking the change in types is all that is necessary as there is cause for this function to return 0 if qom-list doesn't exist. John -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] event: move event filtering to daemon (regression fix)
On 02/05/2014 06:56 AM, Daniel P. Berrange wrote: On Tue, Jan 28, 2014 at 03:48:19PM -0700, Eric Blake wrote: Commit f9f56340 for CVE-2014-0028 almost had the right idea - we need to check the ACL rules to filter which events to send. But it overlooked one thing: the event dispatch queue is running in the main loop thread, and therefore does not normally have a current virIdentityPtr. But filter checks can be based on current identity, so when libvirtd.conf contains access_drivers=[polkit], we ended up rejecting access for EVERY event due to failure to look up the current identity, even if it should have been allowed. ACK Thanks; I've updated the commit message to mention https://bugzilla.redhat.com/show_bug.cgi?id=1058839, and will have the backport pushed to all affected maint branches shortly. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] qemu: introduce spiceport serial backend
On Wed, Feb 05, 2014 at 03:38:49PM +0100, Christophe Fergeau wrote: On Mon, Feb 03, 2014 at 05:41:00PM +0100, Martin Kletzander wrote: signed-off-by: martin kletzander mklet...@redhat.com --- notes: this applies on top of qemu: minor cleanups: https://www.redhat.com/archives/libvir-list/2014-january/msg01584.html docs/formatdomain.html.in | 22 + docs/schemas/domaincommon.rng | 4 + src/conf/domain_audit.c| 3 +- src/conf/domain_conf.c | 40 - src/conf/domain_conf.h | 6 +- src/qemu/qemu_capabilities.c | 8 ++ src/qemu/qemu_capabilities.h | 3 +- src/qemu/qemu_command.c| 96 +- src/qemu/qemu_monitor_json.c | 3 +- tests/qemucapabilitiesdata/caps_1.5.3-1.caps | 1 + tests/qemucapabilitiesdata/caps_1.6.0-1.caps | 1 + tests/qemucapabilitiesdata/caps_1.6.50-1.caps | 1 + .../qemuxml2argv-serial-spiceport-nospice.args | 6 ++ .../qemuxml2argv-serial-spiceport-nospice.xml | 40 + .../qemuxml2argv-serial-spiceport.args | 13 +++ .../qemuxml2argv-serial-spiceport.xml | 43 ++ tests/qemuxml2argvtest.c | 7 ++ tests/qemuxml2xmltest.c| 2 + 18 files changed, 255 insertions(+), 44 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport-nospice.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport-nospice.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-serial-spiceport.xml diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fa1ecb5..8cdd0e9 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -437,7 +437,8 @@ VIR_ENUM_IMPL(virDomainChr, VIR_DOMAIN_CHR_TYPE_LAST, udp, tcp, unix, - spicevmc) + spicevmc, + spiceport) VIR_ENUM_IMPL(virDomainChrTcpProtocol, VIR_DOMAIN_CHR_TCP_PROTOCOL_LAST, raw, @@ -1583,6 +1584,12 @@ virDomainChrSourceDefIsEqual(const virDomainChrSourceDef *src, STREQ_NULLABLE(src-data.nix.path, tgt-data.nix.path); break; +case VIR_DOMAIN_CHR_TYPE_SPICEPORT: +return STREQ_NULLABLE(src-data.spiceport.channel, + tgt-data.spiceport.channel); +return true; this 'return true' is not needed I was probably cleaning this out so many times I over-cleaned it to double returns. +break; + case VIR_DOMAIN_CHR_TYPE_NULL: case VIR_DOMAIN_CHR_TYPE_VC: case VIR_DOMAIN_CHR_TYPE_STDIO: @@ -7090,6 +7097,9 @@ error: return ret; } +#define SERIAL_CHANNEL_NAME_CHARS \ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-. + /* Parse the source half of the XML definition for a character device, * where node is the first element of node-children of the parent * element. def-type must already be valid. Return -1 on failure, @@ -7110,6 +7120,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, char *path = NULL; char *mode = NULL; char *protocol = NULL; +char *channel = NULL; int remaining = 0; while (cur != NULL) { @@ -7154,6 +7165,11 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, VIR_FREE(mode); break; +case VIR_DOMAIN_CHR_TYPE_SPICEPORT: +if (!channel) +channel = virXMLPropString(cur, channel); +break; + case VIR_DOMAIN_CHR_TYPE_LAST: case VIR_DOMAIN_CHR_TYPE_NULL: case VIR_DOMAIN_CHR_TYPE_VC: @@ -7293,6 +7309,21 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, def-data.nix.path = path; path = NULL; break; + +case VIR_DOMAIN_CHR_TYPE_SPICEPORT: +if (!channel) { +virReportError(VIR_ERR_XML_ERROR, %s, + _(Missing source channel attribute for char device)); +goto error; +} Code before that uses VIR_ERR_INTERNAL_ERROR for missing attributes, but VIR_ERR_XML_ERROR seems indeed better. Yes, at least from what I remembered the previous one should be XML_ERROR as well, but I didn't want to mix the cleanup with introducing spiceport. +if (strcspn(channel, SERIAL_CHANNEL_NAME_CHARS)) { If I understood the man page correctly, strcspn will return the number of characters at
Re: [libvirt] [PATCH v2] qemu: Fix crash in virDomainMemoryStats with old qemu
On 2014-02-05 14:19, Jiri Denemark wrote: If virDomainMemoryStats was run on a domain with virtio balloon driver running on an old qemu which supports QMP but does not support qom-list QMP command, libvirtd would crash. The reason is we did not check if qemuMonitorJSONGetObjectListPaths failed and moreover we even stored its result in an unsigned integer type. Signed-off-by: Jiri Denemark jdene...@redhat.com --- Notes: version 2: - use signed type for i and j to avoid comparison between signed and unsigned types; gcc-- for not complaining about it src/qemu/qemu_monitor.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index a968901..a2769db 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1019,7 +1019,7 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, virDomainObjPtr vm, const char *curpath) { -size_t i, j, npaths = 0, nprops = 0; +ssize_t i, j, npaths = 0, nprops = 0; int ret = 0; char *nextpath = NULL; qemuMonitorJSONListPathPtr *paths = NULL; @@ -1045,6 +1045,8 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, VIR_DEBUG(Searching for Balloon Object Path starting at %s, curpath); npaths = qemuMonitorJSONGetObjectListPaths(mon, curpath, paths); +if (npaths 0) +return -1; for (i = 0; i npaths ret == 0; i++) { @@ -1061,6 +1063,11 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, * then this version of qemu/kvm does not support the feature. */ nprops = qemuMonitorJSONGetObjectListPaths(mon, nextpath, bprops); +if (nprops 0) { +ret = -1; +goto cleanup; +} + for (j = 0; j nprops; j++) { if (STREQ(bprops[j]-name, guest-stats-polling-interval)) { VIR_DEBUG(Found Balloon Object Path %s, nextpath); I tested this patch and so far it seems ok: libvirtd hasn't crashed during 1 hour. I'll leave it running during the night to be sure. I only see this now in the logs: 2014-02-05 14:54:41.280+: 8104: error : qemuMonitorJSONCheckError:354 : internal error: unable to execute QEMU command 'qom-list': The command qom-list has not been found 2014-02-05 14:54:41.306+: 8103: error : qemuMonitorJSONCheckError:354 : internal error: unable to execute QEMU command 'qom-list': The command qom-list has not been found 2014-02-05 14:54:41.333+: 8106: error : qemuMonitorJSONCheckError:354 : internal error: unable to execute QEMU command 'qom-list': The command qom-list has not been found 2014-02-05 14:54:41.358+: 8105: error : qemuMonitorJSONCheckError:354 : internal error: unable to execute QEMU command 'qom-list': The command qom-list has not been found but no crashes because of that. Franky -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Add filesystem support to Qemu's attach_device
On 04.02.2014 10:37, Teto wrote: Hi, The following patch was generated with format patch checked with syntax-check. It is really short and adds a new function virDomainFSInsert which is called when Qemu driver is requested t attach a filesystem device. Matt 0001-This-commit-allows-to-register-filesystem-in-qemu-vi.patch From f8c0612c48c06c61199693743d98c251ba4d887e Mon Sep 17 00:00:00 2001 From: Mattmatta...@gmail.com Date: Mon, 3 Feb 2014 17:42:56 +0100 Subject: [PATCH] This commit allows to register filesystem in qemu via the attach_device function (which would previsouly return an error). For this purpose I've introduced a new function virDomainFSInsert and added the necessary code in the qemu driver. It compares filesystems based on their destination folder. So if 2 filesystems share a same destination, they are considered equal and the Qemu driver would reject a new insertion. --- src/conf/domain_conf.c | 12 src/conf/domain_conf.h | 1 + src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 18 ++ 4 files changed, 32 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 28e24f9..3f4dbfe 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -17933,6 +17933,18 @@ virDiskNameToBusDeviceIndex(virDomainDiskDefPtr disk, return 0; } + +int +virDomainFSInsert(virDomainDefPtr def, virDomainFSDefPtr fs) +{ + +if (VIR_REALLOC_N(def-fss, def-nfss+1) 0) +return -1; + +def-fss[def-nfss++] = fs; +return 0; +} + While this works perfectly, we can save some lines by calling VIR_APPEND_ELEMENT(). virDomainFSDefPtr virDomainGetRootFilesystem(virDomainDefPtr def) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d8f2e49..d749e68 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2555,6 +2555,7 @@ int virDiskNameToBusDeviceIndex(virDomainDiskDefPtr disk, int *devIdx); virDomainFSDefPtr virDomainGetRootFilesystem(virDomainDefPtr def); +int virDomainFSInsert(virDomainDefPtr def, virDomainFSDefPtr fs); int virDomainFSIndexByName(virDomainDefPtr def, const char *name); int virDomainVideoDefaultType(const virDomainDef *def); int virDomainVideoDefaultRAM(const virDomainDef *def, int type); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 1a8d088..e872960 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -221,6 +221,7 @@ virDomainFeatureStateTypeFromString; virDomainFeatureStateTypeToString; virDomainFSDefFree; virDomainFSIndexByName; +virDomainFSInsert; virDomainFSTypeFromString; virDomainFSTypeToString; virDomainFSWrpolicyTypeFromString; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 0128356..f2bac0d 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6606,6 +6606,7 @@ qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps, virDomainHostdevDefPtr hostdev; virDomainLeaseDefPtr lease; virDomainControllerDefPtr controller; +virDomainFSDefPtr fs; switch (dev-type) { case VIR_DOMAIN_DEVICE_DISK: @@ -6687,6 +6688,23 @@ qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps, dev-data.chr = NULL; break; +case VIR_DOMAIN_DEVICE_FS: +{ +fs = dev-data.fs; +if (virDomainFSIndexByName(vmdef, fs-dst) = 0) { +VIR_INFO(Identical FS found); +virReportError(VIR_ERR_OPERATION_INVALID, + %s, _(Target already exists)); +return -1; +} + +if (virDomainFSInsert(vmdef, fs) 0) { +return -1; +} +dev-data.fs = NULL; +} +break; + There is no need to enclose the body in { }. Nor for VIR_INFO. While at this - can you implement the detach counterpart? Again, in config level is fine for now. However, I believe our push policy doesn't allow in patches that are missing real name (first and last one at least). So can you fix that too? Michal -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH] maint: fix grammar in conf file
Noticed a misuse of 'to' while testing my event regression under polkit ACLs, and decided to review the entire conf files for other legibility bugs. * daemon/libvirtd.conf: Use correct grammar. * src/qemu/qemu.conf: Likewise. Signed-off-by: Eric Blake ebl...@redhat.com --- Pushing under the trivial rule. daemon/libvirtd.conf | 24 src/qemu/qemu.conf | 14 +++--- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/daemon/libvirtd.conf b/daemon/libvirtd.conf index 5353927..538acae 100644 --- a/daemon/libvirtd.conf +++ b/daemon/libvirtd.conf @@ -63,7 +63,7 @@ # unique on the immediate broadcast network. # # The default is Virtualization Host HOSTNAME, where HOSTNAME -# is subsituted for the short hostname of the machine (without domain) +# is substituted for the short hostname of the machine (without domain) # #mdns_name = Virtualization Host Joe Demo @@ -83,8 +83,8 @@ # Set the UNIX socket permissions for the R/O socket. This is used # for monitoring VM status only # -# Default allows any user. If setting group ownership may want to -# restrict this to: +# Default allows any user. If setting group ownership, you may want to +# restrict this too. #unix_sock_ro_perms = 0777 # Set the UNIX socket permissions for the R/W socket. This is used @@ -94,7 +94,7 @@ # the default will change to allow everyone (eg, 0777) # # If not using PolicyKit and setting group ownership for access -# control then you may want to relax this to: +# control, then you may want to relax this too. #unix_sock_rw_perms = 0770 # Set the name of the directory in which sockets will be found/created. @@ -113,7 +113,7 @@ # - sasl: use SASL infrastructure. The actual auth scheme is then # controlled from /etc/sasl2/libvirt.conf. For the TCP # socket only GSSAPI DIGEST-MD5 mechanisms will be used. -# For non-TCP or TLS sockets, any scheme is allowed. +# For non-TCP or TLS sockets, any scheme is allowed. # # - polkit: use PolicyKit to authenticate. This is only suitable #for use on the UNIX sockets. The default policy will @@ -216,7 +216,7 @@ #tls_no_verify_certificate = 1 -# A whitelist of allowed x509 Distinguished Names +# A whitelist of allowed x509 Distinguished Names # This list may contain wildcards such as # #C=GB,ST=London,L=London,O=Red Hat,CN=* @@ -274,13 +274,13 @@ # The number of priority workers. If all workers from above -# pool will stuck, some calls marked as high priority +# pool are stuck, some calls marked as high priority # (notably domainDestroy) can be executed in this pool. #prio_workers = 5 # Total global limit on concurrent RPC calls. Should be # at least as large as max_workers. Beyond this, RPC requests -# will be read into memory and queued. This directly impact +# will be read into memory and queued. This directly impacts # memory usage, currently each request requires 256 KB of # memory. So by default up to 5 MB of memory is used # @@ -318,7 +318,7 @@ #3: WARNING #4: ERROR # -# Multiple filter can be defined in a single @filters, they just need to be +# Multiple filters can be defined in a single @filters, they just need to be # separated by spaces. # # e.g. to only get warning or errors from the remote layer and only errors @@ -340,7 +340,7 @@ #3: WARNING #4: ERROR # -# Multiple output can be defined, they just need to be separated by spaces. +# Multiple outputs can be defined, they just need to be separated by spaces. # e.g. to log all warnings and errors to syslog under the libvirtd ident: #log_outputs=3:syslog:libvirtd # @@ -387,7 +387,7 @@ ### # Keepalive protocol: # This allows libvirtd to detect broken client connections or even -# dead client. A keepalive message is sent to a client after +# dead clients. A keepalive message is sent to a client after # keepalive_interval seconds of inactivity to check if the client is # still responding; keepalive_count is a maximum number of keepalive # messages that are allowed to be sent to the client without getting @@ -396,7 +396,7 @@ # keepalive_interval * (keepalive_count + 1) seconds since the last # message received from the client. If keepalive_interval is set to # -1, libvirtd will never send keepalive requests; however clients -# can still send them and the deamon will send responses. When +# can still send them and the daemon will send responses. When # keepalive_count is set to 0, connections will be automatically # closed after keepalive_interval seconds of inactivity without # sending any keepalive messages. diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf index 17f1b10..e436084 100644 --- a/src/qemu/qemu.conf +++ b/src/qemu/qemu.conf @@ -58,7 +58,7 @@ #vnc_tls_x509_verify = 1 -# The default VNC password. Only 8 letters are significant for +# The default VNC password. Only 8 bytes are significant
[libvirt] [PATCH 2/2] qemu: blockjob: Print correct file name in error message
When attempting a blockcommit from the top layer, the base argument passed is NULL. This will be dereferenced when attempting a commit with an empty image chain. Output the real volume path instead: virsh blockcommit --verbose --path vda --domain DOMNAME --wait error: invalid argument: top '/path/somefile' in chain for 'vda' has no backing file instead of: error: invalid argument: top '(null)' in chain for 'vda' has no backing file --- src/qemu/qemu_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 38a48db..8998201 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -15180,7 +15180,7 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base, if (!top_meta || !top_meta-backingStore) { virReportError(VIR_ERR_INVALID_ARG, _(top '%s' in chain for '%s' has no backing file), - top, path); + top_canon, path); goto endjob; } if (!base (flags VIR_DOMAIN_BLOCK_COMMIT_SHALLOW)) { -- 1.8.5.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 3/4] libxl: handle domain shutdown events in a thread
Handling the domain shutdown event within the event handler seems a bit unfair to libxl's event machinery. Domain shutdown could take considerable time. E.g. if the shutdown reason is reboot, the domain must be reaped and then started again. Spawn a shutdown handler thread to do this work, allowing libxl's event machinery to go about its business. Signed-off-by: Jim Fehlig jfeh...@suse.com --- src/libxl/libxl_driver.c | 132 --- 1 file changed, 89 insertions(+), 43 deletions(-) diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index d639011..a1c6c0f 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -352,61 +352,107 @@ libxlVmReap(libxlDriverPrivatePtr driver, # define VIR_LIBXL_EVENT_CONST const #endif +struct libxlShutdownThreadInfo +{ +virDomainObjPtr vm; +libxl_event *event; +}; + + static void -libxlEventHandler(void *data, VIR_LIBXL_EVENT_CONST libxl_event *event) +libxlDomainShutdownThread(void *opaque) { libxlDriverPrivatePtr driver = libxl_driver; -libxlDomainObjPrivatePtr priv = ((virDomainObjPtr)data)-privateData; -virDomainObjPtr vm = NULL; +struct libxlShutdownThreadInfo *shutdown_info = opaque; +virDomainObjPtr vm = shutdown_info-vm; +libxlDomainObjPrivatePtr priv = vm-privateData; +libxl_event *ev = shutdown_info-event; +libxl_ctx *ctx = priv-ctx; virObjectEventPtr dom_event = NULL; -libxl_shutdown_reason xl_reason = event-u.domain_shutdown.shutdown_reason; - -if (event-type == LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) { -virDomainShutoffReason reason; - -/* - * Similar to the xl implementation, ignore SUSPEND. Any actions needed - * after calling libxl_domain_suspend() are handled by it's callers. - */ -if (xl_reason == LIBXL_SHUTDOWN_REASON_SUSPEND) -goto cleanup; +libxl_shutdown_reason xl_reason = ev-u.domain_shutdown.shutdown_reason; +virDomainShutoffReason reason; -vm = virDomainObjListFindByID(driver-domains, event-domid); -if (!vm) -goto cleanup; +virObjectLock(vm); -switch (xl_reason) { -case LIBXL_SHUTDOWN_REASON_POWEROFF: -case LIBXL_SHUTDOWN_REASON_CRASH: -if (xl_reason == LIBXL_SHUTDOWN_REASON_CRASH) { -dom_event = virDomainEventLifecycleNewFromObj(vm, - VIR_DOMAIN_EVENT_STOPPED, - VIR_DOMAIN_EVENT_STOPPED_CRASHED); -reason = VIR_DOMAIN_SHUTOFF_CRASHED; -} else { -reason = VIR_DOMAIN_SHUTOFF_SHUTDOWN; -} -libxlVmReap(driver, vm, reason); -if (!vm-persistent) { -virDomainObjListRemove(driver-domains, vm); -vm = NULL; -} -break; -case LIBXL_SHUTDOWN_REASON_REBOOT: -libxlVmReap(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN); -libxlVmStart(driver, vm, 0, -1); -break; -default: -VIR_INFO(Unhandled shutdown_reason %d, xl_reason); -break; -} +switch (xl_reason) { +case LIBXL_SHUTDOWN_REASON_POWEROFF: +case LIBXL_SHUTDOWN_REASON_CRASH: +if (xl_reason == LIBXL_SHUTDOWN_REASON_CRASH) { +dom_event = virDomainEventLifecycleNewFromObj(vm, + VIR_DOMAIN_EVENT_STOPPED, + VIR_DOMAIN_EVENT_STOPPED_CRASHED); +reason = VIR_DOMAIN_SHUTOFF_CRASHED; +} else { +reason = VIR_DOMAIN_SHUTOFF_SHUTDOWN; +} +libxlVmReap(driver, vm, reason); +if (!vm-persistent) { +virDomainObjListRemove(driver-domains, vm); +vm = NULL; +} +break; +case LIBXL_SHUTDOWN_REASON_REBOOT: +libxlVmReap(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN); +libxlVmStart(driver, vm, 0, -1); +break; +default: +VIR_INFO(Unhandled shutdown_reason %d, xl_reason); +break; } -cleanup: if (vm) virObjectUnlock(vm); if (dom_event) libxlDomainEventQueue(driver, dom_event); +libxl_event_free(ctx, ev); +VIR_FREE(shutdown_info); +} + +static void +libxlEventHandler(void *data, VIR_LIBXL_EVENT_CONST libxl_event *event) +{ +virDomainObjPtr vm = data; +libxlDomainObjPrivatePtr priv = vm-privateData; +libxl_shutdown_reason xl_reason = event-u.domain_shutdown.shutdown_reason; +struct libxlShutdownThreadInfo *shutdown_info; +virThread thread; + +if (event-type != LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) { +VIR_INFO(Unhandled event type %d, event-type); +goto cleanup; +} + +
[libvirt] [PATCH 1/4] libxl: fix leaking libxlDomainObjPrivate
When libxl registers an FD with the libxl driver, the refcnt of the associated libxlDomainObjPrivate object is incremented. The refcnt is decremented when libxl deregisters the FD. But some FDs are only deregistered when their libxl ctx is freed, which unfortunately is done in the libxlDomainObjPrivate dispose function. With references held by the FDs, libxlDomainObjPrivate is never disposed. I added the ref/unref in FD registration/deregistration when adding the same in timer registration/deregistration. For timers, this is a simple approach to ensuring the libxlDomainObjPrivate is not disposed prior to their expirtation, which libxl guarantees will occur. It is not needed for FDs, and only causes libxlDomainObjPrivate to leak. This patch removes the reference on libxlDomainObjPrivate for FD registrations, but retains them for timer registrations. Tested on the latest releases of Xen supported by the libxl driver: 4.2.3, 4.3.1, and 4.4.0 RC3. Signed-off-by: Jim Fehlig jfeh...@suse.com --- src/libxl/libxl_domain.c | 21 ++--- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index e72c483..7efc13b 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -1,7 +1,7 @@ /* * libxl_domain.c: libxl domain object private state * - * Copyright (C) 2011-2013 SUSE LINUX Products GmbH, Nuernberg, Germany. + * Copyright (C) 2011-2014 SUSE LINUX Products GmbH, Nuernberg, Germany. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -92,7 +92,13 @@ libxlDomainObjPrivateOnceInit(void) VIR_ONCE_GLOBAL_INIT(libxlDomainObjPrivate) static void -libxlDomainObjEventHookInfoFree(void *obj) +libxlDomainObjFDEventHookInfoFree(void *obj) +{ +VIR_FREE(obj); +} + +static void +libxlDomainObjTimerEventHookInfoFree(void *obj) { libxlEventHookInfoPtr info = obj; @@ -138,12 +144,6 @@ libxlDomainObjFDRegisterEventHook(void *priv, return -1; info-priv = priv; -/* - * Take a reference on the domain object. Reference is dropped in - * libxlDomainObjEventHookInfoFree, ensuring the domain object outlives - * the fd event objects. - */ -virObjectRef(info-priv); info-xl_priv = xl_priv; if (events POLLIN) @@ -152,9 +152,8 @@ libxlDomainObjFDRegisterEventHook(void *priv, vir_events |= VIR_EVENT_HANDLE_WRITABLE; info-id = virEventAddHandle(fd, vir_events, libxlDomainObjFDEventCallback, - info, libxlDomainObjEventHookInfoFree); + info, libxlDomainObjFDEventHookInfoFree); if (info-id 0) { -virObjectUnref(info-priv); VIR_FREE(info); return -1; } @@ -259,7 +258,7 @@ libxlDomainObjTimeoutRegisterEventHook(void *priv, timeout = res.tv_sec * 1000 + (res.tv_usec + 999) / 1000; } info-id = virEventAddTimeout(timeout, libxlDomainObjTimerCallback, - info, libxlDomainObjEventHookInfoFree); + info, libxlDomainObjTimerEventHookInfoFree); if (info-id 0) { virObjectUnref(info-priv); VIR_FREE(info); -- 1.8.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 1/2] maint: Change the text of the NULLSTR() macro to null
Eric Blake suggested to change this message to be different from the glibc's NULL deref protection message in printf to be able to differentiate errors. --- src/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal.h b/src/internal.h index 4ba0e41..cef3da0 100644 --- a/src/internal.h +++ b/src/internal.h @@ -244,7 +244,7 @@ /* * Use this when passing possibly-NULL strings to printf-a-likes. */ -# define NULLSTR(s) ((s) ? (s) : (null)) +# define NULLSTR(s) ((s) ? (s) : null) /** * TODO: -- 1.8.5.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 4/4] libxl: improve subprocess handling
If available, let libxl handle reaping any children it creates by specifying libxl_sigchld_owner_libxl_always_selective_reap. This feature was added to improve subprocess handling in libxl when used in an application that does not install a SIGCHLD handler like libvirt http://lists.xen.org/archives/html/xen-devel/2014-01/msg01555.html Prior to this patch, it is possible to hit asserts in libxl when reaping subprocesses, particularly during simultaneous operations on multiple domains. With this patch, and the corresponding changes to libxl, I no longer see the asserts. Signed-off-by: Jim Fehlig jfeh...@suse.com --- The libxl patch has not yet hit xen.git, but without it this patch has no semantic change, only explicitly setting chldowner to the default of libxl_sigchld_owner_libxl. src/libxl/libxl_domain.c | 9 + 1 file changed, 9 insertions(+) diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index fbd6cab..eb2e50e 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -358,6 +358,14 @@ virDomainDefParserConfig libxlDomainDefParserConfig = { .devicesPostParseCallback = libxlDomainDeviceDefPostParse, }; +static const libxl_childproc_hooks libxl_child_hooks = { +#ifdef LIBXL_HAVE_SIGCHLD_OWNER_SELECTIVE_REAP +.chldowner = libxl_sigchld_owner_libxl_always_selective_reap, +#else +.chldowner = libxl_sigchld_owner_libxl, +#endif +}; + int libxlDomainObjPrivateInitCtx(virDomainObjPtr vm) { @@ -395,6 +403,7 @@ libxlDomainObjPrivateInitCtx(virDomainObjPtr vm) } libxl_osevent_register_hooks(priv-ctx, libxl_event_callbacks, priv); +libxl_childproc_setmode(priv-ctx, libxl_child_hooks, priv); ret = 0; -- 1.8.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] add flag to enforce hugepage backing of guest RAM
On Wed, Feb 05, 2014 at 09:49:53AM +, Daniel P. Berrange wrote: On Tue, Feb 04, 2014 at 03:04:11PM -0700, Eric Blake wrote: On 02/04/2014 02:57 PM, Marcelo Tosatti wrote: So perhaps we do need some policy attribute on the hugepages/ element to indicate desired behaviour here. What about the following new element under hugepages/ ? enforce_hugepage_size=integer Which feels a bit redundant (we're already under the hugepages element, after all). Maybe: hugepages size strict='yes' unit='G'1/size /hugepages where strict could be no if we are giving a hint but don't care if the hint cannot be honored (default yes if omitted), and where unit + value allows the user to input the size in a sensible unit (on output, we'd probably want to use unit='k' and spell out 1048576, for similarity with all our other memory interfaces that output in k for back-compat reasons). I don't think strict=yes|no is neccessarily the best. Per my previous mail in this thread there are at least 3 possible policies that could be implemented. - Require memory size multiple of hugepage size Awkward. If the memory size is not multiple of hugepage size it should still be possible to start the guest (although using smaller page sizes). - Round memory size upto multiple of huge page size QEMU decides, today, whether or not to do this. - Fill in with smaller huge pages Again, QEMU can decide this automatically. So I'd say policy=round|exact|bestfit even if QEMU doesn't decide to actually implement all 3 possible policies, we at least futureproof ourselves by not using a boolean. The request is the following: certain applications require the TLB performance characteristics provided by certain page sizes. For this type of application, the minimum page size is given. Below that page size, its known that the application cannot perform as expected, so guest initialization should instead fail. Except that case, there is no necessity to specify the options you list above. IMO the options should not be created unless their practical use has been verified. So going for hugepages size unit='K/G/M'x/size /hugepages Which is very precise and can be extended. Thanks for the suggestions -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 0/4] libxl: fixes related to concurrency improvements
While reviving old patches to add job support to the libxl driver, testing revealed some problems that were difficult to encounter in the current, more serialized processing approach used in the driver. The first patch is a bug fix, plugging leaks of libxlDomainObjPrivate objects. The second patch removes the list of libxl timer registrations maintained in the driver - a hack I was never fond of. The third patch moves domain shutdown handling to a thread, instead of doing all the shutdown work in the event handler. The fourth patch fixes an issue wrt child process handling discussed in this thread http://lists.xen.org/archives/html/xen-devel/2014-01/msg01553.html Ian Jackson's latest patches on the libxl side are here http://lists.xen.org/archives/html/xen-devel/2014-02/msg00124.html Jim Fehlig (4): libxl: fix leaking libxlDomainObjPrivate libxl: remove list of timer registrations from libxlDomainObjPrivate libxl: handle domain shutdown events in a thread libxl: improve subprocess handling src/libxl/libxl_conf.h | 5 +- src/libxl/libxl_domain.c | 102 --- src/libxl/libxl_domain.h | 8 +-- src/libxl/libxl_driver.c | 135 +++ 4 files changed, 115 insertions(+), 135 deletions(-) -- 1.8.1.4 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
[libvirt] [PATCH 2/4] libxl: remove list of timer registrations from libxlDomainObjPrivate
Due to some misunderstanding of requirements libxl places on timer handling, I introduced the half-brained idea of maintaining a list of timeouts that the driver could force to expire before freeing a libxlDomainObjPrivate (and hence libxl_ctx). But testing all the latest versions of Xen supported by the libxl driver (4.2.3, 4.3.1, 4.4.0 RC3), I see that libxl will handle this just fine and there is no need to force expiration behind libxl's back. Indeed it may be harmful to do so. This patch removes the timer list, allowing libxl to handle cleanup of its timer registrations. Signed-off-by: Jim Fehlig jfeh...@suse.com --- src/libxl/libxl_conf.h | 5 +--- src/libxl/libxl_domain.c | 72 +++- src/libxl/libxl_domain.h | 8 +- src/libxl/libxl_driver.c | 3 +- 4 files changed, 7 insertions(+), 81 deletions(-) diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h index f743541..ca7bc7d 100644 --- a/src/libxl/libxl_conf.h +++ b/src/libxl/libxl_conf.h @@ -1,7 +1,7 @@ /* * libxl_conf.h: libxl configuration management * - * Copyright (C) 2011-2013 SUSE LINUX Products GmbH, Nuernberg, Germany. + * Copyright (C) 2011-2014 SUSE LINUX Products GmbH, Nuernberg, Germany. * Copyright (C) 2011 Univention GmbH. * * This library is free software; you can redistribute it and/or @@ -115,9 +115,6 @@ struct _libxlDriverPrivate { virSysinfoDefPtr hostsysinfo; }; -typedef struct _libxlEventHookInfo libxlEventHookInfo; -typedef libxlEventHookInfo *libxlEventHookInfoPtr; - # define LIBXL_SAVE_MAGIC libvirt-xml\n \0 \r # define LIBXL_SAVE_VERSION 1 diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index 7efc13b..fbd6cab 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -34,37 +34,9 @@ #define VIR_FROM_THIS VIR_FROM_LIBXL -/* Append an event registration to the list of registrations */ -#define LIBXL_EV_REG_APPEND(head, add) \ -do { \ -libxlEventHookInfoPtr temp;\ -if (head) {\ -temp = head; \ -while (temp-next) \ -temp = temp-next; \ -temp-next = add; \ -} else { \ -head = add;\ -} \ -} while (0) - -/* Remove an event registration from the list of registrations */ -#define LIBXL_EV_REG_REMOVE(head, del) \ -do { \ -libxlEventHookInfoPtr temp;\ -if (head == del) { \ -head = head-next; \ -} else { \ -temp = head; \ -while (temp-next temp-next != del)\ -temp = temp-next; \ -if (temp-next) { \ -temp-next = del-next;\ -} \ -} \ -} while (0) - /* Object used to store info related to libxl event registrations */ +typedef struct _libxlEventHookInfo libxlEventHookInfo; +typedef libxlEventHookInfo *libxlEventHookInfoPtr; struct _libxlEventHookInfo { libxlEventHookInfoPtr next; libxlDomainObjPrivatePtr priv; @@ -214,12 +186,7 @@ libxlDomainObjTimerCallback(int timer ATTRIBUTE_UNUSED, void *timer_info) virObjectUnlock(p); libxl_osevent_occurred_timeout(p-ctx, info-xl_priv); virObjectLock(p); -/* - * Timeout could have been freed while the lock was dropped. - * Only remove it from the list if it still exists. - */ -if (virEventRemoveTimeout(info-id) == 0) -LIBXL_EV_REG_REMOVE(p-timerRegistrations, info); +virEventRemoveTimeout(info-id); virObjectUnlock(p); } @@ -265,9 +232,6 @@ libxlDomainObjTimeoutRegisterEventHook(void *priv, return -1; } -virObjectLock(info-priv); -LIBXL_EV_REG_APPEND(info-priv-timerRegistrations, info); -virObjectUnlock(info-priv); *hndp = info; return 0; @@ -306,12 +270,7 @@ libxlDomainObjTimeoutDeregisterEventHook(void *priv ATTRIBUTE_UNUSED, libxlDomainObjPrivatePtr p = info-priv; virObjectLock(p); -/* - * Only remove the timeout from the list if removal from the - * event loop is successful. - */ -if (virEventRemoveTimeout(info-id) == 0) -LIBXL_EV_REG_REMOVE(p-timerRegistrations, info); +virEventRemoveTimeout(info-id); virObjectUnlock(p); } @@ -443,26 +402,3 @@ cleanup: VIR_FREE(log_file); return ret; } - -void
[libvirt] [PATCH 0/2] NULL string fixes
Peter Krempa (2): maint: Change the text of the NULLSTR() macro to null qemu: blockjob: Print correct file name in error message src/internal.h | 2 +- src/qemu/qemu_driver.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) -- 1.8.5.3 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 1/2] maint: Change the text of the NULLSTR() macro to null
On 02/05/2014 10:44 AM, Peter Krempa wrote: Eric Blake suggested to change this message to be different from the glibc's NULL deref protection message in printf to be able to differentiate errors. --- src/internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) ACK (although I'm probably biased) - that way, if we see null in a message, we know we are safe; if we see (null) in a message, we know we have a NULL deref bug to fix. diff --git a/src/internal.h b/src/internal.h index 4ba0e41..cef3da0 100644 --- a/src/internal.h +++ b/src/internal.h @@ -244,7 +244,7 @@ /* * Use this when passing possibly-NULL strings to printf-a-likes. */ -# define NULLSTR(s) ((s) ? (s) : (null)) +# define NULLSTR(s) ((s) ? (s) : null) /** * TODO: -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 2/2] qemu: blockjob: Print correct file name in error message
On 02/05/2014 10:44 AM, Peter Krempa wrote: When attempting a blockcommit from the top layer, the base argument passed is NULL. This will be dereferenced when attempting a commit with an empty image chain. Output the real volume path instead: virsh blockcommit --verbose --path vda --domain DOMNAME --wait error: invalid argument: top '/path/somefile' in chain for 'vda' has no backing file instead of: error: invalid argument: top '(null)' in chain for 'vda' has no backing file --- src/qemu/qemu_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) ACK diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 38a48db..8998201 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -15180,7 +15180,7 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base, if (!top_meta || !top_meta-backingStore) { virReportError(VIR_ERR_INVALID_ARG, _(top '%s' in chain for '%s' has no backing file), - top, path); + top_canon, path); goto endjob; } if (!base (flags VIR_DOMAIN_BLOCK_COMMIT_SHALLOW)) { -- 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] Generate a valid imagelabel even for type 'none'
Commit 2ce63c1 added imagelabel generation when relabeling is turned off. But we weren't filling out the sensitivity for type 'none' labels, resulting in an invalid label: $ virsh managedsave domain error: unable to set security context 'system_u:object_r:svirt_image_t' on fd 28: Invalid argument --- src/security/security_selinux.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index aa47667..448f686 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -670,7 +670,14 @@ virSecuritySELinuxGenSecurityLabel(virSecurityManagerPtr mgr, break; case VIR_DOMAIN_SECLABEL_NONE: -/* no op */ +if (virSecuritySELinuxMCSGetProcessRange(sens, + catMin, + catMax) 0) +goto cleanup; + +if (VIR_STRDUP(mcs, sens) 0) +goto cleanup; + break; default: -- 1.8.3.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Generate a valid imagelabel even for type 'none'
On 02/05/2014 11:47 AM, Ján Tomko wrote: Commit 2ce63c1 added imagelabel generation when relabeling is turned off. But we weren't filling out the sensitivity for type 'none' labels, resulting in an invalid label: $ virsh managedsave domain error: unable to set security context 'system_u:object_r:svirt_image_t' on fd 28: Invalid argument --- src/security/security_selinux.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) ACK. +++ b/src/security/security_selinux.c @@ -670,7 +670,14 @@ virSecuritySELinuxGenSecurityLabel(virSecurityManagerPtr mgr, break; case VIR_DOMAIN_SECLABEL_NONE: -/* no op */ +if (virSecuritySELinuxMCSGetProcessRange(sens, + catMin, + catMax) 0) +goto cleanup; + +if (VIR_STRDUP(mcs, sens) 0) +goto cleanup; + break; default: -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH] Generate a valid imagelabel even for type 'none'
On 02/05/2014 07:54 PM, Eric Blake wrote: On 02/05/2014 11:47 AM, Ján Tomko wrote: Commit 2ce63c1 added imagelabel generation when relabeling is turned off. But we weren't filling out the sensitivity for type 'none' labels, resulting in an invalid label: $ virsh managedsave domain error: unable to set security context 'system_u:object_r:svirt_image_t' on fd 28: Invalid argument --- src/security/security_selinux.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) ACK. Thanks, pushed. Jan signature.asc Description: OpenPGP digital signature -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v3] bhyve: add a basic driver
Daniel P. Berrange wrote: +virCommandAddArg(cmd, -H); /* vmexit from guest on hlt */ +virCommandAddArg(cmd, -P); /* vmexit from guest on pause */ What's the functional effect of having these set, or not ? Having that set should make bhyve process terminate on these events (htl and pause). I guess it'd be better not to use it so bhyve process doesn't suddenly vanish from libvirt radar? Roman Bogorodskiy -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v2] qemu: Fix crash in virDomainMemoryStats with old qemu
On 02/05/2014 07:58 AM, John Ferlan wrote: On 02/05/2014 08:19 AM, Jiri Denemark wrote: If virDomainMemoryStats was run on a domain with virtio balloon driver running on an old qemu which supports QMP but does not support qom-list QMP command, libvirtd would crash. The reason is we did not check if qemuMonitorJSONGetObjectListPaths failed and moreover we even stored its result in an unsigned integer type. Signed-off-by: Jiri Denemark jdene...@redhat.com --- Notes: version 2: - use signed type for i and j to avoid comparison between signed and unsigned types; gcc-- for not complaining about it Returning 0 from this function isn't necessarily bad - it means not found still looking... It's a recursive nightmare. On the recursive path - we can't recurse unless qom-list existed in the first place - either qemu is new enough or it is not. So exiting with -1 avoids the recursion, and if we DO recurse, we wouldn't be failing because of a missing qom-list. As for the non recursive callers... For the qemuMonitorGetMemoryStats() path that's OK - it's allowed to fallback to trying the older former method of calling query-balloon in qemuMonitorJSONGetMemoryStats(). Returning -1 if qom-list isn't found means we won't go the fallback route. Let's look at the callers: ignore_value(qemuMonitorFindBalloonObjectPath(mon, mon-vm, /)); mon-ballooninit = true; ret = qemuMonitorJSONGetMemoryStats(mon, mon-balloonpath, stats, nr_stats); so we don't care whether it returns -1 or 0 or 1; we only care whether mon-balloonpath was set (it is set if we returned 1; and there are no stats to get if it returns -1 or 0). For the qemuMonitorSetMemoryStatsPeriod() returning 0 means don't even try to set. But again, the code does: if (qemuMonitorFindBalloonObjectPath(mon, mon-vm, /) == 1) { ret = qemuMonitorJSONSetMemoryStatsPeriod(mon, mon-balloonpath, period); } so we don't care about the difference between -1 and 0. The only place that cares about the difference is in recursion, but I already argued we aren't recursing if qom-list is missing. for (i = 0; i npaths ret == 0; i++) { @@ -1061,6 +1063,11 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, * then this version of qemu/kvm does not support the feature. */ nprops = qemuMonitorJSONGetObjectListPaths(mon, nextpath, bprops); +if (nprops 0) { +ret = -1; +goto cleanup; +} + Failure here wouldn't be because 'qom-list' doesn't exist, rather there was some other property error or malformed return object. Since not finding guest-stats-polling-interval property for a linkvirtio-balloon-pci object. Indeed - the only way to fail here if the outer loop succeeded is for a failure unrelated to qom-list not existing. But it is still failure. After the for loop that error is reported. So if nprops = 0, then we fall through to that. The other errors are still logged (right?), but we report the error below. for (j = 0; j nprops; j++) { if (STREQ(bprops[j]-name, guest-stats-polling-interval)) { VIR_DEBUG(Found Balloon Object Path %s, nextpath); FWIW: To Dan's comment - not sure how simple it would be to add a test for this condition. I'm still thinking the change in types is all that is necessary as there is cause for this function to return 0 if qom-list doesn't exist. I see no problem with returning -1 if qom-list doesn't exist. I'm happy with the patch as-is: 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] [PATCH 1/2] qemuBuildClockArgStr: Allow localtime clock basis
On 02/05/2014 07:32 AM, Michal Privoznik wrote: https://bugzilla.redhat.com/show_bug.cgi?id=1046192 Commit b8bf79a, which adds clock='variable', forgets to check localtime basis in qemuBuildClockArgStr(). So that localtime basis could not be used. Reported-by: Jincheng Miao jm...@redhat.com Signed-off-by: Michal Privoznik mpriv...@redhat.com --- src/qemu/qemu_command.c | 18 +++--- 1 file changed, 11 insertions(+), 7 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] [PATCH 2/2] qemuxml2argvtest: Test localtime clock basis
On 02/05/2014 07:32 AM, Michal Privoznik wrote: When trying to introduce a test for previous patch, I've noticed that the command line is constructed using current time. This won't work in our test suite (unless you guys wants to set a specific time prior to each test run :) ). Therefore we need to mock calls to time(2) to return the same value every time it's called. Slick. But as we only support mocking calls on Linux, you have converted a test from generic platform to Linux-only. Then again, qemu tests only run where we support qemu, which is currently Linux only, so I'm not sure it will matter. I guess we'll find out if anyone complains that it broke 'make check' on their platform. The only other alternative I can think of is to use regex replacement - in several tests, we have means of munging actual output to recognize specific patterns and replacing them with fixed contents. A timestamp is an easy fixed pattern, and it might be more portable to avoid mocking time() and instead just munge all timestamps of actual output into the expected timestamp. But munging is not quite as precise as your approach of a known fixed point in time - especially if we end up testing multiple expected outputs that have different resulting offsets in relation to the same starting fixed point in time. So I can live with your patch, rather than trying to do regex replacement. --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime-basis-localtime.args @@ -0,0 +1,5 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ +/usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic \ +-monitor unix:/tmp/test-monitor,server,nowait -rtc base=2009-02-14T01:31:30 \ A quick grep finds: tests/qemuxml2argvdata/qemuxml2argv-clock-variable.args:base=2010-2-2T18:22:10 -no-acpi -boot c -usb -hda /dev/HostVG/QEMUGuest1 -net none \ so how was that test working, and why is it unchanged by your mock setting the time to 2009? +++ b/tests/qemuxml2argvtest.c @@ -618,6 +618,7 @@ mymain(void) DO_TEST(bios, QEMU_CAPS_DEVICE, QEMU_CAPS_SGA); DO_TEST(clock-utc, NONE); DO_TEST(clock-localtime, NONE); +DO_TEST(clock-localtime-basis-localtime, QEMU_CAPS_RTC); /* * Can't be enabled since the absolute timestamp changes every time DO_TEST(clock-variable, QEMU_CAPS_RTC); Oh, it _wasn't_ working, but now can be MADE to work. Please uncomment this test, and fix the fallout, at which point, you have: 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] [PATCH v2] qemu: Fix crash in virDomainMemoryStats with old qemu
On 02/05/2014 05:12 PM, Eric Blake wrote: On 02/05/2014 07:58 AM, John Ferlan wrote: On 02/05/2014 08:19 AM, Jiri Denemark wrote: If virDomainMemoryStats was run on a domain with virtio balloon driver running on an old qemu which supports QMP but does not support qom-list QMP command, libvirtd would crash. The reason is we did not check if qemuMonitorJSONGetObjectListPaths failed and moreover we even stored its result in an unsigned integer type. Signed-off-by: Jiri Denemark jdene...@redhat.com --- Notes: version 2: - use signed type for i and j to avoid comparison between signed and unsigned types; gcc-- for not complaining about it Returning 0 from this function isn't necessarily bad - it means not found still looking... It's a recursive nightmare. On the recursive path - we can't recurse unless qom-list existed in the first place - either qemu is new enough or it is not. So exiting with -1 avoids the recursion, and if we DO recurse, we wouldn't be failing because of a missing qom-list. As for the non recursive callers... For the qemuMonitorGetMemoryStats() path that's OK - it's allowed to fallback to trying the older former method of calling query-balloon in qemuMonitorJSONGetMemoryStats(). Returning -1 if qom-list isn't found means we won't go the fallback route. Let's look at the callers: ignore_value(qemuMonitorFindBalloonObjectPath(mon, mon-vm, /)); mon-ballooninit = true; ret = qemuMonitorJSONGetMemoryStats(mon, mon-balloonpath, stats, nr_stats); so we don't care whether it returns -1 or 0 or 1; we only care whether mon-balloonpath was set (it is set if we returned 1; and there are no stats to get if it returns -1 or 0). For the qemuMonitorSetMemoryStatsPeriod() returning 0 means don't even try to set. But again, the code does: if (qemuMonitorFindBalloonObjectPath(mon, mon-vm, /) == 1) { ret = qemuMonitorJSONSetMemoryStatsPeriod(mon, mon-balloonpath, period); } so we don't care about the difference between -1 and 0. The only place that cares about the difference is in recursion, but I already argued we aren't recursing if qom-list is missing. for (i = 0; i npaths ret == 0; i++) { @@ -1061,6 +1063,11 @@ qemuMonitorFindBalloonObjectPath(qemuMonitorPtr mon, * then this version of qemu/kvm does not support the feature. */ nprops = qemuMonitorJSONGetObjectListPaths(mon, nextpath, bprops); +if (nprops 0) { +ret = -1; +goto cleanup; +} + Failure here wouldn't be because 'qom-list' doesn't exist, rather there was some other property error or malformed return object. Since not finding guest-stats-polling-interval property for a linkvirtio-balloon-pci object. Indeed - the only way to fail here if the outer loop succeeded is for a failure unrelated to qom-list not existing. But it is still failure. After the for loop that error is reported. So if nprops = 0, then we fall through to that. The other errors are still logged (right?), but we report the error below. for (j = 0; j nprops; j++) { if (STREQ(bprops[j]-name, guest-stats-polling-interval)) { VIR_DEBUG(Found Balloon Object Path %s, nextpath); FWIW: To Dan's comment - not sure how simple it would be to add a test for this condition. I'm still thinking the change in types is all that is necessary as there is cause for this function to return 0 if qom-list doesn't exist. I see no problem with returning -1 if qom-list doesn't exist. I'm happy with the patch as-is: ACK. I agree - I started going through this, got interrupted by some meeting :-), then dealt with the 8+ of snow outside in my driveway, and well got sidetracked a bit. John -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [v11 4/6] change lxc driver to use hostdev common library
Chunyan Liu wrote: Change lxc driver to use hostdev common library instead of APIs in lxc_hostdev.[ch] Signed-off-by: Chunyan Liu cy...@suse.com --- po/POTFILES.in|1 - src/Makefile.am |1 - src/lxc/lxc_conf.h|4 - src/lxc/lxc_driver.c | 47 --- src/lxc/lxc_hostdev.c | 416 - src/lxc/lxc_hostdev.h | 43 - src/lxc/lxc_process.c | 24 +++- 7 files changed, 48 insertions(+), 488 deletions(-) delete mode 100644 src/lxc/lxc_hostdev.c delete mode 100644 src/lxc/lxc_hostdev.h diff --git a/po/POTFILES.in b/po/POTFILES.in index 9e71db3..94017c6 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -61,7 +61,6 @@ src/locking/lock_manager.c src/locking/sanlock_helper.c src/lxc/lxc_cgroup.c src/lxc/lxc_fuse.c -src/lxc/lxc_hostdev.c src/lxc/lxc_container.c src/lxc/lxc_conf.c src/lxc/lxc_controller.c diff --git a/src/Makefile.am b/src/Makefile.am index e8b6fc4..20ceec2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -619,7 +619,6 @@ LXC_DRIVER_SOURCES = \ lxc/lxc_container.c lxc/lxc_container.h \ lxc/lxc_cgroup.c lxc/lxc_cgroup.h \ lxc/lxc_domain.c lxc/lxc_domain.h \ - lxc/lxc_hostdev.c lxc/lxc_hostdev.h \ lxc/lxc_monitor.c lxc/lxc_monitor.h \ lxc/lxc_process.c lxc/lxc_process.h \ lxc/lxc_fuse.c lxc/lxc_fuse.h \ diff --git a/src/lxc/lxc_conf.h b/src/lxc/lxc_conf.h index e04dcdd..5be159b 100644 --- a/src/lxc/lxc_conf.h +++ b/src/lxc/lxc_conf.h @@ -93,10 +93,6 @@ struct _virLXCDriver { /* Immutable pointer, self-locking APIs */ virDomainObjListPtr domains; -/* Immutable pointer. Requires lock to be held before - * calling APIs. */ -virUSBDeviceListPtr activeUsbHostdevs; - /* Immutable pointer, self-locking APIs */ virObjectEventStatePtr domainEventState; diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 982f3fc..3a62638 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -70,6 +70,7 @@ #include virstring.h #include viraccessapicheck.h #include viraccessapichecklxc.h +#include virhostdev.h #define VIR_FROM_THIS VIR_FROM_LXC @@ -1526,9 +1527,6 @@ static int lxcStateInitialize(bool privileged, if (!(lxc_driver-securityManager = lxcSecurityInit(cfg))) goto cleanup; -if ((lxc_driver-activeUsbHostdevs = virUSBDeviceListNew()) == NULL) -goto cleanup; - if ((virLXCDriverGetCapabilities(lxc_driver, true)) == NULL) goto cleanup; @@ -1643,7 +1641,6 @@ static int lxcStateCleanup(void) virSysinfoDefFree(lxc_driver-hostsysinfo); -virObjectUnref(lxc_driver-activeUsbHostdevs); virObjectUnref(lxc_driver-caps); virObjectUnref(lxc_driver-securityManager); virObjectUnref(lxc_driver-xmlopt); @@ -3903,6 +3900,7 @@ lxcDomainAttachDeviceHostdevSubsysUSBLive(virLXCDriverPtr driver, mode_t mode; bool created = false; virUSBDevicePtr usb = NULL; +virHostdevManagerPtr hostdev_mgr; if (virDomainHostdevFind(vm-def, def, NULL) = 0) { virReportError(VIR_ERR_OPERATION_FAILED, %s, @@ -3910,6 +3908,14 @@ lxcDomainAttachDeviceHostdevSubsysUSBLive(virLXCDriverPtr driver, return -1; } +hostdev_mgr = virHostdevManagerGetDefault(); +if (hostdev_mgr == NULL || +virHostdevPrepareUsbHostdevs(hostdev_mgr, + LXC_DRIVER_NAME, + vm-def-name, + def, 1, 0) 0) +return -1; Should an error be reported here? + if (virAsprintf(vroot, /proc/%llu/root, (unsigned long long)priv-initpid) 0) goto cleanup; @@ -3985,6 +3991,11 @@ lxcDomainAttachDeviceHostdevSubsysUSBLive(virLXCDriverPtr driver, ret = 0; cleanup: +virHostdevReAttachUsbHostdevs(hostdev_mgr, + LXC_DRIVER_NAME, + vm-def-name, + def, + 1); virDomainAuditHostdev(vm, def, attach, ret == 0); if (ret 0 created) unlink(dstfile); @@ -4447,8 +4458,7 @@ cleanup: static int -lxcDomainDetachDeviceHostdevUSBLive(virLXCDriverPtr driver, -virDomainObjPtr vm, +lxcDomainDetachDeviceHostdevUSBLive(virDomainObjPtr vm, virDomainDeviceDefPtr dev) { virLXCDomainObjPrivatePtr priv = vm-privateData; @@ -4457,6 +4467,7 @@ lxcDomainDetachDeviceHostdevUSBLive(virLXCDriverPtr driver, char *dst = NULL; char *vroot = NULL; virUSBDevicePtr usb = NULL; +