[libvirt] libvirt and redis
by B Gordon
Is there interest in teaching libvirt to store configs in a DB? I'd
like to talk out what's desirable in the scope and design with someone
who knows libvirt.
My eventual goal is to synchronize config between multiple libvirtds
using Redis. I've been playing with a prototype that abstracts config
writing and reading into handlers that can be selected at run time or
from libvirtd.conf. This was to get me some familiarity--please tell
me what aspects I should change to suit the rest of libvirt.
The high-level, emphasizing the more questionable aspects:
* "conf drivers" that cargo-cult the jargon used in "drivers" a bit
even though they (currently) aren't quite a fit with the way current
ones are used.
* One global conf driver, because it needs to be accessed in other
state drivers when a connection is not currently present in the API.
* conf drivers present a file system-like key/value API to the rest of
libvirt to minimize disruption. They receive an XML string to store
and must be able to list the keys in a given "directory". Retrieval
is done by passing an optional callback to xml.c that it will use
instead of xmlCtxtReadFile().
* Keys should probably not include the full sysconfdir path, and
many other ways the prototype is too FS-like.
* With a relational DB, API calls to store each type of libvirt struct
might make more sense than formatted XML strings. I have not tried to
do this and vaguely hope that working with XML in a relational DB
would be acceptable or that those calls could be added later. Using
the DB's native XML handling might better for abstraction, actually.
* The conf driver needs a way to receive parameters from
libvirtd.conf. URI parsing? Some other key-value format?
As a low-level example, here's my (current, expected to change based
on feedback!) conversion of domain_conf.c:
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b6aaf33..0c7bb3c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -47,6 +47,7 @@
#include "storage_file.h"
#include "files.h"
#include "bitmap.h"
+#include "conf_driver.h"
#define VIR_FROM_THIS VIR_FROM_DOMAIN
@@ -6158,7 +6159,7 @@ virDomainDefParse(const char *xmlStr,
xmlDocPtr xml;
virDomainDefPtr def = NULL;
- if ((xml = virXMLParse(filename, xmlStr, "domain.xml"))) {
+ if ((xml = virConfParse(filename, xmlStr, "domain.xml"))) {
def = virDomainDefParseNode(caps, xml,
xmlDocGetRootElement(xml), flags);
xmlFreeDoc(xml);
}
@@ -6245,7 +6246,7 @@ virDomainObjPtr virDomainObjParseFile(virCapsPtr
caps,
xmlDocPtr xml;
virDomainObjPtr obj = NULL;
- if ((xml = virXMLParseFile(filename))) {
+ if ((xml = virConfParse(filename, NULL, filename))) {
obj = virDomainObjParseNode(caps, xml,
xmlDocGetRootElement(xml));
xmlFreeDoc(xml);
}
@@ -8324,46 +8325,26 @@ int virDomainSaveXML(const char *configDir,
const char *xml)
{
char *configFile = NULL;
- int fd = -1, ret = -1;
- size_t towrite;
+ int ret = -1;
+ int err;
if ((configFile = virDomainConfigFile(configDir, def->name)) ==
NULL)
goto cleanup;
- if (virFileMakePath(configDir)) {
- virReportSystemError(errno,
+ if ((err = virConfMakePath(configDir, 0))) {
+ virReportSystemError(err,
_("cannot create config directory '%s'"),
configDir);
goto cleanup;
}
- if ((fd = open(configFile,
- O_WRONLY | O_CREAT | O_TRUNC,
- S_IRUSR | S_IWUSR )) < 0) {
- virReportSystemError(errno,
- _("cannot create config file '%s'"),
- configFile);
- goto cleanup;
- }
-
- towrite = strlen(xml);
- if (safewrite(fd, xml, towrite) < 0) {
- virReportSystemError(errno,
- _("cannot write config file '%s'"),
- configFile);
- goto cleanup;
- }
-
- if (VIR_CLOSE(fd) < 0) {
- virReportSystemError(errno,
- _("cannot save config file '%s'"),
- configFile);
+ if (virConfSave(configFile, xml, 0) < 0) {
goto cleanup;
}
ret = 0;
+
cleanup:
- VIR_FORCE_CLOSE(fd);
VIR_FREE(configFile);
return ret;
@@ -8441,7 +8422,7 @@ static virDomainObjPtr
virDomainLoadConfig(virCapsPtr caps,
if ((autostartLink = virDomainConfigFile(autostartDir, name)) ==
NULL)
goto error;
- if ((autostart = virFileLinkPointsTo(autostartLink, configFile)) <
0)
+ if ((autostart = virConfLinkPointsTo(autostartLink, configFile, 0))
< 0)
goto error;
if (!(dom = virDomainAssignDef(caps, doms, def, false)))
@@ -8514,12 +8495,12 @@ int virDomainLoadAllConfigs(virCapsPtr caps,
virDomainLoadConfigNotify notify,
void *opaque)
{
- DIR *dir;
- struct dirent *entry;
+ virConfDirPtr dir;
+ virConfDirEntryPtr entry;
VIR_INFO("Scanning for configs in %s", configDir);
- if (!(dir = opendir(configDir))) {
+ if (!(dir = virConfOpenDir(configDir, 0))) {
if (errno == ENOENT)
return 0;
virReportSystemError(errno,
@@ -8528,23 +8509,17 @@ int virDomainLoadAllConfigs(virCapsPtr caps,
return -1;
}
- while ((entry = readdir(dir))) {
+ while ((entry = virConfReadDir(dir, 0))) {
virDomainObjPtr dom;
- if (entry->d_name[0] == '.')
- continue;
-
- if (!virFileStripSuffix(entry->d_name, ".xml"))
- continue;
-
/* NB: ignoring errors, so one malformed config doesn't
kill the whole process */
- VIR_INFO("Loading config file '%s.xml'", entry->d_name);
+ VIR_INFO("Loading config file '%s.xml'", entry->name);
if (liveStatus)
dom = virDomainLoadStatus(caps,
doms,
configDir,
- entry->d_name,
+ entry->name,
notify,
opaque);
else
@@ -8552,7 +8527,7 @@ int virDomainLoadAllConfigs(virCapsPtr caps,
doms,
configDir,
autostartDir,
- entry->d_name,
+ entry->name,
notify,
opaque);
if (dom) {
@@ -8562,7 +8537,7 @@ int virDomainLoadAllConfigs(virCapsPtr caps,
}
}
- closedir(dir);
+ virConfCloseDir(dir, 0);
return 0;
}
@@ -8580,9 +8555,9 @@ int virDomainDeleteConfig(const char *configDir,
goto cleanup;
/* Not fatal if this doesn't work */
- unlink(autostartLink);
+ virConfDeletePath(autostartLink, 0);
- if (unlink(configFile) < 0 &&
+ if (virConfDeletePath(autostartLink, 0) < 0 &&
errno != ENOENT) {
virReportSystemError(errno,
_("cannot remove config %s"),
@@ -8863,7 +8838,7 @@ virDomainSnapshotDefPtr
virDomainSnapshotDefParseString(const char *xmlStr,
char *creation = NULL, *state = NULL;
struct timeval tv;
- xml = virXMLParse(NULL, xmlStr, "domainsnapshot.xml");
+ xml = virXMLParseString(xmlStr, "domainsnapshot.xml");
if (!xml) {
virDomainReportError(VIR_ERR_XML_ERROR,
"%s",_("failed to parse snapshot xml
document"));
--
http://www.fastmail.fm - Choose from over 50 domains or use your own
13 years, 11 months
[libvirt] [PATCH] qemu: Add flags checking in DomainCoreDump
by Jiri Denemark
---
src/qemu/qemu_driver.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f6e503a..f35616d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2345,7 +2345,8 @@ getCompressionType(struct qemud_driver *driver)
static int qemudDomainCoreDump(virDomainPtr dom,
const char *path,
- int flags ATTRIBUTE_UNUSED) {
+ int flags)
+{
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm;
int resume = 0, paused = 0;
@@ -2353,6 +2354,8 @@ static int qemudDomainCoreDump(virDomainPtr dom,
virDomainEventPtr event = NULL;
qemuDomainObjPrivatePtr priv;
+ virCheckFlags(VIR_DUMP_LIVE | VIR_DUMP_CRASH, -1);
+
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
--
1.7.5.rc1
13 years, 11 months
[libvirt] [PATCH] Make the options "--crash" and "--live" of "virsh dump" mutually exclusive
by Mark Wu
This patch makes the options "--crash" and "--live" of "virsh dump" mutually exclusive
diff --git a/tools/virsh.c b/tools/virsh.c
index 2e35021..ef77d7f 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1869,14 +1869,19 @@ cmdDump(vshControl *ctl, const vshCmd *cmd)
flags |= VIR_DUMP_LIVE;
if (vshCommandOptBool (cmd, "crash"))
flags |= VIR_DUMP_CRASH;
-
+ if ((flags& VIR_DUMP_CRASH)&& (flags& VIR_DUMP_CRASH)) {
+ vshError(ctl, "%s", _("--crash and --live are mutually exclusive. "
+ "Please choose only one."));
+ ret = FALSE;
+ goto cleanup;
+ }
if (virDomainCoreDump(dom, to, flags) == 0) {
vshPrint(ctl, _("Domain %s dumped to %s\n"), name, to);
} else {
vshError(ctl, _("Failed to core dump domain %s to %s"), name, to);
ret = FALSE;
}
-
+cleanup:
virDomainFree(dom);
return ret;
}
13 years, 11 months
[libvirt] libvirt spice command line appears to be incorrect (was: Re: [virt-tools-list] vdagent does not start with domain defined by virt-manager 0.8.7)
by Richard W.M. Jones
[Copying this to libvir-list]
On Mon, Apr 25, 2011 at 01:07:37AM +0400, Emre Erenoglu wrote:
> Hi,
>
> I'm the package maintainer for virt-manager and related packages for Pardus
> distribution. While testing the latest libvirt, virtinst & virt-manager
> packages, I've come across a strange issue and I would like to get your
> valuable opinion.
>
> I add all spice related devices and everything works good, except the
> vdagent inside the windows xp guest. The virtio serial driver is loaded
> correctly. As I track down the issue, I found out that libvirt is starting
> qemu-kvm with parameters which do not match the ones adviced by the spice
> people. Please see below email discussion with them on this. The offending
> line seems to be the chardev parameter. qemu-kvm is started by virt-manager
> with the following parameter for chardev:
>
> -chardev null,id=channel0
>
> and the full spice related parameters are:
>
> -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x8 -chardev
> null,id=channel0 -device
> virtserialport,bus=virtio-serial0.0,nr=0,chardev=channel0,name=com.redhat.spice.0
> -usb -device usb-tablet,id=input0 -spice
> port=5900,addr=127.0.0.1,disable-ticketing -vga qxl -device
> qxl,id=video1,bus=pci.0,addr=0x7
>
> while spice people adviced:
>
> -chardev spicevmc,id=channel0,name=vdagent
>
> and the rest of the parameters to match it. See below mail on the details.
> I don't know if this is really the issue, but I also recognize the following
> inside the domain XML:
>
> <channel type='null'>
> <target type='virtio' name='com.redhat.spice.0'/>
> <address type='virtio-serial' controller='0' bus='0' port='0'/>
> </channel>
>
> the "channel type" is listed as "null", while I assume it should have been
> listed as "spicevmc". (not sure of this, I saw this in some other
> websites). When I edit the domain xml with virsh edit, it saves my changes
> but the "null" stays the same how many times I try to change it.
>
> Please note that I've applied the following patches to virtinst 0.500.6:
>
> constrain-spicevmc-usage-correct.patch
> virtinst-fix-channel-parse.patch
> virtinst-spicevmc-fixes.patch
>
> which I obtained from the git. I also patched virt-manager 0.8.7 with the
> following I obtained from the git:
>
> chardev-hide-unsupported-params-for-selected-type.patch
> only-show-relevant-char-device-fields.patch
> show-char-device-target-name.patch
> chardev-propose-to-add-remove-spice-agent.patch
> allow-setting-char-device-target-name.patch
> fix-adding-removing-channel-device.patch
>
> Any idea what I might be missing to get the vdagent run inside the windows
> guest?
>
> Many thanks,
>
> Emre Erenoglu
>
> ---------- Forwarded message ----------
> From: Marian Krcmarik <mkrcmari(a)redhat.com>
> Date: Mon, Apr 18, 2011 at 5:56 PM
> Subject: Re: [Spice-devel] vdagent does not start
> To: Emre Erenoglu <erenoglu(a)gmail.com>
> Cc: spice-devel(a)lists.freedesktop.org
>
>
>
>
> ----- Original Message -----
> > From: "Emre Erenoglu" <erenoglu(a)gmail.com>
> > To: spice-devel(a)lists.freedesktop.org
> > Sent: Sunday, April 17, 2011 1:10:16 PM
> > Subject: [Spice-devel] vdagent does not start
> > Dear Developers,
> >
> > I have a virtual XP system with the spice channel enabled through the
> > serial port. The command line that runs qemu has (reduced):
> >
> > -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x8
> > -chardev null,id=channel0 -device
> >
> virtserialport,bus=virtio-serial0.0,nr=0,chardev=channel0,name=com.redhat.spice.0
> > -usb -device usb-tablet,id=input0 -spice
> > port=5900,addr=127.0.0.1,disable-ticketing -vga qxl -device
> > qxl,id=video1,bus=pci.0,addr=0x7
>
> I think you may need to specify chardev for spice so I would modify:
>
> -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x8 -chardev
> spicevmc,id=channel0,name=vdagent -device
> virtserialport,bus=virtio-serial0.0,nr=0,chardev=channel0,name=com.redhat.spice.0
> -usb -device usb-tablet,id=input0 -spice
> port=5900,addr=127.0.0.1,disable-ticketing -vga qxl -device
> qxl,id=video1,bus=pci.0,addr=0x7
>
> with agent and virtio-serial driver installed on guest.
> >
> > However, the vdagent services does not start. when I give it a start
> > control, it reports to start then stop immediately. Here are the logs
> > I've found:
>
>
>
> --
> Emre
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming blog: http://rwmj.wordpress.com
Fedora now supports 80 OCaml packages (the OPEN alternative to F#)
http://cocan.org/getting_started_with_ocaml_on_red_hat_and_fedora
13 years, 11 months
[libvirt] [PATCH] Make sure DNSMASQ_STATE_DIR exists
by Guido Günther
Hi,
otherwise the directory returned by networkDnsmasqLeaseFileName will not
be created if ipdef->nhosts == 0 in networkBuildDnsmasqArgv.
O.k. to apply?
Cheers,
-- Guido
---
src/network/bridge_driver.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 8b5c1b6..ed78710 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -662,6 +662,13 @@ networkStartDhcpDaemon(virNetworkObjPtr network)
goto cleanup;
}
+ if ((err = virFileMakePath(DNSMASQ_STATE_DIR)) != 0) {
+ virReportSystemError(err,
+ _("cannot create directory %s"),
+ DNSMASQ_STATE_DIR);
+ goto cleanup;
+ }
+
cmd = virCommandNew(DNSMASQ);
if (networkBuildDnsmasqArgv(network, ipdef, pidfile, cmd) < 0) {
goto cleanup;
--
1.7.4.1
13 years, 11 months
[libvirt] [PATCH] Fix small memory leaks in config parsing related functions
by Matthias Bolte
Found by 'make -C tests valgrind'.
xen_xm.c: Dummy allocation via virDomainChrDefNew is directly
overwritten and lost. Free 'script' in success path too.
vmx.c: Free virtualDev_string in success path too.
domain_conf.c: Free compression in success path too.
---
src/conf/domain_conf.c | 1 +
src/vmx/vmx.c | 16 +++++++++-------
src/xenxs/xen_xm.c | 3 +--
3 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 381e692..0e7aeb5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4058,6 +4058,7 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) {
VIR_FREE(compression);
goto error;
}
+ VIR_FREE(compression);
def->data.spice.zlib = compressionVal;
} else if (xmlStrEqual(cur->name, BAD_CAST "playback")) {
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index daeedc3..aee2d80 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -1818,6 +1818,7 @@ int
virVMXParseSCSIController(virConfPtr conf, int controller, bool *present,
int *virtualDev)
{
+ int result = -1;
char present_name[32];
char virtualDev_name[32];
char *virtualDev_string = NULL;
@@ -1840,16 +1841,17 @@ virVMXParseSCSIController(virConfPtr conf, int controller, bool *present,
controller);
if (virVMXGetConfigBoolean(conf, present_name, present, false, true) < 0) {
- goto failure;
+ goto cleanup;
}
if (! *present) {
- return 0;
+ result = 0;
+ goto cleanup;
}
if (virVMXGetConfigString(conf, virtualDev_name, &virtualDev_string,
true) < 0) {
- goto failure;
+ goto cleanup;
}
if (virtualDev_string != NULL) {
@@ -1870,16 +1872,16 @@ virVMXParseSCSIController(virConfPtr conf, int controller, bool *present,
_("Expecting VMX entry '%s' to be 'buslogic' or 'lsilogic' "
"or 'lsisas1068' or 'pvscsi' but found '%s'"),
virtualDev_name, virtualDev_string);
- goto failure;
+ goto cleanup;
}
}
- return 0;
+ result = 0;
- failure:
+ cleanup:
VIR_FREE(virtualDev_string);
- return -1;
+ return result;
}
diff --git a/src/xenxs/xen_xm.c b/src/xenxs/xen_xm.c
index dbcaf15..63ba153 100644
--- a/src/xenxs/xen_xm.c
+++ b/src/xenxs/xen_xm.c
@@ -983,8 +983,6 @@ xenParseXM(virConfPtr conf, int xendConfigVersion,
continue;
}
- if (!(chr = virDomainChrDefNew()))
- goto cleanup;
if (!(chr = xenParseSxprChar(port, NULL)))
goto cleanup;
@@ -1034,6 +1032,7 @@ xenParseXM(virConfPtr conf, int xendConfigVersion,
goto cleanup;
}
+ VIR_FREE(script);
return def;
no_memory:
--
1.7.0.4
13 years, 11 months
[libvirt] [PATCH] Add virDomainEventRebootNew
by Matthias Bolte
This will be used in the ESX driver event handling.
---
src/conf/domain_event.c | 8 ++++++++
src/conf/domain_event.h | 1 +
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index f0380d3..688bf6c 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -572,11 +572,19 @@ virDomainEventPtr virDomainEventNewFromDef(virDomainDefPtr def, int type, int de
return virDomainEventNew(def->id, def->name, def->uuid, type, detail);
}
+virDomainEventPtr virDomainEventRebootNew(int id, const char *name,
+ const unsigned char *uuid)
+{
+ return virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_REBOOT,
+ id, name, uuid);
+}
+
virDomainEventPtr virDomainEventRebootNewFromDom(virDomainPtr dom)
{
return virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_REBOOT,
dom->id, dom->name, dom->uuid);
}
+
virDomainEventPtr virDomainEventRebootNewFromObj(virDomainObjPtr obj)
{
return virDomainEventNewInternal(VIR_DOMAIN_EVENT_ID_REBOOT,
diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h
index e28293d..c03a159 100644
--- a/src/conf/domain_event.h
+++ b/src/conf/domain_event.h
@@ -112,6 +112,7 @@ virDomainEventPtr virDomainEventNewFromDom(virDomainPtr dom, int type, int detai
virDomainEventPtr virDomainEventNewFromObj(virDomainObjPtr obj, int type, int detail);
virDomainEventPtr virDomainEventNewFromDef(virDomainDefPtr def, int type, int detail);
+virDomainEventPtr virDomainEventRebootNew(int id, const char *name, const unsigned char *uuid);
virDomainEventPtr virDomainEventRebootNewFromDom(virDomainPtr dom);
virDomainEventPtr virDomainEventRebootNewFromObj(virDomainObjPtr obj);
--
1.7.0.4
13 years, 11 months
[libvirt] [PATCH] threads: add one-time initialization support
by Eric Blake
mingw lacks the counterpart to PTHREAD_MUTEX_INITIALIZER, so the
best we can do is portably expose once-only runtime initialization.
* src/util/threads.h (virOnceControlPtr): New opaque type.
(virOnceFunc): New callback type.
(virOnce): New prototype.
* src/util/threads-pthread.h (virOnceControl): Declare.
(VIR_ONCE_CONTROL_INITIALIZER): Define.
* src/util/threads-win32.h (virOnceControl)
(VIR_ONCE_CONTROL_INITIALIZER): Likewise.
* src/util/threads-pthread.c (virOnce): Implement in pthreads.
* src/util/threads-win32.c (virOnce): Implement in WIN32.
* src/libvirt_private.syms: Export it.
---
src/libvirt_private.syms | 1 +
src/util/threads-pthread.c | 5 +++++
src/util/threads-pthread.h | 11 ++++++++++-
src/util/threads-win32.c | 15 ++++++++++++++-
src/util/threads-win32.h | 11 ++++++++++-
src/util/threads.h | 21 ++++++++++++++++++++-
6 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index ba7739d..cb67861 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -866,6 +866,7 @@ virMutexInit;
virMutexInitRecursive;
virMutexLock;
virMutexUnlock;
+virOnce;
virThreadCreate;
virThreadID;
virThreadIsSelf;
diff --git a/src/util/threads-pthread.c b/src/util/threads-pthread.c
index 898c4d4..82ce5c6 100644
--- a/src/util/threads-pthread.c
+++ b/src/util/threads-pthread.c
@@ -40,6 +40,11 @@ void virThreadOnExit(void)
{
}
+int virOnce(virOnceControlPtr once, virOnceFunc init)
+{
+ return pthread_once(&once->once, init);
+}
+
int virMutexInit(virMutexPtr m)
{
diff --git a/src/util/threads-pthread.h b/src/util/threads-pthread.h
index b25d0c2..dcaacb7 100644
--- a/src/util/threads-pthread.h
+++ b/src/util/threads-pthread.h
@@ -1,7 +1,7 @@
/*
* threads.c: basic thread synchronization primitives
*
- * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009, 2011 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
@@ -38,3 +38,12 @@ struct virThread {
struct virThreadLocal {
pthread_key_t key;
};
+
+struct virOnceControl {
+ pthread_once_t once;
+};
+
+#define VIR_ONCE_CONTROL_INITIALIZER \
+{ \
+ .once = PTHREAD_ONCE_INIT \
+}
diff --git a/src/util/threads-win32.c b/src/util/threads-win32.c
index 5661437..f717f98 100644
--- a/src/util/threads-win32.c
+++ b/src/util/threads-win32.c
@@ -1,7 +1,7 @@
/*
* threads-win32.c: basic thread synchronization primitives
*
- * Copyright (C) 2009-2010 Red Hat, Inc.
+ * Copyright (C) 2009-2011 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
@@ -69,6 +69,19 @@ void virThreadOnExit(void)
virMutexUnlock(&virThreadLocalLock);
}
+static BOOL CALLBACK
+virOnceCallback(PINIT_ONCE once, PVOID param, PVOID *context ATTRIBUTE_UNUSED)
+{
+ virOnceFunc func = param;
+ func();
+ return TRUE;
+}
+
+int virOnce(virOnceControlPtr once, virOnceFunc init)
+{
+ return InitOnceExecuteOnce(&once->once, virOnceCallback, init,
+ NULL) ? 0 : -1;
+}
int virMutexInit(virMutexPtr m)
{
diff --git a/src/util/threads-win32.h b/src/util/threads-win32.h
index bb7c455..f169460 100644
--- a/src/util/threads-win32.h
+++ b/src/util/threads-win32.h
@@ -1,7 +1,7 @@
/*
* threads-win32.h basic thread synchronization primitives
*
- * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009, 2011 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
@@ -41,3 +41,12 @@ struct virThread {
struct virThreadLocal {
DWORD key;
};
+
+struct virOnceControl {
+ INIT_ONCE once;
+};
+
+#define VIR_ONCE_CONTROL_INITIALIZER \
+{ \
+ .once = INIT_ONCE_STATIC_INIT \
+}
diff --git a/src/util/threads.h b/src/util/threads.h
index c129301..b72610c 100644
--- a/src/util/threads.h
+++ b/src/util/threads.h
@@ -1,7 +1,7 @@
/*
* threads.h: basic thread synchronization primitives
*
- * Copyright (C) 2009-2010 Red Hat, Inc.
+ * Copyright (C) 2009-2011 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
@@ -36,6 +36,10 @@ typedef virThreadLocal *virThreadLocalPtr;
typedef struct virThread virThread;
typedef virThread *virThreadPtr;
+typedef struct virOnceControl virOnceControl;
+typedef virOnceControl *virOnceControlPtr;
+
+typedef void (*virOnceFunc)(void);
int virThreadInitialize(void) ATTRIBUTE_RETURN_CHECK;
void virThreadOnExit(void);
@@ -57,6 +61,21 @@ void virThreadJoin(virThreadPtr thread);
int virThreadSelfID(void);
int virThreadID(virThreadPtr thread);
+/* Static initialization of mutexes is not possible, so we instead
+ * provide for guaranteed one-time initialization via a callback
+ * function. Usage:
+ * static virOnceControl once = VIR_ONCE_CONTROL_INITIALIZER;
+ * static void initializer(void) { ... }
+ * void myfunc()
+ * {
+ * if (virOnce(&once, initializer) < 0)
+ * goto error;
+ * ...now guaranteed that initializer has completed exactly once
+ * }
+ */
+int virOnce(virOnceControlPtr once, virOnceFunc init)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
+
int virMutexInit(virMutexPtr m) ATTRIBUTE_RETURN_CHECK;
int virMutexInitRecursive(virMutexPtr m) ATTRIBUTE_RETURN_CHECK;
void virMutexDestroy(virMutexPtr m);
--
1.7.1
13 years, 11 months
[libvirt] [PATCH] qemu: Unlink managed state file when a domain is undefined
by Osier Yang
The managed state file is not useful anymore after the domain is
undefined, and perhaps cause confusion. E.g. define & start a domain
which has same name with previous undefined domain later.
---
src/qemu/qemu_driver.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f6e503a..874b455 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3739,6 +3739,7 @@ static int qemudDomainUndefine(virDomainPtr dom) {
virDomainObjPtr vm;
virDomainEventPtr event = NULL;
int ret = -1;
+ char *managed_save = NULL;
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -3766,6 +3767,13 @@ static int qemudDomainUndefine(virDomainPtr dom) {
if (virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm) < 0)
goto cleanup;
+ if (!(managed_save = qemuDomainManagedSavePath(driver, vm)))
+ goto cleanup;
+
+ if (virFileExists(managed_save) && (unlink(managed_save) < 0)) {
+ VIR_WARN("Failed to remove the managed state %s", managed_save);
+ }
+
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_UNDEFINED,
VIR_DOMAIN_EVENT_UNDEFINED_REMOVED);
--
1.7.4
13 years, 11 months
[libvirt] [PATCH] build: fix 32-bit test failure
by Eric Blake
ARRAY_CARDINALITY is typed as size_t, not long; this matters on 32-bit
platforms:
hashtest.c: In function 'testHashRemoveForEach':
hashtest.c:114: error: format '%lu' expects type 'long unsigned int', but argument 4 has type 'unsigned int' [-Wformat]
* tests/hashtest.c (testHashRemoveForEach): Use correct format.
---
Pushing under the build-breaker rule.
tests/hashtest.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tests/hashtest.c b/tests/hashtest.c
index dff0181..722b44c 100644
--- a/tests/hashtest.c
+++ b/tests/hashtest.c
@@ -112,7 +112,7 @@ testHashRemoveForEach(const void *data)
if (count != ARRAY_CARDINALITY(uuids)) {
if (virTestGetVerbose()) {
testError("\nvirHashForEach didn't go through all entries,"
- " %d != %lu\n",
+ " %d != %zu\n",
count, ARRAY_CARDINALITY(uuids));
}
goto cleanup;
--
1.7.4.4
13 years, 11 months