Commit Graph
100 Commits
Author SHA1 Message Date
Michal Privoznik df769041c2 domain_capabilities: Don't report machine type for bhyve
For some drivers the domain's machine type makes no sense. They
just don't use it. A great example is bhyve driver. Therefore it
makes very less sense to report machine in domain capabilities
XML.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-22 09:40:17 +01:00
Michal Privoznik 445708bc77 docs: Document NVDIMM
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-16 12:18:28 +01:00
Michal Privoznik f014247fde docs: Document adaptive timeout for qemu monitor
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-16 09:57:37 +01:00
Michal Privoznik 85af0b803c qemu: Adaptive timeout for connecting to monitor
There were couple of reports on the list (e.g. [1]) that guests
with huge amounts of RAM are unable to start because libvirt
kills qemu in the initialization phase. The problem is that if
guest is configured to use hugepages kernel has to zero them all
out before handing over to qemu process. For instance, 402GiB
worth of 1GiB pages took around 105 seconds (~3.8GiB/s). Since we
do not want to make the timeout for connecting to monitor
configurable, we have to teach libvirt to count with this
fact. This commit implements "1s per each 1GiB of RAM" approach
as suggested here [2].

1: https://www.redhat.com/archives/libvir-list/2017-March/msg00373.html
2: https://www.redhat.com/archives/libvir-list/2017-March/msg00405.html

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-16 09:21:39 +01:00
Michal Privoznik 67dcb797ed virTimeBackOffWait: Avoid long periods of sleep
While connecting to qemu monitor, the first thing we do is wait
for it to show up. However, we are doing it with some timeout to
avoid indefinite waits (e.g. when qemu doesn't create the monitor
socket at all). After beaa447a29 we are using exponential back
off timeout meaning, after the first connection attempt we wait
1ms, then 2ms, then 4 and so on.  This allows us to bring down
wait time for small domains where qemu initializes quickly.
However, on the other end of this scale are some domains with
huge amounts of guest memory. Now imagine that we've gotten up to
wait time of 15 seconds. The next one is going to be 30 seconds,
and the one after that whole minute. Well, okay - with current
code we are not going to wait longer than 30 seconds in total,
but this is going to change in the next commit.

The exponential back off is usable only for first few iterations.
Then it needs to be caped (one second was chosen as the limit)
and switch to constant wait time.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-16 09:21:39 +01:00
Michal Privoznik 7b89f857d9 qemu: Namespaces for NVDIMM
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 17:04:33 +01:00
Michal Privoznik 6e95abb446 qemu: Allow nvdimm in devices CGroups
Some users might want to pass a blockdev or a chardev as a
backend for NVDIMM. In fact, this is expected to be the mostly
used configuration. Therefore libvirt should allow the device in
devices CGroup then.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 16:55:30 +01:00
Michal Privoznik 78612aa597 qemu_hotplug: Relabel memdev
Now that we have APIs for relabel memdevs on hotplug, fill in the
missing implementation in qemu hotplug code.

The qemuSecurity wrappers might look like overkill for now,
because qemu namespace code does not deal with the nvdimms yet.
Nor does our cgroup code.  But hey, there's cgroup_device_acl
variable in qemu.conf. If users add their /dev/pmem* device in
there, the device is allowed in cgroups and created in the
namespace so they can successfully passthrough it to the domain.
It doesn't look like overkill after all, does it?

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 16:55:23 +01:00
Michal Privoznik 679bf50120 secdrivers: Implement memdev relabel APIs
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 16:48:24 +01:00
Michal Privoznik 0064c4e2bc security: Introduce internal APIs for memdev labelling
These APIs will be used whenever we are hot (un-)plugging a
memdev.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 16:45:53 +01:00
Michal Privoznik cde8e31938 security_selinux: Label host side of NVDIMM
When domain is being started up, we ought to relabel the host
side of NVDIMM so qemu has access to it.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 16:45:42 +01:00
Michal Privoznik ea416faf74 security_dac: Label host side of NVDIMM
When domain is being started up, we ought to relabel the host
side of NVDIMM so qemu has access to it.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 14:39:53 +01:00
Michal Privoznik e433546bef qemu: Introduce label-size for NVDIMMs
For NVDIMM devices it is optionally possible to specify the size
of internal storage for namespaces. Namespaces are a feature that
allows users to partition the NVDIMM for different uses.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 14:39:22 +01:00
Michal Privoznik 04dc668a31 qemu: Implement @access for <memory/> banks
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 14:20:18 +01:00
Michal Privoznik 80af11d3dd conf: Introduce @access to <memory/>
Now that NVDIMM has found its way into libvirt, users might want
to fine tune some settings for each module separately. One such
setting is 'share=on|off' for the memory-backend-file object.
This setting - just like its name suggest already - enables
sharing the nvdimm module with other applications. Under the hood
it controls whether qemu mmaps() the file as MAP_PRIVATE or
MAP_SHARED.

Yet again, we have such config knob in domain XML, but it's just
an attribute to numa <cell/>. This does not give fine enough
tuning on per-memdevice basis so we need to have the attribute
for each device too.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 14:18:58 +01:00
Michal Privoznik 1bc173199e qemu: Implement NVDIMM
So, majority of the code is just ready as-is. Well, with one
slight change: differentiate between dimm and nvdimm in places
like device alias generation, generating the command line and so
on.

Speaking of the command line, we also need to append 'nvdimm=on'
to the '-machine' argument so that the nvdimm feature is
advertised in the ACPI tables properly.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 14:16:32 +01:00
Michal Privoznik e21250dee8 qemu: Introduce QEMU_CAPS_DEVICE_NVDIMM
Introduce a qemu capability for -device nvdimm.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 13:33:48 +01:00
Michal Privoznik b4e8a49f8d Introduce NVDIMM memory model
NVDIMM is new type of memory introduced into QEMU 2.6. The idea
is that we have a Non-Volatile memory module that keeps the data
persistent across domain reboots.

At the domain XML level, we already have some representation of
'dimm' modules. Long story short, NVDIMM will utilize the
existing <memory/> element that lives under <devices/> by adding
a new attribute 'nvdimm' to the existing @model and introduce a
new <path/> element for <source/> while reusing other fields. The
resulting XML would appear as:

    <memory model='nvdimm'>
      <source>
        <path>/tmp/nvdimm</path>
      </source>
      <target>
        <size unit='KiB'>523264</size>
        <node>0</node>
      </target>
      <address type='dimm' slot='0'/>
    </memory>

So far, this is just a XML parser/formatter extension. QEMU
driver implementation is in the next commit.

For more info on NVDIMM visit the following web page:

    http://pmem.io/

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 13:30:58 +01:00
Michal Privoznik 8cbdd2ca48 qemuBuildMemoryBackendStr: Reorder args and update comment
Frankly, this function is one big mess. A lot of arguments,
complicated behaviour. It's really surprising that arguments were
in random order (input and output arguments were mixed together),
the documentation was outdated, the description of return values
was bogus.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 10:49:19 +01:00
Michal Privoznik 8b277ae247 qemuBuildMemoryBackendStr: Pass virDomainMemoryDefPtr
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 10:49:19 +01:00
Michal Privoznik cce282fe87 qemuBuildMemoryBackendStr: Check for @memAccess properly
Even though this variable contains just values from an enum where
zero has the usual meaning, it's enum after all and we should
check it as such.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 10:49:19 +01:00
Michal Privoznik 4346c9eb97 qemuBuildMemoryBackendStr: Don't overwrite @force
This is an input argument. We should not overwrite it.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-15 10:49:19 +01:00
Michal Privoznik 290a00e41d qemuDomainBuildNamespace: Handle file mount points
https://bugzilla.redhat.com/show_bug.cgi?id=1431112

Yeah, that's right. A mount point doesn't have to be a directory.
It can be a file too. However, the code that tries to preserve
mount points under /dev for new namespace for qemu does not count
with that option.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-13 13:32:45 +01:00
Michal Privoznik e915942b05 qemuProcessHandleMonitorEOF: Disable namespace for domain
https://bugzilla.redhat.com/show_bug.cgi?id=1430634

If a qemu process has died, we get EOF on its monitor. At this
point, since qemu process was the only one running in the
namespace kernel has already cleaned the namespace up. Any
attempt of ours to enter it has to fail.

This really happened in the bug linked above. We've tried to
attach a disk to qemu and while we were in the monitor talking to
qemu it just died. Therefore our code tried to do some roll back
(e.g. deny the device in cgroups again, restore labels, etc.).
However, during the roll back (esp. when restoring labels) we
still thought that domain has a namespace. So we used secdriver's
transactions. This failed as there is no namespace to enter.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-10 16:02:34 +01:00
Michal Privoznik 887ffbce43 qemuxml2argvtest: Don't overwrite driver stateDir
This is a very historic artefact. Back in the old days of
830ba76c3e when we had macros to add arguments onto qemu command
line (!) we thought it was a good idea to let qemu write out the
PID file. So we passed -pidfile $stateDir/$domName onto the
command line. Thus, in order for tests to work we needed stable
stateDir in the qemu driver. Unfortunately, after 16efa11aa6
where stateDir is mkdtemp()-d, this approach lead to a leak of
temp dir.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-10 09:55:43 +01:00
Michal Privoznik 16efa11aa6 qemuTestDriverInit: Don't access live data
Some of our tests (e.g. qemuhotplugtest) call
virDomainSaveConfig(). Now the problem is, qemuTestDriverInit()
creates a fake qemu driver and fills it with some fake
configuration. At least so we hoped. The truth is, it calls
regular virQEMUDriverConfigNew() and then fix couple of paths.
Literally. Therefore our tests see regular stateDir and configDir
for the user that is running the tests. Directories, where live
domain XMLs are stored. Let's just hope our test suite hasn't
mangled any of them.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-08 10:15:16 +01:00
Michal Privoznik b3388de7f2 qemuDomainSaveImageUpdateDef: Don't overwrite errors from virDomainDefCheckABIStability
https://bugzilla.redhat.com/show_bug.cgi?id=1379200

When we are restoring a domain from a saved image, or just
updating its XML in the saved image - we have to make sure that
the ABI guests sees will not change. We have a function for that
which reports errors. But for some reason if this function fails,
we call it again with slightly different argument. Therefore it
might happen that we overwrite the original error and leave user
with less helpful one.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-08 10:09:15 +01:00
Michal Privoznik 4da534c0b9 qemu: Enforce qemuSecurity wrappers
Now that we have some qemuSecurity wrappers over
virSecurityManager APIs, lets make sure everybody sticks with
them. We have them for a reason and calling virSecurityManager
API directly instead of wrapper may lead into accidentally
labelling a file on the host instead of namespace.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-06 08:54:28 +01:00
Michal Privoznik 9d87f76972 qemuDomainAttachNetDevice: Support attach of type="user"
https://bugzilla.redhat.com/show_bug.cgi?id=1420668

This has worked in previous releases.
My commit c266b60440 broke it.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-03-01 09:05:53 +01:00
Michal Privoznik 2a86209212 testNodeDeviceMockCreateVport: Don't call public APIs
This function is calling public APIs (virNodeDeviceLookupByName
etc.). That requires the driver lock to be unlocked and locked
again. If we, however, replace the public APIs calls with the
internal calls (that public APIs call anyway), we can drop the
lock/unlock exercise.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-28 17:59:58 +01:00
Michal Privoznik 9f26de1285 qemuProcessInit: Jump onto correct label in case of error
After eca76884ea in case of error in qemuDomainSetPrivatePaths()
in pretended start we jump to stop. I've changed this during
review from 'cleanup' which turned out to be correct. Well, sort
of. We can't call qemuProcessStop() as it decrements
driver->nactive and we did not increment it. However, it calls
virDomainObjRemoveTransientDef() which is basically the only
function we need to call. So call that function and goto cleanup;

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-24 14:19:42 +01:00
Michal Privoznik 3cddd63aec qemu_cgroup: Only try to allow devices if devices CGroup's available
When a domain needs an access to some device (be it a disk, RNG,
chardev, whatever), we have to allow it in the devices CGroup (if
it is available), because by default we disallow all the devices.
But some of the functions that are responsible for setting up
devices CGroup are lacking check whether there is any CGroup
available. Thus users might be unable to hotplug some devices:

  virsh # attach-device fedora rng.xml
  error: Failed to attach device from rng.xml
  error: internal error: Controller 'devices' is not mounted

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-23 11:21:26 +01:00
Michal Privoznik 0888cb6ab4 conf: Don't accept dummy values for <memoryBacking/> attributes
Our virSomeEnumTypeFromString() functions return either the value
of item from the enum or -1 on error. Usually however the value 0
means 'this value is not set in the domain XML, use some sensible
default'. Therefore, we don't accept corresponding string in
domain XML, for instance:

<memoryBacking>
  <source mode="none"/>
  <access mode="default"/>
  <allocation mode="none"/>
</memoryBacking>

should be rejected as invalid XML.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-22 09:11:33 +01:00
Michal Privoznik 5c74cf1f44 qemu: Allow @rendernode for virgl domains
When enabling virgl, qemu opens /dev/dri/render*. So far, we are
not allowing that in devices CGroup nor creating the file in
domain's namespace and thus requiring users to set the paths in
qemu.conf. This, however, is suboptimal as it allows access to
ALL qemu processes even those which don't have virgl configured.
Now that we have a way to specify render node that qemu will use
we can be more cautious and enable just that.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-20 10:44:22 +01:00
Michal Privoznik dfa79bd82b news: add entries for recent nodedev driver improvements
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-20 07:39:34 +01:00
Michal Privoznik 1bb787fdc9 qemuDomainGetHostdevPath: Report /dev/vfio/vfio less frequently
So far, qemuDomainGetHostdevPath has no knowledge of the reasong
it is called and thus reports /dev/vfio/vfio for every VFIO
backed device. This is suboptimal, as we want it to:

a) report /dev/vfio/vfio on every addition or domain startup
b) report /dev/vfio/vfio only on last VFIO device being unplugged

If a domain is being stopped then namespace and CGroup die with
it so no need to worry about that. I mean, even when a domain
that's exiting has more than one VFIO devices assigned to it,
this function does not clean /dev/vfio/vfio in CGroup nor in the
namespace. But that doesn't matter.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2017-02-20 07:21:59 +01:00
Michal Privoznik b8e659aa98 qemuDomainGetHostdevPath: Create /dev/vfio/vfio iff needed
So far, we are allowing /dev/vfio/vfio in the devices cgroup
unconditionally (and creating it in the namespace too). Even if
domain has no hostdev assignment configured. This is potential
security hole. Therefore, when starting the domain (or
hotplugging a hostdev) create & allow /dev/vfio/vfio too (if
needed).

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2017-02-20 07:21:58 +01:00
Michal Privoznik 9d92f533f8 qemuSetupHostdevCgroup: Use qemuDomainGetHostdevPath
Since these two functions are nearly identical (with
qemuSetupHostdevCgroup actually calling virCgroupAllowDevicePath)
we can have one function call the other and thus de-duplicate
some code.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2017-02-20 07:21:58 +01:00
Michal Privoznik 60ddceff8f qemu_cgroup: Kill qemuSetupHostSCSIVHostDeviceCgroup
There's no need for this function. Currently it is passed as a
callback to virSCSIVHostDeviceFileIterate(). However, SCSI host
devices have just one file path. Therefore we can mimic approach
used in qemuDomainGetHostdevPath() to get path and call
virCgroupAllowDevicePath() directly.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2017-02-20 07:21:58 +01:00
Michal Privoznik 7bb01ed3cd qemu_cgroup: Kill qemuSetupHostSCSIDeviceCgroup
There's no need for this function. Currently it is passed as a
callback to virSCSIDeviceFileIterate(). However, SCSI devices
have just one file path. Therefore we can mimic approach used in
qemuDomainGetHostdevPath() to get path and call
virCgroupAllowDevicePath() directly.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2017-02-20 07:21:58 +01:00
Michal Privoznik 4d7d1c4bc3 qemu_cgroup: Kill qemuSetupHostUSBDeviceCgroup
There's no need for this function. Currently it is passed as a
callback to virUSBDeviceFileIterate(). However, USB devices have
just one file path. Therefore we can mimic approach used in
qemuDomainGetHostdevPath() to get path and call
virCgroupAllowDevicePath() directly.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2017-02-20 07:21:58 +01:00
Michal Privoznik 78c018693b nodedev: Introduce new drm cap
After 7f1bdec5fa our nodedev driver is capable of
determining DRM devices (DRM stands for Direct Render Manager not
Digital rights management). There is still one bit missing
though: virConnectListAllNodeDevices() is capable of listing
either all devices or just those with specified capability. Well,
DRM capability is missing there.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-17 16:09:15 +01:00
Michal Privoznik 1d9ab0f04a qemu: Allow empty script path to <interface/>
Before 9c17d665fd (v1.3.2 - I know, right?) it was possible to
have the following interface configuration:

  <interface type='ethernet'/>
    <script path=''/>
  </interface>

This resulted in -netdev tap,script=,.. Fortunately, qemu helped
us to get away with this as it just ignored the empty script
path. However, after the commit mentioned above it's libvirtd
who is executing the script. Unfortunately without special
case-ing empty script path.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-16 17:39:34 +01:00
Michal Privoznik 27ac5f3741 qemu_conf: Properly check for retval of qemuDomainNamespaceAvailable
This function is returning a boolean therefore check for '< 0'
makes no sense. It should have been
'!qemuDomainNamespaceAvailable'.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-15 15:40:01 +01:00
Michal Privoznik b57bd206b9 qemu_conf: Check for namespaces availability more wisely
The bare fact that mnt namespace is available is not enough for
us to allow/enable qemu namespaces feature. There are other
requirements: we must copy all the ACL & SELinux labels otherwise
we might grant access that is administratively forbidden or vice
versa.
At the same time, the check for namespace prerequisites is moved
from domain startup time to qemu.conf parser as it doesn't make
much sense to allow users to start misconfigured libvirt just to
find out they can't start a single domain.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-15 12:43:23 +01:00
Michal Privoznik 732629dad3 qemuMonitorCPUModelInfoFree: Don't leak model_info->props
==11846== 240 bytes in 1 blocks are definitely lost in loss record 81 of 107
==11846==    at 0x4C2BC75: calloc (vg_replace_malloc.c:624)
==11846==    by 0x18C74242: virAllocN (viralloc.c:191)
==11846==    by 0x4A05E8: qemuMonitorCPUModelInfoCopy (qemu_monitor.c:3677)
==11846==    by 0x446E3C: virQEMUCapsNewCopy (qemu_capabilities.c:2171)
==11846==    by 0x437335: testQemuCapsCopy (qemucapabilitiestest.c:108)
==11846==    by 0x437CD2: virTestRun (testutils.c:180)
==11846==    by 0x437AD8: mymain (qemucapabilitiestest.c:176)
==11846==    by 0x4397B6: virTestMain (testutils.c:992)
==11846==    by 0x437B44: main (qemucapabilitiestest.c:188)

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-10 10:25:44 +01:00
Michal Privoznik afecfc2bf4 testUSBList: don't leak @dev
==22187== 77 (56 direct, 21 indirect) bytes in 1 blocks are definitely lost in loss record 23 of 37
==22187==    at 0x4C2BC75: calloc (vg_replace_malloc.c:624)
==22187==    by 0x4E75685: virAlloc (viralloc.c:144)
==22187==    by 0x4F0613A: virUSBDeviceNew (virusb.c:332)
==22187==    by 0x4F05BA2: virUSBDeviceSearch (virusb.c:183)
==22187==    by 0x4F05F95: virUSBDeviceFind (virusb.c:296)
==22187==    by 0x403514: testUSBList (virusbtest.c:209)
==22187==    by 0x403BD8: virTestRun (testutils.c:180)
==22187==    by 0x4039E5: mymain (virusbtest.c:285)
==22187==    by 0x4056BC: virTestMain (testutils.c:992)
==22187==    by 0x403A4A: main (virusbtest.c:293)

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-10 10:25:44 +01:00
Michal Privoznik eb58732c01 virusbmock: Link with libvirt_utils
We are using couple of functions from there (e.g. virStrdup) and
rely that the binary linking us has the libvirt_utils linked
already. Well, this makes valgrind sad.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-10 10:25:44 +01:00
Michal Privoznik a9595814ed tests: Trace re-executing processes with valgrind
A lot of our tests re-execute themeselves after loading their
mock library. This, however, makes valgrind sad because currently
we do not tell it to trace the process after exec().

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-10 10:25:44 +01:00
Michal Privoznik c2130c0d47 qemu_security: Introduce ImageLabel APIs
Just like we need wrappers over other virSecurityManager APIs, we
need one for virSecurityManagerSetImageLabel and
virSecurityManagerRestoreImageLabel. Otherwise we might end up
relabelling device in wrong namespace.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-09 08:04:57 +01:00
Michal Privoznik b7feabbfdc qemuDomainNamespaceSetupDisk: Simplify disk check
Firstly, instead of checking for next->path the
virStorageSourceIsEmpty() function should be used which also
takes disk type into account.
Secondly, not every disk source passed has the correct type set
(due to our laziness). Therefore, instead of checking for
virStorageSourceIsBlockLocal() and also S_ISBLK() the former can
be refined to just virStorageSourceIsLocalStorage().

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-08 15:56:21 +01:00
Michal Privoznik 786d8d91b4 qemuDomainDiskChainElement{Prepare,Revoke}: manage /dev entry
Again, one missed bit. This time without this commit there is no
/dev entry  in the namespace of the qemu process when doing disk
snapshots or block-copy.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-08 15:56:13 +01:00
Michal Privoznik 18ce9d139d qemuDomainNamespace{Setup,Teardown}Disk: Don't pass pointer to full disk
These functions do not need to see the whole virDomainDiskDef.
Moreover, they are going to be called from places where we don't
have access to the full disk definition. Sticking with
virStorageSource is more than enough.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-08 15:56:05 +01:00
Michal Privoznik 76d491ef14 qemuDomainNamespaceSetupDisk: Drop useless @src variable
Since its introduction in 81df21507b this variable was never
used.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-08 15:55:56 +01:00
Michal Privoznik 8dc867e978 qemu_domain: Don't pass virDomainDeviceDefPtr to ns helpers
There is no need for this. None of the namespace helpers uses it.
Historically it was used when calling secdriver APIs, but we
don't to that anymore.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-08 15:55:52 +01:00
Michal Privoznik 848dbe1937 qemu_security: Drop qemuSecuritySetRestoreAllLabelData struct
This struct is unused after 095f042ed6.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-08 15:55:46 +01:00
Michal Privoznik 45599e407c qemuDomainAttachSCSIVHostDevice: manage /dev entry
Again, one missed bit. This time without this commit there is no
/dev entry in the namespace of the qemu process when attaching
vhost SCSI device.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-08 15:54:52 +01:00
Michal Privoznik 7d93a88519 qemuDomainAttachSCSIVHostDevice: Prefer qemuSecurity wrappers
Since we have qemuSecurity wrappers over
virSecurityManagerSetHostdevLabel and
virSecurityManagerRestoreHostdevLabel we ought to use them
instead of calling secdriver APIs directly.  Without those
wrappers the labelling won't be done in the correct namespace
and thus won't apply to the nodes seen by qemu itself.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-08 15:53:43 +01:00
Michal Privoznik 7f0b382522 qemuDomainAttachDeviceMknod: Don't loop endlessly
When working with symlinks it is fairly easy to get into a loop.
Don't.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-07 13:20:19 +01:00
Michal Privoznik 3f5fcacf89 qemuDomainAttachDeviceMknod: Deal with symlinks
Similarly to one of the previous commits, we need to deal
properly with symlinks in hotplug case too.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-07 13:20:17 +01:00
Michal Privoznik 4ac847f93b qemuDomainCreateDevice: Don't loop endlessly
When working with symlinks it is fairly easy to get into a loop.
Don't.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-07 13:18:32 +01:00
Michal Privoznik 54ed672214 qemuDomainCreateDevice: Properly deal with symlinks
Imagine you have a disk with the following source set up:

/dev/disk/by-uuid/$uuid (symlink to) -> /dev/sda

After cbc45525cb the transitive end of the symlink chain is
created (/dev/sda), but we need to create any item in chain too.
Others might rely on that.
In this case, /dev/disk/by-uuid/$uuid comes from domain XML thus
it is this path that secdriver tries to relabel. Not the resolved
one.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-07 13:18:10 +01:00
Michal Privoznik b621291f5c qemuDomain{Attach,Detach}Device NS helpers: Don't relabel devices
After previous commit this has become redundant step.
Also setting up devices in namespace and setting their label
later on are two different steps and should be not done at once.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-07 10:40:53 +01:00
Michal Privoznik 0f0fcc2cd4 qemu_security: Use more transactions
The idea is to move all the seclabel setting to security driver.
Having the relabel code spread all over the place looks very
messy.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-07 10:40:53 +01:00
Michal Privoznik 3e6839d4e8 qemuSecurityRestoreAllLabel: Don't use transactions
Because of the nature of security driver transactions, it is
impossible to use them properly. The thing is, transactions enter
the domain namespace and commit all the seclabel changes.
However, in RestoreAllLabel() this is impossible - the qemu
process, the only process running in the namespace, is gone. And
thus is the namespace. Therefore we shouldn't use the transactions
as there is no namespace to enter.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-07 10:40:53 +01:00
Michal Privoznik 0a4652381f qemuDomainPrepareDisk: Fix ordering
The current ordering is as follows:
1) set label
2) create the device in namespace
3) allow device in the cgroup

While this might work for now, it will definitely not work if the
security driver would use transactions as in that case there
would be no device to relabel in the domain namespace as the
device is created in the second step.
Swap steps 1) and 2) to allow security driver to use more
transactions.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-07 10:40:53 +01:00
Michal Privoznik 6094169b83 util: Introduce virFileReadLink
We will need to traverse the symlinks one step at the time.
Therefore we need to see where a symlink is pointing to.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-07 10:40:53 +01:00
Michal Privoznik 3172d26730 virProcessRunInMountNamespace: Report errors from child
The comment to the function states that the errors from the child
process are reported. Well, the error buffer is filled with
possible error messages. But then it is thrown away. Among with
important error message from the child process.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-07 10:40:53 +01:00
Michal Privoznik aaf0ac7e7c xenFormatXLDisk: Don't leak @target
==11260== 1,006 bytes in 1 blocks are definitely lost in loss record 106 of 111
==11260==    at 0x4C2AE5F: malloc (vg_replace_malloc.c:297)
==11260==    by 0x4C2BDFF: realloc (vg_replace_malloc.c:693)
==11260==    by 0x4EA430B: virReallocN (viralloc.c:245)
==11260==    by 0x4EA7C52: virBufferGrow (virbuffer.c:130)
==11260==    by 0x4EA7D28: virBufferAdd (virbuffer.c:165)
==11260==    by 0x4EA8E10: virBufferStrcat (virbuffer.c:718)
==11260==    by 0x42D263: xenFormatXLDiskSrcNet (xen_xl.c:960)
==11260==    by 0x42D4EB: xenFormatXLDiskSrc (xen_xl.c:1015)
==11260==    by 0x42D870: xenFormatXLDisk (xen_xl.c:1101)
==11260==    by 0x42DA89: xenFormatXLDomainDisks (xen_xl.c:1148)
==11260==    by 0x42EAF8: xenFormatXL (xen_xl.c:1558)
==11260==    by 0x40E85F: testCompareParseXML (xlconfigtest.c:105)

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-02-07 10:31:59 +01:00
Michal Privoznik a5cae75a3e qemuBuildChrChardevStr: Don't leak @charAlias
==12618== 110 bytes in 10 blocks are definitely lost in loss record 269 of 295
==12618==    at 0x4C2AE5F: malloc (vg_replace_malloc.c:297)
==12618==    by 0x1CFC6DD7: vasprintf (vasprintf.c:73)
==12618==    by 0x1912B2FC: virVasprintfInternal (virstring.c:551)
==12618==    by 0x1912B411: virAsprintfInternal (virstring.c:572)
==12618==    by 0x50B1FF: qemuAliasChardevFromDevAlias (qemu_alias.c:638)
==12618==    by 0x518CCE: qemuBuildChrChardevStr (qemu_command.c:4973)
==12618==    by 0x522DA0: qemuBuildShmemBackendChrStr (qemu_command.c:8674)
==12618==    by 0x523209: qemuBuildShmemCommandLine (qemu_command.c:8789)
==12618==    by 0x526135: qemuBuildCommandLine (qemu_command.c:9843)
==12618==    by 0x48B4BA: qemuProcessCreatePretendCmd (qemu_process.c:5897)
==12618==    by 0x4378C9: testCompareXMLToArgv (qemuxml2argvtest.c:498)
==12618==    by 0x44D5A6: virTestRun (testutils.c:180)

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-30 10:38:03 +01:00
Michal Privoznik 572eda12ad qemu: Implement mtu on interface
Not only we should set the MTU on the host end of the device but
also let qemu know what MTU did we set.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-26 10:00:01 +01:00
Michal Privoznik b020cf73fe domain_conf: Introduce <mtu/> to <interface/>
So far we allow to set MTU for libvirt networks. However, not all
domain interfaces have to be plugged into a libvirt network and
even if they are, they might want to have a different MTU (e.g.
for testing purposes).

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-26 09:59:56 +01:00
Michal Privoznik eebec1697e virDomainNetDefParseXML: s/ret/rv/
We use @ret to hold the actual return value of the function we
are currently in. To hold a return value of a function called we
use different variables: @rv, @rc, etc. Honour this naming
scheme in virDomainNetDefParseXML too.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-25 09:18:49 +01:00
Michal Privoznik d737fa560f formatnetwork.html.in: Fix #elementsNICS anchor
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-25 09:18:49 +01:00
Michal Privoznik 0cacdc6f24 virDomainHostdevSubsysSCSIVHostDefParseXML: Don't leak @protocol
==24748== 12 bytes in 2 blocks are definitely lost in loss record 25 of 84
==24748==    at 0x4C2BF80: malloc (vg_replace_malloc.c:296)
==24748==    by 0x1A1E1E78: xmlStrndup (in /usr/lib64/libxml2.so.2.9.4)
==24748==    by 0x18D0495F: virXMLPropString (virxml.c:506)
==24748==    by 0x18D1FB3E: virDomainHostdevSubsysSCSIVHostDefParseXML (domain_conf.c:6280)
==24748==    by 0x18D20350: virDomainHostdevDefParseXMLSubsys (domain_conf.c:6450)
==24748==    by 0x18D34E7D: virDomainHostdevDefParseXML (domain_conf.c:13218)
==24748==    by 0x18D42598: virDomainDefParseXML (domain_conf.c:17745)
==24748==    by 0x18D440A9: virDomainDefParseNode (domain_conf.c:18236)
==24748==    by 0x18D43EFA: virDomainDefParse (domain_conf.c:18180)
==24748==    by 0x18D43FA0: virDomainDefParseFile (domain_conf.c:18206)
==24748==    by 0x44EDA1: testCompareDomXML2XMLFiles (testutils.c:1140)
==24748==    by 0x4365F8: testXML2XMLActive (qemuxml2xmltest.c:59)

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-20 16:31:05 +01:00
Michal Privoznik 57b5e27d3d qemu: set default vhost-user ifname
Based on work of Mehdi Abaakouk <sileht@sileht.net>.

When parsing vhost-user interface XML and no ifname is found we
can try to fill it in in post parse callback. The way this works
is we try to make up interface name from given socket path and
then ask openvswitch whether it knows the interface.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-20 15:42:12 +01:00
Michal Privoznik 77831d212e Post-release version bump to 3.1.0
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-18 11:57:54 +01:00
Michal Privoznik 1cbcbd3746 tests: Distribute qemuhotplugtestcpus
Starting from a245abce43 another set of tests for
qemuhotplugtest has been introduced. This time for vcpu hotplug.
However, the test data (which live in qemuhotplugtestcpus dir)
are not being distributed properly.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-18 11:49:02 +01:00
Michal Privoznik d0baf54e53 qemu: Actually unshare() iff running as root
https://bugzilla.redhat.com/show_bug.cgi?id=1413922

While all the code that deals with qemu namespaces correctly
detects whether we are running as root (and turn into NO-OP for
qemu:///session) the actual unshare() call is not guarded with
such check. Therefore any attempt to start a domain under
qemu:///session shall fail as unshare() is reserved for root.

The fix consists of moving unshare() call (for which we have a
wrapper called virProcessSetupPrivateMountNS) into
qemuDomainBuildNamespace() where the proper check is performed.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
2017-01-17 13:23:56 +01:00
Michal Privoznik 93a062c3b2 qemu: Copy SELinux labels for namespace too
When creating new /dev/* for qemu, we do chown() and copy ACLs to
create the exact copy from the original /dev. I though that
copying SELinux labels is not necessary as SELinux will chose the
sane defaults. Surprisingly, it does not leaving namespace with
the following labels:

crw-rw-rw-. root root system_u:object_r:tmpfs_t:s0     random
crw-------. root root system_u:object_r:tmpfs_t:s0     rtc0
drwxrwxrwt. root root system_u:object_r:tmpfs_t:s0     shm
crw-rw-rw-. root root system_u:object_r:tmpfs_t:s0     urandom

As a result, domain is unable to start:

error: internal error: process exited while connecting to monitor: Error in GnuTLS initialization: Failed to acquire random data.
qemu-kvm: cannot initialize crypto: Unable to initialize GNUTLS library: Failed to acquire random data.

The solution is to copy the SELinux labels as well.

Reported-by: Andrea Bolognani <abologna@redhat.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-13 14:45:52 +01:00
Michal Privoznik b7f01ea0ed docs: Fix libvirt_guest nss module name
In the documentation we are mixing libvirt-guest and
libvirt_guest module name. The correct name is the latter.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-13 11:41:11 +01:00
Michal Privoznik f8ec272d98 docs: Document <sndbuf/>
This element has been introduced in fe053dbea7, but isn't
documented yet. After exactly 6 years I guess we can finally
document it.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-12 16:18:33 +01:00
Michal Privoznik b73336755b news: Reflect hugepages patch
In f55afd8 I've made libvirt to construct hugepage path on
per-domain basis. However, this change was not reflected in
the NEWS file.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-12 08:12:13 +01:00
Michal Privoznik cbc45525cb qemuDomainCreateDevice: Canonicalize paths
So far the decision whether /dev/* entry is created in the qemu
namespace is really simple: does the path starts with "/dev/"?
This can be easily fooled by providing path like the following
(for any considered device like disk, rng, chardev, ..):

  /dev/../var/lib/libvirt/images/disk.qcow2

Therefore, before making the decision the path should be
canonicalized.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-11 18:08:13 +01:00
Michal Privoznik 49f326edc0 qemu: Use namespaces iff available on the host kernel
So far the namespaces were turned on by default unconditionally.
For all non-Linux platforms we provided stub functions that just
ignored whatever namespaces setting there was in qemu.conf and
returned 0 to indicate success. Moreover, we didn't really check
if namespaces are available on the host kernel.

This is suboptimal as we might have ignored user setting.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-11 18:07:43 +01:00
Michal Privoznik 41816751a7 util: Introduce virFileMoveMount
This is a simple wrapper over mount(). However, not every system
out there is capable of moving a mount point. Therefore, instead
of having to deal with this fact in all the places of our code we
can have a simple wrapper and deal with this fact at just one
place.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-11 18:06:30 +01:00
Michal Privoznik cd32783cd4 lxc_container: Drop userns_supported
This is unnecessary wrapper around virProcessNamespaceAvailable().

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-11 18:05:03 +01:00
Michal Privoznik 083fcd06d3 lxc: Move lxcContainerAvailable to virprocess
Other drivers (like qemu) would like to know if the namespaces
are available therefore it makes sense to move this function to
a shared module.

At the same time, this function had some default namespaces that
are checked with every call. It is not necessary - let callers
pass just those namespaces they are interested in.

With the move the function is renamed to
virProcessNamespaceAvailable.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-11 18:02:35 +01:00
Michal Privoznik 2ff8c30548 qemuDomainSetupAllInputs: Update debug message
Due to a copy-paste error, the debug message reads:

  Setting up disks

It should have been:

  Setting up inputs.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-11 17:39:24 +01:00
Michal Privoznik 3027bacf95 virSecuritySELinuxSetFileconHelper: Fix build with broken selinux.h
There are still some systems out there that have broken
setfilecon*() prototypes. Instead of taking 'const char *tcon' it
is taking 'char *tcon'. The function should just set the context,
not modify it.

We had been bitten with this problem before which resulted in
292d3f2d and subsequently b109c09765. However, with one my latest
commits (4674fc6afd) I've changed the type of @tcon variable to
'const char *' which results in build failure on the systems from
above.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-10 19:23:49 +01:00
Michal Privoznik 269589146c qemu_domain: Move qemuDomainGetPreservedMounts
This function is used only from code compiled on Linux. Therefore
on non-Linux platforms it triggers compilation error:

../../src/qemu/qemu_domain.c:209:1: error: unused function 'qemuDomainGetPreservedMounts' [-Werror,-Wunused-function]

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-10 19:23:49 +01:00
Michal Privoznik 406e390962 qemu: Drop qemuDomainDeleteNamespace
After previous commits, this function is no longer needed.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-10 13:04:57 +01:00
Michal Privoznik 5d198c2b2c qemuDomainCreateNamespace: move mkdir to qemuDomainBuildNamespace
Again, there is no need to create /var/lib/libvirt/$domain.*
directories in CreateNamespace(). It is sufficient to create them
as soon as we need them which is in BuildNamespace. This way we
don't leave them around for the whole lifetime of domain.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-10 13:04:57 +01:00
Michal Privoznik 5d30057695 qemuDomainGetPreservedMounts: Do not special case /dev
The c1140eb9e got me thinking. We don't want to special case /dev
in qemuDomainGetPreservedMounts(), but in all other places in the
code we special case it anyway. I mean,
/var/run/libvirt/$domain.dev path is constructed separately just
so that it is not constructed here. It makes only a little sense
(if any at all).

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-10 13:04:57 +01:00
Michal Privoznik 40ebbf72d5 qemuDomainCreateNamespace: s/unlink/rmdir/
If something goes wrong in this function we try a rollback. That
is unlink all the directories we created earlier. For some weird
reason unlink() was called instead of rmdir().

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-10 13:04:57 +01:00
Michal Privoznik 095f042ed6 qemu: Use transactions from security driver
So far if qemu is spawned under separate mount namespace in order
to relabel everything it needs an access to the security driver
to run in that namespace too. This has a very nasty down side -
it is being run in a separate process, so any internal state
transition is NOT reflected in the daemon. This can lead to many
sleepless nights. Therefore, use the transaction APIs so that
libvirt developers can sleep tight again.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-10 13:04:11 +01:00
Michal Privoznik 4674fc6afd security_selinux: Implement transaction APIs
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-10 12:50:00 +01:00
Michal Privoznik 67232478db security_dac: Implement transaction APIs
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-10 12:50:00 +01:00
Michal Privoznik 95576b4df0 security driver: Introduce transaction APIs
With our new qemu namespace code in place, the relabelling of
devices is done not as good is it could: a child process is
spawned, it enters the mount namespace of the qemu process and
then runs desired API of the security driver.

Problem with this approach is that internal state transition of
the security driver done in the child process is not reflected in
the parent process. While currently it wouldn't matter that much,
it is fairly easy to forget about that. We should take the extra
step now while this limitation is still fresh in our minds.

Three new APIs are introduced here:
  virSecurityManagerTransactionStart()
  virSecurityManagerTransactionCommit()
  virSecurityManagerTransactionAbort()

The Start() is going to be used to let security driver know that
we are starting a new transaction. During a transaction no
security labels are actually touched, but rather recorded and
only at Commit() phase they are actually updated. Should
something go wrong Abort() aborts the transaction freeing up all
memory allocated by transaction.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-10 12:49:59 +01:00
Michal Privoznik 39779eb195 security_dac: Resolve virSecurityDACSetOwnershipInternal const correctness
The code at the very bottom of the DAC secdriver that calls
chown() should be fine with read-only data. If something needs to
be prepared it should have been done beforehand.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2017-01-10 12:49:59 +01:00