[libvirt] [PATCH] uuid: fix off-by-one
by Eric Blake
Detected by Coverity. Although unlikely, if we are ever started
with stdin closed, we could reach a situation where we open a
uuid file but then fail to close it, making that file the new
stdin for the rest of the process.
* src/util/uuid.c (getDMISystemUUID): Allow for stdin.
---
src/util/uuid.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/util/uuid.c b/src/util/uuid.c
index 823a2b9..15ba5af 100644
--- a/src/util/uuid.c
+++ b/src/util/uuid.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2011 Red Hat, Inc.
+ * Copyright (C) 2007-2012 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
@@ -236,7 +236,7 @@ getDMISystemUUID(char *uuid, int len)
while (paths[i]) {
int fd = open(paths[i], O_RDONLY);
- if (fd > 0) {
+ if (fd >= 0) {
if (saferead(fd, uuid, len) == len) {
VIR_FORCE_CLOSE(fd);
return 0;
--
1.7.7.5
12 years, 10 months
[libvirt] ANNOUNCE: libvirt-glib release 0.0.4
by Daniel P. Berrange
I am pleased to announce that a new release of the libvirt-glib package,
version 0.0.4 is now available from
ftp://libvirt.org/libvirt/glib/
The packages are GPG signed with
Key fingerprint: DAF3 A6FD B26B 6291 2D0E 8E3F BE86 EBB4 1510 4FDF (4096R)
New in this release:
- Add support for configuring sound, serial, parallel
and channel devices
- Add support for newer libvirt shutdown event
- Add support for setting SPICE/VNC passwords
- Fix storage pool annotations
- Improve docs for memory APIs
- Fix problem with duplicated attributes
- Many internal XML helper API cleanups/additions
- Add API for retrieving list of all devices
- Fix mixup between g_new0/g_slice_free
- Change namespace for GVirConfig APIs (breaks ABI
and API)
- New APIs for save/suspend
libvirt-glib comprises three distinct libraries:
- libvirt-glib - Integrate with the GLib event loop and error handling
- libvirt-gconfig - Representation of libvirt XML documents as GObjects
- libvirt-gobject - Mapping of libvirt APIs into the GObject type system
NB: While libvirt aims to be API/ABI stable, for the first few releases,
we are *NOT* guaranteeing that libvirt-glib libraries are API/ABI stable.
ABI stability will only be guaranteed once the bulk of the APIs have been
fleshed out and proved in non-trivial application usage. We anticipate
this will be within the next 6 months in order to line up with Fedora 17.
Follow up comments about libvirt-glib should be directed to the regular
libvir-list redhat com development list.
Thanks to all the people involved in contributing to this release.
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
12 years, 10 months
[libvirt] [PATCH] Rsync keymaps.csv file with GTK-VNC
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Pushing under trivial rule
---
src/util/keymaps.csv | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/util/keymaps.csv b/src/util/keymaps.csv
index c447f46..98c723b 100644
--- a/src/util/keymaps.csv
+++ b/src/util/keymaps.csv
@@ -42,6 +42,7 @@ KEY_L,38,ANSI_L,0x25,38,75,75,38,38,15,VK_L,0x4c,38,38
KEY_SEMICOLON,39,ANSI_Semicolon,0x29,39,76,76,39,39,51,VK_OEM_1,0xba,39,39
KEY_APOSTROPHE,40,ANSI_Quote,0x27,40,82,82,40,40,52,VK_OEM_2,0xbf,40,40
KEY_GRAVE,41,ANSI_Grave,0x32,41,14,14,41,41,53,VK_OEM_3,0xc0,41,41
+KEY_SHIFT,42,Shift,0x38,42,18,18,42,42,225,VK_SHIFT,0x10,42,42
KEY_LEFTSHIFT,42,Shift,0x38,42,18,18,42,42,225,VK_LSHIFT,0xa0,42,42
KEY_BACKSLASH,43,ANSI_Backslash,0x2a,43,93,93,43,43,50,VK_OEM_5,0xdc,43,43
KEY_Z,44,ANSI_Z,0x6,44,26,26,44,44,29,VK_Z,0x5a,44,44
--
1.7.7.5
12 years, 10 months
[libvirt] [PATCH] qemu: eliminate "Ignoring open failure" message when using root-squash NFS
by Laine Stump
This eliminates the warning message reported in:
https://bugzilla.redhat.com/show_bug.cgi?id=624447
It was caused by a failure to open an image file that is not
accessible by root (the uid libvirtd is running as) because it's on a
root-squash NFS share, owned by a different user, with permissions of
660 (or maybe 600).
The solution is to re-try the open using virFileOpenAs() when
appropriate. The codepath that generates the error is during
qemuSetupDiskCGroup(), but the actual open() is in a lower-level
generic function called from many places (virDomainDiskDefForeachPath),
so some other pieces of the code were touched just to add dummy (or
possibly useful) uid and gid arguments.
Eliminating this warning message has the nice side effect that the
requested opearation may even succeed (which in this case isn't
necessary, but shouldn't hurt anything either).
---
src/conf/domain_conf.c | 13 ++++++++++++-
src/conf/domain_conf.h | 1 +
src/qemu/qemu_cgroup.c | 2 ++
src/security/security_dac.c | 1 +
src/security/security_selinux.c | 7 +++++++
src/security/virt-aa-helper.c | 6 +++++-
6 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 180dd2b..2b7ec91 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -13370,6 +13370,7 @@ done:
int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
bool allowProbing,
bool ignoreOpenFailure,
+ uid_t uid, gid_t gid,
virDomainDiskDefPathIterator iter,
void *opaque)
{
@@ -13425,8 +13426,18 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
disk->src);
goto cleanup;
}
+ fd = open(path, O_RDONLY);
+ if ((fd < 0) && (errno == EACCES || errno == EPERM) &&
+ (uid > 0 || gid > 0)) {
+ fd = virFileOpenAs(path, O_RDONLY, 0, uid, gid, VIR_FILE_OPEN_AS_UID);
+ if (fd < 0) {
+ /* open() and virFileOpenAs() have different semantics */
+ errno = -fd;
+ fd = -1;
+ }
+ }
- if ((fd = open(path, O_RDONLY)) < 0) {
+ if (fd < 0) {
if (ignoreOpenFailure) {
char ebuf[1024];
VIR_WARN("Ignoring open failure on %s: %s", path,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3d5d4f8..2ea7861 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1935,6 +1935,7 @@ typedef int (*virDomainDiskDefPathIterator)(virDomainDiskDefPtr disk,
int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
bool allowProbing,
bool ignoreOpenFailure,
+ uid_t uid, gid_t gid,
virDomainDiskDefPathIterator iter,
void *opaque);
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 2d970d6..a07b6cd 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -96,6 +96,7 @@ int qemuSetupDiskCgroup(struct qemud_driver *driver,
return virDomainDiskDefForeachPath(disk,
driver->allowDiskFormatProbing,
true,
+ driver->user, driver->group,
qemuSetupDiskPathAllow,
&data);
}
@@ -137,6 +138,7 @@ int qemuTeardownDiskCgroup(struct qemud_driver *driver,
return virDomainDiskDefForeachPath(disk,
driver->allowDiskFormatProbing,
true,
+ driver->user, driver->group,
qemuTeardownDiskPathDeny,
&data);
}
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 2fb4a14..3e1a72f 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -186,6 +186,7 @@ virSecurityDACSetSecurityImageLabel(virSecurityManagerPtr mgr,
return virDomainDiskDefForeachPath(disk,
virSecurityManagerGetAllowDiskFormatProbing(mgr),
false,
+ priv->user, priv->group,
virSecurityDACSetSecurityFileLabel,
mgr);
}
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index c2dceca..8c8e4f8 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -670,9 +670,16 @@ SELinuxSetSecurityImageLabel(virSecurityManagerPtr mgr,
if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK)
return 0;
+ /* XXX On one hand, it would be nice to have the driver's uid:gid
+ * here so we could retry opens with it. On the other hand, it
+ * probably doesn't matter because in practice that's only useful
+ * for files on root-squashed NFS shares, and NFS doesn't properly
+ * support selinux anyway.
+ */
return virDomainDiskDefForeachPath(disk,
allowDiskFormatProbing,
true,
+ -1, -1, /* current process uid:gid */
SELinuxSetSecurityFileLabel,
secdef);
}
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index 4561bb9..015ef2f 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -909,10 +909,14 @@ get_files(vahControl * ctl)
/* XXX passing ignoreOpenFailure = true to get back to the behavior
* from before using virDomainDiskDefForeachPath. actually we should
* be passing ignoreOpenFailure = false and handle open errors more
- * careful than just ignoring them */
+ * careful than just ignoring them.
+ * XXX2 - if we knew the qemu user:group here we could send it in
+ * so that the open could be re-tried as that user:group.
+ */
int ret = virDomainDiskDefForeachPath(ctl->def->disks[i],
ctl->allowDiskFormatProbing,
true,
+ -1, -1 /* current uid:gid */
add_file_path,
&buf);
if (ret != 0)
--
1.7.7.5
12 years, 10 months
[libvirt] [PATCH] Re-write LXC controller end-of-file I/O handling yet again
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Currently the LXC controller attempts to deal with EOF on a
tty by spawning a thread todo a edge triggered epoll_wait().
This avoids the normal event loop spinning on POLLHUP. There
is a subtle mistake though - even after seeing POLLHUP on a
master PTY, it is still perfectly possible & valid to write
data to the PTY. There is a buffer that can be filled with
data, even when no client is present.
The second mistake is that the epoll_wait() thread was not
looking for the EPOLLOUT condition, so when a new client
connects to the LXC console, it had to explicitly send a
character before any queued output would appear.
Finally, there was in fact no need to spawn a new thread to
deal with epoll_wait(). The epoll file descriptor itself
can be poll()'d on normally.
This patch attempts to deal with all these problems.
- The blocking epoll_wait() thread is replaced by a poll
on the epoll file descriptor which then does a non-blocking
epoll_wait() to handle events
- Even if POLLHUP is seen, we continue trying to write
any pending output until getting EAGAIN from write.
- Once write returns EAGAIN, we modify the epoll event
mask to also look for EPOLLOUT
* src/lxc/lxc_controller.c: Avoid stalled I/O upon
connected to an LXC console
---
src/lxc/lxc_controller.c | 210 +++++++++++++++++++++++++++++++++-------------
1 files changed, 152 insertions(+), 58 deletions(-)
diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c
index bb936ee..7988e79 100644
--- a/src/lxc/lxc_controller.c
+++ b/src/lxc/lxc_controller.c
@@ -736,9 +736,17 @@ struct lxcConsole {
int hostWatch;
int hostFd; /* PTY FD in the host OS */
bool hostClosed;
+ int hostEpoll;
+ bool hostBlocking;
+
int contWatch;
int contFd; /* PTY FD in the container */
bool contClosed;
+ int contEpoll;
+ bool contBlocking;
+
+ int epollWatch;
+ int epollFd; /* epoll FD for dealing with EOF */
size_t fromHostLen;
char fromHostBuf[1024];
@@ -834,102 +842,148 @@ static void lxcConsoleUpdateWatch(struct lxcConsole *console)
int hostEvents = 0;
int contEvents = 0;
- if (!console->hostClosed) {
+ if (!console->hostClosed || (!console->hostBlocking && console->fromContLen)) {
if (console->fromHostLen < sizeof(console->fromHostBuf))
hostEvents |= VIR_EVENT_HANDLE_READABLE;
if (console->fromContLen)
hostEvents |= VIR_EVENT_HANDLE_WRITABLE;
}
- if (!console->contClosed) {
+ if (!console->contClosed || (!console->contBlocking && console->fromHostLen)) {
if (console->fromContLen < sizeof(console->fromContBuf))
contEvents |= VIR_EVENT_HANDLE_READABLE;
if (console->fromHostLen)
contEvents |= VIR_EVENT_HANDLE_WRITABLE;
}
+ VIR_DEBUG("Container watch %d=%d host watch %d=%d",
+ console->contWatch, contEvents,
+ console->hostWatch, hostEvents);
virEventUpdateHandle(console->contWatch, contEvents);
virEventUpdateHandle(console->hostWatch, hostEvents);
-}
+ if (console->hostClosed) {
+ int events = EPOLLIN | EPOLLET;
+ if (console->hostBlocking)
+ events |= EPOLLOUT;
-struct lxcConsoleEOFData {
- struct lxcConsole *console;
- int fd;
-};
-
+ if (events != console->hostEpoll) {
+ struct epoll_event event;
+ int action = EPOLL_CTL_ADD;
+ if (console->hostEpoll)
+ action = EPOLL_CTL_MOD;
-static void lxcConsoleEOFThread(void *opaque)
-{
- struct lxcConsoleEOFData *data = opaque;
- int ret;
- int epollfd = -1;
- struct epoll_event event;
+ VIR_DEBUG("newHostEvents=%x oldHostEvents=%x", events, console->hostEpoll);
- if ((epollfd = epoll_create(2)) < 0) {
- virReportSystemError(errno, "%s",
- _("Unable to create epoll fd"));
- goto cleanup;
+ event.events = events;
+ event.data.fd = console->hostFd;
+ if (epoll_ctl(console->epollFd, action, console->hostFd, &event) < 0) {
+ VIR_DEBUG(":fail");
+ virReportSystemError(errno, "%s",
+ _("Unable to add epoll fd"));
+ quit = true;
+ goto cleanup;
+ }
+ console->hostEpoll = events;
+ VIR_DEBUG("newHostEvents=%x oldHostEvents=%x", events, console->hostEpoll);
+ }
+ } else if (console->hostEpoll) {
+ VIR_DEBUG("Stop epoll oldContEvents=%x", console->hostEpoll);
+ if (epoll_ctl(console->epollFd, EPOLL_CTL_DEL, console->hostFd, NULL) < 0) {
+ virReportSystemError(errno, "%s",
+ _("Unable to add epoll fd"));
+ VIR_DEBUG(":fail");
+ quit = true;
+ goto cleanup;
+ }
+ console->hostEpoll = 0;
}
- event.events = EPOLLIN | EPOLLET;
- event.data.fd = data->fd;
- if (epoll_ctl(epollfd, EPOLL_CTL_ADD, data->fd, &event) < 0) {
- virReportSystemError(errno, "%s",
- _("Unable to add epoll fd"));
- goto cleanup;
+ if (console->contClosed) {
+ int events = EPOLLIN | EPOLLET;
+ if (console->contBlocking)
+ events |= EPOLLOUT;
+
+ if (events != console->contEpoll) {
+ struct epoll_event event;
+ int action = EPOLL_CTL_ADD;
+ if (console->contEpoll)
+ action = EPOLL_CTL_MOD;
+
+ VIR_DEBUG("newContEvents=%x oldContEvents=%x", events, console->contEpoll);
+
+ event.events = events;
+ event.data.fd = console->contFd;
+ if (epoll_ctl(console->epollFd, action, console->contFd, &event) < 0) {
+ virReportSystemError(errno, "%s",
+ _("Unable to add epoll fd"));
+ VIR_DEBUG(":fail");
+ quit = true;
+ goto cleanup;
+ }
+ console->contEpoll = events;
+ VIR_DEBUG("newHostEvents=%x oldHostEvents=%x", events, console->contEpoll);
+ }
+ } else if (console->contEpoll) {
+ VIR_DEBUG("Stop epoll oldContEvents=%x", console->contEpoll);
+ if (epoll_ctl(console->epollFd, EPOLL_CTL_DEL, console->contFd, NULL) < 0) {
+ virReportSystemError(errno, "%s",
+ _("Unable to add epoll fd"));
+ VIR_DEBUG(":fail");
+ quit = true;
+ goto cleanup;
+ }
+ console->contEpoll = 0;
}
+cleanup:
+ return;
+}
+
- for (;;) {
- ret = epoll_wait(epollfd, &event, 1, -1);
+static void lxcEpollIO(int watch, int fd, int events, void *opaque)
+{
+ struct lxcConsole *console = opaque;
+
+ virMutexLock(&lock);
+ VIR_DEBUG("IO event watch=%d fd=%d events=%d fromHost=%zu fromcont=%zu",
+ watch, fd, events,
+ console->fromHostLen,
+ console->fromContLen);
+
+ while (1) {
+ struct epoll_event event;
+ int ret;
+ ret = epoll_wait(console->epollFd, &event, 1, 0);
if (ret < 0) {
if (ret == EINTR)
continue;
virReportSystemError(errno, "%s",
_("Unable to wait on epoll"));
- virMutexLock(&lock);
quit = true;
- virMutexUnlock(&lock);
goto cleanup;
}
+ if (ret == 0)
+ break;
+
+ VIR_DEBUG("fd=%d hostFd=%d contFd=%d hostEpoll=%x contEpoll=%x",
+ event.data.fd, console->hostFd, console->contFd,
+ console->hostEpoll, console->contEpoll);
+
/* If we get HUP+dead PID, we just re-enable the main loop
* which will see the PID has died and exit */
if ((event.events & EPOLLIN)) {
- virMutexLock(&lock);
- if (event.data.fd == data->console->hostFd) {
- data->console->hostClosed = false;
+ if (event.data.fd == console->hostFd) {
+ console->hostClosed = false;
} else {
- data->console->contClosed = false;
+ console->contClosed = false;
}
- lxcConsoleUpdateWatch(data->console);
- virMutexUnlock(&lock);
+ lxcConsoleUpdateWatch(console);
break;
}
}
cleanup:
- VIR_FORCE_CLOSE(epollfd);
- VIR_FREE(data);
-}
-
-static int lxcCheckEOF(struct lxcConsole *console, int fd)
-{
- struct lxcConsoleEOFData *data;
- virThread thread;
-
- if (VIR_ALLOC(data) < 0) {
- virReportOOMError();
- return -1;
- }
-
- data->console = console;
- data->fd = fd;
-
- if (virThreadCreate(&thread, false, lxcConsoleEOFThread, data) < 0) {
- VIR_FREE(data);
- return -1;
- }
- return 0;
+ virMutexUnlock(&lock);
}
static void lxcConsoleIO(int watch, int fd, int events, void *opaque)
@@ -937,6 +991,10 @@ static void lxcConsoleIO(int watch, int fd, int events, void *opaque)
struct lxcConsole *console = opaque;
virMutexLock(&lock);
+ VIR_DEBUG("IO event watch=%d fd=%d events=%d fromHost=%zu fromcont=%zu",
+ watch, fd, events,
+ console->fromHostLen,
+ console->fromContLen);
if (events & VIR_EVENT_HANDLE_READABLE) {
char *buf;
size_t *len;
@@ -993,6 +1051,10 @@ static void lxcConsoleIO(int watch, int fd, int events, void *opaque)
*len -= done;
} else {
VIR_DEBUG("Write fd %d done %d errno %d", fd, (int)done, errno);
+ if (watch == console->hostWatch)
+ console->hostBlocking = true;
+ else
+ console->contBlocking = true;
}
}
@@ -1003,8 +1065,6 @@ static void lxcConsoleIO(int watch, int fd, int events, void *opaque)
console->contClosed = true;
}
VIR_DEBUG("Got EOF on %d %d", watch, fd);
- if (lxcCheckEOF(console, fd) < 0)
- goto error;
}
lxcConsoleUpdateWatch(console);
@@ -1103,9 +1163,32 @@ static int lxcControllerMain(int serverFd,
}
for (i = 0 ; i < nFds ; i++) {
+ consoles[i].epollFd = -1;
+ consoles[i].epollFd = -1;
+ consoles[i].hostWatch = -1;
+ consoles[i].contWatch = -1;
+ }
+
+ for (i = 0 ; i < nFds ; i++) {
consoles[i].hostFd = hostFds[i];
consoles[i].contFd = contFds[i];
+ if ((consoles[i].epollFd = epoll_create(2)) < 0) {
+ virReportSystemError(errno, "%s",
+ _("Unable to create epoll fd"));
+ goto cleanup;
+ }
+
+ if ((consoles[i].epollWatch = virEventAddHandle(consoles[i].epollFd,
+ VIR_EVENT_HANDLE_READABLE,
+ lxcEpollIO,
+ &consoles[i],
+ NULL)) < 0) {
+ lxcError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to watch epoll FD"));
+ goto cleanup;
+ }
+
if ((consoles[i].hostWatch = virEventAddHandle(consoles[i].hostFd,
VIR_EVENT_HANDLE_READABLE,
lxcConsoleIO,
@@ -1146,6 +1229,17 @@ cleanup:
cleanup2:
VIR_FORCE_CLOSE(monitor.serverFd);
VIR_FORCE_CLOSE(monitor.clientFd);
+
+ for (i = 0 ; i < nFds ; i++) {
+ if (consoles[i].epollWatch != -1)
+ virEventRemoveHandle(consoles[i].epollWatch);
+ VIR_FORCE_CLOSE(consoles[i].epollFd);
+ if (consoles[i].contWatch != -1)
+ virEventRemoveHandle(consoles[i].contWatch);
+ if (consoles[i].hostWatch != -1)
+ virEventRemoveHandle(consoles[i].hostWatch);
+ }
+
VIR_FREE(consoles);
return rc;
}
--
1.7.7.5
12 years, 10 months
[libvirt] [PATCH libvirt-glib] Support setting target attributes for console & channel devices
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
---
libvirt-gconfig/libvirt-gconfig-domain-channel.c | 23 ++++++++++++++++++++++
libvirt-gconfig/libvirt-gconfig-domain-channel.h | 11 ++++++++++
libvirt-gconfig/libvirt-gconfig-domain-console.c | 12 +++++++++++
libvirt-gconfig/libvirt-gconfig-domain-console.h | 12 +++++++++++
libvirt-gconfig/libvirt-gconfig-object-private.h | 5 ++++
libvirt-gconfig/libvirt-gconfig-object.c | 15 ++++++++++++++
libvirt-gconfig/libvirt-gconfig.sym | 5 ++++
7 files changed, 83 insertions(+), 0 deletions(-)
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-channel.c b/libvirt-gconfig/libvirt-gconfig-domain-channel.c
index 02f8fe7..a4f9527 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-channel.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-channel.c
@@ -23,6 +23,7 @@
#include <config.h>
#include "libvirt-gconfig/libvirt-gconfig.h"
+#include "libvirt-gconfig/libvirt-gconfig-private.h"
#define GVIR_CONFIG_DOMAIN_CHANNEL_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_CONFIG_TYPE_DOMAIN_CHANNEL, GVirConfigDomainChannelPrivate))
@@ -68,3 +69,25 @@ GVirConfigDomainChannel *gvir_config_domain_channel_new_from_xml(const gchar *xm
return NULL;
return GVIR_CONFIG_DOMAIN_CHANNEL(object);
}
+
+
+void gvir_config_domain_channel_set_target_type(GVirConfigDomainChannel *channel,
+ GVirConfigDomainChannelTargetType type)
+{
+ g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_CHANNEL(channel));
+
+ gvir_config_object_add_child_with_attribute_enum(GVIR_CONFIG_OBJECT(channel),
+ "target", "type",
+ GVIR_CONFIG_TYPE_DOMAIN_CHANNEL_TARGET_TYPE,
+ type);
+}
+
+
+void gvir_config_domain_channel_set_target_name(GVirConfigDomainChannel *channel,
+ const gchar *name)
+{
+ g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_CHANNEL(channel));
+
+ gvir_config_object_add_child_with_attribute(GVIR_CONFIG_OBJECT(channel),
+ "target", "name", name);
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-channel.h b/libvirt-gconfig/libvirt-gconfig-domain-channel.h
index 0e48bcf..a8a3020 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-channel.h
+++ b/libvirt-gconfig/libvirt-gconfig-domain-channel.h
@@ -56,12 +56,23 @@ struct _GVirConfigDomainChannelClass
gpointer padding[20];
};
+typedef enum {
+ GVIR_CONFIG_DOMAIN_CONSOLE_TARGET_GUESTFWD,
+ GVIR_CONFIG_DOMAIN_CHANNEL_TARGET_VIRTIO,
+} GVirConfigDomainChannelTargetType;
+
GType gvir_config_domain_channel_get_type(void);
GVirConfigDomainChannel *gvir_config_domain_channel_new(void);
GVirConfigDomainChannel *gvir_config_domain_channel_new_from_xml(const gchar *xml,
GError **error);
+void gvir_config_domain_channel_set_target_type(GVirConfigDomainChannel *channel,
+ GVirConfigDomainChannelTargetType type);
+void gvir_config_domain_channel_set_target_name(GVirConfigDomainChannel *channel,
+ const gchar *name);
+
+
G_END_DECLS
#endif /* __LIBVIRT_GCONFIG_DOMAIN_CHANNEL_H__ */
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-console.c b/libvirt-gconfig/libvirt-gconfig-domain-console.c
index 03ee1a7..db97322 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-console.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-console.c
@@ -23,6 +23,7 @@
#include <config.h>
#include "libvirt-gconfig/libvirt-gconfig.h"
+#include "libvirt-gconfig/libvirt-gconfig-private.h"
#define GVIR_CONFIG_DOMAIN_CONSOLE_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_CONFIG_TYPE_DOMAIN_CONSOLE, GVirConfigDomainConsolePrivate))
@@ -68,3 +69,14 @@ GVirConfigDomainConsole *gvir_config_domain_console_new_from_xml(const gchar *xm
return NULL;
return GVIR_CONFIG_DOMAIN_CONSOLE(object);
}
+
+void gvir_config_domain_console_set_target_type(GVirConfigDomainConsole *console,
+ GVirConfigDomainConsoleTargetType type)
+{
+ g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_CONSOLE(console));
+
+ gvir_config_object_add_child_with_attribute_enum(GVIR_CONFIG_OBJECT(console),
+ "target", "type",
+ GVIR_CONFIG_TYPE_DOMAIN_CONSOLE_TARGET_TYPE,
+ type);
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-console.h b/libvirt-gconfig/libvirt-gconfig-domain-console.h
index 00e142a..1c735e9 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-console.h
+++ b/libvirt-gconfig/libvirt-gconfig-domain-console.h
@@ -57,11 +57,23 @@ struct _GVirConfigDomainConsoleClass
};
+typedef enum {
+ GVIR_CONFIG_DOMAIN_CONSOLE_TARGET_XEN,
+ GVIR_CONFIG_DOMAIN_CONSOLE_TARGET_SERIAL,
+ GVIR_CONFIG_DOMAIN_CONSOLE_TARGET_UML,
+ GVIR_CONFIG_DOMAIN_CONSOLE_TARGET_VIRTIO,
+ GVIR_CONFIG_DOMAIN_CONSOLE_TARGET_LXC,
+ GVIR_CONFIG_DOMAIN_CONSOLE_TARGET_OPENVZ,
+} GVirConfigDomainConsoleTargetType;
+
GType gvir_config_domain_console_get_type(void);
GVirConfigDomainConsole *gvir_config_domain_console_new(void);
GVirConfigDomainConsole *gvir_config_domain_console_new_from_xml(const gchar *xml,
GError **error);
+void gvir_config_domain_console_set_target_type(GVirConfigDomainConsole *console,
+ GVirConfigDomainConsoleTargetType type);
+
G_END_DECLS
#endif /* __LIBVIRT_GCONFIG_DOMAIN_CONSOLE_H__ */
diff --git a/libvirt-gconfig/libvirt-gconfig-object-private.h b/libvirt-gconfig/libvirt-gconfig-object-private.h
index 0c0c44f..6d01e26 100644
--- a/libvirt-gconfig/libvirt-gconfig-object-private.h
+++ b/libvirt-gconfig/libvirt-gconfig-object-private.h
@@ -59,6 +59,11 @@ void gvir_config_object_add_child_with_attribute(GVirConfigObject *object,
const char *child_name,
const char *attr_name,
const char *attr_value);
+void gvir_config_object_add_child_with_attribute_enum(GVirConfigObject *object,
+ const char *child_name,
+ const char *attr_name,
+ GType attr_type,
+ unsigned int attr_value);
GVirConfigObject *gvir_config_object_replace_child(GVirConfigObject *object,
const char *child_name);
void gvir_config_object_replace_child_with_attribute(GVirConfigObject *object,
diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c
index a3b7109..5645490 100644
--- a/libvirt-gconfig/libvirt-gconfig-object.c
+++ b/libvirt-gconfig/libvirt-gconfig-object.c
@@ -419,6 +419,21 @@ gvir_config_object_add_child_with_attribute(GVirConfigObject *object,
g_object_unref(G_OBJECT(child));
}
+
+void gvir_config_object_add_child_with_attribute_enum(GVirConfigObject *object,
+ const char *child_name,
+ const char *attr_name,
+ GType attr_type,
+ unsigned int attr_value)
+{
+ GVirConfigObject *child;
+
+ child = gvir_config_object_add_child(object, child_name);
+ gvir_config_object_set_attribute_with_type(child, attr_name, attr_type, attr_value, NULL);
+ g_object_unref(G_OBJECT(child));
+}
+
+
G_GNUC_INTERNAL GVirConfigObject *
gvir_config_object_replace_child(GVirConfigObject *object,
const char *child_name)
diff --git a/libvirt-gconfig/libvirt-gconfig.sym b/libvirt-gconfig/libvirt-gconfig.sym
index 7cf3c3d..1c11729 100644
--- a/libvirt-gconfig/libvirt-gconfig.sym
+++ b/libvirt-gconfig/libvirt-gconfig.sym
@@ -33,6 +33,9 @@ LIBVIRT_GCONFIG_0.0.3 {
gvir_config_domain_channel_get_type;
gvir_config_domain_channel_new;
gvir_config_domain_channel_new_from_xml;
+ gvir_config_domain_channel_set_target_type;
+ gvir_config_domain_channel_set_target_name;
+ gvir_config_domain_channel_target_type_get_type;
gvir_config_domain_chardev_get_type;
gvir_config_domain_chardev_set_source;
@@ -55,6 +58,8 @@ LIBVIRT_GCONFIG_0.0.3 {
gvir_config_domain_console_get_type;
gvir_config_domain_console_new;
gvir_config_domain_console_new_from_xml;
+ gvir_config_domain_console_set_target_type;
+ gvir_config_domain_console_target_type_get_type;
gvir_config_domain_device_get_type;
--
1.7.7.5
12 years, 10 months
[libvirt] Using virtEvents in macvtap setup code
by Dirk Herrendoerfer
Hi all,
I'm trying to get libvirt to re-associate lost connections when a vepa
connection
is lost due to a switch error, or lldpad restart.
My take was to use the virtEvent infrastructure to poll for messages
on a netlink
socket and then restart the association if the message indicates that
a link came
back up.
I ran into a problem, that if I start the polling netlink event from
the daemon thread
I would get the file events an the netlink messages, but I cannot
configure the
event handler because the rpc client threads and the daemon do not
share the
same address space.
Is there a way to get file events in the VMs setup code so I can
register a callback
at VM initialization time to receive netlink messages and restart
association if needed ?
Best regards,
D.Herrendoerfer <herrend at de dot ibm dot com > <d.herrendoerfer at
herrendoerfer dot name>
12 years, 10 months
[libvirt] [libvirt-glib] Add API to check if domain is persistent
by Zeeshan Ali (Khattak)
From: "Zeeshan Ali (Khattak)" <zeeshanak(a)gnome.org>
Add a predicate and property to check if domain is persistent or not.
---
libvirt-gobject/libvirt-gobject-domain.c | 29 +++++++++++++++++++++++++++++
libvirt-gobject/libvirt-gobject-domain.h | 1 +
libvirt-gobject/libvirt-gobject.sym | 1 +
3 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c
index 967ff67..2974bb8 100644
--- a/libvirt-gobject/libvirt-gobject-domain.c
+++ b/libvirt-gobject/libvirt-gobject-domain.c
@@ -45,6 +45,7 @@ G_DEFINE_TYPE(GVirDomain, gvir_domain, G_TYPE_OBJECT);
enum {
PROP_0,
PROP_HANDLE,
+ PROP_PERSISTENT,
};
enum {
@@ -80,6 +81,10 @@ static void gvir_domain_get_property(GObject *object,
g_value_set_boxed(value, priv->handle);
break;
+ case PROP_PERSISTENT:
+ g_value_set_boolean(value, gvir_domain_get_persistent (conn));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
@@ -156,6 +161,17 @@ static void gvir_domain_class_init(GVirDomainClass *klass)
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
+ g_object_class_install_property(object_class,
+ PROP_PERSISTENT,
+ g_param_spec_boolean("persistent",
+ "Persistent",
+ "If domain is persistent",
+ TRUE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_NAME |
+ G_PARAM_STATIC_NICK |
+ G_PARAM_STATIC_BLURB));
+
signals[VIR_STARTED] = g_signal_new("started",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
@@ -821,3 +837,16 @@ gboolean gvir_domain_save_finish (GVirDomain *dom,
return TRUE;
}
+
+/**
+ * gvir_domain_get_persistent:
+ * @dom: the domain
+ *
+ * Returns: TRUE if domain is persistent, FALSE otherwise.
+ */
+gboolean gvir_domain_get_persistent(GVirDomain *dom)
+{
+ g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
+
+ return virDomainIsPersistent(dom->priv->handle);
+}
diff --git a/libvirt-gobject/libvirt-gobject-domain.h b/libvirt-gobject/libvirt-gobject-domain.h
index a3649cd..20388f2 100644
--- a/libvirt-gobject/libvirt-gobject-domain.h
+++ b/libvirt-gobject/libvirt-gobject-domain.h
@@ -166,6 +166,7 @@ void gvir_domain_save_async (GVirDomain *dom,
gboolean gvir_domain_save_finish (GVirDomain *dom,
GAsyncResult *result,
GError **err);
+gboolean gvir_domain_get_persistent(GVirDomain *dom);
G_END_DECLS
diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym
index 0e0f34d..4c98c93 100644
--- a/libvirt-gobject/libvirt-gobject.sym
+++ b/libvirt-gobject/libvirt-gobject.sym
@@ -63,6 +63,7 @@ LIBVIRT_GOBJECT_0.0.3 {
gvir_domain_get_config;
gvir_domain_set_config;
gvir_domain_get_info;
+ gvir_domain_get_persistent;
gvir_domain_screenshot;
gvir_domain_snapshot_get_type;
--
1.7.7.5
12 years, 10 months
[libvirt] [libvirt-glib] Add gvir_domain_get_persistent()
by Zeeshan Ali (Khattak)
From: "Zeeshan Ali (Khattak)" <zeeshanak(a)gnome.org>
A predicate to check if domain is persistent or not.
---
libvirt-gobject/libvirt-gobject-domain.c | 13 +++++++++++++
libvirt-gobject/libvirt-gobject-domain.h | 1 +
libvirt-gobject/libvirt-gobject.sym | 1 +
3 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-domain.c b/libvirt-gobject/libvirt-gobject-domain.c
index 967ff67..e3d6a46 100644
--- a/libvirt-gobject/libvirt-gobject-domain.c
+++ b/libvirt-gobject/libvirt-gobject-domain.c
@@ -821,3 +821,16 @@ gboolean gvir_domain_save_finish (GVirDomain *dom,
return TRUE;
}
+
+/**
+ * gvir_domain_get_persistent:
+ * @dom: the domain
+ *
+ * Returns: TRUE if domain is persistent, FALSE otherwise.
+ */
+gboolean gvir_domain_get_persistent(GVirDomain *dom)
+{
+ g_return_val_if_fail(GVIR_IS_DOMAIN(dom), FALSE);
+
+ return virDomainIsPersistent(dom->priv->handle);
+}
diff --git a/libvirt-gobject/libvirt-gobject-domain.h b/libvirt-gobject/libvirt-gobject-domain.h
index a3649cd..20388f2 100644
--- a/libvirt-gobject/libvirt-gobject-domain.h
+++ b/libvirt-gobject/libvirt-gobject-domain.h
@@ -166,6 +166,7 @@ void gvir_domain_save_async (GVirDomain *dom,
gboolean gvir_domain_save_finish (GVirDomain *dom,
GAsyncResult *result,
GError **err);
+gboolean gvir_domain_get_persistent(GVirDomain *dom);
G_END_DECLS
diff --git a/libvirt-gobject/libvirt-gobject.sym b/libvirt-gobject/libvirt-gobject.sym
index 0e0f34d..4c98c93 100644
--- a/libvirt-gobject/libvirt-gobject.sym
+++ b/libvirt-gobject/libvirt-gobject.sym
@@ -63,6 +63,7 @@ LIBVIRT_GOBJECT_0.0.3 {
gvir_domain_get_config;
gvir_domain_set_config;
gvir_domain_get_info;
+ gvir_domain_get_persistent;
gvir_domain_screenshot;
gvir_domain_snapshot_get_type;
--
1.7.7.5
12 years, 10 months