[libvirt] Live migration sanity checks
by Chris Lalancette
All,
One thing that oVirt would like to have (and that might be useful for other
users) is a call that would do some basic sanity checking for live migration.
This call would go over to the remote libvirtd, do some checks, and
return whether we think migration is likely to succeed. Note that I say
"likely to succeed", because there are certainly things that can cause migration
to fail after we've made checks, but anything is better than what we have today
("try it and pray").
Now, in order for this call to be widely useful, I think we would have to allow
the caller to specify *which* of the available checks they would like to
perform, and then have some sort of return value that indicated if there are
show-stopper problems, or just problems that may cause things to be sub-optimal
on the remote side. The caller could then decide what action it wants to take.
There is also a corollary to the "is it sane for me to migrate", which is, given
two hosts A and B, what's the lowest common denominator I need to run my guest
at so that migration will likely be successful between them. This could also be
used by management apps to make sure things are configured properly for the
guest before ever starting it.
The biggest problem with implementing these calls, however, is that there is no
comprehensive list of things we should check. This e-mail is an attempt to
write down some of the more obvious things we need to check, and to garner
discussion of things I might have missed. Once I have a proper list, I'll add
it to the TODO page on the libvirt Wiki so it's at least somewhere permanent.
Note that we don't have to implement *all* of these as a first go at this; if we
leave it open enough, we can add more checks as we go along without breaking
compatibility.
MIGRATION CRITERIA:
0) Matching hypervisors - seems obvious, but I'm not sure if we have these
checks today. Make sure we don't try to migrate Xen to KVM or vice-versa. We
also might want to think of at least warning the caller if you try to migrate
from a "newer" hypervisor (say, Xen 3.2) to an "older" hypervisor (say, Xen
3.1). That should, in theory, work, but maybe the caller would prefer not to do
that if possible. Rich has pointed out that KVM and Xen are accidentally
incompatible in libvirt, but we should make it explicit.
1) Matching CPU architectures - also obvious, but as far as I know today,
there's no checking for this (well, at least in Xen; I don't know about
libvirt). So you can happily attempt to migrate from i386 -> ia64, and watch
the fireworks. We also need to make sure you can't migrate x86_64 -> i386. I
believe i386 -> x86_64 should work, but this might be hypervisor dependent.
2) Matching CPU vendors - this one isn't a hard requirement; given the things
below, we may still be likely to succeed even if we go from AMD to Intel or
vice-versa. It still might be useful information for the caller to know.
3) CPU flags - the CPU flags of the destination *must* be a superset of the CPU
flags that were presented to the guest at startup. Many OS's and application
check for CPU flags once at startup to choose optimized routines, and then never
check again; if they happened to select sse3, and sse3 is not there on the
destination, then they will (eventually) crash.
This is where the CPU masking technology and the lowest common denominator
libvirt call can make a big difference. If you make sure to mask some of the
CPU flags off of the guest when you are first creating it, then the destination
host just needs a superset of the flags that were presented to the guest at
bootup, which makes the problem easier.
4) Number of CPUs - generally, you want the destination to have at least one
physical CPU for each virtual CPU assigned to the guest. However, I can see use
cases where this might not be the case (temporary or emergency migrations). So
this would probably be a warning, and the caller can make the choice of whether
to proceed.
5a) Memory - non-NUMA -> non-NUMA - fairly straightforward. The destination
must have enough memory to fit the guest memory. We might want to do some
"extra" checking on the destination to make sure we aren't going to OOM the
destination as soon as we arrive.
5b) Memory - non-NUMA -> NUMA - A little trickier. There are no cpusets we
have to worry about, since we are coming from non-NUMA, but for absolute best
performance, we should try to fit the whole guest into a single NUMA node. Of
course, if that node is overloaded, that may be a bad idea. NUMA placement
problem, basically.
5c) Memory - NUMA -> non-NUMA - Less tricky. On the destination, all memory is
"equally" far away, so no need to worry about cpusets. Just have to make sure
that there is enough memory on the destination for the guest.
5d) Memory - NUMA -> NUMA - Tricky, just like case 5b). Need to determine if
there is enough memory in the machine first, then check if we can fit the guest
in a single node, and also check if we can match the cpuset from the source on
the destination.
6a) Networks - at the very least, the destination must have the same bridges
configured as the source side. Whether those bridges are hooked to the same
physical networks as the source or not is another question, and may be outside
the bounds of what we can/should check.
6b) Networks - we need to make sure that the device model on the remote side
supports the same devices as the source side. That is, if you have a e1000 nic
on the source side, but your destination doesn't support it, you are going to
fail the migration.
7a) Disks - we have to make sure that all of the disks on the source side are
available on the destination side, at the same paths. To be entirely clear, we
have to make sure that the file on the destination side is the *same* file as on
the source side, not just a file with the same name. For traditional
file-based, the best we can do may be path names. For device names (like LVM,
actual disk partitions, etc.), we might be able to take advantage of device
enumaration API's and validate that the device info is the same (UUID matching,
etc.).
7b) Disks - Additionally, we need to make sure that the device model on the
remote side supports the same devices as the source side. That is, if you have
a virtio drive on the source side, but your destination host doesn't support
virtio on the backend, you are going to fail. (virtio might be a bad example,
but there might be further things in the device model in the future that we
might not necessarily have on both ends).
------ That's the absolute basic criteria. More esoteric/less thought-out
criteria follow:
8) Time skew - this is less thought out at the moment, but if you calibrated
your lpj at boot time, and now you migrate to a host with a different clock
frequency, your time will run either fast or slow compared to what you expect.
Also synchronized vs. unsynchronized TSC could cause issues, etc.
9) PCI-passthrough - this is actually a check on the *source* side. If the
guest is using a PCI passthrough device, it *usually* doesn't make sense to
live migrate it. On the other hand, it looks like various groups are trying to
make this work (with the bonding of a PV NIC to a PCI-passthrough NIC), so we
need to keep that in mind, and not necessarily make this a hard failure.
10) MSR's?? - I've thought about this one before, but I'm not sure what the
answer is. Unfortunately, MSR's in virtualization are sort of done hodge-podge.
That is, some MSR's are emulated for the guests, some MSR's guests have direct
control over, and some aren't emulated at all. This one can get ugly fast; it's
probably something we want to leave until later.
11) CPUID?? - Not entirely sure about this one; there is a lot of
model-specific information encoded in the various CPUID calls (things like cache
size, cache line size, etc. etc). However, I don't know if CPUID instructions
are trapped-n-emulated under the different hypervisors, or if they are done
right on the processor itself. I guess if an OS or application called this at
startup, cached the information, and then checked again later it might get
upset, but it seems somewhat unlikely.
Things that I've missed?
Thanks,
Chris Lalancette
16 years, 1 month
[libvirt] mingw warnings
by Jim Meyering
I've been building with mingw to make sure that my gnulib-upgrade-and-extend
patch doesn't break anything and found some compiler warnings.
I fixed most of them, but this one is ugly:
../qemud/remote_protocol.c:317: warning: assignment from incompatible pointer type
../qemud/remote_protocol.c:346: warning: assignment from incompatible pointer type
That's due to the fact that the mingw xdr.h header,
/usr/i686-pc-mingw32/sys-root/mingw/include/rpc/xdr.h, defines this
#define XDR_INLINE(xdrs, len) \
(*(xdrs)->x_ops->x_inline)(xdrs, len)
and has an x_inline member of type long*,
typedef struct {
enum xdr_op x_op; /* operation; fast additional param */
struct xdr_ops {
bool_t (*x_getlong)(); /* get a long from underlying stream */
bool_t (*x_putlong)(); /* put a long to " */
bool_t (*x_getbytes)();/* get some bytes from " */
bool_t (*x_putbytes)();/* put some bytes to " */
u_int (*x_getpostn)();/* returns bytes off from beginning */
bool_t (*x_setpostn)();/* lets you reposition the stream */
long * (*x_inline)(); /* buf quick ptr to buffered data */
while we're used to one with type matching buf: int32_t*:
If you're serious about getting rid of warnings even on mingw,
here's one approach:
diff --git a/qemud/remote_protocol.c b/qemud/remote_protocol.c
index 68e9696..c8cf504 100644
--- a/qemud/remote_protocol.c
+++ b/qemud/remote_protocol.c
@@ -314,7 +314,7 @@ xdr_remote_node_get_info_ret (XDR *xdrs, remote_node_get_info_ret *objp)
return FALSE;
if (!xdr_quad_t (xdrs, &objp->memory))
return FALSE;
- buf = XDR_INLINE (xdrs, 6 * BYTES_PER_XDR_UNIT);
+ buf = (void*)XDR_INLINE (xdrs, 6 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->cpus))
return FALSE;
@@ -343,7 +343,7 @@ xdr_remote_node_get_info_ret (XDR *xdrs, remote_node_get_info_ret *objp)
return FALSE;
if (!xdr_quad_t (xdrs, &objp->memory))
return FALSE;
- buf = XDR_INLINE (xdrs, 6 * BYTES_PER_XDR_UNIT);
+ buf = (void*)XDR_INLINE (xdrs, 6 * BYTES_PER_XDR_UNIT);
if (buf == NULL) {
if (!xdr_int (xdrs, &objp->cpus))
return FALSE;
Better would be to fix the decl in xdr.h, but probably not feasible.
Alternatively, redefine XDR_INLINE for mingw, adding the void* cast in that.
But that means peeking inside (and copying) the current definition,
so I prefer the above.
So I'm leaning towards using the patch above.
16 years, 1 month
[libvirt] FYI: fixes to events code for mingw
by Daniel P. Berrange
FYI, I just committed the following patch to remove a couple of unneccessary
includes of sys/poll.h, and disable the event-test demo on platforms which
lack sys/poll.h This makes the mingw builds work again
Regards,
Daniel
Index: configure.in
===================================================================
RCS file: /data/cvs/libvirt/configure.in,v
retrieving revision 1.176
diff -u -p -r1.176 configure.in
--- configure.in 23 Oct 2008 13:18:18 -0000 1.176
+++ configure.in 24 Oct 2008 13:08:15 -0000
@@ -70,7 +70,7 @@ dnl Availability of various common funct
AC_CHECK_FUNCS([cfmakeraw regexec uname sched_getaffinity getuid getgid])
dnl Availability of various common headers (non-fatal if missing).
-AC_CHECK_HEADERS([pwd.h paths.h regex.h sys/syslimits.h sys/utsname.h sys/wait.h winsock2.h sched.h termios.h])
+AC_CHECK_HEADERS([pwd.h paths.h regex.h sys/syslimits.h sys/utsname.h sys/wait.h winsock2.h sched.h termios.h sys/poll.h])
dnl Where are the XDR functions?
dnl If portablexdr is installed, prefer that.
Index: examples/domain-events/events-c/event-test.c
===================================================================
RCS file: /data/cvs/libvirt/examples/domain-events/events-c/event-test.c,v
retrieving revision 1.1
diff -u -p -r1.1 event-test.c
--- examples/domain-events/events-c/event-test.c 23 Oct 2008 13:18:18 -0000 1.1
+++ examples/domain-events/events-c/event-test.c 24 Oct 2008 13:08:15 -0000
@@ -1,6 +1,9 @@
#include <config.h>
+
#include <stdio.h>
#include <string.h>
+
+#if HAVE_SYS_POLL_H
#include <sys/types.h>
#include <sys/poll.h>
#include <libvirt/libvirt.h>
@@ -259,3 +262,9 @@ int main(int argc, char **argv)
return 0;
}
+#else
+int main(void) {
+ printf("event-test program not available without sys/poll.h support\n");
+ return 1;
+}
+#endif
Index: src/libvirt.c
===================================================================
RCS file: /data/cvs/libvirt/src/libvirt.c,v
retrieving revision 1.162
diff -u -p -r1.162 libvirt.c
--- src/libvirt.c 24 Oct 2008 08:55:13 -0000 1.162
+++ src/libvirt.c 24 Oct 2008 13:08:16 -0000
@@ -16,7 +16,6 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/poll.h>
#include <unistd.h>
#include <assert.h>
#ifdef HAVE_SYS_WAIT_H
Index: src/remote_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/remote_internal.c,v
retrieving revision 1.89
diff -u -p -r1.89 remote_internal.c
--- src/remote_internal.c 23 Oct 2008 13:18:18 -0000 1.89
+++ src/remote_internal.c 24 Oct 2008 13:08:16 -0000
@@ -34,7 +34,6 @@
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/poll.h>
#include <fcntl.h>
#ifdef HAVE_SYS_WAIT_H
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
16 years, 1 month
[libvirt] PATCH: Remove util-lib file and replace with libvirt_util.la
by Daniel P. Berrange
We've currently got a slightly nasty hack where some of the stuff from
util.c is split into a util-lib.c file so it can be compiled twice,
once for libvirt.la, and second for virsh, without exporting it in our
public API. I'm trying to clean up the code / file deps and build stuff
in preparation of dlopen() support of drivers. We also have a bunch of
stuff in util.a that is exported unofficially in the ABI.
This patch demonstrates a different approach, putting the util-lib.c code
back into util.c. We then define a libtool convenience library covering
a bunch of our generic common code, that is linked to both libvirt.la
and virsh. This also lets us remove most of the secret exports from
util.c.
The main change is that a little more code is statically linked into
virsh binary itself. Personally I don't think this is a huge problem.
Another possible approach though could be to create a real libvirt-common.so
file which gets installed into /usr/lib, but is explicitly not preserving
ABI. We could enforce this by using a version script to encode a version
number against every symbol. This would mean anyone linking to the
libvirt-common.so would be forced to relink on every new update - which
would be such a PITA only in-tree programs like virsh & libvirtd would
do it.
Daniel
diff -r 5bd402f3762e configure.in
--- a/configure.in Fri Oct 24 14:13:53 2008 +0100
+++ b/configure.in Fri Oct 24 14:14:07 2008 +0100
@@ -671,6 +671,8 @@
with_storage_dir=yes
if test "$with_libvirtd" = "no"; then
+ with_qemu=no
+ with_lxc=no
with_storage_dir=no
with_storage_fs=no
with_storage_lvm=no
diff -r 5bd402f3762e qemud/Makefile.am
--- a/qemud/Makefile.am Fri Oct 24 14:13:53 2008 +0100
+++ b/qemud/Makefile.am Fri Oct 24 14:14:07 2008 +0100
@@ -9,8 +9,7 @@
remote_dispatch_prototypes.h \
remote_dispatch_localvars.h \
remote_dispatch_proc_switch.h \
- remote_protocol.h remote_protocol.c \
- $(srcdir)/../src/util-lib.c
+ remote_protocol.h remote_protocol.c
AVAHI_SOURCES = \
mdns.c mdns.h
@@ -88,7 +87,7 @@
$(POLKIT_LIBS)
libvirtd_DEPENDENCIES = ../src/libvirt.la
-libvirtd_LDADD = ../src/libvirt.la ../gnulib/lib/libgnu.la
+libvirtd_LDADD = ../src/libvirt.la ../src/libvirt_util.la ../gnulib/lib/libgnu.la
if HAVE_POLKIT
policydir = $(datadir)/PolicyKit/policy
diff -r 5bd402f3762e src/Makefile.am
--- a/src/Makefile.am Fri Oct 24 14:13:53 2008 +0100
+++ b/src/Makefile.am Fri Oct 24 14:14:07 2008 +0100
@@ -37,21 +37,30 @@
lib_LTLIBRARIES = libvirt.la
+noinst_LTLIBRARIES = libvirt_util.la
+
# These files are not related to driver APIs. Simply generic
# helper APIs for various purposes
-GENERIC_LIB_SOURCES = \
- bridge.c bridge.h \
+UTIL_SOURCES = \
buf.c buf.h \
conf.c conf.h \
event.c event.h \
- iptables.c iptables.h \
memory.c memory.h \
qparams.c qparams.h \
- stats_linux.c stats_linux.h \
uuid.c uuid.h \
util.c util.h \
virterror.c \
xml.c xml.h
+
+DRIVER_SOURCES = \
+ driver.h \
+ hash.c hash.h \
+ internal.h \
+ libvirt.c \
+ bridge.c bridge.h \
+ iptables.c iptables.h \
+ stats_linux.c stats_linux.h
+
# Domain driver generic impl APIs
DOMAIN_CONF_SOURCES = \
@@ -147,14 +156,13 @@
# First deal with sources usable in non-daemon context
libvirt_la_SOURCES = \
- driver.h \
- hash.c hash.h \
- internal.h \
- libvirt.c \
- $(GENERIC_LIB_SOURCES) \
+ $(DRIVER_SOURCES) \
$(DOMAIN_CONF_SOURCES) \
$(NETWORK_CONF_SOURCES) \
$(STORAGE_CONF_SOURCES)
+
+libvirt_util_la_SOURCES = \
+ $(UTIL_SOURCES)
# Drivers usable outside daemon context
if WITH_TEST
@@ -180,6 +188,7 @@
endif
libvirt_la_SOURCES += $(STORAGE_DRIVER_SOURCES)
libvirt_la_SOURCES += $(STORAGE_DRIVER_FS_SOURCES)
+endif
if WITH_QEMU
libvirt_la_SOURCES += $(QEMU_DRIVER_SOURCES)
@@ -200,7 +209,6 @@
if WITH_STORAGE_DISK
libvirt_la_SOURCES += $(STORAGE_DRIVER_DISK_SOURCES)
endif
-endif
# Add all conditional sources just in case...
EXTRA_DIST += \
@@ -220,17 +228,18 @@
libvirt_la_LIBADD = $(LIBXML_LIBS) $(GNUTLS_LIBS) $(SASL_LIBS) $(SELINUX_LIBS) \
$(NUMACTL_LIBS) \
+ libvirt_util.la \
@CYGWIN_EXTRA_LIBADD@ ../gnulib/lib/libgnu.la
libvirt_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libvirt_sym.version \
-version-info @LIBVIRT_VERSION_INFO@ \
$(COVERAGE_CFLAGS:-f%=-Wc,-f%) \
@CYGWIN_EXTRA_LDFLAGS@ @MINGW_EXTRA_LDFLAGS@
-libvirt_la_CFLAGS = $(COVERAGE_CFLAGS) -DIN_LIBVIRT
+libvirt_la_CFLAGS = $(COVERAGE_CFLAGS)
# Create an automake "convenience library" version of libvirt_la,
# just for testing, since the test harness requires access to internal
# bits and pieces that we don't want to make publicly accessible.
-noinst_LTLIBRARIES = libvirt_test.la
+noinst_LTLIBRARIES += libvirt_test.la
# Convert libvirt_sym.version
# to libvirt_test_sym.version, and
@@ -250,12 +259,11 @@
virsh_SOURCES = \
console.c console.h \
- util-lib.c util-lib.h \
virsh.c
virsh_LDFLAGS = $(WARN_CFLAGS) $(COVERAGE_LDFLAGS)
virsh_DEPENDENCIES = $(DEPS)
-virsh_LDADD = $(LDADDS) $(VIRSH_LIBS)
+virsh_LDADD = $(LDADDS) $(VIRSH_LIBS) libvirt_util.la
virsh_CFLAGS = $(COVERAGE_CFLAGS) $(READLINE_CFLAGS)
BUILT_SOURCES = virsh-net-edit.c virsh-pool-edit.c
@@ -320,7 +328,6 @@
libexec_PROGRAMS =
if WITH_STORAGE_DISK
-if WITH_LIBVIRTD
libexec_PROGRAMS += libvirt_parthelper
libvirt_parthelper_SOURCES = $(STORAGE_HELPER_DISK_SOURCES)
@@ -328,22 +335,19 @@
libvirt_parthelper_LDADD = $(LIBPARTED_LIBS)
libvirt_parthelper_CFLAGS = $(LIBPARTED_CFLAGS)
endif
-endif
EXTRA_DIST += $(STORAGE_HELPER_DISK_SOURCES)
if WITH_LXC
-if WITH_LIBVIRTD
libexec_PROGRAMS += libvirt_lxc
libvirt_lxc_SOURCES = \
$(LXC_CONTROLLER_SOURCES) \
- $(GENERIC_LIB_SOURCES) \
$(DOMAIN_CONF_SOURCES)
libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(COVERAGE_LDCFLAGS)
-libvirt_lxc_LDADD = $(LIBXML_LIBS) ../gnulib/lib/libgnu.la
+libvirt_lxc_LDADD = $(LIBXML_LIBS) ../gnulib/lib/libgnu.la \
+ libvirt_util.la
libvirt_lxc_CFLAGS = $(LIBPARTED_CFLAGS)
-endif
endif
EXTRA_DIST += $(LXC_CONTROLLER_SOURCES)
diff -r 5bd402f3762e src/buf.c
--- a/src/buf.c Fri Oct 24 14:13:53 2008 +0100
+++ b/src/buf.c Fri Oct 24 14:14:07 2008 +0100
@@ -88,7 +88,7 @@
*
*/
void
-__virBufferAdd(const virBufferPtr buf, const char *str, int len)
+virBufferAdd(const virBufferPtr buf, const char *str, int len)
{
unsigned int needSize;
@@ -120,7 +120,7 @@
*
*/
void
-__virBufferAddChar (virBufferPtr buf, char c)
+virBufferAddChar (virBufferPtr buf, char c)
{
unsigned int needSize;
@@ -150,7 +150,7 @@
* Returns the buffer content or NULL in case of error.
*/
char *
-__virBufferContentAndReset(const virBufferPtr buf)
+virBufferContentAndReset(const virBufferPtr buf)
{
char *str;
if (buf == NULL)
@@ -176,7 +176,7 @@
* Return true if in error, 0 if normal
*/
int
-__virBufferError(const virBufferPtr buf)
+virBufferError(const virBufferPtr buf)
{
if (buf == NULL)
return 1;
@@ -208,7 +208,7 @@
* Do a formatted print to an XML buffer.
*/
void
-__virBufferVSprintf(const virBufferPtr buf, const char *format, ...)
+virBufferVSprintf(const virBufferPtr buf, const char *format, ...)
{
int size, count, grow_size;
va_list locarg, argptr;
diff -r 5bd402f3762e src/buf.h
--- a/src/buf.h Fri Oct 24 14:13:53 2008 +0100
+++ b/src/buf.h Fri Oct 24 14:14:07 2008 +0100
@@ -34,25 +34,18 @@
};
#endif
-char *__virBufferContentAndReset(const virBufferPtr buf);
-int __virBufferError(const virBufferPtr buf);
+char *virBufferContentAndReset(const virBufferPtr buf);
+int virBufferError(const virBufferPtr buf);
unsigned int virBufferUse(const virBufferPtr buf);
-void __virBufferAdd(const virBufferPtr buf, const char *str, int len);
-void __virBufferAddChar(const virBufferPtr buf, char c);
-void __virBufferVSprintf(const virBufferPtr buf, const char *format, ...)
+void virBufferAdd(const virBufferPtr buf, const char *str, int len);
+void virBufferAddChar(const virBufferPtr buf, char c);
+void virBufferVSprintf(const virBufferPtr buf, const char *format, ...)
ATTRIBUTE_FORMAT(printf, 2, 3);
void virBufferStrcat(const virBufferPtr buf, ...);
void virBufferEscapeString(const virBufferPtr buf, const char *format, const char *str);
void virBufferURIEncodeString (const virBufferPtr buf, const char *str);
#define virBufferAddLit(buf_, literal_string_) \
- __virBufferAdd (buf_, "" literal_string_ "", sizeof literal_string_ - 1)
-
-#define virBufferAdd(b,s,l) __virBufferAdd((b),(s),(l))
-#define virBufferAddChar(b,c) __virBufferAddChar((b),(c))
-#define virBufferVSprintf(b,f,...) __virBufferVSprintf((b),(f), __VA_ARGS__)
-
-#define virBufferContentAndReset(b) __virBufferContentAndReset((b))
-#define virBufferError(b) __virBufferError((b))
+ virBufferAdd (buf_, "" literal_string_ "", sizeof literal_string_ - 1)
#endif /* __VIR_BUFFER_H__ */
diff -r 5bd402f3762e src/conf.c
--- a/src/conf.c Fri Oct 24 14:13:53 2008 +0100
+++ b/src/conf.c Fri Oct 24 14:14:07 2008 +0100
@@ -142,7 +142,7 @@
* Free a value
*/
void
-__virConfFreeValue(virConfValuePtr val)
+virConfFreeValue(virConfValuePtr val)
{
if (val == NULL)
return;
@@ -156,7 +156,7 @@
}
virConfPtr
-__virConfNew(void)
+virConfNew(void)
{
virConfPtr ret;
@@ -691,7 +691,7 @@
#define MAX_CONFIG_FILE_SIZE (1024*1024*10)
/**
- * __virConfReadFile:
+ * virConfReadFile:
* @filename: the path to the configuration file.
*
* Reads a configuration file.
@@ -700,7 +700,7 @@
* read or parse the file, use virConfFree() to free the data.
*/
virConfPtr
-__virConfReadFile(const char *filename)
+virConfReadFile(const char *filename)
{
char *content;
int len;
@@ -724,7 +724,7 @@
}
/**
- * __virConfReadMem:
+ * virConfReadMem:
* @memory: pointer to the content of the configuration file
* @len: length in byte
*
@@ -735,7 +735,7 @@
* parse the content, use virConfFree() to free the data.
*/
virConfPtr
-__virConfReadMem(const char *memory, int len)
+virConfReadMem(const char *memory, int len)
{
if ((memory == NULL) || (len < 0)) {
virConfError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
@@ -748,7 +748,7 @@
}
/**
- * __virConfFree:
+ * virConfFree:
* @conf: a configuration file handle
*
* Frees all data associated to the handle
@@ -756,7 +756,7 @@
* Returns 0 in case of success, -1 in case of error.
*/
int
-__virConfFree(virConfPtr conf)
+virConfFree(virConfPtr conf)
{
virConfEntryPtr tmp;
if (conf == NULL) {
@@ -779,7 +779,7 @@
}
/**
- * __virConfGetValue:
+ * virConfGetValue:
* @conf: a configuration file handle
* @entry: the name of the entry
*
@@ -789,7 +789,7 @@
* associated will be freed when virConfFree() is called
*/
virConfValuePtr
-__virConfGetValue(virConfPtr conf, const char *setting)
+virConfGetValue(virConfPtr conf, const char *setting)
{
virConfEntryPtr cur;
@@ -803,7 +803,7 @@
}
/**
- * __virConfSetValue:
+ * virConfSetValue:
* @conf: a configuration file handle
* @entry: the name of the entry
* @value: the new configuration value
@@ -816,7 +816,7 @@
* Returns 0 on success, or -1 on failure.
*/
int
-__virConfSetValue (virConfPtr conf,
+virConfSetValue (virConfPtr conf,
const char *setting,
virConfValuePtr value)
{
@@ -861,7 +861,7 @@
/**
- * __virConfWriteFile:
+ * virConfWriteFile:
* @filename: the path to the configuration file.
* @conf: the conf
*
@@ -870,7 +870,7 @@
* Returns the number of bytes written or -1 in case of error.
*/
int
-__virConfWriteFile(const char *filename, virConfPtr conf)
+virConfWriteFile(const char *filename, virConfPtr conf)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
virConfEntryPtr cur;
@@ -915,7 +915,7 @@
}
/**
- * __virConfWriteMem:
+ * virConfWriteMem:
* @memory: pointer to the memory to store the config file
* @len: pointer to the length in bytes of the store, on output the size
* @conf: the conf
@@ -928,7 +928,7 @@
* Returns the number of bytes written or -1 in case of error.
*/
int
-__virConfWriteMem(char *memory, int *len, virConfPtr conf)
+virConfWriteMem(char *memory, int *len, virConfPtr conf)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
virConfEntryPtr cur;
diff -r 5bd402f3762e src/conf.h
--- a/src/conf.h Fri Oct 24 14:13:53 2008 +0100
+++ b/src/conf.h Fri Oct 24 14:14:07 2008 +0100
@@ -61,32 +61,22 @@
typedef struct _virConf virConf;
typedef virConf *virConfPtr;
-virConfPtr __virConfNew (void);
-virConfPtr __virConfReadFile (const char *filename);
-virConfPtr __virConfReadMem (const char *memory,
+virConfPtr virConfNew (void);
+virConfPtr virConfReadFile (const char *filename);
+virConfPtr virConfReadMem (const char *memory,
int len);
-int __virConfFree (virConfPtr conf);
-void __virConfFreeValue (virConfValuePtr val);
+int virConfFree (virConfPtr conf);
+void virConfFreeValue (virConfValuePtr val);
-virConfValuePtr __virConfGetValue (virConfPtr conf,
+virConfValuePtr virConfGetValue (virConfPtr conf,
const char *setting);
-int __virConfSetValue (virConfPtr conf,
+int virConfSetValue (virConfPtr conf,
const char *setting,
virConfValuePtr value);
-int __virConfWriteFile (const char *filename,
+int virConfWriteFile (const char *filename,
virConfPtr conf);
-int __virConfWriteMem (char *memory,
+int virConfWriteMem (char *memory,
int *len,
virConfPtr conf);
-#define virConfNew() __virConfNew()
-#define virConfReadFile(f) __virConfReadFile((f))
-#define virConfReadMem(m,l) __virConfReadMem((m),(l))
-#define virConfFree(c) __virConfFree((c))
-#define virConfFreeValue(v) __virConfFreeValue((v))
-#define virConfGetValue(c,s) __virConfGetValue((c),(s))
-#define virConfSetValue(c,s,v) __virConfSetValue((c),(s),(v))
-#define virConfWriteFile(f,c) __virConfWriteFile((f),(c))
-#define virConfWriteMem(m,l,c) __virConfWriteMem((m),(l),(c))
-
#endif /* __VIR_CONF_H__ */
diff -r 5bd402f3762e src/console.c
--- a/src/console.c Fri Oct 24 14:13:53 2008 +0100
+++ b/src/console.c Fri Oct 24 14:14:07 2008 +0100
@@ -37,7 +37,7 @@
#include "console.h"
#include "internal.h"
-#include "util-lib.h"
+#include "util.h"
/* ie Ctrl-] as per telnet */
#define CTRL_CLOSE_BRACKET '\35'
diff -r 5bd402f3762e src/libvirt_sym.version
--- a/src/libvirt_sym.version Fri Oct 24 14:13:53 2008 +0100
+++ b/src/libvirt_sym.version Fri Oct 24 14:14:07 2008 +0100
@@ -157,15 +157,6 @@
guarentee provided for the public
symbols above */
- __virConfNew;
- __virConfReadFile;
- __virConfReadMem;
- __virConfFree;
- __virConfGetValue;
- __virConfSetValue;
- __virConfWriteFile;
- __virConfWriteMem;
-
__virGetDomain;
__virGetNetwork;
__virGetStoragePool;
@@ -183,21 +174,5 @@
__virDomainMigratePerform;
__virDomainMigrateFinish;
- __virFileReadAll;
- __virStrToLong_i;
- __virStrToLong_ull;
-
- __virBufferVSprintf;
- __virBufferAdd;
- __virBufferAddChar;
- __virBufferContentAndReset;
- __virBufferError;
-
- __virMacAddrCompare;
-
- __virAlloc;
- __virAllocN;
- __virReallocN;
- __virFree;
local: *;
};
diff -r 5bd402f3762e src/util-lib.c
--- a/src/util-lib.c Fri Oct 24 14:13:53 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * common, generic utility functions
- *
- * Copyright (C) 2006, 2007, 2008 Red Hat, Inc.
- * See COPYING.LIB for the License of this software
- */
-
-#include <config.h>
-
-#include <unistd.h>
-#include <errno.h>
-
-#include "util-lib.h"
-
-/* Like read(), but restarts after EINTR */
-int saferead(int fd, void *buf, size_t count)
-{
- size_t nread = 0;
- while (count > 0) {
- ssize_t r = read(fd, buf, count);
- if (r < 0 && errno == EINTR)
- continue;
- if (r < 0)
- return r;
- if (r == 0)
- return nread;
- buf = (char *)buf + r;
- count -= r;
- nread += r;
- }
- return nread;
-}
-
-/* Like write(), but restarts after EINTR */
-ssize_t safewrite(int fd, const void *buf, size_t count)
-{
- size_t nwritten = 0;
- while (count > 0) {
- ssize_t r = write(fd, buf, count);
-
- if (r < 0 && errno == EINTR)
- continue;
- if (r < 0)
- return r;
- if (r == 0)
- return nwritten;
- buf = (const char *)buf + r;
- count -= r;
- nwritten += r;
- }
- return nwritten;
-}
diff -r 5bd402f3762e src/util-lib.h
--- a/src/util-lib.h Fri Oct 24 14:13:53 2008 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/*
- * private utility functions
- *
- * Copyright (C) 2008 Red Hat, Inc.
- * See COPYING.LIB for the License of this software
- */
-
-#ifndef __UTIL_LIB_H__
-#define __UTIL_LIB_H__
-
-#include <sys/types.h>
-
-/*
- * To avoid a double definition of the function when compiling
- * programs using both util-lib and libvirt, like virsh
- */
-#ifdef IN_LIBVIRT
-#define saferead libvirt_saferead
-#define safewrite libvirt_safewrite
-#endif
-
-int saferead(int fd, void *buf, size_t count);
-ssize_t safewrite(int fd, const void *buf, size_t count);
-
-#endif
diff -r 5bd402f3762e src/util.c
--- a/src/util.c Fri Oct 24 14:13:53 2008 +0100
+++ b/src/util.c Fri Oct 24 14:14:07 2008 +0100
@@ -52,7 +52,6 @@
#include "buf.h"
#include "util.h"
#include "memory.h"
-#include "util-lib.c"
#ifndef NSIG
# define NSIG 32
@@ -502,7 +501,7 @@
}
/* Like virFileReadLimFP, but use a file descriptor rather than a FILE*. */
-int __virFileReadLimFD(int fd_arg, int maxlen, char **buf)
+int virFileReadLimFD(int fd_arg, int maxlen, char **buf)
{
int fd = dup (fd_arg);
if (fd >= 0) {
@@ -522,7 +521,7 @@
return -1;
}
-int __virFileReadAll(const char *path, int maxlen, char **buf)
+int virFileReadAll(const char *path, int maxlen, char **buf)
{
FILE *fh = fopen(path, "r");
if (fh == NULL) {
@@ -812,7 +811,7 @@
validity. This function is careful to return -1 when the string S
represents a number that is not representable as an "int". */
int
-__virStrToLong_i(char const *s, char **end_ptr, int base, int *result)
+virStrToLong_i(char const *s, char **end_ptr, int base, int *result)
{
long int val;
char *p;
@@ -869,7 +868,7 @@
/* Just like virStrToLong_i, above, but produce an "unsigned long long" value. */
int
-__virStrToLong_ull(char const *s, char **end_ptr, int base, unsigned long long *result)
+virStrToLong_ull(char const *s, char **end_ptr, int base, unsigned long long *result)
{
unsigned long long val;
char *p;
@@ -941,7 +940,7 @@
* as well as leading zeros.
*/
int
-__virMacAddrCompare (const char *p, const char *q)
+virMacAddrCompare (const char *p, const char *q)
{
unsigned char c, d;
do {
@@ -1090,3 +1089,44 @@
return idx;
}
+
+
+/* Like read(), but restarts after EINTR */
+int saferead(int fd, void *buf, size_t count)
+{
+ size_t nread = 0;
+ while (count > 0) {
+ ssize_t r = read(fd, buf, count);
+ if (r < 0 && errno == EINTR)
+ continue;
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return nread;
+ buf = (char *)buf + r;
+ count -= r;
+ nread += r;
+ }
+ return nread;
+}
+
+/* Like write(), but restarts after EINTR */
+ssize_t safewrite(int fd, const void *buf, size_t count)
+{
+ size_t nwritten = 0;
+ while (count > 0) {
+ ssize_t r = write(fd, buf, count);
+
+ if (r < 0 && errno == EINTR)
+ continue;
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return nwritten;
+ buf = (const char *)buf + r;
+ count -= r;
+ nwritten += r;
+ }
+ return nwritten;
+}
+
diff -r 5bd402f3762e src/util.h
--- a/src/util.h Fri Oct 24 14:13:53 2008 +0100
+++ b/src/util.h Fri Oct 24 14:14:07 2008 +0100
@@ -25,7 +25,6 @@
#ifndef __VIR_UTIL_H__
#define __VIR_UTIL_H__
-#include "util-lib.h"
#include "verify.h"
#include <sys/select.h>
@@ -46,11 +45,12 @@
int flags);
int virRun(virConnectPtr conn, const char *const*argv, int *status);
-int __virFileReadLimFD(int fd, int maxlen, char **buf);
-#define virFileReadLimFD(fd,m,b) __virFileReadLimFD((fd),(m),(b))
+int saferead(int fd, void *buf, size_t count);
+ssize_t safewrite(int fd, const void *buf, size_t count);
-int __virFileReadAll(const char *path, int maxlen, char **buf);
-#define virFileReadAll(p,m,b) __virFileReadAll((p),(m),(b))
+int virFileReadLimFD(int fd, int maxlen, char **buf);
+
+int virFileReadAll(const char *path, int maxlen, char **buf);
int virFileMatchesNameSuffix(const char *file,
const char *name,
@@ -88,11 +88,10 @@
int virFileDeletePid(const char *dir,
const char *name);
-int __virStrToLong_i(char const *s,
- char **end_ptr,
- int base,
- int *result);
-#define virStrToLong_i(s,e,b,r) __virStrToLong_i((s),(e),(b),(r))
+int virStrToLong_i(char const *s,
+ char **end_ptr,
+ int base,
+ int *result);
int virStrToLong_ui(char const *s,
char **end_ptr,
@@ -102,14 +101,12 @@
char **end_ptr,
int base,
long long *result);
-int __virStrToLong_ull(char const *s,
- char **end_ptr,
- int base,
- unsigned long long *result);
-#define virStrToLong_ull(s,e,b,r) __virStrToLong_ull((s),(e),(b),(r))
+int virStrToLong_ull(char const *s,
+ char **end_ptr,
+ int base,
+ unsigned long long *result);
-int __virMacAddrCompare (const char *mac1, const char *mac2);
-#define virMacAddrCompare(mac1,mac2) __virMacAddrCompare((mac1),(mac2))
+int virMacAddrCompare (const char *mac1, const char *mac2);
void virSkipSpaces(const char **str);
int virParseNumber(const char **str);
diff -r 5bd402f3762e src/virsh.c
--- a/src/virsh.c Fri Oct 24 14:13:53 2008 +0100
+++ b/src/virsh.c Fri Oct 24 14:14:07 2008 +0100
@@ -47,7 +47,6 @@
#include "buf.h"
#include "console.h"
#include "util.h"
-#include "util-lib.h"
static char *progname;
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
16 years, 1 month
[libvirt] [PATCH] fix mingw compilation warning
by Jim Meyering
Building for mingw, I got this warning:
libvirt.c:242: warning: control reaches end of non-void function
Here's the fix:
fix mingw compilation warning
* src/libvirt.c (winsock_init) [HAVE_WINSOCK2_H]: Always return a value.
diff --git a/src/libvirt.c b/src/libvirt.c
index ca2675a..05a92d3 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -237,8 +237,7 @@ winsock_init (void)
/* http://msdn2.microsoft.com/en-us/library/ms742213.aspx */
winsock_version = MAKEWORD (2, 2);
err = WSAStartup (winsock_version, &winsock_data);
- if (err != 0)
- return -1;
+ return err == 0 ? 0 : -1;
}
#endif
--
1.6.0.2.588.g3102
16 years, 1 month
[libvirt] [PATCH] Allow changing ejectable device in domains using default qemu emulator
by Stuart Jansen
When a qemu domain is launched but an emulator is not explicitly
defined, the default emulator is used. Attempts to attach ejectable
devices to a domains using the default emulator fail with the error:
"Error Connecting CDROM: internal error\nCannot determine QEMU argv
syntax (null)".
The following patch is based on similar code in qemudStartVMDaemon() and
qemudBuildCommandLine(). I've tested it and it works.
Honestly, though, I think this patch is just a band-aid. I'd like to
supply a better patch, but I don't have enough experience to judge
certain side effects.
Instead of requiring functions to determine the emulator that will be
used to launch the next qemu domain, qemudStartVMDaemon() should record
the emulator that was used to start the current domain. It should also
record the emulator's capabilities.
This would make it unnecessary to call virDomainDefDefaultEmulator() in
qemudDomainChangeEjectableMedia(). It would also make it possible to
remove the virDomainDefDefaultEmulator() call from
qemudBuildCommandLine().
However, testCompareXMLToArgvFiles() will fail because
qemudBuildCommandLine() needs to know vm->def->emulator and
virDomainDefParseFile() doesn't set vm->def->emulator to a default
value. I don't know if this is a real problem, or if it just means the
test needs to be updated.
In addition, if we simply set vm->dev->emulator =
strdup(virDomainDefDefaultEmulator()) in qemudStartVMDaemon() then
virDomainDefFormat() will dump <emulator>...</emulator> for domains that
did't actually have it explicitly defined. I don't know if this is a bug
or improvement, but it is a change in behavior.
16 years, 1 month
[libvirt] [PATCH 00/12] Domain Events - Round 3
by Ben Guthro
The following patch series implements the Events API discussed here previously in this thread:
http://www.redhat.com/archives/libvir-list/2008-September/msg00321.html
http://www.redhat.com/archives/libvir-list/2008-October/msg00245.html and
https://www.redhat.com/archives/libvir-list/2008-October/msg00432.html
Once again, I have broken these into the following patches:
events-01-public-api Changes to libvirt.h, and libvirt.c
events-02-internal-api Changes to internal.h and event code
events-03-qemud Changes to the daemon
events-04-qemud-rpc-protocol Changes to the qemud rpc protocol
events-05-driver.patch Changes to the driver API
events-06-driver-qemu Changes to the qemu driver
events-07-driver-remote Changes to the remote driver
events-08-driver-lxc Minor changes to LXC driver structure to prevent compile errors
events-09-driver-openvz Minor changes to openvz driver structure to prevent compile errors
events-10-driver-test Minor changes to test driver structure to prevent compile errors
events-11-example-testapp Test app, and infrastructure changes for an example dir
events-12-python-ignore.patch Add functions to be ignored, for now
Differences from last submission -
Formatting issues brought up by Daniel V
Some protocol simplifications
General fixes suggested from last time around.
Removal of POLLxxx stuff (this caused a bit of churn)
I think I got them all, but please let me know if I missed something.
Again, domain events are only emitted from qemu/kvm guests.
Ben Guthro
16 years, 1 month
[libvirt] [PATCH]: Export <device> during logical pool discovery
by Chris Lalancette
Attached is an updated patch for adding <device> tags to logical
findPoolSources. Given danpb's last feedback, I completely removed the XML
parsing and did it all with structures. The result should (hopefully) be a lot
easier on the eyes, and is a little more generic.
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
16 years, 1 month
[libvirt] [PATCH]: Add default pool types
by Chris Lalancette
As suggested by danpb, to fix up the regression caused by last week's VIR_ENUM
cleanup patch, add a ".defaultFormat" member to .poolOptions. In
storage_conf.c, if virXPathString(/pool/source/format/@type) returns NULL, then
set the pool type to .defaultFormat; otherwise, lookup the type via
formatFromString.
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
16 years, 1 month