[Libvir] PATCH: Allow control over UNIX socket perms & group in libvirtd
by Daniel P. Berrange
When I submitted the patches for PolicyKit[1] support a few weeks back Rich
suggested that we should have the ability to set UNIX socket permissions
and group ownership regardless. So this patch adds that ability. The default
setting is still, group=root, and mode=0700 for R/W socket and mode=0777
for the R/O socket.
It is possible to override this via the config file
eg, Don't allow R/O monitoring
unix_sock_ro_perms="0700"
eg, Allow any user in 'admin' group to manage VMs
unix_sock_group="admin"
unix_sock_rw_perms="0770"
eg, Allow anyone todo anything
unix_sock_rw_perms="0777"
NB, the fchgrp, and fchown syscalls don't have any effect on sockets, so
to set the group ownership & desired mode, I have to play games with the
setgid() and umask() calls prior to bind(), and then restore them to their
original values.
NB, the virConf apis don't seem to recognise Octal numbers when parsing
the config file, so I've used strings for the permissions. Not a big deal
really unless someone desperately wants to fix the config file parser...
Dan.
[1] A new set of patches will be forthcoming soon...
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
17 years, 2 months
[Libvir] PATCH: Avahi advertisement for libvirtd
by Daniel P. Berrange
This is a serious patch at supporting Avahi advertisement of the libvirtd
service.
- configure by default will probe to see if avahi is available and if
found will enable appropriate code.
--with-avahi will force error if not found
--without-avahi will disable it with no checking
- HAVE_AVAHI is defined in config.h if avahi is found & used to conditionally
enable some code in qemud/qemud.c
- HAVE_AVAHI is also a Makefile conditional to enable compilation of the
mdns.c and mdns.h files. A little makefile rearrangement was needed to
make sure variables like EXTRA_DIST were defined before we appended to
them with +=
- The code in mdns.c contains all the support for dealing with the Avahi
APIs.
- The primary Avahi API is horribily complicated for day-to-day
use in application code, exposing far too much of the event loop and
state machine. So we expose a simplified API to libvirt in mdns.h
- We fully support the Avahi state machine, so you can start libvirt even
if Avahi is not running on the machine. If you later start Avahi, then
libvirt will automatically detect & register with it. Likewise if you
stop Avahi we handle that gracefully by shutting down our internal mdns
support & waiting for avahi to restart.
NB this does require that the DBus system bus daemon is running. This
is a limitation of the current Avahi client library & not our use of it.
It is expected this will be fixed in future avahi releases.
- The Avahi client library is basically a shim which talks to the Avahi
daemon using DBus system daemon. The DBus stuff doesn't leak out of
the Avahi APIs - it is loosely couple - all we need do is provide Avahi
with an event loop implementation which was surprisingly easy. The
libvirtd daemon does now indirectly link with DBus, but I don't see any
problem with this. Don't want it - then use --without-avahi
- We advertise a service name of _libvirt._tcp The IETF draft recommends
use of the name from /etc/services associated with your app. There is a
way to register official Avahi services names. We don't have an /etc/service
name registered either though.
- If TLS is *not* enabled, we advertise _libvirt._tcp with a port number
of 0. The use of a port number 0 is explicitly allowed by the IETF
draft docs - see [1] "8. Flagship Naming". If seeing the _libvirt._tcp
service with a port of 0, then clients should figure out some way to
to tunnel to the UNXI domain socket on the advertised machine. The
tunnel mechanism is undefined, though SSH is the obvious choice.
If TLS is enabled, then we use getsockname() to fetch the actual port
number we're listening on for the TLS enabled socket. This plays nice
with admins ability to override the port number. Clients can still of
course choose to tunnel instead of use TLS.
NB. we explicitly refuse to advertise the non-TLS port.
- The default service name we advertise is 'Virtualization Host %h' where
'%h' is the short hostname (ie without domain name). This has to be less
than 63 characters & stripping domain name is usual practice, since this
is implicit from the mdns domain you are browsing.
This can be overridden with mdns_name="Blah" in the libvirtd.conf
configuration file. Service names *must* be unique in the LAN. If a name
clashes, then avahi appends junk like #1, #2, #3... until it is unique.
- Even when compiled in, use of Avahi mdns can be disabled by setting the
mdns_adv=0 config file parameter in /etc/libvirt/libvirtd.conf
- This patch does not advertise any per-VM VNC server instances, but I have
prepared the APIs in mdns.h to be ready to support that with minimal effort.
A pre-requisite for this is an extension to the driver API to get async
signals when VMs start & stop, since making the daemon poll hypervisors
will suck big time.
When implemented each VM will be its own mdns 'group' and the VNC server
associated with it will be the 'service' advertised in that group.
Having applied this patch & started the daemon, if /etc/init.d/avahi-daemon
is running, you should see the service advertised on the LAN. As mentioned
earlier if you start Avahi daemon after libvirt it should detect this too.
You can verify by running the following on another box on the same local
LAN segment.
$ avahi-browse --resolve _libvirt._tcp
When you start libvirtd on the other box the avahi-browse should print out
a record. It should look like this:
+ eth0 IPv4 Virtualization Host avocado _libvirt._tcp local
= eth0 IPv4 Virtualization Host avocado _libvirt._tcp local
hostname = [avocado.local]
address = [10.13.7.48]
port = [16514]
txt = ["org.freedesktop.Avahi.cookie=3025088350"]
If you've not configured TLS, then port will be '0' instead of 16514.
So that brings me nicely onto the main outstanding issue.
Notice the hostname is 'avocado.local' - this is the standard mdns practice
for zero-conf DNS hostnames. If you're /etc/nsswitch.conf is setup correctly
the name avocado.local will actually resolve to the IP address you see there
of '10.13.7.48' (well s/avocado/your hostname/ of course).
Well, x509 certificates include a FQDN in them & the client is expected to
validate the certificate hostname against the hostname it connected to. Now
my FQDN is avocado.virt.boston.redhat.com which is obviously going to not
validate against avocado.local.
There're a couple of ways around this issue I can come up with so far
- Recommend that the client try to reverse-DNS the 'address' field from
the mdns advertisement. If reverse-DNS is working, 10.13.7.48 will be
transformed into 'avocado.virt.boston.redhat.com' which the client can
then connect to.
- Add TXT record containing the hostname associated with the certificate.
If the client were to use this record, then obviously any validation of
it against the resulting certificate is sort-of pointless, since both
came from the server. The first approach rather had this drawback too.
- Advertise the records in the real domain 'virt.boston.redhat.com' instead
of '.local'. Not been able to make this work.
- Simply don't bother validating the remote hostname against the server
certificate cname. ie, take the position that if using zero-conf then
you already have some implicit level of trust in your LAN and validating
the cert against the CA cert is sufficient & hostname matching can be
ignored.
These are all mildy abusing mdns / zeroconf, but then x509 certificates don't
really fit into the model of 'zero conf' in the first place. If people want
true zero-conf then the (SSH) tunnel is better (and always available), but
if they've setup certificates they should still be allowed to use zero-conf
to at least locate hosts. So mildly abusing the rules is reasonable IMHO.
Personally I'm tending towards the latter approach.
Regards,
Dan.
[1] http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
17 years, 2 months
[Libvir] PATCH: Allow updating of timer & file handle event watches
by Daniel P. Berrange
The forthcoming patch to add Avahi support requires a couple of enhancements
to our event loop to support integration with Avahi's event callback needs
- Ability to update the event mask for a pre-existing file handle watch
- Ability to change the frequency of a timer watch
- Ability to have a timer which fires immediately
- Ability to disable events on a timer watch
The first point was trivial - just change the 'events' flag we have recorded
in the virEventHandle struct.
The second point was also trivial - just change the period of the timer as
recorded in virEventTimer struct.
The last two points were more tricky, but doable. To fire a timer immediately
I tweaked the logic so that it allows a frequency of '0'. Obviously to avoid
spinning 100%, the app should unregister the timer once it has fired the
desired number of times (usually 1). To disable a timer temporarily I allow
the use of '-1' in the frequency.
THe code had a bad mix of terminology using a 'timer' and 'timeout' field
in the virEventTimer struct which confused me no end. So I renamed the
'timeout' field to 'frequency' which reflects its actual purpose.
Finally, when building with debugging, the event loop can generate alot of
data, so I added a EVENT_DEBUG macro to the file which prefixes EVENT: on
all debug output so allow easy filtering.
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
17 years, 2 months
[Libvir] PATCH: Disable automake portability warnings
by Daniel P. Berrange
The latest automake has a nasty habit of complaining about use of GNU Make
features such as wildcards. We use these extensively in the tests/ directory
since there are so many test datafiles, listing them explicitly is a waste
of time.
The attached patch passes the -Wno-portability flag to automake to make it
keep quiet.
NB, to do this required a bit of a re-working of the automake/autoconf
initialization stuff. Our current configure script uses AC_INIT and
AM_INIT_AUTOMAKE in the so called 'legacy style'.
To quote the automake manual
[quote]
If your `configure.ac' has:
AC_INIT([src/foo.c])
AM_INIT_AUTOMAKE([mumble], [1.5])
you can modernize it as follows:
AC_INIT([mumble], [1.5])
AC_CONFIG_SRCDIR([src/foo.c])
AM_INIT_AUTOMAKE
[/quote]
This re-arrangement is valid on any non-jurassic era automake & only impacts
developers running autogen.sh - not end users running the configure script
itself.
The one complication is that the version given to AC_INIT must be a literal,
but we currently used an environment variable. So m4 black-magic gets around
this problem.
I also killed LIBVIRT_VERSION_EXTRA since it is not referenced anywhere in
the source tree.
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
17 years, 2 months
[Libvir] Network blocking issue
by Shuveb Hussain
Hi,
I observed this while using the python bindings and accessing a remote
host with libvirt:
>>> import libvirt
>>> c = libvirt.open('xen://veetee/')
>>> c.getInfo()
['i686', 2021, 2, 1864, 1, 1, 2, 1]
>>> c.getInfo()
['i686', 2021, 2, 1864, 1, 1, 2, 1]
# remove network cable from remote machine now
>>> c.getInfo()
# blocks forever....
What is the problem here and is there a solution to this? I am running
FC7 and here is the version info from virsh:
virsh # version
Compiled against library: libvir 0.3.2
Using library: libvir 0.3.2
Using API: Xen 3.0.1
Running hypervisor: Xen 3.1.0
I observed this for more than 10 mins, it was still hung.
Thanks in advance!
--
Shuveb Hussain.
Money has nothing to do with Happiness,
But, Poverty has a lot to do with Sorrow.
Company: www.binarykarma.com
Blog: www.binarykarma.org
17 years, 2 months
[Libvir] NUMA topology calls
by beth kon
Daniel,
We agreed that xenHypervisorGetCapabilities will call a xend_internal.c
function to get the topology through xend.
Was your intent to extend xenDaemonNodeGetInfo or have a new function,
such as xenDaemonNodeGetTopology? I assumed a new function would be
cleaner, but you didn't include such a function in your patch so I'm not
sure if you had some other idea.
--
Elizabeth Kon (Beth)
IBM Linux Technology Center
Open Hypervisor Team
email: eak(a)us.ibm.com
17 years, 2 months
[Libvir] PATCH: Prevent zombie ssh tunnels
by Daniel P. Berrange
I noticed that when using the SSH tunnel for the remote driver I ended up
with alot of zombie SSH processes. We simply forgot to waitpid() on the
child when a connection attempt failed, or when shutting down an open remote
connection. Attached is a possible patch
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
17 years, 2 months
[Libvir] RFC: Broadcast our presence with avahi
by Daniel P. Berrange
All the really trendy network services these days broadcast their presence
on the LAN using mDNS. In Linux world this means becoming an Avahi client
and registering our services. virt-manager is also able to become an Avahi
client and browser for services. So you'll be able to let the user just
pick a host straight off a list instead of typing in hostname.
The attached patch does two things:
- Extends our event loop implementation so it can modify the event mask
associated with an FD, and the timeout associated with a timer. While
you could simulate this with an add & remove, this has the possibility
of failure (from malloc). Merely updating an existing event can be done
without failure. Avahi needs this ability for its event loop integration
- Added qemu/mdns.c file to actually provide the service information. This
has two parts. The first section of code is taken straight from one of
the Avahi example programs. The second section is a implementaiton of the
Avahi event loop contract in terms of our event API - it works very nicely
which says good things about design of our event loop
Some things...
- I arbitrarily picked a service type of '_libvirtd._tcp'. The docs on
picking service types seem non-existant on Avahi website, but it seems
to be common to use service name from /etc/services and protocol both
prefixed with _.
- I advertise two subtypes, of '_xen.libvirtd._tcp' and '_qemu.libvirtd._tcp'
What I actually want todo is to be able to probe the libvirt local drivers
to auto-discover what virtualization platforms are available. A sort of
lightweight virConnectOpen which merely returns TRUE/FALSE and doesn't
actually allocate a virConnectPtr object. Need to extend the internal
driver API for this.
- I want to advertise whether the server is configured with TLS certs or
not, so remote clients can automatically choose to use SSH urls with
the remote driver if neccessary.
- Let the admin turn advertisement on/off in the config file because some
people may not like it on their LAN.
If you fancy trying it, avahi-browse --all from another host on the LAN
should show the service being advertised. The advertisements do not cross
LAN routers by default.
Dan.
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
17 years, 2 months
[Libvir] Segfault with invalid virConnectPtr
by Richard W.M. Jones
Program terminated with signal 11, Segmentation fault.
#0 0x0000003d8b472a1b in free () from /lib64/libc.so.6
(gdb) bt
#0 0x0000003d8b472a1b in free () from /lib64/libc.so.6
#1 0x00002aaaaaae8dd7 in virResetError (err=0x33535c8) at virterror.c:111
#2 0x00002aaaaaae8fce in __virRaiseError (conn=0x33535a0, dom=0x0,
net=0x0,
domain=0, code=6, level=VIR_ERR_ERROR,
str1=0x2aaaaab0c678 "invalid connection pointer in %s",
str2=0x2aaaaab08560 "virConnectNumOfDomains", str3=0x0, int1=0,
int2=0,
msg=0x2aaaaab0c678 "invalid connection pointer in %s") at
virterror.c:358
#3 0x00002aaaaaacfa8e in virLibConnError (conn=0x33535a0,
error=VIR_ERR_INVALID_CONN, info=0x2aaaaab08560
"virConnectNumOfDomains")
at libvirt.c:127
#4 0x00002aaaaaad1052 in virConnectNumOfDomains (conn=0x736e6961)
at libvirt.c:758
#5 0x000000000043fa4e in ?? ()
A preliminary look at the code seems to indicate a fault in this logic:
int
virConnectNumOfDomains(virConnectPtr conn)
{
DEBUG("conn=%p", conn);
if (!VIR_IS_CONNECT(conn)) {
virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
The VIR_IS_CONNECT macro is defined as:
#define VIR_CONNECT_MAGIC 0x4F23DEAD
#define VIR_IS_CONNECT(obj) ((obj) && (obj)->magic==VIR_CONNECT_MAGIC)
Obviously if VIR_IS_CONNECT fails then "conn" should not be used
further, so calling virLibConnError (conn, ...) is wrong. Personally I
think when we detect memory corruption in a C program we should just
call abort().
I'll see if I can come up with a patch to fix this later ... at the
moment I'm more interested in why my program is passing an invalid
connection pointer in the first place :-(
Rich.
--
Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/
Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in
England and Wales under Company Registration No. 03798903
17 years, 2 months
[Libvir] [PATCH] properly check buffer size in virDomainXMLDevID
by Hugh Brock
As promised, a patch to protect the 80-character "device id" buffer from
overflow by the unbounded "device=" XML attribute. Before, a large
"device" attribute gave a stack overflow error; now it merely results in
an obscure (but non-fatal) xend error like so:
libvir: Xen Daemon error : POST operation failed: (xend.err "invalid
literal for int() with base 10:
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'")
(the long string of "x"es was my way of overflowing the buffer).
Please ACK...
--Hugh
--
Red Hat Virtualization Group http://redhat.com/virtualization
Hugh Brock | virt-manager http://virt-manager.org
hbrock(a)redhat.com | virtualization library http://libvirt.org
17 years, 2 months