[libvirt] virt-install?
by Jun Koi
Hi,
I got the libvirt source code (cvs), and compiled. However, I cannot
find the virt-install anywhere. Is it included inside libvirt?
Thank you,
Jun
16 years, 4 months
[libvirt] Re: virDomainMemoryPeek for Xen?
by Richard W.M. Jones
On Wed, Aug 13, 2008 at 01:19:42PM +0900, Jun Koi wrote:
> According to the comment in your driver code for virDomainMemoryPeek,
> libvirt is not currently supporting Xen. Why is that? As far as I see,
> Xen is use the same GPL2 version as libvirt.
>
> I am thinking about implementing the driver for Xen, so have this question.
It'd be really good to have a driver for this for libvirt.
QEMU does virtual->physical translation for us, through the guest's
CR3 & page tables. [This discussion will concentrate on x86 for the
moment :-)] If you look at the qemu source, file target-i386/
helper2.c, function cpu_get_phys_page_debug, you will see the code
they use to navigate through the 3 or 4 levels of page tables for i386
& x86-64 respectively.
The QEMU memsave command made it almost trivial to write
virDomainMemoryPeek (...VIR_MEMORY_VIRTUAL...);
On Xen things are a bit different. You can map in physical pages from
another guest using the libxc call xc_map_foreign_range. Note that
you cannot just call xc_map_foreign_range because the libxc & libvirt
licenses are _not_ compatible. So instead you'd need to do the
underlying sequence of mmap / ioctl / munmap. (See tools/libxc/
xc_linux.c in the Xen source).
But you still need to do virtual to physical page translation, either
using the qemu source as an example, or using
xc_translate_foreign_address as a guide (or just using the Intel
Programmers Reference Manual and doing it from first principles).
Another alternative is to implement virDomainMemoryPeek
(...VIR_MEMORY_PHYSICAL...). It is not possible to implement this for
QEMU at all, at least not without changing QEMU. Implementing this
for Xen would be much easier because you don't need to do address
translation, but it does push the problem of address translation up to
the callers.
Places to look in the QEMU source for inspiration:
monitor.c:do_memory_save
target-i386/helper2.c:cpu_get_phys_page_debug
Other places to look in the Xen source for inspiration:
tools/libxc/xc_linux.c
tools/libxc/xc_pagetab.c
tools/xentrace/xenctx.c (thanks Mark McLoughlin)
Rich.
--
Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://et.redhat.com/~rjones/virt-top
16 years, 4 months
[libvirt] [PATCH]: ruby-libvirt migration fixes
by Chris Lalancette
Attached is a relatively simple patch to the ruby-libvirt bindings with some
bugfixes for the migrate call. The first problem was that there was no way to
pass a "nil" through to the underlying virDomainMigrate() call. This is
important because generally the "dname" and "uri" parameters end up being NULL.
This patch also makes all the parameters beyond the first 2 optional. I've
tested this out by live migrating a KVM guest between two hosts, and this now
does what I expect.
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
16 years, 4 months
[libvirt] PATCH: Block & reset signals when fork/exec'ing children
by Daniel P. Berrange
The LXC patches identified a race condition between fork/exec'ing child
processes and signal handlers.
The process using libvirt can have setup arbitrary signal handlers. In
the libvirtd case we have one attached to SIGCHILD, and the handler writes
to a pipe which is then processeed in the main loop. When you fork() signal
handlers are preserved in the child process, but you may well not want the
signal handlers to be run in the children - for example in LXC we closed
the FD associated the pipe after fork(), and that FD is now asociated
with a socket we use to talk to the container. So if the original signal
handler is run bad stuff will happen in the child.
Now signal handlers will eventually get reset when you exec(), but this
leaves open a race condition window between the fork & exec() when we
cannot assume it is safe to run the signal handlers from the parent
So, this changes the virExec() function so that before fork()ing it
blocks all signals. After fork() the parent process can restore its
original signal mask. The child process meanwhile calls sigaction()
to reset all signal handlers to SIG_DFL, and then unblocks all signals.
NB, the child does not restore the parents sig-mask - libvirt can be
called from any app, and we don't want to inherit whatever mask the
app may have setup.
On Linux there is a convenient NSIG constant defined in signal.h
telling us how many signals there are. If this isn't defined I
simply set it to 32 which is enough for UNIX pre-dating the
addition of real-time signals to POSIX. If we find convenient
or more appropriate values for other non-Linux OS we can update
this as needed.
NB I call pthread_sigmask() instead of sigprocmask() when doing
the fork/exec, because we cannot assume that the application
using libvirt is single-threaded & thus we only want to block
signals in the thread doing the fork/exec.
Daniel
diff -r 1dbfb08d365d src/util.c
--- a/src/util.c Thu Aug 07 16:55:11 2008 +0100
+++ b/src/util.c Thu Aug 07 16:55:53 2008 +0100
@@ -37,6 +37,7 @@
#include <sys/wait.h>
#endif
#include <string.h>
+#include <signal.h>
#include "c-ctype.h"
#ifdef HAVE_PATHS_H
@@ -49,6 +50,10 @@
#include "util.h"
#include "memory.h"
#include "util-lib.c"
+
+#ifndef NSIG
+# define NSIG 32
+#endif
#ifndef MIN
# define MIN(a, b) ((a) < (b) ? (a) : (b))
@@ -104,9 +109,23 @@
_virExec(virConnectPtr conn,
const char *const*argv,
int *retpid, int infd, int *outfd, int *errfd, int non_block) {
- int pid, null;
+ int pid, null, i;
int pipeout[2] = {-1,-1};
int pipeerr[2] = {-1,-1};
+ sigset_t oldmask, newmask;
+ struct sigaction sig_action;
+
+ /*
+ * Need to block signals now, so that child process can safely
+ * kill off caller's signal handlers without a race.
+ */
+ sigfillset(&newmask);
+ if (pthread_sigmask(SIG_SETMASK, &newmask, &oldmask) < 0) {
+ ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("cannot block signals: %s"),
+ strerror(errno));
+ return -1;
+ }
if ((null = open(_PATH_DEVNULL, O_RDONLY)) < 0) {
ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
@@ -122,6 +141,34 @@
goto cleanup;
}
+ if (outfd) {
+ if(non_block &&
+ virSetNonBlock(pipeout[0]) == -1) {
+ ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to set non-blocking file descriptor flag"));
+ goto cleanup;
+ }
+
+ if(virSetCloseExec(pipeout[0]) == -1) {
+ ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to set close-on-exec file descriptor flag"));
+ goto cleanup;
+ }
+ }
+ if (errfd) {
+ if(non_block &&
+ virSetNonBlock(pipeerr[0]) == -1) {
+ ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to set non-blocking file descriptor flag"));
+ goto cleanup;
+ }
+ if(virSetCloseExec(pipeerr[0]) == -1) {
+ ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to set close-on-exec file descriptor flag"));
+ goto cleanup;
+ }
+ }
+
if ((pid = fork()) < 0) {
ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("cannot fork child process: %s"), strerror(errno));
@@ -132,33 +179,48 @@
close(null);
if (outfd) {
close(pipeout[1]);
- if(non_block)
- if(virSetNonBlock(pipeout[0]) == -1)
- ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Failed to set non-blocking file descriptor flag"));
-
- if(virSetCloseExec(pipeout[0]) == -1)
- ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Failed to set close-on-exec file descriptor flag"));
*outfd = pipeout[0];
}
if (errfd) {
close(pipeerr[1]);
- if(non_block)
- if(virSetNonBlock(pipeerr[0]) == -1)
- ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Failed to set non-blocking file descriptor flag"));
-
- if(virSetCloseExec(pipeerr[0]) == -1)
- ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
- _("Failed to set close-on-exec file descriptor flag"));
*errfd = pipeerr[0];
}
*retpid = pid;
+
+ /* Restore our original signal mask now child is safely
+ running */
+ if (pthread_sigmask(SIG_SETMASK, &oldmask, NULL) < 0) {
+ ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("cannot unblock signals: %s"),
+ strerror(errno));
+ return -1;
+ }
+
return 0;
}
/* child */
+
+ /* Clear out all signal handlers from parent so nothing
+ unexpected can happen in our child here */
+ sig_action.sa_handler = SIG_DFL;
+ sig_action.sa_flags = 0;
+ sigemptyset(&sig_action.sa_mask);
+
+ for (i = 0 ; i < NSIG ; i++)
+ /* Only possible errors are EFAULT or EINVAL
+ The former wont happen, the latter we
+ expect, so no need to check return value */
+ sigaction(i, &sig_action, NULL);
+
+ /* Unmask all signals in child, since we've no idea
+ what the caller's done with their signal mask */
+ if (pthread_sigmask(SIG_SETMASK, &oldmask, NULL) < 0) {
+ ReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+ _("cannot unblock signals: %s"),
+ strerror(errno));
+ return -1;
+ }
if (pipeout[0] > 0 && close(pipeout[0]) < 0)
_exit(1);
--
|: 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, 4 months
[libvirt] [PATCH] rewrite virFileLinkPointsTo
by Jim Meyering
I've rewritten virFileLinkPointsTo to be a lot simpler,
and more importantly, it has far fewer failure points.
If anyone wants to preserve the original behavior that
makes it fail when the first parameter does not specify
a symlink, I can add that. The only difference in behavior
would be when the two files are hard-linked.
In any case, I'll remove the FIXME comment.
The diff below is not very readable. Bottom line,
it replaces a pair of functions (the latter is a stub for mingw)
with this:
#define SAME_INODE(Stat_buf_1, Stat_buf_2) \
((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \
&& (Stat_buf_1).st_dev == (Stat_buf_2).st_dev)
int virFileLinkPointsTo(const char *checkLink,
const char *checkDest)
{
struct stat src_sb;
struct stat dest_sb;
if (stat (checkLink, &src_sb) || stat (checkDest, &dest_sb))
return 0;
/* FIXME: if required, lstat checkLink to ensure it's a symlink */
if (! SAME_INODE (src_sb, dest_sb)) {
virLog("Link '%s' does not point to '%s', ignoring\n",
checkLink, checkDest);
return 0;
}
return 1;
}
>From 4e70c02e547b078b8f35afd0996b6887e1593afd Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Tue, 12 Aug 2008 19:07:46 +0200
Subject: [PATCH] rewrite virFileLinkPointsTo
* src/util.c (SAME_INODE): Define.
(virFileLinkPointsTo): Rewrite to be more portable and more efficient.
---
src/util.c | 97 ++++++-----------------------------------------------------
1 files changed, 10 insertions(+), 87 deletions(-)
diff --git a/src/util.c b/src/util.c
index 9f056e0..2905a0a 100644
--- a/src/util.c
+++ b/src/util.c
@@ -397,107 +397,30 @@ int virFileHasSuffix(const char *str,
return STREQ(str + len - suffixlen, suffix);
}
-#ifndef __MINGW32__
+#define SAME_INODE(Stat_buf_1, Stat_buf_2) \
+ ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \
+ && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev)
int virFileLinkPointsTo(const char *checkLink,
const char *checkDest)
{
- char dest[PATH_MAX];
- char real[PATH_MAX];
- char checkReal[PATH_MAX];
- int n;
-
- /* read the link destination */
- if ((n = readlink(checkLink, dest, PATH_MAX)) < 0) {
- switch (errno) {
- case ENOENT:
- case ENOTDIR:
- return 0;
-
- case EINVAL:
- virLog("File '%s' is not a symlink\n",
- checkLink);
- return 0;
-
- }
- virLog("Failed to read symlink '%s': %s\n",
- checkLink, strerror(errno));
- return 0;
- } else if (n >= PATH_MAX) {
- virLog("Symlink '%s' contents too long to fit in buffer\n",
- checkLink);
- return 0;
- }
+ struct stat src_sb;
+ struct stat dest_sb;
- dest[n] = '\0';
+ if (stat (checkLink, &src_sb) || stat (checkDest, &dest_sb))
+ return 0;
- /* make absolute */
- if (dest[0] != '/') {
- char dir[PATH_MAX];
- char tmp[PATH_MAX];
- char *p;
+ /* FIXME: if required, lstat checkLink to ensure it's a symlink */
- strncpy(dir, checkLink, PATH_MAX);
- dir[PATH_MAX-1] = '\0';
-
- if (!(p = strrchr(dir, '/'))) {
- virLog("Symlink path '%s' is not absolute\n", checkLink);
- return 0;
- }
-
- if (p == dir) /* handle unlikely root dir case */
- p++;
-
- *p = '\0';
-
- if (virFileBuildPath(dir, dest, NULL, tmp, PATH_MAX) < 0) {
- virLog("Path '%s/%s' is too long\n", dir, dest);
- return 0;
- }
-
- strncpy(dest, tmp, PATH_MAX);
- dest[PATH_MAX-1] = '\0';
- }
-
- /* canonicalize both paths */
- if (!realpath(dest, real)) {
- virLog("Failed to expand path '%s' :%s\n", dest, strerror(errno));
- strncpy(real, dest, PATH_MAX);
- real[PATH_MAX-1] = '\0';
- }
-
- if (!realpath(checkDest, checkReal)) {
- virLog("Failed to expand path '%s' :%s\n", checkDest, strerror(errno));
- strncpy(checkReal, checkDest, PATH_MAX);
- checkReal[PATH_MAX-1] = '\0';
- }
-
- /* compare */
- if (STRNEQ(checkReal, real)) {
+ if (! SAME_INODE (src_sb, dest_sb)) {
virLog("Link '%s' does not point to '%s', ignoring\n",
- checkLink, checkReal);
+ checkLink, checkDest);
return 0;
}
return 1;
}
-#else /* !__MINGW32__ */
-
-/* Gnulib has an implementation of readlink which could be used
- * to implement this, but it requires LGPLv3.
- */
-
-int
-virFileLinkPointsTo (const char *checkLink ATTRIBUTE_UNUSED,
- const char *checkDest ATTRIBUTE_UNUSED)
-{
- virLog (_("%s: not implemented\n"), __FUNCTION__);
- return 0;
-}
-
-#endif /*! __MINGW32__ */
-
int virFileExists(const char *path)
{
struct stat st;
--
1.6.0.rc2.38.g413e06
16 years, 4 months
[libvirt] Qemu Monitor
by Listen
Hi all,
A simple question, I hope ;)
Is it possible to enable the qemu monitor in libvirt's xml?
It need the monitor, to dynamically add a usb device to a windows vm.
Regards,
Eric
16 years, 4 months
[libvirt] gnome-applet-vm orphaned
by Karel Zak
Hi folks,
unfortunately, I have not enough time to work on the gnome applet.
I'm looking for a new upstream maintainer, or for co-maintainer.
Project home page:
http://fedorahosted.org/gnome-applet-vm/
Note that the applet does not require any heavy development.
Any volunteers around?
Karel
--
Karel Zak <kzak(a)redhat.com>
16 years, 4 months