[libvirt] [libvirt-glib] Don't leak virStreams, take the reference
by Marc-André Lureau
Without this change, after virStreamNew() and
g_value_dup_boxed() it will have refcnt = 2
and will leak when GVirStream is destroyed.
---
libvirt-gobject/libvirt-gobject-stream.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-stream.c b/libvirt-gobject/libvirt-gobject-stream.c
index 88e3a40..4aeb182 100644
--- a/libvirt-gobject/libvirt-gobject-stream.c
+++ b/libvirt-gobject/libvirt-gobject-stream.c
@@ -160,7 +160,7 @@ static void gvir_stream_set_property(GObject *object,
case PROP_HANDLE:
if (priv->handle)
virStreamFree(priv->handle);
- priv->handle = g_value_dup_boxed(value);
+ priv->handle = g_value_get_boxed(value);
break;
default:
--
1.7.6.2
13 years, 1 month
[libvirt] RPM build failure on Redhat6
by Wayne Xia
Hi, I want to build rpm for latest libvit version on Redhat6, but when
I type:
./autogen.sh --system
make rpm -j4
error happens:
sitemap.html.tmp index.html.tmp archdomain.html.tmp downloads.html.tmp
auth.html.tmp internals/locking.html.tmp archnode.html.tmp
hvsupport.html.tmp bugs.html.tmp java.html.tmp locking.html.tmp
logging.html.tmp testapi.html.tmp formatnetwork.html.tmp
bindings.html.tmp uri.html.tmp drvtest.html.tmp contact.html.tmp
formatnwfilter.html.tmp intro.html.tmp drvxen.html.tmp drvesx.html.tmp
drvqemu.html.tmp drvvmware.html.tmp testsuites.html.tmp
devguide.html.tmp firewall.html.tmp architecture.html.tmp todo.html.tmp
formatsnapshot.html.tmp formatstorage.html.tmp deployment.html.tmp
internals.html.tmp api_extension.html.tmp drvuml.html.tmp
virshcmdref.html.tmp csharp.html.tmp python.html.tmp drvremote.html.tmp
archstorage.html.tmp remote.html.tmp drivers.html.tmp formatnode.html.tmp
make[2]: Leaving directory
`/home/xiawenc/WorkDir/Source/libvirt/libvirt/docs'
make[1]: *** [distdir] Error 1
make[1]: Leaving directory `/home/xiawenc/WorkDir/Source/libvirt/libvirt'
make: *** [rpm] Error 2
does anyone knows what is happening?
--
Best Regards
Wayne Xia
mail:xiawenc@linux.vnet.ibm.com
tel:86-010-82450803
13 years, 1 month
[libvirt] [PATCH] qemu: Check for domain being active on successful job acquire
by Michal Privoznik
As this is needed. Although some functions check for domain
being active before obtaining job, we need to check it after,
because obtaining job unlocks domain object, during which
a state of domain can be changed.
---
src/qemu/qemu_driver.c | 75 ++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 69 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ec01cd5..1efc66b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1948,9 +1948,18 @@ static int qemuDomainInjectNMI(virDomainPtr domain, unsigned int flags)
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
qemuDomainObjEnterMonitorWithDriver(driver, vm);
ret = qemuMonitorInjectNMI(priv->mon);
qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+endjob:
if (qemuDomainObjEndJob(driver, vm) == 0) {
vm = NULL;
goto cleanup;
@@ -4387,7 +4396,7 @@ static char *qemuDomainGetXMLDesc(virDomainPtr dom,
virDomainObjPtr vm;
char *ret = NULL;
unsigned long balloon;
- int err;
+ int err = 0;
/* Flags checked by virDomainDefFormat */
@@ -4413,9 +4422,17 @@ static char *qemuDomainGetXMLDesc(virDomainPtr dom,
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_QUERY) < 0)
goto cleanup;
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
qemuDomainObjEnterMonitorWithDriver(driver, vm);
err = qemuMonitorGetBalloonInfo(priv->mon, &balloon);
qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+endjob:
if (qemuDomainObjEndJob(driver, vm) == 0) {
vm = NULL;
goto cleanup;
@@ -7153,6 +7170,12 @@ qemudDomainBlockStatsFlags (virDomainPtr dom,
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_QUERY) < 0)
goto cleanup;
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
qemuDomainObjEnterMonitor(driver, vm);
tmp = *nparams;
ret = qemuMonitorGetBlockStatsParamsNumber(priv->mon, nparams);
@@ -8672,6 +8695,12 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MIGRATION_OP) < 0)
goto cleanup;
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth);
qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth);
@@ -8680,6 +8709,7 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
if (ret == 0)
priv->migMaxBandwidth = bandwidth;
+endjob:
if (qemuDomainObjEndJob(driver, vm) == 0)
vm = NULL;
} else {
@@ -8774,6 +8804,12 @@ qemuDomainSnapshotCreateActive(virConnectPtr conn,
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
return -1;
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
/* savevm monitor command pauses the domain emitting an event which
* confuses libvirt since it's not notified when qemu resumes the
@@ -8823,6 +8859,7 @@ cleanup:
_("resuming after snapshot failed"));
}
+endjob:
if (vm && qemuDomainObjEndJob(driver, vm) == 0) {
/* Only possible if a transient vm quit while our locks were down,
* in which case we don't want to save snapshot metadata. */
@@ -9045,6 +9082,13 @@ qemuDomainSnapshotCreateDiskActive(virConnectPtr conn,
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
return -1;
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto endjob;
+ }
+
+
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
/* In qemu, snapshot_blkdev on a single disk will pause cpus,
* but this confuses libvirt since notifications are not given
@@ -9127,12 +9171,14 @@ cleanup:
(persist &&
virDomainSaveConfig(driver->configDir, vm->newDef) < 0))
ret = -1;
- if (qemuDomainObjEndJob(driver, vm) == 0) {
+ }
+
+endjob:
+ if (vm && (qemuDomainObjEndJob(driver, vm) == 0)) {
/* Only possible if a transient vm quit while our locks were down,
* in which case we don't want to save snapshot metadata. */
*vmptr = NULL;
ret = -1;
- }
}
return ret;
@@ -10272,20 +10318,28 @@ static int qemuDomainMonitorCommand(virDomainPtr domain, const char *cmd,
goto cleanup;
}
+ if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("domain is not running"));
+ goto endjob;
+ }
+
priv = vm->privateData;
qemuDomainObjTaint(driver, vm, VIR_DOMAIN_TAINT_CUSTOM_MONITOR, -1);
hmp = !!(flags & VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP);
- if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
- goto cleanup;
qemuDomainObjEnterMonitorWithDriver(driver, vm);
ret = qemuMonitorArbitraryCommand(priv->mon, cmd, result, hmp);
qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+endjob:
if (qemuDomainObjEndJob(driver, vm) == 0) {
vm = NULL;
- goto cleanup;
}
cleanup:
@@ -10522,10 +10576,19 @@ qemuDomainBlockJobImpl(virDomainPtr dom, const char *path,
if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("domain is not running"));
+ goto endjob;
+ }
+
qemuDomainObjEnterMonitorWithDriver(driver, vm);
priv = vm->privateData;
ret = qemuMonitorBlockJob(priv->mon, device, bandwidth, info, mode);
qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+endjob:
if (qemuDomainObjEndJob(driver, vm) == 0) {
vm = NULL;
goto cleanup;
--
1.7.3.4
13 years, 1 month
[libvirt] [PATCH] events: Propose a separate lock for event queue
by Michal Privoznik
Currently, push & pop from event queue (both server & client side)
rely on lock from higher levels, e.g. on driver lock (qemu),
private_data (remote), ...; This alone is not sufficient as not
every function that interacts with this queue can/does lock,
esp. in client where we have a different approach, "passing
the buck".
Therefore we need a separate lock just to protect event queue.
For more info see:
https://bugzilla.redhat.com/show_bug.cgi?id=743817
---
src/conf/domain_event.c | 65 +++++++++++++++++++++++++++++++++++++++++------
src/conf/domain_event.h | 1 +
2 files changed, 58 insertions(+), 8 deletions(-)
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index 3189346..6cc8168 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -547,6 +547,24 @@ virDomainEventQueuePtr virDomainEventQueueNew(void)
return ret;
}
+static void
+virDomainEventStateLock(virDomainEventStatePtr state)
+{
+ if (!state)
+ return;
+
+ virMutexLock(&state->lock);
+}
+
+static void
+virDomainEventStateUnlock(virDomainEventStatePtr state)
+{
+ if (!state)
+ return;
+
+ virMutexUnlock(&state->lock);
+}
+
/**
* virDomainEventStateFree:
* @list: virDomainEventStatePtr to free
@@ -564,6 +582,8 @@ virDomainEventStateFree(virDomainEventStatePtr state)
if (state->timer != -1)
virEventRemoveTimeout(state->timer);
+
+ virMutexDestroy(&state->lock);
VIR_FREE(state);
}
@@ -590,6 +610,13 @@ virDomainEventStateNew(virEventTimeoutCallback timeout_cb,
goto error;
}
+ if (virMutexInit(&state->lock) < 0) {
+ virReportSystemError(errno, "%s",
+ _("unable to initialize state mutex"));
+ VIR_FREE(state);
+ goto error;
+ }
+
if (VIR_ALLOC(state->callbacks) < 0) {
virReportOOMError();
goto error;
@@ -1161,18 +1188,26 @@ void
virDomainEventStateQueue(virDomainEventStatePtr state,
virDomainEventPtr event)
{
+ int count;
+
if (state->timer < 0) {
virDomainEventFree(event);
return;
}
+ virDomainEventStateLock(state);
+
if (virDomainEventQueuePush(state->queue, event) < 0) {
VIR_DEBUG("Error adding event to queue");
virDomainEventFree(event);
}
- if (state->queue->count == 1)
+ count = state->queue->count;
+ virDomainEventStateUnlock(state);
+
+ if (count == 1)
virEventUpdateTimeout(state->timer, 0);
+
}
void
@@ -1182,6 +1217,7 @@ virDomainEventStateFlush(virDomainEventStatePtr state,
{
virDomainEventQueue tempQueue;
+ virDomainEventStateLock(state);
state->isDispatching = true;
/* Copy the queue, so we're reentrant safe when dispatchFunc drops the
@@ -1190,6 +1226,7 @@ virDomainEventStateFlush(virDomainEventStatePtr state,
tempQueue.events = state->queue->events;
state->queue->count = 0;
state->queue->events = NULL;
+ virDomainEventStateUnlock(state);
virEventUpdateTimeout(state->timer, -1);
virDomainEventQueueDispatch(&tempQueue,
@@ -1198,9 +1235,11 @@ virDomainEventStateFlush(virDomainEventStatePtr state,
opaque);
/* Purge any deleted callbacks */
+ virDomainEventStateLock(state);
virDomainEventCallbackListPurgeMarked(state->callbacks);
state->isDispatching = false;
+ virDomainEventStateUnlock(state);
}
int
@@ -1208,11 +1247,16 @@ virDomainEventStateDeregister(virConnectPtr conn,
virDomainEventStatePtr state,
virConnectDomainEventCallback callback)
{
+ int ret;
+
+ virDomainEventStateLock(state);
if (state->isDispatching)
- return virDomainEventCallbackListMarkDelete(conn,
- state->callbacks, callback);
+ ret = virDomainEventCallbackListMarkDelete(conn,
+ state->callbacks, callback);
else
- return virDomainEventCallbackListRemove(conn, state->callbacks, callback);
+ ret = virDomainEventCallbackListRemove(conn, state->callbacks, callback);
+ virDomainEventStateUnlock(state);
+ return ret;
}
int
@@ -1220,10 +1264,15 @@ virDomainEventStateDeregisterAny(virConnectPtr conn,
virDomainEventStatePtr state,
int callbackID)
{
+ int ret;
+
+ virDomainEventStateLock(state);
if (state->isDispatching)
- return virDomainEventCallbackListMarkDeleteID(conn,
- state->callbacks, callbackID);
+ ret = virDomainEventCallbackListMarkDeleteID(conn,
+ state->callbacks, callbackID);
else
- return virDomainEventCallbackListRemoveID(conn,
- state->callbacks, callbackID);
+ ret = virDomainEventCallbackListRemoveID(conn,
+ state->callbacks, callbackID);
+ virDomainEventStateUnlock(state);
+ return ret;
}
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index b06be16..08930ed 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -61,6 +61,7 @@ struct _virDomainEventState {
int timer;
/* Flag if we're in process of dispatching */
bool isDispatching;
+ virMutex lock;
};
typedef struct _virDomainEventState virDomainEventState;
typedef virDomainEventState *virDomainEventStatePtr;
--
1.7.3.4
13 years, 1 month
[libvirt] [PATCH v4 0/2] Allow domain reboot after core dump
by Michal Privoznik
This is the 4th (and hopefully last) version of these patches.
diff to v3:
-split in 2 patches
-and some other Eric's suggestions taken in
Michal Privoznik (2):
virDomainCoreDump: Introduce VIR_DUMP_RESET flag
qemu: Implement VIR_DUMP_RESET
include/libvirt/libvirt.h.in | 1 +
src/libvirt.c | 15 ++++++++++++++-
src/qemu/qemu_driver.c | 9 ++++++++-
tools/virsh.c | 3 +++
tools/virsh.pod | 4 +++-
5 files changed, 29 insertions(+), 3 deletions(-)
--
1.7.3.4
13 years, 1 month
[libvirt] Possible security hole? unprivileged user can use virsh to overwrite sensitive system file
by Hong Xiang
I found there's a way for a unprivileged user to overwrite sensitive
system file with virsh, here's how:
1. (as an unprivileged user) start virsh and connect to the r/w socket
of libvirtd:
virsh -c qemu+unix:///system?socket=/var/run/libvirt/libvirt-sock
2. start a guest, then issue 'save' or 'dump' command, giving a
sensitive system file path as the <file> parameter, for example,
'/etc/passwd';
3. the sensitive system file will be overwritten;
Attached is a test log. I'm using libvirt-0.8.7 on a OpenClient for RHEL
6.1. And latest libvirt code shows the same symptom.
BTW, virsh expands the <file> parameter in step to an absolute path if
user-provided is not, and libvirtd interprets it as a local file. IMHO
it does not look quite right, especially when the virsh-to-libvirtd
connection is remote.
--
Thanks.
Hong Xiang
13 years, 1 month
[libvirt] [PATCH] qemu: Do not reattach PCI device used by other domain when shutdown
by Osier Yang
When failing on starting a domain, it tries to reattach all the PCI
devices defined in the domain conf, regardless of whether the devices
are still used by other domain. This will cause the devices are deleted
from the list qemu_driver->activePciHostdevs, thus the devices will be
thought as usable even if it's not true. And following commands
nodedev-{reattach,reset} will be successful.
How to reproduce:
1) Define two domains with same PCI device defined in the confs.
2) # virsh start domain1
3) # virsh start domain2
4) # virsh nodedev-reattach $pci_device
You will see the device will be reattached to host successfully.
As pciDeviceReattach just check if the device is still used by
other domain via checking if the device is in list driver->activePciHostdevs,
however, the device is deleted from the list by step 2).
This patch is to prohibit the bug by:
1) Prohibit a domain starting or device attachment right at
preparation period (qemuPrepareHostdevPCIDevices) if the
device is in list driver->activePciHostdevs, which means
it's used by other domain.
2) Introduces a new field for struct _pciDevice, (char *used_by),
it will be set as the domain name at preparation period,
(qemuPrepareHostdevPCIDevices). Thus we can prohibit deleting
the device from driver->activePciHostdevs if it's still used by
other domain when stopping the domain process.
* src/pci.h (define two internal functions, pciDeviceSetUsedBy and
pciDevceGetUsedBy)
* src/pci.c (new field "char *used_by" for struct _pciDevice,
implementations for the two new functions)
* src/libvirt_private.syms (Add the two new internal functions)
* src/qemu_hostdev.h (Modify the definition of functions
qemuPrepareHostdevPCIDevices, and qemuDomainReAttachHostdevDevices)
* src/qemu_hostdev.c (Prohibit preparation and don't delete the
device from activePciHostdevs list if it's still used by other domain)
* src/qemu_hotplug.c (Update function usage, as the definitions are
changed)
---
src/libvirt_private.syms | 2 ++
src/qemu/qemu_hostdev.c | 31 ++++++++++++++++++++++++++++---
src/qemu/qemu_hostdev.h | 2 ++
src/qemu/qemu_hotplug.c | 4 ++--
src/util/pci.c | 22 ++++++++++++++++++++++
src/util/pci.h | 3 +++
6 files changed, 59 insertions(+), 5 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 8235ea1..a5c5e6c 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -872,6 +872,7 @@ virNWFilterHashTableRemoveEntry;
pciDettachDevice;
pciDeviceFileIterate;
pciDeviceGetManaged;
+pciDeviceGetUsedBy;
pciDeviceIsAssignable;
pciDeviceIsVirtualFunction;
pciDeviceListAdd;
@@ -884,6 +885,7 @@ pciDeviceListSteal;
pciDeviceNetName;
pciDeviceReAttachInit;
pciDeviceSetManaged;
+pciDeviceSetUsedBy;
pciFreeDevice;
pciGetDevice;
pciGetPhysicalFunction;
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 6f77717..ef9e3b7 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -101,6 +101,7 @@ cleanup:
int qemuPrepareHostdevPCIDevices(struct qemud_driver *driver,
+ const char *name,
virDomainHostdevDefPtr *hostdevs,
int nhostdevs)
{
@@ -126,7 +127,10 @@ int qemuPrepareHostdevPCIDevices(struct qemud_driver *driver,
for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
pciDevice *dev = pciDeviceListGet(pcidevs, i);
if (!pciDeviceIsAssignable(dev, !driver->relaxedACS))
- goto reattachdevs;
+ goto cleanup;
+
+ if (pciDeviceListFind(driver->activePciHostdevs, dev))
+ goto cleanup;
if (pciDeviceGetManaged(dev) &&
pciDettachDevice(dev, driver->activePciHostdevs) < 0)
@@ -156,6 +160,14 @@ int qemuPrepareHostdevPCIDevices(struct qemud_driver *driver,
pciDeviceListSteal(pcidevs, dev);
}
+ /* Now set the used_by_domain of the device in driver->activePciHostdevs
+ * as domain name.
+ */
+ for (i = 0; i < pciDeviceListCount(driver->activePciHostdevs); i++) {
+ pciDevice * dev = pciDeviceListGet(driver->activePciHostdevs, i);
+ pciDeviceSetUsedBy(dev, name);
+ }
+
ret = 0;
goto cleanup;
@@ -183,7 +195,7 @@ static int
qemuPrepareHostPCIDevices(struct qemud_driver *driver,
virDomainDefPtr def)
{
- return qemuPrepareHostdevPCIDevices(driver, def->hostdevs, def->nhostdevs);
+ return qemuPrepareHostdevPCIDevices(driver, def->name, def->hostdevs, def->nhostdevs);
}
@@ -258,11 +270,13 @@ void qemuReattachPciDevice(pciDevice *dev, struct qemud_driver *driver)
void qemuDomainReAttachHostdevDevices(struct qemud_driver *driver,
+ const char *name,
virDomainHostdevDefPtr *hostdevs,
int nhostdevs)
{
pciDeviceList *pcidevs;
int i;
+ const char *used_by = NULL;
if (!(pcidevs = qemuGetPciHostDeviceList(hostdevs, nhostdevs))) {
virErrorPtr err = virGetLastError();
@@ -277,6 +291,17 @@ void qemuDomainReAttachHostdevDevices(struct qemud_driver *driver,
for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
pciDevice *dev = pciDeviceListGet(pcidevs, i);
+ pciDevice *activeDev = NULL;
+
+ /* Never delete the dev from list driver->activePciHostdevs
+ * if it's used by other domain.
+ */
+ activeDev = pciDeviceListFind(driver->activePciHostdevs, dev);
+ if (activeDev &&
+ (used_by = pciDeviceGetUsedBy(activeDev)) &&
+ STRNEQ(used_by, name))
+ continue;
+
pciDeviceListDel(driver->activePciHostdevs, dev);
}
@@ -305,5 +330,5 @@ void qemuDomainReAttachHostDevices(struct qemud_driver *driver,
if (!def->nhostdevs)
return;
- qemuDomainReAttachHostdevDevices(driver, def->hostdevs, def->nhostdevs);
+ qemuDomainReAttachHostdevDevices(driver, def->name, def->hostdevs, def->nhostdevs);
}
diff --git a/src/qemu/qemu_hostdev.h b/src/qemu/qemu_hostdev.h
index 1f3d1bc..07d7de2 100644
--- a/src/qemu/qemu_hostdev.h
+++ b/src/qemu/qemu_hostdev.h
@@ -30,12 +30,14 @@
int qemuUpdateActivePciHostdevs(struct qemud_driver *driver,
virDomainDefPtr def);
int qemuPrepareHostdevPCIDevices(struct qemud_driver *driver,
+ const char *name,
virDomainHostdevDefPtr *hostdevs,
int nhostdevs);
int qemuPrepareHostDevices(struct qemud_driver *driver,
virDomainDefPtr def);
void qemuReattachPciDevice(pciDevice *dev, struct qemud_driver *driver);
void qemuDomainReAttachHostdevDevices(struct qemud_driver *driver,
+ const char *name,
virDomainHostdevDefPtr *hostdevs,
int nhostdevs);
void qemuDomainReAttachHostDevices(struct qemud_driver *driver,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 6cfe392..dc920e7 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -859,7 +859,7 @@ int qemuDomainAttachHostPciDevice(struct qemud_driver *driver,
return -1;
}
- if (qemuPrepareHostdevPCIDevices(driver, &hostdev, 1) < 0)
+ if (qemuPrepareHostdevPCIDevices(driver, vm->def->name, &hostdev, 1) < 0)
return -1;
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
@@ -925,7 +925,7 @@ error:
hostdev->info.addr.pci.slot) < 0)
VIR_WARN("Unable to release PCI address on host device");
- qemuDomainReAttachHostdevDevices(driver, &hostdev, 1);
+ qemuDomainReAttachHostdevDevices(driver, vm->def->name, &hostdev, 1);
VIR_FREE(devstr);
VIR_FREE(configfd_name);
diff --git a/src/util/pci.c b/src/util/pci.c
index 8d8e157..38548c7 100644
--- a/src/util/pci.c
+++ b/src/util/pci.c
@@ -62,6 +62,7 @@ struct _pciDevice {
char name[PCI_ADDR_LEN]; /* domain:bus:slot.function */
char id[PCI_ID_LEN]; /* product vendor */
char *path;
+ char *used_by; /* The domain which uses the device */
int fd;
unsigned initted;
@@ -1312,6 +1313,7 @@ pciGetDevice(unsigned domain,
dev->bus = bus;
dev->slot = slot;
dev->function = function;
+ dev->used_by = NULL;
if (snprintf(dev->name, sizeof(dev->name), "%.4x:%.2x:%.2x.%.1x",
dev->domain, dev->bus, dev->slot,
@@ -1374,6 +1376,7 @@ pciFreeDevice(pciDevice *dev)
VIR_DEBUG("%s %s: freeing", dev->id, dev->name);
pciCloseConfig(dev);
VIR_FREE(dev->path);
+ VIR_FREE(dev->used_by);
VIR_FREE(dev);
}
@@ -1387,6 +1390,25 @@ unsigned pciDeviceGetManaged(pciDevice *dev)
return dev->managed;
}
+int
+pciDeviceSetUsedBy(pciDevice *dev, const char *name)
+{
+ dev->used_by = strdup(name);
+
+ if (!dev->used_by) {
+ virReportOOMError();
+ return -1;
+ }
+
+ return 0;
+}
+
+const char *
+pciDeviceGetUsedBy(pciDevice *dev)
+{
+ return dev->used_by;
+}
+
void pciDeviceReAttachInit(pciDevice *pci)
{
pci->unbind_from_stub = 1;
diff --git a/src/util/pci.h b/src/util/pci.h
index a1600fe..c9d8227 100644
--- a/src/util/pci.h
+++ b/src/util/pci.h
@@ -47,6 +47,9 @@ int pciResetDevice (pciDevice *dev,
void pciDeviceSetManaged(pciDevice *dev,
unsigned managed);
unsigned pciDeviceGetManaged(pciDevice *dev);
+int pciDeviceSetUsedBy(pciDevice *dev,
+ const char *used_by);
+const char *pciDeviceGetUsedBy(pciDevice *dev);
void pciDeviceReAttachInit(pciDevice *dev);
pciDeviceList *pciDeviceListNew (void);
--
1.7.6
13 years, 1 month
[libvirt] [PATCH 0/3] example: event-test.py
by Philipp Hahn
Some minor improvements to the event-test Python example.
Philipp Hahn (3):
example: Fix argument handling
example: Redirect --help output to stdout/stderr
example: Support debug output and loop switch
examples/domain-events/events-python/event-test.py | 25 +++++++++++++------
1 files changed, 17 insertions(+), 8 deletions(-)
13 years, 1 month
[libvirt] [PATCH 0/4] Xen fixes
by Philipp Hahn
Here are several patches relevant to Xen:
The first two patches fix the test-suite when building as root in a Xen-dom0
domain.
The other two patches fix problems when doing "virsh edit" on Xen domains.
Philipp Hahn (4):
tests: Add support for skipping tests
tests: Skip Xen-HVM tests for root on dom0
xen: fix PyGrub boot device order
xen: Return tap2 for tap2 disks
src/xenxs/xen_sxpr.c | 33 ++++++++++++-----
tests/testutils.c | 4 ++
tests/xencapstest.c | 95 ++++++++++++++++++++++++++++++++++----------------
3 files changed, 93 insertions(+), 39 deletions(-)
13 years, 1 month