1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-08-20 21:50:07 +03:00

Compare commits

..

74 Commits

Author SHA1 Message Date
a3954cc793 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:28 +01:00
3b7ce055e3 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:28:37 -07:00
26a87db8ea 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:16:51 -06:00
a45c8466fa 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 22:08:57 -06:00
040df62ae7 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-09-17 22:00:36 -06:00
261679a8c3 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:24:45 -06:00
c335cc3cd2 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:24:38 -06:00
1571d2d277 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:14:12 -06:00
ecb305fdbd 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, 632f78c

Conflicts:
	src/qemu/qemu_driver.c
2014-06-26 17:13:59 -06:00
44d63f7c64 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:11:49 +02:00
ca508e884b 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:11:39 +02:00
2f5440b747 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:11:35 +02:00
b2149389af 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:11:32 +02:00
4cbba884fc 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 22:20:11 -06:00
b7d051af20 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 13:02:20 +00:00
1439dddbfb 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.
	src/qemu/qemu_driver.c
          - qemuDomainStartWithFlags (called qemuDomainCreateWithFlags
            upstream) gets the domain object using
            qemuDomObjFromDomain() upstream, but
            virDomainObjListFindByUUID() in 1.0.4. This creates a
            small conflict in context.
2014-02-06 15:40:39 +02:00
8f81b33d90 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:35:24 +02:00
636f78d38e 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
    - *EnsureACL*() was added after this branch was created, and
       caused two small conflicts in the context around a hunk.
    - nwfilterDriverReload() was renamed to nwfilterStateReload()
      upstream.
2014-02-06 15:33:26 +02:00
979a3a9531 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)
2014-02-06 15:29:17 +02:00
a591883ac3 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)
2014-02-06 15:29:13 +02:00
d48b2398d6 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)
2014-02-06 15:23:28 +02:00
9b1e050856 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:58:11 -07:00
4888b0b398 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:58:10 -07:00
473b751d89 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:58:08 -07:00
cd7021934e 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:58:07 -07:00
fa5c087aef 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:58:06 -07:00
e966f1155c 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:58:04 -07:00
d003b8f294 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:58:03 -07:00
89b424e78a 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:57:21 -07:00
301a905fe0 build: use proper pod for nested bulleted VIRSH_DEBUG list
Newer pod (hello rawhide) complains if you attempt to mix bullets
and non-bullets in the same list:

virsh.pod around line 3177: Expected text after =item, not a bullet

As our intent was to nest an inner list, we make that explicit to
keep pod happy.

* tools/virsh.pod (ENVIRONMENT): Use correct pod syntax.

(cherry picked from commit 00d69b4af1)
2014-01-15 10:48:13 -07:00
28923d5a7c 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)
2014-01-15 10:42:20 -07:00
30e8839812 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:22 -06:00
692474e608 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:26:49 +02:00
95983486d9 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:33:24 -06:00
a01514b25d 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 17:39:17 +01:00
65f7c07c9f 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)

Conflicts:
	src/util/virprocess.c
	src/util/virstring.c
	src/util/virstring.h
2013-09-18 17:14:23 +01:00
b68a721d45 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:25:43 +02:00
90adeaad93 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 15:34:40 +02:00
c8c1653f8d 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 15:34:29 +02:00
187ed9000d 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)

Conflicts:
	src/storage/storage_backend_scsi.c
2013-07-01 14:19:14 +02:00
b81fad5ccc 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 13:44:12 +02:00
0eba4bcaad 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-07-01 13:43:59 +02:00
81307698c1 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-07-01 13:43:50 +02:00
ca62fde825 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.

Conflicts:
	src/lxc/lxc_driver.c

  * Resolved conflict by using former lxcCgroupHasController() rather than
    virCgroupHasController()
  * Needed to add the code to fetch the 'vm'
     vm = virDomainObjListFindByUUID(driver->domains, domain->uuid);
     if (vm == NULL) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("No such domain %s"), domain->uuid);
         goto cleanup;
     }
  * Used 'ret = strdup("posix");' rather than VIR_STRDUP(ret, "posix");
    and added the virReportOOMError(); on failure.
2013-06-20 09:38:47 -04:00
94c88b4837 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.

Conflicts:
	src/qemu/qemu_driver.c

 * Resolved conflict by using former qemuCgroupHasController() rather than
   virCgroupHasController()
 * Needed to add the code to fetch the 'vm'
      vm = virDomainObjListFindByUUID(driver->domains, dom->uuid);
      if (vm == NULL) {
          virReportError(VIR_ERR_INTERNAL_ERROR,
                         _("No such domain %s"), dom->uuid);
          goto cleanup;
      }
* Used 'ret = strdup("posix");' rather than VIR_STRDUP(ret, "posix");
  and added the virReportOOMError(); on failure.
2013-06-20 09:38:36 -04:00
5313dd013f 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:46:09 +02:00
aeef630b5d 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:45:51 +02:00
05ea6a17f5 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:45:35 +02:00
1056bbdb27 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:14:43 -04:00
24317824e0 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:01:30 +02:00
107ca3631c 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:19:24 +02:00
ebd29c6b1b iscsi: don't leak portal string when starting a pool
(cherry picked from commit 413274f63b)
2013-05-09 15:18:57 +02:00
a24f6841ec qemu: fix default spice password setting
Set spice password even if default VNC password hasn't been set.

https://bugzilla.redhat.com/show_bug.cgi?id=953720
(cherry picked from commit 4327df7eee)
2013-05-09 15:18:25 +02:00
d0c76414c4 qemu: fix crash in qemuOpen
If the path part of connection URI is not present, cfg is used
unitialized.

https://bugzilla.redhat.com/show_bug.cgi?id=950855
(cherry picked from commit 74bff25090)
2013-05-09 15:16:44 +02:00
4c003e79a4 maint: update to latest gnulib
Upstream gnulib determined that we were needlessly compiling in
gnulib's regex instead of glibc's when targetting new-enough glibc,
because the m4 test was being too strict in requiring a particular
answer to undefined behavior.
https://lists.gnu.org/archive/html/bug-gnulib/2013-04/msg00032.html

* .gnulib: Update to latest, for regex.
(cherry picked from commit 842432390b)

Cherry picked because I hit a failure of test-regex when swapping
between incremental builds of libvirt.git master then v1.0.4-maint.
2013-04-22 16:56:36 -06:00
97cf170624 maint: update to latest gnulib
While this update doesn't address any reported problems in libvirt,
doing a post-release update to latest gnulib makes it easier to
stay in sync with best upstream practices.

* .gnulib: Update to latest.
* bootstrap: Resynchronize.
(cherry picked from commit d7468b7d47)
2013-04-22 16:56:26 -06:00
79c23e0363 audit: properly encode device path in cgroup audit
https://bugzilla.redhat.com/show_bug.cgi?id=922186

Commit d04916fa introduced a regression in audit quality - even
though the code was computing the proper escaped name for a
path, it wasn't feeding that escaped name on to the audit message.
As a result, /var/log/audit/audit.log would mention a pair of
fields class=path path=/dev/hpet instead of the intended
class=path path="/dev/hpet", which in turn caused ausearch to
format the audit log with path=(null).

* src/conf/domain_audit.c (virDomainAuditCgroupPath): Use
constructed encoding.

Signed-off-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 31c6bf35b9)
2013-04-22 14:53:05 -06:00
98afc745f1 sanlock: add missing test command in virt-sanlock-cleanup.in
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=949483

Signed-off-by: Alex Jia <ajia@redhat.com>
(cherry picked from commit c3e33e68d9)
2013-04-09 14:04:03 -06:00
0f641de1be spec: Require pod2man when running autoreconf
Since commit b8a32e0e94, all man pages
depend on configure.ac so that they are properly regenerated whenever
libvirt version changes. Thus libvirt.spec needs to have a build
dependency on pod2man when %{enable_autotools} is set.
(cherry picked from commit 6f1b9c8d2a)
2013-04-09 14:02:23 -06:00
dfb42ed1e9 build: check correct protocol.o file
By default, libtool builds two .o files for every .lo rule:
src/foo.o - static builds
src/.libs/foo.o - shared library builds

But since commit ad42b34b disabled static builds, src/foo.o is
no longer built by default.  On a fresh checkout, this means our
protocol check rules using pdwtags were testing a missing file,
and thanks to a lousy behavior of pdwtags happily giving no output
and 0 exit status (http://bugzilla.redhat.com/949034), we were
merely claiming that "dwarves is too old" and skipping the test.

However, if you swap between branches and do incremental builds,
such as building v0.10.2-maint and then switching back to master,
you end up with src/foo.o being leftover from its 0.10.2 state,
and then 'make check' fails because the .o file does not match
the protocol-structs file due to API additions in the meantime.

A simpler fix would be to always look in .libs for the .o to
be parsed; but since it is possible to pass ./configure options
to tell libtool to do a static-only build with no shared .o,
I went with the approach of finding the newest of the two files,
whenever both exist.

* src/Makefile.am (PDWTAGS): Ensure we test just-built file.
(cherry picked from commit 5899e09e61)
2013-04-09 14:01:24 -06:00
a243e21c22 Ensure LD_PRELOAD exists before running test case
The linker will ignore LD_PRELOAD libraries which do not
exist, just printing a warning message. This is not helpful
for the test suite which will be utterly fubar without the
preload library present. Add an explicit test for existence
of the library to protect against this

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit b1d3154a50)
2013-04-09 14:00:52 -06:00
d6ee211328 rpc: Fix connection close callback race condition and memory corruption/crash
The last Viktor's effort to fix the race and memory corruption unfortunately
wasn't complete in the case the close callback was not registered in an
connection. At that time, the trail of event's that I'll describe later could
still happen and corrupt the memory or cause a crash of the client (including
the daemon in case of a p2p migration).

Consider the following prerequisities and trail of events:
Let's have a remote connection to a hypervisor that doesn't have a close
callback registered and the client is using the event loop. The crash happens in
cooperation of 2 threads. Thread E is the event loop and thread W is the worker
that does some stuff. R denotes the remote client.

1.) W - The client finishes everything and sheds the last reference on the client
2.) W - The virObject stuff invokes virConnectDispose that invokes doRemoteClose
3.) W - the remote close method invokes the REMOTE_PROC_CLOSE RPC method.
4.) W - The thread is preempted at this point.
5.) R - The remote side receives the close and closes the socket.
6.) E - poll() wakes up due to the closed socket and invokes the close callback
7.) E - The event loop is preempted right before remoteClientCloseFunc is called
8.) W - The worker now finishes, and frees the conn object.
9.) E - The remoteClientCloseFunc accesses the now-freed conn object in the
        attempt to retrieve pointer for the real close callback.
10.) Kaboom, corrupted memory/segfault.

This patch tries to fix this by introducing a new object that survives the
freeing of the connection object. We can't increase the reference count on the
connection object itself or the connection would never be closed, as the
connection is closed only when the reference count reaches zero.

The new object - virConnectCloseCallbackData - is a lockable object that keeps
the pointers to the real user registered callback and ensures that the
connection callback is either not called if the connection was already freed or
that the connection isn't freed while this is being called.
(cherry picked from commit 8ad126e695)
2013-04-09 14:00:29 -06:00
3e13977c2e virsh: Register and unregister the close callback also in cmdConnect
This patch improves the error message after disconnecting from the
hypervisor and adds the close callback operations required not to leak
the callback reference.
(cherry picked from commit 69ab07560a)
2013-04-09 13:59:51 -06:00
f4a7891e64 virsh: Move cmdConnect from virsh-host.c to virsh.c
The function is used to establish connection so it should be in the main
virsh file. This movement also enables further improvements done in next
patches.

Note that the "connect" command has moved from the host section of virsh to the
main section. It is now listed by 'virsh help virsh' instead of 'virsh help
host'.
(cherry picked from commit ca9e73ebb6)
2013-04-09 13:59:27 -06:00
bec3cc7308 virsh: Unregister the connection close notifier upon termination
Before closing the connection we unregister the close callback
to prevent a reference leak.

Further, the messages on virConnectClose != 0 are a bit more specific
now.

Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
(cherry picked from commit e964ba2786)
2013-04-09 13:58:48 -06:00
cf7dbdd42a libvirt: Increase connection reference count for callbacks
By adjusting the reference count of the connection object we
prevent races between callback function and virConnectClose.

Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
(cherry picked from commit 03a43efa86)
2013-04-09 13:58:23 -06:00
7156c8c784 storage: Fix volume cloning for logical volume.
When creating a logical volume with virStorageVolCreateXMLFrom,
"qemu-img convert" is called internally if clonevol is a file volume.
Then, vol->target.format is used as output_fmt parameter but the
target.format of logical volumes is always 0 because logical volumes
haven't the volume format type element.

Fortunately, 0 was treated as RAW file format before commit f772b3d9,
so there was no problem. But now, 0 is treated as the type of none,
qemu-img fails with "Unknown file format 'none'".

This patch fixes this issue by treating output block devices as RAW
file format like for input block devices.

Signed-off-by: Atsushi Kumagai <kumagai-atsushi@mxc.nes.nec.co.jp>
(cherry picked from commit d369e50825)
2013-04-09 13:57:26 -06:00
d990d6aeb3 Enable full RELRO mode
By passing the flags -z relro -z now to the linker, we can force
it to resolve all library symbols at startup, instead of on-demand.
This allows it to then make the global offset table (GOT) read-only,
which makes some security attacks harder.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit fc8c1787d8)
2013-04-09 13:55:20 -06:00
f015802380 Build all binaries with PIE
PIE (position independent executable) adds security to executables
by composing them entirely of position-independent code (PIC. The
.so libraries already build with -fPIC. This adds -fPIE which is
the equivalent to -fPIC, but for executables. This for allows Exec
Shield to use address space layout randomization to prevent attackers
from knowing where existing executable code is during a security
attack using exploits that rely on knowing the offset of the
executable code in the binary, such as return-to-libc attacks.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
(cherry picked from commit 1150999ca4)
2013-04-09 13:55:18 -06:00
2a702717ce qemu: Fix crash when updating media with shared device
Mimic the fix done in 02b9097274 to fix crash by
accessing an already freed structure. Also copy the explaining comment why the
pointer can't be accessed any more.
(cherry picked from commit 43b6f304bc)
2013-04-09 13:47:27 -06:00
5fdccc8557 virsh: Call virDomainFree in cmdDomFSTrim
https://bugzilla.redhat.com/show_bug.cgi?id=928197

The virsh domfstrim command was not freeing allocated domain,
leaving leaked references behind.
(cherry picked from commit deb86ee912)
2013-04-09 13:47:24 -06:00
5fa7db63a7 smartcard: spell ccid-card-emulated qemu property correctly
Reported by Anthony Messina in
https://bugzilla.redhat.com/show_bug.cgi?id=904692
Present since introduction of smartcard support in commit f5fd9baa

* src/qemu/qemu_command.c (qemuBuildCommandLine): Match qemu spelling.
* tests/qemuxml2argvdata/qemuxml2argv-smartcard-host-certificates.args:
Fix broken test.
(cherry picked from commit 6f7e4ea359)
2013-04-09 13:46:26 -06:00
ce0bbe7000 Resolve valgrind failure
Code added by commit id '523207fe8'

TEST: qemuxml2argvtest
      ........................................ 40
      ........................................ 80
      ........................................ 120
      ........................................ 160
      ........................................ 200
      ........................................ 240
      .................................        273 OK
==30993== 39 bytes in 1 blocks are definitely lost in loss record 33 of 87
==30993==    at 0x4A0887C: malloc (vg_replace_malloc.c:270)
==30993==    by 0x41E501: fakeSecretGetValue (qemuxml2argvtest.c:33)
==30993==    by 0x427591: qemuBuildDriveURIString (qemu_command.c:2571)
==30993==    by 0x42C502: qemuBuildDriveStr (qemu_command.c:2627)
==30993==    by 0x4335FC: qemuBuildCommandLine (qemu_command.c:6443)
==30993==    by 0x41E8A0: testCompareXMLToArgvHelper (qemuxml2argvtest.c:154
==30993==    by 0x41FE8F: virtTestRun (testutils.c:157)
==30993==    by 0x418BE3: mymain (qemuxml2argvtest.c:506)
==30993==    by 0x4204CA: virtTestMain (testutils.c:719)
==30993==    by 0x38D6821A04: (below main) (in /usr/lib64/libc-2.16.so)
==30993==
==30993== 46 bytes in 1 blocks are definitely lost in loss record 64 of 87
==30993==    at 0x4A0887C: malloc (vg_replace_malloc.c:270)
==30993==    by 0x38D690A167: __vasprintf_chk (in /usr/lib64/libc-2.16.so)
==30993==    by 0x4CB28E7: virVasprintf (stdio2.h:210)
==30993==    by 0x4CB29A3: virAsprintf (virutil.c:2017)
==30993==    by 0x4275B4: qemuBuildDriveURIString (qemu_command.c:2580)
==30993==    by 0x42C502: qemuBuildDriveStr (qemu_command.c:2627)
==30993==    by 0x4335FC: qemuBuildCommandLine (qemu_command.c:6443)
==30993==    by 0x41E8A0: testCompareXMLToArgvHelper (qemuxml2argvtest.c:154
==30993==    by 0x41FE8F: virtTestRun (testutils.c:157)
==30993==    by 0x418BE3: mymain (qemuxml2argvtest.c:506)
==30993==    by 0x4204CA: virtTestMain (testutils.c:719)
==30993==    by 0x38D6821A04: (below main) (in /usr/lib64/libc-2.16.so)
==30993==
==30993== 385 (56 direct, 329 indirect) bytes in 1 blocks are definitely los
==30993==    at 0x4A06B6F: calloc (vg_replace_malloc.c:593)
==30993==    by 0x4C6B2CF: virAllocN (viralloc.c:152)
==30993==    by 0x4C9C7EB: virObjectNew (virobject.c:191)
==30993==    by 0x4D21810: virGetSecret (datatypes.c:642)
==30993==    by 0x41E5D5: fakeSecretLookupByUsage (qemuxml2argvtest.c:51)
==30993==    by 0x4D4BEC5: virSecretLookupByUsage (libvirt.c:15295)
==30993==    by 0x4276A9: qemuBuildDriveURIString (qemu_command.c:2565)
==30993==    by 0x42C502: qemuBuildDriveStr (qemu_command.c:2627)
==30993==    by 0x4335FC: qemuBuildCommandLine (qemu_command.c:6443)
==30993==    by 0x41E8A0: testCompareXMLToArgvHelper (qemuxml2argvtest.c:154
==30993==    by 0x41FE8F: virtTestRun (testutils.c:157)
==30993==    by 0x418BE3: mymain (qemuxml2argvtest.c:506)
==30993==
PASS: qemuxml2argvtest

Interesting side note is that running the test singularly via 'make -C tests
check TESTS=qemuxml2argvtest' didn't trip the valgrind error; however,
running during 'make -C tests valgrind' did cause the error to be seen.
(cherry picked from commit 9a80050e52)
2013-04-09 13:45:42 -06:00
08b700b481 Fix crash in virNetDevGetVirtualFunctions
Commit 9a3ff01d7f (which was ACKed at
the end of January, but for some reason didn't get pushed until during
the 1.0.4 freeze) fixed the logic in virPCIGetVirtualFunctions().
Unfortunately, a typo in the fix (replacing VIR_REALLOC_N with
VIR_ALLOC_N during code movement) caused not only a memory leak, but
also resulted in most of the elements of the result array being
replaced with NULL. virNetDevGetVirtualFunctions() assumed (and I think
rightly so) that virPCIGetVirtualFunctions() wouldn't return any NULL
elements in the array, so it ended up segfaulting.

This was found when attempting to use a virtual network with an
auto-created pool of SRIOV VFs, e.g.:

    <forward mode='hostdev' managed='yes'>
      <pf dev='eth4'/>
    </forward>

(the pool of PCI addresses is discovered by calling
virNetDevGetVirtualFunctions() on the PF dev).
2013-04-09 14:39:55 -04:00
1584 changed files with 800427 additions and 1046605 deletions

5
.ctags
View File

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

31
.gitignore vendored
View File

@ -19,7 +19,6 @@
*~
.#*
.deps
.dirstamp
.gdb_history
.git
.git-module-status
@ -29,6 +28,7 @@
.sc-start-sc_*
/ABOUT-NLS
/AUTHORS
/COPYING
/ChangeLog
/GNUmakefile
/INSTALL
@ -59,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
@ -105,23 +104,10 @@
/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
@ -143,12 +129,9 @@
/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
@ -161,12 +144,9 @@
/tests/domainsnapshotxml2xmltest
/tests/esxutilstest
/tests/eventtest
/tests/fchosttest
/tests/fdstreamtest
/tests/hashtest
/tests/jsontest
/tests/libvirtdconftest
/tests/metadatatest
/tests/networkxml2argvtest
/tests/nodeinfotest
/tests/nwfilterxml2xmltest
@ -174,10 +154,8 @@
/tests/object-locking-files.txt
/tests/object-locking.cm[ix]
/tests/openvzutilstest
/tests/qemuagenttest
/tests/qemuargv2xmltest
/tests/qemuhelptest
/tests/qemuhotplugtest
/tests/qemumonitorjsontest
/tests/qemumonitortest
/tests/qemuxmlnstest
@ -200,25 +178,19 @@
/tests/virauthconfigtest
/tests/virbitmaptest
/tests/virbuftest
/tests/vircgrouptest
/tests/virdbustest
/tests/virdrivermoduletest
/tests/virendiantest
/tests/virhashtest
/tests/viridentitytest
/tests/virkeycodetest
/tests/virkeyfiletest
/tests/virlockspacetest
/tests/virlogtest
/tests/virnet*test
/tests/virportallocatortest
/tests/virshtest
/tests/virstoragetest
/tests/virstringtest
/tests/virsystemdtest
/tests/virtimetest
/tests/viruritest
/tests/vmwarevertest
/tests/vmx2xmltest
/tests/xencapstest
/tests/xmconfigtest
@ -226,7 +198,6 @@
/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

Submodule .gnulib updated: 4a5ee89c8a...92f3a4c8e5

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>

111
HACKING
View File

@ -36,8 +36,7 @@ developer is:
git checkout -t origin -b workbranch
Hack, committing any changes along the way
More hints on compiling can be found here <compiling.html>. When you want to
post your patches:
Then, when you want to post your patches:
git pull --rebase
(fix any conflicts)
@ -104,17 +103,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 +116,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
@ -194,12 +182,15 @@ possible to add a filter to avoid the errors. For example:
==4643== by 0x34D8C01569: ??? (in /usr/lib64/ld-2.15.so)
In this instance, it is acceptable to modify the "tests/.valgrind.supp" file
In this instance, it is acceptible 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 +211,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
@ -325,29 +318,6 @@ immediately prior to any closing bracket. E.g.
int foo(int wizz); // 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
@ -360,7 +330,7 @@ Omitting braces with a single-line body is fine:
while (expr) // one-line body -> omitting curly braces is ok
single_line_stmt();
However, the moment your loop/if/else body extends on to a second line, for
However, the moment your loop/if/else body extends onto a second line, for
whatever reason (even if it's just an added comment), then you should add
braces. Otherwise, it would be too easy to insert a statement just before that
comment (without adding braces), thinking it is already a multi-statement loop:
@ -448,11 +418,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__)
@ -536,14 +501,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;
}
@ -552,8 +519,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;
}
@ -562,8 +531,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;
}
@ -574,8 +545,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;
@ -587,8 +560,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;
@ -744,17 +719,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
=============================
@ -822,12 +786,9 @@ stick to the following general plan for all *.c source files:
{
...
Of particular note: *Do not* include libvirt/libvirt.h, libvirt/virterror.h,
libvirt/libvirt-qemu.h, or libvirt/libvirt-lxc.h. They are included by
"internal.h" already and there are some special reasons why you cannot include
these files explicitly. One of the special cases, "libvirt/libvirt.h" is
included prior to "internal.h" in "remote_protocol.x", to avoid exposing
*_LAST enum elements.
Of particular note: *Do not* include libvirt/libvirt.h or libvirt/virterror.h.
It is included by "internal.h" already and there are some special reasons why
you cannot include these files explicitly.
Printf-style functions
@ -890,7 +851,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:

View File

@ -1,25 +1,12 @@
## 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 \
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
@ -31,7 +18,6 @@ XML_EXAMPLES = \
test/*.xml storage/*.xml)))
EXTRA_DIST = \
config-post.h \
ChangeLog-old \
libvirt.spec libvirt.spec.in \
mingw-libvirt.spec.in \
@ -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;

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,11 +18,9 @@ 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 \
--enable-static
--enable-werror
# If the MAKEFLAGS envvar does not yet include a -j option,
# add -jN where N depends on the number of processors.
@ -67,7 +58,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,14 +68,12 @@ 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-python
@ -98,14 +87,12 @@ 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-python
@ -118,7 +105,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

@ -49,10 +49,6 @@ fi
# we rerun bootstrap to pull in those diffs.
bootstrap_hash()
{
if test "$no_git"; then
echo no-git
return
fi
git submodule status | sed 's/^[ +-]//;s/ .*//'
git hash-object bootstrap.conf
git ls-tree -d HEAD gnulib/local | awk '{print $3}'
@ -64,11 +60,9 @@ 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
elif test -d .gnulib; then
if test -d .gnulib; then
t=$(bootstrap_hash; git diff .gnulib)
fi
case $t:${CLEAN_SUBMODULE+set} in
@ -84,7 +78,7 @@ if test -d .git || test -f .git; then
# good, it's up to date, all we need is autoreconf
autoreconf -if
else
if test -z "$no_git" && test ${CLEAN_SUBMODULE+set}; then
if test ${CLEAN_SUBMODULE+set}; then
echo cleaning up submodules...
git submodule foreach 'git clean -dfqx && git reset --hard'
fi

100
bootstrap
View File

@ -1,6 +1,6 @@
#! /bin/sh
# Print a version string.
scriptversion=2013-08-15.22; # UTC
scriptversion=2013-03-08.16; # UTC
# Bootstrap this package from checked-out sources.
@ -140,21 +140,20 @@ po_download_command_format2=\
"wget --mirror -nd -q -np -A.po -P '%s' \
http://translationproject.org/latest/%s/"
# Prefer a non-empty tarname (4th argument of AC_INIT if given), else
# fall back to the package name (1st argument with munging)
extract_package_name='
/^AC_INIT(\[*/{
s///
/^[^,]*,[^,]*,[^,]*,[ []*\([^][ ,)]\)/{
s//\1/
s/[],)].*//
/^AC_INIT(/{
/.*,.*,.*, */{
s///
s/[][]//g
s/)$//
p
q
}
s/[],)].*//
s/AC_INIT(\[*//
s/]*,.*//
s/^GNU //
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
s/[^abcdefghijklmnopqrstuvwxyz0123456789_]/-/g
s/[^A-Za-z0-9_]/-/g
p
}
'
@ -209,16 +208,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 +223,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".
@ -254,12 +255,12 @@ esac
# Extra files from gnulib, which override files from other sources.
test -z "${gnulib_extra_files}" && \
gnulib_extra_files="
build-aux/install-sh
build-aux/mdate-sh
build-aux/texinfo.tex
build-aux/depcomp
build-aux/config.guess
build-aux/config.sub
$build_aux/install-sh
$build_aux/mdate-sh
$build_aux/texinfo.tex
$build_aux/depcomp
$build_aux/config.guess
$build_aux/config.sub
doc/INSTALL
"
@ -324,7 +325,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 +468,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 +502,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,
@ -554,10 +550,10 @@ 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 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'
@ -577,17 +573,13 @@ git_modules_config () {
test -f .gitmodules && git config --file .gitmodules "$@"
}
if $use_git; then
gnulib_path=$(git_modules_config submodule.gnulib.path)
test -z "$gnulib_path" && gnulib_path=gnulib
fi
gnulib_path=$(git_modules_config submodule.gnulib.path)
test -z "$gnulib_path" && gnulib_path=gnulib
# Get gnulib files. Populate $GNULIB_SRCDIR, possibly updating a
# submodule, for use in the rest of the script.
# Get gnulib files.
case ${GNULIB_SRCDIR--} in
-)
# Note that $use_git is necessarily true in this case.
if git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..."
git submodule init || exit $?
@ -608,8 +600,8 @@ case ${GNULIB_SRCDIR--} in
GNULIB_SRCDIR=$gnulib_path
;;
*)
# Use GNULIB_SRCDIR directly or as a reference.
if $use_git && test -d "$GNULIB_SRCDIR"/.git && \
# Use GNULIB_SRCDIR as a reference.
if test -d "$GNULIB_SRCDIR"/.git && \
git_modules_config submodule.gnulib.url >/dev/null; then
echo "$0: getting gnulib files..."
if git submodule -h|grep -- --reference > /dev/null; then
@ -635,9 +627,6 @@ case ${GNULIB_SRCDIR--} in
;;
esac
# $GNULIB_SRCDIR now points to the version of gnulib to use, and
# we no longer need to use git or $gnulib_path below here.
if $bootstrap_sync; then
cmp -s "$0" "$GNULIB_SRCDIR/build-aux/bootstrap" || {
echo "$0: updating bootstrap and restarting..."
@ -695,10 +684,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
@ -234,19 +231,20 @@ touch AUTHORS ChangeLog || exit 1
# Override bootstrap's list - we don't use mdate-sh or texinfo.tex.
gnulib_extra_files="
build-aux/install-sh
build-aux/depcomp
build-aux/config.guess
build-aux/config.sub
$build_aux/install-sh
$build_aux/depcomp
$build_aux/config.guess
$build_aux/config.sub
doc/INSTALL
"
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,30 +109,6 @@ foreach my $file (@ARGV) {
$ret = 1;
last;
}
# Forbid whitespace before ";". 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;
}
}
close FILE;
}

186
cfg.mk
View File

@ -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.
@ -166,7 +165,6 @@ useless_free_options = \
--name=virNodeDeviceObjFree \
--name=virObjectUnref \
--name=virObjectFreeCallback \
--name=virPCIDeviceFree \
--name=virSecretDefFree \
--name=virStorageEncryptionFree \
--name=virStorageEncryptionSecretFree \
@ -380,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:
@ -451,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>' \
@ -502,11 +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)
# Not only do they fail to deal well with ipv6, but the gethostby*
# functions are also not thread-safe.
sc_prohibit_gethostby:
@ -514,12 +493,6 @@ sc_prohibit_gethostby:
halt='use getaddrinfo, not gethostby*' \
$(_sc_search_regexp)
# dirname and basename from <libgen.h> are not required to be thread-safe
sc_prohibit_libgen:
@prohibit='( (base|dir)name *\(|include .libgen\.h)' \
halt='use functions from gnulib "dirname.h", not <libgen.h>' \
$(_sc_search_regexp)
# raw xmlGetProp requires some nasty casts
sc_prohibit_xmlGetProp:
@prohibit='\<xmlGetProp *\(' \
@ -546,23 +519,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 \
@ -693,27 +649,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 \
@ -727,22 +662,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.
@ -798,65 +722,6 @@ sc_prohibit_exit_in_tests:
halt='use return, not exit(), in tests' \
$(_sc_search_regexp)
# Don't include duplicate header in the source (either *.c or *.h)
sc_prohibit_duplicate_header:
@fail=0; for i in $$($(VC_LIST_EXCEPT) | grep '\.[chx]$$'); do \
awk '/# *include.*\.h/ { \
match($$0, /[<"][^>"]*[">]/); \
arr[substr($$0, RSTART + 1, RLENGTH - 2)]++; \
} \
END { \
for (key in arr) { \
if (arr[key] > 1) { \
fail=1; \
printf("%d %s are included\n", arr[key], key); \
} \
} \
if (fail == 1) { \
printf("duplicate header(s) in " FILENAME "\n"); \
exit 1; \
} \
}' $$i || fail=1; \
done; \
if test $$fail -eq 1; then \
{ echo '$(ME): avoid duplicate headers' 1>&2; exit 1; } \
fi;
# Don't include "libvirt/*.h" in "" form.
sc_prohibit_include_public_headers_quote:
@prohibit='# *include *"libvirt/.*\.h"' \
in_vc_files='\.[ch]$$' \
halt='Do not include libvirt/*.h in internal source' \
$(_sc_search_regexp)
# Don't include "libvirt/*.h" in <> form. Except for external tools,
# e.g. Python binding, examples and tools subdirectories.
sc_prohibit_include_public_headers_brackets:
@prohibit='# *include *<libvirt/.*\.h>' \
in_vc_files='\.[ch]$$' \
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)
# We don't use this feature of maint.mk.
prev_version_file = /dev/null
@ -878,7 +743,6 @@ ifeq (0,$(MAKELEVEL))
test -d .git || { echo 0; exit; }; \
test -f po/Makevars || { echo 1; exit; }; \
test -f AUTHORS || { echo 1; exit; }; \
test "no-git" = "$$(cat $(_curr_status))" && { echo 0; exit; }; \
actual=$$(git submodule status | $(_submodule_hash); \
git hash-object bootstrap.conf; \
git ls-tree -d HEAD gnulib/local | awk '{print $$3}'; \
@ -906,8 +770,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: \
@ -924,17 +787,16 @@ $(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
exclude_file_name_regexp--sc_avoid_write = \
^(src/($(_src1))|daemon/libvirtd|tools/virsh-console|tests/($(_test1)))\.c$$
^(src/($(_src1))|daemon/libvirtd|tools/console|tests/(shunload|virnettlscontext)test)\.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/vircgroupmock\.c$$)
exclude_file_name_regexp--sc_flags_usage = ^(docs/|src/util/virnetdevtap\.c$$)
exclude_file_name_regexp--sc_libvirt_unmarked_diagnostics = \
^(src/rpc/gendispatch\.pl$$|tests/)
@ -950,13 +812,10 @@ exclude_file_name_regexp--sc_prohibit_always_true_header_tests = \
^python/(libvirt-(lxc-|qemu-)?override|typewrappers)\.c$$
exclude_file_name_regexp--sc_prohibit_asprintf = \
^(bootstrap.conf$$|src/util/virstring\.[ch]$$|examples/domain-events/events-c/event-test\.c$$|tests/vircgroupmock\.c$$)
exclude_file_name_regexp--sc_prohibit_strdup = \
^(docs/|examples/|python/|src/util/virstring\.c|tests/virnetserverclientmock.c$$)
^(bootstrap.conf$$|src/util/virutil\.c$$|examples/domain-events/events-c/event-test\.c$$)
exclude_file_name_regexp--sc_prohibit_close = \
(\.p[yl]$$|^docs/|^(src/util/virfile\.c|src/libvirt\.c|tests/vircgroupmock\.c)$$)
(\.p[yl]$$|^docs/|^(src/util/virfile\.c|src/libvirt\.c)$$)
exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \
(^tests/(qemuhelp|nodeinfo)data/|\.(gif|ico|png|diff)$$)
@ -977,7 +836,7 @@ exclude_file_name_regexp--sc_prohibit_nonreentrant = \
^((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)$$
^(docs/hacking\.html\.in)|(src/util/viralloc\.[ch]|examples/.*|tests/securityselinuxhelper.c)$$
exclude_file_name_regexp--sc_prohibit_readlink = \
^src/(util/virutil|lxc/lxc_container)\.c$$
@ -987,7 +846,7 @@ 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)$$
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$$
@ -998,11 +857,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)$$)
@ -1016,15 +874,3 @@ exclude_file_name_regexp--sc_correct_id_types = \
(^src/locking/lock_protocol.x$$)
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$$
exclude_file_name_regexp--sc_prohibit_include_public_headers_brackets = \
^(python/|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]$$

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

View File

@ -1,30 +1,15 @@
dnl Process this file with autoconf to produce a configure script.
dnl Copyright (C) 2005-2013 Red Hat, Inc.
dnl
dnl This library is free software; you can redistribute it and/or
dnl modify it under the terms of the GNU Lesser General Public
dnl License as published by the Free Software Foundation; either
dnl version 2.1 of the License, or (at your option) any later version.
dnl
dnl This library is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dnl Lesser General Public License for more details.
dnl
dnl You should have received a copy of the GNU Lesser General Public
dnl License along with this library. If not, see
dnl <http://www.gnu.org/licenses/>.
dnl See COPYING.LIB for the License of this software
AC_INIT([libvirt], [1.1.3.2], [libvir-list@redhat.com], [], [http://libvirt.org])
AC_INIT([libvirt], [1.0.4], [libvir-list@redhat.com], [], [http://libvirt.org])
AC_CONFIG_SRCDIR([src/libvirt.c])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])
AH_BOTTOM([#include <config-post.h>])
AC_CONFIG_MACRO_DIR([m4])
dnl Make automake keep quiet about wildcards & other GNUmake-isms; also keep
dnl quiet about the fact that we intentionally cater to automake 1.9
AM_INIT_AUTOMAKE([-Wno-portability -Wno-obsolete tar-ustar subdir-objects])
dnl Make automake keep quiet about wildcards & other GNUmake-isms
AM_INIT_AUTOMAKE([-Wno-portability tar-ustar])
AM_MAINTAINER_MODE([enable])
# Maintainer note - comment this line out if you plan to rerun
@ -32,11 +17,9 @@ AM_MAINTAINER_MODE([enable])
# Leave it uncommented for normal releases, for faster ./configure.
gl_ASSERT_NO_GNULIB_POSIXCHECK
# Default to using the silent-rules feature when possible. Formatting
# chosen to bypass 'grep' checks that cause older automake to warn.
# Users (include rpm) can still change the default at configure time.
m4_ifndef([AM_SILENT_RULES],
[m4_define([AM_SILENT_RULES],[])])AM_SILENT_RULES([yes])
# Use the silent-rules feature when possible.
m4_ifndef([AM_SILENT_RULES], [m4_define([AM_SILENT_RULES],[])])
AM_SILENT_RULES([yes])
AC_CANONICAL_HOST
@ -140,11 +123,7 @@ AC_TYPE_UID_T
dnl Support building Win32 DLLs (must appear *before* AM_PROG_LIBTOOL)
AC_LIBTOOL_WIN32_DLL
m4_ifndef([LT_INIT], [
AM_PROG_LIBTOOL
], [
LT_INIT([shared disable-static])
])
AM_PROG_LIBTOOL
AM_PROG_CC_C_O
AM_PROG_LD
@ -161,54 +140,9 @@ VERSION_SCRIPT_FLAGS=-Wl,--version-script=
VERSION_SCRIPT_FLAGS="-Wl,-M -Wl,"
AC_MSG_RESULT([$VERSION_SCRIPT_FLAGS])
dnl Specify if we rely on ifconfig instead of iproute2 (e.g. in case
dnl we're working on BSD)
want_ifconfig=no
dnl Make some notes about which OS we're compiling for, as the lxc and qemu
dnl drivers require linux headers, and storage_mpath, dtrace, and nwfilter
dnl are also linux specific. The "network" and storage_fs drivers are known
dnl to not work on MacOS X presently, so we also make a note if compiling
dnl for that
with_linux=no with_osx=no with_freebsd=no
case $host in
*-*-linux*) with_linux=yes ;;
*-*-darwin*) with_osx=yes ;;
*-*-freebsd*) with_freebsd=yes ;;
esac
if test $with_linux = no; then
if test "x$with_lxc" != xyes
then
with_lxc=no
fi
with_dtrace=no
fi
if test $with_freebsd = yes; then
want_ifconfig=yes
with_firewalld=no
fi
if test $with_osx = yes; then
with_qemu=no
fi
AM_CONDITIONAL([WITH_LINUX], [test "$with_linux" = "yes"])
AM_CONDITIONAL([WITH_FREEBSD], [test "$with_freebsd" = "yes"])
if test "$with_libvirtd" = "no" ; then
with_qemu=no
fi
# Check for compiler and library settings.
LIBVIRT_COMPILE_WARNINGS
LIBVIRT_COMPILE_PIE
LIBVIRT_LINKER_RELRO
LIBVIRT_LINKER_NO_INDIRECT
LIBVIRT_CHECK_APPARMOR
LIBVIRT_CHECK_ATTR
@ -255,9 +189,8 @@ AC_CHECK_SIZEOF([long])
dnl Availability of various common functions (non-fatal if missing),
dnl and various less common threadsafe functions
AC_CHECK_FUNCS_ONCE([cfmakeraw geteuid getgid getgrnam_r getmntent_r \
getpwuid_r getuid kill mmap newlocale posix_fallocate posix_memalign \
prlimit regexec sched_getaffinity setgroups setns setrlimit symlink \
sysctlbyname])
getpwuid_r getuid initgroups kill mmap newlocale posix_fallocate \
posix_memalign regexec sched_getaffinity setns])
dnl Availability of pthread functions (if missing, win32 threading is
dnl assumed). Because of $LIB_PTHREAD, we cannot use AC_CHECK_FUNCS_ONCE.
@ -270,8 +203,8 @@ LIBS=$old_libs
dnl Availability of various common headers (non-fatal if missing).
AC_CHECK_HEADERS([pwd.h paths.h regex.h sys/un.h \
sys/poll.h syslog.h mntent.h net/ethernet.h linux/magic.h \
sys/un.h sys/syscall.h sys/sysctl.h netinet/tcp.h ifaddrs.h \
libtasn1.h sys/ucred.h sys/mount.h])
sys/un.h sys/syscall.h netinet/tcp.h ifaddrs.h libtasn1.h \
sys/ucred.h])
dnl Check whether endian provides handy macros.
AC_CHECK_DECLS([htole64], [], [], [[#include <endian.h>]])
@ -368,6 +301,8 @@ AC_PATH_PROG([DNSMASQ], [dnsmasq], [dnsmasq],
[/sbin:/usr/sbin:/usr/local/sbin:$PATH])
AC_PATH_PROG([RADVD], [radvd], [radvd],
[/sbin:/usr/sbin:/usr/local/sbin:$PATH])
AC_PATH_PROG([BRCTL], [brctl], [brctl],
[/sbin:/usr/sbin:/usr/local/sbin:$PATH])
AC_PATH_PROG([TC], [tc], [tc],
[/sbin:/usr/sbin:/usr/local/sbin:$PATH])
AC_PATH_PROG([UDEVADM], [udevadm], [],
@ -406,11 +341,11 @@ AC_DEFINE_UNQUOTED([SCRUB],["$SCRUB"],
[Location or name of the scrub program (for wiping algorithms)])
dnl Specific dir for HTML output ?
AC_ARG_WITH([html-dir], [AS_HELP_STRING([--with-html-dir=path],
AC_ARG_WITH([html-dir], [AC_HELP_STRING([--with-html-dir=path],
[path to base html directory, default $datadir/doc/html])],
[HTML_DIR=$withval], [HTML_DIR='$(datadir)/doc'])
AC_ARG_WITH([html-subdir], [AS_HELP_STRING([--with-html-subdir=path],
AC_ARG_WITH([html-subdir], [AC_HELP_STRING([--with-html-subdir=path],
[directory used under html-dir, default $PACKAGE-$VERSION/html])],
[test "x$withval" != "x" && HTML_DIR="$HTML_DIR/$withval"],
[HTML_DIR="$HTML_DIR/\$(PACKAGE)-\$(VERSION)/html"])
@ -418,7 +353,7 @@ AC_SUBST([HTML_DIR])
dnl Specific XML catalog file for validation of generated html
AC_ARG_WITH([xml-catalog-file],
[AS_HELP_STRING([--with-xml-catalog-file=path],
[AC_HELP_STRING([--with-xml-catalog-file=path],
[path to XML catalog file for validating
generated html, default /etc/xml/catalog])],
[XML_CATALOG_FILE=$withval],
@ -436,80 +371,81 @@ if test "$prefix" = "/usr" && test "$sysconfdir" = '${prefix}/etc' ; then
sysconfdir='/etc'
fi
dnl Make some notes about which OS we're compiling for, as the lxc and qemu
dnl drivers require linux headers, and storage_mpath, dtrace, and nwfilter
dnl are also linux specific. The "network" and storage_fs drivers are known
dnl to not work on MacOS X presently, so we also make a note if compiling
dnl for that
with_linux=no with_osx=no with_freebsd=no
case $host in
*-*-linux*) with_linux=yes ;;
*-*-darwin*) with_osx=yes ;;
*-*-freebsd*) with_freebsd=yes ;;
esac
if test $with_linux = no; then
if test "x$with_lxc" != xyes
then
with_lxc=no
fi
with_dtrace=no
fi
if test $with_freebsd = yes; then
with_firewalld=no
fi
if test $with_osx = yes; then
with_qemu=no
fi
AM_CONDITIONAL([WITH_LINUX], [test "$with_linux" = "yes"])
AM_CONDITIONAL([WITH_FREEBSD], [test "$with_freebsd" = "yes"])
dnl Allow to build without Xen, QEMU/KVM, test or remote driver
AC_ARG_WITH([xen],
[AS_HELP_STRING([--with-xen],
[add XEN support @<:@default=check@:>@])])
m4_divert_text([DEFAULTS], [with_xen=check])
AC_HELP_STRING([--with-xen], [add XEN support @<:@default=check@:>@]),[],[with_xen=check])
AC_ARG_WITH([xen-inotify],
[AS_HELP_STRING([--with-xen-inotify],
[add XEN inotify support @<:@default=check@:>@])])
m4_divert_text([DEFAULTS], [with_xen_inotify=check])
AC_HELP_STRING([--with-xen-inotify], [add XEN inotify support @<:@default=check@:>@]),[],[with_xen_inotify=check])
AC_ARG_WITH([qemu],
[AS_HELP_STRING([--with-qemu],
[add QEMU/KVM support @<:@default=yes@:>@])])
m4_divert_text([DEFAULTS], [with_qemu=yes])
AC_HELP_STRING([--with-qemu], [add QEMU/KVM support @<:@default=yes@:>@]),[],[with_qemu=yes])
AC_ARG_WITH([uml],
[AS_HELP_STRING([--with-uml],
[add UML support @<:@default=check@:>@])])
m4_divert_text([DEFAULTS], [with_uml=check])
AC_HELP_STRING([--with-uml], [add UML support @<:@default=check@:>@]),[],[with_uml=check])
AC_ARG_WITH([openvz],
[AS_HELP_STRING([--with-openvz],
[add OpenVZ support @<:@default=check@:>@])])
m4_divert_text([DEFAULTS], [with_openvz=check])
AC_HELP_STRING([--with-openvz], [add OpenVZ support @<:@default=check@:>@]),[],[with_openvz=check])
AC_ARG_WITH([vmware],
[AS_HELP_STRING([--with-vmware],
[add VMware support @<:@default=yes@:>@])])
m4_divert_text([DEFAULTS], [with_vmware=yes])
AC_HELP_STRING([--with-vmware], [add VMware support @<:@default=yes@:>@]),[],[with_vmware=yes])
AC_ARG_WITH([phyp],
[AS_HELP_STRING([--with-phyp],
[add PHYP support @<:@default=check@:>@])])
m4_divert_text([DEFAULTS], [with_phyp=check])
AC_HELP_STRING([--with-phyp], [add PHYP support @<:@default=check@:>@]),[],[with_phyp=check])
AC_ARG_WITH([xenapi],
[AS_HELP_STRING([--with-xenapi],
[add XenAPI support @<:@default=check@:>@])])
m4_divert_text([DEFAULTS], [with_xenapi=check])
AC_HELP_STRING([--with-xenapi], [add XenAPI support @<:@default=check@:>@]),[],[with_xenapi=check])
AC_ARG_WITH([libxl],
[AS_HELP_STRING([--with-libxl],
[add libxenlight support @<:@default=check@:>@])])
m4_divert_text([DEFAULTS], [with_libxl=check])
AC_HELP_STRING([--with-libxl], [add libxenlight support @<:@default=check@:>@]),[],[with_libxl=check])
AC_ARG_WITH([vbox],
[AS_HELP_STRING([--with-vbox=@<:@PFX@:>@],
[VirtualBox XPCOMC location @<:@default=yes@:>@])])
m4_divert_text([DEFAULTS], [with_vbox=yes])
AC_HELP_STRING([--with-vbox=@<:@PFX@:>@],
[VirtualBox XPCOMC location @<:@default=yes@:>@]),[],
[with_vbox=yes])
AC_ARG_WITH([lxc],
[AS_HELP_STRING([--with-lxc],
[add Linux Container support @<:@default=check@:>@])])
m4_divert_text([DEFAULTS], [with_lxc=check])
AC_HELP_STRING([--with-lxc], [add Linux Container support @<:@default=check@:>@]),[],[with_lxc=check])
AC_ARG_WITH([esx],
[AS_HELP_STRING([--with-esx],
[add ESX support @<:@default=check@:>@])])
m4_divert_text([DEFAULTS], [with_esx=check])
AC_HELP_STRING([--with-esx], [add ESX support @<:@default=check@:>@]),[],[with_esx=check])
AC_ARG_WITH([hyperv],
[AS_HELP_STRING([--with-hyperv],
[add Hyper-V support @<:@default=check@:>@])])
m4_divert_text([DEFAULTS], [with_hyperv=check])
AC_HELP_STRING([--with-hyperv], [add Hyper-V support @<:@default=check@:>@]),[],[with_hyperv=check])
AC_ARG_WITH([parallels],
[AS_HELP_STRING([--with-parallels],
[add Parallels Cloud Server support @<:@default=check@:>@])])
m4_divert_text([DEFAULTS], [with_parallels=check])
AC_HELP_STRING([--with-parallels], [add Parallels Cloud Server support @<:@default=check@:>@]),[],[with_parallels=check])
AC_ARG_WITH([test],
[AS_HELP_STRING([--with-test],
[add test driver support @<:@default=yes@:>@])])
m4_divert_text([DEFAULTS], [with_test=yes])
AC_HELP_STRING([--with-test], [add test driver support @<:@default=yes@:>@]),[],[with_test=yes])
AC_ARG_WITH([remote],
[AS_HELP_STRING([--with-remote],
[add remote driver support @<:@default=yes@:>@])])
m4_divert_text([DEFAULTS], [with_remote=yes])
AC_HELP_STRING([--with-remote], [add remote driver support @<:@default=yes@:>@]),[],[with_remote=yes])
AC_ARG_WITH([libvirtd],
[AS_HELP_STRING([--with-libvirtd],
[add libvirtd support @<:@default=yes@:>@])])
m4_divert_text([DEFAULTS], [with_libvirtd=yes])
AC_HELP_STRING([--with-libvirtd], [add libvirtd support @<:@default=yes@:>@]),[],[with_libvirtd=yes])
AC_ARG_WITH([chrdev-lock-files],
[AS_HELP_STRING([--with-chrdev-lock-files],
[location for UUCP style lock files for character devices
(use auto for default paths on some platforms) @<:@default=auto@:>@])])
m4_divert_text([DEFAULTS], [with_chrdev_lock_files=auto])
AC_HELP_STRING([--with-chrdev-lock-files],
[location for UUCP style lock files for character devices
(use auto for default paths on some platforms)
@<:@default=auto@:>@]),
[],[with_chrdev_lock_files=auto])
dnl
dnl in case someone want to build static binaries
@ -520,9 +456,8 @@ AC_SUBST([STATIC_BINARIES])
dnl --enable-debug=(yes|no)
AC_ARG_ENABLE([debug],
[AS_HELP_STRING([--enable-debug=@<:@no|yes@:>@],
[enable debugging output @<:@default=yes@:>@])],
[],[enable_debug=yes])
[AC_HELP_STRING([--enable-debug=@<:@no|yes@:>@],
[enable debugging output @<:@default=yes@:>@])],[],[enable_debug=yes])
AM_CONDITIONAL([ENABLE_DEBUG], test x"$enable_debug" = x"yes")
if test x"$enable_debug" = x"yes"; then
AC_DEFINE([ENABLE_DEBUG], [], [whether debugging is enabled])
@ -535,10 +470,9 @@ dnl init script flavor
dnl
AC_MSG_CHECKING([for init script flavor])
AC_ARG_WITH([init-script],
[AS_HELP_STRING([--with-init-script@<:@=STYLE@:>@],
[Style of init script to install: redhat, systemd, systemd+redhat,
upstart, check, none @<:@default=check@:>@])],
[],[with_init_script=check])
[AC_HELP_STRING([--with-init-script@<:@=STYLE@:>@],
[Style of init script to install: redhat, systemd, systemd+redhat,
upstart, check, none @<:@default=check@:>@])],[],[with_init_script=check])
init_redhat=no
init_systemd=no
init_upstart=no
@ -576,9 +510,9 @@ AC_MSG_RESULT($with_init_script)
AC_MSG_CHECKING([for whether to install sysctl config])
AC_ARG_WITH([sysctl],
[AS_HELP_STRING([--with-sysctl@<:@=yes/no@:>@],
[Whether to install sysctl configs @<:@default=check@:>@])],
[],[with_sysctl=check])
[AC_HELP_STRING([--with-sysctl@<:@=yes/no@:>@],
[Whether to install sysctl configs @<:@default=check@:>@])],
[],[with_sysctl=check])
if test "$with_sysctl" = "yes" || test "$with_sysctl" = "check"
then
@ -600,7 +534,7 @@ AC_MSG_RESULT($with_sysctl)
dnl RHEL-5 has a peculiar version of Xen, which requires some special casing
AC_ARG_WITH([rhel5-api],
[AS_HELP_STRING([--with-rhel5-api=@<:@ARG@:>@],
[AC_HELP_STRING([--with-rhel5-api=@<:@ARG@:>@],
[build for the RHEL-5 API @<:@default=no@:>@])])
if test x"$with_rhel5_api" = x"yes"; then
AC_DEFINE([WITH_RHEL5_API], [1], [whether building for the RHEL-5 API])
@ -728,6 +662,9 @@ if test "x$with_vbox" = "xyes"; then
fi
AM_CONDITIONAL([WITH_VBOX], [test "$with_vbox" = "yes"])
if test "$with_libvirtd" = "no" ; then
with_qemu=no
fi
if test "$with_qemu" = "yes" ; then
AC_DEFINE_UNQUOTED([WITH_QEMU], 1, [whether QEMU driver is enabled])
fi
@ -941,14 +878,13 @@ if test "$with_libvirtd" = "no" ; then
with_lxc=no
fi
if test "$with_lxc" = "yes" || test "$with_lxc" = "check"; then
AC_LINK_IFELSE([AC_LANG_PROGRAM(
[[
AC_TRY_LINK([
#include <sched.h>
#include <linux/loop.h>
#include <sys/epoll.h>
]], [[
unshare(!(LO_FLAGS_AUTOCLEAR + EPOLL_CLOEXEC));
]])], [
], [
unshare (!(LO_FLAGS_AUTOCLEAR + EPOLL_CLOEXEC));
], [
with_lxc=yes
AC_DEFINE([HAVE_DECL_LO_FLAGS_AUTOCLEAR], [1],
[Define to 1 if you have the declaration of `LO_FLAGS_AUTOCLEAR',
@ -961,18 +897,6 @@ if test "$with_lxc" = "yes" || test "$with_lxc" = "check"; then
AC_MSG_ERROR([Required kernel features for LXC were not found])
fi
])
AC_LINK_IFELSE([AC_LANG_PROGRAM(
[[
#include <sched.h>
#include <linux/loop.h>
#include <sys/epoll.h>
]], [[
unshare(!(LOOP_CTL_GET_FREE));
]])], [
AC_DEFINE([HAVE_DECL_LOOP_CTL_GET_FREE], [1],
[Define to 1 if you have the declaration of `LOOP_CTL_GET_FREE',
and to 0 if you don't.])
])
fi
if test "$with_lxc" = "yes" ; then
AC_DEFINE_UNQUOTED([WITH_LXC], 1, [whether LXC driver is enabled])
@ -1055,38 +979,9 @@ dnl check for kernel headers required by src/bridge.c
dnl
if test "$with_linux" = "yes"; then
if test "$with_qemu" = "yes" || test "$with_lxc" = "yes" ; then
# Various kernel versions have headers that are not self-standing, but
# yet are incompatible with the corresponding glibc headers. In order
# to guarantee compilation across a wide range of versions (from RHEL 5
# to rawhide), we first have to probe whether glibc and kernel can be
# used in tandem; and if not, provide workarounds that ensure that
# ABI-compatible IPv6 types are present for use by the kernel headers.
# These probes mirror the usage in virnetdevbridge.c
AC_CACHE_CHECK(
[whether <linux/*.h> and <netinet/*.h> headers are compatible],
[lv_cv_netinet_linux_compatible],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <netinet/in.h>
#include <linux/in6.h>
]])],
[lv_cv_netinet_linux_compatible=yes],
[lv_cv_netinet_linux_compatible=no])])
if test "x$lv_cv_netinet_linux_compatible" != xyes; then
AC_DEFINE([NETINET_LINUX_WORKAROUND], [1],
[define to 1 if Linux kernel headers require a workaround to avoid
compilation errors when mixed with glibc netinet headers])
fi
AC_CHECK_HEADERS([linux/param.h linux/sockios.h linux/if_bridge.h linux/if_tun.h],,
[AC_MSG_ERROR([You must install kernel-headers in order to compile libvirt with QEMU or LXC support])],
[[#include <netinet/in.h>
#if NETINET_LINUX_WORKAROUND
# define in6_addr in6_addr_
# define sockaddr_in6 sockaddr_in6_
# define ipv6_mreq ipv6_mreq_
# define in6addr_any in6addr_any_
# define in6addr_loopback in6addr_loopback_
#endif
#include <linux/in6.h>
]])
fi
fi
@ -1104,8 +999,7 @@ LIBXML_CFLAGS=""
LIBXML_LIBS=""
LIBXML_FOUND="no"
AC_ARG_WITH([libxml], [AS_HELP_STRING([--with-libxml=@<:@PFX@:>@],
[libxml2 location])])
AC_ARG_WITH([libxml], AC_HELP_STRING([--with-libxml=@<:@PFX@:>@], [libxml2 location]))
if test "x$with_libxml" = "xno" ; then
AC_MSG_CHECKING(for libxml2 libraries >= $LIBXML_REQUIRED)
AC_MSG_ERROR([libxml2 >= $LIBXML_REQUIRED is required for libvirt])
@ -1149,8 +1043,7 @@ LIBS="$old_libs"
dnl GnuTLS library
AC_ARG_WITH([gnutls],
[AS_HELP_STRING([--with-gnutls],
[use GNUTLS for encryption @<:@default=check@:>@])],
AC_HELP_STRING([--with-gnutls], [use GNUTLS for encryption @<:@default=check@:>@]),
[],
[with_gnutls=check])
@ -1167,26 +1060,12 @@ if test "x$with_gnutls" != "xno"; then
LIBS="$LIBS $GNUTLS_LIBS"
GNUTLS_FOUND=no
GNUTLS_GCRYPT=unknown
if test -x "$PKG_CONFIG" ; then
dnl Triple probe: gnutls < 2.12 only used gcrypt, gnutls >= 3.0 uses
dnl only nettle, and versions in between had a configure option.
dnl Our goal is to avoid gcrypt if we can prove gnutls uses nettle,
dnl but it is a safe fallback to use gcrypt if we can't prove anything.
if $PKG_CONFIG --exists 'gnutls >= 3.0'; then
GNUTLS_GCRYPT=no
elif $PKG_CONFIG --exists 'gnutls >= 2.12'; then
GNUTLS_GCRYPT=probe
else
GNUTLS_GCRYPT=yes
fi
PKG_CHECK_MODULES(GNUTLS, gnutls >= $GNUTLS_REQUIRED,
[GNUTLS_FOUND=yes], [GNUTLS_FOUND=no])
fi
if test "$GNUTLS_FOUND" = "no"; then
dnl pkg-config couldn't help us, assume gcrypt is necessary
fail=0
GNUTLS_GCRYPT=yes
AC_CHECK_HEADER([gnutls/gnutls.h], [], [fail=1])
AC_CHECK_LIB([gnutls], [gnutls_handshake],[], [fail=1], [-lgcrypt])
@ -1203,27 +1082,9 @@ if test "x$with_gnutls" != "xno"; then
AC_MSG_ERROR([You must install the GnuTLS library in order to compile and run libvirt])
fi
else
dnl See comments above about when to use gcrypt.
if test "$GNUTLS_GCRYPT" = probe; then
case `$PKG_CONFIG --libs --static gnutls` in
*gcrypt*) GNUTLS_GCRYPT=yes ;;
*nettle*) GNUTLS_GCRYPT=no ;;
*) GNUTLS_GCRYPT=unknown ;;
esac
fi
if test "$GNUTLS_GCRYPT" = yes || test "$GNUTLS_GCRYPT" = unknown; then
GNUTLS_LIBS="$GNUTLS_LIBS -lgcrypt"
dnl We're not using gcrypt deprecated features so define
dnl GCRYPT_NO_DEPRECATED to avoid deprecated warnings
GNUTLS_CFLAGS="$GNUTLS_CFLAGS -DGCRYPT_NO_DEPRECATED"
AC_DEFINE_UNQUOTED([WITH_GNUTLS_GCRYPT], 1,
[set to 1 if it is known or assumed that GNUTLS uses gcrypt])
fi
dnl gnutls 3.x moved some declarations to a new header
AC_CHECK_HEADERS([gnutls/crypto.h], [], [], [[
#include <gnutls/gnutls.h>
]])
dnl Not all versions of gnutls include -lgcrypt, and so we add
dnl it explicitly for the calls to gcry_control/check_version
GNUTLS_LIBS="$GNUTLS_LIBS -lgcrypt"
with_gnutls=yes
fi
@ -1246,8 +1107,7 @@ POLKIT_CFLAGS=
POLKIT_LIBS=
PKCHECK_PATH=
AC_ARG_WITH([polkit],
[AS_HELP_STRING([--with-polkit],
[use PolicyKit for UNIX socket access checks @<:@default=check@:>@])],
AC_HELP_STRING([--with-polkit], [use PolicyKit for UNIX socket access checks @<:@default=check@:>@]),
[],
[with_polkit=check])
@ -1313,8 +1173,7 @@ AC_SUBST([POLKIT_LIBS])
dnl firewalld
AC_ARG_WITH([firewalld],
[AS_HELP_STRING([--with-firewalld],
[enable firewalld support @<:@default=check@:>@])],
AC_HELP_STRING([--with-firewalld], [enable firewalld support @<:@default=check@:>@]),
[],
[with_firewalld=check])
if test "x$with_firewalld" = "xcheck" ; then
@ -1351,8 +1210,7 @@ AM_CONDITIONAL([VIR_CHRDEV_LOCK_FILE_PATH], [test "$with_chrdev_lock_files" != "
AC_ARG_WITH([secdriver-selinux],
[AS_HELP_STRING([--with-secdriver-selinux],
[use SELinux security driver @<:@default=check@:>@])],
AC_HELP_STRING([--with-secdriver-selinux], [use SELinux security driver @<:@default=check@:>@]),
[],
[with_secdriver_selinux=check])
@ -1391,8 +1249,7 @@ AM_CONDITIONAL([WITH_SECDRIVER_SELINUX], [test "$with_secdriver_selinux" != "no"
AC_ARG_WITH([secdriver-apparmor],
[AS_HELP_STRING([--with-secdriver-apparmor],
[use AppArmor security driver @<:@default=check@:>@])],
AC_HELP_STRING([--with-secdriver-apparmor], [use AppArmor security driver @<:@default=check@:>@]),
[],
[with_secdriver_apparmor=check])
@ -1412,8 +1269,7 @@ AM_CONDITIONAL([WITH_SECDRIVER_APPARMOR], [test "$with_secdriver_apparmor" != "n
dnl DTrace static probes
AC_ARG_WITH([dtrace],
[AS_HELP_STRING([--with-dtrace],
[use dtrace for static probing @<:@default=check@:>@])],
AC_HELP_STRING([--with-dtrace], [use dtrace for static probing @<:@default=check@:>@]),
[],
[with_dtrace=check])
@ -1437,8 +1293,7 @@ AM_CONDITIONAL([WITH_DTRACE_PROBES], [test "$with_dtrace" != "no"])
dnl numad
AC_ARG_WITH([numad],
[AS_HELP_STRING([--with-numad],
[use numad to manage CPU placement dynamically @<:@default=check@:>@])],
AC_HELP_STRING([--with-numad], [use numad to manage CPU placement dynamically @<:@default=check@:>@]),
[],
[with_numad=check])
@ -1475,8 +1330,7 @@ LIBPCAP_CFLAGS=""
LIBPCAP_LIBS=""
LIBPCAP_FOUND="no"
AC_ARG_WITH([libpcap], [AS_HELP_STRING([--with-libpcap=@<:@PFX@:>@],
[libpcap location])])
AC_ARG_WITH([libpcap], AC_HELP_STRING([--with-libpcap=@<:@PFX@:>@], [libpcap location]))
if test "$with_qemu" = "yes"; then
case $with_libpcap in
no) LIBPCAP_CONFIG= ;;
@ -1598,9 +1452,7 @@ AC_SUBST([VIRSH_LIBS])
dnl check if the network driver should be compiled
AC_ARG_WITH([network],
[AS_HELP_STRING([--with-network],
[with virtual network driver @<:@default=yes@:>@])],
[],[with_network=yes])
AC_HELP_STRING([--with-network], [with virtual network driver @<:@default=yes@:>@]),[],[with_network=yes])
dnl there's no use compiling the network driver without the libvirt
dnl daemon, nor compiling it for MacOS X, where it breaks the compile
@ -1623,9 +1475,7 @@ AM_CONDITIONAL([WITH_BRIDGE], [test "$with_bridge" = "yes"])
AC_ARG_WITH([secrets],
[AS_HELP_STRING([--with-secrets],
[with local secrets management driver @<:@default=yes@:>@])],
[],[with_secrets=yes])
AC_HELP_STRING([--with-secrets], [with local secrets management driver @<:@default=yes@:>@]),[],[with_secrets=yes])
if test "$with_libvirtd" = "no"; then
with_secrets=no
@ -1637,42 +1487,23 @@ AM_CONDITIONAL([WITH_SECRETS], [test "$with_secrets" = "yes"])
AC_ARG_WITH([storage-dir],
[AS_HELP_STRING([--with-storage-dir],
[with directory backend for the storage driver @<:@default=yes@:>@])],
[],[with_storage_dir=yes])
AC_HELP_STRING([--with-storage-dir], [with directory backend for the storage driver @<:@default=yes@:>@]),[],[with_storage_dir=yes])
AC_ARG_WITH([storage-fs],
[AS_HELP_STRING([--with-storage-fs],
[with FileSystem backend for the storage driver @<:@default=check@:>@])],
[],[with_storage_fs=check])
AC_HELP_STRING([--with-storage-fs], [with FileSystem backend for the storage driver @<:@default=check@:>@]),[],[with_storage_fs=check])
AC_ARG_WITH([storage-lvm],
[AS_HELP_STRING([--with-storage-lvm],
[with LVM backend for the storage driver @<:@default=check@:>@])],
[],[with_storage_lvm=check])
AC_HELP_STRING([--with-storage-lvm], [with LVM backend for the storage driver @<:@default=check@:>@]),[],[with_storage_lvm=check])
AC_ARG_WITH([storage-iscsi],
[AS_HELP_STRING([--with-storage-iscsi],
[with iSCSI backend for the storage driver @<:@default=check@:>@])],
[],[with_storage_iscsi=check])
AC_HELP_STRING([--with-storage-iscsi], [with iSCSI backend for the storage driver @<:@default=check@:>@]),[],[with_storage_iscsi=check])
AC_ARG_WITH([storage-scsi],
[AS_HELP_STRING([--with-storage-scsi],
[with SCSI backend for the storage driver @<:@default=check@:>@])],
[],[with_storage_scsi=check])
AC_HELP_STRING([--with-storage-scsi], [with SCSI backend for the storage driver @<:@default=check@:>@]),[],[with_storage_scsi=check])
AC_ARG_WITH([storage-mpath],
[AS_HELP_STRING([--with-storage-mpath],
[with mpath backend for the storage driver @<:@default=check@:>@])],
[],[with_storage_mpath=check])
AC_HELP_STRING([--with-storage-mpath], [with mpath backend for the storage driver @<:@default=check@:>@]),[],[with_storage_mpath=check])
AC_ARG_WITH([storage-disk],
[AS_HELP_STRING([--with-storage-disk],
[with GPartd Disk backend for the storage driver @<:@default=check@:>@])],
[],[with_storage_disk=check])
AC_HELP_STRING([--with-storage-disk], [with GPartd Disk backend for the storage driver @<:@default=check@:>@]),[],[with_storage_disk=check])
AC_ARG_WITH([storage-rbd],
[AS_HELP_STRING([--with-storage-rbd],
[with RADOS Block Device backend for the storage driver
@<:@default=check@:>@])],
[],[with_storage_rbd=check])
AC_HELP_STRING([--with-storage-rbd], [with RADOS Block Device backend for the storage driver @<:@default=check@:>@]),[],[with_storage_rbd=check])
AC_ARG_WITH([storage-sheepdog],
[AS_HELP_STRING([--with-storage-sheepdog],
[with Sheepdog backend for the storage driver @<:@default=check@:>@])],
[],[with_storage_sheepdog=check])
AC_HELP_STRING([--with-storage-sheepdog], [with Sheepdog backend for the storage driver @<:@default=check@:>@]),[],[with_storage_sheepdog=check])
if test "$with_libvirtd" = "no"; then
with_storage_dir=no
@ -2047,9 +1878,7 @@ dnl check for python
dnl
AC_ARG_WITH([python],
[AS_HELP_STRING([--with-python],
[Build python bindings @<:@default=yes@:>@])],
[],[with_python=yes])
AC_HELP_STRING([--with-python], [Build python bindings @<:@default=yes@:>@]),[],[with_python=yes])
if test "$enable_shared:$with_python" = no:yes; then
AC_MSG_WARN([Disabling shared libraries is incompatible with building Python extensions.])
@ -2123,8 +1952,7 @@ dnl Allow perl overrides
AC_PATH_PROG([PERL], [perl])
AC_ARG_ENABLE([with-test-suite],
[AS_HELP_STRING([--with-test-suite],
[build test suite by default @<:@default=check@:>@])],
AC_HELP_STRING([--with-test-suite], [build test suite by default @<:@default=check@:>@]),
[case "${withval}" in
yes|no|check) ;;
*) AC_MSG_ERROR([bad value ${withval} for tests option]) ;;
@ -2142,30 +1970,8 @@ fi
AC_MSG_RESULT([$withval])
AM_CONDITIONAL([WITH_TESTS], [test "$withval" = "yes"])
AC_ARG_ENABLE([expensive-tests],
[AS_HELP_STRING([--enable-expensive-tests],
[set the default for enabling expensive tests (gnulib and long timeouts) ]
[@<:@default=check@:>@; use VIR_TEST_EXPENSIVE to override during make])],
[case $enableval in
0|no) VIR_TEST_EXPENSIVE_DEFAULT=0 ;;
1|yes) VIR_TEST_EXPENSIVE_DEFAULT=1 ;;
check) ;;
*) AC_MSG_ERROR([bad value ${enableval} for enable-expensive-tests option])
;;
esac], [enableval=check])
if test "$enableval" = check; then
if test -d $srcdir/.git ; then
VIR_TEST_EXPENSIVE_DEFAULT=0
else
VIR_TEST_EXPENSIVE_DEFAULT=1
fi
fi
AC_SUBST([VIR_TEST_EXPENSIVE_DEFAULT])
AM_CONDITIONAL([WITH_EXPENSIVE_TESTS], [test $VIR_TEST_EXPENSIVE_DEFAULT = 1])
AC_ARG_ENABLE([test-coverage],
[AS_HELP_STRING([--enable-test-coverage],
[turn on code coverage instrumentation @<:@default=no@:>@])],
AC_HELP_STRING([--enable-test-coverage], [turn on code coverage instrumentation @<:@default=no@:>@]),
[case "${enableval}" in
yes|no) ;;
*) AC_MSG_ERROR([bad value ${enableval} for test-coverage option]) ;;
@ -2185,8 +1991,7 @@ if test "${enable_coverage}" = yes; then
fi
AC_ARG_ENABLE([test-oom],
[AS_HELP_STRING([--enable-test-oom],
[memory allocation failure checking @<:@default=no@:>@])],
AC_HELP_STRING([--enable-test-oom], [memory allocation failure checking @<:@default=no@:>@]),
[case "${enableval}" in
yes|no) ;;
*) AC_MSG_ERROR([bad value ${enableval} for test-oom option]) ;;
@ -2206,8 +2011,7 @@ fi
AC_ARG_ENABLE([test-locking],
[AS_HELP_STRING([--enable-test-locking],
[thread locking tests using CIL @<:@default=no@:>@])],
AC_HELP_STRING([--enable-test-locking], [thread locking tests using CIL @<:@default=no@:>@]),
[case "${enableval}" in
yes|no) ;;
*) AC_MSG_ERROR([bad value ${enableval} for test-locking option]) ;;
@ -2330,8 +2134,8 @@ AM_CONDITIONAL([WITH_WIN_ICON], [test "$WINDRES" != ""])
dnl Driver-Modules library
AC_ARG_WITH([driver-modules],
[AS_HELP_STRING([--with-driver-modules],
[build drivers as loadable modules @<:@default=check@:>@])],
AC_HELP_STRING([--with-driver-modules],
[build drivers as loadable modules @<:@default=check@:>@]),
[],
[with_driver_modules=check])
@ -2354,7 +2158,7 @@ if test "$with_driver_modules" = "yes" || test "$with_driver_modules" = "check";
fi
if test "$with_driver_modules" = "yes" ; then
DRIVER_MODULE_LDFLAGS="-export-dynamic"
DRIVER_MODULE_CFLAGS="-export-dynamic"
case $ac_cv_search_dlopen in
no*) DRIVER_MODULE_LIBS= ;;
*) DRIVER_MODULE_LIBS=$ac_cv_search_dlopen ;;
@ -2362,7 +2166,7 @@ if test "$with_driver_modules" = "yes" ; then
AC_DEFINE_UNQUOTED([WITH_DRIVER_MODULES], 1, [whether to build drivers as modules])
fi
AM_CONDITIONAL([WITH_DRIVER_MODULES], [test "$with_driver_modules" != "no"])
AC_SUBST([DRIVER_MODULE_LDFLAGS])
AC_SUBST([DRIVER_MODULE_CFLAGS])
AC_SUBST([DRIVER_MODULE_LIBS])
@ -2396,9 +2200,9 @@ AM_CONDITIONAL([WITH_NWFILTER], [test "$with_nwfilter" = "yes"])
dnl check if the interface driver should be compiled
AC_ARG_WITH([interface],
[AS_HELP_STRING([--with-interface],
[with host interface driver @<:@default=check@:>@])],
[],[with_interface=check])
AC_HELP_STRING([--with-interface],
[with host interface driver @<:@default=check@:>@]), [],
[with_interface=check])
dnl Don't compile the interface driver without libvirtd
if test "$with_libvirtd" = "no" ; then
@ -2428,15 +2232,13 @@ else
fi
AC_ARG_WITH([qemu-user],
[AS_HELP_STRING([--with-qemu-user],
[username to run QEMU system instance as
@<:@default=platform dependent@:>@])],
AC_HELP_STRING([--with-qemu-user],
[username to run QEMU system instance as @<:@default=platform dependent@:>@]),
[QEMU_USER=${withval}],
[QEMU_USER=${default_qemu_user}])
AC_ARG_WITH([qemu-group],
[AS_HELP_STRING([--with-qemu-group],
[groupname to run QEMU system instance as
@<:@default=platform dependent@:>@])],
AC_HELP_STRING([--with-qemu-group],
[groupname to run QEMU system instance as @<:@default=platform dependent@:>@]),
[QEMU_GROUP=${withval}],
[QEMU_GROUP=${default_qemu_group}])
AC_DEFINE_UNQUOTED([QEMU_USER], ["$QEMU_USER"], [QEMU user account])
@ -2444,8 +2246,7 @@ AC_DEFINE_UNQUOTED([QEMU_GROUP], ["$QEMU_GROUP"], [QEMU group account])
AC_ARG_WITH([macvtap],
[AS_HELP_STRING([--with-macvtap],
[enable macvtap device @<:@default=check@:>@])],
AC_HELP_STRING([--with-macvtap],[enable macvtap device @<:@default=check@:>@]),
[with_macvtap=${withval}],
[with_macvtap=check])
@ -2478,8 +2279,7 @@ fi
AC_ARG_WITH([virtualport],
[AS_HELP_STRING([--with-virtualport],
[enable virtual port support @<:@default=check@:>@])],
AC_HELP_STRING([--with-virtualport],[enable virtual port support @<:@default=check@:>@]),
[with_virtualport=${withval}],
[with_virtualport=check])
@ -2536,9 +2336,6 @@ if test "$with_linux" = "yes"; then
break
fi
done
case $libnl_ldd:${LIBNL_CFLAGS+set} in
*libnl-3.so.*:) LIBNL_REQUIRED=3.0 ;;
esac
case $libnl_ldd:${LIBNL_CFLAGS+set} in
*libnl.so.1*:) ;;
*)
@ -2570,48 +2367,12 @@ AM_CONDITIONAL([HAVE_LIBNL], [test "$have_libnl" = "yes"])
AC_SUBST([LIBNL_CFLAGS])
AC_SUBST([LIBNL_LIBS])
# Check for Linux vs. BSD ifreq members
AC_CHECK_MEMBERS([struct ifreq.ifr_newname,
struct ifreq.ifr_ifindex,
struct ifreq.ifr_index],
[], [],
[#include <sys/socket.h>
#include <net/if.h>
])
# Check for BSD approach for setting MAC addr
AC_LINK_IFELSE([AC_LANG_PROGRAM(
[[
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_dl.h>
]],
[[
link_addr(0, 0)]])],
[AC_DEFINE([HAVE_DECL_LINK_ADDR],
[1],
[whether link_addr is available])])
# Check for BSD approach for bridge management
AC_CHECK_DECLS([BRDGSFD, BRDGADD, BRDGDEL],
[AC_DEFINE([HAVE_BSD_BRIDGE_MGMT],
[1],
[whether BSD style bridge management is available])],
[],
[#include <stdint.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <net/if_bridgevar.h>
])
# Check if we need to look for ifconfig
if test "$want_ifconfig" = "yes"; then
AC_PATH_PROG([IFCONFIG_PATH], [ifconfig])
if test -z "$IFCONFIG_PATH"; then
AC_MSG_ERROR([Failed to find ifconfig.])
fi
AC_DEFINE_UNQUOTED([IFCONFIG_PATH], "$IFCONFIG_PATH", [path to ifconfig binary])
fi
# Only COPYING.LIB is under version control, yet COPYING
# is included as part of the distribution tarball.
# Copy one to the other, but only if this is a srcdir-build.
# You are unlikely to be doing distribution-related things in a non-srcdir build
test "x$srcdir" = x. && ! test -f COPYING &&
cp -f COPYING.LIB COPYING
# Detect when running under the clang static analyzer's scan-build driver
# or Coverity-prevent's cov-build. Define STATIC_ANALYSIS accordingly.
@ -2635,28 +2396,26 @@ AC_DEFINE_UNQUOTED([base64_encode_alloc],[libvirt_gl_base64_encode_alloc],[Hack
AC_CONFIG_FILES([run],
[chmod +x,-w run])
AC_CONFIG_FILES([\
Makefile src/Makefile include/Makefile docs/Makefile \
docs/schemas/Makefile \
gnulib/lib/Makefile \
gnulib/tests/Makefile \
libvirt.pc libvirt.spec mingw-libvirt.spec \
po/Makefile.in \
include/libvirt/Makefile include/libvirt/libvirt.h \
python/Makefile \
daemon/Makefile \
tools/Makefile \
tests/Makefile \
examples/apparmor/Makefile \
examples/domain-events/events-c/Makefile \
examples/domsuspend/Makefile \
examples/dominfo/Makefile \
examples/openauth/Makefile \
examples/python/Makefile \
examples/hellolibvirt/Makefile \
examples/systemtap/Makefile \
examples/xml/nwfilter/Makefile])
AC_OUTPUT
AC_OUTPUT(Makefile src/Makefile include/Makefile docs/Makefile \
docs/schemas/Makefile \
gnulib/lib/Makefile \
gnulib/tests/Makefile \
libvirt.pc libvirt.spec mingw-libvirt.spec \
po/Makefile.in \
include/libvirt/Makefile include/libvirt/libvirt.h \
python/Makefile python/tests/Makefile \
daemon/Makefile \
tools/Makefile \
tests/Makefile \
examples/apparmor/Makefile \
examples/domain-events/events-c/Makefile \
examples/domsuspend/Makefile \
examples/dominfo/Makefile \
examples/openauth/Makefile \
examples/python/Makefile \
examples/hellolibvirt/Makefile \
examples/systemtap/Makefile \
examples/xml/nwfilter/Makefile)
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Configuration summary])

View File

@ -1,49 +1,36 @@
## 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/>.
## 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
$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl -b 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
$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl -b 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
$(AM_V_GEN)$(PERL) -w $(srcdir)/../src/rpc/gendispatch.pl -b 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,10 +330,10 @@ 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
@ -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

@ -40,7 +40,7 @@ The server lock is used in conjunction with a condition variable
to pass jobs from the event loop thread to the workers. The main
event loop thread handles I/O from the client socket, and once a
complete RPC message has been read off the wire (and optionally
decrypted), it will be placed on the 'dx' job queue for the
decrypted), it will be placed onto the 'dx' job queue for the
associated client object. The job condition will be signalled and
a worker will wakup and process it.

View File

@ -32,8 +32,6 @@
#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
@ -59,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++;
@ -87,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;
}
@ -129,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 { \
@ -139,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)
@ -191,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;
@ -201,13 +208,15 @@ 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;
no_memory:
virReportOOMError();
error:
return -1;
}
@ -219,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
@ -242,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;
@ -274,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 */
@ -291,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;
}
@ -311,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);
@ -369,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)
@ -380,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);
@ -414,7 +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, prio_workers);

View File

@ -45,8 +45,6 @@ struct daemonConfig {
int auth_tcp;
int auth_tls;
char **access_drivers;
int mdns_adv;
char *mdns_name;
@ -63,7 +61,6 @@ struct daemonConfig {
int min_workers;
int max_workers;
int max_clients;
int max_queued_clients;
int prio_workers;

View File

@ -51,12 +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_requests"
| int_entry "max_client_requests"
| int_entry "prio_workers"

View File

@ -43,6 +43,7 @@
#include "libvirtd.h"
#include "libvirtd-config.h"
#include "virutil.h"
#include "viruuid.h"
#include "remote_driver.h"
#include "viralloc.h"
@ -50,11 +51,10 @@
#include "virnetlink.h"
#include "virnetserver.h"
#include "remote.h"
#include "remote_driver.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"
@ -74,9 +74,6 @@
# ifdef WITH_UML
# include "uml/uml_driver.h"
# endif
# ifdef WITH_VBOX
# include "vbox/vbox_driver.h"
# endif
# ifdef WITH_NETWORK
# include "network/bridge_driver.h"
# endif
@ -245,8 +242,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;
@ -263,7 +260,7 @@ daemonPidFilePath(bool privileged,
if (virAsprintf(pidfile, "%s/libvirtd.pid", rundir) < 0) {
VIR_FREE(rundir);
goto error;
goto no_memory;
}
VIR_FREE(rundir);
@ -271,6 +268,8 @@ daemonPidFilePath(bool privileged,
return 0;
no_memory:
virReportOOMError();
error:
return -1;
}
@ -283,15 +282,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;
@ -308,7 +308,7 @@ daemonUnixSocketPaths(struct daemonConfig *config,
if (virAsprintf(sockfile, "%s/libvirt-sock", rundir) < 0) {
VIR_FREE(rundir);
goto error;
goto no_memory;
}
VIR_FREE(rundir);
@ -316,6 +316,8 @@ daemonUnixSocketPaths(struct daemonConfig *config,
}
return 0;
no_memory:
virReportOOMError();
error:
return -1;
}
@ -400,9 +402,6 @@ static void daemonInitialize(void)
# ifdef WITH_UML
virDriverLoadModule("uml");
# endif
# ifdef WITH_VBOX
virDriverLoadModule("vbox");
# endif
#else
# ifdef WITH_NETWORK
networkRegister();
@ -437,9 +436,6 @@ static void daemonInitialize(void)
# ifdef WITH_UML
umlRegister();
# endif
# ifdef WITH_VBOX
vboxRegister();
# endif
#endif
}
@ -485,7 +481,6 @@ static int daemonSetupNetworking(virNetServerPtr srv,
NULL,
#endif
false,
config->max_queued_clients,
config->max_client_requests)))
goto error;
if (sock_path_ro) {
@ -498,7 +493,6 @@ static int daemonSetupNetworking(virNetServerPtr srv,
NULL,
#endif
true,
config->max_queued_clients,
config->max_client_requests)))
goto error;
}
@ -524,7 +518,6 @@ static int daemonSetupNetworking(virNetServerPtr srv,
NULL,
#endif
false,
config->max_queued_clients,
config->max_client_requests)))
goto error;
@ -565,7 +558,6 @@ static int daemonSetupNetworking(virNetServerPtr srv,
config->auth_tls,
ctxt,
false,
config->max_queued_clients,
config->max_client_requests))) {
virObjectUnref(ctxt);
goto error;
@ -666,7 +658,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);
}
@ -684,7 +676,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;
@ -702,13 +694,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);
@ -722,31 +714,13 @@ daemonSetupLogging(struct daemonConfig *config,
return 0;
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)
@ -891,9 +865,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 */
@ -936,8 +907,6 @@ static void daemonRunStateInit(void *opaque)
cleanup:
daemonInhibitCallback(false, srv);
virObjectUnref(srv);
virObjectUnref(sysident);
virIdentitySetCurrent(NULL);
}
static int daemonStateInit(virNetServerPtr srv)
@ -991,10 +960,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;
@ -1038,13 +1006,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"),
@ -1056,26 +1023,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",
@ -1099,6 +1066,10 @@ daemonUsage(const char *argv0, bool privileged)
}
}
enum {
OPT_VERSION = 129
};
#define MAX_LISTEN 5
int main(int argc, char **argv) {
virNetServerPtr srv = NULL;
@ -1120,14 +1091,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}
};
@ -1148,7 +1119,7 @@ int main(int argc, char **argv) {
}
*tmp = '\0';
char *driverdir;
if (virAsprintfQuiet(&driverdir, "%s/../../src/.libs", argv[0]) < 0) {
if (virAsprintf(&driverdir, "%s/../../src/.libs", argv[0]) < 0) {
fprintf(stderr, _("%s: initialization failed\n"), argv[0]);
exit(EXIT_FAILURE);
}
@ -1170,7 +1141,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;
@ -1202,7 +1173,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);
}
@ -1210,23 +1181,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);
}
}
@ -1281,11 +1252,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) {
@ -1322,10 +1288,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();
@ -1334,6 +1297,11 @@ int main(int argc, char **argv) {
goto cleanup;
}
}
if (!run_dir) {
virReportOOMError();
goto cleanup;
}
if (privileged)
old_umask = umask(022);
else

View File

@ -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" ]
#################################################################
#
@ -257,12 +248,6 @@
# over all sockets combined.
#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 minimum limit sets the number of workers to start up
# initially. If the number of active clients exceeds this,

View File

@ -1,7 +1,7 @@
/*
* libvirtd.h: daemon data structure definitions
*
* Copyright (C) 2006-2013 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,6 +27,8 @@
# define VIR_ENUM_SENTINELS
# include <config.h>
# include <rpc/types.h>
# include <rpc/xdr.h>
# include "remote_protocol.h"

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

@ -15,7 +15,6 @@ 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

File diff suppressed because it is too large Load Diff

View File

@ -148,14 +148,6 @@ daemonStreamEvent(virStreamPtr st, int events, void *opaque)
virNetServerClientClose(client);
goto cleanup;
}
/* If we detected EOF during read processing,
* then clear hangup/error conditions, since
* we want the client to see the EOF message
* we just sent them
*/
if (stream->recvEOF)
events = events & ~(VIR_STREAM_EVENT_HANGUP |
VIR_STREAM_EVENT_ERROR);
}
/* If we have a completion/abort message, always process it */
@ -325,8 +317,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;
@ -708,7 +702,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" }
@ -35,7 +32,6 @@ module Test_libvirtd =
{ "2" = "fred@EXAMPLE.COM" }
}
{ "max_clients" = "20" }
{ "max_queued_clients" = "1000" }
{ "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)
@ -322,7 +287,6 @@ install-data-local:
for file in $(devhelphtml) $(devhelppng) $(devhelpcss); do \
$(INSTALL) -m 0644 $(srcdir)/$${file} $(DESTDIR)$(DEVHELP_DIR) ; \
done
$(INSTALL_DATA) $(srcdir)/libvirtLogo.png $(DESTDIR)$(pkgdatadir)
uninstall-local:
for h in $(apihtml); do rm $(DESTDIR)$(HTML_DIR)/$$h; done

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 acces 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>

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>

View File

@ -50,7 +50,6 @@ ignored_words = {
}
ignored_functions = {
"virConnectSupportsFeature": "private function for remote access",
"virDomainMigrateFinish": "private function for migration",
"virDomainMigrateFinish2": "private function for migration",
"virDomainMigratePerform": "private function for migration",
@ -63,19 +62,11 @@ ignored_functions = {
"virDomainMigratePrepare3": "private function for migration",
"virDomainMigrateConfirm3": "private function for migration",
"virDomainMigratePrepareTunnel3": "private function for tunnelled migration",
"virDrvSupportsFeature": "private function for remote access",
"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))
@ -919,7 +910,7 @@ class CParser:
l = lines[0]
i = 0
# Remove all leading '*', followed by at most one ' ' character
# since we need to preserve correct indentation of code examples
# since we need to preserve correct identation of code examples
while i < len(l) and l[i] == '*':
i = i + 1
if i > 0:
@ -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))
@ -1451,7 +1442,7 @@ class CParser:
# 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)
@ -1472,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 (
@ -1524,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":
@ -1539,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
@ -1558,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
@ -1577,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:
@ -1595,24 +1586,24 @@ 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
@ -1627,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()
@ -1635,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)
@ -1668,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()
@ -1700,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
@ -1813,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)
@ -1840,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':
@ -1849,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
#
@ -1874,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()
@ -1897,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)
@ -1920,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:
@ -1935,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:
@ -1977,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, '"', ' ')
@ -2069,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")
@ -2087,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)
@ -2110,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)
@ -2133,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)
@ -2151,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:
@ -2161,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:
@ -2179,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 != "":
@ -2190,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" % (
@ -2202,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:
@ -2219,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" % (
@ -2352,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):
@ -2383,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
@ -2392,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))
@ -2407,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>
@ -204,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
@ -244,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>
@ -358,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>

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,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>
@ -256,15 +253,13 @@ Plugin "gssapiv2" [loaded], API version: 4
features: WANT_CLIENT_FIRST|PROXY_AUTHENTICATION|NEED_SERVER_FQDN
</pre>
<p>
Next it is necessary for the administrator of the Kerberos realm to
issue a principal for the libvirt server. There needs to be one
principal per host running the libvirt daemon. The principal should be
named <code>libvirt/full.hostname@KERBEROS.REALM</code>. This is
typically done by running the <code>kadmin.local</code> command on the
Kerberos server, though some Kerberos servers have alternate ways of
setting up service principals. Once created, the principal should be
exported to a keytab, copied to the host running the libvirt daemon
and placed in <code>/etc/libvirt/krb5.tab</code>
Next it is necessary for the administrator of the Kerberos realm to issue a principle
for the libvirt server. There needs to be one principle per host running the libvirt
daemon. The principle should be named <code>libvirt/full.hostname@KERBEROS.REALM</code>.
This is typically done by running the <code>kadmin.local</code> command on the Kerberos
server, though some Kerberos servers have alternate ways of setting up service principles.
Once created, the principle should be exported to a keytab, copied to the host running
the libvirt daemon and placed in <code>/etc/libvirt/krb5.tab</code>
</p>
<pre>
# kadmin.local
@ -286,7 +281,7 @@ kadmin.local: quit
</pre>
<p>
Any client application wishing to connect to a Kerberos enabled libvirt server
merely needs to run <code>kinit</code> to gain a user principal. This may well
merely needs to run <code>kinit</code> to gain a user principle. This may well
be done automatically when a user logs into a desktop session, if PAM is setup
to authenticate against Kerberos.
</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 >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>

View File

@ -1,285 +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>Control Groups Resource Management</h1>
<ul id="toc"></ul>
<p>
The QEMU and LXC drivers make use of the Linux "Control Groups" facility
for applying resource management to their virtual machines and containers.
</p>
<h2><a name="requiredControllers">Required controllers</a></h2>
<p>
The control groups filesystem supports multiple "controllers". By default
the init system (such as systemd) should mount all controllers compiled
into the kernel at <code>/sys/fs/cgroup/$CONTROLLER-NAME</code>. Libvirt
will never attempt to mount any controllers itself, merely detect where
they are mounted.
</p>
<p>
The QEMU driver is capable of using the <code>cpuset</code>,
<code>cpu</code>, <code>memory</code>, <code>blkio</code> and
<code>devices</code> controllers. None of them are compulsory.
If any controller is not mounted, the resource management APIs
which use it will cease to operate. It is possible to explicitly
turn off use of a controller, even when mounted, via the
<code>/etc/libvirt/qemu.conf</code> configuration file.
</p>
<p>
The LXC driver is capable of using the <code>cpuset</code>,
<code>cpu</code>, <code>cpuset</code>, <code>freezer</code>,
<code>memory</code>, <code>blkio</code> and <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
which use them will cease to operate.
</p>
<h2><a name="currentLayout">Current cgroups layout</a></h2>
<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 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>
$ROOT
|
+- system
| |
| +- libvirtd.service
|
+- machine
|
+- vm1.libvirt-qemu
| |
| +- emulator
| +- vcpu0
| +- vcpu1
|
+- vm2.libvirt-qemu
| |
| +- emulator
| +- vcpu0
| +- vcpu1
|
+- vm3.libvirt-qemu
| |
| +- emulator
| +- vcpu0
| +- vcpu1
|
+- container1.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>
If there is a need to apply resource constraints to groups of
virtual machines or containers, then the single default
partition <code>/machine</code> may not be sufficiently
flexible. The administrator may wish to sub-divide the
default partition, for example into "testing" and "production"
partitions, and then assign each guest to a specific
sub-partition. This is achieved via a small element addition
to the guest domain XML config, just below the main <code>domain</code>
element
</p>
<pre>
...
&lt;resource&gt;
&lt;partition&gt;/machine/production&lt;/partition&gt;
&lt;/resource&gt;
...
</pre>
<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. For
example, given the XML config above, the admin would need
to create a cgroup named '/machine/production.partition'
</p>
<pre>
# cd /sys/fs/cgroup
# for i in blkio cpu,cpuacct cpuset devices freezer memory net_cls perf_event
do
mkdir $i/machine/production.partition
done
# for i in cpuset.cpus cpuset.mems
do
cat cpuset/machine/$i > cpuset/machine/production.partition/$i
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>
Since libvirt aims to provide an API which is portable across
hypervisors, the concept of cgroups is not exposed directly
in the API or XML configuration. It is considered to be an
internal implementation detail. Instead libvirt provides a
set of APIs for applying resource controls, which are then
mapped to corresponding cgroup tunables
</p>
<h3>Scheduler tuning</h3>
<p>
Parameters from the "cpu" controller are exposed via the
<code>schedinfo</code> command in virsh.
</p>
<pre>
# virsh schedinfo demo
Scheduler : posix
cpu_shares : 1024
vcpu_period : 100000
vcpu_quota : -1
emulator_period: 100000
emulator_quota : -1</pre>
<h3>Block I/O tuning</h3>
<p>
Parameters from the "blkio" controller are exposed via the
<code>bkliotune</code> command in virsh.
</p>
<pre>
# virsh blkiotune demo
weight : 500
device_weight : </pre>
<h3>Memory tuning</h3>
<p>
Parameters from the "memory" controller are exposed via the
<code>memtune</code> command in virsh.
</p>
<pre>
# virsh memtune demo
hard_limit : 580192
soft_limit : unlimited
swap_hard_limit: unlimited
</pre>
<h3>Network tuning</h3>
<p>
The <code>net_cls</code> is not currently used. Instead traffic
filter policies are set directly against individual virtual
network interfaces.
</p>
<h2><a name="legacyLayout">Legacy cgroups layout</a></h2>
<p>
Prior to libvirt 1.0.5, the cgroups layout created by libvirt was different
from that described above, and did not allow for administrator customization.
Libvirt used a fixed, 3-level hierarchy <code>libvirt/{qemu,lxc}/$VMNAME</code>
which was rooted at the point in the hierarchy where libvirtd itself was
located. So if libvirtd was placed at <code>/system/libvirtd.service</code>
by systemd, the groups for each virtual machine / container would be located
at <code>/system/libvirtd.service/libvirt/{qemu,lxc}/$VMNAME</code>. In addition
to this, the QEMU drivers further child groups for each vCPU thread and the
emulator thread(s). This leads to a hierarchy that looked like
</p>
<pre>
$ROOT
|
+- system
|
+- libvirtd.service
|
+- libvirt
|
+- qemu
| |
| +- vm1
| | |
| | +- emulator
| | +- vcpu0
| | +- vcpu1
| |
| +- vm2
| | |
| | +- emulator
| | +- vcpu0
| | +- vcpu1
| |
| +- vm3
| |
| +- emulator
| +- vcpu0
| +- vcpu1
|
+- lxc
|
+- container1
|
+- container2
|
+- container3
</pre>
<p>
Although current releases are much improved, historically the use of deep
hierarchies has had a significant negative impact on the kernel scalability.
The legacy libvirt cgroups layout highlighted these problems, to the detriment
of the performance of virtual machines and containers.
</p>
</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><a name="installation">libvirt Installation</a></h1>
@ -65,36 +64,8 @@
checkout it is necessary to generate the configure script and Makefile.in
templates using the <code>autogen.sh</code> command. By default when
the <code>configure</code> script is run from within a GIT checkout, it
will turn on -Werror for builds. This can be disabled with
--disable-werror, but this is not recommended.
</p>
<p>
Libvirt takes advantage of
the <a href="http://www.gnu.org/software/gnulib/">gnulib</a>
project to provide portability to a number of platforms. This
is normally done dynamically via a git submodule in
the <code>.gnulib</code> subdirectory, which is auto-updated as
needed when you do incremental builds. Setting the environment
variable <code>GNULIB_SRCDIR</code> to a local directory
containing a git checkout of gnulib will let you reduce local
disk space requirements and network download time, regardless of
which actual commit you have in that reference directory.
</p>
<p>
However, if you are developing on a platform where git is not
available, or are behind a firewall that does not allow for git
to easily obtain the gnulib submodule, it is possible to instead
use a static mode of operation where you are then responsible
for updating the git submodule yourself. In this mode, you must
track the exact gnulib commit needed by libvirt (usually not the
latest gnulib.git) via alternative means, such as a shared NFS
drive or manual download, and run this any time libvirt.git
updates the commit stored in the .gnulib submodule:</p>
<pre>
$ GNULIB_SRCDIR=/path/to/gnulib ./autogen.sh --no-git
</pre>
<p>To build &amp; install libvirt to your home
will turn on -Werror for builds. This can be disabled with --disable-werror,
but this is not recommended. To build &amp; install libvirt to your home
directory the following commands can be run:
</p>

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>

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>

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,373 +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>
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>
@ -532,158 +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 forceably 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. 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
</p>
<pre>
# virsh -c lxc:/// console myguest
</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>
</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>

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

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>
@ -281,20 +279,6 @@
use the traditional <code>&lt; hostdev&gt;</code> device
definition. <span class="since"> Since 0.10.0</span>
<p>
To use VFIO device assignment rather than
traditional/legacy KVM device assignment (VFIO is a new
method of device assignment that is compatible with UEFI
Secure Boot), a &lt;forward type='hostdev'&gt; interface
can have an optional <code>driver</code> sub-element
with a <code>name</code> attribute set to "vfio". To use
legacy KVM device assignment you can
set <code>name</code> to "kvm" (or simply omit the
&lt;driver&gt; element, since "kvm" is currently the
default).
<span class="since">Since 1.0.5 (QEMU and KVM only, requires kernel 3.6 or newer)</span>
</p>
<p>Note that this "intelligent passthrough" of network
devices is very similar to the functionality of a
standard <code>&lt; hostdev&gt;</code> device, the
@ -376,7 +360,6 @@
<pre>
...
&lt;forward mode='hostdev' managed='yes'&gt;
&lt;driver name='vfio'/&gt;
&lt;address type='pci' domain='0' bus='4' slot='0' function='1'/&gt;
&lt;address type='pci' domain='0' bus='4' slot='0' function='2'/&gt;
&lt;address type='pci' domain='0' bus='4' slot='0' function='3'/&gt;
@ -434,24 +417,20 @@
<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
@ -472,14 +451,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
@ -558,62 +529,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>
@ -631,8 +546,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;
@ -647,7 +560,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>
@ -665,36 +577,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
@ -922,33 +809,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

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,207 +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;auth type='ceph' username='myname'/&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;auth type='chap' username='myname'/&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>
@ -148,9 +146,8 @@
the <a href="formatdomain.html#elementsDisks">disk
devices</a> specified for the domain at the time of the
snapshot. The attribute <code>snapshot</code> is
optional, and the possible values are the same as the
<code>snapshot</code> attribute for
<a href="formatdomain.html#elementsDisks">disk devices</a>
optional, and has the same values of the disk device
element for a domain
(<code>no</code>, <code>internal</code>,
or <code>external</code>). Some hypervisors like ESX
require that if specified, the snapshot mode must not

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,9 +15,9 @@
<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>. 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>
@ -72,21 +70,11 @@
&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;
...</pre>
<pre>
...
&lt;source&gt;
&lt;adapter type='fc_host' parent='scsi_host5' wwnn='20000000c9831b4b' wwpn='10000000c9831b4b'/&gt;
&lt;/source&gt;
...</pre>
<dl>
<dt><code>device</code></dt>
<dd>Provides the source for pools backed by physical devices.
@ -100,23 +88,8 @@
<span class="since">Since 0.4.1</span></dd>
<dt><code>adapter</code></dt>
<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).
Attribute <code>type</code> (<span class="since">1.0.5</span>)
specifies the adapter type. Valid values are "fc_host" and "scsi_host".
If omitted and the <code>name</code> attribute is specified, then it
defaults to "scsi_host". To keep backwards compatibility, the attribute
<code>type</code> is optional for the "scsi_host" adapter, but
mandatory for the "fc_host" adapter. Attributes <code>wwnn</code>
(Word Wide Node Name) and <code>wwpn</code> (Word Wide Port Name)
(<span class="since">1.0.4</span>) are used by the "fc_host" adapter
to uniquely identify the device in the Fibre Channel storage fabric
(the device can be either a HBA or vHBA). Both wwnn and wwpn should
be specified (See command 'virsh nodedev-dumpxml' to known how to get
wwnn/wwpn of a (v)HBA). The optional attribute <code>parent</code>
(<span class="since">1.0.4</span>) specifies the parent device for
the "fc_host" adapter.
only occur once. Contains a single attribute <code>name</code>
which is the SCSI adapter name (ex. "host1").
<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
@ -125,27 +98,6 @@
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. The <code>type</code>
must be either "chap" or "ceph". 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 secret element
<code>type</code> must be either "ceph" or "iscsi". Use "ceph" for
Ceph RBD (Rados Block Device) network sources and use "iscsi" for CHAP
(Challenge-Handshake Authentication Protocol) iSCSI targets.
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 (e.g., a logical volume group name).
@ -214,10 +166,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
@ -356,10 +309,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>
@ -388,22 +337,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>
@ -479,10 +412,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,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>
@ -35,9 +33,7 @@
git checkout -t origin -b workbranch
Hack, committing any changes along the way
</pre>
<p>More hints on compiling can be
found <a href="compiling.html">here</a>. When you want to
post your patches:</p>
<p>Then, when you want to post your patches:</p>
<pre>
git pull --rebase
(fix any conflicts)
@ -118,18 +114,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 +125,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:
@ -230,13 +203,13 @@
==4643== by 0x34D8C01569: ??? (in /usr/lib64/ld-2.15.so)
</pre>
<p>In this instance, it is acceptable to modify the
<p>In this instance, it is acceptible to modify the
<code>tests/.valgrind.supp</code> 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
<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 +234,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>
@ -402,35 +375,6 @@
int foo(int wizz); // 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>
@ -450,7 +394,7 @@
</pre>
<p>
However, the moment your loop/if/else body extends on to a second
However, the moment your loop/if/else body extends onto a second
line, for whatever reason (even if it's just an added comment), then
you should add braces. Otherwise, it would be too easy to insert a
statement just before that comment (without adding braces), thinking
@ -573,13 +517,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>
@ -677,7 +614,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>
@ -686,8 +623,10 @@
<pre>
virDomainPtr domain;
if (VIR_ALLOC(domain) &lt; 0)
if (VIR_ALLOC(domain) &lt; 0) {
virReportOOMError();
return NULL;
}
</pre>
</li>
@ -696,8 +635,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>
@ -706,8 +647,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>
@ -719,8 +662,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>
@ -733,8 +678,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>
@ -906,21 +853,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>
@ -997,12 +929,10 @@
</pre>
<p>
Of particular note: <b>Do not</b> include libvirt/libvirt.h,
libvirt/virterror.h, libvirt/libvirt-qemu.h, or libvirt/libvirt-lxc.h.
They are included by "internal.h" already and there are some special reasons
why you cannot include these files explicitly. One of the special cases,
"libvirt/libvirt.h" is included prior to "internal.h" in "remote_protocol.x",
to avoid exposing *_LAST enum elements.
Of particular note: <b>Do not</b> include libvirt/libvirt.h or
libvirt/virterror.h. It is included by "internal.h" already and there
are some special reasons why you cannot include these files
explicitly.
</p>

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>

View File

@ -18,7 +18,7 @@ my %groupheaders = (
"virDriver" => "Hypervisor APIs",
"virNetworkDriver" => "Virtual Network APIs",
"virInterfaceDriver" => "Host Interface APIs",
"virNodeDeviceDriver" => "Host Device APIs",
"virDeviceMonitor" => "Host Device APIs",
"virStorageDriver" => "Storage Pool APIs",
"virSecretDriver" => "Secret APIs",
"virNWFilterDriver" => "Network Filter APIs",
@ -154,7 +154,7 @@ close FILE;
# Some special things which aren't public APIs,
# but we want to report
$apis{virConnectSupportsFeature} = "0.3.2";
$apis{virConnectDrvSupportsFeature} = "0.3.2";
$apis{virDomainMigratePrepare} = "0.3.2";
$apis{virDomainMigratePerform} = "0.3.2";
$apis{virDomainMigrateFinish} = "0.3.2";
@ -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
@ -189,7 +182,7 @@ open FILE, "<$drivertable"
my %groups;
my $ingrp;
while (defined($line = <FILE>)) {
if ($line =~ /struct _(vir\w*Driver)/) {
if ($line =~ /struct _(vir\w*(?:Driver|Monitor))/) {
my $grp = $1;
if ($grp ne "virStateDriver" &&
$grp ne "virStreamDriver") {
@ -197,15 +190,17 @@ while (defined($line = <FILE>)) {
$groups{$ingrp} = { apis => {}, drivers => {} };
}
} elsif ($ingrp) {
if ($line =~ /^\s*vir(?:Drv)(\w+)\s+(\w+);\s*$/) {
if ($line =~ /^\s*vir(?:Drv|DevMon)(\w+)\s+(\w+);\s*$/) {
my $field = $2;
my $name = $1;
my $api;
if (exists $apis{"vir$name"}) {
$api = "vir$name";
} elsif ($name =~ /\w+(Open|Close)/) {
next;
} elsif (exists $apis{"virConnect$name"}) {
$api = "virConnect$name";
} elsif (exists $apis{"virNode$name"}) {
$api = "virNode$name";
} else {
die "driver $name does not have a public API";
}
@ -263,8 +258,6 @@ foreach my $src (@srcs) {
die "Driver method for $api is NULL in $src" if $meth eq "NULL";
if (!exists($groups{$ingrp}->{apis}->{$api})) {
next if $api =~ /\w(Open|Close)/;
die "Found unexpected method $api in $ingrp\n";
}
@ -297,24 +290,24 @@ $groups{virDriver}->{apis}->{"domainMigrate"} = "virDomainMigrate";
my $openAuthVers = (0 * 1000 * 1000) + (4 * 1000) + 0;
foreach my $drv (keys %{$groups{"virDriver"}->{drivers}}) {
my $openVersStr = $groups{"virDriver"}->{drivers}->{$drv}->{"connectOpen"};
my $openVersStr = $groups{"virDriver"}->{drivers}->{$drv}->{"open"};
my $openVers;
if ($openVersStr =~ /(\d+)\.(\d+)\.(\d+)/) {
$openVers = ($1 * 1000 * 1000) + ($2 * 1000) + $3;
}
# virConnectOpenReadOnly always matches virConnectOpen version
$groups{"virDriver"}->{drivers}->{$drv}->{"connectOpenReadOnly"} =
$groups{"virDriver"}->{drivers}->{$drv}->{"connectOpen"};
$groups{"virDriver"}->{drivers}->{$drv}->{"openReadOnly"} =
$groups{"virDriver"}->{drivers}->{$drv}->{"open"};
# virConnectOpenAuth is always 0.4.0 if the driver existed
# before this time, otherwise it matches the version of
# the driver's virConnectOpen entry
if ($openVersStr eq "Y" ||
$openVers >= $openAuthVers) {
$groups{"virDriver"}->{drivers}->{$drv}->{"connectOpenAuth"} = $openVersStr;
$groups{"virDriver"}->{drivers}->{$drv}->{"openAuth"} = $openVersStr;
} else {
$groups{"virDriver"}->{drivers}->{$drv}->{"connectOpenAuth"} = "0.4.0";
$groups{"virDriver"}->{drivers}->{$drv}->{"openAuth"} = "0.4.0";
}
}
@ -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>

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>

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,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>
@ -421,7 +418,7 @@
After a complete packet has been read, the header must be decoded
and all 6 fields fully validated, before attempting to dispatch
the payload. Once dispatched, the payload can be decoded and passed
on to the appropriate API for execution. The RPC code must not take
onto the appropriate API for execution. The RPC code must not take
any action based on the payload, since it has no way to validate
the semantics of the payload data. It must delegate this to the
execution API (e.g. corresponding libvirt public API).
@ -788,7 +785,7 @@
return value and output parameters, or error object and encode
them into a reply packet. Again it does not attempt to do any
semantic validation of output data, aside from variable length
field limit checks. The worker thread puts the reply packet on
field limit checks. The worker thread puts the reply packet onto
the transmission queue for the client. The worker is now finished
and goes back to wait for another incoming method call.
</p>
@ -814,10 +811,10 @@
for the worker threads, it is sidetracked into a per-stream
processing queue. When the stream becomes writable, queued
incoming stream packets will be processed, passing their data
payload on the stream. Conversely when the stream becomes
payload onto the stream. Conversely when the stream becomes
readable, chunks of data will be read from it, encoded into
new outgoing packets, and placed on the client's transmit
queue.
queue
</p>
<h4><a name="apiserverdispatchex1">Example with overlapping methods</a></h4>

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>Architecture</h1>
<p>Libvirt is a C toolkit manage the virtualization capabilities

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>Java API bindings</h1>

View File

@ -477,17 +477,3 @@ dl.variablelist > dt {
dl.variablelist > dt:after {
content: ": ";
}
table.acl {
margin: 1em;
border-spacing: 0px;
border: 1px solid #ccc;
}
table.acl tr, table.acl td {
padding: 0.3em;
}
table.acl thead {
background: #ddd;
}

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>Virtual machine disk locking</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 >Logging in the library and the daemon</h1>
<p>Libvirt includes logging facilities starting from version 0.6.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>Guest migration</h1>
@ -9,7 +7,7 @@
<p>
Migration of guests between hosts is a complicated problem with many possible
solutions, each with their own positive and negative points. For maximum
flexibility of both hypervisor integration, and administrator deployment,
flexibility of both hypervisor integration, and adminsitrator deployment,
libvirt implements several options for migration.
</p>
@ -32,7 +30,7 @@
</p>
<p>
<img class="diagram" src="migration-native.png" alt="Migration native path"/>
<img class="diagram" src="migration-native.png" alt="Migration native path">
</p>
<h3><a name="transporttunnel">libvirt tunnelled transport</a></h3>
@ -50,7 +48,7 @@
</p>
<p>
<img class="diagram" src="migration-tunnel.png" alt="Migration tunnel path"/>
<img class="diagram" src="migration-tunnel.png" alt="Migration tunnel path">
</p>
<h2><a name="flow">Communication control paths/flows</a></h2>
@ -77,7 +75,7 @@
</p>
<p>
<img class="diagram" src="migration-managed-direct.png" alt="Migration direct, managed"/>
<img class="diagram" src="migration-managed-direct.png" alt="Migration direct, managed">
</p>
@ -99,7 +97,7 @@
</p>
<p>
<img class="diagram" src="migration-managed-p2p.png" alt="Migration peer-to-peer"/>
<img class="diagram" src="migration-managed-p2p.png" alt="Migration peer-to-peer">
</p>
@ -115,7 +113,7 @@
</p>
<p>
<img class="diagram" src="migration-unmanaged-direct.png" alt="Migration direct, unmanaged"/>
<img class="diagram" src="migration-unmanaged-direct.png" alt="Migration direct, unmanaged">
</p>
@ -187,19 +185,19 @@
URI. In this case the management application should specify the
hypervisor specific URI explicitly, using an IP address, or a
correct hostname.</li>
<li>The host has multiple network interfaces. If a host has multiple
<li>The host has multiple network interaces. If a host has multiple
network interfaces, it might be desirable for the migration data
stream to be sent over a specific interface for either security
or performance reasons. In this case the management application
should specify the hypervisor specific URI, using an IP address
associated with the network to be used.</li>
<li>The firewall restricts what ports are available. When libvirt
generates a migration URI it will pick a port number using hypervisor
generates a migration URI will pick a port number using hypervisor
specific rules. Some hypervisors only require a single port to be
open in the firewalls, while others require a whole range of port
numbers. In the latter case the management application may wish
to choose a specific port number outside the default range in order
to comply with local firewall policies.</li>
to comply with local firewall policies</li>
</ol>
<h2><a name="config">Configuration file handling</a></h2>

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