[libvirt] [PATCH] Simplify some redundant locking while unref'ing objects
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
There is no need to hold the mutex when unref'ing
virObject instances
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/conf/domain_conf.c | 4 +---
src/qemu/qemu_driver.c | 4 ++--
src/rpc/virnetserver.c | 3 ---
3 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4aa08d0..0514540 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -741,9 +741,7 @@ static void
virDomainObjListDataFree(void *payload, const void *name ATTRIBUTE_UNUSED)
{
virDomainObjPtr obj = payload;
- virDomainObjLock(obj);
- if (virObjectUnref(obj))
- virDomainObjUnlock(obj);
+ virObjectUnref(obj);
}
int virDomainObjListInit(virDomainObjListPtr doms)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6848924..e963ed3 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3499,8 +3499,8 @@ endjob:
ignore_value(qemuDomainObjEndAsyncJob(driver, wdEvent->vm));
unlock:
- if (virObjectUnref(wdEvent->vm))
- virDomainObjUnlock(wdEvent->vm);
+ virDomainObjUnlock(wdEvent->vm);
+ virObjectUnref(wdEvent->vm);
qemuDriverUnlock(driver);
VIR_FREE(wdEvent);
}
diff --git a/src/rpc/virnetserver.c b/src/rpc/virnetserver.c
index 23493bd..ae4ed46 100644
--- a/src/rpc/virnetserver.c
+++ b/src/rpc/virnetserver.c
@@ -191,10 +191,7 @@ static void virNetServerHandleJob(void *jobOpaque, void *opaque)
if (virNetServerProcessMsg(srv, job->client, job->prog, job->msg) < 0)
goto error;
- virNetServerLock(srv);
virObjectUnref(job->prog);
- virNetServerUnlock(srv);
-
virObjectUnref(job->client);
VIR_FREE(job);
return;
--
1.7.11.2
12 years, 2 months
[libvirt] [PATCH v3] qemu: wait for SPICE to migrate
by Michal Privoznik
Recently, there have been some improvements made to qemu so it
supports seamless migration or something very close to it.
However, it requires libvirt interaction. Once qemu is migrated,
the SPICE server needs to send its internal state to the destination.
Once it's done, it fires SPICE_MIGRATE_COMPLETED event and this
fact is advertised in 'query-spice' output as well.
We must not kill qemu until SPICE server finishes the transfer.
---
src/qemu/qemu_capabilities.c | 4 +++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 8 ++++++
src/qemu/qemu_migration.c | 33 ++++++++++++++++++++++++--
src/qemu/qemu_monitor.c | 24 +++++++++++++++++++
src/qemu/qemu_monitor.h | 2 +
src/qemu/qemu_monitor_json.c | 52 ++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 3 ++
8 files changed, 124 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 278b550..26364ec 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -180,6 +180,8 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"ide-drive.wwn",
"scsi-disk.wwn",
"seccomp-sandbox",
+
+ "seamless-migration", /* 110 */
);
struct _qemuCaps {
@@ -1146,6 +1148,8 @@ qemuCapsComputeCmdFlags(const char *help,
}
if (strstr(help, "-spice"))
qemuCapsSet(caps, QEMU_CAPS_SPICE);
+ if (strstr(help, "seamless-migration="))
+ qemuCapsSet(caps, QEMU_CAPS_SEAMLESS_MIGRATION);
if (strstr(help, "boot=on"))
qemuCapsSet(caps, QEMU_CAPS_DRIVE_BOOT);
if (strstr(help, "serial=s"))
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 4da2a29..2567fd7 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -145,6 +145,7 @@ enum qemuCapsFlags {
QEMU_CAPS_IDE_DRIVE_WWN = 107, /* Is ide-drive.wwn available? */
QEMU_CAPS_SCSI_DISK_WWN = 108, /* Is scsi-disk.wwn available? */
QEMU_CAPS_SECCOMP_SANDBOX = 109, /* -sandbox */
+ QEMU_CAPS_SEAMLESS_MIGRATION = 110, /* seamless-migration for SPICE */
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index cbf4aee..33f7e55 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -6081,6 +6081,14 @@ qemuBuildCommandLine(virConnectPtr conn,
if (def->graphics[0]->data.spice.copypaste == VIR_DOMAIN_GRAPHICS_SPICE_CLIPBOARD_COPYPASTE_NO)
virBufferAddLit(&opt, ",disable-copy-paste");
+ if (qemuCapsGet(caps, QEMU_CAPS_SEAMLESS_MIGRATION)) {
+ /* If qemu supports seamless migration turn it
+ * unconditionally on. If migration destination
+ * doesn't support it, it fallbacks to previous
+ * migration algorithm silently. */
+ virBufferAddLit(&opt, ",seamless-migration=on");
+ }
+
virCommandAddArg(cmd, "-spice");
virCommandAddArgBuffer(cmd, &opt);
if (def->graphics[0]->data.spice.keymap)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 99fc8ce..114d04a 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -891,11 +891,13 @@ static int
qemuMigrationUpdateJobStatus(struct qemud_driver *driver,
virDomainObjPtr vm,
const char *job,
- enum qemuDomainAsyncJob asyncJob)
+ enum qemuDomainAsyncJob asyncJob,
+ bool wait_for_spice)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
int ret;
int status;
+ bool spice_migrated = true;
unsigned long long memProcessed;
unsigned long long memRemaining;
unsigned long long memTotal;
@@ -910,6 +912,13 @@ qemuMigrationUpdateJobStatus(struct qemud_driver *driver,
&memProcessed,
&memRemaining,
&memTotal);
+
+ /* If qemu says migrated, check spice */
+ if (wait_for_spice && (ret == 0) &&
+ (status == QEMU_MONITOR_MIGRATION_STATUS_COMPLETED))
+ ret = qemuMonitorGetSpiceMigrationStatus(priv->mon,
+ &spice_migrated);
+
qemuDomainObjExitMonitorWithDriver(driver, vm);
if (ret < 0 || virTimeMillisNow(&priv->job.info.timeElapsed) < 0) {
@@ -940,6 +949,8 @@ qemuMigrationUpdateJobStatus(struct qemud_driver *driver,
case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED:
priv->job.info.type = VIR_DOMAIN_JOB_COMPLETED;
+ if (spice_migrated)
+ priv->job.info.type = VIR_DOMAIN_JOB_COMPLETED;
ret = 0;
break;
@@ -967,6 +978,13 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm,
{
qemuDomainObjPrivatePtr priv = vm->privateData;
const char *job;
+ bool wait_for_spice;
+
+ /* If guest uses SPICE and supports seamles_migration we have to hold up
+ * migration finish until SPICE server transfers its data */
+ wait_for_spice = (vm->def->ngraphics == 1) &&
+ (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) &&
+ qemuCapsGet(priv->caps, QEMU_CAPS_SEAMLESS_MIGRATION);
switch (priv->job.asyncJob) {
case QEMU_ASYNC_JOB_MIGRATION_OUT:
@@ -988,7 +1006,8 @@ qemuMigrationWaitForCompletion(struct qemud_driver *driver, virDomainObjPtr vm,
/* Poll every 50ms for progress & to allow cancellation */
struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };
- if (qemuMigrationUpdateJobStatus(driver, vm, job, asyncJob) < 0)
+ if (qemuMigrationUpdateJobStatus(driver, vm, job,
+ asyncJob, wait_for_spice) < 0)
goto cleanup;
if (dconn && virConnectIsAlive(dconn) <= 0) {
@@ -1840,6 +1859,7 @@ qemuMigrationRun(struct qemud_driver *driver,
int fd = -1;
unsigned long migrate_speed = resource ? resource : priv->migMaxBandwidth;
virErrorPtr orig_err = NULL;
+ bool wait_for_spice;
VIR_DEBUG("driver=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
"cookieout=%p, cookieoutlen=%p, flags=%lx, resource=%lu, "
@@ -1848,6 +1868,12 @@ qemuMigrationRun(struct qemud_driver *driver,
cookieout, cookieoutlen, flags, resource,
spec, spec->destType, spec->fwdType);
+ /* If guest uses SPICE and supports seamless migration we have to hold up
+ * migration finish until SPICE server transfers its data */
+ wait_for_spice = (vm->def->ngraphics == 1) &&
+ (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) &&
+ qemuCapsGet(priv->caps, QEMU_CAPS_SEAMLESS_MIGRATION);
+
if (virLockManagerPluginUsesState(driver->lockManager) &&
!cookieout) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -1946,7 +1972,8 @@ qemuMigrationRun(struct qemud_driver *driver,
* connection from qemu which may never be initiated.
*/
if (qemuMigrationUpdateJobStatus(driver, vm, _("migration job"),
- QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
+ QEMU_ASYNC_JOB_MIGRATION_OUT,
+ wait_for_spice) < 0)
goto cancel;
while ((fd = accept(spec->dest.unix_socket.sock, NULL, NULL)) < 0) {
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index f36c8a8..7695a81 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1827,6 +1827,30 @@ int qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
}
+int qemuMonitorGetSpiceMigrationStatus(qemuMonitorPtr mon,
+ bool *spice_migrated)
+{
+ int ret;
+ VIR_DEBUG("mon=%p", mon);
+
+ if (!mon) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("monitor must not be NULL"));
+ return -1;
+ }
+
+ if (mon->json) {
+ ret = qemuMonitorJSONGetSpiceMigrationStatus(mon, spice_migrated);
+ } else {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("JSON monitor is required"));
+ return -1;
+ }
+
+ return ret;
+}
+
+
int qemuMonitorMigrateToFd(qemuMonitorPtr mon,
unsigned int flags,
int fd)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 3ebfa3b..bfbeee8 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -343,6 +343,8 @@ int qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
unsigned long long *transferred,
unsigned long long *remaining,
unsigned long long *total);
+int qemuMonitorGetSpiceMigrationStatus(qemuMonitorPtr mon,
+ bool *spice_migrated);
typedef enum {
QEMU_MONITOR_MIGRATE_BACKGROUND = 1 << 0,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index d3a9943..2b77a00 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2490,6 +2490,58 @@ int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
}
+static int
+qemuMonitorJSONSpiceGetMigrationStatusReply(virJSONValuePtr reply,
+ bool *spice_migrated)
+{
+ virJSONValuePtr ret;
+ const char *migrated_str;
+
+ if (!(ret = virJSONValueObjectGet(reply, "return"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-spice reply was missing return data"));
+ return -1;
+ }
+
+ if (!(migrated_str = virJSONValueObjectGetString(ret, "migrated"))) {
+ /* Deliberately don't report error here as we are
+ * probably dealing with older qemu which doesn't
+ * report this yet. Pretend spice is migrated. */
+ *spice_migrated = true;
+ } else {
+ *spice_migrated = STREQ(migrated_str, "true");
+ }
+
+ return 0;
+}
+
+
+int qemuMonitorJSONGetSpiceMigrationStatus(qemuMonitorPtr mon,
+ bool *spice_migrated)
+{
+ int ret;
+ virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-spice",
+ NULL);
+ virJSONValuePtr reply = NULL;
+
+ if (!cmd)
+ return -1;
+
+ ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+ if (ret == 0)
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+
+ if (ret == 0)
+ ret = qemuMonitorJSONSpiceGetMigrationStatusReply(reply,
+ spice_migrated);
+
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
+
+
int qemuMonitorJSONMigrate(qemuMonitorPtr mon,
unsigned int flags,
const char *uri)
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 8e80856..120e2e1 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -134,6 +134,9 @@ int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
int qemuMonitorJSONMigrate(qemuMonitorPtr mon,
unsigned int flags,
const char *uri);
+int qemuMonitorJSONGetSpiceMigrationStatus(qemuMonitorPtr mon,
+ bool *spice_migrated);
+
int qemuMonitorJSONMigrateCancel(qemuMonitorPtr mon);
--
1.7.8.6
12 years, 2 months
[libvirt] [libvirt-glib PATCHv3] Fix *_new_from_xml
by Christophe Fergeau
For objects with a subtype 'type' attribute, when the _new_from_xml
function was called, the 'type' attribute was forcefully set to the
right value rather than checking that the passed-in value matches
the type of the subclass we are trying to instantiate. This commit
changes this, and returns NULL when the value of the 'type' attribute
of the passed-in XML document does not match the expected type.
---
libvirt-gconfig/libvirt-gconfig-domain-address-pci.c | 5 ++++-
libvirt-gconfig/libvirt-gconfig-domain-address-usb.c | 5 ++++-
libvirt-gconfig/libvirt-gconfig-domain-chardev-source-pty.c | 5 ++++-
libvirt-gconfig/libvirt-gconfig-domain-chardev-source-spicevmc.c | 5 ++++-
libvirt-gconfig/libvirt-gconfig-domain-controller-usb.c | 5 ++++-
libvirt-gconfig/libvirt-gconfig-domain-graphics-sdl.c | 5 +++--
libvirt-gconfig/libvirt-gconfig-domain-graphics-spice.c | 5 +++--
libvirt-gconfig/libvirt-gconfig-domain-graphics-vnc.c | 5 +++--
libvirt-gconfig/libvirt-gconfig-domain-interface-bridge.c | 5 +++--
libvirt-gconfig/libvirt-gconfig-domain-interface-network.c | 5 +++--
libvirt-gconfig/libvirt-gconfig-domain-interface-user.c | 5 +++--
libvirt-gconfig/libvirt-gconfig-domain-timer-pit.c | 5 ++++-
libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.c | 5 ++++-
13 files changed, 46 insertions(+), 19 deletions(-)
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-address-pci.c b/libvirt-gconfig/libvirt-gconfig-domain-address-pci.c
index 48e3872..9ad7765 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-address-pci.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-address-pci.c
@@ -67,7 +67,10 @@ GVirConfigDomainAddressPci *gvir_config_domain_address_pci_new_from_xml(const gc
object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_ADDRESS_PCI,
"address", NULL, xml, error);
- gvir_config_object_set_attribute(object, "type", "pci", NULL);
+ if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "pci") != 0) {
+ g_object_unref(G_OBJECT(object));
+ g_return_val_if_reached(NULL);
+ }
return GVIR_CONFIG_DOMAIN_ADDRESS_PCI(object);
}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-address-usb.c b/libvirt-gconfig/libvirt-gconfig-domain-address-usb.c
index 3da5811..cb7a986 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-address-usb.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-address-usb.c
@@ -67,7 +67,10 @@ GVirConfigDomainAddressUsb *gvir_config_domain_address_usb_new_from_xml(const gc
object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_ADDRESS_USB,
"address", NULL, xml, error);
- gvir_config_object_set_attribute(object, "type", "usb", NULL);
+ if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "usb") != 0) {
+ g_object_unref(G_OBJECT(object));
+ g_return_val_if_reached(NULL);
+ }
return GVIR_CONFIG_DOMAIN_ADDRESS_USB(object);
}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-chardev-source-pty.c b/libvirt-gconfig/libvirt-gconfig-domain-chardev-source-pty.c
index 201e123..8b14330 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-chardev-source-pty.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-chardev-source-pty.c
@@ -75,7 +75,10 @@ GVirConfigDomainChardevSourcePty *gvir_config_domain_chardev_source_pty_new_from
*/
object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_CHARDEV_SOURCE_PTY,
"dummy", NULL, xml, error);
- gvir_config_object_set_attribute(object, "type", "pty", NULL);
+ if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "pty") != 0) {
+ g_object_unref(G_OBJECT(object));
+ g_return_val_if_reached(NULL);
+ }
return GVIR_CONFIG_DOMAIN_CHARDEV_SOURCE_PTY(object);
}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-chardev-source-spicevmc.c b/libvirt-gconfig/libvirt-gconfig-domain-chardev-source-spicevmc.c
index 22eabf5..10c0ab8 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-chardev-source-spicevmc.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-chardev-source-spicevmc.c
@@ -75,6 +75,9 @@ GVirConfigDomainChardevSourceSpiceVmc *gvir_config_domain_chardev_source_spicevm
*/
object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_CHARDEV_SOURCE_SPICE_VMC,
"dummy", NULL, xml, error);
- gvir_config_object_set_attribute(object, "type", "spicevmc", NULL);
+ if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "spicevmc") != 0) {
+ g_object_unref(G_OBJECT(object));
+ g_return_val_if_reached(NULL);
+ }
return GVIR_CONFIG_DOMAIN_CHARDEV_SOURCE_SPICE_VMC(object);
}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-controller-usb.c b/libvirt-gconfig/libvirt-gconfig-domain-controller-usb.c
index 1fd248c..d7d7f65 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-controller-usb.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-controller-usb.c
@@ -167,7 +167,10 @@ GVirConfigDomainControllerUsb *gvir_config_domain_controller_usb_new_from_xml(co
object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_CONTROLLER_USB,
"controller", NULL, xml, error);
- gvir_config_object_set_attribute(object, "type", "usb", NULL);
+ if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "usb") != 0) {
+ g_object_unref(G_OBJECT(object));
+ g_return_val_if_reached(NULL);
+ }
return GVIR_CONFIG_DOMAIN_CONTROLLER_USB(object);
}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-graphics-sdl.c b/libvirt-gconfig/libvirt-gconfig-domain-graphics-sdl.c
index 7871ae5..8b22ad0 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-graphics-sdl.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-graphics-sdl.c
@@ -68,9 +68,10 @@ gvir_config_domain_graphics_sdl_new_from_xml(const gchar *xml,
object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_GRAPHICS_SDL,
"graphics", NULL, xml, error);
- if (object == NULL)
+ if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "sdl") != 0) {
+ g_object_unref(G_OBJECT(object));
return NULL;
- gvir_config_object_set_attribute(object, "type", "sdl", NULL);
+ }
return GVIR_CONFIG_DOMAIN_GRAPHICS_SDL(object);
}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-graphics-spice.c b/libvirt-gconfig/libvirt-gconfig-domain-graphics-spice.c
index e60a778..61d3f5b 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-graphics-spice.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-graphics-spice.c
@@ -68,9 +68,10 @@ gvir_config_domain_graphics_spice_new_from_xml(const gchar *xml,
object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_GRAPHICS_SPICE,
"graphics", NULL, xml, error);
- if (object == NULL)
+ if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "spice") != 0) {
+ g_object_unref(G_OBJECT(object));
return NULL;
- gvir_config_object_set_attribute(object, "type", "spice", NULL);
+ }
return GVIR_CONFIG_DOMAIN_GRAPHICS_SPICE(object);
}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-graphics-vnc.c b/libvirt-gconfig/libvirt-gconfig-domain-graphics-vnc.c
index d9d1303..f2fc9d5 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-graphics-vnc.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-graphics-vnc.c
@@ -68,9 +68,10 @@ gvir_config_domain_graphics_vnc_new_from_xml(const gchar *xml,
object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_GRAPHICS_VNC,
"graphics", NULL, xml, error);
- if (object == NULL)
+ if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "vnc") != 0) {
+ g_object_unref(G_OBJECT(object));
return NULL;
- gvir_config_object_set_attribute(object, "type", "vnc", NULL);
+ }
return GVIR_CONFIG_DOMAIN_GRAPHICS_VNC(object);
}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-interface-bridge.c b/libvirt-gconfig/libvirt-gconfig-domain-interface-bridge.c
index ea5eafa..09a7efc 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-interface-bridge.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-interface-bridge.c
@@ -70,9 +70,10 @@ GVirConfigDomainInterfaceBridge *gvir_config_domain_interface_bridge_new_from_xm
object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_INTERFACE_BRIDGE,
"interface", NULL, xml, error);
- if (object == NULL)
+ if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "bridge") != 0) {
+ g_object_unref(G_OBJECT(object));
return NULL;
- gvir_config_object_set_attribute(object, "type", "bridge", NULL);
+ }
return GVIR_CONFIG_DOMAIN_INTERFACE_BRIDGE(object);
}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-interface-network.c b/libvirt-gconfig/libvirt-gconfig-domain-interface-network.c
index 1a7bfad..ce39234 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-interface-network.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-interface-network.c
@@ -69,9 +69,10 @@ GVirConfigDomainInterfaceNetwork *gvir_config_domain_interface_network_new_from_
object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_INTERFACE_NETWORK,
"interface", NULL, xml, error);
- if (object == NULL)
+ if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "network") != 0) {
+ g_object_unref(G_OBJECT(object));
return NULL;
- gvir_config_object_set_attribute(object, "type", "network", NULL);
+ }
return GVIR_CONFIG_DOMAIN_INTERFACE_NETWORK(object);
}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-interface-user.c b/libvirt-gconfig/libvirt-gconfig-domain-interface-user.c
index a455a73..4ede31f 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-interface-user.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-interface-user.c
@@ -69,8 +69,9 @@ GVirConfigDomainInterfaceUser *gvir_config_domain_interface_user_new_from_xml(co
object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_INTERFACE_USER,
"interface", NULL, xml, error);
- if (object == NULL)
+ if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "user") != 0) {
+ g_object_unref(G_OBJECT(object));
return NULL;
- gvir_config_object_set_attribute(object, "type", "user", NULL);
+ }
return GVIR_CONFIG_DOMAIN_INTERFACE_USER(object);
}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-timer-pit.c b/libvirt-gconfig/libvirt-gconfig-domain-timer-pit.c
index d75cd30..d5e57f1 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-timer-pit.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-timer-pit.c
@@ -67,6 +67,9 @@ GVirConfigDomainTimerPit *gvir_config_domain_timer_pit_new_from_xml(const gchar
object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_TIMER_PIT,
"timer", NULL, xml, error);
- gvir_config_object_set_attribute(object, "name", "pit", NULL);
+ if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "pit") != 0) {
+ g_object_unref(G_OBJECT(object));
+ g_return_val_if_reached(NULL);
+ }
return GVIR_CONFIG_DOMAIN_TIMER_PIT(object);
}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.c b/libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.c
index b99c1e3..64b7f80 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.c
@@ -67,6 +67,9 @@ GVirConfigDomainTimerRtc *gvir_config_domain_timer_rtc_new_from_xml(const gchar
object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_TIMER_RTC,
"timer", NULL, xml, error);
- gvir_config_object_set_attribute(object, "name", "rtc", NULL);
+ if (g_strcmp0(gvir_config_object_get_attribute(object, NULL, "type"), "rtc") != 0) {
+ g_object_unref(G_OBJECT(object));
+ g_return_val_if_reached(NULL);
+ }
return GVIR_CONFIG_DOMAIN_TIMER_RTC(object);
}
--
1.7.10.4
12 years, 2 months
[libvirt] [PATCH] Remove pointless virLXCProcessMonitorDestroy method
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Asynchronously setting priv->mon to NULL was pointless,
just remove the destroy callback entirely.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/lxc/lxc_process.c | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 15572cd..b9cff85 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -554,20 +554,6 @@ cleanup:
}
-static void virLXCProcessMonitorDestroy(virLXCMonitorPtr mon,
- virDomainObjPtr vm)
-{
- virLXCDomainObjPrivatePtr priv;
-
- virDomainObjLock(vm);
- priv = vm->privateData;
- if (priv->monitor == mon)
- priv->monitor = NULL;
- if (virObjectUnref(vm))
- virDomainObjUnlock(vm);
-}
-
-
extern virLXCDriverPtr lxc_driver;
static void virLXCProcessMonitorEOFNotify(virLXCMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
@@ -649,7 +635,6 @@ static void virLXCProcessMonitorExitNotify(virLXCMonitorPtr mon ATTRIBUTE_UNUSED
static virLXCMonitorCallbacks monitorCallbacks = {
.eofNotify = virLXCProcessMonitorEOFNotify,
- .destroy = virLXCProcessMonitorDestroy,
.exitNotify = virLXCProcessMonitorExitNotify,
};
--
1.7.11.2
12 years, 2 months
[libvirt] [PATCH] Convert virLXCMonitor to use virObject
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Remove custom reference counting from virLXCMonitor, using
virObject instead
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/lxc/lxc_monitor.c | 63 +++++++++++++++++++++------------------------------
src/lxc/lxc_monitor.h | 4 +---
src/lxc/lxc_process.c | 11 +++------
3 files changed, 30 insertions(+), 48 deletions(-)
diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c
index dacaab4..772c613 100644
--- a/src/lxc/lxc_monitor.c
+++ b/src/lxc/lxc_monitor.c
@@ -35,9 +35,9 @@
#define VIR_FROM_THIS VIR_FROM_LXC
struct _virLXCMonitor {
- int refs;
+ virObject parent;
- virMutex lock; /* also used to protect refs */
+ virMutex lock;
virDomainObjPtr vm;
virLXCMonitorCallbacksPtr cb;
@@ -46,7 +46,21 @@ struct _virLXCMonitor {
virNetClientProgramPtr program;
};
-static void virLXCMonitorFree(virLXCMonitorPtr mon);
+static virClassPtr virLXCMonitorClass;
+static void virLXCMonitorDispose(void *obj);
+
+static int virLXCMonitorOnceInit(void)
+{
+ if (!(virLXCMonitorClass = virClassNew("virLXCMonitor",
+ sizeof(virLXCMonitor),
+ virLXCMonitorDispose)))
+ return -1;
+
+ return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virLXCMonitor)
+
static void
virLXCMonitorHandleEventExit(virNetClientProgramPtr prog,
virNetClientPtr client,
@@ -95,9 +109,7 @@ static void virLXCMonitorEOFNotify(virNetClientPtr client ATTRIBUTE_UNUSED,
static void virLXCMonitorCloseFreeCallback(void *opaque)
{
virLXCMonitorPtr mon = opaque;
- virLXCMonitorLock(mon);
- if (virLXCMonitorUnref(mon) > 0)
- virLXCMonitorUnlock(mon);
+ virObjectUnref(mon);;
}
@@ -108,12 +120,11 @@ virLXCMonitorPtr virLXCMonitorNew(virDomainObjPtr vm,
virLXCMonitorPtr mon;
char *sockpath = NULL;
- if (VIR_ALLOC(mon) < 0) {
- virReportOOMError();
+ if (virLXCMonitorInitialize() < 0)
return NULL;
- }
- mon->refs = 1;
+ if (!(mon = virObjectNew(virLXCMonitorClass)))
+ return NULL;
if (virMutexInit(&mon->lock) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -146,7 +157,7 @@ virLXCMonitorPtr virLXCMonitorNew(virDomainObjPtr vm,
mon->vm = vm;
mon->cb = cb;
- virLXCMonitorRef(mon);
+ virObjectRef(mon);
virNetClientSetCloseCallback(mon->client, virLXCMonitorEOFNotify, mon,
virLXCMonitorCloseFreeCallback);
@@ -157,43 +168,21 @@ cleanup:
no_memory:
virReportOOMError();
error:
- virLXCMonitorFree(mon);
+ virObjectUnref(mon);
mon = NULL;
goto cleanup;
}
-static void virLXCMonitorFree(virLXCMonitorPtr mon)
+static void virLXCMonitorDispose(void *opaque)
{
- VIR_DEBUG("mon=%p", mon);
- if (mon->client)
- virLXCMonitorClose(mon);
+ virLXCMonitorPtr mon = opaque;
+ VIR_DEBUG("mon=%p", mon);
if (mon->cb && mon->cb->destroy)
(mon->cb->destroy)(mon, mon->vm);
virMutexDestroy(&mon->lock);
virObjectUnref(mon->program);
- VIR_FREE(mon);
-}
-
-
-int virLXCMonitorRef(virLXCMonitorPtr mon)
-{
- mon->refs++;
- return mon->refs;
-}
-
-int virLXCMonitorUnref(virLXCMonitorPtr mon)
-{
- mon->refs--;
-
- if (mon->refs == 0) {
- virLXCMonitorUnlock(mon);
- virLXCMonitorFree(mon);
- return 0;
- }
-
- return mon->refs;
}
diff --git a/src/lxc/lxc_monitor.h b/src/lxc/lxc_monitor.h
index 806a6c6..bb8349a 100644
--- a/src/lxc/lxc_monitor.h
+++ b/src/lxc/lxc_monitor.h
@@ -21,6 +21,7 @@
#ifndef __LXC_MONITOR_H__
# define __LXC_MONITOR_H__
+# include "virobject.h"
# include "domain_conf.h"
# include "lxc_protocol.h"
@@ -54,7 +55,4 @@ void virLXCMonitorClose(virLXCMonitorPtr mon);
void virLXCMonitorLock(virLXCMonitorPtr mon);
void virLXCMonitorUnlock(virLXCMonitorPtr mon);
-int virLXCMonitorRef(virLXCMonitorPtr mon);
-int virLXCMonitorUnref(virLXCMonitorPtr mon);
-
#endif /* __LXC_MONITOR_H__ */
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 84128d1..15572cd 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -238,9 +238,7 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver,
if (priv->monitor) {
virLXCMonitorClose(priv->monitor);
- virLXCMonitorLock(priv->monitor);
- if (virLXCMonitorUnref(priv->monitor) > 0)
- virLXCMonitorUnlock(priv->monitor);
+ virObjectUnref(priv->monitor);
priv->monitor = NULL;
}
@@ -675,8 +673,7 @@ static virLXCMonitorPtr virLXCProcessConnectMonitor(virLXCDriverPtr driver,
if (virSecurityManagerClearSocketLabel(driver->securityManager, vm->def) < 0) {
if (monitor) {
- virLXCMonitorLock(monitor);
- virLXCMonitorUnref(monitor);
+ virObjectUnref(monitor);
monitor = NULL;
}
goto cleanup;
@@ -1198,9 +1195,7 @@ cleanup:
}
if (rc != 0) {
if (priv->monitor) {
- virLXCMonitorLock(priv->monitor);
- if (virLXCMonitorUnref(priv->monitor) > 0)
- virLXCMonitorUnlock(priv->monitor);
+ virObjectUnref(priv->monitor);
priv->monitor = NULL;
}
virDomainConfVMNWFilterTeardown(vm);
--
1.7.11.2
12 years, 2 months
[libvirt] [PATCH] Fix start of containers with custom root filesystem
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
A prefix change to unmount the SELinux filesystem broke starting
of LXC containers with a custom root filesystem
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/lxc/lxc_container.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index a749d24..4bb2aff 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -1191,6 +1191,8 @@ static int lxcContainerGetSubtree(const char *prefix,
char **mounts = NULL;
size_t nmounts = 0;
+ VIR_DEBUG("prefix=%s", prefix);
+
*mountsret = NULL;
*nmountsret = 0;
@@ -1528,7 +1530,8 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
/* Some versions of Linux kernel don't let you overmount
* the selinux filesystem, so make sure we kill it first
*/
- if (lxcContainerUnmountSubtree(SELINUX_MOUNT, false) < 0)
+ if (STREQ(root->src, "/") &&
+ lxcContainerUnmountSubtree(SELINUX_MOUNT, false) < 0)
goto cleanup;
#endif
--
1.7.11.2
12 years, 2 months
[libvirt] [PATCH 00/23 v2] Add support for detecting QEMU capabilities via QMP
by Daniel P. Berrange
This is a followup to
https://www.redhat.com/archives/libvir-list/2012-September/msg00643.html
As of QEMU 1.2 libvirt is supposed to stop parsing -help and instead
use various QMP commands to detect capabilities. Before we can do this,
the current QEMU capabilities code needs a serious cleanup and some
refactoring. The first half of this series does that major preparation
work, and the rest adds the new monitor commands and finally uses
them to detect capabilities.
Currently we consider "capabilities" to just refer to flags we detect
from -help. This series expands to cover all the things we detect
from QEMU, specifically including machine types, CPU definitions
and architecture. It introduces a single object to track all this
data and a centralized caching mechanism so we never re-query data
we already have somewhere.
b/src/conf/capabilities.h | 1
b/src/qemu/qemu_capabilities.c | 1813 ++++++----
b/src/qemu/qemu_capabilities.h | 47
b/src/qemu/qemu_command.c | 113
b/src/qemu/qemu_command.h | 6
b/src/qemu/qemu_conf.h | 2
b/src/qemu/qemu_driver.c | 211 -
b/src/qemu/qemu_monitor.c | 197 +
b/src/qemu/qemu_monitor.h | 42
b/src/qemu/qemu_monitor_json.c | 707 +++
b/src/qemu/qemu_monitor_json.h | 36
b/src/qemu/qemu_process.c | 26
b/tests/qemuhelptest.c | 2
b/tests/qemumonitorjsontest.c | 303 +
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-eoi-disabled.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-eoi-disabled.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-eoi-enabled.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-eoi-enabled.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact1.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact1.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact2-nofallback.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact2-nofallback.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact2.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-exact2.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-fallback.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-fallback.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-kvmclock.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-kvmclock.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-fallback.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-fallback.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model-nofallback.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-model.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-passthrough.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-host-passthrough.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-kvmclock.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-kvmclock.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-minimum1.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-minimum1.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-minimum2.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-minimum2.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-nofallback.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa1.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa1.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa2.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-numa2.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-qemu-host-passthrough.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-strict1.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-strict1.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-topology1.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-topology1.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-topology2.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-topology2.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-topology3.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-cpu-topology3.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-eoi-disabled.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-eoi-disabled.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-eoi-enabled.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-eoi-enabled.xml | 2
b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.args | 2
b/tests/qemuxml2argvdata/qemuxml2argv-graphics-spice-timeout.xml | 2
b/tests/qemuxml2argvtest.c | 66
b/tests/qemuxml2xmloutdata/qemuxml2xmlout-graphics-spice-timeout.xml | 2
b/tests/qemuxmlnstest.c | 7
tests/qemuxml2argvdata/qemu-lib.sh | 50
tests/qemuxml2argvdata/qemu-supported-cpus.sh | 15
tests/qemuxml2argvdata/qemu.sh | 15
67 files changed, 2499 insertions(+), 1256 deletions(-)
12 years, 2 months
[libvirt] [PATCH] Update how to compile with -Werror
by Doug Goldstein
--enable-compile-warnings=error has been renamed to --enable-werror so
update the HACKING and the hacking.html to reflect that.
---
docs/hacking.html.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/docs/hacking.html.in b/docs/hacking.html.in
index a97dc22..c3f859c 100644
--- a/docs/hacking.html.in
+++ b/docs/hacking.html.in
@@ -76,7 +76,7 @@
<li><p>Run the automated tests on your code before submitting any changes.
In particular, configure with compile warnings set to -Werror:</p>
<pre>
- ./configure --enable-compile-warnings=error
+ ./configure --enable-werror
</pre>
<p>
and run the tests:
--
1.7.8.6
12 years, 2 months