1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-10-13 11:33:55 +03:00

Compare commits

..

208 Commits

Author SHA1 Message Date
Jiri Denemark
6fd8d6b655 qemu: Let empty default VNC password work as documented
CVE-2016-5008

Setting an empty graphics password is documented as a way to disable
VNC/SPICE access, but QEMU does not always behaves like that. VNC would
happily accept the empty password. Let's enforce the behavior by setting
password expiration to "now".

https://bugzilla.redhat.com/show_bug.cgi?id=1180092

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit bb848feec0)
(cherry picked from commit d933f68ee6)
2016-06-30 14:02:13 +01:00
Laine Stump
0869cab5fe util: eliminate "use after free" in callers of virNetDevLinkDump
virNetDevLinkDump() gets a message from netlink into "resp", then
calls nlmsg_parse() to fill the table "tb" with pointers into resp. It
then returns tb to its caller, but not before freeing the buffer at
resp. That means that all the callers of virNetDevLinkDump() are
examining memory that has already been freed. This can be verified by
filling the buffer at resp with garbage prior to freeing it (or, I
suppose, just running libvirtd under valgrind) then performing some
operation that calls virNetDevLinkDump().

The upstream commit log incorrectly states that the code has been like
this ever since virNetDevLinkDump() was written. In reality, the
problem was introduced with commit e95de74d, first in libvirt-1.0.5,
which was attempting to eliminate a typecast that caused compiler
warnings. It has only been pure luck (or maybe a lack of heavy load,
and/or maybe an allocation algorithm in malloc() that delays re-use of
just-freed memory) that has kept this from causing errors, for example
when configuring a PCI passthrough or macvtap passthrough network
interface.

The solution taken in this patch is the simplest - just return resp to
the caller along with tb, then have the caller free it after they are
finished using the data (pointers) in tb. I alternately could have
made a cleaner interface by creating a new struct that put tb and resp
together along with a vir*Free() function for it, but this function is
only used in a couple places, and I'm not sure there will be
additional new uses of virNetDevLinkDump(), so the value of adding a
new type, extra APIs, etc. is dubious.

(cherry picked from commit f9f9699f40)

Conflicts:
	src/util/virnetdevvportprofile.c - whitespace/copyright change
2014-11-13 13:05:41 -05:00
Eric Blake
107f1ff20e CVE-2014-7823: dumpxml: security hole with migratable flag
Commit 28f8dfd (v1.0.0) introduced a security hole: in at least
the qemu implementation of virDomainGetXMLDesc, the use of the
flag VIR_DOMAIN_XML_MIGRATABLE (which is usable from a read-only
connection) triggers the implicit use of VIR_DOMAIN_XML_SECURE
prior to calling qemuDomainFormatXML.  However, the use of
VIR_DOMAIN_XML_SECURE is supposed to be restricted to read-write
clients only.  This patch treats the migratable flag as requiring
the same permissions, rather than analyzing what might break if
migratable xml no longer includes secret information.

Fortunately, the information leak is low-risk: all that is gated
by the VIR_DOMAIN_XML_SECURE flag is the VNC connection password;
but VNC passwords are already weak (FIPS forbids their use, and
on a non-FIPS machine, anyone stupid enough to trust a max-8-byte
password sent in plaintext over the network deserves what they
get).  SPICE offers better security than VNC, and all other
secrets are properly protected by use of virSecret associations
rather than direct output in domain XML.

* src/remote/remote_protocol.x (REMOTE_PROC_DOMAIN_GET_XML_DESC):
Tighten rules on use of migratable flag.
* src/libvirt-domain.c (virDomainGetXMLDesc): Likewise.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit b1674ad5a9)

Conflicts:
	src/libvirt-domain.c - file split from older src/libvirt.c; context with older virLibConnError
	src/remote/remote_protocol.x - no fine-grained ACLs
Signed-off-by: Eric Blake <eblake@redhat.com>
2014-11-10 09:23:39 -07:00
Pavel Hrdina
f18b86e35f domain_conf: fix domain deadlock
If you use public api virConnectListAllDomains() with second parameter
set to NULL to get only the number of domains you will lock out all
other operations with domains.

Introduced by commit 2c680804.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
(cherry picked from commit fc22b2e748)
2014-10-01 12:15:44 -06:00
Peter Krempa
cc05c6d5d2 CVE-2014-3633: qemu: blkiotune: Use correct definition when looking up disk
Live definition was used to look up the disk index while persistent one
was indexed leading to a crash in qemuDomainGetBlockIoTune. Use the
correct def and report a nice error.

Unfortunately it's accessible via read-only connection, though it can
only crash libvirtd in the cases where the guest is hot-plugging disks
without reflecting those changes to the persistent definition.  So
avoiding hotplug, or doing hotplug where persistent is always modified
alongside live definition, will avoid the out-of-bounds access.

Introduced in: eca96694a7 (v0.9.8)
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1140724
Reported-by: Luyao Huang <lhuang@redhat.com>
Signed-off-by: Peter Krempa <pkrempa@redhat.com>

(cherry picked from commit 3e745e8f77)

Conflicts:
	src/qemu/qemu_driver.c - context due to fewer functions
2014-09-17 21:50:31 -06:00
Peter Krempa
17df6a9b39 qemu: copy: Accept 'format' parameter when copying to a non-existing img
We have the following matrix of possible arguments handled by the logic
statement touched by this patch:
       | flags & _REUSE_EXT | !(flags & _REUSE_EXT)
-------+--------------------+----------------------
 format| (1)                | (2)
-------+--------------------+----------------------
!format| (3)                | (4)
-------+--------------------+----------------------

In cases 1 and 2 the user provided a format, in cases 3 and 4 not. The
user requests to use a pre-existing image in 1 and 3 and libvirt will
create a new image in 2 and 4.

The difference between cases 3 and 4 is that for 3 the format is probed
from the user-provided image, whereas in 4 we just use the existing disk
format.

The current code would treat cases 1,3 and 4 correctly but in case 2 the
format provided by the user would be ignored.

The particular piece of code was broken in commit 35c7701c64
but since it was introduced a few commits before that it was never
released as working.

(cherry picked from commit 42619ed05d)
Signed-off-by: Eric Blake <eblake@redhat.com>

Conflicts:
	src/qemu/qemu_driver.c - no refactoring of commits 7b7bf001, 4f20226
2014-07-02 22:19:17 -06:00
Eric Blake
d528a5e066 build: fix 'make check' with newer git
Newer git doesn't like the maint.mk rule 'public-submodule-commit'
run during 'make check', as inherited from our checkout of gnulib.
I tracked down that libvirt commit 8531301 picked up a gnulib fix
that makes git happy.  Rather than try and do a full .gnulib
submodule update to gnulib.git d18d1b802 (as used in that libvirt
commit), it was easier to just backport the fixed maint.mk from
gnulib on top of our existing submodule level.  I did it as follows,
where these steps will have to be repeated when cherry-picking this
commit to any other maintenance branch:

mkdir -p gnulib/local/top
cd .gnulib
git checkout d18d1b802 top/maint.mk
git diff HEAD > ../gnulib/local/top/maint.mk.diff
git reset --hard
cd ..
git add gnulib/local/top

Signed-off-by: Eric Blake <eblake@redhat.com>
2014-07-02 22:19:11 -06:00
Eric Blake
ceefdec93c docs: publish correct enum values
We publish libvirt-api.xml for others to use, and in fact, the
libvirt-python bindings use it to generate python constants that
correspond to our enum values.  However, we had an off-by-one bug
that any enum that relied on C's rules for implicit initialization
of the first enum member to 0 got listed in the xml as having a
value of 1 (and all later members of the enum were equally
botched).

The fix is simple - since we add one to the previous value when
encountering an enum without an initializer, the previous value
must start at -1 so that the first enum member is assigned 0.

The python generator code has had the off-by-one ever since DV
first wrote it years ago, but most of our public enums were immune
because they had an explicit = 0 initializer.  The only affected
enums are:
- virDomainEventGraphicsAddressType (such as
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4), since commit 987e31e
(libvirt v0.8.0)
- virDomainCoreDumpFormat (such as VIR_DOMAIN_CORE_DUMP_FORMAT_RAW),
since commit 9fbaff0 (libvirt v1.2.3)
- virIPAddrType (such as VIR_IP_ADDR_TYPE_IPV4), since commit
03e0e79 (not yet released)

Thanks to Nehal J Wani for reporting the problem on IRC, and
for helping me zero in on the culprit function.

* docs/apibuild.py (CParser.parseEnumBlock): Fix implicit enum
values.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 9b291bbe20)

Conflicts:
	docs/apibuild.py - context with 2a40951
2014-06-26 17:08:15 -06:00
Peter Krempa
39b5123dc0 qemu: blockcopy: Don't remove existing disk mirror info
When creating a new disk mirror the new struct is stored in a separate
variable until everything went well. The removed hunk would actually
remove existing mirror information for example when the api would be run
if a mirror still exists.

(cherry picked from commit 02b364e186)

This fixes a regression introduced in commit ff5f30b.

Signed-off-by: Eric Blake <eblake@redhat.com>

Conflicts:
	src/qemu/qemu_driver.c - no refactoring of commits 7b7bf001, 4f20226, a88fb30
2014-06-26 17:07:57 -06:00
Daniel P. Berrange
4410a83e18 LSN-2014-0003: Don't expand entities when parsing XML
If the XML_PARSE_NOENT flag is passed to libxml2, then any
entities in the input document will be fully expanded. This
allows the user to read arbitrary files on the host machine
by creating an entity pointing to a local file. Removing
the XML_PARSE_NOENT flag means that any entities are left
unchanged by the parser, or expanded to "" by the XPath
APIs.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit d6b27d3e4c)
2014-05-06 14:32:39 +01:00
Jim Fehlig
05afc98543 libxl: fix framebuffer port setting for HVM domains
libxl uses the libxl_vnc_info and libxl_sdl_info fields from the
hvm union in libxl_domain_build_info struct when generating QEMU
args for VNC or SDL.  These fields were left unset by the libxl
driver, causing libxl to ignore any user settings.  E.g. with

  <graphics type='vnc' port='5950'/>

port would be ignored and QEMU would instead be invoked with

  -vnc 127.0.0.1:0,to=99

Unlike the libxl_domain_config struct, the libxl_domain_build_info
contains only a single libxl_vnc_info and libxl_sdl_info, so
populate these fields from the first vfb in
libxl_domain_config->vfbs.

Signed-off-by: Jim Fehlig <jfehlig@suse.com>
Signed-off-by: David Kiarie <davidkiarie4@gmail.com>
(cherry picked from commit b55cc5f4e3)
2014-05-05 17:01:23 +03:00
Ján Tomko
8d4100bd8c Ignore additional fields in iscsiadm output
There has been a new field introduced in iscsiadm --mode session
output [1], but our regex only expects four fields. This breaks
startup of iscsi pools:
error: Failed to start pool iscsi
error: internal error: cannot find session

Fix this by ignoring anything after the fourth field.

https://bugzilla.redhat.com/show_bug.cgi?id=1067173

[1] https://github.com/mikechristie/open-iscsi/commit/181af9a

(cherry picked from commit 57e17a74b7)
2014-05-02 21:16:12 +02:00
Laine Stump
536197ba1f qemu: fix crash when removing <filterref> from interface with update-device
If a domain network interface that contains a <filterref> is modified
"live" using "virsh update-device --live", libvirtd would crash. This
was because the code supporting live update of an interface's
filterref was assuming that a filterref might be added or modified,
but didn't account for removing the filterref, resulting in a null
dereference of the filter name.

Introduced with commit 258fb278, which was first in libvirt v1.0.1.

This addresses https://bugzilla.redhat.com/show_bug.cgi?id=1093301

(cherry picked from commit 0eac9d1e90)
2014-05-01 16:15:00 +03:00
Martin Kletzander
846a1625eb qemu: make sure agent returns error when required data are missing
Commit 5b3492fa aimed to fix this and caught one error but exposed
another one.  When agent command is being executed and the thread
waiting for the reply is woken up by an event (e.g. EOF in case of
shutdown), the command finishes with no data (rxObject == NULL), but
no error is reported, since this might be desired by the caller
(e.g. suspend through agent).  However, in other situations, when the
data are required (e.g. getting vCPUs), we proceed to getting desired
data out of the reply, but none of the virJSON*() functions works well
with NULLs.  I chose the way of a new parameter for qemuAgentCommand()
function that specifies whether reply is required and behaves
according to that.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1058149

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
(cherry picked from commit 736e017e36)

Conflicts:
	src/qemu/qemu_agent.c -- vCPU functions (3099c063)
2014-04-09 18:38:54 +02:00
Martin Kletzander
42695c1c37 qemu: remove unneeded forward declaration
by moving qemuAgentCommand() after qemuAgentCheckError().

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
(cherry picked from commit e9d09fe196)

Conflicts:
        src/qemu/qemu_agent.c -- label indentation (5922d05a)
                                 comment removal (56874f01)
                                 VIR_ALLOC refactor (e987a30d)
2014-04-09 18:38:49 +02:00
Martin Kletzander
8aaa2c4086 qemu: cleanup error checking on agent replies
On all the places where qemuAgentComand() was called, we did a check
for errors in the reply.  Unfortunately, some of the places called
qemuAgentCheckError() without checking for non-null reply which might
have resulted in a crash.

So this patch makes the error-checking part of qemuAgentCommand()
itself, which:

 a) makes it look better,

 b) makes the check mandatory and, most importantly,

 c) checks for the errors if and only if it is appropriate.

This actually fixes a potential crashers when qemuAgentComand()
returned 0, but reply was NULL.  Having said that, it *should* fix the
following bug:

https://bugzilla.redhat.com/show_bug.cgi?id=1058149

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
(cherry picked from commit 5b3492fadb)

Conflicts:
	src/qemu/qemu_agent.c -- vCPU functions (3099c063)
2014-04-09 18:38:47 +02:00
Peter Krempa
5003b7c798 qemu: Properly report guest agent errors on command passthrough
The code for arbitrary guest agent passthrough was horribly broken since
introduction. Fix it to correctly report errors.

(cherry picked from commit 6e5b36d5d2)
2014-04-09 18:38:45 +02:00
Michal Privoznik
6b48d5e6f5 virNetClientSetTLSSession: Restore original signal mask
Currently, we use pthread_sigmask(SIG_BLOCK, ...) prior to calling
poll(). This is okay, as we don't want poll() to be interrupted.
However, then - immediately as we fall out from the poll() - we try to
restore the original sigmask - again using SIG_BLOCK. But as the man
page says, SIG_BLOCK adds signals to the signal mask:

SIG_BLOCK
      The set of blocked signals is the union of the current set and the set argument.

Therefore, when restoring the original mask, we need to completely
overwrite the one we set earlier and hence we should be using:

SIG_SETMASK
      The set of blocked signals is set to the argument set.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 3d4b4f5ac6)
2014-03-19 17:31:37 -06:00
Daniel P. Berrange
78c35ad5ab Add a mutex to serialize updates to firewall
The nwfilter conf update mutex previously serialized
updates to the internal data structures for firewall
rules, and updates to the firewall itself. The latter
was recently turned into a read/write lock, and filter
instantiation allowed to proceed in parallel. It was
believed that this was ok, since each filter is created
on a separate iptables/ebtables chain.

It turns out that there is a subtle lock ordering problem
on virNWFilterObjPtr instances. __virNWFilterInstantiateFilter
will hold a lock on the virNWFilterObjPtr it is instantiating.
This in turn invokes virNWFilterInstantiate which then invokes
virNWFilterDetermineMissingVarsRec which then invokes
virNWFilterObjFindByName. This iterates over every single
virNWFilterObjPtr in the list, locking them and checking their
name. So if 2 or more threads try to instantiate a filter in
parallel, they'll all hold 1 lock at the top level in the
__virNWFilterInstantiateFilter method which will cause the
other thread to deadlock in virNWFilterObjFindByName.

The fix is to add an exclusive mutex to serialize the
execution of __virNWFilterInstantiateFilter.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 925de19ed7)

Conflicts:
	src/nwfilter/nwfilter_gentech_driver.c
2014-03-10 12:52:59 +00:00
Daniel P. Berrange
f84056cf61 CVE-2013-6456: Avoid unsafe use of /proc/$PID/root in LXC hotunplug code
Rewrite multiple hotunplug functions to to use the
virProcessRunInMountNamespace helper. This avoids
risk of a malicious guest replacing /dev with an absolute
symlink, tricking the driver into changing the host OS
filesystem.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 5fc590ad9f)

Conflicts:
	src/lxc/lxc_driver.c: OOM + cgroups error reporting
2014-02-18 18:29:50 +00:00
Daniel P. Berrange
0e9fee68b3 CVE-2013-6456: Avoid unsafe use of /proc/$PID/root in LXC chardev hostdev hotplug
Rewrite lxcDomainAttachDeviceHostdevMiscLive function
to use the virProcessRunInMountNamespace helper. This avoids
risk of a malicious guest replacing /dev with a absolute
symlink, tricking the driver into changing the host OS
filesystem.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 1cadeafcaa)

Conflicts:
	src/lxc/lxc_driver.c: OOM + cgroups error reporting
2014-02-18 18:29:46 +00:00
Daniel P. Berrange
9849cf6d89 CVE-2013-6456: Avoid unsafe use of /proc/$PID/root in LXC block hostdev hotplug
Rewrite lxcDomainAttachDeviceHostdevStorageLive function
to use the virProcessRunInMountNamespace helper. This avoids
risk of a malicious guest replacing /dev with a absolute
symlink, tricking the driver into changing the host OS
filesystem.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 1754c7f0ab)

Conflicts:
	src/lxc/lxc_driver.c: OOM + cgroups error reporting
2014-02-18 18:29:42 +00:00
Daniel P. Berrange
21821ed4d1 CVE-2013-6456: Avoid unsafe use of /proc/$PID/root in LXC USB hotplug
Rewrite lxcDomainAttachDeviceHostdevSubsysUSBLive function
to use the virProcessRunInMountNamespace helper. This avoids
risk of a malicious guest replacing /dev with a absolute
symlink, tricking the driver into changing the host OS
filesystem.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 7fba01c15c)

Conflicts:
	src/lxc/lxc_driver.c: OOM + cgroups error reporting
2014-02-18 18:29:38 +00:00
Daniel P. Berrange
e57058cfe8 CVE-2013-6456: Avoid unsafe use of /proc/$PID/root in LXC disk hotplug
Rewrite lxcDomainAttachDeviceDiskLive function to use the
virProcessRunInMountNamespace helper. This avoids risk of
a malicious guest replacing /dev with a absolute symlink,
tricking the driver into changing the host OS filesystem.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 4dd3a7d5bc)

Conflicts:
	src/lxc/lxc_driver.c: OOM + cgroups error reporting and
        remove usernamespace integration
2014-02-18 18:29:32 +00:00
Eric Blake
e1e7e05376 CVE-2013-6456: Avoid unsafe use of /proc/$PID/root in LXC shutdown/reboot code
Use helper virProcessRunInMountNamespace in lxcDomainShutdownFlags and
lxcDomainReboot.  Otherwise, a malicious guest could use symlinks
to force the host to manipulate the wrong file in the host's namespace.

Idea by Dan Berrange, based on an initial report by Reco
<recoverym4n@gmail.com> at
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=732394

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit aebbcdd33c)

Conflicts:
	src/lxc/lxc_driver.c: OOM error reporting changes
	src/util/virinitctl.c: OOM error reporting changes
2014-02-18 18:27:19 +00:00
Daniel P. Berrange
1e731bb34d Add helper for running code in separate namespaces
Implement virProcessRunInMountNamespace, which runs callback of type
virProcessNamespaceCallback in a container namespace. This uses a
child process to run the callback, since you can't change the mount
namespace of a thread. This implies that callbacks have to be careful
about what code they run due to async safety rules.

Idea by Dan Berrange, based on an initial report by Reco
<recoverym4n@gmail.com> at
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=732394

Signed-off-by: Daniel Berrange <berrange@redhat.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 7c72ef6f55)

Backport fixed for OOM error reporting
2014-02-18 18:25:50 +00:00
Daniel P. Berrange
613b97051a Add virFileMakeParentPath helper function
Add a helper function which takes a file path and ensures
that all directory components leading up to the file exist.
IOW, it strips the filename part of the path and passes
the result to virFileMakePath.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit c321bfc5c3)

Conflicts:
	src/libvirt_private.syms,
	src/util/virfile.c,
	src/util/virfile.h: Moved code to virutil.{c,h}
2014-02-18 18:25:46 +00:00
Daniel P. Berrange
c376825b6c Move check for cgroup devices ACL upfront in LXC hotplug
The check for whether the cgroup devices ACL is available is
done quite late during LXC hotplug - in fact after the device
node is already created in the container in some cases. Better
to do it upfront so we fail immediately.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit c3eb12cace)
2014-02-18 18:24:22 +00:00
Daniel P. Berrange
43d0716d83 Disks are always block devices, never character devices
The LXC disk hotplug code was allowing block or character devices
to be given as disk. A disk is always a block device.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit d24e6b8b1e)
2014-02-18 18:24:15 +00:00
Daniel P. Berrange
769b92ced1 Fix reset of cgroup when detaching USB device from LXC guests
When detaching a USB device from an LXC guest we must remove
the device from the cgroup ACL. Unfortunately we were telling
the cgroup code to use the guest /dev path, not the host /dev
path, and the guest device node had already been unlinked.
This was, however, fortunate since the code passed &priv->cgroup
instead of priv->cgroup, so would have crash if the device node
were accessible.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 2c2bec94d2)
2014-02-18 18:24:11 +00:00
Daniel P. Berrange
681aff3fb5 Record hotplugged USB device in LXC live guest config
After hotplugging a USB device, the LXC driver forgot
to add the device def to the virDomainDefPtr.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit a537827d15)

Backport fixed for OOM error reporting
2014-02-18 18:24:01 +00:00
Daniel P. Berrange
9194b050d7 Fix path used for USB device attach with LXC
The LXC code missed the 'usb' component out of the path
/dev/bus/usb/$BUSNUM/$DEVNUM, so it failed to actually
setup cgroups for the device. This was in fact lucky
because the call to virLXCSetupHostUsbDeviceCgroup
was also mistakenly passing '&priv->cgroup' instead of
just 'priv->cgroup'. So once the path is fixed, libvirtd
would then crash trying to access the bogus virCgroupPtr
pointer. This would have been a security issue, were it
not for the bogus path preventing the pointer reference
being reached.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit c364897222)
2014-02-18 18:01:58 +00:00
Daniel P. Berrange
5d3891ffa2 Don't block use of USB with containers
virDomainDefCompatibleDevice blocks use of USB if no USB
controller is present. This is not correct for containers
since devices can be assigned directly regardless of any
controllers.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 7a44af963e)
2014-02-18 17:48:47 +00:00
Eric Blake
5967039eb6 storage: avoid short reads while chasing backing chain
Our backing file chain code was not very robust to an ill-timed
EINTR, which could lead to a short read causing us to randomly
treat metadata differently than usual.  But the existing
virFileReadLimFD forces an error if we don't read the entire
file, even though we only care about the header of the file.
So add a new virFile function that does what we want.

* src/util/virfile.h (virFileReadHeaderFD): New prototype.
* src/util/virfile.c (virFileReadHeaderFD): New function.
* src/libvirt_private.syms (virfile.h): Export it.
* src/util/virstoragefile.c (virStorageFileGetMetadataInternal)
(virStorageFileProbeFormatFromFD): Use it.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 5327fad4f2)

Conflicts:
	src/util/virstoragefile.c: OOM error reporting & buffer signedness

Conflicts:
	src/libvirt_private.syms,
	src/util/virfile.c,
	src/util/virfile.h: Moved code to virutil.{c,h}
2014-02-18 17:38:35 +00:00
Eric Blake
66fdc02e95 maint: fix comment typos
* src/lxc/lxc_controller.c (virLXCControllerSetupDisk): Fix typo.
* src/lxc/lxc_driver.c (lxcDomainAttachDeviceDiskLive): Likewise.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 8de47efd3f)

Conflicts:
	src/lxc/lxc_controller.c: No userns support yet
2014-02-18 17:38:17 +00:00
Chen Hanxiao
2eec7e0357 LXC: free dst before lxcDomainAttachDeviceDiskLive returns
Free dst before lxcDomainAttachDeviceDiskLive returns

Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com>
(cherry picked from commit c82513acc2)
2014-02-18 17:37:48 +00:00
Hongwei Bi
d5557a3a58 LXC: Free variable vroot in lxcDomainDetachDeviceHostdevUSBLive()
The variable vroot should be freed in label cleanup.

(cherry picked from commit 46c9bce4c8)
2014-02-18 17:37:41 +00:00
Yuri Chornoivan
b9fa12b328 Fix minor typos in messages and docs
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 5b4c035b08)

Conflicts:
	docs/news.html.in: old releases
2014-02-18 17:37:25 +00:00
Gao feng
d4424a37fc LXC: hostdev: create parent directory for hostdev
Create parent directroy for hostdev automatically when we
start a lxc domain or attach a hostdev to a lxc domain.

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
(cherry picked from commit 468ee0bc4d)
2014-02-18 17:37:21 +00:00
Daniel P. Berrange
bb48b8f5ee Stop passing around old root directory prefix
Many methods accept a string parameter specifying the
old root directory prefix. Since removal of the non-pivot
root container setup codepaths, this parameter is obsolete
in many methods where the callers always pass "/.oldroot".

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 31453a837b)
2014-02-18 17:37:16 +00:00
Gao feng
3bdb7f883e LXC: hostdev: introduce lxcContainerSetupHostdevCapsMakePath
This helper function is used to create parent directory for
the hostdev which will be added to the container. If the
parent directory of this hostdev doesn't exist, the mknod of
the hostdev will fail. eg with /dev/net/tun

Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
(cherry picked from commit c0d8c7c885)

Adapted to lack of VIR_STRDUP
2014-02-18 17:36:55 +00:00
Daniel P. Berrange
419ea63029 Push nwfilter update locking up to top level
The NWFilter code has as a deadlock race condition between
the virNWFilter{Define,Undefine} APIs and starting of guest
VMs due to mis-matched lock ordering.

In the virNWFilter{Define,Undefine} codepaths the lock ordering
is

  1. nwfilter driver lock
  2. virt driver lock
  3. nwfilter update lock
  4. domain object lock

In the VM guest startup paths the lock ordering is

  1. virt driver lock
  2. domain object lock
  3. nwfilter update lock

As can be seen the domain object and nwfilter update locks are
not acquired in a consistent order.

The fix used is to push the nwfilter update lock upto the top
level resulting in a lock ordering for virNWFilter{Define,Undefine}
of

  1. nwfilter driver lock
  2. nwfilter update lock
  3. virt driver lock
  4. domain object lock

and VM start using

  1. nwfilter update lock
  2. virt driver lock
  3. domain object lock

This has the effect of serializing VM startup once again, even if
no nwfilters are applied to the guest. There is also the possibility
of deadlock due to a call graph loop via virNWFilterInstantiate
and virNWFilterInstantiateFilterLate.

These two problems mean the lock must be turned into a read/write
lock instead of a plain mutex at the same time. The lock is used to
serialize changes to the "driver->nwfilters" hash, so the write lock
only needs to be held by the define/undefine methods. All other
methods can rely on a read lock which allows good concurrency.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 6e5c79a1b5)

Conflicts:
	src/conf/nwfilter_conf.c
          - virReportOOMError() in context of one hunk.
	src/lxc/lxc_driver.c
          - functions renamed, and lxc object locking changed, creating
            a conflict in the context.
2014-02-06 15:17:26 +02:00
Daniel P. Berrange
7596594301 Add a read/write lock implementation
Add virRWLock backed up by a POSIX rwlock primitive

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit c065984b58)
2014-02-06 15:17:19 +02:00
Daniel P. Berrange
11a31c0880 Don't ignore errors parsing nwfilter rules
For inexplicable reasons, the nwfilter XML parser is intentionally
ignoring errors that arise during parsing. As well as meaning that
users don't get any feedback on their XML mistakes, this will lead
it to silently drop data in OOM conditions.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 4f2094346d)

Conflicts:
	tests/nwfilterxml2xmltest.c
          - args to virNWFilterDefParseString are different, causing
            small conflict in context.
2014-02-06 15:05:31 +02:00
Cole Robinson
49c6f2688b Prep for release 1.0.5.9 2014-01-16 20:33:29 -05:00
Daniel P. Berrange
eafb61dcd9 Fix race leading to crash when setting up dbus watches
Currently the virDBusAddWatch does

  virEventAddHandle(fd, flags,
                    virDBusWatchCallback,
                    watch, NULL);
  dbus_watch_set_data(watch, info, virDBusWatchFree);

Unfortunately this is racy - since the event loop is in a
different thread, the virDBusWatchCallback method may be
run before we get to calling dbus_watch_set_data. We must
reverse the order of these calls

See https://bugzilla.redhat.com/show_bug.cgi?id=885445

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 7d3a1c8bd1)
2014-01-16 17:30:43 -05:00
Jiri Denemark
99f8d97aa7 Really don't crash if a connection closes early
https://bugzilla.redhat.com/show_bug.cgi?id=1047577

When writing commit 173c291, I missed the fact virNetServerClientClose
unlocks the client object before actually clearing client->sock and thus
it is possible to hit a window when client->keepalive is NULL while
client->sock is not NULL. I was thinking client->sock == NULL was a
better check for a closed connection but apparently we have to go with
client->keepalive == NULL to actually fix the crash.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 066c8ef6c1)
2014-01-15 10:36:44 -07:00
Jiri Denemark
c4d275c935 Don't crash if a connection closes early
https://bugzilla.redhat.com/show_bug.cgi?id=1047577

When a client closes its connection to libvirtd early during
virConnectOpen, more specifically just after making
REMOTE_PROC_CONNECT_SUPPORTS_FEATURE call to check if
VIR_DRV_FEATURE_PROGRAM_KEEPALIVE is supported without even waiting for
the result, libvirtd may crash due to a race in keep-alive
initialization. Once receiving the REMOTE_PROC_CONNECT_SUPPORTS_FEATURE
call, the daemon's event loop delegates it to a worker thread. In case
the event loop detects EOF on the connection and calls
virNetServerClientClose before the worker thread starts to handle
REMOTE_PROC_CONNECT_SUPPORTS_FEATURE call, client->keepalive will be
disposed by the time virNetServerClientStartKeepAlive gets called from
remoteDispatchConnectSupportsFeature. Because the flow is common for
both authenticated and read-only connections, even unprivileged clients
may cause the daemon to crash.

To avoid the crash, virNetServerClientStartKeepAlive needs to check if
the connection is still open before starting keep-alive protocol.

Every libvirt release since 0.9.8 is affected by this bug.

(cherry picked from commit 173c291473)
2014-01-15 10:36:44 -07:00
Jiri Denemark
dee5fc7566 qemu: Fix job usage in virDomainGetBlockIoTune
CVE-2013-6458

Every API that is going to begin a job should do that before fetching
data from vm->def.

(cherry picked from commit 3b56425938)
2014-01-15 10:36:44 -07:00
Jiri Denemark
0135324b9f qemu: Fix job usage in qemuDomainBlockCopy
Every API that is going to begin a job should do that before fetching
data from vm->def.

(cherry picked from commit ff5f30b6bf)

Conflicts:
	src/qemu/qemu_driver.c - context
2014-01-15 10:36:44 -07:00
Jiri Denemark
6cd879829a qemu: Fix job usage in qemuDomainBlockJobImpl
CVE-2013-6458

Every API that is going to begin a job should do that before fetching
data from vm->def.

(cherry picked from commit f93d2caa07)
2014-01-15 10:36:44 -07:00
Jiri Denemark
9233191890 qemu: Avoid using stale data in virDomainGetBlockInfo
CVE-2013-6458

Generally, every API that is going to begin a job should do that before
fetching data from vm->def. However, qemuDomainGetBlockInfo does not
know whether it will have to start a job or not before checking vm->def.
To avoid using disk alias that might have been freed while we were
waiting for a job, we use its copy. In case the disk was removed in the
meantime, we will fail with "cannot find statistics for device '...'"
error message.

(cherry picked from commit b799259583)

Conflicts:
	src/qemu/qemu_driver.c - VIR_STRDUP not backported
2014-01-15 10:36:19 -07:00
Jiri Denemark
c67b0de046 qemu: Do not access stale data in virDomainBlockStats
CVE-2013-6458
https://bugzilla.redhat.com/show_bug.cgi?id=1043069

When virDomainDetachDeviceFlags is called concurrently to
virDomainBlockStats: libvirtd may crash because qemuDomainBlockStats
finds a disk in vm->def before getting a job on a domain and uses the
disk pointer after getting the job. However, the domain in unlocked
while waiting on a job condition and thus data behind the disk pointer
may disappear. This happens when thread 1 runs
virDomainDetachDeviceFlags and enters monitor to actually remove the
disk. Then another thread starts running virDomainBlockStats, finds the
disk in vm->def, and while it's waiting on the job condition (owned by
the first thread), the first thread finishes the disk removal. When the
second thread gets the job, the memory pointed to be the disk pointer is
already gone.

That said, every API that is going to begin a job should do that before
fetching data from vm->def.

(cherry picked from commit db86da5ca2)

Conflicts:
	src/qemu/qemu_driver.c - context: no ACLs
2014-01-15 10:31:21 -07:00
Eric Blake
979d1bac9f tests: be more explicit on qcow2 versions in virstoragetest
While working on v1.0.5-maint (the branch in use on Fedora 19)
with the host at Fedora 20, I got a failure in virstoragetest.
I traced it to the fact that we were using qemu-img to create a
qcow2 file, but qemu-img changed from creating v2 files by
default in F19 to creating v3 files in F20.  Rather than leaving
it up to qemu-img, it is better to write the test to force
testing of BOTH file formats (better code coverage and all).

This patch alone does not fix all the failures in v1.0.5-maint;
for that, we must decide to either teach the older branch to
understand v3 files, or to reject them outright as unsupported.
But for upstream, making the test less dependent on changing
qemu-img defaults is always a good thing.

* tests/virstoragetest.c (testPrepImages): Simplify creation of
raw file; check if qemu supports compat and if so use it.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 974e591452)

Conflicts:
	tests/virstoragetest.c - hardcode test to v2, since this branch doesn't handle v3 correctly
2014-01-15 10:27:03 -07:00
Zeng Junliang
2dd4b39394 qemu: clean up migration ports when migration cancelled
If there's a migration cancelled, the bitmap of migration port should be
cleaned up too.

Signed-off-by: Zeng Junliang <zengjunliang@huawei.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit c92ca769af)
2014-01-09 14:25:35 +01:00
Michal Privoznik
c94b37d43e qemu: Fix augeas support for migration ports
Commit e3ef20d7 allows user to configure migration ports range via
qemu.conf. However, it forgot to update augeas definition file and
even the test data was malicious.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit d9be5a7157)

Conflicts:
  missing support for changing migration listen_address

	src/qemu/libvirtd_qemu.aug
	src/qemu/test_libvirtd_qemu.aug.in
2014-01-09 14:25:35 +01:00
Jiri Denemark
3f0c544119 qemu: Make migration port range configurable
https://bugzilla.redhat.com/show_bug.cgi?id=1019053
(cherry picked from commit e3ef20d7f7)

Conflicts:
  missing support for changing the migration listen address

	src/qemu/qemu.conf
	src/qemu/qemu_conf.c
	src/qemu/qemu_conf.h
	src/qemu/test_libvirtd_qemu.aug.in
2014-01-09 14:25:35 +01:00
Wang Yufei
1359673e42 qemu: Avoid assigning unavailable migration ports
https://bugzilla.redhat.com/show_bug.cgi?id=1019053

When we migrate vms concurrently, there's a chance that libvirtd on
destination assigns the same port for different migrations, which will
lead to migration failure during prepare phase on destination. So we use
virPortAllocator here to solve the problem.

Signed-off-by: Wang Yufei <james.wangyufei@huawei.com>
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 0196845d3a)

Conflicts:
  missing support for WebSockets and listen address
  virAsprintf doesn't report OOM

	src/qemu/qemu_command.h
	src/qemu/qemu_conf.h
	src/qemu/qemu_driver.c
	src/qemu/qemu_migration.c
2014-01-09 14:25:35 +01:00
Jiri Denemark
05700f6045 Don't spam logs with "port 0 must be in range" errors
Whenever virPortAllocatorRelease is called with port == 0, it complains
that the port is not in an allowed range, which is expectable as the
port was never allocated. Let's make virPortAllocatorRelease ignore 0
ports in a similar way free() ignores NULL pointers.

(cherry picked from commit 86dba8f3de)

Conflicts:
  missing VNC websocket support
	src/qemu/qemu_process.c
2014-01-09 14:25:35 +01:00
Martin Kletzander
2e35d28749 Fix crash in lxcDomainSetMemoryParameters
The function doesn't check whether the request is made for active or
inactive domain.  Thus when the domain is not running it still tries
accessing non-existing cgroups (priv->cgroup, which is NULL).

I re-made the function in order for it to work the same way it's qemu
counterpart does.

Reproducer:
 1) Define an LXC domain
 2) Do 'virsh memtune <domain> --hard-limit 133T'

Backtrace:
 Thread 6 (Thread 0x7fffec8c0700 (LWP 26826)):
 #0  0x00007ffff70edcc4 in virCgroupPathOfController (group=0x0, controller=3,
     key=0x7ffff75734bd "memory.limit_in_bytes", path=0x7fffec8bf718) at util/vircgroup.c:1764
 #1  0x00007ffff70e9206 in virCgroupSetValueStr (group=0x0, controller=3,
     key=0x7ffff75734bd "memory.limit_in_bytes", value=0x7fffe409f360 "1073741824")
     at util/vircgroup.c:669
 #2  0x00007ffff70e98b4 in virCgroupSetValueU64 (group=0x0, controller=3,
     key=0x7ffff75734bd "memory.limit_in_bytes", value=1073741824) at util/vircgroup.c:740
 #3  0x00007ffff70ee518 in virCgroupSetMemory (group=0x0, kb=1048576) at util/vircgroup.c:1904
 #4  0x00007ffff70ee675 in virCgroupSetMemoryHardLimit (group=0x0, kb=1048576)
     at util/vircgroup.c:1944
 #5  0x00005555557d54c8 in lxcDomainSetMemoryParameters (dom=0x7fffe40cc420,
     params=0x7fffe409f100, nparams=1, flags=0) at lxc/lxc_driver.c:774
 #6  0x00007ffff72c20f9 in virDomainSetMemoryParameters (domain=0x7fffe40cc420,
     params=0x7fffe409f100, nparams=1, flags=0) at libvirt.c:4051
 #7  0x000055555561365f in remoteDispatchDomainSetMemoryParameters (server=0x555555eb7e00,
     client=0x555555ec4b10, msg=0x555555eb94e0, rerr=0x7fffec8bfb70, args=0x7fffe40b8510)
     at remote_dispatch.h:7621
 #8  0x00005555556133fd in remoteDispatchDomainSetMemoryParametersHelper (server=0x555555eb7e00,
     client=0x555555ec4b10, msg=0x555555eb94e0, rerr=0x7fffec8bfb70, args=0x7fffe40b8510,
     ret=0x7fffe40b84f0) at remote_dispatch.h:7591
 #9  0x00007ffff73b293f in virNetServerProgramDispatchCall (prog=0x555555ec3ae0,
     server=0x555555eb7e00, client=0x555555ec4b10, msg=0x555555eb94e0)
     at rpc/virnetserverprogram.c:435
 #10 0x00007ffff73b207f in virNetServerProgramDispatch (prog=0x555555ec3ae0,
     server=0x555555eb7e00, client=0x555555ec4b10, msg=0x555555eb94e0)
     at rpc/virnetserverprogram.c:305
 #11 0x00007ffff73a4d2c in virNetServerProcessMsg (srv=0x555555eb7e00, client=0x555555ec4b10,
     prog=0x555555ec3ae0, msg=0x555555eb94e0) at rpc/virnetserver.c:165
 #12 0x00007ffff73a4e8d in virNetServerHandleJob (jobOpaque=0x555555ec3e30, opaque=0x555555eb7e00)
     at rpc/virnetserver.c:186
 #13 0x00007ffff7187f3f in virThreadPoolWorker (opaque=0x555555eb7ac0) at util/virthreadpool.c:144
 #14 0x00007ffff718733a in virThreadHelper (data=0x555555eb7890) at util/virthreadpthread.c:161
 #15 0x00007ffff468ed89 in start_thread (arg=0x7fffec8c0700) at pthread_create.c:308
 #16 0x00007ffff3da26bd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
(cherry picked from commit 9faf3f2950)

Conflicts:
	src/lxc/lxc_driver.c
2013-12-20 13:40:17 +00:00
Martin Kletzander
218bd2e871 CVE-2013-6436: fix crash in lxcDomainGetMemoryParameters
The function doesn't check whether the request is made for active or
inactive domain.  Thus when the domain is not running it still tries
accessing non-existing cgroups (priv->cgroup, which is NULL).

I re-made the function in order for it to work the same way it's qemu
counterpart does.

Reproducer:
 1) Define an LXC domain
 2) Do 'virsh memtune <domain>'

Backtrace:
 Thread 6 (Thread 0x7fffec8c0700 (LWP 13387)):
 #0  0x00007ffff70edcc4 in virCgroupPathOfController (group=0x0, controller=3,
     key=0x7ffff75734bd "memory.limit_in_bytes", path=0x7fffec8bf750) at util/vircgroup.c:1764
 #1  0x00007ffff70e958c in virCgroupGetValueStr (group=0x0, controller=3,
     key=0x7ffff75734bd "memory.limit_in_bytes", value=0x7fffec8bf7c0) at util/vircgroup.c:705
 #2  0x00007ffff70e9d29 in virCgroupGetValueU64 (group=0x0, controller=3,
     key=0x7ffff75734bd "memory.limit_in_bytes", value=0x7fffec8bf810) at util/vircgroup.c:804
 #3  0x00007ffff70ee706 in virCgroupGetMemoryHardLimit (group=0x0, kb=0x7fffec8bf8a8)
     at util/vircgroup.c:1962
 #4  0x00005555557d590f in lxcDomainGetMemoryParameters (dom=0x7fffd40024a0,
     params=0x7fffd40027a0, nparams=0x7fffec8bfa24, flags=0) at lxc/lxc_driver.c:826
 #5  0x00007ffff72c28d3 in virDomainGetMemoryParameters (domain=0x7fffd40024a0,
     params=0x7fffd40027a0, nparams=0x7fffec8bfa24, flags=0) at libvirt.c:4137
 #6  0x000055555563714d in remoteDispatchDomainGetMemoryParameters (server=0x555555eb7e00,
     client=0x555555ebaef0, msg=0x555555ebb3e0, rerr=0x7fffec8bfb70, args=0x7fffd40024e0,
     ret=0x7fffd4002420) at remote.c:1895
 #7  0x00005555556052c4 in remoteDispatchDomainGetMemoryParametersHelper (server=0x555555eb7e00,
     client=0x555555ebaef0, msg=0x555555ebb3e0, rerr=0x7fffec8bfb70, args=0x7fffd40024e0,
     ret=0x7fffd4002420) at remote_dispatch.h:4050
 #8  0x00007ffff73b293f in virNetServerProgramDispatchCall (prog=0x555555ec3ae0,
     server=0x555555eb7e00, client=0x555555ebaef0, msg=0x555555ebb3e0)
     at rpc/virnetserverprogram.c:435
 #9  0x00007ffff73b207f in virNetServerProgramDispatch (prog=0x555555ec3ae0,
     server=0x555555eb7e00, client=0x555555ebaef0, msg=0x555555ebb3e0)
     at rpc/virnetserverprogram.c:305
 #10 0x00007ffff73a4d2c in virNetServerProcessMsg (srv=0x555555eb7e00, client=0x555555ebaef0,
     prog=0x555555ec3ae0, msg=0x555555ebb3e0) at rpc/virnetserver.c:165
 #11 0x00007ffff73a4e8d in virNetServerHandleJob (jobOpaque=0x555555ebc7e0, opaque=0x555555eb7e00)
     at rpc/virnetserver.c:186
 #12 0x00007ffff7187f3f in virThreadPoolWorker (opaque=0x555555eb7ac0) at util/virthreadpool.c:144
 #13 0x00007ffff718733a in virThreadHelper (data=0x555555eb7890) at util/virthreadpthread.c:161
 #14 0x00007ffff468ed89 in start_thread (arg=0x7fffec8c0700) at pthread_create.c:308
 #15 0x00007ffff3da26bd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
(cherry picked from commit f8c1cb9021)

Conflicts:
	src/lxc/lxc_driver.c
2013-12-20 13:40:14 +00:00
Cole Robinson
2d0a9b97bb Prep for release 1.0.5.8 2013-12-14 14:26:49 -05:00
Christophe Fergeau
46a6015bec Tie SASL callbacks lifecycle to virNetSessionSASLContext
The array of sasl_callback_t callbacks which is passed to sasl_client_new()
must be kept alive as long as the created sasl_conn_t object is alive as
cyrus-sasl uses this structure internally for things like logging, so
the memory used for callbacks must only be freed after sasl_dispose() has
been called.

During testing of successful SASL logins with
virsh -c qemu+tls:///system list --all
I've been getting invalid read reports from valgrind

==9237== Invalid read of size 8
==9237==    at 0x6E93B6F: _sasl_getcallback (common.c:1745)
==9237==    by 0x6E95430: _sasl_log (common.c:1850)
==9237==    by 0x16593D87: digestmd5_client_mech_dispose (digestmd5.c:4580)
==9237==    by 0x6E91653: client_dispose (client.c:332)
==9237==    by 0x6E9476A: sasl_dispose (common.c:851)
==9237==    by 0x4E225A1: virNetSASLSessionDispose (virnetsaslcontext.c:678)
==9237==    by 0x4CBC551: virObjectUnref (virobject.c:262)
==9237==    by 0x4E254D1: virNetSocketDispose (virnetsocket.c:1042)
==9237==    by 0x4CBC551: virObjectUnref (virobject.c:262)
==9237==    by 0x4E2701C: virNetSocketEventFree (virnetsocket.c:1794)
==9237==    by 0x4C965D3: virEventPollCleanupHandles (vireventpoll.c:583)
==9237==    by 0x4C96987: virEventPollRunOnce (vireventpoll.c:652)
==9237==    by 0x4C94730: virEventRunDefaultImpl (virevent.c:274)
==9237==    by 0x12C7BA: vshEventLoop (virsh.c:2407)
==9237==    by 0x4CD3D04: virThreadHelper (virthreadpthread.c:161)
==9237==    by 0x7DAEF32: start_thread (pthread_create.c:309)
==9237==    by 0x8C86EAC: clone (clone.S:111)
==9237==  Address 0xe2d61b0 is 0 bytes inside a block of size 168 free'd
==9237==    at 0x4A07577: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==9237==    by 0x4C73827: virFree (viralloc.c:580)
==9237==    by 0x4DE4BC7: remoteAuthSASL (remote_driver.c:4219)
==9237==    by 0x4DE33D0: remoteAuthenticate (remote_driver.c:3639)
==9237==    by 0x4DDBFAA: doRemoteOpen (remote_driver.c:832)
==9237==    by 0x4DDC8DC: remoteConnectOpen (remote_driver.c:1031)
==9237==    by 0x4D8595F: do_open (libvirt.c:1239)
==9237==    by 0x4D863F3: virConnectOpenAuth (libvirt.c:1481)
==9237==    by 0x12762B: vshReconnect (virsh.c:337)
==9237==    by 0x12C9B0: vshInit (virsh.c:2470)
==9237==    by 0x12E9A5: main (virsh.c:3338)

This commit changes virNetSASLSessionNewClient() to take ownership of the SASL
callbacks. Then we can free them in virNetSASLSessionDispose() after the corresponding
sasl_conn_t has been freed.

(cherry picked from commit 13fdc6d63e)
2013-12-14 13:44:31 -05:00
Jiri Denemark
140485abaf spec: Don't save/restore running VMs on libvirt-client update
The previous attempt (commit d65e0e1) removed just one of two
libvirt-guests restarts that happened on libvirt-client update. Let's
remove the last one too :-)

https://bugzilla.redhat.com/show_bug.cgi?id=962225

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit 604f79b360)
2013-12-14 13:41:52 -05:00
Don Dugger
dba6ded80d Return right error code for baselineCPU
This Python interface code is returning a -1 on errors for the
`baselineCPU' API.  Since this API is supposed to return a pointer
the error return value should really be VIR_PY_NONE.

NB:  I've checked all the other APIs in this file and this is the
only pointer API that is returning -1.

Signed-off-by: Don Dugger <donald.d.dugger@intel.com>

(crobinso: Upstream in libvirt-python.git)
2013-12-14 13:39:20 -05:00
Cole Robinson
390ed2087c spec: Don't save/restore running VMs on libvirt-client update
Restarting an active libvirt-guests.service is the equivalent of
doing:

/usr/libexec/libvirt-guests.sh stop
/usr/libexec/libvirt-guests.sh start

Which in a default configuration will managedsave every running VM,
and then restore them. Certainly not something we should do every
time the libvirt-client RPM is updated.

Just drop the try-restart attempt, I don't know what purpose it
serves anyways.

https://bugzilla.redhat.com/show_bug.cgi?id=962225
(cherry picked from commit d65e0e1466)
2013-11-22 09:33:59 -05:00
Daniel P. Berrange
6b2e21795e Fix busy wait loop in LXC container I/O handling
If the host side of an LXC container console disconnected
and the guest side continued to write data, until the PTY
buffer filled up, the LXC controller would busy wait. It
would repeatedly see POLLHUP from poll() and not disable
the watch.

This was due to some bogus logic detecting blocking
conditions. Upon seeing a POLLHUP we must disable all
reading & writing from the PTY, and setup the epoll to
wake us up again when the connection comes back.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 5087a5a009)
2013-11-20 10:32:25 -05:00
Cole Robinson
bd719a0114 libvirt-guests: Run only after libvirtd
Possible fix for occasional libvirt-guests failure at boot time:

https://bugzilla.redhat.com/show_bug.cgi?id=906009
(cherry picked from commit d92036754a)
2013-11-20 09:04:09 -05:00
Guido Günther
777e19cb90 Don't depend on syslog.service
Syslog is socket activated since at least systemd v35 so we can drop
this dependency. Debian's linitian otherwise complains about it.

References:

    http://www.freedesktop.org/wiki/Software/systemd/syslog/
    http://lintian.debian.org/tags/systemd-service-file-refers-to-obsolete-target.html

(cherry picked from commit 3c9e40a1e8)
2013-11-20 09:04:06 -05:00
Jeremy Fitzhardinge
e51fa6486d libxl: fix dubious cpumask handling in libxlDomainSetVcpuAffinities
Rather than casting the virBitmap pointer to uint8_t* and then using
the structure contents as a byte array, use the virBitmap API to determine
the bitmap size and test each bit.

Signed-off-by: Jeremy Fitzhardinge <jeremy@goop.org>
(cherry picked from commit ba1bf10063)
2013-11-17 18:02:46 -05:00
Laine Stump
9265a89ae8 util: recognize SMB/CIFS filesystems as shared
This should resolve:

  https://bugzilla.redhat.com/show_bug.cgi?id=1012085

libvirt previously recognized NFS, GFS2, OCFS2, and AFS filesystems as
"shared", and thus eligible for exceptions to certain rules/actions
about chowning image files before handing them off to a guest. This
patch widens the definition of "shared filesystem" to include SMB and
CIFS filesystems (aka "Windows file sharing"); both of these use the
same protocol, but different drivers so there are different magic
numbers for each.

(cherry picked from commit e4e73337e5)
2013-11-17 18:02:40 -05:00
Ján Tomko
b2c87be92e Disable nwfilter driver when running unprivileged
When opening a new connection to the driver, nwfilterOpen
only succeeds if the driverState has been allocated.

Move the privilege check in driver initialization before
the state allocation to disable the driver.

This changes the nwfilter-define error from:
error: cannot create config directory (null): Bad address
To:
this function is not supported by the connection driver:
virNWFilterDefineXML

https://bugzilla.redhat.com/show_bug.cgi?id=1029266
(cherry picked from commit b7829f959b)
2013-11-13 11:02:20 +01:00
Jiri Denemark
c75683da9e spec: Explicitly require libgcrypt-devel
Our configure.ac says:

    Not all versions of gnutls include -lgcrypt, and so we add
    it explicitly for the calls to gcry_control/check_version

Thus we cannot rely on gnutls-devel to bring grcypt-devel as a
dependency.

(cherry picked from commit 3b50a711f0)
2013-11-06 13:55:32 -05:00
Cole Robinson
7fd01c6aa1 Prep for release 1.0.5.7 2013-11-06 12:36:15 -05:00
Michal Privoznik
11253a09f2 qemuSetupMemoryCgroup: Handle hard_limit properly
Since 16bcb3 we have a regression. The hard_limit is set
unconditionally. By default the limit is zero. Hence, if user hasn't
configured any, we set the zero in cgroup subsystem making the kernel
kill the corresponding qemu process immediately. The proper fix is to
set hard_limit iff user has configured any.

(cherry picked from commit 94a24dd3a9)

Conflicts:
	src/qemu/qemu_cgroup.c
2013-11-06 12:16:25 -05:00
Michal Privoznik
9421fd0010 qemu: Drop qemuDomainMemoryLimit
This function is to guess the correct limit for maximal memory
usage by qemu for given domain. This can never be guessed
correctly, not to mention all the pains and sleepless nights this
code has caused. Once somebody discovers algorithm to solve the
Halting Problem, we can compute the limit algorithmically. But
till then, this code should never see the light of the release
again.

(cherry picked from commit 16bcb3b616)

Conflicts:
	src/qemu/qemu_cgroup.c
	src/qemu/qemu_command.c
	src/qemu/qemu_domain.c
	src/qemu/qemu_domain.h
	src/qemu/qemu_hotplug.c
2013-11-06 11:42:45 -05:00
Zhou Yimin
03ba101aa2 remote: fix regression in event deregistration
Introduced by 7b87a3
When I quit the process which only register VIR_DOMAIN_EVENT_ID_REBOOT,
I got error like:
"libvirt: XML-RPC error : internal error: domain event 0 not registered".
Then I add the following code, it fixed.

Signed-off-by: Zhou Yimin <zhouyimin@huawei.com>
Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 9712c2510e)
2013-10-18 07:56:11 -06:00
Martin Kletzander
99fa1ade4b virsh: Fix debugging
Commit a0b6a36f "fixed" what abfff210 broke (URI precedence), but
there was still one more thing missing to fix.  When using virsh
parameters to setup debugging, those weren't honored, because at the
time debugging was initializing, arguments weren't parsed yet.  To
make ewerything work as expected, we need to initialize the debugging
twice, once before debugging (so we can debug option parsing properly)
and then again after these options are parsed.

As a side effect, this patch also fixes a leak when virsh is ran with
multiple '-l' parameters.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
(cherry picked from commit ac43da705f)
2013-10-18 08:11:34 +02:00
Martin Kletzander
4c881b5503 Fix URI connect precedence
Commit abfff210 changed the order of vshParseArgv() and vshInit() in
order to make fix debugging of parameter parsing.  However, vshInit()
did a vshReconnect() even though ctl->name wasn't set according to the
'-c' parameter yet.  In order to keep both issues fixed, I've split
the vshInit() into vshInitDebug() and vshInit().

One simple memleak of ctl->name is fixed as a part of this patch,
since it is related to the issue it's fixing.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=999323
(cherry picked from commit a0b6a36f94)
2013-10-15 15:48:22 +02:00
Liuji (Jeremy)
cdc148ec5b virDomainDefParseXML: set the argument of virBitmapFree to NULL after calling virBitmapFree
After freeing the bitmap pointer, it must set the pointer to NULL.
This will avoid any other use of the freed memory of the bitmap pointer.

https://bugzilla.redhat.com/show_bug.cgi?id=1006710

Signed-off-by: Liuji (Jeremy) <jeremy.liu@huawei.com>
(cherry picked from commit ef5d51d491)
2013-10-15 15:17:44 +02:00
Daniel Hansel
e69a585db4 build: Add lxc testcase to dist list
Introduced by commit 3f029fb531 the RPM build
was broken due to a missing LXC textcase.

Signed-off-by: Daniel Hansel <daniel.hansel@linux.vnet.ibm.com>
(cherry picked from commit 6285c17f79)
2013-10-15 15:17:33 +02:00
Ján Tomko
34ba55e9e2 LXC: Fix handling of RAM filesystem size units
Since 76b644c when the support for RAM filesystems was introduced,
libvirt accepted the following XML:
<source usage='1024' unit='KiB'/>

This was parsed correctly and internally stored in bytes, but it
was formatted as (with an extra 's'):
<source usage='1024' units='KiB'/>
When read again, this was treated as if the units were missing,
meaning libvirt was unable to parse its own XML correctly.

The usage attribute was documented as being in KiB, but it was not
scaled if the unit was missing. Transient domains still worked,
because this was balanced by an extra 'k' in the mount options.

This patch:
Changes the parser to use 'units' instead of 'unit', as the latter
was never documented (fixing persistent domains) and some programs
(libvirt-glib, libvirt-sandbox) already parse the 'units' attribute.

Removes the extra 'k' from the tmpfs mount options, which is needed
because now we parse our own XML correctly.

Changes the default input unit to KiB to match documentation, fixing:
https://bugzilla.redhat.com/show_bug.cgi?id=1015689
(cherry picked from commit 3f029fb531)

Conflicts:
	src/conf/domain_conf.c
	src/conf/domain_conf.h - missing format
	src/lxc/lxc_container.c - virAsprintf doesn't report OOM errors
	tests/lxcxml2xmltest.c - missing format test
2013-10-15 13:26:55 +02:00
Michal Privoznik
5b2b4d5e63 qemuMonitorJSONSendKey: Avoid double free
After successful @cmd construction the memory where @keys points to is
part of @cmd. Avoid double freeing it.
(cherry picked from commit 3e8343e151)
2013-10-15 13:26:55 +02:00
Jiri Denemark
168f70cfe9 virsh domjobinfo: Do not return 1 if job is NONE
https://bugzilla.redhat.com/show_bug.cgi?id=1006864

Commit 38ab1225 changed the default value of ret from true to false but
forgot to set ret = true when job is NONE. Thus, virsh domjobinfo
returned 1 when there was no job running for a domain but it used to
(and should) return 0 in this case.
(cherry picked from commit f084caae7c)
2013-10-15 13:26:55 +02:00
Daniel P. Berrange
c22cb488de Remove use of virConnectPtr from all remaining nwfilter code
The virConnectPtr is passed around loads of nwfilter code in
order to provide it as a parameter to the callback registered
by the virt drivers. None of the virt drivers use this param
though, so it serves no purpose.

Avoiding the need to pass a virConnectPtr means that the
nwfilterStateReload method no longer needs to open a bogus
QEMU driver connection. This addresses a race condition that
can lead to a crash on startup.

The nwfilter driver starts before the QEMU driver and registers
some callbacks with DBus to detect firewalld reload. If the
firewalld reload happens while the QEMU driver is still starting
up though, the nwfilterStateReload method will open a connection
to the partially initialized QEMU driver and cause a crash.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 999d72fbd5)

Conflicts:
	src/nwfilter/nwfilter_driver.c
2013-10-07 09:55:30 -04:00
Daniel P. Berrange
0b9f930836 Don't pass virConnectPtr in nwfilter 'struct domUpdateCBStruct'
The nwfilter driver only needs a reference to its private
state object, not a full virConnectPtr. Update the domUpdateCBStruct
struct to have a 'void *opaque' field instead of a virConnectPtr.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit ebca369e3f)
2013-10-07 09:53:33 -04:00
Daniel P. Berrange
3598addc9e Remove virConnectPtr arg from virNWFilterDefParse*
None of the virNWFilterDefParse* methods require a virConnectPtr
arg, so just drop it

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit b77b16ce41)

Conflicts:
	tests/nwfilterxml2xmltest.c
2013-10-07 09:53:23 -04:00
Michal Privoznik
f22180a383 virNetDevBandwidthEqual: Make it more robust
So far the virNetDevBandwidthEqual() expected both ->in and ->out items
to be allocated for both @a and @b compared. This is not necessary true
for all our code. For instance, running 'update-device' twice over a NIC
with the very same XML results in SIGSEGV-ing in this function.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit ee02fbc8e4)
2013-10-07 09:51:48 -04:00
Michal Privoznik
e6f4742b97 qemu_hotplug: Allow QoS update in qemuDomainChangeNet
The qemuDomainChangeNet() is called when 'virsh update-device' is
invoked on a NIC. Currently, we fail to update the QoS even though
we have routines for that.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
(cherry picked from commit 9fa10d3901)
2013-10-07 09:51:48 -04:00
Peter Krempa
eaf803e7f0 qemu: Use "migratable" XML definition when doing external checkpoints
In the original implementation of external checkpoints I've mistakenly
used the live definition to be stored in the save image. The normal
approach is to use the "migratable" definition. This was discovered when
commit 07966f6a8b changed the behavior to
use a converted XML from the user to do the compatibility check to fix
problem when using the regular machine saving.

As the previous patch added a compatibility layer, we can now change the
type of the XML in the image.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1008340
(cherry picked from commit 1b7bfa65e3)
2013-10-06 14:46:18 -04:00
Peter Krempa
51a1506b29 qemu: Fix checking of ABI stability when restoring external checkpoints
External checkpoints have a bug in the implementation where they use the
normal definition instead of the "migratable" one. This causes errors
when the snapshot is being reverted using the workaround method via
qemuDomainRestoreFlags() with a custom XML. This issue was introduced
when commit 07966f6a8b changed the code to
compare "migratable" XMLs from the user as we should have used
migratable in the image too.

This patch adds a compatibility layer, so that fixing the snapshot code
won't make existing snapshots fail to load.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1008340
(cherry picked from commit 59898a88ce)
2013-10-06 14:46:18 -04:00
Osier Yang
729bd0a37a virsh: Fix regression of vol-resize
Introduced by commit 1daa4ba33a. vshCommandOptStringReq returns
0 on *success* or the option is not required && not present, both
are right result. Error out when returning 0 is not correct.
the caller, it doesn't have to check wether it
(cherry picked from commit 2a3a725c33)
2013-10-03 10:00:05 +02:00
Cole Robinson
3e070c81ab Prep for release 1.0.5.6 2013-09-20 16:30:44 -04:00
Guannan Ren
ff165c6a92 virsh: fix change-media bug on disk block type
Resolves:https://bugzilla.redhat.com/show_bug.cgi?id=923053
When cdrom is block type, the virsh change-media failed to insert
source info because virsh uses "<source block='/dev/sdb'/>" while
the correct name of the attribute for block disks is "dev".

(cherry picked from commit 7729a16814)
2013-09-20 15:54:53 -04:00
Daniel P. Berrange
118d26dc1f Fix crash in remoteDispatchDomainMemoryStats (CVE-2013-4296)
The 'stats' variable was not initialized to NULL, so if some
early validation of the RPC call fails, it is possible to jump
to the 'cleanup' label and VIR_FREE an uninitialized pointer.
This is a security flaw, since the API can be called from a
readonly connection which can trigger the validation checks.

This was introduced in release v0.9.1 onwards by

  commit 158ba8730e
  Author: Daniel P. Berrange <berrange@redhat.com>
  Date:   Wed Apr 13 16:21:35 2011 +0100

    Merge all returns paths from dispatcher into single path

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit e7f400a110)

Conflicts:
	daemon/remote.c - context
2013-09-18 14:03:38 -06:00
Daniel P. Berrange
85ca41529d Add support for using 3-arg pkcheck syntax for process (CVE-2013-4311)
With the existing pkcheck (pid, start time) tuple for identifying
the process, there is a race condition, where a process can make
a libvirt RPC call and in another thread exec a setuid application,
causing it to change to effective UID 0. This in turn causes polkit
to do its permission check based on the wrong UID.

To address this, libvirt must get the UID the caller had at time
of connect() (from SO_PEERCRED) and pass a (pid, start time, uid)
triple to the pkcheck program.

Signed-off-by: Colin Walters <walters@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 922b7fda77)

Conflicts:
	src/access/viraccessdriverpolkit.c

Resolution:
  Dropped file that does not exist in this branch.
2013-09-18 12:22:38 -06:00
Daniel P. Berrange
4407b19b83 Include process start time when doing polkit checks
Since PIDs can be reused, polkit prefers to be given
a (PID,start time) pair. If given a PID on its own,
it will attempt to lookup the start time in /proc/pid/stat,
though this is subject to races.

It is safer if the client app resolves the PID start
time itself, because as long as the app has the client
socket open, the client PID won't be reused.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 979e9c56a7)
Signed-off-by: Eric Blake <eblake@redhat.com>

Conflicts:
	src/rpc/virnetsocket.h - context
	src/util/virprocess.c - needed #include "virstring.h"
	src/util/virstring.c - context
	src/util/virstring.h - context
2013-09-18 12:22:25 -06:00
Michal Privoznik
073812898a qemuDomainChangeGraphics: Check listen address change by listen type
https://bugzilla.redhat.com/show_bug.cgi?id=1006697

Currently, we have a bug when updating a graphics device. A graphics device can
have a listen address set. This address is either defined by user (in which case
it's type is VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS) or it can be inherited
from a network (in which case it's type is
VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK). However, in both cases we have a
listen address to process (e.g. during migration, as I've tried to fix in
7f15ebc7).
Later, when a user tries to update the graphics device (e.g. set a password),
we check if listen addresses match the original as qemu doesn't know how to
change listen address yet. Hence, users are required to not change the listen
address. The implementation then just dumps listen addresses and compare them.
Previously, while dumping the listen addresses, NULL was returned for NETWORK.
After my patch, this is no longer true, and we get a listen address for olddev
even if it is a type of NETWORK. So we have a real string on one side, the NULL
from user's XML on the other side and hence we think user wants to change the
listen address and we refuse it.

Therefore, we must take the type of listen address into account as well.

(cherry picked from commit 752596b5dd)
2013-09-11 20:27:22 -06:00
Eric Blake
9a1145a987 security: provide supplemental groups even when parsing label (CVE-2013-4291)
Commit 29fe5d7 (released in 1.1.1) introduced a latent problem
for any caller of virSecurityManagerSetProcessLabel and where
the domain already had a uid:gid label to be parsed.  Such a
setup would collect the list of supplementary groups during
virSecurityManagerPreFork, but then ignores that information,
and thus fails to call setgroups() to adjust the supplementary
groups of the process.

Upstream does not use virSecurityManagerSetProcessLabel for
qemu (it uses virSecurityManagerSetChildProcessLabel instead),
so this problem remained latent until backporting the initial
commit into v0.10.2-maint (commit c061ff5, released in 0.10.2.7),
where virSecurityManagerSetChildProcessLabel has not been
backported.  As a result of using a different code path in the
backport, attempts to start a qemu domain that runs as qemu:qemu
will end up with supplementary groups unchanged from the libvirtd
parent process, rather than the desired supplementary groups of
the qemu user.  This can lead to failure to start a domain
(typical Fedora setup assigns user 107 'qemu' to both group 107
'qemu' and group 36 'kvm', so a disk image that is only readable
under kvm group rights is locked out).  Worse, it is a security
hole (the qemu process will inherit supplemental group rights
from the parent libvirtd process, which means it has access
rights to files owned by group 0 even when such files should
not normally be visible to user qemu).

LXC does not use the DAC security driver, so it is not vulnerable
at this time.  Still, it is better to plug the latent hole on
the master branch first, before cherry-picking it to the only
vulnerable branch v0.10.2-maint.

* src/security/security_dac.c (virSecurityDACGetIds): Always populate
groups and ngroups, rather than only when no label is parsed.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 745aa55fbf)
2013-08-29 09:17:31 -06:00
Guannan Ren
c43e7e20fc python: return dictionary without value in case of no blockjob
https://bugzilla.redhat.com/show_bug.cgi?id=999077

Currently, when there is no blockjob, dom.blockJobInfo('vda')
still reports error because it doesn't distinguish return value 0 from -1.
libvirt.libvirtError: virDomainGetBlockJobInfo() failed

virDomainGetBlockJobInfo() API return value:
 -1 in case of failure, 0 when nothing found, 1 found.

And use PyDict_SetItemString instead of PyDict_SetItem when key is
of string type. PyDict_SetItemString increments key/value reference
count, so call Py_DECREF() for value. For key, we don't need to
do this, because PyDict_SetItemString will handle it internally.

(cherry picked from commit 0f9e67bfad)
2013-08-20 11:44:55 -06:00
Peter Krempa
1ffdaced5b virbitmap: Refactor virBitmapParse to avoid access beyond bounds of array
The virBitmapParse function was calling virBitmapIsSet() function that
requires the caller to check the bounds of the bitmap without checking
them. This resulted into crashes when parsing a bitmap string that was
exceeding the bounds used as argument.

This patch refactors the function to use virBitmapSetBit without
checking if the bit is set (this function does the checks internally)
and then counts the bits in the bitmap afterwards (instead of keeping
track while parsing the string).

This patch also changes the "parse_error" label to a more common
"error".

The refactor should also get rid of the need to call sa_assert on the
returned variable as the callpath should allow coverity to infer the
possible return values.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=997367

Thanks to Alex Jia for tracking down the issue. This issue is introduced
by commit 0fc8909.

(cherry picked from commit 47b9127e88)
2013-08-20 14:13:43 +02:00
Cole Robinson
ed5274ca2e Prep for release 1.0.5.5 2013-08-01 17:48:53 -04:00
Ján Tomko
f32ea9937f Set the number of elements 0 in virNetwork*Clear
Decrementing it when it was already 0 causes an invalid free
in virNetworkDefUpdateDNSHost if virNetworkDNSHostDefParseXML
fails and virNetworkDNSHostDefClear gets called twice.

virNetworkForwardDefClear left the number untouched even if it
freed all the elements.
(cherry picked from commit c4e23388e6)
2013-08-01 17:14:41 +02:00
Ján Tomko
80fffee94b Don't check validity of missing attributes in DNS SRV XML
This fixes a crash if one of them is missing.

https://bugzilla.redhat.com/show_bug.cgi?id=988718
(cherry picked from commit 461fd86a66)
2013-08-01 17:14:27 +02:00
Ján Tomko
90688b148c cgroup: reuse buffer for getline
Reuse the buffer for getline and track buffer allocation
separately from the string length to prevent unlikely
out-of-bounds memory access.

This fixes the following leak that happened when zero bytes were read:

==404== 120 bytes in 1 blocks are definitely lost in loss record 1,344 of 1,671
==404==    at 0x4C2C71B: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==404==    by 0x906F862: getdelim (iogetdelim.c:68)
==404==    by 0x52A48FB: virCgroupPartitionNeedsEscaping (vircgroup.c:1136)
==404==    by 0x52A0FB4: virCgroupPartitionEscape (vircgroup.c:1171)
==404==    by 0x52A0EA4: virCgroupNewDomainPartition (vircgroup.c:1450)
(cherry picked from commit cc7329317f)
2013-08-01 17:14:14 +02:00
Wido den Hollander
c636c41af7 rbd: Do not free the secret if it is not set
Not all RBD (Ceph) storage pools have cephx authentication turned on,
so "secret" might not be initialized.

It could also be that the secret couldn't be located.

Only call virSecretFree() if "secret" is initialized earlier.

Signed-off-by: Wido den Hollander <wido@widodh.nl>
(cherry picked from commit d58c847844)
2013-08-01 17:13:58 +02:00
Guannan Ren
146d12c6cc caps: use -device for primary video when qemu >=1.6
libvirt: https://bugzilla.redhat.com/show_bug.cgi?id=986384

qemu: https://bugzilla.redhat.com/show_bug.cgi?id=981094
The commit 0ad9025ef introduce qemu flag QEMU_CAPS_DEVICE_VIDEO_PRIMARY
for using -device VGA, -device cirrus-vga, -device vmware-svga and
-device qxl-vga. In use, for -device qxl-vga, mouse doesn't display
in guest window like the desciption in above bug.
This patch try to use -device for primary video when qemu >=1.6 which
contains the bug fix patch

(cherry picked from commit e3f2686bdf)

Conflicts:
	src/qemu/qemu_capabilities.c - context with other new capabilities not backported
2013-07-29 16:43:05 -06:00
Eric Blake
ad4e7f90b4 examples: fix mingw build vs. printf
Mingw *printf is a moving target; newer mingw now provides a version
of asprintf() that fails to understand %lld:

  CC       event_test-event-test.o
../../../../examples/domain-events/events-c/event-test.c: In function 'myDomainEventRTCChangeCallback':
../../../../examples/domain-events/events-c/event-test.c:270:18: error: unknown conversion type character 'l' in format [-Werror=format=]
                  virDomainGetID(dom), offset) < 0)
                  ^

But since our examples already admitted that they were hacking around
a mingw deficiency, it is easier to just use printf() directly, coupled
with <inttypes.h> macros, for a more portable work-around.

* examples/domain-events/events-c/event-test.c
(myDomainEventRTCChangeCallback): Use PRIdMAX instead of asprintf.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 6f4458a017)
2013-07-29 16:20:29 -06:00
Eric Blake
ec15df4e85 build: fix virutil build on mingw
https://bugzilla.redhat.com/show_bug.cgi?id=964358

On platforms without decent group support, the build failed:

Cannot export virGetGroupList: symbol not defined
./.libs/libvirt_security_manager.a(libvirt_security_manager_la-security_dac.o): In function `virSecurityDACPreFork':
/home/eblake/libvirt-tmp/build/src/../../src/security/security_dac.c:248: undefined reference to `virGetGroupList'
collect2: error: ld returned 1 exit status

* src/util/virutil.c (virGetGroupList): Provide dummy implementation.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit cd725c7a93)
2013-07-29 16:17:40 -06:00
Eric Blake
aa11d6888f build: work around mingw header pollution
On Fedora 18, when cross-compiling to mingw with the mingw*-dbus
packages installed, compilation fails with:

  CC       libvirt_net_rpc_server_la-virnetserver.lo
In file included from /usr/i686-w64-mingw32/sys-root/mingw/include/dbus-1.0/dbus/dbus-connection.h:32:0,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/dbus-1.0/dbus/dbus-bus.h:30,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/dbus-1.0/dbus/dbus.h:31,
                 from ../../src/util/virdbus.h:26,
                 from ../../src/rpc/virnetserver.c:39:
/usr/i686-w64-mingw32/sys-root/mingw/include/dbus-1.0/dbus/dbus-message.h:74:58: error: expected ';', ',' or ')' before 'struct'

I have reported this as a bug against two packages:
- mingw-headers, for polluting the namespace
https://bugzilla.redhat.com/show_bug.cgi?id=980270
- dbus, for not dealing with the pollution
https://bugzilla.redhat.com/show_bug.cgi?id=980278

At least dbus has agreed that a future version of dbus headers will
do s/interface/iface/, regardless of what happens in mingw. But it
is also easy to workaround in libvirt in the meantime, without having
to wait for either mingw or dbus to upgrade.

* src/util/virdbus.h (includes): Undo mingw's pollution so that
dbus doesn't fail.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 1528e8b23a)
2013-07-29 16:13:48 -06:00
Eric Blake
543e5adf05 build: configure must not affect tarball contents
On mingw, configure sets the name of the lxc symfile to
libvirt_lxc.defs rather than libvirt_lxc.syms.  But tarballs
must be arch-independent, regardless of the configure options
used for the tree where we ran 'make dist'.  This led to the
following failure in autobuild.sh:

  CCLD     libvirt-lxc.la
  CCLD     libvirt-qemu.la
/usr/lib64/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/bin/ld: cannot find libvirt_lxc.def: No such file or directory
collect2: error: ld returned 1 exit status
make[3]: *** [libvirt-lxc.la] Error 1
make[3]: *** Waiting for unfinished jobs....

We were already doing the right thing with libvirt_qemu.syms.

* src/Makefile.am (EXTRA_DIST): Don't ship a built file which
depends on configure for its final name.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit d79c9273b0)
2013-07-29 16:13:44 -06:00
Eric Blake
ef10647e2e build: avoid build failure without gnutls
Found while trying to cross-compile to mingw:

  CC       libvirt_driver_remote_la-remote_driver.lo
../../src/remote/remote_driver.c: In function 'doRemoteOpen':
../../src/remote/remote_driver.c:487:23: error: variable 'verify' set but not used [-Werror=unused-but-set-variable]

* src/remote/remote_driver.c (doRemoteOpen): Also ignore 'verify'.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 4e6a78e712)
2013-07-29 16:10:55 -06:00
Ján Tomko
15bde978da Fix build with clang
Partially revert cdd703f's revert of c163410, as linking with clang
with --param=ssp-buffer-size=4 still fails with:
"argument unused during compilation".

(cherry picked from commit 4b91dc24d1)
2013-07-29 15:59:21 -06:00
Eric Blake
ab9ff9ed37 maint: update to latest gnulib
Upstream gnulib recently patched a bug in bootstrap, for projects
that use a different name than build-aux for a subdirectory.  We
don't, but it doesn't hurt to update.

* .gnulib: Update, for bootstrap fix.
* bootstrap: Sync to upstream.
* bootstrap.conf: Match upstream bug fix.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit ac0852c72a)
2013-07-29 15:59:14 -06:00
Eric Blake
4a10d56125 maint: update to latest gnulib
Future patches need LGPLv2+ versions of some modules that had
recent license changes; but separating the gnulib update from
the actual use of the modules makes it easier to backport to
an older version while avoiding a submodule update (assuming,
of course, that the backport is to a system where glibc provides
adequate functionaliy without needing the gnulib module).

* .gnulib: Update to latest, for modules needed in later patches.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 7961ad2107)
2013-07-29 15:59:08 -06:00
Eric Blake
29e57f770b build: honor autogen.sh --no-git
Based on a report by Chandrashekar Shastri, at
https://bugzilla.redhat.com/show_bug.cgi?id=979360

On systems where git cannot access the outside world, a developer
can instead arrange to get a copy of gnulib at the right commit
via side channels (such as NFS share drives), set GNULIB_SRCDIR,
then use ./autogen.sh --no-git.  In this setup, we will now
avoid direct use of git.  Of course, this means no automatic
gnulib updates when libvirt.git updates its submodule, but it
is expected that any developer in such a situation is already
prepared to deal with the fallout.

* .gnulib: Update to latest, for bootstrap.
* bootstrap: Synchronize from gnulib.
* autogen.sh (no_git): Avoid git when requested.
* cfg.mk (_update_required): Skip automatic rerun of bootstrap if
we can't use git.
* docs/compiling.html.in: Document this setup.
* docs/hacking.html.in: Mention this.
* HACKING: Regenerate.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 1e503ee534)
2013-07-29 15:58:59 -06:00
Eric Blake
ed3a0d830f maint: update to latest gnulib
The latest mingw headers on Fedora 19 fail to build with gnulib
without an update.

Meanwhile, now that upstream gnulib has better handling of -W
probing for clang, we can drop some of our own solutions in
favor of upstream; thus this reverts commit c1634100, "Correctly
detect warning flags with clang".

* .gnulib: Update to latest, for mingw and clang.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit cdd703f475)
2013-07-29 15:58:36 -06:00
Roman Bogorodskiy
f3b9bb7d4e FreeBSD: disable buggy -fstack-protector-all
FreeBSD ships an old gcc 4.2.1 which generates
bogus code, e.g. getsockopt() call returns
struct xucred with bogus values, which doesn't even
allow to connect to libvirtd:

error: Failed to find group record for gid '1284660778': No error: 0

So roll back to just -fstack-protector on FreeBSD.

(cherry picked from commit cc7cd6232e)
2013-07-29 15:58:34 -06:00
Eric Blake
6fd56b7e20 build: update to latest gnulib, for syntax-check
This picks up a fix for a syntax-check weakness mentioned here:
https://www.redhat.com/archives/libvir-list/2013-May/msg00811.html

* .gnulib: Update to latest, for maint.mk improvement.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 12bd22c70d)
2013-07-29 15:55:05 -06:00
Eric Blake
a2d23560d0 maint: update to latest gnulib
Among others, this fixes a cosmetic bug where bootstrap stated:

./bootstrap: Bootstrapping from checked-out http://libvirt.org sources...

instead of the intended:

./bootstrap: Bootstrapping from checked-out libvirt sources...

* .gnulib: Update to latest, for bootstrap improvement.
* bootstrap: Resync from gnulib.

(cherry picked from commit 3dfc2b71aa)
2013-07-29 15:54:47 -06:00
Eric Blake
a10d077ef2 lxc: correctly backport /dev/tty fix
https://bugzilla.redhat.com/show_bug.cgi?id=982317

maint-only patch; reported by Geert Jansen

Commit 17cdc298 tried to backport upstream 90a0c6d, but in
resolving conflicts, failed to account that upstream commit
e1d32bb refactored code to leave off a leading /dev.

* src/lxc/lxc_container.c (lxcContainerPopulateDevices): Use
correct device name.

Signed-off-by: Eric Blake <eblake@redhat.com>
2013-07-29 15:49:22 -06:00
Eric Blake
6598510159 security: fix deadlock with prefork
https://bugzilla.redhat.com/show_bug.cgi?id=964358

Attempts to start a domain with both SELinux and DAC security
modules loaded will deadlock; latent problem introduced in commit
fdb3bde and exposed in commit 29fe5d7.  Basically, when recursing
into the security manager for other driver's prefork, we have to
undo the asymmetric lock taken at the manager level.

Reported by Jiri Denemark, with diagnosis help from Dan Berrange.

* src/security/security_stack.c (virSecurityStackPreFork): Undo
extra lock grabbed during recursion.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit bfc183c1e3)
2013-07-22 14:04:22 -06:00
Eric Blake
00c2003e25 security_dac: compute supplemental groups before fork
https://bugzilla.redhat.com/show_bug.cgi?id=964358

Commit 75c1256 states that virGetGroupList must not be called
between fork and exec, then commit ee777e99 promptly violated
that for lxc's use of virSecurityManagerSetProcessLabel.  Hoist
the supplemental group detection to the time that the security
manager needs to fork.  Qemu is safe, as it uses
virSecurityManagerSetChildProcessLabel which in turn uses
virCommand to determine supplemental groups.

This does not fix the fact that virSecurityManagerSetProcessLabel
calls virSecurityDACParseIds calls parseIds which eventually
calls getpwnam_r, which also violates fork/exec async-signal-safe
safety rules, but so far no one has complained of hitting
deadlock in that case.

* src/security/security_dac.c (_virSecurityDACData): Track groups
in private data.
(virSecurityDACPreFork): New function, to set them.
(virSecurityDACClose): Clean up new fields.
(virSecurityDACGetIds): Alter signature.
(virSecurityDACSetSecurityHostdevLabelHelper)
(virSecurityDACSetChardevLabel, virSecurityDACSetProcessLabel)
(virSecurityDACSetChildProcessLabel): Update callers.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 29fe5d745f)

Conflicts:
	src/security/security_dac.c - virSecurityDACSetSecurityUSBLabel needed similar treatment
2013-07-22 14:00:57 -06:00
Eric Blake
689d014686 security: framework for driver PreFork handler
https://bugzilla.redhat.com/show_bug.cgi?id=964358

A future patch wants the DAC security manager to be able to safely
get the supplemental group list for a given uid, but at the time
of a fork rather than during initialization so as to pick up on
live changes to the system's group database.  This patch adds the
framework, including the possibility of a pre-fork callback
failing.

For now, any driver that implements a prefork callback must be
robust against the possibility of being part of a security stack
where a later element in the chain fails prefork.  This means
that drivers cannot do any action that requires a call to postfork
for proper cleanup (no grabbing a mutex, for example).  If this
is too prohibitive in the future, we would have to switch to a
transactioning sequence, where each driver has (up to) 3 callbacks:
PreForkPrepare, PreForkCommit, and PreForkAbort, to either clean
up or commit changes made during prepare.

* src/security/security_driver.h (virSecurityDriverPreFork): New
callback.
* src/security/security_manager.h (virSecurityManagerPreFork):
Change signature.
* src/security/security_manager.c (virSecurityManagerPreFork):
Optionally call into driver, and allow returning failure.
* src/security/security_stack.c (virSecurityDriverStack):
Wrap the handler for the stack driver.
* src/qemu/qemu_process.c (qemuProcessStart): Adjust caller.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit fdb3bde31c)
2013-07-22 11:41:50 -06:00
Eric Blake
7d24a0a226 util: make virSetUIDGID async-signal-safe
https://bugzilla.redhat.com/show_bug.cgi?id=964358

POSIX states that multi-threaded apps should not use functions
that are not async-signal-safe between fork and exec, yet we
were using getpwuid_r and initgroups.  Although rare, it is
possible to hit deadlock in the child, when it tries to grab
a mutex that was already held by another thread in the parent.
I actually hit this deadlock when testing multiple domains
being started in parallel with a command hook, with the following
backtrace in the child:

 Thread 1 (Thread 0x7fd56bbf2700 (LWP 3212)):
 #0  __lll_lock_wait ()
     at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:136
 #1  0x00007fd5761e7388 in _L_lock_854 () from /lib64/libpthread.so.0
 #2  0x00007fd5761e7257 in __pthread_mutex_lock (mutex=0x7fd56be00360)
     at pthread_mutex_lock.c:61
 #3  0x00007fd56bbf9fc5 in _nss_files_getpwuid_r (uid=0, result=0x7fd56bbf0c70,
     buffer=0x7fd55c2a65f0 "", buflen=1024, errnop=0x7fd56bbf25b8)
     at nss_files/files-pwd.c:40
 #4  0x00007fd575aeff1d in __getpwuid_r (uid=0, resbuf=0x7fd56bbf0c70,
     buffer=0x7fd55c2a65f0 "", buflen=1024, result=0x7fd56bbf0cb0)
     at ../nss/getXXbyYY_r.c:253
 #5  0x00007fd578aebafc in virSetUIDGID (uid=0, gid=0) at util/virutil.c:1031
 #6  0x00007fd578aebf43 in virSetUIDGIDWithCaps (uid=0, gid=0, capBits=0,
     clearExistingCaps=true) at util/virutil.c:1388
 #7  0x00007fd578a9a20b in virExec (cmd=0x7fd55c231f10) at util/vircommand.c:654
 #8  0x00007fd578a9dfa2 in virCommandRunAsync (cmd=0x7fd55c231f10, pid=0x0)
     at util/vircommand.c:2247
 #9  0x00007fd578a9d74e in virCommandRun (cmd=0x7fd55c231f10, exitstatus=0x0)
     at util/vircommand.c:2100
 #10 0x00007fd56326fde5 in qemuProcessStart (conn=0x7fd53c000df0,
     driver=0x7fd55c0dc4f0, vm=0x7fd54800b100, migrateFrom=0x0, stdin_fd=-1,
     stdin_path=0x0, snapshot=0x0, vmop=VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
     flags=1) at qemu/qemu_process.c:3694
 ...

The solution is to split the work of getpwuid_r/initgroups into the
unsafe portions (getgrouplist, called pre-fork) and safe portions
(setgroups, called post-fork).

* src/util/virutil.h (virSetUIDGID, virSetUIDGIDWithCaps): Adjust
signature.
* src/util/virutil.c (virSetUIDGID): Add parameters.
(virSetUIDGIDWithCaps): Adjust clients.
* src/util/vircommand.c (virExec): Likewise.
* src/util/virfile.c (virFileAccessibleAs, virFileOpenForked)
(virDirCreate): Likewise.
* src/security/security_dac.c (virSecurityDACSetProcessLabel):
Likewise.
* src/lxc/lxc_container.c (lxcContainerSetID): Likewise.
* configure.ac (AC_CHECK_FUNCS_ONCE): Check for setgroups, not
initgroups.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit ee777e9949)

Conflicts:
	src/lxc/lxc_container.c - did not use setUIDGID before 1.1.0
	src/util/virutil.c - oom handling changes not backported
	src/util/virfile.c - functions still lived in virutil.c this far back
	configure.ac - context with previous commit
2013-07-22 11:40:26 -06:00
Eric Blake
fcdaa3df33 util: add virGetGroupList
https://bugzilla.redhat.com/show_bug.cgi?id=964358

Since neither getpwuid_r() nor initgroups() are safe to call in
between fork and exec (they obtain a mutex, but if some other
thread in the parent also held the mutex at the time of the fork,
the child will deadlock), we have to split out the functionality
that is unsafe.  At least glibc's initgroups() uses getgrouplist
under the hood, so the ideal split is to expose getgrouplist for
use before a fork.  Gnulib already gives us a nice wrapper via
mgetgroups; we wrap it once more to look up by uid instead of name.

* bootstrap.conf (gnulib_modules): Add mgetgroups.
* src/util/virutil.h (virGetGroupList): New declaration.
* src/util/virutil.c (virGetGroupList): New function.
* src/libvirt_private.syms (virutil.h): Export it.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 75c125641a)

Conflicts:
	bootstrap.conf - not updating gnulib submodule...
	configure.ac - ...so checking for getgrouplist by hand...
	src/util/virutil.c - ...and copying only the getgrouplist implementation rather than calling the gnulib function
2013-07-22 10:25:48 -06:00
Eric Blake
3a2d5e7e70 util: improve user lookup helper
https://bugzilla.redhat.com/show_bug.cgi?id=964358

A future patch needs to look up pw_gid; but it is wasteful
to crawl through getpwuid_r twice for two separate pieces
of information, and annoying to copy that much boilerplate
code for doing the crawl.  The current internal-only
virGetUserEnt is also a rather awkward interface; it's easier
to just design it to let callers request multiple pieces of
data as needed from one traversal.

And while at it, I noticed that virGetXDGDirectory could deref
NULL if the getpwuid_r lookup fails.

* src/util/virutil.c (virGetUserEnt): Alter signature.
(virGetUserDirectory, virGetXDGDirectory, virGetUserName): Adjust
callers.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit c1983ba4e3)

Conflicts:
	src/util/virutil.c - oom reporting/strdup changes not backported
2013-07-19 17:14:34 -06:00
Cole Robinson
b5ed23b7d1 Prep for release 1.0.5.4 2013-07-12 08:56:21 -04:00
Ján Tomko
efa2739be6 qemu: fix double free in qemuMigrationPrepareDirect
Remove assignment of the string freed by virURIFree
to hostname, since it's not used anywhere.

Double free introduced by ddf8ad8, useless code
introduced by f03dcc5.

https://bugzilla.redhat.com/show_bug.cgi?id=977961
(cherry picked from commit 5744d96f21)
2013-07-12 09:27:04 +02:00
Cole Robinson
508a7a7523 Prep for release 1.0.5.3 2013-07-11 18:12:46 -04:00
Laine Stump
b5b269cbc5 pci: initialize virtual_functions array pointer to avoid segfault
This fixes https://bugzilla.redhat.com/show_bug.cgi?id=971325

The problem was that if virPCIGetVirtualFunctions was given the name
of a non-existent interface, it would return to its caller without
initializing the pointer to the array of virtual functions to NULL,
and the caller (virNetDevGetVirtualFunctions) would try to VIR_FREE()
the invalid pointer.

The final error message before the crash would be:

 virPCIGetVirtualFunctions:2088 :
  Failed to open dir '/sys/class/net/eth2/device':
  No such file or directory

In this patch I move the initialization in virPCIGetVirtualFunctions()
to the begining of the function, and also do an explicit
initialization in virNetDevGetVirtualFunctions, just in case someone
in the future adds code into that function prior to the call to
virPCIGetVirtualFunctions.

(cherry picked from commit 2c2525ab6a)
2013-07-11 17:49:19 -04:00
Ján Tomko
a717d7ba0f qemu: check if block I/O limits fit into long long
We can only pass values up to LLONG_MAX through JSON
and QEMU checks if the int64_t number is not negative
at startup since 1.5.0.

https://bugzilla.redhat.com/show_bug.cgi?id=974010
(cherry picked from commit d3c8788492)
2013-07-11 17:48:44 -04:00
Laine Stump
22d9d9a28f network: increase max number of routes
This fixes the problem reported in:

   https://bugzilla.redhat.com/show_bug.cgi?id=972690

When checking for a collision of a new libvirt network's subnet with
any existing routes, we read all of /proc/net/route into memory, then
parse all the entries. The function that we use to read this file
requires a "maximum length" parameter, which had previously been set
to 64*1024. As each line in /proc/net/route is 128 bytes, this would
allow for a maximum of 512 entries in the routing table.

This patch increases that number to 128 * 100000, which allows for
100,000 routing table entries. This means that it's possible that 12MB
would be allocated, but that would only happen if there really were
100,000 route table entries on the system, it's only held for a very
short time.

Since there is no method of specifying and unlimited max (and that
would create a potential denial of service anyway) hopefully this
limit is large enough to accomodate everyone.

(cherry picked from commit 2bdf548f5f)
2013-07-11 17:47:58 -04:00
Ján Tomko
0943603d9e qemu: allow restore with non-migratable XML input
Convert input XML to migratable before using it in
qemuDomainSaveImageOpen.

XML in the save image is migratable, i.e. doesn't contain implicit
controllers. If these controllers were in a non-default order in the
input XML, the ABI check would fail. Removing and re-adding these
controllers fixes it.

https://bugzilla.redhat.com/show_bug.cgi?id=834196
(cherry picked from commit 07966f6a8b)
2013-07-11 17:47:39 -04:00
Michal Privoznik
ca305a756d qemu_migrate: Dispose listen address if set from config
https://bugzilla.redhat.com/show_bug.cgi?id=971485

As of d7f9d82753 we copy the listen
address from the qemu.conf config file in case none has been provided
via XML. But later, when migrating, we should not include such listen
address in the migratable XML as it is something autogenerated, not
requested by user. Moreover, the binding to the listen address will
likely fail, unless the address is '0.0.0.0' or its IPv6 equivalent.
This patch introduces a new boolean attribute to virDomainGraphicsListenDef
to distinguish autofilled listen addresses. However, we must keep the
attribute over libvirtd restarts, so it must be kept within status XML.

(cherry picked from commit 6546017c50)
2013-07-11 17:47:18 -04:00
Ján Tomko
3b6bc5eda6 iscsi: pass hostnames to iscsiadm instead of resolving them
iscsiadm now supports specifying hostnames in the portal argument [1]

Instead of resolving the hostname to a single IPv4 address, pass the
hostname to isciadm, allowing IPv6 targets to work.

[1] https://bugzilla.redhat.com/show_bug.cgi?id=624437

(cherry picked from commit cbdb3c7326)
2013-07-11 17:46:53 -04:00
Osier Yang
818a933141 qemu: Report the offset from host UTC for RTC_CHANGE event
https://bugzilla.redhat.com/show_bug.cgi?id=964177

Though both libvirt and QEMU's document say RTC_CHANGE returns
the offset from the host UTC, qemu actually returns the offset
from the specified date instead when specific date is provided
(-rtc base=$date).

It's not safe for qemu to fix it in code, it worked like that
for 3 years, changing it now may break other QEMU use cases.
What qemu tries to do is to fix the document:

http://lists.gnu.org/archive/html/qemu-devel/2013-05/msg04782.html

And in libvirt side, instead of replying on the value from qemu,
this converts the offset returned from qemu to the offset from
host UTC, by:

  /*
   * a: the offset from qemu RTC_CHANGE event
   * b: The specified date (-rtc base=$date)
   * c: the host date when libvirt gets the RTC_CHANGE event
   * offset: What libvirt will report
   */

  offset = a + (b - c);

The specified date (-rtc base=$date) is recorded in clock's def as
an internal only member (may be useful to exposed outside?).

Internal only XML tag "basetime" is introduced to not lose the
guest's basetime after libvirt restarting/reloading:

<clock offset='variable' adjustment='304' basis='utc' basetime='1370423588'/>

(cherry picked from commit e31b5cf393)
2013-07-11 17:46:45 -04:00
Peter Krempa
44758cea54 storage: Provide better error message if metadata pre-alloc is unsupported
Instead of a unknown flag error report that metadata pre-allocation is
not supported with the requested volume creation method.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=969982
(cherry picked from commit 77e7f69c3b)
2013-07-11 17:46:32 -04:00
Martin Kletzander
ffe68a85c9 usb: don't spoil decimal addresses
For USB devices, dev->name gets formated as %.3o:%.3o even though the
numbers are decimal.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=967712
(cherry picked from commit dc0c791569)
2013-07-11 17:45:55 -04:00
John Ferlan
e01eedf9bf Check for existence of interface prior to setting terminate flag
https://bugzilla.redhat.com/show_bug.cgi?id=903480

During domain destruction it's possible that the learnIPAddressThread has
already removed the interface prior to the teardown filter path being run.
The teardown code would only be telling the thread to terminate.

(cherry picked from commit 64919d978e)
2013-07-11 17:45:32 -04:00
Peter Krempa
b14ced3932 qemu: snapshot: Don't kill access to disk if snapshot creation fails
If snapshot creation failed for example due to invalid use of the
"REUSE_EXTERNAL" flag, libvirt killed access to the original image file
instead of the new image file. On machines with selinux this kills the
whole VM as the selinux context is enforced immediately.

* qemu_driver.c:qemuDomainSnapshotUndoSingleDiskActive():
    - Kill access to the new image file instead of the old one.

Partially resolves: https://bugzilla.redhat.com/show_bug.cgi?id=906639

(cherry picked from commit 177046753f)
2013-07-11 17:45:22 -04:00
Martin Kletzander
b2c2dd60f1 Fix blkdeviotune for shutoff domain
Function qemuDomainSetBlockIoTune() was checking QEMU capabilities
even when !(flags & VIR_DOMAIN_AFFECT_LIVE) and the domain was
shutoff, resulting in the following problem:

 virsh # domstate asdf; blkdeviotune asdf vda --write-bytes-sec 100
 shut off

 error: Unable to change block I/O throttle
 error: unsupported configuration: block I/O throttling not supported with this QEMU binary

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=965016
(cherry picked from commit 5af3ce8277)
2013-07-11 17:45:08 -04:00
Daniel P. Berrange
1a6333f842 Ensure non-root can read /proc/meminfo file in LXC containers
By default files in a FUSE mount can only be accessed by the
user which created them, even if the file permissions would
otherwise allow it. To allow other users to access the FUSE
mount the 'allow_other' mount option must be used. This bug
prevented non-root users in an LXC container from reading
the /proc/meminfo file.

https://bugzilla.redhat.com/show_bug.cgi?id=967977

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 922ebe4ead)
2013-07-11 17:42:26 -04:00
Richard Weinberger
17cdc298ac LXC: Create /dev/tty within a container
Many applications use /dev/tty to read from stdin.
e.g. zypper on openSUSE.

Let's create this device node to unbreak those applications.
As /dev/tty is a synonym for the current controlling terminal
it cannot harm the host or any other containers.

Signed-off-by: Richard Weinberger <richard@nod.at>
(cherry picked from commit 9a0ac6d9c2)

Conflicts:
	src/lxc/lxc_controller.c
2013-07-11 17:38:47 -04:00
Peter Krempa
6cdff51fb3 qemu: Implement new QMP command for cpu hotplug
This patch implements support for the "cpu-add" QMP command that plugs
CPUs into a live guest. The "cpu-add" command was introduced in QEMU
1.5. For the hotplug to work machine type "pc-i440fx-1.5" is required.

(cherry picked from commit c12b2be516)
2013-07-11 17:29:48 -04:00
Ján Tomko
ad02b24871 udev: fix crash in libudev logging
Call virLogVMessage instead of virLogMessage, since libudev
called us with a va_list object, not a list of arguments.

Honor message priority and strip the trailing newline.

https://bugzilla.redhat.com/show_bug.cgi?id=969152
(cherry picked from commit f753dd62f9)
2013-07-11 17:29:33 -04:00
Daniel P. Berrange
647156870e Don't mount selinux fs in LXC if selinux is disabled
Before trying to mount the selinux filesystem in a container
use is_selinux_enabled() to check if the machine actually
has selinux support (eg not booted with selinux=0)

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 95c6cc344b)
2013-07-11 10:52:04 -06:00
Daniel P. Berrange
269dfa0e08 Re-add selinux/selinux.h to lxc_container.c
Re-add the selinux header to lxc_container.c since other
functions now use it, beyond the patch that was just
reverted.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 63ea1e5432)
2013-07-11 10:51:32 -06:00
Daniel P. Berrange
0616172bdf Fix failure to detect missing cgroup partitions
Change bbe97ae968 caused the
QEMU driver to ignore ENOENT errors from cgroups, in order
to cope with missing /proc/cgroups. This is not good though
because many other things can cause ENOENT and should not
be ignored. The callers expect to see ENXIO when cgroups
are not present, so adjust the code to report that errno
when /proc/cgroups is missing

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit c2cf5f1c2a)
2013-07-11 10:39:45 -06:00
Jim Fehlig
68d92eea16 Fix starting domains when kernel has no cgroups support
Found that I was unable to start existing domains after updating
to a kernel with no cgroups support

  # zgrep CGROUP /proc/config.gz
  # CONFIG_CGROUPS is not set
  # virsh start test
  error: Failed to start domain test
  error: Unable to initialize /machine cgroup: Cannot allocate memory

virCgroupPartitionNeedsEscaping() correctly returns errno (ENOENT) when
attempting to open /proc/cgroups on such a system, but it was being
dropped in virCgroupSetPartitionSuffix().

Change virCgroupSetPartitionSuffix() to propagate errors returned by
its callees.  Also check for ENOENT in qemuInitCgroup() when determining
if cgroups support is available.
(cherry picked from commit bbe97ae968)
2013-07-11 10:38:45 -06:00
Daniel P. Berrange
e0dd41e564 Escaping leading '.' in cgroup names
Escaping a leading '.' with '_' in the cgroup names

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 0ced83dcfb)
2013-07-11 10:37:49 -06:00
Daniel P. Berrange
fdaa5c825c Add docs about cgroups layout and usage
Describe the new cgroups layout, how to customize placement
of guests and what virsh commands are used to access the
parameters.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 486a86eb18)
2013-07-11 10:37:09 -06:00
Daniel P. Berrange
4769d2ae9f Cope with missing swap cgroup controls
It is possible to build a kernel without swap cgroup controls
present. This causes a fatal error when querying memory
parameters. Treat missing swap controls as meaning "unlimited".
The fatal error remains if the user tries to actually change
the limit.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit f493d83fbd)
2013-07-11 10:36:17 -06:00
Jim Fehlig
8c4faa9044 libxl: fix build with Xen4.3
Xen 4.3 fixes a mistake in the libxl event handler signature where the
event owned by the application was defined as const.  Detect this and
define the libvirt libxl event handler signature appropriately.
(cherry picked from commit 43b0ff5b1e)
2013-07-11 10:27:35 -06:00
Ján Tomko
233a616bda qemu: fix return value of qemuDomainBlockPivot on errors
If qemuMonitorBlockJob returned 0, qemuDomainBlockPivot
might return 0 even if an error occured.

https://bugzilla.redhat.com/show_bug.cgi?id=977678
(cherry picked from commit c34107dfd3)
2013-07-11 14:34:16 +02:00
Ján Tomko
14ce155a3a storage: return -1 when fs pool can't be mounted
Don't reuse the return value of virStorageBackendFileSystemIsMounted.
If it's 0, we'd return it even if the mount command failed.

Also, don't report another error if it's -1, since one has already
been reported.

Introduced by 258e06c.

https://bugzilla.redhat.com/show_bug.cgi?id=981251
(cherry picked from commit 13fde7ceab)
2013-07-11 14:33:44 +02:00
Dennis Chen
4d21d84532 Fix vPort management: FC vHBA creation
When creating a virtual FC HBA with virsh/libvirt API, an error message
will be returned: "error: Node device not found",
also the 'nodedev-dumpxml' shows wrong information of wwpn & wwnn
for the new created device.

Signed-off-by: xschen@tnsoft.com.cn

This reverts f90af69 which switched wwpn & wwwn in the wrong place.

https://www.kernel.org/doc/Documentation/scsi/scsi_fc_transport.txt
(cherry picked from commit 3c0d5e224c)
2013-07-01 11:54:22 +02:00
Ján Tomko
0347e778ca bridge: don't crash on bandwidth unplug with no bandwidth
If networkUnplugBandwidth is called on a network which has
no bandwidth defined, print a warning instead of crashing.

This can happen when destroying a domain with bandwidth if
bandwidth was removed from the network after the domain was
started.

https://bugzilla.redhat.com/show_bug.cgi?id=975359
(cherry picked from commit 658c932ab4)
2013-07-01 11:54:11 +02:00
Ján Tomko
1b4cd1e5f0 Fix invalid read in virCgroupGetValueStr
Don't check for '\n' at the end of file if zero bytes were read.

Found by valgrind:
==404== Invalid read of size 1
==404==    at 0x529B09F: virCgroupGetValueStr (vircgroup.c:540)
==404==    by 0x529AF64: virCgroupMoveTask (vircgroup.c:1079)
==404==    by 0x1EB475: qemuSetupCgroupForEmulator (qemu_cgroup.c:1061)
==404==    by 0x1D9489: qemuProcessStart (qemu_process.c:3801)
==404==    by 0x18557E: qemuDomainObjStart (qemu_driver.c:5787)
==404==    by 0x190FA4: qemuDomainCreateWithFlags (qemu_driver.c:5839)

Introduced by 0d0b409.

https://bugzilla.redhat.com/show_bug.cgi?id=978356
(cherry picked from commit 306c49ffd5)
2013-06-26 17:31:28 +02:00
Ján Tomko
c93aef4946 virsh: edit: don't leak XML string on reedit or redefine
Free the old XML strings before overwriting them if the user
has chosen to reedit the file or force the redefinition.

Found by Alex Jia trying to reproduce another bug:
https://bugzilla.redhat.com/show_bug.cgi?id=977430#c3
(cherry picked from commit 1e3a252974)
2013-06-26 17:31:16 +02:00
John Ferlan
f1e454457d lxc: Resolve issue with GetScheduler APIs for non running domain
Cherry-picked from 38ada092d1

As a consequence of the cgroup layout changes from commit 'cfed9ad4', the
lxcDomainGetSchedulerParameters[Flags]()' and lxcGetSchedulerType() APIs
failed to return data for a non running domain.  This can be seen through
a 'virsh schedinfo <domain>' command which returns:

Scheduler      : Unknown
error: Requested operation is not valid: cgroup CPU controller is not mounted

Prior to that change a non running domain would return:

Scheduler      : posix
cpu_shares     : 0
vcpu_period    : 0
vcpu_quota     : 0
emulator_period: 0
emulator_quota : 0

This patch will restore the capability to return configuration only data
for a non running domain regardless of whether cgroups are available.

NOTE: Needed to change the VIR_STRDUP(ret, "posix"); to ret = strdup("posix");
      and added the virReportOOMError(); on failure.
2013-06-20 09:38:51 -04:00
John Ferlan
f1729409fb qemu: Resolve issue with GetScheduler APIs for non running domain
Cherry-picked from b237545341

As a consequence of the cgroup layout changes from commit '632f78ca', the
qemuDomainGetSchedulerParameters[Flags]()' and qemuGetSchedulerType() APIs
failed to return data for a non running domain.  This can be seen through
a 'virsh schedinfo <domain>' command which returns:

Scheduler      : Unknown
error: Requested operation is not valid: cgroup CPU controller is not mounted

Prior to that change a non running domain would return:

Scheduler      : posix
cpu_shares     : 0
vcpu_period    : 0
vcpu_quota     : 0
emulator_period: 0
emulator_quota : 0

This patch will restore the capability to return configuration only data
for a non running domain regardless of whether cgroups are available.

NOTE: Needed to change the VIR_STRDUP(ret, "posix"); to ret = strdup("posix");
      and added the virReportOOMError(); on failure.
2013-06-20 09:37:54 -04:00
Ján Tomko
a06bf7b287 conf: fix use after free in virChrdevOpen
Don't free the stream on error if we've successfully added it
to the hash table, since it will be freed by virChrdevHashEntryFree
callback.

Preserve the error message before calling virStreamFree, since it
resets the error.

Introduced by 4716138, crashing since 6921892.

Reported by Sergey Fionov on libvir-list.
(cherry picked from commit a32b41746c)
2013-06-18 15:30:23 +02:00
Jiri Denemark
067e9988a2 qemu: Avoid leaking uri in qemuMigrationPrepareDirect
(cherry picked from commit ddf8ad82eb)
2013-06-18 15:30:03 +02:00
Ján Tomko
1fc28a4743 virtlockd: fix socket path
Change the socket path to match the one used by lockd driver.

https://bugzilla.redhat.com/show_bug.cgi?id=968128
(cherry picked from commit 70fe129546)
2013-06-18 15:29:54 +02:00
Ján Tomko
7e0b15f2f0 nodedev: fix vport detection for FC HBA
Use the host number as the host number when constructing the sysfs path
instead of the variable we are trying to fill.

https://bugzilla.redhat.com/show_bug.cgi?id=973543
(cherry picked from commit 371c15517c)
2013-06-18 15:29:42 +02:00
Cole Robinson
419605b3a0 Prep for release 1.0.5.2 2013-06-12 16:50:01 -04:00
Cole Robinson
feb2d3375c virsh: migrate: Don't disallow --p2p and --migrateuri
Because it's a valid combination. p2p still uses a separate channel
for qemu migration, so there's value in letting the user specify a manual
migrate URI for overriding auto-port, or libvirt's FQDN lookup.

What _isn't_ allowed is --migrateuri and TUNNELLED, since there is
no separate migration channel. Disallow that instead
(cherry picked from commit 5e1de4fcdd)
2013-06-12 16:37:55 -04:00
Cole Robinson
12b0af5905 qemu: migration: error if tunnelled + storage specified
Since as the code indicates it doesn't work yet, so let's be
explicit about it.
(cherry picked from commit 98bbda00cf)
2013-06-12 16:37:55 -04:00
Cole Robinson
69de4ce80d qemu: migration: Improve p2p error if we can't open conn
By actually showing the Open() error to the user
(cherry picked from commit 5751fc4f4e)
2013-06-12 16:37:55 -04:00
Daniel P. Berrange
9b3455cb78 Add a virGetLastErrorMessage() function
Apps using libvirt will often have code like

   if (virXXXX() < 0) {
      virErrorPtr err = virGetLastError();
      fprintf(stderr, "Something failed: %s\n",
              err && err->message ? err->message :
              "unknown error");
      return -1;
   }

Checking for a NULL error object or message leads to very
verbose code. A virGetLastErrorMessage() helper from libvirt
can simplify this to

   if (virXXXX() < 0) {
      fprintf(stderr, "Something failed: %s\n",
              virGetLastErrorMessage());
      return -1;
   }

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 69c6a58a1d)
2013-06-12 16:37:55 -04:00
Cole Robinson
bdb5808173 qemu: Don't report error on successful media eject
If we are just ejecting media, ret == -1 even after the retry loop
determines that the tray is open, as requested. This means media
disconnect always report's error.

Fix it, and fix some other mini issues:

- Don't overwrite the 'eject' error message if the retry loop fails
- Move the retries decrement inside the loop, otherwise the final loop
  might succeed, yet retries == 0 and we will raise error
- Setting ret = -1 in the disk->src check is unneeded
- Fix comment typos

cc: mprivozn@redhat.com
(cherry picked from commit 406d8a9809)
2013-06-12 15:25:08 -04:00
Michal Privoznik
dc0efacb6f qemuDomainChangeEjectableMedia: Unlock domain while waiting for event
In 84c59ffa I've tried to fix changing ejectable media process. The
process should go like this:

1) we need to call 'eject' on the monitor
2) we should wait for 'DEVICE_TRAY_MOVED' event
3) now we can issue 'change' command

However, while waiting in step 2) the domain monitor was locked. So
even if qemu reported the desired event, the proper callback was not
called immediately. The monitor handling code needs to lock the
monitor in order to read the event. So that's the first lock we must
not hold while waiting. The second one is the domain lock. When
monitor handling code reads an event, the appropriate callback is
called then. The first thing that each callback does is locking the
corresponding domain as a domain or its device is about to change
state. So we need to unlock both monitor and VM lock. Well, holding
any lock while sleep()-ing is not the best thing to do anyway.
(cherry picked from commit 543af79a14)
2013-06-12 15:24:44 -04:00
Christophe Fergeau
0e6aa8fcd2 storage: Ensure 'qemu-img resize' size arg is a 512 multiple
qemu-img resize will fail with "The new size must be a multiple of 512"
if libvirt doesn't round it first.
This fixes rhbz#951495

Signed-off-by: Christophe Fergeau <cfergeau@redhat.com>
(cherry picked from commit 9a8f39d097)
2013-06-12 15:11:50 -04:00
Stefan Berger
12f18158c7 nwfilter: grab driver lock earlier during init (bz96649)
This patch is in relation to Bug 966449:

https://bugzilla.redhat.com/show_bug.cgi?id=966449

This is a patch addressing the coredump.

Thread 1 must be calling  nwfilterDriverRemoveDBusMatches(). It does so with
nwfilterDriverLock held. In the patch below I am now moving the
nwfilterDriverLock(driverState) further up so that the initialization, which
seems to either take a long time or is entirely stuck, occurs with the lock
held and the shutdown cannot occur at the same time.

Remove the lock in virNWFilterDriverIsWatchingFirewallD to avoid
double-locking.

(cherry picked from commit 0ec376c20a)
2013-06-11 18:40:43 -04:00
Doug Goldstein
ab7e3039e0 Fix use of VIR_STRDUP vs strdup
Commit 894f784948 broke the v1.0.5-maint
branch because VIR_STRDUP() didn't exist in the v1.0.5 release so the
resulting build is missing that symbol.

This patch is only for the v1.0.5-maint branch.
2013-06-10 09:36:06 -04:00
Viktor Mihajlovski
dc200aa851 qemu: Fix crash in migration of graphics-less guests.
Commit 7f15ebc7a2 introduced a bug
happening when guests without a <graphics> element are migrated.
The initialization of listenAddress happens unconditionally
from the cookie even if the cookie->graphics pointer was NULL.
Moved the initialization to where it is safe.

Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
(cherry picked from commit 9684bb11fd)
2013-05-31 22:36:32 +02:00
Laine Stump
2f2ed992c0 qemu: prevent termination of guests w/hostdev on driver reconnect
This should resolve:

  https://bugzilla.redhat.com/show_bug.cgi?id=959191

The problem was that qemuUpdateActivePciHostdevs was returning 0
(success) when no hostdevs were present, but would otherwise return -1
(failure) even when it completed successfully. It is only called from
qemuProcessReconnect(), and when qemuProcessReconnect got back an
error, it would not only stop reconnecting, but would terminate the
guest qemu process "to remove danger of it ending up running twice if
user tries to start it again later".

(This bug was introduced in commit 011cf7ad, which was pushed between
v1.0.2 and v1.0.3, so all maintenance branches from v1.0.3 up to 1.0.5
will need this one line patch applied.)
(cherry picked from commit 2ea45647bc)
2013-05-31 15:16:06 -04:00
Ján Tomko
894f784948 qemu: escape literal IPv6 address in NBD migration
A literal IPv6 must be escaped, otherwise migration fails with:
unable to execute QEMU command 'drive-mirror': address resolution failed
for f0::0d:5901: Servname not supported for ai_socktype
since QEMU treats everything after the first ':' as the port.
(cherry picked from commit 2136327e23)
2013-05-31 17:28:31 +02:00
Eric Blake
0ecc5ad70d build: fix build with older gcc
gcc 4.1.2 (hello, RHEL 5!) fails to build on 32-bit platforms with:

conf/domain_conf.c: In function 'virDomainDefParseXML':
conf/domain_conf.c:10581: warning: integer constant is too large for 'long' type

Problem introduced in commit f8e3221f9.

* src/conf/domain_conf.c (virDomainDefParseXML): Mark large constants.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit f6817c70b4)
2013-05-28 20:21:50 -06:00
Ján Tomko
3accd7eb25 qemu: fix NBD migration to hosts with IPv6 enabled
Since f03dcc5 we use [::] as the listening address both on qemu
command line in -incoming and in nbd-server-start QMP command.
However the latter requires just :: without the braces.
(cherry picked from commit 2326006410)
2013-05-25 16:55:19 -04:00
Eric Blake
b4541a2f3d cgroup: be robust against cgroup movement races
https://bugzilla.redhat.com/show_bug.cgi?id=965169 documents a
problem starting domains when cgroups are enabled; I was able
to reliably reproduce the race about 5% of the time when I added
hooks to domain startup by 3 seconds (as that seemed to be about
the length of time that qemu created and then closed a temporary
thread, probably related to aio handling of initially opening
a disk image).  The problem has existed since we introduced
virCgroupMoveTask in commit 9102829 (v0.10.0).

There are some inherent TOCTTOU races when moving tasks between
kernel cgroups, precisely because threads can be created or
completed in the window between when we read a thread id from the
source and when we write to the destination.  As the goal of
virCgroupMoveTask is merely to move ALL tasks into the new
cgroup, it is sufficient to iterate until no more threads are
being created in the old group, and ignoring any threads that
die before we can move them.

It would be nicer to start the threads in the right cgroup to
begin with, but by default, all child threads are created in
the same cgroup as their parent, and we don't want vcpu child
threads in the emulator cgroup, so I don't see any good way
of avoiding the move.  It would also be nice if the kernel were
to implement something like rename() as a way to atomically move
a group of threads from one cgroup to another, instead of forcing
a window where we have to read and parse the source, then format
and write back into the destination.

* src/util/vircgroup.c (virCgroupAddTaskStrController): Ignore
ESRCH, because a thread ended between read and write attempts.
(virCgroupMoveTask): Loop until all threads have moved.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 83e4c77547)
2013-05-21 11:57:07 -06:00
Cole Robinson
6bf4e0e0d0 Prep for release 1.0.5.1 2013-05-19 18:01:21 -04:00
Eric Blake
6a7ae990e7 tests: use portable shell code
'make check' fails since commit 470d5c46 on any system with dash
as /bin/sh, because '<<<' is a bash extension.  For example:

nwfilterschematest: 23: /home/eblake/libvirt/tests/schematestutils.sh: Syntax error: redirection unexpected

Also, there is no need to spawn a grep process when shell globbing
can do the same.

* tests/schematestutils.sh: Replace bashism and subprocess with a
faster and portable construct.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 1d21b884a3)
2013-05-17 21:40:49 -06:00
Martin Kletzander
3efa02e3ed qemu: Fix cgroup handling when setting VCPU BW
Commit 632f78c introduced a regression which causes schedinfo being
unable to set some parameters.  When migrating to priv->cgroup there
was missing variable left out and due to passed NULL to underlying
function, the setting failed.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=963592
2013-05-16 22:16:09 +02:00
Ján Tomko
71e7f1392b daemon: fix leak after listing all volumes
CVE-2013-1962

remoteDispatchStoragePoolListAllVolumes wasn't freeing the pool.
The pool also held a reference to the connection, preventing it from
getting freed and closing the netcf interface driver, which held two
sockets open.
(cherry picked from commit ca697e90d5)
2013-05-16 16:07:43 +02:00
Daniel P. Berrange
a36dbe6475 Fix iohelper usage with streams opened for read
bz #960879

In b2878ed860 we added the O_NOCTTY
flag when opening files in the stream code. Unfortunately a later
piece of code was comparing the flags == O_RDONLY, without masking
out the non-access mode flags. This broke the iohelper when used
with streams for read, since it caused us to attach the stream
output pipe to the stream input FD instead of output FD :-(

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit a2214c5257)
2013-05-14 16:02:29 -06:00
Laine Stump
ce902dcaf0 util: fix virFileOpenAs return value and resulting error logs
This resolves:

     https://bugzilla.redhat.com/show_bug.cgi?id=851411
     https://bugzilla.redhat.com/show_bug.cgi?id=955500

The first problem was that virFileOpenAs was returning fd (-1) in one
of the error cases rather than ret (-errno), so the caller thought
that the error was EPERM rather than ENOENT.

The second problem was that some log messages in the general purpose
qemuOpenFile() function would always say "Failed to create" even if
the caller hadn't included O_CREAT (i.e. they were trying to open an
existing file).

This fixes virFileOpenAs to jump down to the error return (which
returns ret instead of fd) in the previously mentioned incorrect
failure case of virFileOpenAs(), removes all error logging from
virFileOpenAs() (since the callers report it), and modifies
qemuOpenFile to appropriately use "open" or "create" in its log
messages.

NB: I seriously considered removing logging from all callers of
virFileOpenAs(), but there is at least one case where the caller
doesn't want virFileOpenAs() to log any errors, because it's just
going to try again (qemuOpenFile()). We can't simply make a silent
variation of virFileOpenAs() though, because qemuOpenFile() can't make
the decision about whether or not it wants to retry until after
virFileOpenAs() has already returned an error code.

Likewise, I also considered changing virFileOpenAs() to return -1 with
errno set on return, and may still do that, but only as a separate
patch, as it obscures the intent of this patch too much.
(cherry picked from commit a2c1bedbd8)
2013-05-10 13:10:07 -04:00
Ján Tomko
a4f45888ce iscsi: don't leak portal string when starting a pool
(cherry picked from commit 413274f63b)
2013-05-09 15:05:07 +02:00
Ján Tomko
c12dc47c27 don't mention disk controllers in generic controller errors
The controller element supports non-disk controller types too.

https://bugzilla.redhat.com/show_bug.cgi?id=960958
(cherry picked from commit c075f89fa2)
2013-05-09 15:04:48 +02:00
Ján Tomko
9fc6618e74 conf: don't crash on a tpm device with no backends
Print an error instead of crashing when a TPM device without
a backend is specified.

Add a test for tpm device with no backend, which should fail
with a parse error.

https://bugzilla.redhat.com/show_bug.cgi?id=961252
(cherry picked from commit 1d96440a06)
2013-05-09 14:57:00 +02:00
Ján Tomko
a3f71eb908 tests: files named '.*-invalid.xml' should fail validation
Currently, using an invalid XML in tests fails, because
the schema test expects all of them to be valid.

Treat files with -invalid.xml suffix as invalid and expect
them to fail validation.
(cherry picked from commit 470d5c4654)
2013-05-09 14:56:36 +02:00
Laine Stump
6597cc25a1 qemu: allocate network connections sooner during domain startup
VFIO device assignment requires a cgroup ACL to be setup for access to
the /dev/vfio/nn "group" device for any devices that will be assigned
to a guest. In the case of a host device that is allocated from a
pool, it was being allocated during qemuBuildCommandLine(), which is
called by qemuProcessStart() *after* the all-encompassing
qemuSetupCgroup() was called, meaning that the standard Cgroup ACL
setup wasn't creating ACLs for these devices allocated from pools.

One possible solution was to manually add a single ACL down inside
qemuBuildCommandLine() when networkAllocateActualDevice() is called,
but that has two problems: 1) the function that adds the cgroup ACL
requires a virDomainObjPtr, which isn't available in
qemuBuildCommandLine(), and 2) we really shouldn't be doing network
device setup inside qemuBuildCommandLine() anyway.

Instead, I've created a new function called
qemuNetworkPrepareDevices() which is called just before
qemuPrepareHostDevices() during qemuProcessStart() (explanation of
ordering in the comments), i.e. well before the call to
qemuSetupCgroup(). To minimize code churn in a patch that will be
backported to 1.0.5-maint, qemuNetworkPrepareDevices only does
networkAllocateActualDevice() and the bare amount of setup required
for type='hostdev network devices, but it eventually should do *all*
device setup for guest network devices.

Note that some of the code that was previously needed in
qemuBuildCommandLine() is no longer required when
networkAllocateActualDevice() is called earlier:

 * qemuAssignDeviceHostdevAlias() is already done further down in
   qemuProcessStart().

 * qemuPrepareHostdevPCIDevices() is called by
   qemuPrepareHostDevices() which is called after
   qemuNetworkPrepareDevices() in qemuProcessStart().

As hinted above, this new function should be moved into a separate
qemu_network.c (or similarly named) file along with
qemuPhysIfaceConnect(), qemuNetworkIfaceConnect(), and
qemuOpenVhostNet(), and expanded to call those functions as well, then
the nnets loop in qemuBuildCommandLine() should be reduced to only
build the commandline string (which itself can be in a separate
qemuInterfaceBuilldCommandLine() function as suggested by
Michal). However, this will require storing away an array of tapfd and
vhostfd that are needed for the commandline, so I would rather do that
in a separate patch and leave this patch at the minimum to fix the
bug.
(cherry picked from commit 8cd40e7e0d)
2013-05-07 12:46:09 -04:00
Guido Günther
3b8f6e5fd6 Make detect_scsi_host_caps a function on all architectures
In the non linux case some callers like gather_scsi_host_caps needed the
return code of -1 while others like update_caps needed an empty
statement (to avoid a "statement without effect" warning). This is much
simpler solved by using a function instead of a define.
(cherry picked from commit 58662f4416)
2013-05-06 14:20:33 -06:00
Guido Günther
4a4d2300ff Fixup rpcgen code on kFreeBSD too
since it uses glibc's rpcgen.
(cherry picked from commit b562d7b7e4)
2013-05-06 14:20:18 -06:00
Daniel P. Berrange
14ba72b640 Fix release of resources with lockd plugin
The lockd plugin for the lock manager was not correctly
handling the release of resource locks. This meant that
during migration, or when pausing a VM, the locks would
not get released. This in turn made it impossible to
resume the domain, or finish migration
(cherry picked from commit 8dc93ffadc)
2013-05-06 14:19:47 -06:00
Eric Blake
fc8a231018 build: avoid non-portable cast of pthread_t
POSIX says pthread_t is opaque.  We can't guarantee if it is scaler
or a pointer, nor what size it is; and BSD differs from Linux.
We've also had reports of gcc complaining on attempts to cast it,
if we use a cast to the wrong type (for example, pointers have to be
cast to void* or intptr_t before being narrowed; while casting a
function return of scalar pthread_t to void* triggers a different
warning).

Give up on casts, and use unions to get at decent bits instead.  And
rather than futz around with figuring which 32 bits of a potentially
64-bit pointer are most likely to be unique, convert the rest of
the code base to use 64-bit values when using a debug id.

Based on a report by Guido Günther against kFreeBSD, but with a
fix that doesn't regress commit 4d970fd29 for FreeBSD.

* src/util/virthreadpthread.c (virThreadSelfID, virThreadID): Use
union to get at a decent bit representation of thread_t bits.
* src/util/virthread.h (virThreadSelfID, virThreadID): Alter
signature.
* src/util/virthreadwin32.c (virThreadSelfID, virThreadID):
Likewise.
* src/qemu/qemu_domain.h (qemuDomainJobObj): Alter type of owner.
* src/qemu/qemu_domain.c (qemuDomainObjTransferJob)
(qemuDomainObjSetJobPhase, qemuDomainObjReleaseAsyncJob)
(qemuDomainObjBeginNestedJob, qemuDomainObjBeginJobInternal): Fix
clients.
* src/util/virlog.c (virLogFormatString): Likewise.
* src/util/vireventpoll.c (virEventPollInterruptLocked):
Likewise.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 22d12905e6)
2013-05-06 14:19:35 -06:00
Daniel P. Berrange
832049ca29 Fix potential use of undefined variable in remote dispatch code
If an early dispatch check caused a jump to the 'cleanup' branch
then virTypeParamsFree() would be called with an uninitialized
'nparams' variable. Fortunately 'params' is initialized to NULL,
so the uninitialized 'nparams' variable would not be used.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 31dbbb667f)
2013-05-06 14:18:23 -06:00
Eric Blake
6381c1c130 build: fix mingw build of virprocess.c
Commit 776d49f4 added a static function that is only called
conditionally; leading to this compile error on mingw:

  CC       libvirt_util_la-virprocess.lo
../../src/util/virprocess.c:624:26: error: 'struct rlimit' declared inside parameter list [-Werror]
../../src/util/virprocess.c:624:26: error: its scope is only this definition or declaration, which is probably not what you want [-Werror]
../../src/util/virprocess.c:622:1: error: 'virProcessPrLimit' defined but not used [-Werror=unused-function]

* src/util/virprocess.c (virProcessPrLimit): Only declare
virProcessPrLimit when used.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 05f79a3894)
2013-05-06 14:17:35 -06:00
Daniel P. Berrange
3b9243e018 Fix F_DUPFD_CLOEXEC operation args
The F_DUPFD_CLOEXEC operation with fcntl() expects a single
int argument, specifying the minimum FD number for the newly
dup'd file descriptor. We were not specifying that causing
random stack data to be accessed as the FD number. Sometimes
that worked, sometimes it didn't.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit d6670a64e1)
2013-05-06 14:16:14 -06:00
Eric Blake
fa8692cd2e spec: proper soft static allocation of qemu uid
https://bugzilla.redhat.com/show_bug.cgi?id=924501 tracks a
problem that occurs if uid 107 is already in use at the time
libvirt is first installed.  In response that problem, Fedora
packaging guidelines were recently updated.  This fixes the
spec file to comply with the new guidelines:
https://fedoraproject.org/wiki/Packaging:UsersAndGroups

* libvirt.spec.in (daemon): Follow updated Fedora guidelines.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit a2584d58f6)
2013-05-06 14:09:13 -06:00
Eric Blake
c0431c10ee build: clean up stray files found by 'make distcheck'
'make distcheck' complained:

ERROR: files left in build directory after distclean:
./python/libvirt.pyc
./tests/commandhelper.log

Problems introduced in commits f015495 and 25ea8e4 (both v1.0.3).

* tests/commandtest.c (test21): Check (and clean) log file.
* tests/commanddata/test21.log: New file.
* python/Makefile.am (CLEANFILES): Clean up compiled python files.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit c21c38d71b)
2013-05-06 14:09:11 -06:00
Eric Blake
343ab629cf build: always include libvirt_lxc.syms in tarball
On a mingw build, 'make distcheck' fails with:

  GEN      libvirt_qemu.def
make[3]: *** No rule to make target `../../src/libvirt_lxc.syms', needed by `libvirt_lxc.def'.  Stop.

I traced it to a missing entry in EXTRA_DIST.  But rather than keep
the entire list in sync, it is easier to list the three syms files
that drive .so files directly, and then reuse existing makefile
variables for the remaining files (that is, I validated that all
remaining files are added to SYM_FILES, possibly via USED_SYM_FILES,
according to makefile conditionals).

Problem introduced in commit 3d1596b (v1.0.2).

* src/Makefile.am (EXTRA_DIST): Ensure all syms files are shipped.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit ed11ab93fa)
2013-05-06 14:09:10 -06:00
Laine Stump
97633c8682 qemu: fix stupid typos in VFIO cgroup setup/teardown
I must have looked at this a couple dozen times before I noticed it
had "!=" instead of "==". Not doing this setup prevented qemu from
doing anything with the vfio group device.
(cherry picked from commit 52ba0f6e1c)
2013-05-03 14:49:51 -04:00
Eric Blake
3e7adcf682 build: always include sanitytest in tarball
The libvirt 1.0.5 tarball is missing a file which renders 'make
check' broken; first reported on list by Guido Günther.

* python/Makefile.am (EXTRA_DIST): Hoist sanitytest.py out of
HAVE_PYTHON conditional.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 5a3487dadb)
2013-05-03 11:26:38 -04:00
Guido Günther
2b9bf71b6c virInitctlRequest: unbreak make syntax check
introduced by dcf97846d5

To trigger this cppi needs to be installed.
(cherry picked from commit ca75c44310)
2013-05-03 11:26:25 -04:00
Guido Günther
c2de882f32 virInitctlRequest: unbreak make syntax check
introduced by dcf97846d5
(cherry picked from commit a1365d7351)
2013-05-03 11:26:07 -04:00
Laine Stump
d2686140e1 network: fix network driver startup for qemu:///session
This should resolve https://bugzilla.redhat.com/show_bug.cgi?id=958907

Recent new addition of code to read/write active network state to the
NETWORK_STATE_DIR in the network driver broke startup for
qemu:///session. The network driver had several state file paths
hardcoded to /var, which could never possibly work in session mode.

This patch modifies *all* state files to use a variable string that is
set differently according to whether or not we're running
privileged. (It turns out that logDir was never used, so it's been
completely eliminated.)

There are very definitely other problems preventing dnsmasq and radvd
from running in non-privileged mode, but it's more consistent to have
the directories used by them be determined in the same fashion.

NB: I've noted before that the network driver is storing its state
(including dnsmasq and radvd state) in /var/lib, while qemu stores its
state in /var/run. It would probably have been better if the two
matched, but it's been this way for a long time, and changing it would
break running installations during an upgrade, so it's best to just
leave it as it is.
(cherry picked from commit 2ffd87d820)

Conflicts:
	src/network/bridge_driver.c - code removed by this patch had
                                      been modified upstream.
2013-05-03 11:06:20 -04:00
1872 changed files with 844328 additions and 1212987 deletions

5
.ctags
View File

@@ -1,5 +0,0 @@
--recurse
--exclude=*.orig
--exclude=*.html
--exclude=*.html.in
--langmap=c:+.h.in

103
.gitignore vendored
View File

@@ -3,7 +3,6 @@
*.a
*.cov
*.exe
*.exe.manifest
*.gcda
*.gcno
*.gcov
@@ -14,14 +13,12 @@
*.loT
*.o
*.orig
*.pem
*.pyc
*.rej
*.s
*~
.#*
.deps
.dirstamp
.gdb_history
.git
.git-module-status
@@ -31,6 +28,7 @@
.sc-start-sc_*
/ABOUT-NLS
/AUTHORS
/COPYING
/ChangeLog
/GNUmakefile
/INSTALL
@@ -61,7 +59,6 @@
/daemon/libvirtd.policy
/daemon/libvirtd.service
/daemon/test_libvirtd.aug
/docs/aclperms.htmlinc
/docs/apibuild.py.stamp
/docs/devhelp/libvirt.devhelp
/docs/hvsupport.html.in
@@ -71,7 +68,7 @@
/docs/libvirt-refs.xml
/docs/search.php
/docs/todo.html.in
/examples/object-events/event-test
/examples/domain-events/events-c/event-test
/examples/dominfo/info1
/examples/domsuspend/suspend
/examples/hellolibvirt/hellolibvirt
@@ -93,27 +90,24 @@
/mkinstalldirs
/po/*
/proxy/
/python/
/python/generated.stamp
/python/generator.py.stamp
/python/libvirt-export.c
/python/libvirt-lxc-export.c
/python/libvirt-lxc.[ch]
/python/libvirt-qemu-export.c
/python/libvirt-qemu.[ch]
/python/libvirt.[ch]
/python/libvirt.py
/python/libvirt_lxc.py
/python/libvirt_qemu.py
/run
/sc_*
/src/.*.stamp
/src/access/org.libvirt.api.policy
/src/access/viraccessapicheck.c
/src/access/viraccessapicheck.h
/src/access/viraccessapichecklxc.c
/src/access/viraccessapichecklxc.h
/src/access/viraccessapicheckqemu.c
/src/access/viraccessapicheckqemu.h
/src/esx/*.generated.*
/src/hyperv/*.generated.*
/src/libvirt*.def
/src/libvirt.syms
/src/libvirt_access.syms
/src/libvirt_access.xml
/src/libvirt_access_lxc.syms
/src/libvirt_access_lxc.xml
/src/libvirt_access_qemu.syms
/src/libvirt_access_qemu.xml
/src/libvirt_*.stp
/src/libvirt_*helper
/src/libvirt_*probes.h
@@ -135,41 +129,82 @@
/src/rpc/virkeepaliveprotocol.[ch]
/src/rpc/virnetprotocol.[ch]
/src/test_libvirt*.aug
/src/test_virtlockd.aug
/src/util/virkeymaps.h
/src/virt-aa-helper
/src/virtlockd
/src/virtlockd.8
/src/virtlockd.8.in
/src/virtlockd.init
/tests/*.log
/tests/*.pid
/tests/*.trs
/tests/*xml2*test
/tests/commandhelper
/tests/*test
!/tests/*schematest
!/tests/virt-aa-helper-test
/tests/objectlocking
/tests/objectlocking-files.txt
/tests/objectlocking.cm[ix]
/tests/commandtest
/tests/conftest
/tests/cputest
/tests/domainsnapshotxml2xmltest
/tests/esxutilstest
/tests/eventtest
/tests/hashtest
/tests/jsontest
/tests/libvirtdconftest
/tests/networkxml2argvtest
/tests/nodeinfotest
/tests/nwfilterxml2xmltest
/tests/object-locking
/tests/object-locking-files.txt
/tests/object-locking.cm[ix]
/tests/openvzutilstest
/tests/qemuargv2xmltest
/tests/qemuhelptest
/tests/qemumonitorjsontest
/tests/qemumonitortest
/tests/qemuxmlnstest
/tests/qparamtest
/tests/reconnect
/tests/secaatest
/tests/seclabeltest
/tests/securityselinuxlabeltest
/tests/securityselinuxtest
/tests/sexpr2xmltest
/tests/shunloadtest
/tests/sockettest
/tests/ssh
/tests/statstest
/tests/storagebackendsheepdogtest
/tests/sysinfotest
/tests/test_conf
/tests/utiltest
/tests/viratomictest
/tests/virauthconfigtest
/tests/virbitmaptest
/tests/virbuftest
/tests/vircgrouptest
/tests/virdrivermoduletest
/tests/virendiantest
/tests/virhashtest
/tests/viridentitytest
/tests/virkeycodetest
/tests/virkeyfiletest
/tests/virlockspacetest
/tests/virnet*test
/tests/virportallocatortest
/tests/virshtest
/tests/virstoragetest
/tests/virstringtest
/tests/virtimetest
/tests/viruritest
/tests/vmx2xmltest
/tests/xencapstest
/tests/xmconfigtest
/tools/*.[18]
/tools/libvirt-guests.init
/tools/libvirt-guests.service
/tools/libvirt-guests.sh
/tools/virt-login-shell
/tools/virsh
/tools/virsh-*-edit.c
/tools/virt-*-validate
/tools/virt-sanlock-cleanup
/tools/wireshark/src/plugin.c
/tools/wireshark/src/libvirt
/update.log
GPATH
GRTAGS
GTAGS
Makefile
Makefile.in
TAGS

Submodule .gnulib updated: ce457d622d...644c40496c

View File

@@ -18,7 +18,6 @@ Daniel Veillard <veillard@redhat.com>
Dave Allan <dallan@redhat.com>
Doug Goldstein <cardoe@gentoo.org>
Eric Blake <eblake@redhat.com>
Gao Feng <gaofeng@cn.fujitsu.com>
Guannan Ren <gren@redhat.com>
Guido Günther <agx@sigxcpu.org>
Ján Tomko <jtomko@redhat.com>
@@ -27,16 +26,15 @@ Jim Meyering <meyering@redhat.com>
Jiří Denemark <jdenemar@redhat.com>
John Ferlan <jferlan@redhat.com>
John Levon <john.levon@sun.com>
Justin Clift <jclift@redhat.com>
Laine Stump <laine@redhat.com>
Mark McLoughlin <markmc@redhat.com>
Martin Kletzander <mkletzan@redhat.com>
Matthias Bolte <matthias.bolte@googlemail.com>
Michal Prívozník <mprivozn@redhat.com>
Osier Yang <jyang@redhat.com>
Pavel Hrdina <phrdina@redhat.com>
Peter Krempa <pkrempa@redhat.com>
Richard W.M. Jones <rjones@redhat.com>
Roman Bogorodskiy <bogorodskiy@gmail.com>
Stefan Berger <stefanb@us.ibm.com>
Wen Congyang <wency@cn.fujitsu.com>
@@ -45,7 +43,6 @@ Previous maintainers:
Atsushi SAKAI <sakaia@jp.fujitsu.com>
Dan Smith <danms@us.ibm.com>
Dave Leskovec <dlesko@linux.vnet.ibm.com>
Justin Clift <jclift@redhat.com>
Karel Zak <kzak@redhat.com>
Patches have also been contributed by:

339
COPYING
View File

@@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@@ -5504,7 +5504,7 @@ Tue Nov 11 15:51:42 GMT 2008 Daniel P. Berrange <berrange@redhat.com>
Mon Nov 10 12:05:42 GMT 2008 Daniel P. Berrange <berrange@redhat.com>
* src/openvz_conf.c: Read filesystem template name from config
* src/openvz_conf.c: Read filesytem template name from config
files. Increase buffer size when parsing vzctl version number
Thu Nov 6 20:45:42 CET 2008 Jim Meyering <meyering@redhat.com>
@@ -13920,7 +13920,7 @@ Tue Feb 27 10:20:43 EST 2007 Daniel P. Berrange <berrange@redhat.com>
* src/xend_internal.c: Only hardcode port = 5900+domid if
running against old XenD < 3.0.3, because in newer XenD
port is guaranteed to be available in XenStore if the VNC
port is guarenteed to be available in XenStore if the VNC
server is running.
Mon Feb 26 15:33:08 IST 2007 Mark McLoughlin <markmc@redhat.com>
@@ -15228,7 +15228,7 @@ Sun Sep 3 12:34:23 EDT 2006 Daniel Berrange <berrange@redhat.com>
iterating over list of ids/names, because it is not neccessarily
the same as the value returned by virConnectNumOfDomains. Use qsort
to sort active domains by Id, and inactive domains by name, since
there is no guaranteed sort ordering when listing domains. For inactive
there is no guarenteed sort ordering when listing domains. For inactive
domains display a '-' instead of '-1' to make it clear they have no
sensible ID number.

157
HACKING
View File

@@ -45,7 +45,7 @@ post your patches:
--to=libvir-list@redhat.com master
(Note that the "git send-email" subcommand may not be in the main git package
and using it may require installation of a separate package, for example the
and using it may require installion of a separate package, for example the
"git-email" package in Fedora.) For a single patch you can omit
"--cover-letter", but a series of two or more patches needs a cover letter. If
you get tired of typing "--to=libvir-list@redhat.com" designation you can set
@@ -104,17 +104,11 @@ and run the tests:
make syntax-check
make -C tests valgrind
Valgrind <http://valgrind.org/> is a test that checks for memory management
issues, such as leaks or use of uninitialized variables.
Some tests are skipped by default in a development environment, based on the
time they take in comparison to the likelihood that those tests will turn up
problems during incremental builds. These tests default to being run when when
building from a tarball or with the configure option --enable-expensive-tests;
you can also force a one-time toggle of these tests by setting
VIR_TEST_EXPENSIVE to 0 or 1 at make time, as in:
make check VIR_TEST_EXPENSIVE=1
Valgrind
http://valgrind.org/is a test that checks for memory management issues, such as leaks or use of
uninitialized variables.
If you encounter any failing tests, the VIR_TEST_DEBUG environment variable
may provide extra information to debug the failures. Larger values of
@@ -123,11 +117,6 @@ VIR_TEST_DEBUG may provide larger amounts of information:
VIR_TEST_DEBUG=1 make check (or)
VIR_TEST_DEBUG=2 make check
When debugging failures during development, it is possible to focus in on just
the failing subtests by using TESTS and VIR_TEST_RANGE:
make check VIR_TEST_DEBUG=1 VIR_TEST_RANGE=3-5 TESTS=qemuxml2argvtest
Also, individual tests can be run from inside the "tests/" directory, like:
./qemuxml2xmltest
@@ -198,8 +187,11 @@ In this instance, it is acceptable to modify the "tests/.valgrind.supp" file
in order to add a suppression filter. The filter should be unique enough to
not suppress real leaks, but it should be generic enough to cover multiple
code paths. The format of the entry can be found in the documentation found at
the Valgrind home page <http://valgrind.org/>. The following trace was added
to "tests/.valgrind.supp" in order to suppress the warning:
the
Valgrind home page.
http://valgrind.org/The following trace was added to "tests/.valgrind.supp" in order to suppress
the warning:
{
dlInitMemoryLeak1
@@ -220,8 +212,10 @@ feature or changing the output of a program.
There is more on this subject, including lots of links to background reading
on the subject, on Richard Jones' guide to working with open source projects
<http://et.redhat.com/~rjones/how-to-supply-code-to-open-source-projects/>.
on the subject, on
Richard Jones' guide to working with open source projects
http://et.redhat.com/~rjones/how-to-supply-code-to-open-source-projects/
Code indentation
@@ -232,9 +226,22 @@ but we do prefer that contributed code be formatted similarly. In short, use
spaces-not-TABs for indentation, use 4 spaces for each indentation level, and
other than that, follow the K&R style.
If you use Emacs, the project includes a file .dir-locals.el that sets up the
preferred indentation. If you use vim, append the following to your ~/.vimrc
file:
If you use Emacs, add the following to one of one of your start-up files
(e.g., ~/.emacs), to help ensure that you get indentation right:
;;; When editing C sources in libvirt, use this style.
(defun libvirt-c-mode ()
"C mode with adjusted defaults for use with libvirt."
(interactive)
(c-set-style "K&R")
(setq indent-tabs-mode nil) ; indent using spaces, not TABs
(setq c-indent-level 4)
(setq c-basic-offset 4))
(add-hook 'c-mode-hook
'(lambda () (if (string-match "/libvirt" (buffer-file-name))
(libvirt-c-mode))))
If you use vim, append the following to your ~/.vimrc file:
set nocompatible
filetype on
@@ -244,7 +251,7 @@ file:
set tabstop=8
set shiftwidth=4
set expandtab
set cinoptions=(0,:0,l1,t0,L3
set cinoptions=(0,:0,l1,t0
filetype plugin indent on
au FileType make setlocal noexpandtab
au BufRead,BufNewFile *.am setlocal noexpandtab
@@ -312,58 +319,6 @@ immediately prior to any closing bracket. E.g.
int foo(int wizz); // Good
Commas
======
Commas should always be followed by a space or end of line, and never have
leading space; this is enforced during 'make syntax-check'.
call(a,b ,c);// Bad
call(a, b, c); // Good
When declaring an enum or using a struct initializer that occupies more than
one line, use a trailing comma. That way, future edits to extend the list only
have to add a line, rather than modify an existing line to add the
intermediate comma. Any sentinel enumerator value with a name ending in _LAST
is exempt, since you would extend such an enum before the _LAST element.
Another reason to favor trailing commas is that it requires less effort to
produce via code generators. Note that the syntax checker is unable to enforce
a style of trailing commas, so there are counterexamples in existing code
which do not use it; also, while C99 allows trailing commas, remember that
JSON and XDR do not.
enum {
VALUE_ONE,
VALUE_TWO // Bad
};
enum {
VALUE_THREE,
VALUE_FOUR, // Good
};
Semicolons
==========
Semicolons should never have a space beforehand. Inside the condition of a
"for" loop, there should always be a space or line break after each semicolon,
except for the special case of an infinite loop (although more infinite loops
use "while"). While not enforced, loop counters generally use post-increment.
for (i = 0 ;i < limit ; ++i) { // Bad
for (i = 0; i < limit; i++) { // Good
for (;;) { // ok
while (1) { // Better
Empty loop bodies are better represented with curly braces and a comment,
although use of a semicolon is not currently rejected.
while ((rc = waitpid(pid, &st, 0) == -1) &&
errno == EINTR); // ok
while ((rc = waitpid(pid, &st, 0) == -1) &&
errno == EINTR) { // Better
/* nothing */
}
Curly braces
============
Omit the curly braces around an "if", "while", "for" etc. body only when that
@@ -464,11 +419,6 @@ But if negating a complex condition is too ugly, then at least add braces:
Preprocessor
============
Macros defined with an ALL_CAPS name should generally be assumed to be unsafe
with regards to arguments with side-effects (that is, MAX(a++, b--) might
increment a or decrement b too many or too few times). Exceptions to this rule
are explicitly documented for macros in viralloc.h and virstring.h.
For variadic macros, stick with C99 syntax:
#define vshPrint(_ctl, ...) fprintf(stdout, __VA_ARGS__)
@@ -552,14 +502,16 @@ Low level memory management
Use of the malloc/free/realloc/calloc APIs is deprecated in the libvirt
codebase, because they encourage a number of serious coding bugs and do not
enable compile time verification of checks for NULL. Instead of these
routines, use the macros from viralloc.h.
routines, use the macros from memory.h.
- To allocate a single object:
virDomainPtr domain;
if (VIR_ALLOC(domain) < 0)
if (VIR_ALLOC(domain) < 0) {
virReportOOMError();
return NULL;
}
@@ -568,8 +520,10 @@ routines, use the macros from viralloc.h.
virDomainPtr domains;
size_t ndomains = 10;
if (VIR_ALLOC_N(domains, ndomains) < 0)
if (VIR_ALLOC_N(domains, ndomains) < 0) {
virReportOOMError();
return NULL;
}
@@ -578,8 +532,10 @@ routines, use the macros from viralloc.h.
virDomainPtr *domains;
size_t ndomains = 10;
if (VIR_ALLOC_N(domains, ndomains) < 0)
if (VIR_ALLOC_N(domains, ndomains) < 0) {
virReportOOMError();
return NULL;
}
@@ -590,8 +546,10 @@ recommended only for smaller arrays):
virDomainPtr domains;
size_t ndomains = 0;
if (VIR_EXPAND_N(domains, ndomains, 1) < 0)
if (VIR_EXPAND_N(domains, ndomains, 1) < 0) {
virReportOOMError();
return NULL;
}
domains[ndomains - 1] = domain;
@@ -603,8 +561,10 @@ scales better, but requires tracking allocation separately from usage)
size_t ndomains = 0;
size_t ndomains_max = 0;
if (VIR_RESIZE_N(domains, ndomains_max, ndomains, 1) < 0)
if (VIR_RESIZE_N(domains, ndomains_max, ndomains, 1) < 0) {
virReportOOMError();
return NULL;
}
domains[ndomains++] = domain;
@@ -760,17 +720,6 @@ sizeof(dest) returns something meaningful). Note that this is a macro, so
arguments could be evaluated more than once. This is equivalent to
virStrncpy(dest, src, strlen(src), sizeof(dest)).
VIR_STRDUP(char *dst, const char *src);
VIR_STRNDUP(char *dst, const char *src, size_t n);
You should avoid using strdup or strndup directly as they do not report
out-of-memory error, and do not allow a NULL source. Use VIR_STRDUP or
VIR_STRNDUP macros instead, which return 0 for NULL source, 1 for successful
copy, and -1 for allocation failure with the error already reported. In very
specific cases, when you don't want to report the out-of-memory error, you can
use VIR_STRDUP_QUIET or VIR_STRNDUP_QUIET, but such usage is very rare and
usually considered a flaw.
Variable length string buffer
=============================
@@ -906,7 +855,9 @@ logic would be better pulled out into a helper function.
Although libvirt does not encourage the Linux kernel wind/unwind style of
multiple labels, there's a good general discussion of the issue archived at
KernelTrap <http://kerneltrap.org/node/553/2131>
KernelTrap
http://kerneltrap.org/node/553/2131
When using goto, please use one of these standard labels if it makes sense:
@@ -915,16 +866,6 @@ When using goto, please use one of these standard labels if it makes sense:
no_memory: A path only taken upon return with an OOM error code
retry: If needing to jump upwards (e.g., retry on EINTR)
Top-level labels should be indented by one space (putting them on the
beginning of the line confuses function context detection in git):
int foo()
{
/* ... do stuff ... */
cleanup:
/* ... do other stuff ... */
}
Libvirt committer guidelines
============================

View File

@@ -1,38 +1,23 @@
## Process this file with automake to produce Makefile.in
## Copyright (C) 2005-2013 Red Hat, Inc.
##
## This library is free software; you can redistribute it and/or
## modify it under the terms of the GNU Lesser General Public
## License as published by the Free Software Foundation; either
## version 2.1 of the License, or (at your option) any later version.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public
## License along with this library. If not, see
## <http://www.gnu.org/licenses/>.
## Copyright (C) 2005-2012 Red Hat, Inc.
## See COPYING.LIB for the License of this software
LCOV = lcov
GENHTML = genhtml
SUBDIRS = . gnulib/lib include src daemon tools docs gnulib/tests \
tests po examples/object-events examples/hellolibvirt \
examples/dominfo examples/domsuspend examples/apparmor \
examples/xml/nwfilter examples/openauth examples/systemtap \
tools/wireshark
SUBDIRS = gnulib/lib include src daemon tools docs gnulib/tests \
python tests po examples/domain-events/events-c examples/hellolibvirt \
examples/dominfo examples/domsuspend examples/python examples/apparmor \
examples/xml/nwfilter examples/openauth examples/systemtap
ACLOCAL_AMFLAGS = -I m4
ACLOCAL_AMFLAGS = -I m4 -I gnulib/m4
XML_EXAMPLES = \
$(patsubst $(srcdir)/%,%,$(wildcard $(addprefix $(srcdir)/examples/xml/, \
test/*.xml storage/*.xml)))
EXTRA_DIST = \
config-post.h \
ChangeLog-old \
libvirt.spec libvirt.spec.in \
mingw-libvirt.spec.in \
@@ -41,6 +26,7 @@ EXTRA_DIST = \
Makefile.nonreentrant \
autogen.sh \
cfg.mk \
examples/domain-events/events-python \
run.in \
AUTHORS.in \
$(XML_EXAMPLES)
@@ -56,13 +42,10 @@ NEWS: $(top_srcdir)/docs/news.xsl $(top_srcdir)/docs/news.html.in
| perl -pe 's/[ \t]+$$//' \
> $@-t && mv $@-t $@ ; fi
$(top_srcdir)/HACKING: $(top_srcdir)/docs/hacking1.xsl \
$(top_srcdir)/docs/hacking2.xsl \
$(top_srcdir)/docs/wrapstring.xsl \
$(top_srcdir)/docs/hacking.html.in
$(top_srcdir)/HACKING: $(top_srcdir)/docs/hacking1.xsl $(top_srcdir)/docs/hacking2.xsl \
$(top_srcdir)/docs/wrapstring.xsl $(top_srcdir)/docs/hacking.html.in
$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
$(XSLTPROC) --nonet $(top_srcdir)/docs/hacking1.xsl \
$(top_srcdir)/docs/hacking.html.in | \
$(XSLTPROC) --nonet $(top_srcdir)/docs/hacking1.xsl $(top_srcdir)/docs/hacking.html.in | \
$(XSLTPROC) --nonet $(top_srcdir)/docs/hacking2.xsl - \
| perl -0777 -pe 's/\n\n+$$/\n/' \
> $@-t && mv $@-t $@ ; fi;
@@ -72,6 +55,11 @@ rpm: clean
check-local: all tests
tests:
@(cd docs/examples ; $(MAKE) MAKEFLAGS+=--silent tests)
@(if [ "$(pythondir)" != "" ] ; then cd python ; \
$(MAKE) MAKEFLAGS+=--silent tests ; fi)
cov: clean-cov
mkdir $(top_builddir)/coverage
$(LCOV) -c -o $(top_builddir)/coverage/libvirt.info.tmp \

View File

@@ -1,18 +1,3 @@
## Copyright (C) 2009-2010, 2013 Red Hat, Inc.
##
## This library is free software; you can redistribute it and/or
## modify it under the terms of the GNU Lesser General Public
## License as published by the Free Software Foundation; either
## version 2.1 of the License, or (at your option) any later version.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public
## License along with this library. If not, see
## <http://www.gnu.org/licenses/>.
#
# Generated by running the following on Fedora 9:

View File

@@ -8,13 +8,6 @@ set -v
test -n "$1" && RESULTS=$1 || RESULTS=results.log
: ${AUTOBUILD_INSTALL_ROOT=$HOME/builder}
# If run under the autobuilder, we must use --nodeps with rpmbuild;
# but this can lead to odd error diagnosis for normal development.
nodeps=
if test "${AUTOBUILD_COUNTER+set}"; then
nodeps=--nodeps
fi
test -f Makefile && make -k distclean || :
rm -rf coverage
@@ -25,7 +18,6 @@ cd build
# Run with options not normally exercised by the rpm build, for
# more complete code coverage.
../autogen.sh --prefix="$AUTOBUILD_INSTALL_ROOT" \
--enable-expensive-tests \
--enable-test-coverage \
--disable-nls \
--enable-werror \
@@ -67,7 +59,7 @@ else
fi
if test -f /usr/bin/rpmbuild ; then
rpmbuild $nodeps \
rpmbuild --nodeps \
--define "extra_release $EXTRA_RELEASE" \
--define "_sourcedir `pwd`" \
-ba --clean libvirt.spec
@@ -77,16 +69,15 @@ fi
if test -x /usr/bin/i686-w64-mingw32-gcc ; then
make distclean
PKG_CONFIG_LIBDIR="/usr/i686-w64-mingw32/sys-root/mingw/lib/pkgconfig:/usr/i686-w64-mingw32/sys-root/mingw/share/pkgconfig" \
PKG_CONFIG_PATH="$AUTOBUILD_INSTALL_ROOT/i686-w64-mingw32/sys-root/mingw/lib/pkgconfig" \
CC="i686-w64-mingw32-gcc" \
../configure \
--build=$(uname -m)-w64-linux \
--host=i686-w64-mingw32 \
--prefix="$AUTOBUILD_INSTALL_ROOT/i686-w64-mingw32/sys-root/mingw" \
--enable-expensive-tests \
--enable-werror \
--without-libvirtd
--without-libvirtd \
--without-python
make
make install
@@ -97,16 +88,15 @@ fi
if test -x /usr/bin/x86_64-w64-mingw32-gcc ; then
make distclean
PKG_CONFIG_LIBDIR="/usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig:/usr/x86_64-w64-mingw32/sys-root/mingw/share/pkgconfig" \
PKG_CONFIG_PATH="$AUTOBUILD_INSTALL_ROOT/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig" \
CC="x86_64-w64-mingw32-gcc" \
../configure \
--build=$(uname -m)-w64-linux \
--host=x86_64-w64-mingw32 \
--prefix="$AUTOBUILD_INSTALL_ROOT/x86_64-w64-mingw32/sys-root/mingw" \
--enable-expensive-tests \
--enable-werror \
--without-libvirtd
--without-libvirtd \
--without-python
make
make install
@@ -116,7 +106,7 @@ fi
if test -x /usr/bin/i686-w64-mingw32-gcc && test -x /usr/bin/x86_64-w64-mingw32-gcc ; then
if test -f /usr/bin/rpmbuild ; then
rpmbuild $nodeps \
rpmbuild --nodeps \
--define "extra_release $EXTRA_RELEASE" \
--define "_sourcedir `pwd`" \
-ba --clean mingw-libvirt.spec

View File

@@ -64,7 +64,7 @@ bootstrap_hash()
# like to run 'git clean -x -f po' to fix it; but only ./bootstrap regenerates
# the required file po/Makevars.
# Only run bootstrap from a git checkout, never from a tarball.
if test -d .git || test -f .git; then
if test -d .git; then
curr_status=.git-module-status t=
if test "$no_git"; then
t=no-git

View File

@@ -1,10 +1,10 @@
#! /bin/sh
# Print a version string.
scriptversion=2013-12-05.23; # UTC
scriptversion=2013-07-03.20; # UTC
# Bootstrap this package from checked-out sources.
# Copyright (C) 2003-2014 Free Software Foundation, Inc.
# Copyright (C) 2003-2013 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -209,16 +209,12 @@ bootstrap_sync=false
# Use git to update gnulib sources
use_git=true
check_exists() {
($1 --version </dev/null) >/dev/null 2>&1
test $? -lt 126
}
# find_tool ENVVAR NAMES...
# -------------------------
# Search for a required program. Use the value of ENVVAR, if set,
# otherwise find the first of the NAMES that can be run.
# If found, set ENVVAR to the program name, die otherwise.
# otherwise find the first of the NAMES that can be run (i.e.,
# supports --version). If found, set ENVVAR to the program name,
# die otherwise.
#
# FIXME: code duplication, see also gnu-web-doc-update.
find_tool ()
@@ -228,21 +224,27 @@ find_tool ()
find_tool_names=$@
eval "find_tool_res=\$$find_tool_envvar"
if test x"$find_tool_res" = x; then
for i; do
if check_exists $i; then
find_tool_res=$i
break
for i
do
if ($i --version </dev/null) >/dev/null 2>&1; then
find_tool_res=$i
break
fi
done
else
find_tool_error_prefix="\$$find_tool_envvar: "
fi
if test x"$find_tool_res" = x; then
warn_ "one of these is required: $find_tool_names;"
die "alternatively set $find_tool_envvar to a compatible tool"
fi
test x"$find_tool_res" != x \
|| die "one of these is required: $find_tool_names"
($find_tool_res --version </dev/null) >/dev/null 2>&1 \
|| die "${find_tool_error_prefix}cannot run $find_tool_res --version"
eval "$find_tool_envvar=\$find_tool_res"
eval "export $find_tool_envvar"
}
# Find sha1sum, named gsha1sum on MacPorts, and shasum on Mac OS X 10.6.
find_tool SHA1SUM sha1sum gsha1sum shasum
# Override the default configuration, if necessary.
# Make sure that bootstrap.conf is sourced from the current directory
# if we were invoked as "sh bootstrap".
@@ -324,7 +326,7 @@ insert_if_absent() {
die "Error: Duplicate entries in $file: " $duplicate_entries
fi
linesold=$(gitignore_entries $file | wc -l)
linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l)
linesnew=$(echo "$str" | gitignore_entries - $file | sort -u | wc -l)
if [ $linesold != $linesnew ] ; then
{ echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \
|| die "insert_if_absent $file $str: failed"
@@ -467,7 +469,8 @@ check_versions() {
if [ "$req_ver" = "-" ]; then
# Merely require app to exist; not all prereq apps are well-behaved
# so we have to rely on $? rather than get_version.
if ! check_exists $app; then
$app --version >/dev/null 2>&1
if [ 126 -le $? ]; then
warn_ "Error: '$app' not found"
ret=1
fi
@@ -500,12 +503,6 @@ print_versions() {
# can't depend on column -t
}
# Find sha1sum, named gsha1sum on MacPorts, shasum on Mac OS X 10.6.
# Also find the compatible sha1 utility on the BSDs
if test x"$SKIP_PO" = x; then
find_tool SHA1SUM sha1sum gsha1sum shasum sha1
fi
use_libtool=0
# We'd like to use grep -E, to see if any of LT_INIT,
# AC_PROG_LIBTOOL, AM_PROG_LIBTOOL is used in configure.ac,
@@ -551,21 +548,13 @@ if ! printf "$buildreq" | check_versions; then
fi
fi
# Warn the user if autom4te appears to be broken; this causes known
# issues with at least gettext 0.18.3.
probe=$(echo 'm4_quote([hi])' | autom4te -l M4sugar -t 'm4_quote:$%' -)
if test "x$probe" != xhi; then
warn_ "WARNING: your autom4te wrapper eats stdin;"
warn_ "if bootstrap fails, consider upgrading your autotools"
fi
echo "$0: Bootstrapping from checked-out $package sources..."
# See if we can use gnulib's git-merge-changelog merge driver.
if $use_git && test -d .git && check_exists git; then
if $use_git && test -d .git && (git --version) >/dev/null 2>/dev/null ; then
if git config merge.merge-changelog.driver >/dev/null ; then
:
elif check_exists git-merge-changelog; then
elif (git-merge-changelog --version) >/dev/null 2>/dev/null ; then
echo "$0: initializing git-merge-changelog driver"
git config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
git config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
@@ -703,10 +692,11 @@ update_po_files() {
cksum_file="$ref_po_dir/$po.s1"
if ! test -f "$cksum_file" ||
! test -f "$po_dir/$po.po" ||
! $SHA1SUM -c "$cksum_file" < "$new_po" > /dev/null 2>&1; then
! $SHA1SUM -c --status "$cksum_file" \
< "$new_po" > /dev/null; then
echo "$me: updated $po_dir/$po.po..."
cp "$new_po" "$po_dir/$po.po" \
&& $SHA1SUM < "$new_po" > "$cksum_file" || return
&& $SHA1SUM < "$new_po" > "$cksum_file"
fi
done
}

View File

@@ -71,8 +71,6 @@ listen
localeconv
maintainer-makefile
manywarnings
mgetgroups
mkdtemp
mkostemp
mkostemps
mktempd
@@ -93,7 +91,6 @@ recv
regex
random_r
sched
secure_getenv
send
setenv
setsockopt
@@ -176,11 +173,11 @@ fi
# Tell gnulib to:
# require LGPLv2+
# apply any local diffs in gnulib/local/ dir
# put *.m4 files in m4/ dir
# put *.m4 files in new gnulib/m4/ dir
# put *.[ch] files in new gnulib/lib/ dir
# import gnulib tests in new gnulib/tests/ dir
gnulib_name=libgnu
m4_base=m4
m4_base=gnulib/m4
source_base=gnulib/lib
tests_base=gnulib/tests
gnulib_tool_option_extras="\
@@ -192,6 +189,11 @@ gnulib_tool_option_extras="\
"
local_gl_dir=gnulib/local
# Convince bootstrap to use multiple m4 directories.
: ${ACLOCAL=aclocal}
ACLOCAL="$ACLOCAL -I m4"
export ACLOCAL
# Build prerequisites
# Note that some of these programs are only required for 'make dist' to
# succeed from a fresh git checkout; not all of these programs are
@@ -237,11 +239,12 @@ gnulib_extra_files="
"
bootstrap_post_import_hook()
bootstrap_epilogue()
{
# Change paths in gnulib/tests/gnulib.mk from "../../.." to "../..",
# and make tests conditional by changing "TESTS" to "GNULIB_TESTS".
# then ensure that gnulib/tests/Makefile.in is up-to-date.
m=gnulib/tests/gnulib.mk
sed 's,\.\./\.\./\.\.,../..,g; s/^TESTS /GNULIB_TESTS /' $m > $m-t
sed 's,\.\./\.\./\.\.,../..,g' $m > $m-t
mv -f $m-t $m
${AUTOMAKE-automake} gnulib/tests/Makefile
}

View File

@@ -1,7 +1,6 @@
#!/usr/bin/perl
#
# bracket-spacing.pl: Report any usage of 'function (..args..)'
# Also check for other syntax issues, such as correct use of ';'
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -32,11 +31,8 @@ foreach my $file (@ARGV) {
while (defined (my $line = <FILE>)) {
my $data = $line;
# Kill any quoted , ; or "
$data =~ s/'[";,]'/'X'/g;
# Kill any quoted strings
$data =~ s,"([^\\\"]|\\.)*","XXX",g;
# Kill any quoted strongs
$data =~ s,".*?","XXX",g;
# Kill any C++ style comments
$data =~ s,//.*$,//,;
@@ -92,8 +88,8 @@ foreach my $file (@ARGV) {
# Require whitespace immediately after keywords,
# but none after the opening bracket
while ($data =~ /\b(if|for|while|switch|return)\(/ ||
$data =~ /\b(if|for|while|switch|return)\s+\(\s/) {
while ($data =~ /(if|for|while|switch|return)\(/ ||
$data =~ /(if|for|while|switch|return)\s+\(\s/) {
print "$file:$.: $line";
$ret = 1;
last;
@@ -113,48 +109,6 @@ foreach my $file (@ARGV) {
$ret = 1;
last;
}
# Forbid whitespace before ";" or ",". Things like below are allowed:
#
# 1) The expression is empty for "for" loop. E.g.
# for (i = 0; ; i++)
#
# 2) An empty statement. E.g.
# while (write(statuswrite, &status, 1) == -1 &&
# errno == EINTR)
# ;
#
while ($data =~ /[^;\s]\s+[;,]/) {
print "$file:$.: $line";
$ret = 1;
last;
}
# Require EOL, macro line continuation, or whitespace after ";".
# Allow "for (;;)" as an exception.
while ($data =~ /;[^ \\\n;)]/) {
print "$file:$.: $line";
$ret = 1;
last;
}
# Require EOL, space, or enum/struct end after comma.
while ($data =~ /,[^ \\\n)}]/) {
print "$file:$.: $line";
$ret = 1;
last;
}
# Require spaces around assignment '=', compounds and '=='
# with the exception of virAssertCmpInt()
while ($data =~ /[^!<>&|\-+*\/%\^'= ]=\+[^=]/ ||
$data =~ /[^!<>&|\-+*\/%\^'=]=[^= \\\n]/ ||
$data =~ /[\S]==/ ||
($data =~ /==[^\s,]/ && $data !~ /[\s]virAssertCmpInt\(/)) {
print "$file:$.: $line";
$ret = 1;
last;
}
}
close FILE;
}

248
cfg.mk
View File

@@ -1,5 +1,5 @@
# Customize Makefile.maint. -*- makefile -*-
# Copyright (C) 2008-2014 Red Hat, Inc.
# Copyright (C) 2008-2013 Red Hat, Inc.
# Copyright (C) 2003-2008 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
@@ -33,9 +33,8 @@ gnulib_dir = $(srcdir)/.gnulib
# This is all gnulib files, as well as generated files for RPC code.
generated_files = \
$(srcdir)/daemon/*_dispatch.h \
$(srcdir)/src/*/*_dispatch.h \
$(srcdir)/src/remote/*_client_bodies.h \
$(srcdir)/src/*/*_protocol.[ch] \
$(srcdir)/src/remote/*_protocol.[ch] \
$(srcdir)/gnulib/lib/*.[ch]
# We haven't converted all scripts to using gnulib's init.sh yet.
@@ -125,8 +124,9 @@ useless_free_options = \
--name=virDomainDeviceDefFree \
--name=virDomainDiskDefFree \
--name=virDomainEventCallbackListFree \
--name=virObjectEventQueueFree \
--name=virObjectEventStateFree \
--name=virDomainEventFree \
--name=virDomainEventQueueFree \
--name=virDomainEventStateFree \
--name=virDomainFSDefFree \
--name=virDomainGraphicsDefFree \
--name=virDomainHostdevDefFree \
@@ -165,7 +165,6 @@ useless_free_options = \
--name=virNodeDeviceObjFree \
--name=virObjectUnref \
--name=virObjectFreeCallback \
--name=virPCIDeviceFree \
--name=virSecretDefFree \
--name=virStorageEncryptionFree \
--name=virStorageEncryptionSecretFree \
@@ -204,6 +203,7 @@ useless_free_options = \
# y virDomainDeviceDefFree
# y virDomainDiskDefFree
# y virDomainEventCallbackListFree
# y virDomainEventFree
# y virDomainEventQueueFree
# y virDomainFSDefFree
# n virDomainFree
@@ -378,19 +378,10 @@ sc_prohibit_strtol:
$(_sc_search_regexp)
# Use virAsprintf rather than as'printf since *strp is undefined on error.
# But for plain %s, virAsprintf is overkill compared to strdup.
sc_prohibit_asprintf:
@prohibit='\<v?a[s]printf\>' \
halt='use virAsprintf, not as'printf \
$(_sc_search_regexp)
@prohibit='virAsprintf.*, *"%s",' \
halt='use VIR_STRDUP instead of virAsprintf with "%s"' \
$(_sc_search_regexp)
sc_prohibit_strdup:
@prohibit='\<strn?dup\> *\(' \
halt='use VIR_STRDUP, not strdup' \
$(_sc_search_regexp)
# Prefer virSetUIDGID.
sc_prohibit_setuid:
@@ -449,11 +440,6 @@ sc_prohibit_nonreentrant:
done ; \
exit $$fail
sc_prohibit_select:
@prohibit="\\<select *\\(" \
halt="use poll(), not se""lect()" \
$(_sc_search_regexp)
# Prohibit the inclusion of <ctype.h>.
sc_prohibit_ctype_h:
@prohibit='^# *include *<ctype\.h>' \
@@ -466,18 +452,6 @@ sc_correct_id_types:
halt="use pid_t for pid, uid_t for uid, gid_t for gid" \
$(_sc_search_regexp)
# "const fooPtr a" is the same as "foo * const a", even though it is
# usually desired to have "foo const *a". It's easier to just prevent
# the confusing mix of typedef vs. const placement.
# Also requires that all 'fooPtr' typedefs are actually pointers.
sc_forbid_const_pointer_typedef:
@prohibit='(^|[^"])const \w*Ptr' \
halt='"const fooPtr var" does not declare what you meant' \
$(_sc_search_regexp)
@prohibit='typedef [^(]+ [^*]\w*Ptr\b' \
halt='use correct style and type for Ptr typedefs' \
$(_sc_search_regexp)
# Forbid sizeof foo or sizeof (foo), require sizeof(foo)
sc_size_of_brackets:
@prohibit='sizeof\s' \
@@ -512,16 +486,6 @@ sc_prohibit_virBufferAdd_with_string_literal:
halt='use virBufferAddLit, not virBufferAdd, with a string literal' \
$(_sc_search_regexp)
sc_prohibit_virBufferAsprintf_with_string_literal:
@prohibit='\<virBufferAsprintf *\([^,]+, *"([^%"\]|\\.|%%)*"\)' \
halt='use virBufferAddLit, not virBufferAsprintf, with a string literal' \
$(_sc_search_regexp)
sc_forbid_manual_xml_indent:
@prohibit='virBuffer.*" +<' \
halt='use virBufferAdjustIndent instead of spaces when indenting xml' \
$(_sc_search_regexp)
# Not only do they fail to deal well with ipv6, but the gethostby*
# functions are also not thread-safe.
sc_prohibit_gethostby:
@@ -561,23 +525,6 @@ sc_avoid_attribute_unused_in_header:
halt='use ATTRIBUTE_UNUSED in .c rather than .h files' \
$(_sc_search_regexp)
sc_prohibit_int_ijk:
@prohibit='\<(int|unsigned) ([^(]* )*(i|j|k)\>(\s|,|;)' \
halt='use size_t, not int/unsigned int for loop vars i, j, k' \
$(_sc_search_regexp)
sc_prohibit_loop_iijjkk:
@prohibit='\<(int|unsigned) ([^=]+ )*(ii|jj|kk)\>(\s|,|;)' \
halt='use i, j, k for loop iterators, not ii, jj, kk' \
$(_sc_search_regexp)
# RHEL 5 gcc can't grok "for (int i..."
sc_prohibit_loop_var_decl:
@prohibit='\<for *\(\w+[ *]+\w+' \
in_vc_files='\.[ch]$$' \
halt='declare loop iterators outside the for statement' \
$(_sc_search_regexp)
# Many of the function names below came from this filter:
# git grep -B2 '\<_('|grep -E '\.c- *[[:alpha:]_][[:alnum:]_]* ?\(.*[,;]$' \
# |sed 's/.*\.c- *//'|perl -pe 's/ ?\(.*//'|sort -u \
@@ -590,6 +537,16 @@ msg_gen_function += regerror
msg_gen_function += vah_error
msg_gen_function += vah_warning
msg_gen_function += virGenericReportError
msg_gen_function += virLibConnError
msg_gen_function += virLibDomainError
msg_gen_function += virLibDomainSnapshotError
msg_gen_function += virLibInterfaceError
msg_gen_function += virLibNetworkError
msg_gen_function += virLibNodeDeviceError
msg_gen_function += virLibNWFilterError
msg_gen_function += virLibSecretError
msg_gen_function += virLibStoragePoolError
msg_gen_function += virLibStorageVolError
msg_gen_function += virRaiseError
msg_gen_function += virReportError
msg_gen_function += virReportErrorHelper
@@ -698,27 +655,6 @@ sc_spec_indentation:
echo '$(ME): skipping test $@: cppi not installed' 1>&2; \
fi
# Nested conditionals are easier to understand if we enforce that endifs
# can be paired back to the if
sc_makefile_conditionals:
@prohibit='(else|endif)($$| *#)' \
in_vc_files='Makefile\.am' \
halt='match "if FOO" with "endif FOO" in Makefiles' \
$(_sc_search_regexp)
# Long lines can be harder to diff; too long, and git send-email chokes.
# For now, only enforce line length on files where we have intentionally
# fixed things and don't want to regress.
sc_prohibit_long_lines:
@prohibit='.{90}' \
in_vc_files='\.arg[sv]' \
halt='Wrap long lines in expected output files' \
$(_sc_search_regexp)
@prohibit='.{80}' \
in_vc_files='Makefile\.am' \
halt='Wrap long lines in Makefiles' \
$(_sc_search_regexp)
sc_copyright_format:
@require='Copyright .*Red 'Hat', Inc\.' \
containing='Copyright .*Red 'Hat \
@@ -732,22 +668,11 @@ sc_copyright_format:
$(_sc_search_regexp)
# Prefer the new URL listing over the old street address listing when
# calling out where to get a copy of the [L]GPL. Also, while we have
# to ship COPYING (GPL) alongside COPYING.LESSER (LGPL), we want any
# source file that calls out a top-level file to call out the LGPL
# version. Note that our typical copyright boilerplate refers to the
# license by name, not by reference to a top-level file.
sc_copyright_usage:
# calling out where to get a copy of the [L]GPL.
sc_copyright_address:
@prohibit=Boston,' MA' \
halt='Point to <http://www.gnu.org/licenses/>, not an address' \
$(_sc_search_regexp)
@require='COPYING\.LESSER' \
containing='COPYING' \
halt='Refer to COPYING.LESSER for LGPL' \
$(_sc_search_regexp)
@prohibit='COPYING\.LIB' \
halt='Refer to COPYING.LESSER for LGPL' \
$(_sc_search_regexp)
# Some functions/macros produce messages intended solely for developers
# and maintainers. Do not mark them for translation.
@@ -769,7 +694,6 @@ sc_prohibit_cross_inclusion:
cpu/ | locking/ | network/ | rpc/ | security/) \
safe="($$dir|util|conf)";; \
xenapi/ | xenxs/ ) safe="($$dir|util|conf|xen)";; \
qemu/ ) safe="($$dir|util|conf|cpu|network|locking|rpc|security|storage)";; \
*) safe="($$dir|util|conf|cpu|network|locking|rpc|security)";; \
esac; \
in_vc_files="^src/$$dir" \
@@ -825,7 +749,7 @@ sc_prohibit_duplicate_header:
}' $$i || fail=1; \
done; \
if test $$fail -eq 1; then \
{ echo '$(ME): avoid duplicate headers' 1>&2; exit 1; } \
{ echo "$(ME)": avoid duplicate headers >&2; exit 1; } \
fi;
# Don't include "libvirt/*.h" in "" form.
@@ -843,80 +767,6 @@ sc_prohibit_include_public_headers_brackets:
halt='Do not include libvirt/*.h in internal source' \
$(_sc_search_regexp)
# <config.h> is only needed in .c files; .h files do not need it since
# .c files must include config.h before any other .h.
sc_prohibit_config_h_in_headers:
@prohibit='^# *include\>.*config\.h' \
in_vc_files='\.h$$' \
halt='headers should not include <config.h>' \
$(_sc_search_regexp)
sc_prohibit_unbounded_arrays_in_rpc:
@prohibit='<>' \
in_vc_files='\.x$$' \
halt='Arrays in XDR must have a upper limit set for <NNN>' \
$(_sc_search_regexp)
sc_prohibit_getenv:
@prohibit='\b(secure_)?getenv *\(' \
exclude='exempt from syntax-check' \
halt='Use virGetEnv{Allow,Block}SUID instead of getenv' \
$(_sc_search_regexp)
sc_prohibit_atoi:
@prohibit='\bato(i|f|l|ll|q) *\(' \
halt='Use virStrToLong* instead of atoi, atol, atof, atoq, atoll' \
$(_sc_search_regexp)
sc_prohibit_wrong_filename_in_comment:
@fail=0; \
awk 'BEGIN { \
fail=0; \
} FNR < 3 { \
n=match($$0, /[[:space:]][^[:space:]]*[.][ch][[:space:]:]/); \
if (n > 0) { \
A=substr($$0, RSTART+1, RLENGTH-2); \
n=split(FILENAME, arr, "/"); \
if (A != arr[n]) { \
print "in " FILENAME ": " A " mentioned in comments "; \
fail=1; \
} \
} \
} END { \
if (fail == 1) { \
exit 1; \
} \
}' $$($(VC_LIST_EXCEPT) | grep '\.[ch]$$') || fail=1; \
if test $$fail -eq 1; then \
{ echo '$(ME): The file name in comments must match the' \
'actual file name' 1>&2; exit 1; } \
fi;
sc_prohibit_virConnectOpen_in_virsh:
@prohibit='\bvirConnectOpen[a-zA-Z]* *\(' \
in_vc_files='^tools/virsh-.*\.[ch]$$' \
halt='Use vshConnect() in virsh instead of virConnectOpen*' \
$(_sc_search_regexp)
sc_require_space_before_label:
@prohibit='^( ?)?[_a-zA-Z0-9]+:$$' \
in_vc_files='\.[ch]$$' \
halt="Top-level labels should be indented by one space" \
$(_sc_search_regexp)
sc_curly_braces_style:
@files=$$($(VC_LIST_EXCEPT) | grep '\.[ch]$$'); \
$(GREP) -nHP \
'^\s*(?!([a-zA-Z_]*for_?each[a-zA-Z_]*) ?\()([_a-zA-Z0-9]+( [_a-zA-Z0-9]+)* ?\()?(\*?[_a-zA-Z0-9]+(,? \*?[_a-zA-Z0-9\[\]]+)+|void)\) ?\{' \
$$files && { echo '$(ME): Non-K&R style used for curly' \
'braces around function body, see' \
'HACKING' 1>&2; exit 1; } || :
sc_prohibit_windows_special_chars_in_filename:
@files=$$($(VC_LIST_EXCEPT) | grep '[:*?"<>|]'); \
test -n "$$files" && { echo '$(ME): Windows special chars' \
'in filename not allowed:' 1>&2; echo $$files 1>&2; exit 1; } || :
# We don't use this feature of maint.mk.
prev_version_file = /dev/null
@@ -966,8 +816,7 @@ syntax-check: $(top_srcdir)/HACKING bracket-spacing-check
bracket-spacing-check:
$(AM_V_GEN)files=`$(VC_LIST) | grep '\.c$$'`; \
$(PERL) $(top_srcdir)/build-aux/bracket-spacing.pl $$files || \
{ echo '$(ME): incorrect whitespace, see HACKING for rules' 1>&2; \
exit 1; }
(echo $(ME): incorrect whitespace around brackets, see HACKING for rules && exit 1)
# sc_po_check can fail if generated files are not built first
sc_po_check: \
@@ -984,18 +833,17 @@ $(srcdir)/src/remote/remote_client_bodies.h: $(srcdir)/src/remote/remote_protoco
# List all syntax-check exemptions:
exclude_file_name_regexp--sc_avoid_strcase = ^tools/virsh\.h$$
_src1=libvirt|fdstream|qemu/qemu_monitor|util/(vircommand|virfile)|xen/xend_internal|rpc/virnetsocket|lxc/lxc_controller|locking/lock_daemon
_test1=shunloadtest|virnettlscontexttest|virnettlssessiontest|vircgroupmock
_src1=libvirt|fdstream|qemu/qemu_monitor|util/(vircommand|virutil)|xen/xend_internal|rpc/virnetsocket|lxc/lxc_controller|locking/lock_daemon
_test1=shunloadtest|virnettlscontexttest|vircgroupmock
exclude_file_name_regexp--sc_avoid_write = \
^(src/($(_src1))|daemon/libvirtd|tools/virsh-console|tests/($(_test1)))\.c$$
^(src/($(_src1))|daemon/libvirtd|tools/console|tests/($(_test1)))\.c$$
exclude_file_name_regexp--sc_bindtextdomain = ^(tests|examples)/
exclude_file_name_regexp--sc_copyright_usage = \
^COPYING(|\.LESSER)$$
exclude_file_name_regexp--sc_copyright_address = \
^COPYING\.LIB$$
exclude_file_name_regexp--sc_flags_usage = \
^(docs/|src/util/virnetdevtap\.c$$|tests/vir(cgroup|pci|usb)mock\.c$$)
exclude_file_name_regexp--sc_flags_usage = ^(docs/|src/util/virnetdevtap\.c$$|tests/vircgroupmock\.c$$)
exclude_file_name_regexp--sc_libvirt_unmarked_diagnostics = \
^(src/rpc/gendispatch\.pl$$|tests/)
@@ -1003,21 +851,21 @@ exclude_file_name_regexp--sc_libvirt_unmarked_diagnostics = \
exclude_file_name_regexp--sc_po_check = ^(docs/|src/rpc/gendispatch\.pl$$)
exclude_file_name_regexp--sc_prohibit_VIR_ERR_NO_MEMORY = \
^(include/libvirt/virterror\.h|daemon/dispatch\.c|src/util/virerror\.c|docs/internals/oomtesting\.html\.in)$$
^(include/libvirt/virterror\.h|daemon/dispatch\.c|src/util/virerror\.c)$$
exclude_file_name_regexp--sc_prohibit_access_xok = ^src/util/virutil\.c$$
exclude_file_name_regexp--sc_prohibit_asprintf = \
^(bootstrap.conf$$|src/util/virstring\.[ch]$$|tests/vircgroupmock\.c$$)
exclude_file_name_regexp--sc_prohibit_always_true_header_tests = \
^python/(libvirt-(lxc-|qemu-)?override|typewrappers)\.c$$
exclude_file_name_regexp--sc_prohibit_strdup = \
^(docs/|examples/|src/util/virstring\.c|tests/virnetserverclientmock.c$$)
exclude_file_name_regexp--sc_prohibit_asprintf = \
^(bootstrap.conf$$|src/util/virutil\.c$$|examples/domain-events/events-c/event-test\.c$$|tests/vircgroupmock\.c$$)
exclude_file_name_regexp--sc_prohibit_close = \
(\.p[yl]$$|^docs/|^(src/util/virfile\.c|src/libvirt\.c|tests/vir(cgroup|pci)mock\.c)$$)
(\.p[yl]$$|^docs/|^(src/util/virfile\.c|src/libvirt\.c|tests/vircgroupmock\.c)$$)
exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \
(^tests/(qemuhelp|nodeinfo|virpcitest)data/|\.(gif|ico|png|diff)$$)
(^tests/(qemuhelp|nodeinfo)data/|\.(gif|ico|png|diff)$$)
_src2=src/(util/vircommand|libvirt|lxc/lxc_controller|locking/lock_daemon)
exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
@@ -1032,10 +880,10 @@ exclude_file_name_regexp--sc_prohibit_newline_at_end_of_diagnostic = \
^src/rpc/gendispatch\.pl$$
exclude_file_name_regexp--sc_prohibit_nonreentrant = \
^((po|tests)/|docs/.*(py|html\.in)|run.in$$|tools/wireshark/util/genxdrstub\.pl$$)
^((po|tests)/|docs/.*(py|html\.in)|run.in$$)
exclude_file_name_regexp--sc_prohibit_raw_allocation = \
^(docs/hacking\.html\.in)|(src/util/viralloc\.[ch]|examples/.*|tests/securityselinuxhelper\.c|tests/vircgroupmock\.c|tools/wireshark/src/packet-libvirt.c)$$
^(docs/hacking\.html\.in)|(src/util/viralloc\.[ch]|examples/.*|tests/securityselinuxhelper\.c|tests/vircgroupmock\.c)$$
exclude_file_name_regexp--sc_prohibit_readlink = \
^src/(util/virutil|lxc/lxc_container)\.c$$
@@ -1043,12 +891,12 @@ exclude_file_name_regexp--sc_prohibit_readlink = \
exclude_file_name_regexp--sc_prohibit_setuid = ^src/util/virutil\.c$$
exclude_file_name_regexp--sc_prohibit_sprintf = \
^(docs/hacking\.html\.in)|(examples/systemtap/.*stp)|(src/dtrace2systemtap\.pl)|(src/rpc/gensystemtap\.pl)|(tools/wireshark/util/genxdrstub\.pl)$$
^(docs/hacking\.html\.in)|(examples/systemtap/.*stp)|(src/dtrace2systemtap\.pl)|(src/rpc/gensystemtap\.pl)$$
exclude_file_name_regexp--sc_prohibit_strncpy = ^src/util/virstring\.c$$
exclude_file_name_regexp--sc_prohibit_strncpy = ^src/util/virutil\.c$$
exclude_file_name_regexp--sc_prohibit_strtol = \
^(src/(util/virsexpr|(vbox|xen|xenxs)/.*)\.c)|(examples/domsuspend/suspend.c)$$
^src/(util/virsexpr|(vbox|xen|xenxs)/.*)\.c$$
exclude_file_name_regexp--sc_prohibit_xmlGetProp = ^src/util/virxml\.c$$
@@ -1056,11 +904,10 @@ exclude_file_name_regexp--sc_prohibit_xmlURI = ^src/util/viruri\.c$$
exclude_file_name_regexp--sc_prohibit_return_as_function = \.py$$
exclude_file_name_regexp--sc_require_config_h = \
^(examples/|tools/virsh-edit\.c$$)
_virsh_includes=(edit|domain-monitor|domain|volume|pool|network|interface|nwfilter|secret|snapshot|host|nodedev)
exclude_file_name_regexp--sc_require_config_h = ^(examples/|tools/virsh-$(_virsh_includes)\.c$$)
exclude_file_name_regexp--sc_require_config_h_first = \
^(examples/|tools/virsh-edit\.c$$)
exclude_file_name_regexp--sc_require_config_h_first = ^(examples/|tools/virsh-$(_virsh_includes)\.c$$)
exclude_file_name_regexp--sc_trailing_blank = \
(/qemuhelpdata/|/sysinfodata/.*\.data|\.(fig|gif|ico|png)$$)
@@ -1076,16 +923,7 @@ exclude_file_name_regexp--sc_correct_id_types = \
exclude_file_name_regexp--sc_m4_quote_check = m4/virt-lib.m4
exclude_file_name_regexp--sc_prohibit_include_public_headers_quote = \
^(src/internal\.h$$|tools/wireshark/src/packet-libvirt.h$$)
^src/internal\.h$$
exclude_file_name_regexp--sc_prohibit_include_public_headers_brackets = \
^(tools/|examples/|include/libvirt/(virterror|libvirt-(qemu|lxc))\.h$$)
exclude_file_name_regexp--sc_prohibit_int_ijk = \
^(src/remote_protocol-structs|src/remote/remote_protocol.x|cfg.mk|include/)$
exclude_file_name_regexp--sc_prohibit_getenv = \
^tests/.*\.[ch]$$
exclude_file_name_regexp--sc_avoid_attribute_unused_in_header = \
^src/util/virlog\.h$$
^(python/|tools/|examples/|include/libvirt/(virterror|libvirt-(qemu|lxc))\.h$$)

View File

@@ -1,45 +0,0 @@
/*
* Copyright (C) 2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*/
/*
* Since virt-login-shell will be setuid, we must do everything
* we can to avoid linking to other libraries. Many of them do
* unsafe things in functions marked __atttribute__((constructor)).
* The only way avoid to avoid such deps is to re-compile the
* functions with the code in question disabled, and for that we
* must override the main config.h rules. Hence this file :-(
*/
#ifdef LIBVIRT_SETUID_RPC_CLIENT
# undef HAVE_LIBDEVMAPPER_H
# undef HAVE_LIBNL
# undef HAVE_LIBNL3
# undef HAVE_LIBSASL2
# undef WITH_CAPNG
# undef WITH_CURL
# undef WITH_DTRACE_PROBES
# undef WITH_GNUTLS
# undef WITH_GNUTLS_GCRYPT
# undef WITH_MACVTAP
# undef WITH_NUMACTL
# undef WITH_SASL
# undef WITH_SSH2
# undef WITH_VIRTUALPORT
# undef WITH_YAJL
# undef WITH_YAJL2
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,49 +1,36 @@
## Process this file with automake to produce Makefile.in
## Copyright (C) 2005-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/>.
## Copyright (C) 2005-2013 Red Hat, Inc.
## See COPYING.LIB for the License of this software
INCLUDES = \
-I$(top_builddir)/gnulib/lib -I$(top_srcdir)/gnulib/lib \
-I$(top_srcdir) \
-I$(top_builddir)/include -I$(top_srcdir)/include \
-I$(top_builddir)/src -I$(top_srcdir)/src \
-I$(top_srcdir)/src/util \
-I$(top_srcdir)/src/conf \
-I$(top_srcdir)/src/rpc \
-I$(top_srcdir)/src/remote \
-I$(top_srcdir)/src/access \
$(GETTEXT_CPPFLAGS)
CLEANFILES =
DAEMON_GENERATED = \
remote_dispatch.h \
lxc_dispatch.h \
qemu_dispatch.h \
DAEMON_GENERATED = \
$(srcdir)/remote_dispatch.h \
$(srcdir)/lxc_dispatch.h \
$(srcdir)/qemu_dispatch.h \
$(NULL)
DAEMON_SOURCES = \
libvirtd.c libvirtd.h \
libvirtd-config.c libvirtd-config.h \
remote.c remote.h \
stream.c stream.h \
../src/remote/remote_protocol.c \
../src/remote/lxc_protocol.c \
../src/remote/qemu_protocol.c \
$(DAEMON_GENERATED)
LIBVIRTD_CONF_SOURCES = libvirtd-config.c libvirtd-config.h
DISTCLEANFILES =
EXTRA_DIST = \
remote_dispatch.h \
@@ -66,9 +53,7 @@ EXTRA_DIST = \
THREADS.txt \
libvirtd.pod.in \
libvirtd.8.in \
$(DAEMON_SOURCES) \
$(LIBVIRTD_CONF_SOURCES) \
$(NULL)
$(DAEMON_SOURCES)
BUILT_SOURCES =
@@ -76,43 +61,23 @@ REMOTE_PROTOCOL = $(top_srcdir)/src/remote/remote_protocol.x
LXC_PROTOCOL = $(top_srcdir)/src/remote/lxc_protocol.x
QEMU_PROTOCOL = $(top_srcdir)/src/remote/qemu_protocol.x
remote_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(srcdir)/remote_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(REMOTE_PROTOCOL)
$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl \
--mode=server remote REMOTE $(REMOTE_PROTOCOL) \
> $(srcdir)/remote_dispatch.h
--mode=server remote REMOTE $(REMOTE_PROTOCOL) > $@
lxc_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(srcdir)/lxc_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(LXC_PROTOCOL)
$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl \
--mode=server lxc LXC $(LXC_PROTOCOL) \
> $(srcdir)/lxc_dispatch.h
--mode=server lxc LXC $(LXC_PROTOCOL) > $@
qemu_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(srcdir)/qemu_dispatch.h: $(srcdir)/../src/rpc/gendispatch.pl \
$(QEMU_PROTOCOL)
$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl \
--mode=server qemu QEMU $(QEMU_PROTOCOL) \
> $(srcdir)/qemu_dispatch.h
--mode=server qemu QEMU $(QEMU_PROTOCOL) > $@
if WITH_LIBVIRTD
# Build a convenience library, for reuse in tests/libvirtdconftest
noinst_LTLIBRARIES = libvirtd_conf.la
libvirtd_conf_la_SOURCES = $(LIBVIRTD_CONF_SOURCES)
libvirtd_conf_la_CFLAGS = \
$(LIBXML_CFLAGS) \
$(XDR_CFLAGS) \
$(WARN_CFLAGS) $(PIE_CFLAGS) \
$(COVERAGE_CFLAGS) \
$(NULL)
libvirtd_conf_la_LDFLAGS = \
$(RELRO_LDFLAGS) \
$(PIE_LDFLAGS) \
$(COVERAGE_LDFLAGS) \
$(NO_INDIRECT_LDFLAGS) \
$(NULL)
libvirtd_conf_la_LIBADD = $(LIBXML_LIBS)
man8_MANS = libvirtd.8
sbin_PROGRAMS = libvirtd
@@ -146,11 +111,10 @@ libvirtd_CFLAGS = \
-DQEMUD_PID_FILE="\"$(QEMUD_PID_FILE)\""
libvirtd_LDFLAGS = \
$(RELRO_LDFLAGS) \
$(WARN_LDFLAGS) \
$(PIE_LDFLAGS) \
$(COVERAGE_LDFLAGS) \
$(NO_INDIRECT_LDFLAGS) \
$(NULL)
$(RELRO_LDFLAGS) \
$(COVERAGE_LDFLAGS)
libvirtd_LDADD = \
$(LIBXML_LIBS) \
@@ -162,67 +126,60 @@ libvirtd_LDADD = \
if WITH_DTRACE_PROBES
libvirtd_LDADD += ../src/libvirt_probes.lo
endif WITH_DTRACE_PROBES
endif
libvirtd_LDADD += \
libvirtd_conf.la \
../src/libvirt-lxc.la \
../src/libvirt-qemu.la \
../src/libvirt_driver_remote.la \
$(NULL)
../src/libvirt-qemu.la
if ! WITH_DRIVER_MODULES
if WITH_QEMU
libvirtd_LDADD += ../src/libvirt_driver_qemu.la
if WITH_DTRACE_PROBES
libvirtd_LDADD += ../src/libvirt_qemu_probes.lo
endif WITH_DTRACE_PROBES
endif WITH_QEMU
endif
endif
if WITH_LXC
libvirtd_LDADD += ../src/libvirt_driver_lxc.la
endif WITH_LXC
endif
if WITH_XEN
libvirtd_LDADD += ../src/libvirt_driver_xen.la
endif WITH_XEN
endif
if WITH_LIBXL
libvirtd_LDADD += ../src/libvirt_driver_libxl.la
endif WITH_LIBXL
endif
if WITH_UML
libvirtd_LDADD += ../src/libvirt_driver_uml.la
endif WITH_UML
if WITH_VBOX
libvirtd_LDADD += ../src/libvirt_driver_vbox.la
endif WITH_VBOX
endif
if WITH_STORAGE
libvirtd_LDADD += ../src/libvirt_driver_storage.la
endif WITH_STORAGE
endif
if WITH_NETWORK
libvirtd_LDADD += ../src/libvirt_driver_network.la
endif WITH_NETWORK
endif
if WITH_INTERFACE
libvirtd_LDADD += ../src/libvirt_driver_interface.la
endif WITH_INTERFACE
endif
if WITH_NODE_DEVICES
libvirtd_LDADD += ../src/libvirt_driver_nodedev.la
endif WITH_NODE_DEVICES
endif
if WITH_SECRETS
libvirtd_LDADD += ../src/libvirt_driver_secret.la
endif WITH_SECRETS
endif
if WITH_NWFILTER
libvirtd_LDADD += ../src/libvirt_driver_nwfilter.la
endif WITH_NWFILTER
endif ! WITH_DRIVER_MODULES
endif
endif
libvirtd_LDADD += ../src/libvirt.la
@@ -230,11 +187,11 @@ if WITH_POLKIT
if WITH_POLKIT0
policydir = $(datadir)/PolicyKit/policy
policyauth = auth_admin_keep_session
else ! WITH_POLKIT0
else
policydir = $(datadir)/polkit-1/actions
policyauth = auth_admin_keep
endif ! WITH_POLKIT0
endif WITH_POLKIT
endif
endif
libvirtd.policy: libvirtd.policy.in $(top_builddir)/config.status
$(AM_V_GEN) sed \
@@ -243,16 +200,14 @@ libvirtd.policy: libvirtd.policy.in $(top_builddir)/config.status
mv $@-t $@
BUILT_SOURCES += libvirtd.policy
install-data-local: install-init-redhat install-init-systemd \
install-init-upstart \
install-data-local: install-init-redhat install-init-systemd install-init-upstart \
install-data-sasl install-data-polkit \
install-logrotate install-sysctl
$(MKDIR_P) $(DESTDIR)$(localstatedir)/log/libvirt \
$(DESTDIR)$(localstatedir)/run/libvirt \
$(DESTDIR)$(localstatedir)/lib/libvirt
uninstall-local:: uninstall-init-redhat uninstall-init-systemd \
uninstall-init-upstart \
uninstall-local:: uninstall-init-redhat uninstall-init-systemd uninstall-init-upstart \
uninstall-data-sasl uninstall-data-polkit \
uninstall-logrotate uninstall-sysctl
rmdir $(DESTDIR)$(localstatedir)/log/libvirt || :
@@ -266,10 +221,10 @@ install-data-polkit::
uninstall-data-polkit::
rm -f $(DESTDIR)$(policydir)/org.libvirt.unix.policy
rmdir $(DESTDIR)$(policydir) || :
else ! WITH_POLKIT
else
install-data-polkit::
uninstall-data-polkit::
endif ! WITH_POLKIT
endif
remote.c: $(DAEMON_GENERATED)
remote.h: $(DAEMON_GENERATED)
@@ -308,14 +263,10 @@ install-logrotate: $(LOGROTATE_CONFS)
$(DESTDIR)$(localstatedir)/log/libvirt/lxc/ \
$(DESTDIR)$(localstatedir)/log/libvirt/uml/ \
$(DESTDIR)$(sysconfdir)/logrotate.d/
$(INSTALL_DATA) libvirtd.logrotate \
$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd
$(INSTALL_DATA) libvirtd.qemu.logrotate \
$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.qemu
$(INSTALL_DATA) libvirtd.lxc.logrotate \
$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.lxc
$(INSTALL_DATA) libvirtd.uml.logrotate \
$(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.uml
$(INSTALL_DATA) libvirtd.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd
$(INSTALL_DATA) libvirtd.qemu.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.qemu
$(INSTALL_DATA) libvirtd.lxc.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.lxc
$(INSTALL_DATA) libvirtd.uml.logrotate $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd.uml
uninstall-logrotate:
rm -f $(DESTDIR)$(sysconfdir)/logrotate.d/libvirtd \
@@ -346,10 +297,10 @@ install-sysctl:
uninstall-sysctl:
rm -f $(DESTDIR)$(prefix)/lib/sysctl.d/libvirtd.conf
rmdir $(DESTDIR)$(prefix)/lib/sysctl.d || :
else ! WITH_SYSCTL
else
install-sysctl:
uninstall-sysctl:
endif ! WITH_SYSCTL
endif
if LIBVIRT_INIT_SCRIPT_RED_HAT
@@ -363,10 +314,10 @@ install-init-redhat: install-sysconfig libvirtd.init
uninstall-init-redhat: uninstall-sysconfig
rm -f $(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd
rmdir $(DESTDIR)$(sysconfdir)/rc.d/init.d || :
else ! LIBVIRT_INIT_SCRIPT_RED_HAT
else
install-init-redhat:
uninstall-init-redhat:
endif ! LIBVIRT_INIT_SCRIPT_RED_HAT
endif # LIBVIRT_INIT_SCRIPT_RED_HAT
if LIBVIRT_INIT_SCRIPT_UPSTART
@@ -379,15 +330,15 @@ install-init-upstart: install-sysconfig
uninstall-init-upstart: uninstall-sysconfig
rm -f $(DESTDIR)$(sysconfdir)/event.d/libvirtd
rmdir $(DESTDIR)$(sysconfdir)/event.d || :
else ! LIBVIRT_INIT_SCRIPT_UPSTART
else
install-init-upstart:
uninstall-init-upstart:
endif ! LIBVIRT_INIT_SCRIPT_UPSTART
endif # LIBVIRT_INIT_SCRIPT_UPSTART
if LIBVIRT_INIT_SCRIPT_SYSTEMD
SYSTEMD_UNIT_DIR = $(prefix)/lib/systemd/system
SYSTEMD_UNIT_DIR = /lib/systemd/system
BUILT_SOURCES += libvirtd.service
install-init-systemd: install-sysconfig libvirtd.service
@@ -398,10 +349,10 @@ install-init-systemd: install-sysconfig libvirtd.service
uninstall-init-systemd: uninstall-sysconfig
rm -f $(DESTDIR)$(SYSTEMD_UNIT_DIR)/libvirtd.service
rmdir $(DESTDIR)$(SYSTEMD_UNIT_DIR) || :
else ! LIBVIRT_INIT_SCRIPT_SYSTEMD
else
install-init-systemd:
uninstall-init-systemd:
endif ! LIBVIRT_INIT_SCRIPT_SYSTEMD
endif # LIBVIRT_INIT_SCRIPT_SYSTEMD
libvirtd.init: libvirtd.init.in $(top_builddir)/config.status
$(AM_V_GEN)sed \
@@ -438,10 +389,10 @@ check-augeas: test_libvirtd.aug
# are used by nearly every other library.
libvirtd_LDADD += ../gnulib/lib/libgnu.la $(LIBSOCKET)
else ! WITH_LIBVIRTD
else # WITH_LIBVIRTD
install-data-local: install-data-sasl
uninstall-local:: uninstall-data-sasl
endif ! WITH_LIBVIRTD
endif # WITH_LIBVIRTD
POD2MAN = pod2man -c "Virtualization Support" \
-r "$(PACKAGE)-$(VERSION)" -s 8
@@ -455,16 +406,15 @@ $(srcdir)/libvirtd.8.in: libvirtd.pod.in $(top_srcdir)/configure.ac
if WITH_SASL
install-data-sasl:
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/sasl2/
$(INSTALL_DATA) $(srcdir)/libvirtd.sasl \
$(DESTDIR)$(sysconfdir)/sasl2/libvirt.conf
$(INSTALL_DATA) $(srcdir)/libvirtd.sasl $(DESTDIR)$(sysconfdir)/sasl2/libvirt.conf
uninstall-data-sasl:
rm -f $(DESTDIR)$(sysconfdir)/sasl2/libvirt.conf
rmdir $(DESTDIR)$(sysconfdir)/sasl2/ || :
else ! WITH_SASL
else
install-data-sasl:
uninstall-data-sasl:
endif ! WITH_SASL
endif
CLEANFILES += $(BUILT_SOURCES) $(man8_MANS)

View File

@@ -1,7 +1,7 @@
/*
* libvirtd-config.c: daemon start of day, guest process & i/o management
* libvirtd.c: daemon start of day, guest process & i/o management
*
* Copyright (C) 2006-2012, 2014 Red Hat, Inc.
* Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -32,13 +32,9 @@
#include "configmake.h"
#include "remote/remote_protocol.h"
#include "remote/remote_driver.h"
#include "virstring.h"
#include "virutil.h"
#define VIR_FROM_THIS VIR_FROM_CONF
VIR_LOG_INIT("daemon.libvirtd-config");
/* Allocate an array of malloc'd strings from the config file, filename
* (used only in diagnostics), using handle "conf". Upon error, return -1
* and free any allocated memory. Otherwise, save the array in *list_arg
@@ -61,16 +57,19 @@ remoteConfigGetStringList(virConfPtr conf, const char *key, char ***list_arg,
key);
return -1;
}
if (VIR_STRDUP(list[0], p->str) < 0) {
list[0] = strdup(p->str);
list[1] = NULL;
if (list[0] == NULL) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("failed to allocate memory for %s config list value"),
key);
VIR_FREE(list);
return -1;
}
list[1] = NULL;
break;
case VIR_CONF_LIST: {
int len = 0;
size_t i;
int i, len = 0;
virConfValuePtr pp;
for (pp = p->list; pp; pp = pp->next)
len++;
@@ -89,11 +88,15 @@ remoteConfigGetStringList(virConfPtr conf, const char *key, char ***list_arg,
VIR_FREE(list);
return -1;
}
if (VIR_STRDUP(list[i], pp->str) < 0) {
size_t j;
for (j = 0; j < i; j++)
list[i] = strdup(pp->str);
if (list[i] == NULL) {
int j;
for (j = 0 ; j < i ; j++)
VIR_FREE(list[j]);
VIR_FREE(list);
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("failed to allocate memory for %s config list value"),
key);
return -1;
}
@@ -131,8 +134,8 @@ checkType(virConfValuePtr p, const char *filename,
}
/* If there is no config data for the key, #var_name, then do nothing.
If there is valid data of type VIR_CONF_STRING, and VIR_STRDUP succeeds,
store the result in var_name. Otherwise, (i.e. invalid type, or VIR_STRDUP
If there is valid data of type VIR_CONF_STRING, and strdup succeeds,
store the result in var_name. Otherwise, (i.e. invalid type, or strdup
failure), give a diagnostic and "goto" the cleanup-and-fail label. */
#define GET_CONF_STR(conf, filename, var_name) \
do { \
@@ -141,8 +144,10 @@ checkType(virConfValuePtr p, const char *filename,
if (checkType(p, filename, #var_name, VIR_CONF_STRING) < 0) \
goto error; \
VIR_FREE(data->var_name); \
if (VIR_STRDUP(data->var_name, p->str) < 0) \
if (!(data->var_name = strdup(p->str))) { \
virReportOOMError(); \
goto error; \
} \
} \
} while (0)
@@ -158,12 +163,7 @@ checkType(virConfValuePtr p, const char *filename,
} while (0)
static int
remoteConfigGetAuth(virConfPtr conf,
const char *key,
int *auth,
const char *filename)
{
static int remoteConfigGetAuth(virConfPtr conf, const char *key, int *auth, const char *filename) {
virConfValuePtr p;
p = virConfGetValue(conf, key);
@@ -198,8 +198,8 @@ int
daemonConfigFilePath(bool privileged, char **configfile)
{
if (privileged) {
if (VIR_STRDUP(*configfile, SYSCONFDIR "/libvirt/libvirtd.conf") < 0)
goto error;
if (!(*configfile = strdup(SYSCONFDIR "/libvirt/libvirtd.conf")))
goto no_memory;
} else {
char *configdir = NULL;
@@ -208,14 +208,16 @@ daemonConfigFilePath(bool privileged, char **configfile)
if (virAsprintf(configfile, "%s/libvirtd.conf", configdir) < 0) {
VIR_FREE(configdir);
goto error;
goto no_memory;
}
VIR_FREE(configdir);
}
return 0;
error:
no_memory:
virReportOOMError();
error:
return -1;
}
@@ -226,15 +228,18 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
char *localhost;
int ret;
if (VIR_ALLOC(data) < 0)
if (VIR_ALLOC(data) < 0) {
virReportOOMError();
return NULL;
}
data->listen_tls = 1;
data->listen_tcp = 0;
if (VIR_STRDUP(data->tls_port, LIBVIRTD_TLS_PORT) < 0 ||
VIR_STRDUP(data->tcp_port, LIBVIRTD_TCP_PORT) < 0)
goto error;
if (!(data->tls_port = strdup(LIBVIRTD_TLS_PORT)))
goto no_memory;
if (!(data->tcp_port = strdup(LIBVIRTD_TCP_PORT)))
goto no_memory;
/* Only default to PolicyKit if running as root */
#if WITH_POLKIT
@@ -249,10 +254,14 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
}
#endif
if (VIR_STRDUP(data->unix_sock_rw_perms,
data->auth_unix_rw == REMOTE_AUTH_POLKIT ? "0777" : "0700") < 0 ||
VIR_STRDUP(data->unix_sock_ro_perms, "0777") < 0)
goto error;
if (data->auth_unix_rw == REMOTE_AUTH_POLKIT)
data->unix_sock_rw_perms = strdup("0777"); /* Allow world */
else
data->unix_sock_rw_perms = strdup("0700"); /* Allow user only */
data->unix_sock_ro_perms = strdup("0777"); /* Always allow world */
if (!data->unix_sock_ro_perms ||
!data->unix_sock_rw_perms)
goto no_memory;
#if WITH_SASL
data->auth_tcp = REMOTE_AUTH_SASL;
@@ -265,14 +274,15 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
data->min_workers = 5;
data->max_workers = 20;
data->max_clients = 5000;
data->max_anonymous_clients = 20;
data->max_clients = 20;
data->prio_workers = 5;
data->max_requests = 20;
data->max_client_requests = 5;
data->log_buffer_size = 64;
data->audit_level = 1;
data->audit_logging = 0;
@@ -280,13 +290,13 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
data->keepalive_count = 5;
data->keepalive_required = 0;
localhost = virGetHostname();
localhost = virGetHostname(NULL);
if (localhost == NULL) {
/* we couldn't resolve the hostname; assume that we are
* running in disconnected operation, and report a less
* useful Avahi string
*/
ret = VIR_STRDUP(data->mdns_name, "Virtualization Host");
ret = virAsprintf(&data->mdns_name, "Virtualization Host");
} else {
char *tmp;
/* Extract the host part of the potentially FQDN */
@@ -297,11 +307,12 @@ daemonConfigNew(bool privileged ATTRIBUTE_UNUSED)
}
VIR_FREE(localhost);
if (ret < 0)
goto error;
goto no_memory;
return data;
error:
no_memory:
virReportOOMError();
daemonConfigFree(data);
return NULL;
}
@@ -317,12 +328,6 @@ daemonConfigFree(struct daemonConfig *data)
VIR_FREE(data->listen_addr);
VIR_FREE(data->tls_port);
VIR_FREE(data->tcp_port);
tmp = data->access_drivers;
while (tmp && *tmp) {
VIR_FREE(*tmp);
tmp++;
}
VIR_FREE(data->access_drivers);
VIR_FREE(data->unix_sock_ro_perms);
VIR_FREE(data->unix_sock_rw_perms);
@@ -375,8 +380,10 @@ daemonConfigLoadOptions(struct daemonConfig *data,
*/
if (data->auth_unix_rw == REMOTE_AUTH_POLKIT) {
VIR_FREE(data->unix_sock_rw_perms);
if (VIR_STRDUP(data->unix_sock_rw_perms, "0777") < 0)
if (!(data->unix_sock_rw_perms = strdup("0777"))) {
virReportOOMError();
goto error;
}
}
#endif
if (remoteConfigGetAuth(conf, "auth_unix_ro", &data->auth_unix_ro, filename) < 0)
@@ -386,10 +393,6 @@ daemonConfigLoadOptions(struct daemonConfig *data,
if (remoteConfigGetAuth(conf, "auth_tls", &data->auth_tls, filename) < 0)
goto error;
if (remoteConfigGetStringList(conf, "access_drivers",
&data->access_drivers, filename) < 0)
goto error;
GET_CONF_STR(conf, filename, unix_sock_group);
GET_CONF_STR(conf, filename, unix_sock_ro_perms);
GET_CONF_STR(conf, filename, unix_sock_rw_perms);
@@ -420,8 +423,6 @@ daemonConfigLoadOptions(struct daemonConfig *data,
GET_CONF_INT(conf, filename, min_workers);
GET_CONF_INT(conf, filename, max_workers);
GET_CONF_INT(conf, filename, max_clients);
GET_CONF_INT(conf, filename, max_queued_clients);
GET_CONF_INT(conf, filename, max_anonymous_clients);
GET_CONF_INT(conf, filename, prio_workers);
@@ -436,6 +437,7 @@ daemonConfigLoadOptions(struct daemonConfig *data,
GET_CONF_INT(conf, filename, log_level);
GET_CONF_STR(conf, filename, log_filters);
GET_CONF_STR(conf, filename, log_outputs);
GET_CONF_INT(conf, filename, log_buffer_size);
GET_CONF_INT(conf, filename, keepalive_interval);
GET_CONF_INT(conf, filename, keepalive_count);
@@ -443,7 +445,7 @@ daemonConfigLoadOptions(struct daemonConfig *data,
return 0;
error:
error:
return -1;
}

View File

@@ -1,5 +1,5 @@
/*
* libvirtd-config.h: daemon start of day, guest process & i/o management
* libvirtd.c: daemon start of day, guest process & i/o management
*
* Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
@@ -45,8 +45,6 @@ struct daemonConfig {
int auth_tcp;
int auth_tls;
char **access_drivers;
int mdns_adv;
char *mdns_name;
@@ -63,8 +61,6 @@ struct daemonConfig {
int min_workers;
int max_workers;
int max_clients;
int max_queued_clients;
int max_anonymous_clients;
int prio_workers;
@@ -74,6 +70,7 @@ struct daemonConfig {
int log_level;
char *log_filters;
char *log_outputs;
int log_buffer_size;
int audit_level;
int audit_logging;

View File

@@ -51,13 +51,10 @@ module Libvirtd =
| bool_entry "tls_no_sanity_certificate"
| str_array_entry "tls_allowed_dn_list"
| str_array_entry "sasl_allowed_username_list"
| str_array_entry "access_drivers"
let processing_entry = int_entry "min_workers"
| int_entry "max_workers"
| int_entry "max_clients"
| int_entry "max_queued_clients"
| int_entry "max_anonymous_clients"
| int_entry "max_requests"
| int_entry "max_client_requests"
| int_entry "prio_workers"

View File

@@ -1,7 +1,7 @@
/*
* libvirtd.c: daemon start of day, guest process & i/o management
*
* Copyright (C) 2006-2014 Red Hat, Inc.
* Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -35,7 +35,6 @@
#include "libvirt_internal.h"
#include "virerror.h"
#include "virfile.h"
#include "virlog.h"
#include "virpidfile.h"
#include "virprocess.h"
@@ -44,6 +43,7 @@
#include "libvirtd.h"
#include "libvirtd-config.h"
#include "virutil.h"
#include "viruuid.h"
#include "remote_driver.h"
#include "viralloc.h"
@@ -53,9 +53,7 @@
#include "remote.h"
#include "virhook.h"
#include "viraudit.h"
#include "virstring.h"
#include "locking/lock_manager.h"
#include "viraccessmanager.h"
#ifdef WITH_DRIVER_MODULES
# include "driver.h"
@@ -75,12 +73,6 @@
# ifdef WITH_UML
# include "uml/uml_driver.h"
# endif
# ifdef WITH_VBOX
# include "vbox/vbox_driver.h"
# endif
# ifdef WITH_BHYVE
# include "bhyve/bhyve_driver.h"
# endif
# ifdef WITH_NETWORK
# include "network/bridge_driver.h"
# endif
@@ -104,9 +96,6 @@
#include "configmake.h"
#include "virdbus.h"
#include "cpu/cpu_map.h"
VIR_LOG_INIT("daemon.libvirtd");
#if WITH_SASL
virNetSASLContextPtr saslCtxt = NULL;
@@ -115,8 +104,6 @@ virNetServerProgramPtr remoteProgram = NULL;
virNetServerProgramPtr qemuProgram = NULL;
virNetServerProgramPtr lxcProgram = NULL;
volatile bool driversInitialized = false;
enum {
VIR_DAEMON_ERR_NONE = 0,
VIR_DAEMON_ERR_PIDFILE,
@@ -210,7 +197,7 @@ static int daemonForkIntoBackground(const char *argv0)
VIR_FORCE_CLOSE(statuspipe[1]);
/* We wait to make sure the first child forked successfully */
if (virProcessWait(pid, NULL, false) < 0)
if (virProcessWait(pid, NULL) < 0)
goto error;
/* If we get here, then the grandchild was spawned, so we
@@ -242,7 +229,7 @@ static int daemonForkIntoBackground(const char *argv0)
}
}
error:
error:
VIR_FORCE_CLOSE(statuspipe[0]);
VIR_FORCE_CLOSE(statuspipe[1]);
return -1;
@@ -254,8 +241,8 @@ daemonPidFilePath(bool privileged,
char **pidfile)
{
if (privileged) {
if (VIR_STRDUP(*pidfile, LOCALSTATEDIR "/run/libvirtd.pid") < 0)
goto error;
if (!(*pidfile = strdup(LOCALSTATEDIR "/run/libvirtd.pid")))
goto no_memory;
} else {
char *rundir = NULL;
mode_t old_umask;
@@ -272,7 +259,7 @@ daemonPidFilePath(bool privileged,
if (virAsprintf(pidfile, "%s/libvirtd.pid", rundir) < 0) {
VIR_FREE(rundir);
goto error;
goto no_memory;
}
VIR_FREE(rundir);
@@ -280,7 +267,9 @@ daemonPidFilePath(bool privileged,
return 0;
error:
no_memory:
virReportOOMError();
error:
return -1;
}
@@ -292,15 +281,16 @@ daemonUnixSocketPaths(struct daemonConfig *config,
{
if (config->unix_sock_dir) {
if (virAsprintf(sockfile, "%s/libvirt-sock", config->unix_sock_dir) < 0)
goto error;
goto no_memory;
if (privileged &&
virAsprintf(rosockfile, "%s/libvirt-sock-ro", config->unix_sock_dir) < 0)
goto error;
goto no_memory;
} else {
if (privileged) {
if (VIR_STRDUP(*sockfile, LOCALSTATEDIR "/run/libvirt/libvirt-sock") < 0 ||
VIR_STRDUP(*rosockfile, LOCALSTATEDIR "/run/libvirt/libvirt-sock-ro") < 0)
goto error;
if (!(*sockfile = strdup(LOCALSTATEDIR "/run/libvirt/libvirt-sock")))
goto no_memory;
if (!(*rosockfile = strdup(LOCALSTATEDIR "/run/libvirt/libvirt-sock-ro")))
goto no_memory;
} else {
char *rundir = NULL;
mode_t old_umask;
@@ -317,7 +307,7 @@ daemonUnixSocketPaths(struct daemonConfig *config,
if (virAsprintf(sockfile, "%s/libvirt-sock", rundir) < 0) {
VIR_FREE(rundir);
goto error;
goto no_memory;
}
VIR_FREE(rundir);
@@ -325,7 +315,9 @@ daemonUnixSocketPaths(struct daemonConfig *config,
}
return 0;
error:
no_memory:
virReportOOMError();
error:
return -1;
}
@@ -409,12 +401,6 @@ static void daemonInitialize(void)
# ifdef WITH_UML
virDriverLoadModule("uml");
# endif
# ifdef WITH_VBOX
virDriverLoadModule("vbox");
# endif
# ifdef WITH_BHYVE
virDriverLoadModule("bhyve");
# endif
#else
# ifdef WITH_NETWORK
networkRegister();
@@ -449,12 +435,6 @@ static void daemonInitialize(void)
# ifdef WITH_UML
umlRegister();
# endif
# ifdef WITH_VBOX
vboxRegister();
# endif
# ifdef WITH_BHYVE
bhyveRegister();
# endif
#endif
}
@@ -500,7 +480,6 @@ static int daemonSetupNetworking(virNetServerPtr srv,
NULL,
#endif
false,
config->max_queued_clients,
config->max_client_requests)))
goto error;
if (sock_path_ro) {
@@ -513,7 +492,6 @@ static int daemonSetupNetworking(virNetServerPtr srv,
NULL,
#endif
true,
config->max_queued_clients,
config->max_client_requests)))
goto error;
}
@@ -539,7 +517,6 @@ static int daemonSetupNetworking(virNetServerPtr srv,
NULL,
#endif
false,
config->max_queued_clients,
config->max_client_requests)))
goto error;
@@ -580,7 +557,6 @@ static int daemonSetupNetworking(virNetServerPtr srv,
config->auth_tls,
ctxt,
false,
config->max_queued_clients,
config->max_client_requests))) {
virObjectUnref(ctxt);
goto error;
@@ -618,7 +594,7 @@ static int daemonSetupNetworking(virNetServerPtr srv,
return 0;
error:
error:
#if WITH_GNUTLS
virObjectUnref(svcTLS);
#endif
@@ -662,6 +638,8 @@ daemonSetupLogging(struct daemonConfig *config,
virLogSetFromEnv();
virLogSetBufferSize(config->log_buffer_size);
if (virLogGetNbFilters() == 0)
virLogParseFilters(config->log_filters);
@@ -679,7 +657,7 @@ daemonSetupLogging(struct daemonConfig *config,
char *tmp;
if (access("/run/systemd/journal/socket", W_OK) >= 0) {
if (virAsprintf(&tmp, "%d:journald", virLogGetDefaultPriority()) < 0)
goto error;
goto no_memory;
virLogParseOutputs(tmp);
VIR_FREE(tmp);
}
@@ -697,7 +675,7 @@ daemonSetupLogging(struct daemonConfig *config,
if (virAsprintf(&tmp, "%d:file:%s/log/libvirt/libvirtd.log",
virLogGetDefaultPriority(),
LOCALSTATEDIR) == -1)
goto error;
goto no_memory;
} else {
char *logdir = virGetUserCacheDirectory();
mode_t old_umask;
@@ -715,13 +693,13 @@ daemonSetupLogging(struct daemonConfig *config,
if (virAsprintf(&tmp, "%d:file:%s/libvirtd.log",
virLogGetDefaultPriority(), logdir) == -1) {
VIR_FREE(logdir);
goto error;
goto no_memory;
}
VIR_FREE(logdir);
}
} else {
if (virAsprintf(&tmp, "%d:stderr", virLogGetDefaultPriority()) < 0)
goto error;
goto no_memory;
}
virLogParseOutputs(tmp);
VIR_FREE(tmp);
@@ -735,31 +713,13 @@ daemonSetupLogging(struct daemonConfig *config,
return 0;
error:
no_memory:
virReportOOMError();
error:
return -1;
}
static int
daemonSetupAccessManager(struct daemonConfig *config)
{
virAccessManagerPtr mgr;
const char *none[] = { "none", NULL };
const char **driver = (const char **)config->access_drivers;
if (!driver ||
!driver[0])
driver = none;
if (!(mgr = virAccessManagerNewStack(driver)))
return -1;
virAccessManagerSetDefault(mgr);
virObjectUnref(mgr);
return 0;
}
/* Display version information. */
static void
daemonVersion(const char *argv0)
@@ -904,9 +864,6 @@ handleSystemMessageFunc(DBusConnection *connection ATTRIBUTE_UNUSED,
static void daemonRunStateInit(void *opaque)
{
virNetServerPtr srv = opaque;
virIdentityPtr sysident = virIdentityGetSystem();
virIdentitySetCurrent(sysident);
/* Since driver initialization can take time inhibit daemon shutdown until
we're done so clients get a chance to connect */
@@ -925,8 +882,6 @@ static void daemonRunStateInit(void *opaque)
goto cleanup;
}
driversInitialized = true;
#ifdef HAVE_DBUS
/* Tie the non-priviledged libvirtd to the session/shutdown lifecycle */
if (!virNetServerIsPrivileged(srv)) {
@@ -948,11 +903,9 @@ static void daemonRunStateInit(void *opaque)
#endif
/* Only now accept clients from network */
virNetServerUpdateServices(srv, true);
cleanup:
cleanup:
daemonInhibitCallback(false, srv);
virObjectUnref(srv);
virObjectUnref(sysident);
virIdentitySetCurrent(NULL);
}
static int daemonStateInit(virNetServerPtr srv)
@@ -1006,10 +959,9 @@ static int migrateProfile(void)
goto cleanup;
}
config_home = virGetEnvBlockSUID("XDG_CONFIG_HOME");
config_home = getenv("XDG_CONFIG_HOME");
if (config_home && config_home[0] != '\0') {
if (VIR_STRDUP(xdg_dir, config_home) < 0)
goto cleanup;
xdg_dir = strdup(config_home);
} else {
if (virAsprintf(&xdg_dir, "%s/.config", home) < 0) {
goto cleanup;
@@ -1053,13 +1005,12 @@ daemonUsage(const char *argv0, bool privileged)
" %s [options]\n"
"\n"
"Options:\n"
" -h | --help Display program help:\n"
" -v | --verbose Verbose messages.\n"
" -d | --daemon Run as a daemon & write PID file.\n"
" -l | --listen Listen for TCP/IP connections.\n"
" -t | --timeout <secs> Exit after timeout period.\n"
" -f | --config <file> Configuration file.\n"
" -V | --version Display version information.\n"
" | --version Display version information.\n"
" -p | --pid-file <file> Change name of PID file.\n"
"\n"
"libvirt management daemon:\n"),
@@ -1071,26 +1022,26 @@ daemonUsage(const char *argv0, bool privileged)
" Default paths:\n"
"\n"
" Configuration file (unless overridden by -f):\n"
" %s\n"
" %s/libvirt/libvirtd.conf\n"
"\n"
" Sockets:\n"
" %s\n"
" %s\n"
" %s/run/libvirt/libvirt-sock\n"
" %s/run/libvirt/libvirt-sock-ro\n"
"\n"
" TLS:\n"
" CA certificate: %s\n"
" Server certificate: %s\n"
" Server private key: %s\n"
" CA certificate: %s/pki/CA/caert.pem\n"
" Server certificate: %s/pki/libvirt/servercert.pem\n"
" Server private key: %s/pki/libvirt/private/serverkey.pem\n"
"\n"
" PID file (unless overridden by -p):\n"
" %s/run/libvirtd.pid\n"
"\n"),
LIBVIRTD_CONFIGURATION_FILE,
LIBVIRTD_PRIV_UNIX_SOCKET,
LIBVIRTD_PRIV_UNIX_SOCKET_RO,
LIBVIRT_CACERT,
LIBVIRT_SERVERCERT,
LIBVIRT_SERVERKEY,
SYSCONFDIR,
LOCALSTATEDIR,
LOCALSTATEDIR,
SYSCONFDIR,
SYSCONFDIR,
SYSCONFDIR,
LOCALSTATEDIR);
} else {
fprintf(stderr, "%s",
@@ -1114,6 +1065,10 @@ daemonUsage(const char *argv0, bool privileged)
}
}
enum {
OPT_VERSION = 129
};
#define MAX_LISTEN 5
int main(int argc, char **argv) {
virNetServerPtr srv = NULL;
@@ -1135,14 +1090,14 @@ int main(int argc, char **argv) {
mode_t old_umask;
struct option opts[] = {
{ "verbose", no_argument, &verbose, 'v'},
{ "daemon", no_argument, &godaemon, 'd'},
{ "listen", no_argument, &ipsock, 'l'},
{ "verbose", no_argument, &verbose, 1},
{ "daemon", no_argument, &godaemon, 1},
{ "listen", no_argument, &ipsock, 1},
{ "config", required_argument, NULL, 'f'},
{ "timeout", required_argument, NULL, 't'},
{ "pid-file", required_argument, NULL, 'p'},
{ "version", no_argument, NULL, 'V' },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, OPT_VERSION },
{ "help", no_argument, NULL, '?' },
{0, 0, 0, 0}
};
@@ -1154,21 +1109,16 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE);
}
virUpdateSelfLastChanged(argv[0]);
if (strstr(argv[0], "lt-libvirtd") ||
strstr(argv[0], "/daemon/.libs/libvirtd")) {
char *tmp = strrchr(argv[0], '/');
char *cpumap;
if (!tmp) {
fprintf(stderr, _("%s: cannot identify driver directory\n"), argv[0]);
exit(EXIT_FAILURE);
}
*tmp = '\0';
char *driverdir;
if (virAsprintfQuiet(&driverdir, "%s/../../src/.libs", argv[0]) < 0 ||
virAsprintfQuiet(&cpumap, "%s/../../src/cpu/cpu_map.xml",
argv[0]) < 0) {
if (virAsprintf(&driverdir, "%s/../../src/.libs", argv[0]) < 0) {
fprintf(stderr, _("%s: initialization failed\n"), argv[0]);
exit(EXIT_FAILURE);
}
@@ -1181,7 +1131,6 @@ int main(int argc, char **argv) {
#ifdef WITH_DRIVER_MODULES
virDriverModuleInitialize(driverdir);
#endif
cpuMapOverride(cpumap);
*tmp = '/';
/* Must not free 'driverdir' - it is still used */
}
@@ -1191,7 +1140,7 @@ int main(int argc, char **argv) {
int c;
char *tmp;
c = getopt_long(argc, argv, "ldf:p:t:vVh", opts, &optidx);
c = getopt_long(argc, argv, "ldf:p:t:v", opts, &optidx);
if (c == -1) {
break;
@@ -1223,7 +1172,7 @@ int main(int argc, char **argv) {
case 'p':
VIR_FREE(pid_file);
if (VIR_STRDUP_QUIET(pid_file, optarg) < 0) {
if (!(pid_file = strdup(optarg))) {
VIR_ERROR(_("Can't allocate memory"));
exit(EXIT_FAILURE);
}
@@ -1231,23 +1180,23 @@ int main(int argc, char **argv) {
case 'f':
VIR_FREE(remote_config_file);
if (VIR_STRDUP_QUIET(remote_config_file, optarg) < 0) {
if (!(remote_config_file = strdup(optarg))) {
VIR_ERROR(_("Can't allocate memory"));
exit(EXIT_FAILURE);
}
break;
case 'V':
case OPT_VERSION:
daemonVersion(argv[0]);
exit(EXIT_SUCCESS);
case 'h':
daemonUsage(argv[0], privileged);
exit(EXIT_SUCCESS);
return 0;
case '?':
default:
daemonUsage(argv[0], privileged);
return 2;
default:
VIR_ERROR(_("%s: internal error: unknown flag: %c"),
argv[0], c);
exit(EXIT_FAILURE);
}
}
@@ -1302,11 +1251,6 @@ int main(int argc, char **argv) {
exit(EXIT_FAILURE);
}
if (daemonSetupAccessManager(config) < 0) {
VIR_ERROR(_("Can't initialize access manager"));
exit(EXIT_FAILURE);
}
if (!pid_file &&
daemonPidFilePath(privileged,
&pid_file) < 0) {
@@ -1343,10 +1287,7 @@ int main(int argc, char **argv) {
/* Ensure the rundir exists (on tmpfs on some systems) */
if (privileged) {
if (VIR_STRDUP_QUIET(run_dir, LOCALSTATEDIR "/run/libvirt") < 0) {
VIR_ERROR(_("Can't allocate memory"));
goto cleanup;
}
run_dir = strdup(LOCALSTATEDIR "/run/libvirt");
} else {
run_dir = virGetUserRuntimeDirectory();
@@ -1355,6 +1296,11 @@ int main(int argc, char **argv) {
goto cleanup;
}
}
if (!run_dir) {
virReportOOMError();
goto cleanup;
}
if (privileged)
old_umask = umask(022);
else
@@ -1370,7 +1316,7 @@ int main(int argc, char **argv) {
umask(old_umask);
/* Try to claim the pidfile, exiting if we can't */
if ((pid_file_fd = virPidFileAcquirePath(pid_file, false, getpid())) < 0) {
if ((pid_file_fd = virPidFileAcquirePath(pid_file, getpid())) < 0) {
ret = VIR_DAEMON_ERR_PIDFILE;
goto cleanup;
}
@@ -1384,7 +1330,6 @@ int main(int argc, char **argv) {
config->max_workers,
config->prio_workers,
config->max_clients,
config->max_anonymous_clients,
config->keepalive_interval,
config->keepalive_count,
!!config->keepalive_required,
@@ -1539,7 +1484,7 @@ int main(int argc, char **argv) {
virHookCall(VIR_HOOK_DRIVER_DAEMON, "-", VIR_HOOK_DAEMON_OP_SHUTDOWN,
0, "shutdown", NULL, NULL);
cleanup:
cleanup:
virNetlinkEventServiceStopAll();
virObjectUnref(remoteProgram);
virObjectUnref(lxcProgram);
@@ -1568,8 +1513,7 @@ int main(int argc, char **argv) {
daemonConfigFree(config);
if (driversInitialized)
virStateCleanup();
virStateCleanup();
return ret;
}

View File

@@ -63,7 +63,7 @@
# unique on the immediate broadcast network.
#
# The default is "Virtualization Host HOSTNAME", where HOSTNAME
# is substituted for the short hostname of the machine (without domain)
# is subsituted 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, you may want to
# restrict this too.
# Default allows any user. If setting group ownership may want to
# restrict this to:
#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 too.
# control then you may want to relax this to:
#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
@@ -155,15 +155,6 @@
#auth_tls = "none"
# Change the API access control scheme
#
# By default an authenticated user is allowed access
# to all APIs. Access drivers can place restrictions
# on this. By default the 'nop' driver is enabled,
# meaning no access control checks are done once a
# client has authenticated with libvirtd
#
#access_drivers = [ "polkit" ]
#################################################################
#
@@ -216,7 +207,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=*"
@@ -255,18 +246,8 @@
# The maximum number of concurrent client connections to allow
# over all sockets combined.
#max_clients = 5000
#max_clients = 20
# The maximum length of queue of connections waiting to be
# accepted by the daemon. Note, that some protocols supporting
# retransmission may obey this so that a later reattempt at
# connection succeeds.
#max_queued_clients = 1000
# The maximum length of queue of accepted but not yet not
# authenticated clients. The default value is zero, meaning
# the feature is disabled.
#max_anonymous_clients = 20
# The minimum limit sets the number of workers to start up
# initially. If the number of active clients exceeds this,
@@ -278,13 +259,13 @@
# The number of priority workers. If all workers from above
# pool are stuck, some calls marked as high priority
# pool will 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 impacts
# will be read into memory and queued. This directly impact
# memory usage, currently each request requires 256 KB of
# memory. So by default up to 5 MB of memory is used
#
@@ -322,7 +303,7 @@
# 3: WARNING
# 4: ERROR
#
# Multiple filters can be defined in a single @filters, they just need to be
# Multiple filter 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
@@ -344,16 +325,16 @@
# 3: WARNING
# 4: ERROR
#
# Multiple outputs can be defined, they just need to be separated by spaces.
# Multiple output 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"
#
# Log debug buffer size:
#
# This configuration option is no longer used, since the global
# log buffer functionality has been removed. Please configure
# suitable log_outputs/log_filters settings to obtain logs.
# Log debug buffer size: default 64
# The daemon keeps an internal debug log buffer which will be dumped in case
# of crash or upon receiving a SIGUSR2 signal. This setting allows to override
# the default buffer size in kilobytes.
# If value is 0 or less the debug log buffer is deactivated
#log_buffer_size = 64
@@ -391,7 +372,7 @@
###################################################################
# Keepalive protocol:
# This allows libvirtd to detect broken client connections or even
# dead clients. A keepalive message is sent to a client after
# dead client. 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
@@ -400,7 +381,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 daemon will send responses. When
# can still send them and the deamon 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.

View File

@@ -1,7 +1,7 @@
/*
* libvirtd.h: daemon data structure definitions
*
* Copyright (C) 2006-2014 Red Hat, Inc.
* Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -27,11 +27,14 @@
# define VIR_ENUM_SENTINELS
# include <config.h>
# include <rpc/types.h>
# include <rpc/xdr.h>
# include "remote_protocol.h"
# include "lxc_protocol.h"
# include "qemu_protocol.h"
# include "virlog.h"
# include "virthread.h"
# if WITH_SASL
# include "virnetsaslcontext.h"
@@ -42,20 +45,13 @@ typedef struct daemonClientStream daemonClientStream;
typedef daemonClientStream *daemonClientStreamPtr;
typedef struct daemonClientPrivate daemonClientPrivate;
typedef daemonClientPrivate *daemonClientPrivatePtr;
typedef struct daemonClientEventCallback daemonClientEventCallback;
typedef daemonClientEventCallback *daemonClientEventCallbackPtr;
/* Stores the per-client connection state */
struct daemonClientPrivate {
/* Hold while accessing any data except conn */
virMutex lock;
daemonClientEventCallbackPtr *domainEventCallbacks;
size_t ndomainEventCallbacks;
daemonClientEventCallbackPtr *networkEventCallbacks;
size_t nnetworkEventCallbacks;
daemonClientEventCallbackPtr *qemuEventCallbacks;
size_t nqemuEventCallbacks;
int domainEventCallbackID[VIR_DOMAIN_EVENT_ID_LAST];
# if WITH_SASL
virNetSASLSessionPtr sasl;

View File

@@ -9,11 +9,9 @@
# Should-Start: $named
# Should-Start: xend
# Should-Start: avahi-daemon
# Should-Start: virtlockd
# Required-Stop: $network messagebus
# Should-Stop: $named
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Short-Description: daemon for libvirt virtualization API
# Description: This is a daemon for managing guest instances
# and libvirt virtual networks

View File

@@ -36,10 +36,6 @@ from the configuration.
=over
=item B<-h, --help>
Display command line help usage then exit.
=item B<-d, --daemon>
Run as a daemon & write PID file.

View File

@@ -27,5 +27,5 @@ mech_list: digest-md5
# If using digest-md5 for username/passwds, then this is the file
# containing the passwds. Use 'saslpasswd2 -a libvirt [username]'
# to add entries, and 'sasldblistusers2 -f [sasldb_path]' to browse it
# to add entries, and 'sasldblistusers2 -a libvirt' to browse it
sasldb_path: /etc/libvirt/passwd.db

View File

@@ -9,17 +9,12 @@ Before=libvirt-guests.service
After=network.target
After=dbus.service
After=iscsid.service
After=apparmor.service
Documentation=man:libvirtd(8)
Documentation=http://libvirt.org
[Service]
Type=notify
EnvironmentFile=-/etc/sysconfig/libvirtd
ExecStart=@sbindir@/libvirtd $LIBVIRTD_ARGS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
# Override the maximum number of opened files
#LimitNOFILE=2048

View File

@@ -20,14 +20,5 @@
#
#SDL_AUDIODRIVER=pulse
# Override the maximum number of opened files.
# This only works with traditional init scripts.
# In the systemd world, the limit can only be changed by overriding
# LimitNOFILE for libvirtd.service. To do that, just create a *.conf
# file in /etc/systemd/system/libvirtd.service.d/ (for example
# /etc/systemd/system/libvirtd.service.d/openfiles.conf) and write
# the following two lines in it:
# [Service]
# LimitNOFILE=2048
#
# Override the maximum number of opened files
#LIBVIRTD_NOFILES_LIMIT=2048

File diff suppressed because it is too large Load Diff

View File

@@ -32,8 +32,6 @@
#define VIR_FROM_THIS VIR_FROM_STREAMS
VIR_LOG_INIT("daemon.stream");
struct daemonClientStream {
daemonClientPrivatePtr priv;
int refs;
@@ -260,7 +258,7 @@ daemonStreamEvent(virStreamPtr st, int events, void *opaque)
daemonStreamUpdateEvents(stream);
}
cleanup:
cleanup:
virMutexUnlock(&priv->lock);
}
@@ -301,7 +299,7 @@ daemonStreamFilter(virNetServerClientPtr client ATTRIBUTE_UNUSED,
daemonStreamUpdateEvents(stream);
ret = 1;
cleanup:
cleanup:
virMutexUnlock(&stream->priv->lock);
return ret;
}
@@ -327,8 +325,10 @@ daemonCreateClientStream(virNetServerClientPtr client,
VIR_DEBUG("client=%p, proc=%d, serial=%d, st=%p",
client, header->proc, header->serial, st);
if (VIR_ALLOC(stream) < 0)
if (VIR_ALLOC(stream) < 0) {
virReportOOMError();
return NULL;
}
stream->refs = 1;
stream->priv = priv;
@@ -710,7 +710,7 @@ daemonStreamHandleRead(virNetServerClientPtr client,
daemonClientStream *stream)
{
char *buffer;
size_t bufferLen = VIR_NET_MESSAGE_LEGACY_PAYLOAD_MAX;
size_t bufferLen = VIR_NET_MESSAGE_PAYLOAD_MAX;
int ret;
VIR_DEBUG("client=%p, stream=%p tx=%d closed=%d",

View File

@@ -17,9 +17,6 @@ module Test_libvirtd =
{ "auth_unix_rw" = "none" }
{ "auth_tcp" = "sasl" }
{ "auth_tls" = "none" }
{ "access_drivers"
{ "1" = "polkit" }
}
{ "key_file" = "/etc/pki/libvirt/private/serverkey.pem" }
{ "cert_file" = "/etc/pki/libvirt/servercert.pem" }
{ "ca_file" = "/etc/pki/CA/cacert.pem" }
@@ -34,9 +31,7 @@ module Test_libvirtd =
{ "1" = "joe@EXAMPLE.COM" }
{ "2" = "fred@EXAMPLE.COM" }
}
{ "max_clients" = "5000" }
{ "max_queued_clients" = "1000" }
{ "max_anonymous_clients" = "20" }
{ "max_clients" = "20" }
{ "min_workers" = "5" }
{ "max_workers" = "20" }
{ "prio_workers" = "5" }

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1>404 page not found</h1>

View File

@@ -1,20 +1,7 @@
## Process this file with automake to produce Makefile.in
## Copyright (C) 2005-2013 Red Hat, Inc.
##
## This library is free software; you can redistribute it and/or
## modify it under the terms of the GNU Lesser General Public
## License as published by the Free Software Foundation; either
## version 2.1 of the License, or (at your option) any later version.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public
## License along with this library. If not, see
## <http://www.gnu.org/licenses/>.
## Copyright (C) 2005-2012 Red Hat, Inc.
## See COPYING.LIB for the License of this software
SUBDIRS= schemas
@@ -25,6 +12,8 @@ DOC_SOURCE_DIR=../src
DEVHELP_DIR=$(datadir)/gtk-doc/html/libvirt
BUILT_SOURCES=hvsupport.html.in
apihtml = \
html/index.html \
html/libvirt-libvirt.html \
@@ -87,12 +76,6 @@ internals_html_in = \
$(patsubst $(srcdir)/%,%,$(wildcard $(srcdir)/internals/*.html.in))
internals_html = $(internals_html_in:%.html.in=%.html)
# todo.html is special - it is shipped in the tarball, but we
# have a dedicated 'todo' target to rebuild it from a proper
# config file, all other users are able to build it locally.
# For all other files, since we ship pre-built html in the
# tarball, we must also ship the sources, even when those
# sources are themselves generated.
dot_html_in = $(notdir $(wildcard $(srcdir)/*.html.in)) \
todo.html.in \
hvsupport.html.in
@@ -132,7 +115,7 @@ fig = \
migration-unmanaged-direct.fig
EXTRA_DIST= \
apibuild.py genaclperms.pl \
apibuild.py \
site.xsl newapi.xsl news.xsl page.xsl \
hacking1.xsl hacking2.xsl wrapstring.xsl \
$(dot_html) $(dot_html_in) $(gif) $(apihtml) $(apipng) \
@@ -140,22 +123,15 @@ EXTRA_DIST= \
$(xml) $(qemu_xml) $(lxc_xml) $(fig) $(png) $(css) \
$(patches) $(dot_php_in) $(dot_php_code_in) $(dot_php)\
$(internals_html_in) $(internals_html) \
sitemap.html.in aclperms.htmlinc \
sitemap.html.in \
todo.pl hvsupport.pl todo.cfg-example
acl.html:: $(srcdir)/aclperms.htmlinc
$(srcdir)/aclperms.htmlinc: $(top_srcdir)/src/access/viraccessperm.h \
$(srcdir)/genaclperms.pl Makefile.am
$(AM_V_GEN)$(PERL) $(srcdir)/genaclperms.pl $< > $@
MAINTAINERCLEANFILES = \
$(addprefix $(srcdir)/,$(dot_html)) \
$(addprefix $(srcdir)/,$(apihtml)) \
$(addprefix $(srcdir)/,$(devhelphtml)) \
$(addprefix $(srcdir)/,$(internals_html)) \
$(addprefix $(srcdir)/,$(dot_php)) \
$(srcdir)/hvsupport.html.in $(srcdir)/aclperms.htmlinc
$(addprefix $(srcdir)/,$(dot_php))
all-am: web
@@ -173,25 +149,17 @@ todo.html.in: todo.pl
|| { rm $@ && exit 1; }; \
else \
echo "Stubbing $@"; \
printf "%s\n" \
"<html xmlns=\"http://www.w3.org/1999/xhtml\">" \
"<body>" \
"<h1>Todo list unavailable: no config file</h1>" \
"</body></html>" > $@ ; \
echo "<html><body><h1>Todo list</h1></body></html>" > $@ ; \
fi
todo:
rm -f todo.html.in
$(MAKE) todo.html
hvsupport.html:: $(srcdir)/hvsupport.html.in
$(srcdir)/hvsupport.html.in: $(srcdir)/hvsupport.pl \
$(srcdir)/../src/libvirt_public.syms \
hvsupport.html.in: $(srcdir)/hvsupport.pl $(srcdir)/../src/libvirt_public.syms \
$(srcdir)/../src/libvirt_qemu.syms $(srcdir)/../src/libvirt_lxc.syms \
$(srcdir)/../src/driver.h
$(AM_V_GEN)$(PERL) $(srcdir)/hvsupport.pl $(srcdir)/../src > $@ \
|| { rm $@ && exit 1; }
$(AM_V_GEN)$(PERL) $(srcdir)/hvsupport.pl $(srcdir)/../src > $@ || { rm $@ && exit 1; }
.PHONY: todo
@@ -203,7 +171,7 @@ internals/%.html.tmp: internals/%.html.in subsite.xsl page.xsl sitemap.html.in
echo "Generating $@"; \
$(MKDIR_P) internals; \
name=`echo $@ | sed -e 's/.tmp//'`; \
$(XSLTPROC) --stringparam pagename $$name --nonet \
$(XSLTPROC) --stringparam pagename $$name --nonet --html \
$(top_srcdir)/docs/subsite.xsl $< > $@ \
|| { rm $@ && exit 1; }; fi
@@ -211,7 +179,7 @@ internals/%.html.tmp: internals/%.html.in subsite.xsl page.xsl sitemap.html.in
@if [ -x $(XSLTPROC) ] ; then \
echo "Generating $@"; \
name=`echo $@ | sed -e 's/.tmp//'`; \
$(XSLTPROC) --stringparam pagename $$name --nonet \
$(XSLTPROC) --stringparam pagename $$name --nonet --html \
$(top_srcdir)/docs/site.xsl $< > $@ \
|| { rm $@ && exit 1; }; fi
@@ -228,21 +196,20 @@ internals/%.html.tmp: internals/%.html.in subsite.xsl page.xsl sitemap.html.in
%.php.tmp: %.php.in site.xsl page.xsl sitemap.html.in
@if [ -x $(XSLTPROC) ] ; then \
echo "Generating $@"; \
$(XSLTPROC) --stringparam pagename $(@:.tmp=) --nonet \
$(XSLTPROC) --stringparam pagename $(@:.tmp=) --nonet --html \
$(top_srcdir)/docs/site.xsl $< > $@ \
|| { rm $@ && exit 1; }; fi
%.php: %.php.tmp %.php.code.in
@if [ -x $(XSLTPROC) ] ; then \
echo "Scripting $@"; \
sed -e '/<span id="php_placeholder"><\/span>/r '"$(srcdir)/$@.code.in" \
sed -e '/<a id="php_placeholder"><\/a>/r '"$(srcdir)/$@.code.in" \
-e /php_placeholder/d < $@.tmp > $(srcdir)/$@ \
|| { rm $(srcdir)/$@ && exit 1; }; fi
html/index.html: libvirt-api.xml newapi.xsl page.xsl sitemap.html.in
$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then \
$(XSLTPROC) --nonet -o $(srcdir)/ \
--stringparam builddir '$(abs_top_builddir)' \
$(srcdir)/newapi.xsl $(srcdir)/libvirt-api.xml ; fi && \
if test -x $(XMLLINT) && test -x $(XMLCATALOG) ; then \
if $(XMLCATALOG) '$(XML_CATALOG_FILE)' "-//W3C//DTD XHTML 1.0 Strict//EN" \
@@ -292,14 +259,12 @@ $(APIBUILD_STAMP): $(srcdir)/apibuild.py \
check-local: all
dist-local: all
clean-local:
rm -f *~ *.bak *.hierarchy *.signals *-unused.txt *.html
maintainer-clean-local: clean-local
rm -rf $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml \
todo.html.in
rm -rf $(srcdir)/libvirt-api.xml $(srcdir)/libvirt-refs.xml todo.html.in hvsupport.html.in
rm -rf $(srcdir)/libvirt-qemu-api.xml $(srcdir)/libvirt-qemu-refs.xml
rm -rf $(srcdir)/libvirt-lxc-api.xml $(srcdir)/libvirt-lxc-refs.xml
rm -rf $(APIBUILD_STAMP)

View File

@@ -1,100 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Client access control</h1>
<p>
Libvirt's client access control framework allows administrators
to setup fine grained permission rules across client users,
managed objects and API operations. This allows client connections
to be locked down to a minimal set of privileges.
</p>
<ul id="toc"></ul>
<h2><a name="intro">Access control introduction</a></h2>
<p>
In a default configuration, the libvirtd daemon has three levels
of access control. All connections start off in an unauthenticated
state, where the only API operations allowed are those required
to complete authentication. After successful authentication, a
connection either has full, unrestricted access to all libvirt
API calls, or is locked down to only "read only" operations,
according to what socket a client connection originated on.
</p>
<p>
The access control framework allows authenticated connections to
have fine grained permission rules to be defined by the administrator.
Every API call in libvirt has a set of permissions that will
be validated against the object being used. For example, the
<code>virDomainSetSchedulerParametersFlags</code> method will
check whether the client user has the <code>write</code>
permission on the <code>domain</code> object instance passed
in as a parameter. Further permissions will also be checked
if certain flags are set in the API call. In addition to
checks on the object passed in to an API call, some methods
will filter their results. For example the <code>virConnectListAllDomains</code>
method will check the <code>search_domains</code> on the <code>connect</code>
object, but will also filter the returned <code>domain</code>
objects to only those on which the client user has the
<code>getattr</code> permission.
</p>
<h2><a name="drivers">Access control drivers</a></h2>
<p>
The access control framework is designed as a pluggable
system to enable future integration with arbitrary access
control technologies. By default, the <code>none</code>
driver is used, which does no access control checks at
all. At this time, libvirt ships with support for using
<a href="http://www.freedesktop.org/wiki/Software/polkit/">polkit</a> as a real access
control driver. To learn how to use the polkit access
driver consult <a href="aclpolkit.html">the configuration
docs</a>.
</p>
<p>
The access driver is configured in the <code>libvirtd.conf</code>
configuration file, using the <code>access_drivers</code>
parameter. This parameter accepts an array of access control
driver names. If more than one access driver is requested,
then all must succeed in order for access to be granted.
To enable 'polkit' as the driver:
</p>
<pre>
# augtool -s set '/files/etc/libvirt/libvirtd.conf/access_drivers[1]' polkit
</pre>
<p>
And to reset back to the default (no-op) driver
</p>
<pre>
# augtool -s rm /files/etc/libvirt/libvirtd.conf/access_drivers
</pre>
<p>
<strong>Note:</strong> changes to libvirtd.conf require that
the libvirtd daemon be restarted.
</p>
<h2><a name="perms">Objects and permissions</a></h2>
<p>
Libvirt applies access control to all the main object
types in its API. Each object type, in turn, has a set
of permissions defined. To determine what permissions
are checked for specific API call, consult the
<a href="html/libvirt-libvirt.html">API reference manual</a>
documentation for the API in question.
</p>
<div id="include" filename="aclperms.htmlinc"/>
</body>
</html>

View File

@@ -1,408 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Polkit access control</h1>
<p>
Libvirt's client <a href="acl.html">access control framework</a> allows
administrators to setup fine grained permission rules across client users,
managed objects and API operations. This allows client connections
to be locked down to a minimal set of privileges. The polkit driver
provides a simple implementation of the access control framework.
</p>
<ul id="toc"></ul>
<h2><a name="intro">Introduction</a></h2>
<p>
A default install of libvirt will typically use
<a href="http://www.freedesktop.org/wiki/Software/polkit/">polkit</a>
to authenticate the initial user connection to libvirtd. This is a
very coarse grained check though, either allowing full read-write
access to all APIs, or just read-only access. The polkit access
control driver in libvirt builds on this capability to allow for
fine grained control over the operations a user may perform on an
object.
</p>
<h2><a name="perms">Permission names</a></h2>
<p>
The libvirt <a href="acl.html#perms">object names and permission names</a>
are mapped onto polkit action names using the simple pattern:
</p>
<pre>org.libvirt.api.$object.$permission
</pre>
<p>
The only caveat is that any underscore characters in the
object or permission names are converted to hyphens. So,
for example, the <code>search_storage_vols</code> permission
on the <code>storage_pool</code> object maps to the polkit
action:
</p>
<pre>org.libvirt.api.storage-pool.search-storage-vols
</pre>
<p>
The default policy for any permission which corresponds to
a "read only" operation, is to allow access. All other
permissions default to deny access.
</p>
<h2><a name="attrs">Object identity attributes</a></h2>
<p>
To allow polkit authorization rules to be written to match
against individual object instances, libvirt provides a number
of authorization detail attributes when performing a permission
check. The set of attributes varies according to the type
of object being checked
</p>
<h3><a name="object_connect">virConnectPtr</a></h3>
<table class="acl">
<thead>
<tr>
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>connect_driver</td>
<td>Name of the libvirt connection driver</td>
</tr>
</tbody>
</table>
<h3><a name="object_domain">virDomainPtr</a></h3>
<table class="acl">
<thead>
<tr>
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>connect_driver</td>
<td>Name of the libvirt connection driver</td>
</tr>
<tr>
<td>domain_name</td>
<td>Name of the domain, unique to the local host</td>
</tr>
<tr>
<td>domain_uuid</td>
<td>UUID of the domain, globally unique</td>
</tr>
</tbody>
</table>
<h3><a name="object_interface">virInterfacePtr</a></h3>
<table class="acl">
<thead>
<tr>
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>connect_driver</td>
<td>Name of the libvirt connection driver</td>
</tr>
<tr>
<td>interface_name</td>
<td>Name of the network interface, unique to the local host</td>
</tr>
<tr>
<td>interface_mac</td>
<td>MAC address of the network interface, not unique</td>
</tr>
</tbody>
</table>
<h3><a name="object_network">virNetworkPtr</a></h3>
<table class="acl">
<thead>
<tr>
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>connect_driver</td>
<td>Name of the libvirt connection driver</td>
</tr>
<tr>
<td>network_name</td>
<td>Name of the network, unique to the local host</td>
</tr>
<tr>
<td>network_uuid</td>
<td>UUID of the network, globally unique</td>
</tr>
</tbody>
</table>
<h3><a name="object_node_device">virNodeDevicePtr</a></h3>
<table class="acl">
<thead>
<tr>
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>connect_driver</td>
<td>Name of the libvirt connection driver</td>
</tr>
<tr>
<td>node_device_name</td>
<td>Name of the node device, unique to the local host</td>
</tr>
</tbody>
</table>
<h3><a name="object_nwfilter">virNWFilterPtr</a></h3>
<table class="acl">
<thead>
<tr>
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>connect_driver</td>
<td>Name of the libvirt connection driver</td>
</tr>
<tr>
<td>nwfilter_name</td>
<td>Name of the network filter, unique to the local host</td>
</tr>
<tr>
<td>nwfilter_uuid</td>
<td>UUID of the network filter, globally unique</td>
</tr>
</tbody>
</table>
<h3><a name="object_secret">virSecretPtr</a></h3>
<table class="acl">
<thead>
<tr>
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>connect_driver</td>
<td>Name of the libvirt connection driver</td>
</tr>
<tr>
<td>secret_uuid</td>
<td>UUID of the secret, globally unique</td>
</tr>
<tr>
<td>secret_usage_volume</td>
<td>Name of the associated volume, if any</td>
</tr>
<tr>
<td>secret_usage_ceph</td>
<td>Name of the associated Ceph server, if any</td>
</tr>
<tr>
<td>secret_usage_target</td>
<td>Name of the associated iSCSI target, if any</td>
</tr>
</tbody>
</table>
<h3><a name="object_storage_pool">virStoragePoolPtr</a></h3>
<table class="acl">
<thead>
<tr>
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>connect_driver</td>
<td>Name of the libvirt connection driver</td>
</tr>
<tr>
<td>pool_name</td>
<td>Name of the storage pool, unique to the local host</td>
</tr>
<tr>
<td>pool_uuid</td>
<td>UUID of the storage pool, globally unique</td>
</tr>
</tbody>
</table>
<h3><a name="object_storage_vol">virStorageVolPtr</a></h3>
<table class="acl">
<thead>
<tr>
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>connect_driver</td>
<td>Name of the libvirt connection driver</td>
</tr>
<tr>
<td>pool_name</td>
<td>Name of the storage pool, unique to the local host</td>
</tr>
<tr>
<td>pool_uuid</td>
<td>UUID of the storage pool, globally unique</td>
</tr>
<tr>
<td>vol_name</td>
<td>Name of the storage volume, unique to the pool</td>
</tr>
<tr>
<td>vol_key</td>
<td>Key of the storage volume, globally unique</td>
</tr>
</tbody>
</table>
<h2><a name="user">User identity attributes</a></h2>
<p>
At this point in time, the only attribute provided by
libvirt to identify the user invoking the operation
is the PID of the client program. This means that the
polkit access control driver is only useful if connections
to libvirt are restricted to its UNIX domain socket. If
connections are being made to a TCP socket, no identifying
information is available and access will be denied.
Also note that if the client is connecting via an SSH
tunnel, it is the local SSH user that will be identified.
In future versions, it is expected that more information
about the client user will be provided, including the
SASL / Kerberos username and/or x509 distinguished
name obtained from the authentication provider in use.
</p>
<h2><a name="checks">Writing access control policies</a></h2>
<p>
If using versions of polkit prior to 0.106 then it is only
possible to validate (user, permission) pairs via the <code>.pkla</code>
files. Fully validation of the (user, permission, object) triple
requires the new JavaScript <code>.rules</code> support that
was introduced in version 0.106. The latter is what will be
described here.
</p>
<p>
Libvirt does not ship any rules files by default. It merely
provides a definition of the default behaviour for each
action (permission). As noted earlier, permissions which
correspond to read-only operations in libvirt will be allowed
to all users by default; everything else is denied by default.
Defining custom rules requires creation of a file in the
<code>/etc/polkit-1/rules.d</code> directory with a name
chosen by the administrator (<code>100-libvirt-acl.rules</code>
would be a reasonable choice). See the <code>polkit(8)</code>
manual page for a description of how to write these files
in general. The key idea is to create a file containing
something like
</p>
<pre>
polkit.addRule(function(action, subject) {
....logic to check 'action' and 'subject'...
});
</pre>
<p>
In this code snippet above, the <code>action</code> object
instance will represent the libvirt permission being checked
along with identifying attributes for the object it is being
applied to. The <code>subject</code> meanwhile will identify
the libvirt client app (with the caveat above about it only
dealing with local clients connected via the UNIX socket).
On the <code>action</code> object, the permission name is
accessible via the <code>id</code> attribute, while the
object identifying attributes are exposed via the
<code>lookup</code> method.
</p>
<h3><a name="exconnect">Example: restricting ability to connect to drivers</a></h3>
<p>
Consider a local user <code>berrange</code>
who has been granted permission to connect to libvirt in
full read-write mode. The goal is to only allow them to
use the <code>QEMU</code> driver and not the Xen or LXC
drivers which are also available in libvirtd.
To achieve this we need to write a rule which checks
whether the <code>connect_driver</code> attribute
is <code>QEMU</code>, and match on an action
name of <code>org.libvirt.api.connect.getattr</code>. Using
the javascript rules format, this ends up written as
</p>
<pre>
polkit.addRule(function(action, subject) {
if (action.id == "org.libvirt.api.connect.getattr" &amp;&amp;
subject.user == "berrange") {
if (action.lookup("connect_driver") == 'QEMU') {
return polkit.Result.YES;
} else {
return polkit.Result.NO;
}
}
});
</pre>
<h3><a name="exdomain">Example: restricting access to a single domain</a></h3>
<p>
Consider a local user <code>berrange</code>
who has been granted permission to connect to libvirt in
full read-write mode. The goal is to only allow them to
see the domain called <code>demo</code> on the LXC driver.
To achieve this we need to write a rule which checks
whether the <code>connect_driver</code> attribute
is <code>LXC</code> and the <code>domain_name</code>
attribute is <code>demo</code>, and match on a action
name of <code>org.libvirt.api.domain.getattr</code>. Using
the javascript rules format, this ends up written as
</p>
<pre>
polkit.addRule(function(action, subject) {
if (action.id == "org.libvirt.api.domain.getattr" &amp;&amp;
subject.user == "berrange") {
if (action.lookup("connect_driver") == 'LXC' &amp;&amp;
action.lookup("domain_name") == 'demo') {
return polkit.Result.YES;
} else {
return polkit.Result.NO;
}
}
});
</pre>
</body>
</html>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1>The libvirt API concepts</h1>
@@ -207,7 +206,7 @@
virtualization <a href="#Functions">functions</a>. Depending upon the
driver being used, calls will be routed through the remote driver to
the libvirtd daemon. The daemon will reference the connection specific
driver in order to retrieve the requested information and then pass
driver in order to retreive the requested information and then pass
back status and/or data through the connection back to the application.
The application can then decide what to do with that data, such as
display, write log data, etc. <a href="migration.html">Migration</a>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Implementing a new API in Libvirt</h1>
@@ -180,13 +178,12 @@
being called and its parameters;</li>
<li>MUST call virResetLastError();</li>
<li>SHOULD confirm that the connection is valid with
virCheckConnectReturn() or virCheckConnectGoto();</li>
VIR_IS_CONNECT(conn);</li>
<li><strong>SECURITY: If the API requires a connection with write
privileges, MUST confirm that the connection flags do not
indicate that the connection is read-only with
virCheckReadOnlyGoto();</strong></li>
indicate that the connection is read-only;</strong></li>
<li>SHOULD do basic validation of the parameters that are being
passed in, using helpers like virCheckNonNullArgGoto();</li>
passed in;</li>
<li>MUST confirm that the driver for this connection exists and that
it implements this function;</li>
<li>MUST call the internal API;</li>

View File

@@ -64,18 +64,9 @@ ignored_functions = {
"virDomainMigrateConfirm3": "private function for migration",
"virDomainMigratePrepareTunnel3": "private function for tunnelled migration",
"DllMain": "specific function for Win32",
"virTypedParamsValidate": "internal function in virtypedparam.c",
"virTypedParameterArrayValidate": "internal function in virtypedparam.c",
"virTypedParameterAssign": "internal function in virtypedparam.c",
"virTypedParameterAssignFromStr": "internal function in virtypedparam.c",
"virTypedParameterToString": "internal function in virtypedparam.c",
"virTypedParamsCheck": "internal function in virtypedparam.c",
"virTypedParamsCopy": "internal function in virtypedparam.c",
"virDomainMigrateBegin3Params": "private function for migration",
"virDomainMigrateFinish3Params": "private function for migration",
"virDomainMigratePerform3Params": "private function for migration",
"virDomainMigratePrepare3Params": "private function for migration",
"virDomainMigrateConfirm3Params": "private function for migration",
"virDomainMigratePrepareTunnel3Params": "private function for tunnelled migration",
}
ignored_macros = {
@@ -111,7 +102,7 @@ class identifier:
self.extra = extra
self.lineno = lineno
self.static = 0
if conditionals is None or len(conditionals) == 0:
if conditionals == None or len(conditionals) == 0:
self.conditionals = None
else:
self.conditionals = conditionals[:]
@@ -123,13 +114,13 @@ class identifier:
r = "%s %s:" % (self.type, self.name)
if self.static:
r = r + " static"
if self.module is not None:
if self.module != None:
r = r + " from %s" % (self.module)
if self.info is not None:
if self.info != None:
r = r + " " + `self.info`
if self.extra is not None:
if self.extra != None:
r = r + " " + `self.extra`
if self.conditionals is not None:
if self.conditionals != None:
r = r + " " + `self.conditionals`
return r
@@ -149,7 +140,7 @@ class identifier:
def set_static(self, static):
self.static = static
def set_conditionals(self, conditionals):
if conditionals is None or len(conditionals) == 0:
if conditionals == None or len(conditionals) == 0:
self.conditionals = None
else:
self.conditionals = conditionals[:]
@@ -178,17 +169,17 @@ class identifier:
if self.name == debugsym and not quiet:
print "=> update %s : %s" % (debugsym, (module, type, info,
extra, conditionals))
if header is not None and self.header is None:
if header != None and self.header == None:
self.set_header(module)
if module is not None and (self.module is None or self.header == self.module):
if module != None and (self.module == None or self.header == self.module):
self.set_module(module)
if type is not None and self.type is None:
if type != None and self.type == None:
self.set_type(type)
if info is not None:
if info != None:
self.set_info(info)
if extra is not None:
if extra != None:
self.set_extra(extra)
if conditionals is not None:
if conditionals != None:
self.set_conditionals(conditionals)
class index:
@@ -217,10 +208,10 @@ class index:
d = identifier(name, header, module, type, lineno, info, extra, conditionals)
self.identifiers[name] = d
if d is not None and static == 1:
if d != None and static == 1:
d.set_static(1)
if d is not None and name is not None and type is not None:
if d != None and name != None and type != None:
self.references[name] = d
if name == debugsym and not quiet:
@@ -239,10 +230,10 @@ class index:
d = identifier(name, header, module, type, lineno, info, extra, conditionals)
self.identifiers[name] = d
if d is not None and static == 1:
if d != None and static == 1:
d.set_static(1)
if d is not None and name is not None and type is not None:
if d != None and name != None and type != None:
if type == "function":
self.functions[name] = d
elif type == "functype":
@@ -432,7 +423,7 @@ class CLexer:
else:
line = self.line
self.line = ""
if line is None:
if line == None:
return None
if line[0] == '#':
@@ -461,7 +452,7 @@ class CLexer:
tok = tok + line
if found == 0:
line = self.getline()
if line is None:
if line == None:
return None
self.last = ('string', tok)
return self.last
@@ -486,7 +477,7 @@ class CLexer:
tok = tok + line
if found == 0:
line = self.getline()
if line is None:
if line == None:
return None
self.last = ('comment', tok)
return self.last
@@ -598,7 +589,7 @@ class CParser:
self.is_header = 0
self.input = open(filename)
self.lexer = CLexer(self.input)
if idx is None:
if idx == None:
self.index = index()
else:
self.index = idx
@@ -707,7 +698,7 @@ class CParser:
com = token[1]
if self.top_comment == "":
self.top_comment = com
if self.comment is None or com[0] == '*':
if self.comment == None or com[0] == '*':
self.comment = com
else:
self.comment = self.comment + com
@@ -731,7 +722,7 @@ class CParser:
args = []
desc = ""
if self.comment is None:
if self.comment == None:
if not quiet:
self.warning("Missing comment for type %s" % (name))
return((args, desc))
@@ -780,7 +771,7 @@ class CParser:
args = []
desc = ""
if self.comment is None:
if self.comment == None:
if not quiet:
self.warning("Missing comment for macro %s" % (name))
return((args, desc))
@@ -860,7 +851,7 @@ class CParser:
desc = ""
retdesc = ""
if self.comment is None:
if self.comment == None:
if not quiet:
self.warning("Missing comment for function %s" % (name))
return(((ret[0], retdesc), args, desc))
@@ -958,7 +949,7 @@ class CParser:
#
i = 0
while i < nbargs:
if args[i][2] is None and args[i][0] != "void" and args[i][1] is not None:
if args[i][2] == None and args[i][0] != "void" and args[i][1] != None:
self.warning("Function comment for %s lacks description of arg %s" % (name, args[i][1]))
i = i + 1
if retdesc == "" and ret[0] != "void":
@@ -975,7 +966,7 @@ class CParser:
name = token[1]
if name == "#include":
token = self.lexer.token()
if token is None:
if token == None:
return None
if token[0] == 'preproc':
self.index_add(token[1], self.filename, not self.is_header,
@@ -984,14 +975,14 @@ class CParser:
return token
if name == "#define":
token = self.lexer.token()
if token is None:
if token == None:
return None
if token[0] == 'preproc':
# TODO macros with arguments
name = token[1]
lst = []
token = self.lexer.token()
while token is not None and token[0] == 'preproc' and \
while token != None and token[0] == 'preproc' and \
token[1][0] != '#':
lst.append(token[1])
token = self.lexer.token()
@@ -1059,7 +1050,7 @@ class CParser:
self.conditionals = self.conditionals[:-1]
self.defines = self.defines[:-1]
token = self.lexer.token()
while token is not None and token[0] == 'preproc' and \
while token != None and token[0] == 'preproc' and \
token[1][0] != '#':
token = self.lexer.token()
return token
@@ -1076,7 +1067,7 @@ class CParser:
global ignored_words
token = self.lexer.token()
while token is not None:
while token != None:
if token[0] == 'comment':
token = self.parseComment(token)
continue
@@ -1088,7 +1079,7 @@ class CParser:
return token
elif token[0] == "name" and token[1] == "__attribute":
token = self.lexer.token()
while token is not None and token[1] != ";":
while token != None and token[1] != ";":
token = self.lexer.token()
return token
elif token[0] == "name" and ignored_words.has_key(token[1]):
@@ -1109,20 +1100,20 @@ class CParser:
# Parse a typedef, it records the type and its name.
#
def parseTypedef(self, token):
if token is None:
if token == None:
return None
token = self.parseType(token)
if token is None:
if token == None:
self.error("parsing typedef")
return None
base_type = self.type
type = base_type
#self.debug("end typedef type", token)
while token is not None:
while token != None:
if token[0] == "name":
name = token[1]
signature = self.signature
if signature is not None:
if signature != None:
type = string.split(type, '(')[0]
d = self.mergeFunctionComment(name,
((type, None), signature), 1)
@@ -1143,15 +1134,15 @@ class CParser:
self.error("parsing typedef: expecting a name")
return token
#self.debug("end typedef", token)
if token is not None and token[0] == 'sep' and token[1] == ',':
if token != None and token[0] == 'sep' and token[1] == ',':
type = base_type
token = self.token()
while token is not None and token[0] == "op":
while token != None and token[0] == "op":
type = type + token[1]
token = self.token()
elif token is not None and token[0] == 'sep' and token[1] == ';':
elif token != None and token[0] == 'sep' and token[1] == ';':
break
elif token is not None and token[0] == 'name':
elif token != None and token[0] == 'name':
type = base_type
continue
else:
@@ -1165,7 +1156,7 @@ class CParser:
# the balancing } included
#
def parseBlock(self, token):
while token is not None:
while token != None:
if token[0] == "sep" and token[1] == "{":
token = self.token()
token = self.parseBlock(token)
@@ -1205,7 +1196,7 @@ class CParser:
def parseStruct(self, token):
fields = []
#self.debug("start parseStruct", token)
while token is not None:
while token != None:
if token[0] == "sep" and token[1] == "{":
token = self.token()
token = self.parseTypeBlock(token)
@@ -1220,7 +1211,7 @@ class CParser:
#self.debug("before parseType", token)
token = self.parseType(token)
#self.debug("after parseType", token)
if token is not None and token[0] == "name":
if token != None and token[0] == "name":
fname = token[1]
token = self.token()
if token[0] == "sep" and token[1] == ";":
@@ -1236,12 +1227,12 @@ class CParser:
self.comment = None
else:
self.error("parseStruct: expecting ;", token)
elif token is not None and token[0] == "sep" and token[1] == "{":
elif token != None and token[0] == "sep" and token[1] == "{":
token = self.token()
token = self.parseTypeBlock(token)
if token is not None and token[0] == "name":
if token != None and token[0] == "name":
token = self.token()
if token is not None and token[0] == "sep" and token[1] == ";":
if token != None and token[0] == "sep" and token[1] == ";":
token = self.token()
else:
self.error("parseStruct: expecting ;", token)
@@ -1260,7 +1251,7 @@ class CParser:
def parseUnion(self, token):
fields = []
# self.debug("start parseUnion", token)
while token is not None:
while token != None:
if token[0] == "sep" and token[1] == "{":
token = self.token()
token = self.parseTypeBlock(token)
@@ -1275,7 +1266,7 @@ class CParser:
# self.debug("before parseType", token)
token = self.parseType(token)
# self.debug("after parseType", token)
if token is not None and token[0] == "name":
if token != None and token[0] == "name":
fname = token[1]
token = self.token()
if token[0] == "sep" and token[1] == ";":
@@ -1286,12 +1277,12 @@ class CParser:
self.comment = None
else:
self.error("parseUnion: expecting ;", token)
elif token is not None and token[0] == "sep" and token[1] == "{":
elif token != None and token[0] == "sep" and token[1] == "{":
token = self.token()
token = self.parseTypeBlock(token)
if token is not None and token[0] == "name":
if token != None and token[0] == "name":
token = self.token()
if token is not None and token[0] == "sep" and token[1] == ";":
if token != None and token[0] == "sep" and token[1] == ";":
token = self.token()
else:
self.error("parseUnion: expecting ;", token)
@@ -1312,15 +1303,15 @@ class CParser:
name = None
self.comment = None
comment = ""
value = "0"
while token is not None:
value = "-1"
while token != None:
if token[0] == "sep" and token[1] == "{":
token = self.token()
token = self.parseTypeBlock(token)
elif token[0] == "sep" and token[1] == "}":
if name is not None:
if name != None:
self.cleanupComment()
if self.comment is not None:
if self.comment != None:
comment = self.comment
self.comment = None
self.enums.append((name, value, comment))
@@ -1328,8 +1319,8 @@ class CParser:
return token
elif token[0] == "name":
self.cleanupComment()
if name is not None:
if self.comment is not None:
if name != None:
if self.comment != None:
comment = string.strip(self.comment)
self.comment = None
self.enums.append((name, value, comment))
@@ -1446,30 +1437,12 @@ class CParser:
return token
def parseVirLogInit(self, token):
if token[0] != "string":
self.error("parsing VIR_LOG_INIT: expecting string", token)
token = self.token()
if token[0] != "sep":
self.error("parsing VIR_LOG_INIT: expecting ')'", token)
if token[1] != ')':
self.error("parsing VIR_LOG_INIT: expecting ')'", token)
token = self.token()
if token[0] == "sep" and token[1] == ';':
token = self.token()
return token
#
# Parse a C definition block, used for structs or unions it parse till
# the balancing }
#
def parseTypeBlock(self, token):
while token is not None:
while token != None:
if token[0] == "sep" and token[1] == "{":
token = self.token()
token = self.parseTypeBlock(token)
@@ -1490,7 +1463,7 @@ class CParser:
self.struct_fields = []
self.union_fields = []
self.signature = None
if token is None:
if token == None:
return token
while token[0] == "name" and (
@@ -1542,13 +1515,13 @@ class CParser:
if token[0] == "name":
nametok = token
token = self.token()
if token is not None and token[0] == "sep" and token[1] == "{":
if token != None and token[0] == "sep" and token[1] == "{":
token = self.token()
token = self.parseStruct(token)
elif token is not None and token[0] == "op" and token[1] == "*":
elif token != None and token[0] == "op" and token[1] == "*":
self.type = self.type + " " + nametok[1] + " *"
token = self.token()
while token is not None and token[0] == "op" and token[1] == "*":
while token != None and token[0] == "op" and token[1] == "*":
self.type = self.type + " *"
token = self.token()
if token[0] == "name":
@@ -1557,11 +1530,11 @@ class CParser:
else:
self.error("struct : expecting name", token)
return token
elif token is not None and token[0] == "name" and nametok is not None:
elif token != None and token[0] == "name" and nametok != None:
self.type = self.type + " " + nametok[1]
return token
if nametok is not None:
if nametok != None:
self.lexer.push(token)
token = nametok
return token
@@ -1576,14 +1549,14 @@ class CParser:
if token[0] == "name":
nametok = token
token = self.token()
if token is not None and token[0] == "sep" and token[1] == "{":
if token != None and token[0] == "sep" and token[1] == "{":
token = self.token()
token = self.parseUnion(token)
elif token is not None and token[0] == "name" and nametok is not None:
elif token != None and token[0] == "name" and nametok != None:
self.type = self.type + " " + nametok[1]
return token
if nametok is not None:
if nametok != None:
self.lexer.push(token)
token = nametok
return token
@@ -1595,13 +1568,13 @@ class CParser:
self.type = self.type + " " + token[1]
self.enums = []
token = self.token()
if token is not None and token[0] == "sep" and token[1] == "{":
if token != None and token[0] == "sep" and token[1] == "{":
token = self.token()
token = self.parseEnumBlock(token)
else:
self.error("parsing enum: expecting '{'", token)
enum_type = None
if token is not None and token[0] != "name":
if token != None and token[0] != "name":
self.lexer.push(token)
token = ("name", "enum")
else:
@@ -1613,40 +1586,28 @@ class CParser:
return token
elif token[0] == "name" and token[1] == "VIR_ENUM_DECL":
token = self.token()
if token is not None and token[0] == "sep" and token[1] == "(":
if token != None and token[0] == "sep" and token[1] == "(":
token = self.token()
token = self.parseVirEnumDecl(token)
else:
self.error("parsing VIR_ENUM_DECL: expecting '('", token)
if token is not None:
if token != None:
self.lexer.push(token)
token = ("name", "virenumdecl")
return token
elif token[0] == "name" and token[1] == "VIR_ENUM_IMPL":
token = self.token()
if token is not None and token[0] == "sep" and token[1] == "(":
if token != None and token[0] == "sep" and token[1] == "(":
token = self.token()
token = self.parseVirEnumImpl(token)
else:
self.error("parsing VIR_ENUM_IMPL: expecting '('", token)
if token is not None:
if token != None:
self.lexer.push(token)
token = ("name", "virenumimpl")
return token
elif token[0] == "name" and token[1] == "VIR_LOG_INIT":
token = self.token()
if token is not None and token[0] == "sep" and token[1] == "(":
token = self.token()
token = self.parseVirLogInit(token)
else:
self.error("parsing VIR_LOG_INIT: expecting '('", token)
if token is not None:
self.lexer.push(token)
token = ("name", "virloginit")
return token
elif token[0] == "name":
if self.type == "":
self.type = token[1]
@@ -1657,7 +1618,7 @@ class CParser:
token)
return token
token = self.token()
while token is not None and (token[0] == "op" or
while token != None and (token[0] == "op" or
token[0] == "name" and token[1] == "const"):
self.type = self.type + " " + token[1]
token = self.token()
@@ -1665,22 +1626,22 @@ class CParser:
#
# if there is a parenthesis here, this means a function type
#
if token is not None and token[0] == "sep" and token[1] == '(':
if token != None and token[0] == "sep" and token[1] == '(':
self.type = self.type + token[1]
token = self.token()
while token is not None and token[0] == "op" and token[1] == '*':
while token != None and token[0] == "op" and token[1] == '*':
self.type = self.type + token[1]
token = self.token()
if token is None or token[0] != "name" :
if token == None or token[0] != "name" :
self.error("parsing function type, name expected", token)
return token
self.type = self.type + token[1]
nametok = token
token = self.token()
if token is not None and token[0] == "sep" and token[1] == ')':
if token != None and token[0] == "sep" and token[1] == ')':
self.type = self.type + token[1]
token = self.token()
if token is not None and token[0] == "sep" and token[1] == '(':
if token != None and token[0] == "sep" and token[1] == '(':
token = self.token()
type = self.type
token = self.parseSignature(token)
@@ -1698,25 +1659,25 @@ class CParser:
#
# do some lookahead for arrays
#
if token is not None and token[0] == "name":
if token != None and token[0] == "name":
nametok = token
token = self.token()
if token is not None and token[0] == "sep" and token[1] == '[':
if token != None and token[0] == "sep" and token[1] == '[':
self.type = self.type + " " + nametok[1]
while token is not None and token[0] == "sep" and token[1] == '[':
while token != None and token[0] == "sep" and token[1] == '[':
self.type = self.type + token[1]
token = self.token()
while token is not None and token[0] != 'sep' and \
while token != None and token[0] != 'sep' and \
token[1] != ']' and token[1] != ';':
self.type = self.type + token[1]
token = self.token()
if token is not None and token[0] == 'sep' and token[1] == ']':
if token != None and token[0] == 'sep' and token[1] == ']':
self.type = self.type + token[1]
token = self.token()
else:
self.error("parsing array type, ']' expected", token)
return token
elif token is not None and token[0] == "sep" and token[1] == ':':
elif token != None and token[0] == "sep" and token[1] == ':':
# remove :12 in case it's a limited int size
token = self.token()
token = self.token()
@@ -1730,25 +1691,25 @@ class CParser:
# up to the ')' included
def parseSignature(self, token):
signature = []
if token is not None and token[0] == "sep" and token[1] == ')':
if token != None and token[0] == "sep" and token[1] == ')':
self.signature = []
token = self.token()
return token
while token is not None:
while token != None:
token = self.parseType(token)
if token is not None and token[0] == "name":
if token != None and token[0] == "name":
signature.append((self.type, token[1], None))
token = self.token()
elif token is not None and token[0] == "sep" and token[1] == ',':
elif token != None and token[0] == "sep" and token[1] == ',':
token = self.token()
continue
elif token is not None and token[0] == "sep" and token[1] == ')':
elif token != None and token[0] == "sep" and token[1] == ')':
# only the type was provided
if self.type == "...":
signature.append((self.type, "...", None))
else:
signature.append((self.type, None, None))
if token is not None and token[0] == "sep":
if token != None and token[0] == "sep":
if token[1] == ',':
token = self.token()
continue
@@ -1843,17 +1804,17 @@ class CParser:
static = 0
if token[1] == 'extern':
token = self.token()
if token is None:
if token == None:
return token
if token[0] == 'string':
if token[1] == 'C':
token = self.token()
if token is None:
if token == None:
return token
if token[0] == 'sep' and token[1] == "{":
token = self.token()
# print 'Entering extern "C line ', self.lineno()
while token is not None and (token[0] != 'sep' or
while token != None and (token[0] != 'sep' or
token[1] != "}"):
if token[0] == 'name':
token = self.parseGlobal(token)
@@ -1870,7 +1831,7 @@ class CParser:
elif token[1] == 'static':
static = 1
token = self.token()
if token is None or token[0] != 'name':
if token == None or token[0] != 'name':
return token
if token[1] == 'typedef':
@@ -1879,22 +1840,22 @@ class CParser:
else:
token = self.parseType(token)
type_orig = self.type
if token is None or token[0] != "name":
if token == None or token[0] != "name":
return token
type = type_orig
self.name = token[1]
token = self.token()
while token is not None and (token[0] == "sep" or token[0] == "op"):
while token != None and (token[0] == "sep" or token[0] == "op"):
if token[0] == "sep":
if token[1] == "[":
type = type + token[1]
token = self.token()
while token is not None and (token[0] != "sep" or \
while token != None and (token[0] != "sep" or \
token[1] != ";"):
type = type + token[1]
token = self.token()
if token is not None and token[0] == "op" and token[1] == "=":
if token != None and token[0] == "op" and token[1] == "=":
#
# Skip the initialization of the variable
#
@@ -1904,15 +1865,15 @@ class CParser:
token = self.parseBlock(token)
else:
self.comment = None
while token is not None and (token[0] != "sep" or \
while token != None and (token[0] != "sep" or \
(token[1] != ';' and token[1] != ',')):
token = self.token()
self.comment = None
if token is None or token[0] != "sep" or (token[1] != ';' and
if token == None or token[0] != "sep" or (token[1] != ';' and
token[1] != ','):
self.error("missing ';' or ',' after value")
if token is not None and token[0] == "sep":
if token != None and token[0] == "sep":
if token[1] == ";":
self.comment = None
token = self.token()
@@ -1927,7 +1888,7 @@ class CParser:
elif token[1] == "(":
token = self.token()
token = self.parseSignature(token)
if token is None:
if token == None:
return None
if token[0] == "sep" and token[1] == ";":
self.checkLongLegacyFunction(self.name, type, self.signature)
@@ -1950,10 +1911,10 @@ class CParser:
"variable", type)
type = type_orig
token = self.token()
while token is not None and token[0] == "sep":
while token != None and token[0] == "sep":
type = type + token[1]
token = self.token()
if token is not None and token[0] == "name":
if token != None and token[0] == "name":
self.name = token[1]
token = self.token()
else:
@@ -1965,7 +1926,7 @@ class CParser:
if not quiet:
print "Parsing %s" % (self.filename)
token = self.token()
while token is not None:
while token != None:
if token[0] == 'name':
token = self.parseGlobal(token)
else:
@@ -2007,7 +1968,7 @@ class docBuilder:
print >>sys.stderr, "Error:", msg
def indexString(self, id, str):
if str is None:
if str == None:
return
str = string.replace(str, "'", ' ')
str = string.replace(str, '"', ' ')
@@ -2099,17 +2060,17 @@ class docBuilder:
id = self.idx.enums[name]
output.write(" <enum name='%s' file='%s'" % (name,
self.modulename_file(id.header)))
if id.info is not None:
if id.info != None:
info = id.info
if info[0] is not None and info[0] != '':
if info[0] != None and info[0] != '':
try:
val = eval(info[0])
except:
val = info[0]
output.write(" value='%s'" % (val))
if info[2] is not None and info[2] != '':
if info[2] != None and info[2] != '':
output.write(" type='%s'" % info[2])
if info[1] is not None and info[1] != '':
if info[1] != None and info[1] != '':
output.write(" info='%s'" % escape(info[1]))
output.write("/>\n")
@@ -2117,15 +2078,15 @@ class docBuilder:
id = self.idx.macros[name]
output.write(" <macro name='%s' file='%s'>\n" % (name,
self.modulename_file(id.header)))
if id.info is not None:
if id.info != None:
try:
(args, desc) = id.info
if desc is not None and desc != "":
if desc != None and desc != "":
output.write(" <info><![CDATA[%s]]></info>\n" % (desc))
self.indexString(name, desc)
for arg in args:
(name, desc) = arg
if desc is not None and desc != "":
if desc != None and desc != "":
output.write(" <arg name='%s' info='%s'/>\n" % (
name, escape(desc)))
self.indexString(name, desc)
@@ -2140,7 +2101,7 @@ class docBuilder:
output.write(" <union>\n")
for f in field[3]:
desc = f[2]
if desc is None:
if desc == None:
desc = ''
else:
desc = escape(desc)
@@ -2163,7 +2124,7 @@ class docBuilder:
for field in self.idx.structs[name].info:
desc = field[2]
self.indexString(name, desc)
if desc is None:
if desc == None:
desc = ''
else:
desc = escape(desc)
@@ -2181,7 +2142,7 @@ class docBuilder:
name, self.modulename_file(id.header), id.info))
try:
desc = id.extra
if desc is not None and desc != "":
if desc != None and desc != "":
output.write(">\n <info><![CDATA[%s]]></info>\n" % (desc))
output.write(" </typedef>\n")
else:
@@ -2191,7 +2152,7 @@ class docBuilder:
def serialize_variable(self, output, name):
id = self.idx.variables[name]
if id.info is not None:
if id.info != None:
output.write(" <variable name='%s' file='%s' type='%s'/>\n" % (
name, self.modulename_file(id.header), id.info))
else:
@@ -2209,7 +2170,7 @@ class docBuilder:
#
# Processing of conditionals modified by Bill 1/1/05
#
if id.conditionals is not None:
if id.conditionals != None:
apstr = ""
for cond in id.conditionals:
if apstr != "":
@@ -2220,10 +2181,10 @@ class docBuilder:
(ret, params, desc) = id.info
output.write(" <info><![CDATA[%s]]></info>\n" % (desc))
self.indexString(name, desc)
if ret[0] is not None:
if ret[0] != None:
if ret[0] == "void":
output.write(" <return type='void'/>\n")
elif (ret[1] is None or ret[1] == '') and not ignored_functions.has_key(name):
elif (ret[1] == None or ret[1] == '') and not ignored_functions.has_key(name):
self.error("Missing documentation for return of function `%s'" % name)
else:
output.write(" <return type='%s' info='%s'/>\n" % (
@@ -2232,7 +2193,7 @@ class docBuilder:
for param in params:
if param[0] == 'void':
continue
if (param[2] is None or param[2] == ''):
if (param[2] == None or param[2] == ''):
if ignored_functions.has_key(name):
output.write(" <arg name='%s' type='%s' info=''/>\n" % (param[1], param[0]))
else:
@@ -2249,7 +2210,7 @@ class docBuilder:
module = self.modulename_file(file)
output.write(" <file name='%s'>\n" % (module))
dict = self.headers[file]
if dict.info is not None:
if dict.info != None:
for data in ('Summary', 'Description', 'Author'):
try:
output.write(" <%s>%s</%s>\n" % (
@@ -2382,12 +2343,12 @@ class docBuilder:
ids.sort()
for id in ids:
if id[0] != letter:
if letter is not None:
if letter != None:
output.write(" </letter>\n")
letter = id[0]
output.write(" <letter name='%s'>\n" % (letter))
output.write(" <ref name='%s'/>\n" % (id))
if letter is not None:
if letter != None:
output.write(" </letter>\n")
def serialize_xrefs_references(self, output):
@@ -2413,8 +2374,8 @@ class docBuilder:
if len(index[id]) > 30:
continue
if id[0] != letter:
if letter is None or count > 200:
if letter is not None:
if letter == None or count > 200:
if letter != None:
output.write(" </letter>\n")
output.write(" </chunk>\n")
count = 0
@@ -2422,7 +2383,7 @@ class docBuilder:
output.write(" <chunk name='chunk%s'>\n" % (chunk))
first_letter = id[0]
chunk = chunk + 1
elif letter is not None:
elif letter != None:
output.write(" </letter>\n")
letter = id[0]
output.write(" <letter name='%s'>\n" % (letter))
@@ -2437,7 +2398,7 @@ class docBuilder:
output.write(" <ref name='%s'/>\n" % (token))
count = count + 1
output.write(" </word>\n")
if letter is not None:
if letter != None:
output.write(" </letter>\n")
output.write(" </chunk>\n")
if count != 0:

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Applications using <strong>libvirt</strong></h1>
@@ -103,13 +101,6 @@
in a virtual machine. It prints out a list of facts about the
virtual machine, derived from heuristics.
</dd>
<dt><a href="http://sourceware.org/systemtap/">stap</a></dt>
<dd>
SystemTap is a tool used to gather rich information about a running
system through the use of scripts. Starting from v2.4, the front-end
application stap can use libvirt to gather data within virtual
machines.
</dd>
</dl>
<h2><a name="configmgmt">Configuration Management</a></h2>
@@ -211,13 +202,6 @@
<h2><a name="iaas">Infrastructure as a Service (IaaS)</a></h2>
<dl>
<dt><a href="http://cc1.ifj.edu.pl">Cracow Cloud One</a></dt>
<dd>The CC1 system provides a complete solution for Private
Cloud Computing. An intuitive web access interface with an
administration module and simple installation procedure make
it easy to benefit from private Cloud Computing technology.
</dd>
<dt><a href="http://www.emotivecloud.net">EMOTIVE Cloud</a></dt>
<dd>The EMOTIVE (Elastic Management Of Tasks In Virtualized
Environments) middleware allows executing tasks and providing
@@ -251,15 +235,6 @@
integrates libvirt for VM monitoring, live migration, and life-cycle
management.
</dd>
<dt><a href="http://www.openstack.org">OpenStack</a></dt>
<dd>
OpenStack is a "cloud operating system" usable for both public
and private clouds. Its various parts take care of compute,
storage and networking resources and interface with the user
using a dashboard. Compute part uses libvirt to manage VM
life-cycle, monitoring and so on.
</dd>
</dl>
<h2><a name="libraries">Libraries</a></h2>
@@ -277,24 +252,19 @@
host, and there is a subproject to allow merging changes into the
Windows Registry in Windows guests.
</dd>
<dt><a href="http://sandbox.libvirt.org">libvirt-sandbox</a></dt>
<dd>
A library and command line tools for simplifying the creation of
application sandboxes using virtualization technology. It currently
supports either KVM, QEMU or LXC as backends. Integration with
systemd facilitates sandboxing of system services like apache.
</dd>
<dt><a href="https://github.com/ohadlevy/virt#readme">Ruby
Libvirt Object bindings</a></dt>
<dd>
Allows using simple ruby objects to manipulate
hypervisors, guests, storage, network etc. It is
based on top of
the <a href="http://libvirt.org/ruby">native ruby bindings</a>.
</dd>
</dl>
<dl>
<dt><a href="https://github.com/ohadlevy/virt#readme">Ruby
Libvirt Object bindings</a></dt>
<dd>
Allows using simple ruby objects to manipulate
hypervisors, guests, storage, network etc. It is
based on top of
the <a href="http://libvirt.org/ruby">native ruby
bindings</a>.
</dd>
</dl>
<h2><a name="livecd">LiveCD / Appliances</a></h2>
<dl>
@@ -370,7 +340,6 @@
<li>Shows you Systems Inventory (based on Facter) and
provides real time information about hosts status based on
Puppet reports.</li>
</ul>
</dd>
</dl>
@@ -393,15 +362,6 @@
with FreeIPA for Kerberos authentication, and in the future,
certificate management.
</dd>
<dt><a href="http://ispsystem.com/en/software/vmmanager">VMmanager</a></dt>
<dd>
VMmanager is a software solution for virtualization management
that can be used both for hosting virtual machines and
building a cloud. VMmanager can manage not only one server,
but a large cluster of hypervisors. It delivers a number of
functions, such as live migration that allows for load
balancing between cluster nodes, monitoring CPU, memory.
</dd>
</dl>
<h2><a name="mobile">Mobile applications</a></h2>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Domain management architecture</h1>
</body>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1 >libvirt architecture</h1>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1>Network management architecture</h1>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Node device management architecture</h1>
</body>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Storage management architecture</h1>

View File

@@ -1,321 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Audit log</h1>
<ul id="toc"></ul>
<h2><a name="intro">Introduction</a></h2>
<p>
A number of the libvirt virtualization drivers (QEMU/KVM and LXC) include
support for logging details of important operations to the host's audit
subsystem. This provides administrators / auditors with a canonical historical
record of changes to virtual machines' / containers' lifecycle states and
their configuration. On hosts which are running the Linux audit daemon,
the logs will usually end up in <code>/var/log/audit/audit.log</code>
</p>
<h2><a name="config">Configuration</a></h2>
<p>
The libvirt audit integration is enabled by default on any host which has
the Linux audit subsystem active, and disabled otherwise. It is possible
to alter this behaviour in the <code>/etc/libvirt/libvirtd.conf</code>
configuration file, via the <code>audit_level</code> parameter
</p>
<ul>
<li><code>audit_level=0</code> - libvirt auditing is disabled regardless
of host audit subsystem enablement.</li>
<li><code>audit_level=1</code> - libvirt auditing is enabled if the host
audit subsystem is enabled, otherwise it is disabled. This is the
default behaviour.</li>
<li><code>audit_level=2</code> - libvirt auditing is enabled regardless
of host audit subsystem enablement. If the host audit subsystem is
disabled, then libvirtd will refuse to complete startup and exit with
an error.</li>
</ul>
<p>
In addition to have formal messages sent to the audit subsystem it is
possible to tell libvirt to inject messages into its own logging
layer. This will result in messages ending up in the systemd journal
or <code>/var/log/libvirt/libivrtd.log</code> on non-systemd hosts.
This is disabled by default, but can be requested by setting the
<code>audit_logging=1</code> configuration parameter in the same file
mentioned above.
</p>
<h2><a name="types">Message types</a></h2>
<p>
Libvirt defines three core audit message types each of which will
be described below. There are a number of common fields that will
be reported for all message types.
</p>
<dl>
<dt>pid</dt>
<dd>Process ID of the libvirtd daemon generating the audit record.</dd>
<dt>uid</dt>
<dd>User ID of the libvirtd daemon process generating the audit record.</dd>
<dt>subj</dt>
<dd>Security context of the libvirtd daemon process generating the audit record.</dd>
<dt>msg</dt>
<dd>String containing a list of key=value pairs specific to the type of audit record being reported.</dd>
</dl>
<p>
Some fields in the <code>msg</code> string are common to audit records
</p>
<dl>
<dt>virt</dt>
<dd>Type of virtualization driver used. One of <code>qemu</code> or <code>lxc</code></dd>
<dt>vm</dt>
<dd>Host driver unique name of the guest</dd>
<dt>uuid</dt>
<dd>Globally unique identifier for the guest</dd>
<dt>exe</dt>
<dd>Path of the libvirtd daemon</dd>
<dt>hostname</dt>
<dd>Currently unused</dd>
<dt>addr</dt>
<dd>Currently unused</dd>
<dt>terminal</dt>
<dd>Currently unused</dd>
<dt>res</dt>
<dd>Result of the action, either <code>success</code> or <code>failed</code></dd>
</dl>
<h3><a name="typecontrol">VIRT_CONTROL</a></h3>
<p>
Reports change in the lifecycle state of a virtual machine. The <code>msg</code>
field will include the following sub-fields
</p>
<dl>
<dt>op</dt>
<dd>Type of operation performed. One of <code>start</code>, <code>stop</code> or <code>init</code></dd>
<dt>reason</dt>
<dd>The reason which caused the operation to happen</dd>
<dt>vm-pid</dt>
<dd>ID of the primary/leading process associated with the guest</dd>
<dt>init-pid</dt>
<dd>ID of the <code>init</code> process in a container. Only if <code>op=init</code> and <code>virt=lxc</code></dd>
<dt>pid-ns</dt>
<dd>Namespace ID of the <code>init</code> process in a container. Only if <code>op=init</code> and <code>virt=lxc</code></dd>
</dl>
<h3><a name="typemachine">VIRT_MACHINE_ID</a></h3>
<p>
Reports the association of a security context with a guest. The <code>msg</code>
field will include the following sub-fields
</p>
<dl>
<dt>model</dt>
<dd>The security driver type. One of <code>selinux</code> or <code>apparmor</code></dd>
<dt>vm-ctx</dt>
<dd>Security context for the guest process</dd>
<dt>img-ctx</dt>
<dd>Security context for the guest disk images and other assigned host resources</dd>
</dl>
<h3><a name="typeresource">VIRT_RESOURCE</a></h3>
<p>
Reports the usage of a host resource by a guest. The fields include will
vary according to the type of device being reported. When the guest is
initially booted records will be generated for all assigned resources.
If any changes are made to the running guest configuration, for example
hotplug devices, or adjust resources allocation, further records will
be generated.
</p>
<h4><a name="typeresourcevcpu">Virtual CPU</a></h4>
<p>
The <code>msg</code> field will include the following sub-fields
</p>
<dl>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>vcpu</code></dd>
<dt>old-vcpu</dt>
<dd>Original vCPU count, or 0</dd>
<dt>new-vcpu</dt>
<dd>Updated vCPU count</dd>
</dl>
<h4><a name="typeresourcemem">Memory</a></h4>
<p>
The <code>msg</code> field will include the following sub-fields
</p>
<dl>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>mem</code></dd>
<dt>old-mem</dt>
<dd>Original memory size in bytes, or 0</dd>
<dt>new-mem</dt>
<dd>Updated memory size in bytes</dd>
</dl>
<h4><a name="typeresourcedisk">Disk</a></h4>
<p>
The <code>msg</code> field will include the following sub-fields
</p>
<dl>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>disk</code></dd>
<dt>old-disk</dt>
<dd>Original host file or device path acting as the disk backing file</dd>
<dt>new-disk</dt>
<dd>Updated host file or device path acting as the disk backing file</dd>
</dl>
<h4><a name="typeresourcenic">Network interface</a></h4>
<p>
The <code>msg</code> field will include the following sub-fields
</p>
<dl>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>net</code></dd>
<dt>old-net</dt>
<dd>Original MAC address of the guest network interface</dd>
<dt>new-net</dt>
<dd>Updated MAC address of the guest network interface</dd>
</dl>
<p>
If there is a host network interface associated with the guest NIC then
further records may be generated
</p>
<dl>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>net</code></dd>
<dt>net</dt>
<dd>MAC address of the host network interface</dd>
<dt>rdev</dt>
<dd>Name of the host network interface</dd>
</dl>
<h4><a name="typeresourcefs">Filesystem</a></h4>
<p>
The <code>msg</code> field will include the following sub-fields
</p>
<dl>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>fs</code></dd>
<dt>old-fs</dt>
<dd>Original host directory, file or device path backing the filesystem </dd>
<dt>new-fs</dt>
<dd>Updated host directory, file or device path backing the filesystem</dd>
</dl>
<h4><a name="typeresourcehost">Host device</a></h4>
<p>
The <code>msg</code> field will include the following sub-fields
</p>
<dl>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>hostdev</code> or <code>dev</code></dd>
<dt>dev</dt>
<dd>The unique bus identifier of the USB, PCI or SCSI device, if <code>resrc=dev</code></dd>
<dt>disk</dt>
<dd>The path of the block device assigned to the guest, if <code>resrc=hostdev</code></dd>
<dt>chardev</dt>
<dd>The path of the character device assigned to the guest, if <code>resrc=hostdev</code></dd>
</dl>
<h4><a name="typeresourcetpm">TPM</a></h4>
<p>
The <code>msg</code> field will include the following sub-fields
</p>
<dl>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>tpm</code></dd>
<dt>device</dt>
<dd>The path of the host TPM device assigned to the guest</dd>
</dl>
<h4><a name="typeresourcerng">RNG</a></h4>
<p>
The <code>msg</code> field will include the following sub-fields
</p>
<dl>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>rng</code></dd>
<dt>old-rng</dt>
<dd>Original path of the host entropy source for the RNG</dd>
<dt>new-rng</dt>
<dd>Updated path of the host entropy source for the RNG</dd>
</dl>
<h4><a name="typeresourceredir">Redirected device</a></h4>
<p>
The <code>msg</code> field will include the following sub-fields
</p>
<dl>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>redir</code></dd>
<dt>bus</dt>
<dd>The bus type, only <code>usb</code> allowed</dd>
<dt>device</dt>
<dd>The device type, only <code>USB redir</code> allowed</dd>
</dl>
<h4><a name="typeresourcecgroup">Control group</a></h4>
<p>
The <code>msg</code> field will include the following sub-fields
</p>
<dl>
<dt>reason</dt>
<dd>The reason which caused the resource to be assigned to happen</dd>
<dt>resrc</dt>
<dd>The type of resource assigned. Set to <code>cgroup</code></dd>
<dt>cgroup</dt>
<dd>The name of the cgroup controller</dd>
</dl>
</body>
</html>

View File

@@ -1,15 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1>Connection authentication</h1>
<h1 >Authentication &amp; access control</h1>
<p>
When connecting to libvirt, some connections may require client
authentication before allowing use of the APIs. The set of possible
authentication mechanisms is administrator controlled, independent
of applications using libvirt. Once authenticated, libvirt can apply
fine grained <a href="acl.html">access control</a> to the operations
performed by a client.
of applications using libvirt.
</p>
<ul id="toc"></ul>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1 >Bindings for other languages</h1>

View File

@@ -1,24 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1>Bug reporting</h1>
<ul id="toc"></ul>
<h2><a name="security">Security Issues</a></h2>
<p>
If you think that an issue with libvirt may have security
implications, <strong>please do not</strong> publically
report it in the bug tracker, mailing lists, or irc. Libvirt
has <a href="securityprocess.html">a dedicated process for handling (potential) security issues</a>
that should be used instead. So if your issue has security
implications, ignore the rest of this page and follow the
<a href="securityprocess.html">security process</a> instead.
</p>
<h2><a name="bugzilla">Bug Tracking</a></h2>
<p>
@@ -132,7 +119,7 @@
crash, the simplest is to run the program under gdb, reproduce the
steps leading to the crash and then issue a gdb "bt -a" command to
get the stack trace, attach it to the bug. Note that for the
data to be really useful libvirt debug information must be present
data to be really useful libvirt debug informations must be present
for example by installing libvirt debuginfo package on Fedora or
Red Hat Enterprise Linux (with debuginfo-install libvirt) prior
to running gdb.</p>
@@ -147,11 +134,11 @@
<pre> # ps -o etime,pid `pgrep libvirt`
... note the process id from the output
# gdb /usr/sbin/libvirtd
.... some information about gdb and loading debug data
(gdb) attach $the_daemon_process_id
.... some informations about gdb and loading debug data
(gdb) attach $the_damon_process_id
....
(gdb) thread apply all bt
.... information to attach to the bug
.... informations to attach to the bug
(gdb)
</pre>

View File

@@ -33,9 +33,9 @@
<p>
The LXC driver is capable of using the <code>cpuset</code>,
<code>cpu</code>, <code>cpuacct</code>, <code>freezer</code>,
<code>cpu</code>, <code>cpuset</code>, <code>freezer</code>,
<code>memory</code>, <code>blkio</code> and <code>devices</code>
controllers. The <code>cpuacct</code>, <code>devices</code>
controllers. The <code>cpuset</code>, <code>devices</code>
and <code>memory</code> controllers are compulsory. Without
them mounted, no containers can be started. If any of the
other controllers are not mounted, the resource management APIs
@@ -47,121 +47,17 @@
<p>
As of libvirt 1.0.5 or later, the cgroups layout created by libvirt has been
simplified, in order to facilitate the setup of resource control policies by
administrators / management applications. The new layout is based on the concepts
of "partitions" and "consumers". A "consumer" is a cgroup which holds the
processes for a single virtual machine or container. A "partition" is a cgroup
which does not contain any processes, but can have resource controls applied.
A "partition" will have zero or more child directories which may be either
"consumer" or "partition".
</p>
<p>
As of libvirt 1.1.1 or later, the cgroups layout will have some slight
differences when running on a host with systemd 205 or later. The overall
tree structure is the same, but there are some differences in the naming
conventions for the cgroup directories. Thus the following docs split
in two, one describing systemd hosts and the other non-systemd hosts.
</p>
<h3><a name="currentLayoutSystemd">Systemd cgroups integration</a></h3>
<p>
On hosts which use systemd, each consumer maps to a systemd scope unit,
while partitions map to a system slice unit.
</p>
<h4><a name="systemdScope">Systemd scope naming</a></h4>
<p>
The systemd convention is for the scope name of virtual machines / containers
to be of the general format <code>machine-$NAME.scope</code>. Libvirt forms the
<code>$NAME</code> part of this by concatenating the driver type with the name
of the guest, and then escaping any systemd reserved characters.
So for a guest <code>demo</code> running under the <code>lxc</code> driver,
we get a <code>$NAME</code> of <code>lxc-demo</code> which when escaped is
<code>lxc\x2ddemo</code>. So the complete scope name is <code>machine-lxc\x2ddemo.scope</code>.
The scope names map directly to the cgroup directory names.
</p>
<h4><a name="systemdSlice">Systemd slice naming</a></h4>
<p>
The systemd convention for slice naming is that a slice should include the
name of all of its parents prepended on its own name. So for a libvirt
partition <code>/machine/engineering/testing</code>, the slice name will
be <code>machine-engineering-testing.slice</code>. Again the slice names
map directly to the cgroup directory names. Systemd creates three top level
slices by default, <code>system.slice</code> <code>user.slice</code> and
<code>machine.slice</code>. All virtual machines or containers created
by libvirt will be associated with <code>machine.slice</code> by default.
</p>
<h4><a name="systemdLayout">Systemd cgroup layout</a></h4>
<p>
Given this, a possible systemd cgroups layout involving 3 qemu guests,
3 lxc containers and 3 custom child slices, would be:
</p>
<pre>
$ROOT
|
+- system.slice
| |
| +- libvirtd.service
|
+- machine.slice
|
+- machine-qemu\x2dvm1.scope
| |
| +- emulator
| +- vcpu0
| +- vcpu1
|
+- machine-qemu\x2dvm2.scope
| |
| +- emulator
| +- vcpu0
| +- vcpu1
|
+- machine-qemu\x2dvm3.scope
| |
| +- emulator
| +- vcpu0
| +- vcpu1
|
+- machine-engineering.slice
| |
| +- machine-engineering-testing.slice
| | |
| | +- machine-lxc\x2dcontainer1.scope
| |
| +- machine-engineering-production.slice
| |
| +- machine-lxc\x2dcontainer2.scope
|
+- machine-marketing.slice
|
+- machine-lxc\x2dcontainer3.scope
</pre>
<h3><a name="currentLayoutGeneric">Non-systemd cgroups layout</a></h3>
<p>
On hosts which do not use systemd, each consumer has a corresponding cgroup
named <code>$VMNAME.libvirt-{qemu,lxc}</code>. Each consumer is associated
with exactly one partition, which also have a corresponding cgroup usually
named <code>$PARTNAME.partition</code>. The exceptions to this naming rule
are the three top level default partitions, named <code>/system</code> (for
system services), <code>/user</code> (for user login sessions) and
<code>/machine</code> (for virtual machines and containers). By default
every consumer will of course be associated with the <code>/machine</code>
partition.
</p>
<p>
Given this, a possible systemd cgroups layout involving 3 qemu guests,
3 lxc containers and 2 custom child slices, would be:
administrators / management applications. The layout is based on the concepts of
"partitions" and "consumers". Each virtual machine or container is a consumer,
and has a corresponding cgroup named <code>$VMNAME.libvirt-{qemu,lxc}</code>.
Each consumer is associated with exactly one partition, which also have a
corresponding cgroup usually named <code>$PARTNAME.partition</code>. The
exceptions to this naming rule are the three top level default partitions,
named <code>/system</code> (for system services), <code>/user</code> (for
user login sessions) and <code>/machine</code> (for virtual machines and
containers). By default every consumer will of course be associated with
the <code>/machine</code> partition. This leads to a hierarchy that looks
like
</p>
<pre>
@@ -191,21 +87,23 @@ $ROOT
| +- vcpu0
| +- vcpu1
|
+- engineering.partition
| |
| +- testing.partition
| | |
| | +- container1.libvirt-lxc
| |
| +- production.partition
| |
| +- container2.libvirt-lxc
+- container1.libvirt-lxc
|
+- marketing.partition
|
+- container3.libvirt-lxc
+- container2.libvirt-lxc
|
+- container3.libvirt-lxc
</pre>
<p>
The default cgroups layout ensures that, when there is contention for
CPU time, it is shared equally between system services, user sessions
and virtual machines / containers. This prevents virtual machines from
locking the administrator out of the host, or impacting execution of
system services. Conversely, when there is no contention from
system services / user sessions, it is possible for virtual machines
to fully utilize the host CPUs.
</p>
<h2><a name="customPartiton">Using custom partitions</a></h2>
<p>
@@ -228,55 +126,13 @@ $ROOT
...
</pre>
<p>
Note that the partition names in the guest XML are using a
generic naming format, not the low level naming convention
required by the underlying host OS. That is, you should not include
any of the <code>.partition</code> or <code>.slice</code>
suffixes in the XML config. Given a partition name
<code>/machine/production</code>, libvirt will automatically
apply the platform specific translation required to get
<code>/machine/production.partition</code> (non-systemd)
or <code>/machine.slice/machine-production.slice</code>
(systemd) as the underlying cgroup name
</p>
<p>
Libvirt will not auto-create the cgroups directory to back
this partition. In the future, libvirt / virsh will provide
APIs / commands to create custom partitions, but currently
this is left as an exercise for the administrator.
</p>
<p>
<strong>Note:</strong> the ability to place guests in custom
partitions is only available with libvirt &gt;= 1.0.5, using
the new cgroup layout. The legacy cgroups layout described
later in this document did not support customization per guest.
</p>
<h3><a name="createSystemd">Creating custom partitions (systemd)</a></h3>
<p>
Given the XML config above, the admin on a systemd based host would
need to create a unit file <code>/etc/systemd/system/machine-production.slice</code>
</p>
<pre>
# cat &gt; /etc/systemd/system/machine-testing.slice &lt;&lt;EOF
[Unit]
Description=VM testing slice
Before=slices.target
Wants=machine.slice
EOF
# systemctl start machine-testing.slice
</pre>
<h3><a name="createNonSystemd">Creating custom partitions (non-systemd)</a></h3>
<p>
Given the XML config above, the admin on a non-systemd based host
would need to create a cgroup named '/machine/production.partition'
this is left as an exercise for the administrator. For
example, given the XML config above, the admin would need
to create a cgroup named '/machine/production.partition'
</p>
<pre>
@@ -291,6 +147,18 @@ EOF
done
</pre>
<p>
<strong>Note:</strong> the cgroups directory created as a ".partition"
suffix, but the XML config does not require this suffix.
</p>
<p>
<strong>Note:</strong> the ability to place guests in custom
partitions is only available with libvirt &gt;= 1.0.5, using
the new cgroup layout. The legacy cgroups layout described
later did not support customization per guest.
</p>
<h2><a name="resourceAPIs">Resource management APIs/commands</a></h2>
<p>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1><a name="installation">libvirt Installation</a></h1>

View File

@@ -1,23 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1>Contacting the development team</h1>
<ul id="toc"></ul>
<h2><a name="security">Security Issues</a></h2>
<p>
If you think that an issue with libvirt may have security
implications, <strong>please do not</strong> publically
report it in the bug tracker, mailing lists, or irc. Libvirt
has <a href="securityprocess.html">a dedicated process for handling (potential) security issues</a>
that should be used instead. So if your issue has security
implications, ignore the rest of this page and follow the
<a href="securityprocess.html">security process</a> instead.
</p>
<h2><a name="email">Mailing lists</a></h2>
<p>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1>C# API bindings</h1>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Deployment</h1>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1>libvirt Application Development Guide</h1>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Documentation</h1>
</body>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1>Downloads</h1>
@@ -22,9 +21,7 @@
<p>
Once an hour, an automated snapshot is made from the git server
source tree. These snapshots should be usable, but we make no guarantees
about their stability; furthermore, they should NOT be
considered formal releases, and they may have transient security
problems that will not be assigned a CVE.
about their stability:
</p>
<ul>
@@ -32,28 +29,6 @@
<li><a href="http://libvirt.org/sources/libvirt-git-snapshot.tar.gz">libvirt.org HTTP server</a></li>
</ul>
<h2><a name="maintenance">Maintenance releases</a></h2>
<p>
In the git repository are several stable maintenance branches,
matching the
pattern <code>v<i>major</i>.<i>minor</i>.<i>micro</i>-maint</code>;
these branches are forked off the corresponding
<code>v<i>major</i>.<i>minor</i>.<i>micro</i></code> formal
release, and may have further releases of the
form <code>v<i>major</i>.<i>minor</i>.<i>micro</i>.<i>rel</i></code>.
These maintenance branches should only contain bug fixes, and no
new features, backported from the master branch, and are
supported as long as at least one downstream distribution
expresses interest in a given branch. These maintenance
branches are considered during CVE analysis.
</p>
<p>
For more details about contents of maintenance releases, see
<a href="http://wiki.libvirt.org/page/Maintenance_Releases">the
wiki page</a>.
</p>
<h2><a name="git">GIT source repository</a></h2>
<p>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Internal drivers</h1>
@@ -33,7 +31,6 @@
<li><strong><a href="drvhyperv.html">Microsoft Hyper-V</a></strong></li>
<li><strong><a href="drvphyp.html">IBM PowerVM (phyp)</a></strong></li>
<li><strong><a href="drvparallels.html">Parallels</a></strong></li>
<li><strong><a href="drvbhyve.html">Bhyve</a></strong> - The BSD Hypervisor</li>
</ul>
<h2><a name="storage">Storage drivers</a></h2>

View File

@@ -1,83 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Bhyve driver</h1>
<ul id="toc"></ul>
<p>
Bhyve is a FreeBSD hypervisor. It first appeared in FreeBSD 10.0. However, it's
recommended to keep tracking FreeBSD 10-STABLE to make sure all new features
of bhyve are supported.
In order to enable bhyve on your FreeBSD host, you'll need to load the <code>vmm</code>
kernel module. Additionally, <code>if_tap</code> and <code>if_bridge</code> modules
should be loaded for networking support.
</p>
<p>
Additional information on bhyve could be obtained on <a href="http://bhyve.org/">bhyve.org</a>.
</p>
<h2><a name="uri">Connections to the Bhyve driver</a></h2>
<p>
The libvirt bhyve driver is a single-instance privileged driver. Some sample
connection URIs are:
</p>
<pre>
bhyve:///system (local access)
bhyve+unix:///system (local access)
bhyve+ssh://root@example.com/system (remote access, SSH tunnelled)
</pre>
<h2><a name="exconfig">Example guest domain XML configurations</a></h2>
<h3>Example config</h3>
<p>
The bhyve driver in libvirt is in its early stage and under active development. So it supports
only limited number of features bhyve provides. All the supported features could be found
in this sample domain XML.
</p>
<p>
A limitation that is not obvious from this sample domain XML is that currently only a
single network and a single disk device are supported for each domain (as PCI slot allocation code
in libvirt bhyve driver is yet to be implemented).
</p>
<pre>
&lt;domain type='bhyve'&gt;
&lt;name&gt;bhyve&lt;/name&gt;
&lt;uuid&gt;df3be7e7-a104-11e3-aeb0-50e5492bd3dc&lt;/uuid&gt;
&lt;memory&gt;219136&lt;/memory&gt;
&lt;currentMemory&gt;219136&lt;/currentMemory&gt;
&lt;vcpu&gt;1&lt;/vcpu&gt;
&lt;os&gt;
&lt;type&gt;hvm&lt;/type&gt;
&lt;/os&gt;
&lt;features&gt;
&lt;apic/&gt;
&lt;acpi/&gt;
&lt;/features&gt;
&lt;clock offset='utc'/&gt;
&lt;on_poweroff&gt;destroy&lt;/on_poweroff&gt;
&lt;on_reboot&gt;restart&lt;/on_reboot&gt;
&lt;on_crash&gt;destroy&lt;/on_crash&gt;
&lt;devices&gt;
&lt;disk type='file'&gt;
&lt;driver name='file' type='raw'/&gt;
&lt;source file='/path/to/bhyve_freebsd.img'/&gt;
&lt;target dev='hda' bus='sata'/&gt;
&lt;/disk&gt;
&lt;interface type='bridge'&gt;
&lt;model type='virtio'/&gt;
&lt;source bridge="virbr0"/&gt;
&lt;/interface&gt;
&lt;/devices&gt;
&lt;/domain&gt;
</pre>
</body>
</html>

View File

@@ -1,7 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<html><body>
<h1>VMware ESX hypervisor driver</h1>
<ul id="toc"></ul>
<p>

View File

@@ -1,7 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<html><body>
<h1>Microsoft Hyper-V hypervisor driver</h1>
<ul id="toc"></ul>
<p>

View File

@@ -1,98 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>LXC container driver</h1>
<ul id="toc"></ul>
<p>
The libvirt LXC driver manages "Linux Containers". At their simplest, containers
can just be thought of as a collection of processes, separated from the main
host processes via a set of resource namespaces and constrained via control
groups resource tunables. The libvirt LXC driver has no dependency on the LXC
userspace tools hosted on sourceforge.net. It directly utilizes the relevant
kernel features to build the container environment. This allows for sharing
of many libvirt technologies across both the QEMU/KVM and LXC drivers. In
particular sVirt for mandatory access control, auditing of operations,
integration with control groups and many other features.
The libvirt LXC driver manages "Linux Containers". Containers are sets of processes
with private namespaces which can (but don't always) look like separate machines, but
do not have their own OS. Here are two example configurations. The first is a very
light-weight "application container" which does not have its own root image.
</p>
<h2><a name="cgroups">Control groups Requirements</a></h2>
<h2><a name="project">Project Links</a></h2>
<ul>
<li>
The <a href="http://lxc.sourceforge.net/">LXC</a> Linux
container system
</li>
</ul>
<h2>Cgroups Requirements</h2>
<p>
In order to control the resource usage of processes inside containers, the
libvirt LXC driver requires that certain cgroups controllers are mounted on
the host OS. The minimum required controllers are 'cpuacct', 'memory' and
'devices', while recommended extra controllers are 'cpu', 'freezer' and
'blkio'. Libvirt will not mount the cgroups filesystem itself, leaving
this up to the init system to take care of. Systemd will do the right thing
in this respect, while for other init systems the <code>cgconfig</code>
init service will be required. For further information, consult the general
libvirt <a href="cgroups.html">cgroups documentation</a>.
</p>
<h2><a name="namespaces">Namespace requirements</a></h2>
<p>
In order to separate processes inside a container from those in the
primary "host" OS environment, the libvirt LXC driver requires that
certain kernel namespaces are compiled in. Libvirt currently requires
the 'mount', 'ipc', 'pid', and 'uts' namespaces to be available. If
separate network interfaces are desired, then the 'net' namespace is
required. If the guest configuration declares a
<a href="formatdomain.html#elementsOSContainer">UID or GID mapping</a>,
the 'user' namespace will be enabled to apply these. <strong>A suitably
configured UID/GID mapping is a pre-requisite to making containers
secure, in the absence of sVirt confinement.</strong>
</p>
<h2><a name="init">Default container setup</a></h2>
<h3><a name="cliargs">Command line arguments</a></h3>
<p>
When the container "init" process is started, it will typically
not be given any command line arguments (eg the equivalent of
the bootloader args visible in <code>/proc/cmdline</code>). If
any arguments are desired, then must be explicitly set in the
container XML configuration via one or more <code>initarg</code>
elements. For example, to run <code>systemd --unit emergency.service</code>
would use the following XML
The libvirt LXC driver requires that certain cgroups controllers are
mounted on the host OS. The minimum required controllers are 'cpuacct',
'memory' and 'devices', while recommended extra controllers are
'cpu', 'freezer' and 'blkio'. The /etc/cgconfig.conf &amp; cgconfig
init service used to mount cgroups at host boot time. To manually
mount them use:
</p>
<pre>
&lt;os&gt;
&lt;type arch='x86_64'&gt;exe&lt;/type&gt;
&lt;init&gt;/bin/systemd&lt;/init&gt;
&lt;initarg&gt;--unit&lt;/initarg&gt;
&lt;initarg&gt;emergency.service&lt;/initarg&gt;
&lt;/os&gt;
# mount -t cgroup cgroup /dev/cgroup -o cpuacct,memory,devices,cpu,freezer,blkio
</pre>
<h3><a name="envvars">Environment variables</a></h3>
<p>
NB, the blkio controller in some kernels will not allow creation of nested
sub-directories which will prevent correct operation of the libvirt LXC
driver. On such kernels, it may be necessary to unmount the blkio controller.
</p>
<h2>Environment setup for the container init</h2>
<p>
When the container "init" process is started, it will be given several useful
environment variables. The following standard environment variables are mandated
by <a href="http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface">systemd container interface</a>
to be provided by all container technologies on Linux.
</p>
<dl>
<dt>container</dt>
<dd>The fixed string <code>libvirt-lxc</code> to identify libvirt as the creator</dd>
<dt>container_uuid</dt>
<dd>The UUID assigned to the container by libvirt</dd>
<dt>PATH</dt>
<dd>The fixed string <code>/bin:/usr/bin</code></dd>
<dt>TERM</dt>
<dd>The fixed string <code>linux</code></dd>
</dl>
<p>
In addition to the standard variables, the following libvirt specific
environment variables are also provided
environment variables.
</p>
<dl>
@@ -101,381 +52,9 @@ environment variables are also provided
<dt>LIBVIRT_LXC_UUID</dt>
<dd>The UUID assigned to the container by libvirt</dd>
<dt>LIBVIRT_LXC_CMDLINE</dt>
<dd>The unparsed command line arguments specified in the container configuration.
Use of this is discouraged, in favour of passing arguments directly to the
container init process via the <code>initarg</code> config element.</dd>
<dd>The unparsed command line arguments specified in the container configuration</dd>
</dl>
<h3><a name="fsmounts">Filesystem mounts</a></h3>
<p>
In the absence of any explicit configuration, the container will
inherit the host OS filesystem mounts. A number of mount points will
be made read only, or re-mounted with new instances to provide
container specific data. The following special mounts are setup
by libvirt
</p>
<ul>
<li><code>/dev</code> a new "tmpfs" pre-populated with authorized device nodes</li>
<li><code>/dev/pts</code> a new private "devpts" instance for console devices</li>
<li><code>/sys</code> the host "sysfs" instance remounted read-only</li>
<li><code>/proc</code> a new instance of the "proc" filesystem</li>
<li><code>/proc/sys</code> the host "/proc/sys" bind-mounted read-only</li>
<li><code>/sys/fs/selinux</code> the host "selinux" instance remounted read-only</li>
<li><code>/sys/fs/cgroup/NNNN</code> the host cgroups controllers bind-mounted to
only expose the sub-tree associated with the container</li>
<li><code>/proc/meminfo</code> a FUSE backed file reflecting memory limits of the container</li>
</ul>
<h3><a name="devnodes">Device nodes</a></h3>
<p>
The container init process will be started with <code>CAP_MKNOD</code>
capability removed and blocked from re-acquiring it. As such it will
not be able to create any device nodes in <code>/dev</code> or anywhere
else in its filesystems. Libvirt itself will take care of pre-populating
the <code>/dev</code> filesystem with any devices that the container
is authorized to use. The current devices that will be made available
to all containers are
</p>
<ul>
<li><code>/dev/zero</code></li>
<li><code>/dev/null</code></li>
<li><code>/dev/full</code></li>
<li><code>/dev/random</code></li>
<li><code>/dev/urandom</code></li>
<li><code>/dev/stdin</code> symlinked to <code>/proc/self/fd/0</code></li>
<li><code>/dev/stdout</code> symlinked to <code>/proc/self/fd/1</code></li>
<li><code>/dev/stderr</code> symlinked to <code>/proc/self/fd/2</code></li>
<li><code>/dev/fd</code> symlinked to <code>/proc/self/fd</code></li>
<li><code>/dev/ptmx</code> symlinked to <code>/dev/pts/ptmx</code></li>
<li><code>/dev/console</code> symlinked to <code>/dev/pts/0</code></li>
</ul>
<p>
In addition, for every console defined in the guest configuration,
a symlink will be created from <code>/dev/ttyN</code> symlinked to
the corresponding <code>/dev/pts/M</code> pseudo TTY device. The
first console will be <code>/dev/tty1</code>, with further consoles
numbered incrementally from there.
</p>
<p>
Since /dev/ttyN and /dev/console are linked to the pts devices. The
tty device of login program is pts device. the pam module securetty
may prevent root user from logging in container. If you want root
user to log in container successfully, add the pts device to the file
/etc/securetty of container.
</p>
<p>
Further block or character devices will be made available to containers
depending on their configuration.
</p>
<h2><a name="security">Security considerations</a></h2>
<p>
The libvirt LXC driver is fairly flexible in how it can be configured,
and as such does not enforce a requirement for strict security
separation between a container and the host. This allows it to be used
in scenarios where only resource control capabilities are important,
and resource sharing is desired. Applications wishing to ensure secure
isolation between a container and the host must ensure that they are
writing a suitable configuration.
</p>
<h3><a name="securenetworking">Network isolation</a></h3>
<p>
If the guest configuration does not list any network interfaces,
the <code>network</code> namespace will not be activated, and thus
the container will see all the host's network interfaces. This will
allow apps in the container to bind to/connect from TCP/UDP addresses
and ports from the host OS. It also allows applications to access
UNIX domain sockets associated with the host OS, which are in the
abstract namespace. If access to UNIX domains sockets in the abstract
namespace is not wanted, then applications should set the
<code>&lt;privnet/&gt;</code> flag in the
<code>&lt;features&gt;....&lt;/features&gt;</code> element.
</p>
<h3><a name="securefs">Filesystem isolation</a></h3>
<p>
If the guest configuration does not list any filesystems, then
the container will be set up with a root filesystem that matches
the host's root filesystem. As noted earlier, only a few locations
such as <code>/dev</code>, <code>/proc</code> and <code>/sys</code>
will be altered. This means that, in the absence of restrictions
from sVirt, a process running as user/group N:M inside the container
will be able to access almost exactly the same files as a process
running as user/group N:M in the host.
</p>
<p>
There are multiple options for restricting this. It is possible to
simply map the existing root filesystem through to the container in
read-only mode. Alternatively a completely separate root filesystem
can be configured for the guest. In both cases, further sub-mounts
can be applied to customize the content that is made visible. Note
that in the absence of sVirt controls, it is still possible for the
root user in a container to unmount any sub-mounts applied. The user
namespace feature can also be used to restrict access to files based
on the UID/GID mappings.
</p>
<p>
Sharing the host filesystem tree, also allows applications to access
UNIX domains sockets associated with the host OS, which are in the
filesystem namespaces. It should be noted that a number of init
systems including at least <code>systemd</code> and <code>upstart</code>
have UNIX domain socket which are used to control their operation.
Thus, if the directory/filesystem holding their UNIX domain socket is
exposed to the container, it will be possible for a user in the container
to invoke operations on the init service in the same way it could if
outside the container. This also applies to other applications in the
host which use UNIX domain sockets in the filesystem, such as DBus,
Libvirtd, and many more. If this is not desired, then applications
should either specify the UID/GID mapping in the configuration to
enable user namespaces and thus block access to the UNIX domain socket
based on permissions, or should ensure the relevant directories have
a bind mount to hide them. This is particularly important for the
<code>/run</code> or <code>/var/run</code> directories.
</p>
<h3><a name="secureusers">User and group isolation</a></h3>
<p>
If the guest configuration does not list any ID mapping, then the
user and group IDs used inside the container will match those used
outside the container. In addition, the capabilities associated with
a process in the container will infer the same privileges they would
for a process in the host. This has obvious implications for security,
since a root user inside the container will be able to access any
file owned by root that is visible to the container, and perform more
or less any privileged kernel operation. In the absence of additional
protection from sVirt, this means that the root user inside a container
is effectively as powerful as the root user in the host. There is no
security isolation of the root user.
</p>
<p>
The ID mapping facility was introduced to allow for stricter control
over the privileges of users inside the container. It allows apps to
define rules such as "user ID 0 in the container maps to user ID 1000
in the host". In addition the privileges associated with capabilities
are somewhat reduced so that they cannot be used to escape from the
container environment. A full description of user namespaces is outside
the scope of this document, however LWN has
<a href="https://lwn.net/Articles/532593/">a good write-up on the topic</a>.
From the libvirt point of view, the key thing to remember is that defining
an ID mapping for users and groups in the container XML configuration
causes libvirt to activate the user namespace feature.
</p>
<h2><a name="activation">Systemd Socket Activation Integration</a></h2>
<p>
The libvirt LXC driver provides the ability to pass across pre-opened file
descriptors when starting LXC guests. This allows for libvirt LXC to support
systemd's <a href="http://0pointer.de/blog/projects/socket-activated-containers.html">socket
activation capability</a>, where an incoming client connection
in the host OS will trigger the startup of a container, which runs another
copy of systemd which gets passed the server socket, and then activates the
actual service handler in the container.
</p>
<p>
Let us assume that you already have a LXC guest created, running
a systemd instance as PID 1 inside the container, which has an
SSHD service configured. The goal is to automatically activate
the container when the first SSH connection is made. The first
step is to create a couple of unit files for the host OS systemd
instance. The <code>/etc/systemd/system/mycontainer.service</code>
unit file specifies how systemd will start the libvirt LXC container
</p>
<pre>
[Unit]
Description=My little container
[Service]
ExecStart=/usr/bin/virsh -c lxc:/// start --pass-fds 3 mycontainer
ExecStop=/usr/bin/virsh -c lxc:/// destroy mycontainer
Type=oneshot
RemainAfterExit=yes
KillMode=none
</pre>
<p>
The <code>--pass-fds 3</code> argument specifies that the file
descriptor number 3 that <code>virsh</code> inherits from systemd,
is to be passed into the container. Since <code>virsh</code> will
exit immediately after starting the container, the <code>RemainAfterExit</code>
and <code>KillMode</code> settings must be altered from their defaults.
</p>
<p>
Next, the <code>/etc/systemd/system/mycontainer.socket</code> unit
file is created to get the host systemd to listen on port 23 for
TCP connections. When this unit file is activated by the first
incoming connection, it will cause the <code>mycontainer.service</code>
unit to be activated with the FD corresponding to the listening TCP
socket passed in as FD 3.
</p>
<pre>
[Unit]
Description=The SSH socket of my little container
[Socket]
ListenStream=23
</pre>
<p>
Port 23 was picked here so that the container doesn't conflict
with the host's SSH which is on the normal port 22. That's it
in terms of host side configuration.
</p>
<p>
Inside the container, the <code>/etc/systemd/system/sshd.socket</code>
unit file must be created
</p>
<pre>
[Unit]
Description=SSH Socket for Per-Connection Servers
[Socket]
ListenStream=23
Accept=yes
</pre>
<p>
The <code>ListenStream</code> value listed in this unit file, must
match the value used in the host file. When systemd in the container
receives the pre-opened FD from libvirt during container startup, it
looks at the <code>ListenStream</code> values to figure out which
FD to give to which service. The actual service to start is defined
by a correspondingly named <code>/etc/systemd/system/sshd@.service</code>
</p>
<pre>
[Unit]
Description=SSH Per-Connection Server for %I
[Service]
ExecStart=-/usr/sbin/sshd -i
StandardInput=socket
</pre>
<p>
Finally, make sure this SSH service is set to start on boot of the container,
by running the following command inside the container:
</p>
<pre>
# mkdir -p /etc/systemd/system/sockets.target.wants/
# ln -s /etc/systemd/system/sshd.socket /etc/systemd/system/sockets.target.wants/
</pre>
<p>
This example shows how to activate the container based on an incoming
SSH connection. If the container was also configured to have an httpd
service, it may be desirable to activate it upon either an httpd or a
sshd connection attempt. In this case, the <code>mycontainer.socket</code>
file in the host would simply list multiple socket ports. Inside the
container a separate <code>xxxxx.socket</code> file would need to be
created for each service, with a corresponding <code>ListenStream</code>
value set.
</p>
<!--
<h2>Container configuration</h2>
<h3>Init process</h3>
<h3>Console devices</h3>
<h3>Filesystem devices</h3>
<h3>Disk devices</h3>
<h3>Block devices</h3>
<h3>USB devices</h3>
<h3>Character devices</h3>
<h3>Network devices</h3>
-->
<h2>Container security</h2>
<h3>sVirt SELinux</h3>
<p>
In the absence of the "user" namespace being used, containers cannot
be considered secure against exploits of the host OS. The sVirt SELinux
driver provides a way to secure containers even when the "user" namespace
is not used. The cost is that writing a policy to allow execution of
arbitrary OS is not practical. The SELinux sVirt policy is typically
tailored to work with an simpler application confinement use case,
as provided by the "libvirt-sandbox" project.
</p>
<h3>Auditing</h3>
<p>
The LXC driver is integrated with libvirt's auditing subsystem, which
causes audit messages to be logged whenever there is an operation
performed against a container which has impact on host resources.
So for example, start/stop, device hotplug will all log audit messages
providing details about what action occurred and any resources
associated with it. There are the following 3 types of audit messages
</p>
<ul>
<li><code>VIRT_MACHINE_ID</code> - details of the SELinux process and
image security labels assigned to the container.</li>
<li><code>VIRT_CONTROL</code> - details of an action / operation
performed against a container. There are the following types of
operation
<ul>
<li><code>op=start</code> - a container has been started. Provides
the machine name, uuid and PID of the <code>libvirt_lxc</code>
controller process</li>
<li><code>op=init</code> - the init PID of the container has been
started. Provides the machine name, uuid and PID of the
<code>libvirt_lxc</code> controller process and PID of the
init process (in the host PID namespace)</li>
<li><code>op=stop</code> - a container has been stopped. Provides
the machine name, uuid</li>
</ul>
</li>
<li><code>VIRT_RESOURCE</code> - details of a host resource
associated with a container action.</li>
</ul>
<h3>Device access</h3>
<p>
All containers are launched with the CAP_MKNOD capability cleared
and removed from the bounding set. Libvirt will ensure that the
/dev filesystem is pre-populated with all devices that a container
is allowed to use. In addition, the cgroup "device" controller is
configured to block read/write/mknod from all devices except those
that a container is authorized to use.
</p>
<h2><a name="exconfig">Example configurations</a></h2>
<h3>Example config version 1</h3>
<p></p>
@@ -540,199 +119,21 @@ debootstrap, whatever) under /opt/vm-1-root:
&lt;/domain&gt;
</pre>
<h2><a name="usage">Container usage / management</a></h2>
<p>
As with any libvirt virtualization driver, LXC containers can be
managed via a wide variety of libvirt based tools. At the lowest
level the <code>virsh</code> command can be used to perform many
tasks, by passing the <code>-c lxc:///</code> argument. As an
alternative to repeating the URI with every command, the <code>LIBVIRT_DEFAULT_URI</code>
environment variable can be set to <code>lxc:///</code>. The
examples that follow outline some common operations with virsh
and LXC. For further details about usage of virsh consult its
manual page.
</p>
<h3><a name="usageSave">Defining (saving) container configuration</a></h3>
<p>
The <code>virsh define</code> command takes an XML configuration
document and loads it into libvirt, saving the configuration on disk
</p>
In both cases, you can define and start a container using:</p>
<pre>
# virsh -c lxc:/// define myguest.xml
virsh --connect lxc:/// define v1.xml
virsh --connect lxc:/// start vm1
</pre>
<h3><a name="usageView">Viewing container configuration</a></h3>
<p>
The <code>virsh dumpxml</code> command can be used to view the
current XML configuration of a container. By default the XML
output reflects the current state of the container. If the
container is running, it is possible to explicitly request the
persistent configuration, instead of the current live configuration
using the <code>--inactive</code> flag
</p>
and then get a console using:
<pre>
# virsh -c lxc:/// dumpxml myguest
virsh --connect lxc:/// console vm1
</pre>
<h3><a name="usageStart">Starting containers</a></h3>
<p>
The <code>virsh start</code> command can be used to start a
container from a previously defined persistent configuration
<p>Now doing 'ps -ef' will only show processes in the container, for
instance. You can undefine it using
</p>
<pre>
# virsh -c lxc:/// start myguest
virsh --connect lxc:/// undefine vm1
</pre>
<p>
It is also possible to start so called "transient" containers,
which do not require a persistent configuration to be saved
by libvirt, using the <code>virsh create</code> command.
</p>
<pre>
# virsh -c lxc:/// create myguest.xml
</pre>
<h3><a name="usageStop">Stopping containers</a></h3>
<p>
The <code>virsh shutdown</code> command can be used
to request a graceful shutdown of the container. By default
this command will first attempt to send a message to the
init process via the <code>/dev/initctl</code> device node.
If no such device node exists, then it will send SIGTERM
to PID 1 inside the container.
</p>
<pre>
# virsh -c lxc:/// shutdown myguest
</pre>
<p>
If the container does not respond to the graceful shutdown
request, it can be forcibly stopped using the <code>virsh destroy</code>
</p>
<pre>
# virsh -c lxc:/// destroy myguest
</pre>
<h3><a name="usageReboot">Rebooting a container</a></h3>
<p>
The <code>virsh reboot</code> command can be used
to request a graceful shutdown of the container. By default
this command will first attempt to send a message to the
init process via the <code>/dev/initctl</code> device node.
If no such device node exists, then it will send SIGHUP
to PID 1 inside the container.
</p>
<pre>
# virsh -c lxc:/// reboot myguest
</pre>
<h3><a name="usageDelete">Undefining (deleting) a container configuration</a></h3>
<p>
The <code>virsh undefine</code> command can be used to delete the
persistent configuration of a container. If the guest is currently
running, this will turn it into a "transient" guest.
</p>
<pre>
# virsh -c lxc:/// undefine myguest
</pre>
<h3><a name="usageConnect">Connecting to a container console</a></h3>
<p>
The <code>virsh console</code> command can be used to connect
to the text console associated with a container.
</p>
<pre>
# virsh -c lxc:/// console myguest
</pre>
<p>
If the container has been configured with multiple console devices,
then the <code>--devname</code> argument can be used to choose the
console to connect to.
In LXC, multiple consoles will be named
as 'console0', 'console1', 'console2', etc.
</p>
<pre>
# virsh -c lxc:/// console myguest --devname console1
</pre>
<h3><a name="usageEnter">Running commands in a container</a></h3>
<p>
The <code>virsh lxc-enter-namespace</code> command can be used
to enter the namespaces and security context of a container
and then execute an arbitrary command.
</p>
<pre>
# virsh -c lxc:/// lxc-enter-namespace myguest -- /bin/ls -al /dev
</pre>
<h3><a name="usageTop">Monitoring container utilization</a></h3>
<p>
The <code>virt-top</code> command can be used to monitor the
activity and resource utilization of all containers on a
host
</p>
<pre>
# virt-top -c lxc:///
</pre>
<h3><a name="usageConvert">Converting LXC container configuration</a></h3>
<p>
The <code>virsh 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 <tt>lxc.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 <tt>lxc.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>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html> <!-- -*- html -*- -->
<body>
<h1>OpenVZ container driver</h1>

View File

@@ -1,7 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<html><body>
<h1>Parallels Cloud Server driver</h1>
<ul id="toc"></ul>
<p>

View File

@@ -1,7 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<html><body>
<h1>IBM PowerVM hypervisor driver (phyp)</h1>
<ul id="toc"></ul>
<p>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>KVM/QEMU hypervisor driver</h1>
@@ -19,7 +17,6 @@
<li>
The <a href="http://www.linux-kvm.org/">KVM</a> Linux
hypervisor
</li>
<li>
The <a href="http://wiki.qemu.org/Index.html">QEMU</a> emulator
</li>
@@ -560,7 +557,6 @@ $ virsh domxml-to-native qemu-argv demo.xml
possible to add an element <code>&lt;qemu:commandline&gt;</code>
under <code>driver</code>, with the following sub-elements
repeated as often as needed:
</p>
<dl>
<dt><code>qemu:arg</code></dt>
<dd>Add an additional command-line argument to the qemu
@@ -573,6 +569,7 @@ $ virsh domxml-to-native qemu-argv demo.xml
pair recorded in the attributes <code>name</code>
and optional <code>value</code>.</dd>
</dl>
<p>Example:</p><pre>
&lt;domain type='qemu' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'&gt;
&lt;name&gt;QEmu-fedora-i686&lt;/name&gt;

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Remote management driver</h1>
</body>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Test "mock" driver</h1>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>User Mode Linux driver</h1>
@@ -65,7 +63,7 @@ uml+ssh://root@example.com/system (remote access, SSH tunnelled)
</p>
<p>
Once booted the primary console is connected to a PTY, and
Once booted the primary console is connected toa PTY, and
thus accessible with "virsh console" or equivalent tools
</p>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>VirtualBox hypervisor driver</h1>
<p>
@@ -31,18 +29,6 @@ vbox+tcp://user@example.com/session (remote access, SASl/Kerberos)
vbox+ssh://user@example.com/session (remote access, SSH tunnelled)
</pre>
<p>
<strong>NOTE: as of libvirt 1.0.6, the VirtualBox driver will always
run inside the libvirtd daemon, instead of being built-in to the
libvirt.so library directly. This change was required due to the
fact that VirtualBox code is LGPLv2-only licensed, which is not
compatible with the libvirt.so license of LGPLv2-or-later. The
daemon will be auto-started when the first connection to VirtualBox
is requested. This change also means that it will not be possible
to use VirtualBox URIs on the Windows platform, until additional
work is completed to get the libvirtd daemon working there.</strong>
</p>
<h2><a name="xmlconfig">Example domain XML config</a></h2>
<pre>

View File

@@ -1,12 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>VMware Workstation / Player / Fusion hypervisors driver</h1>
<h1>VMware Workstation / Player hypervisors driver</h1>
<p>
The libvirt VMware driver should be able to manage any Workstation,
Player, Fusion version supported by the VMware VIX API. See the
compatibility list
The libvirt VMware Workstation driver should be able to manage any Workstation and
Player version supported by the VMware VIX API. See the compatibility list
<a href="http://www.vmware.com/support/developer/vix-api/vix110_reference/">here</a>.
</p>
<p>
@@ -22,22 +19,17 @@
The <a href="http://www.vmware.com/">VMware Workstation and
Player</a> hypervisors
</li>
<li>
The <a href="http://www.vmware.com/fusion">VMware Fusion</a>
hypervisor
</li>
</ul>
<h2>Connections to VMware driver</h2>
<p>
The libvirt VMware driver provides per-user drivers (the "session" instance).
Three uris are available:
Two uris are available:
</p>
<ul>
<li>"vmwareplayer" for VMware Player</li>
<li>"vmwarews" for VMware Workstation</li>
<li>"vmwarefusion" for VMware Fusion</li>
</ul>
<p>
Some example connection URIs for the driver are:
@@ -46,7 +38,6 @@
<pre>
vmwareplayer:///session (local access to VMware Player per-user instance)
vmwarews:///session (local access to VMware Workstation per-user instance)
vmwarefusion:///session (local access to VMware Fusion per-user instance)
vmwarews+tcp://user@example.com/session (remote access to VMware Workstation, SASl/Kerberos)
vmwarews+ssh://user@example.com/session (remote access to VMware Workstation, SSH tunnelled)
</pre>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Xen hypervisor driver</h1>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1 >Handling of errors</h1>
<p>The main goals of libvirt when it comes to error handling are:</p>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1 >Firewall and network filtering in libvirt</h1>
<p>There are three pieces of libvirt functionality which do network
@@ -142,7 +141,7 @@ MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24</pre>
<p><a href="http://www.dmtf.org/standards/cim/cim_schema_v2230/CIM_Network.pdf">http://www.dmtf.org/standards/cim/cim_schema_v2230/CIM_Network.pdf</a></p>
<p>The filters are managed in libvirt as a top level, standalone object.
This allows the filters to then be referenced by any libvirt object
that requires their functionality, instead tying them only to use
that requires their functionality, instead tieing them only to use
by guest NICs. In the current implementation, filters can be associated
with individual guest NICs via the libvirt domain XML format. In the
future we might allow filters to be associated with the virtual network
@@ -272,7 +271,7 @@ f5c78134-9da4-0c60-a9f0-fb37bc21ac1f no-other-rarp-traffic
to update them. This ensures the guests have their iptables/ebtables
rules recreated.
</p>
<p>To associate the clean-traffic filter with a guest, edit the
<p>To associate the clean-trafffic filter with a guest, edit the
guest XML config and change the <code>&lt;interface&gt;</code> element
to include a <code>&lt;filterref&gt;</code> and also specify the
whitelisted <code>&lt;ip address/&gt;</code> the guest is allowed to

View File

@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1 >XML Format</h1>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Driver capabilities XML format</h1>

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Network XML format</h1>
@@ -155,7 +153,7 @@
&lt;/forward&gt;
...</pre>
<p>
A single IPv4 address can be set by setting
An singe IPv4 address can be set by setting
<code>start</code> and <code>end</code> attributes to
the same value.
</p>
@@ -411,135 +409,43 @@
...</pre>
<p>
The <code>&lt;bandwidth&gt;</code> element allows setting
quality of service for a particular network
(<span class="since">since 0.9.4</span>). Setting
<code>bandwidth</code> for a network is supported only
for networks with a <code>&lt;forward&gt;</code> mode
of <code>route</code>, <code>nat</code>, or no mode at all
(i.e. an "isolated" network). Setting <code>bandwidth</code>
is <b>not</b> supported for forward modes
of <code>bridge</code>, <code>passthrough</code>, <code>private</code>,
or <code>hostdev</code>. Attempts to do this will lead to
a failure to define the network or to create a transient network.
</p>
<p>
The <code>&lt;bandwidth&gt;</code> element can only be a
subelement of a domain's <code>&lt;interface&gt;</code>, a
subelement of a <code>&lt;network&gt;</code>, or a subelement of
a <code>&lt;portgroup&gt;</code> in a <code>&lt;network&gt;</code>.
</p>
<p>
As a subelement of a domain's <code>&lt;interface&gt;</code>,
the bandwidth only applies to that one interface of the domain.
As a subelement of a <code>&lt;network&gt;</code>, the bandwidth
is a total aggregate bandwidth to/from all guest interfaces attached
to that network, <b>not</b> to each guest interface individually.
If a domain's <code>&lt;interface&gt;</code> has
<code>&lt;bandwidth&gt;</code> element values higher
than the aggregate for the entire network, then the aggregate
bandwidth for the <code>&lt;network&gt;</code> takes precedence.
This is because the two choke points are independent of each other
where the domain's <code>&lt;interface&gt;</code> bandwidth control
is applied on the interface's tap device, while the
<code>&lt;network&gt;</code> bandwidth control is applied on the
interface part of the bridge device created for that network.
</p>
<p>
As a subelement of a
<code>&lt;portgroup&gt;</code> in a <code>&lt;network&gt;</code>,
if a domain's <code>&lt;interface&gt;</code> has a
<code>portgroup</code> attribute in its
<code>&lt;source&gt;</code> element <b>and</b> if the
<code>&lt;interface&gt;</code>
itself has no <code>&lt;bandwidth&gt;</code> element, then the
<code>&lt;bandwidth&gt;</code> element of the portgroup will be
applied individually to each guest interface defined to be a
member of that portgroup. Any <code>&lt;bandwidth&gt;</code>
element in the domain's <code>&lt;interface&gt;</code> definition
will override the setting in the portgroup
(<span class="since">since 1.0.1</span>).
</p>
<p>
Incoming and outgoing traffic can be shaped independently. The
<code>bandwidth</code> element can have at most one
<code>inbound</code> and at most one <code>outbound</code>
child element. Leaving either of these children elements out
results in no QoS applied for that traffic direction. So,
when you want to shape only incoming traffic, use
<code>inbound</code> only, and vice versa. Each of these
elements have one mandatory attribute - <code>average</code> (or
<code>floor</code> as described below). The attributes are as follows,
where accepted values for each attribute is an integer number.
</p>
<dl>
<dt><code>average</code></dt>
<dd>
Specifies the desired average bit rate for the interface
being shaped (in kilobytes/second).
</dd>
<dt><code>peak</code></dt>
<dd>
Optional attribute which specifies the maximum rate at
which the bridge can send data (in kilobytes/second).
Note the limitation of implementation: this attribute in the
<code>outbound</code> element is ignored (as Linux ingress
filters don't know it yet).
</dd>
<dt><code>burst</code></dt>
<dd>
Optional attribute which specifies the amount of kilobytes that
can be transmitted in a single burst at <code>peak</code> speed.
</dd>
<dt><code>floor</code></dt>
<dd>
Optional attribute available only for the <code>inbound</code>
element. This attribute guarantees minimal throughput for
shaped interfaces. This, however, requires that all traffic
goes through one point where QoS decisions can take place, hence
why this attribute works only for virtual networks for now
(that is <code>&lt;interface type='network'/&gt;</code> with a
forward type of route, nat, or no forward at all). Moreover, the
virtual network the interface is connected to is required to have
at least inbound QoS set (<code>average</code> at least). If
using the <code>floor</code> attribute users don't need to specify
<code>average</code>. However, <code>peak</code> and
<code>burst</code> attributes still require <code>average</code>.
Currently, the Linux kernel doesn't allow ingress qdiscs to have
any classes therefore <code>floor</code> can be applied only
on <code>inbound</code> and not <code>outbound</code>.
</dd>
</dl>
<p>
Attributes <code>average</code>, <code>peak</code>, and
<code>burst</code> are available
<span class="since">since 0.9.4</span>, while the
<code>floor</code> attribute is available
<span class="since">since 1.0.1</span>.
This part of network XML provides setting quality of service. Incoming
and outgoing traffic can be shaped independently. The
<code>bandwidth</code> element can have at most one <code>inbound</code>
and at most one <code>outbound</code> child elements. Leaving any of these
children element out result in no QoS applied on that traffic direction.
So, when you want to shape only network's incoming traffic, use
<code>inbound</code> only, and vice versa. Each of these elements have one
mandatory attribute <code>average</code>. It specifies average bit rate on
interface being shaped. Then there are two optional attributes:
<code>peak</code>, which specifies maximum rate at which bridge can send
data, and <code>burst</code>, amount of bytes that can be burst at
<code>peak</code> speed. Accepted values for attributes are integer
numbers, The units for <code>average</code> and <code>peak</code> attributes
are kilobytes per second, and for the <code>burst</code> just kilobytes.
The rate is shared equally within domains connected to the network.
Moreover, <code>bandwidth</code> element can be included in
<code>portgroup</code> element.
<span class="since">Since 0.9.4</span>
</p>
<h5><a name="elementVlanTag">Setting VLAN tag (on supported network types only)</a></h5>
<pre>
&lt;network&gt;
&lt;name&gt;ovs-net&lt;/name&gt;
&lt;forward mode='bridge'/&gt;
&lt;bridge name='ovsbr0'/&gt;
&lt;virtualport type='openvswitch'&gt;
&lt;parameters interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/&gt;
&lt;/virtualport&gt;
<b>&lt;vlan trunk='yes'&gt;</b>
<b>&lt;tag id='42' nativeMode='untagged'/&gt;</b>
<b>&lt;tag id='47'/&gt;</b>
<b>&lt;/vlan&gt;</b>
&lt;portgroup name='dontpanic'&gt;
<b>&lt;vlan&gt;</b>
<b>&lt;tag id='42'/&gt;</b>
<b>&lt;/vlan&gt;</b>
&lt;/portgroup&gt;
&lt;/network&gt;
</pre>
...
&lt;devices&gt;
&lt;interface type='bridge'&gt;
<b>&lt;vlan trunk='yes'&gt;</b>
<b>&lt;tag id='42'/&gt;</b>
<b>&lt;tag id='47'/&gt;</b>
<b>&lt;/vlan&gt;</b>
&lt;source bridge='ovsbr0'/&gt;
&lt;virtualport type='openvswitch'&gt;
&lt;parameters interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/&gt;
&lt;/virtualport&gt;
&lt;/interface&gt;
&lt;devices&gt;
...</pre>
<p>
If (and only if) the network type supports vlan tagging
@@ -560,14 +466,6 @@
is desired, the optional attribute <code>trunk='yes'</code> can
be added to the vlan element.
</p>
<p>
For network connections using openvswitch it is possible to
configure the 'native-tagged' and 'native-untagged' vlan modes
<span class="since">Since 1.1.0</span>. This uses the optional
<code>nativeMode</code> attribute on the <code>&lt;tag&gt;</code>
element: <code>nativeMode</code> may be set to 'tagged' or
'untagged'. The id attribute of the element sets the native vlan.
</p>
<p>
<code>&lt;vlan&gt;</code> elements can also be specified in
a <code>&lt;portgroup&gt;</code> element, as well as directly in
@@ -623,7 +521,7 @@
network), and each portgroup has a name, as well as various
subelements associated with it. The currently supported
subelements are <code>&lt;bandwidth&gt;</code>
(described <a href="formatnetwork.html#elementQoS">here</a>)
(documented <a href="formatdomain.html#elementQoS">here</a>)
and <code>&lt;virtualport&gt;</code>
(documented <a href="formatdomain.html#elementsNICSDirect">here</a>).
If a domain interface definition specifies a portgroup (by
@@ -646,62 +544,6 @@
starting.
</p>
<h5><a name="elementsStaticroute">Static Routes</a></h5>
<p>
Static route definitions are used to provide routing information
to the virtualization host for networks which are not directly
reachable from the virtualization host, but *are* reachable from
a guest domain that is itself reachable from the
host <span class="since">since 1.0.6</span>.
</p>
<p>
As shown in <a href="formatnetwork.html#examplesNoGateway">this
example</a>, it is possible to define a virtual network
interface with no IPv4 or IPv6 addresses. Such networks are
useful to provide host connectivity to networks which are only
reachable via a guest. A guest with connectivity both to the
guest-only network and to another network that is directly
reachable from the host can act as a gateway between the
networks. A static route added to the "host-visible" network
definition provides the routing information so that IP packets
can be sent from the virtualization host to guests on the hidden
network.
</p>
<p>
Here is a fragment of a definition which shows the static
route specification as well as the IPv4 and IPv6 definitions
for network addresses which are referred to in the
<code>gateway</code> gateway address specifications. Note
that the third static route specification includes the
<code>metric</code> attribute specification with a value of 2.
This particular route would *not* be preferred if there was
another existing rout on the system with the same address and
prefix but with a lower value for the metric. If there is a
route in the host system configuration that should be overridden
by a route in a virtual network whenever the virtual network is
running, the configuration for the system-defined route should
be modified to have a higher metric, and the route on the
virtual network given a lower metric (for example, the default
metric of "1").
</p>
<pre>
...
&lt;ip address="192.168.122.1" netmask="255.255.255.0"&gt;
&lt;dhcp&gt;
&lt;range start="192.168.122.128" end="192.168.122.254" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;route address="192.168.222.0" prefix="24" gateway="192.168.122.2" /&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" /&gt;
&lt;route family="ipv6" address="2001:db8:ca2:3::" prefix="64" gateway="2001:db8:ca2:2::2"/&gt;
&lt;route family="ipv6" address="2001:db9:4:1::" prefix="64" gateway="2001:db8:ca2:2::3" metric='2'&gt;
&lt;/route&gt;
...
</pre>
<h3><a name="elementsAddress">Addressing</a></h3>
<p>
@@ -719,8 +561,6 @@
&lt;domain name="example.com"/&gt;
&lt;dns&gt;
&lt;txt name="example" value="example value" /&gt;
&lt;forwarder addr="8.8.8.8"/&gt;
&lt;forwarder addr="8.8.4.4"/&gt;
&lt;srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10'/&gt;
&lt;host ip='192.168.122.2'&gt;
&lt;hostname&gt;myhost&lt;/hostname&gt;
@@ -735,7 +575,6 @@
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" /&gt;
&lt;route family="ipv6" address="2001:db9:ca1:1::" prefix="64" gateway="2001:db8:ca2:2::2" /&gt;
&lt;/network&gt;</pre>
<dl>
@@ -753,36 +592,11 @@
with the idiosyncrasies of the platform where libvirt is
running. <span class="since">Since 0.8.8</span>
</dd>
<dt><code>dns</code></dt>
<dd> The dns element of a network contains configuration
information for the virtual network's DNS
server <span class="since">Since 0.9.3</span>.
<p>
The dns element
can have an optional <code>forwardPlainNames</code>
attribute <span class="since">Since 1.1.2</span>.
If <code>forwardPlainNames</code> is "no", then DNS resolution
requests for names that are not qualified with a domain
(i.e. names with no "." character) will not be forwarded to
the host's upstream DNS server - they will only be resolved if
they are known locally within the virtual network's own DNS
server. If <code>forwardPlainNames</code> is "yes",
unqualified names <b>will</b> be forwarded to the upstream DNS
server if they can't be resolved by the virtual network's own
DNS server.
</p>
Currently supported sub-elements of <code>&lt;dns&gt;</code> are:
<dt><code>dns</code></dt><dd>
The dns element of a network contains configuration information for the
virtual network's DNS server. <span class="since">Since 0.9.3</span>
Currently supported elements are:
<dl>
<dt><code>forwarder</code></dt>
<dd>A <code>dns</code> element can have 0 or
more <code>forwarder</code> elements. Each forwarder
element defines an IP address to be used as forwarder in
DNS server configuration. The addr attribute is required
and defines the IP address of every
forwarder. <span class="since">Since 1.1.3</span>
</dd>
<dt><code>txt</code></dt>
<dd>A <code>dns</code> element can have 0 or more <code>txt</code> elements.
Each txt element defines a DNS TXT record and has two attributes, both
@@ -1010,33 +824,6 @@
&lt;/ip&gt;
&lt;/network&gt;</pre>
<p>
Below is yet another IPv6 variation. This variation has only
IPv6 defined with DHCPv6 on the primary IPv6 network. A static
link if defined for a second IPv6 network which will not be
directly visible on the bridge interface but there will be a
static route defined for this network via the specified
gateway. Note that the gateway address must be directly
reachable via (on the same subnet as) one of the &lt;ip&gt;
addresses defined for this &lt;network&gt;.
<span class="since">Since 1.0.6</span>
</p>
<pre>
&lt;network&gt;
&lt;name&gt;net7&lt;/name&gt;
&lt;bridge name="virbr7" /&gt;
&lt;forward mode="route"/&gt;
&lt;ip family="ipv6" address="2001:db8:ca2:7::1" prefix="64" &gt;
&lt;dhcp&gt;
&lt;range start="2001:db8:ca2:7::100" end="2001:db8:ca2::1ff" /&gt;
&lt;host id="0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63" name="lucas" ip="2001:db8:ca2:2:3::4" /&gt;
&lt;/dhcp&gt;
&lt;/ip&gt;
&lt;route family="ipv6" address="2001:db8:ca2:8::" prefix="64" gateway="2001:db8:ca2:7::4" &gt;
&lt;/route&gt;
&lt;/network&gt;</pre>
<h3><a name="examplesPrivate">Isolated network config</a></h3>
<p>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Node devices XML format</h1>
@@ -13,7 +11,7 @@
prefix <code>virNodeDevice</code>, which deal with management of
host devices that can be handed to guests via passthrough as
&lt;hostdev&gt; elements
in <a href="formatdomain.html#elementsHostDev">the domain XML</a>.
in <a href="formatdomain.html#elementsUSB">the domain XML</a>.
These devices are represented as a hierarchy, where a device on
a bus has a parent of the bus controller device; the root of the
hierarchy is the node named "computer".
@@ -80,36 +78,6 @@
<dd>Vendor details from the device ROM, including an
attribute <code>id</code> with the hexadecimal vendor
id, and an optional text name of that vendor.</dd>
<dt><code>iommuGroup</code></dt>
<dd>
This optional element describes the "IOMMU group" this
device belongs to. If the element exists, it has a
mandatory <code>number</code> attribute which tells
the group number used for management of the group (all
devices in group "n" will be found in
"/sys/kernel/iommu_groups/n"). It will also have a
list of <code>address</code> subelements, each
containing the PCI address of a device in the same
group. The toplevel device will itself be included in
this list.
</dd>
<dt><code>capability</code></dt>
<dd>
This optional element can occur multiple times. If it
exists, it has a mandatory <code>type</code> attribute
which will be set to
either <code>physical_function</code>
or <code>virtual_functions</code>. If the type
is <code>physical_function</code>, there will be a
single <code>address</code> subelement which contains
the PCI address of the SRIOV Physical Function (PF)
that is the parent of this device (and this device is,
by implication, an SRIOV Virtual Function (VF)). If
the type is <code>virtual_functions</code>, then this
device is an SRIOV PF, and the capability element will
have a list of <code>address</code> subelements, one
for each VF on this PF.
</dd>
</dl>
</dd>
<dt><code>usb_device</code></dt>
@@ -136,11 +104,11 @@
<dl>
<dt><code>number</code></dt>
<dd>The device number.</dd>
<dt><code>class</code></dt>
<dt><code>number</code></dt>
<dd>The device class.</dd>
<dt><code>subclass</code></dt>
<dt><code>number</code></dt>
<dd>The device subclass.</dd>
<dt><code>protocol</code></dt>
<dt><code>number</code></dt>
<dd>The device protocol.</dd>
<dt><code>description</code></dt>
<dd>If present, a description of the device.</dd>
@@ -262,38 +230,7 @@
&lt;address&gt;00:27:13:6a:fe:00&lt;/address&gt;
&lt;capability type='80203'/&gt;
&lt;/capability&gt;
&lt;/device&gt;
&lt;device&gt;
&lt;name&gt;pci_0000_02_00_0&lt;/name&gt;
&lt;path&gt;/sys/devices/pci0000:00/0000:00:04.0/0000:02:00.0&lt;/path&gt;
&lt;parent&gt;pci_0000_00_04_0&lt;/parent&gt;
&lt;driver&gt;
&lt;name&gt;igb&lt;/name&gt;
&lt;/driver&gt;
&lt;capability type='pci'&gt;
&lt;domain&gt;0&lt;/domain&gt;
&lt;bus&gt;2&lt;/bus&gt;
&lt;slot&gt;0&lt;/slot&gt;
&lt;function&gt;0&lt;/function&gt;
&lt;product id='0x10c9'&gt;82576 Gigabit Network Connection&lt;/product&gt;
&lt;vendor id='0x8086'&gt;Intel Corporation&lt;/vendor&gt;
&lt;capability type='virt_functions'&gt;
&lt;address domain='0x0000' bus='0x02' slot='0x10' function='0x0'/&gt;
&lt;address domain='0x0000' bus='0x02' slot='0x10' function='0x2'/&gt;
&lt;address domain='0x0000' bus='0x02' slot='0x10' function='0x4'/&gt;
&lt;address domain='0x0000' bus='0x02' slot='0x10' function='0x6'/&gt;
&lt;address domain='0x0000' bus='0x02' slot='0x11' function='0x0'/&gt;
&lt;address domain='0x0000' bus='0x02' slot='0x11' function='0x2'/&gt;
&lt;address domain='0x0000' bus='0x02' slot='0x11' function='0x4'/&gt;
&lt;/capability&gt;
&lt;iommuGroup number='12'&gt;
&lt;address domain='0x0000' bus='0x02' slot='0x00' function='0x0'/&gt;
&lt;address domain='0x0000' bus='0x02' slot='0x00' function='0x1'/&gt;
&lt;/iommuGroup&gt;
&lt;/capability&gt;
&lt;/device&gt;
</pre>
&lt;/device&gt;</pre>
</body>
</html>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Network Filters</h1>
@@ -115,7 +113,7 @@
<p>
Filtering rules are organized in filter chains. These chains can be
thought of as having a tree structure with packet
filtering rules as entries in individual chains (branches). <br/>
filtering rules as entries in individual chains (branches). <br>
Packets start their filter evaluation in the <code>root</code> chain
and can then continue their evaluation in other chains, return from
those chains back into the <code>root</code> chain or be
@@ -229,7 +227,7 @@
<p>
A chain with a lower priority value is accessed before one with a
higher value.
<br/>
<br><br>
<span class="since">Since 0.9.8</span> the above listed chains
can be assigned custom priorities by writing a value in the
range [-1000, 1000] into the priority (XML) attribute in the filter
@@ -372,7 +370,7 @@
<p>
Further, the notation of $VARIABLE is short-hand for $VARIABLE[@0]. The
former notation always assumes the iterator with Id '0'.
</p>
<p>
<h3><a name="nwfelemsRulesAdvIPAddrDetection">Automatic IP address detection</a></h3>
<p>
@@ -396,7 +394,7 @@
When a VM is migrated to another host or resumed after a suspend operation,
the first packet sent by the VM will again determine the IP address it can
use on a particular interface.
<br/>
<br/><br>
A value of <code>dhcp</code> specifies that libvirt should only honor DHCP
server-assigned addresses with valid leases. This method supports the detection
and usage of multiple IP address per interface.
@@ -569,7 +567,7 @@
(matching the rule passes this filter, but returns control to
the calling filter for further
analysis) <span class="since">(since 0.9.7)</span>,
or <code>continue</code> (matching the rule goes on to the next
or <code>continue<code> (matching the rule goes on to the next
rule for further analysis) <span class="since">(since
0.9.7)</span>.
</li>
@@ -587,7 +585,7 @@
<span class="since">Since 0.9.8</span> this has been extended to cover
the range of -1000 to 1000. If this attribute is not
provided, priority 500 will automatically be assigned.
<br/>
<br>
Note that filtering rules in the <code>root</code> chain are sorted
with filters connected to the <code>root</code> chain following
their priorities. This allows to interleave filtering rules with
@@ -989,21 +987,11 @@
<td>IP_ADDR</td>
<td>Source IP address in ARP/RARP packet</td>
</tr>
<tr>
<td>arpsrcipmask <span class="since">(Since 1.2.3)</span></td>
<td>IP_MASK</td>
<td>Source IP mask</td>
</tr>
<tr>
<td>arpdstipaddr</td>
<td>IP_ADDR</td>
<td>Destination IP address in ARP/RARP packet</td>
</tr>
<tr>
<td>arpdstipmask <span class="since">(Since 1.2.3)</span></td>
<td>IP_MASK</td>
<td>Destination IP mask</td>
</tr>
<tr>
<td>comment <span class="since">(Since 0.8.5)</span></td>
<td>STRING</td>
@@ -1837,7 +1825,7 @@
initiate a connection from TCP port 80 back towards the VM.
By default the connection state match that enables connection tracking
and then enforcement of directionality of traffic is turned on. <br/>
The following shows an example XML fragment where this feature has been
The following shows an example XML fragement where this feature has been
turned off for incoming connections to TCP port 12345.
</p>
<pre>
@@ -2089,9 +2077,9 @@
To enable traffic for TCP ports 22 and 80 we will add 2 rules to
enable this type of traffic. To allow the VM to send ping traffic
we will add a rule for ICMP traffic. For simplicity reasons
we allow general ICMP traffic to be initiated from the VM, not
we allow general ICMP traffic to be initated from the VM, not
just ICMP echo request and response messages. To then
disallow all other traffic to reach or be initiated by the
disallow all other traffic to reach or be initated by the
VM we will then need to add a rule that drops all other traffic.
Assuming our VM is called <i>test</i> and
the interface we want to associate our filter with is called <i>eth0</i>,
@@ -2365,7 +2353,7 @@
on the source system are equivalent to those on the target system
and vice versa.
<br/><br/>
Migration must occur between libvirt installations of version
Migration must occur between libvirt insallations of version
0.8.1 or later in order not to lose the network traffic filters
associated with an interface.
</p>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Secret XML format</h1>
@@ -41,205 +39,53 @@
<dd>
Specifies what this secret is used for. A mandatory
<code>type</code> attribute specifies the usage category, currently
only <code>volume</code>, <code>ceph</code> and <code>iscsi</code>
are defined. Specific usage categories are described below.
only <code>volume</code> and <code>ceph</code> are defined.
Specific usage categories are described below.
</dd>
</dl>
<h3><a name="VolumeUsageType">Usage type "volume"</a></h3>
<h3>Usage type "volume"</h3>
<p>
This secret is associated with a volume, and it is safe to delete the
secret after the volume is deleted. The <code>&lt;usage
type='volume'&gt;</code> element must contain a
single <code>volume</code> element that specifies the key of the volume
this secret is associated with. For example, create a volume-secret.xml
file as follows:
this secret is associated with.
</p>
<pre>
&lt;secret ephemeral='no' private='yes'&gt;
&lt;description&gt;Super secret name of my first puppy&lt;/description&gt;
&lt;uuid&gt;0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f&lt;/uuid&gt;
&lt;usage type='volume'&gt;
&lt;volume&gt;/var/lib/libvirt/images/puppyname.img&lt;/volume&gt;
&lt;/usage&gt;
&lt;/secret&gt;
</pre>
<h3>Usage type "ceph"</h3>
<p>
Define the secret and set the pass phrase as follows:
</p>
<pre>
# virsh secret-define volume-secret.xml
Secret 0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f created
#
# MYSECRET=`printf %s "open sesame" | base64`
# virsh secret-set-value 0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f $MYSECRET
Secret value set
#
</pre>
<p>
The volume type secret can then be used in the XML for a storage volume
<a href="formatstorageencryption.html">encryption</a> as follows:
</p>
<pre>
&lt;encryption format='qcow'&gt;
&lt;secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/&gt;
&lt;/encryption&gt;
</pre>
<h3><a name="CephUsageType">Usage type "ceph"</a></h3>
<p>
This secret is associated with a Ceph RBD (rados block device).
The <code>&lt;usage type='ceph'&gt;</code> element must contain
a single <code>name</code> element that specifies a usage name
for the secret. The Ceph secret can then be used by UUID or by
this usage name via the <code>&lt;auth&gt;</code> element of
a <a href="formatdomain.html#elementsDisks">disk device</a> or
a <a href="formatstorage.html">storage pool (rbd)</a>.
<span class="since">Since 0.9.7</span>. The following is an example
of the steps to be taken. First create a ceph-secret.xml file:
a <a href="domain.html#elementsDisks">disk
device</a>. <span class="since">Since 0.9.7</span>.
</p>
<pre>
&lt;secret ephemeral='no' private='yes'&gt;
&lt;description&gt;CEPH passphrase example&lt;/description&gt;
&lt;usage type='ceph'&gt;
&lt;name&gt;ceph_example&lt;/name&gt;
&lt;/usage&gt;
&lt;/secret&gt;
</pre>
<p>
Next, use <code>virsh secret-define ceph-secret.xml</code> to define
the secret and <code>virsh secret-set-value</code> using the generated
UUID value and a base64 generated secret value in order to define the
chosen secret pass phrase.
</p>
<pre>
# virsh secret-define ceph-secret.xml
Secret 1b40a534-8301-45d5-b1aa-11894ebb1735 created
#
# virsh secret-list
UUID Usage
-----------------------------------------------------------
1b40a534-8301-45d5-b1aa-11894ebb1735 cephx ceph_example
#
# CEPHPHRASE=`printf %s "pass phrase" | base64`
# virsh secret-set-value 1b40a534-8301-45d5-b1aa-11894ebb1735 $CEPHPHRASE
Secret value set
#
</pre>
<p>
The ceph secret can then be used by UUID or by the
usage name via the <code>&lt;auth&gt;</code> element in a domain's
<a href="formatdomain.html#elementsDisks"><code>&lt;disk&gt;</code></a>
element as follows:
</p>
<pre>
&lt;auth username='myname'&gt;
&lt;secret type='ceph' usage='ceph_example'/&gt;
&lt;/auth&gt;
</pre>
<p>
As well as the <code>&lt;auth&gt;</code> element in a
<a href="formatstorage.html">storage pool (rbd)</a>
<code>&lt;source&gt;</code> element as follows:
</p>
<pre>
&lt;auth type='ceph' username='myname'&gt;
&lt;secret usage='ceph_example'/&gt;
&lt;/auth&gt;
</pre>
<h3><a name="iSCSIUsageType">Usage type "iscsi"</a></h3>
<h3>Usage type "iscsi"</h3>
<p>
This secret is associated with an iSCSI target for CHAP authentication.
The <code>&lt;usage type='iscsi'&gt;</code> element must contain
a single <code>target</code> element that specifies a usage name
for the secret. The iSCSI secret can then be used by UUID or by
for the secret. The iSCSI secret can then be used by UUID or by
this usage name via the <code>&lt;auth&gt;</code> element of
a <a href="formatdomain.html#elementsDisks">disk device</a> or
a <a href="formatstorage.html">storage pool (iscsi)</a>.
<span class="since">Since 1.0.4</span>. The following is an example
of the XML that may be used to generate a secret for iSCSI CHAP
authentication. Assume the following sample entry in an iSCSI
authentication file:
</p>
<pre>
&lt;target iqn.2013-07.com.example:iscsi-pool&gt;
backing-store /home/tgtd/iscsi-pool/disk1
backing-store /home/tgtd/iscsi-pool/disk2
incominguser myname mysecret
&lt;/target&gt;
</pre>
<p>
Define an iscsi-secret.xml file to describe the secret. Use the
<code>incominguser</code> username used in your iSCSI authentication
configuration file as the value for the <code>username</code> attribute.
The <code>description</code> attribute should contain configuration
specific data. The <code>target</code> name may be any name of your
choosing to be used as the <code>usage</code> when used in the pool
or disk XML description.
a <a href="domain.html#elementsDisks">disk
device</a>. <span class="since">Since 1.0.4</span>.
</p>
<h2><a name="example">Example</a></h2>
<pre>
&lt;secret ephemeral='no' private='yes'&gt;
&lt;description&gt;Passphrase for the iSCSI example.com server&lt;/description&gt;
&lt;usage type='iscsi'&gt;
&lt;target&gt;libvirtiscsi&lt;/target&gt;
&lt;description&gt;LUKS passphrase for the main hard drive of our mail server&lt;/description&gt;
&lt;usage type='volume'&gt;
&lt;volume&gt;/var/lib/libvirt/images/mail.img&lt;/volume&gt;
&lt;/usage&gt;
&lt;/secret&gt;
</pre>
<p>
Next, use <code>virsh secret-define iscsi-secret.xml</code> to define
the secret and <code>virsh secret-set-value</code> using the generated
UUID value and a base64 generated secret value in order to define the
chosen secret pass phrase. The pass phrase must match the password
used in the iSCSI authentication configuration file.
</p>
<pre>
# virsh secret-define secret.xml
Secret c4dbe20b-b1a3-4ac1-b6e6-2ac97852ebb6 created
# virsh secret-list
UUID Usage
-----------------------------------------------------------
c4dbe20b-b1a3-4ac1-b6e6-2ac97852ebb6 iscsi libvirtiscsi
# MYSECRET=`printf %s "mysecret" | base64`
# virsh secret-set-value c4dbe20b-b1a3-4ac1-b6e6-2ac97852ebb6 $MYSECRET
Secret value set
#
</pre>
<p>
The iSCSI secret can then be used by UUID or by the
usage name via the <code>&lt;auth&gt;</code> element in a domain's
<a href="formatdomain.html#elementsDisks"><code>&lt;disk&gt;</code></a>
element as follows:
</p>
<pre>
&lt;auth username='myname'&gt;
&lt;secret type='iscsi' usage='libvirtiscsi'/&gt;
&lt;/auth&gt;
</pre>
<p>
As well as the <code>&lt;auth&gt;</code> element in a
<a href="formatstorage.html">storage pool (iscsi)</a>
<code>&lt;source&gt;</code> element as follows:
</p>
<pre>
&lt;auth type='chap' username='myname'&gt;
&lt;secret usage='libvirtiscsi'/&gt;
&lt;/auth&gt;
</pre>
&lt;/secret&gt;</pre>
</body>
</html>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Snapshot XML format</h1>
@@ -170,22 +168,6 @@
snapshots, the original file name becomes the read-only
snapshot, and the new file name contains the read-write
delta of all disk changes since the snapshot.
<span class="since">Since 1.2.2</span> the <code>disk</code> element
supports an optional attribute <code>type</code> if the
<code>snapshot</code> attribute is set to <code>external</code>.
This attribute specifies the snapshot target storage type and allows
to overwrite the default <code>file</code> type. The <code>type</code>
attribute along with the format of the <code>source</code>
sub-element is identical to the <code>source</code> element used in
domain disk definitions. See the
<a href="formatdomain.html#elementsDisks">disk devices</a> section
documentation for further information.
Libvirt currently supports the <code>type</code> element in the qemu
driver and supported values are <code>file</code>, <code>block</code>
and <code>network</code> with a protocol of <code>gluster</code>
<span class="since">(since 1.2.2)</span>.
</dd>
</dl>
</dd>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Storage pool and volume XML format</h1>
@@ -17,15 +15,10 @@
<p>
The top level tag for a storage pool document is 'pool'. It has
a single attribute <code>type</code>, which is one of <code>dir</code>,
<code>fs</code>, <code>netfs</code>, <code>disk</code>,
<code>iscsi</code>, <code>logical</code>, <code>scsi</code>
(all <span class="since">since 0.4.1</span>), <code>mpath</code>
(<span class="since">since 0.7.1</span>), <code>rbd</code>
(<span class="since">since 0.9.13</span>), <code>sheepdog</code>
(<span class="since">since 0.10.0</span>),
or <code>gluster</code> (<span class="since">since
1.2.0</span>). This corresponds to the
storage backend drivers listed further along in this document.
<code>fs</code>,<code>netfs</code>,<code>disk</code>,<code>iscsi</code>,
<code>logical</code>. This corresponds to the storage backend drivers
listed further along in this document.
The storage pool XML format is available <span class="since">since 0.4.1</span>
</p>
<h3><a name="StoragePoolFirst">General metadata</a></h3>
@@ -69,8 +62,7 @@
<p>
A single <code>source</code> element is contained within the top level
<code>pool</code> element. This tag is used to describe the source of
the storage pool. The set of child elements that it will contain
depend on the pool type, but come from the following child elements:
the storage pool. It can contain the following child elements:
</p>
<pre>
@@ -78,9 +70,6 @@
&lt;source&gt;
&lt;host name="iscsi.example.com"/&gt;
&lt;device path="demo-target"/&gt;
&lt;auth type='chap' username='myname'&gt;
&lt;secret type='iscsi' usage='mycluster_myname'/&gt;
&lt;/auth&gt;
&lt;vendor name="Acme"/&gt;
&lt;product name="model"/&gt;
&lt;/source&gt;
@@ -88,6 +77,7 @@
<pre>
...
&lt;source&gt;
&lt;source&gt;
&lt;adapter type='fc_host' parent='scsi_host5' wwnn='20000000c9831b4b' wwpn='10000000c9831b4b'/&gt;
&lt;/source&gt;
@@ -95,23 +85,17 @@
<dl>
<dt><code>device</code></dt>
<dd>Provides the source for pools backed by physical devices
(pool types <code>fs</code>, <code>logical</code>, <code>disk</code>,
<code>iscsi</code>).
<dd>Provides the source for pools backed by physical devices.
May be repeated multiple times depending on backend driver. Contains
a single attribute <code>path</code> which is the fully qualified
path to the block device node. <span class="since">Since 0.4.1</span></dd>
<dt><code>dir</code></dt>
<dd>Provides the source for pools backed by directories (pool
type <code>dir</code>), or optionally to select a subdirectory
within a pool that resembles a filesystem (pool
type <code>gluster</code>). May
<dt><code>directory</code></dt>
<dd>Provides the source for pools backed by directories. May
only occur once. Contains a single attribute <code>path</code>
which is the fully qualified path to the backing directory.
<span class="since">Since 0.4.1</span></dd>
<dt><code>adapter</code></dt>
<dd>Provides the source for pools backed by SCSI adapters (pool
type <code>scsi</code>). May
<dd>Provides the source for pools backed by SCSI adapters. May
only occur once. Attribute <code>name</code> is the SCSI adapter
name (ex. "scsi_host1". NB, although a name such as "host1" is
still supported for backwards compatibility, it is not recommended).
@@ -132,45 +116,18 @@
<span class="since">Since 0.6.2</span></dd>
<dt><code>host</code></dt>
<dd>Provides the source for pools backed by storage from a
remote server (pool types <code>netfs</code>, <code>iscsi</code>,
<code>rbd</code>, <code>sheepdog</code>, <code>gluster</code>). Will be
used in combination with a <code>directory</code>
remote server. Will be used in combination with a <code>directory</code>
or <code>device</code> element. Contains an attribute <code>name</code>
which is the hostname or IP address of the server. May optionally
contain a <code>port</code> attribute for the protocol specific
port number. <span class="since">Since 0.4.1</span></dd>
<dt><code>auth</code></dt>
<dd>If present, the <code>auth</code> element provides the
authentication credentials needed to access the source by the
setting of the <code>type</code> attribute (pool
types <code>iscsi</code>, <code>rbd</code>). The <code>type</code>
must be either "chap" or "ceph". Use "ceph" for
Ceph RBD (Rados Block Device) network sources and use "iscsi" for CHAP
(Challenge-Handshake Authentication Protocol) iSCSI
targets. Additionally a mandatory attribute
<code>username</code> identifies the username to use during
authentication as well as a sub-element <code>secret</code> with
a mandatory attribute <code>type</code>, to tie back to a
<a href="formatsecret.html">libvirt secret object</a> that
holds the actual password or other credentials. The domain XML
intentionally does not expose the password, only the reference
to the object that manages the password.
The <code>secret</code> element requires either a <code>uuid</code>
attribute with the UUID of the secret object or a <code>usage</code>
attribute matching the key that was specified in the
secret object. <span class="since">Since 0.9.7 for "ceph" and
1.1.1 for "chap"</span>
</dd>
<dt><code>name</code></dt>
<dd>Provides the source for pools backed by storage from a
named element (pool types <code>logical</code>, <code>rbd</code>,
<code>sheepdog</code>, <code>gluster</code>). Contains a
string identifier.
named element (e.g., a logical volume group name).
Contains a string identifier.
<span class="since">Since 0.4.5</span></dd>
<dt><code>format</code></dt>
<dd>Provides information about the format of the pool (pool
types <code>fs</code>, <code>netfs</code>, <code>disk</code>,
<code>logical</code>). This
<dd>Provides information about the format of the pool. This
contains a single attribute <code>type</code> whose value is
backend specific. This is typically used to indicate filesystem
type, or network filesystem type, or partition table type, or
@@ -192,11 +149,7 @@
<p>
A single <code>target</code> element is contained within the top level
<code>pool</code> element for some types of pools (pool
types <code>dir</code>, <code>fs</code>, <code>netfs</code>,
<code>logical</code>, <code>disk</code>, <code>iscsi</code>,
<code>scsi</code>, <code>mpath</code>). This tag is used to
describe the mapping of
<code>pool</code> element. This tag is used to describe the mapping of
the storage pool into the host filesystem. It can contain the following
child elements:
</p>
@@ -236,10 +189,11 @@
<span class="since">Since 0.4.1</span>
</dd>
<dt><code>permissions</code></dt>
<dd>This is currently only useful for directory or filesystem based
pools, which are mapped as a directory into the local filesystem
namespace. It provides information about the permissions to use for the
final directory when the pool is built. The
<dd>Provides information about the default permissions to use
when creating volumes. This is currently only useful for directory
or filesystem based pools, where the volumes allocated are simple
files. For pools where the volumes are device nodes, the hotplug
scripts determine permissions. It contains 4 child elements. The
<code>mode</code> element contains the octal permission set. The
<code>owner</code> element contains the numeric user ID. The <code>group</code>
element contains the numeric group ID. The <code>label</code> element
@@ -288,18 +242,14 @@
<h2><a name="StorageVol">Storage volume XML</a></h2>
<p>
A storage volume will generally be either a file or a device
node; <span class="since">since 1.2.0</span>, an optional
output-only attribute <code>type</code> lists the actual type
(file, block, dir, network, or netdir), which is also available
from <code>virStorageVolGetInfo()</code>. The storage volume
XML format is available <span class="since">since 0.4.1</span>
A storage volume will be either a file or a device node.
The storage volume XML format is available <span class="since">since 0.4.1</span>
</p>
<h3><a name="StorageVolFirst">General metadata</a></h3>
<pre>
&lt;volume type='file'&gt;
&lt;volume&gt;
&lt;name&gt;sparse.img&lt;/name&gt;
&lt;key&gt;/var/lib/xen/images/sparse.img&lt;/key&gt;
&lt;allocation&gt;0&lt;/allocation&gt;
@@ -311,10 +261,8 @@
<dd>Providing a name for the volume which is unique to the pool.
This is mandatory when defining a volume. <span class="since">Since 0.4.1</span></dd>
<dt><code>key</code></dt>
<dd>Providing an identifier for the volume which identifies a
single volume. In some cases it's possible to have two distinct keys
identifying a single volume. This field cannot be set when creating
a volume: it is always generated.
<dd>Providing an identifier for the volume which is globally unique.
This cannot be set when creating a volume: it is always generated.
<span class="since">Since 0.4.1</span></dd>
<dt><code>allocation</code></dt>
<dd>Providing the total storage allocation for the volume. This
@@ -384,10 +332,6 @@
&lt;mode&gt;0744&lt;/mode&gt;
&lt;label&gt;virt_image_t&lt;/label&gt;
&lt;/permissions&gt;
&lt;compat&gt;1.1&lt;/compat&gt;
&lt;features&gt;
&lt;lazy_refcounts/&gt;
&lt;/features&gt;
&lt;/target&gt;</pre>
<dl>
@@ -416,22 +360,6 @@
contains the MAC (eg SELinux) label string.
<span class="since">Since 0.4.1</span>
</dd>
<dt><code>compat</code></dt>
<dd>Specify compatibility level. So far, this is only used for
<code>type='qcow2'</code> volumes. Valid values are <code>0.10</code>
and <code>1.1</code> so far, specifying QEMU version the images should
be compatible with. If the <code>feature</code> element is present,
1.1 is used. If omitted, qemu-img default is used.
<span class="since">Since 1.1.0</span>
</dd>
<dt><code>features</code></dt>
<dd>Format-specific features. Only used for <code>qcow2</code> now.
Valid sub-elements are:
<ul>
<li><code>&lt;lazy_refcounts/&gt;</code> - allow delayed reference
counter updates. <span class="since">Since 1.1.0</span></li>
</ul>
</dd>
</dl>
<h3><a name="StorageVolBacking">Backing store elements</a></h3>
@@ -507,10 +435,7 @@
&lt;name&gt;virtimages&lt;/name&gt;
&lt;source&gt;
&lt;host name="iscsi.example.com"/&gt;
&lt;device path="iqn.2013-06.com.example:iscsi-pool"/&gt;
&lt;auth type='chap' username='myuser'&gt;
&lt;secret usage='libvirtiscsi'/&gt;
&lt;/auth&gt;
&lt;device path="demo-target"/&gt;
&lt;/source&gt;
&lt;target&gt;
&lt;path&gt;/dev/disk/by-path&lt;/path&gt;

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Storage volume encryption XML format</h1>

View File

@@ -1,124 +0,0 @@
#!/usr/bin/perl
#
# Copyright (C) 2013 Red Hat, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see
# <http://www.gnu.org/licenses/>.
#
use strict;
use warnings;
my @objects = (
"CONNECT", "DOMAIN", "INTERFACE",
"NETWORK","NODE_DEVICE", "NWFILTER",
"SECRET", "STORAGE_POOL", "STORAGE_VOL",
);
my %class;
foreach my $object (@objects) {
my $class = lc $object;
$class =~ s/(^\w|_\w)/uc $1/eg;
$class =~ s/_//g;
$class =~ s/Nwfilter/NWFilter/;
$class = "vir" . $class . "Ptr";
$class{$object} = $class;
}
my $objects = join ("|", @objects);
my %opts;
my $in_opts = 0;
my %perms;
while (<>) {
if ($in_opts) {
if (m,\*/,) {
$in_opts = 0;
} elsif (/\*\s*\@(\w+):\s*(.*?)\s*$/) {
$opts{$1} = $2;
}
} elsif (m,/\*\*,) {
$in_opts = 1;
} elsif (/VIR_ACCESS_PERM_($objects)_((?:\w|_)+),/) {
my $object = $1;
my $perm = lc $2;
next if $perm eq "last";
$perm =~ s/_/-/g;
$perms{$object} = {} unless exists $perms{$object};
$perms{$object}->{$perm} = {
desc => $opts{desc},
message => $opts{message},
anonymous => $opts{anonymous}
};
%opts = ();
}
}
print <<EOF;
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
EOF
foreach my $object (sort { $a cmp $b } keys %perms) {
my $class = $class{$object};
my $olink = lc "object_" . $object;
print <<EOF;
<h3><a name="$olink">$class</a></h3>
<table class="acl">
<thead>
<tr>
<th>Permission</th>
<th>Description</th>
</tr>
</thead>
<tbody>
EOF
foreach my $perm (sort { $a cmp $b } keys %{$perms{$object}}) {
my $description = $perms{$object}->{$perm}->{desc};
die "missing description for $object.$perm" unless
defined $description;
my $plink = lc "perm_" . $object . "_" . $perm;
$plink =~ s/-/_/g;
print <<EOF;
<tr>
<td><a name="$plink">$perm</a></td>
<td>$description</td>
</tr>
EOF
}
print <<EOF;
</tbody>
</table>
EOF
}
print <<EOF;
</body>
</html>
EOF

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1>Terminology and goals</h1>
<p>To avoid ambiguity about the terms used, here are the definitions

View File

@@ -1,294 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Project governance</h1>
<ul id="toc"></ul>
<p>
The libvirt project operates as a meritocratic, consensus-based community.
Anyone with an interest in the project can join the community, contributing
to the ongoing development of the project's work. This pages describes how
that participation takes place and how contributors earn merit, and thus
influence, within the community.
</p>
<h2><a name="codeofconduct">Code of conduct</a></h2>
<p>
The libvirt project community covers people from a wide variety of
countries, backgrounds and positions. This global diversity is a great
strength of the project, but can also lead to communication issues,
which may in turn cause unhappiness. To maximise happiness of the
project community taken as a whole, all members (whether users,
contributors or committers) are expected to abide by the project's
code of conduct. At a high level the code can be summarized as
<em>"be excellent to each other"</em>. Expanding on this:
</p>
<ul>
<li><strong>Be respectful:</strong> disagreements between people are to
be expected and are usually the sign of healthy debate and engagement.
Disagreements can lead to frustration and even anger for some members.
Turning to personal insults, intimidation or threatening behaviour does
not improve the situation though. Participants should thus take care to
ensure all communications / interactions stay professional at all times.</li>
<li><strong>Be considerate:</strong> remember that the community has members
with a diverse background many of whom have English as a second language.
What might appear impolite, may simply be a result of a lack of knowledge
of the English language. Bear in mind that actions will have an impact
on other community members and the project as a whole, so take potential
consequences into account before pursuing a course of action.</li>
<li><strong>Be forgiving:</strong> humans are fallible and as such prone
to make mistakes and inexplicably change their positions at times. Don't
assume that other members are acting with malicious intent. Be prepared
to forgive people who make mistakes and assist each other in learning
from them. Playing a blame game doesn't help anyone.</li>
</ul>
<h2><a name="roles">Roles and responsibilities</a></h2>
<h3><a href="users">Users</a></h3>
<p>
The users are anyone who has a need for the output of the project.
There are no rules or requirements to become a user of libvirt. Even
if the software does not yet work on their OS platform, a person can
be considered a potential future user and welcomed to participate.
</p>
<p>
Participation by users is key to ensuring the project moves in the
right direction, satisfying their real world needs. Users are
encouraged to participate in the broader libvirt community in any
number of ways:
</p>
<ul>
<li>Evangelism: spread the word about what libvirt is doing, how it
helps solve your problems. This can be via blog articles, social
media postings, video blogs, user group / conference presentations
and any other method of disseminating information</li>
<li>Feedback: let the developers know about what does and does not
work with the project. Talk to developers on the project's
IRC channel and mailing list, or find them at conferences. Tell
them what gaps the project has or where they should look for
future development</li>
<li>Moral support: developers live for recognition of the positive
impact their work has on users' lives. Give thanks to the developers
when evangelising the project, or when meeting them at user groups,
conferences, etc.</li>
</ul>
<p>
The above is not an exhaustive list of things users can do to
participate in the project. Further ideas and suggestions are
welcome. Users are encouraged to take their participation
further and become contributors to the project in any of the
ways listed in the next section.
</p>
<h3><a name="contributors">Contributors</a></h3>
<p>
The contributors are community members who have some concrete impact
to the ongoing development of the project. There are many ways in which
members can contribute, with no requirement to be a software engineer.
Many users can in fact consider themselves contributors merely by
engaging in evangelism for the project.
</p>
<ul>
<li>Bug reporting: improve the quality of the project by reporting
any problems found either to the project's own bug tracker, or to
that of the OS vendor shipping the libvirt code.</li>
<li>User help: join the <a href="contact.html">IRC channel or mailing list</a>
to assist or advice other users in troubleshooting the problems they face.</li>
<li>Feature requests: help set the direction for future work by
reporting details of features which are missing to the project's
own bug tracker or mailing lists.</li>
<li>Graphical design: contribute to the development of the project's
websites / wiki brand with improved graphics, styling or layout.</li>
<li>Code development: write and submit patches to address bugs or implement
new features</li>
<li>Architectural design: improve the usefulness of the project
by providing feedback on the design of proposed features, to
ensure they satisfy the broadest applicable needs and survive
the long term</li>
<li>Code review: look at patches which are submitted and critique
the code to identify bugs, potential design problems or other
issues which should be addressed before the code is accepted</li>
<li>Documentation: contribute to content on personal blogs, the
website, wiki, code comments, or any of the formal documentation
efforts.</li>
<li>Translation: join the Fedora transifex community to improve the
quality of translations needed by the libvirt project.</li>
<li>Testing: try proposed patches or release candidates and report
whether the build passes and the changes work as expected.</li>
</ul>
<p>
The above is not an exhaustive list of things members can do to
contribute to the project. Further ideas and suggestions are
welcome.
</p>
<p>
There are no special requirements to becoming a contributor other
than having the interest and ability to provide a contribution. The
libvirt project <strong>does not require</strong> any
<em>"Contributor License Agreement"</em>
to be signed prior to engagement with the community.
</p>
<p>
In making a contribution to the project, the community member is
implicitly stating that they accept the terms of the license under
which the work they are contributing to is distributed. They are
also implicitly stating that they have the legal right to make the
contribution, if doing so on behalf of a broader organization /
company. Most of the project's code is distributed under the GNU
Lesser General Public License, version 2 or later. Details of the
exact license under which contributions will be presumed to be
covered are found in the source repositories, or website in question.
</p>
<h3><a name="committers">Committers</a></h3>
<p>
The committers are the subset of contributors who have direct access
to commit code to the project's primary source code repositories, which
are currently using the GIT software. The committers are chosen based
on the quality of their contributions over a period of time. This includes
both the quality of code they submit, as well as the quality of reviews
they provide on other contributors' submissions and a demonstration that
they understand day-to-day operation of the project and its goals. There
is no minimum level of contribution required in order to become a committer,
though 2-3 months worth of quality contribution would be a rough guide.
</p>
<p>
There are no special requirements to becoming a committer other than to
have shown a willingness and ability to contribute to the project over
an extended period of time. Proposals for elevating contributors to
committers are typically made by existing committers, though contributors
are also welcome to make proposals. The decision to approve the elevation
of a contributor to a committer is made through "rough consensus" between
the existing committers.
</p>
<p>
The aim in elevating contributors to committers is to ensure that there
is a broad base of experience and expertize across all areas of the
project's work. Committers are not required to have knowledge across
all areas of the project's work. While an approved committer has the
technical ability to commit code to any area of the project, by convention
they will only commit to areas they feel themselves to be qualified to
evaluate the contribution. If in doubt, committers will defer to the
opinion of other committers with greater expertize in an area.
</p>
<p>
The committers hold the ultimate control over what contributions are
accepted by the project, however, this does not mean they have the
right to do whatever they want. Where there is debate and disagreement
between contributors, committers are expected to look at the issues with
an unbiased point of view and help achieve a "rough consensus". If the
committer has a conflict of interest in the discussion, for example due
to their position of employment, they are expected to put the needs of
the community project first. If they cannot put the community project
first, they must declare their conflict of interest, and allow other
non-conflicted committers to make any final decision.
</p>
<p>
The committers are expected to monitor contributions to areas of the
project where they have expertize and ensure that either some form of
feedback is provided to the contributor, or to accept their contribution.
There is no formal minimum level of approval required to accept a
contribution. Positive review by any committer experienced in the area
of work is considered to be enough to justify acceptance in normal
circumstances. Where one committer explicitly rejects a contribution,
however, other committers should not override that rejection without
first establishing a "rough consensus" amongst the broader group of
committers.
</p>
<p>
Being a committer is a privilege, not a right. In exceptional
circumstances, the privilege may be removed from an active
contributor. Such decisions will be taken based on "rough
consensus" amongst other committers. In the event that a committer
is no longer able to participate in the project, after some period
of inactivity passes, they may be asked to confirm that they wish
to retain their role as a committer.
</p>
<h3><a name="secteam">Security team</a></h3>
<p>
The security team consists of a subset of the project committers
along with representatives from vendors shipping the project's
software. The subset of project committers is chosen to be the
minimal size necessary to provide expertise spanning most of
the project's work. Further project committers may be requested
to engage in resolving specific security issues on a case by
case basis. Any vendor who is shipping the project's software
may submit a request for one or more of their representatives
to join the security team. Such requests must by approved by
existing members of the team vouching for the integrity of
the nominated person or organization.
</p>
<p>
Members of the security team are responsible for triaging and
resolving any security issues that are reported to the project.
They are expected to abide by the project's documented
<a href="securityprocess.html">security process</a>. In particular
they must respect any embargo period agreed amongst the team
before disclosing a private issue.
</p>
<h2><a name="roughconsensus">Rough consensus</a></h2>
<p>
A core concept for governance of the project described above is
that of "rough consensus". To expand on this, it is a process
of decision making that involves the following steps
</p>
<ul>
<li>Proposal</li>
<li>Discussion</li>
<li>Vote (exceptional circumstances only)</li>
<li>Decision</li>
</ul>
<p>
To put this into words, any contributor is welcome to make a proposal
for consideration. Any contributor may participate in the discussions
around the proposal. The discussion will usually result in agreement
between the interested parties, or at least agreement between the
committers. Only in the very exceptional circumstance where there
is disagreement between committers, would a vote be considered.
Even in these exceptional circumstances, it is usually found to be
obvious what the majority opinion of the committers is. In the event
that even a formal vote is tied, the committers will have to hold
ongoing discussions until the stalemate is resolved or the proposal
withdrawn.
</p>
<p>
The overall goal of the "rough consensus" process is to ensure that
decisions can be made within the project, with a minimum level of
bureaucracy and process. Implicit in this is that any person who does
not explicitly reject to a proposal is assumed to be supportive, or
at least agnostic.
</p>
</body>
</html>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Contributor guidelines</h1>
@@ -45,7 +43,7 @@
--to=libvir-list@redhat.com master
</pre>
<p>(Note that the "git send-email" subcommand may not be in
the main git package and using it may require installation of a
the main git package and using it may require installion of a
separate package, for example the "git-email" package in
Fedora.) For a single patch you can omit
<code>--cover-letter</code>, but a series of two or more
@@ -118,18 +116,6 @@
variables.
</p>
<p>
Some tests are skipped by default in a development environment,
based on the time they take in comparison to the likelihood
that those tests will turn up problems during incremental builds.
These tests default to being run when when building from a
tarball or with the configure option --enable-expensive-tests;
you can also force a one-time toggle of these tests by
setting VIR_TEST_EXPENSIVE to 0 or 1 at make time, as in:
</p>
<pre>
make check VIR_TEST_EXPENSIVE=1
</pre>
<p>
If you encounter any failing tests, the VIR_TEST_DEBUG
environment variable may provide extra information to debug
@@ -141,17 +127,6 @@
VIR_TEST_DEBUG=1 make check (or)
VIR_TEST_DEBUG=2 make check
</pre>
<p>
When debugging failures during development, it is possible
to focus in on just the failing subtests by using TESTS and
VIR_TEST_RANGE:
</p>
<pre>
make check VIR_TEST_DEBUG=1 VIR_TEST_RANGE=3-5 TESTS=qemuxml2argvtest
</pre>
<p>
Also, individual tests can be run from inside the <code>tests/</code>
directory, like:
@@ -236,7 +211,7 @@
not suppress real leaks, but it should be generic enough to
cover multiple code paths. The format of the entry can be
found in the documentation found at the
<a href="http://valgrind.org/">Valgrind home page</a>.
<a href="http://valgrind.org/">Valgrind home page.</a>
The following trace was added to <code>tests/.valgrind.supp</code>
in order to suppress the warning:
</p>
@@ -261,7 +236,7 @@
There is more on this subject, including lots of links to background
reading on the subject, on
<a href="http://et.redhat.com/~rjones/how-to-supply-code-to-open-source-projects/">
Richard Jones' guide to working with open source projects</a>.
Richard Jones' guide to working with open source projects</a>
</p>
@@ -273,11 +248,26 @@
In short, use spaces-not-TABs for indentation, use 4 spaces for each
indentation level, and other than that, follow the K&amp;R style.
</p>
<p>
If you use Emacs, add the following to one of one of your start-up files
(e.g., ~/.emacs), to help ensure that you get indentation right:
</p>
<pre>
;;; When editing C sources in libvirt, use this style.
(defun libvirt-c-mode ()
"C mode with adjusted defaults for use with libvirt."
(interactive)
(c-set-style "K&amp;R")
(setq indent-tabs-mode nil) ; indent using spaces, not TABs
(setq c-indent-level 4)
(setq c-basic-offset 4))
(add-hook 'c-mode-hook
'(lambda () (if (string-match "/libvirt" (buffer-file-name))
(libvirt-c-mode))))
</pre>
<p>
If you use Emacs, the project includes a file .dir-locals.el
that sets up the preferred indentation. If you use vim,
append the following to your ~/.vimrc file:
If you use vim, append the following to your ~/.vimrc file:
</p>
<pre>
set nocompatible
@@ -288,7 +278,7 @@
set tabstop=8
set shiftwidth=4
set expandtab
set cinoptions=(0,:0,l1,t0,L3
set cinoptions=(0,:0,l1,t0
filetype plugin indent on
au FileType make setlocal noexpandtab
au BufRead,BufNewFile *.am setlocal noexpandtab
@@ -387,72 +377,6 @@
int foo(int wizz); // Good
</pre>
<h2><a name="comma">Commas</a></h2>
<p>
Commas should always be followed by a space or end of line, and
never have leading space; this is enforced during 'make
syntax-check'.
</p>
<pre>
call(a,b ,c);// Bad
call(a, b, c); // Good
</pre>
<p>
When declaring an enum or using a struct initializer that
occupies more than one line, use a trailing comma. That way,
future edits to extend the list only have to add a line, rather
than modify an existing line to add the intermediate comma. Any
sentinel enumerator value with a name ending in _LAST is exempt,
since you would extend such an enum before the _LAST element.
Another reason to favor trailing commas is that it requires less
effort to produce via code generators. Note that the syntax
checker is unable to enforce a style of trailing commas, so
there are counterexamples in existing code which do not use it;
also, while C99 allows trailing commas, remember that JSON and
XDR do not.
</p>
<pre>
enum {
VALUE_ONE,
VALUE_TWO // Bad
};
enum {
VALUE_THREE,
VALUE_FOUR, // Good
};
</pre>
<h2><a name="semicolon">Semicolons</a></h2>
<p>
Semicolons should never have a space beforehand. Inside the
condition of a <code>for</code> loop, there should always be a
space or line break after each semicolon, except for the special
case of an infinite loop (although more infinite loops
use <code>while</code>). While not enforced, loop counters
generally use post-increment.
</p>
<pre>
for (i = 0 ;i &lt; limit ; ++i) { // Bad
for (i = 0; i &lt; limit; i++) { // Good
for (;;) { // ok
while (1) { // Better
</pre>
<p>
Empty loop bodies are better represented with curly braces and a
comment, although use of a semicolon is not currently rejected.
</p>
<pre>
while ((rc = waitpid(pid, &amp;st, 0) == -1) &amp;&amp;
errno == EINTR); // ok
while ((rc = waitpid(pid, &amp;st, 0) == -1) &amp;&amp;
errno == EINTR) { // Better
/* nothing */
}
</pre>
<h2><a name="curly_braces">Curly braces</a></h2>
<p>
@@ -595,13 +519,6 @@
<h2><a name="preprocessor">Preprocessor</a></h2>
<p>Macros defined with an ALL_CAPS name should generally be
assumed to be unsafe with regards to arguments with side-effects
(that is, MAX(a++, b--) might increment a or decrement b too
many or too few times). Exceptions to this rule are explicitly
documented for macros in viralloc.h and virstring.h.
</p>
<p>
For variadic macros, stick with C99 syntax:
</p>
@@ -699,7 +616,7 @@
Use of the malloc/free/realloc/calloc APIs is deprecated in the libvirt
codebase, because they encourage a number of serious coding bugs and do
not enable compile time verification of checks for NULL. Instead of these
routines, use the macros from viralloc.h.
routines, use the macros from memory.h.
</p>
<ul>
@@ -708,8 +625,10 @@
<pre>
virDomainPtr domain;
if (VIR_ALLOC(domain) &lt; 0)
if (VIR_ALLOC(domain) &lt; 0) {
virReportOOMError();
return NULL;
}
</pre>
</li>
@@ -718,8 +637,10 @@
virDomainPtr domains;
size_t ndomains = 10;
if (VIR_ALLOC_N(domains, ndomains) &lt; 0)
if (VIR_ALLOC_N(domains, ndomains) &lt; 0) {
virReportOOMError();
return NULL;
}
</pre>
</li>
@@ -728,8 +649,10 @@
virDomainPtr *domains;
size_t ndomains = 10;
if (VIR_ALLOC_N(domains, ndomains) &lt; 0)
if (VIR_ALLOC_N(domains, ndomains) &lt; 0) {
virReportOOMError();
return NULL;
}
</pre>
</li>
@@ -741,8 +664,10 @@
virDomainPtr domains;
size_t ndomains = 0;
if (VIR_EXPAND_N(domains, ndomains, 1) &lt; 0)
if (VIR_EXPAND_N(domains, ndomains, 1) &lt; 0) {
virReportOOMError();
return NULL;
}
domains[ndomains - 1] = domain;
</pre></li>
@@ -755,8 +680,10 @@
size_t ndomains = 0;
size_t ndomains_max = 0;
if (VIR_RESIZE_N(domains, ndomains_max, ndomains, 1) &lt; 0)
if (VIR_RESIZE_N(domains, ndomains_max, ndomains, 1) &lt; 0) {
virReportOOMError();
return NULL;
}
domains[ndomains++] = domain;
</pre>
</li>
@@ -928,21 +855,6 @@
virStrncpy(dest, src, strlen(src), sizeof(dest)).
</p>
<pre>
VIR_STRDUP(char *dst, const char *src);
VIR_STRNDUP(char *dst, const char *src, size_t n);
</pre>
<p>
You should avoid using strdup or strndup directly as they do not report
out-of-memory error, and do not allow a NULL source. Use
VIR_STRDUP or VIR_STRNDUP macros instead, which return 0 for
NULL source, 1 for successful copy, and -1 for allocation
failure with the error already reported. In very
specific cases, when you don't want to report the out-of-memory error, you
can use VIR_STRDUP_QUIET or VIR_STRNDUP_QUIET, but such usage is very rare
and usually considered a flaw.
</p>
<h2><a name="strbuf">Variable length string buffer</a></h2>
<p>
@@ -1124,20 +1036,6 @@
retry: If needing to jump upwards (e.g., retry on EINTR)
</pre>
<p>
Top-level labels should be indented by one space (putting them on
the beginning of the line confuses function context detection in git):
</p>
<pre>
int foo()
{
/* ... do stuff ... */
cleanup:
/* ... do other stuff ... */
}
</pre>
<h2><a name="committers">Libvirt committer guidelines</a></h2>

View File

@@ -1,7 +1,5 @@
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="no"/>
@@ -23,18 +21,8 @@
<!-- resolve b/i/code tags in a first pass, because they interfere with line
wrapping in the second pass -->
<xsl:template match="html:b">*<xsl:apply-templates/>*</xsl:template>
<xsl:template match="html:i">'<xsl:apply-templates/>'</xsl:template>
<xsl:template match="html:code">"<xsl:apply-templates/>"</xsl:template>
<!-- likewise, reformat a tags in first pass -->
<xsl:template match="html:a">
<xsl:text> </xsl:text><xsl:apply-templates/>
<xsl:if test="@href">
<xsl:text> &lt;</xsl:text><xsl:value-of select="@href"/>
<xsl:text>&gt;</xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="b">*<xsl:apply-templates/>*</xsl:template>
<xsl:template match="i">'<xsl:apply-templates/>'</xsl:template>
<xsl:template match="code">"<xsl:apply-templates/>"</xsl:template>
</xsl:stylesheet>

View File

@@ -1,7 +1,5 @@
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="wrapstring.xsl"/>
@@ -32,7 +30,7 @@ from docs/hacking.html.in!
<!-- title -->
<xsl:template match="html:h1">
<xsl:template match="h1">
<xsl:text> </xsl:text>
<xsl:value-of select="normalize-space(.)"/>
<xsl:text>
@@ -67,14 +65,14 @@ from docs/hacking.html.in!
<xsl:template match="html:h2">
<xsl:template match="h2">
<xsl:value-of select="$newline"/>
<xsl:call-template name="underline"/>
</xsl:template>
<xsl:template match="html:h3">
<xsl:template match="h3">
<xsl:call-template name="underline">
<xsl:with-param name="char" select="'-'"/>
</xsl:call-template>
@@ -93,13 +91,13 @@ from docs/hacking.html.in!
<xsl:template match="html:ol|html:ul|html:p">
<xsl:template match="ol|ul|p">
<xsl:apply-templates/><xsl:value-of select="$newline"/><xsl:value-of select="$newline"/>
</xsl:template>
<xsl:template match="html:ol/html:li">
<xsl:template match="ol/li">
<xsl:choose>
<xsl:when test=".//node()[position()=last()]/self::pre">(<xsl:value-of select="position()"/>) <xsl:apply-templates/>
</xsl:when>
@@ -111,23 +109,23 @@ from docs/hacking.html.in!
<xsl:template match="html:ul/html:li">- <xsl:apply-templates/><xsl:value-of select="$newline"/><xsl:value-of select="$newline"/>
<xsl:template match="ul/li">- <xsl:apply-templates/><xsl:value-of select="$newline"/><xsl:value-of select="$newline"/>
</xsl:template>
<xsl:template match="html:li/html:ul/html:li">-- <xsl:apply-templates/><xsl:value-of select="$newline"/><xsl:value-of select="$newline"/>
<xsl:template match="li/ul/li">-- <xsl:apply-templates/><xsl:value-of select="$newline"/><xsl:value-of select="$newline"/>
</xsl:template>
<!-- add newline before nested <ul> -->
<xsl:template match="html:li/html:ul"><xsl:value-of select="$newline"/><xsl:value-of select="$newline"/><xsl:apply-templates/>
<xsl:template match="li/ul"><xsl:value-of select="$newline"/><xsl:value-of select="$newline"/><xsl:apply-templates/>
</xsl:template>
<xsl:template match="html:pre">
<xsl:template match="pre">
<xsl:choose>
<xsl:when test="starts-with(.,'&#xA;')"><xsl:value-of select="substring(.,2)"/><xsl:value-of select="$newline"/>
</xsl:when>
@@ -138,4 +136,12 @@ from docs/hacking.html.in!
</xsl:template>
<xsl:template match="a">
<xsl:value-of select="$newline"/><xsl:value-of select="$newline"/>
<xsl:text> </xsl:text><xsl:apply-templates/>
<xsl:value-of select="$newline"/>
<xsl:text> </xsl:text><xsl:value-of select="@href"/>
</xsl:template>
</xsl:stylesheet>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1>Hooks for specific system management</h1>
@@ -13,15 +12,9 @@
actions occur:</p>
<ul>
<li>The libvirt daemon starts, stops, or reloads its
configuration
(<span class="since">since 0.8.0</span>)<br/><br/></li>
<li>A QEMU guest is started or stopped
(<span class="since">since 0.8.0</span>)<br/><br/></li>
<li>An LXC guest is started or stopped
(<span class="since">since 0.8.0</span>)<br/><br/></li>
<li>A network is started or stopped or an interface is
plugged/unplugged to/from the network
(<span class="since">since 1.2.2</span>)<br/><br/></li>
configuration<br/><br/></li>
<li>A QEMU guest is started or stopped<br/><br/></li>
<li>An LXC guest is started or stopped<br/><br/></li>
</ul>
<h2><a name="location">Script location</a></h2>
@@ -50,9 +43,6 @@
Executed when a QEMU guest is started, stopped, or migrated<br/><br/></li>
<li><code>/etc/libvirt/hooks/lxc</code><br /><br/>
Executed when an LXC guest is started or stopped</li>
<li><code>/etc/libvirt/hooks/network</code><br/><br/>
Executed when a network is started or stopped or an
interface is plugged/unplugged to/from the network</li>
</ul>
<br/>
@@ -75,39 +65,6 @@
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>
<p>For all cases, stdin of the network hook script is provided with the
full XML description of the network status in the following form:</p>
<pre>&lt;hookData&gt;
&lt;network&gt;
&lt;name&gt;$network_name&lt;/name&gt;
&lt;uuid&gt;afca425a-2c3a-420c-b2fb-dd7b4950d722&lt;/uuid&gt;
...
&lt;/network&gt;
&lt;/hookData&gt;</pre>
<p>In the case of an interface
being plugged/unplugged to/from the network, the network XML will be
followed with the full XML description of the domain containing the
interface that is being plugged/unplugged:</p>
<pre>&lt;hookData&gt;
&lt;network&gt;
&lt;name&gt;$network_name&lt;/name&gt;
&lt;uuid&gt;afca425a-2c3a-420c-b2fb-dd7b4950d722&lt;/uuid&gt;
...
&lt;/network&gt;
&lt;domain type='$domain_type' id='$domain_id'&gt;
&lt;name&gt;$domain_name&lt;/name&gt;
&lt;uuid&gt;afca425a-2c3a-420c-b2fb-dd7b4950d722&lt;/uuid&gt;
...
&lt;/domain&gt;
&lt;/hookData&gt;</pre>
<p>Please note that this approach is different from other cases such as
<code>daemon</code>, <code>qemu</code> or <code>lxc</code> hook scripts,
because two XMLs may be passed here, while in the other cases only a single
XML is passed.</p>
<p>The command line arguments take this approach:</p>
<ol>
@@ -223,49 +180,25 @@
<pre>/etc/libvirt/hooks/lxc guest_name reconnect begin -</pre>
</li>
</ul>
<h5><a name="network">/etc/libvirt/hooks/network</a></h5>
<ul>
<li><span class="since">Since 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>
<li>After the network is started, up &and; running, the script is
called as:<br/>
<pre>/etc/libvirt/hooks/network network_name started begin -</pre></li>
<li>When a network is shut down, this script is called as:<br/>
<pre>/etc/libvirt/hooks/network network_name stopped end -</pre></li>
<li>Later, when network is started and there's an interface from a
domain to be plugged into the network, 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>
<li>When 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/>
<h2><a name="execution">Script execution</a></h2>
<ul>
<li>The "start" operation for the guest and network hook scripts,
executes <b>prior</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>
<li>The "shutdown" operation for the guest and network hook scripts,
executes <b>after</b> the object (guest or network) has stopped. If
the hook script indicates failure in its return, the shut down of the
object cannot be aborted because it has already been performed.
<br/><br/></li>
<li>The "start" operation for the guest hook scripts, qemu and lxc,
executes <b>prior</b> to the guest being created. This allows the
guest start operation to be aborted if the script returns indicating
failure.<br/><br/></li>
<li>The "shutdown" operation for the guest hook scripts, qemu and lxc,
executes <b>after</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>
<li>Hook scripts execute in a synchronous fashion. Libvirt waits
for them to return before continuing the given operation.<br/><br/>
This is most noticeable with the guest or network start operation,
as a lengthy operation in the hook script can mean an extended wait
for the guest or network to be available to end users.<br/><br/></li>
This is most noticeable with the guest start operation, as a lengthy
operation in the hook script can mean an extended wait for the guest
to be available to end users.<br/><br/></li>
<li>For a hook script to be utilised, it must have its execute bit set
(e.g. chmod o+rx <i>qemu</i>), and must be present when the libvirt
(ie. chmod o+rx <i>qemu</i>), and must be present when the libvirt
daemon is started.<br/><br/></li>
<li>If a hook script is added to a host after the libvirt daemon is
already running, it won't be used until the libvirt daemon

View File

@@ -169,13 +169,6 @@ $apis{virDomainMigratePerform3} = "0.9.2";
$apis{virDomainMigrateFinish3} = "0.9.2";
$apis{virDomainMigrateConfirm3} = "0.9.2";
$apis{virDomainMigrateBegin3Params} = "1.1.0";
$apis{virDomainMigratePrepare3Params} = "1.1.0";
$apis{virDomainMigratePrepareTunnel3Params} = "1.1.0";
$apis{virDomainMigratePerform3Params} = "1.1.0";
$apis{virDomainMigrateFinish3Params} = "1.1.0";
$apis{virDomainMigrateConfirm3Params} = "1.1.0";
# Now we want to get the mapping between public APIs
@@ -348,9 +341,7 @@ foreach my $drv (keys %{$groups{"virDriver"}->{drivers}}) {
# Finally we generate the HTML file with the tables
print <<EOF;
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<head>
<title>libvirt API support matrix</title>
</head>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<?xml version="1.0"?>
<html>
<body>
<h1>The virtualization API</h1>
@@ -30,11 +29,6 @@
<li>
A <a href="/qpid/">QMF agent</a> for the AMQP/QPid messaging system
</li>
<li>
A <a href="governance.html">technical meritocracy</a>, in which
participants gain influence over a project through recognition
of their contributions.
</li>
</ul>
<h2>libvirt supports:</h2>
@@ -74,9 +68,6 @@
<li>
The <a href="http://libvirt.org/drvparallels.html">Parallels</a> hypervisor
</li>
<li>
The <a href="http://libvirt.org/drvbhyve.html">Bhyve</a> hypervisor
</li>
<li>
Virtual networks using bridging, NAT, VEPA and VN-LINK.
</li>

View File

@@ -127,9 +127,9 @@ DB=None
def createTable(db, name):
global TABLES
if db is None:
if db == None:
return -1
if name is None:
if name == None:
return -1
c = db.cursor()
@@ -147,7 +147,7 @@ def createTable(db, name):
def checkTables(db, verbose = 1):
global TABLES
if db is None:
if db == None:
return -1
c = db.cursor()
nbtables = c.execute("show tables")
@@ -191,7 +191,7 @@ def checkTables(db, verbose = 1):
def openMySQL(db="libvir", passwd=None, verbose = 1):
global DB
if passwd is None:
if passwd == None:
try:
passwd = os.environ["MySQL_PASS"]
except:
@@ -199,7 +199,7 @@ def openMySQL(db="libvir", passwd=None, verbose = 1):
sys.exit(1)
DB = MySQLdb.connect(passwd=passwd, db=db)
if DB is None:
if DB == None:
return -1
ret = checkTables(DB, verbose)
return ret
@@ -207,13 +207,13 @@ def openMySQL(db="libvir", passwd=None, verbose = 1):
def updateWord(name, symbol, relevance):
global DB
if DB is None:
if DB == None:
openMySQL()
if DB is None:
if DB == None:
return -1
if name is None:
if name == None:
return -1
if symbol is None:
if symbol == None:
return -1
c = DB.cursor()
@@ -238,15 +238,15 @@ def updateSymbol(name, module, type, desc):
global DB
updateWord(name, name, 50)
if DB is None:
if DB == None:
openMySQL()
if DB is None:
if DB == None:
return -1
if name is None:
if name == None:
return -1
if module is None:
if module == None:
return -1
if type is None:
if type == None:
return -1
try:
@@ -299,11 +299,11 @@ def addFunctype(name, module, desc = ""):
def addPage(resource, title):
global DB
if DB is None:
if DB == None:
openMySQL()
if DB is None:
if DB == None:
return -1
if resource is None:
if resource == None:
return -1
c = DB.cursor()
@@ -327,17 +327,17 @@ def addPage(resource, title):
def updateWordHTML(name, resource, desc, id, relevance):
global DB
if DB is None:
if DB == None:
openMySQL()
if DB is None:
if DB == None:
return -1
if name is None:
if name == None:
return -1
if resource is None:
if resource == None:
return -1
if id is None:
if id == None:
id = ""
if desc is None:
if desc == None:
desc = ""
else:
try:
@@ -367,11 +367,11 @@ def updateWordHTML(name, resource, desc, id, relevance):
def checkXMLMsgArchive(url):
global DB
if DB is None:
if DB == None:
openMySQL()
if DB is None:
if DB == None:
return -1
if url is None:
if url == None:
return -1
c = DB.cursor()
@@ -379,7 +379,7 @@ def checkXMLMsgArchive(url):
ret = c.execute(
"""SELECT ID FROM archives WHERE resource='%s'""" % (url))
row = c.fetchone()
if row is None:
if row == None:
return -1
except:
return -1
@@ -389,13 +389,13 @@ def checkXMLMsgArchive(url):
def addXMLMsgArchive(url, title):
global DB
if DB is None:
if DB == None:
openMySQL()
if DB is None:
if DB == None:
return -1
if url is None:
if url == None:
return -1
if title is None:
if title == None:
title = ""
else:
title = string.replace(title, "'", " ")
@@ -408,7 +408,7 @@ def addXMLMsgArchive(url, title):
cmd = """SELECT ID FROM archives WHERE resource='%s'""" % (url)
ret = c.execute(cmd)
row = c.fetchone()
if row is None:
if row == None:
print "addXMLMsgArchive failed to get the ID: %s" % (url)
return -1
except:
@@ -420,13 +420,13 @@ def addXMLMsgArchive(url, title):
def updateWordArchive(name, id, relevance):
global DB
if DB is None:
if DB == None:
openMySQL()
if DB is None:
if DB == None:
return -1
if name is None:
if name == None:
return -1
if id is None:
if id == None:
return -1
c = DB.cursor()
@@ -533,9 +533,9 @@ def splitIdentifier(str):
def addWord(word, module, symbol, relevance):
global wordsDict
if word is None or len(word) < 3:
if word == None or len(word) < 3:
return -1
if module is None or symbol is None:
if module == None or symbol == None:
return -1
if dropWords.has_key(word):
return 0
@@ -544,7 +544,7 @@ def addWord(word, module, symbol, relevance):
if wordsDict.has_key(word):
d = wordsDict[word]
if d is None:
if d == None:
return 0
if len(d) > 500:
wordsDict[word] = None
@@ -559,7 +559,7 @@ def addWord(word, module, symbol, relevance):
return relevance
def addString(str, module, symbol, relevance):
if str is None or len(str) < 3:
if str == None or len(str) < 3:
return -1
ret = 0
str = cleanupWordsString(str)
@@ -573,9 +573,9 @@ def addString(str, module, symbol, relevance):
def addWordHTML(word, resource, id, section, relevance):
global wordsDictHTML
if word is None or len(word) < 3:
if word == None or len(word) < 3:
return -1
if resource is None or section is None:
if resource == None or section == None:
return -1
if dropWords.has_key(word):
return 0
@@ -586,14 +586,14 @@ def addWordHTML(word, resource, id, section, relevance):
if wordsDictHTML.has_key(word):
d = wordsDictHTML[word]
if d is None:
if d == None:
print "skipped %s" % (word)
return 0
try:
(r,i,s) = d[resource]
if i is not None:
if i != None:
id = i
if s is not None:
if s != None:
section = s
relevance = relevance + r
except:
@@ -605,7 +605,7 @@ def addWordHTML(word, resource, id, section, relevance):
return relevance
def addStringHTML(str, resource, id, section, relevance):
if str is None or len(str) < 3:
if str == None or len(str) < 3:
return -1
ret = 0
str = cleanupWordsString(str)
@@ -626,9 +626,9 @@ def addStringHTML(str, resource, id, section, relevance):
def addWordArchive(word, id, relevance):
global wordsDictArchive
if word is None or len(word) < 3:
if word == None or len(word) < 3:
return -1
if id is None or id == -1:
if id == None or id == -1:
return -1
if dropWords.has_key(word):
return 0
@@ -637,7 +637,7 @@ def addWordArchive(word, id, relevance):
if wordsDictArchive.has_key(word):
d = wordsDictArchive[word]
if d is None:
if d == None:
print "skipped %s" % (word)
return 0
try:
@@ -652,7 +652,7 @@ def addWordArchive(word, id, relevance):
return relevance
def addStringArchive(str, id, relevance):
if str is None or len(str) < 3:
if str == None or len(str) < 3:
return -1
ret = 0
str = cleanupWordsString(str)
@@ -683,9 +683,9 @@ def loadAPI(filename):
return doc
def foundExport(file, symbol):
if file is None:
if file == None:
return 0
if symbol is None:
if symbol == None:
return 0
addFunction(symbol, file)
l = splitIdentifier(symbol)
@@ -697,7 +697,7 @@ def analyzeAPIFile(top):
count = 0
name = top.prop("name")
cur = top.children
while cur is not None:
while cur != None:
if cur.type == 'text':
cur = cur.next
continue
@@ -712,7 +712,7 @@ def analyzeAPIFiles(top):
count = 0
cur = top.children
while cur is not None:
while cur != None:
if cur.type == 'text':
cur = cur.next
continue
@@ -725,10 +725,10 @@ def analyzeAPIFiles(top):
def analyzeAPIEnum(top):
file = top.prop("file")
if file is None:
if file == None:
return 0
symbol = top.prop("name")
if symbol is None:
if symbol == None:
return 0
addEnum(symbol, file)
@@ -740,10 +740,10 @@ def analyzeAPIEnum(top):
def analyzeAPIConst(top):
file = top.prop("file")
if file is None:
if file == None:
return 0
symbol = top.prop("name")
if symbol is None:
if symbol == None:
return 0
addConst(symbol, file)
@@ -755,10 +755,10 @@ def analyzeAPIConst(top):
def analyzeAPIType(top):
file = top.prop("file")
if file is None:
if file == None:
return 0
symbol = top.prop("name")
if symbol is None:
if symbol == None:
return 0
addType(symbol, file)
@@ -769,10 +769,10 @@ def analyzeAPIType(top):
def analyzeAPIFunctype(top):
file = top.prop("file")
if file is None:
if file == None:
return 0
symbol = top.prop("name")
if symbol is None:
if symbol == None:
return 0
addFunctype(symbol, file)
@@ -783,10 +783,10 @@ def analyzeAPIFunctype(top):
def analyzeAPIStruct(top):
file = top.prop("file")
if file is None:
if file == None:
return 0
symbol = top.prop("name")
if symbol is None:
if symbol == None:
return 0
addStruct(symbol, file)
@@ -795,7 +795,7 @@ def analyzeAPIStruct(top):
addWord(word, file, symbol, 10)
info = top.prop("info")
if info is not None:
if info != None:
info = string.replace(info, "'", " ")
info = string.strip(info)
l = string.split(info)
@@ -806,17 +806,17 @@ def analyzeAPIStruct(top):
def analyzeAPIMacro(top):
file = top.prop("file")
if file is None:
if file == None:
return 0
symbol = top.prop("name")
if symbol is None:
if symbol == None:
return 0
symbol = string.replace(symbol, "'", " ")
symbol = string.strip(symbol)
info = None
cur = top.children
while cur is not None:
while cur != None:
if cur.type == 'text':
cur = cur.next
continue
@@ -829,7 +829,7 @@ def analyzeAPIMacro(top):
for word in l:
addWord(word, file, symbol, 10)
if info is None:
if info == None:
addMacro(symbol, file)
print "Macro %s description has no <info>" % (symbol)
return 0
@@ -845,17 +845,17 @@ def analyzeAPIMacro(top):
def analyzeAPIFunction(top):
file = top.prop("file")
if file is None:
if file == None:
return 0
symbol = top.prop("name")
if symbol is None:
if symbol == None:
return 0
symbol = string.replace(symbol, "'", " ")
symbol = string.strip(symbol)
info = None
cur = top.children
while cur is not None:
while cur != None:
if cur.type == 'text':
cur = cur.next
continue
@@ -863,23 +863,23 @@ def analyzeAPIFunction(top):
info = cur.content
elif cur.name == "return":
rinfo = cur.prop("info")
if rinfo is not None:
if rinfo != None:
rinfo = string.replace(rinfo, "'", " ")
rinfo = string.strip(rinfo)
addString(rinfo, file, symbol, 7)
elif cur.name == "arg":
ainfo = cur.prop("info")
if ainfo is not None:
if ainfo != None:
ainfo = string.replace(ainfo, "'", " ")
ainfo = string.strip(ainfo)
addString(ainfo, file, symbol, 5)
name = cur.prop("name")
if name is not None:
if name != None:
name = string.replace(name, "'", " ")
name = string.strip(name)
addWord(name, file, symbol, 7)
cur = cur.next
if info is None:
if info == None:
print "Function %s description has no <info>" % (symbol)
addFunction(symbol, file, "")
else:
@@ -898,7 +898,7 @@ def analyzeAPISymbols(top):
count = 0
cur = top.children
while cur is not None:
while cur != None:
if cur.type == 'text':
cur = cur.next
continue
@@ -923,14 +923,14 @@ def analyzeAPISymbols(top):
def analyzeAPI(doc):
count = 0
if doc is None:
if doc == None:
return -1
root = doc.getRootElement()
if root.name != "api":
print "Unexpected root name"
return -1
cur = root.children
while cur is not None:
while cur != None:
if cur.type == 'text':
cur = cur.next
continue
@@ -1056,7 +1056,7 @@ def analyzeHTMLPages():
import time
def getXMLDateArchive(t = None):
if t is None:
if t == None:
t = time.time()
T = time.gmtime(t)
month = time.strftime("%B", T)
@@ -1065,7 +1065,7 @@ def getXMLDateArchive(t = None):
return url
def scanXMLMsgArchive(url, title, force = 0):
if url is None or title is None:
if url == None or title == None:
return 0
ID = checkXMLMsgArchive(url)
@@ -1082,7 +1082,7 @@ def scanXMLMsgArchive(url, title, force = 0):
doc = libxml2.htmlParseFile(url, None)
except:
doc = None
if doc is None:
if doc == None:
print "Failed to parse %s" % (url)
return 0
@@ -1105,7 +1105,7 @@ def scanXMLDateArchive(t = None, force = 0):
doc = libxml2.htmlParseFile(url, None)
except:
doc = None
if doc is None:
if doc == None:
print "Failed to parse %s" % (url)
return -1
ctxt = doc.xpathNewContext()
@@ -1114,16 +1114,16 @@ def scanXMLDateArchive(t = None, force = 0):
newmsg = 0
for anchor in anchors:
href = anchor.prop("href")
if href is None or href[0:3] != "msg":
if href == None or href[0:3] != "msg":
continue
try:
links = links + 1
msg = libxml2.buildURI(href, url)
title = anchor.content
if title is not None and title[0:4] == 'Re: ':
if title != None and title[0:4] == 'Re: ':
title = title[4:]
if title is not None and title[0:6] == '[xml] ':
if title != None and title[0:6] == '[xml] ':
title = title[6:]
newmsg = newmsg + scanXMLMsgArchive(msg, title, force)
@@ -1148,7 +1148,7 @@ def analyzeArchives(t = None, force = 0):
skipped = 0
for word in wordsDictArchive.keys():
refs = wordsDictArchive[word]
if refs is None:
if refs == None:
skipped = skipped + 1
continue
for id in refs.keys():
@@ -1168,7 +1168,7 @@ def analyzeHTMLTop():
skipped = 0
for word in wordsDictHTML.keys():
refs = wordsDictHTML[word]
if refs is None:
if refs == None:
skipped = skipped + 1
continue
for resource in refs.keys():
@@ -1197,7 +1197,7 @@ def analyzeAPITop():
skipped = 0
for word in wordsDict.keys():
refs = wordsDict[word]
if refs is None:
if refs == None:
skipped = skipped + 1
continue
for (module, symbol) in refs.keys():

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>libvirt internals</h1>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Spawning processes / commands from libvirt drivers</h1>
@@ -258,9 +256,8 @@
<pre>
int sharedfd = open("cmd.log", "w+");
int childfd = open("conf.txt", "r");
virCommandPassFD(cmd, sharedfd, 0);
virCommandPassFD(cmd, childfd,
VIR_COMMAND_PASS_FD_CLOSE_PARENT);
virCommandPreserveFD(cmd, sharedfd);
virCommandTransferFD(cmd, childfd);
if (VIR_CLOSE(sharedfd) &lt; 0)
goto cleanup;
</pre>
@@ -430,7 +427,7 @@
if (string)
VIR_DEBUG("about to run %s", string);
VIR_FREE(string);
if (virCommandRun(cmd, NULL) &lt; 0)
if (virCommandRun(cmd) &lt; 0)
return -1;
</pre>
@@ -458,24 +455,15 @@
non-zero exit status can represent a success condition,
it is possible to request the exit status and perform
that check manually instead of letting <code>virCommandRun</code>
raise the error. By default, the captured status is only
for a normal exit (death from a signal is treated as an error),
but a caller can use <code>virCommandRawStatus</code> to get
encoded status that includes any terminating signals.
raise the error
</p>
<pre>
int status;
if (virCommandRun(cmd, &amp;status) &lt; 0)
return -1;
if (status == 1) {
...do stuff...
}
return -1;
virCommandRawStatus(cmd2);
if (virCommandRun(cmd2, &amp;status) &lt; 0)
return -1;
if (WIFEXITED(status) &amp;&amp; WEXITSTATUS(status) == 1) {
if (WEXITSTATUS(status) ...) {
...do stuff...
}
</pre>
@@ -547,7 +535,7 @@
There is no need to check if <code>cmd</code> is NULL
before calling <code>virCommandFree</code>. This scenario
is handled automatically. If the command is still running,
it will be forcibly killed and cleaned up (via waitpid).
it will be forcably killed and cleaned up (via waitpid).
</p>
<h2><a name="example">Complete examples</a></h2>
@@ -560,8 +548,7 @@
<pre>
int runhook(const char *drvstr, const char *id,
const char *opstr, const char *subopstr,
const char *extra)
{
const char *extra) {
int ret;
char *path;
virCommandPtr cmd;

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>Resource Lock Manager</h1>

View File

@@ -1,213 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<h1>Out of memory testing</h1>
<ul id="toc"></ul>
<p>
This page describes how to use the test suite todo out of memory
testing.
</p>
<h2>Building with OOM testing</h2>
<p>
Since OOM testing requires hooking into the malloc APIs, it is
not enabled by default. The flag <code>--enable-test-oom</code>
must be given to <code>configure</code>. When this is done the
libvirt allocation APIs will have some hooks enabled.
</p>
<pre>
$ ./configure --enable-test-oom
</pre>
<h2><a name="basicoom">Basic OOM testing support</a></h2>
<p>
The first step in validating OOM usage is to run a test suite
with full OOM testing enabled. This is done by setting the
<code>VIR_TEST_OOM=1</code> environment variable. The way this
works is that it runs the test once normally to "prime" any
static memory allocations. Then it runs it once more counting
the total number of memory allocations. Then it runs it in a
loop failing a different memory allocation each time. For every
memory allocation failure triggered, it expects the test case
to return an error. OOM testing is quite slow requiring each
test case to be executed O(n) times, where 'n' is the total
number of memory allocations. This results in a total number
of memory allocations of '(n * (n + 1) ) / 2'
</p>
<pre>
$ VIR_TEST_OOM=1 ./qemuxml2argvtest
1) QEMU XML-2-ARGV minimal ... OK
Test OOM for nalloc=42 .......................................... OK
2) QEMU XML-2-ARGV minimal-s390 ... OK
Test OOM for nalloc=28 ............................ OK
3) QEMU XML-2-ARGV machine-aliases1 ... OK
Test OOM for nalloc=38 ...................................... OK
4) QEMU XML-2-ARGV machine-aliases2 ... OK
Test OOM for nalloc=38 ...................................... OK
5) QEMU XML-2-ARGV machine-core-on ... OK
Test OOM for nalloc=37 ..................................... OK
...snip...
</pre>
<p>
In this output, the first line shows the normal execution and
the test number, and the second line shows the total number
of memory allocations from that test case.
</p>
<h3><a name="valgrind">Tracking failures with valgrind</a></h3>
<p>
The test suite should obviously *not* crash during OOM testing.
If it does crash, then to assist in tracking down the problem
it is worth using valgrind and only running a single test case.
For example, supposing test case 5 crashed. Then re-run the
test with
</p>
<pre>
$ VIR_TEST_OOM=1 VIR_TEST_RANGE=5 ../run valgrind ./qemuxml2argvtest
...snip...
5) QEMU XML-2-ARGV machine-core-on ... OK
Test OOM for nalloc=37 ..................................... OK
...snip...
</pre>
<p>
Valgrind should report the cause of the crash - for example a
double free or use of uninitialized memory or NULL pointer
access.
</p>
<h3><a name="stacktraces">Tracking failures with stack traces</a></h3>
<p>
With some really difficult bugs valgrind is not sufficient to
identify the cause. In this case, it is useful to identify the
precise allocation which was failed, to allow the code path
to the error to be traced. The <code>VIR_TEST_OOM</code>
env variable can be given a range of memory allocations to
test. So if a test case has 150 allocations, it can be told
to only test allocation numbers 7-10. The <code>VIR_TEST_OOM_TRACE</code>
variable can be used to print out stack traces.
</p>
<pre>
$ VIR_TEST_OOM_TRACE=2 VIR_TEST_OOM=1:7-10 VIR_TEST_RANGE=5 \
../run valgrind ./qemuxml2argvtest
5) QEMU XML-2-ARGV machine-core-on ... OK
Test OOM for nalloc=37 !virAllocN
/home/berrange/src/virt/libvirt/src/util/viralloc.c:180
virDomainDefParseXML
/home/berrange/src/virt/libvirt/src/conf/domain_conf.c:11786 (discriminator 1)
virDomainDefParseNode
/home/berrange/src/virt/libvirt/src/conf/domain_conf.c:12677
virDomainDefParse
/home/berrange/src/virt/libvirt/src/conf/domain_conf.c:12621
testCompareXMLToArgvFiles
/home/berrange/src/virt/libvirt/tests/qemuxml2argvtest.c:107
virtTestRun
/home/berrange/src/virt/libvirt/tests/testutils.c:266
mymain
/home/berrange/src/virt/libvirt/tests/qemuxml2argvtest.c:388 (discriminator 2)
virtTestMain
/home/berrange/src/virt/libvirt/tests/testutils.c:791
__libc_start_main
??:?
_start
??:?
!virAlloc
/home/berrange/src/virt/libvirt/src/util/viralloc.c:133
virDomainDiskDefParseXML
/home/berrange/src/virt/libvirt/src/conf/domain_conf.c:4790
virDomainDefParseXML
/home/berrange/src/virt/libvirt/src/conf/domain_conf.c:11797
virDomainDefParseNode
/home/berrange/src/virt/libvirt/src/conf/domain_conf.c:12677
virDomainDefParse
/home/berrange/src/virt/libvirt/src/conf/domain_conf.c:12621
testCompareXMLToArgvFiles
/home/berrange/src/virt/libvirt/tests/qemuxml2argvtest.c:107
virtTestRun
/home/berrange/src/virt/libvirt/tests/testutils.c:266
mymain
/home/berrange/src/virt/libvirt/tests/qemuxml2argvtest.c:388 (discriminator 2)
virtTestMain
/home/berrange/src/virt/libvirt/tests/testutils.c:791
__libc_start_main
??:?
_start
??:?
!virAllocN
/home/berrange/src/virt/libvirt/src/util/viralloc.c:180
virXPathNodeSet
/home/berrange/src/virt/libvirt/src/util/virxml.c:609
virDomainDefParseXML
/home/berrange/src/virt/libvirt/src/conf/domain_conf.c:11805
virDomainDefParseNode
/home/berrange/src/virt/libvirt/src/conf/domain_conf.c:12677
virDomainDefParse
/home/berrange/src/virt/libvirt/src/conf/domain_conf.c:12621
testCompareXMLToArgvFiles
/home/berrange/src/virt/libvirt/tests/qemuxml2argvtest.c:107
virtTestRun
/home/berrange/src/virt/libvirt/tests/testutils.c:266
mymain
/home/berrange/src/virt/libvirt/tests/qemuxml2argvtest.c:388 (discriminator 2)
virtTestMain
/home/berrange/src/virt/libvirt/tests/testutils.c:791
__libc_start_main
??:?
_start
??:?
!virAllocN
/home/berrange/src/virt/libvirt/src/util/viralloc.c:180
virDomainDefParseXML
/home/berrange/src/virt/libvirt/src/conf/domain_conf.c:11808 (discriminator 1)
virDomainDefParseNode
/home/berrange/src/virt/libvirt/src/conf/domain_conf.c:12677
virDomainDefParse
/home/berrange/src/virt/libvirt/src/conf/domain_conf.c:12621
testCompareXMLToArgvFiles
/home/berrange/src/virt/libvirt/tests/qemuxml2argvtest.c:107
virtTestRun
/home/berrange/src/virt/libvirt/tests/testutils.c:266
mymain
/home/berrange/src/virt/libvirt/tests/qemuxml2argvtest.c:388 (discriminator 2)
virtTestMain
/home/berrange/src/virt/libvirt/tests/testutils.c:791
__libc_start_main
??:?
_start
??:?
</pre>
<h3><a name="noncrash">Non-crash related problems</a></h3>
<p>
Not all memory allocation bugs result in code crashing. Sometimes
the code will be silently ignoring the allocation failure, resulting
in incorrect data being produced. For example the XML parser may
mistakenly treat an allocation failure as indicating that an XML
attribute was not set in the input document. It is hard to identify
these problems from the test suite automatically. For this, the
test suites should be run with <code>VIR_TEST_DEBUG=1</code> set
and then stderr analysed for any unexpected data. For example,
the XML conversion may show an embedded "(null)" literal, or the
test suite might complain about missing elements / attributes
in the actual vs expected data. These are all signs of bugs in
OOM handling. In the future the OOM tests will be enhanced to
validate that an error VIR_ERR_NO_MEMORY is returned for each
allocation failed, rather than some other error.
</p>
</body>
</html>

View File

@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html>
<body>
<h1>libvirt RPC infrastructure</h1>
@@ -154,7 +152,6 @@
<li>continue: for streams this indicates that further data packets
will be following</li>
</ol>
</dd>
</dl>
<h3><a href="protocolpayload">Packet payload</a></h3>
@@ -743,7 +740,7 @@
<p>
The main libvirt event loop thread is responsible for performing all
socket I/O. It will read incoming packets from clients and will
socket I/O. It will read incoming packets from clients and willl
transmit outgoing packets to clients. It will handle the I/O to/from
streams associated with client API calls. When doing client I/O it
will also pass the data through any applicable encryption layer

Some files were not shown because too many files have changed in this diff Show More