[libvirt] [PATCH] util: Make sure virExec hook failures are raised
by Cole Robinson
With the introduction virDispatchError, hook function errors are
never sent through the error callback, so users will never see
these messages.
Fix this by calling virDispatchError after hook failure.
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
src/util/util.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/src/util/util.c b/src/util/util.c
index ba6b0db..45ca657 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -557,8 +557,11 @@ __virExec(virConnectPtr conn,
}
if (hook)
- if ((hook)(data) != 0)
+ if ((hook)(data) != 0) {
+ VIR_DEBUG0("Hook function failed.");
+ virDispatchError(NULL);
_exit(1);
+ }
/* The steps above may need todo something privileged, so
* we delay clearing capabilities until the last minute */
--
1.6.5.2
14 years, 11 months
[libvirt] [PATCH] Fix linkage of virt-aa-helper to libgnu.a
by Matthias Bolte
---
src/Makefile.am | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index dbf708b..324030b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -876,9 +876,9 @@ virt_aa_helper_LDFLAGS = $(WARN_CFLAGS)
virt_aa_helper_LDADD = \
$(WARN_CFLAGS) \
$(LIBXML_LIBS) \
- @top_srcdir(a)/gnulib/lib/libgnu.la \
@top_srcdir(a)/src/libvirt_conf.la \
- @top_srcdir(a)/src/libvirt_util.la
+ @top_srcdir(a)/src/libvirt_util.la \
+ @top_srcdir(a)/gnulib/lib/libgnu.la
virt_aa_helper_CFLAGS = \
-I@top_srcdir@/src/conf \
-I@top_srcdir@/src/security
--
1.6.3.3
14 years, 11 months
[libvirt] [PATCH] Fix event-test segfault for mixed remote/local driver usage
by Matthias Bolte
If examples/domain-events/events-c/event-test.c uses a local driver
for the hyperviror and a remote driver for storage then the segfault
occurs in remoteDomainEventDispatchFunc because conn->privateData is
used.
The problem is as follows. The doRemoteOpen function registers
remoteDomainEventFired as event handle and remoteDomainEventQueueFlush
as event timeout. The doRemoteOpen function is used in remoteOpen and
remoteOpenSecondaryDriver. So both handlers are registered for all
types of remote drivers, but remoteDomainEventQueueFlush always uses
conn->privateData. That's wrong when remoteDomainEventQueueFlush is
called for any other driver than the hypervisor driver, it should use
conn->storagePrivateData for the storage driver for example.
In the common case this doesn't result in a segfault because in the
common case all drivers for a connection are either all remote or all
local and conn->privateData and conn->storagePrivateData are the same.
But in the local Xen case ('event-test xen:///' executed in Domain-0,
with a libvirtd running in Domain-0) the hypervisor driver is local
and the storage driver is remote. This results in a mismatch between
conn->privateData and conn->storagePrivateData. Now the call to
remoteDomainEventQueueFlush in the context of the storage driver
results in a segfault, because it assumes that conn->privateData points
to remote driver private data, but it points to Xen driver private
data.
To fix this, the pointer to the private driver data gets passed as
opaque parameter instead of the connection pointer. Because some
functions called by the event handler functions need the connection
pointer for other purposes than error reporting the connection
pointer is passed as member of the private remote driver data struct.
Now remoteDomainEventFired and remoteDomainEventQueueFlush have the
correct private data pointer for the respective calling context.
---
src/remote/remote_driver.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index d6f5fce..582b85c 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -152,6 +152,7 @@ struct private_stream_data {
struct private_data {
virMutex lock;
+ virConnectPtr conn;
int sock; /* Socket. */
int watch; /* File handle watch */
@@ -893,7 +894,7 @@ doRemoteOpen (virConnectPtr conn,
if ((priv->watch = virEventAddHandle(priv->sock,
VIR_EVENT_HANDLE_READABLE,
remoteDomainEventFired,
- conn, NULL)) < 0) {
+ priv, NULL)) < 0) {
DEBUG0("virEventAddHandle failed: No addHandleImpl defined."
" continuing without events.");
} else {
@@ -901,7 +902,7 @@ doRemoteOpen (virConnectPtr conn,
DEBUG0("Adding Timeout for remote event queue flushing");
if ( (priv->eventFlushTimer = virEventAddTimeout(-1,
remoteDomainEventQueueFlush,
- conn, NULL)) < 0) {
+ priv, NULL)) < 0) {
DEBUG0("virEventAddTimeout failed: No addTimeoutImpl defined. "
"continuing without events.");
virEventRemoveHandle(priv->watch);
@@ -980,6 +981,7 @@ remoteAllocPrivateData(virConnectPtr conn)
return NULL;
}
remoteDriverLock(priv);
+ priv->conn = conn;
priv->localUses = 1;
priv->watch = -1;
priv->sock = -1;
@@ -8659,8 +8661,7 @@ remoteDomainEventFired(int watch,
int event,
void *opaque)
{
- virConnectPtr conn = opaque;
- struct private_data *priv = conn->privateData;
+ struct private_data *priv = opaque;
remoteDriverLock(priv);
@@ -8684,7 +8685,7 @@ remoteDomainEventFired(int watch,
goto done;
}
- if (remoteIOHandleInput(conn, priv, 0) < 0)
+ if (remoteIOHandleInput(priv->conn, priv, 0) < 0)
DEBUG0("Something went wrong during async message processing");
done:
@@ -8708,8 +8709,7 @@ static void remoteDomainEventDispatchFunc(virConnectPtr conn,
void
remoteDomainEventQueueFlush(int timer ATTRIBUTE_UNUSED, void *opaque)
{
- virConnectPtr conn = opaque;
- struct private_data *priv = conn->privateData;
+ struct private_data *priv = opaque;
virDomainEventQueue tempQueue;
remoteDriverLock(priv);
@@ -8731,7 +8731,7 @@ remoteDomainEventQueueFlush(int timer ATTRIBUTE_UNUSED, void *opaque)
if ( priv->callbackList->count == 0 ) {
/* Tell the server when we are the last callback deregistering */
- if (call (conn, priv, 0, REMOTE_PROC_DOMAIN_EVENTS_DEREGISTER,
+ if (call (priv->conn, priv, 0, REMOTE_PROC_DOMAIN_EVENTS_DEREGISTER,
(xdrproc_t) xdr_void, (char *) NULL,
(xdrproc_t) xdr_void, (char *) NULL) == -1)
VIR_WARN0("Failed to de-register events");
--
1.6.3.3
14 years, 11 months
[libvirt] Set MAC address for host virtual interface?
by Neil Aggarwal
Hello:
Is there a way to set the MAC address for the virtual
interface on the host?
I have this in my guests's XML file:
<interface type='bridge'>
<mac address='54:52:00:7d:f8:fc'/>
<source bridge='br0'/>
<target dev='tkl-joomla'/>
</interface>
the mac address line controls the guest interface
but the host interface seems to get a random MAC
address.
This is causing a problem for me since I use Cacti
to monitor the bandwidth usage of the guest machines.
Every time I stop and start a guest, Cacti creates a
new interface and I have to reset the graphs to use
the new interfaces.
Thanks,
Neil
--
Neil Aggarwal, (281)846-8957, http://UnmeteredVPS.net
Host Joomla!, Wordpress, phpBB, or vBulletin for $25/mo
Unmetered bandwidth = no overage charges, 7 day free trial
14 years, 11 months
[libvirt] Man page patch for BZ 548485
by David Jorm
See https://bugzilla.redhat.com/show_bug.cgi?id=548485
git diff for the patch:
---SNIP---
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -342,7 +342,9 @@ severed upon restore, as TCP timeouts may have expired.
=item B<schedinfo> optional I<--weight> B<number> optional I<--cap> B<number> I<domain-id>
-Allows to show (and set) the domain scheduler parameters.
+Allows you to show (and set) the domain scheduler parameters.
+
+B<Note>: The only parameter currently available for all schedulers is cpu_shares. It has a valid value range of 0-262144.
B<Note>: The weight and cap parameters are defined only for the
XEN_CREDIT scheduler and are now I<DEPRECATED>.
---SNIP---
I hope that's right, I found that BZ a bit confusing to comprehend. Learning curve.
David
14 years, 11 months
[libvirt] [BUG?] "no domain with matching uuid" error, when vm restarts
by su disheng
Hi,
In the following libvirt API calling sequence, I always get an error "no
domain with matching uuid"
Connect _conn = new Connect("qemu:///system", false);
_conn.domainDefineXML(kvm_guest_xml);
Domain dm = _conn.domainLookupByName(kvm_guest_name);
dm.create();
/* stop, undefine, and re-start the vm*/
dm.shutdown();
dm.undefine();
dm.domainDefineXML(kvm_guest_xml);
/****A****/
Domain dm = _conn.domainLookupByName(kvm_guest_name);
dm.create() /********Error!!!!**/
if I close the connection, and re-connect qemu at the end of
/****A****/, then everything is OK.
From the log, seems that uuid is not updated immediately, for this
connection, the uuid is in the stale state?
I am using libvirt 0.6.3, if it's a bug, does it fixed in the latest
code? or Have I need to close the connection for each vm shutdown/re-define?
I am a newbie in this API, any help are appreciated.
14 years, 11 months
[libvirt] [PATCH] virterror: Don't invoke error callback for ERR_OK
by Cole Robinson
Since virDispatchError is now responsible for invoking the error callback,
give it the same semantics as ReportError, which will skip VIR_ERR_OK
(which is encountered when no error was raised).
This fixes invoking the error callback after every non-erroring API call.
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
src/util/virterror.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/src/util/virterror.c b/src/util/virterror.c
index e2128b9..78974ee 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -603,8 +603,12 @@ virDispatchError(virConnectPtr conn)
if (!err)
return;
- /* Set a generic error message if none is already set */
+ /* We never used to raise ERR_OK, so maintain existing behavior */
if (err->code == VIR_ERR_OK)
+ return;
+
+ /* Set a generic error message if none is already set */
+ if (!err->message)
virErrorGenericFailure(err);
/* Copy the global error to per-connection error if needed */
--
1.6.5.2
14 years, 11 months
[libvirt] [PATCH 0/2] Some new utility functions
by Laine Stump
I'm planning to use these to fix the problems with creating storage
volumes on root-squashing NFS servers, but since they may be of
general utility I thought I'd throw them out for comments beforehand -
it something different would make them more generally useful, better
to change it now than after I've already finished code to use them.
My plan is to use virRunWithHook() to call setuid (or possibly some
sort of capng calisthenics) prior to execing qemu-img and
qcow-create. virFileCreate and virDirCreate will be used when creating
raw volumes.
I have written test code to verify that virFileCreate works in several
different scenarios. Haven't done so with virRun yet, but it's a
fairly simple change, just exposing __virExec arguments that were
already there. (I'd previously written test code (yes, it worked ;-))
that used a virRun with uid/gid args added on, but have decided
against that approach, since this seems more flexible)
14 years, 11 months
[libvirt] [PATCH] node_device: udev: Fix memory leak
by Cole Robinson
We are setting the same property two different ways without
free'ing in between. Just drop the second assignment.
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
src/node_device/node_device_udev.c | 6 +-----
1 files changed, 1 insertions(+), 5 deletions(-)
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index a9e196d..ff6bd46 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -997,11 +997,7 @@ static int udevProcessStorage(struct udev_device *device,
goto out;
}
data->storage.block = strdup(devnode);
- if (udevGetStringProperty(device,
- "DEVNAME",
- &data->storage.block) == PROPERTY_ERROR) {
- goto out;
- }
+
if (udevGetStringProperty(device,
"ID_BUS",
&data->storage.bus) == PROPERTY_ERROR) {
--
1.6.5.2
14 years, 11 months
[libvirt] [PATCH] node_device: udev: Enumerate floppy devices
by Cole Robinson
There are quite a few differences between how udev exposes legacy
and USB floppy devs, but this patch takes care of both variants.
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
src/node_device/node_device_udev.c | 88 ++++++++++++++++++++++++++++-------
1 files changed, 70 insertions(+), 18 deletions(-)
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index 55cfee2..a9e196d 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -840,30 +840,19 @@ out:
}
-static int udevProcessCDROM(struct udev_device *device,
- virNodeDeviceDefPtr def)
+static int udevProcessRemoveableMedia(struct udev_device *device,
+ virNodeDeviceDefPtr def,
+ int has_media)
{
union _virNodeDevCapData *data = &def->caps->data;
int tmp_int = 0, ret = 0;
- /* NB: the drive_type string provided by udev is different from
- * that provided by HAL; now it's "cd" instead of "cdrom" We
- * change it to cdrom to preserve compatibility with earlier
- * versions of libvirt. */
- VIR_FREE(def->caps->data.storage.drive_type);
- def->caps->data.storage.drive_type = strdup("cdrom");
- if (def->caps->data.storage.drive_type == NULL) {
- virReportOOMError(NULL);
- goto out;
- }
-
if ((udevGetIntSysfsAttr(device, "removable", &tmp_int, 0) == PROPERTY_FOUND) &&
(tmp_int == 1)) {
def->caps->data.storage.flags |= VIR_NODE_DEV_CAP_STORAGE_REMOVABLE;
}
- if ((udevGetIntProperty(device, "ID_CDROM_MEDIA", &tmp_int, 0)
- == PROPERTY_FOUND) && (tmp_int == 1)) {
+ if (has_media) {
def->caps->data.storage.flags |=
VIR_NODE_DEV_CAP_STORAGE_REMOVABLE_MEDIA_AVAILABLE;
@@ -898,6 +887,53 @@ out:
return ret;
}
+static int udevProcessCDROM(struct udev_device *device,
+ virNodeDeviceDefPtr def)
+{
+ int ret = -1;
+ int tmp_int = 0;
+ int has_media = 0;
+
+ /* NB: the drive_type string provided by udev is different from
+ * that provided by HAL; now it's "cd" instead of "cdrom" We
+ * change it to cdrom to preserve compatibility with earlier
+ * versions of libvirt. */
+ VIR_FREE(def->caps->data.storage.drive_type);
+ def->caps->data.storage.drive_type = strdup("cdrom");
+ if (def->caps->data.storage.drive_type == NULL) {
+ virReportOOMError(NULL);
+ goto out;
+ }
+
+ if ((udevGetIntProperty(device, "ID_CDROM_MEDIA",
+ &tmp_int, 0) == PROPERTY_FOUND))
+ has_media = tmp_int;
+
+ ret = udevProcessRemoveableMedia(device, def, has_media);
+out:
+ return ret;
+}
+
+static int udevProcessFloppy(struct udev_device *device,
+ virNodeDeviceDefPtr def)
+{
+ int tmp_int = 0;
+ int has_media = 0;
+ char *tmp_str = NULL;
+
+ if ((udevGetIntProperty(device, "DKD_MEDIA_AVAILABLE",
+ &tmp_int, 0) == PROPERTY_FOUND))
+ /* USB floppy */
+ has_media = tmp_int;
+ else if (udevGetStringProperty(device, "ID_FS_LABEL",
+ &tmp_str) == PROPERTY_FOUND) {
+ /* Legacy floppy */
+ has_media = 1;
+ VIR_FREE(tmp_str);
+ }
+
+ return udevProcessRemoveableMedia(device, def, has_media);
+}
/* This function exists to deal with the case in which a driver does
* not provide a device type in the usual place, but udev told us it's
@@ -996,9 +1032,23 @@ static int udevProcessStorage(struct udev_device *device,
if (udevGetStringProperty(device,
"ID_TYPE",
&data->storage.drive_type) != PROPERTY_FOUND) {
- /* If udev doesn't have it, perhaps we can guess it. */
- if (udevKludgeStorageType(def) != 0) {
- goto out;
+ int tmp_int = 0;
+
+ /* All floppy drives have the ID_DRIVE_FLOPPY prop. This is
+ * needed since legacy floppies don't have a drive_type */
+ if ((udevGetIntProperty(device, "ID_DRIVE_FLOPPY",
+ &tmp_int, 0) == PROPERTY_FOUND) &&
+ (tmp_int == 1)) {
+
+ data->storage.drive_type = strdup("floppy");
+ if (!data->storage.drive_type)
+ goto out;
+ } else {
+
+ /* If udev doesn't have it, perhaps we can guess it. */
+ if (udevKludgeStorageType(def) != 0) {
+ goto out;
+ }
}
}
@@ -1006,6 +1056,8 @@ static int udevProcessStorage(struct udev_device *device,
ret = udevProcessCDROM(device, def);
} else if (STREQ(def->caps->data.storage.drive_type, "disk")) {
ret = udevProcessDisk(device, def);
+ } else if (STREQ(def->caps->data.storage.drive_type, "floppy")) {
+ ret = udevProcessFloppy(device, def);
} else {
VIR_INFO("Unsupported storage type '%s'\n",
def->caps->data.storage.drive_type);
--
1.6.5.2
14 years, 11 months