[libvirt] [PATCH] [3/4] Implement managed save operations for qemu driver
Daniel Veillard
veillard at redhat.com
Fri Apr 2 21:19:03 UTC 2010
On Fri, Apr 02, 2010 at 02:26:10PM -0600, Eric Blake wrote:
> On 04/02/2010 01:56 PM, Daniel Veillard wrote:
> > +++ b/src/qemu/qemu_driver.c
> > @@ -1399,6 +1399,9 @@ qemudStartup(int privileged) {
> > if (virAsprintf(&qemu_driver->cacheDir,
> > "%s/cache/libvirt/qemu", LOCAL_STATE_DIR) == -1)
> > goto out_of_memory;
> > + if (virAsprintf(&qemu_driver->saveDir,
> > + "%s/lib/libvirt/qemu/save/", LOCAL_STATE_DIR) == -1)
> > + goto out_of_memory;
>
> Would it be more efficient to write a followup patch that does:
>
> if ((qemu_driver->savedir
> = strdup(LOCAL_STATE_DIR "/lib/libvirt/qemu/save/") == NULL)
> goto out_of_memory;
>
> on the grounds that compile-time concatenation and strdup are much
> lighter-weight than run-time concatenation of virAsprintf?
>
> But that doesn't affect the quality of your patch.
there is a block of 4 allocations that way, I think they should be
kept similar
> > } else {
> > uid_t uid = geteuid();
> > char *userdir = virGetUserDirectory(uid);
> > @@ -1423,6 +1426,8 @@ qemudStartup(int privileged) {
> > goto out_of_memory;
> > if (virAsprintf(&qemu_driver->cacheDir, "%s/qemu/cache", base) == -1)
> > goto out_of_memory;
> > + if (virAsprintf(&qemu_driver->saveDir, "%s/qemu/save", base) == -1)
> > + goto out_of_memory;
>
> And constructs like this still need virAsprintf.
same thing, kept code similar to previous blocks.
We could optimize, yes, but it's run once in libvirtd lifetime :-)
> > -static int qemudDomainSave(virDomainPtr dom,
> > - const char *path)
> > +static int qemudDomainSaveFlag(virDomainPtr dom, const char *path,
> > + int compressed)
>
> Should that be bool compressed, since we are only using it as a binary?
> Or are there plans to extend it in the future to allow choice between
> multiple acceptable compression algorithms, in which case it is better
> as an unsigned int?
we can have multiple compression options, so an int, yes
> > +static int qemudDomainSave(virDomainPtr dom, const char *path)
> > +{
> > + struct qemud_driver *driver = dom->conn->privateData;
> > + int compressed;
> > +
> > + /* Hm, is this safe against qemudReload? */
> > + if (driver->saveImageFormat == NULL)
> > + compressed = QEMUD_SAVE_FORMAT_RAW;
> > + else {
> > + compressed = qemudSaveCompressionTypeFromString(driver->saveImageFormat);
> > + if (compressed < 0) {
> > + qemuReportError(VIR_ERR_OPERATION_FAILED,
> > + "%s", _("Invalid save image format specified "
> > + "in configuration file"));
> > + return -1;
> > + }
> > + }
> > +
> > + return qemudDomainSaveFlag(dom, path, compressed);
>
> If you convert the type of the last argument of qemudDomanSaveFlag, then
> here is where you'd convert from int (qemudSaveCompressionTypeFromString
> must remain int, to detect failure) to bool.
>
> > +static int
> > +qemuDomainManagedSave(virDomainPtr dom,
> > + unsigned int flags ATTRIBUTE_UNUSED)
>
> No - for future compability, we NEED to check that flags==0 or fail now.
> Otherwise, a future version, where flags has meaning, will mistakenly
> think that our older version can honor those flags.
Hum, we used to not check undefined flags, we are changing that now,
it makes sense. But no capital/yelling please !
> > + /* FIXME: we should take the flags parameter, and use bits out
> > + * of there to control whether we are compressing or not
> > + */
> > + compressed = QEMUD_SAVE_FORMAT_RAW;
> > +
> > + /* we have to drop our locks here because qemudDomainSaveFlag is
> > + * going to pick them back up. Unfortunately it opens a race window
> > + * between us dropping and qemudDomainSaveFlag picking it back up, but
> > + * if we want to allow other operations to be able to happen while
> > + * qemuDomainSaveFlag is running (possibly for a long time), I'm not
> > + * sure if there is a better solution
> > + */
>
> Is there a way to tell qemudDomainSaveFlag that we called it while the
> lock was already held (that is, consume one of the bits of the flag
> argument that we pass to qemudDomainSaveFlag for internal use)? That
> way, we don't have to drop the lock here, but let qemudDomainSaveFlag
> drop it on our behalf.
Not in the current code as I understand it. This would need some
refactoring.
> > +static int
> > +qemuDomainHasManagedSaveImage(virDomainPtr dom,
> > + unsigned int flags ATTRIBUTE_UNUSED)
>
> Again, we MUST ensure flags==0 now, to allow future compatibility.
[...]
> > +static int
> > +qemuDomainManagedSaveRemove(virDomainPtr dom,
> > + unsigned int flags ATTRIBUTE_UNUSED)
>
> And again.
> > + managed_save = qemuDomainManagedSavePath(driver, vm);
> > + if ((managed_save) && (virFileExists(managed_save))) {
> > + /* We should still have a reference left to vm but */
>
> Incomplete comment?
not really, that could be "but ..." or "but one should check for 0
anyway"
I end up with the following additional patch,
thanks !
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
-------------- next part --------------
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5a678c9..d5ee16a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4871,8 +4871,7 @@ qemuDomainManagedSavePath(struct qemud_driver *driver, virDomainObjPtr vm) {
}
static int
-qemuDomainManagedSave(virDomainPtr dom,
- unsigned int flags ATTRIBUTE_UNUSED)
+qemuDomainManagedSave(virDomainPtr dom, unsigned int flags)
{
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm = NULL;
@@ -4880,6 +4879,13 @@ qemuDomainManagedSave(virDomainPtr dom,
int ret = -1;
int compressed;
+ if (flags != 0) {
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("unsupported flags (0x%x) passed to '%s'"),
+ flags, __FUNCTION__);
+ return -1;
+ }
+
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
@@ -4932,14 +4938,20 @@ error:
}
static int
-qemuDomainHasManagedSaveImage(virDomainPtr dom,
- unsigned int flags ATTRIBUTE_UNUSED)
+qemuDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags)
{
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm = NULL;
int ret = -1;
char *name = NULL;
+ if (flags != 0) {
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("unsupported flags (0x%x) passed to '%s'"),
+ flags, __FUNCTION__);
+ return -1;
+ }
+
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
@@ -4965,14 +4977,20 @@ cleanup:
}
static int
-qemuDomainManagedSaveRemove(virDomainPtr dom,
- unsigned int flags ATTRIBUTE_UNUSED)
+qemuDomainManagedSaveRemove(virDomainPtr dom, unsigned int flags)
{
struct qemud_driver *driver = dom->conn->privateData;
virDomainObjPtr vm = NULL;
int ret = -1;
char *name = NULL;
+ if (flags != 0) {
+ qemuReportError(VIR_ERR_INVALID_ARG,
+ _("unsupported flags (0x%x) passed to '%s'"),
+ flags, __FUNCTION__);
+ return -1;
+ }
+
qemuDriverLock(driver);
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
if (!vm) {
@@ -6174,7 +6192,10 @@ static int qemudDomainStart(virDomainPtr dom) {
*/
managed_save = qemuDomainManagedSavePath(driver, vm);
if ((managed_save) && (virFileExists(managed_save))) {
- /* We should still have a reference left to vm but */
+ /*
+ * We should still have a reference left to vm but
+ * but one should check for 0 anyway
+ */
if (qemuDomainObjEndJob(vm) == 0)
vm = NULL;
virDomainObjUnlock(vm);
More information about the libvir-list
mailing list